Compare commits

..

745 Commits

Author SHA1 Message Date
Paul Chote
253e02ae08 Remove dependency on VCRUNTIME140.dll.
(cherry picked from commit bb6400f6f8585523c31dfeb7ab95073263aadd3c)
2023-02-13 21:27:35 +02:00
penev92
f707b9c975 Fixed Makefile check of MacOS architecture 2023-02-05 00:19:18 +01:00
abcdefg30
8629e578e3 Throw an ArgumentException when trying to translate null keys
(cherry picked from commit e4bb13ea07)
2023-02-03 08:36:24 +02:00
abcdefg30
c65cfd3528 Fix an NRE in ConnectionLogic
(cherry picked from commit 84add8a03d)
2023-02-03 08:34:57 +02:00
Azarus
7ad6cfda40 Add an option to check if an actor can be captured via Lua 2023-01-30 13:47:02 +02:00
Dean Simmons
393fd585b1 Only return file paths when returning zip contents
(cherry picked from commit e1b78c4821)
2023-01-26 19:26:59 +02:00
penev92
ea221f9bfb Fixed RA parabomb/paradrop support power tooltips
The AFLD's AirstrikePower@parabombs' description wasn't updated to the latest balance patch (3 Badgers -> 1 Badger)
2023-01-26 09:32:54 +01:00
N.N
b4ca81d1bd Fix deviator GrantExternalCondition Warhead
Warhead now applies only to enemy and neutral units.
2023-01-18 23:43:12 +01:00
RoosterDragon
49590bb5f7 Fix Locomotor cache coherency for disabled or paused mobile actors.
The cache in Locomotor that is populated via the UpdateCellBlocking method disagreed with the non-cached logic of IsBlockedBy when dealing with Mobile actors. The cache determined an actor to be moving if it was both movable and had horizontal movement types. IsBlockedBy determined an actor to be moving if it had horizontal movement types, but did not check if it was movable. This difference in checks could allow a mobile trait that was disabled or paused and which had horizontal movement to be treated differently be the two methods. UpdateCellBlocking would consider it not moving due to the disabled/paused trait. IsBlockedBy would consider it moving as it didn't care about the disabled/paused state of the trait.

Now, we unify the two methods to consider a mobile trait that is disabled/paused as not moving. This prevents HierarchicalPathFinder from crashing on the inconsistent state, i.e. when asked to path search through a cell of a mobile unit which has disabled or paused movement, but which has horizontal movement types from prior movement.
2023-01-17 18:58:34 +01:00
David Wilson
2d059c0d95 Fix to ensure Windows uninstaller removes reg entries from the 64 bit registry 2023-01-14 13:50:04 +01:00
penev92
d5dd6a9086 Added ITilesetSpecificPaletteInfo for linting 2023-01-10 16:37:56 +00:00
Gustas
a7ca0f0699 Fixed UnhardcodeBaseBuilderBotModule update rule
Update rules should should not read `modData.DefaultRules`

(cherry picked from commit 80b92fb667)
2023-01-10 18:13:01 +02:00
Gustas
4b02d9b700 Fixed UnhardcodeSquadManager update rule
Update rules should should not read `modData.DefaultRules`

(cherry picked from commit 29d21545a6)
2023-01-10 18:12:58 +02:00
Gustas
ebf55c8d86 Exclude Plugs from TS protection types
(cherry picked from commit 326f8115a0)
2023-01-10 18:12:51 +02:00
Paul Chote
f928922f3a Add BeforeUpdate* methods for update rules.
These make it possible to write more advanced update
rules that query state across multiple actors, or
based on resolved state.

(cherry picked from commit 129db98a2f)
2023-01-10 18:05:11 +02:00
penev92
bc3743d9ff Added an update rule for adding ControlGroups 2023-01-10 00:14:45 +01:00
penev92
8aa6600655 Added an update rule for DomainIndex removal
Also for adding the new HPF-related PathFinderOverlay and HierarchicalPathFinderOverlay that were added at the same time.
2023-01-10 00:14:04 +01:00
Ivaylo Draganov
215b3d8ab3 Clarify the wording and explain the meaning of some labels in settings
(cherry picked from commit 04648a66e6)
2023-01-09 21:59:41 +02:00
Matthias Mailänder
a397670dce Fix URL button blocking the party button. 2023-01-08 23:07:44 +01:00
Matthias Mailänder
43d7f9c6df Bump DiscordRichPresence library. 2023-01-08 23:07:42 +01:00
Gustas
6904ea8c6b Fixed a spelling error in Discovery ant mission 2023-01-07 17:02:19 +01:00
Gustas
d702d58d1a Remove bogus bridge tiles from temperate tileset 2023-01-07 17:02:18 +01:00
abcdefg30
e0b0c5624f Remove custom network frame counting from ReplayConnection 2023-01-04 09:35:06 +00:00
abcdefg30
33773f895c Specify targetable offsets for the repair pad in Dune 2000 2023-01-03 13:33:20 +01:00
Matthias Mailänder
9f759f3cc2 Enforce use of 'var' instead of explicit type.
(cherry picked from commit 19ecddcd86)
2022-12-29 10:05:20 +02:00
Paul Chote
9fb4302b2f Downgrade OpenAL-soft to 1.10.1.
1.12.2 introduces noticeable behaviour changes
to source positioning and cash ticks. This also
fixes missing sound backends on Linux.
2022-12-28 00:19:39 +01:00
abcdefg30
4685c1a6b1 Change into the correct directory before trying to push
Each workflow step starts back in the default directory,
so we need to checkout the repository folder again
2022-12-24 16:04:51 +01:00
abcdefg30
70bc5b097d Let the documentation workflow fetch the required git branch 2022-12-24 16:04:45 +01:00
Paul Chote
7691507baf Fix pseudo-fullscreen window size on macs with a notch. 2022-12-24 12:12:12 +01:00
abcdefg30
8d6cebe654 Fix map actors not being spawned with the correct owner 2022-12-24 11:20:58 +02:00
Matthias Mailänder
daf10c34a6 Fix invalid actors not spawning in-game. 2022-12-23 18:33:50 +01:00
Matthias Mailänder
d96ec21b95 In map editor replace invalid actor owners with neutral. 2022-12-23 18:33:49 +01:00
Paul Chote
aea1182bb5 Implement state prediction for lobby ready checkbox. 2022-12-23 16:34:05 +02:00
Paul Chote
b413b97a52 Implement state prediction for debug menu checkboxes. 2022-12-23 16:34:05 +02:00
Paul Chote
7daa27f123 Implement state prediction for lobby checkboxes. 2022-12-23 16:34:05 +02:00
Paul Chote
f3f98d8750 Package macOS releases as a universal binary.
* Minimum macOS version is raised to 10.11.
* App bundles ship 3 versions of the runtime and engine binaries,
  and a fat launcher that selects the appropriate runtime/apphost.
* Mono is used for macOS 10.11 - 10.14, or if OPENRA_PREFER_MONO
  environment variable has been set.
2022-12-23 12:55:53 +02:00
Paul Chote
69eeb2dc84 Update native deps to include macOS and Linux arm64 binaries. 2022-12-23 12:55:53 +02:00
Paul Chote
7cee29ff70 Report CPU arch in logs and sysinfo. 2022-12-23 12:54:29 +02:00
Paul Chote
5e80fee913 Fix MiniYaml source locations being lost when merging. 2022-12-23 10:45:24 +02:00
Gustas
c1474204e2 Added carryalls to spectator Economy statistics 2022-12-21 21:09:16 +01:00
N.N
223f9408fd Change tile 9 to Rough TerrainType 2022-12-21 19:57:19 +02:00
Gustas
674ca8555b Fix contrail using the wrong colors 2022-12-21 19:36:12 +02:00
abcdefg30
275325b0cf Run the CI workflow on PRs targeting prep 2022-12-21 13:28:48 +02:00
Paul Chote
06e399d3ce Bubble unhandled double-click events to OnClick. 2022-12-20 23:06:19 +01:00
RoosterDragon
d6d77eab7c HPF is aware of map projection changes.
An event is added to Map to indicate when the cell projection is changed. This is important as this can mean Map.Contains(CPos) could now return different results for the cell. The HierarchicalPathFinder is made aware of these changes so it can rebuild any out-of-date information. This fixes prevent a crash if a cell that was previously outside the map changes height and becomes inside the map. The local path search will explore the cell as it is inside the map - but if the HPF was unaware if had been updated, it will still consider the cell to be outside the map and unreachable, resulting in a crash.
2022-12-20 09:48:44 +13:00
RoosterDragon
2392566c1d HPF handles searches from unreachable source cells into cut off areas.
If a path search is performed by the HierarchicalPathFinder when the source cell is unreachable location, a path is still allowed and starts from one of the cells adjacent to the location. If moving into one of these cells results in the actor moving into an isolated area that cannot reach the target this would previously crash as no abstract path could be found. Now we handle such locations by giving them a unreachable cost so the path search will not attempt to explore them.

Imagine a map split into two by a one tile wide line of impassable cliffs. If an actor is on top of these cliffs it is allowed to path because it can "jump off" the cliff and move into the cell immediately either side of it. However it is important which side it chooses to jump into, as one it has moved off the cliff it loses access to the other side. The previous error came about because the path might try and search on the side that couldn't reach the target location. Now we avoid that being considered.
2022-12-20 09:48:36 +13:00
Matthias Mailänder
028467f150 Fix documentation deployment. 2022-12-18 12:57:21 +13:00
abcdefg30
eee4b04248 Fix the actor edit panel not always getting closed properly 2022-12-18 12:25:21 +13:00
Gustas
f551b542f3 Fix map editor sliders stealing focus 2022-12-15 21:06:25 +01:00
Smittytron
5d5419702b Remove MustDestroy from longbows in Soviet 11 2022-12-10 16:16:24 +02:00
Smittytron
47e89b7d76 Fix Siberian Conflict 3 win trigger 2022-12-10 16:16:13 +02:00
N.N
9bb0409f19 Update D2k map pool 2022-12-07 23:39:44 +01:00
abcdefg30
80ac494948 Fix carryables vanishing when another unit is picked up 2022-12-04 17:41:44 +02:00
abcdefg30
eb82f2b975 Remove a stray $ from infront of the version string when writing logs 2022-12-03 23:49:24 +02:00
abcdefg30
a5c8db82da Mark the script as executable 2022-12-02 23:32:41 +01:00
abcdefg30
2a26ff6818 Revert "Update Ubuntu"
This reverts commit ac351f6e65.
2022-12-02 23:32:39 +01:00
Matthias Mailänder
5a11d54956 Execute self-contained binaries with runtime as backfall 2022-12-02 23:03:58 +01:00
Gustas
26c5a8b76c Add cell reference HPF crash messages 2022-12-02 17:50:13 +01:00
Matthias Mailänder
efcfab78dc Unify file extensions. 2022-12-01 19:54:07 +02:00
Matthias Mailänder
ac351f6e65 Update Ubuntu 2022-12-01 19:54:07 +02:00
abcdefg30
42bdc9e53e Replace influence instead of throwing an exception in AddInfluence 2022-12-01 18:13:16 +01:00
Gustas
3097efc5b6 Fix UnreserveCarryable unreserving carryables of other carriers 2022-12-01 18:13:16 +01:00
Gustas
853422409f Fix AutoCaryall not unreserving when cargo dies 2022-12-01 18:13:16 +01:00
abcdefg30
f097250394 Make sure PickupUnit runs a TakeOff activity before ending 2022-12-01 18:13:16 +01:00
Paul Chote
96e0f96c12 Remove redundant order copies. 2022-11-27 23:00:53 +01:00
Paul Chote
0a4c4162be Always serialize orders. 2022-11-27 23:00:52 +01:00
Paul Chote
10ff24f24e Fix frame number not being included in pre-serialized order packets. 2022-11-27 23:00:51 +01:00
Matthias Mailänder
aeb96d98f3 Update notarisation to XCode 13 tooling. 2022-11-27 20:32:57 +01:00
Paul Chote
cf4bfdcdfb Fix display bounds when running on macbooks with a notch. 2022-11-26 20:45:22 +01:00
dnqbob
d55af8d75d HarvesterBotModule should not command harvesters that cannot be ordered 2022-11-24 23:22:04 +01:00
Matthias Mailänder
dd9e75d017 Show the host in the download failed error message. 2022-11-23 23:36:10 +01:00
Matthias Mailänder
1b6220962e Fix unknown host not getting translated. 2022-11-23 23:36:08 +01:00
Vapre
f70f2acb39 ExceptionHandler, fix npe. 2022-11-22 12:35:33 +01:00
Matthias Mailänder
32e2507bff Revert "Scripts: Check exit status of background process"
This reverts commit 3f106bef72.
2022-11-20 20:36:58 +02:00
Matthias Mailänder
22a42b7dc9 Manually add game speeds to the linter. 2022-11-18 23:14:54 +01:00
Gustas
c01e4043e8 Introduce MinDistance to AreaBeam projectile 2022-11-17 20:51:28 +01:00
Thomas Christlieb
c8665c98a6 fix misclicks through sidebar 2022-11-16 23:22:39 +01:00
abcdefg30
e54b88a6cb Remove dead code inside SupportPower.cs 2022-11-16 20:45:33 +02:00
RoosterDragon
b8a71215eb Fix Locomotor IsMoving checks.
The Locomotor IsMoving check was allowing us to consider another actor that moving as not a blocker. However for some reason it also considered the actor trying to path being mobile as sufficient for this check to pass which did not make sense. We remove that extra check and inline the method.

This was a regression from 4a609bbee8 which changed the method from IsMovingInMyDirection (which required the lookup of the mobile trait) to just IsMoving. It should have removed the lookup as not required.

This fixes a crash in HPF which was considered the location as blocked when Locomotor considered it unblocked because the logic was not aligned. Removing this check aligns the logic and resolves the crash.
2022-11-15 15:42:02 +02:00
Vapre
7005da3592 SpriteRenderer, do not copy vertex array data each flush. 2022-11-14 23:33:24 +01:00
Gustas
243e2b2a2a Fix cloned widgets not having default cursor set 2022-11-13 15:05:48 -06:00
RoosterDragon
a85ac26367 Pathing considers reachability of source cells consistently.
Using the local pathfinder, you could not find a path to an unreachable destination cell, but it was possible to find a path from an unreachable source cell if there was a reachable cells adjacent to it.

The hierarchical pathfinder did not have this behaviour and considering an unreachable source cell to block attempts to find a path.

Now, we unify the pathfinders to use a consistent behaviour, allowing paths from unreachable source cells to be found.
2022-11-13 19:59:36 +01:00
abcdefg30
bedfa622d7 Update AUTHORS 2022-11-12 07:57:12 +01:00
Gustas
0b86936dcd Nerf player experience 2022-11-10 23:33:52 +01:00
ThomasChr
6c348620f3 Use Stop button on (production) buildings to reset rally point fixes #20414 2022-11-09 08:44:09 +02:00
Gustas
ad269555d9 Don't let the player interrupt takeoff after a succesful caryall pickup 2022-11-08 21:51:12 +01:00
Gustas
5db07097e8 Fix carryall not removing influence when cancelling land activity 2022-11-08 21:51:12 +01:00
Gustas
b401f601de Refresh ChatDisabledUntil when entering a new server 2022-11-06 22:28:52 +01:00
Gustas
33a1bb8e6b Don't disable chat in replays 2022-11-06 22:28:52 +01:00
Ivaylo Draganov
4ecf4f9f3f Add a .zsync suffix to appimagecheck URL to pass appimaged checks
Depends on changes in the master server that rewrite the appimagecheck URL.
2022-11-06 14:00:25 +01:00
Matthias Mailänder
81020e70fa Fix actors with immobile actors that don't occupy space
to be placed everywhere way outside the map boundaries.
2022-11-05 21:41:39 +01:00
Matthias Mailänder
74c35edbd9 Fix a crash when flood filling tiles outside of the map. 2022-11-04 00:10:46 +01:00
Gustas
64908c8e70 Fix RenameContrailProperties UpdateRule 2022-11-03 23:35:57 +01:00
Matthias Mailänder
889be47b23 Remove dubFinder style sheet. 2022-11-02 21:33:32 +01:00
Vapre
4fc232f2a6 Authors, anvilvapre. 2022-11-02 14:05:53 +02:00
ThomasChr
a3f8b41e25 Add dropdown for sorting maps in map chooser dialog 2022-11-01 12:08:01 +02:00
abcdefg30
c664af4fe2 Seal the Server.Connection class
Solves CA1816
2022-10-31 12:19:34 +01:00
abcdefg30
a00348dac1 Dispose all connections when shutting down a server 2022-10-31 12:19:34 +01:00
abcdefg30
111d9e4230 Fix replay player disconnect handling 2022-10-30 14:55:55 +01:00
Gustas
7cdc98c8fa FIx anti-ground missiles damaging air units and vice versa 2022-10-30 14:40:39 +01:00
dnqbob
583d85cc2e Allow weapons with no damage warheads to be fired 2022-10-30 14:38:16 +01:00
N.N
08de346e31 fix worm spawn in campaing 2022-10-30 14:32:25 +01:00
notsinned
5242716887 Fix for turret following invisible unit
Fixed turret tracking invisible units after being attacked

Fix for turret following invisible unit

Fix for turrent following invisible unit
2022-10-30 14:08:29 +01:00
Gustas
57143087d7 Fix Aircraft not updating influence when changing height
Occupied cells was defined by height yet we didn't update actor map on changing height. This in some scenarios could have caused the aircraft to forget to remove its influence from actor map
2022-10-30 14:01:32 +01:00
darkademic
f612d82797 Use MacOS 11 for release packaging. 2022-10-29 18:30:58 +02:00
Matthias Mailänder
c22b3f30bb Log OpenRA and Operating System language on crash. 2022-10-29 13:36:36 +03:00
Matthias Mailänder
147804ac30 Inline variables. 2022-10-29 13:36:36 +03:00
EoralMilk
949ef1662d Add mouse scroll to ProductionPaletteWidget 2022-10-28 19:33:57 +02:00
Matthias Mailänder
efe65701e4 Expose game speeds to localisation. 2022-10-27 23:30:19 +02:00
penev92
425c678cd9 Fix TD missions file not using package syntax 2022-10-24 11:45:36 +02:00
Matthias Mailänder
71956cb2a2 Documentation split release/playtest into different branches. 2022-10-21 18:54:58 +03:00
Matthias Mailänder
34ccaf6e9d Fix a crash in Fall of Greece 1: Personal War 2022-10-21 10:42:48 -05:00
Matthias Mailänder
5c8a537efd Fix a crash in Allies 06a. 2022-10-21 10:42:48 -05:00
abcdefg30
c100e64c8e Update Tiberium Forest 2022-10-21 10:35:52 -05:00
Matthias Mailänder
8f415bc7af Localize developer debug cheats. 2022-10-21 17:08:16 +02:00
Matthias Mailänder
44aaf4dd07 Localise text notifications. 2022-10-21 17:08:16 +02:00
Gustas
c041ea7d39 Crash on image/panel not found and add TryGet functions for searching 2022-10-20 19:28:02 +02:00
Gustas
e743e6dd61 Simplify boolean expressions in ProductionPaletteWidget 2022-10-20 19:20:45 +02:00
Gustas
af3d6792b8 Fix ProductionPalette ClockAnimation and NotBuildableAnimation being ignored. 2022-10-20 19:20:45 +02:00
Matthias Mailänder
bd138db9e2 Don't use header tags for non-headers. 2022-10-20 11:02:58 +03:00
Orb370
d9a8a0619c TD-Fall-2022-Balance-Commit 2022-10-19 20:23:19 +03:00
Gustas
686f158117 Refactor BindButtonIcon 2022-10-19 18:26:24 +02:00
abcdefg30
3de0b7982e Adjust the ZOffset of pyle to avoid clipping through the flagpole 2022-10-19 12:23:35 +02:00
abcdefg30
3f5e5e43b3 Make the exit cells of the GDI Barracks transient 2022-10-19 12:23:35 +02:00
Matthias Mailänder
5c3d4a7fe4 Return an error message for invalid cash amounts. 2022-10-18 23:16:20 +02:00
Gustas
347148e02f Allow cash ticking sound to overlap 2022-10-18 22:36:44 +02:00
abcdefg30
fde4f8d0e5 Throw an exception when map.yaml cannot be read 2022-10-18 22:27:51 +02:00
abcdefg30
95c0846ced Remove the filename from the undefined MapFormat exception 2022-10-18 22:27:51 +02:00
abcdefg30
40e207200a Fix a typo in the undefined MapFormat exception message 2022-10-18 22:27:51 +02:00
Matthias Mailänder
acc2c11e69 Fix SupportPowers ClockAnimation being ignored. 2022-10-17 14:20:11 +03:00
abcdefg30
df484633f7 Update the TD map pool 2022-10-14 21:22:42 -05:00
abcdefg30
9498f067bc Remove crate crushing from Visceroids 2022-10-14 20:56:47 -05:00
abcdefg30
625dca6435 Fix dinos not being able to crush crates 2022-10-14 20:56:47 -05:00
Gustas
3181102415 Fix default expressions in commit 75f642bd09 2022-10-14 14:15:57 +03:00
abcdefg30
6e6c828c85 Fix SquadManagerBotModule caching in RenderDebugState 2022-10-14 13:50:57 +03:00
abcdefg30
d8349a429a Remove unnecessary uses of Exts.IsTraitEnabled 2022-10-14 13:50:57 +03:00
abcdefg30
75f642bd09 Introduce FirstEnabledConditionalTraitOrDefault 2022-10-14 13:50:57 +03:00
Gustas
858d782af1 Simplify 'default' expression (IDE0034) 2022-10-11 17:40:05 +02:00
abcdefg30
02d9ba020d Add a workaround for unbinding script members on Mono 2022-10-10 20:27:07 +03:00
Unrud
a2a34dafde MacOS buildpackage: Fix deduplication
The variable `${MOD}` was not enclosed in quotes, but the value contained a space. This caused the argument to be split into two parts.
Using **find** isn't necessary due to globbing.
2022-10-09 00:39:28 +02:00
Gustas
ab26878033 Fix MapCache mapUpdates 2022-10-08 23:08:53 +02:00
Gustas
7f677f1842 Allow driving under crates and crushable units 2022-10-07 21:06:04 +02:00
Gustas
5abbdc37cb Revert "Fix crushables and crates causing HPF to crash."
This reverts commit 5765e51c56.
2022-10-07 21:06:04 +02:00
Gustas
625dc1dd35 Fix subterranean units teleporting to surface and jump jets to ground 2022-10-06 23:03:33 +02:00
Matthias Mailänder
ee0d37f2b1 Add back the man page install 2022-10-05 22:01:04 +02:00
Matthias Mailänder
38a22ebd55 These are not Linux exclusive. 2022-10-05 22:01:04 +02:00
Gustas
043e6f662f Make demolition conditional 2022-10-04 21:55:17 +02:00
Matthias Mailänder
eb897d755e Add observer vision stats. 2022-10-03 20:48:18 +02:00
Ivaylo Draganov
e7dcbb3c2d Improve translation of power/silo usage tooltip
- Fix an instance where "silo-usage" translation was used without
arguments
- Use the same translation reference for the "Power usage"
- Make the ResourceBarWidget accept a cached transform with the tooltip
text
so it won't have to build the string itself
- Display an infinity symbol when the infinite power cheat is used
- Removes a magic number that is no longer used (>1000000 to check for
unlimited power)
2022-10-03 12:00:42 +02:00
Gustas
ba763ac0f0 Add highlighted state to GetCachedStatefulImage 2022-10-01 16:52:04 +03:00
abcdefg30
a75818026a Use SDL.SDL_OpenURL instead of Process.Start to open FAQ and Logs 2022-10-01 14:19:30 +03:00
Matthias Mailänder
6bd631618c Remove unnecessary value assignment (IDE0059) 2022-10-01 14:15:33 +03:00
abcdefg30
757c4d84c7 Change the incompatible replay dialogue text from "Cancel" to "OK" 2022-09-29 23:34:59 +03:00
abcdefg30
b2498fec7d Fix a crash when version or mod of a replay are null 2022-09-29 23:34:59 +03:00
abcdefg30
0d6a7b3c52 Add line breaks to the incompatible replay translations 2022-09-29 23:34:59 +03:00
abcdefg30
a691112c54 Update Linguini to 0.3.1 2022-09-29 23:34:59 +03:00
RoosterDragon
3c66ca709a Fix some bugs in LongBitSet
- Use LongBitSetAllocator and not BitSetAllocator. Using the wrong allocator means all string based checks and displays would provide incorrect results.
- Remove LongBitSetAllocator.Mask which wasn't being calculated or Reset correctly. We can use world.AllPlayersMask to provide the same effect at use sites.
2022-09-29 21:58:17 +02:00
Matthias Mailänder
0080e98390 Fix No Players No Bots No Spectators label overlapping. 2022-09-26 22:47:33 +03:00
tomas
7b7ccf4128 Fix crash in OrderBuffer 2022-09-26 22:44:13 +03:00
Gustas
899298442a Rename the remaining properties in ScrollItemWidget
BaseName: to BackGround:
2022-09-26 13:33:21 +02:00
Matthias Mailänder
f6d13baf4b Use inline strings. 2022-09-26 11:05:15 +03:00
Matthias Mailänder
90a2b677f1 Exit with error code on invalid commands and arguments. 2022-09-26 11:05:15 +03:00
Gustas
fe72dd4140 Remove a ScrollItem header hack
with the merge of #20218 headers no longer need to be selected
2022-09-24 16:23:59 +02:00
Gustas
6b63114aaa Rename ScrollWidget BaseName to Background
To match button
2022-09-24 16:23:59 +02:00
Gustas
5e6f14c9ee Polish TD ScrollItemWidget 2022-09-24 16:23:59 +02:00
RoosterDragon
5765e51c56 Fix crushables and crates causing HPF to crash.
When crushables and crates change their Location/TopLeft, their crushability is cached, but when their CenterPosition is changed, their cached crushability is not refreshed. Since their CrushableBy functions depends on IsAtGroundLevel, which depends on the CenterPosition, this means that when the crushability is cached it will depend on the current height of the object. If the height of the object changes, the cache is not refreshed and now contains out of date information.

The Locomotor cache and the HPF both cache this same information, but at different times. HPF caches immediately, but Locomotor caches on demand which means there can be a delay. This means they can have inconsistent, differing views of the crushability information. This eventually surfaces in a "The abstract path should never be searched for an unreachable point." error from HPF when it detects the inconsistency.

The bug is that Locomotor was caching information without refreshing it when required. Fixing this to refresh the cache when the CenterPosition changes is likely to have negative performance impacts. As would removing crushability from the cache. These would both be fixes that address the underlying bug.

The high impacts of a proper fix lead us to a workaround instead. If we set the CenterPosition before setting the Location, then when the Location is set and the caches are refreshed, the new CenterPosition is available when caching the crushability information. This means logic depending on IsAtGroundLevel will get the new information and cache a more up-to-date view of things. This means when changing both the CenterPosition and Location together we now cache correct information. However calls that set only the CenterPosition and not the Location can still result in a bad cache state. Although this is imperfect it is an improvement over current affairs, and has less impact.
2022-09-24 15:15:53 +02:00
Gustas
1809817b3f Add ContrailEndColor and Contrail transparency control 2022-09-24 13:19:22 +02:00
Gustas
d8f45714a7 Add contrail property descriptions to Bullet and Missile 2022-09-24 13:19:22 +02:00
Gustas
56b665f243 Add TrailDelay to Contrail 2022-09-24 13:19:22 +02:00
Gustas
c781eb0cab Add pressed state to RA and TS ScrollItemWidget 2022-09-22 17:11:33 +02:00
abcdefg30
28adb915f5 Make CheckPalettes report duplicate palettes 2022-09-21 20:06:11 +02:00
abcdefg30
97c96c46f4 Only search for palette definitions on the world actor 2022-09-21 20:06:11 +02:00
abcdefg30
0bbcff973f Only query the palette attribute once in CheckPalettes 2022-09-21 20:06:11 +02:00
N.N
ae7fc11472 Minor adjustment into the D2k
Minor adjustment into the D2k

- Add rally point into the Palace
- removed harvester MustBeDestroyed in campaing
- Players can see they carryalls and ornothopers under the fog.
- Increased CameraRemoveDelay on Superweapons so player can see superweapon impact.
2022-09-21 18:06:18 +02:00
RoosterDragon
70c2ec15d3 Change spaces to tabs.
To follow code style.
2022-09-19 23:36:30 +02:00
Unrud
3f106bef72 Scripts: Check exit status of background process 2022-09-18 10:30:58 +02:00
Unrud
5b085b6c15 Scripts: Remove obsolete comment 2022-09-18 10:30:58 +02:00
Unrud
c29f1590c9 Scripts: Remove exit stmts covered by errexit 2022-09-18 10:30:58 +02:00
Unrud
e2fd7ce7ed Scripts: Remove some subshells that ignore errors 2022-09-18 10:30:58 +02:00
Unrud
1b9a86c0a0 Sciprts: Set pipefail or remove pipes
Errors in pipes are ignored otherwise
2022-09-18 10:30:58 +02:00
Unrud
946cd8f322 Scripts: Set errexit to catch errors 2022-09-18 10:30:58 +02:00
Unrud
7cd0d8c079 Scripts: Prevent paths interpreted as args 2022-09-18 10:30:58 +02:00
Unrud
ea02b90636 Scripts: Quote path variables 2022-09-18 10:30:58 +02:00
Gustas
bb2ee37cc0 Add pressed state to D2K ScrollItemWidget 2022-09-18 10:07:46 +02:00
Shrooblord
70771da45a don't notify players a Harvester is under attack when it's actually healing
Co-authored-by: Gustas <37534529+PunkPun@users.noreply.github.com>
2022-09-17 18:57:59 +02:00
penev92
49ac9079a2 Renamed SpriteSequence documentation command and output file 2022-09-17 15:15:42 +02:00
penev92
04afa4a72c Added some sorting to documentation output 2022-09-17 15:15:42 +02:00
penev92
6b98a75658 Added referencing types to enum definitions 2022-09-17 15:15:42 +02:00
penev92
07b9c941b4 Added documentation page title 2022-09-17 15:15:42 +02:00
penev92
eda3dfa50f Added enum export to documentation generation 2022-09-17 15:15:42 +02:00
Ivaylo Draganov
a985452907 Add myself to AUTHORS 2022-09-16 09:46:20 +01:00
Zachary Schirm
1339faa5f4 Disallowed Save Map without Title and Author Input 2022-09-13 18:48:21 +03:00
Gustas
d95c6e821c Use CachedTransform in ImageWidget 2022-09-13 16:11:18 +02:00
Matthias Mailänder
1536530f78 Add a fake .zsync suffix parameter to pass linting. 2022-09-13 13:20:05 +03:00
Matthias Mailänder
d3a8b07f05 Remove unread private member (IDE0052) 2022-09-13 10:36:57 +03:00
Gustas
43e0cca663 Prevent game from starting with unavailable map 2022-09-12 20:13:42 +02:00
Vapre
7f404f64a6 Selection, cache DeveloperMode trait. 2022-09-11 22:00:18 +03:00
Matthias Mailänder
3be0e9e8a5 Add an in-game encyclopedia to Dune 2000. 2022-09-11 20:19:58 +03:00
RoosterDragon
d2a3659078 Fix landed aircraft above ground level not removing influence on take off.
When the Land activity is run, the aircraft adds influence to the cell so it cannot be used by other actors. When the TakeOff activity runs, it removes the influence so the cell can be used by other actors.

However, when a Carryall picks up a unit, it is told to Land with a vertical offset - it never reaches ground level. When the TakeOff activity runs, it saw the aircraft was above ground level and bailed out. The means the influence is never removed. The cell is now unusable despite the fact the Carryall has left.

To fix this, TakeOff now checks if influence was applied instead of checking if the aircraft is above ground level. If so, we know the Land activity had decided that influence was required, even if the aircraft has not made it to ground level. When TakeOff runs, it will treat it as a proper take off event even though the aircraft is already above ground level. This means influence will be removed and the cell will become accessible as intended.

In ActorMap, we also fix a design flaw where disposed actors where excluded from queries. This caused cache inconsistencies with clients using ActorMap.CellUpdated event to rely on updates. This event will not get called when the actor was disposed, so the downsteam client may have cached the actors at that location, only for them to "change" when the actor is later disposed. This could cause the Locomotor and HierarchicalPathFInder to have inconsistent views of the actors on the map, causing crashes if the inconsistent state broken some internal invariants. The only reason to exclude disposed actors would be to cover up for the actors not being removed properly from the map, which is fixed now aircraft are handled correctly. If ever an actor isn't removed from the actor map, then the caller needs fixing rather than having the actor map exclude it.
2022-09-11 20:04:12 +03:00
Matthias Mailänder
b8e261ff2f Code cleanup in the Tiberian Dawn Lua scripts.
Uppercase global variables.
Declare local variables.
Remove unused variable.
2022-09-11 19:44:38 +03:00
Matthias Mailänder
ca45e02265 Fix untranslated strings in skirmish objectives. 2022-09-10 22:58:28 +03:00
Ivaylo Draganov
3453d13188 Adjust faction label width in lobby to fit better when truncated 2022-09-10 18:26:40 +02:00
Vapre
e3aa2dc6c0 HitShape, query trait via actor cached targetable positions. 2022-09-10 18:23:12 +02:00
abcdefg30
f88b6d78ff Move update rules from 20201213 to 20210321 2022-09-10 17:52:19 +02:00
Vapre
7754e486ee GpsDotEffect, ShouldRender, optimization. 2022-09-10 17:49:58 +02:00
RoosterDragon
7e67889294 Fix a crash when trying to pathfind from unusable custom movement layers.
If a path search is attempted from a location outside the map, then PathSearch will filter these out to prevent any crashes. The path search will result in no path. However if the location is within the map but on a custom movement layer that the locomotor cannot use, this currently crashes. To fix this we apply a similar filtering logic to ignore any source locations that cannot be used, and so the path search will result in no path for these as well.
2022-09-10 15:24:25 +02:00
penev92
c52913716c Added SpriteSequence documentation generation 2022-09-09 21:18:58 +02:00
penev92
dc8c0221e7 Fixed documentation Python script handling of null
The script would serialize null values as "None" in the Markdown files it produces, which is not great. It's better to leave empty strings.
2022-09-09 21:18:58 +02:00
penev92
99b27bbe7b Added missing file extensions to asset browser
These are all file extensions used by the respective mods ingame, so they should be visible in the asset browser as well.
2022-09-09 16:57:22 +03:00
penev92
60b85c933e Reorder asset browser UI's asset list and filters 2022-09-09 16:57:22 +03:00
penev92
8a38ac0d24 Added an asset type filter to AssetBrowserLogic 2022-09-09 16:57:22 +03:00
Gustas
4901de24b1 Select LastModifiedMap when entering ServerCreation 2022-09-09 14:31:25 +03:00
Gustas
81561778a2 Select LastModifiedMap when entering MissionBrowser
And add auto-updating to the play button
2022-09-09 14:31:25 +03:00
Gustas
63b76d1b53 Select LastModifiedMap when entering LobbyLogic 2022-09-09 14:31:25 +03:00
Gustas
02b6a260af Make IngameMenuLogic use ShowMenu 2022-09-09 14:31:25 +03:00
Zachary Schirm
9a5d352e41 Disallow saving the game with an empty name field 2022-09-09 11:39:31 +03:00
Zachary Schirm
125a7b8c88 Disallow Join button without IP address input
Disallow join button without IP address Input

Closes #20234

Trying to join a server with an empty address crashes the game. This fix disallows pressing join button without ip address field input.  Updated to reuse search for joinButton vs 2 separate calls to search.
2022-09-09 11:22:52 +03:00
Gustas
ee0d958cd1 Fixed incorect fluent name in MissionBrowserLogic 2022-09-08 23:45:11 +02:00
Gustas
9ae27b8e60 Fix team 0 being translated in SpawnSelectorTooltipLogic 2022-09-08 23:45:11 +02:00
Gustas
1b00cef30f Fix a few tooltip translations being called every frame
in WorldTooltipLogic and IngamePowerBarLogic
2022-09-08 23:45:11 +02:00
Ivaylo Draganov
56a9acd035 Extract a couple of untranslated strings 2022-09-08 23:45:11 +02:00
dnqbob
6ccd000257 Make building and bridge repair traits public 2022-09-07 14:04:23 +02:00
Matthias Mailänder
fb5624880b Fix sorting. 2022-09-06 20:52:04 +03:00
Matthias Mailänder
67aa0cdede Avoid Count() when Any() could be used (CA1827) 2022-09-06 20:52:04 +03:00
Matthias Mailänder
7ba6a49378 Avoid using LINQ on indexable collections (CA1826) 2022-09-06 18:02:39 +02:00
Matthias Mailänder
68ca09e896 Fixed "bots" not getting translated in Lobby dropdowns 2022-09-05 22:35:50 +02:00
reaperrr
145f6abc09 Add option to limit render fps to game tick rate
This helps slow systems that struggle to render 2 frames per game tick.
2022-09-04 17:00:37 +03:00
penev92
216029dc27 Fix a crash with BlockingCollection in Connection
The BlockingCollection would have `IsAddingCompleted` to true, but `IsComplete` to false, slipping through the cracks and causing an InvalidOperationException ("The collection has been marked as complete with regards to additions.") when trying to add to it.
We now add a check on `(Try)SendData` to only try to add if we can. The collection is still viable for reading until empty/`IsComplete`.
2022-09-04 13:04:17 +03:00
RoosterDragon
2a681d3791 Fix HierarchicalPathFinder considering some unreachable cells as reachable.
When using the internal AbstractCellForLocalCell method to check if a local cell is reachable, this should return null when the cell is unreachable. If multiple abstract cells were required for that grid, this worked as intended. Only reachable cells are stored in the localCellToAbstractCell mapping. For a grid that required only a single abstract cell, which is the common case, we optimize this to store only the single abstract cell rather than the whole mapping for potentially 100 cells in that grid. However this makes no distinction between the reachable and unreachable cells, so when we check later we get incorrect results. If a cell is unreachable but belongs to the same grid as a single group of reachable cells then we incorrectly report it as reachable. The easiest way to see this incorrect behaviour is when the PathExists is called and can sometimes indicate a path exists when it does not.

To fix this, we now ensure we perform a check to see if the cell is reachable in this single layer case, this allows us to retain the optimization where we don't need to store the whole mapping, but allows us to correctly indicate when cells are unreachable.
2022-09-03 19:28:47 +02:00
Vapre
63499c6334 ShroudRenderer, fix, no shroud or fog in editor. 2022-09-03 19:20:25 +02:00
Vapre
57ce88cc9a ShroudRenderer, fix, render Shroud if fog disabled. 2022-09-02 20:13:56 -05:00
Matthias Mailänder
e2284f660c Add documentation to TeslaZap. 2022-09-02 19:58:48 -05:00
Matthias Mailänder
3513d37702 Fix a line break. 2022-09-02 19:58:48 -05:00
penev92
737cdd7851 Reworked trait documentation generation
Switched the Utility's ExtractTraitDocsCommand output to JSON.
Updated documentation generation to use that and the new Python script to generate the Markdown file, same as the Weapon documentation.
2022-09-02 20:56:55 +02:00
penev92
a522457bb6 Reworked weapon documentation generation
Switched the Utility's ExtractWeaponDocsCommand output to JSON.
Added a Python script to generate documentation Markdown from JSON.
2022-09-02 20:56:55 +02:00
penev92
c21bf31ebc Fixed weapon docs not including WeaponInfo
Also made some code cleanups in the weapon docs export code.
2022-09-02 20:56:55 +02:00
penev92
a73d710bec Added Util.InternalTypeName() 2022-09-02 20:56:55 +02:00
penev92
9ed2e699c6 Fix tiny error in output string 2022-09-02 20:56:55 +02:00
penev92
2f0f5f4cda Fixed ScrollPanelWidget not resetting on Clear 2022-09-02 16:16:45 +02:00
Gustas
8402d7d476 Improved Widget.RemoveChildren performance
Modifying the list potentially several thousand times is really slow, so notify the child elements that they are being removed and then clear the list in one go.
2022-09-02 16:16:45 +02:00
penev92
378c447ded Misc fixes in AssetBrowserLogic and MapOverlaysLogic 2022-09-02 16:16:45 +02:00
penev92
df836620dc Added missing spacing to map editor dropdowns 2022-09-02 16:16:45 +02:00
Ivaylo Draganov
c1e1765c2f Move game speed lobby dropdown before time limit dropdown
Game speed is the more frequently changed option and with the current
layout it was buried below the fold.
2022-09-02 16:09:05 +02:00
Matthias Mailänder
0b67b5bfae Extract translation strings. 2022-09-02 14:41:24 +03:00
Gustas
dfd5a960ed Fix RepairableBuilding never stopping repair 2022-09-01 18:30:47 +03:00
RoosterDragon
2d45e67bca Teach HierarchicalPathFinder about Immovable actors.
By tracking updates on the ActorMap the HierarchicalPathFinder can be aware of actors moving around the map. We track a subset of immovable actors that always block. These actors can be treated as impassable obstacles just like terrain. When a path needs to be found the abstract path will guide the search around this subset of immovable actors just like it can guide the search around impassable terrain. For path searches that were previously imperformant because some immovable actors created a bottleneck that needed to be routed around, these will now be performant instead. Path searches with bottlenecks created by items such as trees, walls and buildings should see a performance improvement. Bottlenecks created by other units will not benefit.

We now maintain two sets of HPFs. One is aware of immovable actors and will be used for path searches that request BlockedByActor.Immovable, BlockedByActor.Stationary and BlockedByActor.All to guide that around the immovable obstacles. The other is aware of terrain only and will be used for searches that request BlockedByActor.None, or if an ignoreActor is provided. A new UI dropdown when using the `/hpf` command will allow switching between the visuals of the two sets.
2022-08-31 23:12:42 +02:00
RoosterDragon
7e7d94ca89 Fix Locomotor CellCache to not consider transit only cells as crushable.
When the UpdateCellBlocking encountered a transit-only cell (the bibs around a building) it would bail from the loop. This would leave the cellCrushablePlayers set to all players. It would update the cell cache and mark that cell as a crushable location.

When CanMoveFreelyInto would later evaluate a cell, it would consider it passable because the crushable check would pass (cellCache.Crushable.Overlaps(actor.Owner.PlayerMask)) rather than because the transit check (otherActor.OccupiesSpace is Building building && building.TransitOnlyCells().Contains(cell)) would pass.

Although this meant the cell was treated as passable in either scenario, it means the cache contained incorrect data. The cell does not contain any crushable actors but the cache would indicate it did. Correcting this means we can rely on the crushability information stored in the cache to be accurate.
2022-08-31 23:12:42 +02:00
RoosterDragon
77779023d5 Notify of shroud state changes when using DevVisibility cheat.
When this cheat is used by notifying of shroud changes we invoke the usual logic that would occur if the visibility had been granted by units. Without this change any cached information about the visibility is not refreshed. Without this refresh actors with different visibility may not act correctly.

One aspect this improves is frozen actors. Using the visibility cheat will show up all actors on the map. If the cheat is then disabled than frozen actors will appear in their place. Prior to this change a frozen actor would fail to appear if the cheat had caused it to be revealed. Healthbars and selection boxes are also made consistent for similar reasons.
2022-08-31 23:31:48 +03:00
RoosterDragon
1fc1bdc849 Fix frozen actors lacking tooltips if they have the cloak ability.
Since bbf5970bc1 we update frozen actors only when required.

In 8339c6843e a regression was fixed where actors created in line of sight would be invisible.

Here, we fix a related regression where cloaked units that are revealed, and then frozen when you move out of line of sight would lack tooltips.

The fix centers around the setting of the Hidden flag. In the old code this used CanBeViewedByPlayer which checks for visibility modifiers and then uses the default visibility. The bug with this code is that when a visibility modifier was not hiding the actor, then we would report the default visibility state instead. However the frozen visibility state applies here which means if the frozen actor is visible, then we consider the actor to be hidden and therefore tooltips will not appear. In the fixed version we only consider the modifiers. This means a visibility modifier such as Cloak can hide the frozen actor tooltips. But otherwise we do not consider the frozen actor to be hidden. This prevents a frozen actor from hiding its own tooltips in some unintended circular logic. Hidden now becomes just a flag to indicate if the visibility modifiers are overriding things, as intended.
2022-08-31 23:31:48 +03:00
Mustafa Alperen Seki
16babc1975 Fix Fog color on Radar. 2022-08-31 16:04:40 +03:00
Vapre
215898c7ec ScriptActorInterfaces, unbind on actor destroy. 2022-08-30 21:44:39 +02:00
Gustas
fc1d8d2355 Update RA maps to format 12 2022-08-30 20:03:40 +02:00
Gustas
f98a74f70d Update TD maps to format 12 2022-08-30 20:03:40 +02:00
Gustas
89bb800dbf Update D2K maps to format 12 2022-08-30 20:03:40 +02:00
Gustas
09cb38bc6e Update TS maps to format 12 2022-08-30 20:03:40 +02:00
Gustas
c40675cfba Include map.png into uid generation 2022-08-30 20:03:40 +02:00
RoosterDragon
bcf4ff3b7c Prevent radar crash when dealing with map height. 2022-08-30 19:58:48 +02:00
Gustas
539bb09d50 Fix shroud selector dropdown 2022-08-29 21:13:27 +03:00
Gustas
51c09ddae9 Fix Mission Group having all headers selected 2022-08-29 13:45:38 +03:00
Gustas
08dbfe0cbd Refactor ScrollItemWidget to use stateful image names 2022-08-29 13:45:38 +03:00
Gustas
11a2e6e19b Add more confirmation dialogue to the map editor
When saving on top of another map, or when saving on a map that has been edited outside the map editor
2022-08-29 12:31:01 +03:00
Gustas
d3589c051d Add descriptions to all projectiles and warheads 2022-08-29 12:26:33 +03:00
Vapre
6e547469d6 Shroud, combine IsVisible and IsExplored into a single function. 2022-08-28 18:50:51 +02:00
Ivaylo Draganov
cc1f10dd35 Truncate faction name in lobby dropdown button 2022-08-25 10:44:17 +03:00
dnqbob
29fc2b80d9 WithMuzzleOverlay is decoration 2022-08-21 23:59:15 +02:00
Gustas
ce254f8b46 Add per player mutes 2022-08-20 14:52:49 +02:00
Gustas
81da717f19 Add chat on/off icon to glyphs 2022-08-20 14:52:49 +02:00
Gustas
16198c121c Increase the size of ingame-info panel
And add an Actions section for Kick
2022-08-20 14:52:49 +02:00
Gustas
dde10249d5 Fixup faction and score info UI
And increase spectator name length to match regular players
2022-08-20 14:52:49 +02:00
Gustas
58fcffa429 Add anti-flood protection 2022-08-20 10:24:25 +02:00
tomas
ac623d784a Remove Do() and replace with foreach() 2022-08-19 22:38:38 +02:00
tomas
92478a219e Fix crash when selecting the same map 2022-08-18 00:03:50 +02:00
Gustas
3ab6d3f00a Remove map editor debug message 2022-08-17 23:29:11 +02:00
RoosterDragon
32aaac1dc2 HierarchicalPathFinder.PathExists checks the locations are in map bounds.
Without this, passing locations outside the map could cause a crash instead of reporting no path.
2022-08-17 10:13:27 +03:00
Gustas
ae3a1c2561 Add truncation to FactionLabel 2022-08-16 18:58:45 +03:00
Mustafa Alperen Seki
1b1868fca6 Render every available ProductionIconOverlay. 2022-08-16 15:08:51 +03:00
Mustafa Alperen Seki
54340591e3 Unhardcode VeteranProductionIconOverlay. 2022-08-16 15:08:51 +03:00
Gustas
d438508994 Added try/catch for TypeDictionary errors in Lint code
TypeDictionary errors are very hard for modders to debug as they don't mention which actor is causing the error
2022-08-15 23:19:18 +02:00
Matthias Mailänder
cc58fe1a0f Extract translation strings. 2022-08-14 16:11:51 +02:00
Matthias Mailänder
8201a57b10 Don't complain about re-usable terms not getting referenced. 2022-08-14 16:11:51 +02:00
Matthias Mailänder
2c8c6e50da Code cleanup 2022-08-14 16:11:51 +02:00
Gustas
10ac07bf9f Fix ChooseInitialMap 2022-08-13 17:14:21 +02:00
RoosterDragon
8339c6843e Fix actors not being visible when created within sight range of an enemy.
Since bbf5970bc1 we only update frozen actor state on demand rather than every tick. However when the actor was initially created we were failing to set the initial visibility state if the frozen actor was invisible.

With this fix, we now set the visibility states on creation correctly. This fixes an issue where enemy actors created within line of sight would not appear.
2022-08-13 12:05:03 +03:00
RoosterDragon
2599cb26d8 Allow custom cost to exclude source locations in path searches.
During the refactoring to introduce HierarchicalPathFinder, custom costs were no longer applied to source locations. The logic being that if we are already in the source location, then there should be no cost added to it to get there - we are already there!

Path searches support the ability to go from multiple sources to a single target, but the reverse is not supported. Some callers that require a search from a single source to one of multiple targets perform their search in reverse, swapping the source and targets so they can run the search, then reversing the path they are given so things are the correct way around again. For callers that also use a custom cost like the harvester code that do this in order to find free refineries, they might want the custom cost to be applied to the source location. The harvester code uses this to filter out overloaded refineries. It wants to search from a harvester to multiple refineries, and thus reverses this in order to perform the path search. Without the custom cost being applied to the "source" locations, this filtering logic never gets applied.

To fix this, we now apply the custom cost to source locations. If the custom cost provides an invalid path, then the source location is excluded entirely. Although this seems unintuitive on its own, this allows searches done "in reverse" to work again.
2022-08-13 11:58:45 +03:00
RoosterDragon
df858e06d6 Fix HierarchicalPathFinder failing to consider multiple source locations.
When asked to find a path from multiple source locations, the abstract search is used to determine which source locations are viable. Source locations that cannot be reached on the abstract graph are excluded from the local path search. As we know the locations are unreachable, this prevents the local path search from expanding over the entire search space in an attempt to find these unreachable locations, preventing wasted effort.

In order to determine these reachable locations, the abstract search is expanded successively trying to reach each source location each time. However, this failed to account for a property of the ExpandToTarget for which a comment is now added. If the location was found previously, then expanding to try and find it again will fail. If the source locations were close together, it was likely that the initial expansions of the search space would have included them, and thus they would not be found on a later expansion. This would mean these locations would incorrectly be thought unreachable.

To fix this, we check if the location has already been explored (has CellStatus.Closed in the graph). If so we can check the cost to determine if it is reachable.
2022-08-13 11:58:45 +03:00
abcdefg30
f49536ea12 Use Attribute.IsDefined over GetCustomAttributes 2022-08-12 20:14:54 +02:00
Matthias Mailänder
aa14c9c570 Add VTOL landing exhaust animation. 2022-08-12 00:54:44 +03:00
Matthias Mailänder
1073a7124f Remove an unused field from TakeOff.cs 2022-08-12 00:54:44 +03:00
Gustas
542c5dcfc3 Cleanup directional cursor yaml 2022-08-08 23:28:51 +02:00
Gustas
88e2314776 Add directional support powers to D2K ornithopters 2022-08-08 23:28:51 +02:00
Gustas
fd9758dcbf Make game timer only blink on pause 2022-08-08 10:47:05 +02:00
RoosterDragon
bbf5970bc1 Update frozen actors only when required.
Previously, actors that were visible would refresh their frozen actor state every tick in preparation for the actor becoming hidden, and the frozen actor appearing as a placeholder instead.

By using ICreatesFrozenActors.OnVisibilityChanged when can avoid refreshing the state constantly, and instead just refresh it the moment the frozen actor needs to appear. This provides a nice performance improvement on the cost on managing frozen actors.
2022-08-07 16:50:53 +02:00
darkademic
e827e9952e Additional performance graph colors so same color is not used multiple times. 2022-08-06 22:33:27 +02:00
abcdefg30
dc6be0fd77 Change the IRC link from Freenode to Libera in the issue template config 2022-08-06 16:12:25 +02:00
abcdefg30
47b6f564e3 Add a link to Discord to the PR template and change Freenode to Libera 2022-08-06 16:12:25 +02:00
abcdefg30
d830bca706 Fix force fire opportunity targets not being persisted properly 2022-08-06 15:38:46 +02:00
abcdefg30
5f86f56bed Reduce code duplication in AttackFollow 2022-08-06 15:38:46 +02:00
abcdefg30
0134f63f4d Fix actors with AttackFollow moving away from their targets on amove 2022-08-06 15:38:46 +02:00
Unrud
b88ebd8499 Make Red Alert SVG artwork square
Fix typo in height (128 instead of 138).
2022-08-04 20:02:44 +02:00
RoosterDragon
93998dc4a7 Add a PathFinderOverlay to visualize path searches.
Activated with the '/path-debug' chat command, this displays the explored search space and costs when searching for paths. It supports custom movement layers, bi-directional searches as well as visualizing searches over the abstract graph of the HierarchicalPathFinder. The most recent search among selected units is shown.
2022-08-03 23:12:42 +02:00
RoosterDragon
aef65d353d Replace DomainIndex internals with a lookup from HierarchicalPathFinder instead
Teach HierarchicalPathFinder to keep a cache of domain indices, refreshing them only on demand and when invalidated by terrain changes. This provides an accurate and quick determination for checking if paths exist between given locations.

By exposing PathExistsForLocomotor on the IPathFinder interface, we can remove the DomainIndex trait entirely.
2022-08-03 23:12:42 +02:00
RoosterDragon
5a8f91aa21 Add a hierarchical path finder to improve pathfinding performance.
Replaces the existing bi-directional search between points used by the pathfinder with a guided hierarchical search. The old search was a standard A* search with a heuristic of advancing in straight line towards the target. This heuristic performs well if a mostly direct path to the target exists, it performs poorly it the path has to navigate around blockages in the terrain. The hierarchical path finder maintains a simplified, abstract graph. When a path search is performed it uses this abstract graph to inform the heuristic. Instead of moving blindly towards the target, it will instead steer around major obstacles, almost as if it had been provided a map which ensures it can move in roughly the right direction. This allows it to explore less of the area overall, improving performance.

When a path needs to steer around terrain on the map, the hierarchical path finder is able to greatly improve on the previous performance. When a path is able to proceed in a straight line, no performance benefit will be seen. If the path needs to steer around actors on the map instead of terrain (e.g. trees, buildings, units) then the same poor pathfinding performance as before will be observed.
2022-08-03 23:12:42 +02:00
abcdefg30
cea9ceb72e Support multiple With(Turret)AimAnimation traits 2022-08-03 21:11:03 +02:00
abcdefg30
f2eb42a4b2 Make With(Turret)AimAnimation support multiple AttackBase traits 2022-08-03 21:11:03 +02:00
abcdefg30
ee3c54b572 Disallow starting a game without players 2022-08-03 21:03:46 +02:00
abcdefg30
ea72c50fb4 Fix GrantConditionOnPowerState not being usable on player actors 2022-08-03 20:58:21 +02:00
abcdefg30
1628ce64db Fix lobby error messages from the server being untranslated 2022-08-03 20:54:13 +02:00
dnqbob
8d3ff9d2fc UnhardcodeBaseBuilderBotModule rule update 2022-08-03 11:22:59 +02:00
dnqbob
013ec52108 Unhardcode defenses in BaseBuilderBotModule 2022-08-03 11:22:59 +02:00
Vapre
e8748200f7 Demolishable, trivial optimization. 2022-08-02 00:29:59 +03:00
Vapre
3f3687f71d Widget, avoid copying child list when reverse iterating. 2022-07-31 22:10:49 +02:00
N.N
a9d1b771a0 Align ORA d2k to original D2k
Align ORA D2k weapons to better match original d2k.
2022-07-28 23:42:00 +02:00
RoosterDragon
8dec998d8f Fix tab completion to work for all available commands.
Commands are registered in WorldLoaded event handlers, and IngameChatLogic takes all registered commands and provides tab completion. However IngameChatLogic is also created during WorldLoaded via LoadWidgetAtGameStart. No initialization order is enforced between commands and LoadWidgetAtGameStart, so they can appear in any order.

If a command gets registered before LoadWidgetAtGameStart runs, then it will get tab completion. If it gets registered after then no tab completion is available, even though the command can still be used and appears when using '/help'.

To fix this, we allow the tab completion to check for available commands lazily, meaning it will check for available commands every time the tab key is pressed. This means it will always have the full list of commands available regardless of the initialization order.
2022-07-26 16:42:18 +02:00
teinarss
999af0c05b Add OrderBuffer and time synchronisation. 2022-07-26 15:09:08 +03:00
abcdefg30
4435bdec3c Fix a crash when there is no briefing text 2022-07-25 20:19:36 -05:00
Gustas
e00887e4e1 Make support power fakes infiltratable 2022-07-25 20:07:02 -05:00
N.N
75554123f6 make ornithopter targetable
make ornithopter targetable by anti-air units

update to use just one Targetable type
2022-07-24 21:17:28 +02:00
Gustas
bf5bd63635 Refactor checkbox 2022-07-23 18:32:43 +02:00
Vapre
804bff1b0e TooltipWidgetContainer, load tooltip ui only when visible. 2022-07-18 17:54:57 +02:00
Andre Mohren
0e5f33ef93 PlayerColorPalette now using the full palette if no RemapIndex is set. 2022-07-18 12:23:39 +03:00
Andre Mohren
df72d303b8 Added PaletteFromGrayscale. 2022-07-18 12:23:39 +03:00
Gustas
b597c000d6 Update LobbyLogic to use the new MapCache map tracking 2022-07-17 22:23:13 +02:00
Gustas
6bcf194874 Add map update tracking to MapCache and fix crash when restarting a game 2022-07-17 22:23:13 +02:00
AspectInteractive2
a1a50d6c98 Added rotation logic to the renderer to enable the use of Interpolated Facings. 2022-07-17 17:03:53 +02:00
Sieds Aalberts
e060d6eb05 CellLayer TryGetValue. Return a value if within cell layer bounds. 2022-07-15 20:41:26 +03:00
Gustas
a5ea98ae35 Add RAGL S12 balance 2022-07-15 19:05:41 +02:00
penev92
4f34029556 Added a missing SequenceReferenceAttribute 2022-07-15 19:23:41 +03:00
tomas
5f4ed5f16b Update TextNotificationsManager to use Ui.Send 2022-07-15 19:19:09 +03:00
tomas
b0329aad35 Add Mediator for UI notifications 2022-07-15 19:19:09 +03:00
Matthias Mailänder
91fbd618ce Fix a crash when encountering 0 byte .vqa placeholders. 2022-07-12 23:23:28 +02:00
Leo512bit
9e34299085 Changed anypower tag name to A Power Plant
Updated wording and changed cnc

Capitlazied and added TS
2022-07-11 23:31:41 +02:00
Unrud
0a36d6f995 Use python3 for gtk-dialog.py
As mentioned in https://github.com/OpenRA/OpenRA/pull/20059#issuecomment-1166288560
2022-07-10 18:55:25 +02:00
Unrud
678f249c63 Scripts: Disable markup in error messages
Error messages are displayed using the following methods:

* **zenity** parses pango markup and replaces escaped characters
* **kdialog** replaces (some) escaped characters
* **gtk-dialog.py** replaces `\n`
* **printf** interprets format strings and replaces escaped characters
* **echo** just displays the text

The error messages themself contain escaped characters and paths from variables.

This PR unifies the behavior by:

* Use **printf** to format error messages and replace escaped characters
* Setting `--no-markup` for **zenity** to disable pango markup and escaped characters
* Remove `\n` replacement from **gtk-dialog.py**.
* Use plain **echo** instead of **printf**
2022-07-10 18:55:25 +02:00
Gustas
a03e794140 Add an option to disable chat in replays 2022-07-08 19:40:04 +02:00
abcdefg30
8a98ad51fd Fix sequences only being checked on actors with RenderSprites 2022-07-08 10:28:39 +03:00
abcdefg30
0ded8f8080 Allow null images for SmokeImage on SmudgeLayer 2022-07-08 10:28:39 +03:00
Gustas
36a86c2cd8 Nerf supply truck XP gain 2022-07-06 19:55:49 -05:00
abcdefg30
90ea611cee Rename the 20201213 update rules directory to 20210321 2022-07-05 16:44:17 +02:00
Unrud
bd6d69c5a1 Makefile: More robust check-scripts
Use **xargs** to pass results of **find** instead of word splitting. Word splitting fails when filenames contain white spaces (or if no files are found).
2022-07-05 16:07:01 +02:00
abcdefg30
8e1dce4bbe Add a lint check for maps without playable player 2022-07-05 16:01:22 +02:00
Gustas
7439f8b20a Update AUTHORS 2022-07-05 16:12:09 +03:00
Vapre
8c042a243e PathSearch, make TargetPredicate a readonly private field. 2022-07-04 20:34:23 +02:00
Matthias Mailänder
834de4efbe Port to Linguini 2022-07-02 22:32:37 +01:00
Matthias Mailänder
9d8c2bb4c4 Recommend .ftl syntax highlighting. 2022-07-02 22:32:37 +01:00
Sieds Aalberts
f5de8be3f0 Rectangle equals, trivial optimization. 2022-07-02 23:40:01 +03:00
Paul Chote
c8df1e864c Rework sequence docs plumbing. 2022-07-02 14:10:52 +03:00
Paul Chote
2037e37d4e Replace Sequence EmbeddedPalette with HasEmbeddedPalette. 2022-07-02 14:10:52 +03:00
abcdefg30
c1822d1cef Fix NREs in CheckUnknownWeaponFields 2022-06-26 23:46:51 +01:00
abcdefg30
82692b9d7f Fix crashes in WeaponInfo when warheads or projectiles cannot be created 2022-06-26 23:46:51 +01:00
abcdefg30
185bef39b0 Fix "Inherits" nodes being resolved as objects during linting 2022-06-26 23:46:51 +01:00
abcdefg30
5fe166dfd3 Fix an NRE in CheckUnknownTraitFields 2022-06-26 23:46:51 +01:00
penev92
07ec2d03fb Added an option to run utility.cmd programatically
And still pass arguments to Utility.exe without having to manually input them.
2022-06-26 16:14:22 +01:00
penev92
c3c5dbfa35 Unhardcoded SpriteSequence properties
To prepare them for documentation generation.
Also added descriptions to SpriteSequence implementations and their properties.
Also made a few code style fixes.
2022-06-26 15:41:19 +01:00
abcdefg30
d1f7fb8fb8 Serialize the actor generation for network orders 2022-06-25 18:18:49 +02:00
abcdefg30
13145557c8 Fix the switch-case formatting in Order.Deserialize 2022-06-25 18:18:49 +02:00
Mustafa Alperen Seki
c15af9f68a Ignore nonexistent actors in D2k importer code instead of crashing. 2022-06-24 22:26:15 +01:00
Mustafa Alperen Seki
6083eb4ac8 Remove D2k CheckImportActors 2022-06-24 22:26:15 +01:00
penev92
07db77fb8d Fix RemoveTurnToDock update rule 2022-06-24 21:16:26 +01:00
Ivaylo Draganov
5f42c7c8df Add support for readonly hotkeys and expose chat input hotkeys 2022-06-24 19:42:53 +01:00
Matthias Mailänder
1969ae361c Add missing ISync 2022-06-12 18:40:35 +02:00
Paul Chote
d050fe9f26 Move UnitOrderGenerator to Mods.Common. 2022-06-12 11:57:38 +02:00
Paul Chote
6eb8a4568b Allow mods to replace UnitOrderGenerator with their own default. 2022-06-12 11:57:38 +02:00
Paul Chote
bbe068f6cb Move IOrderGenerator to OpenRA.Orders namespace. 2022-06-12 11:57:38 +02:00
Ivaylo Draganov
320228f9d9 Add hotkeys for editor map overlays 2022-06-10 18:21:57 +02:00
Ivaylo Draganov
13ceda3259 Add hotkeys for map editor tabs 2022-06-10 18:21:57 +02:00
Ivaylo Draganov
b02a3d0f8f Remove unused yaml node in editor chrome 2022-06-10 18:21:57 +02:00
RoosterDragon
c9ee902510 Fix issues preventing suboptimal path searches.
Two different issues were causing a path search to not explore cells in order of the cheapest estimated route first. This meant the search could sometimes miss a cheaper route and return a suboptimal path.

- PriorityQueue had a bug which would cause it to not check some elements when restoring the heap property of its internal data structure. Failing to do this would invalidate the heap property, meaning it would not longer return the items in correct priority order. Additional tests ensure this is covered.
- When a path search encountered the same cell again with a lower cost, it would not update the priority queue with the new cost. This meant the cell was not explored early enough as it was in the queue with its original, higher cost. Exploring other paths might close off surrounding cells, preventing the cell with the lower cost from progressing. Instead we now add a duplicate with the lower cost to ensure it gets explored at the right time. We remove the duplicate with the higher cost in CanExpand by checking for already Closed cells.
2022-06-07 15:47:02 +02:00
penev92
c1cb9ea6be Removed an using, redundant when building on Mono 2022-06-03 21:43:43 +02:00
abcdefg30
6a31b1f9f3 Update the copyright header year 2022-05-28 00:35:10 -05:00
Matthias Mailänder
3f328a14be Hack removal 2022-05-24 21:07:54 -05:00
Matthias Mailänder
709512b166 Add Lua API export in EmmyLua syntax. 2022-05-24 21:07:54 -05:00
RoosterDragon
550db7e958 Ensure SpawnStartingUnits initializes after Locomotor.
Prior to ef44c31a72, Locomotor would be earlier in the trait initialization sequence than SpawnStartingUnits. After this commit, the initialization sequence was perturbed and SpawnStartingUnits would initialize first. When SpawnStartingUnits would query CanEnterCell this would generate a null reference as Locomotor had not yet initialized.

SpawnStartingUnitsInfo is made to initialize NotBefore LocomotorInfo to enforce the required trait ordering.
2022-05-24 12:45:03 -05:00
darkademic
1fc3785f79 Make range modifiers apply to AreaBeam projectile. 2022-05-22 19:42:23 -05:00
RoosterDragon
89042014bd Gracefully handle trying to find paths outside the map.
Rather than crashing, return no path instead.
2022-05-22 17:39:44 -05:00
abcdefg30
4ec19b3486 Remove deprecated airstrike and paratrooper methods for Lua 2022-05-22 10:57:30 -05:00
abcdefg30
7ec74749be Remove the deprecated WAngle.Range accessor for Lua 2022-05-22 10:57:30 -05:00
abcdefg30
c827d1a4ab Remove deprecated integer facing handling for Lua 2022-05-22 10:57:30 -05:00
abcdefg30
660130653c Use TryGetValue instead of ContainsKey and a lookup for cached sounds 2022-05-22 10:39:27 -05:00
abcdefg30
ea04a7fec5 Clear cached notifications when initializing a new map/mod 2022-05-22 10:39:27 -05:00
abcdefg30
9d481854f3 Make currentSounds readonly 2022-05-22 10:39:27 -05:00
atlimit8
85b9cf0a69 Fix fatal radar sound bug
The following error occurs on a map where the radar activation sound plays:
Exception has occurred: CLR/System.ArgumentException
An exception of type 'System.ArgumentException' occurred in System.Private.CoreLib.dll but was not handled in user code: 'Property set method not found.'
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
   at OpenRA.FieldLoader.LoadField(Object target, String key, String value) in /home/jason/git/OpenRA/OpenRA.Game/FieldLoader.cs:line 609
   at OpenRA.WidgetLoader.LoadWidget(WidgetArgs args, Widget parent, MiniYamlNode node) in /home/jason/git/OpenRA/OpenRA.Game/Widgets/WidgetLoader.cs:line 60
   at OpenRA.WidgetLoader.LoadWidget(WidgetArgs args, Widget parent, MiniYamlNode node) in /home/jason/git/OpenRA/OpenRA.Game/Widgets/WidgetLoader.cs:line 67
   at OpenRA.WidgetLoader.LoadWidget(WidgetArgs args, Widget parent, MiniYamlNode node) in /home/jason/git/OpenRA/OpenRA.Game/Widgets/WidgetLoader.cs:line 67
   at OpenRA.WidgetLoader.LoadWidget(WidgetArgs args, Widget parent, MiniYamlNode node) in /home/jason/git/OpenRA/OpenRA.Game/Widgets/WidgetLoader.cs:line 67
   at OpenRA.WidgetLoader.LoadWidget(WidgetArgs args, Widget parent, String w) in /home/jason/git/OpenRA/OpenRA.Game/Widgets/WidgetLoader.cs:line 43
   at OpenRA.Game.LoadWidget(World world, String id, Widget parent, WidgetArgs args) in /home/jason/git/OpenRA/OpenRA.Game/Game.cs:line 160
   at OpenRA.Mods.Common.Widgets.Logic.LoadIngamePlayerOrObserverUILogic..ctor(Widget widget, World world) in /home/jason/git/OpenRA/OpenRA.Mods.Common/Widgets/Logic/Ingame/LoadIngamePlayerOrObserverUILogic.cs:line 34
2022-05-21 16:10:08 +02:00
Eduardo Cáceres
a1811b4b04 Add fixed issues as warnings to .editorconfig 2022-05-18 11:42:36 -05:00
Eduardo Cáceres
c224bfdc0d Include name in authors 2022-05-18 11:42:36 -05:00
Eduardo Cáceres
8ced155ca3 Simplify 'always true' expressions
Co-authored-by: atlimit8 <atlimit8-vcs@gmx.com>
2022-05-18 11:42:36 -05:00
Eduardo Cáceres
aa998a46d9 Simplify collection initialization 2022-05-18 11:42:36 -05:00
Eduardo Cáceres
cae43808d9 Optimize string comparison 2022-05-18 11:42:36 -05:00
Eduardo Cáceres
c0d270b87d Abstract class with public constructor 2022-05-18 11:42:36 -05:00
Eduardo Cáceres
1b69ff017d Dictionary optimization 2022-05-18 11:42:36 -05:00
Eduardo Cáceres
b71402f64d Convert extension in real extension 2022-05-18 11:42:36 -05:00
Eduardo Cáceres
2677e9c013 Use pattern matching 2022-05-18 11:42:36 -05:00
Eduardo Cáceres
aed2b8afae Remove unnecessarily interpolated strings 2022-05-18 11:42:36 -05:00
Eduardo Cáceres
7eb64ea6fc Use read-only autoimplemented property when possible 2022-05-18 11:42:36 -05:00
Eduardo Cáceres
79f321cb44 .Any(), .Count() -> .Count or .Length 2022-05-18 11:42:36 -05:00
penev92
6eb4fe8980 Added a VSCode task to run the utility 2022-05-15 23:06:25 -05:00
penev92
9a30d260a1 Added launch profiles for the Utility project 2022-05-15 23:06:25 -05:00
abcdefg30
581b5cfacf Resolve an IDE0017 warning in ImportLegacyMapCommand 2022-05-11 15:33:23 +02:00
Paul Chote
c6dc0b58be Change macOS control group defaults back to Cmd. 2022-05-09 14:58:01 +02:00
Ivaylo Draganov
6a1a6b6397 Add platform override support for hotkeys and unhardcode editor hotkeys 2022-05-07 20:55:49 +01:00
Ivaylo Draganov
1cf4838b08 Remove unneeded yaml nodes from hotkey settings 2022-05-03 22:22:55 +02:00
Ivaylo Draganov
f0e69c3f64 Add hotkey filtering functionality (by name and by context) 2022-05-03 22:22:55 +02:00
Paul Chote
56153aac9f Search x86_64 before other multiarch dirs. 2022-05-01 11:55:28 +02:00
Leo512bit
ddef76e833 Added more thief voice lines 2022-04-30 17:19:48 -05:00
Ivaylo Draganov
0522576f73 Allow scrolling of settings panels while hovering a section header 2022-04-30 21:46:55 +02:00
abcdefg30
512eaf2746 Use Building instead of D2kBuilding for the Sietch actor 2022-04-30 12:28:28 -05:00
RoosterDragon
714b38c97c Add CellCostChanged event to Locomotor.
This event allows subscribers to be made aware when the terrain costs for a cell change.
2022-04-30 15:56:04 +02:00
Ivaylo Draganov
bc676fbf78 Add text notifications to many in-game events 2022-04-30 12:39:29 +01:00
Ivaylo Draganov
ea0bcbd1cc Adjust position of transients panel in TS 2022-04-30 12:39:29 +01:00
Ivaylo Draganov
24b9482cc1 Add support for transient text notifications matching speech notifications 2022-04-30 12:39:29 +01:00
Ivaylo Draganov
9f723be65a Add checkbox to settings for toggling transient notifications 2022-04-30 12:39:29 +01:00
Ivaylo Draganov
a1e6ac85dc Add transient notifications pool 2022-04-30 12:39:29 +01:00
RoosterDragon
e22b6de4e8 Rename PathGraph to MapPathGraph.
Move PathCostForInvalidPath and MovementCostForUnreachableCell constants into a new static class, PathGraph.
2022-04-27 23:19:59 +02:00
RoosterDragon
a1a583ea0a Split out a base class for PathGraph.
Move the domain logic involved into a base class named DensePathGraph. The base class contains all the domain logic necessary to traverse a graph including concepts such as custom movement layer.

PathGraph becomes responsible for proving a backing array for the pathfinding information, and is where the pooling logic lives instead, helping split the two concepts out.
2022-04-27 23:19:59 +02:00
penev92
86515610a5 Made all projectile and warhead fields readonly
This came up while working on the new documentation generation and comparing the results to ORAIDE's own code parser.
2022-04-26 22:37:12 +02:00
penev92
2bac492a65 Made all traitInfo fields readonly
This came up while working on the new documentation generation and comparing the results to ORAIDE's own code parser.
2022-04-26 22:37:12 +02:00
Gustas
135823fced fix crash when non-host exits map chooser 2022-04-25 23:03:27 +02:00
Paul Chote
a152bf7324 Replace custom mono defines with toolchain-provided defines. 2022-04-24 20:31:47 +02:00
RoosterDragon
3e5666ca53 Return an empty path when a search with no locations is made.
The restores the previous behaviour before FindUnitPathToTargetCell was introduced. This prevents callers such as the harvester code crashing when a harvester tries to route home to a refinery, but there are no refineries.
2022-04-24 12:52:18 +02:00
RoosterDragon
7df39f3522 On Locomotor initialization, update blocked cells.
Prior to ef44c31a72, Locomotor would be earlier in the trait initialization sequence than SpawnMapActors. Locomotor would assume no actors on the map, and register to update blocked cells when new ones were added. When SpawnMapActors created actors, Locomotor was made aware and kept up-to-date.

After this commit, the initialization sequence was perturbed and SpawnMapActors would initialize first. Locomotor would assume no actors on the map and thus be unaware of these starting units, meaning those starting units would not cause blocking, allowing units to pass through them.

There are two possible fixes. SpawnMapActorsInfo can initialize NotBefore<LocomotorInfo>, enforcing that actors are spawned after locomotor is ready. Or we can remove the assumption in Locomotor that the map starts empty, and have it update blocked cells on startup. The latter seems cleaner, so any other traits that may want to spawn actors don't have to be aware sequencing their initialization with the Locomotor trait, instead things would "just work".
2022-04-24 12:48:52 +02:00
Matthias Mailänder
4c08e449e0 Fix master server respond not being localized. 2022-04-23 22:29:40 +01:00
Paul Chote
0dbd8264b8 Handle exceptions thrown by HttpClient.GetAsync. 2022-04-23 22:44:05 +02:00
Matthias Mailänder
6c81590b20 Extract translation strings. 2022-04-21 13:26:55 +03:00
Matthias Mailänder
99033ab016 Localize dedicated server messages. 2022-04-21 13:26:55 +03:00
Matthias Mailänder
fe15748cc0 Wrap console logging with time stamp. 2022-04-21 13:26:55 +03:00
Matthias Mailänder
aaa3b49496 Update Mono.NAT 2022-04-21 13:11:45 +03:00
RoosterDragon
ecb7c16751 Tweak handling of nullable types in LUA doc generation.
The types for Int32 and Boolean are currently replaced with friendly names of int and bool for the docs. Ensure we apply the same handling when these are nullable types, changing the output from Int32? and Boolean? to int? and bool?
2022-04-18 13:02:05 +02:00
RoosterDragon
d2935672ca Fix the shape of the IPathFinder interface, ensure all path searches use it.
Some path searches, using PathSearch, were created directly at the callsite rather than using the pathfinder trait. This means some searches did not not benefit from the performance checks done in the pathfinder trait. It also means the pathfinder trait was not responsible for all pathing done in the game. Fix this with the following changes:
- Create a sensible shape for the IPathFinder interface and promote it to a trait interface, allowing theoretical replacements of the implementation. Ensure none of the concrete classes in OpenRA.Mods.Common.Pathfinder are exposed in the interface to ensure this is possible.
- Update the PathFinder class to implement the interface, and update several callsites manually running pathfinding code to instead call the IPathFinder interface.
- Overall, this allows any implementation of the IPathFinder interface to intercept and control all path searching performed by the game. Previously some searches would not have used it, and no alternate implementations were possible as the existing implementation was hardcoded into the interface shape.

Additionally:
- Move the responsibility of finding paths on completed path searches from pathfinder to path search, which is a more sensible location.
- Clean up the pathfinder pre-search optimizations.
2022-04-18 11:18:43 +01:00
RoosterDragon
2583a7af31 After NotBefore<> support to control initialization order.
Requires<T> means that trait of type T will be initialized first, and asserts that at least one exists. The new NotBefore<T> means that trait of type T will be initialized first, but allows no traits.

This allows traits to control initialization order for optional dependencies. They want to be initialized second so they can rely on the dependencies having been initialized. But if the dependencies are optional then to not throw if none are present.

We apply this to Locomotor which was previously using AddFrameEndTask to work around trait order initialization. This improves the user experience as the initialization is applied whilst the loading screen is still visible, rather than the game starting and creating jank by performing initialization on the first tick.
2022-04-18 10:31:47 +01:00
Mustafa Alperen Seki
62e7c7a318 Make PortableChrono PausableConditional. 2022-04-17 12:14:50 +02:00
Mustafa Alperen Seki
9de8d8854d Pass PortableChrono instead of PortableChronoInfo to PortableChronoOrderGenerator. 2022-04-17 12:14:50 +02:00
Matthias Mailänder
648c56bca1 Don't crash when joining a game after asset installation. 2022-04-17 00:27:36 +03:00
Matthias Mailänder
0f90713aba Added addition error logging to graphics.log when SDL fails 2022-04-16 22:37:05 +02:00
Mustafa Alperen Seki
30f14dcc4c Fix Army Spectator tab not using FactionImages. 2022-04-15 18:17:49 +02:00
RoosterDragon
ac0969d688 Use nameof instead of hardcoded strings in reflection calls.
This helps improve the safety of code the uses reflection when methods may get renamed, and helps navigating code as the nameof will show up when searching for references to members.
2022-04-14 19:58:15 +02:00
Gustas
b254eb0f3d Add dynamic map refresh 2022-04-14 16:16:38 +02:00
Gustas
61df7974b0 Make the delete button not call MapCache every frame 2022-04-14 16:16:38 +02:00
tomas
515aba0ee7 Update SDL to 2.0.20 2022-04-13 20:13:01 +02:00
Matthias Mailänder
af3362c62f Use string.Contains(char) instead of string.Contains(string)
with single characters
2022-04-13 20:09:57 +02:00
Matthias Mailänder
3bc28ba6e2 Use inline string replacement. 2022-04-13 20:09:57 +02:00
dnqbob
4f43b157a8 Add place variant building for BaseBuilderBotModule.
1. If it follow the refinery placing logic, then we can use Facings in PlaceBuildingVariants to help BaseBuilderBotModule "rotates" it to minefield.

2. If it is a normal building, BaseBuilderBotModule will place a random variant actor.
2022-04-12 22:28:03 +02:00
penev92
f74d1c3cf8 Adjusted D2k mission player colors
PlayerReference colors in D2k missions only affect chat text and minimap colors because actors use specific palette colors.
So using the colors from the original game's minimap.
2022-04-12 22:15:02 +02:00
penev92
2866342522 Add missing PlayerReferences in D2k map import 2022-04-12 22:15:02 +02:00
tomas
8e19463450 Fix desync handling 2022-04-12 21:56:46 +02:00
abcdefg30
dab8ee4f94 Load campaign and utils Lua scripts before map scripts 2022-04-12 21:54:11 +02:00
Mustafa Alperen Seki
c71af0e613 Make NukePower MissileImage optional. 2022-04-12 21:52:29 +02:00
Mustafa Alperen Seki
60b123c641 Split NukePower MissileImage from MissileWeapon. 2022-04-12 21:52:29 +02:00
Matthias Mailänder
0260884369 Added translation support for server orders. 2022-04-03 19:23:26 +02:00
Matthias Mailänder
ee95d2591f Code cleanup. 2022-04-03 19:23:26 +02:00
Matthias Mailänder
7735107deb Add a script trigger overlay. 2022-04-02 18:01:00 +02:00
Matthias Mailänder
058fb51f4c Reduce the menu button size to save space. 2022-04-02 18:01:00 +02:00
Matthias Mailänder
0e7ad43425 Remove unused parameters. 2022-04-01 23:30:26 +02:00
RoosterDragon
ea243b8558 Fix crash in TSEditorResourceLayer when adding resources.
Ensure cells are within map bounds when checking if adjacent cells should be cleared during resource placement.
2022-03-26 23:07:41 +01:00
abcdefg30
e685731b33 Add an update rule for the removal of AttackFrontal's FacingTolerance 2022-03-13 11:16:47 +01:00
abcdefg30
889425ab0f Remove AttackFrontal's FacingTolerance and define it explicitly in rules 2022-03-13 11:16:47 +01:00
dnqbob
9049ae6f20 Add a backawrd moving option for mobile 2022-03-13 10:46:04 +01:00
Vapre
83357af14c WorldRenderer, replace foreach ActorsWithTraits with ApplyToActorsWithTrait. #18798. 2022-03-13 10:45:01 +01:00
Matthias Mailänder
00356b8bbd Setup Tiberian Sun forest fires. 2022-03-12 17:16:43 +01:00
Mustafa Alperen Seki
b54a724aea Add ability to override CannotPlaceNotification per queue. 2022-03-12 12:55:41 +01:00
Matthias Mailänder
a6cb20a4ec Fix overlapping tracks when vehicle rotates.
Also optimize the function slightly.
2022-03-12 12:53:59 +01:00
Matthias Mailänder
5220da1bae This can never be null. 2022-03-12 12:53:59 +01:00
Mustafa Alperen Seki
2f1edd4516 Remove Replacable actors for LineBuild too. 2022-03-11 22:32:08 +01:00
Mustafa Alperen Seki
a7004b2db7 Check for placeablilty of LineBuild Segment instead of the Post. 2022-03-11 22:32:08 +01:00
Mustafa Alperen Seki
153bd14f9e Add Force-Move undeploy to D2k Thumper Infantry. 2022-03-11 22:29:45 +01:00
Leo512bit
d2611ebfb4 Added fsmap to music.ymal and set the lose music to it.
Signed-off-by: Leo512bit <leonardmatthewteyssier@gmail.com>
2022-03-11 21:36:43 +01:00
Ivaylo Draganov
eadc8ad689 Change color of labels that correspond to disabled inputs
- Add a new widget type for input and extend it from other input widgets
- Add a new label type that can be linked to an input widget
- Change the label color when the input's disabled state changes
2022-03-07 21:01:33 +01:00
Mustafa Alperen Seki
0203476da9 Update variables for Flash lua function. 2022-03-05 15:19:01 +01:00
Mustafa Alperen Seki
7e4c3acda3 Fix ZRamp only allowing integer values. 2022-03-02 19:41:49 +01:00
darkademic
e082497a1a Corrected StartBurstReport sound synchronisation when used with FireDelay. 2022-02-26 10:40:19 -06:00
Matthias Mailänder
9605e5ad9c Use the new MiniYAML GitHub syntax. 2022-02-26 17:04:50 +01:00
Matthias Mailänder
da4fb27fca Use modern string syntax. 2022-02-26 17:04:50 +01:00
penev92
57d3321d0f Make WithDockingAnimation optional
The `Refinery` trait has a hardcoded usage of `SpriteHarvesterDockSequence`, which requires the harvester to have `WithDockingAnimation`, making it inconvenient-at-best to NOT have a docking/unloading animation.
2022-02-23 22:06:07 +01:00
IceReaper
fa8bfc6ca0 Allow mods to implement new building placement conditions and cursors. 2022-02-22 01:20:38 +02:00
penev92
0f1ff3f2fc Recommend the MiniYAML language server extension
Recommends  https://marketplace.visualstudio.com/items?itemName=openra.oraide-vscode  as a VSCode extension for the OpenRA workspace.
2022-02-20 16:30:38 +01:00
Mustafa Alperen Seki
91f626c42a Make WithVoxelWalkerBody PausableConditional. 2022-02-18 12:24:23 +01:00
dnqbob
6c33d47ef3 Update rule on renaming 'CloakTypes' to 'DetectionTypes' 2022-02-12 19:30:21 +01:00
dnqbob
831bed2c4d Add enter-cloak & exit-cloak effect for Cloak 2022-02-12 19:30:21 +01:00
RoosterDragon
d67f696bd0 Move BlockedByActor, IPositionableInfo, IPositionable to Mods.Common.
Actor previously cached targetable locations for static actors as an optimization. As we can no longer reference the IPositionable interface, move this optimization to HitShape instead. Although we lose some of the efficiency of caching the final result on the actor, we gain some by allowing HitShape to cache the results as long as they have not changed. So instead of being limited to static actors, we can extend the caching to currently stationary actor.
2022-02-11 23:35:08 +01:00
RoosterDragon
d8a4d7fd1d Cache the global mix database in MixLoader
We can reuse this global database as it doesn't change, rather than loading a new copy each time a new mix file is parsed.
2022-02-11 14:05:55 +01:00
RoosterDragon
f5d1fe4bc4 Use more efficient search in MergeIntoResolved
Switch Enumerable.FirstOrDefault to List.Find. The latter can avoid some allocations because the concrete collection type is known.
2022-02-11 14:01:16 +01:00
RoosterDragon
ed72e61f8f Add detailed documentation for BlockedByActor enum. 2022-02-08 23:34:07 +01:00
RoosterDragon
9cd55df584 Ensure editorconfig naming styles align with StyleCop SA13XX style rules.
Aligns the naming conventions defined in editorconfig (dotnet_naming_style, dotnet_naming_symbols, dotnet_naming_rule) which are reported under the IDE1006 rule with the existing StyleCop rules from the SA13XX range.

This ensures the two rulesets agree when rejecting and accepting naming conventions within the IDE, with a few edges cases where only one ruleset can enforce the convention. IDE1006 allows use to specify a naming convention for type parameters, const locals and protected readonly fields which SA13XX cannot enforce. Some StyleCop SA13XX rules such as SA1309 'Field names should not begin with underscore' are not possible to enforce with the naming rules of IDE1006.

Therefore we enable the IDE1006 as a build time warning to enforce conventions and extend them. We disable SA13XX rules that can now be covered by IDE1006 to avoid double-reporting but leave the remaining SA13XX rules that cover additional cases enabled.

We also re-enable the SA1311 rule convention but enforce it via IDE1006, requiring some violations to be fixed or duplication of existing suppressions. Most violations fixes are trivial renames with the following exception. In ActorInitializer.cs, we prefer to make the fields private instead. ValueActorInit provides a publicly accessible property for access and OwnerInit provides a publicly accessible method. Health.cs is adjusted to access the property base instead when overriding. The reflection calls must be adjusted to target the base class specifically, as searching for a private field from the derived class will fail to locate it on the base class.

Unused suppressions were removed.
2022-02-07 19:14:45 +01:00
Gustas
13ee62c181 Make overlay dropdown optional 2022-02-06 19:21:43 +01:00
Gustas
addfdf50fa Crash when EditorWorld does not have BuildableTerrainOverlay 2022-02-06 19:21:43 +01:00
reaperrr
a17af87a5e Fix aircraft with TakeOffOnCreation=false not freeing exit
...when another actor gets produced.
2022-02-06 19:20:29 +01:00
reaperrr
44fc4a1d0f Fix random placement of AssociateWithAirfieldActivity
It doesn't belong to IMove, so it doesn't belong into that region.
Put it near ICreationActivity where it belongs.
2022-02-06 19:20:29 +01:00
darkademic
257ef95963 Suffix projectile shadow palettes with player name if IsPlayerPalette = true. 2022-02-06 19:18:59 +01:00
Matthias Mailänder
9bb41630e7 Update documentation action to .NET 6 2022-02-06 18:06:44 +01:00
Ivaylo Draganov
f5ab9d95fe Make remove from control group hotkey available only to players 2022-02-06 09:09:33 -06:00
Mustafa Alperen Seki
c096934db8 Fix projectile shadow alpha calculation. 2022-02-04 23:35:44 +01:00
Ivaylo Draganov
1813edc74b Add contexts for hotkey validation 2022-02-04 18:49:05 +01:00
RoosterDragon
1bc95a290f Preallocate dictionary size in ToDictionaryWithConflictLog 2022-02-02 15:10:37 +01:00
Smittytron
74cced319c Change terrain type of clear straight bridge tiles 2022-01-31 14:19:47 +01:00
RoosterDragon
bd30c66f95 Reuse object arrays in FieldLoader Parse methods 2022-01-30 19:47:06 +01:00
RoosterDragon
2ab3917f29 Clean up usage of DomainIndex
- When a path search is being performed the path search will not attempt route to inaccessible cells, so domain index checks to avoid inaccessible cells in the search predicate are redundant and can be removed.
- DomainIndex is a required world trait, so we don't need to use TraitOrDefault and therefore can avoid dealing with the null case.
2022-01-30 16:22:26 +01:00
Matthias Mailänder
4b4b0125a2 Make UnitsInRange accessible to mod code. 2022-01-30 11:56:43 +01:00
Matthias Mailänder
240c96b781 Expose sprite sequence to linting and documentation. 2022-01-30 11:56:43 +01:00
RoosterDragon
6dc189b7d1 Rearrange various API surfaces related to pathfinding.
The existing APIs surfaces for pathfinding are in a wonky shape. We rearrange various responsibilities to better locations and simplify some abstractions that aren't providing value.

- IPathSearch, BasePathSearch and PathSearch are combined into only PathSearch. Its role is now to run a search space over a graph, maintaining the open queue and evaluating the provided heuristic function. The builder-like methods (WithHeuristic, Reverse, FromPoint, etc) are removed in favour of optional parameters in static creation methods. This removes confusion between the builder-aspect and the search function itself. It also becomes responsible for applying the heuristic weight to the heuristic. This fixes an issue where an externally provided heuristic ignored the weighting adjustment, as previously the weight was baked into the default heuristic only.
- Reduce the IGraph interface to the concepts of nodes and edges. Make it non-generic as it is specifically for pathfinding, and rename to IPathGraph accordingly. This is sufficient for a PathSearch to perform a search over any given IGraph. The various customization options are concrete properties of PathGraph only.
- PathFinder does not need to deal with disposal of the search/graph, that is the caller's responsibility.
- Remove CustomBlock from PathGraph as it was unused.
- Remove FindUnitPathToRange as it was unused.
- Use PathFinder.NoPath as the single helper to represent no/empty paths.
2022-01-30 11:47:52 +01:00
Matthias Mailänder
cd1fe2d23b Fix saving into writable system directories. 2022-01-30 11:46:42 +01:00
abcdefg30
2af8296f48 Add the possibility to always show detection circles 2022-01-30 11:41:02 +01:00
abcdefg30
7c085e49c7 Cache DetectCloaked traits in RenderDetectionCircle 2022-01-30 11:41:02 +01:00
xan2622
13fbc412d2 removal 2022-01-30 11:28:16 +01:00
abcdefg30
a9cd2d41c7 Fix ToAhsv using the wrong type for alpha 2022-01-29 13:44:02 +01:00
Ivaylo Draganov
7a93b9ea8c Make control group hotkeys configurable
- Split control groups management to its own interface
- Add hotkeys for selecting, creating, adding to and combining with control groups
- Add a ControlGroups widget to manage the player interaction
2022-01-28 18:38:18 +01:00
Gustas
04b456d6c2 Create overlays dropdown 2022-01-26 23:09:18 +01:00
Gustas
2f130b17ba Fix buildable overlay not updating and make ramps unbuildable 2022-01-23 22:37:02 +01:00
penev92
9cc631ca7e Added a rule about using object initializers 2022-01-23 13:14:57 +01:00
penev92
ab09ce21b4 Changed code to use object initializers everywhere 2022-01-23 13:14:57 +01:00
penev92
70e2769a85 Added a rule about the readonly modifier
Also added a rule to silence StyleCop complaining about StaticReadonlyFieldsMustBeginWithUpperCaseLetter to match what we already have configured for the IDE.
2022-01-22 18:47:06 +00:00
penev92
bf332b6619 Fixed fields missing the readonly modifier 2022-01-22 18:47:06 +00:00
Piotr Usewicz
f83e27d647 Point towards arm libraries
When compiling for macOS using `unix-generic` on Apple M1 processors, point sarchdirs towards the correct location in Homebrew for arm64.
2022-01-22 18:21:36 +00:00
penev92
a67cfabd1e Reordered code style rules
To order them by their number.
2022-01-20 22:10:28 +01:00
penev92
8dbaa0c49f Added more explanations to .editorconfig 2022-01-20 22:10:28 +01:00
penev92
92d1d64dce Changed one-liner braces rule to silent
Having this set to "none" disabled the IDE's option to add braces, whereas "silent" lets it do it on the user's request while still not suggesting it on its own.
2022-01-20 22:10:28 +01:00
penev92
31b3647c09 Added a rule about unordered modifiers 2022-01-20 22:10:28 +01:00
penev92
d37336456d Fixed inconsistent declaration modifier order 2022-01-20 22:10:28 +01:00
penev92
3bacd81b8b Added a rule about zero-length array allocations 2022-01-20 22:10:28 +01:00
penev92
0d24ccc47a Fixed unnecessary zero-length array allocations
Changed all currently present zero-length array allocations in the codebase to use `Array.Empty` instead.
2022-01-20 22:10:28 +01:00
Paul Chote
1312c1aa72 Rename macOS compat packages to mono. 2022-01-20 19:31:43 +01:00
penev92
19dd23e349 Beautified the .editorconfig file 2022-01-19 14:37:14 +01:00
dnqbob
242d589c45 Make AI airstrike aircraft spawns randomly 2022-01-17 15:43:20 +01:00
Mustafa Alperen Seki
d149624b84 Add Lua Scripting for Carryall. 2022-01-12 14:24:13 +01:00
penev92
860ec642b8 Addressed review comments
- Renamed `IVideo.CurrentFrameNumber` to `CurrentFrameIndex`
 - Improved logged error message in VideoPlayerWidget
 - Renumbered fields in ThreadedGraphicsContext
2022-01-11 18:16:31 +01:00
penev92
248b8d1102 Renamed IVideo implementations
To match the interface they are implementing.
2022-01-11 18:16:31 +01:00
penev92
6f0509d235 Removed now-unused ITexture.SetData() overload 2022-01-11 18:16:31 +01:00
penev92
cb8530fbae Reworked internal palettes in video reader classes
This removes the need to pack & unpack color bytes as uints for no gain.
2022-01-11 18:16:31 +01:00
penev92
c4ab7041b8 Updated VideoPlayerWidget to play new IVideo data
Added optional padding to video frames because that's what VideoPlayerWidget expects.
Keeping the option to not use padding for other use-cases like converting frames to PNG.
2022-01-11 18:16:31 +01:00
penev92
ee29d0f9c7 Changed IVideo.CurrentFrameData uint[,] -> byte[] 2022-01-11 18:16:31 +01:00
penev92
1b5f2f1b39 Removed caching properties from video readers
Those seem redundant since the frame number is guaranteed to match the loaded data inside CurrentFrameData.
2022-01-11 18:16:31 +01:00
penev92
0df3b34c52 Did a beautification pass on IVideo and family
Removed property backing fields where applicable, introduced C#7 syntax for properties.
Renamed a bunch of interface properties and class private members with more descriptive names.
Did some inconsequential reordering.
2022-01-11 18:16:31 +01:00
abcdefg30
556413c91d Add whitespace fixes from the automatic update rule run 2022-01-11 18:09:05 +01:00
abcdefg30
f3bc450e20 Fix an oversight in the update rule for AttackBomber's FacingTolerance 2022-01-11 18:09:05 +01:00
abcdefg30
6556b33cef Move update rules to the correct subfolders and paths 2022-01-11 18:09:05 +01:00
abcdefg30
15c2800601 Retire the release-20191117 UpdatePath 2022-01-11 18:09:05 +01:00
abcdefg30
d660ce9c47 Change the UpdatePath targets from playtest-20201213 to release-20210321 2022-01-11 18:09:05 +01:00
Matthias Mailänder
6770c08bf9 Fix scrollitem-nohover-hover not found. 2022-01-11 17:40:58 +01:00
Ivaylo Draganov
99ac128820 Add selected actors count to feedback notification text 2022-01-09 19:07:45 +01:00
Mustafa Alperen Seki
fe05382b24 Change "actor id" to "actor name" in some descs. 2022-01-09 19:02:05 +01:00
Mustafa Alperen Seki
3c60a515f7 Add CarryableConditions to Carryall. 2022-01-09 19:02:05 +01:00
penev92
b67954451a Removed obsolete file OpenRA.sln.DotSettings
- The DEFAULT_PRIVATE_MODIFIER behaviour is now handled by the .editorconfig file via `dotnet_style_require_accessibility_modifiers = omit_if_default:warning`.
 Also added `dotnet_diagnostic.IDE0040.severity = warning` there to raise compile-time errors in the CI.
 - The field naming conventions seem to already be covered by (some) analyzer rules (checked in both VS and VSCode) - IDE1006/SA1306 and SA1307.
2022-01-09 18:58:37 +01:00
penev92
2f6f214bac Removed a bunch of explicit access modifiers 2022-01-09 18:58:37 +01:00
penev92
413d564f1d Removed obsolete file stylecop.json
It currently has two functions, both of which are covered by our .editorconfig file.
2022-01-09 18:58:37 +01:00
penev92
1326bca65c Updated .gitignore file
Removed some obsolete entries now that there is a new build directory.
2022-01-09 18:58:37 +01:00
Mustafa Alperen Seki
721210eafe Fix RevealsMap's effect not being removed for non-owners. 2022-01-09 18:53:16 +01:00
penev92
c6dacb50e8 Added hiding of the palette picker in the AssetBrowser 2022-01-09 18:40:32 +01:00
penev92
495faea96b Updated scale sliders to accout for the new AssetBrowser layout 2022-01-09 18:40:32 +01:00
penev92
b6b417d42f Fixed AssetBrowserLogic disposing audio streams prematurely 2022-01-09 18:40:32 +01:00
penev92
6fb228ddd1 Fixed Mp3Loader and OggLoader not resetting stream position 2022-01-09 18:40:32 +01:00
penev92
87b92b53a4 Reworked ISoundFormat.LengthInSeconds implementations 2022-01-09 18:40:32 +01:00
penev92
631297417c Fixed background music playing momentarily in AssetBrowser when switching to a video asset 2022-01-09 18:40:32 +01:00
penev92
001efc9409 Added containing package name to asset tooltip 2022-01-09 18:40:32 +01:00
penev92
8d20487cb6 Added manual playing and stopping of audio in the AssetBrowserLogic
Also added visualisation of audio file length and progress and improved asset cleanup.
2022-01-09 18:40:32 +01:00
penev92
abea3a0f74 Fixed AudFormat and WavFormat implementations of ISoundFormat.LengthInSeconds
- Fixed a rounding issue in `WavReader.WaveLength()`.
- Fixed `AudReader.SoundLength()` not resetting the stream position.
- Fixed crashes caused by disposed streams because `LengthInSeconds` would try and calculate the length on the fly. It is now precalculated and cached (making it consistent across all 5 current `ISoundFormat` implementations).
- Fixed a crash in `AudReader.LoadSound()`'s `out Func<Stream> result` because that func would try and access the disposed stream's `Length` property. That works for `SegmentStream`, but not for `FileStream`.
- Fixed frameCount/soundLength label positioning in the AssetBrowser window to avoid text clipping .
2022-01-09 18:40:32 +01:00
penev92
8b944e9c82 Added audio playback to the AssetBrowser 2022-01-09 18:40:32 +01:00
penev92
7a9e0863d6 Added a scale slider for sprites in the AssetBrowser 2022-01-09 18:40:32 +01:00
penev92
40c728269c Added a scale slider for models in the AssetBrowser 2022-01-09 18:40:32 +01:00
penev92
6907081c2b Paused shellmap music when opening videos in the AssetBrowser 2022-01-09 18:40:32 +01:00
penev92
a058b1f5bd Split AssetBrowser supported formats
Splitting them from one array into separate allows us to then reliably pick how each asset should be presented. Also lets us unhardcode some checks like "if file is .vxl ... else is sprite".
2022-01-09 18:40:32 +01:00
abcdefg30
8ac2815c9e Fix the first Land ctor not passing targetLineColor on 2022-01-07 01:22:16 +01:00
abcdefg30
942a0c8712 Update an outdated comment in Land.cs 2022-01-07 01:22:16 +01:00
Matthias Mailänder
cdac14b92b Avoid duplicate field. 2022-01-06 16:10:49 +02:00
Matthias Mailänder
718bf88b9a Remove superflous null checks
and cache a dictionary lookup.
2022-01-06 01:54:27 +01:00
Ivaylo Draganov
eb4de47362 Add support for disabled click sound in scrollbar widget 2022-01-05 21:15:19 +01:00
Ivaylo Draganov
c3dfac7ade Remove redundant default hotkey UI notice 2022-01-04 18:35:41 +01:00
Ivaylo Draganov
5aeae694be Use disabled button state for slider thumb 2022-01-04 18:35:41 +01:00
Ivaylo Draganov
bdfe025059 Update introductory prompts to match settings layout 2022-01-04 18:35:41 +01:00
Ivaylo Draganov
8a2b63c944 Update lobby options tab layout to match settings layout 2022-01-04 18:35:41 +01:00
Ivaylo Draganov
9f96d4159a Update common game ingame info tabs to match settings layout 2022-01-04 18:35:41 +01:00
Ivaylo Draganov
955464ee1d Update TD game info panel to match the settings panel 2022-01-04 18:35:41 +01:00
Ivaylo Draganov
3ecaf76804 Overhaul settings panel layout
- make the panel larger
- place settings widgets in a scroll panel
- arrange settings widgets in two columns
- make tabs in TD vertical
2022-01-04 18:35:41 +01:00
Smittytron
a36eb585d3 Fix HiveGassed regression in Ant03 2022-01-04 12:50:00 +01:00
abcdefg30
bf7ec4aec1 Update nuget packages 2022-01-04 12:34:30 +01:00
abcdefg30
b448f2d324 Disable trimmed publishing 2022-01-04 12:34:30 +01:00
abcdefg30
b12c15ea9d Update to .NET 6 2022-01-04 12:34:30 +01:00
abcdefg30
eae6d33cd9 Fix highlighting of the credits tabs 2021-12-30 12:42:56 +00:00
Smittytron
3c24a3f9c7 Update Allies10a to work with Lua cleanup 2021-12-29 17:13:09 +01:00
Matthias Mailänder
bb27837149 Don't make support airplanes huntable. 2021-12-28 13:08:38 -06:00
Ivaylo Draganov
87534022b3 Make size and white-space of game save/load panel more consistent 2021-12-28 17:48:21 +01:00
Ivaylo Draganov
d2c08c72bd Adjust size, position and white-space of several panels 2021-12-28 17:48:21 +01:00
Ivaylo Draganov
0261dcaa7a Make size and white-space of "Mission Browser" panel consistent 2021-12-28 17:48:21 +01:00
Ivaylo Draganov
d14ba6b04d Make size and white-space of "Replay Browser" panel consistent 2021-12-28 17:48:21 +01:00
Ivaylo Draganov
a69d86c587 Make size and white-space of "Asset Browser" panel consistent 2021-12-28 17:48:21 +01:00
Ivaylo Draganov
8fb3bbe5f9 Make size and white-space of "Music" and "Credits" panels consistent 2021-12-28 17:48:21 +01:00
Matthias Mailänder
1c00a2fbec Bump NUnit slightly. 2021-12-27 22:33:06 +01:00
Matthias Mailänder
82ce4717aa Bump Pfim 2021-12-27 22:33:06 +01:00
Matthias Mailänder
2b23bde925 Bump NVorbis 2021-12-27 22:33:06 +01:00
Matthias Mailänder
bc52e8b6a9 Bump Mono.NAT 2021-12-27 22:33:06 +01:00
Matthias Mailänder
fb296d7dcb Bump Fluent.Net 2021-12-27 22:33:06 +01:00
Matthias Mailänder
6997b973ee Fix a null reference exception. 2021-12-17 14:11:19 +01:00
dnqbob
c968a2a902 Contrail smooth&color fix 2021-12-16 23:48:03 +01:00
Matthias Mailänder
5fcc049040 Fix a null reference exception. 2021-12-08 21:07:19 +01:00
Matthias Mailänder
ff20c1c59d Avoid unnecessary variable assignment. 2021-12-06 13:19:28 +01:00
Matthias Mailänder
2c5f1f343f Code style. 2021-12-06 13:19:28 +01:00
Matthias Mailänder
b147da388a Mark fields readonly. 2021-12-06 13:19:28 +01:00
Matthias Mailänder
4a60d56753 Add a lint tag and documentation. 2021-12-06 13:19:28 +01:00
Matthias Mailänder
9d905d8291 Remove unused parameters and variables. 2021-12-06 13:19:28 +01:00
Matthias Mailänder
07815143f1 Fix CA1825 warnings on empty array initialisation. 2021-12-06 13:19:28 +01:00
RoosterDragon
727084c5fc Run spell check over solution 2021-12-05 19:23:43 +01:00
Matthias Mailänder
b3d290edd9 Rename support power field for consistency. 2021-12-05 14:56:01 +01:00
Matthias Mailänder
9852bd08e4 Clean up existing rules. 2021-12-05 14:56:01 +01:00
RoosterDragon
3bde4ebbaf Fix Move.PathSearchOrder
Each successive value of BlockedByActor is a superset of the previous value. Having a mixed up order of values in PathSearchOrder is not useful.

In the previous ordering, if a search for Immovable failed to find a path, it would then attempt Stationary. However Stationary is *more* restrictive then Immovable. If Immovable failed, there is no way Stationary could succeed. This means the search for Stationary is wasted effort.

In the fixed ordering, we try Stationary first. In the fixed ordering there are no pointless searches. Every search might succeed where the previous one failed and is therefore useful to try.
2021-12-05 13:53:56 +01:00
Matthias Mailänder
f44a2ea9a3 Fix formatting problems. 2021-12-05 13:17:32 +01:00
Matthias Mailänder
5eaba4f893 Unhardcode AI defensive priorities. 2021-12-05 13:17:32 +01:00
Matthias Mailänder
e82aa9977e Unhardcode AI air units and exclude scripted aircraft. 2021-12-05 13:17:32 +01:00
Matthias Mailänder
00ece1ba55 Add configurable tooltips to the Discord integration. 2021-12-05 13:09:59 +01:00
Matthias Mailänder
c9022bcb73 Add support for superweapon detected sounds. 2021-12-05 13:02:15 +01:00
darkademic
c51327c4cc Make yaml check utility load each map separately to reduce memory usage. 2021-12-04 20:07:19 +01:00
Ivaylo Draganov
695b7865d3 fixup! Add support for non-overlapping sound notifications 2021-11-29 23:44:59 +01:00
Ivaylo Draganov
fa6ff32f65 Add support for non-overlapping sound notifications 2021-11-29 23:44:59 +01:00
RoosterDragon
137d384304 Remove path caching.
The path cache was originally a moderate benefit, but over time a couple of things have conspired against it:

- Only paths with BlockedByActor.None are cached. Originally all paths regardless of blocking were cached but this was deemed unacceptable due to potentially returning outdated paths as actors move about. Paths with BlockedByActor.None are only invalidated if terrain conditions change, which are rarer.
- Move will try and find a path 4 times, trying with a different BlockedByActor check each time. BlockedByActor.None is the last check and only reached if the other searches fail. This is a rare scenario.

Overall, this means the hit rate for the cache is almost non-existent. Given the constraints on path validity it seems unlikely that the hit rate could be improved significantly, therefore it seems reasonable to remove the cache entirely to remove the overhead of cache management.
2021-11-29 01:03:14 +01:00
Paul Chote
31bd32e7ef Allow launcher scripts to run from other working directories. 2021-11-28 23:09:32 +01:00
GeorgeD64
e00efbf53d Added map name support to Launch.Map command line parameter
Fixed code based on feedback

Replaced try/catch block with a null check and exception throw

Fixed code based on feedback

Fixed code based on feedback

Simplified Launch.Map parameter to use map name directly
2021-11-28 23:06:26 +01:00
Ivaylo Draganov
a537346580 Move selection hotkeys out of world interaction widget
- Split SelectionUtils for selecting actors in the world to a static class
- Split selection hotkeys into their own logic classes
2021-11-27 15:06:39 +01:00
Ivaylo Draganov
e9cc89a336 Yield keyboard focus upon leaving the ingame chat tab 2021-11-27 14:57:04 +01:00
Gustas
975da89400 RAGL balance changes 2021-11-27 13:33:55 +01:00
Matthias Mailänder
5ed3f55ed2 Use global idle hunt. 2021-11-26 23:39:41 +01:00
Matthias Mailänder
b9bfbfd5ac Use global objective initialisation. 2021-11-26 23:39:41 +01:00
Matthias Mailänder
d42edfc0b9 Use global difficulty. 2021-11-26 23:39:41 +01:00
Matthias Mailänder
58b105f0d4 Reorganize global .lua files. 2021-11-26 23:39:41 +01:00
Matthias Mailänder
a502e85e68 Fail gracefully when there is just one default difficulty. 2021-11-26 23:39:41 +01:00
RoosterDragon
a59f4b2c4a Add a helper for multiplying by sqrt(2) 2021-11-25 22:50:22 +01:00
RoosterDragon
f0e24f6d21 Make knowledge of height discontinuities live in Locomotor not PathGraph. 2021-11-21 17:52:12 +01:00
RoosterDragon
8c627aa185 Clean up PathSearch
- Remove functionality for tracking cells considered during the search, as nothing relies on this.
- Rename various parameters in the expand function to closer match naming of fields used in CellInfo, intended to improve clarity.
2021-11-21 12:03:16 +01:00
Orb370
e1ade59a32 TD Balance Fall 2021 Commit
TD-Balance-Fall-2021 Commit

TD-Balance-Fall-2021-Commit
2021-11-20 17:37:43 -06:00
RoosterDragon
290ed17c9d Adjust some naming and order of parameters in CellInfo
- Make Status the first field.
- Rename EstimatedTotal to EstimatedTotalCost to make it clearer it has the same unit as the CostSoFar field.
- Rename PreviousPos to PreviousNode as node terminology is a better match for usage.
2021-11-20 12:13:42 +01:00
Matthias Mailänder
98b25ddd5e Check for dead actors when searching for exits. 2021-11-18 20:52:05 +01:00
RoosterDragon
31267aa22d Fix some incorrect logic in PathGraph.GetConnections.PathGraph
Firstly, when dealing with maps with height discontinuities, the neighbouring cells we need to search are more that the set we need to search on flat maps. We ensure that as we traverse a map with varying height, we now consider cells "behind" us that may have become accessible due to a height change.

Secondly, when considering connections available via Custom Movement Layers, make sure the target cell on the new layer is actually enterable. Previously this cell would be reported as a valid connection, even if it wasn't actually possible to enter the cell as it was blocked. We also apply the same optimization of ignoring already closed cells.
2021-11-16 00:33:19 +01:00
RoosterDragon
1d23c23d06 Adjust span comparisons for clarity and add some test cases. 2021-11-15 13:20:34 +01:00
RoosterDragon
5416910249 Remove unused method in MiniYaml 2021-11-15 13:20:34 +01:00
RoosterDragon
73547c31ec Remove MiniYamlNodes alias in MiniYaml. 2021-11-15 13:20:34 +01:00
RoosterDragon
2db312a792 In MiniYaml, presize some collections and trim lists during parsing. 2021-11-15 13:20:34 +01:00
RoosterDragon
0f01df5474 Avoid string allocations in MiniYaml parsing.
- Stream lines in as memory rather than needing to realise a string for each line, via a new method in StreamExts.
- Use span to avoid string allocations during parsing until we want to realise the node itself, in MiniYaml.FromLines.
- Change several callsites to use the streaming extension method rather than string method where possible.
2021-11-15 13:20:34 +01:00
penev92
270c566570 Fixed the Windows make script building in Release
This is a follow-up to PR 19379, which aimed to "provide an easy debug option for VSCode developers", but only did so for non-Windows users. VSCode has been building in Release mode for ever and continued to do so on Windows after that PR.
2021-11-14 10:07:18 +00:00
RoosterDragon
225bcbbd22 Normalize all support dir paths to end with a directory separator.
Previously, some paths used a separator and some did not. This broke some de-duplication logic in ExternalMods which tried to enumerate distinct paths but would end up running logic on the same directory more than one as it was provided both with and without a trailing directory separator. By normalizing the path this logic now works.
2021-11-13 22:24:43 +01:00
Vapre
d53601daa6 World, SyncHash, cache per tick. 2021-11-13 21:46:40 +01:00
RoosterDragon
dd9d600ef9 Change GetCustomMovementLayers to expose an array, not a dictionary.
As there are few custom movement layers, using an array is good for improving lookup speed. Additionally, we can simplify some code by reserving index 0 of the array for the ground layer. Code that needs to maintain a state for the ground layer and every custom movement layer can now maintain a flat array of state using index 0 for the ground layer, and the the ICustomMovementLayer.Index for the custom movement layer. This removes a lot of ternary statements checking for the ground layer special case.
2021-11-13 12:15:48 +00:00
Ivaylo Draganov
3310f14dea Use mission notifications pool with appropriate chat line template 2021-11-12 22:30:07 +01:00
penev92
a71da0a25a Unhardcoded engine credits file
Moved the file name/path to ModCredits, read from mod.yaml
2021-11-12 22:24:44 +01:00
Matthias Mailänder
9b1cec7712 Add support for gapless looping music. 2021-11-11 23:49:54 +01:00
abcdefg30
9916e4c4ac Fix a crash in the TSEditorResourceLayer neighbour validation 2021-11-11 15:09:24 +01:00
abcdefg30
31cec0c17f Fix a crash in the TSResourceLayer neighbour validation 2021-11-11 15:09:24 +01:00
reaperrr
430c7a4d7d Fix TD voice crashes
The original PR used too much copy-paste.
2021-11-08 14:46:41 +01:00
Matthias Mailänder
7d83d4d47f Add OmniSharp settings. 2021-11-08 14:41:34 +01:00
Matthias Mailänder
2fa1c05ed0 Ignore workspace settings. 2021-11-08 14:41:34 +01:00
Matthias Mailänder
f7fd3dfff8 Remove workspace settings. 2021-11-08 14:41:34 +01:00
abcdefg30
93c45255f1 Move a using into the Mono specific code path 2021-11-07 00:26:15 +01:00
abcdefg30
280dd8e2a5 Update launch-game.cmd to specify Engine.LaunchPath and support restarting 2021-11-06 11:21:13 +01:00
Paul Chote
5d83706eae Require an explicit launch path for mod registrations.
This also removes a workaround that allowed the current mod to be
registered even if it defined a bogus path. Uses of Game.ExternalMods
should therefore always use TryGetValue and correctly handle it
returning false.
2021-11-06 11:21:13 +01:00
Paul Chote
4275e87c57 Show an error prompt if restart mod switch fails. 2021-11-06 11:21:13 +01:00
Gustas
c5a6577cee Fix production scalling 2021-11-05 00:01:21 +01:00
Matthias Mailänder
ade5d211e9 IRC moved to Libera 2021-10-31 17:02:00 +01:00
Matthias Mailänder
e05b86b935 Recommend the OpenRA Lua extension. 2021-10-30 13:11:14 +02:00
Matthias Mailänder
e8ee31cd6e The launch settings have been migrated to .NET Core already. 2021-10-30 13:11:14 +02:00
Matthias Mailänder
59bed108b1 Minor csharp warning fixes. 2021-10-30 13:11:14 +02:00
abcdefg30
05420ab5ce Fix the Windows packing script not working with wget only 2021-10-29 22:25:59 +02:00
abcdefg30
32bc561878 Add a check for wine64 to the Windows packaging 2021-10-29 22:25:59 +02:00
abc013
311b6fcd83 Don't count actors owned by noncombatant players to kills statistic 2021-10-29 21:07:06 +02:00
abc013
c0da9f1eab Fix walls counting to kills/deaths statistic 2021-10-29 21:07:06 +02:00
Ivaylo Draganov
98434ef96b Add audio feedback for selection hotkeys 2021-10-29 20:55:41 +02:00
Ivaylo Draganov
9b9c116097 Add text feedback for type selection hotkey when selection is empty 2021-10-29 20:55:41 +02:00
Ivaylo Draganov
3c77df276a Add full-stop to UI feedback text notifications 2021-10-29 20:55:41 +02:00
Ivaylo Draganov
a680cae00c Move audio muted/unmuted notifications to feedback pool 2021-10-29 20:55:41 +02:00
Ivaylo Draganov
01d47566cc Add a transients panel with corresponding chrome logic and a notification template 2021-10-29 20:55:41 +02:00
Ivaylo Draganov
9e92340ea7 Rework chat line templates and logic
- Extract chat line templates and logic so they can be reused across widgets
- Make text notification styling entirely template driven (by removing chat color configuration and making color optional for `TextNotification`)
- Add a new TextNotificationsDisplay widget (based on and replacing ChatDisplayWidget)
- Add timestamp support to text notifications
2021-10-29 20:55:41 +02:00
abc013
8416dc3f2d Fix wrong subcell offsets for TS 2021-10-27 21:53:39 +02:00
abc013
c33290c19b Display error message instead of stack trace in battlefield news when failing to fetch news 2021-10-27 18:40:52 +02:00
teinarss
1a56cee9a1 Add Tick scale plumbing 2021-10-26 22:40:15 +02:00
Oliver Brakmann
7f3130c7a6 Use TimeLimitManager in mission Allies10a 2021-10-26 16:40:47 +02:00
Oliver Brakmann
be4466115d Do not update countdown label unless there is a timelimit 2021-10-26 16:40:47 +02:00
Smittytron
0c42f59656 Add Allies10a 2021-10-26 16:40:47 +02:00
Orb370
3a56532f0b Fix Europe Map Commit
Fix Europe Map Commit

Fix Europe Map Commit

Fix Europe Map Commit
2021-10-26 16:18:18 +02:00
abc013
442752b6ba Fix owner of selected actor not always being selected owner in editor 2021-10-24 22:54:10 +02:00
abc013
0898655175 Fix radar preview not updating when editing actor owner 2021-10-24 22:54:10 +02:00
RoosterDragon
3bee524c6b Avoid allocation in PackageEntry.HashFilename
This is a very frequently called method during loading, and taking some care to avoid allocations improves performance noticeably.
2021-10-24 21:40:01 +02:00
RoosterDragon
2ed4cb8aff Ensure Clear(T) also have a safety check to ensure no listener is attached.
Move related methods next to each other.
Change Clear(T) to use Array.Fill.
2021-10-23 15:43:47 +02:00
RoosterDragon
19760b04bd Allow the default value of a CellInfo to be an Unvisited location.
In CellInfoLayerPool, instead of having to store a layer with the default values, we know we can just clear the pooled layer in order to reset it. This saves on memory, and also makes resetting marginally faster.

In PathSearch, we need to amend a check to ensure a cell info is not Unvisited before we check on its cost.
2021-10-23 15:43:47 +02:00
Matthias Mailänder
6edd5d7bfa Avoid an unnecessary assignment. 2021-10-22 22:02:15 +02:00
Matthias Mailänder
a3ccc81892 Remove unused fields and parameters. 2021-10-22 22:02:15 +02:00
Matthias Mailänder
3b5bfb4bf4 Avoid initialisation of empty arrays. 2021-10-22 22:02:15 +02:00
Matthias Mailänder
5ff9d9a1f1 Add missing flags attribute required for HasFlags. 2021-10-22 22:02:15 +02:00
penev92
f056cbba13 Added a bunch of TraitLocationAttributes
Also moved a few traits to their proper subfolders.
2021-10-16 20:52:50 +02:00
penev92
67598dd151 Moved some traits from ^BaseWorld to World in TS 2021-10-16 20:52:50 +02:00
Paul Chote
166583b1ec Fix disabled chat focus issues. 2021-10-16 13:34:39 -05:00
penev92
e1e76411f7 Added a rule for unused usings to OpenRA.ruleset
Unfortunately due to bugs in the analyzers or something else, the IDE0005 doesn't work as expected. The "officially suggested" workaround is to enable XML documentation generation to trigger IDE0005 during compiling. Then we need to add three more rules to silence the warnings that come from the XML documentation generation. We also need to enable code style enforcing on build for all of this to work.
Known issue is that all of this produces a bunch (tens to hundreds) of obscure analyzer warnings on older versions of Visual Studio, but those seem to not be causing issues.
2021-10-15 13:12:33 +02:00
penev92
8ba6d13b2f Removed unused using directives 2021-10-15 13:12:33 +02:00
Matthias Mailänder
3790a4a6a4 Fix actor has multiple AttackBase traits. 2021-10-15 12:11:35 +02:00
abcdefg30
e8e0e155e5 Explain the try-finally clause in Sync.cs in a comment 2021-10-14 19:45:29 +02:00
abcdefg30
b366db7175 Revert "Directly run unsynced functions if we don't check sync hashes"
This reverts commit 1dc0a603c7.
2021-10-14 19:45:29 +02:00
penev92
3ce32fe354 Added faction-specific units for colorpicker previews in TS 2021-10-13 23:59:11 +02:00
Matthias Mailänder
2b361ad41e Add a link to the web chat
as ircs:// isn't linked on GitHub
and not everyone is familiar with IRC clients
2021-10-12 10:57:35 +02:00
Matthias Mailänder
f9f540f47e Website repository has changed. 2021-10-12 10:57:35 +02:00
Matthias Mailänder
c9b0ddf772 Add a link to Discord with badge. 2021-10-12 10:57:35 +02:00
Matthias Mailänder
139af0c2bc Fix a crash when building placements are moved out of the map. 2021-10-12 10:47:34 +02:00
Orb370
d88198e61e Allow Targeting While Defenses are in the Construction Animation Commit 2021-10-11 17:49:44 -05:00
RoosterDragon
df9398a871 Use named pathfinding constants.
- Rename CostForInvalidCell to PathCostForInvalidPath
- Add MovementCostForUnreachableCell
- Update usages of int.MaxValue and short.Maxvalue to use named constants where relevant.
- Update costs on ICustomMovementLayer to return short, for consistency with costs from Locomotor.
- Rename some methods to distinguish between path/movement cost.
2021-10-10 17:09:38 +02:00
abcdefg30
884e6cdb51 Exempt D2k Harvesters from slowness modifiers applied when damaged 2021-10-09 14:55:27 -05:00
abcdefg30
4269fc67d5 Remove hacks around checking sync while disposing the shellmap 2021-10-09 21:13:35 +02:00
abcdefg30
69248132ad Don't desync while the world is disposing 2021-10-09 21:13:35 +02:00
abcdefg30
1dc0a603c7 Directly run unsynced functions if we don't check sync hashes 2021-10-09 21:13:35 +02:00
Ivaylo Draganov
091d756c14 Change lobby options description to make sense in both disabled and enabled state 2021-10-09 08:43:28 -05:00
RoosterDragon
9bcbbdd3fc Remove unused code in Move. 2021-10-09 00:02:00 +02:00
abcdefg30
a930c123ed Initialize the Discord rich presence with an empty presence 2021-10-08 00:47:10 +03:00
abcdefg30
62c083bb01 Remove a bogus and unneeded import 2021-10-08 00:47:10 +03:00
Raf Czlonka
5cc1405f3f Update links
- _http_ `->` _https_ where appropriate
- _wiki.openra.net_ `->` _https://github.com/OpenRA/OpenRA/wiki_
- _bugs.openra.net_ `->` _https://github.com/OpenRA/OpenRA/issues_
- the IRC channel is now on Libera.Chat + make it into a URI

This is in order to be consistent (one link to GitHub wiki already
exists), reflect reality, as well as avoid unnecessary redirects.
2021-10-07 12:38:36 -05:00
VonNah
0e33d08384 Fixed incorrect voice lines for Generic-, Vehicle-, Moebius- and CommandoVoice.
Signed-off-by: VonNah <vonnahora@gmail.com>
2021-10-03 19:39:28 -05:00
abcdefg30
dc11b82fc9 Fix a NRE in DeliverUnit.ReleaseUnit.OnFirstRun 2021-10-02 22:01:24 +01:00
RoosterDragon
6e0917169d Teach FieldLoader.ParseCPos about CPos.Layer. 2021-10-02 21:54:26 +01:00
RoosterDragon
4cc33b2871 Add some ToString overrides to improve debug experience. 2021-10-02 21:54:26 +01:00
RoosterDragon
3a020e96fe Update ICustomMovementLayer to not depend on actor for costs.
No implementations require the actor.
2021-10-02 21:47:24 +01:00
RoosterDragon
6f3b4ecae9 Speed up Map.Contains checks for non-flat maps.
We observe that most cells within a map lie within a region where no matter their height, their projection would still remain in map bounds. We can utilise this to perform a fast check for such cells and skipping the expensive checks on their actual height. We only need to check the actual height of a cell if this could cause the projection to go out of bounds.
2021-10-02 21:43:11 +01:00
abcdefg30
d370cb48c5 Remove unreachable code in TransformsIntoTransforms 2021-10-02 21:34:51 +01:00
KonH
9ed809943d Just use Dispose methods without arguments (disposing always passed as true) 2021-10-02 22:14:08 +02:00
KonH
8bce6eb3ac Remove GC.SuppressFinalize calls from classes without destructors 2021-10-02 22:14:08 +02:00
teinarss
279e7eb1c9 Disable Stylecop on debug config 2021-10-02 21:13:58 +02:00
Paul Chote
defaf92752 Send order queue length in ping responses. 2021-10-02 21:03:00 +02:00
Paul Chote
2d08f2bbfd Allow the server to ack no or multiple packets in the same frame. 2021-10-02 21:03:00 +02:00
Zimmermann Gyula
a13d046304 Add twinkle effects to the gems. 2021-10-02 20:17:03 +02:00
Matthias Mailänder
a2a668077c Refactor RandomDelay:
Allow different types of random
and reflect other use cases by renaming.
2021-10-02 20:17:03 +02:00
RoosterDragon
3a7aeb5324 Ensure TargetLineRenderable width and marker size don't get lost.
By making the constructor take non-optional parameters, this highlights some calls sites which were forgetting to set these values. These are now fixed.

Set the path debug to have a marker size of 2 for better visibility.
2021-10-02 12:14:54 +01:00
Vapre
9d4d4bb924 Locomotor, PathGraph, trivial optimizations. 2021-10-01 22:21:47 +02:00
tovl
a428aaa602 Make sure OpenAlSound.Source is never accessed after the source is freed for reuse 2021-10-01 21:15:52 +02:00
tovl
2bc03b4d84 Fix OpenAlSound.Complete being incorrect when OpenAl source is reused. 2021-10-01 21:15:52 +02:00
teinarss
289c4ef2b7 Remove Microsoft.DotNet.PlatformAbstractions 2021-09-29 20:52:44 +02:00
teinarss
80b6a5a27f Update nuget packages 2021-09-29 20:52:44 +02:00
Ivaylo Draganov
7f2ac477a2 Improve Game.Mod argument check in launch script 2021-09-28 21:44:53 +02:00
Ivaylo Draganov
69b375dc48 Replace zenity select dropdown with a list 2021-09-28 21:44:53 +02:00
Vapre
e8bae2e50a Crash on capture fix. #19482. 2021-09-27 21:19:12 +01:00
Matthias Mailänder
6b3eee8481 Don't just swallow the web exception. 2021-09-27 20:16:22 +02:00
Paul Chote
3d73d5ef29 Remove incorrect comment and merge nested conditionals. 2021-09-27 19:48:05 +02:00
Paul Chote
a0d49729f5 Ignore modifiers when applying terrain damage. 2021-09-27 19:31:25 +02:00
Ikko Ashimine
a573052f2e Fix typo in rules.yaml
recieved -> received
2021-09-27 18:08:05 +02:00
Ivaylo Draganov
994ba35507 Add description to difficulty lobby option for missions 2021-09-26 21:25:08 +01:00
Ivaylo Draganov
2d178f5033 Do not center lobby options vertically in the scroll panel 2021-09-26 21:25:08 +01:00
Ivaylo Draganov
f018fdecdd Remove special handling for cases when there's only one game info tab
The addition of the lobby options tab ensures that there will always
be at least two tabs ("Objectives" and "Options").
2021-09-26 21:25:08 +01:00
Ivaylo Draganov
fa0adb5a1b Hide various lobby options from missions and minigames 2021-09-26 21:25:08 +01:00
Ivaylo Draganov
3e0834b4ef Display lobby options in-game on a dedicated tab 2021-09-26 21:25:08 +01:00
RoosterDragon
fc5f8fcd31 Fix indent 2021-09-26 15:49:48 +02:00
RoosterDragon
2f955e01f5 Fix style errors 2021-09-26 15:49:48 +02:00
Paul Chote
c958bf9680 Restore threaded renderer. 2021-09-26 15:19:20 +02:00
Matthias Mailänder
98b87004cc Bump SharpZipLib. 2021-09-26 11:18:15 +01:00
Paul Chote
8588af1001 Disable chat for the first 5s (configurable) after joining a server. 2021-09-23 12:52:20 +02:00
teinarss
9eab92e90a Add Rich Presence button with link to website 2021-09-22 15:57:54 +02:00
Paul Chote
2424ddc79a Move NetTickScale (now NetFrameInterval) control to the server. 2021-09-21 15:12:36 +02:00
Paul Chote
df798fb620 Overhaul client latency calculations.
The ping/pong orders are replaced with a dedicated
(and much smaller) Ping packet that is handled
directly in the client and server Connection wrappers.

This allows clients to respond when the orders are
processed, instead of queuing the pong order to be
sent in the next frame (which added an extra 120ms
of unwanted latency).

The ping frequency has been raised to 1Hz, and pings
are now routed through the server events queue in
preparation for the future dynamic latency system.

The raw ping numbers are no longer sent to clients,
the server instead evaluates a single ConnectionQuality
value that in the future may be based on more than
just the ping times.
2021-09-21 15:12:36 +02:00
Paul Chote
67face8cf0 Rename connection packet handling. 2021-09-21 15:12:36 +02:00
Paul Chote
4eefa637a3 Remove obsolete threaded renderer workarounds. 2021-09-20 22:33:25 +02:00
Paul Chote
be8e2cf3a4 Move OpenGL context creation to the main thread. 2021-09-20 22:33:25 +02:00
2391 changed files with 31326 additions and 15972 deletions

View File

@@ -25,91 +25,189 @@ csharp_using_directive_placement = outside_namespace:suggestion
csharp_new_line_before_open_brace = all
csharp_space_around_binary_operators = before_and_after
#### Naming styles ####
## Naming styles:
dotnet_naming_style.camel_case.capitalization = camel_case
dotnet_naming_style.pascal_case.capitalization = pascal_case
# Symbol specifications
dotnet_naming_style.i_prefix_pascal_case.capitalization = pascal_case
dotnet_naming_style.i_prefix_pascal_case.required_prefix = I
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal
## Symbol specifications:
dotnet_naming_symbols.const_private_field.applicable_kinds = field
dotnet_naming_symbols.const_private_field.required_modifiers = const
dotnet_naming_symbols.const_private_field.applicable_accessibilities = private
dotnet_naming_symbols.const_locals.applicable_kinds = local
dotnet_naming_symbols.const_locals.applicable_accessibilities = *
dotnet_naming_symbols.const_locals.required_modifiers = const
dotnet_naming_symbols.internal_field.applicable_kinds = field
dotnet_naming_symbols.internal_field.applicable_accessibilities = internal
dotnet_naming_symbols.const_fields.applicable_kinds = field
dotnet_naming_symbols.const_fields.applicable_accessibilities = *
dotnet_naming_symbols.const_fields.required_modifiers = const
dotnet_naming_symbols.static_private_or_internal_field.required_modifiers = static
dotnet_naming_symbols.static_private_or_internal_field.applicable_accessibilities = internal, private
dotnet_naming_symbols.static_readonly_fields.applicable_kinds = field
dotnet_naming_symbols.static_readonly_fields.applicable_accessibilities = *
dotnet_naming_symbols.static_readonly_fields.required_modifiers = static, readonly
dotnet_naming_symbols.private_or_internal_field.applicable_kinds = field
dotnet_naming_symbols.private_or_internal_field.applicable_accessibilities = internal, private
dotnet_naming_symbols.non_private_readonly_fields.applicable_kinds = field
dotnet_naming_symbols.non_private_readonly_fields.applicable_accessibilities = public, internal, protected, protected_internal, private_protected
dotnet_naming_symbols.non_private_readonly_fields.required_modifiers = readonly
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal
dotnet_naming_symbols.private_or_protected_fields.applicable_kinds = field
dotnet_naming_symbols.private_or_protected_fields.applicable_accessibilities = private, protected, private_protected
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal
dotnet_naming_symbols.interfaces.applicable_kinds = interface
dotnet_naming_symbols.interfaces.applicable_accessibilities = *
dotnet_naming_symbols.parameters.applicable_kinds = parameter
dotnet_naming_symbols.parameters_and_locals.applicable_kinds = parameter, local
dotnet_naming_symbols.parameters_and_locals.applicable_accessibilities = *
# Naming rules
dotnet_naming_symbols.most_symbols.applicable_kinds = namespace, class, struct, enum, field, property, method, local_function, event, delegate, type_parameter
dotnet_naming_symbols.most_symbols.applicable_accessibilities = *
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = warning
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
## Naming rules:
dotnet_naming_rule.const_locals_should_be_pascal_case.symbols = const_locals
dotnet_naming_rule.const_locals_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.const_locals_should_be_pascal_case.severity = warning
dotnet_naming_rule.static_private_or_internal_field_should_be_pascal_case.severity = none
dotnet_naming_rule.static_private_or_internal_field_should_be_pascal_case.symbols = static_private_or_internal_field
dotnet_naming_rule.static_private_or_internal_field_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.const_fields_should_be_pascal_case.symbols = const_fields
dotnet_naming_rule.const_fields_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.const_fields_should_be_pascal_case.severity = warning
dotnet_naming_rule.const_private_field_should_be_pascal_case.severity = warning
dotnet_naming_rule.const_private_field_should_be_pascal_case.symbols = const_private_field
dotnet_naming_rule.const_private_field_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.static_readonly_fields_should_be_pascal_case.symbols = static_readonly_fields
dotnet_naming_rule.static_readonly_fields_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.static_readonly_fields_should_be_pascal_case.severity = warning
dotnet_naming_rule.const_private_or_internal_field_should_be_pascal_case.severity = warning
dotnet_naming_rule.const_private_or_internal_field_should_be_pascal_case.symbols = internal_field
dotnet_naming_rule.const_private_or_internal_field_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.symbols = non_private_readonly_fields
dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.severity = warning
dotnet_naming_rule.private_or_internal_field_should_be_camel_case.severity = warning
dotnet_naming_rule.private_or_internal_field_should_be_camel_case.symbols = private_or_internal_field
dotnet_naming_rule.private_or_internal_field_should_be_camel_case.style = camel_case
dotnet_naming_rule.private_or_protected_fields_should_be_camel_case.symbols = private_or_protected_fields
dotnet_naming_rule.private_or_protected_fields_should_be_camel_case.style = camel_case
dotnet_naming_rule.private_or_protected_fields_should_be_camel_case.severity = warning
dotnet_naming_rule.parameters.severity = warning
dotnet_naming_rule.parameters.symbols = parameters
dotnet_naming_rule.parameters.style = camel_case
dotnet_naming_rule.interfaces_should_be_i_prefix_pascal_case.symbols = interfaces
dotnet_naming_rule.interfaces_should_be_i_prefix_pascal_case.style = i_prefix_pascal_case
dotnet_naming_rule.interfaces_should_be_i_prefix_pascal_case.severity = warning
# Naming rules
dotnet_naming_rule.parameters_and_locals_should_be_camel_case.symbols = parameters_and_locals
dotnet_naming_rule.parameters_and_locals_should_be_camel_case.style = camel_case
dotnet_naming_rule.parameters_and_locals_should_be_camel_case.severity = warning
#require a space before the colon for bases or interfaces in a type declaration
dotnet_naming_rule.most_symbols_should_be_pascal_case.symbols = most_symbols
dotnet_naming_rule.most_symbols_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.most_symbols_should_be_pascal_case.severity = warning
## Formatting:
# Also handled by StyleCopAnalyzers - SA1024: ColonsMustBeSpacedCorrectly.
csharp_space_after_colon_in_inheritance_clause = true
#require a space after a keyword in a control flow statement such as a for loop
csharp_space_after_keywords_in_control_flow_statements = true
#require a space before the colon for bases or interfaces in a type declaration
# Also handled by StyleCopAnalyzers - SA1024: ColonsMustBeSpacedCorrectly.
csharp_space_before_colon_in_inheritance_clause = true
#Formatting - wrapping options
# Also handled by StyleCopAnalyzers - SA1000: KeywordsMustBeSpacedCorrectly.
csharp_space_after_keywords_in_control_flow_statements = true
#leave code block on single line
# Leave code block on single line.
csharp_preserve_single_line_blocks = true
#leave statements and member declarations on the same line
# Leave statements and member declarations on the same line.
csharp_preserve_single_line_statements = true
#prefer the language keyword for member access expressions, instead of the type name, for types that have a keyword to represent them
dotnet_style_predefined_type_for_member_access = true:suggestion
# IDE0049, IDE-only counterpart of StyleCopAnalyzers - SA1121: UseBuiltInTypeAlias.
dotnet_style_predefined_type_for_member_access = true
#prefer the language keyword for local variables, method parameters, and class members, instead of the type name, for types that have a keyword to represent them
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
# IDE0049, IDE-only counterpart of StyleCopAnalyzers - SA1121: UseBuiltInTypeAlias.
dotnet_style_predefined_type_for_locals_parameters_members = true
#don't prefer braces (for one liners)
dotnet_diagnostic.IDE0011.severity = none
## Others:
# Show an IDE warning when default access modifiers are explicitly specified.
dotnet_style_require_accessibility_modifiers = omit_if_default:warning
# use 'var' instead of explicit type
dotnet_diagnostic.IDE0007.severity = warning
# Don't prefer braces (for one liners).
dotnet_diagnostic.IDE0011.severity = silent
# Object initialization can be simplified / Use object initializer.
dotnet_diagnostic.IDE0017.severity = warning
# Collection initialization can be simplified
dotnet_diagnostic.IDE0028.severity = warning
# Simplify 'default' expression
dotnet_diagnostic.IDE0034.severity = warning
# Modifiers are not ordered.
dotnet_diagnostic.IDE0036.severity = warning
# Raise a warning on build when default access modifiers are explicitly specified.
dotnet_diagnostic.IDE0040.severity = warning
# Make field readonly.
dotnet_diagnostic.IDE0044.severity = warning
# Unused private member.
dotnet_diagnostic.IDE0052.severity = warning
# Unnecessary value assignment.
dotnet_diagnostic.IDE0059.severity = warning
# Unused parameter.
dotnet_diagnostic.IDE0060.severity = warning
# Naming rule violation.
dotnet_diagnostic.IDE1006.severity = warning
# Avoid unnecessary zero-length array allocations.
dotnet_diagnostic.CA1825.severity = warning
# Do not use Enumerable methods on indexable collections. Instead use the collection directly.
dotnet_diagnostic.CA1826.severity = warning
# Count() is used where Any() could be used instead to improve performance.
dotnet_diagnostic.CA1827.severity = warning
# Use Length/Count property instead of Enumerable.Count method.
dotnet_diagnostic.CA1829.severity = warning
# Use string.Contains(char) instead of string.Contains(string) with single characters.
dotnet_diagnostic.CA1847.severity = warning
; 4-column tab indentation
[*.yaml]
indent_style = tab
indent_size = 4
# Use 'Count' property instead of 'Any' method.
dotnet_diagnostic.RCS1080.severity = warning
# Use read-only auto-implemented property.
dotnet_diagnostic.RCS1170.severity = warning
# Unnecessary interpolated string.
dotnet_diagnostic.RCS1214.severity = warning
# Unnecessary usage of verbatim string literal.
dotnet_diagnostic.RCS1192.severity = warning
# Use pattern matching instead of combination of 'as' operator and null check.
dotnet_diagnostic.RCS1221.severity = warning
# Expression is always equal to 'true'.
dotnet_diagnostic.RCS1215.severity = warning
# Use StringComparison when comparing strings.
dotnet_diagnostic.RCS1155.severity = warning
# Abstract type should not have public constructors.
dotnet_diagnostic.RCS1160.severity = warning
# Optimize 'Dictionary<TKey, TValue>.ContainsKey' call.
dotnet_diagnostic.RCS1235.severity = warning
# Call extension method as instance method.
dotnet_diagnostic.RCS1196.severity = warning

1
.github/FUNDING.yml vendored
View File

@@ -1 +0,0 @@
patreon: orahosting

View File

@@ -10,5 +10,5 @@ contact_links:
url: https://discord.openra.net/
about: Join the community Discord server for community discussion and support.
- name: OpenRA IRC Channel
url: https://webchat.freenode.net/#openra
about: Join our development IRC channel on freenode for discussion of development topics.
url: https://web.libera.chat/#openra
about: Join our development IRC channel on Libera for discussion of development topics.

View File

@@ -13,4 +13,4 @@ You can help speed up the review process by following a few steps:
* Respond to review comments as soon as you reasonably can. Reviewers will usually prioritize Pull Requests that are still fresh in their minds. Make sure to leave a comment when you push new changes, otherwise GitHub does not automatically notify reviewers!
* Leave a polite comment asking for reviews if a week or more has passed without feedback.
If you need any help you can ask in the #openra IRC channel on freenode (most active during European evenings).
If you need any help you can ask on Discord (https://discord.openra.net) or in the #openra IRC channel on Libera (not as active as Discord).

View File

@@ -3,21 +3,21 @@ name: Continuous Integration
on:
push:
pull_request:
branches: [ bleed ]
branches: [ bleed, 'prep-*' ]
jobs:
linux:
name: Linux (.NET 5.0)
name: Linux (.NET 6.0)
runs-on: ubuntu-20.04
steps:
- name: Clone Repository
uses: actions/checkout@v2
- name: Install .NET 5
- name: Install .NET 6.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: '5.0.x'
dotnet-version: '6.0.x'
- name: Check Code
run: |
@@ -48,17 +48,17 @@ jobs:
make RUNTIME=mono test
windows:
name: Windows (.NET 5.0)
name: Windows (.NET 6.0)
runs-on: windows-2019
steps:
- name: Clone Repository
uses: actions/checkout@v2
- name: Install .NET 5
- name: Install .NET 6.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: '5.0.x'
dotnet-version: '6.0.x'
- name: Check Code
shell: powershell

View File

@@ -19,6 +19,11 @@ jobs:
with:
ref: ${{ github.event.inputs.tag }}
- name: Install .NET 6
uses: actions/setup-dotnet@v1
with:
dotnet-version: '6.0.x'
- name: Prepare Environment
run: |
make all
@@ -65,43 +70,71 @@ jobs:
with:
ref: ${{ github.event.inputs.tag }}
- name: Install .NET 6
uses: actions/setup-dotnet@v1
with:
dotnet-version: '6.0.x'
- name: Prepare Environment
run: |
make all
- name: Clone docs.openra.net
- name: Clone docs.openra.net (Playtest)
if: startsWith(github.event.inputs.tag, 'playtest-')
uses: actions/checkout@v2
with:
repository: openra/docs
token: ${{ secrets.DOCS_TOKEN }}
path: docs
ref: playtest
- name: Clone docs.openra.net (Release)
if: startsWith(github.event.inputs.tag, 'release-')
uses: actions/checkout@v2
with:
repository: openra/docs
token: ${{ secrets.DOCS_TOKEN }}
path: docs
ref: release
- name: Update docs.openra.net (Playtest)
if: startsWith(github.event.inputs.tag, 'playtest-')
env:
GIT_TAG: ${{ github.event.inputs.tag }}
run: |
./utility.sh all --docs "${GIT_TAG}" > "docs/api/playtest/traits.md"
./utility.sh all --weapon-docs "${GIT_TAG}" > "docs/api/playtest/weapons.md"
./utility.sh all --lua-docs "${GIT_TAG}" > "docs/api/playtest/lua.md"
./utility.sh all --docs "${GIT_TAG}" | python3 ./packaging/format-docs.py > "docs/api/traits.md"
./utility.sh all --weapon-docs "${GIT_TAG}" | python3 ./packaging/format-docs.py > "docs/api/weapons.md"
./utility.sh all --sprite-sequence-docs "${GIT_TAG}" | python3 ./packaging/format-docs.py > "docs/api/sprite-sequences.md"
./utility.sh all --lua-docs "${GIT_TAG}" > "docs/api/lua.md"
- name: Update docs.openra.net (Release)
if: startsWith(github.event.inputs.tag, 'release-')
env:
GIT_TAG: ${{ github.event.inputs.tag }}
run: |
./utility.sh all --docs "${GIT_TAG}" > "docs/api/release/traits.md"
./utility.sh all --weapon-docs "${GIT_TAG}" > "docs/api/release/weapons.md"
./utility.sh all --lua-docs "${GIT_TAG}" > "docs/api/release/lua.md"
./utility.sh all --docs "${GIT_TAG}" | python3 ./packaging/format-docs.py > "docs/api/traits.md"
./utility.sh all --weapon-docs "${GIT_TAG}" | python3 ./packaging/format-docs.py > "docs/api/weapons.md"
./utility.sh all --sprite-sequence-docs "${GIT_TAG}" | python3 ./packaging/format-docs.py > "docs/api/sprite-sequences.md"
./utility.sh all --lua-docs "${GIT_TAG}" > "docs/api/lua.md"
- name: Push docs.openra.net
- name: Commit docs.openra.net
env:
GIT_TAG: ${{ github.event.inputs.tag }}
run: |
cd docs
git config --local user.email "actions@github.com"
git config --local user.name "GitHub Actions"
git add --all
git add api/*.md
git commit -m "Update auto-generated documentation for ${GIT_TAG}"
git push origin master
- name: Push docs.openra.net (Release)
if: startsWith(github.event.inputs.tag, 'release-')
run: |
cd docs
git push origin release
- name: Push docs.openra.net (Playtest)
if: startsWith(github.event.inputs.tag, 'playtest-')
run: |
cd docs
git push origin playtest

View File

@@ -39,10 +39,10 @@ jobs:
- name: Clone Repository
uses: actions/checkout@v2
- name: Install .NET 5
- name: Install .NET 6.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: '5.0.x'
dotnet-version: '6.0.x'
- name: Prepare Environment
run: echo "GIT_TAG=${GITHUB_REF#refs/tags/}" >> ${GITHUB_ENV}
@@ -62,21 +62,21 @@ jobs:
file: build/linux/*
macos:
name: macOS Disk Images
runs-on: macos-10.15
name: macOS Disk Image
runs-on: macos-11
steps:
- name: Clone Repository
uses: actions/checkout@v2
- name: Install .NET 5
- name: Install .NET 6.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: '5.0.x'
dotnet-version: '6.0.x'
- name: Prepare Environment
run: echo "GIT_TAG=${GITHUB_REF#refs/tags/}" >> ${GITHUB_ENV}
- name: Package Disk Images
- name: Package Disk Image
env:
MACOS_DEVELOPER_IDENTITY: ${{ secrets.MACOS_DEVELOPER_IDENTITY }}
MACOS_DEVELOPER_CERTIFICATE_BASE64: ${{ secrets.MACOS_DEVELOPER_CERTIFICATE_BASE64 }}
@@ -87,7 +87,7 @@ jobs:
mkdir -p build/macos
./packaging/macos/buildpackage.sh "${GIT_TAG}" "${PWD}/build/macos"
- name: Upload Packages
- name: Upload Package
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
@@ -103,10 +103,10 @@ jobs:
- name: Clone Repository
uses: actions/checkout@v2
- name: Install .NET 5
- name: Install .NET 6.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: '5.0.x'
dotnet-version: '6.0.x'
- name: Prepare Environment
run: |

19
.gitignore vendored
View File

@@ -13,19 +13,10 @@ obj
_ReSharper.*/
/.vs
# Visual Studio Code
/.vscode/settings.json
# binaries
mods/*/*.dll
mods/*/*.mdb
mods/*/*.pdb
/*.dll
/*.dll.config
/*.so
/*.dylib
/*.pdb
/*.mdb
/*.exe
/*.exe.config
thirdparty/download/*
IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP
# backup files by various editors
@@ -50,10 +41,6 @@ Settings.md
openra.6
update.log
# StyleCop
*.Cache
StyleCopViolations.xml
# SublimeText
*.sublime-project
*.sublime-workspace

View File

@@ -1,7 +1,9 @@
{
"recommendations": [
"ms-dotnettools.csharp",
"openra.oraide-vscode",
"openra.vscode-openra-lua",
"EditorConfig.EditorConfig",
"ms-vscode.mono-debug"
"macabeus.vscode-fluent",
]
}

14
.vscode/launch.json vendored
View File

@@ -45,5 +45,19 @@
"args": ["Game.Mod=ts", "Engine.EngineDir=.."],
"preLaunchTask": "build",
},
{
"name": "Launch Utility",
"type": "coreclr",
"request": "launch",
"program": "${workspaceRoot}/bin/OpenRA.Utility.dll",
"windows": {
"program": "${workspaceRoot}/bin/OpenRA.Utility.exe",
},
"args": ["all", "--docs", "{DEV_VERSION}"],
"env": {
"ENGINE_DIR": ".."
},
"preLaunchTask": "build",
},
]
}

View File

@@ -1,3 +0,0 @@
{
"omnisharp.enableRoslynAnalyzers": true
}

23
.vscode/tasks.json vendored
View File

@@ -1,5 +1,10 @@
{
"version": "2.0.0",
"options": {
"env": {
"ENGINE_DIR": ".."
}
},
"tasks": [
{
"label": "build",
@@ -8,6 +13,24 @@
"windows": {
"command": "make.cmd"
}
},
{
"label": "Run Utility",
"command": "dotnet ${workspaceRoot}/bin/OpenRA.Utility.dll ${input:modId} ${input:command}",
"type": "shell",
}
],
"inputs": [
{
"id": "modId",
"description": "ID of the mod to run",
"default": "all",
"type": "promptString"
}, {
"id": "command",
"description": "Name of the command + parameters",
"default": "",
"type": "promptString"
},
]
}

17
AUTHORS
View File

@@ -2,28 +2,30 @@ OpenRA wouldn't be where it is today without the
hard work of many contributors.
The OpenRA developers are:
* Chris Forbes (chrisf)
* Gustas Kažukauskas (PunkPun)
* Lukas Franke (abcdefg30)
* Matthias Mailänder (Mailaender)
* Paul Chote (pchote)
* Reaperrr
Previous developers included:
* Alli Witheford (alzeih)
* Caleb Anderson (RobotCaleb)
* Chris Forbes (chrisf)
* Curtis Shmyr (hamb)
* Daniel Hernandez (Mancano)
* Igor Popov (ihptru)
* Megan Bowra-Dean (beedee)
* Mike Bundy (kehaar)
* Oliver Brakmann (obrakmann)
* Paul Chote (pchote)
* Pavel Penev (penev92)
* Reaperrr
* Robert Pepperell (ytinasni)
* ScottNZ
* Tom Roostan (RoosterDragon)
Also thanks to:
* abmyii
* anvilvapre (anvilvapre)
* Adam Valy (Tschokky)
* Akseli Virtanen (RAGEQUIT)
* Alexander Fast (mizipzor)
@@ -37,6 +39,7 @@ Also thanks to:
* Arik Lirette (Angusm3)
* Barnaby Smith (mvi)
* Bellator
* Bernd Stellwag (burned42)
* Biofreak
* Braxton Williams (Buddytex)
* Brendan Gluth (Mechanical_Man)
@@ -46,6 +49,7 @@ Also thanks to:
* Chris Cameron (Vesuvian)
* Chris Grant (Unit158)
* Christer Ulfsparre (Holloweye)
* Christoph Lahner (chlah)
* clem
* Cody Brittain (Generalcamo)
* Constantin Helmig (CH4Code)
@@ -58,6 +62,7 @@ Also thanks to:
* DeadlySurprise
* Dmitri Suvorov (suvjunmd)
* dtluna
* Eduardo Cáceres (eduherminio)
* Erasmus Schroder (rasco)
* Eric Bajumpaa (SteelPhase)
* Evgeniy Sergeev (evgeniysergeev)
@@ -75,6 +80,7 @@ Also thanks to:
* Imago
* Iran
* Ishan Bhargava (ishantheperson)
* Ivaylo Draganov (dragunoff)
* Jacob Dufault (jacobdufault)
* James Dunne (jsd)
* James Gilbert (DSUK)
@@ -135,12 +141,12 @@ Also thanks to:
* Rikhardur Bjarni Einarsson (WolfGaming)
* Sascha Biedermann (bidifx)
* Sean Hunt (coppro)
* Sebastien Kerguen (xanax)
* Shawn Collins (UberWaffe)
* Simon Verbeke (Saticmotion)
* Stuart McHattie (SDJMcHattie)
* Taryn Hill (Phrohdoh)
* Teemu Nieminen (Temeez)
* Thomas Christlieb (ThomasChr)
* Tim Mylemans (gecko)
* Tirili
* Tomas Einarsson (Mesacer)
@@ -202,6 +208,9 @@ Using ANGLE distributed under the BS3 3-Clause license.
Using Pfim developed by Nick Babcock
distributed under the MIT license.
Using Linguini by the Space Station 14 team
licensed under Apache and MIT terms.
This site or product includes IP2Location LITE data
available from http://www.ip2location.com.

View File

@@ -56,8 +56,8 @@ further defined and clarified by project maintainers.
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by private-messaging a project team member (users with a + in front
of their name) via our IRC channel (#openra on freenode
[webchat](http://webchat.freenode.net/?channels=openra)). All
of their name) via our IRC channel (#openra on Libera
[webchat](https://web.libera.chat/#openra)). All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.

View File

@@ -7,7 +7,6 @@
<Optimize>true</Optimize>
<LangVersion>7.3</LangVersion>
<DebugSymbols>true</DebugSymbols>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<EngineRootPath Condition="'$(EngineRootPath)' == ''">..</EngineRootPath>
<OutputPath>$(EngineRootPath)/bin</OutputPath>
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -18,8 +17,8 @@
</PropertyGroup>
<PropertyGroup>
<TargetFramework Condition="'$(Mono)' == ''">net5.0</TargetFramework>
<TargetFramework Condition="'$(Mono)' != ''">netstandard2.1</TargetFramework>
<TargetFramework Condition="'$(MSBuildRuntimeType)'!='Mono'">net6.0</TargetFramework>
<TargetFramework Condition="'$(MSBuildRuntimeType)'=='Mono'">netstandard2.1</TargetFramework>
</PropertyGroup>
<PropertyGroup>
@@ -47,8 +46,7 @@
<!-- StyleCop -->
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" PrivateAssets="All" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
<AdditionalFiles Include="$(EngineRootPath)/stylecop.json" />
</ItemGroup>
</Project>

View File

@@ -8,7 +8,7 @@ Windows
Compiling OpenRA requires the following dependencies:
* [Windows PowerShell >= 4.0](http://microsoft.com/powershell) (included by default in recent Windows 10 versions)
* [.NET 5 SDK](https://dotnet.microsoft.com/download/dotnet/5.0) (or via Visual Studio)
* [.NET 6 SDK](https://dotnet.microsoft.com/download/dotnet/6.0) (or via Visual Studio)
To compile OpenRA, open the `OpenRA.sln` solution in the main folder, build it from the command-line with `dotnet` or use the Makefile analogue command `make all` scripted in PowerShell syntax.
@@ -17,9 +17,9 @@ Run the game with `launch-game.cmd`. It can be handed arguments that specify the
Linux
=====
.NET 5 or Mono (version 6.4 or later) is required to compile OpenRA. We recommend using .NET 5 when possible, as Mono is poorly packaged by most Linux distributions (e.g. missing the required `msbuild` toolchain), and has been deprecated as a standalone project.
.NET 6 or Mono (version 6.4 or later) is required to compile OpenRA. We recommend using .NET 6 when possible, as Mono is poorly packaged by most Linux distributions (e.g. missing the required `msbuild` toolchain), and has been deprecated as a standalone project.
The [.NET 5 download page](https://dotnet.microsoft.com/download/dotnet/5.0) provides repositories for various package managers and binary releases for several architectures. If you prefer to use Mono, we suggest adding the [upstream repository](https://www.mono-project.com/download/stable/#download-lin) for your distro to obtain the latest version and the `msbuild` toolchain.
The [.NET 6 download page](https://dotnet.microsoft.com/download/dotnet/6.0) provides repositories for various package managers and binary releases for several architectures. If you prefer to use Mono, we suggest adding the [upstream repository](https://www.mono-project.com/download/stable/#download-lin) for your distro to obtain the latest version and the `msbuild` toolchain.
To compile OpenRA, run `make` from the command line (or `make RUNTIME=mono` if using Mono). After this one can run the game with `./launch-game.sh`. It is also possible to specify the mod you wish to run from the command line, e.g. with `./launch-game.sh Game.Mod=ts` if you wish to try the experimental Tiberian Sun mod.
@@ -78,6 +78,6 @@ Type `sudo make install` for system-wide installation. Run `sudo make install-li
macOS
=====
[.NET 5](https://dotnet.microsoft.com/download/dotnet/5.0) or [Mono](https://www.mono-project.com/download/stable/#download-mac) (version 6.4 or later) is required to compile OpenRA. We recommend using .NET 5 unless you are running a very old version of macOS (10.9 through 10.12).
[.NET 6](https://dotnet.microsoft.com/download/dotnet/6.0) or [Mono](https://www.mono-project.com/download/stable/#download-mac) (version 6.4 or later) is required to compile OpenRA. We recommend using .NET 6 unless you are running a very old version of macOS (10.9 through 10.14).
To compile OpenRA, run `make` from the command line (or `make RUNTIME=mono` if using Mono). Run with `./launch-game.sh`.

View File

@@ -3,31 +3,34 @@
# to compile, run:
# make
#
# to compile using Mono (version 6.4 or greater) instead of .NET 5, run:
# to compile using Mono (version 6.4 or greater) instead of .NET 6, run:
# make RUNTIME=mono
#
# to compile using system libraries for native dependencies, run:
# make [RUNTIME=net5] TARGETPLATFORM=unix-generic
# make [RUNTIME=net6] TARGETPLATFORM=unix-generic
#
# to check the official mods for erroneous yaml files, run:
# make [RUNTIME=net5] test
# make [RUNTIME=net6] test
#
# to check the engine and official mod dlls for code style violations, run:
# make [RUNTIME=net5] check
# make [RUNTIME=net6] check
#
# to compile and install Red Alert, Tiberian Dawn, and Dune 2000, run:
# make [RUNTIME=net5] [prefix=/foo] [bindir=/bar/bin] install
# make [RUNTIME=net6] [prefix=/foo] [bindir=/bar/bin] install
#
# to compile and install Red Alert, Tiberian Dawn, and Dune 2000
# using system libraries for native dependencies, run:
# make [prefix=/foo] [bindir=/bar/bin] TARGETPLATFORM=unix-generic install
#
# to install Linux startup scripts, desktop files, icons, and MIME metadata
# to install FreeDesktop startup scripts, desktop files, icons, and MIME metadata
# make install-linux-shortcuts
#
# to install Linux AppStream metadata
# to install FreeDesktop AppStream metadata
# make install-linux-appdata
#
# to install the Unix man page
# make install-man
#
# for help, run:
# make help
#
@@ -53,8 +56,10 @@ RM_R = $(RM) -r
RM_F = $(RM) -f
RM_RF = $(RM) -rf
RUNTIME ?= net5
RUNTIME ?= net6
CONFIGURATION ?= Release
DOTNET_RID = $(shell ${DOTNET} --info | grep RID: | cut -w -f3)
ARCH_X64 = $(shell echo ${DOTNET_RID} | grep x64)
# Only for use in target version:
VERSION := $(shell git name-rev --name-only --tags --no-undefined HEAD 2>/dev/null || (c=$$(git rev-parse --short HEAD 2>/dev/null) && echo git-$$c))
@@ -64,15 +69,23 @@ ifndef TARGETPLATFORM
UNAME_S := $(shell uname -s)
UNAME_M := $(shell uname -m)
ifeq ($(UNAME_S),Darwin)
ifeq ($(ARCH_X64),)
TARGETPLATFORM = osx-arm64
else
TARGETPLATFORM = osx-x64
endif
else
ifeq ($(UNAME_M),x86_64)
TARGETPLATFORM = linux-x64
else
ifeq ($(UNAME_M),aarch64)
TARGETPLATFORM = linux-arm64
else
TARGETPLATFORM = unix-generic
endif
endif
endif
endif
##################### DEVELOPMENT BUILDS AND TESTS #####################
#
@@ -80,7 +93,7 @@ all:
@echo "Compiling in ${CONFIGURATION} mode..."
ifeq ($(RUNTIME), mono)
@command -v $(firstword $(MSBUILD)) >/dev/null || (echo "OpenRA requires the '$(MSBUILD)' tool provided by Mono >= 6.4."; exit 1)
@$(MSBUILD) -t:Build -restore -p:Configuration=${CONFIGURATION} -p:TargetPlatform=$(TARGETPLATFORM) -p:Mono=true
@$(MSBUILD) -t:Build -restore -p:Configuration=${CONFIGURATION} -p:TargetPlatform=$(TARGETPLATFORM)
else
@$(DOTNET) build -c ${CONFIGURATION} -nologo -p:TargetPlatform=$(TARGETPLATFORM)
endif
@@ -97,11 +110,13 @@ clean:
check:
@echo
@echo "Compiling in debug mode..."
@echo "Compiling in Debug mode..."
ifeq ($(RUNTIME), mono)
@$(MSBUILD) -t:build -restore -p:Configuration=Debug -p:TargetPlatform=$(TARGETPLATFORM) -p:Mono=true
# Enabling EnforceCodeStyleInBuild and GenerateDocumentationFile as a workaround for some code style rules (in particular IDE0005) being bugged and not reporting warnings/errors otherwise.
@$(MSBUILD) -t:build -restore -p:Configuration=Debug -warnaserror -p:TargetPlatform=$(TARGETPLATFORM) -p:EnforceCodeStyleInBuild=true -p:GenerateDocumentationFile=true
else
@$(DOTNET) build -c Debug -nologo -p:TargetPlatform=$(TARGETPLATFORM)
# Enabling EnforceCodeStyleInBuild and GenerateDocumentationFile as a workaround for some code style rules (in particular IDE0005) being bugged and not reporting warnings/errors otherwise.
@$(DOTNET) build -c Debug -nologo -warnaserror -p:TargetPlatform=$(TARGETPLATFORM) -p:EnforceCodeStyleInBuild=true -p:GenerateDocumentationFile=true
endif
ifeq ($(TARGETPLATFORM), unix-generic)
@./configure-system-libraries.sh
@@ -116,9 +131,7 @@ endif
check-scripts:
@echo
@echo "Checking for Lua syntax errors..."
@luac -p $(shell find mods/*/maps/* -iname '*.lua')
@luac -p $(shell find lua/* -iname '*.lua')
@luac -p $(shell find mods/*/bits/scripts/* -iname '*.lua')
@find lua/ mods/*/{maps,scripts}/ -iname "*.lua" -print0 | xargs -0n1 luac -p
test: all
@echo
@@ -153,34 +166,41 @@ install-linux-shortcuts:
install-linux-appdata:
@sh -c '. ./packaging/functions.sh; install_linux_appdata $(CWD) "$(DESTDIR)" "$(datadir)" cnc d2k ra'
install-man: all
@mkdir -p $(DESTDIR)$(mandir)/man6/
@./utility.sh all --man-page > $(DESTDIR)$(mandir)/man6/openra.6
help:
@echo 'to compile, run:'
@echo ' make'
@echo
@echo 'to compile using Mono (version 6.4 or greater) instead of .NET 5, run:'
@echo 'to compile using Mono (version 6.4 or greater) instead of .NET 6, run:'
@echo ' make RUNTIME=mono'
@echo
@echo 'to compile using system libraries for native dependencies, run:'
@echo ' make [RUNTIME=net5] TARGETPLATFORM=unix-generic'
@echo ' make [RUNTIME=net6] TARGETPLATFORM=unix-generic'
@echo
@echo 'to check the official mods for erroneous yaml files, run:'
@echo ' make [RUNTIME=net5] test'
@echo ' make [RUNTIME=net6] test'
@echo
@echo 'to check the engine and official mod dlls for code style violations, run:'
@echo ' make [RUNTIME=net5] check'
@echo ' make [RUNTIME=net6] check'
@echo
@echo 'to compile and install Red Alert, Tiberian Dawn, and Dune 2000 run:'
@echo ' make [RUNTIME=net5] [prefix=/foo] [TARGETPLATFORM=unix-generic] install'
@echo ' make [RUNTIME=net6] [prefix=/foo] [TARGETPLATFORM=unix-generic] install'
@echo
@echo 'to compile and install Red Alert, Tiberian Dawn, and Dune 2000'
@echo 'using system libraries for native dependencies, run:'
@echo ' make [RUNTIME=net5] [prefix=/foo] [bindir=/bar/bin] TARGETPLATFORM=unix-generic install'
@echo ' make [RUNTIME=net6] [prefix=/foo] [bindir=/bar/bin] TARGETPLATFORM=unix-generic install'
@echo
@echo 'to install Linux startup scripts, desktop files, icons, and MIME metadata'
@echo 'to install FreeDesktop startup scripts, desktop files, icons, and MIME metadata'
@echo ' make install-linux-shortcuts'
@echo
@echo 'to install Linux AppStream metadata'
@echo 'to install FreeDesktop AppStream metadata'
@echo ' make install-linux-appdata'
@echo
@echo 'to install a Unix man page'
@echo ' make install-man'
########################### MAKEFILE SETTINGS ##########################
#
@@ -188,4 +208,4 @@ help:
.SUFFIXES:
.PHONY: all clean check check-scripts test version install install-linux-shortcuts install-linux-appdata help
.PHONY: all clean check check-scripts test version install install-linux-shortcuts install-linux-appdata install-man help

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -22,7 +22,7 @@ namespace OpenRA.Activities
IsInterruptible = interruptible;
}
Action a;
readonly Action a;
public override bool Tick(Actor self)
{

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -65,9 +65,10 @@ namespace OpenRA
public int Generation;
public Actor ReplacedByActor;
public IEffectiveOwner EffectiveOwner { get; private set; }
public IOccupySpace OccupiesSpace { get; private set; }
public ITargetable[] Targetables { get; private set; }
public IEffectiveOwner EffectiveOwner { get; }
public IOccupySpace OccupiesSpace { get; }
public ITargetable[] Targetables { get; }
public IEnumerable<ITargetablePositions> EnabledTargetablePositions { get; private set; }
public bool IsIdle => CurrentActivity == null;
public bool IsDead => Disposed || (health != null && health.IsDead);
@@ -102,7 +103,7 @@ namespace OpenRA
/// <summary>Read-only version of conditionCache that is passed to IConditionConsumers.</summary>
readonly IReadOnlyDictionary<string, int> readOnlyConditionCache;
internal SyncHash[] SyncHashes { get; private set; }
internal SyncHash[] SyncHashes { get; }
readonly IFacing facing;
readonly IHealth health;
@@ -114,10 +115,8 @@ namespace OpenRA
readonly IDefaultVisibility defaultVisibility;
readonly INotifyBecomingIdle[] becomingIdles;
readonly INotifyIdle[] tickIdles;
readonly IEnumerable<ITargetablePositions> enabledTargetablePositions;
WPos[] staticTargetablePositions;
readonly IEnumerable<WPos> enabledTargetableWorldPositions;
bool created;
bool setStaticTargetablePositions;
internal Actor(World world, string name, TypeDictionary initDict)
{
@@ -146,7 +145,6 @@ namespace OpenRA
Info = world.Map.Rules.Actors[name];
IPositionable positionable = null;
var resolveOrdersList = new List<IResolveOrder>();
var renderModifiersList = new List<IRenderModifier>();
var rendersList = new List<IRender>();
@@ -168,7 +166,6 @@ namespace OpenRA
// performance-sensitive parts of the core game engine, such as pathfinding, visibility and rendering.
// Note: The blocks are required to limit the scope of the t's, so we make an exception to our normal style
// rules for spacing in order to keep these assignments compact and readable.
{ if (trait is IPositionable t) positionable = t; }
{ if (trait is IOccupySpace t) OccupiesSpace = t; }
{ if (trait is IEffectiveOwner t) EffectiveOwner = t; }
{ if (trait is IFacing t) facing = t; }
@@ -195,10 +192,9 @@ namespace OpenRA
tickIdles = tickIdlesList.ToArray();
Targetables = targetablesList.ToArray();
var targetablePositions = targetablePositionsList.ToArray();
enabledTargetablePositions = targetablePositions.Where(Exts.IsTraitEnabled);
EnabledTargetablePositions = targetablePositions.Where(Exts.IsTraitEnabled);
enabledTargetableWorldPositions = EnabledTargetablePositions.SelectMany(tp => tp.TargetablePositions(this));
SyncHashes = syncHashesList.ToArray();
setStaticTargetablePositions = positionable == null && targetablePositions.Any() && targetablePositions.All(tp => tp.AlwaysEnabled);
}
}
@@ -233,11 +229,6 @@ namespace OpenRA
foreach (var notify in allObserverNotifiers)
notify(this, readOnlyConditionCache);
// All actors that can move or teleport should have IPositionable, if not it's pretty safe to assume the actor is completely immobile and
// all targetable positions can be cached if all ITargetablePositions have no conditional requirements.
if (setStaticTargetablePositions)
staticTargetablePositions = enabledTargetablePositions.SelectMany(tp => tp.TargetablePositions(this)).ToArray();
// TODO: Other traits may need initialization after being notified of initial condition state.
// TODO: A post condition initialization notification phase may allow queueing activities instead.
@@ -490,7 +481,7 @@ namespace OpenRA
health.InflictDamage(this, attacker, damage, false);
}
public void Kill(Actor attacker, BitSet<DamageType> damageTypes = default(BitSet<DamageType>))
public void Kill(Actor attacker, BitSet<DamageType> damageTypes = default)
{
if (Disposed || health == null)
return;
@@ -539,11 +530,8 @@ namespace OpenRA
public IEnumerable<WPos> GetTargetablePositions()
{
if (staticTargetablePositions != null)
return staticTargetablePositions;
if (enabledTargetablePositions.Any())
return enabledTargetablePositions.SelectMany(tp => tp.TargetablePositions(this));
if (EnabledTargetablePositions.Any())
return enabledTargetableWorldPositions;
return new[] { CenterPosition };
}
@@ -552,7 +540,7 @@ namespace OpenRA
void UpdateConditionState(string condition, int token, bool isRevoke)
{
ConditionState conditionState = conditionStates.GetOrAdd(condition);
var conditionState = conditionStates.GetOrAdd(condition);
if (isRevoke)
conditionState.Tokens.Remove(token);

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -58,7 +58,13 @@ namespace OpenRA
public bool Equals(CPos other) { return Bits == other.Bits; }
public override bool Equals(object obj) { return obj is CPos && Equals((CPos)obj); }
public override string ToString() { return X + "," + Y; }
public override string ToString()
{
if (Layer == 0)
return X + "," + Y;
return X + "," + Y + "," + Layer;
}
public MPos ToMPos(Map map)
{

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,20 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
namespace OpenRA
{
public interface ICacheStorage<T>
{
void Remove(string key);
void Store(string key, T data);
T Retrieve(string key);
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -17,8 +17,8 @@ namespace OpenRA.Effects
{
public class AsyncAction : IEffect
{
Action a;
IAsyncResult ar;
readonly Action a;
readonly IAsyncResult ar;
public AsyncAction(IAsyncResult ar, Action a)
{

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -17,7 +17,7 @@ namespace OpenRA.Effects
{
public class DelayedAction : IEffect
{
Action a;
readonly Action a;
int delay;
public DelayedAction(int delay, Action a)

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -66,12 +66,7 @@ namespace OpenRA
// Several types of support directory types are available, depending on
// how the player has installed and launched the game.
// Read registration metadata from all of them
var sources = Enum.GetValues(typeof(SupportDirType))
.Cast<SupportDirType>()
.Select(t => Platform.GetSupportDir(t))
.Distinct();
foreach (var source in sources)
foreach (var source in GetSupportDirs(ModRegistration.User | ModRegistration.System))
{
var metadataPath = Path.Combine(source, "ModMetadata");
if (!Directory.Exists(metadataPath))
@@ -148,7 +143,7 @@ namespace OpenRA
if (stream != null)
yaml.Value.Nodes.Add(new MiniYamlNode("Icon3x", Convert.ToBase64String(stream.ReadAllBytes())));
var sources = new List<string>();
var sources = new HashSet<string>();
if (registration.HasFlag(ModRegistration.System))
sources.Add(Platform.GetSupportDir(SupportDirType.System));
@@ -167,7 +162,7 @@ namespace OpenRA
LoadMod(yaml.Value, forceRegistration: true);
var lines = new List<MiniYamlNode> { yaml }.ToLines().ToArray();
foreach (var source in sources.Distinct())
foreach (var source in sources)
{
var metadataPath = Path.Combine(source, "ModMetadata");
@@ -191,23 +186,9 @@ namespace OpenRA
/// * Filename doesn't match internal key
/// * Fails to parse as a mod registration
/// </summary>
internal void ClearInvalidRegistrations(ExternalMod activeMod, ModRegistration registration)
internal void ClearInvalidRegistrations(ModRegistration registration)
{
var sources = new List<string>();
if (registration.HasFlag(ModRegistration.System))
sources.Add(Platform.GetSupportDir(SupportDirType.System));
if (registration.HasFlag(ModRegistration.User))
{
// User support dir may be using the modern or legacy value, or overridden by the user
// Add all the possibilities and let the .Distinct() below ignore the duplicates
sources.Add(Platform.GetSupportDir(SupportDirType.User));
sources.Add(Platform.GetSupportDir(SupportDirType.ModernUser));
sources.Add(Platform.GetSupportDir(SupportDirType.LegacyUser));
}
var activeModKey = ExternalMod.MakeKey(activeMod);
foreach (var source in sources.Distinct())
foreach (var source in GetSupportDirs(registration))
{
var metadataPath = Path.Combine(source, "ModMetadata");
if (!Directory.Exists(metadataPath))
@@ -222,13 +203,10 @@ namespace OpenRA
var m = FieldLoader.Load<ExternalMod>(yaml);
modKey = ExternalMod.MakeKey(m);
// Continue to the next entry if it is the active mod (even if the LaunchPath is bogus)
if (modKey == activeModKey)
continue;
// Continue to the next entry if this one is valid
if (File.Exists(m.LaunchPath) && Path.GetFileNameWithoutExtension(path) == modKey &&
!(activeMod != null && m.LaunchPath == activeMod.LaunchPath && m.Id == activeMod.Id && m.Version != activeMod.Version))
// HACK: Explicitly invalidate paths to OpenRA.dll to clean up bogus metadata files
// that were created after the initial migration from .NET Framework to Core/5.
if (File.Exists(m.LaunchPath) && Path.GetFileNameWithoutExtension(path) == modKey && Path.GetExtension(m.LaunchPath) != ".dll")
continue;
}
catch (Exception e)
@@ -258,23 +236,10 @@ namespace OpenRA
internal void Unregister(Manifest mod, ModRegistration registration)
{
var sources = new List<string>();
if (registration.HasFlag(ModRegistration.System))
sources.Add(Platform.GetSupportDir(SupportDirType.System));
if (registration.HasFlag(ModRegistration.User))
{
// User support dir may be using the modern or legacy value, or overridden by the user
// Add all the possibilities and let the .Distinct() below ignore the duplicates
sources.Add(Platform.GetSupportDir(SupportDirType.User));
sources.Add(Platform.GetSupportDir(SupportDirType.ModernUser));
sources.Add(Platform.GetSupportDir(SupportDirType.LegacyUser));
}
var key = ExternalMod.MakeKey(mod);
mods.Remove(key);
foreach (var source in sources.Distinct())
foreach (var source in GetSupportDirs(registration))
{
var path = Path.Combine(source, "ModMetadata", key + ".yaml");
try
@@ -290,6 +255,24 @@ namespace OpenRA
}
}
IEnumerable<string> GetSupportDirs(ModRegistration registration)
{
var sources = new HashSet<string>(4);
if (registration.HasFlag(ModRegistration.System))
sources.Add(Platform.GetSupportDir(SupportDirType.System));
if (registration.HasFlag(ModRegistration.User))
{
// User support dir may be using the modern or legacy value, or overridden by the user
// Add all the possibilities and let the HashSet ignore the duplicates
sources.Add(Platform.GetSupportDir(SupportDirType.User));
sources.Add(Platform.GetSupportDir(SupportDirType.ModernUser));
sources.Add(Platform.GetSupportDir(SupportDirType.LegacyUser));
}
return sources;
}
public ExternalMod this[string key] => mods[key];
public int Count => mods.Count;
public ICollection<string> Keys => mods.Keys;

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -38,12 +38,6 @@ namespace OpenRA
catch { return def; }
}
public static void Do<T>(this IEnumerable<T> e, Action<T> fn)
{
foreach (var ee in e)
fn(ee);
}
public static Lazy<T> Lazy<T>(Func<T> p) { return new Lazy<T>(p); }
public static IEnumerable<string> GetNamespaces(this Assembly a)
@@ -53,7 +47,7 @@ namespace OpenRA
public static bool HasAttribute<T>(this MemberInfo mi)
{
return mi.GetCustomAttributes(typeof(T), true).Length != 0;
return Attribute.IsDefined(mi, typeof(T));
}
public static T[] GetCustomAttributes<T>(this MemberInfo mi, bool inherit)
@@ -107,7 +101,7 @@ namespace OpenRA
// - the triangles ACD and BCD must have opposite sense (clockwise or anticlockwise)
// - the triangles CAB and DAB must have opposite sense
// Segments intersect if the orientation (clockwise or anticlockwise) of the two points in each line segment are opposite with respect to the other
// Assumes that lines are not colinear
// Assumes that lines are not collinear
return WindingDirectionTest(c, d, a) != WindingDirectionTest(c, d, b) && WindingDirectionTest(a, b, c) != WindingDirectionTest(a, b, d);
}
@@ -161,7 +155,7 @@ namespace OpenRA
if (throws)
throw new ArgumentException("Collection must not be empty.", nameof(ts));
else
return default(T);
return default;
}
else
return xs.ElementAt(r.Next(xs.Count));
@@ -238,7 +232,7 @@ namespace OpenRA
if (throws)
throw new ArgumentException("Collection must not be empty.", nameof(ts));
else
return default(T);
return default;
t = e.Current;
u = selector(t);
while (e.MoveNext())
@@ -357,6 +351,11 @@ namespace OpenRA
return root;
}
public static int MultiplyBySqrtTwo(short number)
{
return number * 46341 / 32768;
}
public static int IntegerDivisionRoundingAwayFromZero(int dividend, int divisor)
{
var quotient = Math.DivRem(dividend, divisor, out var remainder);
@@ -375,6 +374,11 @@ namespace OpenRA
return ts.Concat(moreTs);
}
public static IEnumerable<T> Exclude<T>(this IEnumerable<T> ts, params T[] exclusions)
{
return ts.Except(exclusions);
}
public static HashSet<T> ToHashSet<T>(this IEnumerable<T> source)
{
return new HashSet<T>(source);
@@ -397,7 +401,8 @@ namespace OpenRA
// Try to build a dictionary and log all duplicates found (if any):
var dupKeys = new Dictionary<TKey, List<string>>();
var d = new Dictionary<TKey, TElement>();
var capacity = source is ICollection<TSource> collection ? collection.Count : 0;
var d = new Dictionary<TKey, TElement>(capacity);
foreach (var item in source)
{
var key = keySelector(item);
@@ -408,22 +413,21 @@ namespace OpenRA
continue;
// Check for a key conflict:
if (d.ContainsKey(key))
if (!d.TryAdd(key, element))
{
if (!dupKeys.TryGetValue(key, out var dupKeyMessages))
{
// Log the initial conflicting value already inserted:
dupKeyMessages = new List<string>();
dupKeyMessages.Add(logValue(d[key]));
dupKeyMessages = new List<string>
{
logValue(d[key])
};
dupKeys.Add(key, dupKeyMessages);
}
// Log this conflicting value:
dupKeyMessages.Add(logValue(element));
continue;
}
d.Add(key, element);
}
// If any duplicates were found, throw a descriptive error
@@ -521,7 +525,7 @@ namespace OpenRA
if (t.IsTraitEnabled())
return t;
return default(T);
return default;
}
public static T FirstEnabledTraitOrDefault<T>(this T[] ts)
@@ -531,7 +535,27 @@ namespace OpenRA
if (t.IsTraitEnabled())
return t;
return default(T);
return default;
}
public static T FirstEnabledConditionalTraitOrDefault<T>(this IEnumerable<T> ts) where T : IDisabledTrait
{
// PERF: Avoid LINQ.
foreach (var t in ts)
if (!t.IsTraitDisabled)
return t;
return default;
}
public static T FirstEnabledConditionalTraitOrDefault<T>(this T[] ts) where T : IDisabledTrait
{
// PERF: Avoid LINQ.
foreach (var t in ts)
if (!t.IsTraitDisabled)
return t;
return default;
}
public static LineSplitEnumerator SplitLines(this string str, char separator)
@@ -592,7 +616,7 @@ namespace OpenRA
if (values.Any(x => !names.Contains(x)))
{
value = default(T);
value = default;
return false;
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -17,7 +17,6 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using OpenRA.Primitives;
using OpenRA.Support;
@@ -272,6 +271,11 @@ namespace OpenRA
if (value != null)
{
var parts = value.Split(SplitComma, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length == 3)
return new CPos(
Exts.ParseIntegerInvariant(parts[0]),
Exts.ParseIntegerInvariant(parts[1]),
Exts.ParseByte(parts[2]));
return new CPos(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]));
}
@@ -474,9 +478,15 @@ namespace OpenRA
return set;
var parts = value.Split(SplitComma, StringSplitOptions.RemoveEmptyEntries);
var addMethod = fieldType.GetMethod("Add", fieldType.GetGenericArguments());
var arguments = fieldType.GetGenericArguments();
var addMethod = fieldType.GetMethod(nameof(List<object>.Add), arguments);
var addArgs = new object[1];
for (var i = 0; i < parts.Length; i++)
addMethod.Invoke(set, new[] { GetValue(fieldName, fieldType.GetGenericArguments()[0], parts[i].Trim(), field) });
{
addArgs[0] = GetValue(fieldName, arguments[0], parts[i].Trim(), field);
addMethod.Invoke(set, addArgs);
}
return set;
}
@@ -484,13 +494,13 @@ namespace OpenRA
{
var dict = Activator.CreateInstance(fieldType);
var arguments = fieldType.GetGenericArguments();
var addMethod = fieldType.GetMethod("Add", arguments);
var addMethod = fieldType.GetMethod(nameof(Dictionary<object, object>.Add), arguments);
var addArgs = new object[2];
foreach (var node in yaml.Nodes)
{
var key = GetValue(fieldName, arguments[0], node.Key, field);
var val = GetValue(fieldName, arguments[1], node.Value, field);
addMethod.Invoke(dict, new[] { key, val });
addArgs[0] = GetValue(fieldName, arguments[0], node.Key, field);
addArgs[1] = GetValue(fieldName, arguments[1], node.Value, field);
addMethod.Invoke(dict, addArgs);
}
return dict;
@@ -554,7 +564,7 @@ namespace OpenRA
fli.Field.SetValue(self, val);
}
if (missing.Any())
if (missing.Count > 0)
throw new MissingFieldsException(missing.ToArray());
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -26,11 +26,11 @@ namespace OpenRA.FileFormats
{
static readonly byte[] Signature = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
public int Width { get; private set; }
public int Height { get; private set; }
public Color[] Palette { get; private set; }
public byte[] Data { get; private set; }
public SpriteFrameType Type { get; private set; }
public int Width { get; }
public int Height { get; }
public Color[] Palette { get; }
public byte[] Data { get; }
public SpriteFrameType Type { get; }
public Dictionary<string, string> EmbeddedData = new Dictionary<string, string>();
public int PixelStride => Type == SpriteFrameType.Indexed8 ? 1 : Type == SpriteFrameType.Rgb24 ? 3 : 4;

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -63,7 +63,7 @@ namespace OpenRA.FileSystem
{
// Raw directories are the easiest and one of the most common cases, so try these first
var resolvedPath = Platform.ResolvePath(filename);
if (!resolvedPath.Contains("|") && Directory.Exists(resolvedPath))
if (!resolvedPath.Contains('|') && Directory.Exists(resolvedPath))
return new Folder(resolvedPath);
// Children of another package require special handling

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -55,7 +55,8 @@ namespace OpenRA.FileSystem
get
{
foreach (ZipEntry entry in pkg)
yield return entry.Name;
if (entry.IsFile)
yield return entry.Name;
}
}
@@ -142,7 +143,7 @@ namespace OpenRA.FileSystem
sealed class ZipFolder : IReadOnlyPackage
{
public string Name => path;
public ReadOnlyZipFile Parent { get; private set; }
public ReadOnlyZipFile Parent { get; }
readonly string path;
public ZipFolder(ReadOnlyZipFile parent, string path)

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -16,7 +16,6 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime;
using System.Threading;
using OpenRA.Graphics;
@@ -30,7 +29,6 @@ namespace OpenRA
{
public static class Game
{
public const int NetTickScale = 3; // 120 ms net tick for 40 ms local tick
public const int TimestepJankThreshold = 250; // Don't catch up for delays larger than 250ms
public static InstalledMods Mods { get; private set; }
@@ -85,6 +83,9 @@ namespace OpenRA
static void JoinInner(OrderManager om)
{
// Refresh TextNotificationsManager before the game starts.
TextNotificationsManager.Clear();
// HACK: The shellmap World and OrderManager are owned by the main menu's WorldRenderer instead of Game.
// This allows us to switch Game.OrderManager from the shellmap to the new network connection when joining
// a lobby, while keeping the OrderManager that runs the shellmap intact.
@@ -121,8 +122,8 @@ namespace OpenRA
}
// More accurate replacement for Environment.TickCount
static Stopwatch stopwatch = Stopwatch.StartNew();
public static long RunTime => stopwatch.ElapsedMilliseconds;
static readonly Stopwatch Stopwatch = Stopwatch.StartNew();
public static long RunTime => Stopwatch.ElapsedMilliseconds;
public static int RenderFrame = 0;
public static int NetFrameNumber => OrderManager.NetFrameNumber;
@@ -234,6 +235,17 @@ namespace OpenRA
// Reseed the RNG so this isn't an exact repeat of the last game
lobbyInfo.GlobalSettings.RandomSeed = CosmeticRandom.Next();
// Note: the map may have been changed on disk outside the game, changing its UID.
// Use the updated UID if we have tracked the update instead of failing.
lobbyInfo.GlobalSettings.Map = ModData.MapCache.GetUpdatedMap(lobbyInfo.GlobalSettings.Map);
if (lobbyInfo.GlobalSettings.Map == null)
{
Disconnect();
Ui.ResetAll();
LoadShellMap();
return;
}
var orders = new[]
{
Order.Command($"sync_lobby {lobbyInfo.Serialize()}"),
@@ -306,7 +318,7 @@ namespace OpenRA
if (!string.IsNullOrEmpty(supportDirArg))
Platform.OverrideSupportDir(supportDirArg);
Console.WriteLine("Platform is {0}", Platform.CurrentPlatform);
Console.WriteLine($"Platform is {Platform.CurrentPlatform} ({Platform.CurrentArchitecture})");
// Load the engine version as early as possible so it can be written to exception logs
try
@@ -318,13 +330,13 @@ namespace OpenRA
if (string.IsNullOrEmpty(EngineVersion))
EngineVersion = "Unknown";
Console.WriteLine("Engine version is {0}", EngineVersion);
Console.WriteLine("Runtime: {0}", Platform.RuntimeVersion);
Console.WriteLine($"Engine version is {EngineVersion}");
Console.WriteLine($"Runtime: {Platform.RuntimeVersion}");
// Special case handling of Game.Mod argument: if it matches a real filesystem path
// then we use this to override the mod search path, and replace it with the mod id
var modID = args.GetValue("Game.Mod", null);
var explicitModPaths = new string[0];
var explicitModPaths = Array.Empty<string>();
if (modID != null && (File.Exists(modID) || Directory.Exists(modID)))
{
explicitModPaths = new[] { modID };
@@ -353,12 +365,13 @@ namespace OpenRA
{
var rendererPath = Path.Combine(Platform.BinDir, "OpenRA.Platforms." + p + ".dll");
#if !MONO
#if NET5_0_OR_GREATER
var loader = new AssemblyLoader(rendererPath);
var platformType = loader.LoadDefaultAssembly().GetTypes().SingleOrDefault(t => typeof(IPlatform).IsAssignableFrom(t));
#else
var assembly = Assembly.LoadFile(rendererPath);
// NOTE: This is currently the only use of System.Reflection in this file, so would give an unused using error if we import it above
var assembly = System.Reflection.Assembly.LoadFile(rendererPath);
var platformType = assembly.GetTypes().SingleOrDefault(t => typeof(IPlatform).IsAssignableFrom(t));
#endif
@@ -373,7 +386,7 @@ namespace OpenRA
}
catch (Exception e)
{
Log.Write("graphics", "{0}", e);
Log.Write("graphics", $"{e}");
Console.WriteLine("Renderer initialization failed. Check graphics.log for details.");
Renderer?.Dispose();
@@ -392,7 +405,7 @@ namespace OpenRA
Mods = new InstalledMods(modSearchPaths, explicitModPaths);
Console.WriteLine("Internal mods:");
foreach (var mod in Mods)
Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Metadata.Title, mod.Value.Metadata.Version);
Console.WriteLine($"\t{mod.Key}: {mod.Value.Metadata.Title} ({mod.Value.Metadata.Version})");
modLaunchWrapper = args.GetValue("Engine.LaunchWrapper", null);
@@ -408,27 +421,18 @@ namespace OpenRA
if (launchPath != null && launchPath.First() == '"' && launchPath.Last() == '"')
launchPath = launchPath.Substring(1, launchPath.Length - 2);
if (launchPath == null)
{
// When launching the assembly directly we must propagate the Engine.EngineDir argument if defined
// Platform-specific launchers are expected to manage this internally.
launchPath = Assembly.GetEntryAssembly().Location;
if (!string.IsNullOrEmpty(engineDirArg))
launchArgs.Add("Engine.EngineDir=\"" + engineDirArg + "\"");
}
// Metadata registration requires an explicit launch path
if (launchPath != null)
ExternalMods.Register(Mods[modID], launchPath, launchArgs, ModRegistration.User);
ExternalMods.Register(Mods[modID], launchPath, launchArgs, ModRegistration.User);
if (ExternalMods.TryGetValue(ExternalMod.MakeKey(Mods[modID]), out var activeMod))
ExternalMods.ClearInvalidRegistrations(activeMod, ModRegistration.User);
ExternalMods.ClearInvalidRegistrations(ModRegistration.User);
}
Console.WriteLine("External mods:");
foreach (var mod in ExternalMods)
Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Title, mod.Value.Version);
Console.WriteLine($"\t{mod.Key}: {mod.Value.Title} ({mod.Value.Version})");
InitializeMod(modID, args);
Ui.InitializeTranslation();
}
public static void InitializeMod(string mod, Arguments args)
@@ -461,7 +465,7 @@ namespace OpenRA
if (!Mods.ContainsKey(mod))
throw new InvalidOperationException($"Unknown or invalid mod '{mod}'.");
Console.WriteLine("Loading mod: {0}", mod);
Console.WriteLine($"Loading mod: {mod}");
Sound.StopVideo();
@@ -567,6 +571,9 @@ namespace OpenRA
public static void RunAfterTick(Action a) { delayedActions.Add(a, RunTime); }
public static void RunAfterDelay(int delayMilliseconds, Action a) { delayedActions.Add(a, RunTime + delayMilliseconds); }
[TranslationReference("filename")]
static readonly string SavedScreenshot = "saved-screenshot";
static void TakeScreenshotInner()
{
using (new PerfTimer("Renderer.SaveScreenshot"))
@@ -580,7 +587,7 @@ namespace OpenRA
Log.Write("debug", "Taking screenshot " + path);
Renderer.SaveScreenshot(path);
TextNotificationsManager.Debug("Saved screenshot " + filename);
TextNotificationsManager.Debug(ModData.Translation.GetString(SavedScreenshot, Translation.Arguments("filename", filename)));
}
}
@@ -780,13 +787,15 @@ namespace OpenRA
// ReplayTimestep = 0 means the replay is paused: we need to keep logicInterval as UI.Timestep to avoid breakage
if (logicWorld != null && !(logicWorld.IsReplay && logicWorld.ReplayTimestep == 0))
logicInterval = logicWorld.IsLoadingGameSave ? 1 :
logicWorld.IsReplay ? logicWorld.ReplayTimestep :
logicWorld.Timestep;
logicInterval = logicWorld == OrderManager.World ? OrderManager.SuggestedTimestep : logicWorld.Timestep;
// Ideal time between screen updates
var maxFramerate = Settings.Graphics.CapFramerate ? Settings.Graphics.MaxFramerate.Clamp(1, 1000) : 1000;
var renderInterval = 1000 / maxFramerate;
var renderInterval = logicInterval;
if (!Settings.Graphics.CapFramerateToGameFps)
{
var maxFramerate = Settings.Graphics.CapFramerate ? Settings.Graphics.MaxFramerate.Clamp(1, 1000) : 1000;
renderInterval = 1000 / maxFramerate;
}
// Tick as fast as possible while restoring game saves, capping rendering at 5 FPS
if (OrderManager.World != null && OrderManager.World.IsLoadingGameSave)
@@ -964,12 +973,9 @@ namespace OpenRA
Order.Command($"state {Session.ClientState.Ready}")
};
var path = Platform.ResolvePath(launchMap);
var map = ModData.MapCache.SingleOrDefault(m => m.Uid == launchMap) ??
ModData.MapCache.SingleOrDefault(m => m.Package.Name == path);
var map = ModData.MapCache.SingleOrDefault(m => m.Uid == launchMap || Path.GetFileName(m.Package.Name) == launchMap);
if (map == null)
throw new InvalidOperationException($"Could not find map '{launchMap}'.");
throw new ArgumentException($"Could not find map '{launchMap}'.");
CreateAndStartLocalServer(map.Uid, orders);
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -35,7 +35,7 @@ namespace OpenRA
/// <summary>Gets the game's duration, from the time the game started until the replay recording stopped.</summary>
public TimeSpan Duration => EndTimeUtc > StartTimeUtc ? EndTimeUtc - StartTimeUtc : TimeSpan.Zero;
public IList<Player> Players { get; private set; }
public IList<Player> Players { get; }
public HashSet<int> DisabledSpawnPoints = new HashSet<int>();
public MapPreview MapPreview => Game.ModData.MapCache[MapUid];
public IEnumerable<Player> HumanPlayers { get { return Players.Where(p => p.IsHuman); } }

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -110,10 +110,11 @@ namespace OpenRA
{
Trait = i,
Type = i.GetType(),
Dependencies = PrerequisitesOf(i).ToList()
Dependencies = PrerequisitesOf(i).ToList(),
OptionalDependencies = OptionalPrerequisitesOf(i).ToList()
}).ToList();
var resolved = source.Where(s => !s.Dependencies.Any()).ToList();
var resolved = source.Where(s => s.Dependencies.Count == 0 && s.OptionalDependencies.Count == 0).ToList();
var unresolved = source.Except(resolved);
var testResolve = new Func<Type, Type, bool>((a, b) => a == b || a.IsAssignableFrom(b));
@@ -122,7 +123,9 @@ namespace OpenRA
var more = unresolved.Where(u =>
u.Dependencies.All(d => // To be resolvable, all dependencies must be satisfied according to the following conditions:
resolved.Exists(r => testResolve(d, r.Type)) && // There must exist a resolved trait that meets the dependency.
!unresolved.Any(u1 => testResolve(d, u1.Type)))); // All matching traits that meet this dependency must be resolved first.
!unresolved.Any(u1 => testResolve(d, u1.Type))) && // All matching traits that meet this dependency must be resolved first.
u.OptionalDependencies.All(d => // To be resolvable, all optional dependencies must be satisfied according to the following condition:
!unresolved.Any(u1 => testResolve(d, u1.Type)))); // All matching traits that meet this optional dependencies must be resolved first.
// Continue resolving traits as long as possible.
// Each time we resolve some traits, this means dependencies for other traits may then be possible to satisfy in the next pass.
@@ -142,7 +145,9 @@ namespace OpenRA
foreach (var u in unresolved)
{
var deps = u.Dependencies.Where(d => !resolved.Exists(r => r.Type == d));
exceptionString += u.Type + ": { " + string.Join(", ", deps) + " }\r\n";
var optDeps = u.OptionalDependencies.Where(d => !resolved.Exists(r => r.Type == d));
var allDeps = string.Join(", ", deps.Select(o => o.ToString()).Concat(optDeps.Select(o => $"[{o}]")));
exceptionString += $"{u.Type}: {{ {allDeps} }}\r\n";
}
throw new YamlException(exceptionString);
@@ -161,6 +166,15 @@ namespace OpenRA
.Select(t => t.GetGenericArguments()[0]);
}
public static IEnumerable<Type> OptionalPrerequisitesOf(TraitInfo info)
{
return info
.GetType()
.GetInterfaces()
.Where(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(NotBefore<>))
.Select(t => t.GetGenericArguments()[0]);
}
public bool HasTraitInfo<T>() where T : ITraitInfoInterface { return traits.Contains<T>(); }
public T TraitInfo<T>() where T : ITraitInfoInterface { return traits.Get<T>(); }
public T TraitInfoOrDefault<T>() where T : ITraitInfoInterface { return traits.GetOrDefault<T>(); }

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -9,7 +9,6 @@
*/
#endregion
using System.IO;
using OpenRA.FileSystem;
namespace OpenRA.GameRules

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -131,7 +131,7 @@ namespace OpenRA
filterNode: n => n.Key.StartsWith(ActorInfo.AbstractActorPrefix, StringComparison.Ordinal));
var weapons = MergeOrDefault("Manifest,Weapons", fs, m.Weapons, null, null,
k => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value));
k => new WeaponInfo(k.Value));
var voices = MergeOrDefault("Manifest,Voices", fs, m.Voices, null, null,
k => new SoundInfo(k.Value));
@@ -190,7 +190,7 @@ namespace OpenRA
filterNode: n => n.Key.StartsWith(ActorInfo.AbstractActorPrefix, StringComparison.Ordinal));
var weapons = MergeOrDefault("Weapons", fileSystem, m.Weapons, mapWeapons, dr.Weapons,
k => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value));
k => new WeaponInfo(k.Value));
var voices = MergeOrDefault("Voices", fileSystem, m.Voices, mapVoices, dr.Voices,
k => new SoundInfo(k.Value));
@@ -235,7 +235,7 @@ namespace OpenRA
static bool AnyCustomYaml(MiniYaml yaml)
{
return yaml != null && (yaml.Value != null || yaml.Nodes.Any());
return yaml != null && (yaml.Value != null || yaml.Nodes.Count > 0);
}
static bool AnyFlaggedTraits(ModData modData, List<MiniYamlNode> actors)
@@ -248,7 +248,7 @@ namespace OpenRA
{
var traitName = traitNode.Key.Split('@')[0];
var traitType = modData.ObjectCreator.FindType(traitName + "Info");
if (traitType != null && traitType.GetInterface("ILobbyCustomRulesIgnore") == null)
if (traitType != null && traitType.GetInterface(nameof(ILobbyCustomRulesIgnore)) == null)
return true;
}
catch (Exception ex)

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -33,23 +33,28 @@ namespace OpenRA.GameRules
{
FieldLoader.Load(this, y);
VoicePools = Exts.Lazy(() => Voices.ToDictionary(a => a.Key, a => new SoundPool(1f, a.Value)));
VoicePools = Exts.Lazy(() => Voices.ToDictionary(a => a.Key, a => new SoundPool(1f, SoundPool.DefaultInterruptType, a.Value)));
NotificationsPools = Exts.Lazy(() => ParseSoundPool(y, "Notifications"));
}
Dictionary<string, SoundPool> ParseSoundPool(MiniYaml y, string key)
static Dictionary<string, SoundPool> ParseSoundPool(MiniYaml y, string key)
{
var ret = new Dictionary<string, SoundPool>();
var classifiction = y.Nodes.First(x => x.Key == key);
foreach (var t in classifiction.Value.Nodes)
{
var volumeModifier = 1f;
var volumeModifierNode = t.Value.Nodes.FirstOrDefault(x => x.Key == "VolumeModifier");
var volumeModifierNode = t.Value.Nodes.FirstOrDefault(x => x.Key == nameof(SoundPool.VolumeModifier));
if (volumeModifierNode != null)
volumeModifier = FieldLoader.GetValue<float>(volumeModifierNode.Key, volumeModifierNode.Value.Value);
var interruptType = SoundPool.DefaultInterruptType;
var interruptTypeNode = t.Value.Nodes.FirstOrDefault(x => x.Key == nameof(SoundPool.InterruptType));
if (interruptTypeNode != null)
interruptType = FieldLoader.GetValue<SoundPool.InterruptType>(interruptTypeNode.Key, interruptTypeNode.Value.Value);
var names = FieldLoader.GetValue<string[]>(t.Key, t.Value.Value);
var sp = new SoundPool(volumeModifier, names);
var sp = new SoundPool(volumeModifier, interruptType, names);
ret.Add(t.Key, sp);
}
@@ -59,13 +64,17 @@ namespace OpenRA.GameRules
public class SoundPool
{
public enum InterruptType { DoNotPlay, Interrupt, Overlap }
public const InterruptType DefaultInterruptType = InterruptType.DoNotPlay;
public readonly float VolumeModifier;
public readonly InterruptType Type;
readonly string[] clips;
readonly List<string> liveclips = new List<string>();
public SoundPool(float volumeModifier, params string[] clips)
public SoundPool(float volumeModifier, InterruptType interruptType, params string[] clips)
{
VolumeModifier = volumeModifier;
Type = interruptType;
this.clips = clips;
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -36,7 +36,7 @@ namespace OpenRA.GameRules
public class WarheadArgs
{
public WeaponInfo Weapon;
public int[] DamageModifiers = { };
public int[] DamageModifiers = Array.Empty<int>();
public WPos? Source;
public WRot ImpactOrientation;
public WPos ImpactPosition;
@@ -127,7 +127,12 @@ namespace OpenRA.GameRules
[FieldLoader.LoadUsing(nameof(LoadWarheads))]
public readonly List<IWarhead> Warheads = new List<IWarhead>();
public WeaponInfo(string name, MiniYaml content)
/// <summary>
/// This constructor is used solely for documentation generation!
/// </summary>
public WeaponInfo() { }
public WeaponInfo(MiniYaml content)
{
// Resolve any weapon-level yaml inheritance or removals
// HACK: The "Defaults" sequence syntax prevents us from doing this generally during yaml parsing
@@ -139,7 +144,11 @@ namespace OpenRA.GameRules
{
if (!yaml.ToDictionary().TryGetValue("Projectile", out var proj))
return null;
var ret = Game.CreateObject<IProjectileInfo>(proj.Value + "Info");
if (ret == null)
return null;
FieldLoader.Load(ret, proj);
return ret;
}
@@ -150,6 +159,9 @@ namespace OpenRA.GameRules
foreach (var node in yaml.Nodes.Where(n => n.Key.StartsWith("Warhead")))
{
var ret = Game.CreateObject<IWarhead>(node.Value.Value + "Warhead");
if (ret == null)
continue;
FieldLoader.Load(ret, node.Value);
retList.Add(ret);
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -50,37 +50,41 @@ namespace OpenRA.Graphics
}
public int CurrentFrame => backwards ? CurrentSequence.Length - frame - 1 : frame;
public Sprite Image => CurrentSequence.GetSprite(CurrentFrame, facingFunc());
public IRenderable[] Render(WPos pos, in WVec offset, int zOffset, PaletteReference palette)
{
var tintModifiers = CurrentSequence.IgnoreWorldTint ? TintModifiers.IgnoreWorldTint : TintModifiers.None;
var alpha = CurrentSequence.GetAlpha(CurrentFrame);
var imageRenderable = new SpriteRenderable(Image, pos, offset, CurrentSequence.ZOffset + zOffset, palette, CurrentSequence.Scale, alpha, float3.Ones, tintModifiers, IsDecoration);
var (image, rotation) = CurrentSequence.GetSpriteWithRotation(CurrentFrame, facingFunc());
var imageRenderable = new SpriteRenderable(image, pos, offset, CurrentSequence.ZOffset + zOffset, palette, CurrentSequence.Scale, alpha, float3.Ones, tintModifiers, IsDecoration,
rotation);
if (CurrentSequence.ShadowStart >= 0)
{
var shadow = CurrentSequence.GetShadow(CurrentFrame, facingFunc());
var shadowRenderable = new SpriteRenderable(shadow, pos, offset, CurrentSequence.ShadowZOffset + zOffset, palette, CurrentSequence.Scale, 1f, float3.Ones, tintModifiers, true);
var shadowRenderable = new SpriteRenderable(shadow, pos, offset, CurrentSequence.ShadowZOffset + zOffset, palette, CurrentSequence.Scale, 1f, float3.Ones, tintModifiers,
true, rotation);
return new IRenderable[] { shadowRenderable, imageRenderable };
}
return new IRenderable[] { imageRenderable };
}
public IRenderable[] RenderUI(WorldRenderer wr, int2 pos, in WVec offset, int zOffset, PaletteReference palette, float scale = 1f)
public IRenderable[] RenderUI(WorldRenderer wr, int2 pos, in WVec offset, int zOffset, PaletteReference palette, float scale = 1f, float rotation = 0f)
{
scale *= CurrentSequence.Scale;
var screenOffset = (scale * wr.ScreenVectorComponents(offset)).XY.ToInt2();
var imagePos = pos + screenOffset - new int2((int)(scale * Image.Size.X / 2), (int)(scale * Image.Size.Y / 2));
var alpha = CurrentSequence.GetAlpha(CurrentFrame);
var imageRenderable = new UISpriteRenderable(Image, WPos.Zero + offset, imagePos, CurrentSequence.ZOffset + zOffset, palette, scale, alpha);
var imageRenderable = new UISpriteRenderable(Image, WPos.Zero + offset, imagePos, CurrentSequence.ZOffset + zOffset, palette, scale, alpha, rotation);
if (CurrentSequence.ShadowStart >= 0)
{
var shadow = CurrentSequence.GetShadow(CurrentFrame, facingFunc());
var shadowPos = pos - new int2((int)(scale * shadow.Size.X / 2), (int)(scale * shadow.Size.Y / 2));
var shadowRenderable = new UISpriteRenderable(shadow, WPos.Zero + offset, shadowPos, CurrentSequence.ShadowZOffset + zOffset, palette, scale);
var shadowRenderable = new UISpriteRenderable(shadow, WPos.Zero + offset, shadowPos, CurrentSequence.ShadowZOffset + zOffset, palette, scale, 1f, rotation);
return new IRenderable[] { shadowRenderable, imageRenderable };
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -35,7 +35,7 @@ namespace OpenRA.Graphics
ZOffset = zOffset;
}
public IRenderable[] Render(Actor self, WorldRenderer wr, PaletteReference pal)
public IRenderable[] Render(Actor self, PaletteReference pal)
{
var center = self.CenterPosition;
var offset = OffsetFunc?.Invoke() ?? WVec.Zero;

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -144,6 +144,15 @@ namespace OpenRA.Graphics
}
public static Sprite GetImage(string collectionName, string imageName)
{
var image = TryGetImage(collectionName, imageName);
if (image == null)
throw new ArgumentException($"Sprite `{collectionName}/{imageName}` was not found.");
return image;
}
public static Sprite TryGetImage(string collectionName, string imageName)
{
if (string.IsNullOrEmpty(collectionName))
return null;
@@ -153,10 +162,7 @@ namespace OpenRA.Graphics
return sprite;
if (!collections.TryGetValue(collectionName, out var collection))
{
Log.Write("debug", "Could not find collection '{0}'", collectionName);
return null;
}
if (!collection.Regions.TryGetValue(imageName, out var mi))
return null;
@@ -176,6 +182,15 @@ namespace OpenRA.Graphics
}
public static Sprite[] GetPanelImages(string collectionName)
{
var panel = TryGetPanelImages(collectionName);
if (panel == null)
throw new ArgumentException($"Panel `{collectionName}` was not found.");
return panel;
}
public static Sprite[] TryGetPanelImages(string collectionName)
{
if (string.IsNullOrEmpty(collectionName))
return null;
@@ -185,17 +200,14 @@ namespace OpenRA.Graphics
return cachedSprites;
if (!collections.TryGetValue(collectionName, out var collection))
{
Log.Write("debug", "Could not find collection '{0}'", collectionName);
return null;
}
Sprite[] sprites;
if (collection.PanelRegion != null)
{
if (collection.PanelRegion.Length != 8)
{
Log.Write("debug", "Collection '{0}' does not define a valid PanelRegion", collectionName);
Log.Write("debug", $"Collection '{collectionName}' does not define a valid PanelRegion");
return null;
}
@@ -222,18 +234,23 @@ namespace OpenRA.Graphics
}
else
{
// PERF: We don't need to search for images if there are no definitions.
// PERF: It's more efficient to send an empty array rather than an array of 9 nulls.
if (!collection.Regions.Any())
return Array.Empty<Sprite>();
// Support manual definitions for unusual dialog layouts
sprites = new[]
{
GetImage(collectionName, "corner-tl"),
GetImage(collectionName, "border-t"),
GetImage(collectionName, "corner-tr"),
GetImage(collectionName, "border-l"),
GetImage(collectionName, "background"),
GetImage(collectionName, "border-r"),
GetImage(collectionName, "corner-bl"),
GetImage(collectionName, "border-b"),
GetImage(collectionName, "corner-br")
TryGetImage(collectionName, "corner-tl"),
TryGetImage(collectionName, "border-t"),
TryGetImage(collectionName, "corner-tr"),
TryGetImage(collectionName, "border-l"),
TryGetImage(collectionName, "background"),
TryGetImage(collectionName, "border-r"),
TryGetImage(collectionName, "corner-bl"),
TryGetImage(collectionName, "border-b"),
TryGetImage(collectionName, "corner-br")
};
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -35,7 +35,7 @@ namespace OpenRA.Graphics
Cursor cursor;
bool isLocked = false;
int2 lockedPosition;
bool hardwareCursorsDisabled = false;
readonly bool hardwareCursorsDisabled = false;
bool hardwareCursorsDoubled = false;
public CursorManager(CursorProvider cursorProvider)

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -17,15 +17,15 @@ namespace OpenRA.Graphics
{
public sealed class HardwarePalette : IDisposable
{
public ITexture Texture { get; private set; }
public ITexture ColorShifts { get; private set; }
public ITexture Texture { get; }
public ITexture ColorShifts { get; }
public int Height { get; private set; }
readonly Dictionary<string, ImmutablePalette> palettes = new Dictionary<string, ImmutablePalette>();
readonly Dictionary<string, MutablePalette> mutablePalettes = new Dictionary<string, MutablePalette>();
readonly Dictionary<string, int> indices = new Dictionary<string, int>();
byte[] buffer = new byte[0];
float[] colorShiftBuffer = new float[0];
byte[] buffer = Array.Empty<byte>();
float[] colorShiftBuffer = Array.Empty<float>();
public HardwarePalette()
{

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -84,6 +84,7 @@ namespace OpenRA.Graphics
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "IDE0060:Remove unused parameter", Justification = "Load game API")]
public PlaceholderModelSequenceLoader(ModData modData) { }
public IModelCache CacheModels(IReadOnlyFileSystem fileSystem, ModData modData, IReadOnlyDictionary<string, MiniYamlNode> modelDefinitions)

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -65,7 +65,7 @@ namespace OpenRA.Graphics
shader.SetTexture("Palette", palette);
}
public void SetViewportParams(Size screen, int2 scroll)
public void SetViewportParams()
{
var a = 2f / renderer.SheetSize;
var view = new[]

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -42,7 +42,7 @@ namespace OpenRA.Graphics
class ReadOnlyPalette : IPalette
{
IPalette palette;
readonly IPalette palette;
public ReadOnlyPalette(IPalette palette) { this.palette = palette; }
public uint this[int index] => palette[index];
@@ -108,7 +108,7 @@ namespace OpenRA.Graphics
public ImmutablePalette(IPalette p)
{
for (int i = 0; i < Palette.Size; i++)
for (var i = 0; i < Palette.Size; i++)
colors[i] = p[i];
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -84,6 +84,7 @@ namespace OpenRA
public interface IGraphicsContext : IDisposable
{
IVertexBuffer<Vertex> CreateVertexBuffer(int size);
Vertex[] CreateVertices(int size);
ITexture CreateTexture();
IFrameBuffer CreateFrameBuffer(Size s);
IFrameBuffer CreateFrameBuffer(Size s, Color clearColor);
@@ -105,6 +106,11 @@ namespace OpenRA
{
void Bind();
void SetData(T[] vertices, int length);
/// <summary>
/// Upon return `vertices` may reference another array object of at least the same size - containing random values.
/// </summary>
void SetData(ref T[] vertices, int length);
void SetData(T[] vertices, int offset, int start, int length);
}
@@ -124,7 +130,6 @@ namespace OpenRA
public interface ITexture : IDisposable
{
void SetData(uint[,] colors);
void SetData(byte[] colors, int width, int height);
void SetFloatData(float[] data, int width, int height);
byte[] GetData();

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -10,7 +10,6 @@
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Primitives;

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -261,7 +261,7 @@ namespace OpenRA.Graphics
return new Vertex(xyz, cr, cg, cb, ca, 0, 0);
}
public void FillEllipse(in float3 tl, in float3 br, Color color, int vertices = 32, BlendMode blendMode = BlendMode.Alpha)
public void FillEllipse(in float3 tl, in float3 br, Color color, BlendMode blendMode = BlendMode.Alpha)
{
// TODO: Create an ellipse polygon instead
var a = (br.X - tl.X) / 2;

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -22,28 +22,28 @@ namespace OpenRA.Graphics
this.parent = parent;
}
public void DrawSprite(Sprite s, in float3 location, in float3 scale)
public void DrawSprite(Sprite s, in float3 location, in float3 scale, float rotation = 0f)
{
if (s.Channel != TextureChannel.RGBA)
throw new InvalidOperationException("DrawRGBASprite requires a RGBA sprite.");
parent.DrawSprite(s, 0, location, scale);
parent.DrawSprite(s, 0, location, scale, rotation);
}
public void DrawSprite(Sprite s, in float3 location, float scale = 1f)
public void DrawSprite(Sprite s, in float3 location, float scale = 1f, float rotation = 0f)
{
if (s.Channel != TextureChannel.RGBA)
throw new InvalidOperationException("DrawRGBASprite requires a RGBA sprite.");
parent.DrawSprite(s, 0, location, scale);
parent.DrawSprite(s, 0, location, scale, rotation);
}
public void DrawSprite(Sprite s, in float3 location, float scale, in float3 tint, float alpha)
public void DrawSprite(Sprite s, in float3 location, float scale, in float3 tint, float alpha, float rotation = 0f)
{
if (s.Channel != TextureChannel.RGBA)
throw new InvalidOperationException("DrawRGBASprite requires a RGBA sprite.");
parent.DrawSprite(s, 0, location, scale, tint, alpha);
parent.DrawSprite(s, 0, location, scale, tint, alpha, rotation);
}
public void DrawSprite(Sprite s, in float3 a, in float3 b, in float3 c, in float3 d, in float3 tint, float alpha)

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -26,6 +26,7 @@ namespace OpenRA.Graphics
int Length { get; }
int Stride { get; }
int Facings { get; }
int InterpolatedFacings { get; }
int Tick { get; }
int ZOffset { get; }
int ShadowStart { get; }
@@ -37,6 +38,7 @@ namespace OpenRA.Graphics
Sprite GetSprite(int frame);
Sprite GetSprite(int frame, WAngle facing);
(Sprite, WAngle) GetSpriteWithRotation(int frame, WAngle facing);
Sprite GetShadow(int frame, WAngle facing);
float GetAlpha(int frame);
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -17,7 +17,7 @@ namespace OpenRA.Graphics
{
public sealed class SpriteFont : IDisposable
{
public int TopOffset { get; private set; }
public int TopOffset { get; }
readonly int size;
readonly SheetBuilder builder;
readonly IFont font;

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -9,6 +9,7 @@
*/
#endregion
using System;
using System.Collections.Generic;
using OpenRA.Primitives;
@@ -16,7 +17,7 @@ namespace OpenRA.Graphics
{
public class SpriteRenderable : IPalettedRenderable, IModifyableRenderable, IFinalizedRenderable
{
public static readonly IEnumerable<IRenderable> None = new IRenderable[0];
public static readonly IEnumerable<IRenderable> None = Array.Empty<IRenderable>();
readonly Sprite sprite;
readonly WPos pos;
@@ -24,12 +25,14 @@ namespace OpenRA.Graphics
readonly int zOffset;
readonly PaletteReference palette;
readonly float scale;
readonly WAngle rotation = WAngle.Zero;
readonly float3 tint;
readonly TintModifiers tintModifiers;
readonly float alpha;
readonly bool isDecoration;
public SpriteRenderable(Sprite sprite, WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale, float alpha, float3 tint, TintModifiers tintModifiers, bool isDecoration)
public SpriteRenderable(Sprite sprite, WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale, float alpha,
float3 tint, TintModifiers tintModifiers, bool isDecoration, WAngle rotation)
{
this.sprite = sprite;
this.pos = pos;
@@ -37,6 +40,7 @@ namespace OpenRA.Graphics
this.zOffset = zOffset;
this.palette = palette;
this.scale = scale;
this.rotation = rotation;
this.tint = tint;
this.isDecoration = isDecoration;
this.tintModifiers = tintModifiers;
@@ -49,6 +53,10 @@ namespace OpenRA.Graphics
this.palette = null;
}
public SpriteRenderable(Sprite sprite, WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale, float alpha,
float3 tint, TintModifiers tintModifiers, bool isDecoration)
: this(sprite, pos, offset, zOffset, palette, scale, alpha, tint, tintModifiers, isDecoration, WAngle.Zero) { }
public WPos Pos => pos + offset;
public WVec Offset => offset;
public PaletteReference Palette => palette;
@@ -59,19 +67,34 @@ namespace OpenRA.Graphics
public float3 Tint => tint;
public TintModifiers TintModifiers => tintModifiers;
public IPalettedRenderable WithPalette(PaletteReference newPalette) { return new SpriteRenderable(sprite, pos, offset, zOffset, newPalette, scale, alpha, tint, tintModifiers, isDecoration); }
public IRenderable WithZOffset(int newOffset) { return new SpriteRenderable(sprite, pos, offset, newOffset, palette, scale, alpha, tint, tintModifiers, isDecoration); }
public IRenderable OffsetBy(in WVec vec) { return new SpriteRenderable(sprite, pos + vec, offset, zOffset, palette, scale, alpha, tint, tintModifiers, isDecoration); }
public IRenderable AsDecoration() { return new SpriteRenderable(sprite, pos, offset, zOffset, palette, scale, alpha, tint, tintModifiers, true); }
public IPalettedRenderable WithPalette(PaletteReference newPalette)
{
return new SpriteRenderable(sprite, pos, offset, zOffset, newPalette, scale, alpha, tint, tintModifiers, isDecoration, rotation);
}
public IRenderable WithZOffset(int newOffset)
{
return new SpriteRenderable(sprite, pos, offset, newOffset, palette, scale, alpha, tint, tintModifiers, isDecoration, rotation);
}
public IRenderable OffsetBy(in WVec vec)
{
return new SpriteRenderable(sprite, pos + vec, offset, zOffset, palette, scale, alpha, tint, tintModifiers, isDecoration, rotation);
}
public IRenderable AsDecoration()
{
return new SpriteRenderable(sprite, pos, offset, zOffset, palette, scale, alpha, tint, tintModifiers, true, rotation);
}
public IModifyableRenderable WithAlpha(float newAlpha)
{
return new SpriteRenderable(sprite, pos, offset, zOffset, palette, scale, newAlpha, tint, tintModifiers, isDecoration);
return new SpriteRenderable(sprite, pos, offset, zOffset, palette, scale, newAlpha, tint, tintModifiers, isDecoration, rotation);
}
public IModifyableRenderable WithTint(in float3 newTint, TintModifiers newTintModifiers)
{
return new SpriteRenderable(sprite, pos, offset, zOffset, palette, scale, alpha, newTint, newTintModifiers, isDecoration);
return new SpriteRenderable(sprite, pos, offset, zOffset, palette, scale, alpha, newTint, newTintModifiers, isDecoration, rotation);
}
float3 ScreenPosition(WorldRenderer wr)
@@ -93,7 +116,7 @@ namespace OpenRA.Graphics
if ((tintModifiers & TintModifiers.ReplaceColor) != 0)
a *= -1;
wsr.DrawSprite(sprite, palette, ScreenPosition(wr), scale, t, a);
wsr.DrawSprite(sprite, palette, ScreenPosition(wr), scale, t, a, rotation.RendererRadians());
}
public void RenderDebugGeometry(WorldRenderer wr)
@@ -101,13 +124,16 @@ namespace OpenRA.Graphics
var pos = ScreenPosition(wr) + sprite.Offset;
var tl = wr.Viewport.WorldToViewPx(pos);
var br = wr.Viewport.WorldToViewPx(pos + sprite.Size);
Game.Renderer.RgbaColorRenderer.DrawRect(tl, br, 1, Color.Red);
if (rotation == WAngle.Zero)
Game.Renderer.RgbaColorRenderer.DrawRect(tl, br, 1, Color.Red);
else
Game.Renderer.RgbaColorRenderer.DrawPolygon(Util.RotateQuad(tl, br - tl, rotation.RendererRadians()), 1, Color.Red);
}
public Rectangle ScreenBounds(WorldRenderer wr)
{
var screenOffset = ScreenPosition(wr) + sprite.Offset;
return new Rectangle((int)screenOffset.X, (int)screenOffset.Y, (int)sprite.Size.X, (int)sprite.Size.Y);
return Util.BoundingRectangle(screenOffset, sprite.Size, rotation.RendererRadians());
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -11,7 +11,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Primitives;
namespace OpenRA.Graphics
@@ -24,7 +23,7 @@ namespace OpenRA.Graphics
readonly Renderer renderer;
readonly IShader shader;
readonly Vertex[] vertices;
Vertex[] vertices;
readonly Sheet[] sheets = new Sheet[SheetCount];
BlendMode currentBlend = BlendMode.Alpha;
@@ -35,7 +34,7 @@ namespace OpenRA.Graphics
{
this.renderer = renderer;
this.shader = shader;
vertices = new Vertex[renderer.TempBufferSize];
vertices = renderer.Context.CreateVertices(renderer.TempBufferSize);
}
public void Flush()
@@ -50,7 +49,9 @@ namespace OpenRA.Graphics
renderer.Context.SetBlendMode(currentBlend);
shader.PrepareRender();
renderer.DrawBatch(vertices, nv, PrimitiveType.TriangleList);
// PERF: The renderer may choose to replace vertices with a different temporary buffer.
renderer.DrawBatch(ref vertices, nv, PrimitiveType.TriangleList);
renderer.Context.SetBlendMode(BlendMode.None);
nv = 0;
@@ -127,35 +128,40 @@ namespace OpenRA.Graphics
return pal.TextureIndex;
}
internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 location, in float3 scale)
internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 location, in float3 scale, float rotation = 0f)
{
var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, location + scale * s.Offset, s, samplers, paletteTextureIndex, nv, scale * s.Size, float3.Ones, 1f);
Util.FastCreateQuad(vertices, location + scale * s.Offset, s, samplers, paletteTextureIndex, nv, scale * s.Size, float3.Ones,
1f, rotation);
nv += 6;
}
internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 location, float scale)
internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 location, float scale, float rotation = 0f)
{
var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, location + scale * s.Offset, s, samplers, paletteTextureIndex, nv, scale * s.Size, float3.Ones, 1f);
Util.FastCreateQuad(vertices, location + scale * s.Offset, s, samplers, paletteTextureIndex, nv, scale * s.Size, float3.Ones,
1f, rotation);
nv += 6;
}
public void DrawSprite(Sprite s, PaletteReference pal, in float3 location, float scale = 1f)
public void DrawSprite(Sprite s, PaletteReference pal, in float3 location, float scale = 1f, float rotation = 0f)
{
DrawSprite(s, ResolveTextureIndex(s, pal), location, scale);
DrawSprite(s, ResolveTextureIndex(s, pal), location, scale, rotation);
}
internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 location, float scale, in float3 tint, float alpha)
internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 location, float scale, in float3 tint, float alpha,
float rotation = 0f)
{
var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, location + scale * s.Offset, s, samplers, paletteTextureIndex, nv, scale * s.Size, tint, alpha);
Util.FastCreateQuad(vertices, location + scale * s.Offset, s, samplers, paletteTextureIndex, nv, scale * s.Size, tint, alpha,
rotation);
nv += 6;
}
public void DrawSprite(Sprite s, PaletteReference pal, in float3 location, float scale, in float3 tint, float alpha)
public void DrawSprite(Sprite s, PaletteReference pal, in float3 location, float scale, in float3 tint, float alpha,
float rotation = 0f)
{
DrawSprite(s, ResolveTextureIndex(s, pal), location, scale, tint, alpha);
DrawSprite(s, ResolveTextureIndex(s, pal), location, scale, tint, alpha, rotation);
}
internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 a, in float3 b, in float3 c, in float3 d, in float3 tint, float alpha)

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -22,7 +22,7 @@ namespace OpenRA.Graphics
readonly int width;
readonly int markerSize;
public TargetLineRenderable(IEnumerable<WPos> waypoints, Color color, int width = 1, int markerSize = 1)
public TargetLineRenderable(IEnumerable<WPos> waypoints, Color color, int width, int markerSize)
{
this.waypoints = waypoints;
this.color = color;
@@ -34,13 +34,13 @@ namespace OpenRA.Graphics
public int ZOffset => 0;
public bool IsDecoration => true;
public IRenderable WithZOffset(int newOffset) { return new TargetLineRenderable(waypoints, color); }
public IRenderable WithZOffset(int newOffset) { return this; }
public IRenderable OffsetBy(in WVec vec)
{
// Lambdas can't use 'in' variables, so capture a copy for later
var offset = vec;
return new TargetLineRenderable(waypoints.Select(w => w + offset), color);
return new TargetLineRenderable(waypoints.Select(w => w + offset), color, width, markerSize);
}
public IRenderable AsDecoration() { return this; }
@@ -56,14 +56,14 @@ namespace OpenRA.Graphics
foreach (var b in waypoints.Skip(1).Select(pos => wr.Viewport.WorldToViewPx(wr.Screen3DPosition(pos))))
{
Game.Renderer.RgbaColorRenderer.DrawLine(a, b, width, color);
DrawTargetMarker(wr, color, b, markerSize);
DrawTargetMarker(color, b, markerSize);
a = b;
}
DrawTargetMarker(wr, color, first);
DrawTargetMarker(color, first);
}
public static void DrawTargetMarker(WorldRenderer wr, Color color, int2 screenPos, int size = 1)
public static void DrawTargetMarker(Color color, int2 screenPos, int size = 1)
{
var offset = new int2(size, size);
var tl = screenPos - offset;

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -12,7 +12,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -22,8 +22,9 @@ namespace OpenRA.Graphics
readonly PaletteReference palette;
readonly float scale;
readonly float alpha;
readonly float rotation = 0f;
public UISpriteRenderable(Sprite sprite, WPos effectiveWorldPos, int2 screenPos, int zOffset, PaletteReference palette, float scale = 1f, float alpha = 1f)
public UISpriteRenderable(Sprite sprite, WPos effectiveWorldPos, int2 screenPos, int zOffset, PaletteReference palette, float scale = 1f, float alpha = 1f, float rotation = 0f)
{
this.sprite = sprite;
this.effectiveWorldPos = effectiveWorldPos;
@@ -32,6 +33,7 @@ namespace OpenRA.Graphics
this.palette = palette;
this.scale = scale;
this.alpha = alpha;
this.rotation = rotation;
// PERF: Remove useless palette assignments for RGBA sprites
// HACK: This is working around the fact that palettes are defined on traits rather than sequences
@@ -48,7 +50,7 @@ namespace OpenRA.Graphics
public PaletteReference Palette => palette;
public int ZOffset => zOffset;
public IPalettedRenderable WithPalette(PaletteReference newPalette) { return new UISpriteRenderable(sprite, effectiveWorldPos, screenPos, zOffset, newPalette, scale, alpha); }
public IPalettedRenderable WithPalette(PaletteReference newPalette) { return new UISpriteRenderable(sprite, effectiveWorldPos, screenPos, zOffset, newPalette, scale, alpha, rotation); }
public IRenderable WithZOffset(int newOffset) { return this; }
public IRenderable OffsetBy(in WVec vec) { return this; }
public IRenderable AsDecoration() { return this; }
@@ -56,19 +58,22 @@ namespace OpenRA.Graphics
public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; }
public void Render(WorldRenderer wr)
{
Game.Renderer.SpriteRenderer.DrawSprite(sprite, palette, screenPos, scale, float3.Ones, alpha);
Game.Renderer.SpriteRenderer.DrawSprite(sprite, palette, screenPos, scale, float3.Ones, alpha, rotation);
}
public void RenderDebugGeometry(WorldRenderer wr)
{
var offset = screenPos + sprite.Offset.XY;
Game.Renderer.RgbaColorRenderer.DrawRect(offset, offset + sprite.Size.XY, 1, Color.Red);
if (rotation == 0f)
Game.Renderer.RgbaColorRenderer.DrawRect(offset, offset + sprite.Size.XY, 1, Color.Red);
else
Game.Renderer.RgbaColorRenderer.DrawPolygon(Util.RotateQuad(offset, sprite.Size, rotation), 1, Color.Red);
}
public Rectangle ScreenBounds(WorldRenderer wr)
{
var offset = screenPos + sprite.Offset;
return new Rectangle((int)offset.X, (int)offset.Y, (int)sprite.Size.X, (int)sprite.Size.Y);
return Util.BoundingRectangle(offset, sprite.Size, rotation);
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -20,12 +20,44 @@ namespace OpenRA.Graphics
// yes, our channel order is nuts.
static readonly int[] ChannelMasks = { 2, 1, 0, 3 };
public static void FastCreateQuad(Vertex[] vertices, in float3 o, Sprite r, int2 samplers, float paletteTextureIndex, int nv, in float3 size, in float3 tint, float alpha)
public static void FastCreateQuad(Vertex[] vertices, in float3 o, Sprite r, int2 samplers, float paletteTextureIndex, int nv,
in float3 size, in float3 tint, float alpha, float rotation = 0f)
{
var b = new float3(o.X + size.X, o.Y, o.Z);
var c = new float3(o.X + size.X, o.Y + size.Y, o.Z + size.Z);
var d = new float3(o.X, o.Y + size.Y, o.Z + size.Z);
FastCreateQuad(vertices, o, b, c, d, r, samplers, paletteTextureIndex, tint, alpha, nv);
float3 a, b, c, d;
// Rotate sprite if rotation angle is not equal to 0
if (rotation != 0f)
{
var center = o + 0.5f * size;
var angleSin = (float)Math.Sin(-rotation);
var angleCos = (float)Math.Cos(-rotation);
// Rotated offset for +/- x with +/- y
var ra = 0.5f * new float3(
size.X * angleCos - size.Y * angleSin,
size.X * angleSin + size.Y * angleCos,
(size.X * angleSin + size.Y * angleCos) * size.Z / size.Y);
// Rotated offset for +/- x with -/+ y
var rb = 0.5f * new float3(
size.X * angleCos + size.Y * angleSin,
size.X * angleSin - size.Y * angleCos,
(size.X * angleSin - size.Y * angleCos) * size.Z / size.Y);
a = center - ra;
b = center + rb;
c = center + ra;
d = center - rb;
}
else
{
a = o;
b = new float3(o.X + size.X, o.Y, o.Z);
c = new float3(o.X + size.X, o.Y + size.Y, o.Z + size.Z);
d = new float3(o.X, o.Y + size.Y, o.Z + size.Z);
}
FastCreateQuad(vertices, a, b, c, d, r, samplers, paletteTextureIndex, tint, alpha, nv);
}
public static void FastCreateQuad(Vertex[] vertices,
@@ -191,6 +223,69 @@ namespace OpenRA.Graphics
}
}
/// <summary>Rotates a quad about its center in the x-y plane.</summary>
/// <param name="tl">The top left vertex of the quad</param>
/// <param name="size">A float3 containing the X, Y, and Z lengths of the quad</param>
/// <param name="rotation">The number of radians to rotate by</param>
/// <returns>An array of four vertices representing the rotated quad (top-left, top-right, bottom-right, bottom-left)</returns>
public static float3[] RotateQuad(float3 tl, float3 size, float rotation)
{
var center = tl + 0.5f * size;
var angleSin = (float)Math.Sin(-rotation);
var angleCos = (float)Math.Cos(-rotation);
// Rotated offset for +/- x with +/- y
var ra = 0.5f * new float3(
size.X * angleCos - size.Y * angleSin,
size.X * angleSin + size.Y * angleCos,
(size.X * angleSin + size.Y * angleCos) * size.Z / size.Y);
// Rotated offset for +/- x with -/+ y
var rb = 0.5f * new float3(
size.X * angleCos + size.Y * angleSin,
size.X * angleSin - size.Y * angleCos,
(size.X * angleSin - size.Y * angleCos) * size.Z / size.Y);
return new float3[]
{
center - ra,
center + rb,
center + ra,
center - rb
};
}
/// <summary>
/// Returns the bounds of an object. Used for determining which objects need to be rendered on screen, and which do not.
/// </summary>
/// <param name="offset">The top left vertex of the object</param>
/// <param name="size">A float 3 containing the X, Y, and Z lengths of the object</param>
/// <param name="rotation">The angle to rotate the object by (use 0f if there is no rotation)</param>
public static Rectangle BoundingRectangle(float3 offset, float3 size, float rotation)
{
if (rotation == 0f)
return new Rectangle((int)offset.X, (int)offset.Y, (int)size.X, (int)size.Y);
var rotatedQuad = Util.RotateQuad(offset, size, rotation);
var minX = rotatedQuad[0].X;
var maxX = rotatedQuad[0].X;
var minY = rotatedQuad[0].Y;
var maxY = rotatedQuad[0].Y;
for (var i = 1; i < rotatedQuad.Length; i++)
{
minX = Math.Min(rotatedQuad[i].X, minX);
maxX = Math.Max(rotatedQuad[i].X, maxX);
minY = Math.Min(rotatedQuad[i].Y, minY);
maxY = Math.Max(rotatedQuad[i].Y, maxY);
}
return new Rectangle(
(int)minX,
(int)minY,
(int)Math.Ceiling(maxX) - (int)minX,
(int)Math.Ceiling(maxY) - (int)minY);
}
public static Color PremultiplyAlpha(Color c)
{
if (c.A == byte.MaxValue)

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -9,21 +9,20 @@
*/
#endregion
using System;
using OpenRA.FileSystem;
using OpenRA.Primitives;
namespace OpenRA.Video
{
public interface IVideo
{
ushort Frames { get; }
ushort FrameCount { get; }
byte Framerate { get; }
ushort Width { get; }
ushort Height { get; }
uint[,] FrameData { get; }
int CurrentFrame { get; }
/// <summary>
/// Current frame color data in 32-bit BGRA.
/// </summary>
byte[] CurrentFrameData { get; }
int CurrentFrameIndex { get; }
void AdvanceFrame();
bool HasAudio { get; }

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -15,15 +15,15 @@ namespace OpenRA.Video
{
public interface IVideoLoader
{
bool TryParseVideo(Stream s, out IVideo video);
bool TryParseVideo(Stream s, bool useFramePadding, out IVideo video);
}
public static class VideoLoader
{
public static IVideo GetVideo(Stream stream, IVideoLoader[] loaders)
public static IVideo GetVideo(Stream stream, bool useFramePadding, IVideoLoader[] loaders)
{
foreach (var loader in loaders)
if (loader.TryParseVideo(stream, out var video))
if (loader.TryParseVideo(stream, useFramePadding, out var video))
return video;
return null;

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -238,7 +238,7 @@ namespace OpenRA.Graphics
if (unlockMinZoom)
{
// Specators and the map editor support zooming out by an extra factor of two.
// Spectators and the map editor support zooming out by an extra factor of two.
// TODO: Allow zooming out until the full map is visible
// We need to improve our viewport scroll handling to center the map as we zoom out
// before this will work well enough to enable

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -26,7 +26,7 @@ namespace OpenRA.Graphics
public readonly Size TileSize;
public readonly int TileScale;
public readonly World World;
public Viewport Viewport { get; private set; }
public Viewport Viewport { get; }
public readonly ITerrainLighting TerrainLighting;
public event Action PaletteInvalidated = null;
@@ -151,14 +151,14 @@ namespace OpenRA.Graphics
// PERF: Avoid LINQ.
void GenerateOverlayRenderables()
{
foreach (var a in World.ActorsWithTrait<IRenderAboveShroud>())
World.ApplyToActorsWithTrait<IRenderAboveShroud>((actor, trait) =>
{
if (!a.Actor.IsInWorld || a.Actor.Disposed || (a.Trait.SpatiallyPartitionable && !onScreenActors.Contains(a.Actor)))
continue;
if (!actor.IsInWorld || actor.Disposed || (trait.SpatiallyPartitionable && !onScreenActors.Contains(actor)))
return;
foreach (var renderable in a.Trait.RenderAboveShroud(a.Actor, this))
foreach (var renderable in trait.RenderAboveShroud(actor, this))
preparedOverlayRenderables.Add(renderable.PrepareRender(this));
}
});
foreach (var a in World.Selection.Actors)
{
@@ -177,8 +177,7 @@ namespace OpenRA.Graphics
foreach (var e in World.Effects)
{
var ea = e as IEffectAboveShroud;
if (ea == null)
if (!(e is IEffectAboveShroud ea))
continue;
foreach (var renderable in ea.RenderAboveShroud(this))
@@ -193,14 +192,14 @@ namespace OpenRA.Graphics
// PERF: Avoid LINQ.
void GenerateAnnotationRenderables()
{
foreach (var a in World.ActorsWithTrait<IRenderAnnotations>())
World.ApplyToActorsWithTrait<IRenderAnnotations>((actor, trait) =>
{
if (!a.Actor.IsInWorld || a.Actor.Disposed || (a.Trait.SpatiallyPartitionable && !onScreenActors.Contains(a.Actor)))
continue;
if (!actor.IsInWorld || actor.Disposed || (trait.SpatiallyPartitionable && !onScreenActors.Contains(actor)))
return;
foreach (var renderAnnotation in a.Trait.RenderAnnotations(a.Actor, this))
foreach (var renderAnnotation in trait.RenderAnnotations(actor, this))
preparedAnnotationRenderables.Add(renderAnnotation.PrepareRender(this));
}
});
foreach (var a in World.Selection.Actors)
{
@@ -219,8 +218,7 @@ namespace OpenRA.Graphics
foreach (var e in World.Effects)
{
var ea = e as IEffectAnnotation;
if (ea == null)
if (!(e is IEffectAnnotation ea))
continue;
foreach (var renderAnnotation in ea.RenderAnnotation(this))
@@ -272,15 +270,16 @@ namespace OpenRA.Graphics
if (enableDepthBuffer)
Game.Renderer.ClearDepthBuffer();
foreach (var a in World.ActorsWithTrait<IRenderAboveWorld>())
if (a.Actor.IsInWorld && !a.Actor.Disposed)
a.Trait.RenderAboveWorld(a.Actor, this);
World.ApplyToActorsWithTrait<IRenderAboveWorld>((actor, trait) =>
{
if (actor.IsInWorld && !actor.Disposed)
trait.RenderAboveWorld(actor, this);
});
if (enableDepthBuffer)
Game.Renderer.ClearDepthBuffer();
foreach (var a in World.ActorsWithTrait<IRenderShroud>())
a.Trait.RenderShroud(this);
World.ApplyToActorsWithTrait<IRenderShroud>((actor, trait) => trait.RenderShroud(this));
if (enableDepthBuffer)
Game.Renderer.Context.DisableDepthBuffer();

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -20,6 +20,8 @@ namespace OpenRA
public readonly Hotkey Default = Hotkey.Invalid;
public readonly string Description = "";
public readonly HashSet<string> Types = new HashSet<string>();
public readonly HashSet<string> Contexts = new HashSet<string>();
public readonly bool Readonly = false;
public bool HasDuplicates { get; internal set; }
public HotkeyDefinition(string name, MiniYaml node)
@@ -36,6 +38,22 @@ namespace OpenRA
var typesNode = node.Nodes.FirstOrDefault(n => n.Key == "Types");
if (typesNode != null)
Types = FieldLoader.GetValue<HashSet<string>>("Types", typesNode.Value.Value);
var contextsNode = node.Nodes.FirstOrDefault(n => n.Key == "Contexts");
if (contextsNode != null)
Contexts = FieldLoader.GetValue<HashSet<string>>("Contexts", contextsNode.Value.Value);
var platformNode = node.Nodes.FirstOrDefault(n => n.Key == "Platform");
if (platformNode != null)
{
var platformOverride = platformNode.Value.Nodes.FirstOrDefault(n => n.Key == Platform.CurrentPlatform.ToString());
if (platformOverride != null)
Default = FieldLoader.GetValue<Hotkey>("value", platformOverride.Value.Value);
}
var readonlyNode = node.Nodes.FirstOrDefault(n => n.Key == "Readonly");
if (readonlyNode != null)
Readonly = FieldLoader.GetValue<bool>("Readonly", readonlyNode.Value.Value);
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -35,12 +35,12 @@ namespace OpenRA
foreach (var kv in settings)
{
if (definitions.ContainsKey(kv.Key))
if (definitions.ContainsKey(kv.Key) && !definitions[kv.Key].Readonly)
keys[kv.Key] = kv.Value;
}
foreach (var hd in definitions)
hd.Value.HasDuplicates = GetFirstDuplicate(hd.Value.Name, this[hd.Value.Name].GetValue(), hd.Value) != null;
hd.Value.HasDuplicates = GetFirstDuplicate(hd.Value, this[hd.Value.Name].GetValue()) != null;
}
internal Func<Hotkey> GetHotkeyReference(string name)
@@ -61,6 +61,9 @@ namespace OpenRA
if (!definitions.TryGetValue(name, out var definition))
return;
if (definition.Readonly)
return;
keys[name] = value;
if (value != definition.Default)
settings[name] = value;
@@ -68,7 +71,7 @@ namespace OpenRA
settings.Remove(name);
var hadDuplicates = definition.HasDuplicates;
definition.HasDuplicates = GetFirstDuplicate(definition.Name, this[definition.Name].GetValue(), definition) != null;
definition.HasDuplicates = GetFirstDuplicate(definition, this[definition.Name].GetValue()) != null;
if (hadDuplicates || definition.HasDuplicates)
{
@@ -77,19 +80,22 @@ namespace OpenRA
if (hd.Value == definition)
continue;
hd.Value.HasDuplicates = GetFirstDuplicate(hd.Value.Name, this[hd.Value.Name].GetValue(), hd.Value) != null;
hd.Value.HasDuplicates = GetFirstDuplicate(hd.Value, this[hd.Value.Name].GetValue()) != null;
}
}
}
public HotkeyDefinition GetFirstDuplicate(string name, Hotkey value, HotkeyDefinition definition)
public HotkeyDefinition GetFirstDuplicate(HotkeyDefinition definition, Hotkey value)
{
if (definition == null)
return null;
foreach (var kv in keys)
{
if (kv.Key == name)
if (kv.Key == definition.Name)
continue;
if (kv.Value == value && definitions[kv.Key].Types.Overlaps(definition.Types))
if (kv.Value == value && definitions[kv.Key].Contexts.Overlaps(definition.Contexts))
return definitions[kv.Key];
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -26,7 +26,7 @@ namespace OpenRA
var total = response.Content.Headers.ContentLength ?? -1;
var canReportProgress = total > 0;
#if !MONO
#if NET5_0_OR_GREATER
using (var contentStream = await response.Content.ReadAsStreamAsync(token))
#else
using (var contentStream = await response.Content.ReadAsStreamAsync())

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -15,21 +15,18 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using OpenRA.FileSystem;
using OpenRA.Graphics;
namespace OpenRA
{
public class InstalledMods : IReadOnlyDictionary<string, Manifest>
{
readonly Dictionary<string, Manifest> mods;
readonly SheetBuilder sheetBuilder;
/// <summary>Initializes the collection of locally installed mods.</summary>
/// <param name="searchPaths">Filesystem paths to search for mod packages.</param>
/// <param name="explicitPaths">Filesystem paths to additional mod packages.</param>
public InstalledMods(IEnumerable<string> searchPaths, IEnumerable<string> explicitPaths)
{
sheetBuilder = new SheetBuilder(SheetType.BGRA, 256);
mods = GetInstalledMods(searchPaths, explicitPaths);
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -83,9 +83,9 @@ namespace OpenRA
var client = HttpClientFactory.Create();
var httpResponseMessage = await client.GetAsync(playerDatabase.Profile + Fingerprint);
var result = await httpResponseMessage.Content.ReadAsStringAsync();
var result = await httpResponseMessage.Content.ReadAsStreamAsync();
var yaml = MiniYaml.FromString(result).First();
var yaml = MiniYaml.FromStream(result).First();
if (yaml.Key == "Player")
{
innerData = FieldLoader.Load<PlayerProfile>(yaml.Value);
@@ -157,7 +157,7 @@ namespace OpenRA
}
innerState = LinkState.Uninitialized;
parameters = default(RSAParameters);
parameters = default;
innerFingerprint = null;
innerData = null;
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -79,18 +79,19 @@ namespace OpenRA
public readonly IReadOnlyDictionary<string, string> Packages;
public readonly IReadOnlyDictionary<string, string> MapFolders;
public readonly MiniYaml LoadScreen;
public readonly string DefaultOrderGenerator;
public readonly string[] SoundFormats = { };
public readonly string[] SpriteFormats = { };
public readonly string[] PackageFormats = { };
public readonly string[] VideoFormats = { };
public readonly string[] SoundFormats = Array.Empty<string>();
public readonly string[] SpriteFormats = Array.Empty<string>();
public readonly string[] PackageFormats = Array.Empty<string>();
public readonly string[] VideoFormats = Array.Empty<string>();
readonly string[] reservedModuleNames =
{
"Include", "Metadata", "Folders", "MapFolders", "Packages", "Rules",
"Sequences", "ModelSequences", "Cursors", "Chrome", "Assemblies", "ChromeLayout", "Weapons",
"Voices", "Notifications", "Music", "Translations", "TileSets", "ChromeMetrics", "Missions", "Hotkeys",
"ServerTraits", "LoadScreen", "SupportsMapsFrom", "SoundFormats", "SpriteFormats", "VideoFormats",
"ServerTraits", "LoadScreen", "DefaultOrderGenerator", "SupportsMapsFrom", "SoundFormats", "SpriteFormats", "VideoFormats",
"RequiresMods", "PackageFormats"
};
@@ -161,6 +162,9 @@ namespace OpenRA
MapCompatibility = compat.ToArray();
if (yaml.ContainsKey("DefaultOrderGenerator"))
DefaultOrderGenerator = yaml["DefaultOrderGenerator"].Value;
if (yaml.ContainsKey("PackageFormats"))
PackageFormats = FieldLoader.GetValue<string[]>("PackageFormats", yaml["PackageFormats"].Value);
@@ -205,10 +209,10 @@ namespace OpenRA
customDataLoaded = true;
}
static string[] YamlList(Dictionary<string, MiniYaml> yaml, string key, bool parsePaths = false)
static string[] YamlList(Dictionary<string, MiniYaml> yaml, string key)
{
if (!yaml.ContainsKey(key))
return new string[] { };
return Array.Empty<string>();
return yaml[key].ToDictionary().Keys.ToArray();
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -66,7 +66,7 @@ namespace OpenRA
{
var init = GetOrDefault<T>(info);
if (init == null)
throw new InvalidOperationException($"TypeDictionary does not contain instance of type `{typeof(T)}`");
throw new InvalidOperationException($"TypeDictionary does not contain instance of type `{typeof(T)}`");
return init;
}
@@ -140,7 +140,7 @@ namespace OpenRA
public abstract class ValueActorInit<T> : ActorInit
{
protected readonly T value;
readonly T value;
protected ValueActorInit(TraitInfo info, T value)
: base(info.InstanceName) { this.value = value; }
@@ -159,7 +159,7 @@ namespace OpenRA
public virtual void Initialize(T value)
{
var field = GetType().GetField(nameof(value), BindingFlags.NonPublic | BindingFlags.Instance);
var field = typeof(ValueActorInit<T>).GetField(nameof(value), BindingFlags.NonPublic | BindingFlags.Instance);
if (field != null)
field.SetValue(this, value);
}
@@ -226,7 +226,7 @@ namespace OpenRA
public class OwnerInit : ActorInit, ISingleInstanceInit
{
public readonly string InternalName;
protected readonly Player value;
readonly Player value;
public OwnerInit(Player value)
{
@@ -246,14 +246,14 @@ namespace OpenRA
public void Initialize(MiniYaml yaml)
{
var field = GetType().GetField(nameof(InternalName), BindingFlags.Public | BindingFlags.Instance);
var field = typeof(OwnerInit).GetField(nameof(InternalName), BindingFlags.Public | BindingFlags.Instance);
if (field != null)
field.SetValue(this, yaml.Value);
}
public void Initialize(Player player)
{
var field = GetType().GetField(nameof(value), BindingFlags.NonPublic | BindingFlags.Instance);
var field = typeof(OwnerInit).GetField(nameof(value), BindingFlags.NonPublic | BindingFlags.Instance);
if (field != null)
field.SetValue(this, player);
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -25,7 +25,7 @@ namespace OpenRA
public class ActorReference : IEnumerable
{
public string Type;
Lazy<TypeDictionary> initDict;
readonly Lazy<TypeDictionary> initDict;
internal TypeDictionary InitDict => initDict.Value;
@@ -72,7 +72,7 @@ namespace OpenRA
var init = (ActorInit)FormatterServices.GetUninitializedObject(type);
if (initInstance.Length > 1)
type.GetField("InstanceName").SetValue(init, initInstance[1]);
type.GetField(nameof(ActorInit.InstanceName)).SetValue(init, initInstance[1]);
var loader = type.GetMethod("Initialize", new[] { typeof(MiniYaml) });
if (loader == null)
@@ -87,8 +87,7 @@ namespace OpenRA
var ret = new MiniYaml(Type);
foreach (var o in initDict.Value)
{
var init = o as ActorInit;
if (init == null || o is ISuppressInitExport)
if (!(o is ActorInit init) || o is ISuppressInitExport)
continue;
if (initFilter != null && !initFilter(init))

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -29,24 +29,27 @@ namespace OpenRA
{
if (CellEntryChanged != null)
throw new InvalidOperationException(
"Cannot copy values when there are listeners attached to the CellEntryChanged event.");
$"Cannot copy values when there are listeners attached to the {nameof(CellEntryChanged)} event.");
base.CopyValuesFrom(anotherLayer);
}
public static CellLayer<T> CreateInstance(Func<MPos, T> initialCellValueFactory, Size size, MapGridType mapGridType)
public override void Clear()
{
var cellLayer = new CellLayer<T>(mapGridType, size);
for (var v = 0; v < size.Height; v++)
{
for (var u = 0; u < size.Width; u++)
{
var mpos = new MPos(u, v);
cellLayer[mpos] = initialCellValueFactory(mpos);
}
}
if (CellEntryChanged != null)
throw new InvalidOperationException(
$"Cannot clear values when there are listeners attached to the {nameof(CellEntryChanged)} event.");
return cellLayer;
base.Clear();
}
public override void Clear(T clearValue)
{
if (CellEntryChanged != null)
throw new InvalidOperationException(
$"Cannot clear values when there are listeners attached to the {nameof(CellEntryChanged)} event.");
base.Clear(clearValue);
}
// Resolve an array index from cell coordinates
@@ -72,11 +75,11 @@ namespace OpenRA
/// <summary>Gets or sets the <see cref="CellLayer"/> using cell coordinates</summary>
public T this[CPos cell]
{
get => entries[Index(cell)];
get => Entries[Index(cell)];
set
{
entries[Index(cell)] = value;
Entries[Index(cell)] = value;
CellEntryChanged?.Invoke(cell);
}
@@ -85,16 +88,38 @@ namespace OpenRA
/// <summary>Gets or sets the layer contents using raw map coordinates (not CPos!)</summary>
public T this[MPos uv]
{
get => entries[Index(uv)];
get => Entries[Index(uv)];
set
{
entries[Index(uv)] = value;
Entries[Index(uv)] = value;
CellEntryChanged?.Invoke(uv.ToCPos(GridType));
}
}
public bool TryGetValue(CPos cell, out T value)
{
// .ToMPos() returns the same result if the X and Y coordinates
// are switched. X < Y is invalid in the RectangularIsometric coordinate system,
// so we pre-filter these to avoid returning the wrong result
if (GridType == MapGridType.RectangularIsometric && cell.X < cell.Y)
{
value = default;
return false;
}
var uv = cell.ToMPos(GridType);
if (Bounds.Contains(uv.U, uv.V))
{
value = Entries[Index(uv)];
return true;
}
value = default;
return false;
}
public bool Contains(CPos cell)
{
// .ToMPos() returns the same result if the X and Y coordinates
@@ -108,7 +133,7 @@ namespace OpenRA
public bool Contains(MPos uv)
{
return bounds.Contains(uv.U, uv.V);
return Bounds.Contains(uv.U, uv.V);
}
public CPos Clamp(CPos uv)

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
@@ -21,8 +21,8 @@ namespace OpenRA
public readonly Size Size;
public readonly MapGridType GridType;
protected readonly T[] entries;
protected readonly Rectangle bounds;
protected readonly T[] Entries;
protected readonly Rectangle Bounds;
public CellLayerBase(Map map)
: this(map.Grid.Type, new Size(map.MapSize.X, map.MapSize.Y)) { }
@@ -30,9 +30,9 @@ namespace OpenRA
public CellLayerBase(MapGridType gridType, Size size)
{
Size = size;
bounds = new Rectangle(0, 0, Size.Width, Size.Height);
Bounds = new Rectangle(0, 0, Size.Width, Size.Height);
GridType = gridType;
entries = new T[size.Width * size.Height];
Entries = new T[size.Width * size.Height];
}
public virtual void CopyValuesFrom(CellLayerBase<T> anotherLayer)
@@ -40,19 +40,24 @@ namespace OpenRA
if (Size != anotherLayer.Size || GridType != anotherLayer.GridType)
throw new ArgumentException("Layers must have a matching size and shape (grid type).", nameof(anotherLayer));
Array.Copy(anotherLayer.entries, entries, entries.Length);
Array.Copy(anotherLayer.Entries, Entries, Entries.Length);
}
/// <summary>Clears the layer contents with their default value</summary>
public virtual void Clear()
{
Array.Clear(Entries, 0, Entries.Length);
}
/// <summary>Clears the layer contents with a known value</summary>
public void Clear(T clearValue)
public virtual void Clear(T clearValue)
{
for (var i = 0; i < entries.Length; i++)
entries[i] = clearValue;
Array.Fill(Entries, clearValue);
}
public IEnumerator<T> GetEnumerator()
{
return ((IEnumerable<T>)entries).GetEnumerator();
return ((IEnumerable<T>)Entries).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()

Some files were not shown because too many files have changed in this diff Show More