Compare commits

...

4425 Commits

Author SHA1 Message Date
Matthias Mailänder
157db79ae7 Enable itch app auto updates on Windows. 2020-09-06 13:50:50 +02:00
ABrandau
c01c39954a Update Harpy Rotor 2020-09-01 18:57:43 +02:00
Matthias Mailänder
c48eb572e3 Remove MuzzleSplitFacings and expose MuzzleSequence to testing. 2020-09-01 18:53:43 +02:00
Paul Chote
b03ab1212f Remove install-core target. 2020-09-01 18:48:54 +02:00
Paul Chote
8a9b5e7e01 Split a separate "compat" macOS package that uses the system mono. 2020-09-01 18:48:54 +02:00
Paul Chote
9b90e4f25a Remove Coverity references. 2020-09-01 18:48:54 +02:00
Paul Chote
8a4401bdcb Fix Appveyor GeoIP download. 2020-09-01 18:48:54 +02:00
Paul Chote
d52e90cf23 Improve .travis.yml compatibility for non-OpenRA deploys. 2020-09-01 18:48:54 +02:00
Paul Chote
14ef0a7740 Remove markdown/html pages from windows install. 2020-09-01 18:48:54 +02:00
Paul Chote
c1f79b348a Generate platform-specific artwork from common source files. 2020-09-01 18:48:54 +02:00
Paul Chote
62166a50d9 Move itch upload script. 2020-09-01 18:48:54 +02:00
Brent Gardner
283b330403 Workaround for GLES 2.0 hardware 2020-09-01 18:00:51 +02:00
teinarss
2cf6b74295 Refactoring on GetEventBounds in Widget 2020-09-01 17:56:12 +02:00
abcdefg30
1a9f707d18 Remove the last reference to DedicatedLoop 2020-08-30 18:12:48 +02:00
Aigamo
06a1c88e86 Replace 0x7FFFFFFF with int.MaxValue 2020-08-29 12:37:20 +01:00
ycanardeau
f358b566b1 Replace NetFrameNumber >= 1 with GameStarted 2020-08-29 12:37:20 +01:00
reaperrr
15fc27d142 Use cached selected in SelectionDecorationsBase 2020-08-28 12:24:07 +02:00
reaperrr
ad20597d74 Cache hue picker sprite in HueSliderWidget 2020-08-27 21:17:37 +02:00
reaperrr
6d409a7c97 Cache indicator sprite in ResourceBarWidget at initialization 2020-08-27 21:17:37 +02:00
reaperrr
36d5ae5421 Cache SupportPowersWidget offsets at initialization
As well as overlay font.
2020-08-27 21:17:37 +02:00
tovl
db9744ea7f Let TS aircraft turn slower when circling. 2020-08-27 21:15:38 +02:00
tovl
5e62fe86fc Add IdleSpeed to aircraft trait. 2020-08-27 21:15:38 +02:00
Paul Chote
6cfa27c33b Replace per-color font caches with tinted rendering. 2020-08-24 18:38:08 +02:00
Taryn Hill
a405969199 docs: link to docs.openra.net instead of wiki.openra.net in readme for generated trait docs 2020-08-23 11:20:02 +02:00
Paul Praet
9a6f3b4c05 Reset Ready status of players in Lobby when options change
Addresses #11274
2020-08-23 00:05:55 +03:00
Matthias Mailänder
7be059a79b Download our cached version after they blocked Travis CI... 2020-08-22 13:06:08 +02:00
reaperrr
29b55de042 Cache rectangles and font in ProductionTabsWidget 2020-08-21 18:06:18 +02:00
reaperrr
235fb19aa8 Cache overlay traits in ProductionPaletteWidget
Instead of looking this up every Draw tick,
cache and update it only when a non-null new
CurrentQueue is set (as the overlays can only change
at that time).
2020-08-21 18:06:18 +02:00
reaperrr
c0f54fa4fc Cache offsets in ProductionPaletteWidget
At least those that never change.
2020-08-21 18:06:18 +02:00
reaperrr
cdc216aca0 Fix airborne husk target types
Doesn't really make a difference, since it only matters
for effect warheads and those already could target both
air and ground actors, but GroundActor was still wrong.
2020-08-20 20:46:58 +02:00
reaperrr
4505053618 Simplify CreateEffectWarhead code
Simplified and streamlined code,
based on past feedback and suggestions.

Note: The new methods will move to
Warhead later, once they're used by more
than one warhead.
2020-08-20 20:46:58 +02:00
abcdefg30
e0d53126d6 Remove the Light Tank husk 2020-08-20 19:17:39 +02:00
abcdefg30
12ff1dd14c Add RAGL balance changes 2020-08-20 19:17:39 +02:00
abcdefg30
50db3152f6 Fix the windows uninstaller name 2020-08-20 17:33:48 +02:00
teinarss
9c4fd0e3d3 Use Null-Propagation Operator 2020-08-19 18:11:07 +01:00
teinarss
8d27d22100 Use discard syntax 2020-08-19 18:11:07 +01:00
teinarss
27f1a7ab27 Use out var syntax 2020-08-19 18:11:07 +01:00
teinarss
d52e4793fe Refactor classes to structs 2020-08-19 11:54:29 +02:00
teinarss
544ac6cb33 Fix crash after entering manage content 2020-08-19 11:40:43 +02:00
Paul Chote
06fbc1a6cf Hide TraitInfo.InstanceName from FieldLoader. 2020-08-17 20:13:32 +02:00
abcdefg30
edab10e6a6 Make the Phase Transport uncloak during repair by mechanics 2020-08-16 21:01:16 +02:00
abcdefg30
dd99fc93e4 Uncloak during resupply when "UncloakOn: Dock" is defined 2020-08-16 21:01:16 +02:00
abcdefg30
dbe824d4e5 Correct "offseted" to "offset" 2020-08-16 15:02:56 +02:00
Paul Chote
6e73d7f5c2 Tidy MapEditorLogic ctor. 2020-08-16 14:17:45 +02:00
Paul Chote
960056d300 Fix mod switcher icon handling. 2020-08-16 14:17:45 +02:00
Paul Chote
3efac3287e Fix Session.Deserialize error handling. 2020-08-16 14:17:45 +02:00
Paul Chote
c4b4a8c8a5 Fix incorrect ramp fill in Map.Resize. 2020-08-16 14:17:45 +02:00
Paul Chote
b833f033bf Remove redundant check from LabelWithHighlightWidget. 2020-08-16 14:17:45 +02:00
Paul Chote
ad75e2be89 Remove redundant check from SupportPowerInstance. 2020-08-16 14:17:45 +02:00
Orb
7ee4fbeb0d New Money Settings 2020-08-15 21:02:01 +01:00
Paul Chote
9886f0ca9a Fix Harvester crash when multiple resource renderers are used. 2020-08-15 18:43:40 +02:00
Paul Chote
46cf56d6ff Remove editor-specific resource rendering.
Mods must manually move their *ResourceRenderer definitions from
World onto BaseWorld to restore resource rendering in the editor.
2020-08-15 18:43:40 +02:00
Matthias Mailänder
e7af295b5e Allow news per mod. 2020-08-15 16:21:21 +01:00
Matthias Mailänder
9d179d9a1a Initialize the font only once and make it configurable. 2020-08-15 16:13:21 +01:00
Matthias Mailänder
15010f9567 Fix production palette ignoring yaml font overrides. 2020-08-15 16:13:21 +01:00
Oliver Brakmann
a7f4f6c1cf Use LeaveMapAtClosestEdge for scripted MiGs on Intervention 2020-08-15 13:38:57 +01:00
Oliver Brakmann
3eeb677f14 Add LeaveMapAtClosestEdge idle behaviour for Aircraft 2020-08-15 13:38:57 +01:00
Paul Chote
ef69a3de66 Use nameof() in PaletteReference. 2020-08-15 13:41:45 +02:00
abcdefg30
0aa5e07252 Send the 'minefieldStart' along with a 'PlaceMinefield' order 2020-08-15 11:34:00 +01:00
abcdefg30
07d58337f1 Let order generators account for selection changes 2020-08-15 11:34:00 +01:00
abcdefg30
b5e3f25418 Fix CashTrickler crashing without IOccupiesSpace 2020-08-15 11:21:39 +01:00
teinarss
19b02875c7 Use Tuple syntax 2020-08-15 10:37:10 +01:00
Taryn Hill
8a74f6ea18 change whitespace-only lines to empty lines in Lua scripts 2020-08-14 15:08:14 +02:00
abcdefg30
a847f3eafa Fix actors not yet in the world improperly updating power state 2020-08-14 11:46:38 +02:00
Curtis Shmyr
a751f074e7 Added actor parameter to Lua UnloadPassenger 2020-08-10 10:38:35 +02:00
Paul Chote
75cb5c2166 Convert turret facings to WAngle relative to the body. 2020-08-09 19:43:53 +02:00
Paul Chote
70a86bed7a Optimize WRot negation.
The conjugate of a quaternion just negates the x/y/z components, so
there is no need to recalculate from scratch and throw away precision
by forcing a quat->euler->quat round trip.
2020-08-09 19:43:53 +02:00
dnqbob
f67f8ed05e WithLandingCraftAnimation can stop on all movement 2020-08-09 13:22:56 +02:00
Mustafa Alperen Seki
1ae53220d6 Add CurrentMuzzleFacing to FireClusterWarhead. 2020-08-09 13:18:39 +02:00
Matthias Mailänder
c546cb552e Make the fonts configurable. 2020-08-09 13:14:32 +02:00
Matthias Mailänder
10f8836d7b Fix a null reference exception. 2020-08-09 13:14:32 +02:00
dnqbob
7ecd4124ce Make "RepairableNear" public, helpful for modder 2020-08-08 13:20:39 +02:00
abcdefg30
54cd77be8e Add Tiberium near the transformable tree in cnc64gdi01 2020-08-05 11:45:11 +02:00
Mustafa Alperen Seki
43388cb7fc Don't check HasAdequateRefineryCount if no RefineryTypes defined. 2020-08-05 11:29:22 +02:00
Mustafa Alperen Seki
4cc5104fde Unhardcode AI's MinimumRefineryCount numbers. 2020-08-05 11:29:22 +02:00
Curtis Shmyr
d519cabae3 Add actor experience to the Lua API 2020-08-03 18:35:50 +02:00
abcdefg30
9852e29835 Fix subs targeting naval structures by default 2020-08-03 17:50:36 +02:00
Matthias Mailänder
3a427c3630 Add a sequence reference attribute to label fallbacks. 2020-08-02 22:15:13 +02:00
Matthias Mailänder
336656e8f7 Remove superflous warning as null is a valid value here. 2020-08-02 22:15:13 +02:00
Matthias Mailänder
06ad9666e8 Replace burns with more modular and testable trait combinations. 2020-08-02 22:15:13 +02:00
Matthias Mailänder
728e0c6600 If it defaults to the actor type, then it shouldn't be required. 2020-08-02 22:15:13 +02:00
Matthias Mailänder
657e690bdd Add an image override. 2020-08-02 22:15:13 +02:00
Matthias Mailänder
2d36d0a659 Reflect in naming that negative SelfHealing is a thing. 2020-08-02 22:15:13 +02:00
Matthias Mailänder
c42fd5d2e2 Add IsDecoration as a configurable option. 2020-08-02 22:15:13 +02:00
Trevor Nichols
10bf97eff6 Reduce severity of editorconfig and prefer multiline braces 2020-08-02 14:37:39 +02:00
Matthias Mailänder
ea9992247d Reorder string placeholders. 2020-08-02 12:00:53 +02:00
Matthias Mailänder
b90fecff76 Remove the prefixed method name. 2020-08-02 12:00:53 +02:00
Matthias Mailänder
a4fc9fea3b Unify AIUtils.BotDebug prefixes. 2020-08-02 12:00:53 +02:00
abcdefg30
b7c7eff2a2 Fix the position of the red cross in RA 2020-08-02 11:56:15 +02:00
Stuart McHattie
8c10dc406a Prevent Mac's Cmd+Q from exiting the game
This operation can be devastating if you were trying to assign a control group using Cmd + 1 but accidentally catch the Q key during gameplay.
2020-07-28 23:12:39 +01:00
Stuart McHattie
05c3861426 Add myself to the authors list 2020-07-28 23:12:39 +01:00
Matthias Mailänder
1ef5db8896 Document the built in hitshape types. 2020-07-28 23:42:26 +02:00
Andre Mohren
006a87692a Removed unused imports. 2020-07-28 18:22:51 +02:00
Oliver Brakmann
e019b70420 Fix actor previews for actors with types written in capital letters 2020-07-26 10:57:18 +02:00
Smittytron
70ec5b0344 Add flash to mission paranukes 2020-07-26 10:52:06 +02:00
abcdefg30
5401ace540 Add a death animation to Visceroids 2020-07-24 18:13:11 +02:00
abcdefg30
ab9081c852 Force enable Visceroids in the default rules 2020-07-24 18:13:11 +02:00
Matthias Mailänder
3a9b35980c Revert "Reduce order latency locally"
This reverts commit 20e5219cf4.
2020-07-21 21:58:31 +02:00
Matthias Mailänder
150439d215 Revert "Change where we send orders"
This reverts commit 616d9421d6.
2020-07-21 21:58:31 +02:00
Matthias Mailänder
b01a534a98 Revert "Refactor the OrderManager and world tick loop, improves input latency"
This reverts commit f642cead44.
2020-07-21 21:58:31 +02:00
Trevor Nichols
758b0b08d0 Add to .editorconfig additional naming rules to match this codebase's style 2020-07-21 16:15:30 +02:00
teinarss
f87ba1d8a4 Update SP maps with transformable trees 2020-07-20 14:05:52 +02:00
teinarss
67fa7bdcc9 Add TransformsNearResources 2020-07-20 14:05:52 +02:00
Matthias Mailänder
0b03aca104 Fix linter for player palettes. 2020-07-19 10:44:55 +02:00
Paul Chote
3bf61f1043 Fix incorrect rotation calculation in ThrowsShrapnel. 2020-07-19 10:41:05 +02:00
Paul Chote
ac975f4139 Convert yaml-exposed facings to WAngle. 2020-07-19 10:41:05 +02:00
abcdefg30
6d12301f88 Fix the aircraft facing slider in the editor 2020-07-18 01:45:00 +02:00
Andre Mohren
914950c4a5 When zooming using the mousewheel, zoom towards the pointer location. 2020-07-17 20:12:10 +02:00
Paul Chote
b417b267dd Store quaternion components directly.
This avoids precision loss when combining rotations.
The equivalent Euler angles are calculated for external use
but the quaternion components are preferred for any further
internal calculations.
2020-07-17 15:02:32 +02:00
Paul Chote
aae497eff1 Pass pre-combined rotations into the rendering code. 2020-07-17 15:02:32 +02:00
Paul Chote
3c9db4c2ac Add WRot.Rotate to allow rotations to be combined. 2020-07-17 15:02:32 +02:00
Paul Chote
8c3793e7ea Rename WRot.Zero to WRot.None. 2020-07-17 15:02:32 +02:00
Oliver Brakmann
60a7f53491 Fix target lines appearing not long enough on screen
Also changes the Delay attribute from ticks to milliseconds.
2020-07-16 00:28:05 +02:00
Mustafa Alperen Seki
04bfd62f2f Fix FireClusterWarhead playing wrong Report sound. 2020-07-15 23:55:01 +02:00
Paul Chote
117b8b3653 Change tiberium colors to match the original game. 2020-07-13 14:02:02 +02:00
Paul Chote
70cb0d2924 Improve TS map importer and reimport classic maps. 2020-07-13 14:02:02 +02:00
Paul Chote
c5ea496c45 Add terrain lighting definitions to TS. 2020-07-13 14:02:02 +02:00
Paul Chote
01e955ca37 Implement TS-style terrain lighting. 2020-07-13 14:02:02 +02:00
Paul Chote
fdb66c769c Change terrain layers to track sequences instead of sprites. 2020-07-13 14:02:02 +02:00
Paul Chote
38b3fbbdbe Fix [RequireExplicitImplementation] failures on event properties. 2020-07-13 14:02:02 +02:00
Paul Chote
3bc5d2d02c Add INotifyEditorPlacementInfo interface.
This allows TraitInfos to act when the actor preview is placed
in the editor, returning arbitrary data which the editor stores
and gives back if the preview is removed.
2020-07-13 14:02:02 +02:00
Paul Chote
ac7eda8ca2 Add support for rendering tinted artwork. 2020-07-13 14:02:02 +02:00
reaperrr
baf58f53b3 Adapt SpreadDamageWH to ImpactOrientation
The ImpactOrientation needs to be computed from
point of impact to target if the target wasn't hit directly.

Also adapted warhead code to use WarheadArgs consistently,
as well as pass HitShape instead of just HitShapeInfo
(both needed for future and/or downstream features).
2020-07-12 19:52:55 +02:00
reaperrr
8513a83331 Add ImpactOrientation to WarheadArgs
Allows to pass the horizontal facing/yaw
and vertical angle/pitch of the carrier
projectile to warheads for further use.

Add ImpactPosition to WarheadArgs

InflictDamage doesn't pass the impact pos
directly, and the very point of WarheadArgs
is to avoid adding more and more arguments
to the warhead methods.
2020-07-12 19:52:55 +02:00
Orb
bf7fecff10 TD Balance Summer 2020 2020-07-12 19:31:59 +02:00
Oliver Brakmann
6e1f2f636c Increase GameOverDelay for missions from 1.5 to 3 secs 2020-07-12 15:06:55 +02:00
Oliver Brakmann
8b3db6f3d6 Allow granting a condition to Carryalls currently carrying units 2020-07-12 14:36:01 +02:00
Matthias Mailänder
39d0abe982 Remove bit rot. 2020-07-12 14:32:32 +02:00
teinarss
c2026dc254 Add Discord Rich Presence 2020-07-12 14:27:59 +02:00
Matthias Mailänder
cae6c28754 Change the prefix in front of replays. 2020-07-12 13:43:05 +02:00
Sly
3b99924799 Corrected spelling error 2020-07-10 14:48:22 +02:00
Sly
b2b548b103 Corrected spelling error 2020-07-10 14:46:40 +02:00
Pavel Penev
c2e3806a77 Added a FlashPaletteEffect to RA nukes and removed from D2k 2020-07-10 13:22:54 +02:00
Pavel Penev
25500a7dda Updated a stale copyright header 2020-07-10 13:22:54 +02:00
Pavel Penev
8c394a4cb5 Created FlashPaletteEffectWarhead and removed the hardcoded flashing from NukeLaunch
Not actually hardcoded, but there was a hard dependency in NukeLaunch on FlashPaletteEffect and explicit flashing checks.
2020-07-10 13:22:54 +02:00
Pavel Penev
2e7bd4de4b Fixed a bug with the NukeLaunch's Player palette 2020-07-10 13:22:54 +02:00
Matthias Mailänder
7261322e41 Add support for Visual Studio Code. 2020-07-10 12:33:57 +03:00
abcdefg30
cada396733 Fix a crash when previewing an actor using WithCrateBody in the editor 2020-07-09 20:31:03 +02:00
Chris
9f9709f058 Add python3 support to launch-game.sh 2020-07-09 20:21:48 +02:00
abcdefg30
26fc65209d Fix the bogus Actors iterator 2020-07-09 18:11:53 +02:00
Adam Mitchell
f642cead44 Refactor the OrderManager and world tick loop, improves input latency 2020-07-09 13:48:55 +02:00
Adam Mitchell
616d9421d6 Change where we send orders 2020-07-09 13:48:55 +02:00
Adam Mitchell
20e5219cf4 Reduce order latency locally 2020-07-09 13:48:55 +02:00
Vapre
9edda21b06 Avoid three time array lookup in TraitContainer.Actors. 2020-07-09 12:16:04 +02:00
Paul Chote
6d6822ca15 Update map inits in RA/TD/D2k. 2020-07-08 20:38:30 +02:00
Paul Chote
a2269e7ee7 Convert (Dynamic)FacingInit, (Dynamic)TurretFacingInit to WAngle. 2020-07-08 20:38:30 +02:00
Paul Chote
e8f443f4a9 Remove TurretFacingsInit and PlugsInit. 2020-07-08 20:38:30 +02:00
Ivaylo Draganov
67f8452178 Add button to override duplicate hotkey bindings 2020-07-08 19:59:07 +02:00
Ivaylo Draganov
47f6e407d9 Cancel hotkey rebind on Esc key press 2020-07-08 19:59:07 +02:00
abcdefg30
889e2152a4 Cache ProjectedCellBounds during load time 2020-07-08 18:37:50 +02:00
abcdefg30
173aae1f81 Directly check the map bounds instead of converting to PPos 2020-07-08 18:37:50 +02:00
abcdefg30
baed80983b Fix the launch-game.sh newlines not displaying in the console 2020-07-07 22:30:55 +02:00
abcdefg30
b00423dc76 Correct the crash dialog title 2020-07-07 22:30:55 +02:00
abcdefg30
376ed15079 Correct the support folder location in the crash dialog 2020-07-07 22:30:55 +02:00
abcdefg30
a6d8d6cd8e Use tabs as indentation consistently 2020-07-07 22:30:55 +02:00
Paul Chote
b3ee8b447e Reduce duplication between Map and PlayerRadarTerrain. 2020-07-07 22:12:22 +02:00
Paul Chote
5f588561b6 Rewrite TS minimap rendering:
* Rename LeftColor and RightColor to MinColor and MaxColor
  These are mapped from LowRadarColor and HighRadarColor in
  the original inis, and appear to be used to set the bounding
  values for selecting a random colour, NOT for left/right
  pixels (which caused noticeably wrong banding).

* Adjust brightness based on terrain height.
  MinHeightColorBrightness and MaxHeightColorBrightness
  were chosen by trial/error to match the original
  map preview rendering.
2020-07-07 22:12:22 +02:00
Smittytron
83c53e17e0 Allow repairable tech buildings in campaign-rules 2020-07-07 19:47:10 +02:00
Smittytron
c028488894 Add Soviet 09 2020-07-07 19:47:10 +02:00
abcdefg30
b066005f7e Fix AttackBomber marking aircraft that are not in the world as in range 2020-07-06 22:30:41 +02:00
abcdefg30
87e33a75c6 Fix a crash when calling an airstrike at the map edge 2020-07-06 22:30:41 +02:00
Matthias Mailänder
4961b0943b Add a text base spy disguise decoration. 2020-07-05 21:43:12 +02:00
Smittytron
eda1e9c266 Add Counterstrike mission Siberian Conflict 1: Fresh Tracks 2020-07-05 21:33:56 +02:00
abcdefg30
bc7bf174d8 Don't tick the announcement timer when not in low power
When entering low power it will be reset to 0 again anyway
2020-07-05 20:37:17 +02:00
abcdefg30
2e06d5790b Update the PowerState only when power is added or removed 2020-07-05 20:37:17 +02:00
abcdefg30
ab8790e8f1 Style/Readability changes 2020-07-05 20:37:17 +02:00
abcdefg30
7d630e63e7 Let Railgun implement ISync 2020-07-05 18:10:14 +02:00
Smittytron
77899191f3 Add Aftermath mission Situation Critical 2020-07-05 17:21:43 +02:00
Smittytron
6871873e93 Add Counterstrike mission Fall of Greece 1: Personal War 2020-07-05 15:59:18 +02:00
Smittytron
fc4bd131cd Add Aftermath mission: Production Disruption 2020-07-05 15:58:10 +02:00
Pavel Penev
d866286f82 Added back the DescAttributes on projectiles' Inaccuracy fields 2020-07-05 13:04:18 +02:00
Pavel Penev
76dfda164e Moved projectile inaccuracy calculations to Common.Util
Also moved the InaccuracyType enum there. This also quietly adds the RangeModifiers to the calculations for all projectiles, while they were only used on Bullet so far, which seemed very wrong.
2020-07-05 13:04:18 +02:00
Pavel Penev
134d47e48c Added InaccuracyType.Absolute to projectiles 2020-07-05 13:04:18 +02:00
Pavel Penev
a2dbd5e013 Changed weapons in D2k to use the new PerCellIncrement inaccuracy
Also adjusted the inaccuracy values. This should bring inaccuracy in D2k pretty much in line with the original game, with the potential liberty of decreased inaccuracy for the Deviator tank.
2020-07-05 13:04:18 +02:00
Pavel Penev
c27412c83a Added InaccuracyType enum and updated projectiles accordingly
Also updated the inaccuracy calculations to account for the new inaccuracy type - either based on distance up to a max defined inaccuracy at max range (old style) or based on distance with each cell (1024 range) increasing the inaccuracy with a set step.
2020-07-05 13:04:18 +02:00
Pavel Penev
4143aba595 Added syncing to some Railgun projectile fields 2020-07-05 13:04:18 +02:00
Ivaylo Draganov
39ccac4022 Refactor command bar buttons to use unified widget state names 2020-07-05 11:50:45 +01:00
Ivaylo Draganov
7943f4deb6 Unify widget state image suffixes (disabled, pressed, hover, focus)
- Add a property for arrows image collection (in drop-downs, scrollbars
and production tabs)
- Add a property for separators image collection (in drop-downs)
- Add hover and disable states to the drop-down separator
- Unify button, textfield and checkbox state suffixes
2020-07-05 11:50:45 +01:00
Curtis Shmyr
2dda2d7689 Added lua IsCloaked actor property 2020-07-04 21:06:52 +02:00
Matthias Mailänder
b8f2a14ea0 Automatically upload release to itch.io using butler. 2020-07-04 20:59:10 +02:00
Oliver Brakmann
595809f090 Fix Carryalls waiting for actors on transit-only tiles 2020-07-04 16:47:17 +02:00
abcdefg30
477db9cd4a Fix travis builds not failing when errors occur during static checking 2020-07-03 21:29:25 +01:00
teinarss
67ff292d62 Refactor WorldRenderer to use less allocations 2020-07-03 17:41:41 +02:00
darkademic
ae882b85a9 Make AI randomly scan map for targets for its air squads. 2020-07-02 23:05:49 +02:00
abcdefg30
5e92915095 Fix the cargo unload regression with scripted transports
The activity is not interruptible, so we'd continue after the Move regardless
2020-07-02 21:14:35 +02:00
Smittytron
95809db03c Move Harvester overrides to campaign-rules.yaml 2020-07-02 19:29:37 +02:00
Smittytron
6d5a5121bc Remove worthless function from Allies08 2020-07-02 19:29:37 +02:00
Smittytron
86992751c7 Update Soviet-08a 2020-07-02 19:29:37 +02:00
Smittytron
2eba8b6c37 Add Soviet-08b 2020-07-02 19:29:37 +02:00
Smittytron
e1523e939d Utilize Panic function with added OnDamaged trigger 2020-06-28 17:30:24 +02:00
Smittytron
15a92f443d Replace paraprop power with scripted drops in Soviet01 2020-06-28 17:30:24 +02:00
KorGgenT
b57c68e392 Fix units walk over tunnels and under bridges. 2020-06-28 17:21:54 +02:00
Matthias Mailänder
e95fcb6bc0 Don't let blossom tree poof all at the same time. 2020-06-28 13:43:33 +02:00
Matthias Mailänder
6581fcb6a7 Add a random interval to idle animations. 2020-06-28 13:43:33 +02:00
tovl
6551337bd8 Make TS walkers AlwaysTurnInPlace. 2020-06-28 00:11:26 +02:00
tovl
137df52fdd Make infantry AlwaysTurnInPlace. 2020-06-28 00:11:26 +02:00
tovl
b79aa7eb6a Add AlwaysTurnInPlace option to Mobile. 2020-06-28 00:11:26 +02:00
Alfred Lang
1c8c49dc8e Fix do allow AI do place plugbuildings like RBG Tower on GDI Component Tower 2020-06-27 10:35:06 +02:00
Andrew Odintsov
f0c808d2fc Replace FloodFill with IEditorAction implementation 2020-06-24 19:08:54 +02:00
Curtis Shmyr
26d9ae88df Replace TargetAndAttack with a global aircraft attack function 2020-06-23 20:09:42 +02:00
Curtis Shmyr
3c7f119bb1 Add a damage parameter to Lua OnDamage callback 2020-06-23 19:58:31 +02:00
Ian T. Jacobsen
fea35923f0 Minefield now shows red when out of map bounds and Minelayer now does not get stuck at edge of map
Made it impossible to detect enemy units again

Fix whitespace
2020-06-21 20:16:57 +02:00
Paul Chote
9627776318 Add pitch and roll to TS aircraft. 2020-06-21 18:05:40 +02:00
Paul Chote
6dcde3af72 Allow voxel-based aircraft to pitch and roll. 2020-06-21 18:05:40 +02:00
Paul Chote
43717a89b5 Add Orientation getter to IFacing. 2020-06-21 18:05:40 +02:00
Matthias Mailänder
c7ba359688 Add drop pod reinforcements. 2020-06-21 17:28:24 +02:00
Matthias Mailänder
dc3dbf6d85 Remove uneccessary parentheses. 2020-06-21 17:28:24 +02:00
Smittytron
71664c85ff Fix TargetTypes regression in SnipeWeapon 2020-06-21 12:34:43 +02:00
Nikita Pozdeev
cb41be113a Fix map editor radar ignoring color from terrain 2020-06-20 14:37:23 +02:00
Matthias Mailänder
4fe7daa85e Fix juggernaut preview being disabled by default. 2020-06-19 21:30:34 +02:00
abcdefg30
f75afc6ee4 Fix a compilation error in WithInfantryBody.cs 2020-06-19 20:01:04 +02:00
abcdefg30
67fd71ab92 Add a ProjectedCellLayer and use it in Shroud.cs 2020-06-19 18:31:51 +02:00
abcdefg30
385e70552e Create CellLayerBase 2020-06-19 18:31:51 +02:00
Matthias Mailänder
1e2c67bfca Increase UPnP device discovery timeout. 2020-06-19 18:00:27 +02:00
Paul Chote
56739f87fb Allow plugs to be configured in the map editor. 2020-06-19 17:57:56 +02:00
Paul Chote
571eb7614f Support multiple turrets in the editor. 2020-06-19 17:57:56 +02:00
Paul Chote
c6c3a8c60d Make ActorPreview and EditorActorPreview wrap ActorReference. 2020-06-19 17:57:56 +02:00
Paul Chote
ae7cfa56b7 Restrict IActorPreviewInitInfo to ActorInit. 2020-06-19 17:57:56 +02:00
Paul Chote
b856613194 Add ISingleInstanceInit interface.
Inits that are logically singletons (e.g. actor
location or owner) should implement this interface
to avoid runtime inconsistencies.

Duplicate instances are rejected at init-time,
allowing simpler queries when they are used.
2020-06-19 17:57:56 +02:00
Paul Chote
86305879cb Parse Enum *ValueInit as string values, not integers. 2020-06-19 17:28:01 +02:00
Paul Chote
e5a1a8a706 Replace deprecated API usage. 2020-06-19 17:28:01 +02:00
Paul Chote
27602a4a97 Add WAngle-compatible airstrike/paratrooper APIs. 2020-06-19 17:28:01 +02:00
Paul Chote
a98e460257 Expose WAngle to Lua API and deprecate old Facing. 2020-06-19 17:28:01 +02:00
Paul Chote
0349435650 Remove deprecated Paratrooper API methods. 2020-06-19 17:28:01 +02:00
Paul Chote
c3fbdca18f Add yellow-shirt technician. 2020-06-19 17:09:13 +02:00
Paul Chote
acb5245a28 Restore correct palette and voices for RA civilians.
A new C11 infantry has been added to use the custom
c3 sprite that was originally added back when only
c1 and c2 were used in OpenRA.
2020-06-19 17:09:13 +02:00
Paul Chote
23561cd76b Add custom palette support to WithInfantryBody. 2020-06-19 17:09:13 +02:00
Paul Chote
d3ab3d7d78 Move IndexedPlayerPalette to Mods.Common and add a non-player version. 2020-06-19 17:09:13 +02:00
Matthias Mailänder
5b870be83f Let the 2nd civilian panic when his mate gets electrocuted. 2020-06-19 16:50:28 +02:00
Matthias Mailänder
6130d5622c Add a panic function to the Lua API. 2020-06-19 16:50:28 +02:00
abcdefg30
318c4e3456 Remove InitialStanceAI overrides from campaign missions 2020-06-19 16:46:34 +02:00
abcdefg30
ab701449e2 Change Subs to use the Defend stance by default 2020-06-19 16:46:34 +02:00
abcdefg30
9a3447d863 Fix airstrike and paratroopers power not removing cameras at the map edge 2020-06-19 16:04:54 +02:00
matjaeck
5280637adf Fix PickupUnit not validating cargo on first run. 2020-06-19 15:59:14 +02:00
Matthias Mailänder
3bce55ac44 Cancel the attack when no traits are active. 2020-06-19 13:43:03 +02:00
Curtis Shmyr
a3f79503ed Fix Lua DisplaySystemMessage writing twice 2020-06-16 13:11:02 +02:00
Curtis Shmyr
02d462a82c Fix copying public key to clipboard if already authed 2020-06-13 19:15:27 +02:00
Smittytron
3d17328d0d Fix regression and cleanup scu35ea 2020-06-12 23:50:44 +02:00
reaperrr
0e81abc21b Fix weapons not accounting for Air
If a weapon was aiming at a target position rather
than an actor target, it would always check target types
of the terrain below, ignoring altitude (and therefore ignoring
"InvalidTargets: Air").
2020-06-12 21:00:53 +02:00
Paul Chote
803b930405 Change IFacing.TurnSpeed to WAngle. 2020-06-12 18:35:41 +02:00
Paul Chote
6adf45bcb4 Convert IFacing.Facing and TurnSpeed to WAngle. 2020-06-12 18:35:41 +02:00
Matthias Mailänder
01417c88c5 Add missing actor reference for lint testing. 2020-06-10 19:07:14 +02:00
abcdefg30
60bbbe0d93 Fix the Death Hand launch notification playing for the player not enemy 2020-06-10 18:57:08 +02:00
Matthias Mailänder
888dfd3654 Stop the boat to remove it immediately. 2020-06-09 22:40:32 +02:00
Matthias Mailänder
12de56ff62 Fix crash notication "AlertBeep" not found. 2020-06-09 22:40:32 +02:00
Matthias Mailänder
b7cee41c54 Fix TD gunboat not updating actor map influence. 2020-06-09 22:40:32 +02:00
Paul Chote
10aac03f75 Add CompositeActorInit and simplify chronoshift inits. 2020-06-08 19:18:38 +02:00
Paul Chote
0eb0041f90 Allow ActorInits to target a specific trait by matching the @ suffix. 2020-06-08 19:18:38 +02:00
Paul Chote
b38018af9c Replace IActorInit with an abstract class.
A shared ValueActorInit<T> is introduced to reduce duplication
in the most common init cases, and an ActorInitActorReference
allow actors to be referenced by map.yaml name.
2020-06-08 19:18:38 +02:00
Unknown
4df5ac0385 Change default to ground-attack 2020-06-07 10:31:44 -05:00
Unknown
a7476bc303 Improve detail + double fire rate/half damage 2020-06-07 10:31:44 -05:00
Unknown
cc4b3cb361 Add APC ground attack sprite turret 2020-06-07 10:31:44 -05:00
Ivaylo Draganov
31a965b29a Add suffix to player name in shroud selector 2020-06-06 14:40:48 +01:00
Ivaylo Draganov
7a213338a2 Add helper method to add suffix to player name label 2020-06-06 14:40:48 +01:00
abcdefg30
fb27a25e52 Fix a crash with support powers and units without selection decorations 2020-06-06 13:46:27 +01:00
abcdefg30
534b09ae4a Fix bots not working after adminship was transferred 2020-06-03 18:30:18 +02:00
abcdefg30
341a9f370c Fix a crash in Evacuation 2020-06-02 22:53:40 +02:00
Matthias Mailänder
607d9b2d5c Fix index out of bounds exception for off world aircraft. 2020-06-02 19:25:53 +01:00
abcdefg30
507ce40ad2 Fix a crash in LegacyBridgeLayer 2020-06-02 19:22:19 +01:00
reaperrr
f58c3aed32 Use OccupiesSpace to save more trait look-ups
This time in Locomotor.IsBlockedBy.
2020-06-02 20:08:34 +02:00
reaperrr
55e85bd9ca Save Mobile look-up in BasePathSearch
By casting to OccupiesSpace and then
looking up Info.LocomotorInfo directly.
2020-06-02 20:08:34 +02:00
reaperrr
4bf614c5cd Use OccupiesSpace to avoid Mobile look-up in Move
While individual trait look-ups may be cheap,
if a large army that is currently standing still gets
its first move-including order, the look-ups of dozens
or even hundreds of actors may happen on the same tick.

Therefore this may help reducing that first-order lag spike,
at least a little bit.
2020-06-02 20:08:34 +02:00
abcdefg30
96b06c75d1 Make Resupply display target lines for all queued move activities 2020-06-02 18:23:54 +02:00
Matthias Mailänder
d261648ab0 Fix BeingCapturedCondition getting revoked from the wrong actor. 2020-06-02 10:45:49 +02:00
Paul Chote
7b81b9e806 Bullet Facing -> WAngle. 2020-06-01 21:34:32 +02:00
Paul Chote
a93aea3e4e AreaBeam Facing -> WAngle. 2020-06-01 21:34:32 +02:00
Paul Chote
2cfacc2c7d ProjectileArgs facing -> WAngle. 2020-06-01 21:34:32 +02:00
Paul Chote
6d6b21a0eb Convert Aircraft.Facing to WAngle. 2020-06-01 20:25:38 +02:00
Matthias Mailänder
7a78c37851 Add .NET Coding Conventions 2020-05-31 13:27:03 +01:00
Ivaylo Draganov
b8a9f41892 Add missing trait descriptions for cursors and unify the language 2020-05-31 00:12:04 +02:00
Ivaylo Draganov
227567dfe1 Formatting: wrap and indent long argument lists 2020-05-31 00:12:04 +02:00
Ivaylo Draganov
d5ff5c672b Add configurable cursors for entering allied actor targeters 2020-05-31 00:12:04 +02:00
Ivaylo Draganov
393f6eca3a Add configurable target cursors to various traits 2020-05-31 00:12:04 +02:00
Paul Chote
d193ef856e Fix harvest animation facing glitch. 2020-05-30 19:58:03 +02:00
abcdefg30
44d3691fa1 Assign Player.IsBot before calling INotifyCreated.Created 2020-05-30 19:47:29 +02:00
abcdefg30
27d0465891 Remove workarounds for querying the PlayerActor in Created 2020-05-30 19:47:29 +02:00
abcdefg30
52a9fcef3c Rename "Created" to "Initialize" and let it handle adding to the world 2020-05-30 19:47:29 +02:00
abcdefg30
7386816f52 Manually construct the PlayerActor to fix crashes during actor creation 2020-05-30 19:47:29 +02:00
abcdefg30
9c0075b233 Move hardcoded PlayerActorTypes to shared const variables 2020-05-30 19:47:29 +02:00
abcdefg30
e4c5700baf Remove an unused using 2020-05-30 19:47:29 +02:00
reaperrr
e1b7df8b6a Use OccupiesSpace to avoid Mobile look-ups
in PathFinder.FindUnitPath and FindUnitPathToRange.
2020-05-30 04:05:29 -05:00
Paul Chote
c999b2d778 Convert QuantizeFacing to WAngle facings. 2020-05-28 21:23:51 +02:00
Paul Chote
bfb6c671fb Change QuantizeFacing to return a facing instead of an index. 2020-05-28 21:23:51 +02:00
Paul Chote
7c6ec577dc Rewrite ActorInit queries. 2020-05-28 19:04:53 +02:00
Paul Chote
626b40f31b Account for ramps in terrain height calculations. 2020-05-28 09:41:55 -05:00
Paul Chote
5af12440ba Replace MapGrid.CellCorners with a new CellRamp struct. 2020-05-28 09:41:55 -05:00
Paul Chote
4614f6febe Cache cell ramps to avoid repeated tileset lookups. 2020-05-28 09:41:55 -05:00
Pavel Penev
1354ffc32e Added multiple production speedup to D2k
Based on the specification in issue 18051.
2020-05-27 10:32:35 +02:00
Pavel Penev
3723939c99 Adjusted D2k build times to match the original game
Removed custom production queue speedups and custom actor build time slowdowns and adjusted BuildDurations based on the specifications in issue 18051.
2020-05-27 10:32:35 +02:00
Pavel Penev
e099739e13 Reduced HitShape radius of D2k units to minimum
Since they are only used to hold the armor type anyway.
2020-05-27 10:28:25 +02:00
Pavel Penev
21a48cc41d Switched D2k to use the new DamageCalculationType
This brings D2k in line with the damage model of the original game.
2020-05-27 10:28:25 +02:00
Pavel Penev
4740266308 Added DamageCalculationType enum to SpreadDamageWarhead 2020-05-27 10:28:25 +02:00
Pavel Penev
78139413d7 Equalized the DoImpact methods in damage warheads 2020-05-27 10:28:25 +02:00
Pavel Penev
f0578a75f4 Cleaned up DamageWarhead
Reordered methods and fixed access modifiers. Also removed unused using statements from warheads.
2020-05-27 10:28:25 +02:00
abcdefg30
7a0e55a02a Restore trailing whitespaces to windows batch scripts 2020-05-26 22:57:11 +02:00
reaperrr
f132bac80d Add Tree armor type and remove tree-only warheads
This simplifies #12467.
Using a tree-exclusive amor type is far more efficient
than adding more warheads, which cost performance
due to their huge Spread

This also restores the 100% efficiency vs. trees for
some of the incendiary nuke warheads (which have
reduced efficiency vs. Wood since #13643).

Note: Atomic had two tree-only warheads with a Delay
of 15, I believe the first one to be a copy-paste error
and moved the damage to the regular SpreadDamage
with a Delay of 10.
2020-05-26 22:51:29 +02:00
reaperrr
109ea4fe5b Fix Barrel explosion damage 2020-05-26 22:46:26 +02:00
Matthias Mailänder
f33feafd0e Add TurnOnIdle. 2020-05-25 13:07:19 +02:00
reaperrr
9195356e3a Upgrade DepthCharge effect setup
- med_explosion instead of small_explosion on surface hit
- only play explosion on surfaced subs
- only play h2obomb2.aud when hitting a submerged sub
2020-05-24 13:26:40 +02:00
reaperrr
eff91108f4 Make RA ships show both explosion and splash
...when destroyed, to imply sinking.
2020-05-24 13:26:40 +02:00
reaperrr
e40c0516e6 Adapt RA warheads to new target types 2020-05-24 13:26:40 +02:00
reaperrr
c580a94ab7 Fix RA weapon ValidTargets 2020-05-24 13:26:40 +02:00
reaperrr
6a545bb942 Streamline RA target types
No more sharing of target types between terrain
and actors (except bridges), removed 'Ground(Actor)'
from WaterActors (was only used by weapons/warheads,
which can just list both ground- and water types.
2020-05-24 13:26:40 +02:00
Matthias Mailänder
672bd2d9fe Don't crash when putting the trait on the World actor. 2020-05-24 12:36:26 +02:00
Ivaylo Draganov
3ab4a584ab Remove trailing white-space from various files 2020-05-23 11:38:44 +02:00
Ivaylo Draganov
150d02ac0d Remove trailing white-space from lua files 2020-05-23 11:38:44 +02:00
Ivaylo Draganov
6d26f60904 Remove trailing white-space from yaml files 2020-05-23 11:38:44 +02:00
abcdefg30
b42276953f Fix a crash when a harvester is rebuilt in cnc64gdi01 2020-05-22 21:25:58 +02:00
abcdefg30
7c290b9f76 Fix not all harvesters in cnc64gdi01 being rebuilt 2020-05-22 21:25:58 +02:00
abcdefg30
51fe1d6629 Let AI autotargeting in D2k ignore sandworms 2020-05-22 20:40:36 +02:00
Matthias Mailänder
8f558d2b47 Add a bullet bounce sound. 2020-05-21 14:44:13 +02:00
abcdefg30
3f5fadf2e9 Move stray update rules into the correct subfolder 2020-05-21 14:08:14 +02:00
abcdefg30
07c16cee1d Add TargetTypes to HealActorsCrateAction 2020-05-21 14:08:14 +02:00
abcdefg30
24130dfcdc Add an update rule for the RenameHealCrateAction rename 2020-05-21 14:08:14 +02:00
abcdefg30
15a2341a91 Rename HealUnitsCrateAction to HealActorsCrateAction 2020-05-21 14:08:14 +02:00
Paul Chote
86f61298e6 Replace ITraitInfo interface with TraitInfo class. 2020-05-21 13:01:04 +02:00
abcdefg30
3cd7ec3878 Make the TS Test AI build aircraft 2020-05-21 10:05:05 +02:00
abcdefg30
8b13d3e4c7 Fix resupply not displaying target lines correctly 2020-05-19 22:11:20 +02:00
Ivaylo Draganov
327d451abc Add trim_trailing_whitespace to .editorconfig 2020-05-18 17:39:24 +02:00
atlimit8
2dac16ee02 add SquadManagerBotModuleInfo.IgnoredEnemyTargetTypes 2020-05-17 22:02:32 +01:00
abcdefg30
d4b92a19d7 Remove bogus weapon override defintions from TD campaign maps 2020-05-17 13:39:51 +01:00
tovl
e0357596f5 Correct aircraft repulsion direction when outside of the map. 2020-05-17 12:46:17 +02:00
atlimit8
1ef27d18c1 check name for Actor.GrantCondition() 2020-05-17 12:33:29 +02:00
Matthias Mailänder
1d2d8ed107 Don't hard-code the transparent background color. 2020-05-16 22:28:52 +01:00
reaperrr
1bf01bc214 Remove WaterStructure TargetType from RA SYRD/SPEN
- only used for auto-targeting
- inconsistent with their fakes (which didn't have this)
- unnecessary, since the 'Ship' target type covers all
  surface water actors we want to be auto-targetable by default,
  while 'Structure' is enough to add syard/spen in AttackAnything.
2020-05-15 08:22:02 +02:00
reaperrr
0015deca47 Fix TS Tiberium Fiend target types
Was missing Creep, preventing actors from
auto-targeting it (unlike all other critters).
2020-05-15 08:22:02 +02:00
reaperrr
ddfdc6e90f Clean up TD weapon ValidTargets
- Missiles can now force-fire on water like other weapons
- Superweapons can now target empty water
- made Chemspray null InvalidTargets to avoid yaml-merge issues
- Improved APCGun effect warhead perf by ignoring actors
- removed stale Tiberium weapon mission overrides
2020-05-15 08:22:02 +02:00
abcdefg30
5db2ad54f2 Fix a scripting error in nod04b 2020-05-14 22:40:44 +01:00
teinarss
b8a5750529 Add map.contains check to CanStayInCell 2020-05-14 20:06:21 +02:00
Andrew Odintsov
98d5b8c7cc Remove redundant call to OnTextEdited 2020-05-14 11:01:48 +02:00
Andrew Odintsov
3f34154a1e Add OnTextEdited call to RemoveSelectedText
This would allow expty text box to be processed and disable filtering
2020-05-14 11:01:48 +02:00
thisisjacob
3119f831b3 Added notice for entering vehicles in docs 2020-05-13 17:25:49 -05:00
thisisjacob
8a07b762a2 Changed documentation for OnEnterComplete 2020-05-13 17:25:49 -05:00
Matthias Mailänder
551ab2fc59 Cache the footprint LINQ for performance. 2020-05-12 20:53:05 -05:00
Zimmermann Gyula
99957e57b9 Update the default mods. 2020-05-12 20:53:05 -05:00
Matthias Mailänder
be2c59bc6e Add upgrade rule to convert ranges to footprints. 2020-05-12 20:53:05 -05:00
Zimmermann Gyula
57f9a49b66 Use footprints in ChronoshiftPower. 2020-05-12 20:53:05 -05:00
Zimmermann Gyula
54bd0eb99d Use footprints in GrantExternalConditionPower. 2020-05-12 20:53:05 -05:00
Zimmermann Gyula
485faac294 Implement SupportPower.CellsMatching. 2020-05-12 20:53:05 -05:00
Andrew Odintsov
d531d6f3ef Simplify groupActors condition 2020-05-12 15:06:50 +02:00
Andrew Odintsov
3a9fdb82f5 Add IsInWorld check for controlled groups 2020-05-12 15:06:50 +02:00
reaperrr
5024ae1156 TS ClusterMissile typo fix 2020-05-10 15:20:25 +02:00
abcdefg30
0135dd9ed3 Use inheritance to shorten the desert shellmap custom rules 2020-05-09 14:36:50 -05:00
abcdefg30
a6e9b86bbe Remove AnnounceOnKill Tanya overwrites from the desert shellmap 2020-05-09 14:36:50 -05:00
abcdefg30
237c4444b5 Remove DeathSounds overwrites from the desert shellmap 2020-05-09 14:36:50 -05:00
reaperrr
a68467292e Use TargetType.Invalid checks instead of IsValidFor 2020-05-09 17:59:23 +02:00
reaperrr
978c69d0c3 Make Warhead.IsValidTarget method protected
IsValidTarget is never called from outside warheads.
2020-05-09 17:59:23 +02:00
reaperrr
3eabc59921 Make resource warheads AirThreshold-aware 2020-05-09 17:59:23 +02:00
reaperrr
2b3d99fac2 Sanitize resource warheads
- Fix potential crash due to invalid target (no CenterPosition)
- Fix potential crash on multiple ResourceLayers
2020-05-09 17:59:23 +02:00
reaperrr
2bdefe0e9e Move AirThreshold to Warhead
To reduce duplication and for later use in more warheads.
2020-05-09 17:59:23 +02:00
reaperrr
de81fc2aca Minor CreateEffectWarhead optimization
Palette only matters if we actually display an explosion.
2020-05-09 17:59:23 +02:00
reaperrr
b514e0a6e7 D2k yaml comment removal
Naming the warhead for its purpose is cleaner
than comments, in my opinion.
2020-05-09 17:56:08 +02:00
reaperrr
715dfa4541 Use args in FireClusterWarhead methods
Instead of directly passing damage modifiers.
2020-05-09 17:56:08 +02:00
reaperrr
ac57a37224 DamageWarhead polish
Use BitSet.IsEmpty.
2020-05-09 17:56:08 +02:00
Paul Chote
afd620b092 Reimplement ClassicQuantizeFacing using a look-up-table. 2020-05-09 10:40:50 -05:00
Paul Chote
552bceb07c SpriteEffect facing -> WAngle. 2020-05-09 10:20:23 -05:00
Paul Chote
fe58ed1283 Animation facing -> WAngle. 2020-05-09 10:20:23 -05:00
Paul Chote
361e2d463c ISpriteSequence facing -> WAngle. 2020-05-09 10:20:23 -05:00
atlimit8
259c8d2c98 Merge ConditionManager trait directly into Actor 2020-05-09 15:46:11 +02:00
abcdefg30
e12c1dc9aa Retire the "release-20190314" path 2020-05-09 13:08:10 +01:00
abcdefg30
7fb49e383d Update and fix the latest update path and rules 2020-05-09 13:08:10 +01:00
Matthias Mailänder
1df3e28253 Initialize RangeModifiers. 2020-05-08 20:58:27 +02:00
Paul Chote
bacec2689d Remove error message duplication. 2020-05-08 15:17:44 +02:00
jrb0001
bf397591f9 Implement IPv6 support for server and direct connect 2020-05-08 15:17:44 +02:00
Matthias Mailänder
bd1a936c7a Add the armed technician. 2020-05-08 09:42:14 +02:00
Matthias Mailänder
0871d6e321 Setup the Firestorm civilian voices. 2020-05-08 09:42:14 +02:00
abcdefg30
265d296db6 Add infiltration sounds support to InfiltrateForSupportPowerReset 2020-05-05 15:16:09 -05:00
Matthias Mailänder
5ec136b57c Don't play the make animation on the wall sprite body. 2020-05-05 13:23:58 +02:00
atlimit8
f1e8f9c9d0 Fixed PNG frame count calculation
This fixes the order of operations and rounding issue, making it columns * rows.
2020-05-02 23:14:31 +02:00
Paul Chote
f03841c4e4 Hide selection decorations when spectators zoom too far out. 2020-05-02 14:30:04 -05:00
Pavel Penev
0ae58ff0ea Adjusted damage spread ranges on weapons in D2k to match the original game 2020-05-02 20:22:01 +01:00
Pavel Penev
390c1899ca Changed weapons in D2k to have a linear damage falloff to match the original game 2020-05-02 20:22:01 +01:00
Matthias Mailänder
89aa6d1e4e Don't attack during buildup. 2020-05-02 20:07:09 +01:00
Matthias Mailänder
24638b02a9 Fix turret build sounds. 2020-05-02 20:07:09 +01:00
Matthias Mailänder
4b0ab6ab37 Add the crumble overlay to the turrets. 2020-05-02 20:07:09 +01:00
Matthias Mailänder
1f02d9f141 Add the make animation for the turrets. 2020-05-02 20:07:09 +01:00
Matthias Mailänder
0103c38c13 Don't change the animation when it's not your turn. 2020-05-02 20:07:09 +01:00
Matthias Mailänder
3cc76f91b4 Fix the make animation for the silos. 2020-05-02 20:07:09 +01:00
abcdefg30
10dc248f07 Remove unused usings from BaseBuilderBotModule 2020-05-02 14:05:44 -05:00
abcdefg30
d1f89c6217 Update the Desc of GrantCondition 2020-05-02 14:05:44 -05:00
abcdefg30
76ba4fc32d Use a modular AI in soviet05 2020-05-02 14:05:44 -05:00
abcdefg30
37f90fff44 Throw LuaExceptions instead of InvalidDataExceptions in ConditionProperties 2020-05-02 14:05:44 -05:00
abcdefg30
9fa6da3bc7 Add PlayerConditionProperties 2020-05-02 14:05:44 -05:00
abcdefg30
aa8cf237ab Make Greece the owner of all starting actors in soviet05 2020-05-02 14:05:44 -05:00
Matthias Mailänder
c131728aa4 Give more context when crashing during .png sheet loading. 2020-05-02 13:26:06 -05:00
Paul Chote
2abd137494 Remove OpenRA.PostProcess.exe.
The LAA flag is now set when packaging
Windows release installers.
2020-05-02 17:26:54 +02:00
Paul Chote
90815ace59 Add a decoration glyph for friendly units in tunnels. 2020-05-02 16:16:16 +02:00
Matthias Mailänder
53d916d7f1 Add some basic error handling to png metadata writing. 2020-05-02 04:13:34 -05:00
reaperrr
2b4035979b Make all warheads use WarheadArgs
Instead of passing damageModifiers directly.
2020-05-02 03:09:18 +03:00
Matthias Mailänder
38cdc93010 Default the optional effect sequence to null 2020-05-01 19:43:36 +03:00
Matthias Mailänder
346dad3898 Remove trailing spaces. 2020-05-01 19:43:36 +03:00
Matthias Mailänder
42256bc262 Add an out of bounds check. 2020-05-01 19:41:06 +03:00
Matthias Mailänder
70babb4067 Validate the target before querying it's center position. 2020-05-01 16:53:29 +02:00
Matthias Mailänder
3603e6373d Check for invalid targets. 2020-04-30 01:42:19 -05:00
Matthias Mailänder
bd1760682f Rename WithNukeLaunch* traits to WithSupportPower*. 2020-04-30 01:37:05 -05:00
Matthias Mailänder
52d0490f95 Supersede INotifyNuke 2020-04-30 01:37:05 -05:00
Matthias Mailänder
b3b0aa75ae Add new interfaces for support powers. 2020-04-30 01:37:05 -05:00
Paul Chote
e42d177920 Include selection decorations when calculating ScreenMap bounds. 2020-04-30 00:09:57 +02:00
Paul Chote
c2156af7b0 Restore missing minelayer pips. 2020-04-29 22:59:48 +02:00
dnqbob
86394eb56c "FindEnemy" functions ignore hidden actors
(helped by reaperrr and abcdefg30)
2020-04-28 15:35:02 +02:00
dnqbob
2d7790f5e4 StateBase.cs modified:
1. Optimize & move "ammo" related function from "AirStates.cs" to StateBase.cs

2. Optimize & move "IsRearm" function from "AirStates.cs" to StateBase.cs, name changed to "IsRearming"

(optimized by reaperrr)
2020-04-28 15:35:02 +02:00
Matthias Mailänder
3df43529a6 Document BitSet<TargetableType> 2020-04-27 16:06:32 +02:00
Matthias Mailänder
a1c9b27057 Add InfiltrateForSupportPowerReset 2020-04-27 16:06:32 +02:00
abcdefg30
089dd233a5 Correct the support dir location in ExtractSettingsDocsCommand 2020-04-26 12:38:11 +01:00
Matthias Mailänder
86a7a0bd6c Move Render*Circle traits to their base traits. 2020-04-26 10:30:50 +02:00
Paul Chote
7ebca36a9c Disable debug callbacks on Intel HD 4000. 2020-04-25 21:03:43 +02:00
Paul Chote
d5aed5a88a Expose GL Profile in settings menu. 2020-04-25 21:03:43 +02:00
Paul Chote
dac1f270ce Restore legacy OpenGL 2.1 support. 2020-04-25 21:03:43 +02:00
Paul Chote
839be24053 Replace PreferGLES settings flag with GLProfile enum. 2020-04-25 21:03:43 +02:00
Paul Chote
91c4179f05 Split GLProfile from GLFeatures. 2020-04-25 21:03:43 +02:00
Matthias Mailänder
a4b427bfac Clarify AttackPanicChance and add PanicChance. 2020-04-24 18:38:54 +02:00
reaperrr
250f5bec18 Misc yaml style fixes 2020-04-24 18:22:35 +02:00
reaperrr
336e2a10e0 Fixed RA STNK turret not using fudged facings 2020-04-24 18:22:35 +02:00
reaperrr
b5e9b7635e MoveClassicFacingFudge update rule 2020-04-24 18:22:35 +02:00
reaperrr
0df7fa1596 Add sequence update rule support 2020-04-24 18:22:35 +02:00
reaperrr
c10487d635 Move ClassicFacingFudge support to Mods.Cnc
This moves the TD/RA-specific re-mapping of sprite facings
and coordinates to Mods.Cnc.
2020-04-24 18:22:35 +02:00
abcdefg30
bc9b3bef74 Fix a crash when completing objectives in Allies06 out of order 2020-04-23 21:56:46 +01:00
abcdefg30
e57462e7ca Make attack moving and guarding use a grouped order 2020-04-21 01:35:40 -05:00
abcdefg30
78bf27709f Add basic support for grouped orders 2020-04-21 01:35:40 -05:00
Matthias Mailänder
fc84cd9204 Add an is in world check to fix a crash. 2020-04-21 01:15:43 -05:00
Matthias Mailänder
e361f7b246 The category field has been pluralized. 2020-04-19 15:21:10 +02:00
Matthias Mailänder
b0497b7505 Fix double whitespace. 2020-04-19 15:21:10 +02:00
Zimmermann Gyula
a894e31fa5 Remove now obsolete tileset palette entry. 2020-04-19 15:21:10 +02:00
Matthias Mailänder
dd062adec2 Add descriptions as those are not obvious in this context. 2020-04-18 13:56:26 -05:00
Matthias Mailänder
d187575a2c Make support power icons configurable and testable. 2020-04-18 13:56:26 -05:00
teinarss
85096c4ba2 Update CoordinateTest to be compatible with new nunit version. 2020-04-18 11:36:25 -05:00
teinarss
e13fd693c3 Add Nuget packages for all dependencies 2020-04-18 11:36:25 -05:00
Mustafa Alperen Seki
cc35512472 Add a trait to reveal the whole map when conditions are met. 2020-04-18 10:49:25 -05:00
abcdefg30
4e548291ce Treat transit-only tiles as invalid locations for minelayers 2020-04-18 13:35:06 +01:00
abcdefg30
3ba86f329f Remove Game.HasInputFocus 2020-04-17 22:26:03 -05:00
Mustafa Alperen Seki
5b34af0f12 Change all instances of ToLower() to ToLowerInvariant() 2020-04-17 17:01:42 -05:00
Adam Mitchell
0a9eb1ff83 Fix units stuck on transit-only when resupplying 2020-04-17 11:13:46 +02:00
abcdefg30
942dd0e5f7 Adapt the utility commands to import crates as well 2020-04-17 10:52:59 +02:00
abcdefg30
400102f3d3 Remove a TODO about grey nod colors 2020-04-17 10:52:59 +02:00
abcdefg30
9ccdeb3d36 Set the wcrate and scrate sequences up 2020-04-17 10:52:59 +02:00
abcdefg30
7e0f0dd2d2 Add missing money crates to TD campaign missions 2020-04-17 10:52:59 +02:00
abcdefg30
d920cbb7f6 Move money crates to a default in the shared campaign rules 2020-04-17 10:52:59 +02:00
Paul Chote
417677e6f4 Work around and explain color picker conversion issue. 2020-04-17 10:41:08 +02:00
Paul Chote
33f3038316 Fix map-specific factions remaining selected when changing map. 2020-04-16 16:49:00 +02:00
Paul Chote
429dbe3e0c Block profiles with revoked keys from joining auth-only servers. 2020-04-16 16:43:10 +02:00
abcdefg30
471fc44751 Add more engineers to the wave in nod07
Otherwise buildings will only be damaged
2020-04-16 13:21:33 +02:00
abcdefg30
1b8e346307 Fix APC reinforcements in nod07a and b 2020-04-16 13:21:33 +02:00
abcdefg30
a456583a08 Fix a crash in nod07b 2020-04-16 13:21:33 +02:00
Paul Chote
a63c17baab Disable IP tooltip in skirmish games. 2020-04-15 23:16:24 +02:00
Paul Chote
9c4faddc0f Switch GeoIP database from MaxMind to IP2Location.
The IP2Location data is licensed under CC BY-SA, which
allows us to distribute the database with releases.
2020-04-15 23:16:24 +02:00
Paul Chote
6828c4c1e9 Fix long player locations overrunning the player tooltip. 2020-04-15 23:16:24 +02:00
Matthias Mailänder
80131e7ec0 Group readonly fields. 2020-04-15 21:42:50 +02:00
Matthias Mailänder
ac381a6f58 Allow multiple ResourceRenderer traits. 2020-04-15 21:42:50 +02:00
Matthias Mailänder
521b516bf9 Mark suggested fields as readonly. 2020-04-15 21:42:50 +02:00
netnazgul
6a825f8e60 Modify preset colors to not get flagged by color validator 2020-04-14 18:31:18 +02:00
Paul Chote
f0a243ca10 Fix mine layer desync.
World.FogObscures depends on the local RenderPlayer and should not
be used from simulation code!
2020-04-12 23:06:55 +02:00
Matthias Mailänder
e5457a3390 Allow wall renderers in mod code. 2020-04-11 16:29:00 +02:00
Matthias Mailänder
47e21f8bef Remove unused using. 2020-04-11 16:29:00 +02:00
Matthias Mailänder
331b854e4e Add a lint check for production bar types. 2020-04-10 21:00:26 +02:00
Matthias Mailänder
274bc9cbba Add missing sequence reference. 2020-04-10 20:56:54 +02:00
Matthias Mailänder
827f8d95b4 Remove unused using. 2020-04-10 20:56:54 +02:00
Matthias Mailänder
2946dd35d5 Spaces to tabs. 2020-04-10 20:14:39 +02:00
Matthias Mailänder
74d884787d Remove trailing tabs/spaces. 2020-04-09 22:32:05 +02:00
Matthias Mailänder
5516e16fb8 Make the default player color configurable in mod.yaml 2020-04-09 22:32:05 +02:00
reaperrr
cadf4eb322 Limit TS fona to temperate theater
Their art wasn't drawn with snow terrain in mind,
so no point in allowing to place them on snow maps.
2020-04-07 22:04:16 +02:00
Matthias Mailänder
269249e86e Fix the fona sequence definitions. 2020-04-07 22:04:16 +02:00
Matthias Mailänder
30f87d2308 Port some Translucent=yes from Art.ini 2020-04-07 22:00:31 +02:00
Zimmermann Gyula
8b7e72b95e Add three additional blending modes. 2020-04-07 22:00:31 +02:00
abcdefg30
1e64048956 Cache PlayerResources and unit cost in Resupply 2020-04-07 21:27:16 +02:00
abcdefg30
8512e696f5 Add Creeps as enemy in all D2k missions 2020-04-07 21:19:08 +02:00
abcdefg30
6a03a9ec5f Fix a yaml error in GDI08a 2020-04-07 20:59:17 +02:00
netnazgul
5e04c99d57 Fix tile errors on the map "Pie of Animosity" 2020-04-07 20:53:28 +02:00
Mustafa Alperen Seki
82f15491c0 Allow Engineers in RA to enter undamaged (Camo) PillBoxes. 2020-04-03 04:09:43 -05:00
Mustafa Alperen Seki
101843fbb7 Make EngineerRepairable conditional. 2020-04-03 04:09:43 -05:00
Zimmermann Gyula
9e534f3804 Add damagetypes to repairing. 2020-03-31 01:10:51 -05:00
Punsho
ca3cfc0184 RA Balance patch 2020-03-29 21:57:12 +02:00
Paul Chote
d62fb901e2 Fix actors with no footprint leaving stale data when deleted. 2020-03-29 21:10:45 +02:00
Matthias Mailänder
73a2b59c2c Add additional notification support to infiltration. 2020-03-29 12:00:16 -05:00
Paul Chote
2c7a56625c Move selectableActor check inside InputOverridesSelection. 2020-03-29 13:20:10 +02:00
Ivaylo Draganov
e2572b214f Adjust spacing and width in editor category dropdown 2020-03-28 20:41:03 +00:00
abcdefg30
d22cd3a74f Adjust the map visibility panel height 2020-03-28 20:41:03 +00:00
abcdefg30
0c8fcedfdf Start with randomized wind strength 2020-03-28 19:46:47 +01:00
Paul Chote
99009c37ce Fix and simplify WeatherOverlay:
- Fix rendering issues
- Track particles in world pixels instead of screen pixels
- Removed un/underused fade in/out support
- Update wind once per tick instead of once per particle
- Make Particle struct readonly
2020-03-28 19:46:47 +01:00
Paul Chote
d9f5771778 Make the right edge of the airfield transitable. 2020-03-28 19:13:14 +01:00
Paul Chote
d35b5070fb Fix minelayers leaking enemy mine positions through the fog. 2020-03-28 18:49:07 +01:00
Paul Chote
02f41f9afc Fix SpriteEffect updating twice in the first tick. 2020-03-28 17:12:25 +01:00
abcdefg30
c797aa1d5e Change syrf to syrd on the desert shellmap 2020-03-27 19:24:22 +01:00
Paul Chote
b2f7f67756 Fix and simplify ScrollPanelWidget thumb rect calculation. 2020-03-26 16:54:46 +01:00
dnqbob
09014ab6d5 transformation can pass exp to new actor 2020-03-26 02:04:44 -05:00
Matthias Mailänder
8f8747d65e Always show the building fake tags 2020-03-26 00:52:24 -05:00
Ivaylo Draganov
be19e137e2 Align lobby bits in the player tab in TD 2020-03-25 13:01:49 +01:00
Paul Chote
3155291064 Restore ability to configure RMB orders + RMB panning. 2020-03-25 12:36:21 +01:00
Paul Chote
a5b22e6a36 Remove text caching from CncLoadScreen.
We have repeatedly failed at invalidating these
cached values when things change, so the small perf
win is not worth the hassle.
2020-03-25 12:20:14 +01:00
Paul Chote
9c251e8b6a Fix detection circle line rendering. 2020-03-24 20:59:46 +01:00
Matthias Mailänder
6056568182 Remove unused terrain type. 2020-03-24 19:48:54 +01:00
Zimmermann Gyula
7b7c1da18d Add a shared parallel production queue. 2020-03-24 13:35:15 -05:00
Paul Chote
fb5b4b3547 Rename Defense button tooltip to Support. 2020-03-24 13:13:18 -05:00
Paul Chote
19918d485e Disable plugs when there are no sockets to place them. 2020-03-24 13:13:18 -05:00
Paul Chote
45c6c6ba10 Fix Waste Refinery bib. 2020-03-24 13:13:18 -05:00
Paul Chote
0e436bc686 Move plugs and superweapons to Building queue. 2020-03-24 13:13:18 -05:00
Ivaylo Draganov
b0dfea0a09 Adjust the stroke of the muted indicator glyph 2020-03-24 16:56:49 +01:00
Paul Chote
2c4e6c4188 Remove special-case rollover rendering. 2020-03-24 00:07:10 -05:00
Paul Chote
9f3254dbd1 Implement isometric selection boxes for TS structures. 2020-03-24 00:07:10 -05:00
Paul Chote
88cdad4189 Add support for polygon selection shapes. 2020-03-24 00:07:10 -05:00
Paul Chote
4ba50a4379 Remove IEquatable from ActorBoundsPair. 2020-03-24 00:07:10 -05:00
Paul Chote
2b6c104011 Update RA decorations. 2020-03-24 00:07:10 -05:00
Paul Chote
4b446d100e Update D2k decorations. 2020-03-24 00:07:10 -05:00
Paul Chote
f9ca2114a9 Update TS decorations. 2020-03-24 00:07:10 -05:00
Paul Chote
afc9c6ef85 Update TD decorations. 2020-03-24 00:07:10 -05:00
Paul Chote
ac200f6173 Rework decoration renderable traits:
- Removed implicit pip definitions and IPips interface.
  New decoration traits have been added to render them.
  Pip types are no longer hardcoded in OpenRA.Game.

- Decoration rendering is now managed by SelectionDecorations(Base),
  which allows us to remove assumptions about the selection box
  geometry from the decoration traits.

- RenderNameTag has been replaced by WithNameTagDecoration, which is
  an otherwise normal decoration trait.

- Unify the configuration and reduce duplication between traits.

- Removed hardcoded references to specific selection box renderables.

- Remove legacy cruft.
2020-03-24 00:07:10 -05:00
Paul Chote
73a78eadb1 Move Interactable and Selectable to Mods.Common. 2020-03-24 00:07:10 -05:00
Matthias Mailänder
c5139fb6c2 Remove the hard-coded ban of placing buildings on resources. 2020-03-23 23:48:33 -05:00
Paul Chote
9faf9aa1b9 Replace deprecated native OpenAL with OpenAL Soft on macOS. 2020-03-23 11:13:31 +01:00
unknown
3c2e9be248 Add gdi09ea 2020-03-21 21:09:52 +01:00
Matthias Mailänder
5b59f6612f Remove .lua scripts from the .NET solution file. 2020-03-21 17:30:26 +00:00
abcdefg30
3d69363f35 Add support for destroying enemy carryalls 2020-03-21 10:58:17 +01:00
abcdefg30
b580b4fd33 Add support for an announcement function for carryall reinforcements 2020-03-21 10:58:17 +01:00
abcdefg30
74f86d70f8 Add Ordos06a 2020-03-21 10:58:17 +01:00
abcdefg30
3959104f9b Let VS2019 remove a duplicate line from the solution 2020-03-21 10:58:17 +01:00
Paul Chote
1ff037a257 Remove invalid caching from GCOT. 2020-03-20 17:43:24 +01:00
abcdefg30
32700df117 Fix the settings tooltip container being overwritten ingame 2020-03-20 16:06:06 +01:00
Matthias Mailänder
b4edec215e Fix spy ignoring the target's faction. 2020-03-19 23:11:38 +01:00
Michael Silber
dffa1e45f4 Add gdi08a 2020-03-17 19:04:36 +01:00
Paul Chote
df3b6dde34 Update macOS launcher to fix "View Logs" button. 2020-03-16 20:15:58 +01:00
Matthias Mailänder
834bbf467e Make GlobalLightingPaletteEffect public 2020-03-16 11:10:30 +01:00
Paul Chote
4d4f94208e Cache CandidateMovementCells within the same tick. 2020-03-12 17:07:14 +01:00
Paul Chote
416713de0c Fix infantry switching subcells and blocking eachother while moving. 2020-03-11 15:40:12 +01:00
Paul Chote
c523ca8efe Fix FreeSubCell ignoring preferred subcell requests. 2020-03-11 15:40:12 +01:00
Paul Chote
9acea56108 Fix pathing across transit-only cells. 2020-03-11 15:40:12 +01:00
Paul Chote
44a7422375 Fix variable naming in Locomotor. 2020-03-11 15:40:12 +01:00
abcdefg30
0d0e7eb179 Fix aircraft not taking off properly 2020-03-08 17:20:39 +01:00
abcdefg30
ea6c840343 Fix the panic chance calculation in ScaredyCat 2020-03-08 16:33:23 +01:00
abcdefg30
d2db0913ac Fix the missle jamming chance calculation 2020-03-08 16:33:23 +01:00
Punsho
3721dae74d Making missiles properly go over terrrain and track air units 2020-03-07 13:00:28 +01:00
Matthias Mailänder
9050a2447b Add remappable support to production icons. 2020-03-04 22:02:30 +01:00
abcdefg30
df4c363e9c Notify blockers upon paradropping 2020-03-03 20:51:39 +00:00
abcdefg30
a909a3e692 Ignore self and actors not at ground level in Parachutable.OnLanded 2020-03-03 20:51:39 +00:00
abcdefg30
dd26253905 Fix the IgnoreActor check in Parachutable 2020-03-03 20:51:39 +00:00
abcdefg30
69b7ba2d22 Fix NREs in ProductionParadrop 2020-03-03 20:51:39 +00:00
Paul Chote
d2f306e488 Fix GetActorsAt(CPos, SubCell) with special-case subcells.
If given FullCell or Any we should be returning actors in
any subcell, not none.
2020-03-03 20:06:51 +01:00
Paul Chote
4a6fefa434 Disable idle scanning on RA planes. 2020-03-02 22:22:56 +01:00
Paul Chote
16e0ea611e Revert "Fix AttackFollow ignoring allowMove flag when auto-targeting."
This reverts commit 3e116060cf.
2020-03-02 22:22:56 +01:00
Paul Chote
05a2e77be2 Add support for uncompressed databases. 2020-03-02 17:29:30 +01:00
Paul Chote
dd2fa36261 Fix invalid channel server crash. 2020-03-02 17:29:30 +01:00
abcdefg30
5fa1dec6d8 Fix a crash in --clear-invalid-mod-registrations 2020-03-02 17:26:34 +01:00
Paul Chote
f86d96794d Add explicitly defined version strings to the lua docs. 2020-03-02 17:24:17 +01:00
Paul Chote
304307df5a Fix wiki script again. 2020-03-01 16:41:19 +00:00
Paul Chote
c8856749f3 Only update the wiki from the Linux host. 2020-03-01 16:10:07 +00:00
Paul Chote
ce91c5a76f Fix WithDisguisingInfantryBody idle animation crash. 2020-03-01 14:43:12 +01:00
Paul Chote
e6314a944c Round dropdown arrow position to an integer pixel. 2020-03-01 14:41:17 +01:00
Paul Chote
93d006e14e Fix incorrect end point rendering in DrawConnectedLine. 2020-02-29 18:13:54 +01:00
Paul Chote
d73ed7670a Port missions to the new Paratroopers API. 2020-02-29 16:07:24 +01:00
Paul Chote
c0587cc568 Introduce ActivateParatroopers Lua API.
SendParatroopers and SendParatroopersFrom are now deprecated.
The paratrooper actors themselves can be accessed using the
Trigger.OnPassengerExited trigger.
2020-02-29 16:07:24 +01:00
Paul Chote
ed415cb637 Remove deprecated *Upgrade Lua API methods. 2020-02-29 16:07:24 +01:00
abcdefg30
a10deddf53 Update the Lua API 2020-02-28 18:48:05 +01:00
abcdefg30
a5bc841355 Ignore the types of an exit when the production type is null or empty 2020-02-28 18:48:05 +01:00
Paul Chote
41657dd291 Allow spectators to be kicked after the game starts. 2020-02-28 00:04:49 +01:00
abcdefg30
a7d5b7b8b0 Fix FreeActorWithDelivery not being properly conditional 2020-02-27 18:50:51 +01:00
reaperrr
eb007fc43c Add Frames support to Combine 2020-02-27 18:44:34 +01:00
Paul Chote
301d09ea8f Remove undefined RequiresForceMove from TransformsIntoTransforms. 2020-02-27 18:42:48 +01:00
Paul Chote
ac46b4b791 Fix transparent pixels in Mobile Flack icon. 2020-02-27 00:11:39 +01:00
Paul Chote
fb7c781a66 Add multi-resolution mod icon support. 2020-02-26 23:47:15 +01:00
Paul Chote
e5309ee586 Remove unused InstalledMods.Icons cache. 2020-02-26 23:47:15 +01:00
Paul Chote
84df61c672 Add multi-resolution badge support. 2020-02-26 23:47:15 +01:00
Paul Chote
de4a7cecf0 Rework multi-resolution sprite handling:
- Sprite.Bounds now refers to rectangles in the source image.
  Use this when copying pixels, etc.
- Sprite.Size now refers to sizes in effective pixel coordinates.
  Use this when rendering.
- Sheet.DPIScale has been removed.
- "Density" term is introduced to refer to the number of artwork
  pixels per effective pixel.
2020-02-26 23:47:15 +01:00
abc013
c0ece00c4b Prevent production cycling when producing actor does not occupy space 2020-02-26 23:25:41 +01:00
Paul Chote
6ba02800ab Add TransformsIntoTransforms to enable queued MCV redeploy. 2020-02-24 12:56:49 +01:00
Paul Chote
84419e4259 Add queued argument to CanIssueDeployOrder. 2020-02-24 12:56:49 +01:00
Paul Chote
2016ab105e Fix Reverses parsing. 2020-02-23 16:41:57 +01:00
Paul Chote
def65b10bd Don't crash with an unhelpful IndexOutOfRangeException. 2020-02-23 16:41:57 +01:00
Matthias Mailänder
31d98cc802 Reduce the electro death loop length. 2020-02-23 16:41:57 +01:00
Matthias Mailänder
ccbaa4f816 Setup the original laser zap death animation. 2020-02-23 16:41:57 +01:00
Matthias Mailänder
2049d1b26a Allow guessing of sprite sequence length from number of frames. 2020-02-23 16:41:57 +01:00
Matthias Mailänder
15f8469272 Use the original elongated tesla zap death animation. 2020-02-23 16:41:57 +01:00
Matthias Mailänder
43cac2f051 Don't complain about shadow frame length when there are none. 2020-02-23 16:41:57 +01:00
Matthias Mailänder
39b7db2703 Allow repetition of frames in sequence setups. 2020-02-23 16:41:57 +01:00
Paul Chote
d3291ea585 Fix script error in ordos05. 2020-02-23 11:03:23 +01:00
Ivaylo Draganov
2e8740d6a8 Change default hotkey bindings for select and cycle production buildings 2020-02-22 20:06:21 +00:00
Ivaylo Draganov
1bcad55c1f Add a hotkey to select the current production facility 2020-02-22 20:06:21 +00:00
Paul Chote
7ffc689037 Fix TD panel-transparent definition. 2020-02-22 12:39:11 -06:00
Paul Chote
7d17916e3f Load badges on the main thread. 2020-02-22 19:19:20 +01:00
abcdefg30
e877bb1206 Fix GrantConditionOnProduction not using ShowSelectionBar 2020-02-22 18:05:40 +00:00
reaperrr
226159d220 AttackBase ResolveOrder optimization
Only check for "Stop" when the other 'if' didn't apply.
2020-02-22 17:56:47 +00:00
reaperrr
da4ed24064 Mobile ResolveOrder optimization
When the order is "Move", the other two 'if' checks
are redundant, so 'else if' makes more sense here.
2020-02-22 17:56:47 +00:00
reaperrr
b524dc9b72 Carryall ResolveOrder optimization
There can be only one OrderString at a time,
so we make 'PickupUnit' an "else if", too.
2020-02-22 17:56:47 +00:00
reaperrr
1e43a8f590 Minor Aircraft ResolveOrder optimization
Streamline RTB if checks.
2020-02-22 17:56:47 +00:00
Matthias Mailänder
805a8fc556 Specify unicode without BOM as standard. 2020-02-22 18:44:10 +01:00
Robert
885931ae74 Run every color validation together
This ensures that color picks that have multiple issues will
have them all checked at the same time, including ensuring that
the fix for one issue doesn't cause another issue.

Handling of the onError action has been changed from being called
at once to collecting the potential errors in a HashSet to deduplicate
them and then calling onError after a valid color has been found.
(Otherwise you would in the worst case get 256 error messages logged!)
2020-02-22 16:31:29 +00:00
Robert
4d4f1d6068 Avoid null vectors when making colors valid
If the picked color and a forbidden color are identical (like
if they both picked the same palette color and in the special case
when a picked color is outside of the allowed range and the method
returns the picked color as the forbidden color),
the vector between them is zero and the maths for adjusting
the color fails by hitting the iteration limit. This changes
the zero vector to the smallest possible vector in order to
avoid the issue.

This can result in some seriously close adjustments in the case of
picking identical palette colors, which might
be undesirable compared to picking a new palette color.
2020-02-22 16:31:29 +00:00
Robert
fafa219d11 Added error message if color could not be adjusted
The failsafe in ColorValidator aborts after 255 iterations of
adjusting the color and picks a random color. This message makes it
clearer to the user. Results in two messages being displayed,
first one about adjusting and the about a random color pick.
2020-02-22 16:31:29 +00:00
Paul Chote
eae287efc3 Fix travis packaging. 2020-02-22 10:28:48 -06:00
Paul Chote
8903577227 Update native libraries shipped in the AppImages:
* SDL2 reverted back to 2.0.8 (2.0.9 and 2.0.10 generate compilation
  errors so are missing from the libs tarball)
* Package Freetype 2.0.10
2020-02-22 10:28:48 -06:00
Matthias Mailänder
103cb61020 Add a new rallypoint established notification. 2020-02-22 17:16:17 +01:00
Ivaylo Draganov
1dd1786469 Reduce duplication of "Battlefield Control" chat line label 2020-02-22 15:58:00 +00:00
Ivaylo Draganov
3e2022a3dd Allow players to mute shellmap background music 2020-02-22 15:50:01 +00:00
Paul Chote
28f7604172 Reset nextScanTime only when actually scanning for targets. 2020-02-22 16:30:07 +01:00
Paul Chote
96463634c7 Add --debug-chrome-regions utility command. 2020-02-22 16:18:45 +01:00
Paul Chote
01f5ecb2f9 Fix save game loading screen stripe bounds. 2020-02-22 16:14:32 +01:00
reaperrr
d835090d0b Move LCWCompression support to Mods.Cnc 2020-02-22 15:40:37 +01:00
reaperrr
c687600d66 Duplicate part of LCWCompression to VqaReader
Duplicates the part needed by the VqaReader,
so we can move LCWCompression to Mods.Cnc
ahead of VQA (which has some additional prerequisites).
2020-02-22 15:40:37 +01:00
reaperrr
ed618c807d Streamline LCWCompression code
Just making it more concise to reduce line count.
No functionality/efficiency changes.
2020-02-22 15:40:37 +01:00
Paul Chote
85faa5edf6 Add visual indicator when the game is muted. 2020-02-22 14:42:11 +01:00
Paul Chote
3f601e1ec1 Update color picker hue slider when the color changes. 2020-02-22 14:00:12 +01:00
teinarss
9d68b815a1 Fix tooltip in Observer widgets 2020-02-22 11:38:53 +01:00
teinarss
cffe5e3d9d Add owner token to TooltipContainer 2020-02-22 11:38:53 +01:00
Paul Chote
7e72cd262c Fix FlyAttack invalid target crash. 2020-02-19 23:35:16 -06:00
Paul Chote
9a6602656b Ignore nearEnough if we think the actor can get closer. 2020-02-18 19:37:17 +01:00
Matthias Mailänder
57da756f2f Set the camera pitch to 30° 2020-02-18 00:49:04 +01:00
abcdefg30
40bb45a02b Deprecate the release-20181215 path 2020-02-17 20:14:56 +00:00
abcdefg30
f73d23661f Update the update paths for release-20200202 2020-02-17 20:14:56 +00:00
Paul Chote
09a019f9c6 Add a lint check for LockFaction on mission players. 2020-02-16 20:51:29 +01:00
Paul Chote
4ec258cbdd Add missing LockFaction definitions to nod09, 10a, 10b. 2020-02-16 20:51:29 +01:00
Paul Chote
41d7a2d429 Fix an integer overflow when calculating selection priorities. 2020-02-16 17:57:04 +01:00
abcdefg30
7cec1b771d Fix Actor.CurrentActivity bogusly pointing to finished activities 2020-02-16 16:58:06 +01:00
abcdefg30
b1b74c13c3 Ensure that we never tick an activity before calling OnFirstRun 2020-02-16 16:58:06 +01:00
abcdefg30
c4a5540bfd Ensure that we never run Done child activities 2020-02-16 16:58:06 +01:00
abcdefg30
abcb2ea512 Directly mark queued activities that are cancelled as Done 2020-02-16 16:58:06 +01:00
Paul Chote
f45dd24781 Update AppImage SDL2 dependency to 2.0.10. 2020-02-16 14:53:42 +01:00
Paul Chote
8d23994a04 Update Windows SDL2 dependency to 2.0.10. 2020-02-16 14:53:42 +01:00
Paul Chote
46e0b3b363 Update macOS SDL2 dependency to 2.0.10. 2020-02-16 14:53:42 +01:00
Paul Chote
689049cc12 Fix NRE in ArmyUnit constructor. 2020-02-16 13:57:19 +01:00
Paul Chote
1485194ef3 Automatically scale DPI under Linux. 2020-02-16 13:44:50 +01:00
Paul Chote
4203a3191f Overhaul macOS packaging:
- Build on Travis-CI macOS VM
- Sign and notarize for distribution
- Create macOS-specific files from generic sources during packaging
- Add volume icon
- Rename osx directory to macos
2020-02-15 18:51:21 +01:00
Paul Chote
7b4019577d Force disable glDebugMessageCallback on Linux+AMD. 2020-02-15 11:38:30 +01:00
Paul Chote
52f4e24e22 Fix spectator minimap not updating when in "Disable Shroud" view. 2020-02-14 23:07:31 +01:00
Paul Chote
ab196a23e6 Fix AttackFollow ignoring allowMove flag when auto-targeting. 2020-02-14 17:30:38 +01:00
Paul Chote
3a688e03f0 Add multiple levels of fallback. 2020-02-12 21:17:39 +00:00
Paul Chote
a43335c7b0 Restore transient blocker check in pathfinding queries. 2020-02-12 21:17:39 +00:00
Paul Chote
585b8dc13c Set default rally point to an empty path. 2020-02-09 16:52:22 +01:00
Paul Chote
b2f0ac15e8 Generalize RallyPointInfo.Offset to support arbitrary length paths. 2020-02-09 16:52:22 +01:00
Paul Chote
9dc4ea8541 Fix production door not closing if the actor stays on the exit cell. 2020-02-09 16:52:22 +01:00
teinarss
817f75c808 Add unique ingame-observer.yaml for D2K 2020-02-09 16:37:21 +01:00
teinarss
7e3830e053 Updated production spec widget to handle overflow 2020-02-09 16:37:21 +01:00
teinarss
b81ede2d64 Added widget showing the army for players in spec 2020-02-09 16:37:21 +01:00
Mustafa Alperen Seki
6ab0ace9e1 Add PlayLaunchSounds() to SupportPowers which are missing it. 2020-02-09 13:34:46 +01:00
Paul Chote
85a5b6cc17 Fix subcell crusher logic. 2020-02-09 13:18:57 +01:00
Ivaylo Draganov
62af58c2e6 Calculate position of dropdown arrow glyph based on image width 2020-02-09 12:53:30 +01:00
abcdefg30
aeacc86028 Remove a loop closure guard variable 2020-02-09 12:18:09 +01:00
abcdefg30
5c4ec1bf0e Fix a crash when a SourceActor does not occupy space 2020-02-09 12:18:09 +01:00
abcdefg30
e3f545cae9 Make WarheadArgs.Source nullable 2020-02-09 12:18:09 +01:00
Paul Chote
71cbfc5968 Change default player color to dark red. 2020-02-08 20:09:02 +01:00
Paul Chote
fdc3a6a32d Change default name from Newbie to Commander. 2020-02-08 20:09:02 +01:00
Paul Chote
e6c1356d59 Add introduction prompt on first run. 2020-02-08 20:09:02 +01:00
Paul Chote
e8df28c518 Extract sysinfo logic to its own class. 2020-02-08 20:09:02 +01:00
Martin Bertsche
98aef70e88 Added display selection option to settings for fullscreen modes. 2020-02-08 18:14:35 +00:00
abcdefg30
de0bb9ee39 Fix a crash in the ReplaceAttackTypeStrafe update rule 2020-02-06 21:52:46 +00:00
tovl
c18857f15d Let immovable actors block individual minefield cells. 2020-02-06 22:26:15 +01:00
Paul Chote
9a0916afbb Add UI Scale dropdown to the settings menu. 2020-02-04 19:56:15 +01:00
Paul Chote
6388a6bff4 Add Graphics.UIScale setting to modify UI size. 2020-02-04 19:56:15 +01:00
Paul Chote
ce445f993c Add SupportDir argument to the launch-dedicated scripts. 2020-02-04 00:21:52 +01:00
Paul Chote
0e39c98989 Ignore empty support directory overrides. 2020-02-04 00:21:52 +01:00
Paul Chote
c2bc313bf0 Fix key repeat events queueing many deploy/scatter/stop orders. 2020-02-01 13:18:04 +01:00
Paul Chote
5c76a6e7a7 Fix key up events queueing duplicate deploy/scatter/stop orders. 2020-02-01 13:18:04 +01:00
Matthias Mailänder
1e8912b4e4 Fix the namespace. 2020-02-01 02:42:25 +01:00
abcdefg30
6cc27eaa76 Fix the description of VeteranProductionIconOverlay 2020-01-31 13:55:56 +01:00
Ivaylo Draganov
1020a7bfab Use common notice colors for UPnP status labels 2020-01-31 00:50:25 +01:00
Ivaylo Draganov
b80928bd95 Display a confirmation prompt on settings panel reset 2020-01-30 23:06:49 +01:00
abcdefg30
a6371f6fa9 Fix mission specific buildings not granting prerequisites 2020-01-29 20:59:45 +00:00
Paul Chote
bf314fdc7b Define window size in effective pixel coordinates. 2020-01-26 20:22:49 +01:00
Paul Chote
f0033c44c7 Use full window resolution on Windows. 2020-01-26 20:22:49 +01:00
Paul Chote
fd64ad7c89 Support rendering at non-integer display scales:
* 2x and 3x DPI artwork can be specified using
  Image2x and Image3x in chrome.yaml.
* Images are rendered using bilinear interpolation.
* For non-integer screen scales, prefer downscaling
  the next biggest resolution image over upscaling.
2020-01-26 20:22:49 +01:00
Paul Chote
809b1507a6 Fix font rendering at non-integer display scales. 2020-01-26 20:22:49 +01:00
Paul Chote
d91495a041 Allocate 1px empty margin between sprites. 2020-01-26 20:22:49 +01:00
Paul Chote
84daf890d3 Use antialiasing filter when rendering world annotations. 2020-01-26 20:22:49 +01:00
Paul Chote
1bc6fb0f46 Use antialiasing filter when rendering UI icons and actors. 2020-01-26 20:22:49 +01:00
Paul Chote
1f849e9f7d Add antialiasing support for paletted sprites. 2020-01-26 20:22:49 +01:00
Paul Chote
bd4724842c Fix software cursor rendering at fractional scales. 2020-01-26 20:22:49 +01:00
Paul Chote
25a7299c67 Fix scroll event position calculation. 2020-01-26 20:22:49 +01:00
Paul Chote
518450cd8a Extract load screen sheet handling into a superclass. 2020-01-26 20:22:49 +01:00
Paul Chote
57a8cf7a59 Rework Display settings tab. 2020-01-26 17:11:45 +01:00
Paul Chote
83732f299b Add DropDownButtonWidget.PanelAlign. 2020-01-26 17:11:45 +01:00
Paul Chote
f730b55255 Move hardware cursor control to hidden DisableHardwareCursors setting. 2020-01-26 17:11:45 +01:00
Paul Chote
370f7a44fa Restore cursor doubling for "default" cursor. 2020-01-26 17:11:45 +01:00
Paul Chote
f7e5111123 Apply cursor doubling setting without requiring a restart. 2020-01-26 17:11:45 +01:00
Paul Chote
847db5e59b Merge HardwareCursor and SoftwareCursor into CursorManager. 2020-01-26 17:11:45 +01:00
Mustafa Alperen Seki
d7f43b33c7 Make GrantConditionOnAttack PausableConditional 2020-01-26 17:05:02 +01:00
Paul Chote
3a6d88cfef Align settings to the standard row height. 2020-01-26 16:52:14 +01:00
Paul Chote
70f899c8d1 Remove unused localization options from settings.yaml. 2020-01-26 16:52:14 +01:00
Paul Chote
e138afc328 Overhaul Input settings. 2020-01-26 16:52:14 +01:00
Paul Chote
a84c914317 Move highlighting logic into a dedicated widget. 2020-01-26 16:52:14 +01:00
Paul Chote
46d59eef5e Update TD cash glyphs. 2020-01-25 22:02:43 +01:00
Paul Chote
79d25b9eca Update RA cash glyphs. 2020-01-25 22:02:43 +01:00
Paul Chote
cc530649c7 Fix horizontal positioning of dropdown arrow glyph. 2020-01-25 21:56:02 +01:00
abcdefg30
aeb623498f Remove old update rules 2020-01-25 21:29:36 +01:00
Mustafa Alperen Seki
d4b08850f3 Fix conditionality of DisguiseTooltipInfo. 2020-01-25 17:28:15 +02:00
Paul Chote
1fada0f2b4 Add KHR suffix as defined by the KHR_debug spec. 2020-01-25 13:44:06 +01:00
Paul Chote
b08f9886be Add Graphics.DisableGLDebugMessageCallback setting. 2020-01-25 13:44:06 +01:00
reaperrr
46384d25f2 Improve Rectangle HitShape debug overlay
Showing vertical sides, too.
2020-01-25 13:38:35 +01:00
reaperrr
9dcba8710b Add turret-linking support to HitShape
Allows to link a HitShape to the
position and facing of a turret.
2020-01-25 13:38:35 +01:00
reaperrr
b839204c7f Minor WithInfantryBody reorganisation
Move PlayStandAnimation to a more suitable position
inside the file.
2020-01-25 13:26:25 +01:00
reaperrr
595b6c8923 Greatly simplified WithInfantryBody TickIdle code
There was a lot of redundancy and unnecessary
complexity in several checks.

This now also prevents infantry from randomly
restarting and potentially switching between stand
sequences if there are no idle sequences.
Old behavior can still be replicated by listing
stand sequences as IdleSequences.
2020-01-25 13:26:25 +01:00
Ivaylo Draganov
9474bdba5c Use proper glyph for in-game chat close button 2020-01-25 13:17:09 +01:00
abcdefg30
f5aa304e09 Add stray update rules to the correct path 2020-01-25 10:48:50 +00:00
Pavel Penev
93bec9e430 Updated the default mods' weapons 2020-01-24 13:09:37 +01:00
Pavel Penev
d33a5bf94e Added an UpgradeRule CreateScreenShakeWarhead 2020-01-24 13:09:37 +01:00
Pavel Penev
b00154e2bc Created ShakeScreenWarhead and removed the hardcoded shaking from NukeLaunch and MadTank 2020-01-24 13:09:37 +01:00
reaperrr
6220d7e62e Introduce WarheadArgs
- Passes additional arguments to warheads on impact
- Uses that to reduce parameter count of DoImpact by 1
2020-01-21 19:31:34 +01:00
Paul Chote
fdc0a6e2b9 Rework TS Chrome in preparation for UI scaling. 2020-01-19 20:36:59 +01:00
Paul Chote
f37d9a7010 Rework D2k Chrome in preparation for UI scaling. 2020-01-19 20:34:18 +01:00
abcdefg30
9f66e3936d Add issue templates for the new issue template chooser 2020-01-19 17:27:43 +01:00
Paul Chote
f1325e12d4 Extract text contrast radius to ChromeMetrics and reduce to 1px. 2020-01-19 17:18:22 +01:00
Paul Chote
7611449d3d Reimplement text contrast using greyscale dilation. 2020-01-19 17:18:22 +01:00
abcdefg30
15b2d6b9e0 Let all Positionable traits notify visual position changes 2020-01-18 23:07:23 +00:00
Paul Chote
d0f44143c2 Fix activity cancellation on FlyAttack RTB.
* AbortOnResupply will now cancel queued activities
  in addition to the current attack.
* Resupply if no ammo is available during a standard attack.
* Don't resupply (move directly to target) if no ammo is available
  during an attack move (C&C3 style).
2020-01-18 16:38:53 +01:00
Paul Chote
51870a471a Add AttackSource enum. 2020-01-18 16:38:53 +01:00
Paul Chote
6f52365f9d Don't run NextActivity if it has been canceled. 2020-01-18 16:38:53 +01:00
Paul Chote
66b8689957 Use 32bit modcontent cursor. 2020-01-17 16:49:58 +01:00
Paul Chote
4fd475f7c2 Add RGBA cursor support. 2020-01-17 16:49:58 +01:00
Paul Chote
522861e484 Support 32 bit png sprites. 2020-01-17 16:49:58 +01:00
Paul Chote
1111ce4754 Add support for 32 bit BGRA sprites. 2020-01-17 16:49:58 +01:00
Paul Chote
cdbee49280 Fix slider ticks in TD. 2020-01-17 13:42:51 +01:00
reaperrr
aa63696933 Update rule for WithPermanentInjury removal 2020-01-16 22:56:39 +01:00
reaperrr
10540839f6 Make crippled TS Cyborgs use permanent TakeCover
This is more in line with original behavior.
Also allows us to remove WithPermanentInjury.
2020-01-16 22:56:39 +01:00
reaperrr
a9eca2cf54 Add support for enabling prone state permanently
Negative ProneTime now activates prone state
permanently as soon as the trait is enabled.
2020-01-16 22:56:39 +01:00
Paul Chote
d6436858a9 Fix IPAddress capitalization. 2020-01-15 12:12:54 +01:00
Paul Chote
38cb818469 Anonymise client IPs and allow server operators to disable sharing. 2020-01-15 12:12:54 +01:00
Paul Chote
422cc2b0d0 Hide location and IP labels if not known. 2020-01-15 12:12:54 +01:00
Paul Chote
d74a5065b9 Require GeoLite2 database path to be specified by the server operator. 2020-01-15 12:12:54 +01:00
Paul Chote
6b2c019caa Evaluate player location on the server. 2020-01-15 12:12:54 +01:00
Paul Chote
c430884c8b Require GeoLite2 database path to be specified by the server operator. 2020-01-15 12:12:54 +01:00
Matthias Mailänder
8dda6d8e3d Remove unnecessary null check. 2020-01-14 22:08:57 +01:00
Matthias Mailänder
c43d581e7f Add cursor palette support to GIMP/Jasc palette definitions. 2020-01-14 22:08:57 +01:00
teinarss
f0b69f8b8d Separated resource rendering into another trait 2020-01-14 19:38:47 +01:00
Matthias Mailänder
0e93d85273 Move the AssetBrowserFileEndingsFilter to IGlobalModData
to avoid mods having to duplicate the whole chrome layout.
2020-01-13 13:46:34 +01:00
Paul Chote
adb3c8e39c Split fixed-wing attack and strafe attack types. 2020-01-12 21:06:35 +01:00
tovl
85bc843554 Fix aircraft failing to engage targets within range. 2020-01-12 21:06:35 +01:00
Matthias Mailänder
c95216cd19 Move the hard-coded shroud palette to the C&C folder. 2020-01-12 19:35:41 +00:00
Paul Chote
cc05621c10 Draw editor terrain/resource preview as part of the world. 2020-01-12 18:30:50 +01:00
Paul Chote
e74033bded Render editor actor previews as part of the world. 2020-01-12 18:30:50 +01:00
Paul Chote
fe25fdf0ff Improve robustness of editor actor cell checks. 2020-01-12 18:30:50 +01:00
Paul Chote
1282650274 Rework RA Chrome in preparation for UI scaling. 2020-01-12 18:16:41 +01:00
Paul Chote
d622015b59 Fix Texture.GetData under GLES. 2020-01-12 17:04:23 +01:00
Paul Chote
524e8875d0 Restore MODIFIER_OVERRIDES handling of unmodified attack move hotkey. 2020-01-12 16:33:35 +01:00
Paul Chote
8c2a2d2cb8 Rework TD/modcontent chrome in preparation for UI scaling. 2020-01-12 15:52:12 +01:00
abcdefg30
a28992aa38 Default LocalClientId in ReplayConnection to -1
We do not have a local client in replays.
This change prevents anything from accidentally using (sometimes there might be clients with ID 0 present).
2020-01-12 14:23:34 +01:00
Paul Chote
0db4085950 Load and save registrations to both the active and legacy support directories. 2020-01-12 14:10:23 +01:00
Paul Chote
f162d90e9f Rework support dir initialization. 2020-01-12 14:10:23 +01:00
abcdefg30
abfb28a4f3 Fix the Build function in gdi04b 2020-01-12 14:04:51 +01:00
abcdefg30
c15a555cff Fix cargo initialisation 2020-01-12 13:58:04 +01:00
abcdefg30
e1c07d32d5 Prevent cell triggers in sarin-gas-2 from firing several times 2020-01-12 13:49:25 +01:00
tovl
fbfef903ac Let movement trigger visibility recalculation. 2020-01-12 04:50:25 +01:00
tovl
695d9a6cb1 Centralize shroud changes in one pass to improve performance. 2020-01-12 04:50:25 +01:00
Paul Chote
0106ed3669 Restore red lines for harvester targets. 2020-01-12 04:08:59 +01:00
abcdefg30
ac42dd79ca Make the command bar directly check if a GuardOrderGenerator is active 2020-01-12 00:54:38 +00:00
abcdefg30
deffc2dd15 Add support for defining the palette of WithResourceLevelOverlay 2020-01-12 00:47:20 +00:00
reaperrr
bb1d5f1d5c Fix ReloadAmmoPool.ResetFire ignoring multipliers 2020-01-11 23:29:37 +00:00
teinarss
43eabdf54a Fix naming in editor 2020-01-11 22:03:26 +00:00
tovl
0e32cbee5e Fix crash in RallyPointIndicator. 2020-01-11 21:26:47 +00:00
reaperrr
308c64c7b1 Fix trait order issues with KillsSelf 2020-01-06 21:47:53 +00:00
reaperrr
16c2062d9d Replace LandOnCondition with landing when paused 2020-01-06 21:47:53 +00:00
reaperrr
ac44367440 Refactor Spin to MaximumSpinSpeed
Additionally, add descriptions to
other FallsToEarth properties.
2020-01-06 21:47:53 +00:00
reaperrr
20beb4abe1 Fix Harpy husk rotor offset 2020-01-06 21:47:53 +00:00
reaperrr
a369634ea8 Display EMP effect on EMP'd aircraft's husks
When EMP'd while airborne.
2020-01-06 21:47:53 +00:00
reaperrr
7a095f30ec Make TS aircraft crash when EMP'd mid-air
And refuse move orders if EMP'd while landed.
Matches original behaviour.
2020-01-06 21:47:53 +00:00
Punsho
59bcac410f Make EMP effect carryall and orca transport 2020-01-06 21:47:53 +00:00
reaperrr
4499343ed2 Make Aircraft actually pausable/disableable
This commit makes aircraft
- ignore any aircraft-specific orders while disabled
- show blocked move cursor while paused
- set speeds to zero while paused or disabled
2020-01-06 21:47:53 +00:00
reaperrr
4b006bc484 Make Aircraft PausableConditional
Note: This commit only does the minimum changes
to implement PausableConditional, there are no
logic changes yet (like disabling movement on PauseOnCondition).
2020-01-06 21:47:53 +00:00
abcdefg30
23b3c237b7 Update the year numbers in all license headers to 2020 2020-01-05 17:00:34 +00:00
Matthias Mailänder
e33cf8a8ae Fix a crash when cursor is null. 2020-01-05 13:27:53 +00:00
Matthias Mailänder
7e9a3d3bc9 Unhardcode transparent index in manual palettes as well. 2020-01-05 13:17:43 +00:00
Matthias Mailänder
6ea85a1a62 Don't hard-code the transparent background color. 2020-01-05 13:17:43 +00:00
Ivaylo Draganov
535144b208 Use system chat line for audio muted/unmuted notifications 2020-01-04 23:05:25 +00:00
Paul Chote
439cd4aded Rework HardwareCursor sprite padding.
All frames in a sequence now use the same bounds
and hotspot, and have a size that is a multiple of 8.
2020-01-04 22:45:51 +01:00
tovl
2094142b7d Include tunnel check in CanStayInCell. 2020-01-04 16:04:27 +00:00
tovl
196d9670d3 Disallow units from idling on bibs in TS. 2020-01-04 16:04:27 +00:00
tovl
434c46058f Disallow units idling on service depot. 2020-01-04 16:04:27 +00:00
tovl
c360d8bcef Make service depot passable. 2020-01-04 16:04:27 +00:00
teinarss
76221471ff Remove unused code from Cargo trait 2020-01-03 19:34:56 +01:00
teinarss
a9d7535915 Remove cargo initialization from Tick 2020-01-03 19:34:56 +01:00
teinarss
20610d05a2 Remove CurrentAdjacentCells update on each tick in Cargo 2020-01-03 19:34:56 +01:00
Ivaylo Draganov
af5d8a3bbe Add a hotkey to cycle harvesters 2020-01-02 23:42:22 +01:00
abcdefg30
ab348336f5 Fix ants teleporting into the map area
Waypoint17 is not at the map edge, waypoint7 is.
Also fixes a path, since waypoint20 -> waypoint10 is going back and makes no sense.
Going directly waypoint20 -> waypoint2 works and as compensation I added waypoint21 -> waypoint10 -> waypoint2.
2020-01-02 16:34:38 +00:00
reaperrr
804d61a6a1 Fix DeliverUnit-related crash 2020-01-01 20:42:36 +01:00
Paul Chote
baa5b3d25e Bypass fingerprint validation for skirmish/mission servers. 2020-01-01 20:33:30 +01:00
Paul Chote
8f2bf27edf Replace Server.Dedicated with Server.Type. 2020-01-01 20:33:30 +01:00
abcdefg30
a9f37bc9f1 Remove a leftover geoip reference from the linux packaging script 2019-12-31 17:03:05 +00:00
unknown
79136a520f Remove dublicate function 2019-12-31 17:32:43 +01:00
Paul Chote
adf1c0b616 Remove GeoIP database from install/packaging scripts. 2019-12-31 17:28:30 +01:00
Paul Chote
e063e13ff4 Remove automatic GeoIP download from the build scripts.
The database file is now locked behind an account login.

https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-geolite2-databases/
2019-12-31 17:28:30 +01:00
reaperrr
9d7ecdbc2c Disable SupportPowerInstances when player lost
Fixes bots using player actor powers after defeat.
2019-12-30 22:50:54 +01:00
reaperrr
7a57f0e6ef Expose delay of WithDeathAnimation
Allows to show it a few ticks after death if the modder
wishes so.
2019-12-30 18:01:09 +00:00
reaperrr
c55c65f6d7 Add delay support to SpriteEffect 2019-12-30 18:01:09 +00:00
reaperrr
037ce9ebf3 Rename ProneTime to Duration
More in line with our property naming conventions.

Additionally, added descs to ProneOffset and
ProneSequencePrefix, since at  least the purpose of
the former isn't entirely clear without looking at the code.
2019-12-30 11:34:41 +01:00
reaperrr
cef940fea9 Fix TakeCover to be disabled properly
Speed and Damage modifiers were ignoring IsTraitDisabled.
2019-12-30 11:34:41 +01:00
Paul Chote
a7ae93978a Disable sound controls when no audio device is available. 2019-12-29 17:53:44 +01:00
Paul Chote
4052620f94 Rename dummy sound label to "No Sound Output". 2019-12-29 17:53:44 +01:00
Paul Chote
032c412e09 Fix WithTextDecoration rendering. 2019-12-28 21:44:26 +01:00
Paul Chote
5a686b3289 Fix duplicated/distorted SequencePlaceBuildingPreview annotations. 2019-12-28 20:56:09 +01:00
Paul Chote
2bf16a34d6 Filter invalid actor IDs when restoring selection save data. 2019-12-28 20:48:46 +01:00
Paul Chote
7ccc63b51c Fix incorrect region definitions. 2019-12-28 19:15:36 +01:00
Paul Chote
e7253fd643 Manual chrome.yaml cleanups. 2019-12-28 19:15:36 +01:00
Paul Chote
f3d7bf403e Rework chrome.yaml format and panel rendering. 2019-12-28 19:15:36 +01:00
Paul Chote
0b8a367867 Fix MiniYaml parsing of empty comments 2019-12-28 19:15:36 +01:00
abcdefg30
aabfd91001 Fix an indentation style issue in TransformsIntoAircraft 2019-12-28 19:16:21 +03:00
Ivaylo Draganov
3d1b4c2509 Remove "Surrender" button for single player games 2019-12-28 15:06:26 +00:00
Ivaylo Draganov
14bc7885b3 Always prompt the user to confirm when leaving a game 2019-12-28 15:06:26 +00:00
Ivaylo Draganov
2204e807b8 Add restart button to main menu for single player (missions, skirmish, replays) 2019-12-28 15:06:26 +00:00
abcdefg30
baa50c9c53 Pass DamageTypes in Explodes 2019-12-28 10:54:27 +01:00
Paul Chote
7d887f0332 Fix NV shader compile errors in combined.frag. 2019-12-27 20:20:42 +01:00
Paul Chote
51eaa17b1e Replace frame limit text field with a slider. 2019-12-26 17:25:38 +01:00
Paul Chote
35a36b4cdf Disable frame limiter by default
VSync does a more reliable job of this.
2019-12-26 17:25:38 +01:00
Paul Chote
2231183fe0 Account for game ticks when applying the frame limiter. 2019-12-26 17:25:38 +01:00
Paul Chote
656a260171 Add VSync setting. 2019-12-26 17:25:38 +01:00
abcdefg30
959c750851 Move voice playing for orders into a helper function 2019-12-23 15:01:36 +01:00
abcdefg30
4d407da3e6 Fix a potential crash in PlayVoiceForOrders 2019-12-23 15:01:36 +01:00
abcdefg30
bb1d1f8140 Remove a nowadays unnecessary loop safeguard 2019-12-23 14:57:50 +01:00
abcdefg30
d2db707521 Move unit order resolving into a helper function 2019-12-23 14:53:13 +01:00
Abdurrahmaan Iqbal
a107da0888 Fix for mod credits overriding engine credits 2019-12-23 13:48:47 +00:00
Paul Chote
b1f7c5c4e3 Remove overlapping vision ranges from RA actors.
This brings a significant perf saving by reducing
the number of evaluated tiles.
2019-12-23 13:53:08 +01:00
Paul Chote
04bad1ae66 Add MinRange support to AffectsShroud. 2019-12-23 13:53:08 +01:00
Paul Chote
5830d4de6c Fix ATEK vision ranges. 2019-12-23 13:53:08 +01:00
abcdefg30
bb85146544 Make orcas buildable on nod07c 2019-12-21 00:48:03 +01:00
abcdefg30
c4ab5d4561 Fix/Update the patrols on nod07c 2019-12-21 00:48:03 +01:00
abcdefg30
54e2aad1cd Fix broken reinforcements on gdi04 and limit them to 3 waves 2019-12-21 00:48:03 +01:00
abcdefg30
b1f6c69fce Use a global script in Tiberian Dawn 2019-12-21 00:48:03 +01:00
abcdefg30
dbe73a06ad Remove ISync from RallyPoint 2019-12-15 23:21:27 +01:00
Paul Chote
f36d0cc214 Fix ModContent cursor. 2019-12-15 22:29:26 +01:00
abcdefg30
1e138a9774 Drop invisible invalid targets immediately when changing stance 2019-12-14 17:17:36 +01:00
abcdefg30
905e02b765 Prevent a crash in AutoTarget.HasValidTargetPriority 2019-12-14 17:17:36 +01:00
Paul Chote
3487846636 Restore NukePower support for proxy actors. 2019-12-14 17:07:16 +01:00
tovl
203fff0ab7 Allow queued structure rallypoints. 2019-12-13 23:51:03 +01:00
tovl
3236499fb7 Increase IMove.MoveTo call flexibility. 2019-12-13 23:51:03 +01:00
Paul Chote
28dbda29e3 Add zoom hotkeys. 2019-12-13 21:29:43 +01:00
Paul Chote
1dcb903580 Implement new viewport size/zoom UI. 2019-12-13 21:29:43 +01:00
Paul Chote
860117daf9 Implement optimized pixel-art antialiasing mode for non-integer world zoom. 2019-12-13 21:29:43 +01:00
Paul Chote
cd368b43df Draw GPS dots using the UI renderers. 2019-12-13 21:29:43 +01:00
Torleif West
ae4b2591bf fix for RA2 cloning vats
formatting

minor formatting

passing CI

closing line bracket

use production unit

opening should not be followed by a blank line

revert tab change
2019-12-12 22:08:25 +01:00
Paul Chote
b0c65c5eb9 Overhaul cursor double setting. 2019-12-11 13:38:52 +01:00
Paul Chote
010fafc6d3 Fix hardware cursors on systems with >150% DPI scaling. 2019-12-11 13:38:52 +01:00
Paul Chote
79aac08a48 Fix turret positioning in the map editor. 2019-12-11 11:02:04 +01:00
Paul Chote
630ca0aefb Draw editor selection box using the UI renderers. 2019-12-11 11:02:04 +01:00
abcdefg30
2918ecadaa Fix team chat messages not always being displayed 2019-12-10 13:05:38 +01:00
reaperrr
82be8d9990 Move AUD support to Mods.Cnc 2019-12-09 22:06:53 +01:00
reaperrr
4d92fde5f7 Remove VqaReader dependency on AudReader
Use ImaAdpcmReader directly, since VQAs only contain
header-less raw IMA  ADPCM audio.
2019-12-09 22:06:53 +01:00
reaperrr
5afc1c1443 Remove duplication between IMA and AUD readers
These parts were identical duplicates, so I removed them
and made AudReader depend on ImaAdpcmReader instead.

Applied some style fixes while I was at it.
2019-12-09 22:06:53 +01:00
abcdefg30
22374ed732 Remove the bogus 'GameSaved' speech notification definition 2019-12-08 21:56:24 +01:00
abcdefg30
bc484a9858 Add 'AirstrikeReady' to 'DisablePrefixes' 2019-12-08 21:56:24 +01:00
abcdefg30
9a57980952 Remove 'AbilityInsufficientPower' from cnc's notifications 2019-12-08 21:56:24 +01:00
Ivaylo Draganov
0900ac2b2f Remove stray "Hotkeys" label in the Input Settings panel in TD 2019-12-08 21:38:28 +01:00
reaperrr
4751b1a176 Move ShpTDLoader, LZO and XORDelta formats to Mods.Cnc
They're pretty much RA/TD-specific formats.
2019-12-08 19:43:51 +00:00
reaperrr
cd123830c3 Move VocLoader from D2k to Cnc
My assumption that the D2 mod would want,
let alone need Mods.D2k was wrong.
Meanwhile, it does need Mods.Cnc for at least
the Pak format as well, so this is a good enough
compromise.
2019-12-08 18:14:17 +00:00
Ivaylo Draganov
93e42b0b27 Add selection tiers as inheritable templates 2019-12-08 18:39:21 +01:00
tovl
088919fecc Change color of selection box based on selection mode. 2019-12-08 17:34:10 +01:00
reaperrr
efc06a020b Move WithDeliveryAnimation to Mods.Common 2019-12-08 16:03:14 +00:00
reaperrr
fe1d3b3821 Move ProductionAirdrop to Mods.Common 2019-12-08 16:03:14 +00:00
reaperrr
948a9c9b19 Add ProductionAirdrop.ActorType update rule 2019-12-08 16:03:14 +00:00
Paul Chote
2603a495e6 Add render_world perf sampler. 2019-12-08 04:36:31 +01:00
Paul Chote
8c41e6a3f7 Remove redundant zoom parameter. 2019-12-08 04:36:31 +01:00
Paul Chote
327866ffc3 Render world via an intermediate FrameBuffer. 2019-12-08 04:36:31 +01:00
Paul Chote
0c8a47b5af Add scissor support to IFrameBuffer. 2019-12-08 04:36:31 +01:00
Paul Chote
e7de7b4c05 Introduce World and UI rendering phases. 2019-12-08 04:36:31 +01:00
Paul Chote
ebd1557523 Draw voxel debug annotations using the UI renderers. 2019-12-08 04:36:31 +01:00
abcdefg30
9a5eaa7cb7 Don't throw an exception when a field is missing 2019-12-07 09:15:38 +01:00
Curtis Shmyr
f037436536 Added TooltipName as an actor Lua property 2019-12-06 09:33:23 +01:00
abcdefg30
b1571ad17a Make Parachutable public 2019-12-05 23:13:35 +01:00
Paul Chote
494a7870d6 Add fallback exits to RA Kennel. 2019-12-05 18:01:09 +01:00
Paul Chote
dbe1d2d928 Add fallback exits to TS barracks. 2019-12-05 18:01:09 +01:00
Paul Chote
2146dd29bb Add priority levels to Exit. 2019-12-05 18:01:09 +01:00
matjaeck
5ac9d2c2f1 Fix botmodules querying the Player actor before it is assigned. 2019-12-05 01:48:56 +01:00
reaperrr
a74235bdbc Move ShpD2 and TmpRA/TD loaders to Mods.Cnc
Reducing the count of proprietary formats in Mods.Common.

Note: Moving ShpD2 to Mods.Cnc is intentional. RA/TD
use it for their original mouse shp files, and any D2(k) mod
will normally need Mods.Cnc anyway, while we can avoid
adding a Mods.D2k dependency to RA/TD this way.
2019-12-01 16:23:54 +01:00
reaperrr
a98a96b05d Update update rule paths 2019-11-30 20:08:27 +01:00
abc013
b4c116cb31 Fix ExtractLanguageStrings utility command 2019-11-29 16:40:00 +01:00
reaperrr
074ebefee1 Fix FCOM still providing space while being captured 2019-11-27 23:04:28 +01:00
tovl
6fb3dc050b Let CreateGroup use ExtraActors field. 2019-11-26 22:06:37 +01:00
tovl
00ce1d7ee6 Allow additional actor IDs to be send with orders. 2019-11-26 22:06:37 +01:00
reaperrr
b8e15fbe40 Move FastByteReader from LCW to own file
And make it public.
Making it easier to move formats that depend on it
to Mods.Cnc independently later.
2019-11-23 19:04:27 +01:00
reaperrr
3f06541b2b Move Shp conversion/remap commands to Mods.Cnc 2019-11-23 19:04:27 +01:00
reaperrr
65728bc032 Move VocLoader to Mods.D2k
While this is strictly speaking a D2 format, any
D2 mod is pretty much guaranteed to use Mods.D2k,
so this should be a good enough place to move it to.
2019-11-23 19:04:27 +01:00
reaperrr
c4597b5c6b Fix RA desert tree fire palette
By default WithDamageOverlay uses the actors'
palette, but RA's desert terrain uses the TD desert.pal
which isn't compatible with RA's fire animation shps.
2019-11-23 18:40:27 +01:00
abcdefg30
142f823e6f Explain that CanEnterCell ignores 'subCell' if there is a free subcell 2019-11-21 14:13:17 +01:00
abcdefg30
25b7386f0d Let Mobile's CanEnterCell consider ToSubCell 2019-11-21 14:13:17 +01:00
abcdefg30
4717e98c48 Add a subCell parameter to IPositionableInfo.CanEnterCell 2019-11-21 14:13:17 +01:00
abcdefg30
980c1e1b6a Fix McvManagerBotModule spamming deploy orders
Removes the 'activeMCVs' list since it was not useful.
The real bugfix is not iterating over 'activeMCVs' when issueing new orders
(this was previously needed for already discovered mcvs that stopped)
but over 'newMCVs' instead.
2019-11-20 16:44:39 +01:00
teinarss
a47f60d3a6 Add a trait PlayerRadarTerrain to track explored terrain 2019-11-20 16:24:56 +01:00
reaperrr
ee00954f2e Replace AmmoPool lookup methods with properties
And gave the more suitable names while at it.
This is more in line with how we do things in
other places.
2019-11-20 15:45:41 +01:00
teinarss
c77aa4c8f9 Add IsDead check to FerryUnit OnFirstRun 2019-11-19 15:59:27 +01:00
reaperrr
8181a452cb Fix some header dates
Seems these were overlooked or merged after
the dates of the other files were updated.
2019-11-17 22:32:51 +01:00
Paul Chote
f39b688c39 Add GrantPrerequisiteChargeDrainPower and DrainPrerequisitePowerOnDamage.
These traits implement the Firestorm defense charge/drain logic.
2019-11-17 17:06:29 +01:00
Paul Chote
1fa90c0474 Allow support powers to override the icon overlay/tooltip labels. 2019-11-17 17:06:29 +01:00
Paul Chote
70b020205d Rename *Time to *Ticks and increase internal resolution. 2019-11-17 17:06:29 +01:00
Paul Chote
e03abdc0da Add support for custom SupportPowerInstances. 2019-11-17 17:06:29 +01:00
Paul Chote
61c56dcb00 Fix DamageModifier crashes when an actor is demolished.
Demolish calls GetDamageModifier with a null Damage.
2019-11-17 17:06:29 +01:00
Paul Chote
6b1e81a7b5 Spawn ejected pilots inside a FrameEndTask. 2019-11-16 23:07:58 +01:00
RoosterDragon
04912ea996 Expose a setting for Weighted A*
Replace Constants.CellCost and Constants.DiagonalCellCost with a dynamically calculated value based on the lowest cost terrain to traverse. Using a fixed value meant the pathfinder heuristics would be incorrect.

In the four default mods, the minimum cost is in fact 100, not 125. This increase would essentially allow the pathfinder to return suboptimal paths up to 25% longer in the worst case, but it would be quicker to do so.

This is exactly what Weighted A* does - overestimate the heuristic by some factor in order to speed up the search by checking fewer routes. This makes the heuristic inadmissible and it may now return suboptimal paths, but their worst case length is bounded by the weight. A weight of 125% will never produce paths more than 25% longer than the shortest, optimal, path.

We set the default weight to 25% to effectively maintain the existing, suboptimal, behaviour due to the choice of the old constant - in future it may prove a useful tuning knob for performance.
2019-11-15 13:05:41 +01:00
Abdurrahmaan Iqbal
72eb4e1749 Fix #17230: Dummy audio output class 2019-11-14 23:46:14 +01:00
blackhand1001
70b1df6ce7 Fix squadmanager adding naval units to ground attack forces.
Fix squadmanager adding naval units to ground attack forces. This was breaking the behavior of both naval and ground squads.
2019-11-09 11:19:09 +01:00
abcdefg30
a586f10875 Don't allow movement for actors without IMove
However, this does not check if any existing IMove traits are enabled.
2019-11-08 23:31:59 +01:00
abcdefg30
980c0c9cd4 Fix actors returning fire at invisible attackers 2019-11-08 23:31:59 +01:00
blackhand1001
d20182f158 Simplify for loop structure now that it only has one check
Simplify for loop structure now that it only has one check
2019-11-08 21:04:32 +01:00
blackhand1001
49d07e9d64 Fix MCV Manager glitch when restrict building area is enabled.
Fix MCV Manager glitch when restrict building area is enabled. It was checking if the location was close enough to the Base center instead of using the MCV Managers min and max ranges. This would cause it to often have no valid locations despite having a huge range.
2019-11-08 21:04:32 +01:00
matjaeck
ba73842747 Allow GrantCondition to grant conditions permanently. 2019-11-08 16:37:13 +01:00
matjaeck
900e857bfa Let AI ignore frozen actors and target original actors instead. 2019-11-08 15:32:06 +01:00
Abdurrahmaan Iqbal
d2819dca77 Show dialogue only when there are unsaved changes 2019-11-07 20:33:43 +01:00
blackhand1001
780982dbe2 Add PlaceDefenseTowardsEnemyChance trait to basebuilderbotmodule
Add PlaceDefenseTowardsEnemyChance trait to basebuilderbotmodule. This defeaults to 100 which is the current behavior. This change now allows you to set the chance that bots will place defenses evenly around the base like the AI in stock red alert and Tiberian sun did.
2019-11-06 10:30:36 +01:00
reaperrr
2de51ae73c Cache IPathFinder in Mobile at creation
Avoiding look-ups on every move order,
as well as reducing line lengths.
2019-11-03 20:53:29 +01:00
Paul Chote
27205b30e5 Remove landing behaviour from force-move orders on selectable buildings. 2019-11-02 18:29:16 +00:00
abcdefg30
34f4c9bdaa Prevent chronoshifting an empty selection 2019-11-02 11:29:28 +01:00
Abdurrahmaan Iqbal
023750db06 Prevent showing wall connections in unexplored terrain 2019-11-01 22:13:38 +01:00
teinarss
c94cf61069 Fix OccupiedCells for units sharing cells 2019-10-31 21:49:07 +00:00
Paul Chote
5315f8603f Override selection if the mouse is over an already selected actor. 2019-10-30 14:53:23 +01:00
Paul Chote
0e4cb53ada Pass contextual information to TargetOverridesSelection. 2019-10-30 14:53:23 +01:00
Paul Chote
3d6621f7ff Force selection cursor when selection overrides input. 2019-10-30 14:53:23 +01:00
Paul Chote
9d4f683d80 Remove WorldRenderer argument from InputOverridesSelection. 2019-10-30 14:53:23 +01:00
Paul Chote
0cfd6337ff Fix InputOverridesSelection only considering the closest actor. 2019-10-30 14:53:23 +01:00
Paul Chote
230a0b330c Fix EjectOnDeath pilot spawning. 2019-10-29 23:03:11 +01:00
Paul Chote
3ee697a54d Install x64 release into correct Program Files on Windows. 2019-10-28 21:03:49 +01:00
tovl
d2991247a3 Add separate condition to mobile for disabling nudging only. 2019-10-28 19:35:32 +01:00
tovl
38caadfdf0 Clean up nudging code. 2019-10-28 19:35:32 +01:00
tovl
c4d1468f62 Make locomotor cache and nudging logic aware of mobile trait status. 2019-10-28 19:35:32 +01:00
reaperrr
7e5b1abc0e Simplified initial Wanders countdown initialization
I don't see a technical reason for the old approach.
2019-10-27 18:03:34 +02:00
RoosterDragon
b98123d9f8 Use SegmentStream.CreateWithoutOwningStream to avoid reading data into memory.
To avoid creating copied data in memory (e.g. via MemoryStream), this method can be used to reference offsets on files on disk, reducing memory requirements.
2019-10-24 20:48:14 +02:00
blackhand1001
9a9bf441ba Add UseResourceStorage trait to CashTrickler 2019-10-23 20:20:03 +02:00
Paul Chote
1599eac66c Rename SelectionBoxRenderable to SelectionBoxAnnotationRenderable. 2019-10-20 23:46:33 +02:00
Paul Chote
43e84c89ef Rename SelectionBarsRenderable to SelectionBarsAnnotationRenderable. 2019-10-20 23:46:33 +02:00
Paul Chote
8e280ef0a7 Rename RangeCircleRenderable to RangeCircleAnnotationRenderable. 2019-10-20 23:46:33 +02:00
Paul Chote
81d9b705a6 Rename DetectionCircleRenderable to DetectionCircleAnnotationRenderable. 2019-10-20 23:46:33 +02:00
Paul Chote
4ec0fa299d Rename TextRenderable to TextAnnotationRenderable. 2019-10-20 23:46:33 +02:00
Paul Chote
7937383bf4 Replace scaleSizeWithZoom with SpriteAnnotation. 2019-10-20 23:46:33 +02:00
Paul Chote
e772adb0a9 Draw annotations using the UI renderers. 2019-10-20 23:46:33 +02:00
Paul Chote
8c1b0f1afe Add IEffectAnnotation interface. 2019-10-20 23:46:33 +02:00
Paul Chote
0ff078968d Change IPlaceBuildingDecorationInfo to use annotations. 2019-10-20 23:46:33 +02:00
Paul Chote
7d1ce0c83b Add annotation support to IOrderGenerator. 2019-10-20 23:46:33 +02:00
Paul Chote
1dc84f48de Migrate traits to IRenderAnnotations. 2019-10-20 23:46:33 +02:00
Paul Chote
edaa7918fc Add IRenderAnnotations(WhenSelected) interfaces. 2019-10-20 23:46:33 +02:00
Paul Chote
060ea80ca4 Fix infantry idle animations playing immediately after creation. 2019-10-20 16:38:25 +02:00
Paul Chote
c15a0a54bb Don't consider unit creation as movement. 2019-10-20 16:38:25 +02:00
Paul Chote
252c833320 Don't override spawn CenterPosition for non-aircraft reinforcements. 2019-10-19 23:45:42 +02:00
abcdefg30
fdd3bffa1d Throw a lua exception when setting an owner to null/nil 2019-10-19 13:34:43 +02:00
Paul Chote
988d6079e3 Disable Carryable while submerged. 2019-10-19 13:11:00 +02:00
Paul Chote
f14d3985a0 Allow carryall pickup orders on deployed vehicles. 2019-10-19 13:11:00 +02:00
Paul Chote
5f8fa7a35a Add UndeployOnPickup to GrantConditionOnDeploy. 2019-10-19 13:11:00 +02:00
Paul Chote
69970d42f3 Prevent movement pausing at invalid position. 2019-10-19 13:11:00 +02:00
Paul Chote
ae34410c80 Replace MoveIntoWorld with ReturnToCell/AssociateWithAirfield. 2019-10-17 23:31:15 +02:00
Paul Chote
9b4d149a06 Revert "Suppress MoveIntoWorldInit for map-placed Mobile actors."
This reverts commit f0c28cc153.
2019-10-17 23:31:15 +02:00
abcdefg30
f5f626cd89 Revert "Production should set SubCellInit"
This reverts commit fa1ca981ac.
2019-10-17 23:31:15 +02:00
Abdurrahmaan Iqbal
763e6d8109 Fix #17229: Refactor ReturnToBase.cs 2019-10-17 10:28:43 +02:00
reaperrr
aa953ba5a1 Remove unused and buggy stand2 sequence from ants
They were unused, their settings were wrong,
and even if fixed they'd make idle ants look
glitchy, because the game switches between
stand sequences randomly.
2019-10-15 14:48:11 +02:00
reaperrr
33bba98773 Fix zombie stand2 sequence and run tickrate 2019-10-14 17:28:46 +02:00
abc013
8b1f1b21e7 Adjusted die sequence length of zombie 2019-10-14 17:28:46 +02:00
abc013
3ec0aa55b9 Fixed zombie.shp
Added missing zombie attack frame
and other fixes.
2019-10-14 17:28:46 +02:00
tovl
33d089a9d6 Fix lastVisibleTarget not being set in FlyAttack and AttackActivity. 2019-10-14 01:22:04 +02:00
abcdefg30
1d90e08bd0 Guard against overlaps on HiDPI by having a 5px border on graphs 2019-10-14 01:02:23 +02:00
abcdefg30
acf028581a Special case the TD spectator UI to fit the minimum width 2019-10-14 01:02:23 +02:00
abcdefg30
9084295d7c Reduce the width of the combat stats tab 2019-10-14 01:02:23 +02:00
abcdefg30
3f89f74d8e Reduce the Width of INGAME_OBSERVERSTATS_BG 2019-10-14 01:02:23 +02:00
reaperrr
88d930579b Fix missing rules in prep update path 2019-10-13 22:37:03 +01:00
abc013
3d3814f336 Add isDead-check to the flamethrowers in allies06b 2019-10-13 18:14:10 +02:00
abc013
3e244998cd Make normal difficulty on allies06b easier 2019-10-13 18:14:10 +02:00
Nakarin Srijumrat
17bec1435b increased ingame edge scrollspeed to 30 from 10 2019-10-13 13:20:24 +02:00
teinarss
fa1ca981ac Production should set SubCellInit 2019-10-12 00:08:15 +02:00
abcdefg30
e9020048fb Add an update rule to remove 'yes' and 'no' 2019-10-12 00:07:05 +02:00
abcdefg30
76ad9962d7 Split off a new UpdatePath for changes not going into prep-1908 2019-10-12 00:07:05 +02:00
abcdefg30
55c3f313b1 Remove 'yes' and 'no' in favor of 'true' and 'false' 2019-10-12 00:07:05 +02:00
abc013
c4f48ad521 Use another plug location for placing plugs on a building when current plug location is already blocked 2019-10-11 22:52:55 +02:00
Paul Chote
ba2d2299d9 Update macOS launcher package.
This pulls in a fix for the missing libmono-native-compat.dylib
2019-10-11 21:58:32 +02:00
abcdefg30
f9f1167b62 Minor style fixes 2019-10-11 21:48:24 +02:00
abcdefg30
e2bbbde494 Reduce string allocations in ObserverStatsLogic 2019-10-11 21:48:24 +02:00
abcdefg30
3672b4e674 Keep army and income graph disabled if they were disabled once 2019-10-11 21:48:24 +02:00
abcdefg30
ee839869fc Replace "$/min" by "Income" and increase graph update rates 2019-10-11 21:48:24 +02:00
abcdefg30
4ca42f6e83 Remove $/min from the basic stats 2019-10-11 21:48:24 +02:00
abcdefg30
0ad8320bff Add an XAxisTicksPerLabel property to LineGraphWidget 2019-10-11 21:48:24 +02:00
abcdefg30
feb58801e0 Work around a recursive loop in TargetAndAttack 2019-10-11 21:00:53 +02:00
Paul Chote
3860cd1b98 Add "Deployed" checkbox in the map editor actor properties. 2019-10-10 19:50:05 +02:00
Paul Chote
c08e290f44 Add "Spawn Child Actor" checkbox in the map editor actor properties. 2019-10-10 19:50:05 +02:00
Paul Chote
966290a623 Add EditorActorCheckbox plumbing. 2019-10-10 19:50:05 +02:00
Paul Chote
5eaa99827d Suppress MoveIntoWorldInit for map-placed Mobile actors. 2019-10-07 19:02:48 +02:00
tovl
eed00ded0d pause MovePart when Mobile is paused. 2019-10-06 20:28:20 +01:00
Jonas A. Lind
1557f4c134 Redo buildpaletteorder for RA vehicles
Restructure RA's vehicle build tab. More streamlined and better looking.
2019-10-06 20:22:16 +02:00
abcdefg30
acea19312d Fix FallsToEarth queueing an activity in its ctor 2019-10-06 14:42:50 +01:00
abcdefg30
56726a0533 Add an ICreationActivity interface 2019-10-06 14:42:50 +01:00
abcdefg30
39f8d34494 Fix setting the position of the wrong actor 2019-10-06 14:42:50 +01:00
abcdefg30
ab87e78dff Fix the XAxis of LineGraphWidget not being updated properly 2019-10-06 13:10:58 +01:00
abcdefg30
548ff411ef Cache method call results in variables in Draw of LineGraphWidget 2019-10-06 13:10:58 +01:00
Chris Cameron
36c48e1785 feat: Using a glDebugMessageCallback instead of glGetError on devices that support it 2019-10-05 21:26:20 +01:00
Punsho
460f5bbb30 Make EMP dissable subterranean units while they're underground 2019-10-05 19:19:57 +02:00
Punsho
d9ec3e0d88 Make EMP dissable detection of mobile sensor array 2019-10-05 19:19:57 +02:00
Punsho
e1e7691fb4 Make laser fence dissable on emp 2019-10-05 19:19:57 +02:00
tovl
ac6431acf8 Clean up usage of CancelActivity. 2019-10-05 19:07:54 +02:00
teinarss
1e786b8e31 Add null check to EditorDefaultBrush for resources 2019-10-05 18:39:39 +02:00
Paul Chote
575541ff4e Remove double-negative from appimage wrapper. 2019-10-05 18:25:13 +02:00
Paul Chote
e94f20f7ca Reset environment variables before switching mods. 2019-10-05 18:25:13 +02:00
Paul Chote
3bda890f7b Add Engine.LaunchWrapper launch argument for mod switching. 2019-10-05 18:25:13 +02:00
Paul Chote
bdd0f68a4a Compile using Mono 6.4.0. 2019-10-05 18:24:45 +02:00
Paul Chote
275365917c Update packaged mono to 6.4.0. 2019-10-05 18:24:45 +02:00
SoScared
b9b7f435dd Redo buildpaletteorder for D2K buildings 2019-10-05 18:21:08 +02:00
Andre Mohren
7f7341a369 Fixed incorrect sequence frame amount checks using Stride. 2019-10-05 18:03:09 +02:00
Paul Chote
c30bb28210 Filter invalid actors when loading and saving games. 2019-10-05 17:50:10 +02:00
Paul Chote
3ad3c39b21 Replace actor list with count in UnitBuilderBotModule. 2019-10-05 17:50:10 +02:00
abcdefg30
b839796b89 Fix double clicking a save in the save game dialogue loading it 2019-10-05 17:39:23 +02:00
abcdefg30
ca92e13b24 Fix harvesters idling on Infiltration 2019-10-05 16:09:42 +02:00
abcdefg30
294908485f Fix the town attackers in Infiltration not stopping 2019-10-05 16:09:42 +02:00
abcdefg30
d2a2c11326 Remove unnecessary SearchFromHarvesterRadius overwrites from TD missions 2019-10-05 16:03:32 +02:00
abcdefg30
716aeb1e8c Add SearchFromProcRadius to TD missions that need it 2019-10-05 16:03:32 +02:00
abcdefg30
321c891bc0 Fix a crash when MaxLevel of GainsExperience is zero 2019-10-05 15:56:59 +02:00
teinarss
d34bce9eab Remove CanEnterCell from OccupiedCells 2019-10-05 14:37:54 +02:00
teinarss
9bfc324c04 Mark cells that have changed MovementType as dirty 2019-10-05 14:37:54 +02:00
Ivaylo Draganov
ad02adff3e Set duplicates flag for hotkeys in HotkeyManager 2019-10-05 13:17:20 +02:00
Punsho
38f5d2c100 RA balance changes for September 2019 2019-10-05 11:03:06 +01:00
Michael Silber
81eb939d4d Fix destroyed truck escaping ra mission sarin-gas-1 2019-10-04 22:41:10 +01:00
Paul Chote
865d8d77e0 Expire invalid instances from the SupportPowerBotModule cache. 2019-10-01 19:25:30 +02:00
Paul Chote
cf427f8cb3 Drop invalid power references when loading save games. 2019-10-01 19:25:30 +02:00
abcdefg30
6f85711252 Increase the SearchFromProcRadius radius in soviet05 2019-09-30 20:28:26 +02:00
abcdefg30
70c278dec5 Remove the now unnecessary Helper refinery 2019-09-30 20:28:26 +02:00
Punsho
9ca7eb6ab1 Make mine targetable on attack everything stance for AutoTargetGround 2019-09-28 14:20:23 +02:00
teinarss
93704ccfcf Add check to see if transport is dead to UnreserveSpace 2019-09-28 14:08:01 +02:00
abcdefg30
411316726b Fix the expansion mcv in soviet05 being transported off the map 2019-09-28 14:01:36 +02:00
abcdefg30
4d2b70acd1 Revert the search radius decrease in D2k 2019-09-28 13:58:24 +02:00
abcdefg30
c0620bd186 Revert the search radius decrease in TS 2019-09-28 13:58:24 +02:00
teinarss
0e6fa51bb0 Rename duplicated actors 2019-09-27 18:04:29 +02:00
teinarss
76034c198e Added Undo Redo to editor 2019-09-27 17:40:32 +02:00
teinarss
1f78b3a425 Cleanup in MapEditorTabsLogic 2019-09-27 17:40:32 +02:00
tovl
48059e8249 Skip rally point if order is queued after resupply. 2019-09-26 18:39:44 +02:00
tovl
09cd56b367 Add missing target line to aircraft taking off from resupplying. 2019-09-26 18:39:44 +02:00
tovl
145b6a05a3 Refactor unreserve actions. 2019-09-26 18:39:44 +02:00
tovl
5787f74af9 Prevent bogus attackmove on take-off. 2019-09-26 18:39:44 +02:00
Punsho
78d7f79817 Fix ctank and stank building faster then they should 2019-09-26 17:13:42 +02:00
abcdefg30
9356c8afd0 Fix unarmed units idling on the ts shellmap 2019-09-24 16:48:52 +02:00
abcdefg30
72bff74ca5 Fix passengers idling on the ts shellmap 2019-09-24 16:48:52 +02:00
abcdefg30
2d304efb73 Convert all spaces to tabs in the ts shellmap script 2019-09-24 16:48:52 +02:00
abcdefg30
c7784cbc8e Fix reinforcements on the ts shellmap not attack moving 2019-09-24 16:48:52 +02:00
Punsho
e1a5a725b0 Fix MRV not auto targeting vehicles 2019-09-22 18:46:56 +02:00
tovl
3d4838b5bc Make airlift landing direction configurable. 2019-09-21 18:16:34 +02:00
tovl
b4270af170 Fix airlift direction in isometric mods. 2019-09-21 18:16:34 +02:00
tovl
3fb54ea6ea Add option for airlift to arrive from player baseline. 2019-09-21 18:16:34 +02:00
tovl
ed7667683b Fix deployed units being nudgeable. 2019-09-19 20:52:13 +02:00
SoScared
61aaac888b Add map Climax to RA map pool 2019-09-16 00:21:47 +02:00
RoosterDragon
6c9fbd40dc Implement IEquatable on structs.
Any struct which overrides object.Equals(object obj) should implement IEquatable<T> to gain a more efficient Equals(T other) overload. This overload will be used by hashing collections like Dictionary which enables them to check equality without boxing the struct.
2019-09-15 19:56:58 +02:00
tovl
4a609bbee8 Allow units to give way when path is blocked by oncoming unit. 2019-09-15 17:51:34 +01:00
Ivaylo Draganov
32309bb8ea Add duplicate hotkey tracking with a boolean property on the definition 2019-09-15 16:35:18 +02:00
Paul Chote
df2300bee0 Fix player viewport saving for non-spectators. 2019-09-15 15:11:47 +02:00
Oliver Brakmann
6e18de4370 Fix idling aircraft on Intervention 2019-09-15 15:02:01 +02:00
abcdefg30
0462cfa507 Remove selling from Infilitration
It is weird, unsatisfying for the player and inconsistent with the rest of our missions
2019-09-15 14:51:32 +02:00
abcdefg30
aee9ee6187 Fix potentially bogus usages of OnAllRemovedFromWorld 2019-09-15 14:51:32 +02:00
RoosterDragon
31918e8712 Add UnionRectangles extension method. 2019-09-14 22:09:40 +02:00
Paul Chote
0e6c37d765 Convert TerrainGeometryOverlay to IRenderAboveShroud. 2019-09-14 18:49:44 +02:00
Paul Chote
f45423ed76 Convert EditorSelectionLayer to IRenderAboveShroud. 2019-09-14 18:49:44 +02:00
Paul Chote
b3984c8db4 Convert WarheadDebugOverlay to IRenderAboveShroud. 2019-09-14 18:49:44 +02:00
Paul Chote
999ad0e18a Convert CustomTerrainDebugOverlay to IRenderAboveShroud. 2019-09-14 18:49:44 +02:00
Paul Chote
ccd07b6cfe Convert ExitsDebugOverlay to IRenderAboveShroudWhenSelected. 2019-09-14 18:49:44 +02:00
Paul Chote
60e42c1ea1 Convert CombatDebugOverlay to IRenderAboveShroud. 2019-09-14 18:49:44 +02:00
Paul Chote
c9ed749908 Add (Polygon|Circle|Line)AnnotationRenderable. 2019-09-14 18:49:44 +02:00
Paul Chote
a9a43d54f7 Convert WithRangeCircle to IRenderAboveShroud. 2019-09-14 18:49:44 +02:00
abcdefg30
7f6149713e Fix actors with no footprint not being copied and pasted 2019-09-13 23:55:48 +01:00
tovl
eb39080248 Allow minefields to start and end on occupied cells. 2019-09-13 23:47:34 +01:00
matt barbier
97fe36af5a Moved GrantExternalConditionToProduced into the Traits/Conditions folder 2019-09-13 22:04:35 +01:00
teinarss
c15f66aa62 PlayerStatistics should stop ticking after lost/win 2019-09-13 21:42:11 +01:00
reaperrr
694680720e Updated AcceptsOrder check to be more readable
This hopefully also fixes handling of multiple enabled
RejectsOrders traits.
2019-09-13 19:49:19 +01:00
abcdefg30
465ee97090 Prevent users from selecting a directional target outside the map 2019-09-13 14:47:29 +02:00
Paul Chote
a8b1762464 Fix ActorPreviewWidget viewport manipulation. 2019-09-13 11:24:57 +02:00
tovl
46c0b4cf31 Fix crash with dead cargo. 2019-09-13 10:34:15 +02:00
Jan Beich
4f99982ef1 Extend Linux dllmap to other systems
- Drop `os` in Eluant config as it's only used on Linux
- Make generic to help BSDs and Solaris
- Update OpenAL-CS and SDL2-CS to get the same

Exception of type `System.DllNotFoundException`: lua51.dll
TypeName=``
  at (wrapper managed-to-native) Eluant.LuaApi.lua_newstate(Eluant.LuaRuntime/LuaAllocator,intptr)
  at Eluant.LuaRuntime..ctor ()
  at Eluant.MemoryConstrainedLuaRuntime..ctor ()
  at OpenRA.Scripting.ScriptContext..ctor (OpenRA.World world, OpenRA.Graphics.WorldRenderer worldRenderer, System.Collections.Generic.IEnumerable`1[T] scripts)
  at OpenRA.Mods.Common.Scripting.LuaScript.OpenRA.Traits.IWorldLoaded.WorldLoaded (OpenRA.World world, OpenRA.Graphics.WorldRenderer worldRenderer)
  at OpenRA.World.LoadComplete (OpenRA.Graphics.WorldRenderer wr)
  at OpenRA.Game.StartGame (System.String mapUID, OpenRA.WorldType type)
  at OpenRA.Game.LoadShellMap ()
  at OpenRA.Mods.Common.LoadScreens.BlankLoadScreen.StartGame (OpenRA.Arguments args)
  at OpenRA.Game.InitializeMod (System.String mod, OpenRA.Arguments args)
  at OpenRA.Game.Initialize (OpenRA.Arguments args)
  at OpenRA.Game.InitializeAndRun (System.String[] args)
  at OpenRA.Program.Main (System.String[] args)
2019-09-13 00:25:50 +02:00
Jan Beich
fe48eede0e command -v with more than one argument is non-portable
On FreeBSD build fails, so check if `msbuild` exists without arguments.

$ gmake
command: wrong number of arguments
OpenRA requires the 'msbuild -verbosity:m -nologo' tool provided by Mono >= 5.4.
gmake: *** [Makefile:154: core] Error 1

# FreeBSD sh
$ command -v echo ls
command: wrong number of arguments

# dash
$ command -v echo ls
echo

# ksh, bash, zsh
$ command -v echo ls
echo
/bin/ls
2019-09-13 00:25:50 +02:00
Paul Chote
afe3e24cda Remove duplication in Texture. 2019-09-12 18:58:37 +01:00
Paul Chote
ce8112fb5a Migrate rendering to OpenGL 3.2 / OpenGL ES 3.0. 2019-09-12 18:58:37 +01:00
Paul Chote
91c63034d3 Clean references to disposed textures. 2019-09-12 18:58:37 +01:00
teinarss
d712bdea85 Locomotor cache should handle custom layers 2019-09-09 21:39:25 +02:00
abcdefg30
912a424596 Replaced "Earned this min" by an Oil Derrick count in the economy statistics 2019-09-08 12:47:33 +02:00
abcdefg30
1e6660ecb2 Add an "UpdatesDerrickCount" trait 2019-09-08 12:47:33 +02:00
Paul Chote
8f267ebcef Remove IronCurtainable from RA aircraft. 2019-09-08 12:24:27 +02:00
teinarss
c13fb80257 Fix crushable logic for actors in cell 2019-09-07 13:31:57 +01:00
abcdefg30
ca8ca2df5c Fix a division by zero error in FindAndDeliverResources
by preventing an overflow through dividing directly
2019-09-07 10:48:20 +01:00
puritylake
aff3bf369b #17018 Gets rif of cutoff line in chat window 2019-09-06 23:02:50 +02:00
teinarss
6fe31e44cb More robust logic for ThisMinute stats 2019-09-06 14:00:42 +02:00
teinarss
6795fb6967 GetAvailableSubCell should block cells outside the map 2019-09-06 13:32:09 +02:00
abcdefg30
9516ee511d Remove the duplicate Selectable trait on TENF 2019-09-06 13:18:37 +02:00
Paul Chote
1d106e71c4 Save screenshots via the frame buffer. 2019-09-04 20:20:04 +02:00
Paul Chote
c0ee346c1c Render via an intermediate frame buffer. 2019-09-04 20:20:04 +02:00
Paul Chote
d2298b6f04 Allow FrameBuffer clear color to be customized. 2019-09-04 20:20:04 +02:00
Paul Chote
09dd66fd5a Correctly fix BlendMode.Subtractive alpha handling. 2019-09-04 20:20:04 +02:00
Paul Chote
b93c7cabb3 Render voxels before BeginFrame. 2019-09-04 20:20:04 +02:00
Oliver Brakmann
5d786f411f Update comment in Activity.cs
SequenceActivities() was removed.
2019-09-02 01:45:35 +02:00
reaperrr
801f5ba525 Rename FlyCircle to FlyIdle and make it tick TickIdle
It now handles both hovering and circling aircraft, for consistency.
2019-09-01 16:38:44 +02:00
teinarss
ce29dcad87 Update PlayerResources capacity from INotify* methods 2019-08-28 00:32:01 +02:00
reaperrr
8edd202b64 Move InflictDamage method back to DamageWarhead
From TargetDamageWarhead.
Saves a few lines and allows warheads that are not
TargetDamageWarhead-based to use it.
2019-08-27 23:05:19 +02:00
reaperrr
07de3ba5e0 Change default preview facing to 96
92 is not a multiple of 8, and all sprite actors
in the official mods have at most 32 facings.
2019-08-27 22:59:22 +02:00
Paul Chote
2b4ad71151 Remove unused OwnerLinkedProc field. 2019-08-25 17:20:38 +02:00
Paul Chote
815ea1e13b Make LastSearchFailed local to FindAndDeliverResources. 2019-08-25 17:20:38 +02:00
Paul Chote
1d2b3ac917 Update the displayed replay filename after renaming. 2019-08-25 16:10:29 +02:00
Paul Chote
c1be8d277e Disable player color for TD walls. 2019-08-25 15:33:46 +02:00
Paul Chote
19d9541aad Disable player color for RA walls. 2019-08-25 15:33:46 +02:00
teinarss
4dd8472d9b Reset server after game 2019-08-25 15:30:45 +02:00
Paul Chote
6702395357 Fix flare animation definition in RA and TD. 2019-08-25 15:24:32 +02:00
tovl
946c9f420b Fix Move not cancelling during turns. 2019-08-25 13:13:37 +02:00
Paul Chote
8b0f2e1462 Fix NRE in SquadManagerBotModule. 2019-08-24 14:33:11 +02:00
Paul Chote
d5f42c0628 Recalculate visibility during moves too. 2019-08-23 14:31:29 +02:00
Paul Chote
76d1447a91 Fix incorrect shroud visibility for stationary units. 2019-08-23 14:31:29 +02:00
Paul Chote
4db3da61e1 Avoid an integer (long) overflow in FindAndDeliverResources. 2019-08-23 14:15:51 +02:00
Ivaylo Draganov
be1f820674 Move hotkey dialog logic into SettingsLogic, fix bugs and improve usability of the dialog 2019-08-23 14:08:09 +02:00
tovl
ed8abe9861 Define nearenough parameter for aircraft so they can exit movement early when stuck. 2019-08-23 13:54:58 +02:00
reaperrr
e71001f4f8 Fix Resupply closeEnough bugs
Fixes that
- RepairableNear actors wouldn't move close enough
- isCloseEnough would return 'true' even if the host
  is invalid.
2019-08-22 10:26:36 +01:00
Paul Chote
8457dfdc39 Add Gatekeeper notice to macOS dmg. 2019-08-21 15:16:00 +01:00
Paul Chote
a491bae39b Bind triggers to RA Shellmap's APC passengers. 2019-08-21 11:24:20 +02:00
Paul Chote
f31cfe5b96 Fix SendParatroopers return value. 2019-08-21 11:24:20 +02:00
Paul Chote
ab94ea9715 Discourage harvesters from wandering too far from the refinery. 2019-08-20 20:22:39 +02:00
Paul Chote
7e4da8ea2c Don't reload after finishing a field. 2019-08-20 19:51:12 +02:00
Paul Chote
7311ae889f Clear placed mines queued fields too. 2019-08-20 19:51:12 +02:00
Paul Chote
9aec48aec3 Lay mines in order from start to end. 2019-08-20 19:51:12 +02:00
abcdefg30
3a51cf0ef8 Update AUTHORS 2019-08-20 19:26:02 +02:00
teinarss
7544d4b4e6 Cells with Temporary blockers should not exit early in locomotor cache 2019-08-19 19:06:57 +02:00
abcdefg30
345905bf68 Remove the gunboat from Lost Souls 2019-08-19 16:55:35 +02:00
abcdefg30
8cf6aa267c Allow single observers to use spectator team chat in mp 2019-08-19 16:45:15 +02:00
tovl
3fe78a8311 Add to AUTHORS. 2019-08-19 00:33:38 +02:00
tovl
2d394f33b8 Fix units from transports appearing at load point. 2019-08-19 00:33:38 +02:00
tovl
70459b311e Refactor FlyAttack to make strafing runs interruptible when target becomes invalid. 2019-08-18 12:50:20 +02:00
Paul Chote
e600848947 Fix crash for invalid Resupply hosts. 2019-08-18 12:48:17 +02:00
Hedog
2a6f2bbe0e Update movement inside leap to show attack animation 2019-08-17 12:42:06 +02:00
Paul Chote
2c24a607bc Fix Target.Positions returning null for invalid FrozenActors. 2019-08-15 20:13:04 +02:00
Ivaylo Draganov
8f7da18dc5 Kill buildings on surrender in TS 2019-08-15 19:13:15 +02:00
tovl
08c472b2e2 Disallow attack-moving units from chasing their targets. 2019-08-15 18:03:30 +02:00
Paul Chote
441585b3aa Truncate SLOT_OPTIONS and PLAYER_ACTION dropdown labels. 2019-08-15 17:25:14 +02:00
Paul Chote
78302ea593 Rework aircraft rally point handling. 2019-08-15 17:02:27 +02:00
reaperrr
08db7586d4 Fix Enter cursor for non-TakeOffOnResupply
If the aircraft does not take off on resupply,
we allow it to enter resuppliers without ForceMove modifier.

ResolveOrder already handled this correctly, only the cursor
shown was wrong.
2019-08-13 02:26:21 +02:00
teinarss
e05dc0afe3 Remove support power timers from spectator ui 2019-08-13 02:13:54 +02:00
Paul Chote
9c81507d6d Adjust lobby option bin margins. 2019-08-12 19:13:05 +02:00
abcdefg30
ea80a13b11 Let the utility remove stray trailing whitespaces 2019-08-11 16:40:55 +02:00
abcdefg30
84fbcd7c47 Apply the update rule to the default mods 2019-08-11 16:40:55 +02:00
abcdefg30
bfc3e1354b Rename SearchFromOrderRadius to SearchFromHarvesterRadius 2019-08-11 16:40:55 +02:00
abcdefg30
698ef5e375 Don't use SearchFromProcRadius when searching from self.Location 2019-08-11 16:40:55 +02:00
abcdefg30
ead35bccda Decrease SearchFromProcRadius and SearchFromOrderRadius 2019-08-11 16:40:55 +02:00
reaperrr
b7d966f78f Don't exit FlyOffMap immediately on leaving map
Usually they'll get removed afterwards, so they need to be
out of players' sight before ending this activity.
2019-08-11 16:28:42 +02:00
reaperrr
64780fc865 Fix ProductionAirdrop aircraft removal timing
...when leaving map before finishing TakeOff.
2019-08-11 16:28:42 +02:00
teinarss
ff1d4ec9ae Fix Out of sync caused by Locomotor cache 2019-08-11 09:53:02 +02:00
abcdefg30
859d01da7d Always remove the spawn cameras after prison infiltration 2019-08-10 21:20:17 +01:00
abcdefg30
a8ff8e75fc Make warfactory infiltration a secondary objective 2019-08-10 21:20:17 +01:00
abcdefg30
7ddae59d83 Prevent a second infiltration of warfactory or prison 2019-08-10 21:20:17 +01:00
abcdefg30
851d115a44 Fix allies05a crashing by ensuring the cameras exist before removing them 2019-08-10 21:20:17 +01:00
tovl
a8b9562d74 Adjust waypoint linewidths. 2019-08-10 21:17:38 +01:00
tovl
8690a4a6ce CLean up type check in harvesterbotmodule. 2019-08-10 19:12:50 +01:00
tovl
1b4ab564fe Fix AI harvester not resuming after chronoshift. 2019-08-10 19:12:50 +01:00
tovl
5393b689d4 Disable preemptive targeting for queued orders. 2019-08-10 19:10:45 +01:00
teinarss
4193247169 Reset Locomotor cache on world loaded 2019-08-10 17:34:11 +02:00
teinarss
ab9834fdcd Update locomotor cache when Crushable is enabled/disabled 2019-08-10 17:34:11 +02:00
teinarss
277906c657 Fixes on blocking logic 2019-08-10 17:34:11 +02:00
Tomase
98602cb1cb Change impassable terrain to short.max 2019-08-10 17:34:11 +02:00
Paul Chote
702f4d1937 Remove unused return values from Show*Dropdown methods. 2019-08-10 16:03:59 +02:00
Paul Chote
d0faaf29ff Restore selection lines for TargetLinesType.Automatic spectators. 2019-08-10 16:03:59 +02:00
Paul Chote
19aea3c07a Change target line default to "Manual". 2019-08-10 16:03:59 +02:00
Paul Chote
95ca14d4a3 Replace DrawTargetLine checkbox with an Automatic/Manual/Disabled dropdown. 2019-08-10 16:03:59 +02:00
Paul Chote
2909445452 Display target lines when the Waypoint command bar mode is active. 2019-08-10 16:03:59 +02:00
Paul Chote
292196e2d6 Allow left click to cancel AttackMove without clearing selected units. 2019-08-10 13:08:32 +02:00
Paul Chote
ad099b5c98 Allow Attack Move and Guard OGs to be activated while shift is held. 2019-08-10 13:08:32 +02:00
abcdefg30
d1c56d78e1 Fix spamming repair orders repairing faster 2019-08-10 11:39:12 +01:00
tovl
c0d5cd750d Add missing target lines. 2019-08-10 12:17:36 +02:00
teinarss
daa82d113e Prevent crash when unloading Cargo structures 2019-08-10 11:52:33 +02:00
Ivaylo Draganov
017eca3dc1 Add support for "select all" and "select by type" for multiple players 2019-08-09 22:40:09 +02:00
reaperrr
7cfc65010f Fix that aircraft with TakeOffOnResupply can't force-land 2019-08-09 09:45:40 +02:00
reaperrr
969be686a3 Fix aircraft with TakeOffOnResupply not taking off
...after auto-resupply.
2019-08-09 09:45:40 +02:00
abcdefg30
ddf824b494 Fix AutoCarryall crashing when the cargo dies 2019-08-08 17:46:34 +02:00
reaperrr
ac3b3db7ac Made Resupply canceling more robust
The following improvements are made here:
- merged and streamlined the two IsCanceling checks in Tick
  into one that covers both isCloseEnough cases
- isCloseEnough now only checks distance to host
  if host is still valid and otherwise returns 'false'
- called transports are now also cancelled when host becomes
  invalid, not only if the activity is cancelled via order
- aircraft now always take off if the host becomes invalid
- ground actors only try to leave if host is still existing
2019-08-08 17:22:53 +02:00
Paul Chote
ddc4c4ff06 Add queuing support to RepairOrderGenerator for units. 2019-08-07 21:31:20 +02:00
Paul Chote
1543ccb749 Reverse target line draw order. 2019-08-07 14:03:40 +02:00
reaperrr
b0a7865cfa Reduce Map.Contains(CPos) cost in legacy mods
If a mod uses rectangular maps and no height levels,
checking if the CPos is within Bounds
should be enough and cheaper than the whole ToMPos
conversion and checks.
2019-08-07 14:02:18 +02:00
Paul Chote
8ffd8ae822 Remove ShowTargetLines from delivery Lua API calls.
Lines should only be activated in response to an
explicit player action.
2019-08-06 17:56:56 +02:00
Paul Chote
96263d47c5 Restore target line display for allied players and spectators.
Change behaviour to require the force-display modifier to reduce
visual noise.
2019-08-06 17:52:43 +02:00
tovl
58bb7fcbc0 Rework minefield visualisation. 2019-08-05 02:53:09 +01:00
tovl
b7a7b7aa7e Revise target line colours to distinguish different attack types. 2019-08-05 02:53:09 +01:00
Turupawn
3240b1e9eb Overhaul target line rendering:
- Targets are now defined by the activities
- Queued activities are shown
- Support custom attack colors
2019-08-05 02:53:09 +01:00
Paul Chote
bc4dea406d Fix AttackTDGunboatTurreted exiting early. 2019-08-05 02:53:09 +01:00
tovl
8c7ff3b5b0 Make VisualMove uninterruptible by making Turn a Child of Drag. 2019-08-04 11:48:59 +02:00
tovl
207305e7d2 Reimplement MADtank logic as activity. 2019-07-30 11:03:32 +02:00
tovl
9e6f8aef60 Do not cancel parent activity when refinery is destroyed. 2019-07-29 19:56:23 +02:00
Paul Chote
a4b8ffa99d Allow PBOG to nudge blocking helicopters. 2019-07-28 11:31:24 +02:00
Paul Chote
2f99512bd4 Clear dirty blocking cells after updating. 2019-07-27 17:21:43 +02:00
Paul Chote
6345655bb1 Add a PerfSample to UpdateCellBlocking. 2019-07-27 17:21:43 +02:00
Paul Chote
8ae2b00414 Allow boxes to be placed in interior maps. 2019-07-27 13:11:51 +02:00
Paul Chote
6e978db1da Extract a ^Box template to reduce duplication. 2019-07-27 13:11:51 +02:00
4mfie
ff02b8ba06 Add timestamps to server log files
Servers are now writing timestamps to the log files using the the ISO 8601 timestamp format defined in the game server settings.
2019-07-27 10:47:24 +01:00
Andre Mohren
ebc533ed53 Exception should inform which actors causes it. 2019-07-27 10:44:30 +01:00
teinarss
b5c387774c Fixed selecting none in spec dropdown should set none as active panel 2019-07-27 10:17:34 +01:00
teinarss
cc84daacea Added cache for cell cost and blocking 2019-07-26 15:54:22 +02:00
teinarss
fb1af81280 Updated TerrainInfo cost to use short 2019-07-26 15:54:22 +02:00
teinarss
27077d6427 Added CellUpdated event to ActorMap 2019-07-26 15:54:22 +02:00
teinarss
3a17b26405 Creating PlayerMask 2019-07-26 15:54:22 +02:00
teinarss
2ddf9fa826 Using Locomotor instead of Info for pathfinding 2019-07-26 15:54:22 +02:00
Paul Chote
c00b13a18e Fix player color when a client is bumped to a spectator slot. 2019-07-24 23:07:12 +02:00
reaperrr
4c3f2f3afa Fix aircraft allowing enter when it should not
Show "enter-blocked" cursor when resupply is not possible,
except when
-  the actor CanForceLand,
- does not TakeOffOnResupply,
- and has active ForceEnter modifier.
2019-07-23 17:01:41 +02:00
reaperrr
5b3e6175ea Fix Repairable returning order targeter for aircraft
Aircraft (currently) does its own order targeting for resupplies,
so this could lead to conflicts.
2019-07-23 17:01:41 +02:00
reaperrr
e7769357a8 Improve AircraftCanEnter readability 2019-07-23 17:01:41 +02:00
reaperrr
e662f17f06 Fix that VTOLs can ignore TurnToDock/-Land
When already at horizontal target position, no Turn was queued.
2019-07-23 16:17:18 +02:00
tovl
d9e1a68453 Cancel carryall transport request when cancelling order. 2019-07-22 22:54:01 +02:00
Punsho
9ac3d7507c Add Fake Allied Barracks to RA 2019-07-21 23:59:14 +02:00
reaperrr
f25449a3bf Set InitialFacing for TS aircraft to 224
North-East looks better as starting and landing facing.
2019-07-21 16:29:38 +02:00
reaperrr
30c2e6b4d2 Remove Resupply re-queueing hack from Aircraft
By preventing that other traits can remotely cancel Resupply
or ReturnToBase.
2019-07-21 16:29:38 +02:00
reaperrr
bfcdb3a8a2 Add IdleBehavior enum to Aircraft 2019-07-21 16:29:38 +02:00
reaperrr
d185f6e9f1 Remove AbortOnResupply from Aircraft again
This was accidentally re-added during a rebase in
a previous PR.
2019-07-21 16:29:38 +02:00
reaperrr
7f4fbfcf46 Change Resupply closeEnough 'infinite' to negative
...instead of 'zero'.

Returning 'true' at a distance of zero was a legacy left-over
that isn't used anymore once #16695 is merged.
2019-07-21 15:17:09 +02:00
reaperrr
fa41554309 Fix actors resupplying even if too far from resupplier 2019-07-21 15:17:09 +02:00
teinarss
f46cad5347 Fix game minute in PlayerStatistics 2019-07-21 14:23:25 +02:00
teinarss
e06c97bc03 Updated the LineGraphWidget with new layout 2019-07-21 14:23:25 +02:00
teinarss
60250e621c Fix random flag for spec in score screen 2019-07-21 13:50:02 +02:00
teinarss
551d72b061 Fixes flag in spec ui 2019-07-21 13:50:02 +02:00
tovl
c5558e2145 Remove SequenceActivities. 2019-07-20 23:41:31 +02:00
Ivaylo Draganov
86c8dfe96e Add a tooltip text to overflowing ButtonWidget in hotkey settings panel 2019-07-20 17:39:07 +02:00
Ivaylo Draganov
ef0cb7552d Revert "Scissor the text of a ButtonWidget if it overflows and display a tooltip"
This reverts parts of commit 76a6e7ec92.
2019-07-20 17:39:07 +02:00
Punsho
70dc053c5f RA balance changes 2019-07-20 12:09:54 +01:00
tovl
a38c2d9aae Allow ReturnToBase to exit if actor does not land at building. 2019-07-19 12:19:15 +02:00
tovl
ed18ecfcaf Allow explicit landing orders to be disabled in yaml. 2019-07-19 12:14:39 +02:00
teinarss
931d5acc33 Balancing changes TD 2019-07-19 12:08:45 +02:00
tovl
0e62490d57 Let autocarryall switch destination when carryable switches destination. 2019-07-19 10:49:24 +02:00
tovl
231825d0d0 Remove WaitForTransport activity. 2019-07-19 10:49:24 +02:00
tovl
922c6e9c40 Fix harvesters losing their last harvesting position when carried by carryall. 2019-07-19 10:49:24 +02:00
tovl
d59b01597a Always clear requested targets when exiting AttackActivity/Flyattack. 2019-07-18 23:14:56 +01:00
reaperrr
83a607e089 Fix resupply anim continuing if docked actor dies during resupply 2019-07-18 22:59:27 +01:00
Punsho
8fa7bb16f8 Remove redundant burst delay from heavy tanks 2019-07-18 13:31:43 +02:00
reaperrr
4bf659ca38 CanSlide update rule 2019-07-18 10:26:43 +02:00
reaperrr
747e60d8b1 Revert FlightDynamics yaml changes
- TD and RA were straight up reverted.

- D2k was manually reverted with following changes:
-- Frigate staying VTOL.
-- Carryall staying CanSlide: true but CanHover: false.
-- bogus VTOL/CanHover flags on Ornithopter staying removed.

- TS was manually reverted to keep the behavior
improvements of the original FlightDynamics PR.
2019-07-18 10:26:43 +02:00
reaperrr
cf4d73ab91 Revert FlightDynamics
This needs more thought and most parts might get superseded
by other approaches.

Kept CanSlide separation from CanHover.
2019-07-18 10:26:43 +02:00
reaperrr
aa5c8b4efa Revert FlightDynamics update rule 2019-07-18 10:26:43 +02:00
Mustafa Alperen Seki
30e2b69dba Fix several traits missing OrderString checks for VoicePhraseForOrder 2019-07-16 10:04:55 +01:00
reaperrr
c51f2c036a Make aircraft always take off after repair
Reservable logic doesn't handle repairs, and we
don't want aircraft to block repair bays etc. until it does.
2019-07-15 23:48:54 +01:00
reaperrr
a010c72780 Fixed comment typo in Aircraft 2019-07-15 23:48:54 +01:00
reaperrr
5211eb25aa Improve handling of finished/cancelled Resupply 2019-07-15 23:48:54 +01:00
reaperrr
5b65e618ee Remove Resupply Cancel override
This became detrimental to actor responsiveness
while resupplying.
2019-07-15 23:48:54 +01:00
reaperrr
e4011b86ac Move AbortOnResupply to AttackAircraft
Additionally, if AbortOnResupply is set to 'true',
abort FlyAttack right away when queueing ReturnToBase.
2019-07-15 23:48:54 +01:00
reaperrr
1f16cb6864 Make Repairable(Near) implement interfaces explicitly 2019-07-15 23:48:54 +01:00
reaperrr
1bb988512f Move AmmoPool RemainingTicks reset to Rearmable
This is a better place to do this than the Resupply activity.
2019-07-15 23:48:54 +01:00
reaperrr
f71912f337 Move movement to resupplier inside Resupply activity
From Repairable(Near).
2019-07-15 23:48:54 +01:00
reaperrr
a7fa372045 Fix Resupply regression
The work-around was originally written with ground units in mind
and caused issues with aircraft.
2019-07-15 23:48:54 +01:00
abcdefg30
4fc6a911a0 Disable MAD tanks on exodus 2019-07-15 23:33:58 +01:00
abcdefg30
e37474cf63 Make some Soviet actors buildable in exodus
Their Allied counter-parts are already buildable.
Arty is still excluded on purpose.
2019-07-15 23:33:58 +01:00
abcdefg30
7908ce6274 Remove unnecessary definitions
The production buildings for those units are not buildable
2019-07-15 23:33:58 +01:00
abcdefg30
736a726a2b Rebrand leftover Hind rules in the missions 2019-07-15 23:33:58 +01:00
Paul Chote
579d2c19e2 Add --check-conditional-trait-interface-overrides utility command.
This command is used by `make check` to detect traits that incorrectly
override interface methods that are required for conditions to work
correctly.
2019-07-14 00:41:59 +02:00
Paul Chote
6eaf615798 Fix conditional traits that incorrectly override INotifyCreated. 2019-07-14 00:41:59 +02:00
Punsho
37325dbfc7 Reskin Hind with Black Hawk sprite 2019-07-13 01:10:30 +02:00
reaperrr
701b1524e5 Fix InstantHit crashing if blockable and target is dead
If the weapon has TargetActorCenter, the projectile is Blockable
and the target dies the same tick the projectile is fired but before
the 'blocked' check is performed, the target.CenterPosition lookup
would crash since the target has become invalid.

Work around this by ignoring TargetActorCenter and using
args.PassiveTarget position instead if the target is already dead.
2019-07-12 22:09:14 +02:00
tovl
71a1060ecb Prevent carryalls picking up non-existent units. 2019-07-11 13:19:19 +02:00
tovl
0562814efa Prevent carryalls delivering non-existent units. 2019-07-11 13:19:19 +02:00
Ivaylo Draganov
768043bc4e Add missing tooltip container to settings.yaml 2019-07-10 19:55:30 +01:00
reaperrr
1c03fb9e51 Revert Simplify CreateEffectWarhead
Reverts #16312.
2019-07-07 19:15:08 +02:00
tovl
2912bff850 Fix location checks for queued deployment. 2019-07-07 00:40:38 +01:00
abcdefg30
b4b3ce68a9 chrome.yaml style fixes 2019-07-05 13:38:49 +02:00
reaperrr
da8a353e65 Remove redundant code from ProductionAirdrop
With the updated Land code, this is now obsolete.
2019-07-05 00:03:36 +02:00
reaperrr
bbf4495668 Update rule for FlightDynamics 2019-07-05 00:03:36 +02:00
reaperrr
990087d434 FlightDynamics yaml changes
Rules updates for official mods.
2019-07-05 00:03:36 +02:00
reaperrr
0ebeb30880 Replace various Aircraft fields with FlightDynamics
Replaces various booleans with a FlightDynamics flag list.
2019-07-05 00:03:36 +02:00
tovl
824db72a4c Prevent VisualMoveIntoTarget from overshooting when turning. 2019-07-03 20:42:19 +02:00
tovl
985020b4ad Simplify special exits of several acitivities. 2019-07-03 20:42:19 +02:00
tovl
3790169db9 Make Tick return bool 2019-07-03 20:42:19 +02:00
tovl
09c1611239 Always check if activity state is Done. 2019-07-03 20:42:19 +02:00
tovl
714b09ac4f Add default for Activity-Tick 2019-07-03 20:42:19 +02:00
tovl
b9c302a73a Move ChildActivity handling into base Activity class. 2019-07-03 20:42:19 +02:00
tovl
37379daf3c Refactor MoveAdjacentTo. 2019-07-03 20:42:19 +02:00
tovl
3ac5ac25f6 Queue WaitForTransport childactivity in OnFirstRun. 2019-07-03 20:42:19 +02:00
abcdefg30
b35dfb50a8 Remove Selectable from planes in TD 2019-07-01 20:19:10 +01:00
Punsho
4f6aa79e91 Normalise Construction Yard Cost 2019-07-01 17:04:14 +02:00
Paul Chote
5d8b6d6057 Fix force-landed transports taking off after (un)loading passengers. 2019-07-01 16:00:03 +02:00
Paul Chote
da0b24e891 Disable water trails for carried Hover MLRS. 2019-06-30 18:04:43 +02:00
tovl
71a035315c Prevent infinite loop between FlyAttack and ReturnToBase. 2019-06-30 18:04:43 +02:00
tovl
5920de1384 Airborne transports only land to (un)load. 2019-06-30 18:04:43 +02:00
tovl
76422933f6 Allow forced landing on helipads and enforce takeoff otherwise. 2019-06-30 18:04:43 +02:00
tovl
79a48765d9 Allow VTOLs to land with force-move 2019-06-30 18:04:43 +02:00
tovl
8e5875453a Improve Carryall behaviour and integration with Aircraft. 2019-06-30 18:04:43 +02:00
tovl
adecd4ca87 Overhaul Land activity:
- Landing on an actor is no longer blocked by the underlying terrain
- Land in a nearby cell if the requested location is blocked
- Internally manages the fixed-wing landing sequence
- ProductionAirdrop transport waits until the exit is free before landing
2019-06-30 18:04:43 +02:00
Paul Chote
ff9db0bf7a Reset RequestedTargets that are cancelled before the first attack tick. 2019-06-29 23:28:23 +02:00
Paul Chote
8f7426f579 Reduce duplication around AttackFollow's targets. 2019-06-29 23:28:23 +02:00
Ivaylo Draganov
caa440ce9a Adjust height of multiplayer-browser chrome to be in line with other panels 2019-06-29 23:10:25 +02:00
Ivaylo Draganov
3fb60740be Add support for opening DropDownButtonWidget upwards if clipped by the viewport 2019-06-29 23:10:25 +02:00
Ivaylo Draganov
e23054631d Add "Flat" and "Low Priority" selection modes to default mods 2019-06-29 20:46:12 +02:00
Ivaylo Draganov
c1fc0c1b74 Allow selection priority to be modified using a hotkey 2019-06-29 20:46:12 +02:00
Mustafa Alperen Seki
3e39ada304 Implement DetectCloakedMultiplier. 2019-06-28 12:19:08 +02:00
Mustafa Alperen Seki
d36973138c Implement ReloadAmmoDelay multiplier. 2019-06-28 12:16:48 +02:00
Ivaylo Draganov
c9ff54bfd5 Add hotkey settings panel with a hotkey remap dialog
* Add HotkeyDialogLogic.cs
* Add dialog-hotkey.yaml to all mods
* Add `GetFirstDuplicate` method to HotkeyManager to aid in validation
* Add "Player" and/or "Spectator" type to all hotkeys to allow for
validation based on overlapping types
* Change settings.yaml and SettingsLogic.cs to work with the new dialog
2019-06-28 12:10:48 +02:00
Ivaylo Draganov
9783fdaf78 Change the name of Keycode.UNKNOWN to "Undefined" 2019-06-28 12:10:48 +02:00
Ivaylo Draganov
7dfd91bc39 Remove from HotkeyManager hotkeys found in settings.yaml but not in hotkey definitons 2019-06-28 12:10:48 +02:00
Ivaylo Draganov
db8c8fee4d Add generic notice colors for the UI (info, success, warning, error) 2019-06-28 12:10:48 +02:00
Ivaylo Draganov
76a6e7ec92 Scissor the text of a ButtonWidget if it overflows and display a tooltip
Also:
* add a variable to a comomn pattern used for truncating text in HotkeyEntryWidget and TextFieldWidget
2019-06-28 12:10:48 +02:00
teinarss
f325a4d190 Relative mouse pos 2019-06-27 23:34:16 +02:00
teinarss
d7643602c1 Added a MouseAttachmentWidget to render the Direction arrows in SelectDirectionalTarget 2019-06-27 23:34:16 +02:00
teinarss
f07fb57e98 Rework relative mouse events. 2019-06-27 23:34:16 +02:00
teinarss
647cc2698b CursorViewportZoomed in SelectDirectionalTarget 2019-06-27 23:34:16 +02:00
teinarss
ffd3834849 Lock mouse position 2019-06-27 23:34:16 +02:00
abcdefg30
7bbfd823d0 Fix Minelayer crashes 2019-06-27 20:22:10 +02:00
Paul Chote
739f437c18 Fix blocked cursor for queued undeploy orders. 2019-06-25 01:15:10 +02:00
RoosterDragon
8f573568c8 Fix PostProcess command to handle paths with spaces. 2019-06-24 23:19:24 +02:00
Paul Chote
98125a3d94 Fix Mobile conditions.
The explicit IObservesVariables implementation was hiding
the base PausableConditionalTrait variable initialization.
2019-06-24 16:25:40 +02:00
Paul Chote
71ed22a473 Fix crate paradrop animation. 2019-06-22 15:52:19 +03:00
Paul Chote
d70c86d37a Allow crates to spawn in water. 2019-06-22 15:52:19 +03:00
Paul Chote
a2d51753ba Fix final parachuted actor position. 2019-06-22 15:52:19 +03:00
Ivaylo Draganov
d26919efd5 Fix position of lobby admin icon in player tooltips 2019-06-21 23:07:34 +01:00
RoosterDragon
58dced7e05 Silence some doc errors in VS2019. 2019-06-21 21:22:12 +02:00
teinarss
b647d46196 Vertical alignment in TS 2019-06-21 12:51:45 +02:00
teinarss
95874ccfde Vertical alignment in RA 2019-06-21 12:51:45 +02:00
teinarss
ed1250b14d Vertical alignment in D2k 2019-06-21 12:51:45 +02:00
teinarss
702a419fc5 Vertical alignment fixes in common 2019-06-21 12:51:45 +02:00
teinarss
d2639645bf Vertical alignment on labels in TD 2019-06-21 12:51:45 +02:00
teinarss
cc588f11c4 Updated vertical alignment for labels in Manage Content 2019-06-21 12:51:45 +02:00
teinarss
4e84545b55 Updated ChatDisplayWidget to use the new vertical alignment 2019-06-21 12:51:45 +02:00
teinarss
ab382ce4d6 Removed BaseLine and updated ButtonWidget and CheckboxWidget to use Font.TopOffset 2019-06-21 12:51:45 +02:00
teinarss
9982b01642 Get the Ascender value from mod.yaml instead from the Font 2019-06-21 12:51:45 +02:00
Paul Chote
a260b50ce1 Document the revised protocol. 2019-06-20 22:50:17 +02:00
Paul Chote
c6232f20f9 Split Protocol version into Handshake vs Orders.
Handshake is kept at 7.
Orders is incremented to 8 to reflect immediate order changes.
2019-06-20 22:50:17 +02:00
Paul Chote
fe41dcb45e Restore 0xFE order for handshakes.
This restores handshake compatibility with protocol 7 servers.
2019-06-20 22:50:17 +02:00
Paul Chote
bfddfec461 Replace magic numbers with an OrderType enum. 2019-06-20 22:50:17 +02:00
Paul Chote
862a274357 Merge ServerOrder into Order and 0xFE order type into 0xFF. 2019-06-20 22:50:17 +02:00
Paul Chote
90ebffc6c0 Remove unused PauseGame handling.
Pause is not an immediate order.
2019-06-20 22:50:17 +02:00
Paul Chote
9daf02a955 Remove unused field from HandshakeRequest.
This field was not serialised, so compatibility
is not impacted.
2019-06-20 22:50:17 +02:00
Paul Chote
1e23c0a7b7 Fix bot PlaceBuilding orders. 2019-06-20 18:51:02 +01:00
reaperrr
db0c6d88bf Fix AbortOnResupply not working
Going by yaml rules, all(!) aircraft in the shipping
mods should be aborting any previous activities
on resupply. None actually did, due to this bug.
2019-06-20 15:01:30 +01:00
Ivaylo Draganov
9f59b007ab Add palette order to support powers in TD, RA and d2k 2019-06-15 09:55:22 +02:00
Ivaylo Draganov
a85b634655 Add SupportPowerPaletteOrder to SupportPowerInfo 2019-06-15 09:55:22 +02:00
Paul Chote
a8b7fcaf87 Fix undeploy orders always being queued. 2019-06-15 09:49:23 +02:00
Mustafa Alperen Seki
b63792c73e Update global mix database.dat with Sole Survivor definitions. 2019-06-15 06:23:24 +02:00
reaperrr
c8a42cbce2 Introduce AirAttackType
Aircraft attack behavior (currently FlyBy or Hover)
is now controlled via this instead of the CanHover boolean.
2019-06-10 12:43:34 +02:00
Paul Chote
b59ae476e4 Add PlaceBuildingVariant trait. 2019-06-10 11:46:32 +02:00
Paul Chote
44e41cc054 Add key handling to order generators. 2019-06-10 11:46:32 +02:00
Mustafa Alperen Seki
0eb5063260 Add lua function Media.DisplaySystemMessage 2019-06-09 16:29:42 +02:00
reaperrr
97084effac Improve Aircraft firstTick code
- Remove ReserveSpawnBuilding:
Only used in one place, and removing it
avoids a double GetActorBelow() look-up.

- Remove FallsToEarth check form Aircraft.firstTick:
Aircraft triggers UnReserve() on actor disposal,
so this work-around should no longer be necessary.
2019-06-09 11:24:07 +01:00
Paul Chote
788e73db64 Enable StyleCop rule SA1115. 2019-06-08 19:28:14 +02:00
Paul Chote
4dd08d9dc2 Enable StyleCop rule SA1500. 2019-06-08 19:26:53 +02:00
Paul Chote
ebf2ce32c0 Make sure braces for multi-line statements are on their own lines. 2019-06-08 19:26:53 +02:00
Paul Chote
c89f8dbb89 Enable StyleCop rule SA1002. 2019-06-08 18:46:03 +02:00
Paul Chote
65856f3b0e Fix remaining semicolon spacing issues. 2019-06-08 18:46:03 +02:00
Paul Chote
c253aaeb9d Replace for(;;) with while (true). 2019-06-08 18:46:03 +02:00
Paul Chote
4d8aaeb690 Enable StyleCop rule SA1128. 2019-06-08 18:44:50 +02:00
Paul Chote
674155a8dd Move ctor initializers to their own line. 2019-06-08 18:44:50 +02:00
reaperrr
979ed1b140 Merge HeliAttack into FlyAttack
And polish CanHover FlyAttack behavior:

- Get rid of direct TickFacing usage
- Fix that the CanHover facing/altitude update would override
  TakeOff child of Fly
- Streamline the queueing of child activities
- Get rid of a direct FlyTick in favor of relying on Fly activity
- Pull queueing of TakeOff out of the if-else
2019-06-08 17:07:18 +01:00
Paul Chote
a7617b2443 Reseed the RNG when restarting a game. 2019-06-08 16:23:33 +02:00
abcdefg30
586fa80943 Defer running the contents of TraitEnabled in WithMoveAnimation 2019-06-08 15:28:54 +02:00
Paul Chote
1aa80f9c11 Add download hashes for the default mod packages. 2019-06-08 13:39:17 +02:00
Paul Chote
03c1eaad76 Add a SHA1 check for downloaded packages. 2019-06-08 13:39:17 +02:00
Paul Chote
1d3754f9c0 Enable StyleCop rules SA1509, SA1513. 2019-06-08 13:20:14 +02:00
Paul Chote
548de12e85 Add newlines after closing braces. 2019-06-08 13:20:14 +02:00
Paul Chote
9f15754926 Remove scoped blocks in ReplayBrowserLogic. 2019-06-08 13:20:14 +02:00
Paul Chote
208b5b9686 Enable StyleCop rule SA1129. 2019-06-08 13:19:57 +02:00
Paul Chote
ebd36891dc Switch other struct types to default(T). 2019-06-08 13:19:57 +02:00
Paul Chote
dba1301b61 Change new BitSet<T> to default(BitSet<T>). 2019-06-08 13:19:57 +02:00
Paul Chote
37889af20e Enable StyleCop rule SX1101 2019-06-08 13:19:27 +02:00
Paul Chote
dabc7ec8dd Remove unnecessary this. references. 2019-06-08 13:19:27 +02:00
Paul Chote
ebe37a44ad Require force move for all undeploy-triggering orders. 2019-06-08 02:09:30 +02:00
Paul Chote
5d886b79f1 Remove AlternateTransportsMode.
This conflicts with undeploy orders and has been largely
superseded by queued enter orders.
2019-06-08 02:09:30 +02:00
Paul Chote
ecd8dee575 Add TransformsInto* traits to trigger construction yard undeploy. 2019-06-08 02:09:30 +02:00
Paul Chote
1b026b7e20 Disable out-of-range non-force targeting for deployed units. 2019-06-08 02:09:30 +02:00
Paul Chote
c853e8c5d6 Disable non-force move for deployed units. 2019-06-08 02:09:30 +02:00
tovl
ea036d4cc0 Allow move orders to cancel DeployForGrantedCondition. 2019-06-08 02:09:30 +02:00
reaperrr
8589e26dc2 Resolve rally point target on first run. 2019-06-07 22:18:33 +01:00
reaperrr
e6402d28a3 Fix and streamline MaximumPitch values in TS
The internal default is way too low for TS aircraft
(especially when passing cliffs).
2019-06-07 22:18:33 +01:00
reaperrr
52ef5617d3 Clarify MaximumPitch and AltitudeVelocity descriptions
AltitudeVelocity is strictly only for vertical-only movement,
MaximumPitch is only for altitude changes during horizontal movement.
2019-06-07 22:18:33 +01:00
reaperrr
ac08f24828 Make aircraft move to CruiseAltitude on new order 2019-06-07 22:18:33 +01:00
reaperrr
ce3d7c98ad Refactor TakeOff
- Make it self-contained by moving actual take-off
  from 'Fly' to this
- Make 'moveToRallyPoint' a simple boolean
- Make AttackMove to rally point a child activity
- Make TakeOff uninterruptible
2019-06-07 22:18:33 +01:00
reaperrr
4f8f8cfb9d Merge HeliFly into Fly 2019-06-07 22:18:33 +01:00
reaperrr
5698ea0910 Remove HeliFlyAndLandWhenIdle
Already obsolete, as aircraft with CanHover do properly become idle
and land when LandOnIdle is set to 'true'.
They currently need VTOL too, but all CanHover-aircraft
in the shipping mods have that and it will be fixed soon as well.
2019-06-07 22:18:33 +01:00
abcdefg30
27cfa9b1f0 Fix MAD tanks always being repairable 2019-06-06 00:48:50 +02:00
abcdefg30
bf6fa94224 Remove unnecessary comments from aircraft.yaml 2019-06-05 00:54:55 +02:00
abcdefg30
26ec5946b3 Add LandableTerrainTypes to D2k's frigate 2019-06-05 00:54:55 +02:00
abcdefg30
1a078d13aa Remove the Ore landable terrain type from TRAN in TD 2019-06-05 00:54:55 +02:00
abcdefg30
c10f4e53e0 Work around C17s not being able to deliver units 2019-06-05 00:54:55 +02:00
Paul Chote
760a2b483e Fix RA/TD map editor copy/paste tile definitions. 2019-06-02 16:09:12 +02:00
Mustafa Alperen Seki
ccc68b0272 Make Crate trait public. 2019-06-02 15:34:06 +02:00
Paul Chote
229bac6777 Disable capturing while the make animation is playing. 2019-06-02 15:26:26 +02:00
reaperrr
3ff8fb3cd2 Rename Hovers' OffsetModifier to BobDistance 2019-06-02 10:00:58 +01:00
reaperrr
2f1f0c8aec Adapt TS aircraft to changed Hovers defaults 2019-06-02 10:00:58 +01:00
reaperrr
d5c66d9474 Fix or prevent bugs in Hovers
- Clamp fallTickHeight to at least 1,
  to avoid potential DivideByZero crash.
- Prevent modders from setting values that
  are bogus or would trigger other bugs,
  via loadtime YamlExceptions.
2019-06-02 10:00:58 +01:00
reaperrr
b60346abb1 Polish various aspects of Hovers
- Use WDist instead of int for fields
- Change default values to approximately restore previous
  releases' default behavior
- Improve and clarify descriptions
2019-06-02 10:00:58 +01:00
teinarss
4fae77ed1c Writing benchmark data at the end of the game 2019-06-02 00:00:48 +02:00
Ivaylo Draganov
982291119c Fix misaligned TD production tooltip icons 2019-06-01 08:52:59 +01:00
Paul Chote
1614cba99e Fix warhead removal lint warnings. 2019-05-31 20:55:38 +02:00
Paul Chote
fb075dc803 Improve linting of weapon and trait yaml removals. 2019-05-31 20:55:38 +02:00
ltem
2a7ea28b74 Fix inconsistency in oberserver statistics 2019-05-31 20:50:23 +02:00
abcdefg30
11e4c971c4 Fix a compiler error (wrong using) in D2kActorPreviewPlaceBuildingPreview 2019-05-31 16:36:19 +02:00
Evgeniy S
3a30b013a5 Move Selection into a Trait 2019-05-31 15:50:53 +02:00
Paul Chote
6723306bb4 Remove Enum.HasFlag from building preview generation. 2019-05-31 15:44:09 +02:00
Paul Chote
697935f931 Display yellow footprint for cells that trigger damage in D2k. 2019-05-31 15:44:09 +02:00
Paul Chote
3b2b093e0e Use original RA and TD footprint artwork. 2019-05-31 15:44:09 +02:00
Paul Chote
b3c1d96027 Add place previews for TS building plugs. 2019-05-31 15:44:09 +02:00
Paul Chote
087887250f Add line-build palette to RA, TD, D2k. 2019-05-31 15:44:09 +02:00
Paul Chote
3f9e4a313f Improve visibility of building placement preview. 2019-05-31 15:44:09 +02:00
Paul Chote
cdad07d172 Fix footprint type for line build structures. 2019-05-31 15:44:09 +02:00
Paul Chote
52fd32c311 Split IPlaceBuildingPreviewGeneratorInfo from PBOG. 2019-05-31 15:44:09 +02:00
Paul Chote
e2b27328bd Rework paradrop logic to be more robust. 2019-05-31 15:31:47 +02:00
Paul Chote
829b8cd2e1 Fix loadscreen text when switching between internal mods. 2019-05-31 15:22:08 +02:00
abcdefg30
1c965d812f Fix WithSpriteBody crashes 2019-05-29 20:58:45 +01:00
reaperrr
7a403c9af5 Play StartSequence when With*SpriteBody is enabled
Not only on actor creation.
2019-05-28 22:13:38 +02:00
reaperrr
666169e9b9 Add LockOnInaccuracy to Missile 2019-05-28 22:13:38 +02:00
Ivaylo Draganov
fde215360c Add tooltips to overflowing labels 2019-05-27 17:28:47 +02:00
Ivaylo Draganov
1fee50be2e Add TruncateLabelWithTooltip helper function
* Move GetContrastColor helper to SpriteFont
* Move WidgetUtils  from OpenRA.Game.Widgets to OpenRA.Mods.Common.Widgets
2019-05-27 17:28:47 +02:00
Ivaylo Draganov
79d1899426 Remove redundant compiler workaround 2019-05-27 17:28:47 +02:00
Paul Chote
1c6c55092f Fix Appveyor builds. 2019-05-26 23:13:37 +02:00
Paul Chote
4358b0956e Fix RunConfiguration condition whitespace. 2019-05-26 23:13:37 +02:00
Paul Chote
bb5268bef6 Package separate x64 and x86 Windows installers. 2019-05-26 23:13:37 +02:00
Paul Chote
4f7dca809f Fix csproj formatting. 2019-05-26 23:13:37 +02:00
Paul Chote
845fca25d1 Change platform from x86 to Any CPU (preferring 64 bit)
A Release-x86 configuration allows x86 Windows installers to still be created.
2019-05-26 23:13:37 +02:00
Paul Chote
7cf939fc68 Update OpenAL-CS.
Required for Win64 support.
2019-05-26 23:13:37 +02:00
Paul Chote
aed6098eaa Change default support dir location on Windows and Linux:
Windows now prefers the ApplicationData directory
Linux now prefers XDG_CONFIG_HOME

Fall back to the previous directory to avoid data loss or duplication.
2019-05-26 21:13:35 +02:00
teinarss
c89f4b7a76 Added tooltip to support powers in spec ui 2019-05-26 19:08:24 +01:00
teinarss
12484caf04 Added field to ProductionQueue to customize ordering in ObserverProductionIconsWidget 2019-05-26 19:04:54 +01:00
reaperrr
71995dbcbe Fix Bullet contrails 2019-05-26 13:02:54 +02:00
abcdefg30
29d238ba03 Empty the default of TrailSequences in NukePower (version 2) 2019-05-26 01:19:12 +02:00
Mustafa Alperen Seki
e007568e17 Make ClonesProducedUnits Conditional. 2019-05-25 23:19:41 +02:00
Paul Chote
1ed36da107 Update macOS launcher tag in fetch-thirdparty-deps-osx.sh. 2019-05-25 20:10:14 +02:00
reaperrr
3735c60533 Simplify CreateEffectWarhead 2019-05-24 20:08:33 +01:00
Paul Chote
78a70be0d4 Fix and enable SA1133, SA1134 style rules. 2019-05-24 10:47:57 +02:00
Evgeniy S
fbf9461890 Make StoresResources trait public 2019-05-23 14:20:38 +02:00
teinarss
9fc8b829e4 Updated the observer ui 2019-05-22 22:37:50 +01:00
teinarss
b90b3095a6 Updated ColorBlockWidget to handle setting the Color in yaml 2019-05-22 22:37:50 +01:00
teinarss
dad29cd3b3 Added GradientColorBlockWidget 2019-05-22 22:37:50 +01:00
teinarss
b25d0694b8 Updated ScrollPanelWidget to handle Scrollbar alignment 2019-05-22 22:37:50 +01:00
Paul Chote
c480b2b599 Prefer own service depots over allies. 2019-05-22 20:41:51 +02:00
Paul Chote
217221d174 Fix multiple clients being assigned as admin. 2019-05-22 20:30:54 +02:00
teinarss
881cacbef8 Replaces RunConfiguration and Configuration with launchSettings.json 2019-05-22 19:58:56 +02:00
teinarss
a495c0c475 Remove check to see if DeveloperMode is enabled 2019-05-22 19:46:30 +02:00
Mustafa Alperen Seki
3709380733 Implement ResourcePurifier 2019-05-22 19:41:21 +02:00
Mustafa Alperen Seki
feeae74455 Add INotifyResourceDumped Interface 2019-05-22 19:41:21 +02:00
Zimmermann Gyula
1e99075c70 Implement RefineryResourceMultiplier. 2019-05-22 19:41:21 +02:00
Zimmermann Gyula
71acfaf014 Implement HarvesterResourceMultiplier. 2019-05-22 19:41:21 +02:00
teinarss
ef47a3394f Added cell pos and world pos to debug 2019-05-21 22:28:44 +01:00
Paul Chote
3ca9d4b773 Drop targets when switching to a more restrictive stance. 2019-05-21 15:52:55 +02:00
Paul Chote
62b5d22e53 Add INotify(Activity)StanceChanged interfaces. 2019-05-21 15:52:55 +02:00
Paul Chote
07dc2a1132 Fix "Max Speed" option when viewing replays. 2019-05-19 18:09:45 +02:00
Paul Chote
327fdaea2d Defer NSIS installation to the pre-packaging step. 2019-05-19 16:59:54 +01:00
Paul Chote
15e88d9e58 Bump travis and the macOS/Linux packaging to use mono 5.20.1. 2019-05-19 16:59:54 +01:00
reaperrr
a2775a5c0f Fix DivideByZero crashes in Railgun projectile 2019-05-19 16:56:49 +02:00
reaperrr
90325305d6 Minor projectile clean-ups and perf optimizations 2019-05-19 16:56:49 +02:00
airetaM
6897ebe2a8 Makes Dogs buildable at the Barracks/Tent 2019-05-19 13:44:44 +02:00
Paul Chote
fbce22784b Fix ICaptureProgressWatchers continuing after captor disposal. 2019-05-19 13:37:42 +02:00
Paul Chote
44c5d38a0e Disable AutoTarget if targeting a persistent fallback. 2019-05-19 13:23:01 +02:00
Paul Chote
55f6744cf3 Replace IPreventsAutoTarget with IDisable(Enemy)AutoTarget.
This allows traits on the attacking unit to suppress auto targeting
and makes the distinction between the two interfaces clear.
2019-05-19 13:23:01 +02:00
Paul Chote
f9fe7486b3 Fix TD observer production icon hover crash. 2019-05-19 13:14:00 +02:00
Punsho
336cfedf84 Mines will no longer damage each other 2019-05-18 20:08:42 +02:00
Ivaylo Draganov
0bb832917a Fix TD chrome.yaml definitions for panel-allblack 2019-05-17 21:01:54 +02:00
Paul Chote
4756558f8a Merge man-page target into install-man-page 2019-05-17 19:02:46 +01:00
Paul Chote
c47c9d7ed6 Fix Makefile targets 2019-05-17 19:02:46 +01:00
reaperrr
7becbe6b14 Allow non-VTOL to LandOnCondition
Note: This might still break in unexpected ways,
since non-VTOLs implicitly rely on ReturnToBase
to calculate the approach vector for them.
2019-05-17 18:51:21 +01:00
reaperrr
0c2666b97e Streamline Land activity
Removed some redundant parameters, some redundant overloads
and made Land always consider LandAltitude relative to target.
2019-05-17 18:51:21 +01:00
reaperrr
14bd5ada1a Merge HeliLand into Land activity 2019-05-17 18:51:21 +01:00
abcdefg30
bc3cabdea0 Display an error when TrailSequences is empty and TrailImage is not 2019-05-17 18:53:52 +02:00
abcdefg30
b8fbc63542 Empty the default of TrailSequences in NukePower 2019-05-17 18:53:52 +02:00
teinarss
79f0bdc65c Added configurations for starting the mods in VS 2019-05-16 19:34:21 +01:00
teinarss
70f0075415 Use Write-Host instead of echo 2019-05-16 20:05:55 +02:00
abcdefg30
e888a235c0 Fix powershell if statements not checking the return value of calls 2019-05-16 19:41:29 +02:00
Paul Chote
242ebc5da9 Fix FrozenUnderFog visibility calculation when fog is disabled. 2019-05-16 18:23:47 +02:00
abcdefg30
215af20e62 Give a lint error when TimeLimitDefault is not in TimeLimitOptions 2019-05-16 14:56:56 +02:00
abcdefg30
09d6387e64 Prevent negative times in GameTimerLogic 2019-05-16 14:56:56 +02:00
Oliver Brakmann
28016a3a33 Disable TimeLimit dropdown on MP missions and Fort Lonestar 2019-05-16 14:56:56 +02:00
Oliver Brakmann
f617da08f6 Convert "Top o' the World" mission to use TimeLimit API 2019-05-16 14:56:56 +02:00
Oliver Brakmann
f11b7393ef Convert Allies-02 to make use of TimeLimit API 2019-05-16 14:56:56 +02:00
Oliver Brakmann
26d712728a Add scripting support for TimeLimitManager 2019-05-16 14:56:56 +02:00
Oliver Brakmann
47d88983fb Let sidebar timer count backwards if a time limit is set 2019-05-16 14:56:56 +02:00
abcdefg30
4a35d85884 Add a DropdownVisible property to TimeLimitManager 2019-05-16 14:56:56 +02:00
Oliver Brakmann
a63cc2d317 Add a time limit lobby option 2019-05-16 14:56:56 +02:00
abcdefg30
1364581696 Fix Sarin Gas Crackdown not ending after losing all units 2019-05-16 14:22:03 +02:00
evgeniysergeev
3bc5b07277 Fix for System.IO.InvalidDataException in VocLoader
Fix for VOC version check

use cached value from MoveNext instead of try/catch section
2019-05-15 21:20:24 +02:00
Paul Chote
72dbb871ac Add faction specific tooltip backgrounds. 2019-05-15 21:05:49 +02:00
Ivaylo Draganov
a5bd08bd02 Revamp Tiberian Dawn ingame UI 2019-05-15 21:05:49 +02:00
Ivaylo Draganov
4931fc2ca6 Enable AddFactionSuffixLogic for ProductionTabsWidget and BackgroundWidget 2019-05-15 21:05:49 +02:00
Paul Chote
6f1aaab3e3 Remove CallFunc. 2019-05-12 19:06:52 +02:00
Paul Chote
e57e881662 Use Target in DeliverUnit 2019-05-12 19:06:52 +02:00
tovl
0b747ba927 Rework Carryall drop-off queueing and ordering. 2019-05-12 19:06:52 +02:00
reaperrr
a403d9937d Fix palette effects on desert buildings/rocks 2019-05-12 17:46:25 +02:00
Paul Chote
6248326b29 Rename AttackMove *ScanConditions. 2019-05-12 10:59:36 +02:00
tovl
0e1374f0eb Replace pseudo-childactivities in AttackMoveActivity. 2019-05-12 10:59:36 +02:00
abcdefg30
1c13520ffd Update the forum link in the readme 2019-05-10 00:35:44 +01:00
reaperrr
17a40099df Fix launch delay and offset of TS ClusterMissile 2019-05-09 22:28:46 +01:00
reaperrr
6eb31401f1 Implement D2k DeathHand cluster logic 2019-05-09 22:28:46 +01:00
reaperrr
cf091e0548 Implement TS cluster missile warhead 2019-05-09 22:28:46 +01:00
reaperrr
9e91232ca7 Add DetonationAltitude to NukePower
And RemoveMissileOnDetonation boolean.

Allows airburst, and optionally missile continuing
until it hits the ground (without a second explosion).
2019-05-09 22:28:46 +01:00
Zimmermann Gyula
2648764ee3 Add FireClusterWarhead 2019-05-09 22:28:46 +01:00
teinarss
0e3d343f15 VAlign correctly in LabelWidget 2019-05-09 22:17:24 +02:00
teinarss
2d1c110857 Calculate font size correctly 2019-05-09 22:17:24 +02:00
Paul Chote
7c71e55b01 Restore no-arg ExponentialSliderWidget ctor.
This is required for dynamic widget creation.
2019-05-09 21:38:40 +02:00
Paul Chote
ba282865f1 Replace legacy StyleCop(Plus) with StyleCopAnalyzers
Analyzers are enabled in the Debug configuration
only to avoid unnecessary overheads when compiling
normally.
2019-05-09 20:40:08 +02:00
Paul Chote
353db73381 Fix a collection of minor style violations.
This enables several new StyleCopAnalyzer rules to
be enabled immediately during migration.
2019-05-09 20:40:08 +02:00
Paul Chote
76a8ae9f98 Set default values for BitSet<TargetableType>. 2019-05-09 20:40:08 +02:00
reaperrr
c24398e32c Repulsion performance optimizations
`cruising` is updated  on every position change,
so we can safely re-use it instead of
performing another DAT check.
Additionally, if repulsion force is
horizontally zero, it's guaranteed to be WVec.Zero,
so we can save that conversion too.
2019-05-09 19:00:07 +02:00
reaperrr
83b4e448c8 Fix Jumpjet default HeightOffset
Jumpjet CruiseHeight in TS was 500, roughly equivalent to
3.9 cells in OpenRA.
2019-05-05 23:41:55 +02:00
reaperrr
2953cbd9f1 Improve TS Harpy rotor offset 2019-05-05 23:41:55 +02:00
reaperrr
64d891cc6c Improve TS aircraft altitude values
The CruiseAltitude values and AltitudeVelocity
default were far too low compared to the original.
2019-05-05 23:41:55 +02:00
Paul Chote
f0d59391b5 Remove Start-Process from make.ps1.
This also removes the hardcoded path
requirement for dotnet.exe, and simplifies
the utility and dotnet detection.

The nr flag is no longer needed for dotnet,
and nologo is added to reduce unnecessary output.

The Release configuration is set for consistency
with the real Makefile.
2019-05-05 23:19:04 +02:00
Paul Chote
ac8252531b Fix solution listings in the Rider IDE. 2019-05-05 23:19:04 +02:00
Paul Chote
b93490efd0 Remove legacy cruft from .gitignore. 2019-05-05 23:19:04 +02:00
Paul Chote
1955cac84e Unify Windows and mono build systems.
The Makefile behaviour is recreated using the new and significantly
cleaner .NET Core csproj format.

fixheader.exe is promoted to OpenRA.PostProcess.exe and now runs
on all platforms.
2019-05-05 23:19:04 +02:00
Paul Chote
6e364cdbee Switch AppVeyor to use Visual Studio 2017. 2019-05-05 23:19:04 +02:00
Paul Chote
761b5e094d Reduce minimum .NET requirement to 4.6.1.
4.7.2 causes compatibility issues with Mono 5.4
in the interim period before we migrate to netstandard2.
2019-05-05 23:19:04 +02:00
Mustafa Alperen Seki
a4bac42c7f Add /playerxp command. 2019-05-05 21:52:28 +02:00
Paul Chote
5e38cfda81 Enable skirmish saves. 2019-05-05 09:30:58 +02:00
Paul Chote
c8f2ee5270 Save and load skirmish spectator viewport. 2019-05-05 09:30:58 +02:00
Paul Chote
410d0796c3 Disable bot logic while reloading game saves. 2019-05-05 09:30:58 +02:00
Paul Chote
100ec17ef0 Implement IGameSaveTraitData on BotModules. 2019-05-05 09:30:58 +02:00
Paul Chote
5f8a0f3372 Add IBotEnabled interface. 2019-05-05 09:30:58 +02:00
tovl
9abf715fd7 Allow opportunity fire for aircraft. 2019-05-04 23:40:16 +02:00
tovl
f16ff9eaa0 Base AttackAircraft on AttackFollow and get rid of SequenceActivities. 2019-05-04 23:40:16 +02:00
reaperrr
da6bf1a57d Make ActorTags display ChildActivities 2019-05-04 21:33:10 +02:00
jrb0001
b774556a5f Reduce overhead of every single order/sync frame by 162/222 bytes 2019-05-04 09:48:36 +02:00
LipkeGu
7f7809fe70 Use TryGet instead of Get and assign a default Fallback Color
This Fixes a crash in Situations when custom mods are used and reset OpenRA to its initial state.
2019-05-04 09:39:56 +02:00
matjaeck
c7b8f9f09f Add references to the Code of Conduct. 2019-05-04 09:27:34 +02:00
Paul Chote
e3f868f0a8 Update TS map previews and formatting. 2019-05-02 13:40:22 +02:00
Paul Chote
143cee2a80 Update D2k map previews and formatting. 2019-05-02 13:40:22 +02:00
Paul Chote
67683aacdb Update TD map previews and formatting. 2019-05-02 13:40:22 +02:00
Paul Chote
fe68780d1c Remove space from "Snow Town" map path. 2019-05-02 13:40:22 +02:00
Paul Chote
e431954107 Update RA map previews and formatting. 2019-05-02 13:40:22 +02:00
Paul Chote
f301cb891f Add missing LockPreview to mission maps. 2019-05-02 13:40:22 +02:00
Paul Chote
5f157c572f Restore newlines between top-level map.yaml blocks. 2019-05-02 13:40:22 +02:00
Paul Chote
d9c30c9659 Fix missing EOF yaml newlines and other style issues. 2019-05-02 13:40:22 +02:00
Paul Chote
2a085945df Add terminating newline to yaml strings. 2019-05-02 13:40:22 +02:00
Paul Chote
753a0b1e3e Add --refresh-map utility command. 2019-05-02 13:40:22 +02:00
reaperrr
ad4c0e6dee Remove HeliFlyCircle activity
FlyCircle actually works fine for D2k Carryalls,
and no other place used this.
2019-05-01 20:50:10 +01:00
Unknown
77d890848b Fix givecashall debug command
Issuing an order to another client causes a validation error in
ValidateOrder.OrderValidation(...). To fix this /givecashall will now
be issued as an order to the client that introduced the command. This
client will then resolve the command and give the cash to all playable
parties.
2019-05-01 18:30:44 +02:00
reaperrr
543d46f47c Make ground actors leave resupplier if resupply is aborted 2019-04-29 01:40:52 +01:00
reaperrr
bc0d8ca015 Remove ResupplyAircraft and AllowYieldingReservation
The few extra things those two activities did can be done
in Resupply, making them redundant.
2019-04-29 01:40:52 +01:00
reaperrr
4a06c66dbd Fix resupply anim not always finishing properly 2019-04-29 01:40:52 +01:00
reaperrr
83934074a4 Merge INotifyRearm/Repair into INotifyResupply
And streamline its notify methods.
Also cache INotifyResupply traits at beginning
of Resupply activity.
2019-04-29 01:40:52 +01:00
reaperrr
ba4b5738d7 Merge Rearm and Repair into Resupply activity
Allows parallel rearming and repairing.
2019-04-29 01:40:52 +01:00
Smittytron
123b3f054f Remove cash steal objectives from Allies 06a and 06b 2019-04-28 10:19:37 +02:00
Paul Chote
f26992443d Remove periods from lobby option tooltips. 2019-04-28 00:24:28 +02:00
teinarss
d9d2202599 System messages should be yellow to distinguish them from normal 2019-04-27 14:51:59 +02:00
jrb0001
db487e1264 Give every immediate order its own framing 2019-04-23 01:00:52 +02:00
jrb0001
f3133617dd Prevent immediate orders from being sent as regular orders 2019-04-23 01:00:52 +02:00
BGluth
55aa346ad7 Aircraft can now scatter 2019-04-22 22:04:51 +02:00
teinarss
e801537d96 Hide cursor and render the placeholder directly 2019-04-22 21:51:49 +02:00
teinarss
09f4b69aef Fixed the problem with clicking the Support Power button 2019-04-22 21:51:49 +02:00
teinarss
5e58364fad Made SelectDirectionalTarget a opted in feature and added fields for palettes 2019-04-22 21:51:49 +02:00
abcdefg30
b2278e85f0 Add support for arbitrary objective type names 2019-04-22 21:04:42 +02:00
abcdefg30
38b3a4a668 Split INotifyWinStateChanged from INotifyObjectivesUpdated 2019-04-22 21:04:42 +02:00
abcdefg30
6163523334 Enable spectator team chat in the lobby 2019-04-22 19:55:04 +01:00
abcdefg30
e6feba8884 Remove the TeamChat order type 2019-04-22 19:55:04 +01:00
abcdefg30
83b92ebacb Disable team chat when only one team member is alive 2019-04-22 19:55:04 +01:00
abcdefg30
9a84ccdd1d Send the designated team number as extra data in the order 2019-04-22 19:55:04 +01:00
abcdefg30
991093df81 Let immediate orders send a bitfield for extra order data 2019-04-22 19:55:04 +01:00
abcdefg30
5e363f18c9 Disable the team chat button after the game ended 2019-04-22 19:55:04 +01:00
abcdefg30
7b8df0ed54 Disable spectator chat when there is only one spectator
and re-enable it when players die
2019-04-22 19:55:04 +01:00
abcdefg30
767de564fc Use Team numbers instead of stances 2019-04-22 19:55:04 +01:00
abcdefg30
43f22f908d Don't make team messages of dead players public 2019-04-22 19:55:04 +01:00
abcdefg30
9bd0a71ca8 Return early instead of nesting 2019-04-22 19:55:04 +01:00
abcdefg30
e7f60a1e25 Don't ignore the message limit in team chat 2019-04-22 19:55:04 +01:00
abcdefg30
4a9a5ba757 Remove and restyle comments in UnitOrders 2019-04-22 19:55:04 +01:00
Mustafa Alperen Seki
2bb2d6e9c5 Add ability to grant condition multipile times to GrantExternalConditionCrateAction 2019-04-22 20:51:23 +02:00
Mustafa Alperen Seki
de7706c98f Add ProductionCost/TimeMultiplier 2019-04-22 20:44:50 +02:00
Mustafa Alperen Seki
1f730fbfb9 Make EngineerRepairable Conditional. 2019-04-22 20:25:52 +02:00
Mustafa Alperen Seki
c89d90e4b0 Add Types to EngineerRepair(able). 2019-04-22 20:25:52 +02:00
Mustafa Alperen Seki
e63f52c43f Add RepairSound to EngineerRepair. 2019-04-22 20:25:52 +02:00
Mustafa Alperen Seki
0f9a157943 Add support for Custom Cursors in EngineerRepairable. 2019-04-22 20:25:52 +02:00
Mustafa Alperen Seki
2194584b25 Fix EngineerRepairable stance checks. 2019-04-22 20:25:52 +02:00
Mustafa Alperen Seki
8752e76d1e Split EngineerRepairable to its own file. 2019-04-22 20:25:52 +02:00
Mustafa Alperen Seki
2463b2ed43 Remove Exit: from D2k ConYard. 2019-04-22 20:20:47 +02:00
Mustafa Alperen Seki
7a9d04395a Check for producee's IOccupySpaceInfo for production completation. 2019-04-22 20:20:47 +02:00
Mustafa Alperen Seki
f9ef41f165 Properly check for exitinfo != null in DoProduction() 2019-04-22 20:20:47 +02:00
Mustafa Alperen Seki
1573da03bb Fix production of dummy actors from producers without Exit trait. 2019-04-22 20:20:47 +02:00
tovl
ffbee7e45b Temp fix for harvester getting stuck around resource spawn 2019-04-22 16:39:47 +02:00
tovl
2eaeb2097c Refactor resource harvesting logic. 2019-04-22 16:39:47 +02:00
Mustafa Alperen Seki
77b313611e Make Queue Groups work with ClassicProductionQueue. 2019-04-22 16:16:35 +02:00
tovl
8e91a1ba89 Add order voice to GrantConditionOnDeploy. 2019-04-22 15:34:07 +02:00
tovl
9419d1b924 Fix TS artillery barrel disapearing during deploy animation. 2019-04-22 15:34:07 +02:00
tovl
351df4769b Let TS deployable units honor emp-disabled. 2019-04-22 15:34:07 +02:00
reaperrr
36783efbfb Give TS ClusterMissile a smoke trail
And increase visual FlightVelocity.

We don't know when this will be replaced with
TS-style voxel projectile, so a bit of visual polish can't hurt.
2019-04-22 15:13:11 +02:00
reaperrr
cee56a00af Give some translucency to TS missile trails 2019-04-22 15:13:11 +02:00
reaperrr
ba04965a63 Fix missile offsets & implement trail on DeathHand 2019-04-22 15:13:11 +02:00
reaperrr
78f538f103 Add sprite trail support to NukeLaunch/NukePower 2019-04-22 15:13:11 +02:00
reaperrr
4a71a6746f Group all Bullet Trail* properties together
Just a small code readability improvement.
2019-04-22 15:13:11 +02:00
tovl
560f8c26bc Add crushing logic to aircraft. 2019-04-22 02:56:57 +02:00
tovl
c633e07410 Make aircraft occupy cells when landed. 2019-04-22 02:56:57 +02:00
reaperrr
04a71a6c6a Exclude OpenRA.Platforms.Default.dll.config from clean
OpenRA.Platforms.Default.dll.config is part of the repo.
Linux makefile already excludes the file from removal.
2019-04-21 20:31:35 +02:00
tovl
6aea91bd46 Replace pseudo-childactivities in WaitForTransport. 2019-04-20 16:14:59 +01:00
tovl
a000b173d8 Replace pseudo-childactivities in Enter and related. 2019-04-20 16:14:59 +01:00
Paul Chote
d5588c51ed Implement "Game Saved" / "Game Loaded" notifications in RA and D2k. 2019-04-20 14:54:48 +02:00
Paul Chote
492b5aec82 Save and restore viewport position / selection / control groups. 2019-04-20 14:54:48 +02:00
Paul Chote
de9649df27 Add save/load browser and buttons to the UI. 2019-04-20 14:54:48 +02:00
Paul Chote
3a693d8def Implement loading screens. 2019-04-20 14:54:48 +02:00
Paul Chote
1f3b30c2d2 Implement game save/load backend. 2019-04-20 14:54:48 +02:00
Paul Chote
877215c86a Dynamically populate the ingame menu. 2019-04-20 14:54:48 +02:00
Paul Chote
1cfb110d03 Allow the cursor to be force disabled. 2019-04-20 14:54:48 +02:00
Paul Chote
f731c09086 Fix TD input prompt button height. 2019-04-20 14:54:48 +02:00
Paul Chote
bb324fb2d4 Add Sound.DisableAllSounds property. 2019-04-20 14:54:48 +02:00
Paul Chote
5d43417a5f Add player trait support for IWorldLoaded. 2019-04-20 14:54:48 +02:00
Lars Beckers
e6750bf19c Fix attack behaviour of disabled units. 2019-04-20 02:28:27 +02:00
abcdefg30
1bb319425b Add Sound.Play overloads that play a random sound from a list 2019-04-20 01:22:30 +02:00
reaperrr
5f6c8ba5d3 Fix Mobile.CurrentMovementType vertical handling
On bleed, the Horizontal flag is always returned on any position change,
even if that change is vertical-only.
2019-04-20 00:48:12 +02:00
abcdefg30
981fe6fae1 Remove the Lua return type of Beacon.New 2019-04-19 16:31:03 +02:00
abcdefg30
c93dc1424c Throw a LuaException when placing a beacon without the player trait 2019-04-19 16:31:03 +02:00
reaperrr
db68c6e264 Fix Mobile actors turning even if Mobile is paused 2019-04-14 21:58:28 +02:00
tovl
cc7e758b27 Replace pseudo-childactivities in carryall logic. 2019-04-14 19:05:06 +01:00
reaperrr
0eb0a5a2bd Add WithHarvesterSpriteBody
And move PrefixByFullness there.
Also put it into Mods.Cnc, as RA is the only shipping mod
using this.
2019-04-14 19:09:28 +02:00
reaperrr
840eb7006d Make actors ignore ReturnToBase order if already on resupplier 2019-04-13 18:47:08 +02:00
reaperrr
717b8a24f1 Fix ReturnToBase restarting on each hotkey press
Now that the RTB process is a single activity with childs,
it's relatively easy to prevent the activity from restarting
every time the deploy/RTB hotkey is pressed.
2019-04-13 18:47:08 +02:00
reaperrr
b24e4510c8 Make aircraft without TakeOffOnResupply always land
on resupplier, even if ammo is full, when given a
"ReturnToBase" order via deploy key.
In other words, in that case treat the RTB order like an
explicit "Repair" or "Enter" order.
2019-04-13 18:47:08 +02:00
reaperrr
c7eee6ae5d Improve ReturnToBase Activity.cs adherance
And make it use child activities for queueability.
2019-04-13 18:47:08 +02:00
reaperrr
8edf5b56ea Exclude dead actors from ChooseResupplier 2019-04-13 18:47:08 +02:00
reaperrr
2cdae0b380 Merge HeliReturnToBase into ReturnToBase 2019-04-13 18:47:08 +02:00
tovl
2a942bd04a Fix crash in FindAndDeliverResources.GetSearchFromLocation. 2019-04-13 16:04:54 +02:00
abcdefg30
14a4c47758 Increase the ZOffset of ore and gem mines in RA 2019-04-12 00:11:47 +02:00
teinarss
71596ae959 Added drag direction mouse interaction for set the approach direction for airstrike and parabombs 2019-04-04 20:10:34 +02:00
teinarss
1dd90a1d7b Pushed down the MouseInput handling to the OrderGenerators and made a base class for handling the basic logic 2019-04-04 20:10:34 +02:00
Mustafa Alperen Seki
9ec8d25dff Add AppearsOnMapPreview to default mods.
To Walls, (Tib)Trees, Ore/Gem Mines and Tech Structures.
2019-04-04 19:37:19 +02:00
Mustafa Alperen Seki
9fef2c01ec Add AppearsOnMapPreview
Allows preplaced actors to be rendered on map preview when saving the
map.

Also removes requirements for ResourceLayer in OpenRA.Game and moves it
to OpenRA.Mods.Common.
2019-04-04 19:37:19 +02:00
tovl
ea4f24d0b7 Rework harvester automation. 2019-04-04 19:22:25 +02:00
tovl
1d590ac207 Sanitize harvester search behavior. 2019-04-04 19:22:25 +02:00
tovl
8d8cade266 Remove no-op on harvester creation. 2019-04-04 19:22:25 +02:00
tovl
bc7516989e Rework harvester unblock and idle behavior. 2019-04-04 19:22:25 +02:00
tovl
3bfa32ca33 harvester Harvest order works with queues
fix for autocarryable harvesters

Make use of QueueActivity's own handling of order.Queued
2019-04-04 19:22:25 +02:00
tovl
307a87cd9e harvester Deliver order works with queues 2019-04-04 19:22:25 +02:00
Anson Wayman
f64c8f1ee8 Fix pluggable regression
Modified gapowr and gatower upgrade requirements to prevent multiple
stacking plug bug.
2019-04-04 19:11:04 +02:00
Mustafa Alperen Seki
e7b8a56511 Add ValidStances to AutoTargetPriority. 2019-04-04 19:08:10 +02:00
tovl
25bc3ae2d2 Fix chinook being unable to land. 2019-03-31 18:25:14 +02:00
teinarss
a467e2c92e Added the setting insert_final_newline to editorconfig 2019-03-31 18:02:17 +02:00
Daniel Llewellyn
6289816a69 Update thirdparty/configure-native-deps.sh
Add aarch64 and ppc64le architecture library to search paths.
2019-03-31 15:47:05 +02:00
Oliver Brakmann
320717003f Fix crash due to conflicting access to collection in killed Cargo 2019-03-31 08:41:06 +02:00
Mustafa Alperen Seki
1373a4e16e Seperate TS shellmap rules to Rules yaml.
And make all buildings and walls indestructible.
2019-03-30 23:08:46 +01:00
Paul Chote
f69c6ab3fb Update SharpZipLib to 1.1.0.
The default code page has been changed to UTF8
so our workarounds are no longer needed.
2019-03-30 20:47:22 +01:00
Paul Chote
9cbf08201f Disable debug and enable optimizations by default.
This does not affect stacktraces produced during
a crash when run using `mono --debug`.
2019-03-30 20:17:17 +01:00
Paul Chote
93193d4e63 Document dependency changes in INSTALL.md. 2019-03-30 20:17:17 +01:00
Paul Chote
2c0711d5fb Enable HiDPI rendering in Windows installer. 2019-03-30 20:17:17 +01:00
Paul Chote
d53338ca5e Switch to the newer Roslyn compiler on Linux/macOS. 2019-03-30 20:17:17 +01:00
Paul Chote
5b00586de2 Update Travis to Ubuntu 16.04, Mono 5.10, NSIS 3.03. 2019-03-30 20:17:17 +01:00
tovl
8ee11028d7 Replace SequenceActivities with ChildActivity in several air activities. 2019-03-30 18:54:30 +00:00
Mustafa Alperen Seki
7fe2d1223b Disable veterancy on TS Shellmap 2019-03-30 17:26:43 +01:00
Mustafa Alperen Seki
18be10b537 Make walls on shellmap indestructible. 2019-03-30 17:26:43 +01:00
Mustafa Alperen Seki
dc2fe5b682 Fix Veterancy removal on shellmap rules. 2019-03-30 17:26:43 +01:00
reaperrr
c82888204b MovementTypes refactor update rule 2019-03-30 16:24:47 +00:00
reaperrr
404eee23f9 Adapt WithMoveAnimation to INotifyMoving
And add ValidMovementTypes for configurability.
2019-03-30 16:24:47 +00:00
reaperrr
4c53599736 Adapt GrantConditionOnMovement to INotifyMoving 2019-03-30 16:24:47 +00:00
reaperrr
a10af382b4 Add plumbing for notifying traits of movement
More precisely, about start and stop of movement.
2019-03-30 16:24:47 +00:00
reaperrr
32ab822786 Fix ResupplyAircraft being cancelable by Stop command
It is now immediately queued again, as long as the actor
has not finished rearming/repairing yet.
2019-03-30 16:44:04 +01:00
reaperrr
b92aef5754 Make Aircraft.GetActorBelow() LandAltitude-aware 2019-03-30 16:44:04 +01:00
reaperrr
3211119027 Simplify ResupplyAircraft
By moving part of the take-off prevention (when TakeOffOnResupply
is set to false) to Aircraft.

Main reason & advantage is that dropping the 'WaitFor' child
makes this activity always end when resupplies are done,
which makes it more compatible with being queued as ChildActivity
itself (for example by ReturnToBase).
2019-03-30 16:44:04 +01:00
Oliver Brakmann
b4fd7331b2 Simplify Activity class
After the removal of the CompositeActivity class, all the supporting
code that made it work can be removed as well.
2019-03-30 14:38:23 +00:00
AngryBirdz
19977bb7da Counterstrike Soviet mission Top o' The World ported
I've just finished porting this mission. Tell me if you spot something wrong ;)

Update: Fixed a few things in the lua and rules.
2019-03-28 15:21:21 +01:00
Ivaylo Draganov
7695714f66 Add hotkey for removing actors from control groups
* Add `RemoveFromControlGroup` hotkey
* Add `RemoveFromControlGroup` method to `OpenRA.Game.Selection`
2019-03-28 13:20:47 +01:00
Smittytron
99987db5d9 Add Counterstrike mission Sarin Gas 2: Down Under 2019-03-28 13:14:35 +01:00
Clément Bœsch
3b926d71b5 Honor modifiers in multitap detection
Fixes Issue #15577.
2019-03-26 22:29:04 +01:00
Paul Chote
54d5afed57 Package mono inside the macOS app bundles.
This also removes the explicit dependency on mono's
packaged FreeType, which should allow development
builds to be used with homebrew-packaged mono.
2019-03-26 22:11:58 +01:00
tovl
872bf737e0 Fix transport being blocked by its own passengers. 2019-03-26 21:55:43 +01:00
Voidwalker
a46ec5d930 Cargo improvements 2019-03-26 21:34:09 +01:00
tovl
30de4df749 Replace SequenceActivities with ChildActivity in several activities. 2019-03-25 20:22:35 +00:00
Paul Chote
90ddf24cf3 Display the correct version on generated wiki pages. 2019-03-24 23:24:04 +01:00
Paul Chote
d7ff894346 Actually push the generated weapon docs to the wiki. 2019-03-24 23:24:04 +01:00
Vasya N
63817ae807 TS: fix disruptor healing 2019-03-24 17:23:49 +00:00
Oliver Brakmann
44ca01d36c Remove pretick argument from Activity.Queue()
Pre-ticking a next activity would break the assumption that activities
in a queue would be processed in sequence.
2019-03-24 15:53:13 +00:00
reaperrr
9a15df9dde Update bleed update rule folder and update path
The release is out now, so it's time for updating this.
2019-03-23 21:34:22 +01:00
tovl
5782dde1c7 Remove ISync from AttackMove. 2019-03-23 21:02:04 +01:00
reaperrr
151fea9c00 Remove duplicate Aircraft from TS jumpjet husk 2019-03-23 12:35:12 +01:00
Paul Chote
817db8dbe0 Fix build artifacts leaking between platforms.
This moves the `dependencies` target from `core`
to `default`, so that we aren't forced to run
`linux-dependencies` for non-linux platforms.
2019-03-22 21:36:20 +01:00
Paul Chote
2afd8a3a74 Package mono 5.10 in the AppImages. 2019-03-22 21:36:20 +01:00
Paul Chote
2ba2510018 Check for unpackaged dependencies in make check. 2019-03-22 21:36:20 +01:00
Mustafa Alperen Seki
6c9d961bb5 Polishing Hovers 2019-03-22 21:12:36 +01:00
tovl
16f1750252 Remove ResupplyAircraft hack 2019-03-22 19:02:05 +01:00
tovl
e2e4caf0ba Make Aircraft.OnBecomingIdle accesible. 2019-03-22 19:02:05 +01:00
tovl
64cec4a0ad Revise AttackMoveActivity. 2019-03-22 19:02:05 +01:00
Paul Chote
01f6f98097 Require .NET Framework >= 4.7.2 on Windows. 2019-03-21 20:04:14 +01:00
Mustafa Alperen Seki
ac7d2e00e3 Use .Trait<ConditionManager>(); on GrantConditionOnDamageState 2019-03-21 14:36:33 +01:00
Mustafa Alperen Seki
d54e4395e5 Add GrantConditionOnHealth 2019-03-21 14:36:33 +01:00
Maarten
040f071833 Also trigger mission fail when subpen is sold 2019-03-21 14:25:48 +01:00
abcdefg30
a3325277d9 Prevent support powers from creating two camera actors 2019-03-14 19:29:39 +00:00
Paul Chote
aa9724cc40 Remove SharpFont dependency. 2019-03-14 16:39:26 +01:00
Paul Chote
ebeaf95e4c Reimplement FreeTypeFont against FreeType directly. 2019-03-14 16:39:26 +01:00
Paul Chote
1d4576229a Move FreeType handling into the Platform dll. 2019-03-14 16:39:26 +01:00
abcdefg30
e2a51676f7 Add an update rule for the PlaceSimpleBeacon removal 2019-03-14 01:55:34 +01:00
abcdefg30
2ab127537c Remove PlaceSimpleBeacon and AnimatedBeacon 2019-03-14 01:55:34 +01:00
abcdefg30
8578ce1346 Merge PlaceSimpleBeacon and AnimatedBeacon into PlaceBeacon and Beacon 2019-03-14 01:55:34 +01:00
Mustafa Alperen Seki
8edbf665c5 Make D2k AI don't update ConYard for 2,5 Minutes. 2019-03-14 01:36:44 +01:00
Mustafa Alperen Seki
2aebb05cd0 Implement Building/UnitDelays 2019-03-14 01:36:44 +01:00
Paul Chote
2a9721a9f8 Remove System.Drawing dependency. 2019-03-14 01:01:49 +01:00
Paul Chote
5cc81f7bf7 Implement a simple managed png writer. 2019-03-14 01:01:49 +01:00
tovl
9f419fca34 make cargo unload deploy action queueable
fix line spacing

remove unnecessary null check
2019-03-14 00:54:54 +01:00
tovl
da2e56e478 Make deploying mines queueable. 2019-03-14 00:23:47 +01:00
Mustafa Alperen Seki
556774804f Make Capture related traits conditional. 2019-03-13 23:43:16 +01:00
Mustafa Alperen Seki
35ad33e8be Fix filenames of capture related traits. 2019-03-13 23:43:16 +01:00
abcdefg30
00b8576edf Remove the unused INotifySold.Selling implementation 2019-03-13 23:14:35 +01:00
abcdefg30
f021439dee Use explicit implementation in ScriptTriggers.cs 2019-03-13 23:14:35 +01:00
abcdefg30
59a438b80e Add the ScriptTriggers trait to the world actors 2019-03-13 23:14:35 +01:00
abcdefg30
2db2148310 Add OnAnyProduction and OnSold lua triggers 2019-03-13 23:14:35 +01:00
tovl
c096fbde96 make portable chrono queueable
give PortableChrono fallback movement

style fix

add chrono target line

require and cache IMove
2019-03-12 13:38:48 +01:00
Paul Chote
71b61ad8ee Remove bogus and unnecessary Color[] FieldLoader override. 2019-03-12 12:44:29 +01:00
Paul Chote
d70055c38d Add int channel version of Color.FromAhsl. 2019-03-12 12:41:06 +01:00
Paul Chote
6927767013 Add authentication fingerprint to replay metadata. 2019-03-12 12:37:51 +01:00
abcdefg30
ed255fa919 Move update rules into the correct subfolder 2019-03-11 21:56:13 +00:00
Curtis Shmyr
c1506416c9 Change MECH repair voice from Move to Action 2019-03-11 22:38:47 +01:00
abcdefg30
0ab7e0a855 Add support for multiple (un)deploy sounds on GrantConditionOnDeploy 2019-03-11 21:31:39 +00:00
Paul Chote
ab6ae7bc8d Support 24 bit png loading. 2019-03-11 20:14:09 +01:00
reaperrr
ea2e452075 Add SpawnActorEffect
And use it to drop DelayedAction from ReinforcementsGlobal.
2019-03-11 12:54:58 +01:00
reaperrr
ab4268025a Fix TS Stealth Generator ignoring EMP
On bleed it continues to stealth the surrounding actors when EMP'd.
2019-03-10 23:16:25 +00:00
tovl
6f213dddec Make Attack use ChildActivities 2019-03-10 20:51:47 +01:00
reaperrr
5ec47b47af Rename fields on Repairable traits
To bring them in line with RearmActors,
Repairable.RepairBuildings and
RepairableNear.Buildings have been renamed
to RepairActors.
Additionally, their RA-specific internal
defaults were removed and the FieldLoader
now requires them to be set explicitly.
2019-03-10 19:19:49 +01:00
Mazar Farran
6dd84b2882 Add mazarf to AUTHORS 2019-03-10 18:20:01 +01:00
Oliver Brakmann
0bd00d3b7c Add a ReturnToGroundLayerOnIdle flag to CustomMovementLayers
Co-authored-by: Mazar Farran <farranmazar@gmail.com>
Co-authored-by: Paul Chote <paul@chote.net>
2019-03-10 18:20:01 +01:00
Paul Chote
8fc483b30b Work around a crash for invalid FrozenActor targets. 2019-03-10 17:29:17 +01:00
Paul Chote
6472840690 Notify players when a vehicle have been lost to a Thief. 2019-03-10 17:11:38 +01:00
Paul Chote
71dd84b9d5 Fix invalid target crash in SupportPowerManager.Activate. 2019-03-10 13:26:49 +01:00
Mustafa Alperen Seki
1a728ee153 Add ExperienceTrickler trait. 2019-03-10 13:13:16 +01:00
Mustafa Alperen Seki
b8a85091d4 Make WithRangeCircle conditional 2019-03-10 02:39:27 +01:00
Paul Chote
2ee6243e67 Remove shadow remapping from RA cursors. 2019-03-09 21:57:37 +00:00
Paul Chote
06e63e7dbc Remove bogus green-shadow remap from TD cursors. 2019-03-09 21:57:37 +00:00
tovl
705795abde Activity.Cancel returns void instead of bool. 2019-03-09 21:47:43 +00:00
tovl
a17cd0fa06 Replaced Canceled state with Canceling state. 2019-03-09 21:47:43 +00:00
tovl
8191a6566b Add missing self and optional pretick parameters to Queue, QueueChild and PrintActivity methods.
This means sequenceActivities needs to accept self as well.
2019-03-09 21:47:43 +00:00
tovl
69004f2b94 Prevent premature nulling of childactivities. 2019-03-09 21:47:43 +00:00
tovl
35dba74ded remove unused CompositeActivity 2019-03-09 21:47:43 +00:00
tovl
6d51d3988c fix aircraft ResupplyActivity 2019-03-09 21:47:43 +00:00
Mustafa Alperen Seki
0b0b82bd43 Implement Harvester>BaleUnloadAmount 2019-03-09 12:19:02 +00:00
reaperrr
a7702a8ecd Make HeliReturnToBase use RTB.ChooseResupplier
Small consistency fix and prep for merging HRTB into RTB.
2019-03-09 12:12:51 +00:00
reaperrr
2ac9d92ce7 Remove some legacy activity cruft from Aircraft
You only need to look at the RTB activities to tell that
Aircraft doing its own stuff here was somewhat redundant
and just made things worse regarding debugging and
code consistency.
2019-03-09 12:12:51 +00:00
reaperrr
d7f8f2ba7b Fix D2k Death Hand launch transition
Missile would otherwise visually disappear for a tick.
2019-03-09 12:02:44 +00:00
reaperrr
fa3bf5cefe Add delay support to NukeLaunch
And use that to remove the remaining DelayedAction from NukePower.
2019-03-09 12:02:44 +00:00
abcdefg30
d0c2dbcbb0 Let civilians use the normal stand animation when panicking 2019-03-09 11:57:45 +01:00
abcdefg30
0524a59b6b Fix map preview generation for isometric terrain 2019-03-08 21:21:10 +01:00
abcdefg30
19b2cb0afb Log the stack trace when map saving fails 2019-03-08 21:21:10 +01:00
Pavel Penev
ffac21c3d3 Explicitly specified NuGet package source in the Windows dependencies script
Otherwise NuGet breaks there are alternative (private) NuGet feeds set up on the local machine and one of them isn't responding currently.
2019-03-07 23:58:23 +01:00
Pavel Penev
6d63c99104 Changed NuGet download link for the Windows dependencies script
The previous link downloaded a very old version of nuget.exe for some reason.
2019-03-07 23:58:23 +01:00
reaperrr
2c311a84c9 Add OpenRA.StyleCheck.exe.config 2019-03-07 19:39:57 +01:00
reaperrr
33060a661f Revert #16196 2019-03-07 19:39:57 +01:00
tovl
2e5e7c22f4 Make Mobile a PausableConditionalTrait 2019-03-07 02:50:43 +01:00
Paul Chote
f63d0272a7 Fix map title not updating after remote query completes. 2019-03-06 18:23:33 +01:00
Paul Chote
fc9169a633 Reset spawn previews for empty servers. 2019-03-06 18:23:33 +01:00
Paul Chote
dad21fe879 Remove unused references to System.Data and System.XML. 2019-03-04 18:26:42 +00:00
Paul Chote
4886cca5d3 Remove System.Drawing references from mod code. 2019-03-04 18:26:42 +00:00
Paul Chote
3e404f6ac2 Remove HSLColor. 2019-03-04 18:26:42 +00:00
Paul Chote
ab4a7e3558 Replace System.Drawing primitives with our own. 2019-03-04 18:26:42 +00:00
Paul Chote
ef9f74411b Remove unused variable in ButtonTooltipWithDescHighlightLogic. 2019-03-04 18:26:42 +00:00
Paul Chote
094c8b6432 Use Color.ToString() in perf logs. 2019-03-04 18:26:42 +00:00
Paul Chote
015316e909 Remove uses of state-mutating Rectangle.Offset and Intersect. 2019-03-04 18:26:42 +00:00
Paul Chote
0b641c20df Remove unnecessary uses of System.Drawing primitives. 2019-03-04 18:26:42 +00:00
Paul Chote
00496e2ec2 Remove Order.TargetLocation. 2019-03-04 18:08:42 +00:00
Paul Chote
c7dc237143 Remove Order.TargetLocation from Mobile. 2019-03-04 18:08:42 +00:00
Paul Chote
4c6f4f97d5 Remove Order.TargetLocation from Carryall. 2019-03-04 18:08:42 +00:00
Paul Chote
a5c89c2edc Remove Order.TargetLocation from AttackMove. 2019-03-04 18:08:42 +00:00
Paul Chote
c7d9d9613e Remove Order.TargetLocation from Harvester. 2019-03-04 18:08:42 +00:00
Paul Chote
cd92e94d74 Remove Order.TargetLocation from Aircraft. 2019-03-04 18:08:42 +00:00
Paul Chote
f70a452c56 Remove Order.TargetLocation from Minelayer. 2019-03-04 18:08:42 +00:00
Paul Chote
9c4231165b Remove Order.TargetLocation from beacons. 2019-03-04 18:08:42 +00:00
Paul Chote
d91d96a2e3 Remove Order.TargetLocation from building code. 2019-03-04 18:08:42 +00:00
Paul Chote
6dcd23e874 Remove Order.TargetLocation from support powers. 2019-03-04 18:08:42 +00:00
Unrud
7d72aae5ba Add /app/lib to Lua search locations (for Flatpak) 2019-03-02 20:11:06 +00:00
Paul Chote
666d2e7bac Work around harvester unloading activity queue issues. 2019-03-02 18:22:44 +01:00
Paul Chote
8b618ef7bc Fix maximum range estimation for stationary turrets. 2019-03-02 18:16:12 +01:00
Orb
cbbafd096d MGG Speed Reduction 2019-03-02 17:50:41 +01:00
Orb
e7134282c2 Balance Changes for Next Release by Orb 2019-03-02 17:50:41 +01:00
abcdefg30
7f3c527f4e Fix a crash in soviet05 2019-03-01 22:26:54 +00:00
reaperrr
cae6da77d4 Increase dog attack damage
To make sure it kills veteran Tanya as well as Drop Zone shok troopers.
2019-03-01 14:52:31 +01:00
reaperrr
638c727f5b Fix Drop Zone maps
Fixes Lint errors, Bomb truck gfx & lobby options.
2019-03-01 14:52:31 +01:00
TheChosenEvilOne
30103da2db Conditional TakeCover 2019-02-24 14:43:47 +01:00
Paul Chote
94f7f6fd2e Remove obsolete code. 2019-02-24 14:02:19 +01:00
Paul Chote
5a1124426d Rewrite screenshot saving. 2019-02-24 14:02:19 +01:00
Paul Chote
5f212a99fe Convert Map.SavePreview to new Png code. 2019-02-24 14:02:19 +01:00
Paul Chote
368b0314d5 Convert ConvertSpriteToPngCommand to new Png code. 2019-02-24 14:02:19 +01:00
Paul Chote
82fade25a6 Replace Sheet.AsBitmap with Sheet.AsPng. 2019-02-24 14:02:19 +01:00
Paul Chote
2c96eb9d24 Simplify PngSheetImportMetadataCommand. 2019-02-24 14:02:19 +01:00
Paul Chote
b41d4f5cee Allow Pngs to be created from pixel data. 2019-02-24 14:02:19 +01:00
Paul Chote
4f73b51240 Add Png.Save method. 2019-02-24 14:02:19 +01:00
netnazgul
88d16904ff Fix Pitfight: split stacked ore mine actors to different cells 2019-02-24 13:11:20 +01:00
Paul Chote
ea05e8aae5 Remove flawed RateLimit implementation. 2019-02-23 18:05:57 +00:00
tovl
dc9c758f12 unreserve when not queued 2019-02-22 21:48:34 +00:00
tovl
2975738477 make ReturnToBase order queueable 2019-02-22 21:48:34 +00:00
Punsho
621a42b7d7 Update fakes.yaml 2019-02-22 21:30:48 +00:00
SoScared
b480fecdbd Alter default bot and faction dropdownhights for the RA mod. 2019-02-22 21:26:37 +00:00
Andre Mohren
42446ac9ba Implemented trait defined Rollovers. 2019-02-22 21:15:33 +00:00
Mustafa Alperen Seki
7049f68fbd Add a boolean to show or not Refund X$ on the tooltip while selling. 2019-02-22 21:07:29 +00:00
Mustafa Alperen Seki
bc0296ad13 Add descriptions to the fields in Sellable, which lack them. 2019-02-22 21:07:29 +00:00
Mustafa Alperen Seki
3672a281d2 Make JamsMissiles conditional 2019-02-22 21:01:51 +00:00
portablestew
d592f37617 App config for StyleCheck 2019-02-22 20:15:20 +00:00
reaperrr
117dde32ba Removed unused sanity checks from pathfinding
These haven't been active and used in years.
2019-02-22 19:59:41 +00:00
reaperrr
5166b8cd5d Add missing closing bracket in Move comment 2019-02-22 19:59:41 +00:00
Paul Chote
f6ac32412d Avoid resetting FrozenActor.Hidden when refreshing GPS. 2019-02-22 20:53:39 +01:00
Paul Chote
bf9d06cb12 Reuse GPSDotEffect for the lifetime of the actor. 2019-02-22 20:40:23 +01:00
Ivaylo Draganov
3b6249323d Reorder stance hotkeys in settings to match command bar 2019-02-22 14:45:13 +01:00
abcdefg30
7c2f8ef918 Update the description of EnemyWatcher and AnnounceOnSeen 2019-02-22 14:32:16 +01:00
abcdefg30
db7414e822 Include a note about the necessity of AnnounceOnSeen for OnDiscovered 2019-02-22 14:32:16 +01:00
abcdefg30
599d174f33 Fix a typo in the Lua API description of OnDiscovered 2019-02-22 14:32:16 +01:00
Paul Chote
72c90d84a8 Fix editor crash when modifying newly placed actor ID. 2019-02-21 16:22:32 +01:00
Oliver Brakmann
6841da286c Fix pre-placed frozen actors not being targetable 2019-02-20 16:31:13 +00:00
teinarss
be741cea5e Prevent multiple enumeration of validCells in SpawnMPUnits 2019-02-18 19:35:33 +01:00
Maarten
f91d3f2603 Clarify mission objectives #16169 2019-02-15 15:30:43 +01:00
portablestew
a49287cc97 Possible fix for #14102: Consider airfield available if already reserved for the same actor 2019-02-15 13:59:53 +01:00
Paul Chote
f9cf45e634 Cache passenger bounty traits.
This avoids querying from potentially dead actors.
2019-02-09 19:46:46 +01:00
Paul Chote
49621bebd0 Abort activities when we don't know how close to move to a target. 2019-02-09 19:20:10 +01:00
portablestew
2d4bad66ae Fix for #7083: Fly stops turning when target is inside the turn radius 2019-02-08 19:38:01 +01:00
Paul Chote
95dc9cb1d2 Defer UpdateFrozenActor until the end of the tick.
Updating the frozen actor calls Actor.GetTargetablePositions,
and so we must guarantee that Created has been called for
the ITargetablePositions traits first.
2019-02-07 19:50:50 +00:00
Oliver Brakmann
0ee9219df3 Fix unresponsive aircraft when executing orders queued during resupply 2019-02-06 18:01:51 +00:00
reaperrr
297be6d6cc Normalize RA tracks 2019-02-03 20:46:39 +01:00
reaperrr
6ff41fe894 Normalize TD track volumes and fix order
Some tracks from the original were falsely listed under CovOps.
2019-02-03 20:46:39 +01:00
abcdefg30
25a4d156ce Let the extraction helicopter of Monster Tank Madness leave 2019-02-03 19:32:51 +00:00
Paul Chote
2b6ebcd09c Fix inconsistent FrozenActor state on capture/destruction. 2019-02-03 20:21:51 +01:00
Paul Chote
08e3e429db Remove obsolete LegacyEnter and ResolveFrozenActorOrder. 2019-02-03 20:21:51 +01:00
Paul Chote
42068f380e Remove ResolveFrozenActorOrder from MadTank. 2019-02-03 20:21:51 +01:00
Paul Chote
6ed2654038 Remove ResolveFrozenActorOrder from EntersTunnels. 2019-02-03 20:21:51 +01:00
Paul Chote
240c2243f2 Remove ResolveFrozenActorOrder from Carryall. 2019-02-03 20:21:51 +01:00
Paul Chote
71dd3202c3 Port EnterTransport to the new Enter activity.
This dramatically simplifies the reservation logic,
which seemed to be needlessly complicated. This may
regress unexpected edge-cases.
2019-02-03 20:21:51 +01:00
Paul Chote
d6b7d5c4c7 Port DonateExperience to the new Enter activity. 2019-02-03 20:21:51 +01:00
Paul Chote
cc288f5afc Port DonateCash to the new Enter activity. 2019-02-03 20:21:51 +01:00
Paul Chote
4551625bb4 Port RepairBridge to the new Enter activity. 2019-02-03 20:21:51 +01:00
Paul Chote
49e3c46d00 Port RepairBuilding to the new Enter activity. 2019-02-03 20:21:51 +01:00
Paul Chote
167371d540 Port Demolish to the new Enter activity. 2019-02-03 20:21:51 +01:00
Paul Chote
a17608a24e Port Infiltrate to the new Enter activity. 2019-02-03 20:21:51 +01:00
Paul Chote
e9c3216048 Port CaptureActor to the new Enter activity. 2019-02-03 20:21:51 +01:00
Paul Chote
c1e8bbfc58 Rewrite Enter activity, accounting for frozen and hidden actors. 2019-02-03 20:21:51 +01:00
Paul Chote
d2274f4285 Rewrite Mobile.MoveIntoTarget to support moving targets. 2019-02-03 20:21:51 +01:00
Paul Chote
1f7b558b29 Rename Enter to LegacyEnter. 2019-02-03 20:21:51 +01:00
Paul Chote
83212b100e Pause actor movement between cells when Mobile is disabled. 2019-02-03 20:21:51 +01:00
Paul Chote
c8f05e90dc Fix turn disabling mobile.IsMoving when setIsMoving is false. 2019-02-03 20:21:51 +01:00
Paul Chote
5995915281 Fix Positions returned by FrozenActor targets.
Also removes redundant Targetables check from actors.
2019-02-03 20:21:51 +01:00
reaperrr
31f4b0a5c4 Fix D2k bots wasting cash on building repairs
D2k bots not repairing buildings when damaged due to placement
without concrete was intentional, and this was bleed's default behavior
before BuildingRepairBotModule got introduced, too.
2019-02-03 18:24:15 +01:00
Paul Chote
f8991470da Disable OpportunityFire on Disruptors.
The original game defined NoMovingFire=true.
2019-02-03 18:07:02 +01:00
Paul Chote
c26e77552e Allow turreted actors to acquire targets while doing other activities. 2019-02-03 18:07:02 +01:00
Paul Chote
012b17b974 Implement a secondary target-of-opportunity for AttackFollow. 2019-02-03 18:07:02 +01:00
Smittytron
1830b3ee80 Add e6 and thf to Monster Tank Madness 2019-02-03 17:05:54 +01:00
Paul Chote
2194f17dc2 Fix double-revoke crash in Demolishable. 2019-02-03 16:38:04 +01:00
Paul Chote
0a57fbda3c Prefer target to lastVisible target if it is visible. 2019-02-03 16:32:25 +01:00
matjaeck
b466b5d660 Reset unit stance on owner change. 2019-02-03 16:20:24 +01:00
Paul Chote
fd013ad9d0 Remove unnecessary trait queries from HarvesterBotModule 2019-02-03 15:54:07 +01:00
reaperrr
4da2d32bc5 Fix that bots don't re-use capturers
They were never removed from activeCapturers when their target becomes invalid,
preventing the bot from reusing them.
2019-02-03 12:12:34 +00:00
reaperrr
32a3caf423 Fix CaptureManagerBotModule crashing on multiple Capturable
By removing the now-redundant CaptureTarget class.
2019-02-03 12:12:34 +00:00
Oliver Brakmann
3093f67427 Consider dead aircraft to no longer be in range 2019-02-03 11:31:44 +00:00
tovl
ee19cb61b4 add check for NextActivity to FlyCircle
prevent infinite loop

fix for ReturnToBase

cleanup
2019-02-03 11:24:19 +00:00
Paul Chote
b71c080285 Add VolumeModifier support to music. 2019-02-02 22:32:29 +01:00
Paul Chote
810aa744bf Remove AttackSuicides trait. 2019-02-01 23:18:18 +00:00
Paul Chote
24a491a7d7 Implement Hunter-Seeker kill behaviour. 2019-02-01 23:18:18 +00:00
Paul Chote
d750db26b7 Replace AttackSuicides with AttackFrontal and conditions in RA. 2019-02-01 23:18:18 +00:00
Paul Chote
0464a0db58 Remove unused negativeDamage variable from AttackBase. 2019-02-01 23:18:18 +00:00
Smittytron
f1f040a361 Reduce thief speed and engineer CaptureDelay 2019-02-01 22:42:36 +01:00
Paul Chote
cbb9b75144 Enable "campaign" bot for all scripted players in D2k missions. 2019-02-01 20:59:19 +01:00
Paul Chote
61acb905cd Enable "campaign" bot for all scripted players in TD missions. 2019-02-01 20:59:19 +01:00
Paul Chote
73b42e452d Enable "campaign" bot for all scripted players in RA missions. 2019-02-01 20:59:19 +01:00
Paul Chote
9c9cad1a15 Amend Force Attack command bar tooltip. 2019-01-28 00:14:27 +01:00
Paul Chote
2d9822638f Enable ForceFireIgnoresActors on artillery-style units. 2019-01-28 00:14:27 +01:00
Paul Chote
ab6dd3dcf2 Add ForceFireIgnoresActors to AttackBase. 2019-01-28 00:14:27 +01:00
Paul Chote
a2e35144a7 Fix gate animations. 2019-01-27 21:37:55 +01:00
Paul Chote
d6d1f3a06d Fix FrozenUnderFog / FrozenActor visibility consistency.
This fixes cases where both objects return visible / not
when queried at the wrong time during a tick.
2019-01-27 15:21:13 +01:00
Paul Chote
dc40a973e3 Allow attack orders to preempt move completion for turreted units. 2019-01-27 15:21:13 +01:00
Paul Chote
518a54a494 Reduce cash tick volume in the default mods. 2019-01-27 15:05:27 +01:00
Paul Chote
cbe3733deb Add VolumeModifier support to sound definitions. 2019-01-27 15:05:27 +01:00
Paul Chote
70f4c51a17 Add AttackMove workaround for Aircraft. 2019-01-27 00:19:50 +00:00
Paul Chote
60fcf5951c Fix target invalidation and reacquisition in fly activities. 2019-01-26 22:53:46 +00:00
Paul Chote
8efa0da54d Fix target invalidation and reacquisition in (Fly|Heli)Attack. 2019-01-26 22:53:46 +00:00
Paul Chote
0bfc487999 Fix target invalidation and reacquisition in AttackFollow. 2019-01-26 22:53:46 +00:00
Paul Chote
5ef7809002 Fix target invalidation and reacquisition in LeapAttack. 2019-01-26 22:53:46 +00:00
Paul Chote
7c52a6f498 Fix target invalidation and reacquisition in Attack. 2019-01-26 22:53:46 +00:00
Paul Chote
616b6c8499 Fix target invalidation and reacquisition in Follow. 2019-01-26 22:53:46 +00:00
Paul Chote
975821023d Fix target invalidation and reacquisition in MoveAdjacentTo. 2019-01-26 22:53:46 +00:00
Paul Chote
d03c5b1c48 Split Target.Recalculate into methods with and without invalidation.
TargetExtensions is moved into its own file.
2019-01-26 22:53:46 +00:00
Paul Chote
2080c72ab9 Define plumbing to pass initial target positions to inner move activities. 2019-01-26 22:53:46 +00:00
Paul Chote
b2d960ec19 Pass target line color to inner move activities. 2019-01-26 22:53:46 +00:00
Paul Chote
62102b9f77 Add support for Terrain targets with multiple positions. 2019-01-26 22:53:46 +00:00
Paul Chote
fbb1947624 Make Target fields readonly. 2019-01-26 22:53:46 +00:00
Paul Chote
c627a59b54 Fix self parameter name in DrawLineToTarget. 2019-01-26 22:53:46 +00:00
Paul Chote
7d85c1e81f Remove FrameEndTask from DrawLineToTarget.
This is no longer needed and causes ordering
issues when the unit becomes idle in the same
tick that SetTargetLine is called.
2019-01-26 22:53:46 +00:00
abcdefg30
2c6c2c00b4 Change the year number in README.md from 2018 to 2019 2019-01-26 23:15:21 +01:00
abcdefg30
4a9b00d3e7 Update the year numbers in the packaging section to 2019 2019-01-26 23:15:21 +01:00
abcdefg30
6151443618 Update CreateManPage.cs to print the new header 2019-01-26 23:15:21 +01:00
abcdefg30
12f278cdac Remove trailing white spaces from ant-attack.lua 2019-01-26 23:15:21 +01:00
abcdefg30
03e0fb6986 Add a header to ant-attack.lua 2019-01-26 23:15:21 +01:00
abcdefg30
8b9603168a Change the year number in all lua headers from 2018 to 2019 2019-01-26 23:15:21 +01:00
abcdefg30
cadbd0d9ab Change the year number in all cs headers from 2018 to 2019 2019-01-26 23:15:21 +01:00
Paul Chote
628547a8e5 Fix source package creation. 2019-01-26 23:07:20 +01:00
Paul Chote
9025d11c54 Map Ctrl to Cmd for editor copy hotkey. 2019-01-26 21:46:46 +00:00
rob-v
de851fba2c Add shortcut for Copy in Map editor 2019-01-26 21:46:46 +00:00
Paul Chote
a545b2e5fa Deselect actors when their owner changes. 2019-01-26 21:40:31 +00:00
Paul Chote
0df159e73b Cache world INotifySelection traits in Selection. 2019-01-26 21:40:31 +00:00
Paul Chote
64c853a4e0 Only play queued notification if queue is empty.
This matches the behaviour of the RA2 sidebar.
2019-01-26 21:36:45 +00:00
Paul Chote
8d276ff9de Replace broken (Disabled)TabClick and with (Disabled)ClickSound. 2019-01-26 21:36:45 +00:00
Paul Chote
635038aa0b Disable bot logic during replays. 2019-01-26 21:33:47 +00:00
abcdefg30
531560c41e Allies03b: Fix the insertion helicopter revealing shroud 2019-01-26 21:29:04 +00:00
abcdefg30
e637b45cab Allies03: Remove hacke6 2019-01-26 21:29:04 +00:00
abcdefg30
c9c4d15b1e Allies03b: Fix heavy tank reinforcements triggering twice 2019-01-26 21:29:04 +00:00
abcdefg30
ff0521e5c8 Allies01: Remove redundance (caused by inheritance) 2019-01-26 21:29:04 +00:00
abcdefg30
c0b1225edc Allies01: Add a new line at the end of the briefing 2019-01-26 21:29:04 +00:00
abcdefg30
41dc9c7ca3 Allies01: Fix civilian infantry being visible below fog 2019-01-26 21:29:04 +00:00
abcdefg30
43a6558ac6 Allies01: Fix the extraction helicopter revealing shroud 2019-01-26 21:29:04 +00:00
abcdefg30
76b05c0c0d Allies01: Fix the extraction helicopter landing before being removed 2019-01-26 21:29:04 +00:00
abcdefg30
3e93242929 Fix OnAllRemovedFromWorld only triggering once 2019-01-22 23:09:21 +00:00
Paul Chote
d379555784 Remove Game.Debug messages from ValidateOrder. 2019-01-22 22:59:37 +00:00
rob-v
a2c6b19205 No player name in replay for chat commands 2019-01-22 22:57:11 +00:00
abcdefg30
428155c093 Fix LeapAttack setting attack.IsAiming too early 2019-01-22 22:52:43 +00:00
abcdefg30
3039b1d710 Reset the client state when being moved to spectator 2019-01-22 22:47:39 +00:00
abcdefg30
e08b75c2ad Only consider system maps in the mission browser 2019-01-19 18:47:29 +00:00
abcdefg30
717b483ce7 Use map folder names instead of paths in the mission browser 2019-01-19 18:47:29 +00:00
rob-v
9ed2ffea91 Fix Warhead.IsValidAgainst (FrozenActor.Owner null) 2019-01-19 12:03:15 +00:00
abcdefg30
7eff82c99b Move Actor103 in Allies02 one cell to the right
He was standing on impassable terrain and therefore couldn't move.
2019-01-19 11:56:22 +00:00
abcdefg30
30e3b45637 Let the remaing enemy troops in Allies02 attack the player
once the base is destroyed.
Does not include unit guarding the convoy path.
2019-01-19 11:56:22 +00:00
Smittytron
da40f45ece Add IsDead check to fix crash in Sarin Gas 1 2019-01-19 11:45:31 +00:00
abcdefg30
9c7ba51e29 Fix a crash in Infiltration 2019-01-19 11:27:15 +00:00
Smittytron
98e54edf04 Change tree husks from FrozenUnderFog to HiddenUnderShroud 2019-01-19 11:16:12 +00:00
Paul Chote
b1e87e4f60 Remove System.Bitmap from ITexture. 2019-01-08 21:20:06 +00:00
Paul Chote
84e965835b Remove System.Bitmap from badge and mod icons. 2019-01-08 21:20:06 +00:00
Paul Chote
f65a777366 Remove System.Bitmap from map preview loading. 2019-01-08 21:20:06 +00:00
Paul Chote
4f10d4a302 Remove System.Bitmap from UI artwork loading. 2019-01-08 21:20:06 +00:00
Paul Chote
52be0192f6 Add RGBA support to png parser. 2019-01-08 21:20:06 +00:00
Paul Chote
49b04221b2 Add palette checks for png sprites. 2019-01-08 21:20:06 +00:00
Paul Chote
d2ee9bcad9 Move Png loader back to OpenRA.Game. 2019-01-08 21:20:06 +00:00
Smittytron
05b866a87a Change LST turn speed to default max 2019-01-07 12:37:00 +01:00
Oliver Brakmann
c2cf8ba599 Add an interface to prevent actors from being spawned by SpawnMapActors 2019-01-07 10:13:50 +00:00
Mustafa Alperen Seki
df1d928242 Hide husks under fog regardless of their owner. 2019-01-06 22:12:04 +01:00
Paul Chote
6de92de8d9 Revert macOS dark mode (again).
The updated GL surface appears to have regressed vsync behaviour.
2019-01-06 08:33:11 +00:00
reaperrr
b05d246c48 Add BotDebug message for external unit build requests
For easier bot debugging of things like MCV- and harvester replacement.
2019-01-06 08:39:45 +01:00
reaperrr
3a1656c3dd Remove unused BuildUnit overload from UnitBuilderBotModule
Unused and didn't check things like Buildable, so better just remove it.
2019-01-06 08:39:45 +01:00
reaperrr
b2649749d9 Enable harvester replacement in official mods 2019-01-06 08:39:45 +01:00
reaperrr
137d3be346 Add plumbing for bots auto-replacing harvesters
If their number drops below refinery count.
2019-01-06 08:39:45 +01:00
reaperrr
e36ef57e35 Increase default scan interval for idle bot harvesters
Every 2 seconds (at default speed) should be enough.
2019-01-06 08:39:45 +01:00
reaperrr
481e5e03d8 Make bots deploy MCV on first tick
And use a boolean instead of counting ticks.
2019-01-06 08:39:45 +01:00
Paul Chote
4d3db0d454 Fix invalid target crash if Leap target dies. 2019-01-05 23:59:25 +01:00
Paul Chote
01f5c67036 Fix spectator crash if replay does not define FinalGameTick. 2019-01-05 23:56:21 +01:00
Paul Chote
f929087d15 Fix artwork when leaping. 2019-01-05 19:54:38 +01:00
Paul Chote
ae38133c9f Use the CenterPosition as the starting position. 2019-01-05 19:54:38 +01:00
Paul Chote
0c7158efcd Calculate Leap state on first run instead of construct. 2019-01-05 19:54:38 +01:00
abcdefg30
6b9a2a3c29 Reduce the range of DogJaw from 3c0 to 2c0 2019-01-05 18:28:57 +00:00
Paul Chote
f5d788f4fc Prevent unit requests from stacking during production. 2019-01-04 21:14:20 +00:00
Ivaylo Draganov
caead311cb Add hotkey for Army value statistics panel 2019-01-04 21:12:06 +00:00
Ivaylo Draganov
f26905f5d0 Rearrange default observer hotkeys
* Move replay speed hotkeys to `F9 - F12`
* Set `F5` as default for `StatisticsGraph`
2019-01-04 21:12:06 +00:00
rob-v
a77d2f15b1 Map Editor - Copy filter 2019-01-03 20:32:10 +01:00
Paul Chote
5a8f7f1a5f Increase squad calculation intervals.
These were unnecessarily short, increasing the
AI performance overhead, and making it difficult
for units to escape concave terrain features.
2019-01-03 02:04:08 +01:00
Paul Chote
3d9e877eb2 Disable rush attacks against enemy aircraft. 2019-01-03 02:04:08 +01:00
Paul Chote
8a6a68feef Unify Squad enemy unit filtering. 2019-01-03 02:04:08 +01:00
Paul Chote
6fc291a634 Disable target recalculation for bots.
This fixes bot-controlled units freezing when they
lock on to units that aren't visible.
2019-01-03 02:04:08 +01:00
Mustafa Alperen Seki
4578ea09ba Add DamageTypes to Capture Sabotage 2019-01-02 20:04:06 +01:00
Mustafa Alperen Seki
baac3f3ee9 Remove C17 from map editor. 2019-01-02 19:57:24 +01:00
Mustafa Alperen Seki
816cb2cdc2 Remove duplicate D2k starport actors from map editor. 2019-01-02 19:57:24 +01:00
Mustafa Alperen Seki
0c540cd41e Remove actors with AttackBomber trait from map editor. 2019-01-02 19:57:24 +01:00
Mustafa Alperen Seki
6b4ba96e34 Remove aircraft husks from map editor actor list. 2019-01-02 19:57:24 +01:00
Mustafa Alperen Seki
b0188cc476 Remove Buildable traits from A10 and C17.
Leftover from upgrade rule that move description from Tooltip to
Buildable.
2019-01-02 19:57:24 +01:00
Mustafa Alperen Seki
eaa9b49793 Add Stance Support to GrantExternalConditionPower. 2019-01-01 23:05:56 +01:00
Paul Chote
d7c54d74ad Evaluate smooth scrolling per-frame instead of per-tick. 2019-01-01 21:52:13 +01:00
Clément Bœsch
bb5e0eafba Observer: display army value in a new dedicated graph tab 2019-01-01 18:25:44 +00:00
Clément Bœsch
11b064a333 Observer: display army value in stats widget 2019-01-01 18:25:44 +00:00
Clément Bœsch
501c029579 TS: set UpdatesPlayerStatistics.AddToArmyValue where appropriate 2019-01-01 18:25:44 +00:00
Clément Bœsch
7cde528969 D2K: set UpdatesPlayerStatistics.AddToArmyValue where appropriate 2019-01-01 18:25:44 +00:00
Clément Bœsch
a162cdda41 CNC: set UpdatesPlayerStatistics.AddToArmyValue where appropriate 2019-01-01 18:25:44 +00:00
Clément Bœsch
3aedeefced RA: set UpdatesPlayerStatistics.AddToArmyValue where appropriate 2019-01-01 18:25:44 +00:00
Clément Bœsch
3ec2f23109 Add Army value to player statistics
To be accounted as army, the unit needs to have
UpdatesPlayerStatistics.AddToArmyValue to true (false by default)
2019-01-01 18:25:44 +00:00
Paul Chote
4d56ecb3a8 Remove unused MaximumDefenseRadius parameter. 2019-01-01 12:43:10 +01:00
Paul Chote
e23b6f8a9d Fix screenshot pixel opacity. 2019-01-01 11:28:05 +00:00
rob-v
8c94f262b6 Map Editor - Tiles' filters multiple selection 2019-01-01 11:25:31 +00:00
rob-v
f18d874524 CommonSelectorLogic for ActorSelectorLogic and TileSelectionLogic 2019-01-01 11:25:31 +00:00
reaperrr
63f76fc277 Exclude dogs from bot squads in RA
This prevents bots from using their up-to-4 dogs in attacks.
Bots aren't good at using them effectively, so they're better as passive defense
against infantry attacks or spies/engineers sent by human players (and maybe later bots, too).
2018-12-31 16:15:03 +00:00
reaperrr
7ccfe0d2e7 Move up GrantConditionOnBotOwner in AI yamls
Right below the bot traits is better for readability than between modules.
2018-12-31 16:15:03 +00:00
Paul Chote
59f2f5669f Change UpdateRules to account for 20181215 hotfix 2018-12-31 14:22:49 +01:00
reaperrr
d179f6eaae HackyAI dissolve update rule and yaml updates 2018-12-31 10:56:01 +00:00
reaperrr
54c2894b4e Split off last bot modules
And dissolve AI namespace.
There would have been so little left in Common.AI,
that keeping it made no sense anymore.
2018-12-31 10:56:01 +00:00
Paul Chote
b74ff33039 Revert "Fix QuantizeFacing returning values >= numFacings."
This reverts commit f35ee8c303.
2018-12-31 00:01:03 +00:00
Paul Chote
cc004b3546 Fix compatibility with macOS's dark mode. 2018-12-30 23:57:06 +00:00
Smittytron
1facff6ab1 Override Bio Lab construction options in campain-rules.yaml 2018-12-30 21:54:27 +01:00
Smittytron
d751c055b5 Add Counterstrike mission Sarin Gas 1: Crackdown 2018-12-30 21:54:27 +01:00
Dylan Manitta
f5d12bfde1 Add ant mission 1 2018-12-30 21:20:56 +01:00
abcdefg30
0ff4e466ee Refactor Leap attack logic 2018-12-29 19:21:54 +01:00
abcdefg30
9c4cb9091e Change the setter of AttackBase.IsAiming to be public 2018-12-29 19:21:54 +01:00
abcdefg30
8689030f79 Add GrantConditionWhileAiming 2018-12-29 19:21:54 +01:00
dtluna
7608922ff0 Add Nod 10a mission 2018-12-27 21:09:14 +01:00
dtluna
809f57e48d Add Nod 10b mission 2018-12-27 19:22:37 +01:00
Smittytron
a0089d97e6 Fix typo in CrateSpawner 2018-12-27 04:11:54 +01:00
Mustafa Alperen Seki
00faccdecc Fix LandOnCondition causing stopping after changing altitude. 2018-12-26 17:44:45 +01:00
Paul Chote
2a2ad71db9 Add GUI checkbox for Debug.StrictActivityChecking. 2018-12-26 17:33:55 +01:00
Paul Chote
4dea39fffe Reorder and document advanced settings. 2018-12-26 17:33:55 +01:00
Paul Chote
69105180eb Hide developer-only settings behind a hidden setting. 2018-12-26 17:33:55 +01:00
Paul Chote
601990aa27 Add setting to check BotModule sync. 2018-12-26 17:33:55 +01:00
Paul Chote
83e44bee66 Rework and rename Sync.CheckSyncUnchanged 2018-12-26 17:33:55 +01:00
Paul Chote
b41c178cb9 Revert "Units that have turrets while deployed now move their turrets back to their initial positions before undeploying"
This reverts commit d34bea2935.
2018-12-26 16:35:26 +01:00
Unknown
7184f5f97e Fix QueryRemoteMapDetails multi-map status updates 2018-12-25 11:14:48 +13:00
Mustafa Alperen Seki
a2ac95d140 Add facing support to Gravity Bomb. 2018-12-24 20:58:55 +01:00
Jeremy
85a97998aa Added final game tick to replay meta data for completion percentage on replay. 2018-12-24 20:51:03 +01:00
Mustafa Alperen Seki
863091d5cc Make Concrete under buildings indestructible. 2018-12-24 13:48:19 +01:00
reaperrr
be310ab6a6 Streamline resource anim traits
- Replaces WithSiloAnimation with
  WithResourceLevelSpriteBody.

PlayFetchIndex on a With*Animation trait conflicts
with the animation concept, as it's bound to conflict
with pretty much all 'normal' animation traits and
blocks progress on the animation priority system.

We also already have multiple similar SpriteBody traits,
like WithGateSpriteBody and WithWallSpriteBody.

- Rename WithResources to WithResourceLevelOverlay

Make name more accurate and consistent with sprite body
equivalent.
Also fix TS silo yaml setup (bleed setup stems from times
before WithResources was introduced).
2018-12-24 21:29:42 +13:00
reaperrr
305d82f887 Replace WithChargeAnimation with -SpriteBody
PlayFetchIndex on a With*Animation trait conflicts with the animation
concept, as it's bound to conflict with pretty much all 'normal'
animation traits and blocks progress on the animation priority system.

We also already have multiple precedent SpriteBody traits of similar kind,
like WithGateSpriteBody and WithWallSpriteBody.
2018-12-24 21:29:42 +13:00
Chris Forbes
e292e88bff Improve RenderShroudCircle configuration. 2018-12-24 01:57:11 +01:00
Oliver Brakmann
680ffffff2 Cache some more strings in GameInfoStatsLogic 2018-12-24 00:55:09 +01:00
Oliver Brakmann
3507167e79 Fix player score not updating while game info screen is visible 2018-12-24 00:55:09 +01:00
David Wilson
bbc83c1799 Rate limits for notification sounds 2018-12-24 12:18:52 +13:00
Paul Chote
9b3ddee517 Fix QuantizeFacing returning values >= numFacings. 2018-12-24 00:00:06 +01:00
Oliver Brakmann
e5f34a99ac Fix Lint test failures in Allies08b 2018-12-24 11:06:17 +13:00
Paul Chote
3817c7b96f Change existing husks to neutral when owner loses. 2018-12-23 22:14:56 +01:00
Smittytron
65269f7950 Add Allies08b 2018-12-23 21:59:14 +01:00
reaperrr
7ed67338f3 Allow forcing sprite body Z position to ground 2018-12-23 17:16:06 +13:00
Paul Chote
5efbcf19f2 Fix cell-out-of-bounds crashes in BuildableTerrainLayer. 2018-12-22 21:15:09 +01:00
reaperrr
6db27b1839 Split off CaptureManagerBotModule
from HackyAI.

Note: This isn't used in any official mod right know,
and known to be bugged on bleed already.
2018-12-22 17:42:53 +01:00
Paul Chote
d823d38e8c Fix "game is full" error when the game is not full.
Client.IsObserver is not valid to check until the
slot has been assigned.
2018-12-22 04:55:57 +01:00
Oliver Brakmann
e71a31925f Require explicit implementation of INotifyObjectivesUpdated 2018-12-22 16:39:06 +13:00
Smittytron
d10d48c25f RA balance changes for December 2018 2018-12-22 11:07:27 +13:00
reaperrr
9914848356 BaseBuilder- and BuildingRepairBotModule update rule 2018-12-19 21:50:54 +13:00
reaperrr
d46710d6ce Fix bot module update rule setting wrong RequiresCondition
Yaml nodes are reference types, so caching this meant changes would be applied on all of them.
Additionally, only add HarvesterBotModule if at least one AI is actually using it.
2018-12-19 21:50:54 +13:00
reaperrr
04c34741c8 Extract BaseBuilderBotModule from HackyAI 2018-12-19 21:50:54 +13:00
Paul Chote
9f30e2ecb0 Add a --utility argument to the AppImages. 2018-12-17 22:34:37 +01:00
Paul Chote
224377f078 Track visibility modifiers on FrozenActors. 2018-12-17 22:19:26 +01:00
Paul Chote
5f79c31a57 Add AutoTarget support for FrozenActors. 2018-12-17 22:19:26 +01:00
Paul Chote
c34dd4b824 Allow Attack activities to target FrozenActors directly.
Removing the legacy FrozenActor to Actor workaround
fixes a number of long-standing bugs.

This also prevents units from losing their target when
it transforms into a different actor type.
2018-12-17 22:19:26 +01:00
Paul Chote
0406b89a96 Add Actor.ReplacedByActor to track transformations.
This isn't great conceptually, but has precedent
in the Generation number.
2018-12-17 22:19:26 +01:00
Paul Chote
2ac7e451b4 Remove AttackBase.IgnoresVisibility.
This was a workaround for D2K sandworms, which is
now implemented using a custom attack activity.
2018-12-17 22:19:26 +01:00
Paul Chote
8eeb6d68e7 Tweak FrozenActorLayer queries:
- FrozenActorsInRegion now filters for valid and (optionally) visible FAs
- Add new FrozenActorsInCircle to mirror World.FindActorsInCircle.

The first change means that SupportPowerDecision now correctly ignores
FrozenActors that the AI has not discovered.
2018-12-17 22:19:26 +01:00
Paul Chote
3e490e5843 Cache FrozenActorLayer on the Player object.
This avoids unnecessary trait queries.
2018-12-17 22:19:26 +01:00
Andre Mohren
f238e2c5cc Fixed filename 2018-12-17 10:28:54 +13:00
reaperrr
b048e9c77b Fix two typos in TD music.yaml
One major (filename, track wouldn't show up) and one minor (titles should be all uppercase).
2018-12-16 18:19:40 +01:00
Paul Chote
98b80d44eb Remove legacy workaround that crashes modern Mono. 2018-12-15 23:35:29 +01:00
Paul Chote
04359206ff Remove long-broken setting to ignore version mismatches. 2018-12-15 23:30:36 +01:00
Paul Chote
b7317f2202 Add auth and sync report settings to dedicated server scripts. 2018-12-15 23:30:36 +01:00
Paul Chote
cc707f0037 Disable MP sync report generation by default.
A new Server.EnableSyncReports option is provided
so that server operators can restore them remotely
in the event of a future desync bug.
2018-12-15 23:30:36 +01:00
Paul Chote
081182b60f Profile sync report generation separately. 2018-12-15 23:30:36 +01:00
Paul Chote
9cee77ed8c Add hardcoded fallback mountpoints for asset detection on Linux. 2018-12-15 22:22:54 +01:00
abcdefg30
ee221f3e0d Revert balance changes to civilian buildings for the campaign missions 2018-12-10 10:01:31 +13:00
abcdefg30
48360bad8b Use the tooltips from the original game for MISS and FCOM 2018-12-10 10:01:31 +13:00
abcdefg30
fe05dad670 Disable inaccurate tooltip descriptions in the campaign missions 2018-12-10 10:01:31 +13:00
Paul Chote
ea9f12ffbc Simplify and fix panel positioning at different zooms. 2018-12-08 22:53:13 +01:00
Paul Chote
4723e5ddb9 Expose common actor Inits in the map editor. 2018-12-08 22:53:13 +01:00
Paul Chote
f6768fe624 Remove legacy editor actor properties plumbing. 2018-12-08 22:53:13 +01:00
Paul Chote
1d98b8b8f0 Fix damagestates in the map editor. 2018-12-08 22:53:13 +01:00
Paul Chote
07fc67f58d Remove obsolete and unused PreventsTeleport method. 2018-12-08 22:34:44 +01:00
Paul Chote
38f341ac1d Allow MadTank Detonate order to be queued. 2018-12-08 22:34:44 +01:00
Ivaylo Draganov
9be7298311 Remove airstrike/paradrop beacon when the whole squad is shot down 2018-12-08 22:30:17 +01:00
Paul Chote
13f5ef50b9 Fix production tooltip padding. 2018-12-08 15:32:58 +01:00
Paul Chote
3e7caa2faa Fix Commando/Tanya build announcements. 2018-12-08 15:27:06 +01:00
Paul Chote
d9f8afdbe5 Add GrantExternalConditionToProduced trait. 2018-12-08 15:27:06 +01:00
Paul Chote
73198dc45a Fix queued EnterTransport unload glitch. 2018-12-08 11:41:20 +01:00
Paul Chote
4b6853b433 Prevent multiple Transforms from triggering in the same tick.
This leads to actor duplication.
2018-12-08 11:34:49 +01:00
Smittytron
72923b9572 Merge Hijacker into Thief 2018-12-07 17:38:24 +03:00
Inq8
e6668bbb59 Improve Hind visibility
Recoloured the hind to a lighter shade to alleviate #15401
2018-12-06 18:09:23 +13:00
reaperrr
bdbc19376a Fix bot module update rule NRE on overrides
We cannot reliably update overrides of base HackyAI definitions,
unless they (re-)define Type.
If they don't, we now instead just list their locations.
2018-12-05 09:29:13 +13:00
reaperrr
20ba45d467 Remove queueing HeliFlyCircle from AutoCarryall 2018-12-05 09:20:58 +13:00
reaperrr
ac3e601edf Use INotifyIdle on Aircraft
For now only to trigger landing or circling.
2018-12-05 09:20:58 +13:00
reaperrr
d8220b390a Add IdleTurnSpeed to Aircraft
Instead of hardcoding 1/3 of normal TurnSpeed on HeliFlyCircle.
2018-12-05 09:20:58 +13:00
reaperrr
1553a8a5cb Fix empty activity tick when becoming idle
Activities usually don't do much more than cleanup on their last, 'null' tick.
That, combined with queued activities normally only starting to tick on the next tick,
would lead to visible 1-tick 'gaps' between movement activities.
Non-movement activities would suffer from the same problem,
only with different (presumably less noticable) symptoms.

Now we start ticking any activity that was queued from OnBecomingIdle
immediately, to avoid that issue.
2018-12-05 09:20:58 +13:00
reaperrr
87fa8a77c2 Make various D2k map deco require Neutral owner
And make worm require Creeps.
2018-12-05 09:07:30 +13:00
reaperrr
eaca8b6287 Make various RA map deco require Neutral owner 2018-12-05 09:07:30 +13:00
reaperrr
7c9856ded7 Make various TD map deco require Neutral owner 2018-12-05 09:07:30 +13:00
reaperrr
7503919659 Enforce Neutral owner for TS decorations
Fortunately, all official maps already adhered to that.
2018-12-05 09:07:30 +13:00
reaperrr
eb86160021 Remove CrateEffect in favor of using updated SpriteEffect 2018-12-05 09:04:29 +13:00
reaperrr
4de0d0fcb9 Replace LaunchEffect with updated SpriteEffect 2018-12-05 09:04:29 +13:00
reaperrr
c2d6b78b18 Add dynamic position support to SpriteEffect
This was the last missing 'puzzle piece' to replace some remaining spcial-case effects.
2018-12-05 09:04:29 +13:00
Paul Chote
6ac7f887c0 Fix a VS code style suggestion. 2018-11-26 19:46:05 +01:00
Paul Chote
9e85aefca8 Make the lobby teamchat selector match the in-game selector. 2018-11-26 19:46:05 +01:00
Oliver Brakmann
7454427b13 Fix FindResources aborting to early 2018-11-25 22:41:46 +00:00
Paul Chote
8a95241fd5 Change mechanics to repair ally-owned husks.
Now uses the goldwrench cursor and keeps the
original owner.
2018-11-25 19:20:28 +01:00
Paul Chote
89161b61ec Remove neutral-owner workaround from RA husks. 2018-11-25 19:20:28 +01:00
Paul Chote
fac271245b Add InfiltrateForTransform trait. 2018-11-25 19:20:28 +01:00
Paul Chote
66464a6164 Add cursor support to Infiltrates.
Also fixes targeting vs ally-owned actors.
2018-11-25 19:20:28 +01:00
Paul Chote
26363e5811 Remove references to buildings from infiltration Descs. 2018-11-25 19:20:28 +01:00
Paul Chote
7ddcc2e958 Remove the default notification from Infiltrates. 2018-11-25 19:20:28 +01:00
reaperrr
451a38338b Convert AISupportPowerManager to module 2018-11-25 19:00:44 +01:00
netnazgul
c195699476 Implement a slider widget for volume control that returns an exponentially scaled value 2018-11-25 16:54:30 +01:00
Smittytron
9c08e430e2 Add myself to AUTHORS 2018-11-24 23:21:01 +01:00
Smittytron
32968e4f4b Add Soviet08a 2018-11-24 23:21:01 +01:00
reaperrr
67cba65800 Fix bot module plumbing
Fixes the issues pointed out after the original harvester module was merged.
Also merges the update rules as discussed on IRC.
2018-11-24 11:05:37 +00:00
David Wilson
22bece2dc9 Add a basic actor properties panel to the editor. 2018-11-24 10:14:17 +00:00
abcdefg30
9b4db3468b Fix CombatProperties not accounting for multiple AttackBase traits 2018-11-22 23:16:30 +00:00
Brenton Horne
2d4d6cdc1b Fixing several ShellCheck warnings 2018-11-22 21:30:59 +00:00
Paul Chote
807a40c209 Remove IExplodeModifier interface. 2018-11-22 22:16:56 +01:00
Paul Chote
80842fd4b8 Add GrantConditionOnPlayerResources trait. 2018-11-22 22:16:56 +01:00
Paul Chote
3be008f592 Add EmptyCondition to Harvester. 2018-11-22 22:16:56 +01:00
Paul Chote
5f2cc5981d Remove unused IExplodeModifier from Refinery. 2018-11-22 22:16:56 +01:00
reaperrr
10e51db236 Remove hardcoded mpspawn owner lint check
Use RequiresSpecificOwner to enforce the owner
that owns the world instead.

Require 'Neutral' in the official mods accordingly.
2018-11-21 22:29:55 +00:00
reaperrr
1eb573bcbc Enforce required owner in map editor
It can easily happen that mappers forget to set the
current player to Neutral before placing more trees,
for example, so we force the editor to set a valid owner.
2018-11-21 22:29:55 +00:00
reaperrr
fcb09d069b Add RequiresSpecificOwners trait
To enforce specific owners via Lint rules,
and possibly other means later.
This is for cases where accidentally setting an
unfitting owner via editor could cause issues.

Example: AI might try to attack Creeps-owned trees
and get stuck.
2018-11-21 22:29:55 +00:00
Oliver Brakmann
310b63150f Check for player trait prereqs in ProximityCapturable 2018-11-21 22:12:07 +00:00
Andre Mohren
c3f4bc484d Correctly handle Production traits disabled by condition. 2018-11-21 22:13:20 +01:00
Mustafa Alperen Seki
53032576e2 Update default mods for Heal WH full health check removal 2018-11-21 19:25:45 +01:00
Mustafa Alperen Seki
6a599e57f6 Remove check for full health for negative damage warheads 2018-11-21 19:25:45 +01:00
Andre Mohren
99de33bbe3 Added smudge chance. 2018-11-21 18:00:11 +01:00
TheChosenEvilOne
e01953afa3 Made Turreted PausableConditional 2018-11-21 17:32:53 +01:00
Paul Chote
1af9efe246 Avoid a crash if subjects is empty.
This can happen in the rare instance that the last
actor in the selection is killed in the same tick
that the OG is activated, and GetCursor is called
before the next tick cancels the OG.
2018-11-20 21:55:55 +01:00
teinarss
3b6024c086 Defer setting slot on client to completeConnection 2018-11-19 22:05:32 +00:00
reaperrr
b8d3c9f73a Fix aircraft being repaired mid-air
Repairable was originally written for ground actors,
so it's both safer and much easier to just handle this in Aircraft directly.
2018-11-19 21:40:10 +00:00
reaperrr
560d7b4ee8 Fix Repairable crash
MoveAdjacentTo is a Mobile-only activity.
2018-11-19 21:40:10 +00:00
reaperrr
7d695f0c8f Fix actors in ReturnFire stance following targets
On bleed, if AllowMovement is true actors with ReturnFire will actually follow the acquired target, unlike in Defend stance.
This is at least unintuitive, since ReturnFire is expected to be more passive than Defend.
2018-11-18 16:19:50 +01:00
teinarss
bc009634e5 Show team/spawn widget after admin transfer. 2018-11-18 14:47:10 +01:00
Paul Chote
ad4b4dc7f8 Remove unused tileset update/save code. 2018-11-18 14:11:11 +01:00
Andre Mohren
0fca984463 Implemented InfiniteBuildAfter. 2018-11-17 17:39:18 +00:00
Andre Mohren
89051d40e8 Remove utf8 BOM. 2018-11-17 17:23:22 +00:00
Andre Mohren
7323db1492 Unified copyright regions. 2018-11-17 17:23:22 +00:00
Andre Mohren
b1a44086a0 Removed unused using directives. 2018-11-17 17:23:22 +00:00
Ivaylo Draganov
db64dc82c3 Fix damaged-idle sequence of RA refinery 2018-11-16 21:33:23 +01:00
reaperrr
cd82382f68 Change CreateEffectWarhead to use World.LocalRandom 2018-11-11 19:50:16 +01:00
reaperrr
16e78b8ca8 Add LocalRandom to World
To - in the long term - reduce or remove Game.CosmeticRandom.
2018-11-11 19:50:16 +01:00
Mustafa Alperen Seki
becfc154c5 Add Creates/RevealsShroudMultiplier. 2018-11-10 12:14:14 +01:00
Mustafa Alperen Seki
4987d45f23 Fix a crash when protected properties are [Sync]ed. 2018-11-10 12:14:14 +01:00
Mustafa Alperen Seki
3224843d70 Add Demolition>(Force)TargetStances 2018-11-10 11:48:28 +01:00
TheChosenEvilOne
51ec97fb2c Check for null in Turreted.StopAiming 2018-11-09 23:58:16 +01:00
reaperrr
74fa8752c9 Revert granting condition from HackyAI
In favor of using GrantConditionOnBotOwner.
Updated update rule and shipping mods accordingly.
2018-11-09 23:45:24 +01:00
reaperrr
4c9c8bf7fc Remove unused HarvesterEnemyAvoidanceRadius
...from HackyAI. This removal either got lost during rebase,
or was simply forgotten to apply when partially rewriting HarvesterBotModule.
2018-11-07 11:01:21 +01:00
Paul Chote
2064dc7c30 Support non-int Enum types in the Lua API. 2018-11-04 18:32:33 +01:00
Chris Forbes
d653614e75 Replicate palette high bits into the low bits
Previously we didn't quite get the full range -- the most intense value we
could produce was 0xfc.
2018-11-04 15:06:50 +01:00
abcdefg30
ae0a0163cc Fix DamagesConcreteWarhead crashing when a target becomes invalid 2018-11-04 10:49:29 +00:00
Ivaylo Draganov
31f2441709 Draw target lines for allied players and observers 2018-11-04 06:34:43 +01:00
reaperrr
927b6cd561 Convert AIHarvesterManager into *Module 2018-11-04 01:11:00 +01:00
reaperrr
04c69efc30 Prepare HackyAI for module support
- Split order handling to BotOrderManager
- Make HackyAI provide a condition
- Move BotDebug to AIUtils
2018-11-04 01:11:00 +01:00
reaperrr
71fb670def Move InitialFacing to ^Helicopter default
In RA and TD mods.
2018-11-04 00:25:55 +01:00
reaperrr
92912c6c94 Add TurnToDock to Aircraft
Instead of hard-coding a turn before VTOLs
land/dock on resupplier.
2018-11-04 00:25:55 +01:00
reaperrr
e2227b9450 Make HeliReturnToBase use a landingProcedures list
Like ReturnToBase already does. Makes them easier to compare and later merge.
2018-11-04 00:25:55 +01:00
reaperrr
577fc1c409 Remove separate AircraftInfo caching from ReturnToBase
This extra info caching was overkill and most likely had zero effect on performance.
2018-11-04 00:25:55 +01:00
reaperrr
54d3656205 Move CalculateTurnRadius up in ReturnToBase
Just a slight readability improvement.
2018-11-04 00:25:55 +01:00
Mustafa Alperen Seki
a3d9822bb3 Update TD mod for Cloak>RequiresCondition to PauseOnCondition 2018-11-03 22:40:28 +00:00
Mustafa Alperen Seki
b1db79cce2 Update D2k mod for Cloak>RequiresCondition to PauseOnCondition 2018-11-03 22:40:28 +00:00
Mustafa Alperen Seki
faad2b8653 Update TS mod for Cloak>RequiresCondition to PauseOnCondition 2018-11-03 22:40:28 +00:00
Mustafa Alperen Seki
d9ecbb0351 Update RA mod for Cloak>RequiresCondition to PauseOnCondition 2018-11-03 22:40:28 +00:00
Mustafa Alperen Seki
dd39ab5b12 Add Update Rule to change Cloak>RequiresCondition to PauseOnCondition 2018-11-03 22:40:28 +00:00
Mustafa Alperen Seki
dd92ec4d02 Make Cloak PausableConditional
If disabled now it CloakDelay resets to InitialCloakDelay when
reenabled, if paused it continues with CloakDelay when resumed.
2018-11-03 22:40:28 +00:00
Ivaylo Draganov
a7279415dc Allow player to add a "priority unit" to production queue
* If production is ordered by `Ctrl + Left Click` the item is added to the top of the stack after the currently produced item
* Works with `Shift` for priority queueing of 5 items
* This modifier is not taken into account for `ParallelProductionQueue` as it doesn't make sense in that context
2018-11-03 17:54:50 +01:00
Paul Chote
81d53a4f1a Improve error message for children of removals. 2018-11-03 17:36:40 +01:00
Paul Chote
f05e3e871f Fix crash when Inherits has child nodes. 2018-11-03 17:36:40 +01:00
abcdefg30
f968b169ad Fix PrimaryBuilding changing the status of and from disabled queues 2018-11-03 17:30:05 +01:00
abcdefg30
272d9b99fd Fix ProductionFromMapEdge blocking the base Created call. 2018-11-03 17:30:05 +01:00
abcdefg30
cde18221e6 Add Lua API support for actors with multiple Production traits. 2018-11-03 17:30:05 +01:00
abcdefg30
c0ee199ad1 Support multiple Production traits in WithProductionOverlay. 2018-11-03 17:30:05 +01:00
abcdefg30
a03abe78af Ignore disabled production traits. 2018-11-03 17:30:05 +01:00
Paul Chote
4a4415c74b Remove unnecessary caching of ProductionAirdropInfo. 2018-11-03 17:30:05 +01:00
abcdefg30
394e33dcc2 Improve ClonesProducedUnits logic:
- Supports multiple Production trait instances
- Clones the correct faction variant, if defined
2018-11-03 17:30:05 +01:00
Paul Chote
ea3731a7cc Pass the original init dict to UnitProducedByOther. 2018-11-03 17:30:05 +01:00
abcdefg30
5e5183549c Overhaul ProductionBar:
- Is now a conditional trait
- Now respects multiple Production trait instances
- ProductionType is now required
2018-11-03 17:30:05 +01:00
abcdefg30
7f255a17da Revert "Add conyard.corrino"
This reverts commit a0d4a03530.
2018-11-03 17:30:05 +01:00
Smittytron
557c87eecb Remove unused waypoints from Soviet02a 2018-11-03 15:34:00 +01:00
Paul Chote
fc6ada38f4 Revoke WithMakeAnimation condition at the end of the tick.
This fixes traits becoming enabled for a tick
between the animation completing and the actor
being removed from the world.
2018-11-03 15:28:05 +01:00
Paul Chote
47a470e945 Remove legacy Building plumbing. 2018-11-03 15:09:14 +01:00
Paul Chote
e77aaa1a47 Remove (INotify)BuildComplete from Attack* 2018-11-03 15:09:14 +01:00
Paul Chote
e57087cb5b Remove building lock from Production. 2018-11-03 15:09:14 +01:00
Paul Chote
7bc53dd266 Remove building lock from ToggleConditionOnOrder. 2018-11-03 15:09:14 +01:00
Paul Chote
94088d37a6 Remove building lock from Sellable. 2018-11-03 15:09:14 +01:00
Paul Chote
492bcdd9a7 Remove building lock from Transforms. 2018-11-03 15:09:14 +01:00
Paul Chote
18b84750aa Reimplement demolition lock using conditions. 2018-11-03 15:09:14 +01:00
Paul Chote
0901a7d9de Simplify FlashTarget.
Now defined in terms of a flash count, interval, and delay.
Broken FlashDuration parameter removed from Demolition.
2018-11-03 15:09:14 +01:00
Paul Chote
1b9f23eca0 Replace AnnounceOnBuild with VoiceAnnouncement. 2018-11-03 15:09:14 +01:00
Paul Chote
78a2d9aa23 Remove INotifyBuildComplete from ConyardChronoReturn. 2018-11-03 15:09:14 +01:00
Paul Chote
ae3bfb73a1 Fix LastChildMatching ignoring the includeRemovals argument. 2018-11-03 15:09:14 +01:00
Paul Chote
3d6b170ec3 Support multiple capture traits in order targeter and script plumbing. 2018-11-03 14:47:22 +01:00
Paul Chote
346e670563 Simplify type filtering in GivesCashOnCapture/TransformOnCapture. 2018-11-03 14:47:22 +01:00
Paul Chote
7e67ce0139 Pass CaptureTypes through the INotifyCapture interface.
Also make it require explicit implementation.
2018-11-03 14:47:22 +01:00
Paul Chote
4ea3e8382d Work around a race condition between server join and auth validation. 2018-11-03 14:25:05 +01:00
reaperrr
e42094625d Merge AttackPlane and AttackHeli into AttackAircraft 2018-11-03 11:37:23 +00:00
Taryn Hill
5899636e10 Fix SubCell indexing in Map.CenterOfSubCell and MapGrid.OffsetOfSubCell 2018-11-02 22:42:51 +00:00
reaperrr
8f1d8a67cc Remove RearmBuildings from Aircraft and Minelayer
In favor of using Rearmable trait.
2018-11-02 22:28:08 +00:00
reaperrr
2485029452 Add Rearmable trait 2018-11-02 22:28:08 +00:00
reaperrr
139d5efba8 Remove RepairBuildings from Aircraft
Require them to use Repairable trait instead.
2018-11-02 22:28:08 +00:00
abcdefg30
ed7d12506d Add an update rule for CarryableHarvester 2018-11-02 22:24:56 +00:00
abcdefg30
db58b35856 Further untangle (and - hopefully - fix) the afterLandActivity mess 2018-11-02 22:24:56 +00:00
abcdefg30
7e20bdd7ea Introduce a new CarryableHarvester trait 2018-11-02 22:24:56 +00:00
Andre Mohren
89e3b62f61 Allow different color picker preview actors per faction. 2018-11-02 21:17:50 +00:00
Smittytron
8e00ddedc7 Move Moneycrate to campaign-rules.yaml 2018-11-01 19:06:51 +01:00
Paul Chote
95c5c683e3 Limit samplers to 8 in combined.frag.
The additional palette sampler wasn't accounted
for in the original PR.
2018-11-01 14:38:57 +01:00
reaperrr
a12bb54ded Add overlooked entries to bleed update path
Those were forgotten to be added in their respective PR.
Not adding them at the bottom because
  a) RenameCrateActionNotification was merged later than them
  b) this might allow some open PRs to rebase without merge conflicts
2018-11-01 09:33:09 +00:00
Paul Chote
c05527c561 Add ARM architecture support to dependency configuration. 2018-11-01 04:21:20 +01:00
Mustafa Alperen Seki
5a0c1459b2 Add MPSpawnUnits>BaseActorOffset 2018-11-01 02:16:59 +01:00
abcdefg30
d46e47d16d Fix target lines still being visible after an owner change 2018-11-01 02:09:36 +01:00
Andre Mohren
8b8a14e0b8 Proper usage of IHealthInfo. 2018-10-30 20:59:04 +00:00
Paul Chote
2ad8179672 Add PngSheetMetadata sprite metadata. 2018-10-28 20:55:40 +00:00
Paul Chote
6b7f1c6458 Use EmbeddedSpritePalette in D2k. 2018-10-28 20:55:40 +00:00
Paul Chote
eb61c45e14 Add EmbeddedSpritePalette sprite metadata. 2018-10-28 20:55:40 +00:00
Paul Chote
dee6d03626 Allow sprites to store custom metadata. 2018-10-28 20:55:40 +00:00
abcdefg30
0b89883012 Prevent ReturnToBase from causing a divide by zero crash 2018-10-28 18:54:32 +01:00
reaperrr
e05baf6ec7 Reduce RA helipad reload animation speed
Matching TD helipad.
2018-10-28 17:22:41 +00:00
Mustafa Alperen Seki
1a16ef3537 Add RenameCrateActionNotification to bleed update path 2018-10-28 11:21:49 +00:00
abcdefg30
9cbe7bc62d Fix infantry getting stuck in the last attack frame 2018-10-28 02:13:18 +01:00
Andre Mohren
cc036cfd62 Implement AnnounceOnBuildInfo.OnlyToOwner 2018-10-27 15:21:33 +02:00
Mustafa Alperen Seki
98006d3870 Make CrateAction>Sound to play for everyone 2018-10-26 22:37:00 +01:00
Mustafa Alperen Seki
2dcd377aaf Update main mods for CrateAction>Notification rename 2018-10-26 22:37:00 +01:00
Mustafa Alperen Seki
5f17f0b5b0 Add actual notification support for *CrateAction traits 2018-10-26 22:37:00 +01:00
Mustafa Alperen Seki
f066655bb7 Rename CrateAction>Notification to Sound 2018-10-26 22:37:00 +01:00
reaperrr
f18ce8cfda Make HitShape mandatory for damaging actors and refactor warheads.
* Adds support for linking Armor traits to HitShapes.
* Adds spread support to TargetDamageWarhead
* Removes ring-damage support from HealthPercentageDamage
* Removes IsValidAgainst check from DoImpact(Actor victim...) overload
  and instead lets warheads perform the check beforehand
  (to avoid HitShape look-ups on invalid targets).
* Reduces duplication and improves readability of Warhead implementations
2018-10-26 22:03:34 +02:00
reaperrr
e2050dfdc9 Fix FindActorsOnCircle summary
The summary was not entirely correct:
Since FAOC simply adds the largest existing OuterRadius to the specified circle range, it's still possible (very likely, in fact) for this helper to return actors whose HitShape is entirely outside the specified range (*without* the added largest OuterRadius).
2018-10-26 22:03:34 +02:00
Smittytron
b815e80e99 Reorganize RA missions list 2018-10-24 15:32:50 +01:00
Mustafa Alperen Seki
f3cbc5f72b Make CrateAction conditional. 2018-10-24 15:13:04 +01:00
Ectras
93977782a7 Updated Description for TerrainSpeeds
Added check for speed > 0
2018-10-18 18:45:51 +02:00
reaperrr
3e73357619 Remove IsIdle check from DrawLineToTarget.OnBecomingIdle
OnBecomingIdle is triggered when IsIdle becomes true, so this check is bogus.
2018-10-15 22:53:57 +02:00
reaperrr
422ba16ed9 Run TickIdle from inside Actor.Tick instead of World.Tick
Avoids calling ActorsWithTrait<INotifyIdle> every tick and allows caching all INotifyIdle traits at creation.
2018-10-15 22:53:57 +02:00
abcdefg30
cf4dc42c8f Fix lint warnings in RA missions 2018-10-15 19:16:27 +02:00
abcdefg30
a6716e2c2d Fix TS units not using the being-captured condition 2018-10-15 19:16:27 +02:00
abcdefg30
ed5bb1b1a1 Fix RA vehicles not using the being-captured condition 2018-10-15 19:16:27 +02:00
Paul Chote
a06cfb4004 Move TerrainRenderer to a mod-defined trait. 2018-10-13 18:16:56 +02:00
Inq8
fec9fe1ad4 Aircraft Takeoff & Landing Sounds (Fixed-Wing)
Added Takeoff & Landing sounds to planes.

Changed Aircraft Trait, TakeoffSounds & LandingSounds are now arrays & accept a list of sound files & it will randomly select one to play.

Changed/fixed take off & landing sounds to originate from the aircraft location, rather than play a global sound.
2018-10-12 14:29:53 +02:00
Smittytron
9cf8cba750 Touchup Allies08a errors 2018-10-10 01:01:06 +02:00
Mustafa Alperen Seki
9972d69c5d Change capture Production lock back to exit lock 2018-10-08 22:00:39 +01:00
Mustafa Alperen Seki
faa35946b8 Make Exit Conditional 2018-10-08 22:00:39 +01:00
Mustafa Alperen Seki
47c4be9191 Update mods for LowPowerSlowdown to LowPowerModifier 2018-10-08 21:38:30 +01:00
Mustafa Alperen Seki
9bcb222a2d Add Update rule for LPSlowdown to LPModifier 2018-10-08 21:38:30 +01:00
Mustafa Alperen Seki
5b00c12ca3 Change default value of LowPowerModifier to 100 2018-10-08 21:38:30 +01:00
Mustafa Alperen Seki
53304a0353 Change LowPowerSlowdown to LowPowerModifier 2018-10-08 21:38:30 +01:00
Smittytron
831ec0aeda Add Allies08a 2018-10-07 20:02:46 +02:00
Paul Chote
e038b86742 Hook up make animation conditions for the default mods. 2018-10-07 19:29:34 +02:00
Paul Chote
14607f55c5 Replace INotifyBuildComplete in render traits with conditions. 2018-10-07 19:29:34 +02:00
abcdefg30
26b0a06a17 Remove a wrong empty line from ra/rules/player.yaml 2018-10-07 18:28:37 +01:00
Andre Mohren
450dc70375 Refactored cursors.yaml to use palettes from rules. 2018-10-07 19:28:11 +02:00
Noam
c71f97e2c6 Update editor sidebar when a player is removed. 2018-10-07 19:01:55 +02:00
abcdefg30
52900f8112 Correct the amount of money found in crates in allies03 2018-10-07 17:59:34 +01:00
Paul Chote
1abfaa94af Remove unwanted overrides from allies-03*. 2018-10-07 18:46:21 +02:00
Paul Chote
769f9429f9 Stop vehicle movement when a hijacker is entering. 2018-10-07 18:46:21 +02:00
Paul Chote
de8fa56461 Remove obsolete building lock check from BaseProvider. 2018-10-07 18:46:21 +02:00
Paul Chote
22bd7fd90b Remove obsolete code. 2018-10-07 18:46:21 +02:00
Paul Chote
b1b35c1e1b Rework RA Engineer behaviour.
Capturing now behaves as in C&C3:KW - wait for 8 seconds
outside the structure before running inside and being disposed.

A "Reusable Engineer" lobby option is provided to restore
the previous non-disposing behaviour.
2018-10-07 18:46:21 +02:00
Paul Chote
ccad3bd185 Add MergeCaptureTraits update rule. 2018-10-07 18:46:21 +02:00
Paul Chote
a4405009c8 Add PreventsAutoTarget. 2018-10-07 18:46:21 +02:00
Paul Chote
132268bc49 Remove default building capture type. 2018-10-07 18:46:21 +02:00
Paul Chote
e50b0b193d Disable sabotaging by default. 2018-10-07 18:46:21 +02:00
Paul Chote
db1f794beb Fix captor being disposed if the capture fails. 2018-10-07 18:46:21 +02:00
Paul Chote
d97a2a5fa0 Remove legacy building lock calls.
This has been superseded by conditions.
2018-10-07 18:46:21 +02:00
Paul Chote
50423b13fb Add ConsumedByCapture flag to emulate legacy external behaviour. 2018-10-07 18:46:21 +02:00
Paul Chote
4d2f1f8942 Add capture progress bars and blinking. 2018-10-07 18:46:21 +02:00
Paul Chote
bab34252dd Add support for capture delays and conditions.
CaptureDelay is defined per-trait, and the shortest
delay will be used if multiple traits are enabled.

CapturingCondition and BeingCapturedCondition are
global, and are granted when any capture is in progress.

The capture period is defined from when the unit reaches
the cell next to the target, and either starts to wait
or enter the target through to when the capture succeeds
or fails.
2018-10-07 18:46:21 +02:00
Paul Chote
a53ef6e503 Add CaptureManager trait to fix multiple-trait interactions.
This fixes the various edge cases that occur when multiple
Captures or Capturable traits are defined on an actor and
are toggled using conditions.

The Sabotage threshold field moves from Capturable to
Captures in order to simplify the plumbing. The previous
behaviour ingame can be restored by creating a new
capturable type for each threshold level, each with their
own Captures trait.
2018-10-07 18:46:21 +02:00
Paul Chote
588a5d784f Add IMove.EstimatedMoveDuration. 2018-10-07 18:46:21 +02:00
Paul Chote
3b16938ae5 Remove legacy building.Locked and building.BuildComplete from Gate. 2018-10-07 18:23:03 +02:00
BGluth
b88b84c05a Units that have turrets while deployed now move their turrets back to their initial positions before undeploying
- Tested in TS with all deployable units and did a quick check for obvious issues in TD and RA.
2018-10-07 12:19:09 +01:00
abcdefg30
00dc161628 Add a proper exception when creating an actor with an invalid owner in Lua 2018-10-07 11:09:06 +00:00
Brenton Horne
38e8bed9c9 [INSTALL.md] Pkg lists->command; add extra distros 2018-10-06 23:48:36 +01:00
Paul Chote
eb0e2eeb9d Fix misc indentation errors. 2018-10-06 23:32:38 +02:00
Mustafa Alperen Seki
416f529cb0 Make GPS dots use a bit darker remap colors. 2018-10-06 17:25:43 +01:00
SoScared
143951a409 polish sniper shp 2018-10-06 17:20:22 +01:00
Paul Chote
cc9da63323 Fix sampler index check
The index values are round numbers. Checking agaist
the half-values improves robustness against small
floating point delta errors that occur on some GPUs.
2018-10-06 15:10:43 +01:00
abcdefg30
01d340db09 Properly end capturing during an owner change 2018-10-06 14:59:33 +01:00
Mustafa Alperen Seki
f60b2275fc Make WithBuildingPlacedAnimation not play during vortex 2018-10-06 13:31:47 +01:00
Mustafa Alperen Seki
536f5f05a8 Make WithBuildingPlacedAnimation conditional 2018-10-06 13:31:47 +01:00
reaperrr
dd3c600258 Fix WithLandingCraftAnimation compatibility with elevated terrain 2018-10-06 13:11:10 +01:00
Smittytron
a7de079a53 Remove redundant demolishable overrides from evacuation 2018-10-02 10:44:06 +02:00
teinarss
cfaf5a6467 Updated CPos struct to use a bit field for all properties. 2018-10-02 00:54:45 +01:00
abcdefg30
9f82ef999f Set AutoGenerateBindingRedirects to true in OpenRA.Game.csproj 2018-10-01 17:52:52 +01:00
teinarss
e353c8c176 Changed SubCell to byte 2018-09-30 19:48:27 +01:00
Andre Mohren
52a7d39e51 Implemented Parallel ProductionQueue style. 2018-09-30 16:58:49 +02:00
Andre Mohren
3bfcecd539 Refactored ProductionQueue to support different production styles. 2018-09-30 16:58:49 +02:00
Andre Mohren
6cd1919cca Calling PreparingAttack before calculating Muzzle. 2018-09-30 15:34:08 +02:00
Mustafa Alperen Seki
abdb1f7547 Add TargetTypes to AttackSuicides 2018-09-30 14:34:14 +02:00
reaperrr
adc03c41b1 Cache DomainIndex in PathFinder
Should save a trait look-up for each path search. Also ditch bogus null checks (this trait is a must-have anyway, so we *want* to crash if it's missing).
2018-09-30 14:34:05 +02:00
SoScared
893e20ee76 Fix yaml error with notifications.yaml 2018-09-30 06:52:41 +00:00
Andre Mohren
693b5a54af PNG spritesheet support, along with PaletteFromPng.
Cursor palette loader can now be specified via yaml.
2018-09-29 21:12:40 +02:00
Andre Mohren
48248266a8 ClickSound and ClickDisabledSound and ChatLine are optional ui sounds. 2018-09-29 20:05:53 +02:00
Andre Mohren
28623ce54c Allow usage of different palette for WithSpriteTurret 2018-09-29 19:47:47 +02:00
Andre Mohren
640078a2b1 Refactored Health usage to IHealth. 2018-09-29 18:12:40 +02:00
reaperrr
83cd7cf485 Merge two ifs in RevealOnDeath 2018-09-29 12:54:34 +01:00
reaperrr
ade85f8977 Skip DamageWarhead armor lookups if no Versus defined
- directly return 100 when no Versus values are defined (meaning the warhead would have 100% efficiency vs. all armor types anyway)
2018-09-29 12:54:34 +01:00
reaperrr
1f7edf9f0b Cache *Notify traits in Health where applicable
During heated battles, those TraitsImplementing look-ups in Health might cause bursty CPU load on warhead impacts. Caching the notify traits of the actor + owner can reduce the trait look-ups per impact by more than half.
2018-09-29 12:54:34 +01:00
reaperrr
13769d48a1 Minor Health readability style fix 2018-09-29 12:54:34 +01:00
reaperrr
43693d84d1 Migrate DamageState thresholds to integer
While avoiding divisions.

While there haven't been any desyncs to speak of recently (not in this part of the code, in any case), this still looks like an oversight from when we migrated away from using floats.
This also makes it easier to expose the thresholds to modders later.
2018-09-29 12:54:34 +01:00
reaperrr
0b0c3b7170 Changed an 'if' to 'else' in Health.Tick
Since the two 'if's were mutually exclusive, the 2nd 'if' was turned into an 'else' to potentially skip that check if the 1st succeeds.
2018-09-29 12:54:34 +01:00
Mustafa Alperen Seki
b53c13dca4 Add GrantConditionOnProduction 2018-09-29 12:10:11 +01:00
Smittytron
2bb2cd51cc Change menu cancel buttons to back 2018-09-28 23:33:17 +01:00
abcdefg30
4298584af2 Prevent units from gaining more experience than MaxLevel requires 2018-09-28 22:48:50 +01:00
Andre Mohren
a86f41cd5c Made Valued optional for traits who do not require it. 2018-09-28 22:06:56 +01:00
reaperrr
ec15acbc80 Enable LaserZap launch-effect syncing with current source barrel/muzzle facing 2018-09-28 21:32:34 +02:00
reaperrr
28c89920ac Add dynamic muzzle LaunchEffect facing plumbing 2018-09-28 21:32:34 +02:00
Mike
619457828f Soviet Soldier Volkov & Chitzkoi fully ported
Crash fixed.
2018-09-28 21:12:15 +02:00
reaperrr
8144fca5be Merge repair and rearm anim traits into WithResupplyAnimation
This is the safest approach to avoid conflicts/visual glitches when the host is responsible for both resupply types.
The new trait will simply play a looping animation as long as the actor is resupplying in any form.
2018-09-27 16:38:08 +02:00
Smittytron
9fb8f6c6f8 Add Allies07 2018-09-27 16:04:17 +02:00
reaperrr
288dfdbf03 Update UpdatePaths and move bleed rules to subfolder 2018-09-26 23:43:30 +01:00
Paul Chote
09d8aafddf Add a lint test for audio notifications.
Only traits are linted - the UI still hardcodes
too many audio references for this to be worthwhile.
2018-09-26 13:57:05 +02:00
Smittytron
096de8f5aa Remove out of bound actors from RA missions 2018-09-25 18:38:08 +02:00
Smittytron
f668e18f37 Remove out of bounds actors from TD missions 2018-09-25 18:38:08 +02:00
Andre Mohren
f342ecf18a Added UpdateRule. 2018-09-24 22:43:14 +02:00
Andre Mohren
a68ea0fe2d RepairsUnits notification now optional. 2018-09-24 22:43:14 +02:00
Andre Mohren
091f660dc7 Extracted Repairing notification to RepairableBuilding. 2018-09-24 22:43:14 +02:00
Andre Mohren
a0ad79e555 Extracted RadarUp and RadarDown notifications to RadarWidget. 2018-09-24 22:43:14 +02:00
Andre Mohren
d7f81d4a20 Extracted Win and Lose and Leave notifications MissionObjectives. 2018-09-24 22:43:14 +02:00
Andre Mohren
fac758f38e ProductionQueue notifications now optional. 2018-09-24 22:43:14 +02:00
Andre Mohren
c2b1a5f4e0 Extracted BuildingCannotPlaceAudio to PlaceBuilding. 2018-09-24 22:43:14 +02:00
Andre Mohren
8834cee13c PlaceBuilding notification now optional. 2018-09-24 22:43:14 +02:00
Andre Mohren
7057e32902 PowerManager notification now optional. 2018-09-24 22:43:14 +02:00
Andre Mohren
90c2249317 PrimaryBuilding notification now optional. 2018-09-24 22:43:14 +02:00
Andre Mohren
cf84e6f8d5 GainsExperience notification now optional. 2018-09-24 22:43:14 +02:00
Andre Mohren
e353ff326e Extracted CashTickUp and CashTickDown to PlayerResources. 2018-09-24 22:43:14 +02:00
reaperrr
bb7c19ad02 Fix spawning 1 crate too much if maximum == minimum
If Maximum == Minimum but 'crates' < Maximum, the formula would simply return min + 1 regardless of max being identical to min.
Only adding 1 more crate if Maximum is higher than Minimum fixes that.
2018-09-24 22:06:21 +02:00
reaperrr
1098804f9b Make WithSpriteBody always use Animation.PlayRepeating
... for looped sequences.

PlayCustomAnimationRepeating looping back into itself via Action instead of simply using Animation.PlayRepeating is weird, and in fact causes a slight 'desync' in animation speed with Animation.PlayRepeating in at least one downstream mod.
2018-09-24 22:06:10 +02:00
reaperrr
9bcb754836 Add OnActorDispose plumbing to Activity
This allows activities to perform necessary cleanups on actor
death/disposal, for example by running OnLastRun directly,
which would otherwise be skipped when the actor dies or is disposed
through other means.
2018-09-24 22:01:22 +02:00
Andre Mohren
e8eb4d9563 Credit removal due to request. 2018-09-24 13:11:15 +02:00
Paul Chote
7d59602c0b Revert "Update macOS launcher template to osx-launcher-20180723."
This reverts commit 904c3afc4d.
2018-09-22 18:57:21 +02:00
abcdefg30
978d447d42 Disable the restart button on dedicated servers 2018-09-22 15:44:56 +01:00
abcdefg30
92e8fbf4d0 Make the menu widget readonly 2018-09-22 15:44:56 +01:00
Ectras
d9946f63e4 Renamed EditorTilesetFilter to MapEditorData and added an update rule 2018-09-22 15:12:15 +02:00
Glen
2e3f2e079a Github Username Change 2018-09-20 11:23:06 +02:00
Matthias Mailänder
cb05d8a98d Fix CustomTerrainDebugOverlay not rendered in isometric mods 2018-09-19 20:04:41 +02:00
Noam
4e7a35b50f add NoAvailableMaps exception.
modify ChooseInitialMap to throw NoAvailalbeMaps exception if no maps were loaded.
implement Utilities.TryWithPrompt - safe execution of a provided action with ability to prompt user on error.
2018-09-19 12:52:51 +02:00
Matthias Mailänder
399e451ada Add a DamagesConcreteWarhead to remove buildable concrete. 2018-09-15 15:36:12 +02:00
Paul Chote
7438af8266 Improve status line display for unknown-size downloads. 2018-09-14 18:55:58 +02:00
Emmalyn Renato
3f4d5fa68c Fix display of progress text in Advanced Install when total file size is unknown. 2018-09-14 17:30:53 +01:00
Paul Chote
91adc61abd Revert RA Grenadier explosion DamageSource. 2018-09-13 17:11:15 +02:00
SoScared
c242333922 Fix d2k bots not excluding harvesters from squads 2018-09-13 17:01:23 +02:00
SoScared
953d76a20a Enable nuke for d2k omnius ai 2018-09-13 17:01:23 +02:00
SoScared
3f9fde8855 Tweak AI excess power and unit production 2018-09-13 17:01:23 +02:00
Dennis Snell
95558a36ab Fix: Display progress message properly when download size missing (#1)
When I downloaded the assets for Red Alert through the Quick Install I noticed the progress bar proceed and display a recognizable message: `Downloading from … 1.47/12 MB (12%)`. This was fine.

When I downloaded the assets for one of the other games, maybe Dune 2000, there was obviously no total download size available. I was an unexpected message: `Downloading from … 1.47/NaN (NaN%)`

The code handling network progress events seems to be aware of the possibility that no full download size exists but it doesn't update the message. In this path I'm proposing that we display a separate messaging indicating that we don't know how much more we have to download for these cases.

Of the alternative ways to implement this I chose to move the reassignment of `getStatusText` into the conditional structures to preserve the existing choice. The message was qualitatively different and so I felt it worthwhile to create entirely different closures vs. doing something like this…

```cs
getStatusText = () => ( Double.isNaN( dataTotal ) ? "Downloading {1} of unknown amount" : "Downloading {1}/{2}" ).F( … );
```
2018-09-13 16:55:51 +02:00
Andre Mohren
ef7c49c116 Allow mods to determine associated SuperPower from SelectGenericPowerTarget 2018-09-12 15:11:18 +02:00
Paul Chote
16ff9fbc8e Fix menu/exit fade effect for paused replays. 2018-09-11 23:29:23 +02:00
reaperrr
bbf6e38faa Always leave trails when no TerrainTypes are defined
Requiring terrain types is bogus, as it unnecessarily complicates using this trait for airborne units.
2018-09-10 19:45:02 +02:00
Paul Chote
8533aa8d26 Disable sync reports when we know we won't need them.
Generating the sync report takes ~twice as long as
a normal tick, and occurs once every 3 ticks.

These reports record of all of the synced state
(separate to the sync hash, which is still calculated)
in order to generate the syncreport.log of the game
desyncs. This perf overhead is completely unnecessary
when we know that we won't have other syncreports to
compare against (singleplayer, replays).

Disabling report generation in these cases gives
us an easy 40% average tick-time win.
2018-09-10 19:44:06 +02:00
Paul Chote
0a507f3d33 Allow deploy orders to be queued from the command bar. 2018-09-10 19:42:24 +02:00
Paul Chote
3abc85b588 Add a Desc for Buildable.BuildPaletteOrder.
Also removes the long-outdated UI-fluff comment.
2018-09-10 11:27:50 +02:00
SoScared
024722a96c Enable airfield for AI as Ukraine 2018-09-10 03:45:59 +01:00
abcdefg30
5d1c37a4c5 Remove the CodeAnalysisRuleSet property from all csproj files 2018-08-25 22:02:59 +02:00
Paul Chote
48f2519811 Make SetupLatencyWidget consistent with SetupProfileWidget. 2018-08-25 21:56:10 +02:00
Paul Chote
0c098e74f1 Don't crash when mousing over a bot as a non-admin. 2018-08-25 21:56:10 +02:00
Paul Chote
8475bd6294 Ignore malformed orders instead of crashing. 2018-08-25 18:23:35 +02:00
rtri
cdfa52d918 fix threadedRenderer context creation logic 2018-08-23 01:50:18 +02:00
Chris Forbes
67d9ad6a93 Convert cloak types to use BitSet
Fixes #15412
2018-08-20 01:11:43 +02:00
Chris Forbes
1f71377d82 Convert cloneabletypes to bitsets
Fixes #15411
2018-08-20 01:11:43 +02:00
Paul Chote
8634c001f9 Add requires-auth indicator to the server lists. 2018-08-18 16:57:28 +02:00
Paul Chote
e374c8e6c3 Sync auth information with the master server. 2018-08-18 16:57:28 +02:00
Paul Chote
77bb39304b Give server operators more control over client validation. 2018-08-18 16:57:28 +02:00
Paul Chote
9ec22e48a6 Revert "Re-active Edge-Scrolling for inverted Mouse-Scrolling"
This reverts commit c4867d4030.
2018-08-18 16:51:51 +02:00
Paul Chote
03adceb656 Rework master server ping rate-limit logic.
Pings are now delayed instead of dropped to avoid data loss.
2018-08-18 09:31:11 +01:00
Paul Chote
efccd610d3 Simplify server tick timeout handling. 2018-08-18 09:31:11 +01:00
Paul Chote
d37119655b Add Engine.SupportDir argument. 2018-08-17 21:02:36 +02:00
Andre Mohren
8c5caaf154 Fixed unnecessary crash if RallyPoint palette is not used. 2018-08-16 22:24:58 +02:00
Paul Chote
4a5525d1af Ensure that TLS 1.2 is enabled for web downloads. 2018-08-16 19:56:18 +02:00
Mustafa Alperen Seki
6df243f79b Fix GivesExperienceModifier not working 2018-08-16 19:44:08 +02:00
Paul Chote
e56cb9901b Add a hard requirement on the cert-sync utility.
This tool is required to sync the certificates
used for https queries. This also has a side-effect
of prompting the mono-complete package on Mint,
which pulls in other required but missing packages.
2018-08-15 21:21:56 +01:00
Paul Chote
20dbf76e81 Fix the Chronoshift-return cancellation bug. 2018-08-15 21:17:27 +01:00
Paul Chote
4375dc2fc1 Kill chronoshifted actors if the return-to-origin fails. 2018-08-15 21:17:27 +01:00
Paul Chote
6f864b055d Remove IPreventsTeleport interface.
MadTank is changed to use conditions instead.
This has a side-benefit of disabling the move
cursor while deployed.
2018-08-15 21:17:27 +01:00
Paul Chote
e6d552eee7 Make Chronoshiftable conditional. 2018-08-15 21:17:27 +01:00
Paul Chote
828106cf82 Fix a typo in ChronosphereProperties class name. 2018-08-15 21:17:27 +01:00
Mustafa Alperen Seki
1977e64e07 Fix Cargo>EjectOnDeath crash with multipile INotifyBlockingMove 2018-08-14 23:00:08 +02:00
reaperrr
c983dda077 Fix husks not updating targetable positions on teleport
This should have checked for IPositionableInfo to begin with.

Husk already implements IPositionable, so implementing *Info as well
makes sense, even if it only serves to exclude it from
ITargetablePositions caching for now.
2018-08-14 17:26:36 +01:00
BGluth
09b9ed3506 Rearming aircraft now reapplies rearming order if canceled on landing structure
- Implemented by making the ResupplyAircraft activity recreate a new resupply activity if cancelled and also having no other queued activities.
- Tested in TD, RA, TS.
2018-08-12 21:16:23 +02:00
Paul Chote
1bfe70e923 Revert "Add "Restart" button for multiplayer replays"
This reverts commit 3a377a572c.
2018-08-12 18:57:12 +02:00
reaperrr
ba231636f5 Minor RepairsUnits style fix 2018-08-12 14:36:59 +01:00
reaperrr
46cee82027 Move RepairsUnits out of Building folder 2018-08-12 14:36:59 +01:00
reaperrr
77d03ce1e1 Replace Airfield/Helipad references with generic Resupplier in RTB activities
More generalization to prepare for possible future activity merger.
2018-08-12 14:24:21 +02:00
reaperrr
fc79e04c49 Generalize Land activities Aircraft caching naming
To make a possible future merger (or inheritance or other code-sharing) of these activities easier.
2018-08-12 14:24:21 +02:00
reaperrr
3f9aab7e86 Generalize Fly* plane activities Aircraft caching naming
To make a possible future merger (or inheritance or other code-sharing) with other activities easier.
2018-08-12 14:24:21 +02:00
reaperrr
6810ac92ba Generalize HeliAttack activity Aircraft caching naming
To make a possible future merger (or inheritance or other code-sharing) with FlyAttack easier.
2018-08-12 14:24:21 +02:00
reaperrr
c3a0d129a3 Generalize FlyCircle activity Aircraft caching naming
To make a possible future merger (or inheritance or other code-sharing) of these activities easier.
2018-08-12 14:24:21 +02:00
reaperrr
ae92255ded Generalize Fly activity Aircraft caching naming
To make a possible future merger (or inheritance or other code-sharing) of these activities easier.
2018-08-12 14:24:21 +02:00
reaperrr
96032d1953 Generalize *ReturnToBase trait caching naming
Makes both copying changes as well as a potential future activity merger a little easier.
2018-08-12 14:24:21 +02:00
Smittytron
bd569c9ae2 Revert ranger change and dial back missile sub damage 2018-08-11 23:04:41 +02:00
Paul Chote
3711a695c5 Fix badge label padding. 2018-08-11 23:02:41 +02:00
abcdefg30
94c47fdac0 Remove TSLauncher.exe from the IDFiles of the origin ts install 2018-08-11 22:58:28 +02:00
abcdefg30
60a492803d Remove RA95Launcher.exe from the IDFiles of the origin ra install 2018-08-11 22:58:28 +02:00
abcdefg30
4473059c60 Remove CNC95Launcher.exe from the IDFiles of the origin cnc and ra installs 2018-08-11 22:58:28 +02:00
Paul Chote
1b1521812c Add EnabledByDefault check to WithInfantryBody. 2018-08-11 14:30:01 +02:00
Paul Chote
d110a21bfe Add missing EnabledByDefault checks to WithSpriteBodyInfo subclasses. 2018-08-11 14:30:01 +02:00
abcdefg30
0b53c1f139 Resolve conflicts between actor and API names (Radar) 2018-08-10 20:49:06 +02:00
Oliver Brakmann
1927b88a18 Fix issueing superfluous difficulty lobby command from mission browser 2018-08-09 20:07:06 +01:00
Smittytron
e57f1dcd8c Fix death sequences of Chan, Einstein, and Delphi 2018-08-05 12:57:11 +02:00
reaperrr
6c401f0f9a Fix AI idle harvester management
This was broken because our default mods now list `harv` under `ExcludeFromSquads`, which prevents them from being added to `activeUnits`.
2018-08-04 22:30:07 +02:00
reaperrr
35600d9291 Some HackyAI cleanups
- harvManager.Tick should run after FindNewUnits() in case new harvesters have appeared
- moved the FindNewUnits Mcv and ExcludeFromSquads checks to the foreach loop, for better readability and preparation of the idle harvester fix
2018-08-04 22:30:07 +02:00
Paul Chote
a51b916eaa Hide the Ready checkbox when a spectator transfers away Admin. 2018-08-04 22:12:43 +02:00
BGluth
5c42f55b3a Fixed aircraft in TS landing instantly to reload their ammo
- Updated calculating the landing altitude for the Land activity not taking into account the terrain height.
- Fixes 14312.
2018-08-04 21:09:59 +02:00
Andre Mohren
3f81df9c52 Fixed backwards animation playback. 2018-08-04 20:58:02 +02:00
Paul Chote
a0dcd9e106 Clear selection when a text field's contents is changed programatically. 2018-08-04 20:29:19 +02:00
Paul Chote
d6737ccfab Fix missing profile indicator for spectators. 2018-08-04 20:22:35 +02:00
Paul Chote
3661dbdfd0 Disable the threaded renderer on Windows.
A DisableWindowsRenderThread graphics setting is
added to allow players to optionally reenable it.
2018-08-04 20:10:52 +02:00
reaperrr
599e87c4aa Fix tree owners in TD (for real this time) 2018-08-04 19:06:32 +01:00
Paul Chote
567ab47765 Revert ShpTD empty space trimming.
This reverts the following commits:
 * 1faae73c08
 * a7d39fc76d
2018-08-04 19:56:24 +02:00
Unknown
c97f36793c Implemented horizontal allign support for SupportPowersWidget 2018-08-04 17:39:18 +02:00
reaperrr
e179a9529e Fix tree owner on TD maps
Needs to be Neutral instead of Creeps, to avoid confusing the AI.
2018-08-04 14:03:02 +01:00
reaperrr
606bf6d9bb Fix tree owner on several RA maps
Owner: Creeps can lead to AI trying to attack trees, so all trees must have Neutral as owner.
2018-08-04 14:03:02 +01:00
abcdefg30
e8068cf329 Remove all uses of Server.ExternalPort 2018-08-04 12:32:01 +02:00
Andre Mohren
8f15535da0 Allow to use non tileset specific build-valid. 2018-08-04 12:28:41 +02:00
Mustafa Alperen Seki
d062523700 Add GetActorsByTypes. 2018-08-04 12:20:16 +02:00
Smittytron
6e18caa096 Remove duplicate line from V19.Husk 2018-08-04 12:18:01 +02:00
Zimmermann Gyula
6027a123d4 Split off the upgrade rules of the previous release cycle. 2018-08-02 17:00:02 +02:00
abcdefg30
f9bc1113b5 Fix the die1 sequence of fremen 2018-07-31 21:00:59 +02:00
Smittytron
df76834a5f Correct typo in DefineGroundCorpseDefault update rule 2018-07-31 20:42:03 +02:00
Curtis Shmyr
de8c5e40c4 Remove creation of irc.log 2018-07-31 20:39:08 +02:00
Smittytron
055041c142 Fix several map tiling errors 2018-07-29 09:23:45 -07:00
Zimmermann Gyula
813e53f823 Fix deathsounds regression. 2018-07-29 09:13:53 -07:00
Smittytron
a44e36cb04 Add hijacker idle sequence 2018-07-29 01:39:18 +02:00
Paul Chote
6ec93bd8cf Add player badges. 2018-07-29 00:30:17 +02:00
Paul Chote
7ec19b82e3 Add in-game tooltips for registered / anonymous players. 2018-07-29 00:30:17 +02:00
Paul Chote
70706ca531 Add lobby tooltips for registered / anonymous players. 2018-07-29 00:30:17 +02:00
Paul Chote
b5a5eecc25 Add login/profile display to the main menu. 2018-07-29 00:30:17 +02:00
Paul Chote
c74159e549 Add player authentication backend. 2018-07-29 00:30:17 +02:00
Paul Chote
0965464148 Add crypto helpers for working with RSA keys. 2018-07-29 00:30:17 +02:00
Paul Chote
630936a211 Adjust lobby tooltip plumbing:
- Pass Client instead of Client ID
- Pass WorldRenderer and OrderManager to util helpers.
2018-07-29 00:30:17 +02:00
Paul Chote
97c03b00f2 Strip the client block down to latency only. 2018-07-29 00:30:17 +02:00
Paul Chote
f08bfae9a0 Count direct children of text fields and buttons for mouseover.
This improves polish when mousing over prefix glyphs.
2018-07-29 00:30:17 +02:00
Paul Chote
df20ae1aec Fix TextFieldWidget margin properties not being cloned. 2018-07-29 00:30:17 +02:00
Paul Chote
9a6fdfa180 Expose setting clipboard text to mod code. 2018-07-29 00:30:17 +02:00
Paul Chote
8347d0afd0 Move TD main menu perf text to the bottom-right corner. 2018-07-29 00:30:17 +02:00
Chris Forbes
51e000599a Convert crushclasses to bitset 2018-07-28 21:28:46 +01:00
Mustafa Alperen Seki
82f6c2b862 Make SpawnActorsOnSell conditional 2018-07-28 21:20:28 +01:00
Mustafa Alperen Seki
ea2794b417 Make EjectOnDeath conditional 2018-07-28 21:20:28 +01:00
reaperrr
0bff9e9119 Make some Attack* methods/classes public
Instead of protected, because some 3rd-party mods rely on these being
public.
2018-07-28 21:35:42 +02:00
reaperrr
b2a069f8ab Add FillTriangle support 2018-07-28 21:35:42 +02:00
Chris Forbes
d4ef841678 Convert masses of HashSet<string> to BitSet<DamageType> 2018-07-28 20:12:42 +01:00
abcdefg30
6d12e84bd9 Add a player action dropdown to d2k 2018-07-28 19:43:19 +01:00
Zimmermann Gyula
51a99cb43c Special-case the player actor on GCOnBotOwner. 2018-07-28 17:59:34 +02:00
abcdefg30
1513068114 Remove wrong idle sequences from medic and mechanic 2018-07-28 16:58:29 +01:00
matjaeck
d33ac0c838 Fix tooltip descriptions for spectators. 2018-07-28 17:49:42 +02:00
Andre Mohren
be2c41d51c Added PlaceBuildingInit. 2018-07-28 17:38:46 +02:00
Mustafa Alperen Seki
34d887ecc3 Update D2k mod for CanUndeploy removal 2018-07-28 16:32:37 +01:00
Mustafa Alperen Seki
5a780577b9 Add Desc() field to GrantConditionOnDeployInfo. 2018-07-28 16:32:37 +01:00
Zimmermann Gyula
a456c234ca Provide appropriate upgrade rule. 2018-07-28 16:32:37 +01:00
Zimmermann Gyula
f07460edd2 Convert GrantConditionOnDeploy to a pausableconditional trait.
Also remove CanUndeploy as pausing achieves the same effect.
2018-07-28 16:32:37 +01:00
Mustafa Alperen Seki
c01bcc61b8 Make D2k Factories don't play ProductionOverlay for Upgrades 2018-07-28 16:17:47 +01:00
Mustafa Alperen Seki
f05fc0cae8 Add WithProductionOverlay>Queues 2018-07-28 16:17:47 +01:00
Paul Chote
e64a966b4f Group update rule display by update path. 2018-07-28 15:12:55 +01:00
Paul Chote
f9230a72f2 Fix NRE in mods that don't immediately show the main menu. 2018-07-27 18:38:30 +02:00
Matthias Mailänder
65776bdeb5 Set Offset for train tracks. 2018-07-26 15:08:32 +01:00
Andre Mohren
a57cfc7d40 Fixed ProductionItem costs calculation. 2018-07-26 14:01:37 +00:00
fusion809
e1b1070bcf Adding wget support to fetch scripts 2018-07-26 14:19:31 +01:00
Andre Mohren
81e1b39bb9 Made PowerManager optional for traits who do not require it. 2018-07-26 14:02:42 +01:00
Chris Forbes
dcf93203ea Get rid of unit pathing delay completely 2018-07-26 13:19:31 +01:00
Zimmermann Gyula
e9c3927b0c Filter Explodes->DeathTypes when Threshold is above 0. 2018-07-26 13:10:50 +01:00
Mustafa Alperen Seki
6073de52ca Add DamageSource to Explodes 2018-07-26 13:04:59 +01:00
reaperrr
d07bd029db Change Parachutable.GroundCorpseSequence default to null
Missions and 3rd-party mods may paradrop vehicles which normally don't need a corpse sequence (because they already have Explodes), so the old infantry-centric internal default can cause more harm than good.
2018-07-26 13:01:09 +01:00
reaperrr
42d5799f4e Parachutable.cs readability improvements 2018-07-26 13:01:09 +01:00
reaperrr
a30727b155 Make disabling parachute corpse sequences easier 2018-07-26 13:01:09 +01:00
Mustafa Alperen Seki
6b1451f7ca Remove GivesBounty>LevelMod 2018-07-26 12:53:33 +01:00
Mustafa Alperen Seki
81deb2b00c Make Multipile GivesBounty traits to work properly 2018-07-26 12:53:33 +01:00
Smittytron
1ffe87b005 Use correct effects for TD anti-air explosions 2018-07-26 12:43:52 +01:00
Mustafa Alperen Seki
c14c7653bc Make Prerequisite Lint Check use ITechTreePrerequisiteInfo 2018-07-26 12:34:26 +01:00
Alfredo Brandau
e33f729682 Fix expectator kick dropdown crash. 2018-07-26 10:52:09 +01:00
Mustafa Alperen Seki
9c61217bc6 Add ability to send a radar ping with lua. 2018-07-26 00:03:45 +01:00
Andre Mohren
b86355cda6 Made MapBuildRadius optional for traits who do not require it. 2018-07-25 22:35:46 +01:00
Paul Chote
2270460c9a Update macOS launcher template to osx-launcher-20180723.
This adds support for the dark appearance on macOS 10.14.
2018-07-23 23:29:43 +02:00
Paul Chote
e8584033f8 Update AppImage dependencies to 20180723 tag.
This switches the build system from CentOS 6 to
Debian 7 to fix issues with the ingame cursors.
2018-07-23 17:23:58 +01:00
BGluth
e5bbe70186 Add myself to AUTHORS 2018-07-23 17:20:26 +01:00
BGluth
a43bdff603 Implemented #15325
- Leaving a game now returns you to the respective menu.
- I think that I covered all of the possibilities (mission, skirmish, multiplayer, map editor, replay).
2018-07-23 17:20:26 +01:00
Paul Chote
d6682faeee Keep a 1px border around trimmed ShpTD data. 2018-07-23 17:02:50 +01:00
Smittytron
b091be6304 Assign grey passenger pips to TD civilians 2018-07-22 15:24:40 +02:00
Smittytron
fe455f17e1 Utilize grey and blue passenger pip colors in RA 2018-07-22 15:24:40 +02:00
reaperrr
c434a38b1f Move 20171014-20180218 update rules to subfolder
Also synced order of appearance with order they're applied in when running the full update path.
2018-07-22 13:54:21 +01:00
reaperrr
4c55e820d6 Add beta warning to legacy update path 2018-07-22 13:54:21 +01:00
abcdefg30
27765f6448 Add all remaining update rules 2018-07-22 13:54:21 +01:00
abcdefg30
24f9ff0ac2 Add a 'ReplaceRequiresPower' update rule 2018-07-22 13:54:21 +01:00
abcdefg30
6c8a943dc9 Add four more update rules 2018-07-22 13:54:21 +01:00
reaperrr
94ad93a301 Add ScaleSupportPowerSecondsToTicks 2018-07-22 13:54:21 +01:00
abcdefg30
ab2fe92dfb Add ScaleDefaultHealth and subclass update rules 2018-07-22 13:54:21 +01:00
abcdefg30
af1a2429b1 Add five more update rules 2018-07-22 13:54:21 +01:00
Paul Chote
01684bc329 Add two more update rules 2018-07-22 13:54:21 +01:00
Paul Chote
fd49e487ec Fix MCV deploy erasing Iron Curtain history. 2018-07-22 13:45:37 +01:00
Paul Chote
d5399aaf6b Fix MCV deploy erasing Chronoshift history.
If the MCV is deployed as a Construction Yard when
the timer expires the structure will take a 50%
damage hit from a chrono-vortex.

If the MCV is in the process of (un)deploying it
will be returned in MCV form.
2018-07-22 13:45:37 +01:00
Paul Chote
8f215a0219 Persist Chronoshift properties across transform. 2018-07-22 13:45:37 +01:00
Paul Chote
b93d782688 Add ChronoshiftDurationInit.
Fixes time remaining bar not displaying if selection
bars are enabled on killed actors.
2018-07-22 13:45:37 +01:00
Paul Chote
01c3c14a4c Add ITransformActorInitModifier.
Remove hardcoded Cargo reference from Transform.
2018-07-22 13:45:37 +01:00
reaperrr
496155ff0e Remove facing check from WithVoxelWalkerBody
`Mobile` now supports considering turning as `IsMoving`, so this check is no longer needed.
2018-07-19 22:09:43 +02:00
reaperrr
2d47f61409 Make TS mechs display walk anim while turning
This matches the original, and turning without moving their legs looked silly either way.
2018-07-19 22:09:43 +02:00
reaperrr
6984c0ec10 Add AlwaysConsiderTurnAsMove plumbing to Mobile
Can be used to make walker units like the TS mechs display move animations while turning on the spot.
2018-07-19 22:09:43 +02:00
Smittytron
755cc40459 Fix TD crop fields 2018-07-19 19:10:57 +00:00
Mustafa Alperen Seki
a65a5d17e4 Add CashTricklerMultiplier 2018-07-19 18:49:35 +00:00
Smittytron
530b7af9c5 Use correct CustomSellValue for RA Ore Refinery 2018-07-19 18:41:26 +00:00
Paul Chote
128c65ff71 Tidy font definitions
Order by size/weight and fix key-value spacing.
2018-07-12 09:28:38 +00:00
teinarss
25a8de8a47 Fixing pathfinding calc when the distance was to small for the bidirectional logic to work. 2018-07-12 10:06:55 +02:00
teinarss
1c0aa24640 Added a player action dropdown.
Adds options for:
 - handling kick
 - transferring admin
 - move to spectator
2018-07-05 23:22:09 +01:00
teinarss
0c1b11ed4f Added Dedicated to GlobalSettings 2018-07-05 23:22:09 +01:00
teinarss
a156a31cf5 Added text aligment to button
Cloning LeftMargin and RightMargin

Refactored the calculations for Text position in ButtonWidget
2018-07-05 23:22:09 +01:00
teinarss
23155c039d Extract LobbyCommand command logic to their own methods. 2018-07-05 23:22:09 +01:00
abcdefg30
2471b07e55 Fix the mode documentation in gtk-dialog.py 2018-07-05 22:28:10 +01:00
Oliver Brakmann
3e29ef0bd6 Avoid sending HTTP requests to the FetchNews URL when FetchNews is disabled
Also disables the 'Send SysInfo' settings checkbox when 'Fetch News' is disabled as well.
2018-07-05 11:22:44 +02:00
Smittytron
d21b959bf0 Fix TD RippedApartDeath 2018-07-04 23:01:47 +02:00
Smittytron
01d10f392d Fix RA death animations 2018-07-04 23:01:47 +02:00
Mustafa Alperen Seki
052bfcd023 Update some D2K reveal ranges to match original. 2018-07-04 20:11:55 +02:00
Paul Chote
01a613a057 Show a python GTK3 dialog if zenity is missing. 2018-07-04 18:58:24 +01:00
Paul Chote
29442cec13 Fix an error flagged by shellcheck. 2018-07-04 18:46:09 +01:00
Paul Chote
6adff732eb Include a wiki link in the error dialog. 2018-07-04 18:46:09 +01:00
Paul Chote
fbc5fde646 Prompt mono installation on compatible systems. 2018-07-04 18:46:09 +01:00
Mustafa Alperen Seki
51c207dd28 Add ability to use IonCannonPower via lua. 2018-07-04 16:41:27 +02:00
Mustafa Alperen Seki
2387e49ee7 Add ability to use NukePower via lua. 2018-07-04 16:41:27 +02:00
reaperrr
f31e5d17b3 Fix RA refinery selection bounds offset
Selection bounds were too low on the vertical axis.
2018-07-01 19:57:37 +01:00
reaperrr
d85f96bc98 Give all RA structures fixed select/deco bounds 2018-07-01 19:57:37 +01:00
reaperrr
f0166207a7 Fix fake RA service depot bounds and footprint 2018-07-01 19:57:37 +01:00
reaperrr
be6ca960c8 Tweak TD refinery selection bounds
The old vertical offset made the bounds include the entire concrete 'bib', but not the processor tower in the back.
2018-07-01 19:57:37 +01:00
reaperrr
291af67b8c Ensure select/deco bounds of TD buildings are consistent
Regardless of current frame's bounds.
2018-07-01 19:57:37 +01:00
reaperrr
1ae5a989bf Ensure selectable bounds of TD landing craft are consistent
Regardless of current frame's bounds.
2018-07-01 19:57:37 +01:00
reaperrr
9b41416020 Ensure interactable/deco bounds of TD walls are consistent
Regardless of current frame's bounds.
2018-07-01 19:57:37 +01:00
reaperrr
4c239d4ebc Set Mobile.IsMoving to "true" if queueing a turn that takes only a single tick
At the end of L-turns, actors often end up with an internal facing not 100% matching the direction of the next cell on their path.
As a result, if they haven't reached their destination yet, Move queues a quick Turn as ChildActivity, which previously was not considered as IsMoving.
However, we don't want those mini-turns to interrupt move animations, so we now consider them a move as well. Additionally, to avoid any issues, we make these mini-turns non-interruptible, just like the MovePart activities already are.
2018-07-01 15:33:30 +01:00
reaperrr
e167d1f848 Add plumbing to make Turn uninterruptible 2018-07-01 15:33:30 +01:00
reaperrr
c93333a816 Cache IFacing in Turn activity
Instead of looking it up every tick.
2018-07-01 15:33:30 +01:00
reaperrr
96377a99c4 Fix losing a tick when next Move.ChildActivity is Turn
While the first tick of the MoveFirstHalf child would run at the parent Move tick (see 2nd-to-last line in Move.Tick), this was not the case for Turn.
As a result, this Move tick would get wasted if a Turn was necessary, which at least contibuted to that visible jerk at the end of each L-turn (actors usually don't have the exact facing needed for the next move at the end of an L-turn).
2018-07-01 15:33:30 +01:00
reaperrr
1c78073808 Lint check for distinct sprite body names 2018-07-01 13:16:07 +02:00
reaperrr
d060f885e8 Fix various Mods.Cnc animation traits not supporting actors having multiple sprite bodies 2018-07-01 13:16:07 +02:00
reaperrr
9d24c40f92 Fix various Mods.Common animation traits not supporting actors having multiple sprite bodies 2018-07-01 13:16:07 +02:00
reaperrr
0d0d2e0ae3 Play WithAcceptDeliveredCashAnimation only on the assigned WithSpriteBody 2018-07-01 13:16:07 +02:00
reaperrr
f85f2cd104 Add LaunchEffect support to LaserZap
Can act as replacement for WithMuzzleOverlay.
2018-07-01 12:19:32 +02:00
reaperrr
384aaf14b5 Added LaunchEffect effect 2018-07-01 12:19:32 +02:00
reaperrr
145b8c87c5 Make LaserZap source point follow source actor muzzle
For moving actors, it looks better when the source point of the beam follows the source actor.
2018-07-01 12:19:32 +02:00
reaperrr
0fafaf1b09 Add DamageDuration and DamageInterval to LaserZap 2018-07-01 12:19:32 +02:00
Paul Chote
f4d3ccc301 Fix newlines in misc other files. 2018-07-01 11:08:32 +02:00
Paul Chote
670e153372 Remove byte order marks from csproj files. 2018-07-01 11:08:32 +02:00
Paul Chote
1ac13de4b2 Remove byte order marks from C# files. 2018-07-01 11:08:32 +02:00
Paul Chote
8c0f4fde81 Fix newlines in C# files. 2018-07-01 11:08:32 +02:00
Paul Chote
6b6167d37c Use the default sprite sequence for automatic mouse bounds. 2018-07-01 01:20:55 +02:00
Paul Chote
707514572b Fix crlfs in CheckUnknown*Fields lint tests. 2018-07-01 00:25:56 +02:00
Paul Chote
ca5af0755d Fix line endings in project files. 2018-06-30 23:17:20 +01:00
Smittytron
8fa3ab74c7 Remove redundant overrides from RA 2018-06-30 23:48:31 +02:00
Smittytron
6c6ed1cfbf Remove redundant TD overrides 2018-06-30 23:48:31 +02:00
Paul Chote
39a3bc4b78 Squash warnings in Allies 03a and b. 2018-06-30 17:12:19 +01:00
Paul Chote
51a2ca8253 Add CheckUnknownWeaponFields lint check. 2018-06-30 17:12:19 +01:00
Paul Chote
0a5016c803 Add CheckUnknownTraitFields lint check. 2018-06-30 17:12:19 +01:00
Paul Chote
d46278ab0e Add ModData parameter to ILintMapPass. 2018-06-30 17:12:19 +01:00
Zimmermann Gyula
f50a891d18 Explicitly specify line-endings of source files in gitattributes. 2018-06-30 16:54:25 +01:00
Paul Chote
8ec3df7550 Fix recently introduced bad line endings. 2018-06-30 16:54:25 +01:00
Zimmermann Gyula
b892336285 Update default mods. 2018-06-30 16:31:39 +01:00
Zimmermann Gyula
86bfd4700f Implement DeathTypes support to OwnerLostAction. 2018-06-30 16:31:39 +01:00
SoScared
fa29a4b991 simplify ra buildtime yaml and game rules for t3 units 2018-06-28 08:22:39 +02:00
Paul Chote
1b63d65ad2 Add an AppImage workaround to import SSL certs. 2018-06-26 15:59:14 +02:00
Paul Chote
0875766bcc Use MoveAndRenameNode in MoveHackyAISupportPowerDecisions. 2018-06-26 15:47:39 +02:00
RoosterDragon
bb536ee4fc Run graphics rendering on a dedicated thread.
The main game thread can offload some of the CPU cost to the rendering thread, freeing up its time to run more logic and render ticks.
2018-06-22 18:40:16 +01:00
Paul Chote
ea068a36f7 Allow window size/scale properties to be accessed from other threads. 2018-06-22 18:40:16 +01:00
Zimmermann Gyula
72eb5543c2 Rename a server-affecting artifact within SeparateTeamSpawns. 2018-06-22 17:28:20 +01:00
Zimmermann Gyula
9e3d210ee0 Change CRLF line-endings to LF in Harvester.cs. 2018-06-20 12:34:52 +02:00
reaperrr
29d71c9a00 Fix TS component tower power-down-ability 2018-06-18 15:24:29 +02:00
Smittytron
3af6a5d4ed Fix Shellmap Chinook wobble 2018-06-17 16:27:16 +02:00
Zimmermann Gyula
d9786dcf72 Normalize the line-endings on RepairableBuilding. 2018-06-17 16:13:16 +02:00
Ivaylo Draganov
3a377a572c Add "Restart" button for multiplayer replays 2018-06-16 15:53:43 +02:00
Andre Mohren
fc82c24e1f FreeActor now supports to be triggered by condition. 2018-06-16 14:47:45 +02:00
reaperrr
3a60dcd4a1 Use new update util extensions to simplify some update rules 2018-06-16 00:00:13 +02:00
reaperrr
f6278a1f41 Add some more useful extensions to UpdateUtils
In many situations, these will save up to 3-4 lines, because quite often this will be enough to avoid curly brackets, "if"s or one-by-on renamings.
2018-06-16 00:00:13 +02:00
reaperrr
3c9891e729 Refactor some update util extensions
Using arguments instead of separate overloads, plus better support for
automatically handling trait/property removals ('-' prefix).
2018-06-16 00:00:13 +02:00
reaperrr
4a081e2111 Replace spaces with tabs in RenameEmitInfantryOnSell 2018-06-16 00:00:13 +02:00
Paul Chote
4d664d4f74 Report custom map rule errors in the lint output. 2018-06-15 23:39:48 +02:00
reaperrr
15e78332a3 Fix Ant sharing cell 2018-06-15 23:37:13 +02:00
Paul Chote
cce9b06a40 Move SupportPowerDecisions to a single parent node.
This is required before we can force all trait
properties to match a TraitInfo-defined field.
2018-06-15 17:24:00 +02:00
Jason Zmuda
f82674cfef Removed 'Crush' per issue #15246 2018-06-14 15:41:31 +02:00
Paul Chote
75f78f8d27 Remove bogus undefined/unused trait property definitions.
None of these exist in current bleed, so this
won't change any in-game behaviour.
2018-06-14 13:40:18 +02:00
Paul Chote
6435869846 Fix RocketLauncher projectile inheritance.
This projectile inherits the Missile template,
but then overrides it with ballistic behaviour.
This prevents all of the Missile properties that
aren't used by Bullet from being inherited.
2018-06-14 13:40:18 +02:00
Paul Chote
6e45f7633a Run SplitAimAnimations update rule on TS. 2018-06-14 13:40:18 +02:00
Paul Chote
ddc47da11c Restore the missing "full" harvester husk. 2018-06-14 13:40:18 +02:00
Paul Chote
9c978ddc32 Fix DamageTypes definitions for forest fires.
In practice this doesn't actually change anything
because TargetType restrictions already guarantee
that only Incideniary weapons can damage them.
2018-06-14 13:40:18 +02:00
Paul Chote
e1717487f6 Fix editor category for RA boxes01. 2018-06-14 13:40:18 +02:00
Paul Chote
7461657394 Fix Death Hand missile launch audio notification. 2018-06-14 13:40:18 +02:00
Paul Chote
0e34e4f310 Fix HQ tooltip in nod03b. 2018-06-14 13:40:18 +02:00
Vasya N
afcb5148bc fix capturable buildings (TSun) 2018-06-14 12:54:19 +02:00
Paul Chote
9ff177359b Split IGraphicsContext from IPlatformWindow. 2018-06-13 18:45:21 +01:00
Paul Chote
ab14a86d39 Rename Renderer.Device to Renderer.Window. 2018-06-13 18:45:21 +01:00
Paul Chote
28c8089bc7 Rename IGraphicsDevice to IPlatformWindow. 2018-06-13 18:45:21 +01:00
Paul Chote
72c0e344ad Extract SDL2HardwareCursor to its own file. 2018-06-13 18:45:21 +01:00
Vasya N
0fc466daee fix hijacker build limit 2018-06-12 14:00:12 +02:00
Paul Chote
e4dd78c5cd Add a tab to the credits panel for mod-specific text.
Enabled by adding a ModCredits block to mod.yaml.
2018-06-11 22:07:20 +02:00
Lars Beckers
314169f2b0 Fix production queue numbers increasing needlessly. 2018-06-11 08:56:08 +01:00
Paul Chote
f7166c3800 Add a FPS counter to the perf debug text. 2018-06-09 21:58:26 +02:00
Paul Chote
8461a82577 Remove requirement for depth sprites to share color sheet. 2018-06-04 23:33:57 +02:00
Paul Chote
2f2a7724d5 Rename shp.(frag|vert) to combined.(frag|vert). 2018-06-04 23:33:57 +02:00
Paul Chote
bfcbe8c004 Improve batching by binding up to 8 simultaneous textures. 2018-06-04 23:33:57 +02:00
Paul Chote
131496ebf8 Merge RGBA sprite rendering into SpriteRenderer.
Renderer.RgbaSpriteRenderer is kept as a thin
wrapper to maintain compatibility with consumer
code.
2018-06-04 23:33:57 +02:00
Paul Chote
ba38878933 Add TextureChannel.RGBA for RBGA sprites. 2018-06-04 23:33:57 +02:00
Paul Chote
c307b3e291 Encode channel attributes in a more sensible way. 2018-06-04 23:33:57 +02:00
Paul Chote
382f4c3af5 Remove the AddEditorPlayer update rule. 2018-06-04 23:15:56 +02:00
Paul Chote
df95b90de2 Remove CheckDeathTypes lint test.
This causes false positive errors when mods use
SpawnActorOnDeath to implement special-case death
effects.
2018-06-04 23:12:07 +02:00
Paul Chote
6c338eb06c Revert "Run graphics rendering on a dedicated thread."
This reverts commit b9be52c542.
2018-06-04 23:04:35 +02:00
Paul Chote
afc5a54ab5 Remove unused gate sequences.
The artwork no longer exists, so these cause
errors to be written to debug.log.
2018-06-03 18:21:23 +02:00
Paul Chote
d4592c13d8 Remove Training Camp minigame map. 2018-06-03 17:16:53 +01:00
Paul Chote
5b47aa4a9e Remove unused map options from minigame maps. 2018-06-03 12:27:20 +01:00
Voidwalker
398ae75525 Added fully random spawn position option. 2018-06-03 12:27:20 +01:00
reaperrr
1408fb74b2 Use Armament.ReloadingCondition on RA V2
The new property makes the AmmoPool work-around obsolete.
2018-06-03 12:23:54 +01:00
reaperrr
e4738ce722 Update rule for AimAnimation splits and ReloadPrefix removal 2018-06-03 12:23:54 +01:00
reaperrr
2136d6dc4a Split and refactor aim animation from WithAttackAnimation
Splitting it from the attack animation, triggering start and end of the aiming animation via interface, as well as removing ReloadPrefix (in favor of switching sprite bodies via condition when reloading) allows us to drop updating via ITick, which in turn will make it much easier to ultimately make this trait compatible with other animation traits, once the priority system lands.
2018-06-03 12:23:54 +01:00
reaperrr
7d4956e309 Refactor WithTurretAimAnimation using INotifyAiming
Triggering start and end of the aiming animation via interface, as well as removing ReloadPrefix (in favor of switching sprite bodies via condition when reloading), allows us to drop updating via ITick, which in turn will make it much easier to ultimately make this trait compatible with other animation traits, once the priority system lands.
2018-06-03 12:23:54 +01:00
reaperrr
a784081973 Add ReloadingCondition to Armament
Allows to grant condition while reloading.
2018-06-03 12:23:54 +01:00
reaperrr
bd38fe4926 Add INotifyAiming interface
And trigger notifications from Attack* traits.
2018-06-03 12:23:54 +01:00
reaperrr
4898873617 Locomotor update rule typo fix 2018-06-03 12:15:11 +01:00
Paul Chote
a61454f409 Fix experience/hospital indicator overlap in TS. 2018-06-02 18:12:08 +02:00
Paul Chote
74971cfbb1 Add hospital heal indicators to RA. 2018-06-02 18:12:08 +02:00
Paul Chote
6359d32946 Fix overlapping veterancy/hospital/hazmat indicators in TD.
This also changes the hazmat indicator to only be visible when on
tiberium, and the hospital indicator to blink while active and only
be visible when the infantry is damaged.
2018-06-02 18:12:08 +02:00
Paul Chote
eccfac7840 Add blink parameters to WithDecoration. 2018-06-02 18:12:08 +02:00
Paul Chote
82d3829c87 Fix overlapping repair / powerdown indicators. 2018-06-02 18:12:08 +02:00
Paul Chote
bb34d4de49 Add conditional offset support to WithDecoration. 2018-06-02 18:12:08 +02:00
Paul Chote
2ef6f7c0cc Replace repair indicator effect with a Decoration subclass. 2018-06-02 18:12:08 +02:00
Paul Chote
218914458f Document RepairableBuilding fields. 2018-06-02 18:12:08 +02:00
lawando
7dd64445fc Rename EmitInfantryOnSell and remove default actor type. 2018-06-02 15:37:35 +02:00
Paul Chote
3d79541148 Remove unused usings and add end of file newline. 2018-06-02 15:30:59 +02:00
Paul Chote
55d3040a0e Blink the color picker palette tab when the Store button is pressed.
This provides some visual feedback that something
has happened on the hidden tab.
2018-06-02 15:30:59 +02:00
Jason Zmuda
2cf3c4873d Update EmitInfantryOnSell.cs 2018-05-31 20:48:40 +02:00
Paul Chote
ebf3ec0e90 Add some basic safeguards around RenderPlayer.set. 2018-05-31 18:54:07 +02:00
Paul Chote
3a1857886a Add support for displaying master server warnings. 2018-05-31 17:45:58 +02:00
Paul Chote
de4199048f Add additional metadata to the default mods. 2018-05-31 17:45:58 +02:00
Paul Chote
c425650b7d Truncate mod-version labels to the correct width. 2018-05-31 17:45:58 +02:00
Paul Chote
6ef802b929 Send mod title, website, and an icon URL to the master server.
Prefer the title returned by the master server in the games list.
2018-05-31 17:45:58 +02:00
Paul Chote
10aaa8eea8 Cancel Rearm activity when the host goes away.
This also ensures that the first reload tick always
takes the correct amount of time.
2018-05-30 18:17:37 +02:00
Paul Chote
ba8eac0e38 Remove deprecated Order.TargetActor and Target.FromOrder. 2018-05-30 18:06:59 +02:00
Paul Chote
768265bbd2 Unify TargetFlash handling around Targets. 2018-05-30 18:06:59 +02:00
Paul Chote
d0be594609 Remove order.TargetActor from RepairsBridges. 2018-05-30 18:06:59 +02:00
Paul Chote
eb01fe6b26 Fix missing voice response when ordering a minelayer to reload. 2018-05-30 18:06:59 +02:00
Paul Chote
6528edecb1 Fix order queuing on Repairable. 2018-05-30 18:06:59 +02:00
Paul Chote
e5701ecb20 Remove order.TargetActor from Repairable. 2018-05-30 18:06:59 +02:00
Paul Chote
2e2f982e41 Fix order queuing on Passenger. 2018-05-30 18:06:59 +02:00
Paul Chote
c78ee66d92 Remove order.TargetActor from Passenger. 2018-05-30 18:06:59 +02:00
Paul Chote
fde531b808 Fix order queuing on RepairableNear. 2018-05-30 18:06:59 +02:00
Paul Chote
148b5cad2c Remove order.TargetActor from RepairableNear. 2018-05-30 18:06:59 +02:00
Paul Chote
ae056e969f Remove order.TargetActor from Harvester. 2018-05-30 18:06:59 +02:00
Paul Chote
883834f1c3 Remove order.TargetActor from Aircraft. 2018-05-30 18:06:59 +02:00
Paul Chote
4a7bb39fbe Remove order.TargetActor from Infiltrates, EngineerRepair, ExternalCaptures.
These cases already checked order.Target.Type so these are simple swaps.
2018-05-30 18:06:59 +02:00
Paul Chote
6e400c5d60 Don't trigger LobbyInfoSynced on ping update.
This interface is only used for updating the master
server advertisement, which doesn't use the player
pings at all.  Removing this should reduce the
master server traffic by a factor of several tens.
2018-05-30 18:05:32 +02:00
RoosterDragon
b96e062a0d Run graphics rendering on a dedicated thread.
The main game thread can offload some of the CPU cost to the rendering thread, freeing up its time to run more logic and render ticks.
2018-05-29 23:05:39 +01:00
RoosterDragon
8ec90525e3 Change Shader.Render to Shader.PrepareRender.
Instead of running the shader operation as an action, just run it after the shader is prepared.
2018-05-29 23:05:39 +01:00
RoosterDragon
95ac1aa5b2 Avoid redundant property sets in WorldRenderer.Draw. 2018-05-29 23:05:39 +01:00
RoosterDragon
296c732525 Avoid redundant implicit float3 conversions. 2018-05-29 23:05:39 +01:00
RoosterDragon
90981e5bda Avoid redundant property reads in Renderer.SetViewportParams 2018-05-29 23:05:39 +01:00
Paul Chote
3082df7dfd Disable kill bounties by default in campaigns, skirmish, and MP. 2018-05-28 19:05:34 +02:00
AoAGeneral
31dcb825b7 Update TD balancing:
Apache damage vs infantry at prone increased from 50 percent to 80 percent.

  Apache damage was cut in half making them less effective versus infantry. Giving them an extra boost damage wise versus prone is enough then going with a universal damage boost.

MCV Price from 4000 to 3500.

  Some say they want 3000 but im still paranoid of the epidemics that have happened in the past with 1v1 and team games. Needs more team game tests if they want 3000.

Repair Pad decrease power from -30 to -20.

 Power consumption is a little high. Specifically if they want to build extras.

APC Price from 550 to 600.

APC HP from 21500 to 19000.

APC turn speed from 8 to 5.

APC build duration from 900 to 938.

APC AA range from 7 to 6.

APC reduce vision range from 7c0 to 6c0.

APC projectile speed reduced from 2c0 to 900.

  See notes below.

Power Plant buff HP from 50,000 to 55,000

  Makes power plant sniping a little tougher. But still effective to take out.

Change power structures (Airstrip/Factory and Refinery to 40 power)

  Important change. This allows more diverse builds to happen such as now able to build refinery > barracks > factory. This combo helps easy defends with quick vehicle herasses.

MRLS Price reduction from 1000 to 900.

  Allows an easier method to build on the field. A unit that is often times killed by airstrikes allows more forgiveness when on the field.

Light vehicle husks HP reduce to 2000. (reduce timer on field wreckage.)

  Prevents early on refinery blocks and other pathing unit issues.

Oil Derrick reduce HP from 100,000 to 80,000

  Oil Derricks were a little to strong. Easily can be killed now.

Change power plant build duration from 12 seconds to 8 seconds. (Low power build duration from 24 seconds to 16 seconds.) Note: Does not include Adv. Power plant

  Due to the struggle of low power this enables players to build regular power plants to help get back up quickly. This however, does not apply to Adv. power plants. The outcome is then scattered extra power plants rather then Adv. power due to the player being on low power.

Change engineer capture threshold from 50 to 55 and added a lower selection priority.

  Fixes the structures from being fixed and preventing the second engineer from getting canceled out or being wasted on damaging the structure again.

NOTES:

I have mentioned that I disagree on the above APC changes. The reasons I conclude may happen is buffing the bikes with a lack of counter. This may result in games where infantry are now used to help counter against buggy/bike play rather then an APC/infantry play or APC/hummer play. If and when players speak about bikes being OP please look back at the changes that happened in the past.
2018-05-28 11:13:09 +01:00
Mustafa Alperen Seki
4bf606b3ca Leave walls as neutral owned after their owner defeated 2018-05-28 10:42:45 +01:00
Mustafa Alperen Seki
497211c328 Make tech buildings turn to neutral when owner is defeated. 2018-05-28 10:42:45 +01:00
Mustafa Alperen Seki
1b451a34ca Spawn Aircraft Husks owned by owner of the aircraft
Rather than neutral with EffectiveOwner of aircraft's owner
2018-05-28 10:42:45 +01:00
Mustafa Alperen Seki
cdbc2d2613 Update default mods for OwnerLostAction 2018-05-28 10:42:45 +01:00
Mustafa Alperen Seki
367a7f617c Added OwnerLostAction
Allows customisation of what will happen to an actor when its owner
loses.
2018-05-28 10:42:45 +01:00
teinarss
0d23070c8e Updated HpPerStep for vehicles in TD 2018-05-24 09:13:56 +02:00
abcdefg30
58dac1ba3f Fix ProductionQueue audio notifications in TS
Overwrote "BlockedAudio" with "" as the default "NoBuild" notification was removed.
2018-05-24 08:51:55 +02:00
Paul Chote
a329711011 Render lines using SpriteRenderer without breaking the batch. 2018-05-23 23:28:22 +02:00
reaperrr
9e95cd5331 Considerably raise Locomotor WaitAverage and WaitSpread
This considerably reduces frequency of repathing attempts without too much of an impact of in-game repathing speed, since most of the time the blocking actor doesn't move out of the way that fast anyway.
2018-05-22 13:10:43 +02:00
reaperrr
e2979658a2 Extract AI support power handling to AISupportPowerManager 2018-05-21 16:41:53 +02:00
Paul Chote
3c1b129158 Tweak the project README.
- Remove BountySource references (deprecated for a long time).
- Add a comment about the Hacking page being very outdated.
- Add a link to the Mod SDK.
2018-05-21 02:57:03 +02:00
abcdefg30
3a74e880c5 Add 'update.log' to .gitignore 2018-05-20 23:08:08 +02:00
Paul Chote
be6fd1c7c7 Copy updater messages to an update.log file in the working directory. 2018-05-20 23:08:08 +02:00
abcdefg30
e83f5a9d59 Replace "\r\n" by "\n" in unit tests 2018-05-20 22:44:34 +02:00
Paul Chote
ba9d1c3182 Improve MiniYaml nunit tests:
- Fixes incorrectly used variable.
- Adds additional tests for node positions.
2018-05-20 22:44:34 +02:00
reaperrr
8e11f0cf4e Add Oasis Trouble to TS 2018-05-20 21:02:30 +01:00
reaperrr
295d665db1 Add The Pit to TS 2018-05-20 21:02:30 +01:00
reaperrr
fa9dd45e30 Add Tournament Rift to TS 2018-05-20 21:02:30 +01:00
reaperrr
92f720d121 Add Way to Uganda to TS 2018-05-20 21:02:30 +01:00
lawando
32c7869718 Add stance filter to TooltipDescription; Add YAML descriptions. 2018-05-20 20:04:59 +02:00
Zimmermann Gyula
c4b5ec5241 Shift temporary owner-change logic from D2k to Common. 2018-05-20 19:44:35 +02:00
Smittytron
38f415255b Make shellmap bridges unkillable 2018-05-20 19:35:39 +02:00
Smittytron
847d2fd106 Add destructable desert bridges 2018-05-20 19:35:39 +02:00
Paul Chote
a9fa9ee741 Fix NRE when updating actors with inline comments. 2018-05-20 19:16:47 +02:00
Paul Chote
dbf6937062 Trim empty space around edges of Shp(TD) frames.
This significantly cuts down the amount of texture
space allocated in VRAM.
2018-05-20 14:12:11 +02:00
Paul Chote
178b6b658d Remove broken DEV_VERSION warning.
This (before it was broken) was hardcoding upstream policy-specific
conventions into the core engine.
2018-05-20 13:55:10 +02:00
Paul Chote
9073249fe4 Fix player connection notifications.
New player notifications are now never reported to the joining player,
and always reported in the dedicated server output.
2018-05-20 13:55:10 +02:00
Paul Chote
c77051790a Fix spurious "This isn't a server order" logging on player disconnect. 2018-05-20 12:35:58 +02:00
teinarss
dcc11c7a41 Added HpPerStep to Repairable for enable repair speed to be changed per unit. 2018-05-14 19:56:35 +02:00
Smittytron
c5e36636ae Fix Nod Laser Turret disabled on lowpower 2018-05-12 17:47:13 +02:00
Smittytron
d154349a29 Fix power down speech notification 2018-05-12 17:47:13 +02:00
Paul Chote
6fdb25b48f Fix yaml formatting. 2018-05-12 16:42:54 +02:00
Paul Chote
82e2595beb Enable comment and whitespace parsing where it is useful. 2018-05-12 16:42:54 +02:00
Paul Chote
df31690332 Extend MiniYaml parser with new features:
- Add support for escaping '#' inside values
- Add support for escaping leading and trailing whitespace

And when discardCommentsAndWhitespace is set to false:
- Add proper support for comments
- Persist empty lines

Whitespace and comment support requires an explicit opt-in because
they produce MiniYamlNodes with null keys.  Supporting these through
the entire game engine would require changing all yaml enumerations
to explicitly check and account for these keys with no benefit.

Comments and whitespace are now treated as real nodes during parsing,
which means that the yaml parser will throw errors if they have
incorrect indentation, even if these nodes will be discarded.
2018-05-12 16:42:54 +02:00
Paul Chote
7a41b3aa89 Fix incorrect yaml indents in the default mods. 2018-05-12 16:42:54 +02:00
reaperrr
c30970975a Fix TS GDI APC leaving water trails while on high bridges 2018-05-10 20:57:01 +02:00
Michael Silber
b199f45f04 Account for custom terrain layers in GrantConditionOnTerrain. 2018-05-10 20:57:01 +02:00
Paul Chote
579cc090a7 Suppress 0-cash ticks on CashTricker and GivesCashOnCapture. 2018-05-07 19:47:41 +02:00
Paul Chote
0eeb38a310 Show negative bounty cash ticks. 2018-05-07 19:47:41 +02:00
Paul Chote
c65d6d1484 Suppress negative cash crate action if the collector has no cash. 2018-05-07 19:47:41 +02:00
GSonderling
bf4dbd9b80 Added checks to make sure cash can't be < 0. 2018-05-07 19:47:41 +02:00
Paul Chote
b8fd4abc4a Fix NRE in Guard when the target actor is dead. 2018-05-07 19:41:13 +02:00
reaperrr
ff8f147955 Some Mobile and Harvester clean-ups
Made Harvester interface implementations explicit.
Made Mobile internal VisualMove activity private.
2018-05-07 19:40:07 +02:00
reaperrr
545ca5da61 Made some interface implementations in Mobile explicit 2018-05-07 19:40:07 +02:00
reaperrr
98289d8573 Reorganized Mobile.cs to be more readable and structured
Implicit interface members, explicit interface members, local method etc. were happily scattered all over the place.
We can't explicitly implement most IMove/IPositionable interface members without some large rewrite,
so we should at least organize the file in a way that makes it less of a pain to tell which parts belong to which interface.
2018-05-07 19:40:07 +02:00
reaperrr
45ee4ad4cf Move IOccupySpace interface right above IPositionable in TraitsInterfaces 2018-05-07 19:40:07 +02:00
reaperrr
030902f691 Style fixes to some code comments in Mobile 2018-05-07 19:40:07 +02:00
Mustafa Alperen Seki
6c5c4a129f Add CargoCondition(s) to Passenger 2018-05-06 20:09:39 +01:00
Paul Chote
3febae1644 Fix exception in DefaultSpriteSequence.GetSprite. 2018-05-06 17:32:17 +02:00
abcdefg30
7ae6326f2a Fix Repairable not accounting for multiple ICallForTransport traits 2018-05-06 16:31:21 +01:00
abcdefg30
c6fee041b1 Add an update rule adding ShakeOnDeath to bridges 2018-05-06 04:51:03 +02:00
abcdefg30
917fd2103f Use ShakeOnDeath instead of the hardcoded shaking for bridges 2018-05-06 04:51:03 +02:00
abcdefg30
b89e6211b2 Add an update rules for the ShakeOnDeath fix 2018-05-06 04:51:03 +02:00
abcdefg30
e7b060c1be Fix ShakeOnDeath using intensity as duration 2018-05-06 04:51:03 +02:00
Paul Chote
91f22c40bd Add kdialog support for KDE. 2018-05-05 22:34:27 +02:00
Paul Chote
b78e9ee89a Extract error messages to a variable to reduce duplication. 2018-05-05 22:34:27 +02:00
Paul Chote
562cf2ad44 Suppress GTK transient parent warning. 2018-05-05 22:34:27 +02:00
Paul Chote
c1a4e66b29 Adjust zenity crash dialog.
This removes the "View FAQ" button, which does not work in the AppImage
enivronment.  It also replaces the inconsistent question mark icon with
a more appropriate stop symbol, and makes the wording consistent across
the zenity, terminal, and native macOS dialogs.
2018-05-05 22:34:27 +02:00
Paul Chote
6397e1443f Add AppImage packaging for Linux. 2018-05-05 22:34:27 +02:00
Paul Chote
c6c431cd95 Rework icon installation. 2018-05-05 22:34:27 +02:00
Paul Chote
6e2abdb687 Fix appdata uninstallation. 2018-05-05 22:34:27 +02:00
Paul Chote
f65188af1c Polish crash dialog code and UI. 2018-05-05 22:34:27 +02:00
Paul Chote
3ce00065a7 Standardize on {MODID} in template files. 2018-05-05 22:34:27 +02:00
Paul Chote
a8fb90d97c Simplify mime type handling. 2018-05-05 22:34:27 +02:00
Paul Chote
0586dabd7e Remove .deb package generation. 2018-05-05 22:34:27 +02:00
Smittytron
b585f46f91 RA Balance changes April 2018 2018-05-05 21:24:45 +01:00
KOYK
36981e90c4 Adds parachute animation to E1,E2,E3,E4,E6,SHOK
Uses conditions without changing the art file.
2018-05-05 01:12:58 +02:00
abcdefg30
6b10895c50 Use the new functions in already existing rules 2018-05-05 00:25:29 +02:00
abcdefg30
9a8e50e82f Add a RemoveNode(MiniYamlNode) method to UpdateUtils 2018-05-05 00:25:29 +02:00
abcdefg30
ae9371f627 Add a ReplaceValue method to UpdateUtils 2018-05-05 00:25:29 +02:00
abcdefg30
399692341d Add a new AddNode(MiniYamlNode) overload to UpdateUtils 2018-05-05 00:25:29 +02:00
Paul Chote
4750188e7b Enable type filtering where appropriate. 2018-05-05 00:15:06 +02:00
Paul Chote
59c2a9e4da Add a Type (= General, Filename, Integer) to TextFieldWidget. 2018-05-05 00:15:06 +02:00
abcdefg30
df8e2f4be4 Fix the ts map importer saving default values for Health and Facing 2018-05-04 23:54:04 +02:00
reaperrr
3c34330925 Skip check for ITemporaryBlocker entirely if rules don't contain any temporary blockers
This benefits all mods without temporary blockers like gates or energy walls.
2018-05-04 19:40:18 +02:00
reaperrr
2a4299906d Add missing update rules to bleed update path
I forgot to add these in their respective PR.
2018-05-04 19:20:39 +02:00
reaperrr
d6e0598bd0 Fix Locomotor lint check
It was missing from the project file (oops...) and missing a check for duplicate Locomotor names.
2018-05-04 19:20:39 +02:00
reaperrr
43478e9e72 Group lint rules together in Mods.Common csproj
Makes it easier to manually add/remov/disable individual lint rules.
2018-05-04 19:20:39 +02:00
reaperrr
079570190c Make TS use Locomotor 2018-05-03 10:49:21 +02:00
reaperrr
1ee815fe3f Make D2k use Locomotor 2018-05-03 10:49:21 +02:00
reaperrr
7441badc96 Make TD use Locomotor 2018-05-03 10:49:21 +02:00
reaperrr
0501ced440 Make RA use Locomotor 2018-05-03 10:49:21 +02:00
reaperrr
5aefff421c Locomotor update rule 2018-05-03 10:49:21 +02:00
reaperrr
e7fb32b09c Replace DomainIndex passability hack with Locomotor boolean 2018-05-03 10:49:21 +02:00
reaperrr
5364515004 Don't pass movement class via IsPassable directly
Let IsPassable get that info from the locomotor instead.
2018-05-03 10:49:21 +02:00
reaperrr
a52e83ca49 Add Locomotor lint check 2018-05-03 10:49:21 +02:00
reaperrr
81343926b6 Split Locomotor trait from Mobile
Add GrantConditionOn*Layer traits

This allows to
- drop some booleans from Locomotor
- drop a good part of the subterranean- and jumpjet-specific code/hacks from Mobile
- grant more than 1 condition per layer type (via multiple traits)
- easily add more traits of this kind for other layers
2018-05-03 10:49:21 +02:00
quinno
f453d9c148 Fix args in linux server scripts
Looks like a typo.
Any args passed to the openra-{MOD}-server scripts were not correctly passed to OpenRA.Server.exe.
The client/game ones are fine.
(I guess "$$@" resolves to a PID with an '@' hanging off it)
2018-05-02 13:20:15 +02:00
Paul Chote
bf4b91741a Ignore unused frames when loading Sequences into Sheets. 2018-05-02 09:59:03 +02:00
Paul Chote
d9fd0f272c Add support on-demand sprite frame loading.
Passing the getUsedFrames argument will cause frames to be buffered
locally (and not added to the SheetBuilder) until they are explicitly
requested. This allows unused frames in sprite files to be skipped
instead of wasting space in GPU memory.
2018-05-02 09:59:03 +02:00
Paul Chote
94dd83bc13 Fix the frame mapping used to select sprites for the SpriteBounds. 2018-05-02 09:59:03 +02:00
Paul Chote
efc744dec3 Improve consistency between the update rule code and descriptions. 2018-05-02 09:25:39 +02:00
Paul Chote
8c2f25e249 Remove explicit line numbers from update rule reports.
Additions/removals by other rules in the set will almost certainly
invalidate these.  Reporting the block and file is the best we can
reasonably do.
2018-05-02 09:25:39 +02:00
Paul Chote
677d004cfa List ignored map includes only once. 2018-05-01 00:46:57 +02:00
Paul Chote
691c432b72 Ignore yaml files imported from other mods. 2018-05-01 00:46:57 +02:00
Paul Chote
91295f9c68 Add IReadOnlyFileSystem.IsExternalModFile. 2018-05-01 00:46:57 +02:00
Voidwalker
0c30a1d670 Fix projectiles to use IRulesetLoaded properly 2018-05-01 00:16:58 +02:00
Paul Chote
f0e190825a Fix map updater breaking unicode characters. 2018-04-30 02:37:53 +02:00
Paul Chote
952f41b4e4 Add --dump-sequence-sheets Utility command.
This can be used to debug and optimize the texture
data that is uploaded to VRAM.
2018-04-30 02:05:43 +02:00
RoosterDragon
7bc5bd5791 Force buffered sheets to commit data to a texture on buffer release.
Previously ReleaseBuffer did not immediately null out the buffer, instead the releaseBufferOnCommit flag allows it to be nulled when the texture is next access and the pending changes from the buffer are committed to it. Now the texture is committed immediately, thus the buffer is null once ReleaseBuffer returns.

Once loaded, we force a GC to reclaim temporary memory used during loading. Previously the buffer would not be null as it was pending commit to the texture and thus could not be reclaimed. As soon as we rendered the first frame, the buffer is nulled but we are now in a low GC state - and the buffer will not be reclaimed until the next gen 2 GC which may be dozens of minutes away.

This change ensures the buffer is null in time for the post-load GC, and thus can be reclaimed before we start rendering.
2018-04-29 18:11:48 +02:00
reaperrr
83f100618b Make INotifyAppliedDamage require explicit implementation 2018-04-29 11:59:49 +01:00
reaperrr
3a82b13093 Make INotifyKilled require explicit implementation 2018-04-29 11:59:49 +01:00
reaperrr
7ca9aa5e0b Make INotifyDamage require explicit implementation 2018-04-29 11:59:49 +01:00
reaperrr
ccd070afd6 Make IRenderModifier require explicit implementation 2018-04-29 11:59:49 +01:00
reaperrr
06dbf71461 Make IStoreResources require explicit implementation 2018-04-29 11:59:49 +01:00
reaperrr
cc4c5a5492 Make IVoiced require explicit implementation 2018-04-29 11:59:49 +01:00
Paul Chote
da29250711 Move PlayerResources to Mods.Common. 2018-04-28 20:42:10 +02:00
Paul Chote
d186ca38f7 Explicitly require PowerShell 3 or higher. 2018-04-28 20:29:31 +02:00
Mustafa Alperen Seki
ec61527ebc Don't show negative prerequisites on tooltip 2018-04-26 17:10:26 +02:00
Paul Chote
160ade1060 Add CaptureTypes to GiveCashOnCapture. 2018-04-26 08:27:35 +02:00
abcdefg30
c3bfd32192 Fix PlayMovieInRadar crashing for spectators 2018-04-23 21:52:49 +02:00
Paul Chote
7508a13f92 Enable "Unable to comply, building in progress" notification. 2018-04-22 18:01:57 +02:00
Paul Chote
0654f18f22 Break out of cancellation loop when there is nothing left to cancel. 2018-04-22 18:01:57 +02:00
Paul Chote
f2cf51d1a4 Play appropriate audio notifications when build/production limit is reached. 2018-04-22 18:01:57 +02:00
Paul Chote
da10e94b41 Add per-item and total queue length limits to ProductionQueue.
Implement 999 per-actor limit.
2018-04-22 18:01:57 +02:00
reaperrr
ffeea72130 Remove RA gates
They aren't used on any shipping map, and removing them significantly
reduces the overscan radius of blockable projectiles in the mod.
2018-04-22 10:55:23 +02:00
reaperrr
18ed04eab5 Only use largest blocker instead of largest actor for projectile blocker overscan
Before this, we unconditionally used the largest OuterRadius of all actors inside a mod for overscanning of blockable projectiles.
However, in many mods the only blockable actors are 1-cell walls, and even if there are gates like in TS, they usually aren't the largest actors in terms of hit-shape.

So this measure should save a bit of performance by reducing the overscan radius of blockable projectiles, especially in mods where walls are the only blocking actors.
2018-04-22 10:55:23 +02:00
FrameLimiter
39aa1a9f9c Adds ships to the MECH's autotarget priority list
The mechanic was not automatically targeting & repairing damaged ships.
2018-04-12 17:08:57 +02:00
abcdefg30
dd080eb882 Fix bridges not being targetable by enter activities 2018-04-12 17:04:57 +02:00
abcdefg30
b8077f1d5d Fix the campaign AI defending captured buildings 2018-04-12 17:01:59 +02:00
abcdefg30
2e7b8bc30a Add a missing word in the description of atreides05 2018-04-12 17:01:59 +02:00
abcdefg30
dfd60655af Fix a crash in atreides05
We removed ExternalCondition from starport
2018-04-12 17:01:59 +02:00
Mustafa Alperen Seki
dc71a71a09 Change the way NukePower>SkipAscent works 2018-04-12 08:19:18 +02:00
Andre Mohren
5b7d43f1e0 Virtual ProductionQueue.AllQueued 2018-04-12 08:08:45 +02:00
David Wilson
1b685955cd Fixes for WavReader to explictly handle "LIST" and "cue " chunks (RA2), and skip to EOF on unknown chunk 2018-04-11 19:22:47 +01:00
abcdefg30
42954aa18e Remove BagFile 2018-04-11 17:18:03 +02:00
RoosterDragon
4da9b6f00a Ensure BagFile.GetStream returns unique streams.
GetStream must return a unique stream on each call to ensure multiple callers can read their streams without affecting each other. As bag file returned multiple references to the same underlying stream, it was possible for multiple callers to disturb reads of each other, and thus read bad audio from each file.
2018-04-10 22:09:39 +02:00
Smittytron
68ad4b6092 Remove leftover sniper disabled from missions 2018-04-10 13:08:22 +02:00
JordanBergin
0226c06b93 No longer check Carryable IsInWorld when Carryall is killed. Also the Carryable's position is updated to Carryall's position when the Carryall is killed. 2018-04-10 12:52:42 +02:00
Smittytron
348932692a Change TD water crossings to Rough terrain 2018-04-10 01:13:29 +02:00
Chris Forbes
770f14fa2a Use IPositionable.CanExistInCell in Bridge/GroundLevelBridge
We don't care whether there's empty space for the actor now -- we care whether
the terrain the actor is ALREADY standing on remains suitable after the
bridge state change.
2018-04-10 01:01:53 +02:00
Chris Forbes
dddd057e3d Add IPositionable.CanExistInCell
This is like CanEnterCell, but doesn't take into account conflicting
actors, etc.
2018-04-10 01:01:53 +02:00
reaperrr
fba08cd066 Don't create empty MissionGroups
Only create MissionGroups if there's at least one visible mission.
2018-04-09 12:19:28 +02:00
Paul Chote
4f0aa89c01 Remove TileSet.Palette and PaletteFromCurrentTileset. 2018-04-08 21:14:29 +02:00
Joe Alam
7221c29d9b Added text selection and copy support to TextFieldWidget.
Use Shift and navigation key (cursor, home, end) to select a portion of
text, and replace/delete/cut as appropriate.
Also provides support for selection with mouse (click and drag)
2018-04-08 19:24:22 +02:00
Zimmermann Gyula
b5893d4c6d Implement GrantExternalConditionToCrusher. 2018-04-08 19:04:05 +02:00
Paul Chote
cc04ec607c Allow d2k turrets to replace walls. 2018-04-07 23:32:24 +02:00
Michael Silber
29dd497c19 Allows GDI-Turrets, GDI- and Nod-Gates to replace walls. 2018-04-07 23:32:24 +02:00
Michael Silber
1b110b7833 Add Replaceable and Replacement traits to support wall overrides. 2018-04-07 23:32:24 +02:00
reaperrr
0c52ff3ae5 Cache TargetablePositions in Actor
To speed up Target.Positions.
2018-04-07 17:24:13 +01:00
reaperrr
4c16e51f92 Add EditorPlayer to all mods
To prevent the editor from loading unnecessary or even incompatible
player traits.
2018-04-06 20:46:47 +02:00
reaperrr
563c8ad302 HarvManager update rule 2018-04-06 20:16:36 +02:00
reaperrr
4f651c2f88 Remove HarvesterInfo look-up from HackyAI 2018-04-06 20:16:36 +02:00
reaperrr
5276636598 Extract a HarvesterManager from HackyAI
This takes action when AI harvesters don't find ore near the base or became idle for some other reason.
2018-04-06 20:16:36 +02:00
reaperrr
82867b6c3a Move some stuff from HackyAI to new AIUtils 2018-04-06 20:16:36 +02:00
abcdefg30
63093eb986 Fix color picker actors being abstract 2018-04-04 18:33:53 +02:00
RoosterDragon
c9b19ffe52 Prevent attack move crashing if selected actors die.
- Cancel attack move if all actors die.
- Command bar no longer shows available actions from any dead units.
2018-04-04 18:30:47 +02:00
Paul Chote
7be71eb381 Remove broken Server.ExternalPort setting. 2018-03-31 18:09:07 +02:00
IceReaper
12407ae995 Fix asset browser displaying wrong file
If multiple files with same filename are present.
2018-03-31 16:08:35 +02:00
Kanar
dc46dd1f26 Re-active Edge-Scrolling for inverted Mouse-Scrolling 2018-03-30 23:47:32 +01:00
Paul Chote
2400b152ea Process shared map includes as part of the mod rules.
This ensures that they are only updated once instead
of repeating the updates for every map that includes them.
2018-03-30 21:31:15 +02:00
Paul Chote
02f769964e Fix a crash in UpdateMapCommand. 2018-03-30 21:31:15 +02:00
Paul Chote
aa5b9401c3 Add Chrome update plumbing. 2018-03-30 17:35:30 +02:00
abcdefg30
910064dfe5 Fix FormatMessageList appending a new line at the end of the list 2018-03-30 12:57:18 +01:00
abcdefg30
207a355909 Fix map files being labeled as "<no filename available>" 2018-03-30 12:57:18 +01:00
abcdefg30
13b89b1c50 Add IgnoreAbstractActors.cs 2018-03-30 12:57:18 +01:00
abcdefg30
972255c6a6 Fix line endings in upgrade rules files
- Use unix line endings
- No "\n" at the end of a message
2018-03-30 12:57:18 +01:00
CH4Code
5b24649c44 Add vision and VTOL husk to the carryall while in process of lifting harvesters. 2018-03-25 13:16:20 +02:00
abcdefg30
d15b462350 Remove the deprecated Difficulty member from MapGlobal (lua) 2018-03-23 20:23:09 +01:00
Paul Chote
ea68f1abb9 Implement new mod/map updater framework. 2018-03-23 20:04:52 +01:00
Thomas Ze
7552afeb16 Fix ActorMap.RemoveInfluenceInner see #14939 (RemoveInfluenceInner(influenceNode.Next.Next) call on influenceNode.Actor == toRemove) 2018-03-23 04:43:03 -03:00
RoosterDragon
f6471d411e Reuse set when rendering actors in the world to avoid allocations. 2018-03-22 23:32:03 -03:00
reaperrr
3069bbfa7d Fix infinite loop in HeliReturnToBase
This can happen if HeliAttack tells the heli to return to base when the player doesn't have any of the RearmBuildings available, because the activity queues itself after the HRTB, and the latter will, after a forced land, then queue back HeliAttack, which then immediately queues back HRTB and so on.

Instead, we now assume that if there is no base to return to, going to NextActivity is pointless and don't queue NextActivity.
RTB was likely ordered by HeliAttack due to lack of ammo, so resuming the attack would be pointless.
2018-03-22 22:50:50 +01:00
Paul Chote
d79d4479c7 Work around AI orders to invalid cells. 2018-03-22 13:52:41 +01:00
Paul Chote
7e94fa8c8a Fix multi-turreted actors not appearing in the map editor. 2018-03-22 12:21:34 +01:00
Michael Silber
6b24271a17 Pass ActorInfo through building-placement-validation code. 2018-03-21 12:53:50 +01:00
Paul Chote
8ea1da1046 Apply map upgrade rules without instantiating the Map object.
This avoids a crash that stops the maps from being updated
when the base mod ruleset is not valid (e.g. a trait is missing a
FieldLoader.Required property).  This also significantly improves the
upgrade performance.
2018-03-21 12:15:23 +01:00
Peter Antal
d2ff5b49fd Allow each caller on MergeOrDefault to discard nodes.
Use filtering ActorInfo's to drop template actors.
2018-03-21 12:10:31 +01:00
reaperrr
40d7b41e84 Tweak Cruiser and Destroyer turret offsets
Moved back turret of cruiser a bit more backwards and destroyer turret a bit forward.
2018-03-21 12:09:18 +01:00
RoosterDragon
d0f7511a62 Add TrimExcess to TypeDictionary.
After adding is finished, this can be used to reduce the memory footprint of the dictionary.
2018-03-21 12:08:23 +01:00
RoosterDragon
e17ede34ef Add Int32Matrix4x4 struct.
This allows matrices to be represented as a value type, and additionally allows avoiding array allocations when calculating rotations.
2018-03-21 12:07:53 +01:00
RoosterDragon
5bd5a384b7 Use a BitSet for representing target types.
- Rename Bits<T> to BitSet<T>.
- Implement set based helpers for BitSet<T>.
- When representing TargetTypes of ITargetable in various traits, use a BitSet<TargetableType> instead of HashSet<string> for better performance & reduced memory usage.
- Fix FieldLoader to trim input values when generating a BitSet<T>.
- Require T in BitSet<T> and BitSetAllocator<T> to be a class since it's just a marker value. This allows the JIT to instantiate generic code for these classes once, as they don't benefit from specialized code for T. (Typically JITs will generate shared code for all reference types, and unique code for every value type encountered).
2018-03-21 12:07:44 +01:00
Peter Antal
8fa94c5301 -Perform null check and add exception logging in RuleSet.
-Explicitly recognize connection termination on ServerOrder.Deserialize()
-Use explicit exception type for SDL2HardwareCursor failures.
2018-03-21 01:55:42 -03:00
reaperrr
f351f0346f Cache map option ShortGame at game load
To reduce MapOptions calls.
2018-03-21 01:49:52 -03:00
RoosterDragon
0555ce9321 Reduce allocations in AutoTarget.ChooseTarget.
- Cache active target query.
- Prefer .Count == 0 over Any when working with Lists.
- Use helper for GetEnabledTargetTypes.
- Don't declare target variable until actually needed.
2018-03-21 01:08:59 -03:00
RoosterDragon
986025ca76 Reuse HashSets for actors entered/exited in CellTrigger & ProximityTrigger.
Actors involved in the trigger are determined as actors move around near the trigger - and can be expensive in some maps. This allows us to avoid allocating new sets and the CPU hit required to set it up each time.
2018-03-21 01:01:48 -03:00
abcdefg30
11b44963da Remove duplicated rules from nod02a
They are already inherited from 'campaign-maprules.yaml'
and 'campaign-palettes.yaml'.
2018-03-21 00:52:18 -03:00
abcdefg30
7f55e85530 Rename DefaultCashLocked to DefaultCashDropdownLocked in yaml 2018-03-21 00:52:18 -03:00
Mustafa Alperen Seki
9122aac555 Fix rendering of IProductionIconOverlay on Spec UI 2018-03-19 23:11:48 +01:00
Paul Chote
e0bcfa918d Fix half-pixel offset in ColorBlock rendering. 2018-03-19 17:31:44 +01:00
Paul Chote
27d9a9e6ff Remove pre-20171014 upgrade rules. 2018-03-19 15:00:41 +01:00
David Wilson
9bc9ce4577 Color picker update with team color presets. Bots added will use available team color presets by default 2018-03-18 23:29:47 -03:00
netnazgul
b383b9abc9 Fix actors with PauseOnCondition ammo not scanning for targets when reloading 2018-03-18 22:57:18 +01:00
C. Helmig
aa829427f0 Fix silo preventing player elimination. 2018-03-18 22:11:36 +01:00
RoosterDragon
d2f2029caf Add FirstNonEmptyBounds method for IDecorationBounds interface.
This provides a more efficient way of determining the bounds by avoiding LINQ. A helper that works directly on arrays prevents allocation of an enumerator when the collection is know to be an array.
2018-03-18 22:06:12 +01:00
RoosterDragon
3b642b1a79 Reuse TargetTypes collection in FrozenActor.RefreshState. 2018-03-18 16:50:20 +01:00
RoosterDragon
b4609337f8 Reuse a HashSet for deduplicating footprints in AffectsShroud.
Shroud footprints are recalculated as actors move around the map, and thus this gets called quite often. This allows us to avoid allocating a new set and the CPU hit required to set it up each time.
2018-03-18 16:46:07 +01:00
RoosterDragon
63810220e4 Improve some usages of Aggregate. 2018-03-18 16:44:17 +01:00
RoosterDragon
adc4538c44 Prevent crash when invalid or not yet created LAN games are discovered. 2018-03-18 16:23:06 +01:00
RoosterDragon
f47595b780 Hide map preview when no replay is selected.
This prevents interaction with the widget than can cause crashes as no replay is selected yet.
2018-03-18 16:06:27 +01:00
Mustafa Alperen Seki
356f24b78c Add logic to disallowing On Hold on a queue. 2018-03-18 15:58:57 +01:00
RoosterDragon
f2e270ce06 Return IRenderable[] rather than IEnumerable<IRenderable> for animations.
Since some callers now know they have an array, then can enumerate it more efficiently and without allocating an enumerator.
2018-03-17 17:51:16 +01:00
fruehstueck
65c42a68ce Add shortcuts for make.ps1 commands 2018-03-15 17:46:39 +00:00
Paul Chote
be96bafc69 Match missions using the unresolved path. 2018-03-11 16:32:10 +01:00
Paul Chote
ac7b6e42f0 Improve behaviour of Platform.UnresolvePath on Windows. 2018-03-11 16:32:10 +01:00
DESKTOP-7PLKRFC\jur_1
311cd521e3 Refinery spawned harvesters should prioritize lower ore #14827 2018-03-11 00:50:55 +01:00
xecollons
227cf35d5f Added TooltipDescription 2018-03-10 17:55:05 +01:00
Peter Antal
3ce2417a06 Create SupportDirPrefix and IsPathRelativeToSupportDirectory() as members on Platform class. 2018-03-10 12:54:01 +00:00
reaperrr
1f4573886b Improve TD service depot hitshape and target offsets 2018-03-10 04:44:46 +01:00
reaperrr
ce396e840d Improve RA service depot hitshape + target offsets 2018-03-10 04:44:46 +01:00
reaperrr
fd83cbf60f Fix WithTurretAimAnimation disabled handling
The old sequence was not recovering when this trait lost its required
condition while the aim anim was running.

Now it doesn't unconditionally return, but instead checks what the
current sequence is and resets to base turret sequence if AimAnim is
disabled.
2018-03-10 00:13:42 +01:00
Mustafa Alperen Seki
1d8b1906ef Add IsPlayerPalette support to WithDecoration 2018-03-10 00:12:56 +01:00
abcdefg30
b012fa62fe Replace 'target point' by 'center' in all descriptions 2018-03-09 23:32:07 +01:00
abcdefg30
ed6a6b61de Throw a proper error when parsing an invalid int2 2018-03-09 23:32:07 +01:00
atlimit8
7283f9804e Added Polygon IHitShape 2018-03-09 23:32:07 +01:00
abcdefg30
56e7b1edc2 Fix int2 arrays not being parsed 2018-03-09 23:32:07 +01:00
reaperrr
5a889c0efd De-duplicate some WithTurretAttackAnimation code 2018-03-09 21:30:30 +01:00
reaperrr
769a49ef0b Make WithTurretAimAnimation conditional 2018-03-09 21:30:30 +01:00
reaperrr
76da40bbda Make WithTurretAttackAnimation conditional 2018-03-09 21:30:30 +01:00
reaperrr
02b1530300 Fix upgrade rule dates 2018-03-09 19:28:29 +01:00
reaperrr
79c78090d1 Remove WithSpriteTurret.AimSequence
We can now use WithTurretAimAnimation instead.
2018-03-09 19:28:29 +01:00
reaperrr
a1ad76ba74 Split *AimAnimation from WithTurretAttackAnimation
These two didn't interact and actually even conflicted when used at the same time, so splitting them is the sensible thing to do.
2018-03-09 19:28:29 +01:00
reaperrr
bd097730cf Adapt TS 2018-03-09 18:58:49 +01:00
reaperrr
e17e8c8cbd Adapt TD 2018-03-09 18:58:49 +01:00
reaperrr
b40970ca5d Adapt RA rules 2018-03-09 18:58:49 +01:00
reaperrr
d643d2ebda Remove legacy .aud sound defaults from Common traits
While C&C-specific sound defaults might be acceptable for C&C-specific traits like MadTank and Chronoshiftable, for common, generic traits like Building they no longer are.
2018-03-09 18:58:49 +01:00
netnazgul
58b5e7b243 Fix Pitfight and Ascent maps in RA mod map pool 2018-03-09 15:57:07 +01:00
Mustafa Alperen Seki
5e7e3bb011 Add DamageTypes to Kill() and make some traits use it. 2018-03-09 00:25:29 +01:00
Pavel Penev
b620e8107f Added GrantRandomCondition trait. 2018-03-08 18:15:54 +01:00
Mustafa Alperen Seki
c976bb1d7b Make BaseProvider PausableConditional 2018-03-08 17:19:23 +01:00
Matthias Mailänder
12054506e1 Add support for JASC and GIMP color palettes 2018-03-08 16:54:13 +01:00
reaperrr
92584c3c85 Fix upgrade rule dates to be after release-20180307 2018-03-08 16:03:14 +01:00
reaperrr
d90ff99e74 Replace WithReloadingSpriteTurret with conditions
WithReloadingSpriteTurret was bound to run into conflicts with any WithTurret*Animation traits due to overriding the turret sequence constantly via ITick.
Using (stacked) conditions instead avoids that.
2018-03-08 16:03:14 +01:00
reaperrr
55b11d1745 Don't cache ActorSpawners at creation
Re-evaluate before every spawn attempt instead.
Also accounts for ActorSpawner being conditional now.

While a bit more costly in terms of performance, this allows to create spawns mid-game.
2018-03-08 15:39:44 +01:00
Voidwalker
711bad91a3 Generalize WormManager into ActorSpawnManager.
Added support of multiple actors, conditions and types.
2018-03-08 15:39:44 +01:00
Paul Chote
e69cf4fd5c Rename another Stream.Write(byte[]) extension method. 2018-03-07 22:29:35 +01:00
Paul Chote
fadcfa0828 Bump mono requirement to 4.2 in the deb package. 2018-03-05 23:16:34 +01:00
Smittytron
1d9ed31f7d Add secondary objective and difficulty levels to nod06b 2018-03-04 21:31:27 +01:00
Smittytron
f9a45130fa Add Bridge to TerrainType 2018-03-04 21:29:11 +01:00
Paul Chote
42f1db0d4b Rename Stream.Write(byte[]) extension method to fix compatibility with newer mono. 2018-03-03 18:40:01 +01:00
Peter Antal
9ce0bcb0b7 Mop up active Stylecop nits.
Style consistency cleanup.
2018-03-03 11:45:35 +00:00
Peter Antal
701675fd4c Add "Slowest" gamespeed with Timestep of 80.
Drop "Slowest" latency to 2 frames, to balance out with the particularly long timestep.
2018-02-28 13:06:24 +01:00
reaperrr
700c46d6af Prevent TS AI from building too many (advanced) power plants
While scaling minimum excess power with base size to make sure they don't build too few, either.
2018-02-27 19:47:00 +01:00
reaperrr
342114878c Prevent D2k AIs from building too many wind traps
While scaling minimum excess power with base size to make sure they don't build too few, either.
2018-02-27 19:47:00 +01:00
reaperrr
7c79d20083 Prevent TD AIs from building too many (advanced) power plants
While scaling minimum excess power with base size to make sure they don't build too few, either.
2018-02-27 19:47:00 +01:00
reaperrr
de47d570d5 Prevent RA AIs from building too many (advanced) power plants
While scaling minimum excess power with base size to make sure they don't build too few, either.
2018-02-27 19:47:00 +01:00
reaperrr
c5f9d6ff2d Add more configurability to AI MinimumExcessPower logic
Allows to scale the targeted minimum excess with building count as well as define a maximum cap to avoid overproducing powerplants.
2018-02-27 19:47:00 +01:00
abcdefg30
851c38012e Set 'SecurityProtocol' to 'Tls12' for download dependencies on windows
But only for dependencies downloaded from github.
2018-02-26 01:42:00 +01:00
ltem
4376dd8c52 Add Github issue template 2018-02-25 15:16:29 +01:00
Smittytron
9de1fe40a5 Add difficulty levels to nod06a 2018-02-25 11:13:52 +01:00
Matthias Mailänder
cf944ae9f1 Require IntoActor everywhere. 2018-02-23 20:02:47 +01:00
Matthias Mailänder
e3e710bb27 Add Visceroid fusing 2018-02-23 20:02:47 +01:00
Matthias Mailänder
6bd1e90671 Add TransformCrusherOnCrush 2018-02-23 20:02:47 +01:00
reaperrr
025f664820 Fix Tiberian Fiend editor category 2018-02-23 19:59:33 +01:00
Matthias Mailänder
f189b85caa Render Tiberian Fiend spikes in Tiberium green. 2018-02-23 19:59:33 +01:00
Matthias Mailänder
8cfb406e29 Don't hide while attacking. 2018-02-23 19:59:33 +01:00
Matthias Mailänder
e5810d19d9 Add Tiberium Fiend hiding mechanic. 2018-02-23 19:59:33 +01:00
abcdefg30
93513db09e Fix launch-game.cmd accepting wrong mod IDs 2018-02-23 14:41:51 +01:00
Mustafa Alperen Seki
763da40092 Fix palette of Oil Pump, Ice, Boxes, Hedgehogs and Utility Poles on Desert Tileset 2018-02-23 02:23:10 +01:00
reaperrr
9107ca3bc1 Remove unused legacy IsWater flag
This was planned anyway, we had just forgotten about it when the last blocker was removed.
2018-02-22 11:51:10 +01:00
Alexis Hunt
08ad7d7f4e Refactor handling of hit radii in projectiles.
penev discovered that the RulesetLoaded functions of projectiles were
never being called, meaning that their blocking calculations were not
properly accounting for actors with large hitboxes.

The best fix for this is to change FindActorsOnLine to always account
for the largest actor's hit radius, rather than forcing callers to pass
the largest radius. Per the comment in Util.cs, as a result, move this
computation to ActorMap. I decided to simplify by not making a separate
calculation for actors that block projectiles only; this may cause a
small performance degradation as the search space is a bit larger.

Similarly to this, I've removed the ability to specify a search radius
manually. Because this is only a search radius, setting a value smaller
than the largest eligible actor makes no sense; that would lead to
completely inconsistent blocking. Setting a larger value, on the other
hand, would make no difference.

CreateEffectWarhead was the only place in core code any of these search
radii were set, and that's because 0 was a mysterious magic value that
made the warhead incapable of hitting actors. I replaced it with a
boolean flag that more clearly indicates the actual behaviour.

Fixes #14151.
2018-02-21 23:26:41 +01:00
Mustafa Alperen Seki
c4b0ad45e3 Add lua functions for DeliverCash and DeliverExperience 2018-02-21 21:38:43 +01:00
Guido L
21472f2cc6 HackyAI: Refactor and remove duplicated logic. 2018-02-21 21:34:00 +01:00
reaperrr
c46a050da3 D2k yaml style fixes 2018-02-21 22:04:33 +03:00
reaperrr
b2885c7563 C&C yaml style fixes 2018-02-21 22:04:33 +03:00
reaperrr
0d5bfff88f RA mod yaml style fixes 2018-02-21 22:04:33 +03:00
reaperrr
e6e860ee36 Common UI yaml style fixes
As suggested by upgrade rules.
2018-02-21 22:04:33 +03:00
reaperrr
5ae1d1c4bf Fix bracket style issue in ProductionQueue
While it's really minor and insignificant, our style convention is to put opening { brackets on a newline (unless everything fits into a single line).
2018-02-21 22:04:33 +03:00
Mustafa Alperen Seki
8979730c32 Add "FactionSuffix-x: allies" for unused Allied countries 2018-02-19 15:05:07 +01:00
Mustafa Alperen Seki
913e7fc995 Unhardcode GrantExternalConditionPower cursors 2018-02-18 23:02:31 +01:00
Mustafa Alperen Seki
f136c200bc Check if AI Production is no longer on hold more often 2018-02-18 22:53:11 +01:00
Mustafa Alperen Seki
94ed985739 Remove NoAutoTarget from Atr5 starport.
Buildings are no longer auto targeted by default.
2018-02-18 22:53:11 +01:00
Mustafa Alperen Seki
384b78aae4 Fix Harkonnen Base definitions on Ord4 2018-02-18 22:53:11 +01:00
Mustafa Alperen Seki
bf2600c2fb Add Ordos 5 2018-02-18 22:53:11 +01:00
abcdefg30
0f1cd07dee Don't render empty background images 2018-02-18 20:18:30 +01:00
Mustafa Alperen Seki
0e0ab318e6 Make ThrowsShrapnel conditional 2018-02-18 18:41:29 +01:00
Mustafa Alperen Seki
733055007a Add Player Palette support for Bullet, Missile and GravityBomb. 2018-02-18 18:23:24 +01:00
AoAGeneral
a06b21f636 TD APC Change. 20180217
Changed the build timer for APCs from 14 seconds to 15 seconds.

An oddity here is that it wasn't exactly on 14 seconds. It was closer to 13.6 seconds.
Changing this to be about 14.8 seconds will help a little from the mass production problem
rather then changing damages or HP further.
2018-02-18 15:41:58 +01:00
abcdefg30
0da8efd9b4 Make Aircraft spawn husks with a neutral owner 2018-02-17 12:21:55 +01:00
abcdefg30
bed6b26428 Fix FallsToEarth not accounting for effective ownership 2018-02-17 12:21:55 +01:00
Arular101
5afa260d4e Don't show new build walls in fow 2018-02-11 23:39:39 +01:00
abcdefg30
bb801e5948 Fix a "granted condition is never consumed" warning in D2k 2018-02-07 21:22:59 +01:00
Mustafa Alperen Seki
a45e0d9d0a Seperate Imperial and Harkonnen Sardaukars 2018-02-06 21:20:00 +01:00
Mustafa Alperen Seki
a0d4a03530 Add conyard.corrino 2018-02-06 21:09:38 +01:00
Mustafa Alperen Seki
3ed8e4b4e8 Make SPM not fire from an actor with disabled instance of a SW. 2018-02-06 21:09:38 +01:00
Mustafa Alperen Seki
7474c38943 Limit D2K Palace SWs to their Faction's Palaces' 2018-02-06 21:09:38 +01:00
Mustafa Alperen Seki
99eedfd0e7 Make SupportPowerChargeBar conditional 2018-02-06 21:09:38 +01:00
Mustafa Alperen Seki
ce63dd33db Make PrimaryBuilding conditional. 2018-02-06 21:09:38 +01:00
Mustafa Alperen Seki
491f808b75 Add GrantConditionOnFaction. 2018-02-06 21:09:38 +01:00
Mustafa Alperen Seki
065eb78afc Make AttackSuicides coditional 2018-02-06 03:10:15 +01:00
Muh-Muh
9fa37bbb02 Add myself to authors 2018-02-06 03:08:40 +01:00
Muh-Muh
f34911eeb6 Make only the right warfactory infiltratable. don't break the game if a player manages without infiltration. 2018-02-06 03:08:40 +01:00
Muh-Muh
0a092237d3 Add Capture as a possibility for completing the objectives on Soviet06 2018-02-06 03:07:08 +01:00
netnazgul
a6a7f641ac Revise the map pool of RA mod 2018-02-04 16:28:16 +01:00
Paul Chote
5737f4f771 Preserve arguments passed into the windows launcher. 2018-02-04 16:14:04 +01:00
Paul Chote
222d1af706 Don't create invalid targets (dead actors) in UOG. 2018-02-04 15:46:36 +01:00
Paul Chote
234e6cc566 Prevent injected unpause orders from restarting a finished game. 2018-02-04 15:30:53 +01:00
Paul Chote
258df13451 Fix missing PauseStateLocked check on "/pause" chat command. 2018-02-04 15:30:53 +01:00
Paul Chote
237d9b3a29 Fix missing click sounds on observer stat hotkeys. 2018-02-03 19:16:18 +01:00
Paul Chote
8174d0e69a Use EffectiveOwner for actor tooltips. 2018-02-03 18:35:50 +01:00
Paul Chote
2fccfdf1ee Add support for disabling IIssueDeployOrders. 2018-01-28 18:06:30 +01:00
RoosterDragon
a726b57367 Fix order serialization issues. 2018-01-28 15:41:28 +01:00
Paul Chote
3af6ffc017 Revert "Remove CreateGroup order as the ActorGroupProxy is gone." 2018-01-28 14:58:44 +01:00
Paul Chote
fc31fac1f0 Work around duplicated notification sound when the ingame menu is open. 2018-01-28 14:51:41 +01:00
Paul Chote
73f5f1fa75 Remove AddChatLine registration on IngameChatLogic dispose. 2018-01-28 14:51:41 +01:00
Smittytron
5f54e46eae Dial back Atry V2 min range change 2018-01-21 10:49:59 +01:00
Mustafa Alperen Seki
aac45915cb Fix Flamers sometimes explode with UnitExplode 2018-01-20 23:51:37 +01:00
Arular101
21504a774d Add missing copyright notice 2018-01-17 23:07:01 +01:00
Arular101
8a60918841 Update copyright notice year to 2018 2018-01-17 00:47:34 +01:00
AoAGeneral
52494e2c91 Changes in TD:
APC vs none decreased from 35 to 30

APC vs wood decreased from 35 to 25

APC vs heavy decreased from 35 to 25

Obelisk HP Increased from 600 (60000) to 750 (75000)

APCs are doing to much damage vs structures and heavy armor. They are managing to kill Guard Towers, light tanks, and power plants to effectively in numbers between 5 and 10. This will help to prevent this from happening. A small decrease vs infantry allows rocket infantry to last just a little bit longer as well.

Obelisk is getting a HP increase. Going from the old notes and responses happening now leaves me to believe its HP is to small. In one testing example an obelisk getting airstriked leaves it with no HP left. 4 minigunner shots and then it dies. Increasing the HP allows an expensive structure to stand longer.
2018-01-16 23:40:29 +01:00
Paul Chote
ea57ed575b Remove helicopter RTB from TD command bar deploy description. 2018-01-14 23:25:47 +01:00
Paul Chote
7dea5e28af Remove ReturnToBase order feedback if no RearmBuildings are defined.
ReturnToBase requires RearmBuildings to function.
2018-01-14 23:25:47 +01:00
Mustafa Alperen Seki
283af60b7c Add PrimaryBuilding: to D2K Palaces 2018-01-13 17:55:57 +01:00
Mustafa Alperen Seki
c87aa62647 Make ProduceActorPower care for PrimaryBuilding 2018-01-13 17:55:57 +01:00
Arular101
24b7f7a23f Cast to long to avoid overflow when multiplying by the health (part 2) 2018-01-13 17:32:34 +01:00
Arular101
30acee38c9 Cast to long to avoid overflow when multiplying by the health 2018-01-13 17:32:34 +01:00
Oliver Brakmann
32b0170785 Fix primary building flag not working properly in D2k 2018-01-13 17:19:38 +01:00
Alexis Hunt
157a783df5 Correct UI for unslowed queues in low power.
Because of the way the tick logic works, 0 (or any negative number) for
LowPowerSlowdown is functionally equivalent to 1. But LowPowerSlowdown
is multipled by a time in several cases, so while 1 will produce the
correct result (no slowdown), 0 will say that the time remaining is
00:00. Forbid nonpositive values, and correct the d2k mod which was
using 0.

Additionally, in the production tooltip, the colour should display as
white even in low power if there is no slowdown.
2018-01-13 16:13:59 +01:00
Mustafa Alperen Seki
ff39802090 Make /kill and /dispose use orders. 2018-01-13 15:50:54 +01:00
Mustafa Alperen Seki
23a2e8fdce Fix building armors in D2k 2018-01-11 17:50:37 +01:00
C. Helmig
75b7e0a58c Fix d2k walls being always visible through f.o.w. 2018-01-11 17:22:49 +01:00
Alexis Hunt
f0267ccb51 Do not speed D2K upgrades up based on buildings. 2018-01-11 11:59:09 +01:00
C. Helmig
14d91452e0 Added primary building and "PRIMARY" text to high tech factory. 2018-01-09 22:39:54 +01:00
C. Helmig
8dd5ba3ac7 Add production bar to high tech factory. 2018-01-09 22:39:54 +01:00
Paul Chote
9a7c6ba34e Refresh lobby server list when switching to the Servers tab. 2018-01-09 21:55:23 +01:00
Paul Chote
3f37f02e84 Use https for web services. 2018-01-09 20:52:25 +01:00
Mustafa Alperen Seki
4d55fa9ca9 Make 1st missions use same way as 2nd to disable upgrades 2018-01-08 20:51:12 +01:00
Mustafa Alperen Seki
f89953113c Disable upgrades in 2nd missions 2018-01-08 20:51:12 +01:00
Mustafa Alperen Seki
d4f7d669f7 Fix the crash on Har5 2018-01-07 23:13:52 +01:00
Paul Chote
c77e328614 Remove "Mission Aborted" notification.
This has been causing confusion for players who have already completed a mission.
2018-01-06 22:35:10 +03:00
RoosterDragon
b1e2ee9b79 ScreenMap should TickRender, rather than just Tick.
This is as FrozenUnderFog.TickRender queues an update to the screen map. If this is not processed in the same tick, this results in screen bounds for the frozen actor being 1 tick behind. By making ScreenMap TickRender, it ensures changes from both Tick and TickRender traits are processed, rather than just Tick traits.
2018-01-06 15:16:59 +01:00
RoosterDragon
c60ca83751 Revert "Fix actors disappearing for a tick when swapping to the frozen actor."
This reverts commit 2eb090f153.

This fixes flicker for the actor->frozen transition, but then introduces the same flicker for the frozen->actor transition instead.
2018-01-06 15:16:59 +01:00
Paul Chote
f6fcf4ca6f Fix crash when the mouse-overed support power loses all instances. 2018-01-06 14:32:00 +01:00
Mustafa Alperen Seki
a021bd4584 Remove ^Tank default from RA mod 2018-01-06 12:08:25 +01:00
GSonderling
69e6e033a6 AI will now defend MCV as if it was a harvester or a building.
Adjusted comments.
2018-01-04 22:11:43 +01:00
FrameLimiter
9f8ebdce42 Fixes STEK TargetTypes in mission allies-06a
The Soviet Tech Centers were automatically being targeted by units.
2018-01-04 08:05:55 +01:00
FrameLimiter
89b95a5408 Fixes STEK TargetTypes in mission allies-06b
The Soviet Tech Center was automatically being targeted by units.
2018-01-04 08:05:55 +01:00
Smittytron
77ac0e5407 Reduce value of TD Civilian to 10 2018-01-03 11:00:53 +01:00
Mustafa Alperen Seki
2e3f302088 Fix the misplaced BridgePlaceholder on Tread Lightly 2018-01-01 21:44:07 +01:00
Paul Chote
36c3e07535 Remove CRLF from GameServer.cs. 2018-01-01 21:12:58 +01:00
Paul Chote
58547fda89 Guess mod titles based on other versions, if they exist. 2018-01-01 21:12:58 +01:00
Paul Chote
73da5e7a20 Fix d2k ingame-client tooltip background. 2018-01-01 22:12:09 +02:00
Paul Chote
7f20d1474d Fix RA aircraft prerequisites. 2018-01-01 19:40:38 +01:00
Paul Chote
ee728be537 Fix WithCargo crash. 2018-01-01 19:25:50 +01:00
Paul Chote
7b056509ec Don't try to remove tooltips that haven't been added. 2018-01-01 18:23:16 +02:00
Paul Chote
2eb090f153 Fix actors disappearing for a tick when swapping to the frozen actor. 2018-01-01 16:01:44 +01:00
Paul Chote
f8abd5d319 Serialize the correct player in FrozenActor-targeting orders. 2018-01-01 16:01:44 +01:00
Paul Chote
b3cde077fc Don't break the order stream if a frozen actor refers to a bogus player. 2018-01-01 16:01:44 +01:00
Paul Chote
47fa9e496d Fix tooltips not showing for frozen actors with dead backing actors.
This also documents some old bugs.
2018-01-01 16:01:44 +01:00
abcdefg30
19a9c70d5c Fix the communications center being on low power 2018-01-01 15:49:56 +01:00
abcdefg30
94a062b3e7 Properly unload passengers in nod05
Also lets the transport fly out of the map
2018-01-01 15:49:56 +01:00
Andrii Yukhymchak
11db40a2b3 Fixed issue with unit ready when capturing 2018-01-01 12:52:47 +00:00
Paul Chote
dec11f4fa0 Force spectator color to white to avoid spoofing by the server. 2018-01-01 11:25:08 +01:00
Paul Chote
ae394f937b Fix the color validator overriding spectator colors. 2018-01-01 11:25:08 +01:00
Paul Chote
3353215b66 Add a total player count to the MP browser. 2018-01-01 11:12:27 +01:00
Paul Chote
cd6dfd2185 Work around the "BUG: in order targeter" game chat warning. 2018-01-01 10:48:03 +01:00
Paul Chote
e70b61c4b0 Fix Chrono Tanks telesporting towards (0,0) when force-moving to an actor. 2018-01-01 10:48:03 +01:00
Mustafa Alperen Seki
2f6bbd906b Ignore Silos for SW Targeting on Harkonnen Missions
Also Defences for Saboteur
2017-12-31 12:02:13 +01:00
reaperrr
8fe45cb894 Fix surface ships except transport being unable to exit ship yard 2017-12-31 08:36:37 +02:00
FrameLimiter
61df53ea82 Fixes civilian panic from civ building explosion
The Civilian building explosions were not making the civilians panic.
2017-12-31 03:26:17 +01:00
abc013
38c4c10c73 Added Allies-06b to the Red Alert mod 2017-12-31 02:51:03 +01:00
Mustafa Alperen Seki
1aa57cd5b1 Fix an owner change for Smugglers on Har6s. 2017-12-30 21:30:10 +01:00
Mustafa Alperen Seki
b7830d97f2 Add Harkonnen9b 2017-12-30 21:30:10 +01:00
Mustafa Alperen Seki
a80924ebb3 Add Harkonnen 8 2017-12-30 20:18:37 +01:00
Mustafa Alperen Seki
69e9b94c5d Add Campaign Tooltip to D2K 2017-12-30 17:40:09 +01:00
Paul Chote
45f346c004 Fix label offsets. 2017-12-30 17:03:58 +01:00
Paul Chote
7fba6a2155 Add a view-only server list tab to the multiplayer lobby. 2017-12-30 17:03:58 +01:00
Paul Chote
235b16d4b3 Split server list logic into its own LogicObject. 2017-12-30 17:03:58 +01:00
reaperrr
4ef11f2763 Fix TD Orca missiles alternating between offsets
This is now properly fixed by using Burst: 1.
2017-12-29 15:28:34 +00:00
reaperrr
b3c3c7b414 Make RA heli weapons alternate between offsets
Instead of using one for AG-only and one for AA-only.
2017-12-29 15:28:34 +00:00
reaperrr
9b629a8f39 Remove dysfunctional TS yaml hacks
In addition to now being redundant due to Armament-side cycling through LocalOffsets, these didn't work because Burst is reset once ReloadDelay is reached, so that equal BurstDelay never really had the intended effect.
2017-12-29 15:28:34 +00:00
reaperrr
cefe3d2c8f When Armament has multiple LocalOffsets but weapon has Burst: 1, cycle through offsets 2017-12-29 15:28:34 +00:00
Mustafa Alperen Seki
9871abe562 Make crushable conditional 2017-12-29 15:25:38 +00:00
Paul Chote
14f6601f2b Tweak wording of playtest notice. 2017-12-29 02:56:50 +01:00
Paul Chote
1d8b2a9a08 Replace contrast with shadow on main menu version label. 2017-12-29 02:56:50 +01:00
Paul Chote
5c53172ab0 Add an update warning to the main menu. 2017-12-29 02:56:50 +01:00
Paul Chote
3effa5cec4 Add a setting to disable version checks. 2017-12-29 02:56:50 +01:00
Paul Chote
0208d0cc10 Move the version check code to WebServices and run only on first launch. 2017-12-29 02:56:50 +01:00
FrameLimiter
759bd044ed Moved Chinook entry/exit points to edge 2017-12-29 01:29:32 +01:00
FrameLimiter
4cdab30c48 Added an entry delay to insertion transport 2017-12-29 01:29:32 +01:00
FrameLimiter
98ec28e850 Fixes the chinooks not being removed in Nod04b
∙The entry/exit points for the Chinooks were out bounds.
∙The rally/unload points for the Chinooks were very close together and causing unloaded cargo to overlap.
2017-12-29 01:29:32 +01:00
Paul Chote
ef680dbbfe Add tooltips to the password icon and player count. 2017-12-28 22:42:50 +01:00
Paul Chote
0eaec5d861 Add an animated reload glyph to the MP server refresh. 2017-12-28 22:42:50 +01:00
Mustafa Alperen Seki
7014393211 Move Generic Prefixes to yaml and add prefix for Neutral 2017-12-28 12:00:53 +00:00
Mustafa Alperen Seki
841c873276 Fix Crash when Mcv: UnitsCommonName is empty. 2017-12-28 11:36:44 +00:00
TheChosenEvilOne
15354f52c1 Added FACT unpack checkbox to ra/cnc/ts. 2017-12-28 11:22:29 +00:00
TheChosenEvilOne
1a947907d3 Make Transforms a PausableConditionalTrait. 2017-12-28 11:22:29 +00:00
reaperrr
3d4095cffd Make sure AttackOrFlee returns Attack when it makes sense
Not listing enemy "NearDead" and own relative atk power "Strong" here looked wrong, and might've resulted in no decision being made.
2017-12-28 11:00:18 +00:00
reaperrr
104148378f Remove some redundancy in AttackOrFleeFuzzy 2017-12-28 11:00:18 +00:00
reaperrr
6b567722b8 Factor number of bursts plus ReloadDelay into AttackOrFleeFuzzy.RelativePower 2017-12-28 11:00:18 +00:00
reaperrr
a4595af1e3 Make AttackOrFleeFuzzy consider all DamageWarheads instead of only the first 2017-12-28 11:00:18 +00:00
reaperrr
382c0b5f1d Make AI StateBase.CanAttackTarget only return true on valid armaments that are also enabled 2017-12-28 10:40:31 +00:00
reaperrr
e6835cef6e Replace some .Any checks with explicit .Count checks in AI 2017-12-28 10:40:31 +00:00
reaperrr
3fe808e0fb Make Ground and Navy AI squads look for enabled (instead of any) targetables 2017-12-28 10:40:31 +00:00
reaperrr
6de90b02d0 Unhardcode various AI squad radii 2017-12-28 10:40:31 +00:00
Arular101
eefaf23885 Fix global-bounty warnings 2017-12-28 10:23:23 +00:00
reaperrr
1bac76fdd1 Remove redundant custom Duration from Bomber John Chronoshift power
The MNLYR has ReturnToOrigin: false anyway, so this was redundant and made no difference whatsoever.
2017-12-28 10:04:43 +00:00
reaperrr
f0ee87f078 Upgrade TS rules to SupportPower seconds -> ticks 2017-12-28 10:04:43 +00:00
reaperrr
7fb595a437 Upgrade D2k rules to SupportPower seconds -> ticks 2017-12-28 10:04:43 +00:00
reaperrr
88704ebac6 Upgrade TD rules to SupportPower seconds -> ticks 2017-12-28 10:04:43 +00:00
reaperrr
aa6ddc6a6e Upgrade RA rules to SupportPower seconds -> ticks 2017-12-28 10:04:43 +00:00
reaperrr
b70e4de5ee Refactor support powers to use ticks instead of seconds for all delays - code changes
Also renamed ChargeTime to ChargeInterval.
2017-12-28 10:04:43 +00:00
Arular101
3d62b1f9b3 Adjusted Minigun damage vs wood to match current damage after multiplying by 100. From 8 * 0.6 = 4.8 (actual value is 4) to 800 * 0.5 = 400 2017-12-28 10:12:52 +01:00
Arular101
4ea6a3c18c Small adjustments 2017-12-28 10:12:52 +01:00
Arular101
e734668f56 Upgrade rules for increasing HP and damage by 100x for the TS mod 2017-12-28 10:12:52 +01:00
Arular101
be89ce9efd Add myself to authors 2017-12-28 10:12:52 +01:00
Arular101
ede72410ff Increase damage and HP by 100x 2017-12-28 10:12:52 +01:00
C. Helmig
3a9ee8d51a Fixes mines not being auto-targeted even if revealed. 2017-12-28 08:06:14 +01:00
Paul Chote
27beed402f Display information banners in the MP server browser.
Notices are provided for outdated / unknown mod versions
and latest but playtest available.
2017-12-28 03:40:41 +01:00
Paul Chote
e7ce9aa263 Unhardcode server ping/query URLs. 2017-12-28 03:40:41 +01:00
Michael Silber
86a17e9260 Added TS map They All Float (Westwood). Part of Issue #12518
Added me (frühstück) to AUTHORS
2017-12-27 22:09:09 +01:00
Paul Chote
c6ad768a76 Remove redundant powerdown conditions. 2017-12-27 20:18:27 +01:00
Paul Chote
5425a5a28e Replace CanPowerDown with ToggleConditionOnOrder. 2017-12-27 20:18:27 +01:00
Michael Silber
b8ec20a010 Carryall pickup indicator set to top, left corner 2017-12-27 19:07:44 +00:00
Michael Silber
c445a20acf D2K carryall pickup indicator offset fix 2017-12-27 19:07:44 +00:00
Mustafa Alperen Seki
7f77e4cf40 Remove ProductionDoorOverlay while transforming 2017-12-27 13:50:58 +00:00
Mustafa Alperen Seki
acf25354b0 Consider BuildAtProductionType for exit types too for normal ProductionQueue 2017-12-27 13:46:20 +00:00
Mustafa Alperen Seki
5ac0625f97 Add /kill and /dispose chat commands 2017-12-27 13:26:38 +00:00
Mustafa Alperen Seki
fc07391c8c Add Type Support for InfiltrateFor* traits 2017-12-27 11:13:09 +00:00
Mustafa Alperen Seki
f7de5d46be Allow GrantConditionOnPrerequisite to work on Player: 2017-12-27 02:31:07 +01:00
Matthias
7b6b79493c Replace @ with new lines in legacy map briefing sections 2017-12-27 02:12:58 +01:00
Michael Silber
a3b186ccbc Burnt Trees using RadarColor from trees; issue #14582 2017-12-26 23:45:37 +01:00
Paul Chote
c73ce50a09 Include bots in the player count for consistency with the sidebar. 2017-12-26 20:05:38 +01:00
Paul Chote
8fc2caa01a Change the "Empty" filter to not discard servers that have only spectators. 2017-12-26 20:05:38 +01:00
Paul Chote
bccc0f8f17 Add a player list to the MP server browser. 2017-12-26 20:05:38 +01:00
Paul Chote
3ba610b535 Implement new master server ping protocol. 2017-12-26 20:05:38 +01:00
Paul Chote
a3882501b1 Ignore malformed LAN advertisements instead of crashing.
This matches the behaviour for online game handling.
2017-12-26 20:05:38 +01:00
Paul Chote
ec97214c16 Fix ProductionOverlay crash. 2017-12-25 21:34:31 +01:00
Unknown
4be593123d add me (jongleur1983) to AUTHORS
#14558: MovingToRefinery takes actor instead of CPos

DeliveryOffset (previously added by the harvester) is now taken into account by the AutoCarryable
fix whitespaces
2017-12-25 03:52:44 +01:00
Peter Amrehn
73bd80ebc5 #14542: order CarrryAll to the target's location, not to 0,0
(which is in order.TargetLocation
#14542: don't use deprecated TargetActor property, replace by

Target.Actor.Location
2017-12-25 03:52:44 +01:00
Matthias
ebd8a2b193 Adhere to the ZeroBranePackage conventions. 2017-12-24 10:35:13 +00:00
Paul Chote
0b446167b6 Unify and tweak layout of MP browser window. 2017-12-24 01:47:44 +01:00
Paul Chote
959804b167 Restore separated server creation dialog.
This also adds details about advertising and configuration.
2017-12-24 01:47:44 +01:00
Paul Chote
5256fb7bbd Restore separated direct connect dialog. 2017-12-24 01:47:44 +01:00
Paul Chote
205c45198c Remove secondary AllowPortForward setting.
The global setting is fine, and this simplifies
both the code and the UI.
2017-12-24 01:47:44 +01:00
abcdefg30
38cb3dea05 Make vehicles spawn husks with a neutral owner 2017-12-24 00:41:15 +01:00
abcdefg30
a6258485c9 Add a "EffectiveOwnerFromOwner" property to change the effective owner of a spawned actor 2017-12-24 00:41:15 +01:00
abcdefg30
b99d21b818 Add support for carrying effective owners over to husk actors 2017-12-24 00:41:15 +01:00
abcdefg30
b9987dcbda Add a fallback to InternalOwner if the victim was defeated 2017-12-24 00:41:15 +01:00
abcdefg30
d4d9959159 Let Husk implement IEffectiveOwner 2017-12-24 00:41:15 +01:00
abcdefg30
eab93ccf97 Add an EffectiveOwnerInit 2017-12-24 00:41:15 +01:00
abcdefg30
503b91d391 Remove an unused using 2017-12-24 00:41:15 +01:00
abcdefg30
bd52e56aaf Add the possibility to deny spawning actors for dead players 2017-12-24 00:41:15 +01:00
RoosterDragon
e42e766bb6 Prevent incorrect usage of ModelRenderer.
Force BeginFrame/EndFrame to be called correctly, and prevent calls to RenderAsync when outside of a frame.
2017-12-23 22:58:17 +01:00
Paul Chote
4c64a37e1d Reject invalid orders from unvalidated clients. 2017-12-23 21:48:59 +01:00
Mustafa Alperen Seki
e2f3989f46 Fix that conditions for InitialUnits are not given 2017-12-23 21:22:31 +01:00
Mustafa Alperen Seki
65e4019424 Update some prerequisites to include subfactions too 2017-12-23 18:35:01 +00:00
Mustafa Alperen Seki
4490eb3a2a Change Smuggler Starport and Merc HFac Cameo to use Ordos ones 2017-12-23 18:28:00 +00:00
Mustafa Alperen Seki
d762411b95 Update D2K voice and notifications to include subfactions 2017-12-23 18:28:00 +00:00
Mustafa Alperen Seki
395eb36cd1 Update D2K FactionImages
Default is now Ordos, as there are 3 ordos subfactions and 2 for others.
Fremen now uses Atreides Structures as in original, rather than
Harkonnen
2017-12-23 18:28:00 +00:00
reaperrr
fbc18dfb18 Use HashSet instead of IEnumerable to pass actors to renderable lists 2017-12-23 17:56:11 +00:00
reaperrr
04fb0f209d Spatially partition some actor overlays 2017-12-23 17:56:11 +00:00
reaperrr
6ef95405bf Split overlay renderable generation to separate list
To make the code a bit more readable and consistent with normal renderables.
2017-12-23 17:56:11 +00:00
Paul Chote
4993e74748 Fix SelectionBox line depths. 2017-12-23 17:32:07 +00:00
Paul Chote
2794b14f52 Calculate actor preview bounds directly. 2017-12-23 17:16:13 +00:00
Mustafa Alperen Seki
7bf3d5d7f6 Fix Cruiser's Turret 2017-12-23 13:16:41 +01:00
Mustafa Alperen Seki
27cc487575 Add Harkonnen 9a 2017-12-22 12:22:08 +01:00
abcdefg30
3af3299921 Fix a crash in PlaceBuilding.cs 2017-12-22 09:06:27 +00:00
reaperrr
41dd7ca428 Fix NukeLaunch being displayed too early
Adding it to ScreenMap from the ctor unconditionally didn't mesh well with potentially being added to world with a delay.
2017-12-22 04:17:18 +02:00
Paul Chote
028f7c6546 Adjust TD airstrike targeting to account for limited visibility. 2017-12-22 02:33:25 +01:00
Paul Chote
2ad42b6a7e Account for visibility when selecting AI superweapon targets. 2017-12-22 02:33:25 +01:00
Paul Chote
9dc330b300 Update FrozenActor TargetTypes alongside other variable state. 2017-12-22 02:33:25 +01:00
Paul Chote
b9e03ac009 Add FrozenActorLayer.FrozenActorsInRegion. 2017-12-22 02:33:25 +01:00
Paul Chote
b221787350 Allow CellRegions to be created with MPos. 2017-12-22 02:33:25 +01:00
Paul Chote
d24d80f483 Update minigames for bounty checkbox. 2017-12-21 23:52:04 +01:00
Paul Chote
cd4f54ade3 Add Kill Bounties checkbox to RA. 2017-12-21 23:52:04 +01:00
Paul Chote
1a73a2578b Make GivesBounty conditional. 2017-12-21 23:52:04 +01:00
Paul Chote
e79680e22c Add LobbyPrerequisiteCheckbox trait. 2017-12-21 23:52:04 +01:00
Pavel Penev
f8b75bbed4 Fixed HarvesterInsurance assuming all refineries get free harvesters via FreeActorWithDelivery 2017-12-21 21:55:55 +00:00
Mustafa Alperen Seki
956dbb762c Add Harkonnen 7 2017-12-21 22:54:57 +01:00
reaperrr
14c608786d Fix ReloadAmmoPool upgrade rule 2017-12-21 21:29:51 +02:00
Paul Chote
cfb293a53a Add a pull request template with important contributor information. 2017-12-21 21:04:37 +02:00
Paul Chote
ec4cf0646f Rewrite Serialize to improve clarity. 2017-12-21 20:01:14 +01:00
Paul Chote
5b51261dd3 Serialize the correct target type. 2017-12-21 20:01:14 +01:00
Paul Chote
9c88fc154f Remove redundant switch from order serialization. 2017-12-21 20:01:14 +01:00
RoosterDragon
987d0b77ac When dumping syncable traits, use a struct for the synced values.
Since most traits have few syncable members, this allows us to avoid allocating an array whose lifetime is only a few ticks long. For traits with more members, we fall back to allocating the array.
2017-12-19 22:01:08 +02:00
RoosterDragon
ca01a1f186 Presize MemoryStream when possible.
Also use GetBuffer when we know we have presized the stream to the exact required size to prevent a needless copy.
2017-12-19 00:59:11 +01:00
RoosterDragon
5d8c9a560a Release audio resource for video when StopVideo is called. 2017-12-19 00:57:58 +01:00
RoosterDragon
3f8c1ad5df Don't allocate a full-sized array when creating a VertexBuffer.
We can allocate a much smaller zeroed buffer and copy that multiple times in order to zero the memory. When creating large VertexBuffers, this caps our temporary allocation size significantly.
2017-12-19 00:57:02 +01:00
Paul Chote
c269525397 Fix support power tooltip time coloring. 2017-12-19 00:55:09 +01:00
Mustafa Alperen Seki
77ef13816f Add 4PLAY10 2017-12-18 23:19:44 +00:00
Mustafa Alperen Seki
09f4c6339e Add 4PLAY8 2017-12-18 23:15:45 +00:00
Mustafa Alperen Seki
2251078dde Add 4PLAY5 2017-12-18 23:11:04 +00:00
Mustafa Alperen Seki
365251f845 Add 4PLAY1 2017-12-18 23:09:15 +00:00
Mustafa Alperen Seki
c6f0b3e1a0 Add 2PLAY14 2017-12-18 23:07:28 +00:00
Mustafa Alperen Seki
31206de855 Add 2PLAY11 2017-12-18 23:04:43 +00:00
Mustafa Alperen Seki
fe3534ebcd Add 2PLAY9 2017-12-18 23:02:29 +00:00
Mustafa Alperen Seki
0dd52acd98 Add 2PLAY4 2017-12-18 23:00:04 +00:00
Mustafa Alperen Seki
a36242d524 Add 2PLAY3 2017-12-18 22:57:32 +00:00
Mustafa Alperen Seki
ecc09256d8 Add 2PLAY5 2017-12-18 22:54:38 +00:00
Mustafa Alperen Seki
fe01afe794 Move Update Queue to bottom on Player.yaml and ingame-player.yaml 2017-12-18 19:22:07 +00:00
Mustafa Alperen Seki
6f41be209c Allow all upgradable structures to build upgrades. 2017-12-18 19:22:07 +00:00
Paul Chote
e35e93557c Remove obsolete NearestCellTo helper. 2017-12-18 07:47:15 +00:00
Paul Chote
30cafcbc25 Use Util.AdjacentCells to determine ExternalCapture validity.
This matches the set of cells targeted by MoveAdjacentTo.
2017-12-18 07:47:15 +00:00
reaperrr
85c54e04d9 Replace LINQ in AirStates.CountAntiAirUnits 2017-12-17 21:18:44 +00:00
reaperrr
01a88862b3 Remove IDisable for good 2017-12-17 21:18:44 +00:00
reaperrr
c1cba4ecc1 Make Gate more independent from Building and pausable-conditional
Replace Gate IsDisabled checks with IsTraitDisabled/Paused checks
2017-12-17 21:18:44 +00:00
reaperrr
383840135f Replace IsDisabled checks in production with IsTraitPaused/Disabled checks
Note: We might want to separate IsTraitDisabled checks later (possibly make the latter cancel the currently produced item), but that can be done in a follow-up.
2017-12-17 21:18:44 +00:00
reaperrr
3aa8b3ae29 Remove unit.IsDisabled check from AirStates 2017-12-17 21:18:44 +00:00
RoosterDragon
be761de768 Compute map UIDs without copying all data to a MemoryStream.
We can use MergedStream to create a single combined stream with all the input and pass this to the hash function. This saves copying all the data into a MemoryStream to achieve the same goal, which requires more memory and allocations.
2017-12-17 19:20:12 +01:00
Paul Chote
49f0e4ebcf Fix incorrectly named lobby option properties. 2017-12-17 14:51:10 +02:00
Paul Chote
1a405b17ba Register the current mod even if LaunchPath is bogus. 2017-12-17 04:21:17 +01:00
RoosterDragon
a9d1d374b8 Remove draw line 2D helper method.
Callers can provide 3D points easily, and this avoids the need to allocate and slow down enumeration via the points.Select(p => new float3(p, 0)) wrapper.
2017-12-17 01:51:51 +01:00
RoosterDragon
de38313579 Cache VariableExpressions on load.
Compiling these expressions is sadly expensive, and we needed new ones for every trait on every actor each time one was generated. The expressions thankfully can be shared as they are pure functions, which removes this overhead.
2017-12-17 01:42:21 +01:00
RoosterDragon
bf21fc5213 Use StringComparison.Ordinal for StartsWith checks in TechTree.cs. 2017-12-17 01:28:25 +01:00
RoosterDragon
13edaefcac Avoid LINQ when building map domains. 2017-12-17 01:28:25 +01:00
RoosterDragon
dd2ae9fe5e Avoid LINQ in some Tick methods.
As Tick is called often, avoiding allocation overhead in these methods is useful.
2017-12-17 01:28:25 +01:00
Kevin Hinton
86f9b8807e Add EffectiveOwner to Lua Scripting API. 2017-12-16 18:00:41 +00:00
FrameLimiter
72a11ec2a5 Removed duplicate values in defaults.yaml 2017-12-16 17:45:33 +00:00
FrameLimiter
60633dfdf2 Removed duplicate values in civilian.yaml 2017-12-16 17:45:33 +00:00
FrameLimiter
a6dc9c3b21 Removed duplicate value in allies-01 rules.yaml 2017-12-16 17:45:33 +00:00
RoosterDragon
5b51f2a0fa Avoid format strings in some places.
Where it is possible to directly concat strings, prefer this in some often-called methods.
2017-12-16 17:26:29 +01:00
RoosterDragon
f78c3bef33 Allow VS 2017 to format solution file. 2017-12-16 17:25:55 +01:00
RoosterDragon
c8c7629bce Convert some stray spaces to tabs. 2017-12-16 15:53:03 +00:00
Paul Chote
502c3e2bf5 Remove global chat integration. 2017-12-13 21:04:16 +01:00
GSonderling
488cec64b8 Added support for filtering exits by production type. 2017-12-13 04:08:52 +01:00
Arular101
1bf59e885d Upgrade rules for increasing HP and damage by 10x for the D2K mod 2017-12-12 23:56:25 +01:00
Arular101
50185d3ccd Small adjustments 2017-12-12 23:56:25 +01:00
Arular101
64a3187fd1 Increase damage and HP by 10x 2017-12-12 23:56:25 +01:00
Arular101
a1b3fe2bda Parabombs tooltip for airfield
with selection grouping
2017-12-12 23:14:30 +01:00
Arular101
56634564f2 Parabomb tooltip fixes 2017-12-12 23:14:30 +01:00
Mustafa Alperen Seki
fd1aa07f83 Adjust D2K Building Selection Boxes 2017-12-12 23:02:55 +01:00
Paul Chote
3ad6a87920 Center the vertical alignment of lobby options if less than the panel height.
This also enables an extra row to be shown before triggering the scroll bar.
2017-12-12 22:43:11 +01:00
Paul Chote
3f67feab0e Rename boolean LobbyOption fields. 2017-12-12 22:43:11 +01:00
Paul Chote
36fccbc453 Add Checkbox/Dropdown to lobby options yaml fields. 2017-12-12 22:43:11 +01:00
Paul Chote
ea32c758eb Expose default UI labels and tooltips to yaml. 2017-12-12 22:43:11 +01:00
Paul Chote
99908c4d80 Move hardcoded list of lobby options into yaml. 2017-12-12 22:43:11 +01:00
Paul Chote
2e24c14503 Make SpawnMPUnitsInfo fields readonly. 2017-12-12 22:43:11 +01:00
Paul Chote
2c17780b94 Make ShroudInfo fields readonly. 2017-12-12 22:43:11 +01:00
Paul Chote
763630f547 Make DeveloperInfo fields readonly. 2017-12-12 22:43:11 +01:00
Paul Chote
97cdce7448 Add additional metadata to lobby options. 2017-12-12 22:43:11 +01:00
Arular101
b71b2ad523 Upgrade rules for increasing HP and damage by 100x for the TD mod 2017-12-12 22:18:41 +01:00
Arular101
7ad989fc43 Adjust values in custom maps and missions 2017-12-12 22:18:41 +01:00
Arular101
4e62531b11 Adjust values to match current damage 2017-12-12 22:18:41 +01:00
Arular101
2e681ba674 Increase damage and HP by 100x 2017-12-12 22:18:41 +01:00
Arular101
917d6b7627 Upgrade rules for increasing HP and damage by 100x for the RA mod 2017-12-12 20:50:27 +01:00
Arular101
261126194c Balance changes from #14471 2017-12-12 20:50:27 +01:00
Arular101
8069247726 Adjust values in custom maps and missions 2017-12-12 20:50:27 +01:00
Arular101
a429a62bf9 Adjust values to match current damage 2017-12-12 20:50:27 +01:00
Arular101
e049452f22 Increase damage and HP by 100x 2017-12-12 20:50:27 +01:00
RoosterDragon
7760c41bd9 Avoid array resizing in OpenAlAsyncLoadSound.
- Where it is accessible, use the length of the stream to presize the MemoryStream to the correct size.
- Instead of copying out the result via ToArray, grab the underlying buffer via GetBuffer and use that to create the sound source.

This avoids extraneous copying of the array containing the audio.
2017-12-12 00:01:04 +01:00
RoosterDragon
0899d02377 Avoid allocations when generating RadarSignatureCells.
The RadarWidget can supply a reusable buffer to each trait to avoid individual traits having to return new enumerables. Additionally, this allows the two traits to avoid LINQ and further allocations as they can manually enumerate and populate the buffer themselves.
2017-12-12 00:00:51 +01:00
Mustafa Alperen Seki
c69df4eedf Make subfactions use UI for their main faction
So it won't crash if a human player uses them.
2017-12-11 23:43:10 +01:00
Paul Chote
6633483d12 Increase infantry mouse bounds to improve usability. 2017-12-11 19:45:07 +01:00
Paul Chote
55b6084b60 Add a lint test for conflicting Interactable and Selectable. 2017-12-11 19:45:07 +01:00
Paul Chote
c87409ed1a Remove legacy bounds code. 2017-12-11 19:45:07 +01:00
Paul Chote
bf57eceeec Select highest priority actor when not drag selecting. 2017-12-11 19:45:07 +01:00
Paul Chote
ff5b4b15b3 Introduce IDecorationBounds to replace Actor.SelectionOverlayBounds. 2017-12-11 19:45:07 +01:00
Paul Chote
6f5d035e79 Introduce IMouseBounds and split/rework mouse rectangles.
The render bounds for an actor now include the area covered
by bibs, shadows, and any other widgets. In many cases this
area is much larger than we really want to consider for
tooltips and mouse selection.

An optional Margin is added to Selectable to support cases
like infantry, where we want the mouse area of the actor
to be larger than the drawn selection box.
2017-12-11 19:45:07 +01:00
Paul Chote
8fcc80b05a Use IRender.ScreenBounds in ScreenMap.
Traits are now required to trigger a ScreenMap update whenever they
believe that their ScreenBounds have changed.
2017-12-11 19:45:07 +01:00
Paul Chote
fa65fef4d1 Add IRenderModifier.ModifyScreenBounds to support WithShadow. 2017-12-11 19:45:07 +01:00
Paul Chote
86bfe28ade Add ScreenBounds method to IRender interface.
This method is expected to return Rectangles that cover
the region where Renderables returned by Render may exist.
2017-12-11 19:45:07 +01:00
Paul Chote
46f6263061 Update ScreenMap state in a single pass at the end of the tick. 2017-12-11 19:45:07 +01:00
Paul Chote
373aaee004 Use World.(AddTo|RemoveFrom)Maps in Immobile/Building. 2017-12-11 19:45:07 +01:00
Paul Chote
9e18ec7314 Simplify ScreenMap bounds checking. 2017-12-11 19:45:07 +01:00
Paul Chote
cdc426d162 Add IActorPreview.ScreenBounds. 2017-12-11 19:45:07 +01:00
Paul Chote
29255c8e01 Add IModel.AggregateBounds and ModelAnimation.ScreenBounds.
The bounds define the smallest Rectangle that covers all
rotations of all frames within a model sequence.
2017-12-11 19:45:07 +01:00
Paul Chote
506b677527 Add ModelAnimation.IsVisible property. 2017-12-11 19:45:07 +01:00
Paul Chote
041431d966 Add ISpriteSequence.Bounds and Animation(WithOffset).ScreenBounds.
The bounds define the smallest Rectangle that covers all frames within a sequence.
2017-12-11 19:45:07 +01:00
reaperrr
85c5259361 Fix AI crashing when trying to make parachuted harvester search map for resources while mid-air 2017-12-11 01:55:18 +01:00
reaperrr
b5ffe17d60 Make AI skip harvester orders if map has no resources 2017-12-11 01:55:18 +01:00
reaperrr
9ad0d78cdd Make the AI only consider harvesters 'idle' if last resource search failed
Otherwise the AI would consider the harvester 'idle' in too many situations.
This way, the AI now only uses its own resource search algorithm if the next resource patch is too far away for the FindResources activity to find it.
2017-12-11 01:55:18 +01:00
reaperrr
4d553900cf Move up harv.IsEmpty check in HackyAI
This is a fairly cheap check, so we should perform it before the activity checks
2017-12-11 01:55:18 +01:00
RoosterDragon
70ffa99203 Fix some uses of Exts.IsTraitEnabled. 2017-12-11 01:46:41 +01:00
RoosterDragon
9241c0f8b7 Provide only one overload of IsTraitEnabled. 2017-12-11 01:46:41 +01:00
RoosterDragon
c75a866f0d Lazily allocate sheet builder in ModelRenderer.
Avoid allocating the sheet builder each frame until it is needed. For mods that do not need to render models, this avoids allocating a large buffer and backing sheet as it will never render to the sheet. For mods that do render models, but don't need any this frame, this avoids allocating a new SheetBuilder that will not be used.
2017-12-11 01:44:21 +01:00
RoosterDragon
ec84b61316 Reduce memory required in MovementClassDomainIndex
The number of distinct domains on a map is often dozens, or at most hundreds. We can use a ushort to represent this easily, and reduce the size of the backing storage required to track domain indicies over the whole map.
2017-12-11 01:41:07 +01:00
RoosterDragon
2dd1bd2d39 Initialize map inverse cell projections with capacity 1.
This prevents the capacity being set to 4 when the first item is added. For flat maps, the inverse projection will only ever be of size 1, thus this is sufficient capacity. For isometric maps, 1 is often sufficient, we only need more near height changes where the discontinuity means multiple cells may project back. We can pay for some reallocations to expand the size in these cases.

On flat maps, this reduces the memory required by the backing array 4x.
2017-12-11 01:38:17 +01:00
RoosterDragon
8ef8c60a1a Remove allocations when enumerating sync hashes on an actor.
Exposing Actor.SyncHashes as an array allows allocation free enumeration, we just need to adjust the SyncHash type to run the hash function.
2017-12-10 13:49:52 +00:00
RoosterDragon
5338784e45 Fix bad uses of FirstEnabledTraitOrDefault on TraitInfos.
These are not traits so this method does not work. We can use EnabledByDefault on the ConditionalTraitInfo instead.
2017-12-10 13:39:24 +00:00
RoosterDragon
7a7eed4fb7 Add FirstEnabledTraitOrDefault helper method.
This avoids the allocations caused by LINQ when using traits.FirstOrDefault(Exts.IsTraitEnabled). This is important in FrozenActorLayer.RefreshState which is called very often. We apply the new helper method to all areas using the old pattern. An overload that takes an array allows arrays to be enumerated without causing allocations.
2017-12-10 13:39:24 +00:00
Paul Chote
cb670d83b3 Set PredictedStance when changing stance from Lua. 2017-12-08 01:54:55 +01:00
reaperrr
1a20dd15cb Fix D2k hightech factory sprite offsets
To match original.
2017-12-08 02:41:11 +02:00
reaperrr
2218b1a078 Fix terrain type of d2k tile #401 2017-12-08 02:41:11 +02:00
reaperrr
ce88d50d9c Fix offset and animation speed of D2k refinery smoke overlay 2017-12-08 02:41:11 +02:00
Paul Chote
7ebea32be9 Remove hardcoded settings backend. 2017-12-08 01:29:15 +01:00
Paul Chote
eb3ab682e8 Remove unused hotkeys from each mod. 2017-12-08 01:29:15 +01:00
Paul Chote
b4c5346346 Migrate hotkey linter to HotkeyManager. 2017-12-08 01:29:15 +01:00
Paul Chote
74c390d1d0 Migrate input settings to HotkeyManager. 2017-12-08 01:29:15 +01:00
Paul Chote
2f79173044 Migrate hotkey consumers to HotkeyManager. 2017-12-08 01:29:15 +01:00
Paul Chote
35a3df3736 Duplicate default hotkeys in yaml. 2017-12-08 01:29:15 +01:00
Paul Chote
f98907f42e Add HotkeyManager class. 2017-12-08 01:29:15 +01:00
Paul Chote
811427adc4 Add HotkeyReference.IsActivatedBy method. 2017-12-08 01:29:15 +01:00
Paul Chote
c4237d6a1a Rename NamedHotkey to HotkeyReference. 2017-12-08 01:29:15 +01:00
abcdefg30
6dd42f7ab1 Replace bogus ROF values in missions 2017-12-07 20:44:41 +02:00
RoosterDragon
62ab6ae6f1 OccupiedCells and TargetableCells must return arrays, not just enumerables.
This allows callers to efficiently enumerate these returned collections without the allocation and overhead imposed by the IEnumerable interface. All implementations were already returning arrays, so this only required a signature change.
2017-12-07 20:39:30 +02:00
FrameLimiter
da036c5728 Fixes EditorTilesetFilter for T04 cactus 2017-12-05 21:32:28 +01:00
Smittytron
3d8ab75faf RA Balance changes (December 2017) 2017-12-05 12:38:13 +01:00
Paul Chote
9d2935935c Add a debug visualization for screen map rectangles. 2017-12-04 23:10:23 +01:00
Paul Chote
0f512088d2 Unify ingame-debug.yaml. 2017-12-04 23:10:23 +01:00
Paul Chote
1a1c6368fc Fix ScreenMap handling of flipped sprites. 2017-12-04 03:54:23 +02:00
Arular101
1b94378f71 Disable the new build radius lobby option for minigames 2017-12-02 20:26:23 +01:00
Mustafa Alperen Seki
f4086e4fe0 Update one of the dead worm tiles 2017-12-02 05:18:19 +01:00
Pavel Penev
77ae802b9c Added D2k asset installer d2k-e 2017-12-02 00:08:50 +01:00
Pavel Penev
8f5787a57f Added D2k asset installer d2k-d 2017-12-02 00:08:50 +01:00
Pavel Penev
45a2f5e6c1 Added D2k asset installer d2k-c 2017-12-02 00:08:50 +01:00
Pavel Penev
649971d517 Renamed D2k asset installers to systematize namings 2017-12-02 00:08:50 +01:00
Pavel Penev
450cbeea96 Added an extra bit of installer data to Install.log 2017-12-02 00:08:50 +01:00
Pavel Penev
e09d502ce1 Make mod launchers run the game inside a child launcher instead of via OpenRA.Game.exe
This also removes the need to manually set application icons on Windows.
2017-12-02 00:05:57 +01:00
Pavel Penev
bd67bd24c0 Pull out game loop initialization from OpenRA.Program into OpenRA.Game and exception handling into its own class under OpenRA.Game/Support 2017-12-02 00:05:57 +01:00
abcdefg30
f249554b4f Fix swapped waypoint naming in Survival 01 2017-11-30 02:00:43 +01:00
abcdefg30
53dabfeb49 Move all waypoints of Survival 01 inside the map bounds 2017-11-30 02:00:43 +01:00
abcdefg30
3a94312fcd Move all waypoints of Evacuation inside the map bounds 2017-11-30 02:00:43 +01:00
abcdefg30
616ee6cce4 Remove a misplaced camera actor 2017-11-30 02:00:43 +01:00
RoosterDragon
6a97502e09 Reuse buffers when loading Xcc databases.
We can reuse the list as a buffer when reading strings to avoid throwaway allocations, which will reduce GC pressure during loading.
2017-11-30 02:16:51 +02:00
reaperrr
c48ddbdfa5 Fix Mammoth Mk2 render bounds
And polish trait internals a little.
2017-11-29 11:39:24 +02:00
reaperrr
d21992130a Fix TS harvester render bounds 2017-11-29 11:39:24 +02:00
Paul Chote
4994716cf7 Ignore empty children when aggregating EventBounds. 2017-11-27 16:09:34 +02:00
dsimmons87
65a2410738 Fixed bug in map Retry Install
If the download failed, the map status would be MapStatus.DownloadError,
which would cause the Install method to return immediately. I've updated
the Install method now to account for MapStatus.DownloadError.
2017-11-27 15:18:33 +02:00
Paul Chote
8fea476a0d Fix NRE when ProvidesPrerequisite is defined on the player actor. 2017-11-26 19:51:46 +01:00
abcdefg30
ed67cea852 Fix a crash in Disguise.cs when order.TargetActor is null 2017-11-26 18:41:53 +01:00
abcdefg30
c83dda4ce7 Initialize AsActor as self.Info 2017-11-26 18:41:53 +01:00
abcdefg30
4c707ad6a6 Fix WithDisguisingInfantryBody crashing when losing the disguise 2017-11-26 18:41:53 +01:00
Arular101
02d57c5fee Soviet05 Radar Reveal
Added beacon and message
2017-11-26 17:26:57 +01:00
Mustafa Alperen Seki
2043576857 Add Modified Outpost tooltip to Ordos4. 2017-11-26 16:53:17 +01:00
Mustafa Alperen Seki
15b77f8d91 Add Harkonnen 5 2017-11-26 16:53:17 +01:00
Paul Chote
b898b5001a Rename AttackBase.IsAttacking to IsAiming to make its uses and assumptions clear. 2017-11-26 15:58:00 +01:00
Paul Chote
ea05221180 Count AttackStatus.NeedsToTurn as valid for AttackBase.IsAttacking. 2017-11-26 15:58:00 +01:00
Marwan
8a38c6ef23 WithTextDecoration Fix 2017-11-26 15:35:50 +01:00
Mustafa Alperen Seki
43d100246f Remove ^TowerHusk: 2017-11-26 15:26:44 +01:00
Mustafa Alperen Seki
73134b0417 Rename D2K vehicle husks 2017-11-26 15:26:44 +01:00
Smittytron
d5622ae1ca Fix TD cliff tiles 29-31 2017-11-26 15:17:38 +01:00
Arular101
3ed18f51e3 Fix V2 Rocket Launcher facings
Now with AmmoPool

V2 changes for Fort Lonestar
2017-11-26 15:01:43 +01:00
Paul Chote
855042894c Fix bogus cached PowerState for map placed actors. 2017-11-26 03:37:33 +01:00
reaperrr
5ec3ad0957 Fix turrets following target even if AttackTurreted is disabled or paused 2017-11-25 03:55:56 +02:00
reaperrr
e215c5019e Fix regressions introduced by #13998 2017-11-25 03:55:56 +02:00
reaperrr
6e59fe3bc2 Adapt TS to removal of IsDisabled checks from Attack* traits 2017-11-25 03:55:56 +02:00
reaperrr
456d32f3eb Make Attack* traits PausableConditional and replace IsDisabled with IsTraitDisabled checks 2017-11-25 03:55:56 +02:00
reaperrr
68487d1197 Replace turret IsDisabled check with AT.IsTraitDisabled check 2017-11-25 03:55:56 +02:00
reaperrr
cea2658f31 Remove IsDisabled from AffectsShroud traits
Makes them only disableable via conditions.
2017-11-25 03:55:56 +02:00
reaperrr
00cd7a8da5 Adapt TS to removal of actor IsDisabled check in Cloak 2017-11-25 03:55:56 +02:00
reaperrr
ede6d5a57d Remove Actor.IsDisabled check from Cloak
Makes cloaking only disableable via conditions.
2017-11-25 03:55:56 +02:00
Smittytron
9c729c77bc Add Real tough guy difficulty to Allies04 2017-11-24 00:35:39 +01:00
Paul Chote
7c901c27f1 Generate a versioned tarball during package creation. 2017-11-22 22:39:08 +01:00
Mustafa Alperen Seki
8ce460ad8c Fix badgers showing owner row on RA mod. 2017-11-22 18:24:50 +01:00
reaperrr
56b6aabbb8 Use new IAutoRenderSize for determining actor render bounds 2017-11-21 01:00:09 +02:00
reaperrr
2501a93b87 Remove superflous AutoSelectionSize from TS high bridge placeholder
It defines CustomSelectionSize, so AutoSelectionSize is redundant/wrong here.
2017-11-21 01:00:09 +02:00
reaperrr
5a596d27c9 Switch RenderNameTag to use SelectionOverlayBounds 2017-11-21 01:00:09 +02:00
reaperrr
6711af63eb Move SelectionBarsRenderable to Mods.Common 2017-11-21 01:00:09 +02:00
reaperrr
be290cfabd Split Actor.Bounds into RenderBounds and SelectableBounds
Additionally, internally renamed VisualBounds to SelectionOverlayBounds to avoid confusion with RenderBounds.

This step was necessary to prevent actors with selectable area smaller than their graphics to be removed too early from ScreenMap even though part of the graphics should still be visible.
RA cruisers were a prime example, but to a lesser extent several other actors were affected as well.

This separation also serves as preparation to determine the final RenderBounds from multiple source bounds later, to fix the remaining ScreenMap issues (building 'bibs', aircraft shadows).
2017-11-21 01:00:09 +02:00
Mustafa Alperen Seki
ca1448c7ba Add Support of Types for GivesBuildableArea 2017-11-20 16:17:13 +02:00
Paul Chote
4cbc2ee6f3 Add support for custom sell cursors. 2017-11-19 23:40:33 +01:00
Paul Chote
5030a2257e Delegate cursor selection to GlobalButtonOrderGenerator subclasses. 2017-11-19 23:40:33 +01:00
Arular101
586dd6541b More Changes 2017-11-19 23:23:24 +01:00
Arular101
9c61f524f0 Tooltip fixes 2017-11-19 23:23:24 +01:00
Paul Chote
10fb487abf Update macOS launcher/dependencies to latest tag.
This supports/forces the 64 bit mono runtime, and
is the first version that compiles all native code
using travis-ci.
2017-11-19 16:55:44 +00:00
Andre Mohren
25968ee66f Allow WithIdleOverlayInfo to render while the actor is being build. 2017-11-19 16:52:59 +00:00
Mustafa Alperen Seki
7b12cf887d Add Harkonnen 6b 2017-11-19 16:21:42 +01:00
Mustafa Alperen Seki
01c1e08bd8 Add Original Remap Palette for RA Mod Campaign
and Shellmap
2017-11-19 15:08:42 +01:00
Arular101
3e5829355d Small override fix mission Intervention 2017-11-19 13:48:42 +00:00
abcdefg30
48df21c4a5 Fix the insertion transport not being removed in allies03b
The exit was outside of the map's border
2017-11-19 14:42:37 +01:00
abcdefg30
8654bcc244 Fix the FreePrisoners objective being completed without freeing prisoners 2017-11-19 14:42:37 +01:00
abcdefg30
dddc5dc80f Capturing also fires OnRemovedFromWorld 2017-11-19 14:42:37 +01:00
abcdefg30
3e3d98c735 Resolve a TODO in allies03a.lua 2017-11-19 14:42:37 +01:00
Arular101
f16f9b8ae3 Allies06a Radar Reveal
Added beacon and message
2017-11-19 14:32:33 +01:00
Mustafa Alperen Seki
29ec16f15d Some changes to crate unit bonuses 2017-11-19 12:58:34 +00:00
FrameLimiter
1e94ded9dd Changed Warhead to Warhead@1Dam 2017-11-19 12:55:28 +00:00
FrameLimiter
edd9e39dcd Removed redundent LaunchAngle override on 8Inch 2017-11-19 12:55:28 +00:00
FrameLimiter
cfe1a8cd02 Removed the redundant overrides 2017-11-19 12:55:28 +00:00
FrameLimiter
e6f73dc68f Updated weapon trait names for drop-zone-w mission 2017-11-19 12:55:28 +00:00
FrameLimiter
c70efd4a14 Fixes PortaTesla Warhead override for drop-zone-tikiaki 2017-11-19 12:49:43 +00:00
FrameLimiter
b7c3bc4e25 Fixes PortaTesla Warhead override for drop-zone 2017-11-19 12:49:43 +00:00
RoosterDragon
471d7ae40d Run GC more during loading.
This helps reduce the peak GC size by trimming temporary loading garbage a bit more often, rather than just doing it at the end of loading.
2017-11-19 12:42:25 +00:00
RoosterDragon
a71a5cc71d Reduce the size of the sheets created for fonts.
- A 512x512 sheet is about half full after precaching and some usage, but uses 16x less memory than the default 2048x2048 sheet. This saving occurs twice as we maintain a managed buffer for this sheet.
- Only precache smaller fonts, as the larger fonts are less used and take up more space than is worthwhile.
- Only precache in white, as red is largely unused.
2017-11-19 12:40:04 +00:00
RoosterDragon
713cdaef5d Reduce allocations needed by ReplayConnection.
Packets from each chunk are now saved directly in an array, removing the overhead of a list. Additionally, a list is reused as a buffer for decoding packets into, preventing a new buffer from needing to be allocated for each chunk.
2017-11-19 12:11:38 +00:00
FrameLimiter
f4502e9aa7 Map editor fix for misplaced T09.Husk 2017-11-19 01:32:52 +01:00
FrameLimiter
a5d7218dee Removed TilesetOverride for desert tree husk t08 2017-11-19 01:29:30 +01:00
FrameLimiter
773a619d2d Palette fix for desert tree husks 2017-11-19 01:26:13 +01:00
Smittytron
20a25c2f5e TD disable DetectCloaked on low power 2017-11-18 16:06:25 +01:00
Smittytron
070c54d069 Disable DetectCloaked on low power Tesla Coil 2017-11-17 13:42:51 +01:00
abcdefg30
2836cec0a3 Fix reinforcements in Nod06a not playing a notification 2017-11-17 13:28:10 +01:00
Mustafa Alperen Seki
f35f6c0813 Move Sprite handling from Disguise to WithDisguisingInfantryBody 2017-11-15 15:48:24 +00:00
Mustafa Alperen Seki
ecdfcda43e Add DisguisedAsCondition 2017-11-15 15:48:24 +00:00
Arular101
3efce265a8 Reduce barrel explosion damage vs wood armor 2017-11-15 15:17:08 +00:00
Smittytron
9d45528496 Remove Airstrike from nod06a Normal Difficulty 2017-11-15 14:47:55 +00:00
Arular101
8bec765925 Campaign file changes and cleanup
Remove NoAutoTarget
2017-11-15 15:43:44 +01:00
Arular101
fd9cd78810 Fix spy voices 2017-11-15 15:20:34 +01:00
Mustafa Alperen Seki
bb600620a9 Add ShowTicks to InfiltrateForCash 2017-11-15 15:16:39 +01:00
Forcecore
c762453607 (External)Capturable are now conditional 2017-11-15 13:54:15 +02:00
reaperrr
a7620c97f0 Some internal renamings in power-related traits 2017-11-13 03:09:05 +02:00
reaperrr
7f5f2eac6f Don't scale RepairIndicator with zoom 2017-11-13 03:09:05 +02:00
reaperrr
d328b9b7d8 Adapt RA to low power/power-down refactor 2017-11-13 03:09:05 +02:00
reaperrr
bb790b83e6 Adapt TD to low power/power-down refactor
Removed CanPowerDown from TD buildings.

Manual power-down is intentionally not supported by the in-game UI, the remaining CanPowerDown entries were effectively bit-rot.
2017-11-13 03:09:05 +02:00
reaperrr
e0e1f56af5 Adapt D2k to low power/power down refactor 2017-11-13 03:09:05 +02:00
reaperrr
7537daf74e Adapt TS to power-related trait refactorings 2017-11-13 03:09:05 +02:00
reaperrr
99edc71c54 PowerDown/low power refactor upgrade rule 2017-11-13 03:09:05 +02:00
reaperrr
917c6884ed Make WithSpriteBody a pausable trait
Allowing to drop the PauseAnimationWhenDisabled property (in favor of using PausOnCondition).
2017-11-13 03:09:05 +02:00
reaperrr
786a0eb07f Refactor PowerManager and RequiresPower to use conditions
Instead of Actor.IsDisabled.
Added INotifyPowerLevelChanged interface to do so as efficiently as possible.
2017-11-13 03:09:05 +02:00
reaperrr
6c02e3f2b7 Refactor CanPowerDown to provide a condition instead of triggering IsDisabled 2017-11-13 03:09:05 +02:00
Pavel Penev
8d7eb0bc47 Fix order deserialization when there is no indended order subject 2017-11-13 00:37:44 +01:00
reaperrr
d602ec6485 Rename SelfReloads to AutoReloads 2017-11-12 19:48:06 +00:00
reaperrr
18c371d702 Changed AmmoCondition to support condition stacking 2017-11-12 19:48:06 +00:00
reaperrr
9dabc9d672 Upgrade rule for adapting to removal of Armament.OutOfAmmo 2017-11-12 19:48:06 +00:00
reaperrr
8b7a71685c Remove AmmoPool-awareness from Armament 2017-11-12 19:48:06 +00:00
reaperrr
ded92f394c Upgrade rule for AmmoPool.SelfReloads removal 2017-11-12 19:48:06 +00:00
reaperrr
6f95080aa4 Add ReloadAmmoPool and adapt AmmoPool
Refactored and simplified Rearm activity.
Uses local Reload now.

Removed AmmoPool.SelfReloads.
2017-11-12 19:48:06 +00:00
reaperrr
a017018bee Fix official mods Aircraft.RearmBuildings setups
Only aircraft that a) have an AmmoPool and b) don't auto-reload should define RearmBuildings.
2017-11-12 19:48:06 +00:00
Forcecore
d49c98ce18 Move activity implementation now uses ChildActivity 2017-11-12 19:46:05 +01:00
abc013
3092927a7f Added a visual explosion to e4 2017-11-12 18:34:03 +00:00
Smittytron
3ce6cac9f3 Clarify gdi07 Secondary Objective 2017-11-12 18:29:54 +00:00
Arular101
fdac023a8d Rename V2 Rocket to V2 Rocket Launcher 2017-11-12 18:26:46 +00:00
Andrii Yukhymchak
f4dbf55510 Chrono into map edge fix 2017-11-12 18:23:17 +00:00
Smittytron
e65ffc8be2 Change remaining Vulcan vs Light values to 50 2017-11-12 18:18:11 +00:00
Forcecore
ef878c6aeb Introduced CaptureTypes for TransformOnCapture 2017-11-12 18:14:30 +00:00
Mustafa Alperen Seki
3aa91a08cc Fix Fake Naval Yard's Name 2017-11-12 12:30:28 +00:00
Arular101
a8d27257eb Remove custom aud for cruiser in shellmap 2017-11-11 11:21:27 +01:00
Mustafa Alperen Seki
dadfc0b09c Fix AutoTargetPriority traits of ra infantry 2017-11-09 22:38:52 +02:00
abcdefg30
0377c8ae20 Replace bogus values in the Fort Lonestar rules 2017-11-09 22:24:14 +02:00
abcdefg30
eac9286b78 Fix tiling errors on some RA maps 2017-11-09 09:54:59 +01:00
Mustafa Alperen Seki
ba50fbba18 Dont show refund text if Sellable: trait is disabled. 2017-11-05 16:22:42 +02:00
Forcecore
4c78a05081 ADD GrantConditionOnAttack Trait
Useful for making Gattling weapons (Yuri's Revenge and C&C Generals) or
Boris (RA2) / Natasha (RA3) call for airstrike.
2017-11-04 17:18:24 +01:00
Mustafa Alperen Seki
8914227811 Add ShowTicks to sellable 2017-11-04 17:16:26 +01:00
Paul Chote
a3636c69d9 Update macOS launcher with space-in-filename metadata registration fix. 2017-11-04 16:23:41 +01:00
Paul Chote
faf2634e3d Upgrade mod rules. 2017-11-04 16:08:58 +01:00
Paul Chote
d2f0e5ac2d Replace Allow(Allies|Neutral|Enemies) with ValidStances enum. 2017-11-04 16:08:58 +01:00
Paul Chote
1caf982c1f Support multiple capture types on Capturable. 2017-11-04 16:08:58 +01:00
Mustafa Alperen Seki
77feb3f76d Add GPS Dots for Comm Center and Forward Command 2017-11-03 13:36:40 +01:00
Paul Chote
4fe7ffed85 Simplify and fix code quality in GpsDot. 2017-11-03 09:56:00 +01:00
Paul Chote
1376ad674e Remove Player.CanViewActor and .CanTargetActor. 2017-11-03 09:56:00 +01:00
Paul Chote
47634b25f9 Remove IFogVisibilityModifier. 2017-11-03 09:56:00 +01:00
Paul Chote
4dba9f5b88 Add RevealDisguiseType.Move. 2017-11-03 09:30:50 +01:00
Paul Chote
7afd219742 Expose Disguise ValidStances and TargetTypes to yaml. 2017-11-03 09:30:50 +01:00
Paul Chote
c9c7c5744c Explicitly implement interfaces in Disguise trait. 2017-11-03 09:30:50 +01:00
Mustafa Alperen Seki
bfe540cd8b Add Harkonnen 6a 2017-11-03 08:32:04 +01:00
abcdefg30
025d5c8d05 Fix the "Secure the convoy's path" objective being completed without securing a path 2017-11-03 07:54:48 +01:00
Mustafa Alperen Seki
817449c018 Fix Inconsistency with AcceptsDeliveredCash on RA mod 2017-11-01 20:41:00 +01:00
Andrii Yukhymchak
636a9a74a1 Font Crash gracious fallback 2017-11-01 18:50:15 +01:00
kosti1
6a750d7a65 Added buildradius checkbox to lobby options 2017-11-01 18:18:41 +01:00
Paul Chote
b8326bfead Fix crash with AllyRepair on dead structures. 2017-10-26 18:48:41 +03:00
Paul Chote
5f9a67ed87 Migrate frozen actors from ExtraData to Target. 2017-10-26 18:48:41 +03:00
Paul Chote
29c423772f Serialize order Target directly instead of TargetActor/TargetCell. 2017-10-26 18:48:41 +03:00
Andrii Yukhymchak
6e1c1eaa94 Submarine fix 2017-10-26 01:48:36 +02:00
Paul Chote
77a7453347 Improve WidgetUtils.WrapText performance on long lines. 2017-10-26 01:42:16 +02:00
Andre Mohren
88c94ee841 Allow remaining time to be hidden in ProductionPaletteWidget. 2017-10-26 01:31:32 +02:00
Andre Mohren
aadfcdac66 Allow RallyPoint cursor to be defined via Yaml 2017-10-26 01:28:42 +02:00
Andre Mohren
cfeeb6563e RallyPointIndicator now optional 2017-10-26 01:21:29 +02:00
abcdefg30
cba7c60f6f Fix the "Unit Ready" notification playing erroneously 2017-10-25 22:43:35 +01:00
Paul Chote
cfac996438 Generalize factionVariant to a TypeDictionary of Inits. 2017-10-22 03:32:21 +03:00
rob-v
315cc966f4 Clear team in lobby for spectators 2017-10-21 14:12:11 +01:00
Paul Chote
5540eb1f2f Specify C# 5 as the language version in the Makefile too. 2017-10-19 14:18:03 +02:00
RoosterDragon
3a9abda441 Specify C# 5 as the language version used in all projects.
Attempts to use features from a new version will generate compile errors (on Roslyn and possibly other compilers), preventing accidental adoption of new language features.
2017-10-19 14:18:03 +02:00
Pi Delport
7da7764a65 (Update my name) 2017-10-18 08:03:57 -05:00
Paul Chote
9bdedda43a Make float2 immutable. 2017-10-17 15:46:07 +02:00
Paul Chote
69b4b541d2 Fix mutable use of float2 in SpriteFont. 2017-10-17 15:46:07 +02:00
Paul Chote
bee3f33f5f Remove long dead ResourceBarStyle.Bevelled code. 2017-10-17 15:46:07 +02:00
Matthias
cdedd1c7ac Some packages have been renamed in openSUSE
tested with openSUSE Leap 42.3
2017-10-16 15:35:06 +02:00
Matthias
7675c87593 Nuget dependency was dropped in #13912 2017-10-16 15:35:06 +02:00
Sam Gleske
80ce6d9988 Update package-all.sh
- Remove subshells and instead use bash parameter expansion.
- Utilize a function with a subshell to make adding additional packages easy.
2017-10-16 15:12:42 +02:00
Matthias Mailänder
ebb982789e Display a blocked cursor when not allowed to MoveIntoShroud. 2017-10-16 14:38:26 +02:00
Matthias Mailänder
b27289106d Don't give an okay voice when not allowed to move into shroud. 2017-10-16 14:38:26 +02:00
Matthias Mailänder
d4340fa799 Add a MoveIntoShroud switch to AttackMove as well. 2017-10-16 14:38:26 +02:00
reaperrr
db2d432c39 Fix Helis facing target center instead of attacked position 2017-10-16 14:25:03 +02:00
reaperrr
95dbcc1273 Update upgrade rule dates
These were merged after the release preparation branch for release 20171014 was created.
2017-10-16 14:22:11 +02:00
Smittytron
5471a3e729 Assign Gunboat and Sub to Techlevel Low 2017-10-15 23:15:43 +02:00
Paul Chote
d967c564a2 Remove TargetActor and TargetLocation from order issuing. 2017-10-15 19:07:46 +02:00
Paul Chote
4896a90b8d Add plumbing to issue orders against a generic Target. 2017-10-15 19:07:46 +02:00
Paul Chote
19b2c33514 Remove unused code from AttackOrderPower. 2017-10-15 19:07:46 +02:00
Andre Mohren
10740de6e9 DefaultSpriteSequence now allows derived classes to enhance sprites. 2017-10-14 19:50:05 +02:00
Raffael Zica
f2b5040d30 YamlException is now thrown if WeaponInfo can not be found in Ruleset.Weapons
Removed invalid spacing at the end of the line 36 in ThrowsShrapnel

Prevented NullReferenceException in cases where weapons aren't optional
2017-10-14 14:12:08 +02:00
abc013
c8b2a7dc04 Changed Aircraft explosion 2017-10-14 13:59:59 +02:00
abcdefg30
7ccf41be77 Catch invalid default game speeds while loading the ruleset 2017-10-14 13:54:26 +02:00
gkaretka
97e0f17e15 Add notification sound when paratroopers land 2017-10-14 13:40:53 +02:00
abcdefg30
a8c6d12c43 Fix the map editor crashing on invisible actors 2017-10-14 13:35:33 +02:00
Paul Chote
0e3de71036 Add line limit to global chat. 2017-10-14 13:10:27 +02:00
Paul Chote
ef43d8a86f Add missing StringComparison to IngameChatLogic. 2017-10-14 13:10:27 +02:00
Paul Chote
75d4062698 Limit chat messages to 2500 characters. 2017-10-14 13:10:27 +02:00
Paul Chote
249e813444 Fix submarine autotarget behaviour. 2017-10-08 20:11:30 +02:00
Paul Chote
e3e5dc1b49 Fix Defend stance auto-targeting naval structures. 2017-10-08 20:11:30 +02:00
Paul Chote
f425cbe0a4 Fix double-chronoshift return location exploit. 2017-10-08 20:04:36 +02:00
Paul Chote
f96c2710cd Remove directory creation side effect from Platform.SupportDir. 2017-10-08 19:53:10 +02:00
abcdefg30
4bca0c4c24 Fix devastators being carryable while overloading 2017-10-08 18:48:28 +01:00
abcdefg30
49e1af7f3f Fix the devastator lint warnings 2017-10-08 18:48:28 +01:00
abcdefg30
0727f7e9ff Only lint system maps 2017-10-08 18:23:25 +01:00
abcdefg30
5fdb828b60 Log which maps are processed by UpgradeModCommand
Upgrading the maps can take quite some time,
and at the moment you are left without information if something is happening.
2017-10-08 18:23:25 +01:00
abcdefg30
98170b0452 Use MapCache.LoadMapsWithoutCaching in UpgradeModCommand 2017-10-08 18:23:25 +01:00
abcdefg30
27345c1f6a Fix map linting crashing for not existing directories 2017-10-08 18:23:25 +01:00
abcdefg30
24c293e821 Fix Cargo force-requiring ConditionManager 2017-10-08 13:32:22 +01:00
abcdefg30
2366490fa0 Add an domain index check 2017-10-08 13:08:51 +02:00
abcdefg30
f48ba0ff86 Find alternative landing spots for blocked reinforcements 2017-10-08 13:08:51 +02:00
DeadlySurprise
80bf36e1a8 Deprecate Actor.IsDisabled 2017-10-08 00:12:15 +02:00
abc013
fb74c8351f Change Road -> Bridge on bridge tiles 2017-10-07 10:27:18 +02:00
reaperrr
8533debc44 Require explicit INotifyAddedToWorld and INotifyRemovedFromWorld 2017-10-07 10:17:11 +02:00
reaperrr
8ec3d5ddb8 Require explicit ITickRender 2017-10-07 10:17:11 +02:00
reaperrr
0ce3c113e1 Require explicit ITargetableCells 2017-10-07 10:17:11 +02:00
reaperrr
7ca9679b34 Require explicit ITargetablePositions 2017-10-07 10:17:11 +02:00
Andre Mohren
edeb980f5b Implemented a percentual chance to play the ImpactSound to CreateEffectWarhead 2017-10-07 10:15:22 +02:00
Matthias Mailänder
5b16bb952f Count all zero images as valid. 2017-10-07 10:09:35 +02:00
Matthias Mailänder
a8288a38f8 Allow sprites with empty frames to pass the ShpTS checks. 2017-10-07 10:09:35 +02:00
Matthias Mailänder
d7323e07cc Avoid modData.MapCache during lint checks 2017-10-07 10:08:53 +02:00
Mustafa Alperen Seki
2102fad2b5 Add CashTricklerBar 2017-10-06 23:02:02 +02:00
Mustafa Alperen Seki
a4b0bf5c52 Make CashTrickler PausableConditional 2017-10-06 23:02:02 +02:00
Mustafa Alperen Seki
049096efd7 Add InitialDelay to CashTrickler 2017-10-06 23:02:02 +02:00
abc013
dfe2076826 Fix passive vehicles can become ranks 2017-10-06 22:24:24 +02:00
abc013
f84699454f Fix some tiling errors in the map Haos Ridges [RA] 2017-10-06 22:04:32 +02:00
abc013
8c387c3bcf Fix a tile error in map Asymetric Battle [RA] 2017-10-06 22:02:39 +02:00
Andre Mohren
4e45747b41 Game no longer crashes if no ResourceLayer is used. 2017-10-06 21:57:57 +02:00
Matthias Mailänder
d64a9e6afc Add Devastator reactor overload upon deployment 2017-10-06 18:14:17 +02:00
Matthias Mailänder
370ee0841f Add GrantsCondition to KillsSelf 2017-10-06 18:14:17 +02:00
Forcecore
18c6fe09db Sound and Animation support for DonateCash 2017-10-06 18:07:18 +02:00
Paul Chote
d170262e09 Fix yaml merging of nodes that define their own overrides. 2017-10-06 17:54:11 +02:00
Paul Chote
18f6317560 Add a unit test for merging duplicated yaml nodes. 2017-10-06 17:54:11 +02:00
abcdefg30
178e7afd30 Remove a tiny bit of duplication on the TS walls 2017-10-06 15:38:53 +02:00
Paul Chote
4aee91cd47 Remove unnecessary trait lookups when cloaking/decloaking. 2017-10-06 10:09:12 +02:00
gkaretka
cf4c16b6bb Add .idea to .gitignore 2017-10-04 11:20:19 +02:00
abc013
b55ae1dcf0 Fixed TS Hand of Nod lights 2017-10-03 13:52:06 +02:00
Paul Chote
a1347a7f32 Populate MapLocations from LoadMaps.
This ensures that the map locations won't be created by the utility
but means that LoadMaps must be called before attempting to use MapLocations.
2017-09-30 17:37:52 +02:00
Paul Chote
64afe4cfde Display (attack|assault)move-blocked cursor outside map bounds.
This makes them consistent with the regular move order.
2017-09-30 14:33:40 +02:00
Paul Chote
e93183f0eb Clamp out of bounds attack-move orders to the edge of the map. 2017-09-30 14:33:40 +02:00
Paul Chote
36af2107d6 Fix the attack move order generator activating with an empty selection. 2017-09-30 14:33:40 +02:00
Paul Chote
d8f53a9ccd Fix crash when selection contains destroyed actors. 2017-09-30 14:33:40 +02:00
Paul Chote
fa8ab19dfd Fix global chat history buffer timestamps. 2017-09-28 15:09:12 +02:00
reaperrr
9aaf800bca Require explicit INotifyActorDisposing 2017-09-28 13:14:08 +02:00
reaperrr
5026dfe5d3 Require explicit INotifyCreated 2017-09-28 13:14:08 +02:00
reaperrr
6f790938d0 Require explicit IGameOver 2017-09-28 13:14:08 +02:00
reaperrr
2b391d5724 Require explicit ICreatePlayers 2017-09-28 13:14:08 +02:00
reaperrr
d7c2c6afc4 Require explicit INotifySelected and INotifySelection 2017-09-28 13:14:08 +02:00
reaperrr
a8e6cd2604 Require explicit IRenderOverlay 2017-09-28 13:14:08 +02:00
Paul Chote
69daa7e7cc Don't draw mine overlay for single-cell fields. 2017-09-27 21:00:56 +02:00
Paul Chote
a0e028ee0e Fix mine field overlay extending to map corner for the first tick. 2017-09-27 21:00:56 +02:00
Paul Chote
cc17b7419a Add voice feedback when issuing a mine deploy order. 2017-09-27 21:00:56 +02:00
Paul Chote
1d6cd81690 Add mine deployment to the command bar. 2017-09-27 21:00:56 +02:00
Jean-Rémy Buchs
2b96c2ed78 Add RequiresCondition to ProvidesPrerequisite 2017-09-24 14:56:47 +01:00
rob-v
c9b4568117 Add Statistics options hotkeys 2017-09-24 15:32:02 +02:00
Forcecore
b86d632c8c Land activity now lets the actor to land midair
Midair, at the altitude of the target actor.
2017-09-24 15:03:20 +02:00
Matthias Mailänder
205c947670 Settings documentation is no longer aimed at server admins. 2017-09-24 14:18:20 +02:00
Matthias Mailänder
030c942f73 Describe SendSystemInformation so people know how to opt-out. 2017-09-24 14:18:20 +02:00
Matthias Mailänder
da02620c4e Add field description from current Settings wiki entry. 2017-09-24 14:18:20 +02:00
Matthias Mailänder
2cf102d81a Remove trailing spaces. 2017-09-24 14:18:20 +02:00
Matthias Mailänder
95278b1f07 Don't add the launch arguments to the settings documentation. 2017-09-24 14:18:20 +02:00
Matthias Mailänder
faad941714 git ignore the auto-generated settings documentation 2017-09-24 14:18:20 +02:00
Matthias Mailänder
7549abc516 Wiki publish the auto-generated settings documentation. 2017-09-24 14:18:20 +02:00
Matthias Mailänder
1d8a50cdab Add build script support for the settings documentation. 2017-09-24 14:18:20 +02:00
Matthias Mailänder
0018bf3063 Add start and stop repair overlay animation support. 2017-09-24 11:43:49 +01:00
RoosterDragon
7160c8a1a9 Allow multiple VocFormat streams.
VocFormat.GetPCMInputStream now returns independent streams, allowing multiple instances of the same source to be streamed.
2017-09-24 11:23:39 +01:00
RoosterDragon
7ed769421e Providing streaming WavFormat data.
WavFormat.GetPCMInputStream now returns data that is streamed, rather than a MemoryStream.
2017-09-24 11:23:39 +01:00
reaperrr
4ae92a5c22 Only add partitioned effects to ScreenMap if (current) bounds are valid
This serves to avoid adding effect where either width or height is 0.
2017-09-24 10:54:58 +01:00
reaperrr
593e86325b Fix SpriteEffect not updating ScreenMap 2017-09-24 10:54:58 +01:00
reaperrr
eea14ec922 Fix DepthCharge dealing no damage to surfaced subs 2017-09-23 20:06:23 +01:00
reaperrr
eb3b68e24a Fix DepthCharge not showing an explosion when hitting emerged subs 2017-09-23 20:06:23 +01:00
reaperrr
1d402d4f8b Fix submerged sub vulnerability to most weapons 2017-09-23 20:06:23 +01:00
Andre Mohren
800f6adc21 Made WithSpriteTurret.TurretOffset protected virtual to be overridden by mod traits. 2017-09-22 13:29:15 +02:00
Matthias Mailänder
d17e414648 Fix the overlay to actor rule for crates 2017-09-22 13:04:29 +02:00
Matthias Mailänder
44cfa793df Don't import veinholedummy and correct it's index
as it is a Westwood hack we don't need to immitate.
There are already better ways to limit vein growth.
2017-09-22 13:04:29 +02:00
Paul Chote
48a018d994 Fix cheats reenabling OneShot support powers. 2017-09-19 17:53:53 +02:00
Matthias Mailänder
3af0b1a7a0 Remove PlayerPaletteFromCurrentTileset. 2017-09-17 16:20:38 +02:00
RoosterDragon
3b4904775a Remove OpenAlStreamingSound.
Whilst the implementation appears to work most of the time, it sometimes stops playing audio mid-track. This could be an implementation issue, or bugs in the underlying streaming APIs of the OpenAL library. Either way, it is not currently reliable enough to be used.
2017-09-17 15:50:49 +02:00
RoosterDragon
94942cb140 Create OpenAlAsyncLoadSound.
This loads the sound inside a task, then begins playing it, avoiding blocking the UI thread. Unlike OpenAlStreamingSound it does not stream the sound from disk, rather, it loads the entire sound into memory and plays it in one go.
2017-09-17 15:50:49 +02:00
Paul Chote
f4c2b36778 Fix height calculations in custom terrain layers. 2017-09-17 15:35:40 +02:00
reaperrr
c3ece99796 Spatially partition SatelliteLaunch and GpsSatellite effects 2017-09-17 12:52:04 +01:00
reaperrr
be370cb855 Spatially partition NukeLaunch effect 2017-09-17 12:52:04 +01:00
reaperrr
9aa861eca9 Spatially partition CrateEffect 2017-09-17 12:52:04 +01:00
reaperrr
46132ed5c6 Spatially partition SpriteEffect 2017-09-17 12:52:04 +01:00
Matthias Mailänder
1aebf9857c Add support for only rendering effects inside screen bounds 2017-09-17 12:52:04 +01:00
Matthias Mailänder
8ca43e3d6b Import map Hidden Valley 2017-09-17 11:45:45 +01:00
abcdefg30
1f6b9a7638 Add missing wall tiles to the interior tileset 2017-09-16 17:31:15 +02:00
reaperrr
32df83d3c4 A few more misc explicit interface changes
By-products of making ITick require explicit implementation.
2017-09-16 15:51:37 +02:00
reaperrr
28e1f391e0 Make ITick require explicit implementation 2017-09-16 15:51:37 +02:00
reaperrr
85e60ef77f More misc explicit interface implementations
By-product from making ITick explicit in various places.
2017-09-16 15:51:37 +02:00
reaperrr
03c3a5f310 Make ITick implementations explicit in OpenRA.Game 2017-09-16 15:51:37 +02:00
reaperrr
ec354f89cd Make ITick implementations explicit in Mods.Cnc and Mods.D2k 2017-09-16 15:51:37 +02:00
reaperrr
83afcc3448 Some misc explicit interfaces
Just a by-product from a previous commit, not meant to do anything specific other than bringing us a tiny step closer to requiring explicit implementations for these interfaces too, at some point.
2017-09-16 15:51:37 +02:00
reaperrr
761a4f29ab Make INotifyIdle and INotifyBecomingIdle require explicit implementation 2017-09-16 15:51:37 +02:00
reaperrr
ddfed13db4 Make Tick and TickIdle explicit in WithInfantryBody 2017-09-16 15:51:37 +02:00
Smittytron
a1ef581749 Remove EjectOnDeath from Vehicles 2017-09-16 14:10:54 +01:00
reaperrr
0c73baab3e Add large blue tib crystals to Hot Springs
Matching original positions.
2017-09-16 13:50:17 +02:00
reaperrr
89c143ae85 Fix remapable TS big blue tib crystal sequence offset 2017-09-16 13:50:17 +02:00
abcdefg30
d99a472456 Fix HackyAI trying to deploy undeployable actors 2017-09-16 11:01:53 +01:00
Paul Chote
42c4c7b7eb Fix compile error in CommandBarLogic. 2017-09-15 22:49:56 +01:00
Paul Chote
e04ae9aa2c Move remaining hardcoded selection power keys into yaml. 2017-09-15 23:06:38 +02:00
Paul Chote
83d522d945 Split unrelated hotkeys from WorldInteractionController. 2017-09-15 23:06:38 +02:00
Paul Chote
0e3bfcfb35 Replace WorldCommandWidget with individual logic classes. 2017-09-15 23:06:38 +02:00
Paul Chote
983f9c4cde Remove hardcoded DevReloadChrome and HideUserInterface hotkeys. 2017-09-15 23:06:38 +02:00
Paul Chote
25e88008ef Make the mute hotkey global. 2017-09-15 23:06:38 +02:00
Paul Chote
c759a68492 Move hardcoded screenshot hotkey into yaml. 2017-09-15 23:06:38 +02:00
Paul Chote
8c4afa414a Add a base single-hotkey logic class to avoid future duplication. 2017-09-15 23:06:38 +02:00
Paul Chote
c6fe1639db Support multiple key handlers. 2017-09-15 23:06:38 +02:00
Paul Chote
7459050af9 Rework global music hotkey bindings. 2017-09-15 23:06:38 +02:00
reaperrr
08aaa998aa Fix AI BuildingLimits
The AI BaseBuilder would allow building a structure not only when the current number was lower, but also of it was equal to the limit, which allowed the AI to build one too much of every building.
2017-09-15 19:31:57 +01:00
reaperrr
dbcfb0c92e Rename and move WithTurretedSpriteBody
The name wasn't in line with our implicit naming convention and ambigous on top of that.
Also, only used by RA and TD so moved to Mods.Cnc.
2017-09-15 18:10:13 +01:00
reaperrr
c611b5aeeb Remove 'ed' from WithTurretedAttackAnimation
Too confusing, as people might think it requires 'WithTurretedSpriteBody', also not entirely in line with our (admittedly implicit) render trait naming convention.
2017-09-15 18:10:13 +01:00
Mustafa Alperen Seki
c0b8bb3fcf Add Generals Pilot Logic 2017-09-14 23:26:10 +02:00
gwenzek
11a990e352 check if target is alive 2017-09-14 23:19:28 +02:00
gwenzek
7721d0b328 add a "capturing" condition for ExternalCapture 2017-09-14 23:19:28 +02:00
Forcecore
8027bed6b2 Separated ship squad from ground unit squad
Just like aircrafts are independent from ground squads.
2017-09-13 23:31:26 +02:00
abcdefg30
5ddf28fa81 Bomber John rules cleanup
Removed hacks, default values and duplicates
2017-09-13 22:13:49 +02:00
abcdefg30
0f95febefa Bomber John sequence cleanup
Most of those sequences were unused or default values
Tick count fixed as well
2017-09-13 22:13:49 +02:00
abcdefg30
ed598d2ab4 Make it possible to disable adjacency 2017-09-13 22:13:49 +02:00
abcdefg30
17f7aac35c Add more RevealDisguiseOn types 2017-09-13 21:18:21 +02:00
abcdefg30
71f2026b32 Remove the hardcoded cloak reference from activities 2017-09-13 21:18:21 +02:00
Paul Chote
049ed086f9 Add assault move to TS. 2017-09-11 19:08:33 +02:00
Paul Chote
646a6aa1e8 Fix TS target types. 2017-09-11 19:08:33 +02:00
Paul Chote
3575e82078 Add assault move to D2K. 2017-09-11 19:08:33 +02:00
Paul Chote
d588854cc5 Add assault move to TD. 2017-09-11 19:08:33 +02:00
Paul Chote
c46d1944d9 Add assault move to RA. 2017-09-11 19:08:33 +02:00
Paul Chote
a81749e102 Add frontend code for issuing assault move orders. 2017-09-11 19:08:33 +02:00
Paul Chote
ffee45cd76 Add AttackMove support for AssaultMove orders and condition granting. 2017-09-11 19:08:33 +02:00
Paul Chote
1e4640dc0b Clean up SupportPowerTooltipLogic:
- Avoid creating unnecessary bindings
- Avoid duplicated text size calculations
- Relayout panel when (and only when) needed
- Color timer red when paused
2017-09-10 21:30:55 +02:00
Paul Chote
458c913264 Clean up ProductionTooltipLogic:
- Avoid creating unnecessary bindings
- Fix time display not updating on low power
- Fix power usage color not updating on power changes
- Avoid duplicated text size calculations
2017-09-10 21:30:55 +02:00
Paul Chote
b3b2efa781 Move hardcoded viewport keys into yaml. 2017-09-10 21:30:55 +02:00
Paul Chote
2a6bb0678e Move hardcoded support power keys into yaml. 2017-09-10 21:30:55 +02:00
Paul Chote
4f00d62237 Move hardcoded production keys into yaml. 2017-09-10 21:30:55 +02:00
Paul Chote
19000219af Allow widgets to expose custom hotkey names to the linter. 2017-09-10 21:30:55 +02:00
Paul Chote
1180c5ddaa Move hardcoded production tab keys into yaml. 2017-09-10 21:30:55 +02:00
Paul Chote
f5e38a4e2c Move ISeedableResource interface to Mods.Common. 2017-09-10 18:36:39 +02:00
Paul Chote
1de767d9bf Move objectives interfaces to Mods.Common. 2017-09-10 18:36:39 +02:00
Paul Chote
3f72076e1a Move radar signature interfaces to Mods.Common. 2017-09-10 18:36:39 +02:00
Paul Chote
e54cf9acc3 Move linter interfaces to Mods.Common. 2017-09-10 18:36:39 +02:00
Paul Chote
0648fc9f31 Move damage notification interfaces to Mods.Common. 2017-09-10 18:36:39 +02:00
Paul Chote
e3212d1e64 Move the IMove interface to Mods.Common. 2017-09-10 18:36:39 +02:00
Paul Chote
0f6dda3f5f Calculate building placement offsets in screen space. 2017-09-10 18:26:54 +02:00
reaperrr
0161d68237 Fix RA TorpTube bridge explosions
There were two issues at work here:
1) The combination of default MaximumLaunchAngle and default CruiseAltitude made torpedoes fly a ballistic curve, which combined with BoundToTerrain type made them explode 'in the air' when hitting non-water tiles. This would result in AIr returned as target type, which is invalid for torpedoes.
2) The explosion warheads were missing the Ground target type, which is actually the (only) target type that the bridge tiles you hit with torpedoes have.
2017-09-10 18:10:24 +02:00
reaperrr
b68c935807 Fix water splash on bridge in RA
On bleed, both the explosion as well as the water splash warhead of weapons triggered on bridges, since they have both the Ground and Water target types.

Ground cannot be made invalid for water splashes without causing regressions elsewhere, so a new Bridge target type is introduced to explicitly make bridges invalid targets for water splash effect warheads.
2017-09-10 18:10:24 +02:00
Paul Chote
23382dc508 Remove dummy d2k support bin overlay. 2017-09-10 15:25:43 +02:00
SoScared
b78736acb7 Replace all Creep with Neutral actors on map Agenda 2017-09-10 15:06:41 +02:00
Taryn Hill
48a071c756 Always use noget in fetch-thirdparty-deps-windows.sh 2017-09-10 14:52:13 +02:00
Forcecore
1dfba51665 Removed dead WSB from Refinery trait 2017-09-09 11:15:31 +01:00
reaperrr
43664a12b5 Tweaked TS tiberium colors
- excluded tiberium palettes from global lighting, just like in the original
- tweaked colors to match original more closely
2017-09-07 21:40:29 +01:00
Ishan Bhargava
9cd81a6310 Add myself to AUTHORS
Pull request #5666
2017-09-07 18:33:34 +02:00
reaperrr
024887b268 Move Contrail to Traits
And make interface implementations explicit while we're at it.
2017-09-06 22:07:02 +01:00
Paul Chote
898ef8fe50 Add support for queuing Guard orders. 2017-09-03 12:54:09 +02:00
Paul Chote
f4f27f8980 Add support for queuing AttackMove orders. 2017-09-03 12:54:09 +02:00
SoScared
2bfc7cdd46 RevealOnDeath with Aircraft 2017-09-02 20:17:05 +02:00
abcdefg30
1649f3aa60 Don't spawn aircraft husks when not airborne 2017-09-02 16:26:12 +02:00
Matthias Mailänder
3ce8026337 Tweak the atomic missile SpawnOffsets. 2017-09-02 15:10:35 +02:00
Matthias Mailänder
6774c9ce01 Setup the Temple of Nod smoke in Tiberian Dawn. 2017-09-02 15:10:35 +02:00
Matthias Mailänder
fd0c34bf61 Fix death hand missile offsets. 2017-09-02 15:10:35 +02:00
Matthias Mailänder
2980decc93 Fix the Dune 2000 missile overlay offset. 2017-09-02 15:10:35 +02:00
Matthias Mailänder
855f1816f4 Tweak the time until hatch opening and rocket away. 2017-09-02 15:10:35 +02:00
Matthias Mailänder
4526344eed Add WithNukeLaunchAnimation and -Overlay traits. 2017-09-02 15:10:35 +02:00
Matthias Mailänder
c63620e979 Remove trailing spaces. 2017-09-02 15:10:35 +02:00
SoScared
df9c07da41 change damage vs None with ^Cannon 2017-09-02 14:58:19 +02:00
reaperrr
96e98a24ae Polish RA Jeep and APC muzzle offsets
And Jeep turret offset.
2017-09-02 14:29:34 +02:00
Matthias Mailänder
e9e3e9c22e Bring back the MiGs to the desert shellmap. 2017-09-02 14:14:50 +02:00
rob-v
6eb7a98cd2 Change default Observer shroud option for Explored map 2017-09-02 14:02:24 +02:00
Matthias Mailänder
49919e3d73 Add missing AutoTarget to DOGGIE. 2017-09-02 13:33:35 +02:00
Paul Chote
3c1e7896a5 Clear editor search fields and yield focus on escape. 2017-09-02 12:48:42 +02:00
Matthias Mailänder
0ce4d91dd6 Add map No where to run 2017-09-02 12:14:39 +02:00
Matthias Mailänder
b3dbeb13ca Add map Tiers of Sorrow. 2017-09-02 12:14:13 +02:00
reaperrr
15c636525d Fixed no explosions showing on some RA civ structures
The combination of HitShape, but not Targetable makes the actors be considered invalid for effect warheads.
Lack of Targetable makes them invulnerable anyway, so removing HitShape and Health (and Explodes) is the most logical fix.
2017-09-02 09:27:30 +01:00
Matthias Mailänder
918690f9b2 Remove a bogus ore map in a water segment. 2017-09-02 09:13:14 +01:00
Matthias Mailänder
3c0b95cf6e Fix indentions of weapon documentation table of contents. 2017-09-02 08:56:31 +01:00
Paul Chote
3cf9d47b39 Fix TD stance bar naming. 2017-09-01 11:56:37 +02:00
Paul Chote
4a2988e676 Remove UnitCommandWidget. 2017-09-01 11:56:37 +02:00
Paul Chote
2a3a27aa65 Add CommandBarBlacklist to TS. 2017-09-01 11:56:37 +02:00
Paul Chote
9607c09516 Add command bar to TS. 2017-09-01 11:56:37 +02:00
Paul Chote
7997a24559 Adjust chrome.png and yaml layout.
Also cleans up stray whitespace.
2017-09-01 11:56:37 +02:00
reaperrr
2f66f83051 Remove IsPlane hack
The new VTOL boolean together with CanHover is enough to replace this.
2017-08-31 18:03:59 +02:00
reaperrr
28ffcfea3c Upgrade rule for setting VTOL to true for CanHover actors 2017-08-31 18:03:59 +02:00
reaperrr
3b01da737c Introduce Aircraft VTOL boolean
Rather than hard-linking vertical take-off/land to the CanHover = Helicopter assumption.
2017-08-31 18:03:59 +02:00
reaperrr
5d58374962 Remove FlyCircleTimed activity
A FlyCircle overload is sufficient.
2017-08-31 18:03:59 +02:00
reaperrr
df94765eac Upgrade rule for TakeOffOnResupply 2017-08-31 18:03:59 +02:00
reaperrr
c9ff362ea2 Add TakeOffOnCreation and TakeOffOnResupply to Aircraft
Before this, it was impossible to replicate the behavior of the original games (staying on pad/airfield after reload) without hacking around in Mods.Common.
This allows modders to disable these without meddling with code.
2017-08-31 18:03:59 +02:00
abcdefg30
5cfb5aaf2d Rework the addition and removal of building influence 2017-08-31 17:36:22 +02:00
reaperrr
93f385e9fc Give TS JumpJet shadow when airborne 2017-08-31 16:54:03 +02:00
reaperrr
d1a4133752 Fix WithShadow
It *modifies* the actor rendering, so returning an empty renderable was bogus, as were the IsInWorld/IsDead checks.
2017-08-31 16:54:03 +02:00
Paul Chote
69251d508b Suppress scroll events from the DropDownWidget fullscreen mask. 2017-08-31 12:43:17 +02:00
Paul Chote
1bd1a185f5 Unhardcode spectator combined/world view hotkeys. 2017-08-31 12:33:34 +02:00
Paul Chote
0525408664 Unhardcode map editor zooming hotkey. 2017-08-31 12:33:34 +02:00
Paul Chote
9a5b5d9b6f Unhardcode music control hotkeys. 2017-08-31 12:33:34 +02:00
Paul Chote
8d4ffee32a Add hotkey linting support for logic args. 2017-08-31 12:33:34 +02:00
SoScared
1a95aeda19 patch tent cost increase 2017-08-28 20:41:22 +02:00
atlimit8
fd6b2c0107 Move timers from ConditionManager to ExternalCondition 2017-08-27 12:43:27 +01:00
atlimit8
c61cd37bec ExternalCondition: List<struct TimedToken> timedTokens 2017-08-27 12:43:27 +01:00
atlimit8
62c76b8ae9 ExternalCondition: remove timedTokensBySource 2017-08-27 12:43:27 +01:00
atlimit8
f51323daa3 ExternalCondition: remove unneeded source references 2017-08-27 12:43:27 +01:00
atlimit8
c7d3c3ec73 Changes to ExternalCondition.TryRevokeCondition 2017-08-27 12:43:27 +01:00
Forcecore
72236b66f6 D2K Thumper deploy animation fix 2017-08-27 13:22:00 +02:00
abcdefg30
d6d8cf05b0 Adjust IsAtGroundLevel fixing EjectOnDeath 2017-08-26 15:54:02 -07:00
Taryn Hill
eed9af88f5 Always use noget in fetch-thirdparty-deps.sh 2017-08-26 15:50:47 -07:00
reaperrr
b1c63a4752 Fix FindActorsOnLine overscan 2017-08-26 15:43:44 -07:00
Paul Chote
a7c2f3e7e3 Add mod-specific appdata metadata. 2017-08-26 15:43:26 -07:00
Matthias Mailänder
8ae2a65d9d Shroud is actually a player trait. 2017-08-26 22:47:48 +01:00
Matthias Mailänder
a445049e3d Fix the indentions. 2017-08-26 18:35:41 +01:00
Paul Chote
49d5283ce1 Use curl instead of wget in fetch-thirdparty-deps. 2017-08-26 13:49:56 +02:00
Forcecore
739d0c0bb2 Disabled Ground squads finding targets individually
* Now they will tend to focus fire.
* Provides performance when when the AI designer implements better
  (and complex) target selection code
2017-08-25 23:13:26 +02:00
Zimmermann Gyula
cb36dfa532 Implement instant refineries.
AKA RA2 refinery logic.
2017-08-25 22:19:03 +02:00
Paul Chote
a29360f313 Add a lint test for hotkeys. 2017-08-25 21:56:52 +02:00
Paul Chote
1e0148e092 Migrate ButtonWidget to NamedHotkey. 2017-08-25 21:56:52 +02:00
Paul Chote
42bf232b37 Introduce NamedHotkey type. 2017-08-25 21:56:52 +02:00
Paul Chote
13a06c6e8d Move hardcoded static asset browser hotkeys to yaml. 2017-08-25 21:56:52 +02:00
Matthias Mailänder
988353e431 Remove cloak sounds not featured in the original.
closes #9519
2017-08-25 19:42:38 +02:00
SoScared
1e1109034f Additional tweak of the Artillery weapon 2017-08-25 15:29:18 +02:00
atlimit8
43880ea7b8 Make AppearsOnRadar trait conditional 2017-08-25 15:10:28 +02:00
atlimit8
8a825f2999 Add VariableExpression.NoVariables 2017-08-25 15:10:28 +02:00
Matthias Mailänder
2ccba3768b Add overlay animations to CAARAY. 2017-08-25 10:48:35 +01:00
Matthias Mailänder
dc72b8080c Fix Dune 2000 harvester husk offset.
Closes #10087.
2017-08-24 11:28:06 +02:00
C. Helmig
80b69af30c d2k: sonic weapon fix.
Works around buggy friend-foe discrimination (/Falloff) for sonic weapon. Damage values closer to original game. (Fixes #13850)
2017-08-23 13:02:54 +02:00
reaperrr
120d7f9976 WithHarvestAnimation style fixes
Make interface implementations explicit.
2017-08-23 12:34:00 +02:00
reaperrr
0103b7ca87 Make WithSpriteBody.PlayCustomAnimation resume loop of Sequence
...after it finished playing.
2017-08-23 12:34:00 +02:00
reaperrr
90a4fe7ca1 Resume looping default WithSpriteTurret.Sequence after custom anim
It doesn't really make sense not to, and the only trait using PlayCustomAnimation previously did this manually anyway.
2017-08-23 12:34:00 +02:00
reaperrr
c75e64a952 Properly account for disabled Armaments in various places
These places didn't care if an Armament was disabled, which could lead to unexpected behavior.
2017-08-22 20:55:46 +01:00
reaperrr
951ee2210c Consider disabled armaments invalid 2017-08-22 20:55:46 +01:00
SoScared
28e28bf34c fix ore spots on Dual Cold Front 2017-08-22 19:28:06 +02:00
Matthias Mailänder
cba0fc3475 Remove CreateGroup order as the ActorGroupProxy is gone. 2017-08-22 18:44:35 +02:00
rob-v
01d631b228 Load replays also in sub directories 2017-08-21 14:54:46 +02:00
Mustafa Alperen Seki
f7983692ae Make Captures Upgradeable 2017-08-21 13:06:00 +02:00
Matthias Mailänder
287290bbdf Fix indentions of trait documentation table of contents. 2017-08-20 23:06:59 +02:00
reaperrr
a4ef199b75 Tweak TS Juggernaut BurstDelays and Report
Since the original sound contains 3 shots, it could happen that the sound played even though only 1 shot had been fired.
Additionally, it could happen that no sound was played when shooting because the first burst had already been fired.
Finally, in the original the 3rd shot was delayed a little compared to the first two.

This adresses all these issues.
2017-08-20 20:48:25 +02:00
reaperrr
c4bfb052d9 Apply BurstDelays rename to TS 2017-08-20 20:48:25 +02:00
reaperrr
98357cf2a9 Apply BurstDelays rename to RA 2017-08-20 20:48:25 +02:00
reaperrr
5581688781 Apply BurstDelays rename to TD 2017-08-20 20:48:25 +02:00
reaperrr
7704ae655e Apply BurstDelays rename to D2k 2017-08-20 20:48:25 +02:00
reaperrr
834a40b18d Refactor BurstDelay to BurstDelays
Allowing to set custom per-burst delays.
2017-08-20 20:48:25 +02:00
abcdefg30
4ce2e82ff0 AI States style fixes and minor polish 2017-08-17 23:25:51 +01:00
reaperrr
98b1468801 Clean up Harvester TickIdle a bit
Triggering UnblockRefinery each idle tick is bogus.
2017-08-17 22:58:37 +01:00
reaperrr
406f482a19 Cache INotifyHarvesterAction trait look-ups 2017-08-17 22:58:37 +01:00
reaperrr
bac8d3233a Streamline Harvester.SetProcLines return check 2017-08-17 22:58:37 +01:00
reaperrr
e9a420a9e5 Remove redundant TakeOff from Aircraft
ResupplyAircraft queues a TakeOff anyway, if the aircraft is a helicopter.
2017-08-17 22:19:05 +01:00
reaperrr
95d3d61ffa Make some Aircraft interface implementations explicit with subclassing 2017-08-17 22:19:05 +01:00
reaperrr
6c3ff0dc02 Make AircraftInfo more readable
Added some descriptions where I considered it necessary, added newlines between entries, reordered entries where it made sense.
2017-08-17 22:19:05 +01:00
reaperrr
cab6a96b16 Allow skipping make anim for actors with WithMakeAnimation and GrantConditionOnDeploy 2017-08-17 22:03:42 +01:00
reaperrr
f3f2621eeb Allow skipping 'sell'/reversed make anim on Sell 2017-08-17 22:03:42 +01:00
reaperrr
eb5fb5abba Allow skipping 'sell'/undeploy anim for actors that TransformOnCapture 2017-08-17 22:03:42 +01:00
rob-v
c848b30e9e Add chat tab to multiplayer/replays ingame menu 2017-08-17 21:54:19 +01:00
Paul Chote
daee217431 Add x64process stat. 2017-08-17 19:45:11 +02:00
Paul Chote
9fc0970cfc Force '.' decimal point for windowscale stat. 2017-08-17 19:45:11 +02:00
abcdefg30
7156c2c09d Add the missing base implementation to AttackFrontal's RulesetLoaded 2017-08-17 19:28:51 +02:00
rob-v
dd9d5450bc Add EnableDebugCommandsInReplays option 2017-08-17 19:23:22 +02:00
abcdefg30
6840177776 Fix actors being able to walk on cliffs after the sietch was destroyed 2017-08-17 19:05:38 +02:00
abcdefg30
d78b29b545 Fix sietches being repairable and remove the Power trait (unused) 2017-08-17 19:05:38 +02:00
abcdefg30
b66605033a Let the fremen fallback in atreides04 instead of attacking the base 2017-08-17 19:05:38 +02:00
abcdefg30
b329bf2642 Add more fail conditions to the spice harvesting missions 2017-08-17 19:05:38 +02:00
abcdefg30
02c371f68a Fix a bogus condition 2017-08-17 19:05:38 +02:00
abcdefg30
6907929cb4 Fix the harvest protection logic 2017-08-17 19:05:38 +02:00
abcdefg30
e07779942e Add a warning when attacking the Outpost to ordos04 2017-08-17 19:05:38 +02:00
abcdefg30
a942ca8f57 Add a global script for campaign missions in d2k 2017-08-17 19:05:38 +02:00
Mustafa Alperen Seki
7f0c7cee0d Make D2K Missions use Vanilla Remap Colors 2017-08-17 18:46:06 +02:00
Mustafa Alperen Seki
3bf217aaf7 Rename Emparor to Corrino on Shellmap 2017-08-17 18:46:06 +02:00
SoScared
6d1ca72a80 probe new civilian structures 2017-08-17 15:24:39 +02:00
abc013
944dfeb476 Corrected gnrl sequences & added TakeCover: to him 2017-08-13 21:06:14 +02:00
AoAGeneral
ab5d2766f6 TD Bridges.
Currently in both playtest and release the bridges for TD used to be 500hp with no armor. Meaning that minigunners and other unit types were able to kill them off fairly quickly. Giving them extra HP and an armor type means units such as minigunners, humvees, flamethrowers, and APCs can't kill bridges off quickly.
2017-08-13 20:17:15 +02:00
rob-v
eb21c4bddd Keep Attack M./Guard action while holding hotkey (revert Playtest change) 2017-08-13 17:44:26 +01:00
Allan Greis Eriksen
5435e34b9a Audio device names is now shown correcly in the Audio Device combolist. 2017-08-13 18:38:18 +02:00
Oliver Brakmann
8f26b4e92b Fix Mobile not sanitizing target location of Move orders 2017-08-13 17:23:37 +01:00
Paul Chote
62a006ed3e Change beaconlib reference to match other deps. 2017-08-13 18:15:55 +02:00
Paul Chote
cf386c6149 Update BeaconLib to 1.0.1. 2017-08-13 18:15:55 +02:00
abcdefg30
84d6fa1540 Fix monster tanks not attacking radar domes 2017-08-13 18:01:02 +02:00
abcdefg30
2dad2de0ff Add the win and loss videos to Monster Tank Madness 2017-08-13 18:01:02 +02:00
Paul Chote
34a44acf85 Update macOS launcher to 20170812 tag. 2017-08-13 17:53:23 +02:00
Paul Chote
b937bf43f7 Switch to .NET 4.5 compatible Marshal.SizeOf overload. 2017-08-13 17:39:00 +02:00
Paul Chote
f4d4a7eed4 Fix d2k commandbar artwork glitch. 2017-08-13 14:07:47 +02:00
Paul Chote
4e493f265f Revert TicksBeforePathing move from Mobile to Move.
This partially reverts commit 11c8cda0c3.
2017-08-13 13:31:58 +02:00
abc013
6e8dd5058e Changed SAM launch offset 2017-08-13 12:49:04 +02:00
Paul Chote
ad2c46ea73 Add a community code of conduct.
This adopts the standard 1.4 version of the Contributor Covenant.
http://contributor-covenant.org/
2017-08-13 12:32:01 +02:00
Jean-Rémy Buchs
49f42401e6 Improve the description of LandOnCondition of Aircraft 2017-08-11 10:56:27 -05:00
abcdefg30
de7a0c9861 Remove TargetWhenIdle and TargetWhenDamaged from AutoTarget 2017-08-10 19:11:47 +02:00
abcdefg30
0209c1c848 Add TRUCK.Husk to Tiberian Dawn 2017-08-10 18:24:19 +02:00
SoScared
64dfc38c2e final RA balance patch for the next playtest/release 2017-08-10 18:16:58 +02:00
abcdefg30
d1ab421240 Don't spawn new actors before all RemovedFromWorld callbacks have run 2017-08-10 17:57:11 +02:00
Paul Chote
22d7031819 Focus the ViewportController on Standard/Inverted scroll modes. 2017-08-10 12:50:00 +02:00
Paul Chote
d0d8062dbf Extract ViewportEdgeScrollMargin settings entry. 2017-08-10 12:44:44 +02:00
Paul Chote
dd709a2679 Revert "Have some activities count as idle activities"
This reverts commit ae111248f3.
2017-08-10 12:22:28 +02:00
rob-v
86cff9a774 Disable click sound on command bar buttons 2017-08-09 21:50:34 +01:00
rob-v
0c67ca3321 Add ButtonWidget.DisableKeySound property 2017-08-09 21:50:34 +01:00
reaperrr
f744a429a4 Fix SpawnActorPower not playing launch sounds 2017-08-09 21:27:42 +01:00
reaperrr
11d6dc2d3a Add TS base-building hit-shapes 2017-08-09 21:25:05 +01:00
reaperrr
6e2418d940 Add TS civilian hit-shapes 2017-08-09 21:25:05 +01:00
reaperrr
1b28cb9f60 Add TS default hit-shapes 2017-08-09 21:25:05 +01:00
reaperrr
ab6d18eab6 Center two-legged billboard sprites
They are supposed to be positioned in the middle of the two cells they occupy.
2017-08-09 21:25:05 +01:00
reaperrr
c40ec62511 Tweak sprite offsets of some TS aban civ buildings
In cases where the sprite has enough margin to the footprint cell edges, moving down the sprite a bit is much easier than manually setting up custom targetable offsets.
2017-08-09 21:25:05 +01:00
abcdefg30
94a386eda8 Move the interior tile 384 from the Floor to the Wall category 2017-08-09 20:52:00 +02:00
rob-v
88a3656f0a Fix Client tooltip crash in Lobby 2017-08-09 19:17:00 +01:00
SoScared
3c4a75e4b6 Add Gap effect values to new vision range changes and ironing out misc. values 2017-08-09 20:13:58 +02:00
Jean-Rémy Buchs
1d1802a163 Add LandOnCondition to the trait Aircraft which triggers a landing and prevents takeoffs while the condition is met 2017-08-08 15:13:50 -05:00
abc013
c4d2fdbd83 Fix ground units can stay on water (tile 409) 2017-08-08 12:32:43 +02:00
AoAGeneral
baa4b61d3f TD Prerequisite changes.
Adds prerequisite labels to E1, E3, E6, and TDTRUCK.

Closes #13780
2017-08-08 12:21:37 +02:00
reaperrr
b388c6186a Shrink shape of TD SAM 2017-08-07 14:49:24 +02:00
reaperrr
97bbfd34fd Shrink shape of RA SAM
To adress balancing concerns.
Also tweaked sprite offsets to make it more centered.
2017-08-07 14:49:24 +02:00
reaperrr
6945ae1747 Rename tdtruk to truck 2017-08-07 11:01:21 +02:00
reaperrr
f4499c1e84 Rename TD TowerMissle to TowerMissile 2017-08-07 11:01:21 +02:00
reaperrr
20efd1fc29 Fix RA effect waheads
- take Trees into consideration (they don't have Ground TargetType)
- fixed the delayed effect warheads on Vulcan
2017-08-07 11:01:21 +02:00
Oliver Brakmann
d61939f59f Fix harv docking activities getting lost under certain circumstances 2017-08-07 10:45:45 +02:00
forcecore
d1328212c6 AttackFrontal's FacingTolerance is now in effect 2017-08-07 10:26:26 +02:00
reaperrr
d949e17b88 Perform FogObscures as late as possible
FogObscures is more expensive than simpler boolean, player or HasTraitInfo checks, so in these places it makes sense to perform the other checks first.
2017-08-07 09:42:12 +02:00
AoAGeneral
99dac05fd7 TD Balance Changes. (20170802)
Engineer movement speed reduced to 48 from 56.

Helicopter crash damage increased to 100 from 40.

Rocket infantry spread damage reduced to 32 from 128.

------

Engineer movement was the same speed as minigunners and at times would enable them to escape the minigunners. This slight speed reduction helps for this.

Helicopter crash damage was lacking and a slight increase in this enables them to do some damage. With the cost of the helicopter it is still not a good idea to sacrifice aircraft just for exta damage.

Rocket infantry spread is reduced because of the damage done to infantry packs. Games turned into tanks mixed with rocket infantry. Reducing this spread enables them to single target units more closely then in larger armies.
2017-08-07 09:35:20 +02:00
Matthias Mailänder
fdad5e2c48 Add weapon rules documentation. 2017-08-05 21:00:06 +02:00
Matthias Mailänder
1a54b36e2b Cache shouldn't be exposed at all so drop it. 2017-08-05 21:00:06 +02:00
Matthias Mailänder
55ea54ff2d Explain the color notation. 2017-08-05 21:00:06 +02:00
Matthias Mailänder
59d88199cf Give Dictionaries a friendlier notation. 2017-08-05 21:00:06 +02:00
Matthias Mailänder
0a150bcc75 Move friendly type names into shared helper class. 2017-08-05 21:00:06 +02:00
reaperrr
879ab2ac1f Remove redundant Disposed checks
IsDead returns true if Disposed is true.
2017-08-05 18:31:15 +02:00
Lars Beckers
68607872bd Fix RA Aftermath installer metadata on Linux 2017-08-02 20:09:28 +02:00
FrameLimiter
9fdb7dc51b Fix duplicate Targetable value on ^Ammobox 2017-08-02 19:40:08 +02:00
Taryn Hill
57fb551545 Improve the exception message when a Bridge's DemolishWeapon cannot be found 2017-07-29 22:26:30 +02:00
reaperrr
8ee742d66a Split MuzzleOffset and MuzzleOrientation calcs to protected methods
To make overriding easier for downstream traits inheriting Armament.
2017-07-29 22:14:58 +02:00
reaperrr
26be2a3e99 Split Burst updating to separate method 2017-07-29 22:14:58 +02:00
reaperrr
e847f49256 Split barrel firing to separate method 2017-07-29 22:14:58 +02:00
reaperrr
514bd12885 Merge some Armament CanFire checks 2017-07-29 22:14:58 +02:00
reaperrr
bdfa8a361b Split Barrel can-fire checks to separate CanFire method 2017-07-29 22:14:58 +02:00
AoAGeneral
dc61c98098 TD Engineer Description.
Closes #13720
2017-07-25 18:59:47 -05:00
Paul Chote
4c222e5f2b Add Demo Truck and MAD Tank to Deploy description. 2017-07-23 20:10:08 +02:00
Paul Chote
cd9fc96c37 Implement IIssueDeployOrder on MADTank. 2017-07-23 20:10:08 +02:00
GSonderling
ef0b0847bc Removed references to make docs 2017-07-23 15:33:39 +02:00
rob-v
97306f2bcd Move DeveloperMode trait to Mods.Common 2017-07-23 15:08:24 +02:00
rob-v
d4e9e0e069 Add Visualization chat commands 2017-07-23 15:08:24 +02:00
reaperrr
8403adba37 Implement damage-based slowdown on TD Gunboats
In line with original.
2017-07-23 15:06:03 +02:00
reaperrr
9a25b33beb Adapt TD missions to TDGunboat refactor 2017-07-23 15:06:03 +02:00
reaperrr
94fa24088b Add dedicated TDGunboat traits
And get rid of Mobile.OnRails hack.
2017-07-23 15:06:03 +02:00
reaperrr
3bdd35fd2d Move AttackPopupTurreted to Attack subfolder 2017-07-23 15:06:03 +02:00
SoScared
4903912e3c Revert 4 cell adjacency of Kennel/Silo back to 2. 2017-07-22 22:48:33 +01:00
abcdefg30
aaaf66a6a3 Disable bots on Poland Raid (again) 2017-07-22 22:33:44 +01:00
Forcecore
0573f52a37 Add Railgun projectile 2017-07-21 23:18:38 +01:00
Paul Chote
9d84f4a845 Fix the automated installer generation. 2017-07-21 18:49:59 +01:00
reaperrr
5b24fddd5a Fix TD airfield targetable positions 2017-07-21 17:42:18 +01:00
Paul Chote
0f54d6f709 Allow mod to be launched after installing required content. 2017-07-21 00:15:38 +02:00
Paul Chote
d1ed0e09d0 Create user map directory if it doesn't exist. 2017-07-21 00:10:48 +02:00
abcdefg30
d8bc4905cb Add a selection priority of 6 to supply trucks 2017-07-20 15:13:41 +01:00
abcdefg30
4204ba1c1f Fix funpark01 failing at mission start 2017-07-18 22:49:12 +01:00
reaperrr
17f469f1a5 Revert Yak gun strafing 2017-07-18 14:25:00 +02:00
SoScared
0e64ac4709 Reduce vision range of MSILO, IC and Chronoshpere to 6c0 2017-07-18 01:13:15 +02:00
Paul Chote
afd8b9ab86 Rework harvester resource claiming:
* Maintains lists of claims, and only restricts
   reservations for friendly units.
 * Removes OnNotifyResourceClaimLost; it's not
   clear whether that is still useful, and it
   prevents future necessary cleanups.
 * Moves other code without changing behaviour.

This fixed stale claims from dead units and enemy
claims from preventing otherwise valid harvest
activities.
2017-07-18 01:09:19 +02:00
SoScared
9097837e6d Adjust AoE damage vs Wood in relation to HitShapes 2017-07-18 00:59:25 +02:00
Paul Chote
93fcfbb131 Fix ReadWriteZipFile crashing on update. 2017-07-18 00:10:07 +02:00
GSonderling
7a2d2cfd5f Reorganised desert beach templates.
Deleted spurious tabs and spaces

As requested by @reaperrr

Removed more spaces.

One last space deleted.
2017-07-18 00:02:24 +02:00
SoScared
bfca4897ea Visual, Polish/Performance and Balance Tweak 2017-07-17 23:37:04 +02:00
Jean-Rémy Buchs
488440197e Add new trait ReloadArmamentsBar which renders a bar to show the current reload status 2017-07-16 14:58:00 +01:00
Paul Chote
4ffcd9b4a5 Add template type to editor coordinate label. 2017-07-16 13:12:13 +02:00
Paul Chote
72cf5d29e7 Add search bar to editor Template list. 2017-07-16 13:12:13 +02:00
Paul Chote
f1b54ece8a Add search bar to editor Actors list. 2017-07-16 13:12:13 +02:00
andrew
ce671a2737 TD Supply Truck 2017-07-16 11:07:35 +01:00
Jean-Rémy Buchs
224ca78257 Fix crash in DistanceFromEdge if vector is too long 2017-07-15 17:49:29 +02:00
reaperrr
ace353cb84 Upgrade rule for Missile.TerrainHeightAware 2017-07-15 17:36:20 +02:00
reaperrr
7e8f920bc1 Allow disabling terrain height checks in Missile
This saves a good deal of performance for mods with no real height levels, including RA, TD and D2k.
2017-07-15 17:36:20 +02:00
reaperrr
86ab6e7ed3 Fix MoveWithinRange subcell consideration 2017-07-15 17:31:25 +02:00
reaperrr
b859b9ee43 Fix RotationPaletteEffect not working with player palettes 2017-07-15 11:19:09 +01:00
abcdefg30
0b6b997e81 Add a CommandBarBlacklist trait to blacklist Stop and Waypoint Mode 2017-07-14 23:18:28 +01:00
AoAGeneral
f921a45747 TD Airstrike Balance.
This has been a tough decision. I have nerfed the napalm damage from 65 to 35 commited by reaperrr since at 65 they were still one shotting weapon factories and airstrips. The problem however was that it still did way to much damage. Bringing the Vulcan down from 25 to 15 wood damage helps to keep it alive a majority of the time. (Still brings it to red at times.) Problem now is the airstrike is now a unit killing role rather then killing power plants and various other structures. (Doesn't exactly kill barracks/helipads everytime anymore.)
2017-07-15 00:16:19 +02:00
Paul Chote
3bea08f020 Fix Windows desktop icons being installed for all users. 2017-07-15 00:12:45 +02:00
RoosterDragon
9413d9595c Providing streaming AudFormat data.
AudFormat.GetPCMInputStream now returns data that is streamed, rather than a MemoryStream.
2017-07-14 23:02:49 +01:00
RoosterDragon
85c948fd8d Add a streaming audio playback interface.
This allows audio to be streamed, rather than needed to be fully loaded into memory.
2017-07-14 23:02:49 +01:00
reaperrr
45606c9528 Editor actor categories style fixes 2017-07-14 10:28:29 +02:00
reaperrr
1b0ae1e512 Mention hard-coded 'Air' TargetType in CEWH.AirThreshod desc 2017-07-13 20:58:47 +02:00
reaperrr
70b43222fe Adapt D2k AA missiles to CEWH refactor 2017-07-13 20:58:47 +02:00
reaperrr
bc54789641 Adapt TD anti-air weapons to CEWH refactor 2017-07-13 20:58:47 +02:00
reaperrr
65920a883f Upgrade rule for CreateEffectWarhead ImpactTypes -> Targets 2017-07-13 20:58:47 +02:00
reaperrr
5cd8acada4 Adapt TS effect warheads to CEWH refactor 2017-07-13 20:58:47 +02:00
reaperrr
ce8f3ed168 RA mission weapon warhead fixes 2017-07-13 20:58:47 +02:00
reaperrr
a7334d5583 Adapt RA missiles to CEWH refactor 2017-07-13 20:58:47 +02:00
reaperrr
db16165261 Adapt RA explosions, supers and other weapons to CEWH refactor 2017-07-13 20:58:47 +02:00
reaperrr
34dc52451a Adapt RA smallarms to CEWH refactor 2017-07-13 20:58:47 +02:00
reaperrr
346b6af30d Adapt RA ballistic weapons to CEWH refactor 2017-07-13 20:58:47 +02:00
reaperrr
13983765d6 Tweak RA naval vessel target types
The extremely coarse, shared with terrain Ground and Water types make it hard to distinguish between different actor categories, so we add Ship to all non-submerged vessels.
Additionally, we add 'Water' to submerged subs to prevent players from finding them by moving the cursor of a ship with DepthCharge over the suspected sub position.
The latter also allows force-firing DepthCharge at empty water cells.
2017-07-13 20:58:47 +02:00
reaperrr
cf5abc68ad Refactor CreateEffectWarhead ImpactTypes
Use target validity to simplify ImpactTypes.
2017-07-13 20:58:47 +02:00
reaperrr
efd8a9c1cb Rebalanced Yak
- increased ammo per gun from 9 to 10, for two full double-5-burst salvoes, adjusted ReloadDelay to keep total reload time about the same
- increased Spread by 33% to make up for lower effective pin-point accuracy
- increased damage vs. infantry by 25%, vs. light armor by 16.67%, vs. heavy armor by ~10%
2017-07-13 19:12:16 +02:00
reaperrr
fa02c97111 RA Parabombs balance fix
They're too over-powered on bleed due to the hitshap changes.
2017-07-13 19:12:16 +02:00
reaperrr
4afe9dd248 Enable RA ParaBomb shadow 2017-07-13 19:12:16 +02:00
reaperrr
abb8e27747 TD airstrike balance tweak
The increased building hitshape sizes allowed TD airstrikes to kill even Cyards and temples on bleed, which is overpowered compared to before the hitshapes were merged.
Cutting bomb damage vs. Wood to 65% lets Cyards, temples and adv. comm. centres survive airstrikes with yellow health.
2017-07-13 19:12:16 +02:00
reaperrr
afa9b9760e Unhardcode AttackBomber bomb and gun logic 2017-07-13 19:12:16 +02:00
reaperrr
a1cb0cf002 AttackBomber style fixes 2017-07-13 19:12:16 +02:00
reaperrr
07edf2f7c6 Reset burst counter if ReloadDelay has passed since last shot
This fixes the following issues:
- units like mammoth tanks sometimes at first only fired 1 shot on new encounter because they only depleted 1 burst before previous target was killed
- weapons that use strafing logic would not reset the offset multiplier after passing the target once, leading to wrong offsets on following attacks
2017-07-13 19:12:16 +02:00
reaperrr
6212b82f6d Use strafing for RA Yak
This is done by modifying the target offset by a value matching the Yak's
speed * BurstDelay, to sync the offsets with the actor speed.
2017-07-13 19:12:16 +02:00
reaperrr
afa8d3522c Add strafing support to weapons 2017-07-13 19:12:16 +02:00
reaperrr
92c9988eea Fix D2k Palace footprint 2017-07-13 17:43:41 +02:00
reaperrr
d95d7e0b0f Rename UseOccupiedCellsOffsets to UseTargetableCellsOffsets
With the introduction of the new 'u' BlockingUntargetable cell type, the old property name became inaccurate.
2017-07-13 17:43:41 +02:00
reaperrr
77ef3a0ed2 Simplify RA base building hitshape rules 2017-07-13 17:43:41 +02:00
reaperrr
70c251d5d5 Simplify TD base building hitshape rules 2017-07-13 17:43:41 +02:00
reaperrr
03c7c8f79c Simplify D2k TargetableOffsets rules
By using the new 'u' Footprint letter.
2017-07-13 17:43:41 +02:00
reaperrr
5bdb7bd689 Add OccupiedUntargetable FootprintCellType
For cells that are occupied & unpassable, but should be ignored by HitShape.UseOccupiedCellsOffsets.
2017-07-13 17:43:41 +02:00
reaperrr
fdb3866238 Remove FootprintUtils 2017-07-13 17:43:41 +02:00
reaperrr
46dc827d46 Refactor footprint cell lookups and move them to Building
Removing FootprintUtils happens in the next commit for better
reviewability.
2017-07-13 17:43:41 +02:00
Forcecore
801796b184 FIX game hanging when units with 0 min-range attack units at 0 range.
Fixes #13307
2017-07-12 20:51:35 +02:00
Paul Chote
59dae0ebf6 Split install-core into finer grained targets for the mod template. 2017-07-12 16:22:36 +02:00
Paul Chote
1c2db8806b Update to latest osx launcher tag. 2017-07-12 16:22:36 +02:00
reaperrr
9a7778e55d Fix black tile on template 438 of RA desert tileset 2017-07-12 15:57:19 +02:00
Jean-Rémy Buchs
6749060e57 Add RangeCircleMode to trait RenderRangeCircle 2017-07-12 00:10:52 +02:00
AoAGeneral
4a39bc8286 TD Balance Changes. 20172606
The list of changes do not affect the new hitboxes of the structures.

+ Orca damage increased from 25 to 28.
Damage is increased because of their lack of damage vs armored units and structures.

+ Apache ammo reload reduced from 200 to 40.
Apaches gaining a full clip of ammo is a bit to strong. Firing the first shot starts the timer tick and will reload even if the clip is not fully reloaded. This also fixes so they don't sit on top of infantry and blow them all away to quickly.

+ Apache ammo reload amount reduced from 10 to 1.
Fixed in unison with ammo reload timer.

+ Sam now fires two missiles. (CNC95)
Does extra damage.

+ Sam range increase from 8c0 to 10c0.
Compensate for the aircraft changes. Also had a problem of MSAMs were always the better choice rather then the structure SAMs itself. This change will make them more viable.

+ Sam range limit from 9c614 to 12c0.
Makes it so aircraft can still escape while the missile won't detonate at the edge of the circle range.

+ Humvee damag vs light increased from 50 to 55.
Compensates for the price of the hummer. Having just the HP wasn't enough to counter certian builds of Nod. Enabling them a slightly higher damage allows them to kill buggies and bikes a bit more effectively. Makes them also decent arty and MRLS killers.

+ Crates got some love.

+ Viceroids now spawn.

+ An atomic bomb can now detonate. (CNC95)

+ Veterancy level is now to rank 4.
This makes grabbing crates all the more rewarding and riskier. Such as willing to bring a mammoth tank or commando to the crate rather then a minigunner.
2017-07-11 16:25:49 +02:00
Paul Chote
e38db04ab7 Move Stylecop checks to their own helper executable. 2017-07-09 21:58:21 +02:00
Paul Chote
1fa1677204 Register default mods during installation on Windows. 2017-07-09 20:54:02 +02:00
Paul Chote
2685dbea3b Register default mods during installation on Debian/Ubuntu. 2017-07-09 20:54:02 +02:00
Paul Chote
2c522e0371 Add mod registration utility commands. 2017-07-09 20:54:02 +02:00
Paul Chote
bc4a5193e9 Add ExternalMods.Unregister method. 2017-07-09 20:54:02 +02:00
Paul Chote
739f357090 Read mod registrations from system support dir. 2017-07-09 20:54:02 +02:00
Paul Chote
e69f129fed Add Platform.SystemSupportDir for shared user data. 2017-07-09 20:54:02 +02:00
Paul Chote
372d940936 Rework stale ExternalMod metadata clearing. 2017-07-09 20:54:02 +02:00
Paul Chote
b30cfe4ada Move launchPath argument from ExternalMods ctor to .Register. 2017-07-09 20:54:02 +02:00
Paul Chote
daf8f8d956 Throw a FileNotFoundException if source zip file isn't found. 2017-07-08 23:22:44 +02:00
Paul Chote
6e145f902b Fix empty lobby faction tooltips. 2017-07-08 22:45:51 +02:00
Paul Chote
cd9ef47f94 Suppress unrelated mouse events while scrolling. 2017-07-08 22:21:04 +02:00
rob-v
f341330d5e Fix Joystick scrolling stuck 2017-07-08 22:21:04 +02:00
Paul Chote
4f16b0d464 Revert "Replace legacy Evaluator with IntegerExpressions."
This reverts commit cd0898236d.
2017-07-08 22:11:36 +02:00
Paul Chote
f7c57cfc6f Fix crash when loading read-only ReadWriteZipFiles. 2017-07-08 16:45:44 +01:00
Paul Chote
ab1a798d04 Add GrantConditionOnBotOwner trait. 2017-07-07 21:31:45 +01:00
Paul Chote
96a1c8d54b Update internal ra/cnc/d2k/ts bot types. 2017-07-07 21:31:45 +01:00
Paul Chote
b0906e1836 Add a bot type identifier. 2017-07-07 21:31:45 +01:00
Paul Chote
e88754cd4a Expose Player.BotType and make fields readonly. 2017-07-07 21:31:45 +01:00
Markus Hartung
3a6796ac9d Fix for some AppDomains that doesn't add trailing DirectorySeparatorChar. 2017-07-06 18:29:24 +01:00
Markus Hartung
c2e36b8eeb Ignore Visual Studio 2017 generated files 2017-07-06 18:29:24 +01:00
rob-v
1a546d9baf Polish Actor Categories 2017-07-06 01:50:43 +02:00
rob-v
aab9dfcaa0 Add TS Actor Categories 2017-07-06 01:50:43 +02:00
rob-v
8da112dc92 Add D2K Actor Categories 2017-07-06 01:50:43 +02:00
rob-v
6c962b6675 Add TD Actor Categories 2017-07-06 01:50:43 +02:00
rob-v
6005b59064 Add RA Actor Categories 2017-07-06 01:50:43 +02:00
rob-v
686686417f Add Actor Categories and Category dropdown filter in Map editor 2017-07-06 01:50:43 +02:00
reaperrr
8f4a92af99 Upgrade rules and yaml updates for Bib refactor 2017-07-06 01:42:55 +02:00
reaperrr
3200f4fb0f Remove bib-related hacks from Building and FootprintUtils 2017-07-06 01:42:55 +02:00
reaperrr
9b137afa6d Add ITargetableCells interface 2017-07-06 01:42:55 +02:00
reaperrr
69aa4f5962 Building style fixes for better readability 2017-07-06 01:42:55 +02:00
RoosterDragon
297f4ad9ed Ensure we set ZipConstants.DefaultCodePage by using a helper method.
We were currently dealing with this terrible global variable in FileSystem/ZipFile.cs previously, but other parts of the code such as DownloadPackageLogic were creating these files too, and may not have executed the static ctors that fixed the encoding yet.
2017-07-05 22:45:15 +01:00
rob-v
1f436ad0cb TS - Rename Template.Category to Template.Categories 2017-07-05 22:46:59 +02:00
rob-v
c3ccd1906d D2K - Rename Template.Category to Template.Categories 2017-07-05 22:46:59 +02:00
rob-v
5cee040fc0 TD - Rename Template.Category to Template.Categories 2017-07-05 22:46:59 +02:00
rob-v
03cfd5b880 RA - Rename Template.Category to Template.Categories 2017-07-05 22:46:59 +02:00
rob-v
4b9c6c4746 Allow multiple terrain (tile) categories 2017-07-05 22:46:59 +02:00
reaperrr
3abd65052c Fix TS Titan barrel, armament offsets and disable projectile image 2017-07-03 18:52:54 +02:00
reaperrr
b491ec871c Tweak TS sprite walker animations
- replace WithInfantryBody with WithFacingSpriteBody + WithMoveAnimation on Titan
- rename all mech 'run' anims to 'walk'
- tweak walk anim rates to better match movement speed/original
- tweak Wolverine attack anim to play a little faster
2017-07-03 18:52:54 +02:00
reaperrr
9a25dd6a60 Add elite explosion to TS Sonic & Stealth Tanks
Matching original TS.
2017-07-02 16:03:40 -05:00
reaperrr
faf9f7cede Change Explodes.Weapon default to null
FieldLoader.Require makes the default pointless, so it makes more sense to change it to null.
2017-07-02 16:03:40 -05:00
reaperrr
a6b9bab033 Make Explodes conditional 2017-07-02 16:03:40 -05:00
Mustafa Alperen Seki
6dca6b3740 Reimport 8PLAY3 and 5 2017-07-02 21:04:16 +02:00
Jean-Rémy Buchs
2e4cd8d820 Make SpawnActorOnDeath conditional 2017-07-02 10:00:08 -05:00
reaperrr
9e138178ad WithAttackAnimation style fix
Looks better this way.
2017-07-01 12:33:51 +01:00
reaperrr
9c2e3aaa05 Make WithMoveAnimation conditional and modify only a single assigned sprite body
The latter to match what we do on WithAttackAnimation already.
2017-07-01 12:33:51 +01:00
reaperrr
8a5a8a1646 RA yaml style fix 2017-07-01 11:11:51 +01:00
reaperrr
ff268eee44 Remove comments on explosion sequences in TD
We don't ship comments for explosions in the other mods, and every modder will either already know or can look them up in the asset browser.
2017-07-01 11:11:51 +01:00
reaperrr
ec5c218ac4 TD yaml style fixes 2017-07-01 11:11:51 +01:00
Paul Chote
fdafbd9f15 Remove hardcoded references to FacingInit and TurretFacingInit. 2017-07-01 10:35:22 +01:00
Paul Chote
2a2bd676a3 Remove hardcoded references to HideBibPreviewInit. 2017-07-01 10:35:22 +01:00
Paul Chote
b2c3a55c12 Add IActorPreviewInitInfo interface. 2017-07-01 10:35:22 +01:00
Paul Chote
e10b64d62c Add command bar to D2K. 2017-07-01 00:35:47 +02:00
Paul Chote
f801fc502f Adjust UI spritesheet to make more usable space. 2017-07-01 00:35:47 +02:00
reaperrr
3f8efb1163 Remove ApplyToAllTargetablePositions hack from RectangleShape
In its current form it is bad for performance due to the ITargetablePositions look-up, and fixing that only to remove the hack entirely a few weeks later would be kind of pointless, so let's get this over with.
2017-06-29 22:01:19 +02:00
rob-v
f75115a645 Remove unnecessary loading mod exceptions, log missing icon.png 2017-06-29 19:43:44 +02:00
abcdefg30
04033e5c79 Don't iterate over an array with only one element 2017-06-29 16:56:21 +02:00
abcdefg30
841798a0a8 Don't use a broken version string when git is not found 2017-06-29 16:56:21 +02:00
abcdefg30
057c201e85 Don't echo "Invalid command" when using the version command with a parameter 2017-06-29 16:56:21 +02:00
abcdefg30
83be37acaf Try to bypass the security warning 2017-06-29 16:56:21 +02:00
abcdefg30
57af145c12 Don't let the launcher scripts close the console window 2017-06-29 16:56:21 +02:00
Markus Hartung
27ce2fcda9 Add some resharper rules 2017-06-27 22:47:50 +01:00
rob-v
78bedb0513 Fix IsSinglePlayer 2017-06-27 22:43:15 +01:00
C. Helmig
8a508ecafa Change concrete radar color to match rock.
This is/was problematic, because right now players can spot expansions through the fog-of-war instantly.
This replicates original game behavior, too. Concrete in original dune2k doesn't show up on the radar.
2017-06-27 23:31:09 +02:00
Paul Chote
dbe16bfdb5 Add faction tooltips to TS. 2017-06-27 23:27:53 +02:00
Paul Chote
88ab77ce0f Polish Random faction tooltips. 2017-06-27 23:27:53 +02:00
Paul Chote
714b24329c Use standard button tooltip for faction descriptions. 2017-06-27 23:27:53 +02:00
Paul Chote
3996aadcb6 Add description yaml to D2K button tooltip. 2017-06-27 23:27:53 +02:00
reaperrr
2650973d51 Add ForceDisplayAtGroundLevel to CreateEffectWarhead
Allows to force the effect to always play at ground level, regardless of explosion altitude.
2017-06-27 23:19:32 +02:00
reaperrr
d283231d94 Fix TS Cyborg explosion and Tiberium explosion palette
Otherwise these would appear darker than the other explosions on maps with darker ambient color and have now translucency.
2017-06-27 23:19:32 +02:00
reaperrr
f7aac24c43 Fix TS Grenade explosion size
Now matches original.
2017-06-27 23:19:32 +02:00
rob-v
3e7bf1880f Fix Map editor total ore money 2017-06-27 22:05:40 +01:00
reaperrr
266b5d194f Fix TS visceroid and tib floater weapons
They'll need to target closest targetable position to be able to attack larger buildings, which conflicts with the TargetDamage warhead.
2017-06-27 21:07:39 +01:00
ltem
115c72aa4b Fixed the positioning of the performance graph. 2017-06-26 23:11:32 +01:00
Paul Chote
d81a07931f Fix D2K units not auto-targeting defenses in Defend stance. 2017-06-25 22:49:37 +02:00
reaperrr
ba1279aa93 Disable some effect warhead victim scans in TS 2017-06-25 22:40:12 +02:00
reaperrr
32e7ab7a30 Disable effect warhead victim scans in TD
They are meant to play regardless of whether an actor was hit anyway.
2017-06-25 22:40:12 +02:00
reaperrr
4823d5454d Disable effect warhead victim scans in D2k
They are always displayed unconditionally anyway.
2017-06-25 22:40:12 +02:00
reaperrr
e0abf8ed27 Disable effect WH victim scans in RA where sensible
AA missiles, flame weapons and nukes, pretty much, because they always
display the effect regardless of what they hit.
2017-06-25 22:40:12 +02:00
reaperrr
1d2361cdd3 Change default and auto-calc of victim scans to -1
For all projectiles and warheads.

Not really a must for everything else, but for CreateEffectWarhead, the
ImpactTypes refactor (separate PR) makes it a bit harder to make the
warhead valid in every situation, so setting the victim scan to zero is the easiest way to disable scanning for actors completely.
2017-06-25 22:40:12 +02:00
reaperrr
ca475fe133 Projectile style fixes 2017-06-25 22:40:12 +02:00
reaperrr
dc5818d035 Warhead style fixes
Implement interfaces explicitly
2017-06-25 22:40:12 +02:00
Paul Chote
a755070d76 Fix VisualHeight of RA commandbar buttons. 2017-06-25 22:37:36 +02:00
rob-v
f29d2028fe Fix missing-failing logging of Ruleset (Yaml)Exceptions 2017-06-25 18:45:12 +02:00
rob-v
6e1b2333f3 Fix ClientTooltip disables tooltip delay 2017-06-24 11:52:27 +01:00
rob-v
1b3422db2d Fix flickering tooltip 2017-06-24 11:52:27 +01:00
rob-v
7772ebedf4 Check for Carryall, RevealOnFire FrozenActor.Actor is null 2017-06-24 11:42:50 +01:00
rob-v
78bf530a4e Check for EnterTunnel FrozenActor.Actor is null 2017-06-24 11:42:50 +01:00
rob-v
6df7f18a3b Fix Initialize sounds (dispose of null SoundSource) 2017-06-24 11:29:55 +01:00
reaperrr
0a1083e554 Merge the Valid(...)Weapons methods 2017-06-24 11:24:17 +01:00
reaperrr
33e8bf9928 Adapt Attack logic to Weapon.TargetActorCenter 2017-06-24 11:24:17 +01:00
reaperrr
edffaa4987 Introduce Weapon.TargetActorCenter and adapt projectiles
This also fixes issues with attackers that don't have their own Attack
trait.
2017-06-24 11:24:17 +01:00
reaperrr
6b3c04a584 Fix old shape scaling 2017-06-24 11:15:12 +01:00
reaperrr
7d3cf7894b Fix upgrade rule dates
These were merged into bleed after prep was branched off, so they need a date newer than last release.
2017-06-24 11:15:12 +01:00
reaperrr
522a29f1e4 Reduce Ornithopter damage vs buildings
Especially larger ones.
2017-06-24 11:11:56 +01:00
abcdefg30
c58db84d35 Fix the harvesting sequence being invisible in TS 2017-06-23 12:45:16 +02:00
abcdefg30
1760a12428 Replace the wrong CURRENTENGINE description by OLDENGINE 2017-06-23 11:42:44 +02:00
abcdefg30
118039ded3 Add a missing i 2017-06-22 14:35:26 +02:00
abcdefg30
839945cf57 Fix a crash in CheckSequences when the sprite image is null 2017-06-22 14:35:26 +02:00
rob-v
da5c70184e Refactor RefreshServerListInner's games+lanGames argument 2017-06-22 11:59:04 +02:00
rob-v
3c323a8672 Extract loading of game rows into LoadGameRows method. 2017-06-22 11:59:04 +02:00
rob-v
53c7954f84 MP Browser - display current mod+version first 2017-06-22 11:59:04 +02:00
rob-v
7237fd83c6 Fix error handling of failed MP server refresh 2017-06-22 11:59:04 +02:00
reaperrr
8e9f20cf4b Cache traits implementing INotifyAttack 2017-06-22 04:13:47 -05:00
reaperrr
779218f381 Cache traits implementing modifiers 2017-06-22 04:13:47 -05:00
reaperrr
243ed3d76a Cache traits implementing INotifyBurstComplete 2017-06-22 04:13:47 -05:00
Forcecore
100abe3246 Requested changes applied
* private this.info --> public Info for GCOnDeploy
* Parameter change for (un)deploy activities
2017-06-20 23:42:14 -05:00
Forcecore
a7cedc54ff Deploy activities for mods and future AI scripting 2017-06-20 23:42:14 -05:00
Paul Chote
300a7222f3 Don't autotarget structures in Defend stance. 2017-06-18 21:07:21 +02:00
Paul Chote
2e2e1cae7f Fix MSAM/MLRS autotargeting. 2017-06-18 21:07:21 +02:00
Paul Chote
57df34dcbf Fix auto-targeting vs TD/TS/D2K creeps. 2017-06-18 21:07:21 +02:00
Paul Chote
0a1f2b7275 Fix auto-targeting vs submerged but detected RA submarines. 2017-06-18 21:07:21 +02:00
Paul Chote
0aa84aa5ed Fix auto-targeting vs RA tanks. 2017-06-18 21:07:21 +02:00
Paul Chote
4040863707 Fix queued move activities. 2017-06-18 20:55:50 +02:00
Oliver Brakmann
f6e87f63e7 Fix GetSupportDir not returning an absolute path 2017-06-18 20:46:22 +02:00
Mustafa Alperen Seki
c4e8af08ec Implement EliteAbility=VEIN_PROOF and SENSORS on units that need 2017-06-18 16:23:34 +02:00
Forcecore
a3c9d72cfd Unbreak queued order 2017-06-18 12:03:29 +01:00
Forcecore
07a2ee5eab Engineer repair activity can be queued 2017-06-18 12:03:29 +01:00
Forcecore
568d7efdb1 ExternalCaptures Type filter fix up 2017-06-18 12:37:59 +02:00
Paul Chote
4b4172f757 Make the Enter activity use the closest target position. 2017-06-17 21:18:28 +02:00
Paul Chote
995a3da43a Rename Enter.targetCenter to repathWhileMoving. 2017-06-17 21:18:28 +02:00
rob-v
b0f1059df2 Remove unnecessary PostBuildEvent from D2k project 2017-06-17 20:17:31 +02:00
Paul Chote
f0ffb4e8d9 Remove leftover target references.
Fixes a warning generated by `xbuild`.
2017-06-17 20:17:31 +02:00
Paul Chote
3db15beeb9 Fix compatibility with msbuild/csc on non-windows. 2017-06-17 20:17:31 +02:00
Forcecore
728162e688 GCOnDeploy's ValidTerrain() takes location parameter
Fixes ##13394.

Possible use: AI's future deploy planning when the actor isn't actually
there yet. Also used in my mod for Slave Miner's deploy planning
2017-06-17 19:00:07 +02:00
reaperrr
f98e7656da Make TS GDI Juggernaut attack the target center
Instead of closest targetable position/offset.
2017-06-15 01:32:37 +02:00
reaperrr
c20d02fd2e Make TD artillery actors attack the target center
Instead of closest targetable position/offset.
Applies to:
-Artillery
-Rocket Launcher (MLRS)
2017-06-15 01:32:37 +02:00
reaperrr
26e6d86821 Make RA artillery actors attack the target center
Instead of closest targetable position/offset.
Applies to:
-Artillery
-Cruiser
-Missile Sub
2017-06-15 01:32:37 +02:00
reaperrr
7eab278711 Adapt tracking projectiles to support targeting CenterPosition
Instead of closest targetable position.
2017-06-15 01:32:37 +02:00
reaperrr
da7433a95f Add plumbing for targeting of target center instead of closest targetable position
Note: Projectiles that can track their target need minor additional changes, but for InstantHit (which already implemented support for this) and unguided projectiles (Bullet, GravityBomb) this commit is already sufficient.
2017-06-15 01:32:37 +02:00
Paul Chote
9c9a23be86 Make Frames and Limbs private. 2017-06-14 18:56:06 +02:00
Paul Chote
2683b2507e Fix remaining voxel references in Game. 2017-06-14 18:56:06 +02:00
Paul Chote
6ca0208694 Rename VoxelPreview to ModelPreview. 2017-06-14 18:56:06 +02:00
Paul Chote
736e70df78 Rename VoxelRenderable to ModelRenderable. 2017-06-14 18:56:06 +02:00
Paul Chote
17089f2aee Rename VoxelSequences to ModelSequences. 2017-06-14 18:56:06 +02:00
Paul Chote
34810756c2 Move Voxel code to Mods.Cnc. 2017-06-14 18:56:06 +02:00
Paul Chote
dc4c3fd546 Rename VoxelRenderer to ModelRenderer. 2017-06-14 18:56:06 +02:00
Paul Chote
4f42778d26 Rename VoxelAnimation to ModelAnimation. 2017-06-14 18:56:06 +02:00
Paul Chote
e1cd00c1dd Add backend plumbing for model loaders. 2017-06-14 18:56:06 +02:00
reaperrr
086fc88e3e Increased ZOffset of TD explosions
To make sure they always play on top of actors.
2017-06-14 18:28:20 +02:00
reaperrr
35e131bac7 Give TD base buildings custom hit shapes 2017-06-14 18:28:20 +02:00
reaperrr
b219214426 Give TD civilian and tech buildings custom shapes 2017-06-14 18:28:20 +02:00
reaperrr
d1790229a9 Add hit-shape defaults to TD
Plus some resulting cleanup of defaults.yaml.
2017-06-14 18:28:20 +02:00
reaperrr
600478603c Fix TD civ field husk footprint
Players should not be able to build on it.
2017-06-14 18:28:20 +02:00
Mustafa Alperen Seki
4187a69904 Remove afld and hpad from Rush AI's Production: list 2017-06-14 18:26:18 +02:00
Paul Chote
90778bc8a8 Fix queued move orders on Chrono Tank. 2017-06-12 19:38:18 -05:00
Paul Chote
242f33c2ba Implement RA command bar. 2017-06-12 19:38:18 -05:00
Paul Chote
2923c9907f Fix minor issues with TD command bar. 2017-06-12 19:38:18 -05:00
reaperrr
d52313ab18 Rename WithAttackAnimation.BodyName to just .Body
Shorter and more consistent with Armament.Turret, WithTurretedAttackAnimation.Turret, WithSpriteBarrel.Armament etc.
2017-06-12 19:01:10 -05:00
reaperrr
fef388834e Throw yaml exception if WithAttackAnimation has no assigned sprite body
...or too many assigned bodies.

Also, further simplify WithAttackAnimation code.
2017-06-12 19:01:10 -05:00
reaperrr
5fb468922e Make WithAttackAnimation conditional 2017-06-12 19:01:10 -05:00
reaperrr
2e70b6931b Refactor WithAttackAnimation
- made trait compatible with actors that have more than one sprite body or enable/disable sprite bodies via conditions
- added check for running attack anim and prevent aim/reload sequences from overriding it
- added caching of whether trait has either aim or reload sequence, to avoid some string.IsNullOrEmpty look-ups every tick
2017-06-12 19:01:10 -05:00
rob-v
8276b17570 Fix Sound memory leak (OutOfMemoryException), remove Music caching to free memory 2017-06-12 18:33:53 -05:00
RoosterDragon
2def72a078 Clear previous effects data when generating a new sync report. 2017-06-12 18:25:35 -05:00
Paul Chote
2e801a55ce Update ts AutoTarget definitions. 2017-06-11 17:14:21 -05:00
Paul Chote
52b08a769d Update d2k AutoTarget definitions. 2017-06-11 17:14:21 -05:00
Paul Chote
d7f9c2f852 Update cnc AutoTarget definitions. 2017-06-11 17:14:21 -05:00
Paul Chote
b613b1b2e0 Update RA AutoTarget definitions. 2017-06-11 17:14:21 -05:00
Paul Chote
716343732f Add AutoTargetPriority trait for smarter AutoTarget logic. 2017-06-11 17:14:21 -05:00
reaperrr
ab8bc53ed8 Replace doneDamage bool in TeslaZap with DamageDuration
Allows it to deal continous damage via a single projectile.
2017-06-11 23:28:17 +02:00
reaperrr
6ff31786cb Refactor TeslaZap targeting
- made it target closest targetable position, instead of CenterPosition
- made target tracking optional (enabled by default)
- made tracking independent from whether damage has already been dealt
- cache target position and update it in Tick only if tracking
2017-06-11 23:28:17 +02:00
reaperrr
c474b77d79 Remove unused 'initialized' bool from TeslaZap
It was never set to 'true', and doing so would break Duration > 1, so it's better to just remove it.
2017-06-11 23:28:17 +02:00
reaperrr
2704f3bcd5 Minor TeslaZap cleanup
Renaming timeUntilRemove to ticksUntilRemove makes it more clear and allows to drop the comment.
2017-06-11 23:28:17 +02:00
reaperrr
16e260e69f Increase ZOffset of RA explosions
To make sure they play on top of actors.
2017-06-10 11:38:04 +01:00
reaperrr
7cadbcb8f6 Set custom hit shapes for civilian buildings 2017-06-10 11:38:04 +01:00
reaperrr
07e6708b88 Align RA base building hitshapes with their sprites 2017-06-10 11:38:04 +01:00
reaperrr
7ba276c0c1 Add building hitshape defaults to RA
And do some cleanup.
Intentionally omitted uncommon shapes that only appear once or twice.
2017-06-10 11:38:04 +01:00
C. Helmig
3b626e5ff7 Fixes tile error in #13047. See comment Item in #12868. 2017-06-07 18:54:39 +02:00
C. Helmig
452aed0a97 Multiple passability changes to replicate original game behavior. (= Items comments on #12868 )
Fix the passability of some bridge tiles
2017-06-07 18:54:39 +02:00
abcdefg30
5d40ed3e32 Move tiles into correct category. 2017-06-07 18:54:39 +02:00
abcdefg30
8494200321 Renamed and reordered Categories - uniform naming, similar categories adjacent to one another, most used to top. 2017-06-07 18:54:39 +02:00
Paul Chote
83c4c842ee Update to latest osx launcher package. 2017-06-06 22:08:08 +02:00
reaperrr
423ea555b3 Fix RA bridge crash 2017-06-06 22:04:00 +02:00
reaperrr
4af31be6bd Fix TD bridge crash 2017-06-06 22:04:00 +02:00
Paul Chote
ff9bddbf21 Add unit command bar to TD. 2017-06-06 08:53:54 -06:00
Paul Chote
52f1ab0969 Add backend code for unit command bar. 2017-06-06 08:53:54 -06:00
Paul Chote
f1eb96b273 Add DisableKeyRepeat flag to ButtonWidget. 2017-06-06 08:53:54 -06:00
Paul Chote
854dd75282 Add ButtonTooltipWithDescHighlightLogic.
Highlights TooltipDesc characters inside {}.
2017-06-06 08:53:54 -06:00
Paul Chote
8f2a933ba8 Add support for button tooltip descriptions. 2017-06-06 08:53:54 -06:00
Paul Chote
ce233a6cca Reduce edge scrolling threshold and polish cursor hotspots. 2017-06-06 08:53:54 -06:00
Paul Chote
94fba3521a Add ForceModifiersOrderGenerator for force move/attack and queueing. 2017-06-06 08:53:54 -06:00
Paul Chote
8dfb7d8bbc Add Selection.Hash for tracking selection changes. 2017-06-06 08:53:54 -06:00
Paul Chote
e8d6d63707 Add IIssueDeployOrder. 2017-06-06 08:53:54 -06:00
Paul Chote
533b2f9ad7 Flip tooltips above the cursor at the bottom of the screen. 2017-06-06 08:53:54 -06:00
Mustafa Alperen Seki
46d0157c2e Add Harkonnen 4 2017-06-05 22:32:49 +02:00
reaperrr
3507ad2f87 Give D2k structures footprint hit-shapes 2017-06-05 14:22:47 +02:00
reaperrr
e2647e8a60 Move down D2k High-tech factory sprite
This better aligns its visuals with the footprint, hit-shape and targetable positions.
2017-06-05 14:22:47 +02:00
reaperrr
6a212eea53 Make attacking actors/turrets face the targeted position 2017-06-05 14:22:47 +02:00
reaperrr
7acc6dacbc Fix armaments/projectiles to aim at closest Target.Positions
Instead of CenterPosition.
TargetablePositions were already used for targeting/attack decisions, but not armaments/projectiles.
2017-06-05 14:22:47 +02:00
Markus Hartung
73577e3a7e Add myself to authors 2017-06-04 17:11:44 +02:00
Markus Hartung
2a0b3b39ea INotifyCreated.Created now calls base properly 2017-06-04 17:11:44 +02:00
Markus Hartung
f7ddb969c6 Change so Attack* calls Created on base class 2017-06-04 17:11:44 +02:00
abcdefg30
40e8c5136d Fix the close enough check in Repair.cs 2017-06-04 15:35:40 +02:00
Paul Chote
abdcf90c30 Ship VERSION with binary releases. 2017-06-04 13:21:27 +02:00
Paul Chote
36d7b5131e Use ContentInstallerMod in MainMenuLogic. 2017-06-04 13:21:27 +02:00
Paul Chote
f79a3a8d03 Use engine version in crash logs. 2017-06-04 13:21:27 +02:00
Paul Chote
f7db7e3308 Use engine version for master server queries. 2017-06-04 13:21:27 +02:00
Paul Chote
49f0e35bd7 Add engine VERSION file. 2017-06-04 13:21:27 +02:00
reaperrr
82758a8bef Add TargetableOffsets to HitShape
And remove ITargetablePositions from Building.
Also, added UseFootprintOffsets to replicate the old Building behavior for easier setup of TargetablePositions for buildings.
2017-06-04 00:07:08 +02:00
reaperrr
7fd0a3aa58 Lint check and yaml enforcement for HitShape
Now that Health no longer provides a HitShape, actors with Health need at
least one HitShape trait.
2017-06-04 00:07:08 +02:00
reaperrr
7f81de2f8a Upgrade rule for Health.Shape to HitShape.Type 2017-06-04 00:07:08 +02:00
reaperrr
43b55ae333 Move Shape from Health to new HitShape trait
Renamed Shape to Type
2017-06-04 00:07:08 +02:00
reaperrr
c7c6cf864c Fix inconsistent rules in preparation of HitShape refactor
- TD C17 and A10 are not targetable and therefore technically invulnerable, so we should remove Health and Armor
- D2k ^carryall.colorpicker and TS ^mmch.colorpicker shouldn't have Health
- TS crash sites are supposed to be indestructible map deco as per original (they had "Immune=yes")
2017-06-04 00:07:08 +02:00
Mustafa Alperen Seki
61afa096e3 Add 8PLAY6 2017-06-03 16:17:34 +02:00
Mustafa Alperen Seki
aa9c00367b Add 8PLAY2 2017-06-03 16:14:52 +02:00
Oliver Brakmann
677904c682 Hide tooltips for unoccupied spawnpoints in the replay browser 2017-06-03 15:56:27 +02:00
rob-v
fc0495ac27 Fix keys scrolling stuck (+ some function double calls) 2017-06-01 23:07:25 +02:00
Mustafa Alperen Seki
f4988356a0 Add 8PLAY4 2017-06-01 20:28:48 +02:00
Mustafa Alperen Seki
8bcc2b30d9 Add 8PLAY1 2017-06-01 20:14:59 +02:00
Andre Mohren
96ca3baff8 Fixed PNGLoader crash with palette containing less than 256 colors. 2017-05-31 20:34:09 +02:00
Oliver Brakmann
a869dacdc4 Remove tooltips from map preview in MP server browser 2017-05-30 22:30:31 +01:00
rob-v
ada5b6d0e5 Add Unit stance hotkeys, remove Cycle Stance hotkey 2017-05-30 21:16:31 +02:00
Andre Mohren
d080a47cbf Allow load screens to override StartGame. 2017-05-30 18:15:28 +02:00
atlimit8
afa5a7772d Split ConditionByStance in AutoTarget 2017-05-29 20:41:10 +01:00
atlimit8
cadfbe8a29 Grant condition by unit stance 2017-05-29 20:41:10 +01:00
reaperrr
5834d7615b Fix Rectangle OuterRadius
Rectangle shapes always assumed that either top-left or bottom-right would have the largest distance from actor center, which is wrong, because depending on the position of the shape, top-right or bottom-left can be the furthest away corner as well, potentially resulting in a too small OuterRadius.
2017-05-29 07:41:20 -05:00
reaperrr
bc5eb66088 Add OuterRadius debug overlay to Rectangle and Capsule
Circle obviously doesn't need it now (might change with the introduction of offsets, but we can still add it when that happens).
2017-05-29 07:41:20 -05:00
reaperrr
8d69d26542 Add debug overlay for custom TargetPositions 2017-05-29 07:41:20 -05:00
reaperrr
479795f494 Fix D2k repair pad footprint
To match the original.
2017-05-29 07:41:20 -05:00
rob-v
45041bde14 Dispose-stop Beacon on closing server browser 2017-05-29 13:28:39 +01:00
rob-v
9a9920e4af Catch and ignore BeaconLib errors 2017-05-29 13:28:39 +01:00
abcdefg30
e1b7fc2617 Replace the removed SupplyTruck trait in disable-player-experience.yaml 2017-05-29 07:15:57 -05:00
Paul Chote
45b13dabfb Explicitly implement interfaces in AttackBase. 2017-05-29 06:27:19 -05:00
Paul Chote
34844e87a3 Replace Lazy trait lookups with INotifyCreated. 2017-05-29 06:27:19 -05:00
Paul Chote
69587a2128 Move InstallShieldPackage to Mods.Common. 2017-05-29 12:41:28 +02:00
Paul Chote
e5222f95f6 Remove ambiguity from FileSystem references. 2017-05-29 12:41:28 +02:00
Paul Chote
ba7290cc2c Move classic-mod package loaders and support files to Mods.Cnc. 2017-05-29 12:41:28 +02:00
Paul Chote
28fdb71163 Remove mod chooser reference from music installation prompt. 2017-05-29 12:33:20 +02:00
Paul Chote
8321d1f3e3 Remove legacy FileSystem.OpenPackage(string, IReadOnlyPackage). 2017-05-29 12:27:24 +02:00
Paul Chote
df40d38b91 Rework read/write zip file loading/saving. 2017-05-29 12:20:32 +02:00
evgeniysergeev
c06df1ed21 make IsCloseEnoughToBase function virtual 2017-05-29 11:50:56 +02:00
abcdefg30
aecfff905d Throw a more detailed error message when creating invalid frozen actors 2017-05-28 14:02:18 +02:00
abcdefg30
2a3139dc39 Add a IAutoSelctionSizeInfo trait interface 2017-05-28 14:02:18 +02:00
Mustafa Alperen Seki
767fd5438e Add Ordos 3b 2017-05-28 13:49:08 +02:00
Paul Chote
a43ec158fa Update error messages. 2017-05-27 13:03:47 +02:00
Paul Chote
7f3f36885a Fix bogus variable names in widget widths. 2017-05-27 13:00:00 +02:00
Paul Chote
29d827079e Fix "game" chat tab mouseover not working from globalchat login tab. 2017-05-27 13:00:00 +02:00
Paul Chote
b104f8baa2 Improve handling of unknown error codes. 2017-05-27 12:43:25 +02:00
Glenn Martin Jensen
e8b2a12714 Add support for blacklist response
Adds support for the new blacklist response in servernames
2017-05-27 12:43:25 +02:00
Paul Chote
0ddc4360fe Remove unused MiniYaml DictFromFile. 2017-05-26 23:02:25 -05:00
Paul Chote
c6816cd33f Persist unknown settings.yaml entries across load/save. 2017-05-26 23:02:25 -05:00
Paul Chote
b1ac1d06e3 Catch and ignore exceptions while loading map previews. 2017-05-26 23:41:30 +02:00
abcdefg30
1f93029e51 Always make sure to be on the host actor when repairing 2017-05-26 22:53:03 +02:00
Jean-Rémy Buchs
2e0d7d0e79 Add KillCargo and FlashScreen to PortableChrono 2017-05-26 10:31:59 +02:00
Paul Chote
2e7de2874d Fix cloak sounds playing on build for initially cloaked actors. 2017-05-24 16:30:04 +02:00
Mustafa Alperen Seki
5dd6aa7a3a Add Ordos 3a 2017-05-20 13:30:41 +02:00
abcdefg30
5e40a5b683 Remove the effect from MissionColt 2017-05-20 11:28:14 +02:00
abcdefg30
ddba9b2efd Remove outdated values and replace Bullet by InstantHit in allies05a 2017-05-20 11:28:14 +02:00
abcdefg30
7ea40482e2 Fix the Colt sometimes shooting even after Tanya was released 2017-05-20 11:28:14 +02:00
abcdefg30
cc6191554a Remove the hacky MissionColt actor from allies05a 2017-05-20 11:28:14 +02:00
abcdefg30
550256373a Replace Camera.Truk by using ValidStances on RevealsShroud 2017-05-20 11:28:14 +02:00
abcdefg30
434ea9ca88 Throw a lint error or an exception when no player owns the world 2017-05-20 11:02:00 +02:00
abcdefg30
ac4fef6630 Don't close the console window when OpenRA closes 2017-05-20 10:55:09 +02:00
abcdefg30
61659d0d32 Add support for using launch-game.cmd with parameters 2017-05-20 10:55:09 +02:00
Paul Chote
b74141666b Implement a workaround for the mono 5.0 cursor enumerator bug. 2017-05-19 14:31:00 +02:00
rob-v
3258d89651 Fix map parameter warning as error from PR 13233 2017-05-17 22:58:56 +02:00
rob-v
127ef8bb27 LobbyLogic, ReplayBrowserLogic Map property changed to map field 2017-05-14 21:06:16 +01:00
rob-v
a26210f914 Replays with MapPreview (like in Lobby) 2017-05-14 21:06:16 +01:00
rob-v
0e3cc1ad28 (Lobby)MapPreviewLogic refactoring 2017-05-14 21:06:16 +01:00
rob-v
ffc3f6e0d0 LAN games discovery 2017-05-14 22:01:25 +02:00
rob-v
b2e6a0484b Fix Selecting a map resets player color 2017-05-14 14:00:45 +01:00
reaperrr
d95bb4152a Add Firestorm Juggernaut to TS 2017-05-14 14:41:20 +02:00
rob-v
224bda6de5 Fix Player slot when changing map 2017-05-14 13:19:18 +02:00
reaperrr
d8edcb1bad Fix TS Nod artillery turret / barrel / weapon offsets 2017-05-14 11:52:42 +01:00
Paul Chote
d45870ca23 Allow fixed barrel pitches to be defined in yaml. 2017-05-14 11:52:42 +01:00
Paul Chote
430429f337 Fix WRot FieldLoader parsing. 2017-05-14 11:52:42 +01:00
reaperrr
b8c251cf41 Add StartBurstReport to WeaponInfo
The FS Juggernaut firing sound already contains 3 shots, so without this, players would hear a total of 9(!) shots per salvo.
2017-05-14 11:49:38 +01:00
reaperrr
d502b296bb Upgrade rule for DeployAnimation removal 2017-05-14 00:22:26 -05:00
reaperrr
aa8d9f5dda Fix GrantConditionOnDeploy to support multiple sprite bodies 2017-05-14 00:22:26 -05:00
reaperrr
6f19379a2b Make WithMoveAnimation multi-WithSpriteBody-compatible 2017-05-14 00:22:26 -05:00
reaperrr
3b798897be Add Name ID field to WithSpriteBody 2017-05-14 00:22:26 -05:00
rob-v
48abb7372b Remove ChatSettings.NickName, use PlayerName always as default 2017-05-13 11:40:47 -07:00
reaperrr
5b8c313d55 Remove lint rule for victim scan radii
They're now calculated automatically to use the most sensible value by default. Only people who know what they're doing or fool around will use custom values, and in that case a lint rule might actually just annoy people.
2017-05-13 11:15:38 -07:00
reaperrr
96d629cefd Upgrade rule for victim scan radii changes
The game/engine now calculates the best values automatically and the field names have changed, so instead of renaming, we can just remove them under the assumption that only modders who really know what they're doing will ever use the override.
2017-05-13 11:15:38 -07:00
reaperrr
d04c6275da Make warheads use the the most sensible victim scan radius
By default, but allow custom overrides.
2017-05-13 11:15:38 -07:00
reaperrr
033268a7ba Make projectiles use most sensible blocker scan radius
By default, but allow custom overrides.
2017-05-13 11:15:38 -07:00
reaperrr
9f9d1f9e5f Added helper utility for finding best hit-shape scan radius 2017-05-13 11:15:38 -07:00
reaperrr
d92d9f86fc Add IBlocksProjectilesInfo interface 2017-05-13 11:15:38 -07:00
Zimmermann Gyula
0d2d17d2fb Fix the AI acting the same at game restart. 2017-05-13 19:08:20 +01:00
reaperrr
db85fff7c0 Remove TS infantry hit-shape height
We should either implement this for all non-blocker actors at once, or not at all. By now we have walls/gates as examples for vertical shape height, so for now there's no reason to leave this on infantry.
2017-05-13 10:51:41 -07:00
reaperrr
91c65f1e9c Adapt blocking height of TS walls etc.
to WDist rescaling.

Also, make wall hit-shape height match blocking height and tweak it to
approximate original TS behaviour as much as possible (Tick Tanks could
shoot over them, but only from certain angles/distances).
2017-05-13 10:51:41 -07:00
reaperrr
ccda89f268 Refactor Shape.Rectangle.RotateToIsometry
And fixes TS wall and gate shapes.
2017-05-13 10:51:41 -07:00
C. Helmig
b11af3bcb5 D2k editor: Moved all appropriate tiles into Cliff-Type-Changer and replaced Sand-Smooth with Cliff-Ends category. 2017-05-13 10:48:37 -07:00
reaperrr
97ec200dcf Merge pull request #13282 from pchote/osx-fullscreen
Work around resolution issues in (legacy) Fullscreen on OSX.
2017-05-13 15:51:10 +02:00
Paul Chote
42232f4a55 Work around resolution issues in (legacy) Fullscreen on OSX. 2017-05-13 00:02:29 +01:00
reaperrr
cf65bb6e41 Merge pull request #13203 from reaperrr/ts-balance-fixes
Fix some wrong TS unit stats
2017-05-12 15:30:39 +02:00
reaperrr
5e736527b7 Merge pull request #13223 from pchote/mod-package-loaders
Unhardcode mod package loaders
2017-05-12 14:04:58 +02:00
reaperrr
2a0cfa5c43 Merge pull request #13278 from reaperrr/disable-win-dpi
Disable DPI scaling on Windows by default
2017-05-12 01:11:15 +02:00
reaperrr
f0c6e5e855 Disable DPI scaling on WIndows by default 2017-05-11 20:09:13 +02:00
abcdefg30
618ac5838a Merge pull request #13215 from pchote/packaging-simplification
Overhaul packaging scripts
2017-05-10 16:34:01 +02:00
atlimit8
55de4a59d0 Merge pull request #13247 from pchote/widget-evaluator-expressions
Replaced legacy Evaluator with IntegerExpressions.
2017-05-08 21:19:52 -05:00
atlimit8
4a80c37507 Merge pull request #13253 from pchote/rescale-isometric-world-coords
Rescaled isometric world coordinates to measure 1024 along the cell axes.
2017-05-08 20:59:51 -05:00
reaperrr
e94ef1658f Merge pull request #13156 from MustaphaTR/d2k-harkonnen-3b
D2K - Add Harkonnen Mission 3b
2017-05-07 16:53:26 +02:00
Paul Chote
552cf83951 Fix missile characteristics. 2017-05-07 13:49:50 +01:00
Paul Chote
fc29438748 Fix grenade speed. 2017-05-07 13:49:44 +01:00
Paul Chote
d2973801e4 Update TS LocalOffsets for new coordinate system. 2017-05-07 13:47:12 +01:00
Paul Chote
cf09b99ed8 Adjust TS subcell positions for new coordinate system. 2017-05-07 13:45:30 +01:00
Paul Chote
cdf2df58a0 Define RectangularIsometric world coordinate scale along the cell axis. 2017-05-07 13:45:30 +01:00
Paul Chote
5dcb840f9f Fix WithHarvesterOffset.LocalOffset name. 2017-05-07 13:44:47 +01:00
Paul Chote
a3f7641b68 Move D2kSoundResources to Mods.D2k dll. 2017-05-07 13:25:43 +01:00
Paul Chote
0222ea675c Implement mod-defined package loaders. 2017-05-07 13:25:38 +01:00
Paul Chote
9b4f602cca Remove unused leftover oramod loading code. 2017-05-07 13:25:04 +01:00
Paul Chote
248c12827e Resolve assembly paths before loading the FileSystem. 2017-05-07 13:25:03 +01:00
Paul Chote
f0d7a6caca Move GetLoaders to ObjectCreator. 2017-05-07 13:25:03 +01:00
reaperrr
74437ed56c Merge pull request #13178 from rob-v/ReturnHeliToNearestBase
Helis return to nearest base like Planes
2017-05-07 13:16:40 +02:00
reaperrr
1194f14cfe Merge pull request #13232 from rob-v/NumberAIPlayers
Number AI players
2017-05-07 13:09:20 +02:00
reaperrr
e9926fdc28 Merge pull request #13248 from pchote/detect-key-repeat
Prevent repeated keys from toggling observer shroud selector.
2017-05-07 13:03:34 +02:00
Paul Chote
e6ec071ceb Merge pull request #13093 from rob-v/ServicePadMoveToRallyPoint
Fix Service Depot Rally point path finding
2017-05-07 08:48:47 +01:00
Paul Chote
d787429a2e Merge pull request #12996 from atlimit8/RemoveIDisable-part2
Remove IDisable - part 2
2017-05-07 08:38:09 +01:00
atlimit8
e01c79be06 Added rule upgrade notice for support powers' PauseOnCondition. 2017-05-06 17:19:43 -05:00
atlimit8
431f06cd49 Convert support powers from actor disabled to pausable-conditional. 2017-05-06 17:19:43 -05:00
atlimit8
9a1ba31753 Added upgrade rule for PauseOnLowPower removal & AffectedByPowerOutage condition granting. 2017-05-06 17:19:43 -05:00
atlimit8
700b117122 Convert WithRepairAnimation from disable to conditional. 2017-05-06 17:19:43 -05:00
atlimit8
5fd4b3a1bd Convert WithRearmAnimation from disable to conditional. 2017-05-06 17:19:42 -05:00
atlimit8
b0706e7cd0 Removes actor disabled support from WithIdleAnimation. 2017-05-06 17:19:42 -05:00
atlimit8
0dfdea1826 Convert AffectedByPowerOutage from disabler to conditional condition granter. 2017-05-06 17:19:42 -05:00
atlimit8
61b84e0c5a Added ts power outage WithIdleOverlay polish. 2017-05-06 17:19:42 -05:00
atlimit8
64a2b9de55 WithRepairOverlay into pausable-conditional trait EMP disabled polish. 2017-05-06 17:19:42 -05:00
atlimit8
1c5427c86f Convert WithIdleOverlay from actor disabled to pausable-conditional. 2017-05-06 17:19:42 -05:00
atlimit8
11933c7e2c Added /poweroutage dev command. 2017-05-06 17:19:39 -05:00
rob-v
fb1d8d780f Fix Service Depot Rally point path finding (+rename ignoredActor) 2017-05-06 19:49:40 +02:00
Paul Chote
c867687d9a Prevent repeated keys from toggling observer shroud selector. 2017-05-06 14:13:12 +01:00
Paul Chote
fff2f097d0 Add KeyInput.IsRepeat. 2017-05-06 14:10:24 +01:00
Paul Chote
cd0898236d Replace legacy Evaluator with IntegerExpressions. 2017-05-06 13:50:30 +01:00
reaperrr
669cf01d80 Merge pull request #13224 from daVoodooShuffle/fix-13153
Cleaned Up Chrome Expression Whitespacing
2017-05-06 14:44:40 +02:00
Paul Chote
9be5ef2bd5 Merge pull request #13214 from GraionDilach/expand-disguise
Expose the drop-disguise-when-attacking aspect to yaml.
2017-05-06 12:00:02 +01:00
daVoodooShuffle
53bf52149c Closes #13153
Modified all expressions to contain a space on either side

Only effects the YAML files that contain config variables:

X:
Y:
Width:
Height:
2017-05-06 15:26:41 +10:00
reaperrr
22d8167d49 Merge pull request #13162 from pchote/tunnel-enter-cursor
Implement "Enter Tunnel" cursor
2017-05-05 23:47:57 +02:00
reaperrr
f5ddea305a Merge pull request #13217 from pchote/jumpjet-death
Fix jumpjet flying death animations
2017-05-05 13:11:17 +02:00
Zimmermann Gyula
81b79a1b29 Expose the drop-disguise-when-attacking aspect to yaml.
Also adds Damaged for more usecases.
2017-05-05 07:58:14 +02:00
atlimit8
4ec0089250 Merge pull request #13219 from GraionDilach/fix-rangemodifier-regression
Fix RangeMultiplier regression.
2017-05-04 20:10:13 -05:00
reaperrr
ea29cce3cf Merge pull request #13002 from rob-v/LobbyOptionsEditableByHost
Host can change Team and Spawn of any player. #12936
2017-05-04 19:15:01 +02:00
reaperrr
c4e79a11a8 Merge pull request #12919 from obrakmann/transform-refactor
Refactor Transform to make use of child activities
2017-05-04 18:55:41 +02:00
rob-v
1ff11d4115 Number AI players 2017-05-03 19:33:04 +02:00
Zimmermann Gyula
c48cf51190 Fix RangeMultiplier regression. 2017-05-01 14:47:17 +02:00
Paul Chote
21a10f84a5 Fix jumpjet flying death animations. 2017-05-01 11:43:18 +01:00
Paul Chote
7a7b668f2b Merge pull request #12999 from reaperrr/RevealOnDeath
Add RevealOnDeath trait
2017-05-01 11:17:18 +01:00
reaperrr
dcf31f356d Merge pull request #13211 from pchote/d2k-hires-logo
Add new d2k mod logo
2017-05-01 12:02:07 +02:00
reaperrr
dbe4b670d0 Make D2k structures reveal shroud on death 2017-05-01 11:57:12 +02:00
Paul Chote
5a273700bf Merge pull request #13204 from IceReaper/reloading-sound
Added ReloadSound and ReloadSoundDelay to weapon declarations.
2017-05-01 00:05:19 +01:00
Andre Mohren
d68bc48ba5 Added ReloadSound and ReloadSoundDelay to weapon declarations. 2017-04-30 22:43:32 +02:00
reaperrr
437f9a7930 Merge pull request #12955 from atlimit8/RemoveIDisable-part1
Remove IDisable - part 1
2017-04-30 21:21:12 +02:00
Oliver Brakmann
f9913db5e8 Make Transform use child activities 2017-04-30 19:40:14 +01:00
Oliver Brakmann
f9951f76ca Allow cancelling an activity without aborting the entire queue 2017-04-30 19:07:50 +01:00
atlimit8
166063337e Make Repair activity halt if RepairsUnit is paused or abort if disabled. 2017-04-30 09:59:03 -05:00
atlimit8
6075569659 Make RepairsUnits pausable-conditional 2017-04-30 09:48:02 -05:00
atlimit8
748afad45e Added PausableConditionalTrait abstract trait 2017-04-30 09:47:28 -05:00
atlimit8
18eddf4a70 Convert ProximityExternalCondition from disable-able to conditional. 2017-04-30 09:46:56 -05:00
atlimit8
770efd710b Remove DisabledOverlay using WithColoredOverlay & remove IDisable from Husk 2017-04-30 09:46:21 -05:00
Paul Chote
705d77501b Add new high resolution D2K mod logo. 2017-04-30 13:38:12 +01:00
Paul Chote
696b48b7bf Overhaul the packaging scripts:
- Ingame mod versions now always match the package version
- Adds macOS compatibility
- Removes trait and lua api docs pending future overhaul
- Individual platform packages can be compiled directly
- Improved error checking
- Removes unnecessary redundancy and indirection
2017-04-30 13:26:36 +01:00
Paul Chote
3111b2cf9b Merge pull request #13129 from pchote/osx-packaging
Update OSX packaging for per-mod launchers.
2017-04-30 13:23:42 +01:00
Paul Chote
e0adbe652e Merge pull request #13138 from pchote/deb-packaging
Update Linux packaging for per-mod launchers.
2017-04-30 13:21:39 +01:00
reaperrr
1349dfb670 Merge pull request #13210 from pchote/polish-deployers
Polish TS deployer animations
2017-04-30 12:14:40 +02:00
reaperrr
d5740efda8 Merge pull request #13186 from rob-v/TakeScreenshotInDialogs
Take screenshot in dialogs #13184
2017-04-30 11:53:13 +02:00
rob-v
382fefebfe Take screenshot in dialogs #13184 2017-04-30 10:17:55 +02:00
Paul Chote
1871715699 Implement "Enter Tunnel" cursor. 2017-04-29 15:58:42 +01:00
Paul Chote
10734f2877 Reenable and polish broken bridge in Sunstroke. 2017-04-29 15:50:16 +01:00
Paul Chote
43ff56eea9 Fix tunnel top definitions. 2017-04-29 15:50:16 +01:00
Taryn Hill
12f2fc3410 Merge pull request #13175 from rob-v/GlobalChat
Enhance - unify global chat (with lobby chat)
2017-04-29 09:28:34 -05:00
atlimit8
cb6e4b9926 Merge pull request #13202 from reaperrr/UpgradeRejectsOrders
Add Reject field to RejectsOrders for blacklisting orders.
2017-04-29 08:51:34 -05:00
Paul Chote
69ca9ffaba Set the default voxel Scale to match the original game. 2017-04-29 13:21:13 +01:00
Paul Chote
4e6af29bb8 Match LPST pre/post deploy sizes and offsets. 2017-04-29 12:21:30 +01:00
Paul Chote
993f4ee6da Match TTNK pre/post deploy sizes and offsets. 2017-04-29 12:21:10 +01:00
reaperrr
53aaa28a71 Remove bogus Turreted from TS amphib APC 2017-04-29 13:13:53 +02:00
reaperrr
0c6911bd2f Fix Mobile Sensor Array sight ranges to match original 2017-04-29 13:13:23 +02:00
reaperrr
398956b690 Add support for multiple RejectsOrders traits per actor 2017-04-29 12:56:30 +02:00
atlimit8
4917c6e453 Merge pull request #12924 from reaperrr/fix-tunnel-atk
Prevent units in tunnels/underground from attacking
2017-04-29 00:25:23 -05:00
reaperrr
9759fce9d7 Fix TS MCV stats to match original 2017-04-27 21:33:37 +02:00
reaperrr
2d2d869b5a Fix TS engineer health to match original 2017-04-27 21:18:48 +02:00
reaperrr
965a73fc53 Fix TS infantry sight range
In original TS, E1 had 5, E2 and E3 had 7.
2017-04-27 21:18:23 +02:00
reaperrr
0a484b424e Fix TS infantry move speed
E3 speed in original was 4.
JumpJet ground speed in original was 5.
2017-04-27 21:17:06 +02:00
reaperrr
1fae993593 Prevent attacking while in tunnel/underground 2017-04-27 17:50:02 +02:00
Paul Chote
bc38cb3cc2 Package OSX launchers in a disk image. 2017-04-26 22:17:27 +01:00
Paul Chote
74bbde751f Create separate OSX launchers for each mod. 2017-04-26 22:17:26 +01:00
Paul Chote
60bc114e39 Merge pull request #13133 from pchote/windows-packaging
Update Windows packaging for per-mod launchers.
2017-04-26 22:12:05 +01:00
Paul Chote
c8af9168c9 Improve general installer quality:
- Remove uninstaller and readme start menu links
  (they are explicitly discouraged by best practices)
- Explicitly declare installer execution level
- Define additional control panel metadata
2017-04-26 22:00:42 +01:00
Paul Chote
2c1b8da7fd Merge pull request #13191 from Enverex/patch-1
Correct make install command for Linux
2017-04-26 21:58:17 +01:00
reaperrr
539ed67527 Merge pull request #13190 from pchote/object-weirdness
Fix ObjectCreator assembly resolving on Windows.
2017-04-26 21:29:33 +02:00
atlimit8
2ae40e7eb4 Merge pull request #13181 from pchote/repair-cursor-flash
Fix repair cursor visual feedback target.
2017-04-25 16:52:10 -05:00
reaperrr
61a1cc18e1 Merge pull request #13195 from atlimit8/ActorExts-AppearsFriendlyTo-simplification
ActorExts.AppearsFriendlyTo Simplification
2017-04-25 23:29:37 +02:00
atlimit8
6aaa7fa042 ActorExts.AppearsFriendlyTo simplification 2017-04-25 15:53:50 -05:00
Paul Chote
a01b3f88fc Remove unused ObjectCreator constructor. 2017-04-25 21:49:37 +01:00
Paul Chote
8dd50c0421 Keep ObjectCreator ResolveAssembly override bound until disposal. 2017-04-25 21:49:37 +01:00
Benjamin Hodgetts
8abf5ce372 Correct make install command
No-longer "install-all".
2017-04-25 12:08:13 +01:00
reaperrr
a9676235db Add custom DeathTypes/DamageTypes support to RevealOnDeath 2017-04-24 19:12:31 +02:00
reaperrr
7dddc7fc44 Make FallToEarth kill the actor instead of disposing it 2017-04-24 19:12:31 +02:00
reaperrr
6045ad2ecf Make D2k units reveal shroud on destruction
For 4 seconds.
2017-04-24 19:12:31 +02:00
reaperrr
4bfd306cc2 Add RevealOnDeath trait
Allows revealing shroud on actor death.
2017-04-24 19:12:31 +02:00
Paul Chote
d9800d4e2b Fix repair cursor visual feedback target. 2017-04-24 08:52:48 +01:00
atlimit8
99f3f37afe Merge pull request #13104 from rob-v/RepairNavalUnitsWithRepairCursor
Naval units (RepairableNear) units repairable using Repair cursor
2017-04-23 22:05:46 -05:00
atlimit8
fe03929e6b Merge pull request #13174 from reaperrr/ts-floater
Add Tiberium Floater to TS
2017-04-23 21:38:27 -05:00
reaperrr
e8f16b1b75 Merge pull request #13150 from rob-v/SaveMapError
Show 'Failed to save map' error message in dialog box
2017-04-23 15:29:10 +02:00
reaperrr
9ce110f6d9 Merge pull request #12971 from rob-v/LobbyResetingPlayerName
Global chat name is reset when connecting
2017-04-23 15:11:24 +02:00
reaperrr
2dc528899e Add Tib Floaters to Sunstroke 2017-04-23 15:00:33 +02:00
reaperrr
f3f443d904 Add FS Tiberium Floater to TS
For better compatibility with FS maps, and more variety for mappers.
2017-04-23 15:00:31 +02:00
rob-v
bd025873cf Host can change Team and Spawn of any player. #12936 2017-04-23 12:06:44 +02:00
atlimit8
172161b9fe Merge pull request #13180 from GraionDilach/make-ps1-gamemonitor
Remove the bitrot GameMonitor StyleCop check.
2017-04-22 22:46:01 -05:00
atlimit8
7a7197216c Merge pull request #13025 from pchote/laser-fence
Implement TS Laser Fences
2017-04-22 19:41:36 -05:00
Paul Chote
fcbdb147ed Update build icon order. 2017-04-23 00:44:11 +01:00
Paul Chote
0ddb631117 Add TS Laser Fences. 2017-04-23 00:44:11 +01:00
Paul Chote
64896eb73d Add EnergyWall trait. 2017-04-23 00:44:11 +01:00
Paul Chote
a83c0f96dd Add GrantConditionOnLineBuildDirection trait. 2017-04-23 00:44:10 +01:00
Paul Chote
f8af51643d Add LineBuildSegmentExternalCondition. 2017-04-23 00:44:10 +01:00
Paul Chote
a8bb03aa34 Draw TS line-build cell previews with increased translucency. 2017-04-23 00:44:10 +01:00
Paul Chote
227b80d6c2 Add support for removing segments when parent nodes are removed. 2017-04-23 00:44:10 +01:00
Paul Chote
304e3ef9f9 Distinguish between line build nodes and segments. 2017-04-23 00:44:09 +01:00
Paul Chote
62603b324d Add support for granting a condition while the make animation plays. 2017-04-23 00:44:09 +01:00
Paul Chote
2b9b9bb984 Fix powerdown indicator position. 2017-04-23 00:44:09 +01:00
Paul Chote
227655f9aa Fix wall artwork interaction with conditions. 2017-04-23 00:44:09 +01:00
Paul Chote
ac53bc502e Remove bogus Requires<HealthInfo> from GrantConditionOnDisabled. 2017-04-23 00:44:08 +01:00
Zimmermann Gyula
2ca6721027 Remove the bitrot GameMonitor StyleCop check. 2017-04-22 23:17:39 +02:00
atlimit8
6744cec239 Merge pull request #13172 from pchote/mod-metadata-cleanup
Remove metadata that was only used by the mod chooser.
2017-04-22 15:57:53 -05:00
rob-v
1206205d17 Enhance - unify global chat (with lobby chat) 2017-04-22 20:25:20 +02:00
reaperrr
ac1d45211d Merge pull request #13134 from atlimit8/NegMinusExpressionParsing
VariableExpression: whitespace/hyphen/binop parsing fix
2017-04-22 19:33:47 +02:00
reaperrr
e29c234ce9 Merge pull request #13164 from reaperrr/ts-arty-deploy
Migrate TS artillery deployment to condition system
2017-04-22 16:44:00 +02:00
reaperrr
863d477928 Merge pull request #13157 from atlimit8/RemoveDictionaryLoadUsings
Remove LoadUsing where FieldLoader.GetValue works for the dictionaries
2017-04-22 16:27:13 +02:00
reaperrr
9ca75d6c8d Merge pull request #13176 from pchote/fix-td-dialog-spam
Remove invalid Background widgets from TD map editor.
2017-04-22 16:15:35 +02:00
rob-v
df07d89f9e Helis return to nearest base like Planes 2017-04-22 15:53:05 +02:00
reaperrr
b53ac5df36 Merge pull request #13074 from atlimit8/IConditionConsumerProvider
Better Support for Multiple Condition Expressions in a Trait
2017-04-22 15:48:37 +02:00
atlimit8
d433473249 Replace IConditionConsumer w/ variable observers for multiple variable expressions for traits. 2017-04-22 08:36:18 -05:00
reaperrr
9f8e9426af Merge pull request #13005 from rob-v/LobbyMapTooltips
Added tooltip to Lobby Map title #12930 #12595
2017-04-22 15:31:34 +02:00
Paul Chote
2e751e937f Remove invalid Background widgets from TD map editor. 2017-04-22 14:17:33 +01:00
atlimit8
8a04156280 VariableExpression: require whitespace around bool/arithmetic binary operators. 2017-04-22 08:14:52 -05:00
rob-v
63de0bb910 Fix ignored 'Failed to save map' #13036 2017-04-22 14:44:06 +02:00
reaperrr
1e63013eb1 Add support for random sounds to AmbientSound 2017-04-22 14:36:55 +02:00
Paul Chote
9b93771dbc Remove metadata that was only used by the mod chooser. 2017-04-22 11:31:43 +01:00
Paul Chote
b24e681531 Create separate Linux launchers for each mod. 2017-04-21 20:18:05 +01:00
Paul Chote
62b0be9db8 Allow non-openra:// Launch.URI prefixes. 2017-04-21 20:18:05 +01:00
Paul Chote
07dc79ab19 Separate release/playtest/git installs. 2017-04-21 20:16:58 +01:00
Paul Chote
3e0f055a3c Create separate Windows launchers for each mod. 2017-04-21 20:16:58 +01:00
Paul Chote
b5523d6b3f Allow non-openra:// Launch.URI prefixes. 2017-04-21 20:16:58 +01:00
Paul Chote
4c990e48d7 Merge pull request #13166 from gdavegdave/bleed
Tweaked map Deterring Democracy to fix harvester stall
2017-04-21 18:52:16 +01:00
GDave
8dbeada0f7 Tweaked map Deterring Democracy to prevent harvester stalling to the immediate right of the lower-right green tree. 2017-04-21 18:40:40 +01:00
Oliver Brakmann
7f204b2dec Merge pull request #13049 from pchote/mod-content
Remove ingame mod chooser.
2017-04-21 19:16:49 +02:00
Paul Chote
9d248433c9 Fix linux packaging. 2017-04-21 18:02:20 +01:00
Paul Chote
84db123b93 Rename modchooser to modcontent. 2017-04-21 18:02:20 +01:00
Paul Chote
ff088323b5 Update --man-page utility command. 2017-04-21 18:02:20 +01:00
Paul Chote
ec42aed6bc Redirect mod chooser to content manager. 2017-04-21 18:02:20 +01:00
Paul Chote
688feea33b Require Game.Mod to be give an a launch arg to OpenRA.Game.exe. 2017-04-21 18:02:14 +01:00
Paul Chote
215aa6fa60 Remove support for loading mods from the support dir. 2017-04-21 17:55:15 +01:00
Paul Chote
e984c98565 Remove oramod package support. 2017-04-21 17:55:15 +01:00
Paul Chote
5d5fd7a0e8 Remove RequiredMods logic. 2017-04-21 17:55:15 +01:00
reaperrr
d9eb224c77 Move Tib Fiend and visc rules to critters.yaml 2017-04-21 17:39:25 +02:00
reaperrr
ec704b7e34 Move Tiberian Fiend and visceroid sequences to critters.yaml 2017-04-21 16:53:10 +02:00
Oliver Brakmann
43b9aa00d8 Merge pull request #13161 from reaperrr/mods-cnc-tweak
Unhardcode LightPaletteRotator properties
2017-04-21 15:26:04 +02:00
reaperrr
5e1cd5dff9 Disable automatic turret realign for deployed Tick Tank and Artillery 2017-04-21 12:41:18 +02:00
reaperrr
5789b73091 Convert TS Nod Artillery to condition system
Getting rid of legacy Transforms approach.
2017-04-21 12:41:18 +02:00
atlimit8
c23f248840 Merge pull request #13159 from pchote/return-to-ground
Force Mobile units to return to the ground layer when becoming idle.
2017-04-20 23:55:58 -05:00
reaperrr
4a8571161a Unhardcode LightPaletteRotator properties 2017-04-21 00:24:23 +02:00
atlimit8
3fbdde5317 Merge pull request #13160 from pchote/fix-tunnel-harvesting
Fix harvesters harvesting resources from underground.
2017-04-20 16:21:48 -05:00
reaperrr
04f8a85cc6 Make LightPaletteRotator interfaces explicit and add desc 2017-04-20 21:12:07 +02:00
Paul Chote
c5547ec20b Fix harvesters harvesting resources from underground. 2017-04-20 19:57:26 +01:00
reaperrr
bb9790c754 Move legacy map import commands into matching subfolder 2017-04-20 20:50:04 +02:00
Paul Chote
b373714da7 Force Mobile units to return to the ground layer when becoming idle. 2017-04-20 19:48:21 +01:00
reaperrr
60fccc1bc4 Merge pull request #12980 from abcdefg30/laysTerrain
Update the documentation of LaysTerrain
2017-04-20 20:10:14 +02:00
reaperrr
ebb6505190 Merge pull request #13106 from abcdefg30/spawnOffset
Add an Offset property to SpawnActorOnDeath
2017-04-20 17:53:33 +02:00
abcdefg30
57bdb1cff3 Update the documentation of LaysTerrain 2017-04-20 15:41:35 +02:00
atlimit8
b97162d9f1 Merge pull request #13110 from MartinCurwen/bleed
Multiple armament check fix in AttackGarrisoned
2017-04-19 12:05:35 -05:00
MartinCurwen
ea6e1fdd64 Multiple armament check fix in AttackGarrisoned 2017-04-19 17:40:14 +01:00
atlimit8
4767b91037 Remove LoadUsing where FieldLoader.GetValue works for the dictionaries 2017-04-19 09:51:06 -05:00
Mustafa Alperen Seki
c94eb2582b Add Harkonnen 3b 2017-04-19 16:46:42 +02:00
Oliver Brakmann
843ac85c92 Merge pull request #13000 from reaperrr/supply-to-cnc
Refactor SupplyTruck/AcceptsSupplies to *Cash traits
2017-04-18 23:38:29 +02:00
Oliver Brakmann
89c19e717f Merge pull request #13118 from MustaphaTR/d2k-harkonnen-3a
D2K - Add Harkonnen Mission 3a
2017-04-18 22:55:31 +02:00
atlimit8
2053aec5f9 Rename VariableExpression.OperandSides => VariableExpression.Sides 2017-04-18 15:22:04 -05:00
atlimit8
c34b947e43 VariableExpression: Restrict CharClass.Mixed to middle of identifiers 2017-04-18 15:15:21 -05:00
atlimit8
f9974624c8 VariableExpression: hyphen after digit lexing fix 2017-04-18 15:14:55 -05:00
reaperrr
225d26bfdb Add explicit Reject field to RejectsOrders 2017-04-18 20:23:00 +02:00
reaperrr
afc1f22c63 Merge pull request #13149 from pchote/defer-tunnel-orders
Require cancelled move orders to exit tunnels before completion.
2017-04-18 19:42:49 +02:00
reaperrr
9814083ac3 Rename DonateSupplies activity to DonateCash 2017-04-18 19:27:46 +02:00
reaperrr
80ec530e4c Refactor supply traits to *Cash traits
Adding 'Type' and 'Stances' support as well.
2017-04-18 19:27:46 +02:00
abcdefg30
361cbc34cc Merge pull request #13139 from AoAGeneral/AoATD
TD Flame infantry spread.
2017-04-18 17:10:27 +02:00
abcdefg30
7416cd0ac1 Add an Offset property to SpawnActorOnDeath 2017-04-18 17:09:25 +02:00
abcdefg30
23ba3cfcb6 Merge pull request #13050 from rob-v/DefeatedPlayersCanNotPauseGame
Lost players except Host can not pause game #12227
2017-04-18 17:00:04 +02:00
abcdefg30
8e6f6a3a52 Merge pull request #13007 from rob-v/ProductionStatisticsTooltip
Add tooltips to production statistics #12820
2017-04-18 16:55:05 +02:00
Oliver Brakmann
e164a6119d Merge pull request #13123 from SoScared/fix3maps
[RA] [Map Pool] Fix tiles on Countercross, Siberian Pass & Six Below Zero.
2017-04-18 16:29:26 +02:00
Paul Chote
0b0f8bc51e Require cancelled move orders to exit tunnels before completion. 2017-04-17 22:34:21 +01:00
Paul Chote
c6d8957307 Merge pull request #13080 from reaperrr/fix-ts-effectlighting
Make TS explosions + muzzle flashes unaffected by global lighting
2017-04-17 21:14:44 +01:00
rob-v
199e9847d1 Add tooltips to production statistics #12820 2017-04-17 21:51:23 +02:00
reaperrr
2548e62e31 Merge pull request #13148 from obrakmann/fix13147_fix-rtb-dead-dest-race
Check for dead destination airfield in ReturnToBase
2017-04-17 20:41:39 +02:00
Oliver Brakmann
b50f15c645 Check for dead destination helipad in HeliReturnToBase 2017-04-17 19:31:53 +02:00
Oliver Brakmann
ff8f204cac Check for dead destination airfield in ReturnToBase 2017-04-17 19:23:11 +02:00
Paul Chote
6df453f806 Merge pull request #13127 from obrakmann/fix13099_disableDpiScalingSetting
Add a setting to disable DPI scaling on Windows systems
2017-04-17 17:46:46 +01:00
Oliver Brakmann
3ec6754289 Merge pull request #13141 from pchote/mod-urls
Move web urls from user config to mod config.
2017-04-17 17:13:52 +02:00
Paul Chote
462ee48c60 Merge pull request #13119 from rob-v/DownloadPackageErrorLog
Add exception message to Download (Invalid archive) error #12985
2017-04-17 15:14:36 +01:00
Matthias Mailänder
37219ad67b Make Tiberian Sun railways passable by trains. 2017-04-17 15:11:33 +01:00
Matthias Mailänder
4480f49e0f Add ChangesTerrain. 2017-04-17 15:11:33 +01:00
reaperrr
1860b448b7 Merge pull request #13143 from reaperrr/icereap-bleed
Added WithTurretedAttackAnimation
2017-04-17 16:10:42 +02:00
Paul Chote
774a717c19 Merge pull request #13117 from abcdefg30/veteranOverlay
Fixed VeteranProductionIcons not being disabled when Prerequisites are removed
2017-04-17 14:47:32 +01:00
Andre Mohren
9b22f0e11a Support attack animation for turrets via new WithTurretedAttackAnimation trait. 2017-04-17 15:34:45 +02:00
reaperrr
1d3daa5e4d Merge pull request #13108 from atlimit8/ConditionsToVariables
ConditionExpression to (Boolean|Integer)Expression refactor
2017-04-17 14:52:21 +02:00
reaperrr
4c63c7bdd8 Merge pull request #13096 from rob-v/DisableEdgeScrollWhileStandardScroll
Fix/Disable Edge scroll while standard (middle mouse) scroll
2017-04-17 14:36:21 +02:00
Paul Chote
1722f42f83 Move web urls from user config to mod config. 2017-04-17 12:00:41 +01:00
AoAGeneral
ddc31825ec TD Flame infantry spread.
Increases the flame infantry attack spread from 341 to 468.

This allows the flame infantry to have a wider cone attack as the previous 10 damage increase helped. They still however lacked the wide attack spread needed on massive infantry assaults. Their attack spread matches that of grenadiers and a lot of armaments (Artillery) and being a frontal unit can use a slight increase to help with this.
Units going prone still takes three hits to kill infantry (two for e3 and anyone standing).
2017-04-16 14:13:12 -07:00
SoScared
7168912273 Fix tiles on Countercross, Siberian Pass, Sudden Death & Six Below Zero. 2017-04-15 19:50:12 +02:00
reaperrr
04f5937476 Merge pull request #13086 from kyrylo/winter-storm-update
mods/ra/maps: update Winter Storm
2017-04-15 13:45:24 +02:00
reaperrr
8c1ed0d39f Merge pull request #13102 from abcdefg30/06yak
Fix allies06a freezing when yaks try to attack camo pillboxes
2017-04-15 12:36:18 +02:00
Oliver Brakmann
0635f3636d Add a setting to disable DPI scaling on Windows systems 2017-04-14 23:23:14 +02:00
Oliver Brakmann
3cd7493664 Merge pull request #13095 from jrb0001/licenseheaders-lua
add GPLv3+ header to all lua scripts
2017-04-14 22:25:46 +02:00
Oliver Brakmann
63e4fbc5ad Merge pull request #12828 from Phrohdoh/util-engine-mod-search-paths
Utility and server: Get mod search paths from env MOD_SEARCH_PATHS
2017-04-14 21:59:09 +02:00
Paul Chote
9637e1b2c7 Merge pull request #13120 from MustaphaTR/update-openra-sln-for-lua-again
Add new lua files added with new D2K missions to OpenRA.sln (Again)
2017-04-14 14:54:56 +01:00
rob-v
ee91396984 Add exception to Archive extraction failed (Invalid archive) error ##12985 2017-04-13 20:44:03 +02:00
Mustafa Alperen Seki
cdf01cc25b Update OpenRA.sln for lua files again 2017-04-13 18:51:16 +02:00
abcdefg30
87a44023b2 Fixed VeteranProductionIcons not being disabled when Prerequisites are removed 2017-04-13 17:54:17 +02:00
Mustafa Alperen Seki
c170f658ff Add Harkonnen 3a 2017-04-13 17:53:01 +02:00
abcdefg30
81fe19ca4a Merge pull request #12966 from pchote/windows-launcher
Reorganize Windows game launcher to support per-mod launchers.
2017-04-13 15:34:10 +02:00
reaperrr
e043539805 Merge pull request #13056 from AoAGeneral/AoATD
TD Commando ScanRadius.
2017-04-12 20:39:36 +02:00
reaperrr
b0caa104f6 Merge pull request #13053 from MustaphaTR/ts-build-palette-orders
TS - Reorder the Cameos
2017-04-12 20:38:29 +02:00
reaperrr
e058eae706 Merge pull request #13063 from MustaphaTR/d2k-ordos-4
D2K - Add Ordos Mission 4
2017-04-12 20:30:25 +02:00
reaperrr
8e5fbfe227 Merge pull request #12785 from abcdefg30/atreides05
Add atreides05
2017-04-12 19:26:02 +02:00
reaperrr
fb4cb04934 Merge pull request #13066 from rob-v/MouseWheelZoomWithoutModifier
Mouse wheel zoom without modifier option
2017-04-12 19:20:28 +02:00
reaperrr
f33bf002ea Merge pull request #13109 from abcdefg30/clean
Fix the make.ps1 clean command not removing all files
2017-04-12 19:13:47 +02:00
reaperrr
882b5da20d Make TS explosions and muzzle flashes 'glow' on darker maps
The new effectglow palette is not affected by global lighting, making effects 'glow' at full light on darker maps.
Exception: pistol/rifle/machine gun piffs.
2017-04-12 19:11:24 +02:00
abcdefg30
39cdf65764 Fix the make.ps1 clean command not removing all files 2017-04-12 01:14:07 +02:00
atlimit8
6b18eb1993 Merge pull request #12977 from rob-v/RallyPointPrimaryBuilding
When changing rally point with ctrl also make primary
2017-04-11 18:05:16 -05:00
abcdefg30
035c4adeb0 Merge pull request #12909 from pchote/file-handlers
Remove oramod and orarep file type handlers from Windows and Linux.
2017-04-12 01:01:34 +02:00
rob-v
a11ff104a2 Lost players except Host can not pause game #12227 2017-04-11 21:40:59 +02:00
rob-v
9216427c2b RepairableNearUnitsWithRepairCursor #12361 2017-04-11 19:03:41 +02:00
abcdefg30
739653ce37 Merge pull request #13089 from rob-v/FixPreDamagedTilesHealth
Fix Pre-damaged bridge tiles visually transform to new #13076
2017-04-11 18:22:01 +02:00
Paul Chote
bbbf3b086b Add multi-resolution RA logo icon. 2017-04-11 17:17:47 +01:00
Paul Chote
2997f31bc3 Set OpenRA.Game.exe icon to match the mod. 2017-04-11 17:17:47 +01:00
Paul Chote
8e96d85d24 Allow runtime mod to be customized. 2017-04-11 17:15:22 +01:00
Paul Chote
31a91a0269 Allow FAQ URL to be customized. 2017-04-11 17:15:21 +01:00
Paul Chote
044a5e18ee Allow mod display name to be customized. 2017-04-11 17:15:21 +01:00
Paul Chote
005b4166cc Move Windows launcher compilation to packaging scripts. 2017-04-11 17:15:21 +01:00
Paul Chote
35249c1faf Remove windows icon from OpenRA.Game.exe. 2017-04-11 17:15:20 +01:00
Paul Chote
a853d431fc Remove long unneeded tools target. 2017-04-11 17:15:20 +01:00
abcdefg30
3808a1885e Merge pull request #12976 from rob-v/ConnectionFailedCustomMap
Connection Failed when trying to join custom map #12881
2017-04-11 13:15:23 +02:00
abcdefg30
e37667efb6 Merge pull request #12606 from reaperrr/forward-bombs2
Add forward movement support to GravityBomb
2017-04-11 13:07:15 +02:00
abcdefg30
60531c6eef Merge pull request #13088 from pchote/muzzle-fix
Fix duplicate muzzle rendering.
2017-04-11 12:58:47 +02:00
atlimit8
b0187dd646 Added (Boolean|Integer)Expression subclasses of VariableExpression 2017-04-11 02:52:54 -05:00
atlimit8
e73d3922dd Rename ConditionExpression => VariableExpression 2017-04-11 01:26:38 -05:00
Jean-Rémy Buchs
fc725c6c0c add GPLv3+ header to all lua scripts 2017-04-10 21:13:51 +02:00
rob-v
e87a96f2b8 Fix/Disable Edge scroll while standard (middle mouse) scroll 2017-04-10 19:56:53 +02:00
Kyrylo Silin
09c610e2cc mods/ra/maps: update Winter Storm
Map link: http://resource.openra.net/maps/20503/

Changes:

* Renamed from `Winter Storm 2` to `Winter Storm`
* Decorated the chain links near middle oil derricks
* Resized the map from 89x82 to 89x86 to add more sea tiles to the top
  and to the bottom
* Fixed broken tile near the ridge to the middle right
2017-04-10 10:32:21 +03:00
reaperrr
1fa8286f1e Merge pull request #13085 from kyrylo/tandem-update
mods/ra/maps: update Tandem
2017-04-10 00:31:28 +02:00
reaperrr
563d9abce9 Merge pull request #13083 from kyrylo/behind-the-veil-update
mods/ra/maps: update Behind the Veil
2017-04-10 00:22:28 +02:00
abcdefg30
14ece703ef Fix allies06a freezing when yaks try to attack camo pillboxes 2017-04-09 15:50:27 +02:00
Mustafa Alperen Seki
2ca3a1d120 Reorder the TS Cameos 2017-04-09 15:24:49 +02:00
rob-v
4b652aa894 Fix Pre-damaged bridge tiles visually transform to new when attacked #13076 2017-04-09 14:50:36 +02:00
atlimit8
c69a85a328 Merge pull request #12992 from pchote/launch-game-dot-sh
Overhaul launch-game.sh for OS X/Linux/POSIX
2017-04-09 07:13:14 -05:00
Paul Chote
b5068facdc Fix duplicate muzzle rendering. 2017-04-09 12:41:53 +01:00
Paul Chote
5c0674d695 Merge pull request #13048 from reaperrr/fix-ts-lights
Fix some TS building overlays
2017-04-09 11:45:04 +01:00
Paul Chote
77af9ca01d Overhaul launch-game.sh
- Adds macOS support
- Adds mod chooser dialog if zenity available
- Improved text-mode output when zenity not available.
2017-04-09 11:33:27 +01:00
Paul Chote
d7c710e5fc Remove oramod and orarep file type handlers. 2017-04-09 11:09:14 +01:00
Kyrylo Silin
2c678a240c mods/ra/maps: update Tandem
Map link: http://resource.openra.net/maps/20495/

Changes:

* Fixed some bad tiles (thanks to Frame Limiter)

  > Bad tile: 75,45
  > Road tiles: 98,59 , 50,12

* Changed author name from `Kyrylo` to `Kyrylo Silin`
2017-04-09 12:02:36 +03:00
Kyrylo Silin
6d84079a94 mods/ra/maps: update Behind The Veil
Map link: http://resource.openra.net/maps/20494/

Changes:

* Renamed from `Behind The Veil` to `Behind the Veil`
* Replaced chain link with walls in the middle to protect oil derricks
  from direct attacks
* Added barrels to the middle area. A middle oil derrick can be
  captured only from 2 spots (if barrels are not destroyed)
* Added barrels between side ridges
* Fixed some bad road tiles (thanks to Frame Limiter)
* Widen side passages to corner expansions by 1 cell
2017-04-09 11:36:22 +03:00
Oliver Brakmann
3f4f56d728 Merge pull request #13073 from atlimit8/fix-ConditionManager.GrantCondition-doc
Fix ConditionManager.GrantCondition doc
2017-04-08 23:38:17 +02:00
Oliver Brakmann
92bf1f43af Merge pull request #13079 from pchote/fix-carryall-crash
Fix crash when carryall cargo is killed on same tick as pickup.
2017-04-08 22:49:14 +02:00
Oliver Brakmann
59d6b14e06 Merge pull request #13069 from abcdefg30/mtmTran
Fix the extraction helicopter not showing up in Monster Tank Madness
2017-04-08 22:43:27 +02:00
Paul Chote
a82e835f87 Set sensible initial turret facings. 2017-04-08 21:30:38 +01:00
Oliver Brakmann
b9f0504380 Fix friendly monster tanks not revealing shroud in Monster Tank Madness 2017-04-08 20:55:40 +02:00
Paul Chote
043d7587a6 Fix crash when carryall cargo is killed on same tick as pickup. 2017-04-08 12:58:18 +01:00
atlimit8
8f2f54f92f Fix ConditionManager.GrantCondition doc 2017-04-06 22:05:16 -05:00
abcdefg30
8f50052a1c Remove a misplaced barrel 2017-04-05 22:27:39 +02:00
abcdefg30
009cbb74f5 Fix Oil Pumps spawning infantry on death 2017-04-05 22:19:55 +02:00
abcdefg30
d6cf3b35b6 Fix the explosions of the civilian buildings
- it looked weird when they spawned civilians
- other buildings on the map exploded with the wrong explosion
2017-04-05 22:16:37 +02:00
abcdefg30
e4d3712205 Set the initial cash to 0 2017-04-05 21:53:31 +02:00
abcdefg30
49c3dfe2fc Fix the extraction helicopter not showing up in Monster Tank Madness 2017-04-05 21:52:19 +02:00
Oliver Brakmann
737764a47a Merge pull request #13019 from gdavegdave/bleed
Update the official cnc/TD map pool
2017-04-05 21:25:25 +02:00
GDave
d6b9304fd8 Update the official cnc/TD map pool 2017-04-05 11:32:42 +01:00
rob-v
6217cfbcd2 Mouse wheel zoom without modifier option 2017-04-05 10:57:40 +02:00
Mustafa Alperen Seki
1c3276c935 Add Ordos 4 2017-04-05 09:19:17 +02:00
abcdefg30
96e2b4fe70 Add atreides-05 2017-04-04 23:23:44 +02:00
Taryn Hill
4d5f9e0de7 Server: Get mod search paths from env MOD_SEARCH_PATHS 2017-04-03 17:58:44 -05:00
abcdefg30
62a3099215 Merge pull request #13047 from MustaphaTR/d2k-ordos-2b
D2K - Add Ordos Mission 2b
2017-04-03 22:07:53 +02:00
Mustafa Alperen Seki
2c8b2c5c7d Add Ordos 2b 2017-04-03 19:57:24 +02:00
rob-v
ffb639bd7c Added tooltip to Lobby Map title #12930 #12595 2017-04-03 10:11:29 +02:00
atlimit8
1afdcfb749 Merge pull request #12906 from pchote/project-args
Allow specific mods to be launched from MD/XS >= 6.1 GUI.
2017-04-02 21:53:52 -05:00
atlimit8
ee260af064 Merge pull request #13021 from abcdefg30/idleActivity
FlyCircle and HeliFlyCircle count as idle activities.
2017-04-02 21:11:37 -05:00
Taryn Hill
d095ccf668 Utility: Get mod search paths from env MOD_SEARCH_PATHS 2017-04-02 18:49:03 -05:00
AoAGeneral
af85ca8f18 TD Commando ScanRadius. 2017-04-02 14:01:31 -07:00
abcdefg30
6b4700b24f Merge pull request #13045 from reaperrr/fix-ts-grenpal
Fix palette and disable false Report of TS Grenade
2017-04-02 22:32:31 +02:00
Oliver Brakmann
d33a0105a2 Merge pull request #13042 from AoAGeneral/AoATD
TD Artillery/MRLS Vision.
2017-04-02 22:00:59 +02:00
Oliver Brakmann
11f85a1a36 Merge pull request #13020 from abcdefg30/airHunt
Fixed aircraft not being able to hunt
2017-04-02 21:40:34 +02:00
rob-v
c3255e275c Connection Failed when trying to join custom map #12881 2017-04-02 16:26:13 +02:00
Paul Chote
8b9c363222 Merge pull request #12888 from jrb0001/bleed
Load debug symbols for mods if they are loaded from the filesystem
2017-04-02 14:56:17 +01:00
Oliver Brakmann
832ae3149d Merge pull request #13033 from pchote/launch-game-dot-cmd
Add a windows version of the launch-game script.
2017-04-01 19:36:02 +02:00
Oliver Brakmann
b492e1e891 Merge pull request #12973 from rob-v/SortPlayingGamesInLobby
Sort 'Playing' games in the lobby by play time. #12959
2017-04-01 19:20:01 +02:00
reaperrr
d9b3d0fd84 Fix TS helipad anim speed
Too slow on bleed compared to original, especially the GDI one.
2017-04-01 16:39:11 +02:00
reaperrr
8ee67a4438 Fix TS ConYard top lights anim speed
Way too slow on bleed compared to original
2017-04-01 16:35:04 +02:00
reaperrr
fd717041ae Fix TS factory/barracks lights
In TS,
-GDI Factory lights were all idle and didn't have a damaged state
-GDI Barracks lights were all idle, and flag anim played more slowly
-Hand of Nod lights were all idle
-Nod Factory lights were idle
2017-04-01 16:30:20 +02:00
reaperrr
7ba8a19862 Fix palette and disable false Report of TS Grenade 2017-04-01 15:06:09 +02:00
reaperrr
783eb1e9ea Merge pull request #13031 from FrameLimiter/patch-3
Fixed vision for aircraft husks under Gap
2017-04-01 14:22:08 +02:00
abcdefg30
0fa6c7ed3c Merge pull request #12993 from reaperrr/fix-ts-obsicon
Fix TS observer flag alignment
2017-04-01 13:28:36 +02:00
AoAGeneral
537184b65c TD Artillery/MRLS Vision.
This is changing the vision of Artillery and MRLS from 8c0 to 5c0.

The reason behind this is because we have scouting artillery and MRLS units that have a much larger vision range then infantry and the same vision as hummers and buggies. This turns into games where people build infantry and artillery/MRLS armies and march of death to the enemy. Its more counterable in 1v1 and 2v2 but team games of 3v3+ it becomes incredibly spammy of these units and hard to stop.
2017-03-31 15:04:32 -07:00
reaperrr
4f07a00994 Merge pull request #13038 from reaperrr/misc-cleanups-0317
Misc yaml style fixes (all mods)
2017-03-31 12:27:56 +02:00
reaperrr
df85ea222a TS yaml style fixes
To reduce upgrade rule 'noise' a little.
2017-03-31 11:23:44 +02:00
reaperrr
cf8db74d85 RA yaml style fixes
To reduce upgrade rule noise a little.
2017-03-31 11:23:42 +02:00
reaperrr
2172d91efb Add newline to TD shellmap's map.yaml
To avoid upgrade rule 'noise'.
2017-03-31 11:00:04 +02:00
reaperrr
4fdda9efd2 Remove wrong space and 2nd free line from d2k yamls 2017-03-31 10:55:01 +02:00
Paul Chote
ae7a7418eb Add a windows version of the launch-game script. 2017-03-29 21:09:13 +01:00
reaperrr
edc1753e22 Update GravityBomb velocity after position
Otherwise launch velocity would already be Velocity + Acceleration.
2017-03-29 19:30:55 +02:00
reaperrr
7fdbe10319 Upgrade rule for GravityBomb velocity/accel changes 2017-03-29 19:30:54 +02:00
reaperrr
e1e47e7e0d Tweak TS Orca bomb fall behavior 2017-03-29 19:30:52 +02:00
reaperrr
5b617cf6e5 Refactor GravityBomb velocity/acceleration 2017-03-29 19:30:51 +02:00
FrameLimiter
b59f1f39fe Fixed vision for aircraft husks under Gap. 2017-03-29 11:42:32 -04:00
reaperrr
aa3f21632c Merge pull request #12880 from MustaphaTR/d2k-ordos-2a
D2K - Add Ordos Mission 2a
2017-03-29 16:52:19 +02:00
atlimit8
4c32e23f89 Merge pull request #12634 from GraionDilach/bullet-airburst
Implement airburst support to Bullet.
2017-03-28 17:53:24 -05:00
reaperrr
bfc0f7f9e6 Merge pull request #12997 from SoScared/mapEnsioFix
[RA] [Map pool] Fix tile errors on various maps.
2017-03-28 22:39:29 +02:00
Mustafa Alperen Seki
7f68c38e72 Add Ordos 2a 2017-03-27 17:19:54 +02:00
abcdefg30
dac8a8e4f6 Merge pull request #13024 from MustaphaTR/d2k-remove-sonic-tank-immunity
D2K - Remove Sonic Tanks' immunity to other friendly Sonic Tanks.
2017-03-26 19:26:23 +02:00
Mustafa Alperen Seki
5ccfcb1cb9 Remove Sonic Tanks' immunity to other friendly sonic tanks. 2017-03-26 10:15:19 +02:00
SoScared
d2a0535442 fix tile errors on various maps 2017-03-25 15:36:03 +01:00
abcdefg30
ae111248f3 Have some activities count as idle activities 2017-03-24 18:06:10 +01:00
abcdefg30
4d335af9fc Fixed aircraft not being able to hunt 2017-03-24 17:40:11 +01:00
rob-v
bfcb37e1b7 When changing rally point also make primary building #12855 2017-03-22 16:41:30 +01:00
atlimit8
b6810f3dd3 Merge pull request #12986 from abcdefg30/withDesc
Expand the documentation of Reinforce(WithTransport)
2017-03-22 10:23:36 -05:00
abcdefg30
cc67f9328c Merge pull request #12974 from rob-v/IngameMessagePrefixes
Unify ingame message prefixes. #12923
2017-03-19 23:13:59 +01:00
atlimit8
ff998fd552 Merge pull request #12981 from abcdefg30/grantOwner
Fix GrantConditionOnPrerequisite not refreshing when the actor's owner changes.
2017-03-19 17:09:08 -05:00
abcdefg30
d819f3206e Merge pull request #12882 from abc013/ContrailFix
Fix contrail gets rendered between loading in and loading out position
2017-03-19 23:03:33 +01:00
atlimit8
a49227c494 Merge pull request #12862 from abcdefg30/captureCursor
Minor revision to CaptureOrderTargeter.
2017-03-19 10:54:22 -05:00
abc013
b7ca740155 Fix contrail gets rendered between loading in and loading out position 2017-03-19 09:25:39 +01:00
abcdefg30
aa99c3cd40 Merge pull request #12729 from Mailaender/sunstroke
Added Firestorm map Sunstroke
2017-03-19 03:01:05 +01:00
reaperrr
294259c726 Set up custom creeps on Sunstroke 2017-03-19 02:51:33 +01:00
reaperrr
44254472d5 Disable fixed palette for TS old base buildings 2017-03-19 02:51:33 +01:00
reaperrr
ee63835778 Fix allowed terrain types of veins 2017-03-19 02:51:33 +01:00
Matthias Mailänder
1291d1a53d Add the custom rules
sunrise effect and TW1 units.
2017-03-19 02:51:25 +01:00
Matthias Mailänder
49d26fd238 Outcomment high bridge huts and low bridge segments. 2017-03-19 02:34:29 +01:00
Matthias Mailänder
37101bf4f0 Import the Sunstroke map
http://www.ppmforums.com/viewtopic.php?t=15379
2017-03-19 02:34:28 +01:00
abcdefg30
e1dda2bf54 Fix GrantConditionOnPrerequisite not refreshing when the actor's owner changes 2017-03-19 02:30:45 +01:00
abcdefg30
b2b3390bc0 Move GrantConditionOnPrerequisite into the Conditions folder 2017-03-19 02:29:26 +01:00
abcdefg30
ceab7a222e Merge pull request #12902 from MustaphaTR/d2k-add-6PLAY3
D2K - Add Mauddib's Cave to map pool.
2017-03-19 02:18:49 +01:00
reaperrr
7a3bae33ea Fix TS observer flag position 2017-03-19 00:20:02 +01:00
abcdefg30
00d854f31b Merge pull request #12984 from MustaphaTR/ts-add-tech-levels
TS - Add Tech Levels
2017-03-18 22:49:01 +01:00
rob-v
bad2c1c2bf Unify ingame message prefixes. #12923
Unify ingame message prefixes. #12923
2017-03-18 21:46:30 +01:00
Mustafa Alperen Seki
66d50ba0b5 Add Tech Levels to Tiberian Sun 2017-03-18 20:08:44 +02:00
reaperrr
245ca7d996 Merge pull request #12989 from abcdefg30/onDoc
Add a note about EnemyWatcher being required for On(Player)Discovered
2017-03-18 18:25:11 +01:00
Mustafa Alperen Seki
0e345b465c Add 6PLAY3 2017-03-18 19:21:40 +02:00
abcdefg30
b295f36fa7 Merge pull request #12987 from reaperrr/fast-gamespeed
Add "Fast" game speed to all mods
2017-03-18 18:12:45 +01:00
abcdefg30
a36a77d637 Add a note about EnemyWatcher being required for On(Player)Discovered 2017-03-18 18:09:20 +01:00
abcdefg30
7bb8cbf867 Merge pull request #12901 from MustaphaTR/d2k-add-6PLAY2
D2K - Add Carthag to map pool.
2017-03-18 18:00:46 +01:00
abcdefg30
c19463f5b4 Merge pull request #12903 from MustaphaTR/d2k-add-6PLAY4
D2K - Add Thufir's Point to map pool.
2017-03-18 17:58:48 +01:00
abcdefg30
7491ede65a Merge pull request #12904 from MustaphaTR/d2k-add-6PLAY5
D2K - Add Leto's Erg to map pool.
2017-03-18 17:55:34 +01:00
abcdefg30
1abe93f25a Merge pull request #12900 from MustaphaTR/d2k-add-6PLAY1
D2K - Add Arakeen to map pool.
2017-03-18 17:51:22 +01:00
reaperrr
785e20e0f3 Add "Fast" game speed to all mods
Sitting smack in the middle between Default and "Faster", except for order delay (which is same as Faster to avoid rejected/dropped orders).
2017-03-18 17:45:02 +01:00
abcdefg30
6069a12973 Expand the documentation of Reinforce(WithTransport) 2017-03-18 16:40:35 +01:00
Zimmermann Gyula
902d2a0016 Implement airburst support to Bullet. 2017-03-18 15:05:06 +01:00
Mustafa Alperen Seki
31d5d048fe Add 6PLAY1 2017-03-18 15:23:46 +02:00
reaperrr
28e204a8ae Merge pull request #12982 from rob-v/MissionsDifficultyTough
Real tough guy difficulty doesn't fit the UI #12844
2017-03-18 14:23:43 +01:00
Mustafa Alperen Seki
8fd9f98180 Add 6PLAY2 2017-03-18 15:22:24 +02:00
Mustafa Alperen Seki
dd12d70ded Add 6PLAY4 2017-03-18 15:19:33 +02:00
Mustafa Alperen Seki
06f6a8646f Add 6PLAY5 2017-03-18 15:18:14 +02:00
reaperrr
02b82ae344 Merge pull request #12860 from abcdefg30/removeGroupProxy
Remove the dead ActorGroupProxy trait
2017-03-18 14:04:28 +01:00
reaperrr
d0e859cbeb Merge pull request #12784 from abcdefg30/d2kTiles
Add missing tiles to arrakis.yaml and fixed the map import
2017-03-18 13:58:12 +01:00
reaperrr
620ae45cb3 Merge pull request #12747 from atlimit8/Pluggable-Requirements
Prevent duplicate upgrades (plugs) to GDI Upgrade Center (Pluggable Requirements)
2017-03-18 13:55:30 +01:00
abcdefg30
880f90345e Add an upgrade rule 2017-03-18 13:42:49 +01:00
abcdefg30
5e923ff091 Remove the dead ActorGroupProxy trait 2017-03-18 13:40:05 +01:00
rob-v
d7684ee680 Real tough guy difficulty doesn't fit the UI #12844 2017-03-17 22:31:02 +01:00
abcdefg30
fbd62c242f Merge pull request #12969 from atlimit8/UncloakOnDamageSign
UncloakOn: Damage, Heal, SelfHeal split
2017-03-17 21:12:10 +01:00
C. Helmig
b331065b87 Add the missing d2k tiles for the MP maps 2017-03-17 20:00:25 +01:00
abcdefg30
80f4feeab3 Let the map importer account for duplicate tiles 2017-03-17 20:00:18 +01:00
abcdefg30
a6078b6e46 Add missing templates to arrakis.yaml 2017-03-17 19:58:32 +01:00
Jean-Rémy Buchs
fbd3a2efea Load debug symbols (.mdb on mono only; .pdb on .NET only) for mods if they are present 2017-03-16 17:22:59 +01:00
rob-v
f38c5f3380 Sort 'Playing' games in the lobby by play time. #12959 2017-03-16 17:17:35 +01:00
atlimit8
abad50d2b9 MiniYaml upgrade rule for UncloakOn: Damage => Damage, Heal, SelfHeal 2017-03-15 20:26:08 -05:00
atlimit8
cca7eda530 Restore CloakOn: Heal behavior in mods via MiniYaml changes. 2017-03-15 20:26:08 -05:00
atlimit8
d3e4720507 Added UncloakOn: SelfHeal (not overlapping with Heal). 2017-03-15 20:26:05 -05:00
atlimit8
aa8c434668 Make Repair activity host actor the attacker for repairs. 2017-03-15 20:25:12 -05:00
atlimit8
8e7de1a4fa Make UncloakOn Damage check sign with added Heal value for UncloakOn. 2017-03-15 20:25:08 -05:00
rob-v
e766c6f342 Global chat name is reset when connecting #12325
removed TrySetNickname(Game.Settings.Player.Name) in GlobalChat ctor overwriting Chat.Nickname. instead of removing, it could be replaced by TrySetNickname(Game.Settings.Chat.Nickname)
2017-03-15 23:53:43 +01:00
Paul Chote
34a37421f6 Allow specific mods to be launched from VS/MD gui. 2017-03-15 22:01:01 +00:00
abcdefg30
eb77c57ac3 Merge pull request #12968 from SoScared/DualColdFrontReverse
[RA] Map Pool - Reverse alteration of Dual Cold Front
2017-03-15 22:16:08 +01:00
abcdefg30
bbc08627ac Merge pull request #12970 from SoScared/WallTweak
[RA] [Balance] Tweak price/production of S.Bags/Fence/Walls
2017-03-15 22:00:48 +01:00
Paul Chote
67144fe66b Merge pull request #12842 from abc013/Allies06SubFix
Allies 06a: Make the AI only build submarines if the player has a shipyard
2017-03-15 20:12:18 +00:00
Paul Chote
395d31b249 Merge pull request #12967 from SoScared/ReverseFriendlyMines
Reverse making friendly units aware of friendly mines.
2017-03-15 19:58:57 +00:00
SoScared
e0985162a0 Double price/production of S.Bags/Fence/Walls 2017-03-15 16:55:29 +01:00
SoScared
681dcc81a1 Reverse alteration of Dual Cold Front 2017-03-15 00:26:16 +01:00
SoScared
33bcdb10ba Reverse making friendly units aware of friendly mines. 2017-03-14 20:46:19 +01:00
abc013
046427beea Polished the mission objectives in allies06a 2017-03-14 19:29:40 +01:00
abc013
db4554acec Make the AI only build submarines if the player has a shipyard 2017-03-14 17:31:03 +01:00
abcdefg30
3aeddbf9bd Merge pull request #12953 from MustaphaTR/d2k-add-stealth-detection-to-turrets
D2K - Make defences detect Cloak
2017-03-14 15:48:56 +01:00
reaperrr
4c32803c16 Merge pull request #12945 from MustaphaTR/add-noozes-1-tile-cliffs
RA/TD - Add 1 Tile Cliffs by Nooze
2017-03-13 19:59:51 +01:00
Mustafa Alperen Seki
4f0e317371 Add Nooze's 1 Tile Cliffs to TD 2017-03-13 17:20:05 +02:00
Mustafa Alperen Seki
ab6b7c8551 Add Nooze's 1 Tile Cliffs to RA 2017-03-13 17:19:46 +02:00
reaperrr
d138a05baf Merge pull request #12946 from pchote/fix-serverquery-crash
Fix crash when master server query returns unexpected data.
2017-03-12 18:44:06 +01:00
Mustafa Alperen Seki
dcf1cfe118 Make defences detect cloak. 2017-03-12 16:04:51 +02:00
atlimit8
fbc850a73f Prevent duplicate upgrades (plugs) to GDI Upgrade Center 2017-03-12 03:43:42 -05:00
atlimit8
08a71795d1 PluggableInfo.Requirements entry overrides in-use check now to allow swapping. 2017-03-12 03:43:42 -05:00
atlimit8
daf4eb812c Added ConditionExpression Requirements for plugs to Pluggable 2017-03-12 03:43:35 -05:00
Oliver Brakmann
63ee126898 Merge pull request #12947 from pchote/fix-obelisk-targeting
Fix obelisk targeting.
2017-03-11 22:28:42 +01:00
reaperrr
0847cb9d31 Merge pull request #12951 from SoScared/fixGapEffect_vs_Airplanes
Fix RevealsShroud@GAPGEN vs MiG/YAK
2017-03-11 17:58:20 +01:00
SoScared
daeba01bc1 fixed RevealsShroud@GAPGEN vs MiG/YAK 2017-03-11 13:44:44 +01:00
Paul Chote
c45634ed8d Merge pull request #12941 from forcecore/ai_ref_placement
HackyAI now builds refinery near ore.
2017-03-11 12:40:48 +00:00
Paul Chote
f3cfe24e11 Merge pull request #12942 from SoScared/mapswap5
[RA] Add/remove official maps 5.
2017-03-11 11:56:47 +00:00
Paul Chote
a3030aa074 Merge pull request #12933 from SoScared/mapswap4
[RA] Add/remove official maps 4.
2017-03-11 11:41:48 +00:00
reaperrr
d86ff6696a Merge pull request #12887 from MustaphaTR/ra-make-turkish-flag-outline-blue
Change Turkish Flag outline to Blue
2017-03-10 22:19:43 +01:00
reaperrr
da2330a116 Merge pull request #12935 from pchote/td-map-tweaks
Update TD playtest maps
2017-03-10 21:22:57 +01:00
Paul Chote
4d2563cc11 Remove unnecessary AttackTesla : AttackOmni subclass. 2017-03-10 19:42:18 +00:00
Paul Chote
a9cfbd9ad7 Fix Obelisk not dropping targets when they move out of range. 2017-03-10 19:42:15 +00:00
Paul Chote
00b1bc7cd2 Fix crash when master server query returns unexpected data. 2017-03-10 18:38:35 +00:00
SoScared
2f48e67e6d final 6p plus map pool alteration 2017-03-09 18:24:31 +01:00
Forcecore
7588d6708b HackyAI now builds refinery near ore. 2017-03-09 09:42:56 -06:00
abcdefg30
5e737980fe Merge pull request #12910 from pchote/fix-bogus-enumeration-issue
Fix spurious warnings when the support mods dir doesn't exist.
2017-03-09 09:19:55 +01:00
SoScared
73698c2ecb final 2-4 player map alteration 2017-03-08 23:51:03 +01:00
Paul Chote
f6b11bb662 Remove TD map Vectors of Battle (10p). 2017-03-08 22:06:16 +00:00
Paul Chote
e055db94ab Update TD map Order of Battle. 2017-03-08 22:05:50 +00:00
Paul Chote
82d5979eb1 Update TD map Axis of Advance. 2017-03-08 22:05:39 +00:00
Oliver Brakmann
3499325f23 Merge pull request #12921 from reaperrr/ts-economy
Fix TS economy to match original
2017-03-08 22:19:30 +01:00
Oliver Brakmann
439a4a70d4 Merge pull request #12908 from reaperrr/polish-poseidon
Polish Morbid Aimless Poseidon
2017-03-08 22:03:44 +01:00
Jean-Rémy Buchs
28cd480225 Load debug symbols (.mdb on mono only; .pdb) for mods if they are present 2017-03-08 20:11:41 +01:00
Jean-Rémy Buchs
f999001caf Load debug symbols (.mdb on mono only; .pdb) for mods if they are present 2017-03-07 18:30:08 +01:00
abcdefg30
c87e1c789a Merge pull request #12920 from reaperrr/fix-spy-atk
Fix RA Spy attack sequence
2017-03-06 22:40:35 +01:00
reaperrr
386e5b3772 Limit TS AI silos to 2
The up to 4 refineries already provide a total of 8000 credits storage, 2 silos for additional 3000 should be more than the AI will likely ever need.
2017-03-06 04:00:38 +01:00
reaperrr
1d636082a3 Fix TS harvester load, unload and movement speed
Matching original.
2017-03-06 03:55:22 +01:00
reaperrr
a40639c559 Fix TS tiberium values
25 for green, 40 for blue (Vinifera). Alternate blue tib (Aboreus) with value 30 might be added later.
2017-03-06 03:54:25 +01:00
reaperrr
062eef37f4 Fix TS silo storage pip color 2017-03-06 03:52:59 +01:00
reaperrr
d7a49daae8 Fix TS refinery storage capacity to match original 2017-03-06 03:52:37 +01:00
reaperrr
e57fd37697 Fix RA Spy attack sequence 2017-03-06 02:30:48 +01:00
Paul Chote
407ecbc397 Fix spurious warnings when the support mods dir doesn't exist. 2017-03-05 19:13:07 +00:00
reaperrr
e25cb2914f Polish Morbid Aimless Poseidon
A lot of the cliffs, in particular "north-facing" ones, only reptitively used a single variant, and in some cases the one that should only be used for the "left ending" of a cliff. I fixed the latter and added variation to the former cases.
2017-03-05 17:07:11 +01:00
reaperrr
120efcedaa Merge pull request #12859 from abcdefg30/supportPrereqs
Fix support powers not being enabled by cheats
2017-03-05 16:27:43 +01:00
reaperrr
efcaa86db6 Merge pull request #12889 from Mailaender/bye
Removed myself from the active developer list
2017-03-05 15:32:14 +01:00
Jean-Rémy Buchs
a0598d2b9c Load debug symbols (.mdb .pdb) for mods if they are present 2017-03-04 17:37:40 +01:00
Jean-Rémy Buchs
19616c059c Load debug symbols for mods if they are present 2017-03-04 14:20:16 +01:00
Matthias Mailänder
06c7dad50e Move myself to previous developers. 2017-03-04 12:56:34 +01:00
Jean-Rémy Buchs
d3491c2979 Load debug symbols for mods if they are loaded from the filesystem 2017-03-04 12:38:07 +01:00
Mustafa Alperen Seki
7ad63bd3c7 Change Turkish Flag outline to Blue. 2017-03-04 08:54:18 +02:00
abcdefg30
8b7797326a Revise CaptureOrderTargeter a tiny bit 2017-02-27 00:28:18 +01:00
abcdefg30
e318c028ba Fix support powers not being enabled by cheats 2017-02-25 16:57:30 +01:00
2846 changed files with 215379 additions and 91513 deletions

View File

@@ -1,16 +1,106 @@
; Top-most http://editorconfig.org/ file
root = true
charset=utf-8
; Unix-style newlines
[*]
end_of_line = LF
insert_final_newline = true
trim_trailing_whitespace = true
; 4-column tab indentation
; 4-column tab indentation and .NET coding conventions
[*.cs]
indent_style = tab
indent_size = 4
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = true
csharp_style_var_elsewhere = true:suggestion
csharp_style_var_for_built_in_types = true:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion
csharp_prefer_braces = when_multiline:suggestion
csharp_using_directive_placement = outside_namespace:suggestion
csharp_new_line_before_open_brace = all
csharp_space_around_binary_operators = before_and_after
#### Naming styles ####
dotnet_naming_style.camel_case.capitalization = camel_case
dotnet_naming_style.pascal_case.capitalization = pascal_case
# Symbol specifications
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal
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.internal_field.applicable_kinds = field
dotnet_naming_symbols.internal_field.applicable_accessibilities = internal
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.private_or_internal_field.applicable_kinds = field
dotnet_naming_symbols.private_or_internal_field.applicable_accessibilities = internal, private
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.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal
# Naming rules
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
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_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.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.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
# Naming rules
#require a space before the colon for bases or interfaces in a type declaration
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
csharp_space_before_colon_in_inheritance_clause = true
#Formatting - wrapping options
#leave code block on single line
csharp_preserve_single_line_blocks = true
#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
#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
; 4-column tab indentation
[*.yaml]
indent_style = tab
indent_size = 4
indent_size = 4

8
.gitattributes vendored
View File

@@ -1,12 +1,10 @@
# Enforce LF normalization on Windows
*.yaml eol=lf
*.lua eol=lf
*.cs eol=lf
*.csproj eol=lf
*.sln eol=lf
* text=lf
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union

33
.github/ISSUE_TEMPLATE/bug-report.md vendored Normal file
View File

@@ -0,0 +1,33 @@
---
name: Bug report
about: Report unexpected behavior or any issues you experienced in OpenRA.
title: ''
labels: Bug
assignees: ''
---
<!-- This is a guideline that shall help you to include information we need to understand and fix the issue you experienced. Please follow the instructions and replace any placeholders that are written in capital letters. Instructions like this comment will not be visible in your report. -->
<!-- Important: Help us to avoid duplicates and use the search function to find existing reports for your issue. Please do not submit duplicate reports! Try to help others to find your report by using a precise title. -->
## Issue Summary
<!-- Please provide a a clear and concise description of what the issue is below. -->
DESCRIPTION
## Reproduction
<!-- Please provide information about how the issue can be reproduced below. -->
STEPS TO REPRODUCE THE ISSUE
## Expected behavior
<!-- Please explain what you expected to happen below. -->
EXPECTED BEHAVIOR
## Screenshots / Screen recordings / Replays
<!-- If applicable, attach screenshots, screen recordings or replays to help explain your problem. -->

11
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: OpenRA Forum
url: https://forum.openra.net/
about: "Please ask questions about modding here."
- name: OpenRA Discord server
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."

35
.github/ISSUE_TEMPLATE/crash-report.md vendored Normal file
View File

@@ -0,0 +1,35 @@
---
name: Crash report
about: Report a game crash.
title: My game crashed
labels: Crash
assignees: ''
---
<!-- This is a guideline that shall help you to include all the required information we depend on to investigate and fix game-breaking bugs. Please follow the instructions and replace any placeholders that are written in capital letters. Instructions like this comment will not be visible in your report. -->
## System Information
<!-- Information about the operating system, engine version, game mod and package source are mandatory for investigating and fixing crashes. -->
- Operating System: OPERATING SYSTEM
- OpenRA Version: ENGINE VERSION
- OpenRA Mod: GAME MOD
- Source: Official download package OR self-compiled OR third-party package
- For self-compiled or third-party packages: Mono version
## Exception log
<!-- Please replace the placeholder below with the content of the exception.log file. The three backticks before and after the placeholder are used for formatting, so don't remove them. If you don't find the log folder consult https://github.com/OpenRA/OpenRA/wiki/FAQ#my-game-just-crashed. -->
```
PASTE LOG HERE
```
## Replay
<!-- If you have a replay file for the game that crashed, and it crashes again when you play it back, it will be a great help for us to fix the issue. Please compress the replay into a zip file and drag it here to include it in the report. -->
## Additional information
<!-- Please tell us below everything that you think is important for us to know about the crash. Specifically, what you were doing in the moment before the crash or ideally steps to reproduce it are very valuable information. -->

View File

@@ -0,0 +1,35 @@
---
name: Feature / Enhancement request
about: Describe what you think is missing or could be improved in OpenRA.
title: ''
labels: Idea/Wishlist
assignees: ''
---
<!-- This is a guideline that shall help you to describe your idea for a missing feature or enhancement. Please follow the instructions and replace any placeholders that are written in capital letters. Instructions like this comment will not be visible in your report. -->
<!-- Important: Help us to avoid duplicates and use the search function to find existing requests. Please do not submit duplicate requests! Try to help others to find your request by using a precise title. -->
## Motivation
<!-- Please provide a clear and concise description of the motivation behind the request. If your request is related to a problem or limitation, describe it below. -->
REQUEST MOTIVATION
## Proposed solution
<!-- Please describe your idea and how it is intended to address the motivation of your request. Provide a clear and concise description of the proposed changes. -->
PROPOSED SOLUTION
## Side effects
<!-- Changes often have side effects or unintended consequences. If you expect that your solution has any side effects, please describe them below. -->
EXPECTED SIDE EFFECTS
## Alternatives
<!-- Please outline any alternative solutions you have considered. -->
ALTERNATIVES

16
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,16 @@
Thank you for your contribution to OpenRA!
Please be aware that we do not have enough project maintainers to match the rate of contributions, so it may take several days before somebody is able to respond to your Pull Request.
You can help speed up the review process by following a few steps:
* Make sure that you have read and understand the OpenRA Coding Standard (see https://github.com/OpenRA/OpenRA/wiki/Coding-Standard).
* Write quality commit messages (see https://chris.beams.io/posts/git-commit/).
* Only commit changes that directly relate to your Pull Request. Use your Git interface to unstage any unrelated changes to project files, line endings, whitespace, or other files.
* Review the code diff view below to double check that your changes satisfy the above three points.
* Use the `make test` and `make check` commands to check for (and fix!) any issues that are reported by our automated tests.
* If you are changing shared mod or engine code, make sure that you have tested your changes in all four default mods.
* 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).

150
.gitignore vendored
View File

@@ -1,81 +1,69 @@
# Visual Studio
Release
bin
obj
*.ncb
*.vcproj*
*.suo
*.user
*.sln.cache
*.manifest
*.CodeAnalysisLog.xml
*.lastcodeanalysissucceeded
_ReSharper.*/
# movies
*.vqa
# archives
*.mix
# binaries
mods/*/*.dll
mods/*/*.mdb
mods/*/*.pdb
/*.dll
/*.dll.config
/*.so
/*.dylib
/*.pdb
/*.mdb
/*.exe
thirdparty/download/*
*.mmdb.gz
# backup files by various editors
*~
*.orig
\#*
.*.sw?
# Monodevelop
*.pidb
*.userprefs
# Mac OS X
.DS_Store
# XCode
packaging/osx/launcher/build/
packaging/osx/launcher/OpenRA.xcodeproj/*.pbxuser
packaging/osx/launcher/OpenRA.xcodeproj/*.perspectivev3
packaging/osx/launcher/OpenRA.xcodeproj/*.mode1v3
temp.c
temp.o
temp.s
OpenRA.Launcher.Mac/build/
OpenRA.Launcher.Mac/OpenRA.xcodeproj/*.pbxuser
OpenRA.Launcher.Mac/OpenRA.xcodeproj/*.perspectivev3
OpenRA.Launcher.Mac/OpenRA.xcodeproj/*.mode1v3
*.resources
# auto-generated documentation
DOCUMENTATION.md
Lua-API.md
*.html
openra.6
# StyleCop
*.Cache
StyleCopViolations.xml
# SublimeText
*.sublime-project
*.sublime-workspace
# NUnit
/TestResult.xml
/lib/
# Support directory
/Support
# Visual Studio
Release
bin
obj
*.ncb
*.vcproj*
*.suo
*.user
*.sln.cache
*.manifest
*.CodeAnalysisLog.xml
*.lastcodeanalysissucceeded
_ReSharper.*/
/.vs
# 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
*~
*.orig
\#*
.*.sw?
# Monodevelop
*.pidb
*.userprefs
# Mac OS X
.DS_Store
# auto-generated documentation
DOCUMENTATION.md
WEAPONS.md
Lua-API.md
Settings.md
*.html
openra.6
update.log
# StyleCop
*.Cache
StyleCopViolations.xml
# SublimeText
*.sublime-project
*.sublime-workspace
# NUnit
/TestResult.xml
/lib/
# Support directory
/Support
# IntelliJ files
.idea

View File

@@ -2,23 +2,25 @@
# see travis-ci.org for details
language: csharp
mono: 4.6.1
mono: 6.4.0
os: linux
dist: xenial
# http://docs.travis-ci.com/user/migrating-from-legacy
sudo: false
cache:
directories:
- thirdparty/download
jobs:
include:
- os: linux
dist: xenial
- os: osx
if: tag IS present
osx_image: xcode10
addons:
apt:
packages:
- lua5.1
- nsis
- nsis-common
- dpkg
- markdown
- zsync
- imagemagick
# Environment variables
env:
@@ -30,29 +32,28 @@ env:
# call OpenRA to check for YAML errors
# Run the NUnit tests
script:
- travis_retry make all-dependencies
- make all SDK="-sdk:4.5"
- make check
- make check-scripts
- make test
- make nunit
# Automatically update the trait documentation and Lua API
after_success:
- test $TRAVIS_PULL_REQUEST == "false" && make docs && cd packaging && ./update-wiki.sh $TRAVIS_BRANCH; cd ..
- make all
- |
if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
make check || travis_terminate 1;
make check-scripts || travis_terminate 1;
make test || travis_terminate 1;
mono ~/.nuget/packages/nunit.consolerunner/3.11.1/tools/nunit3-console.exe --noresult OpenRA.Test.dll || travis_terminate 1;
fi
# Only watch the development branch and tagged release.
branches:
only:
- /^release-.*$/
- /^playtest-.*$/
- /^pkgtest-.*$/
- /^devtest-.*$/
- /^prep-.*$/
- bleed
# Notify developers when build passed/failed.
notifications:
irc:
if: repo = OpenRA/OpenRA
template:
- "%{repository}#%{build_number} %{commit} %{author}: %{message} %{build_url}"
channels:
@@ -61,21 +62,31 @@ notifications:
skip_join: true
before_deploy:
- export PATH=$PATH:$HOME/usr/bin
- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
wget https://mirrors.edge.kernel.org/ubuntu/pool/universe/n/nsis/nsis-common_3.04-1_all.deb;
wget https://mirrors.edge.kernel.org/ubuntu/pool/universe/n/nsis/nsis_3.04-1_amd64.deb;
sudo dpkg -i nsis-common_3.04-1_all.deb;
sudo dpkg -i nsis_3.04-1_amd64.deb;
echo ${TRAVIS_REPO_SLUG};
if [[ "${TRAVIS_REPO_SLUG}" == "OpenRA/OpenRA" ]]; then
cd packaging && ./update-wiki.sh ${TRAVIS_TAG} && cd ..;
fi;
fi
- export PATH=${PATH}:${HOME}/usr/bin
- DOTVERSION=`echo ${TRAVIS_TAG} | sed "s/-/\\./g"`
- cd packaging
- mkdir build
- ./package-all.sh ${TRAVIS_TAG} ${PWD}/build/
- if [[ "${TRAVIS_REPO_SLUG}" == "OpenRA/OpenRA" ]]; then
./upload-itch.sh ${TRAVIS_TAG} ${PWD}/build/;
fi
deploy:
provider: releases
api_key:
secure: "g/LU11f+mjqv+lj0sR1UliHwogXL4ofJUwoG5Dbqlvdf5UTLWytw/OWSCv8RGyuh10miyWeaoqHh1cn2C1IFhUEqN1sSeKKKOWOTvJ2FR5mzi9uH3d/MOBzG5icQ7Qh0fZ1YPz5RaJJhYu6bmfvA/1gD49GoaX2kxQL4J5cEBgg="
file:
- build/OpenRA-${TRAVIS_TAG}.exe
- build/OpenRA-${TRAVIS_TAG}.zip
- build/openra_${DOTVERSION}_all.deb
token: ${GH_DEPLOY_API_KEY}
file_glob: true
file: build/*
skip_cleanup: true
on:
all_branches: true
tags: true
repo: OpenRA/OpenRA

7
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"recommendations": [
"ms-dotnettools.csharp",
"EditorConfig.EditorConfig",
"ms-vscode.mono-debug"
]
}

61
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,61 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch (TD)",
"type": "clr",
"linux": {
"type": "mono"
},
"osx": {
"type": "mono"
},
"request": "launch",
"program": "${workspaceRoot}/OpenRA.Game.exe",
"cwd": "${workspaceRoot}",
"args": ["Game.Mod=cnc"]
},
{
"name": "Launch (RA)",
"type": "clr",
"linux": {
"type": "mono"
},
"osx": {
"type": "mono"
},
"request": "launch",
"program": "${workspaceRoot}/OpenRA.Game.exe",
"cwd": "${workspaceRoot}",
"args": ["Game.Mod=ra"]
},
{
"name": "Launch (D2k)",
"type": "clr",
"linux": {
"type": "mono"
},
"osx": {
"type": "mono"
},
"request": "launch",
"program": "${workspaceRoot}/OpenRA.Game.exe",
"cwd": "${workspaceRoot}",
"args": ["Game.Mod=d2k"]
},
{
"name": "Launch (TS)",
"type": "clr",
"linux": {
"type": "mono"
},
"osx": {
"type": "mono"
},
"request": "launch",
"program": "${workspaceRoot}/OpenRA.Game.exe",
"cwd": "${workspaceRoot}",
"args": ["Game.Mod=ts"]
},
]
}

3
.vscode/settings.json vendored Normal file
View File

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

13
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,13 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "make",
"args": ["all"],
"windows": {
"command": "make.cmd"
}
}
]
}

58
AUTHORS
View File

@@ -3,26 +3,27 @@ hard work of many contributors.
The OpenRA developers are:
* Chris Forbes (chrisf)
* Igor Popov (ihptru)
* Lukas Franke (abcdefg30)
* Matthias Mailänder (Mailaender)
* Oliver Brakmann (obrakmann)
* Paul Chote (pchote)
* Reaperrr
* Tom Roostan (RoosterDragon)
Previous developers included:
* Alli Witheford (alzeih)
* Caleb Anderson (RobotCaleb)
* Curtis Shmyr (hamb)
* Daniel Hernandez (Mancano)
* Igor Popov (ihptru)
* Matthias Mailänder (Mailaender)
* Megan Bowra-Dean (beedee)
* Mike Bundy (kehaar)
* Oliver Brakmann (obrakmann)
* Pavel Penev (penev92)
* Robert Pepperell (ytinasni)
* ScottNZ
* Tom Roostan (RoosterDragon)
Also thanks to:
* abmyii
* Adam Valy (Tschokky)
* Akseli Virtanen (RAGEQUIT)
* Alexander Fast (mizipzor)
@@ -38,12 +39,16 @@ Also thanks to:
* Bellator
* Biofreak
* Braxton Williams (Buddytex)
* Brendan Gluth (Mechanical_Man)
* Brent Gardner (bggardner)
* Bryan Wilbur
* Bugra Cuhadaroglu (BugraC)
* Christer Ulfsparre (Holloweye)
* Chris Cameron (Vesuvian)
* Chris Grant (Unit158)
* Christer Ulfsparre (Holloweye)
* clem
* Cody Brittain (Generalcamo)
* Constantin Helmig (CH4Code)
* D2k Sardaukar
* D'Arcy Rush (r34ch)
* Daniel Derejvanik (Harisson)
@@ -52,6 +57,7 @@ Also thanks to:
* David Russell (DavidARussell)
* DeadlySurprise
* Dmitri Suvorov (suvjunmd)
* dtluna
* Erasmus Schroder (rasco)
* Eric Bajumpaa (SteelPhase)
* Evgeniy Sergeev (evgeniysergeev)
@@ -59,24 +65,26 @@ Also thanks to:
* Florian Wiesbauer (FiveAces)
* Frank Razenberg (zzattack)
* Gareth Needham (Ripley`)
* Glen Anderson (GlenLife)
* Glen Anderson (glen7)
* Glenn Martin Jensen (Baxxster)
* Gordon Martin (Happy0)
* Guido Lipke (LipkeGu)
* Gyula Zimmermann (Graion Dilach)
* Hervé Matysiak (Herve-M)
* Huw Pascoe
* Ian T. Jacobsen (Smilex)
* Imago
* Iran
* Ishan Bhargava (ishantheperson)
* Jacob Dufault (jacobdufault)
* James Dunne (jsd)
* James Gilbert (DSUK)
* Jan-Willem Buurlage (jwbuurlage)
* Jason (atlimit8)
* Jeff Harris (jeff_1amstudios)
* Jefri Sevkin (Arular)
* Jes
* Joakim Lindberg (booom3)
* Joe Alam (joealam)
* John Turner (whinis)
* Jonas A. Lind (SoScared)
* Joppy Furr
@@ -84,21 +92,29 @@ Also thanks to:
* Kenny Hoxworth (hoxworth)
* Kevin Azzam (ChaoticMind)
* Krishnakanth Mallik
* Kyle Smith (Smitty)
* Kyrre Soerensen (zypres)
* Lawrence Wang
* Lesueur Benjamin (Valkirie)
* Maarten Meuris (Nyerguds)
* Manuel Geiger (Ectras)
* Mark Olson (markolson)
* Markus Hartung (hartmark)
* Matija Hustic (matija-hustic)
* Matthew Gatland (mgatland)
* Matthew Uzzell (MUzzell)
* Matthijs Benschop (Nerdie)
* Max621
* Max Ugrumov (katzsmile)
* Mazar Farran (mazarf)
* Michael Rätzel
* Michael Silber (frühstück)
* Michael Sztolcman (s1w_)
* Mike Gagné (AngryBirdz)
* Muh
* Mustafa Alperen Seki (MustaphaTR)
* Neil Shivkar (havok13888)
* Nikolay Fomin (netnazgul)
* Nooze
* Nukem
* Okunev Yu Dmitry (xaionaro)
@@ -107,8 +123,9 @@ Also thanks to:
* Paul Dovydaitis (pdovy)
* Pavlos Touboulidis (pav)
* Pedro Ferreira Ramos (bateramos)
* Peter Amrehn (jongleur1983)
* Pizzaoverhead
* Piët Delport (pjdelport)
* Pi Delport (pjdelport)
* Psydev
* Raphael Vogt (TheRaffy, Yellow)
* Raymond Bedrossian (Squiggles211)
@@ -121,14 +138,18 @@ Also thanks to:
* Sebastien Kerguen (xanax)
* Shawn Collins (UberWaffe)
* Simon Verbeke (Saticmotion)
* Stuart McHattie (SDJMcHattie)
* Taryn Hill (Phrohdoh)
* Teemu Nieminen (Temeez)
* Tim Mylemans (gecko)
* Tirili
* Tomas Einarsson (Mesacer)
* Tom van Leth (tovl)
* Tristan Keating (Kilkakon)
* Tristan Mühlbacher (MicroBit)
* UnknownProgrammer
* Vladimir Komarov (VrKomarov)
* Wojciech Walaszek (Voidwalker)
* Wuschel
Using GNU FreeFont distributed under the GNU GPL
@@ -142,15 +163,6 @@ FreeType License.
Using OpenAL Soft distributed under the GNU LGPL.
Using MaxMind GeoIP2 .NET API distributed under
the Apache 2.0 license.
Using GeoLite2 data created by MaxMind and
distributed under the CC BY-SA 3.0 license.
Using SharpFont created by Robert Rouhani and
distributed under the MIT license.
Using SDL2-CS and OpenAL-CS created by Ethan
Lee and released under the zlib license.
@@ -167,9 +179,17 @@ under the MIT license.
Using ICSharpCode.SharpZipLib initially by Mike
Krueger and distributed under the GNU GPL terms.
Using SmartIrc4Net developed by Mirco Bauer
distributed under the LGPL version 2.1 or later.
Using rix0rrr.BeaconLib developed by Rico Huijbers
distributed under MIT License.
Using DiscordRichPresence developed by Lachee
distributed under MIT License.
Using Json.NET developed by James Newton-King
distributed under MIT License.
This site or product includes IP2Location LITE data
available from http://www.ip2location.com.
Finally, special thanks goes to the original teams
at Westwood Studios and EA for creating the classic

76
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,76 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
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
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.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View File

@@ -1,5 +1,8 @@
# OpenRA Contributing Guidelines
## Participating
Help us keep OpenRA open and inclusive. Please read and follow our [Code of Conduct](https://github.com/OpenRA/OpenRA/blob/bleed/CODE_OF_CONDUCT.md).
## Bug reports
* Have you read the [FAQ](https://github.com/OpenRA/OpenRA/wiki/FAQ)?

File diff suppressed because one or more lines are too long

View File

@@ -6,78 +6,106 @@ The following lists per-platform dependencies required to build from source.
Windows
=======
* [Windows PowerShell >= 4.0](http://microsoft.com/powershell)
* [.NET Framework >= 4.5 (Client Profile)](http://www.microsoft.com/en-us/download/details.aspx?id=30653)
* [SDL 2](http://www.libsdl.org/download-2.0.php) (included)
* [FreeType](http://gnuwin32.sourceforge.net/packages/freetype.htm) (included)
* [zlib](http://gnuwin32.sourceforge.net/packages/zlib.htm) (included)
* [OpenAL](http://kcat.strangesoft.net/openal.html) (included)
* [liblua 5.1](http://luabinaries.sourceforge.net/download.html) (included)
Compiling OpenRA requires the following dependencies:
* [Windows PowerShell >= 4.0](http://microsoft.com/powershell) (included by default in recent Windows 10 versions)
* [.NET Framework 4.7.2 (Developer Pack)](https://dotnet.microsoft.com/download/dotnet-framework/net472) (or via Visual Studio 2017)
* [.NET Core 2.2 SDK](https://dotnet.microsoft.com/download/dotnet-core/2.2) (or via Visual Studio 2017)
You need to fetch the thirdparty dependencies using [NuGet](http://www.nuget.org) and place them at the appropriate places by typing `make dependencies` in a command terminal.
To compile OpenRA, open the `OpenRA.sln` solution in the main folder, build it from the command-line with MSBuild or use the Makefile analogue command `make all` scripted in PowerShell syntax.
Run the game with `OpenRA.Game.exe Game.Mod=ra` for Red Alert or `OpenRA.Game.exe Game.Mod=cnc` for Tiberian Dawn.
Run the game with `launch-game.cmd`. It can be handed arguments that specify the exact mod one wishes to run, for example, run `launch-game.cmd Game.Mod=ra` to launch Red Alert, `launch-game.cmd Game.Mod=cnc` to start Tiberian dawn or `launch-game.cmd Game.Mod=d2k` to launch Dune 2000.
Linux
=====
Use `make dependencies` to map the native libraries to your system, fetch the remaining CLI dependencies using [NuGet](http://www.nuget.org) and place them at the appropriate places.
Mono, version 5.18 or later, is required to compile OpenRA. You can add the [upstream mono repository](https://www.mono-project.com/download/stable/#download-lin) for your distro to obtain the latest version if your system packages are not sufficient.
To compile OpenRA, run `make all` from the command line.
To compile OpenRA, run `make` from the command line. 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.
Run with either `launch-game.sh` or `mono --debug OpenRA.Game.exe`.
The default behaviour on the x86_64 architecture is to download several pre-compiled native libraries using the Nuget packaging manager. If you prefer to use system libraries, compile instead using `make TARGETPLATFORM=unix-generic`.
Type `sudo make install-all` for system wide installation. Run `make install-linux-shortcuts` to get startup scripts, icons and desktop files. You can then run from the `openra` shortcut.
If you choose to use system libraries, or your system is not x86_64, you will need to install the following using your system package manager:
* [SDL 2](http://www.libsdl.org/download-2.0.php)
* [FreeType](http://gnuwin32.sourceforge.net/packages/freetype.htm)
* [OpenAL](http://kcat.strangesoft.net/openal.html)
* [liblua 5.1](http://luabinaries.sourceforge.net/download.html)
Type `sudo make install` for system-wide installation. Run `sudo make install-linux-shortcuts` to get startup scripts, icons and desktop files. You can then run the Red Alert by executing the `openra-ra` command, the Dune 2000 mod by running the `openra-d2k` command and Tiberian Dawn by the `openra-cnc` command. Alternatively, you can also run these mods by clicking on their desktop shortcuts if you ran `sudo make install-linux-shortcuts`.
Arch Linux
----------
It is important to note there is an unofficial [`openra-git`](https://aur.archlinux.org/packages/openra-git) package in the Arch User Repository (AUR) of Arch Linux. If manually compiling is the way you wish to go the build and runtime dependencies can be installed with:
```
sudo pacman -S mono openal libgl freetype2 sdl2 lua51 xdg-utils zenity
```
Debian/Ubuntu
-------------
* nuget
* mono-devel
* libfreetype6
* libopenal1
* liblua5.1-0
* libsdl2-2.0-0
* xdg-utils
* zenity
* curl
:warning: The `mono` packages in the Ubuntu < 19.04 and Debian < 10 repositories are too old to support OpenRA. :warning:
openSUSE
--------
See the instructions under the *Linux* section above to upgrade `mono` using the upstream releases if needed.
* mono-devel
* nuget
* openal
* freetype2
* SDL2
* lua51
* xdg-utils
* zenity
* curl
```
sudo apt install mono-devel libfreetype6 libopenal1 liblua5.1-0 libsdl2-2.0-0 xdg-utils zenity wget
```
Fedora
------
:warning: The `mono` packages in the Fedora repositories are too old to support OpenRA. :warning:
See the instructions under the *Linux* section above to upgrade `mono` using the upstream releases.
```
sudo dnf install "pkgconfig(mono)" SDL2 freetype "lua = 5.1" openal-soft xdg-utils zenity
```
Gentoo
------
* dev-lang/mono
* dev-dotnet/libgdiplus
* dev-dotnet/nuget
* media-libs/freetype:2
* media-libs/libsdl2
* media-libs/openal
* virtual/jpeg
* virtual/opengl
* dev-lang/lua-5.1.5
* x11-misc/xdg-utils
* gnome-extra/zenity
* net-misc/curl
```
sudo emerge -av dev-lang/mono dev-dotnet/libgdiplus media-libs/freetype:2 media-libs/libsdl2 media-libs/openal virtual/jpeg virtual/opengl '=dev-lang/lua-5.1.5*' x11-misc/xdg-utils gnome-extra/zenity
```
OSX
Mageia
------
```
sudo dnf install "pkgconfig(mono)" SDL2 freetype "lib*lua5.1" "lib*freetype2" "lib*sdl2.0_0" openal-soft xdg-utils zenity
```
openSUSE
--------
```
sudo zypper in mono-devel openal-soft freetype2 SDL2 lua51 xdg-utils zenity
```
Red Hat Enterprise Linux (and rebuilds, e.g. CentOS)
----------------------------------------------------
The EPEL repository is required in order for the following command to run properly.
```
sudo yum install "pkgconfig(mono)" SDL2 freetype "lua = 5.1" openal-soft xdg-utils zenity
```
macOS
=====
Use `make dependencies` to map the native libraries to your system.
Before compiling OpenRA you must install the following dependencies:
* [Mono >= 5.18](https://www.mono-project.com/download/stable/#download-mac)
To compile OpenRA, run `make` from the command line.
To compile OpenRA, run `make` from the command line. Run with `./launch-game.sh`.
The default behaviour is to download several pre-compiled native libraries using the Nuget packaging manager. If you prefer to use system libraries, compile instead using `make TARGETPLATFORM=unix-generic`. If you choose to use system libraries you will need to install:
* [SDL 2](http://www.libsdl.org/download-2.0.php) (`brew install sdl2`)
* [FreeType](http://gnuwin32.sourceforge.net/packages/freetype.htm) (`brew install freetype`)
* [OpenAL](http://kcat.strangesoft.net/openal.html) (`brew install openal-soft`)
* [liblua 5.1](http://luabinaries.sourceforge.net/download.html) (`brew install lua@5.1`)
Run with `mono --debug OpenRA.Game.exe`.

555
Makefile
View File

@@ -1,34 +1,28 @@
############################# INSTRUCTIONS #############################
#
# to compile, run:
# make [DEBUG=false]
# make [DEBUG=true]
#
# to compile with development tools, run:
# make all [DEBUG=false]
# to compile using system libraries for native dependencies, run:
# make [DEBUG=true] TARGETPLATFORM=unix-generic
#
# to check unit tests (requires NUnit version >= 2.6), run:
# make nunit [NUNIT_CONSOLE=<path-to/nunit[2]-console>] [NUNIT_LIBS_PATH=<path-to-libs-dir>] [NUNIT_LIBS=<nunit-libs>]
# Use NUNIT_CONSOLE if nunit[3|2]-console was not downloaded by `make dependencies` nor is it in bin search paths
# Use NUNIT_LIBS_PATH if NUnit libs are not in search paths. Include trailing /
# Use NUNIT_LIBS if NUnit libs have different names (such as including a prefix or suffix)
# to check the official mods for erroneous yaml files, run:
# make test
#
# to check the official mod dlls for StyleCop violations, run:
# to check the engine and official mod dlls for code style violations, run:
# make check
#
# to generate documentation aimed at modders, run:
# make docs
#
# to install, run:
# make [prefix=/foo] [bindir=/bar/bin] install
#
# to install with development tools, run:
# make [prefix=/foo] [bindir=/bar/bin] install-all
#
# to install Linux startup scripts, desktop files and icons:
# make install-linux-shortcuts [DEBUG=false]
#
# to install the engine and common mod files (omitting the default mods):
# make install-engine
# make install-dependencies
# make install-common-mod-files
#
# to uninstall, run:
# make uninstall
#
@@ -38,28 +32,22 @@
# to start the game, run:
# openra
############################## TOOLCHAIN ###############################
#
SDK ?=
CSC = mcs $(SDK)
CSFLAGS = -nologo -warn:4 -codepage:utf8 -unsafe -warnaserror
DEFINE = TRACE
COMMON_LIBS = System.dll System.Core.dll System.Data.dll System.Data.DataSetExtensions.dll System.Drawing.dll System.Xml.dll thirdparty/download/ICSharpCode.SharpZipLib.dll thirdparty/download/FuzzyLogicLibrary.dll thirdparty/download/MaxMind.Db.dll thirdparty/download/Eluant.dll thirdparty/download/SmarIrc4net.dll
# List of .NET assemblies that we can guarantee exist
# OpenRA.Game.dll is a harmless false positive that we can ignore
WHITELISTED_OPENRA_ASSEMBLIES = OpenRA.Game.exe OpenRA.Utility.exe OpenRA.Platforms.Default.dll OpenRA.Mods.Common.dll OpenRA.Mods.Cnc.dll OpenRA.Mods.D2k.dll OpenRA.Game.dll
# These are explicitly shipped alongside our core files by the packaging script
WHITELISTED_THIRDPARTY_ASSEMBLIES = ICSharpCode.SharpZipLib.dll FuzzyLogicLibrary.dll Eluant.dll BeaconLib.dll Open.Nat.dll SDL2-CS.dll OpenAL-CS.Core.dll DiscordRPC.dll Newtonsoft.Json.dll
# These are shipped in our custom minimal mono runtime and also available in the full system-installed .NET/mono stack
# This list *must* be kept in sync with the files packaged by the AppImageSupport and OpenRALauncherOSX repositories
WHITELISTED_CORE_ASSEMBLIES = mscorlib.dll System.dll System.Configuration.dll System.Core.dll System.Numerics.dll System.Security.dll System.Xml.dll Mono.Security.dll netstandard.dll
NUNIT_LIBS_PATH :=
NUNIT_LIBS := $(NUNIT_LIBS_PATH)nunit.framework.dll
DEBUG = true
ifeq ($(DEBUG), $(filter $(DEBUG),false no n off 0))
CSFLAGS += -debug:pdbonly -optimize+
else
CSFLAGS += -debug:full -optimize-
DEFINE := DEBUG;$(DEFINE)
endif
######################### UTILITIES/SETTINGS ###########################
#
# install locations
@@ -86,83 +74,29 @@ INSTALL_DIR = $(INSTALL) -d
INSTALL_PROGRAM = $(INSTALL) -m755
INSTALL_DATA = $(INSTALL) -m644
# program targets
CORE = pdefault game utility server
TOOLS = gamemonitor
VERSION = $(shell git name-rev --name-only --tags --no-undefined HEAD 2>/dev/null || echo git-`git rev-parse --short HEAD`)
# Toolchain
MSBUILD = msbuild -verbosity:m -nologo
# Enable 32 bit builds while generating the windows installer
WIN32 = false
# dependencies
ifndef TARGETPLATFORM
UNAME_S := $(shell uname -s)
UNAME_M := $(shell uname -m)
ifeq ($(UNAME_S),Darwin)
os-dependencies = osx-dependencies
TARGETPLATFORM = osx-x64
else
os-dependencies = linux-dependencies
ifeq ($(UNAME_M),x86_64)
TARGETPLATFORM = linux-x64
else
TARGETPLATFORM = unix-generic
endif
endif
endif
######################## PROGRAM TARGET RULES ##########################
#
# Core binaries
game_SRCS := $(shell find OpenRA.Game/ -iname '*.cs')
game_TARGET = OpenRA.Game.exe
game_KIND = winexe
game_LIBS = $(COMMON_LIBS) $(game_DEPS) thirdparty/download/SharpFont.dll thirdparty/download/Open.Nat.dll
game_FLAGS = -win32icon:OpenRA.Game/OpenRA.ico
PROGRAMS += game
game: $(game_TARGET)
# Platform dlls
pdefault_SRCS := $(shell find OpenRA.Platforms.Default/ -iname '*.cs')
pdefault_TARGET = OpenRA.Platforms.Default.dll
pdefault_KIND = library
pdefault_DEPS = $(game_TARGET)
pdefault_LIBS = $(COMMON_LIBS) thirdparty/download/SDL2-CS.dll thirdparty/download/OpenAL-CS.dll $(pdefault_DEPS)
PROGRAMS += pdefault
platforms: $(pdefault_TARGET)
# Mods Common
mod_common_SRCS := $(shell find OpenRA.Mods.Common/ -iname '*.cs')
mod_common_TARGET = mods/common/OpenRA.Mods.Common.dll
mod_common_KIND = library
mod_common_DEPS = $(game_TARGET)
mod_common_LIBS = $(COMMON_LIBS) $(STD_MOD_LIBS) thirdparty/download/StyleCop.dll thirdparty/download/StyleCop.CSharp.dll thirdparty/download/StyleCop.CSharp.Rules.dll
PROGRAMS += mod_common
mod_common: $(mod_common_TARGET)
# NUnit testing
test_dll_SRCS := $(shell find OpenRA.Test/ -iname '*.cs')
test_dll_TARGET = OpenRA.Test.dll
test_dll_KIND = library
test_dll_DEPS = $(game_TARGET) $(mod_common_TARGET)
test_dll_FLAGS = -warn:1
test_dll_LIBS = $(COMMON_LIBS) $(game_TARGET) $(mod_common_TARGET) $(NUNIT_LIBS)
PROGRAMS += test_dll
test_dll: $(test_dll_TARGET)
##### Official Mods #####
STD_MOD_LIBS = $(game_TARGET)
STD_MOD_DEPS = $(STD_MOD_LIBS)
# Command and Conquer
mod_cnc_SRCS := $(shell find OpenRA.Mods.Cnc/ -iname '*.cs')
mod_cnc_TARGET = mods/common/OpenRA.Mods.Cnc.dll
mod_cnc_KIND = library
mod_cnc_DEPS = $(STD_MOD_DEPS) $(mod_common_TARGET)
mod_cnc_LIBS = $(COMMON_LIBS) $(STD_MOD_LIBS) $(mod_common_TARGET)
PROGRAMS += mod_cnc
mod_cnc: $(mod_cnc_TARGET)
# Dune 2000
mod_d2k_SRCS := $(shell find OpenRA.Mods.D2k/ -iname '*.cs')
mod_d2k_TARGET = mods/d2k/OpenRA.Mods.D2k.dll
mod_d2k_KIND = library
mod_d2k_DEPS = $(STD_MOD_DEPS) $(mod_common_TARGET)
mod_d2k_LIBS = $(COMMON_LIBS) $(STD_MOD_LIBS) $(mod_common_TARGET)
PROGRAMS += mod_d2k
mod_d2k: $(mod_d2k_TARGET)
# program targets
VERSION = $(shell git name-rev --name-only --tags --no-undefined HEAD 2>/dev/null || echo git-`git rev-parse --short HEAD`)
check-scripts:
@echo
@@ -170,58 +104,21 @@ check-scripts:
@luac -p $(shell find mods/*/maps/* -iname '*.lua')
@luac -p $(shell find lua/* -iname '*.lua')
check: utility mods
check:
@echo
@echo "Compiling in debug mode..."
@$(MSBUILD) -t:build -p:Configuration=Debug
@echo
@echo "Checking runtime assemblies..."
@mono --debug OpenRA.Utility.exe all --check-runtime-assemblies $(WHITELISTED_OPENRA_ASSEMBLIES) $(WHITELISTED_THIRDPARTY_ASSEMBLIES) $(WHITELISTED_CORE_ASSEMBLIES)
@echo
@echo "Checking for explicit interface violations..."
@mono --debug OpenRA.Utility.exe all --check-explicit-interfaces
@echo
@echo "Checking for code style violations in OpenRA.Game..."
@mono --debug OpenRA.Utility.exe ra --check-code-style OpenRA.Game
@echo
@echo "Checking for code style violations in OpenRA.Platforms.Default..."
@mono --debug OpenRA.Utility.exe ra --check-code-style OpenRA.Platforms.Default
@echo
@echo "Checking for code style violations in OpenRA.GameMonitor..."
@mono --debug OpenRA.Utility.exe ra --check-code-style OpenRA.GameMonitor
@echo
@echo "Checking for code style violations in OpenRA.Mods.Common..."
@mono --debug OpenRA.Utility.exe ra --check-code-style OpenRA.Mods.Common
@echo
@echo "Checking for code style violations in OpenRA.Mods.Cnc..."
@mono --debug OpenRA.Utility.exe ra --check-code-style OpenRA.Mods.Cnc
@echo
@echo "Checking for code style violations in OpenRA.Mods.D2k..."
@mono --debug OpenRA.Utility.exe ra --check-code-style OpenRA.Mods.D2k
@echo
@echo "Checking for code style violations in OpenRA.Utility..."
@mono --debug OpenRA.Utility.exe ra --check-code-style OpenRA.Utility
@echo
@echo "Checking for code style violations in OpenRA.Test..."
@mono --debug OpenRA.Utility.exe ra --check-code-style OpenRA.Test
@echo
@echo "Checking for code style violations in OpenRA.Server..."
@mono --debug OpenRA.Utility.exe ra --check-code-style OpenRA.Server
@echo "Checking for incorrect conditional trait interface overrides..."
@mono --debug OpenRA.Utility.exe all --check-conditional-trait-interface-overrides
NUNIT_CONSOLE := $(shell test -f thirdparty/download/nunit3-console.exe && echo mono thirdparty/download/nunit3-console.exe || \
which nunit3-console 2>/dev/null || which nunit2-console 2>/dev/null || which nunit-console 2>/dev/null)
nunit: test_dll
@echo
@echo "Checking unit tests..."
@if [ "$(NUNIT_CONSOLE)" = "" ] ; then \
echo 'nunit[3|2]-console not found!'; \
echo 'Was "make dependencies" called or is NUnit installed?'>&2; \
echo 'See "make help".'; \
exit 1; \
fi
@if $(NUNIT_CONSOLE) --help | head -n 1 | grep -E "NUnit version (1|2\.[0-5])";then \
echo 'NUnit version >= 2.6 required'>&2; \
echo 'Try "make dependencies" first to use NUnit from NuGet.'>&2; \
echo 'See "make help".'; \
exit 1; \
fi
@$(NUNIT_CONSOLE) --noresult OpenRA.Test.nunit
test: utility mods
test: core
@echo
@echo "Testing Tiberian Sun mod MiniYAML..."
@mono --debug OpenRA.Utility.exe ts --check-yaml
@@ -235,146 +132,75 @@ test: utility mods
@echo "Testing Red Alert mod MiniYAML..."
@mono --debug OpenRA.Utility.exe ra --check-yaml
##### Launchers / Utilities #####
gamemonitor_SRCS := $(shell find OpenRA.GameMonitor/ -iname '*.cs')
gamemonitor_TARGET = OpenRA.exe
gamemonitor_KIND = winexe
gamemonitor_DEPS = $(game_TARGET)
gamemonitor_LIBS = $(COMMON_LIBS) $(gamemonitor_DEPS) System.Windows.Forms.dll
gamemonitor_FLAGS = -win32icon:OpenRA.Game/OpenRA.ico
PROGRAMS += gamemonitor
gamemonitor: $(gamemonitor_TARGET)
# Backend for the launcher apps - queries game/mod info and applies actions to an install
utility_SRCS := $(shell find OpenRA.Utility/ -iname '*.cs')
utility_TARGET = OpenRA.Utility.exe
utility_KIND = exe
utility_DEPS = $(game_TARGET)
utility_LIBS = $(COMMON_LIBS) $(utility_DEPS) thirdparty/download/ICSharpCode.SharpZipLib.dll
PROGRAMS += utility
utility: $(utility_TARGET)
# Dedicated server
server_SRCS := $(shell find OpenRA.Server/ -iname '*.cs')
server_TARGET = OpenRA.Server.exe
server_KIND = exe
server_DEPS = $(game_TARGET)
server_LIBS = $(COMMON_LIBS) $(server_DEPS)
PROGRAMS += server
server: $(server_TARGET)
# Patches binary headers to work around a mono bug
fixheader.exe: packaging/fixheader.cs
@command -v $(CSC) >/dev/null || (echo "Mono is not installed. Please install Mono from http://www.mono-project.com/download/ before building OpenRA."; exit 1)
@echo CSC fixheader.exe
@$(CSC) packaging/fixheader.cs $(CSFLAGS) -out:fixheader.exe -t:exe $(COMMON_LIBS:%=-r:%)
# Generate build rules for each target defined above in PROGRAMS
define BUILD_ASSEMBLY
$$($(1)_TARGET): $$($(1)_SRCS) Makefile $$($(1)_DEPS) fixheader.exe
@echo CSC $$(@)
@$(CSC) $$($(1)_LIBS:%=-r:%) \
-out:$$(@) $(CSFLAGS) $$($(1)_FLAGS) \
-define:"$(DEFINE)" \
-t:"$$($(1)_KIND)" \
$$($(1)_EXTRA) \
$$($(1)_SRCS)
@mono fixheader.exe $$(@) > /dev/null
@test `echo $$(@) | sed 's/^.*\.//'` = "dll" && chmod a-x $$(@) || ``
@$$($(1)_EXTRA_CMDS)
endef
$(foreach prog,$(PROGRAMS),$(eval $(call BUILD_ASSEMBLY,$(prog))))
########################## MAKE/INSTALL RULES ##########################
#
default: core
all: core
core: dependencies game platforms mods utility server
tools: gamemonitor
package: all-dependencies core tools docs version
mods: mod_common mod_cnc mod_d2k
all: dependencies core tools
core:
@command -v $(firstword $(MSBUILD)) >/dev/null || (echo "OpenRA requires the '$(MSBUILD)' tool provided by Mono >= 5.18."; exit 1)
@$(MSBUILD) -t:Build -restore -p:Configuration=Release -p:TargetPlatform=$(TARGETPLATFORM)
ifeq ($(TARGETPLATFORM), unix-generic)
@./configure-system-libraries.sh
endif
@./fetch-geoip.sh
clean:
@-$(RM_F) *.exe *.dll *.dylib *.dll.config ./OpenRA*/*.dll ./OpenRA*/*.mdb *.mdb mods/**/*.dll mods/**/*.mdb *.resources
@-$(RM_F) *.config IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP
@-$(RM_F) *.exe *.dll *.dll.config *.so *.dylib ./OpenRA*/*.dll *.pdb mods/**/*.dll mods/**/*.pdb *.resources
@-$(RM_RF) ./*/bin ./*/obj
@-$(RM_RF) ./thirdparty/download
@ $(MSBUILD) -t:clean
distclean: clean
cli-dependencies:
@./thirdparty/fetch-thirdparty-deps.sh
@ $(CP_R) thirdparty/download/*.dll .
@ $(CP_R) thirdparty/download/*.dll.config .
linux-dependencies: cli-dependencies linux-native-dependencies
linux-native-dependencies:
@./thirdparty/configure-native-deps.sh
windows-dependencies:
@./thirdparty/fetch-thirdparty-deps-windows.sh
osx-dependencies: cli-dependencies
@./thirdparty/fetch-thirdparty-deps-osx.sh
@ $(CP_R) thirdparty/download/osx/*.dylib .
@ $(CP_R) thirdparty/download/osx/*.dll.config .
dependencies: $(os-dependencies)
@./thirdparty/fetch-geoip-db.sh
@ $(CP) thirdparty/download/GeoLite2-Country.mmdb.gz .
all-dependencies: cli-dependencies windows-dependencies osx-dependencies
version: mods/ra/mod.yaml mods/cnc/mod.yaml mods/d2k/mod.yaml mods/ts/mod.yaml mods/modchooser/mod.yaml mods/all/mod.yaml
version: VERSION mods/ra/mod.yaml mods/cnc/mod.yaml mods/d2k/mod.yaml mods/ts/mod.yaml mods/modcontent/mod.yaml mods/all/mod.yaml
@echo "$(VERSION)" > VERSION
@for i in $? ; do \
awk '{sub("Version:.*$$","Version: $(VERSION)"); print $0}' $${i} > $${i}.tmp && \
awk '{sub("\tmodchooser:.*$$","\tmodchooser: $(VERSION)"); print $0}' $${i}.tmp > $${i}.tmp2 && \
awk '{sub("/[^/]*: User$$", "/$(VERSION): User"); print $0}' $${i}.tmp2 > $${i} && \
rm $${i}.tmp $${i}.tmp2; \
awk '{sub("/[^/]*: User$$", "/$(VERSION): User"); print $0}' $${i}.tmp > $${i} && \
rm $${i}.tmp; \
done
docs: utility mods version
@mono --debug OpenRA.Utility.exe all --docs > DOCUMENTATION.md
@mono --debug OpenRA.Utility.exe all --lua-docs > Lua-API.md
man-page: utility mods
@mono --debug OpenRA.Utility.exe all --man-page > openra.6
install: install-core
install-all: install-core install-tools
install: core install-engine install-common-mod-files install-default-mods
@$(CP) *.sh "$(DATA_INSTALL_DIR)"
install-linux-shortcuts: install-linux-scripts install-linux-icons install-linux-desktop
install-core: default
@-echo "Installing OpenRA to $(DATA_INSTALL_DIR)"
@$(INSTALL_DIR) "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) $(foreach prog,$(CORE),$($(prog)_TARGET)) "$(DATA_INSTALL_DIR)"
@$(INSTALL_DIR) "$(DATA_INSTALL_DIR)/mods"
@$(CP_R) mods/common "$(DATA_INSTALL_DIR)/mods/"
@$(INSTALL_PROGRAM) $(mod_common_TARGET) "$(DATA_INSTALL_DIR)/mods/common"
@$(INSTALL_PROGRAM) $(mod_cnc_TARGET) "$(DATA_INSTALL_DIR)/mods/common"
@$(CP_R) mods/cnc "$(DATA_INSTALL_DIR)/mods/"
@$(CP_R) mods/ra "$(DATA_INSTALL_DIR)/mods/"
@$(CP_R) mods/d2k "$(DATA_INSTALL_DIR)/mods/"
@$(INSTALL_PROGRAM) $(mod_d2k_TARGET) "$(DATA_INSTALL_DIR)/mods/d2k"
@$(CP_R) mods/modchooser "$(DATA_INSTALL_DIR)/mods/"
install-dependencies:
ifeq ($(TARGETPLATFORM), $(filter $(TARGETPLATFORM),win-x86 win-x64))
@-echo "Installing OpenRA dependencies to $(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) soft_oal.dll "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) SDL2.dll "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) freetype6.dll "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) lua51.dll "$(DATA_INSTALL_DIR)"
endif
ifeq ($(TARGETPLATFORM), linux-x64)
@-echo "Installing OpenRA dependencies to $(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) soft_oal.so "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) SDL2.so "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) freetype6.so "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) lua51.so "$(DATA_INSTALL_DIR)"
endif
ifeq ($(TARGETPLATFORM), osx-x64)
@-echo "Installing OpenRA dependencies to $(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) soft_oal.dylib "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) SDL2.dylib "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) freetype6.dylib "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) lua51.dylib "$(DATA_INSTALL_DIR)"
endif
@$(INSTALL_DATA) "global mix database.dat" "$(DATA_INSTALL_DIR)/global mix database.dat"
@$(INSTALL_DATA) "GeoLite2-Country.mmdb.gz" "$(DATA_INSTALL_DIR)/GeoLite2-Country.mmdb.gz"
install-engine:
@-echo "Installing OpenRA engine to $(DATA_INSTALL_DIR)"
@$(INSTALL_DIR) "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) OpenRA.Game.exe "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) OpenRA.Server.exe "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) OpenRA.Utility.exe "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) OpenRA.Platforms.Default.dll "$(DATA_INSTALL_DIR)"
ifneq ($(TARGETPLATFORM), $(filter $(TARGETPLATFORM),win-x86 win-x64))
@$(INSTALL_DATA) OpenRA.Platforms.Default.dll.config "$(DATA_INSTALL_DIR)"
endif
@$(INSTALL_DATA) VERSION "$(DATA_INSTALL_DIR)/VERSION"
@$(INSTALL_DATA) AUTHORS "$(DATA_INSTALL_DIR)/AUTHORS"
@$(INSTALL_DATA) COPYING "$(DATA_INSTALL_DIR)/COPYING"
@$(INSTALL_DATA) IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP "$(DATA_INSTALL_DIR)/IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP"
@$(CP_R) glsl "$(DATA_INSTALL_DIR)"
@$(CP_R) lua "$(DATA_INSTALL_DIR)"
@@ -383,136 +209,163 @@ install-core: default
@$(CP) Eluant* "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) ICSharpCode.SharpZipLib.dll "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) FuzzyLogicLibrary.dll "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) SharpFont.dll "$(DATA_INSTALL_DIR)"
@$(CP) SharpFont.dll.config "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) Open.Nat.dll "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) MaxMind.Db.dll "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) SmarIrc4net.dll "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) BeaconLib.dll "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) DiscordRPC.dll "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) Newtonsoft.Json.dll "$(DATA_INSTALL_DIR)"
ifneq ($(UNAME_S),Darwin)
@$(CP) *.sh "$(DATA_INSTALL_DIR)"
endif
install-common-mod-files:
@-echo "Installing OpenRA common mod files to $(DATA_INSTALL_DIR)"
@$(INSTALL_DIR) "$(DATA_INSTALL_DIR)/mods"
@$(CP_R) mods/common "$(DATA_INSTALL_DIR)/mods/"
@$(INSTALL_PROGRAM) mods/common/OpenRA.Mods.Common.dll "$(DATA_INSTALL_DIR)/mods/common"
@$(INSTALL_PROGRAM) mods/common/OpenRA.Mods.Cnc.dll "$(DATA_INSTALL_DIR)/mods/common"
@$(INSTALL_DATA) "global mix database.dat" "$(DATA_INSTALL_DIR)/global mix database.dat"
install-tools: tools
@-echo "Installing OpenRA tools to $(DATA_INSTALL_DIR)"
@$(INSTALL_DIR) "$(DATA_INSTALL_DIR)"
@$(INSTALL_PROGRAM) $(foreach prog,$(TOOLS),$($(prog)_TARGET)) "$(DATA_INSTALL_DIR)"
install-default-mods:
@-echo "Installing OpenRA default mods to $(DATA_INSTALL_DIR)"
@$(INSTALL_DIR) "$(DATA_INSTALL_DIR)/mods"
@$(CP_R) mods/cnc "$(DATA_INSTALL_DIR)/mods/"
@$(CP_R) mods/ra "$(DATA_INSTALL_DIR)/mods/"
@$(CP_R) mods/d2k "$(DATA_INSTALL_DIR)/mods/"
@$(INSTALL_PROGRAM) mods/d2k/OpenRA.Mods.D2k.dll "$(DATA_INSTALL_DIR)/mods/d2k"
@$(CP_R) mods/modcontent "$(DATA_INSTALL_DIR)/mods/"
install-linux-icons:
@$(INSTALL_DIR) "$(DESTDIR)$(datadir)/icons/"
@$(CP_R) packaging/linux/hicolor "$(DESTDIR)$(datadir)/icons/"
for SIZE in 16x16 32x32 48x48 64x64 128x128; do \
$(INSTALL_DIR) "$(DESTDIR)$(datadir)/icons/hicolor/$$SIZE/apps"; \
$(INSTALL_DATA) packaging/artwork/ra_$$SIZE.png "$(DESTDIR)$(datadir)/icons/hicolor/$$SIZE/apps/openra-ra.png"; \
$(INSTALL_DATA) packaging/artwork/cnc_$$SIZE.png "$(DESTDIR)$(datadir)/icons/hicolor/$$SIZE/apps/openra-cnc.png"; \
$(INSTALL_DATA) packaging/artwork/d2k_$$SIZE.png "$(DESTDIR)$(datadir)/icons/hicolor/$$SIZE/apps/openra-d2k.png"; \
done
$(INSTALL_DIR) "$(DESTDIR)$(datadir)/icons/hicolor/scalable/apps"
$(INSTALL_DATA) packaging/artwork/ra_scalable.svg "$(DESTDIR)$(datadir)/icons/hicolor/scalable/apps/openra-ra.svg"
$(INSTALL_DATA) packaging/artwork/cnc_scalable.svg "$(DESTDIR)$(datadir)/icons/hicolor/scalable/apps/openra-cnc.svg"
install-linux-desktop:
@$(INSTALL_DIR) "$(DESTDIR)$(datadir)/applications"
@$(INSTALL_DATA) packaging/linux/openra.desktop "$(DESTDIR)$(datadir)/applications"
@sed 's/{MODID}/ra/g' packaging/linux/openra.desktop.in | sed 's/{MODNAME}/Red Alert/g' | sed 's/{TAG}/$(VERSION)/g' > packaging/linux/openra-ra.desktop
@$(INSTALL_DATA) packaging/linux/openra-ra.desktop "$(DESTDIR)$(datadir)/applications"
@sed 's/{MODID}/cnc/g' packaging/linux/openra.desktop.in | sed 's/{MODNAME}/Tiberian Dawn/g' | sed 's/{TAG}/$(VERSION)/g' > packaging/linux/openra-cnc.desktop
@$(INSTALL_DATA) packaging/linux/openra-cnc.desktop "$(DESTDIR)$(datadir)/applications"
@sed 's/{MODID}/d2k/g' packaging/linux/openra.desktop.in | sed 's/{MODNAME}/Dune 2000/g' | sed 's/{TAG}/$(VERSION)/g' > packaging/linux/openra-d2k.desktop
@$(INSTALL_DATA) packaging/linux/openra-d2k.desktop "$(DESTDIR)$(datadir)/applications"
@-$(RM) packaging/linux/openra-ra.desktop packaging/linux/openra-cnc.desktop packaging/linux/openra-d2k.desktop
install-linux-mime:
@$(INSTALL_DIR) "$(DESTDIR)$(datadir)/mime/packages/"
@$(INSTALL_DATA) packaging/linux/openra-mimeinfo.xml "$(DESTDIR)$(datadir)/mime/packages/openra.xml"
@$(INSTALL_DIR) "$(DESTDIR)$(datadir)/applications"
@$(INSTALL_DATA) packaging/linux/openra-join-servers.desktop "$(DESTDIR)$(datadir)/applications"
@$(INSTALL_DATA) packaging/linux/openra-replays.desktop "$(DESTDIR)$(datadir)/applications"
@$(INSTALL_DATA) packaging/linux/openra-launch-mod.desktop "$(DESTDIR)$(datadir)/applications"
@sed 's/{MODID}/ra/g' packaging/linux/openra-mimeinfo.xml.in | sed 's/{TAG}/$(VERSION)/g' > packaging/linux/openra-mimeinfo.xml
@$(INSTALL_DATA) packaging/linux/openra-mimeinfo.xml "$(DESTDIR)$(datadir)/mime/packages/openra-ra.xml"
@sed 's/{MODID}/cnc/g' packaging/linux/openra-mimeinfo.xml.in | sed 's/{TAG}/$(VERSION)/g' > packaging/linux/openra-mimeinfo.xml
@$(INSTALL_DATA) packaging/linux/openra-mimeinfo.xml "$(DESTDIR)$(datadir)/mime/packages/openra-cnc.xml"
@sed 's/{MODID}/d2k/g' packaging/linux/openra-mimeinfo.xml.in | sed 's/{TAG}/$(VERSION)/g' > packaging/linux/openra-mimeinfo.xml
@$(INSTALL_DATA) packaging/linux/openra-mimeinfo.xml "$(DESTDIR)$(datadir)/mime/packages/openra-d2k.xml"
install-linux-appdata:
@$(INSTALL_DIR) "$(DESTDIR)$(datadir)/appdata/"
@$(INSTALL_DATA) packaging/linux/openra.appdata.xml "$(DESTDIR)$(datadir)/appdata/"
@sed 's/{MODID}/ra/g' packaging/linux/openra.appdata.xml.in | sed 's/{MOD_NAME}/Red Alert/g' | sed 's/{SCREENSHOT_RA}/ type="default"/g' | sed 's/{SCREENSHOT_CNC}//g' | sed 's/{SCREENSHOT_D2K}//g'> packaging/linux/openra-ra.appdata.xml
@$(INSTALL_DATA) packaging/linux/openra-ra.appdata.xml "$(DESTDIR)$(datadir)/appdata/"
@sed 's/{MODID}/cnc/g' packaging/linux/openra.appdata.xml.in | sed 's/{MOD_NAME}/Tiberian Dawn/g' | sed 's/{SCREENSHOT_RA}//g' | sed 's/{SCREENSHOT_CNC}/ type="default"/g' | sed 's/{SCREENSHOT_D2K}//g'> packaging/linux/openra-cnc.appdata.xml
@$(INSTALL_DATA) packaging/linux/openra-cnc.appdata.xml "$(DESTDIR)$(datadir)/appdata/"
@sed 's/{MODID}/d2k/g' packaging/linux/openra.appdata.xml.in | sed 's/{MOD_NAME}/Dune 2000/g' | sed 's/{SCREENSHOT_RA}//g' | sed 's/{SCREENSHOT_CNC}//g' | sed 's/{SCREENSHOT_D2K}/ type="default"/g'> packaging/linux/openra-d2k.appdata.xml
@$(INSTALL_DATA) packaging/linux/openra-d2k.appdata.xml "$(DESTDIR)$(datadir)/appdata/"
@-$(RM) packaging/linux/openra-ra.appdata.xml packaging/linux/openra-cnc.appdata.xml packaging/linux/openra-d2k.appdata.xml
install-man-page: man-page
install-man-page:
@$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man6/"
@mono --debug OpenRA.Utility.exe all --man-page > openra.6
@$(INSTALL_DATA) openra.6 "$(DESTDIR)$(mandir)/man6/"
@-$(RM) openra.6
install-linux-scripts:
@echo "#!/bin/sh" > openra
@echo 'cd "$(gameinstalldir)"' >> openra
# Note: this relies on the non-standard -f flag implemented by gnu readlink
ifeq ($(DEBUG), $(filter $(DEBUG),false no n off 0))
@echo 'mono OpenRA.Game.exe Engine.LaunchPath="$$(readlink -f $$0)" "$$@"' >> openra
@sed 's/{DEBUG}//' packaging/linux/openra.in | sed 's|{GAME_INSTALL_DIR}|$(gameinstalldir)|' | sed 's|{BIN_DIR}|$(bindir)|' > packaging/linux/openra.debug.in
@sed 's/{DEBUG}//' packaging/linux/openra-server.in | sed 's|{GAME_INSTALL_DIR}|$(gameinstalldir)|' | sed 's|{BIN_DIR}|$(bindir)|' > packaging/linux/openra-server.debug.in
else
@echo 'mono --debug OpenRA.Game.exe Engine.LaunchPath="$$(readlink -f $$0)" "$$@"' >> openra
endif
@echo 'if [ $$? != 0 -a $$? != 1 ]' >> openra
@echo 'then' >> openra
@echo 'ZENITY=`which zenity` || echo "OpenRA needs zenity installed to display a graphical error dialog. See ~/.openra. for log files."' >> openra
@echo '$$ZENITY --question --title "OpenRA" --text "OpenRA has encountered a fatal error.\nLog Files are available in ~/.openra." --ok-label "Quit" --cancel-label "View FAQ" || xdg-open https://github.com/OpenRA/OpenRA/wiki/FAQ' >> openra
@echo 'exit 1' >> openra
@echo 'fi' >> openra
@$(INSTALL_DIR) "$(BIN_INSTALL_DIR)"
@$(INSTALL_PROGRAM) -m +rx openra "$(BIN_INSTALL_DIR)"
@-$(RM) openra
@echo "#!/bin/sh" > openra-server
@echo 'cd "$(gameinstalldir)"' >> openra-server
ifeq ($(DEBUG), $(filter $(DEBUG),false no n off 0))
@echo 'mono OpenRA.Server.exe "$$@"' >> openra-server
else
@echo 'mono --debug OpenRA.Server.exe "$$@"' >> openra-server
@sed 's/{DEBUG}/--debug/' packaging/linux/openra.in | sed 's|{GAME_INSTALL_DIR}|$(gameinstalldir)|' | sed 's|{BIN_DIR}|$(bindir)|' > packaging/linux/openra.debug.in
@sed 's/{DEBUG}/--debug/' packaging/linux/openra-server.in | sed 's|{GAME_INSTALL_DIR}|$(gameinstalldir)|' | sed 's|{BIN_DIR}|$(bindir)|' > packaging/linux/openra-server.debug.in
endif
@sed 's/{MODID}/ra/g' packaging/linux/openra.debug.in | sed 's/{TAG}/$(VERSION)/g' | sed 's/{MODNAME}/Red Alert/g' > packaging/linux/openra-ra
@sed 's/{MODID}/cnc/g' packaging/linux/openra.debug.in | sed 's/{TAG}/$(VERSION)/g' | sed 's/{MODNAME}/Tiberian Dawn/g' > packaging/linux/openra-cnc
@sed 's/{MODID}/d2k/g' packaging/linux/openra.debug.in | sed 's/{TAG}/$(VERSION)/g' | sed 's/{MODNAME}/Dune 2000/g' > packaging/linux/openra-d2k
@$(INSTALL_DIR) "$(BIN_INSTALL_DIR)"
@$(INSTALL_PROGRAM) -m +rx openra-server "$(BIN_INSTALL_DIR)"
@-$(RM) openra-server
@$(INSTALL_PROGRAM) -m +rx packaging/linux/openra-ra "$(BIN_INSTALL_DIR)"
@$(INSTALL_PROGRAM) -m +rx packaging/linux/openra-cnc "$(BIN_INSTALL_DIR)"
@$(INSTALL_PROGRAM) -m +rx packaging/linux/openra-d2k "$(BIN_INSTALL_DIR)"
@-$(RM) packaging/linux/openra-ra packaging/linux/openra-cnc packaging/linux/openra-d2k packaging/linux/openra.debug.in
@sed 's/{MODID}/ra/g' packaging/linux/openra-server.debug.in | sed 's/{MODNAME}/Red Alert/g' > packaging/linux/openra-ra-server
@sed 's/{MODID}/cnc/g' packaging/linux/openra-server.debug.in | sed 's/{MODNAME}/Tiberian Dawn/g' > packaging/linux/openra-cnc-server
@sed 's/{MODID}/d2k/g' packaging/linux/openra-server.debug.in | sed 's/{MODNAME}/Dune 2000/g' > packaging/linux/openra-d2k-server
@$(INSTALL_DIR) "$(BIN_INSTALL_DIR)"
@$(INSTALL_PROGRAM) -m +rx packaging/linux/openra-ra-server "$(BIN_INSTALL_DIR)"
@$(INSTALL_PROGRAM) -m +rx packaging/linux/openra-cnc-server "$(BIN_INSTALL_DIR)"
@$(INSTALL_PROGRAM) -m +rx packaging/linux/openra-d2k-server "$(BIN_INSTALL_DIR)"
@-$(RM) packaging/linux/openra-ra-server packaging/linux/openra-cnc-server packaging/linux/openra-d2k-server packaging/linux/openra-server.debug.in
uninstall:
@-$(RM_R) "$(DATA_INSTALL_DIR)"
@-$(RM_F) "$(BIN_INSTALL_DIR)/openra"
@-$(RM_F) "$(BIN_INSTALL_DIR)/openra-server"
@-$(RM_F) "$(DESTDIR)$(datadir)/applications/openra.desktop"
@-$(RM_F) "$(DESTDIR)$(datadir)/applications/openra-join-servers.desktop"
@-$(RM_F) "$(DESTDIR)$(datadir)/applications/openra-launch-mod.desktop"
@-$(RM_F) "$(DESTDIR)$(datadir)/applications/openra-join-servers.desktop"
@-$(RM_F) "$(DESTDIR)$(datadir)/icons/hicolor/16x16/apps/openra.png"
@-$(RM_F) "$(DESTDIR)$(datadir)/icons/hicolor/32x32/apps/openra.png"
@-$(RM_F) "$(DESTDIR)$(datadir)/icons/hicolor/48x48/apps/openra.png"
@-$(RM_F) "$(DESTDIR)$(datadir)/icons/hicolor/64x64/apps/openra.png"
@-$(RM_F) "$(DESTDIR)$(datadir)/icons/hicolor/128x128/apps/openra.png"
@-$(RM_F) "$(DESTDIR)$(datadir)/mime/packages/openra.xml"
@-$(RM_F) "$(DESTDIR)$(datadir)/appdata/openra.appdata.xml"
@-$(RM_F) "$(BIN_INSTALL_DIR)/openra-ra"
@-$(RM_F) "$(BIN_INSTALL_DIR)/openra-ra-server"
@-$(RM_F) "$(BIN_INSTALL_DIR)/openra-cnc"
@-$(RM_F) "$(BIN_INSTALL_DIR)/openra-cnc-server"
@-$(RM_F) "$(BIN_INSTALL_DIR)/openra-d2k"
@-$(RM_F) "$(BIN_INSTALL_DIR)/openra-d2k-server"
@-$(RM_F) "$(DESTDIR)$(datadir)/applications/openra-ra.desktop"
@-$(RM_F) "$(DESTDIR)$(datadir)/applications/openra-cnc.desktop"
@-$(RM_F) "$(DESTDIR)$(datadir)/applications/openra-d2k.desktop"
@-for SIZE in 16x16 32x32 48x48 64x64 128x128; do \
$(RM_F) "$(DESTDIR)$(datadir)/icons/hicolor/$$SIZE/apps/openra-ra.png"; \
$(RM_F) "$(DESTDIR)$(datadir)/icons/hicolor/$$SIZE/apps/openra-cnc.png"; \
$(RM_F) "$(DESTDIR)$(datadir)/icons/hicolor/$$SIZE/apps/openra-d2k.png"; \
done
@-$(RM_F) "$(DESTDIR)$(datadir)/icons/hicolor/scalable/apps/openra-ra.svg"
@-$(RM_F) "$(DESTDIR)$(datadir)/icons/hicolor/scalable/apps/openra-cnc.svg"
@-$(RM_F) "$(DESTDIR)$(datadir)/mime/packages/openra-ra.xml"
@-$(RM_F) "$(DESTDIR)$(datadir)/mime/packages/openra-cnc.xml"
@-$(RM_F) "$(DESTDIR)$(datadir)/mime/packages/openra-d2k.xml"
@-$(RM_F) "$(DESTDIR)$(datadir)/appdata/openra-ra.appdata.xml"
@-$(RM_F) "$(DESTDIR)$(datadir)/appdata/openra-cnc.appdata.xml"
@-$(RM_F) "$(DESTDIR)$(datadir)/appdata/openra-d2k.appdata.xml"
@-$(RM_F) "$(DESTDIR)$(mandir)/man6/openra.6"
help:
@echo 'to compile, run:'
@echo ' make [DEBUG=false]'
@echo ' make [DEBUG=true]'
@echo
@echo 'to compile with development tools, run:'
@echo ' make all [DEBUG=false]'
@echo
@echo 'to check unit tests (requires NUnit version >= 2.6), run:'
@echo ' make nunit [NUNIT_CONSOLE=<path-to/nunit[3|2]-console>] [NUNIT_LIBS_PATH=<path-to-libs-dir>] [NUNIT_LIBS=<nunit-libs>]'
@echo ' Use NUNIT_CONSOLE if nunit[3|2]-console was not downloaded by `make dependencies` nor is it in bin search paths'
@echo ' Use NUNIT_LIBS_PATH if NUnit libs are not in search paths. Include trailing /'
@echo ' Use NUNIT_LIBS if NUnit libs have different names (such as including a prefix or suffix)'
@echo 'to compile using system libraries for native dependencies, run:'
@echo ' make [DEBUG=true] TARGETPLATFORM=unix-generic'
@echo
@echo 'to check the official mods for erroneous yaml files, run:'
@echo ' make test'
@echo
@echo 'to generate documentation aimed at modders, run:'
@echo ' make docs'
@echo 'to check the engine and official mod dlls for code style violations, run:'
@echo ' make test'
@echo
@echo 'to install, run:'
@echo ' make [prefix=/foo] [bindir=/bar/bin] install'
@echo
@echo 'to install with development tools, run:'
@echo ' make [prefix=/foo] [bindir=/bar/bin] install-all'
@echo
@echo 'to install Linux startup scripts, desktop files and icons'
@echo ' make install-linux-shortcuts [DEBUG=false]'
@echo
@echo ' to install the engine and common mod files (omitting the default mods):'
@echo ' make install-engine'
@echo ' make install-dependencies'
@echo ' make install-common-mod-files'
@echo
@echo 'to uninstall, run:'
@echo ' make uninstall'
@echo
@echo 'to start the game, run:'
@echo ' openra'
########################### MAKEFILE SETTINGS ##########################
#
.DEFAULT_GOAL := default
.DEFAULT_GOAL := all
.SUFFIXES:
.PHONY: core tools package all mods clean distclean dependencies version $(PROGRAMS) nunit
.PHONY: check-scripts check test all core clean version install install-linux-shortcuts install-dependencies install-engine install-common-mod-files install-default-mods install-linux-icons install-linux-desktop install-linux-mime install-linux-appdata install-man-page install-linux-scripts uninstall help

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,183 +12,156 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Primitives;
using OpenRA.Traits;
namespace OpenRA.Activities
{
public enum ActivityState { Queued, Active, Done, Canceled }
public enum ActivityState { Queued, Active, Canceling, Done }
public class TargetLineNode
{
public readonly Target Target;
public readonly Color Color;
public readonly Sprite Tile;
public TargetLineNode(Target target, Color color, Sprite tile = null)
{
// Note: Not all activities are drawable. In that case, pass Target.Invalid as target,
// if "yield break" in TargetLineNode(Actor self) is not feasible.
Target = target;
Color = color;
Tile = tile;
}
}
/*
* Activities are actions carried out by actors during each tick.
*
* Activities exist in a graph data structure built up amongst themselves. Each activity has a parent activity,
* optionally child activities, and usually a next activity. An actor's CurrentActivity is a pointer into that graph
* and moves through it as activities run.
*
* There are two kinds of activities, the base activity and composite activities. They differ in the way their children
* are run: while a base activity is responsible for running its children itself, a composite activity relies on the actor's
* activity-running code. Therefore, the actor's CurrentActivity stays on the base activity while it runs its children. With
* composite activities however, the CurrentActivity moves through the list of children as they run.
*
*
* Things to be aware of when writing activities:
*
* - Use "return NextActivity" at least once somewhere in the tick method.
* - Do not use "return new SomeActivity()" as that will break the graph. Queue the new activity and use "return NextActivity" instead.
* - Do not "reuse" (with "SequenceActivities", for example) activity objects that have already finished running.
* - Use "return true" at least once somewhere in the tick method.
* - Do not "reuse" activity objects (by queuing them as next or child, for example) that have already started running.
* Queue a new instance instead.
* - Avoid calling actor.CancelActivity(). It is almost always a bug. Call activity.Cancel() instead.
* - A composite activity will run at least twice. The first time when it returns its children,
* the second time when its last child returns its Parent.
* - Do not return the Parent explicitly unless you have an extremly good reason. "return NextActivity"
* will do the right thing in all circumstances.
* - You do not need to care about the ChildActivity pointer advancing through the list of children,
* the activity code already takes care of that.
* - If you want to check whether there are any follow-up activities queued, check against "NextInQueue"
* in favour of "NextActivity" to avoid checking against the Parent activity.
*
*
* Guide when to use which kind of activity:
*
* - The activity does not have any children -> base activity
* - The activity needs to run preparatory steps during each tick before its children can be run -> base activity
* - The activity or the actor is left in a bogus state when one of the child activities is canceled -> base activity
* - The activity's children are self-contained and can run independently of the parent -> composite activity
* - The activity does not have any or little logic of its own, but is just composed of sub-steps -> composite activity
*/
public abstract class Activity
* - Do not evaluate dynamic state (an actor's location, health, conditions, etc.) in the activity's constructor,
* as that might change before the activity gets to tick for the first time. Use the OnFirstRun() method instead.
*/
public abstract class Activity : IActivityInterface
{
public ActivityState State { get; private set; }
/// <summary>
/// Returns the top-most activity *from the point of view of the calling activity*. Note that the root activity
/// can and likely will have next activities of its own, which would in turn be the root for their children.
/// </summary>
public Activity RootActivity
{
get
{
var p = this;
while (p.ParentActivity != null)
p = p.ParentActivity;
return p;
}
}
Activity parentActivity;
public Activity ParentActivity
{
get
{
return parentActivity;
}
protected set
{
parentActivity = value;
var next = NextInQueue;
if (next != null)
next.ParentActivity = parentActivity;
}
}
Activity childActivity;
protected Activity ChildActivity
{
get
{
return childActivity != null && childActivity.State < ActivityState.Done ? childActivity : null;
}
set
{
if (value == this || value == ParentActivity || value == NextInQueue)
childActivity = null;
else
{
childActivity = value;
if (childActivity != null)
childActivity.ParentActivity = this;
}
}
get { return SkipDoneActivities(childActivity); }
private set { childActivity = value; }
}
Activity nextActivity;
/// <summary>
/// The getter will return either the next activity or, if there is none, the parent one.
/// </summary>
public virtual Activity NextActivity
public Activity NextActivity
{
get
{
return nextActivity != null ? nextActivity : ParentActivity;
}
set
{
if (value == this || value == ParentActivity || (value != null && value.ParentActivity == this))
nextActivity = null;
else
{
nextActivity = value;
if (nextActivity != null)
nextActivity.ParentActivity = ParentActivity;
}
}
get { return SkipDoneActivities(nextActivity); }
private set { nextActivity = value; }
}
/// <summary>
/// The getter will return the next activity on the same level _only_, in contrast to NextActivity.
/// Use this to check whether there are any follow-up activities queued.
/// </summary>
public Activity NextInQueue
internal static Activity SkipDoneActivities(Activity first)
{
get { return nextActivity; }
set { NextActivity = value; }
// If first.Cancel() was called while it was queued (i.e. before it first ticked), its state will be Done
// rather than Queued (the activity system guarantees that it cannot be Active or Canceling).
// An unknown number of ticks may have elapsed between the Cancel() call and now,
// so we cannot make any assumptions on the value of first.NextActivity.
// We must not return first (ticking it would be bogus), but returning null would potentially
// drop valid activities queued after it. Walk the queue until we find a valid activity or
// (more likely) run out of activities.
while (first != null && first.State == ActivityState.Done)
first = first.NextActivity;
return first;
}
public bool IsInterruptible { get; protected set; }
public bool IsCanceled { get { return State == ActivityState.Canceled; } }
public bool ChildHasPriority { get; protected set; }
public bool IsCanceling { get { return State == ActivityState.Canceling; } }
bool finishing;
bool firstRunCompleted;
bool lastRun;
public Activity()
{
IsInterruptible = true;
ChildHasPriority = true;
}
public Activity TickOuter(Actor self)
{
if (State == ActivityState.Done && Game.Settings.Debug.StrictActivityChecking)
throw new InvalidOperationException("Actor {0} attempted to tick activity {1} after it had already completed.".F(self, this.GetType()));
if (State == ActivityState.Done)
throw new InvalidOperationException("Actor {0} attempted to tick activity {1} after it had already completed.".F(self, GetType()));
if (State == ActivityState.Queued)
{
OnFirstRun(self);
firstRunCompleted = true;
State = ActivityState.Active;
}
var ret = Tick(self);
if (ret == null || (ret != this && ret.ParentActivity != this))
if (!firstRunCompleted)
throw new InvalidOperationException("Actor {0} attempted to tick activity {1} before running its OnFirstRun method.".F(self, GetType()));
// Only run the parent tick when the child is done.
// We must always let the child finish on its own before continuing.
if (ChildHasPriority)
{
// Make sure that the Parent's ChildActivity pointer is moved forwards as the child queue advances.
// The Child's ParentActivity will be set automatically during assignment.
if (ParentActivity != null && ParentActivity != ret)
ParentActivity.ChildActivity = ret;
if (State != ActivityState.Canceled)
State = ActivityState.Done;
OnLastRun(self);
lastRun = TickChild(self) && (finishing || Tick(self));
finishing |= lastRun;
}
return ret;
// The parent determines whether the child gets a chance at ticking.
else
lastRun = Tick(self);
// Avoid a single tick delay if the childactivity was just queued.
if (ChildActivity != null && ChildActivity.State == ActivityState.Queued)
{
if (ChildHasPriority)
lastRun = TickChild(self) && finishing;
else
TickChild(self);
}
if (lastRun)
{
State = ActivityState.Done;
OnLastRun(self);
return NextActivity;
}
return this;
}
public abstract Activity Tick(Actor self);
protected bool TickChild(Actor self)
{
ChildActivity = ActivityUtils.RunActivity(self, ChildActivity);
return ChildActivity == null;
}
/// <summary>
/// Called every tick to run activity logic. Returns false if the activity should
/// remain active, or true if it is complete. Cancelled activities must ensure they
/// return the actor to a consistent state before returning true.
///
/// Child activities can be queued using QueueChild, and these will be ticked
/// instead of the parent while they are active. Activities that need to run logic
/// in parallel with child activities should set ChildHasPriority to false and
/// manually call TickChildren.
///
/// Queuing one or more child activities and returning true is valid, and causes
/// the activity to be completed immediately (without ticking again) once the
/// children have completed.
/// </summary>
public virtual bool Tick(Actor self)
{
return true;
}
/// <summary>
/// Runs once immediately before the first Tick() execution.
@@ -200,30 +173,46 @@ namespace OpenRA.Activities
/// </summary>
protected virtual void OnLastRun(Actor self) { }
public virtual bool Cancel(Actor self)
/// <summary>
/// Runs once on Actor.Dispose() (through OnActorDisposeOuter) and can be used to perform activity clean-up on actor death/disposal,
/// for example by force-triggering OnLastRun (which would otherwise be skipped).
/// </summary>
protected virtual void OnActorDispose(Actor self) { }
/// <summary>
/// Runs once on Actor.Dispose().
/// Main purpose is to ensure ChildActivity.OnActorDispose runs as well (which isn't otherwise accessible due to protection level).
/// </summary>
internal void OnActorDisposeOuter(Actor self)
{
ChildActivity?.OnActorDisposeOuter(self);
OnActorDispose(self);
}
public virtual void Cancel(Actor self, bool keepQueue = false)
{
if (!keepQueue)
NextActivity = null;
if (!IsInterruptible)
return false;
return;
if (ChildActivity != null && !ChildActivity.Cancel(self))
return false;
ChildActivity?.Cancel(self);
State = ActivityState.Canceled;
NextActivity = null;
ChildActivity = null;
return true;
// Directly mark activities that are queued and therefore didn't run yet as done
State = State == ActivityState.Queued ? ActivityState.Done : ActivityState.Canceling;
}
public virtual void Queue(Activity activity)
public void Queue(Activity activity)
{
if (NextInQueue != null)
NextInQueue.Queue(activity);
if (NextActivity != null)
NextActivity.Queue(activity);
else
NextInQueue = activity;
NextActivity = activity;
}
public virtual void QueueChild(Activity activity)
public void QueueChild(Activity activity)
{
if (ChildActivity != null)
ChildActivity.Queue(activity);
@@ -232,30 +221,29 @@ namespace OpenRA.Activities
}
/// <summary>
/// Prints the activity tree, starting from the root or optionally from a given origin.
/// Prints the activity tree, starting from the top or optionally from a given origin.
///
/// Call this method from any place that's called during a tick, such as the Tick() method itself or
/// the Before(First|Last)Run() methods. The origin activity will be marked in the output.
/// </summary>
/// <param name="origin">Activity from which to start traversing, and which to mark. If null, mark the calling activity, and start traversal from the root.</param>
/// <param name="self">The actor performing this activity.</param>
/// <param name="origin">Activity from which to start traversing, and which to mark. If null, mark the calling activity, and start traversal from the top.</param>
/// <param name="level">Initial level of indentation.</param>
protected void PrintActivityTree(Activity origin = null, int level = 0)
protected void PrintActivityTree(Actor self, Activity origin = null, int level = 0)
{
if (origin == null)
RootActivity.PrintActivityTree(this);
self.CurrentActivity.PrintActivityTree(self, this);
else
{
Console.Write(new string(' ', level * 2));
if (origin == this)
Console.Write("*");
Console.WriteLine(this.GetType().ToString().Split('.').Last());
Console.WriteLine(GetType().ToString().Split('.').Last());
if (ChildActivity != null)
ChildActivity.PrintActivityTree(origin, level + 1);
ChildActivity?.PrintActivityTree(self, origin, level + 1);
if (NextInQueue != null)
NextInQueue.PrintActivityTree(origin, level);
NextActivity?.PrintActivityTree(self, origin, level);
}
}
@@ -263,39 +251,34 @@ namespace OpenRA.Activities
{
yield break;
}
}
/// <summary>
/// In contrast to the base activity class, which is responsible for running its children itself,
/// composite activities rely on the actor's activity-running logic for their children.
/// </summary>
public abstract class CompositeActivity : Activity
{
/// <summary>
/// The getter will return the first non-null value of either child, next or parent activity, in that order, or ultimately null.
/// </summary>
public override Activity NextActivity
public virtual IEnumerable<TargetLineNode> TargetLineNodes(Actor self)
{
get
yield break;
}
public IEnumerable<string> DebugLabelComponents()
{
var act = this;
while (act != null)
{
if (ChildActivity != null)
return ChildActivity;
else if (NextInQueue != null)
return NextInQueue;
else
return ParentActivity;
yield return act.GetType().Name;
act = act.ChildActivity;
}
}
}
public static class ActivityExts
{
public static IEnumerable<Target> GetTargetQueue(this Actor self)
public IEnumerable<T> ActivitiesImplementing<T>(bool includeChildren = true) where T : IActivityInterface
{
return self.CurrentActivity
.Iterate(u => u.NextActivity)
.TakeWhile(u => u != null)
.SelectMany(u => u.GetTargets(self));
if (includeChildren && ChildActivity != null)
foreach (var a in ChildActivity.ActivitiesImplementing<T>())
yield return a;
if (this is T)
yield return (T)(object)this;
if (NextActivity != null)
foreach (var a in NextActivity.ActivitiesImplementing<T>())
yield return a;
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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
@@ -24,10 +24,10 @@ namespace OpenRA.Activities
Action a;
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
if (a != null) a();
return NextActivity;
a?.Invoke();
return true;
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,7 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using Eluant;
using Eluant.ObjectBinding;
@@ -28,8 +28,9 @@ namespace OpenRA
internal struct SyncHash
{
public readonly ISync Trait;
public readonly int Hash;
public SyncHash(ISync trait, int hash) { Trait = trait; Hash = hash; }
readonly Func<object, int> hashFunction;
public SyncHash(ISync trait) { Trait = trait; hashFunction = Sync.GetHashFunction(trait); }
public int Hash() { return hashFunction(Trait); }
}
public readonly ActorInfo Info;
@@ -41,15 +42,19 @@ namespace OpenRA
public Player Owner { get; internal set; }
public bool IsInWorld { get; internal set; }
public bool WillDispose { get; private set; }
public bool Disposed { get; private set; }
public Activity CurrentActivity { get; private set; }
Activity currentActivity;
public Activity CurrentActivity
{
get { return Activity.SkipDoneActivities(currentActivity); }
private set { currentActivity = value; }
}
public Group Group;
public int Generation;
public Actor ReplacedByActor;
public Rectangle Bounds { get; private set; }
public Rectangle VisualBounds { get; private set; }
public IEffectiveOwner EffectiveOwner { get; private set; }
public IOccupySpace OccupiesSpace { get; private set; }
public ITargetable[] Targetables { get; private set; }
@@ -64,30 +69,67 @@ namespace OpenRA
{
get
{
// TODO: Support non-zero pitch/roll in IFacing (IOrientation?)
var facingValue = facing != null ? facing.Facing : 0;
return new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facingValue));
return facing != null ? facing.Orientation : WRot.None;
}
}
internal IEnumerable<SyncHash> SyncHashes { get; private set; }
/// <summary>Value used to represent an invalid token.</summary>
public static readonly int InvalidConditionToken = -1;
class ConditionState
{
/// <summary>Delegates that have registered to be notified when this condition changes.</summary>
public readonly List<VariableObserverNotifier> Notifiers = new List<VariableObserverNotifier>();
/// <summary>Unique integers identifying granted instances of the condition.</summary>
public readonly HashSet<int> Tokens = new HashSet<int>();
}
readonly Dictionary<string, ConditionState> conditionStates = new Dictionary<string, ConditionState>();
/// <summary>Each granted condition receives a unique token that is used when revoking.</summary>
readonly Dictionary<int, string> conditionTokens = new Dictionary<int, string>();
int nextConditionToken = 1;
/// <summary>Cache of condition -> enabled state for quick evaluation of token counter conditions.</summary>
readonly Dictionary<string, int> conditionCache = new Dictionary<string, int>();
/// <summary>Read-only version of conditionCache that is passed to IConditionConsumers.</summary>
readonly IReadOnlyDictionary<string, int> readOnlyConditionCache;
internal SyncHash[] SyncHashes { get; private set; }
readonly IFacing facing;
readonly IHealth health;
readonly IRenderModifier[] renderModifiers;
readonly IRender[] renders;
readonly IDisable[] disables;
readonly IMouseBounds[] mouseBounds;
readonly IVisibilityModifier[] visibilityModifiers;
readonly IDefaultVisibility defaultVisibility;
readonly INotifyBecomingIdle[] becomingIdles;
readonly INotifyIdle[] tickIdles;
readonly ITargetablePositions[] targetablePositions;
WPos[] staticTargetablePositions;
bool created;
internal Actor(World world, string name, TypeDictionary initDict)
{
var duplicateInit = initDict.WithInterface<ISingleInstanceInit>().GroupBy(i => i.GetType())
.FirstOrDefault(i => i.Count() > 1);
if (duplicateInit != null)
throw new InvalidDataException("Duplicate initializer '{0}'".F(duplicateInit.Key.Name));
var init = new ActorInitializer(this, initDict);
readOnlyConditionCache = new ReadOnlyDictionary<string, int>(conditionCache);
World = world;
ActorID = world.NextAID();
if (initDict.Contains<OwnerInit>())
Owner = init.Get<OwnerInit, Player>();
var ownerInit = init.GetOrDefault<OwnerInit>();
if (ownerInit != null)
Owner = ownerInit.Value(world);
if (name != null)
{
@@ -111,51 +153,87 @@ namespace OpenRA
// PERF: Cache all these traits as soon as the actor is created. This is a fairly cheap one-off cost per
// actor that allows us to provide some fast implementations of commonly used methods that are relied on by
// performance-sensitive parts of the core game engine, such as pathfinding, visibility and rendering.
Bounds = DetermineBounds();
VisualBounds = DetermineVisualBounds();
EffectiveOwner = TraitOrDefault<IEffectiveOwner>();
facing = TraitOrDefault<IFacing>();
health = TraitOrDefault<IHealth>();
renderModifiers = TraitsImplementing<IRenderModifier>().ToArray();
renders = TraitsImplementing<IRender>().ToArray();
disables = TraitsImplementing<IDisable>().ToArray();
mouseBounds = TraitsImplementing<IMouseBounds>().ToArray();
visibilityModifiers = TraitsImplementing<IVisibilityModifier>().ToArray();
defaultVisibility = Trait<IDefaultVisibility>();
becomingIdles = TraitsImplementing<INotifyBecomingIdle>().ToArray();
tickIdles = TraitsImplementing<INotifyIdle>().ToArray();
Targetables = TraitsImplementing<ITargetable>().ToArray();
targetablePositions = TraitsImplementing<ITargetablePositions>().ToArray();
world.AddFrameEndTask(w =>
{
// Caching this in a AddFrameEndTask, because trait construction order might cause problems if done directly at creation time.
// 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 (!Info.HasTraitInfo<IPositionableInfo>() && targetablePositions.Any() && targetablePositions.All(tp => tp.AlwaysEnabled))
staticTargetablePositions = targetablePositions.SelectMany(tp => tp.TargetablePositions(this)).ToArray();
});
SyncHashes =
TraitsImplementing<ISync>()
.Select(sync => Pair.New(sync, Sync.GetHashFunction(sync)))
.ToArray()
.Select(pair => new SyncHash(pair.First, pair.Second(pair.First)));
SyncHashes = TraitsImplementing<ISync>().Select(sync => new SyncHash(sync)).ToArray();
}
Rectangle DetermineBounds()
internal void Initialize(bool addToWorld = true)
{
var si = Info.TraitInfoOrDefault<SelectableInfo>();
var size = (si != null && si.Bounds != null) ? new int2(si.Bounds[0], si.Bounds[1]) :
TraitsImplementing<IAutoSelectionSize>().Select(x => x.SelectionSize(this)).FirstOrDefault();
created = true;
var offset = -size / 2;
if (si != null && si.Bounds != null && si.Bounds.Length > 2)
offset += new int2(si.Bounds[2], si.Bounds[3]);
// Make sure traits are usable for condition notifiers
foreach (var t in TraitsImplementing<INotifyCreated>())
t.Created(this);
return new Rectangle(offset.X, offset.Y, size.X, size.Y);
}
var allObserverNotifiers = new HashSet<VariableObserverNotifier>();
foreach (var provider in TraitsImplementing<IObservesVariables>())
{
foreach (var variableUser in provider.GetVariableObservers())
{
allObserverNotifiers.Add(variableUser.Notifier);
foreach (var variable in variableUser.Variables)
{
var cs = conditionStates.GetOrAdd(variable);
cs.Notifiers.Add(variableUser.Notifier);
Rectangle DetermineVisualBounds()
{
var sd = Info.TraitInfoOrDefault<ISelectionDecorationsInfo>();
if (sd == null || sd.SelectionBoxBounds == null)
return Bounds;
// Initialize conditions that have not yet been granted to 0
// NOTE: Some conditions may have already been granted by INotifyCreated calling GrantCondition,
// and we choose to assign the token count to safely cover both cases instead of adding an if branch.
conditionCache[variable] = cs.Tokens.Count;
}
}
}
var size = new int2(sd.SelectionBoxBounds[0], sd.SelectionBoxBounds[1]);
// Update all traits with their initial condition state
foreach (var notify in allObserverNotifiers)
notify(this, readOnlyConditionCache);
var offset = -size / 2;
if (sd.SelectionBoxBounds.Length > 2)
offset += new int2(sd.SelectionBoxBounds[2], sd.SelectionBoxBounds[3]);
// TODO: Some traits may need initialization after being notified of initial condition state.
return new Rectangle(offset.X, offset.Y, size.X, size.Y);
// TODO: A post condition initialization notification phase may allow queueing activities instead.
// The initial activity should run before any activities queued by INotifyCreated.Created
// However, we need to know which traits are enabled (via conditions), so wait for after the calls and insert the activity as the first
ICreationActivity creationActivity = null;
foreach (var ica in TraitsImplementing<ICreationActivity>())
{
if (!ica.IsTraitEnabled())
continue;
if (creationActivity != null)
throw new InvalidOperationException("More than one enabled ICreationActivity trait: {0} and {1}".F(creationActivity.GetType().Name, ica.GetType().Name));
var activity = ica.GetCreationActivity();
if (activity == null)
continue;
creationActivity = ica;
activity.Queue(CurrentActivity);
CurrentActivity = activity;
}
if (addToWorld)
World.Add(this);
}
public void Tick()
@@ -164,8 +242,18 @@ namespace OpenRA
CurrentActivity = ActivityUtils.RunActivity(this, CurrentActivity);
if (!wasIdle && IsIdle)
foreach (var n in TraitsImplementing<INotifyBecomingIdle>())
{
foreach (var n in becomingIdles)
n.OnBecomingIdle(this);
// If IsIdle is true, it means the last CurrentActivity.Tick returned null.
// If a next activity has been queued via OnBecomingIdle, we need to start running it now,
// to avoid an 'empty' null tick where the actor will (visibly, if moving) do nothing.
CurrentActivity = ActivityUtils.RunActivity(this, CurrentActivity);
}
else if (wasIdle)
foreach (var tickIdle in tickIdles)
tickIdle.TickIdle(this);
}
public IEnumerable<IRenderable> Render(WorldRenderer wr)
@@ -191,27 +279,57 @@ namespace OpenRA
yield return renderable;
}
public IEnumerable<Rectangle> ScreenBounds(WorldRenderer wr)
{
var bounds = Bounds(wr);
foreach (var modifier in renderModifiers)
bounds = modifier.ModifyScreenBounds(this, wr, bounds);
return bounds;
}
IEnumerable<Rectangle> Bounds(WorldRenderer wr)
{
// PERF: Avoid LINQ. See comments for Renderables
foreach (var render in renders)
foreach (var r in render.ScreenBounds(this, wr))
if (!r.IsEmpty)
yield return r;
}
public Polygon MouseBounds(WorldRenderer wr)
{
foreach (var mb in mouseBounds)
{
var bounds = mb.MouseoverBounds(this, wr);
if (!bounds.IsEmpty)
return bounds;
}
return Polygon.Empty;
}
public void QueueActivity(bool queued, Activity nextActivity)
{
if (!queued)
CancelActivity();
QueueActivity(nextActivity);
}
public void QueueActivity(Activity nextActivity)
{
if (!created)
throw new InvalidOperationException("An activity was queued before the actor was created. Queue it inside the INotifyCreated.Created callback instead.");
if (CurrentActivity == null)
CurrentActivity = nextActivity;
else
CurrentActivity.RootActivity.Queue(nextActivity);
CurrentActivity.Queue(nextActivity);
}
public bool CancelActivity()
public void CancelActivity()
{
if (CurrentActivity != null)
return CurrentActivity.RootActivity.Cancel(this);
return true;
CurrentActivity?.Cancel(this);
}
public override int GetHashCode()
@@ -261,6 +379,13 @@ namespace OpenRA
public void Dispose()
{
// If CurrentActivity isn't null, run OnActorDisposeOuter in case some cleanups are needed.
// This should be done before the FrameEndTask to avoid dependency issues.
CurrentActivity?.OnActorDisposeOuter(this);
// Allow traits/activities to prevent a race condition when they depend on disposing the actor (e.g. Transforms)
WillDispose = true;
World.AddFrameEndTask(w =>
{
if (Disposed)
@@ -275,35 +400,43 @@ namespace OpenRA
World.TraitDict.RemoveActor(this);
Disposed = true;
if (luaInterface != null)
luaInterface.Value.OnActorDestroyed();
luaInterface?.Value.OnActorDestroyed();
});
}
// TODO: move elsewhere.
public void ChangeOwner(Player newOwner)
{
World.AddFrameEndTask(w =>
{
if (Disposed)
return;
World.AddFrameEndTask(_ => ChangeOwnerSync(newOwner));
}
var oldOwner = Owner;
var wasInWorld = IsInWorld;
/// <summary>
/// Change the actors owner without queuing a FrameEndTask.
/// This must only be called from inside an existing FrameEndTask.
/// </summary>
public void ChangeOwnerSync(Player newOwner)
{
if (Disposed)
return;
// momentarily remove from world so the ownership queries don't get confused
if (wasInWorld)
w.Remove(this);
var oldOwner = Owner;
var wasInWorld = IsInWorld;
Owner = newOwner;
Generation++;
// momentarily remove from world so the ownership queries don't get confused
if (wasInWorld)
World.Remove(this);
foreach (var t in TraitsImplementing<INotifyOwnerChanged>())
t.OnOwnerChanged(this, oldOwner, newOwner);
Owner = newOwner;
Generation++;
if (wasInWorld)
w.Add(this);
});
foreach (var t in TraitsImplementing<INotifyOwnerChanged>())
t.OnOwnerChanged(this, oldOwner, newOwner);
foreach (var t in World.WorldActor.TraitsImplementing<INotifyOwnerChanged>())
t.OnOwnerChanged(this, oldOwner, newOwner);
if (wasInWorld)
World.Add(this);
}
public DamageState GetDamageState()
@@ -322,21 +455,12 @@ namespace OpenRA
health.InflictDamage(this, attacker, damage, false);
}
public void Kill(Actor attacker)
public void Kill(Actor attacker, BitSet<DamageType> damageTypes = default(BitSet<DamageType>))
{
if (Disposed || health == null)
return;
health.Kill(this, attacker);
}
public bool IsDisabled()
{
// PERF: Avoid LINQ.
foreach (var disable in disables)
if (disable.Disabled)
return true;
return false;
health.Kill(this, attacker, damageTypes);
}
public bool CanBeViewedByPlayer(Player player)
@@ -349,21 +473,23 @@ namespace OpenRA
return defaultVisibility.IsVisible(this, player);
}
public IEnumerable<string> GetAllTargetTypes()
public BitSet<TargetableType> GetAllTargetTypes()
{
// PERF: Avoid LINQ.
var targetTypes = default(BitSet<TargetableType>);
foreach (var targetable in Targetables)
foreach (var targetType in targetable.TargetTypes)
yield return targetType;
targetTypes = targetTypes.Union(targetable.TargetTypes);
return targetTypes;
}
public IEnumerable<string> GetEnabledTargetTypes()
public BitSet<TargetableType> GetEnabledTargetTypes()
{
// PERF: Avoid LINQ.
var targetTypes = default(BitSet<TargetableType>);
foreach (var targetable in Targetables)
if (targetable.IsTraitEnabled())
foreach (var targetType in targetable.TargetTypes)
yield return targetType;
targetTypes = targetTypes.Union(targetable.TargetTypes);
return targetTypes;
}
public bool IsTargetableBy(Actor byActor)
@@ -376,6 +502,77 @@ namespace OpenRA
return false;
}
public IEnumerable<WPos> GetTargetablePositions()
{
if (staticTargetablePositions != null)
return staticTargetablePositions;
var enabledTargetablePositionTraits = targetablePositions.Where(Exts.IsTraitEnabled);
if (enabledTargetablePositionTraits.Any())
return enabledTargetablePositionTraits.SelectMany(tp => tp.TargetablePositions(this));
return new[] { CenterPosition };
}
#region Conditions
void UpdateConditionState(string condition, int token, bool isRevoke)
{
ConditionState conditionState = conditionStates.GetOrAdd(condition);
if (isRevoke)
conditionState.Tokens.Remove(token);
else
conditionState.Tokens.Add(token);
conditionCache[condition] = conditionState.Tokens.Count;
// Conditions may be granted or revoked before the state is initialized.
// These notifications will be processed after INotifyCreated.Created.
if (created)
foreach (var notify in conditionState.Notifiers)
notify(this, readOnlyConditionCache);
}
/// <summary>
/// Grants a specified condition if it is valid.
/// Otherwise, just returns InvalidConditionToken.
/// </summary>
/// <returns>The token that is used to revoke this condition.</returns>
public int GrantCondition(string condition)
{
if (string.IsNullOrEmpty(condition))
return InvalidConditionToken;
var token = nextConditionToken++;
conditionTokens.Add(token, condition);
UpdateConditionState(condition, token, false);
return token;
}
/// <summary>
/// Revokes a previously granted condition.
/// </summary>
/// <param name="token">The token ID returned by GrantCondition.</param>
/// <returns>The invalid token ID.</returns>
public int RevokeCondition(int token)
{
if (!conditionTokens.TryGetValue(token, out var condition))
throw new InvalidOperationException("Attempting to revoke condition with invalid token {0} for {1}.".F(token, this));
conditionTokens.Remove(token);
UpdateConditionState(condition, token, true);
return InvalidConditionToken;
}
/// <summary>Returns whether the specified token is valid for RevokeCondition</summary>
public bool TokenValid(int token)
{
return conditionTokens.ContainsKey(token);
}
#endregion
#region Scripting interface
Lazy<ScriptActorInterface> luaInterface;
@@ -393,8 +590,7 @@ namespace OpenRA
public LuaValue Equals(LuaRuntime runtime, LuaValue left, LuaValue right)
{
Actor a, b;
if (!left.TryGetClrValue(out a) || !right.TryGetClrValue(out b))
if (!left.TryGetClrValue(out Actor a) || !right.TryGetClrValue(out Actor b))
return false;
return a == b;

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<loadFromRemoteSources enabled="true" />
</runtime>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<loadFromRemoteSources enabled="true" />
</runtime>
</configuration>

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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
@@ -18,11 +18,29 @@ namespace OpenRA
{
public struct CPos : IScriptBindable, ILuaAdditionBinding, ILuaSubtractionBinding, ILuaEqualityBinding, ILuaTableBinding, IEquatable<CPos>
{
public readonly int X, Y;
public readonly byte Layer;
// Coordinates are packed in a 32 bit signed int
// X and Y are 12 bits (signed): -2048...2047
// Layer is an unsigned byte
// Packing is XXXX XXXX XXXX YYYY YYYY YYYY LLLL LLLL
public readonly int Bits;
// X is padded to MSB, so bit shift does the correct sign extension
public int X { get { return Bits >> 20; } }
// Align Y with a short, cast, then shift the rest of the way
// The signed short bit shift does the correct sign extension
public int Y { get { return ((short)(Bits >> 4)) >> 4; } }
public byte Layer { get { return (byte)Bits; } }
public CPos(int bits) { Bits = bits; }
public CPos(int x, int y)
: this(x, y, 0) { }
public CPos(int x, int y, byte layer)
{
Bits = (x & 0xFFF) << 20 | (y & 0xFFF) << 8 | layer;
}
public CPos(int x, int y) { X = x; Y = y; Layer = 0; }
public CPos(int x, int y, byte layer) { X = x; Y = y; Layer = layer; }
public static readonly CPos Zero = new CPos(0, 0, 0);
public static explicit operator CPos(int2 a) { return new CPos(a.X, a.Y); }
@@ -32,12 +50,12 @@ namespace OpenRA
public static CPos operator -(CPos a, CVec b) { return new CPos(a.X - b.X, a.Y - b.Y, a.Layer); }
public static CVec operator -(CPos a, CPos b) { return new CVec(a.X - b.X, a.Y - b.Y); }
public static bool operator ==(CPos me, CPos other) { return me.X == other.X && me.Y == other.Y && me.Layer == other.Layer; }
public static bool operator ==(CPos me, CPos other) { return me.Bits == other.Bits; }
public static bool operator !=(CPos me, CPos other) { return !(me == other); }
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode() ^ Layer.GetHashCode(); }
public override int GetHashCode() { return Bits.GetHashCode(); }
public bool Equals(CPos other) { return X == other.X && Y == other.Y && Layer == other.Layer; }
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; }
@@ -71,9 +89,7 @@ namespace OpenRA
public LuaValue Add(LuaRuntime runtime, LuaValue left, LuaValue right)
{
CPos a;
CVec b;
if (!left.TryGetClrValue(out a) || !right.TryGetClrValue(out b))
if (!left.TryGetClrValue(out CPos a) || !right.TryGetClrValue(out CVec b))
throw new LuaException("Attempted to call CPos.Add(CPos, CVec) with invalid arguments ({0}, {1})".F(left.WrappedClrType().Name, right.WrappedClrType().Name));
return new LuaCustomClrObject(a + b);
@@ -81,21 +97,18 @@ namespace OpenRA
public LuaValue Subtract(LuaRuntime runtime, LuaValue left, LuaValue right)
{
CPos a;
var rightType = right.WrappedClrType();
if (!left.TryGetClrValue(out a))
if (!left.TryGetClrValue(out CPos a))
throw new LuaException("Attempted to call CPos.Subtract(CPos, (CPos|CVec)) with invalid arguments ({0}, {1})".F(left.WrappedClrType().Name, rightType.Name));
if (rightType == typeof(CPos))
{
CPos b;
right.TryGetClrValue(out b);
right.TryGetClrValue(out CPos b);
return new LuaCustomClrObject(a - b);
}
else if (rightType == typeof(CVec))
{
CVec b;
right.TryGetClrValue(out b);
right.TryGetClrValue(out CVec b);
return new LuaCustomClrObject(a - b);
}
@@ -104,8 +117,7 @@ namespace OpenRA
public LuaValue Equals(LuaRuntime runtime, LuaValue left, LuaValue right)
{
CPos a, b;
if (!left.TryGetClrValue(out a) || !right.TryGetClrValue(out b))
if (!left.TryGetClrValue(out CPos a) || !right.TryGetClrValue(out CPos b))
return false;
return a == b;
@@ -132,4 +144,4 @@ namespace OpenRA
#endregion
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,9 +10,9 @@
#endregion
using System;
using System.Drawing;
using Eluant;
using Eluant.ObjectBinding;
using OpenRA.Primitives;
using OpenRA.Scripting;
namespace OpenRA
@@ -75,8 +75,7 @@ namespace OpenRA
public LuaValue Add(LuaRuntime runtime, LuaValue left, LuaValue right)
{
CVec a, b;
if (!left.TryGetClrValue(out a) || !right.TryGetClrValue(out b))
if (!left.TryGetClrValue(out CVec a) || !right.TryGetClrValue(out CVec b))
throw new LuaException("Attempted to call CVec.Add(CVec, CVec) with invalid arguments ({0}, {1})".F(left.WrappedClrType().Name, right.WrappedClrType().Name));
return new LuaCustomClrObject(a + b);
@@ -84,8 +83,7 @@ namespace OpenRA
public LuaValue Subtract(LuaRuntime runtime, LuaValue left, LuaValue right)
{
CVec a, b;
if (!left.TryGetClrValue(out a) || !right.TryGetClrValue(out b))
if (!left.TryGetClrValue(out CVec a) || !right.TryGetClrValue(out CVec b))
throw new LuaException("Attempted to call CVec.Subtract(CVec, CVec) with invalid arguments ({0}, {1})".F(left.WrappedClrType().Name, right.WrappedClrType().Name));
return new LuaCustomClrObject(a - b);
@@ -98,8 +96,7 @@ namespace OpenRA
public LuaValue Equals(LuaRuntime runtime, LuaValue left, LuaValue right)
{
CVec a, b;
if (!left.TryGetClrValue(out a) || !right.TryGetClrValue(out b))
if (!left.TryGetClrValue(out CVec a) || !right.TryGetClrValue(out CVec b))
return false;
return a == b;

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,4 +17,4 @@ namespace OpenRA
void Store(string key, T data);
T Retrieve(string key);
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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.IO;
using System.Linq;
using System.Security.Cryptography;
@@ -18,6 +19,228 @@ namespace OpenRA
{
public static class CryptoUtil
{
// Fixed byte pattern for the OID header
static readonly byte[] OIDHeader = { 0x30, 0xD, 0x6, 0x9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0xD, 0x1, 0x1, 0x1, 0x5, 0x0 };
public static string PublicKeyFingerprint(RSAParameters parameters)
{
// Public key fingerprint is defined as the SHA1 of the modulus + exponent bytes
return SHA1Hash(parameters.Modulus.Append(parameters.Exponent).ToArray());
}
public static string EncodePEMPublicKey(RSAParameters parameters)
{
var data = Convert.ToBase64String(EncodePublicKey(parameters));
var output = new StringBuilder();
output.AppendLine("-----BEGIN PUBLIC KEY-----");
for (var i = 0; i < data.Length; i += 64)
output.AppendLine(data.Substring(i, Math.Min(64, data.Length - i)));
output.Append("-----END PUBLIC KEY-----");
return output.ToString();
}
public static RSAParameters DecodePEMPublicKey(string key)
{
try
{
// Reconstruct original key data
var lines = key.Split('\n');
var data = Convert.FromBase64String(lines.Skip(1).Take(lines.Length - 2).JoinWith(""));
// Pull the modulus and exponent bytes out of the ASN.1 tree
// Expect this to blow up if the key is not correctly formatted
using (var s = new MemoryStream(data))
{
// SEQUENCE
s.ReadByte();
ReadTLVLength(s);
// SEQUENCE -> fixed header junk
s.ReadByte();
var headerLength = ReadTLVLength(s);
s.Position += headerLength;
// SEQUENCE -> BIT_STRING
s.ReadByte();
ReadTLVLength(s);
s.ReadByte();
// SEQUENCE -> BIT_STRING -> SEQUENCE
s.ReadByte();
ReadTLVLength(s);
// SEQUENCE -> BIT_STRING -> SEQUENCE -> INTEGER (modulus)
s.ReadByte();
var modulusLength = ReadTLVLength(s);
s.ReadByte();
var modulus = s.ReadBytes(modulusLength - 1);
// SEQUENCE -> BIT_STRING -> SEQUENCE -> INTEGER (exponent)
s.ReadByte();
var exponentLength = ReadTLVLength(s);
s.ReadByte();
var exponent = s.ReadBytes(exponentLength - 1);
return new RSAParameters
{
Modulus = modulus,
Exponent = exponent
};
}
}
catch (Exception e)
{
throw new InvalidDataException("Invalid PEM public key", e);
}
}
static byte[] EncodePublicKey(RSAParameters parameters)
{
using (var stream = new MemoryStream())
{
var writer = new BinaryWriter(stream);
var modExpLength = TripletFullLength(parameters.Modulus.Length + 1) + TripletFullLength(parameters.Exponent.Length + 1);
var bitStringLength = TripletFullLength(modExpLength + 1);
var sequenceLength = TripletFullLength(bitStringLength + OIDHeader.Length);
// SEQUENCE
writer.Write((byte)0x30);
WriteTLVLength(writer, sequenceLength);
// SEQUENCE -> fixed header junk
writer.Write(OIDHeader);
// SEQUENCE -> BIT_STRING
writer.Write((byte)0x03);
WriteTLVLength(writer, bitStringLength);
writer.Write((byte)0x00);
// SEQUENCE -> BIT_STRING -> SEQUENCE
writer.Write((byte)0x30);
WriteTLVLength(writer, modExpLength);
// SEQUENCE -> BIT_STRING -> SEQUENCE -> INTEGER
// Modulus is padded with a zero to avoid issues with the sign bit
writer.Write((byte)0x02);
WriteTLVLength(writer, parameters.Modulus.Length + 1);
writer.Write((byte)0);
writer.Write(parameters.Modulus);
// SEQUENCE -> BIT_STRING -> SEQUENCE -> INTEGER
// Exponent is padded with a zero to avoid issues with the sign bit
writer.Write((byte)0x02);
WriteTLVLength(writer, parameters.Exponent.Length + 1);
writer.Write((byte)0);
writer.Write(parameters.Exponent);
return stream.ToArray();
}
}
static void WriteTLVLength(BinaryWriter writer, int length)
{
if (length < 0x80)
{
// Length < 128 is stored in a single byte
writer.Write((byte)length);
}
else
{
// If 128 <= length < 256**128 first byte encodes number of bytes required to hold the length
// High-bit is set as a flag to use this long-form encoding
var lengthBytes = BitConverter.GetBytes(length).Reverse().SkipWhile(b => b == 0).ToArray();
writer.Write((byte)(0x80 | lengthBytes.Length));
writer.Write(lengthBytes);
}
}
static int ReadTLVLength(Stream s)
{
var length = s.ReadByte();
if (length < 0x80)
return length;
var data = new byte[4];
s.ReadBytes(data, 0, Math.Min(length & 0x7F, 4));
return BitConverter.ToInt32(data.ToArray(), 0);
}
static int TripletFullLength(int dataLength)
{
if (dataLength < 0x80)
return 2 + dataLength;
return 2 + dataLength + BitConverter.GetBytes(dataLength).Reverse().SkipWhile(b => b == 0).Count();
}
public static string DecryptString(RSAParameters parameters, string data)
{
try
{
using (var rsa = new RSACryptoServiceProvider())
{
rsa.ImportParameters(parameters);
return Encoding.UTF8.GetString(rsa.Decrypt(Convert.FromBase64String(data), false));
}
}
catch (Exception e)
{
Log.Write("debug", "Failed to decrypt string with exception: {0}", e);
Console.WriteLine("String decryption failed: {0}", e);
return null;
}
}
public static string Sign(RSAParameters parameters, string data)
{
return Sign(parameters, Encoding.UTF8.GetBytes(data));
}
public static string Sign(RSAParameters parameters, byte[] data)
{
try
{
using (var rsa = new RSACryptoServiceProvider())
{
rsa.ImportParameters(parameters);
using (var csp = SHA1.Create())
return Convert.ToBase64String(rsa.SignHash(csp.ComputeHash(data), CryptoConfig.MapNameToOID("SHA1")));
}
}
catch (Exception e)
{
Log.Write("debug", "Failed to sign string with exception: {0}", e);
Console.WriteLine("String signing failed: {0}", e);
return null;
}
}
public static bool VerifySignature(RSAParameters parameters, string data, string signature)
{
return VerifySignature(parameters, Encoding.UTF8.GetBytes(data), signature);
}
public static bool VerifySignature(RSAParameters parameters, byte[] data, string signature)
{
try
{
using (var rsa = new RSACryptoServiceProvider())
{
rsa.ImportParameters(parameters);
using (var csp = SHA1.Create())
return rsa.VerifyHash(csp.ComputeHash(data), CryptoConfig.MapNameToOID("SHA1"), Convert.FromBase64String(signature));
}
}
catch (Exception e)
{
Log.Write("debug", "Failed to verify signature with exception: {0}", e);
Console.WriteLine("Signature validation failed: {0}", e);
return false;
}
}
public static string SHA1Hash(Stream data)
{
using (var csp = SHA1.Create())

View File

@@ -0,0 +1,20 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 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
using OpenRA.Primitives;
namespace OpenRA
{
public class DefaultPlayer : IGlobalModData
{
public readonly Color Color = Color.FromAhsl(0, 0, 238);
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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
@@ -43,8 +43,19 @@ namespace OpenRA
}
}
void EnableTLS12OnWindows()
{
// Enable TLS 1.2 on Windows: .NET 4.7 on Windows 10 only supports obsolete protocols by default
// SecurityProtocolType.Tls12 is not defined in the .NET 4.5 reference dlls used by mono,
// so we must use the enum's constant value directly
if (Platform.CurrentPlatform == PlatformType.Windows)
ServicePointManager.SecurityProtocol |= (SecurityProtocolType)3072;
}
public Download(string url, string path, Action<DownloadProgressChangedEventArgs> onProgress, Action<AsyncCompletedEventArgs> onComplete)
{
EnableTLS12OnWindows();
lock (syncObject)
{
wc = new WebClient { Proxy = null };
@@ -56,6 +67,8 @@ namespace OpenRA
public Download(string url, Action<DownloadProgressChangedEventArgs> onProgress, Action<DownloadDataCompletedEventArgs> onComplete)
{
EnableTLS12OnWindows();
lock (syncObject)
{
wc = new WebClient { Proxy = null };
@@ -77,8 +90,7 @@ namespace OpenRA
public void CancelAsync()
{
lock (syncObject)
if (wc != null)
wc.CancelAsync();
wc?.CancelAsync();
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,8 +9,8 @@
*/
#endregion
using System;
using System.Collections.Generic;
using OpenRA.GameRules;
using OpenRA.Graphics;
using OpenRA.Traits;
@@ -19,28 +19,25 @@ namespace OpenRA.Effects
public class DelayedImpact : IEffect
{
readonly Target target;
readonly Actor firedBy;
readonly IEnumerable<int> damageModifiers;
readonly IWarhead wh;
readonly WarheadArgs args;
int delay;
public DelayedImpact(int delay, IWarhead wh, Target target, Actor firedBy, IEnumerable<int> damageModifiers)
public DelayedImpact(int delay, IWarhead wh, Target target, WarheadArgs args)
{
this.wh = wh;
this.delay = delay;
this.target = target;
this.firedBy = firedBy;
this.damageModifiers = damageModifiers;
this.args = args;
}
public void Tick(World world)
{
if (--delay <= 0)
world.AddFrameEndTask(w => { w.Remove(this); wh.DoImpact(target, firedBy, damageModifiers); });
world.AddFrameEndTask(w => { w.Remove(this); wh.DoImpact(target, args); });
}
public IEnumerable<IRenderable> Render(WorldRenderer wr) { yield break; }
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,5 +20,9 @@ namespace OpenRA.Effects
IEnumerable<IRenderable> Render(WorldRenderer r);
}
// Identifier interface for effects that are added to ScreenMap
public interface ISpatiallyPartitionable { }
public interface IEffectAboveShroud { IEnumerable<IRenderable> RenderAboveShroud(WorldRenderer wr); }
public interface IEffectAnnotation { IEnumerable<IRenderable> RenderAnnotation(WorldRenderer wr); }
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,14 +12,17 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Primitives;
namespace OpenRA
{
[Flags]
enum ModRegistration { User = 1, System = 2 }
public class ExternalMod
{
public readonly string Id;
@@ -28,6 +31,8 @@ namespace OpenRA
public readonly string LaunchPath;
public readonly string[] LaunchArgs;
public Sprite Icon { get; internal set; }
public Sprite Icon2x { get; internal set; }
public Sprite Icon3x { get; internal set; }
public static string MakeKey(Manifest mod) { return MakeKey(mod.Id, mod.Metadata.Version); }
public static string MakeKey(ExternalMod mod) { return MakeKey(mod.Id, mod.Version); }
@@ -38,110 +43,209 @@ namespace OpenRA
{
readonly Dictionary<string, ExternalMod> mods = new Dictionary<string, ExternalMod>();
readonly SheetBuilder sheetBuilder;
readonly string launchPath;
public ExternalMods(string launchPath)
Sheet CreateSheet()
{
// Process.Start requires paths to not be quoted, even if they contain spaces
if (launchPath.First() == '"' && launchPath.Last() == '"')
launchPath = launchPath.Substring(1, launchPath.Length - 2);
var sheet = new Sheet(SheetType.BGRA, new Size(512, 512));
this.launchPath = launchPath;
sheetBuilder = new SheetBuilder(SheetType.BGRA, 256);
// We must manually force the buffer creation to avoid a crash
// that is indirectly triggered by rendering from a Sheet that
// has not yet been written to.
sheet.CreateBuffer();
sheet.GetTexture().ScaleFilter = TextureScaleFilter.Linear;
// Load registered mods
var supportPath = Platform.ResolvePath(Path.Combine("^", "ModMetadata"));
if (!Directory.Exists(supportPath))
return sheet;
}
public ExternalMods()
{
// Don't try to load mod icons if we don't have a texture to put them in
if (Game.Renderer != null)
sheetBuilder = new SheetBuilder(SheetType.BGRA, CreateSheet);
// 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)
{
var metadataPath = Path.Combine(source, "ModMetadata");
if (!Directory.Exists(metadataPath))
continue;
foreach (var path in Directory.GetFiles(metadataPath, "*.yaml"))
{
try
{
var yaml = MiniYaml.FromStream(File.OpenRead(path), path).First().Value;
LoadMod(yaml, path);
}
catch (Exception e)
{
Log.Write("debug", "Failed to parse mod metadata file '{0}'", path);
Log.Write("debug", e.ToString());
}
}
}
}
void LoadMod(MiniYaml yaml, string path = null, bool forceRegistration = false)
{
var mod = FieldLoader.Load<ExternalMod>(yaml);
if (sheetBuilder != null)
{
var iconNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Icon");
if (iconNode != null && !string.IsNullOrEmpty(iconNode.Value.Value))
using (var stream = new MemoryStream(Convert.FromBase64String(iconNode.Value.Value)))
mod.Icon = sheetBuilder.Add(new Png(stream));
var icon2xNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Icon2x");
if (icon2xNode != null && !string.IsNullOrEmpty(icon2xNode.Value.Value))
using (var stream = new MemoryStream(Convert.FromBase64String(icon2xNode.Value.Value)))
mod.Icon2x = sheetBuilder.Add(new Png(stream), 1f / 2);
var icon3xNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Icon3x");
if (icon3xNode != null && !string.IsNullOrEmpty(icon3xNode.Value.Value))
using (var stream = new MemoryStream(Convert.FromBase64String(icon3xNode.Value.Value)))
mod.Icon3x = sheetBuilder.Add(new Png(stream), 1f / 3);
}
// Avoid possibly overwriting a valid mod with an obviously bogus one
var key = ExternalMod.MakeKey(mod);
if ((forceRegistration || File.Exists(mod.LaunchPath)) && (path == null || Path.GetFileNameWithoutExtension(path) == key))
mods[key] = mod;
}
internal void Register(Manifest mod, string launchPath, ModRegistration registration)
{
if (mod.Metadata.Hidden)
return;
foreach (var path in Directory.GetFiles(supportPath, "*.yaml"))
var key = ExternalMod.MakeKey(mod);
var yaml = new MiniYamlNode("Registration", new MiniYaml("", new List<MiniYamlNode>()
{
new MiniYamlNode("Id", mod.Id),
new MiniYamlNode("Version", mod.Metadata.Version),
new MiniYamlNode("Title", mod.Metadata.Title),
new MiniYamlNode("LaunchPath", launchPath),
new MiniYamlNode("LaunchArgs", "Game.Mod=" + mod.Id)
}));
using (var stream = mod.Package.GetStream("icon.png"))
if (stream != null)
yaml.Value.Nodes.Add(new MiniYamlNode("Icon", Convert.ToBase64String(stream.ReadAllBytes())));
using (var stream = mod.Package.GetStream("icon-2x.png"))
if (stream != null)
yaml.Value.Nodes.Add(new MiniYamlNode("Icon2x", Convert.ToBase64String(stream.ReadAllBytes())));
using (var stream = mod.Package.GetStream("icon-3x.png"))
if (stream != null)
yaml.Value.Nodes.Add(new MiniYamlNode("Icon3x", Convert.ToBase64String(stream.ReadAllBytes())));
var sources = new List<string>();
if (registration.HasFlag(ModRegistration.System))
sources.Add(Platform.GetSupportDir(SupportDirType.System));
if (registration.HasFlag(ModRegistration.User))
{
sources.Add(Platform.GetSupportDir(SupportDirType.User));
// If using the modern support dir we must also write the registration
// to the legacy support dir for older engine versions, but ONLY if it exists
var legacyPath = Platform.GetSupportDir(SupportDirType.LegacyUser);
if (Directory.Exists(legacyPath))
sources.Add(legacyPath);
}
// Make sure the mod is available for this session, even if saving it fails
LoadMod(yaml.Value, forceRegistration: true);
var lines = new List<MiniYamlNode> { yaml }.ToLines().ToArray();
foreach (var source in sources.Distinct())
{
var metadataPath = Path.Combine(source, "ModMetadata");
try
{
var yaml = MiniYaml.FromStream(File.OpenRead(path), path).First().Value;
LoadMod(yaml);
Directory.CreateDirectory(metadataPath);
File.WriteAllLines(Path.Combine(metadataPath, key + ".yaml"), lines);
}
catch (Exception e)
{
Log.Write("debug", "Failed to parse mod metadata file '{0}'", path);
Log.Write("debug", "Failed to register current mod metadata");
Log.Write("debug", e.ToString());
}
}
}
void LoadMod(MiniYaml yaml)
/// <summary>
/// Removes invalid mod registrations:
/// * LaunchPath no longer exists
/// * LaunchPath and mod id matches the active mod, but the version is different
/// * Filename doesn't match internal key
/// * Fails to parse as a mod registration
/// </summary>
internal void ClearInvalidRegistrations(ExternalMod activeMod, ModRegistration registration)
{
var mod = FieldLoader.Load<ExternalMod>(yaml);
var iconNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Icon");
if (iconNode != null && !string.IsNullOrEmpty(iconNode.Value.Value))
var sources = new List<string>();
if (registration.HasFlag(ModRegistration.System))
sources.Add(Platform.GetSupportDir(SupportDirType.System));
if (registration.HasFlag(ModRegistration.User))
{
using (var stream = new MemoryStream(Convert.FromBase64String(iconNode.Value.Value)))
using (var bitmap = new Bitmap(stream))
mod.Icon = sheetBuilder.Add(bitmap);
// 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));
}
mods.Add(ExternalMod.MakeKey(mod), mod);
}
internal void Register(Manifest mod)
{
if (mod.Metadata.Hidden)
return;
var iconData = "";
using (var stream = mod.Package.GetStream("icon.png"))
if (stream != null)
iconData = Convert.ToBase64String(stream.ReadAllBytes());
var key = ExternalMod.MakeKey(mod);
var yaml = new List<MiniYamlNode>()
var activeModKey = ExternalMod.MakeKey(activeMod);
foreach (var source in sources.Distinct())
{
new MiniYamlNode("Registration", new MiniYaml("", new List<MiniYamlNode>()
var metadataPath = Path.Combine(source, "ModMetadata");
if (!Directory.Exists(metadataPath))
continue;
foreach (var path in Directory.GetFiles(metadataPath, "*.yaml"))
{
new MiniYamlNode("Id", mod.Id),
new MiniYamlNode("Version", mod.Metadata.Version),
new MiniYamlNode("Title", mod.Metadata.Title),
new MiniYamlNode("Icon", iconData),
new MiniYamlNode("LaunchPath", launchPath),
new MiniYamlNode("LaunchArgs", "Game.Mod=" + mod.Id)
}))
};
string modKey = null;
try
{
var yaml = MiniYaml.FromStream(File.OpenRead(path), path).First().Value;
var m = FieldLoader.Load<ExternalMod>(yaml);
modKey = ExternalMod.MakeKey(m);
var supportPath = Platform.ResolvePath(Path.Combine("^", "ModMetadata"));
// Continue to the next entry if it is the active mod (even if the LaunchPath is bogus)
if (modKey == activeModKey)
continue;
try
{
// Make sure the mod is available for this session, even if saving it fails
LoadMod(yaml.First().Value);
// 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))
continue;
}
catch (Exception e)
{
Log.Write("debug", "Failed to parse mod metadata file '{0}'", path);
Log.Write("debug", e.ToString());
}
Directory.CreateDirectory(supportPath);
File.WriteAllLines(Path.Combine(supportPath, key + ".yaml"), yaml.ToLines(false).ToArray());
}
catch (Exception e)
{
Log.Write("debug", "Failed to register currrent mod metadata");
Log.Write("debug", e.ToString());
}
// Remove from the ingame mod switcher
if (Path.GetFileNameWithoutExtension(path) == modKey)
mods.Remove(modKey);
// Clean up stale mod registrations:
// - LaunchPath no longer exists (uninstalled)
// - LaunchPath and mod match the current mod, but version differs (newer version installed on top)
List<string> toRemove = null;
foreach (var kv in mods)
{
var k = kv.Key;
var m = kv.Value;
if (!File.Exists(m.LaunchPath) || (m.LaunchPath == launchPath && m.Id == mod.Id && k != key))
{
Log.Write("debug", "Removing stale mod metadata entry '{0}'", k);
if (toRemove == null)
toRemove = new List<string>();
toRemove.Add(k);
var path = Path.Combine(supportPath, k + ".yaml");
// Remove stale or corrupted metadata
try
{
File.Delete(path);
Log.Write("debug", "Removed invalid mod metadata file '{0}'", path);
}
catch (Exception e)
{
@@ -150,10 +254,40 @@ namespace OpenRA
}
}
}
}
if (toRemove != null)
foreach (var r in toRemove)
mods.Remove(r);
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())
{
var path = Path.Combine(source, "ModMetadata", key + ".yaml");
try
{
if (File.Exists(path))
File.Delete(path);
}
catch (Exception e)
{
Log.Write("debug", "Failed to remove mod metadata file '{0}'", path);
Log.Write("debug", e.ToString());
}
}
}
public ExternalMod this[string key] { get { return mods[key]; } }

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,11 +11,10 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.Linq;
using System.Reflection;
using OpenRA.Primitives;
using OpenRA.Support;
using OpenRA.Traits;
@@ -79,19 +78,9 @@ namespace OpenRA
return val;
}
public static bool Contains(this Rectangle r, int2 p)
{
return r.Contains(p.ToPoint());
}
public static bool Contains(this RectangleF r, int2 p)
{
return r.Contains(p.ToPointF());
}
static int WindingDirectionTest(int2 v0, int2 v1, int2 p)
{
return (v1.X - v0.X) * (p.Y - v0.Y) - (p.X - v0.X) * (v1.Y - v0.Y);
return Math.Sign((v1.X - v0.X) * (p.Y - v0.Y) - (p.X - v0.X) * (v1.Y - v0.Y));
}
public static bool PolygonContains(this int2[] polygon, int2 p)
@@ -112,6 +101,16 @@ namespace OpenRA
return windingNumber != 0;
}
public static bool LinesIntersect(int2 a, int2 b, int2 c, int2 d)
{
// If line segments AB and CD intersect:
// - 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
return WindingDirectionTest(c, d, a) != WindingDirectionTest(c, d, b) && WindingDirectionTest(a, b, c) != WindingDirectionTest(a, b, d);
}
public static bool HasModifier(this Modifiers k, Modifiers mod)
{
// PERF: Enum.HasFlag is slower and requires allocations.
@@ -126,8 +125,7 @@ namespace OpenRA
public static V GetOrAdd<K, V>(this Dictionary<K, V> d, K k, Func<K, V> createFn)
{
V ret;
if (!d.TryGetValue(k, out ret))
if (!d.TryGetValue(k, out var ret))
d.Add(k, ret = createFn(k));
return ret;
}
@@ -162,6 +160,26 @@ namespace OpenRA
return xs.ElementAt(r.Next(xs.Count));
}
public static Rectangle Union(this IEnumerable<Rectangle> rects)
{
// PERF: Avoid LINQ.
var first = true;
var result = Rectangle.Empty;
foreach (var rect in rects)
{
if (first)
{
first = false;
result = rect;
continue;
}
result = Rectangle.Union(rect, result);
}
return result;
}
public static float Product(this IEnumerable<float> xs)
{
return xs.Aggregate(1f, (a, x) => a * x);
@@ -175,7 +193,11 @@ namespace OpenRA
public static IEnumerable<T> Iterate<T>(this T t, Func<T, T> f)
{
for (;;) { yield return t; t = f(t); }
while (true)
{
yield return t;
t = f(t);
}
}
public static T MinBy<T, U>(this IEnumerable<T> ts, Func<T, U> selector)
@@ -330,8 +352,7 @@ namespace OpenRA
public static int IntegerDivisionRoundingAwayFromZero(int dividend, int divisor)
{
int remainder;
var quotient = Math.DivRem(dividend, divisor, out remainder);
var quotient = Math.DivRem(dividend, divisor, out var remainder);
if (remainder == 0)
return quotient;
return quotient + (Math.Sign(dividend) == Math.Sign(divisor) ? 1 : -1);
@@ -375,11 +396,14 @@ namespace OpenRA
var key = keySelector(item);
var element = elementSelector(item);
// Discard elements with null keys
if (!typeof(TKey).IsValueType && key == null)
continue;
// Check for a key conflict:
if (d.ContainsKey(key))
{
List<string> dupKeyMessages;
if (!dupKeys.TryGetValue(key, out dupKeyMessages))
if (!dupKeys.TryGetValue(key, out var dupKeyMessages))
{
// Log the initial conflicting value already inserted:
dupKeyMessages = new List<string>();
@@ -444,27 +468,6 @@ namespace OpenRA
return result;
}
public static Rectangle Bounds(this Bitmap b) { return new Rectangle(0, 0, b.Width, b.Height); }
public static Bitmap CloneWith32bbpArgbPixelFormat(this Bitmap original)
{
// Note: We would use original.Clone(original.Bounds(), PixelFormat.Format32bppArgb)
// but this doesn't work on mono.
var clone = new Bitmap(original.Width, original.Height, PixelFormat.Format32bppArgb);
try
{
using (var g = System.Drawing.Graphics.FromImage(clone))
g.DrawImage(original, original.Bounds());
}
catch (Exception)
{
clone.Dispose();
throw;
}
return clone;
}
public static int ToBits(this IEnumerable<bool> bits)
{
var i = 0;
@@ -484,6 +487,11 @@ namespace OpenRA
return int.Parse(s, NumberStyles.Integer, NumberFormatInfo.InvariantInfo);
}
public static byte ParseByte(string s)
{
return byte.Parse(s, NumberStyles.Integer, NumberFormatInfo.InvariantInfo);
}
public static bool TryParseIntegerInvariant(string s, out int i)
{
return int.TryParse(s, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out i);
@@ -494,14 +502,30 @@ namespace OpenRA
return long.TryParse(s, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out i);
}
public static bool IsTraitEnabled(this object trait)
public static bool IsTraitEnabled<T>(this T trait)
{
return trait as IDisabledTrait == null || !(trait as IDisabledTrait).IsTraitDisabled;
var disabledTrait = trait as IDisabledTrait;
return disabledTrait == null || !disabledTrait.IsTraitDisabled;
}
public static bool IsTraitEnabled<T>(T t)
public static T FirstEnabledTraitOrDefault<T>(this IEnumerable<T> ts)
{
return IsTraitEnabled(t as object);
// PERF: Avoid LINQ.
foreach (var t in ts)
if (t.IsTraitEnabled())
return t;
return default(T);
}
public static T FirstEnabledTraitOrDefault<T>(this T[] ts)
{
// PERF: Avoid LINQ.
foreach (var t in ts)
if (t.IsTraitEnabled())
return t;
return default(T);
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,15 +12,12 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using OpenRA.Graphics;
using OpenRA.Primitives;
using OpenRA.Support;
@@ -42,7 +39,8 @@ namespace OpenRA
}
}
public MissingFieldsException(string[] missing, string header = null, string headerSingle = null) : base(null)
public MissingFieldsException(string[] missing, string header = null, string headerSingle = null)
: base(null)
{
Header = missing.Length > 1 ? header : headerSingle ?? header;
Missing = missing;
@@ -71,6 +69,11 @@ namespace OpenRA
static readonly ConcurrentCache<MemberInfo, bool> MemberHasTranslateAttribute =
new ConcurrentCache<MemberInfo, bool>(member => member.HasAttribute<TranslateAttribute>());
static readonly ConcurrentCache<string, BooleanExpression> BooleanExpressionCache =
new ConcurrentCache<string, BooleanExpression>(expression => new BooleanExpression(expression));
static readonly ConcurrentCache<string, IntegerExpression> IntegerExpressionCache =
new ConcurrentCache<string, IntegerExpression>(expression => new IntegerExpression(expression));
static readonly object TranslationsLock = new object();
static Dictionary<string, string> translations;
@@ -118,8 +121,7 @@ namespace OpenRA
{
ret = null;
MiniYaml yaml;
if (!md.TryGetValue(yamlName, out yaml))
if (!md.TryGetValue(yamlName, out var yaml))
return false;
ret = GetValue(field.Name, field.FieldType, yaml, field);
@@ -177,42 +179,36 @@ namespace OpenRA
public static object GetValue(string fieldName, Type fieldType, MiniYaml yaml, MemberInfo field)
{
var value = yaml.Value;
if (value != null) value = value.Trim();
var value = yaml.Value?.Trim();
if (fieldType == typeof(int))
{
int res;
if (Exts.TryParseIntegerInvariant(value, out res))
if (Exts.TryParseIntegerInvariant(value, out var res))
return res;
return InvalidValueAction(value, fieldType, fieldName);
}
else if (fieldType == typeof(ushort))
{
ushort res;
if (ushort.TryParse(value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out res))
if (ushort.TryParse(value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out var res))
return res;
return InvalidValueAction(value, fieldType, fieldName);
}
if (fieldType == typeof(long))
{
long res;
if (long.TryParse(value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out res))
if (long.TryParse(value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out var res))
return res;
return InvalidValueAction(value, fieldType, fieldName);
}
else if (fieldType == typeof(float))
{
float res;
if (value != null && float.TryParse(value.Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res))
if (value != null && float.TryParse(value.Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out var res))
return res * (value.Contains('%') ? 0.01f : 1f);
return InvalidValueAction(value, fieldType, fieldName);
}
else if (fieldType == typeof(decimal))
{
decimal res;
if (value != null && decimal.TryParse(value.Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res))
if (value != null && decimal.TryParse(value.Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out var res))
return res * (value.Contains('%') ? 0.01m : 1m);
return InvalidValueAction(value, fieldType, fieldName);
}
@@ -224,59 +220,25 @@ namespace OpenRA
}
else if (fieldType == typeof(Color))
{
Color color;
if (value != null && HSLColor.TryParseRGB(value, out color))
if (value != null && Color.TryParse(value, out var color))
return color;
return InvalidValueAction(value, fieldType, fieldName);
}
else if (fieldType == typeof(Color[]))
{
if (value != null)
{
var parts = value.Split(',');
var colors = new Color[parts.Length];
for (var i = 0; i < colors.Length; i++)
if (!HSLColor.TryParseRGB(parts[i], out colors[i]))
return InvalidValueAction(value, fieldType, fieldName);
return colors;
}
return InvalidValueAction(value, fieldType, fieldName);
}
else if (fieldType == typeof(HSLColor))
{
if (value != null)
{
Color rgb;
if (HSLColor.TryParseRGB(value, out rgb))
return new HSLColor(rgb);
// Allow old HSLColor/ColorRamp formats to be parsed as HSLColor
var parts = value.Split(',');
if (parts.Length == 3 || parts.Length == 4)
return new HSLColor(
(byte)Exts.ParseIntegerInvariant(parts[0]).Clamp(0, 255),
(byte)Exts.ParseIntegerInvariant(parts[1]).Clamp(0, 255),
(byte)Exts.ParseIntegerInvariant(parts[2]).Clamp(0, 255));
}
return InvalidValueAction(value, fieldType, fieldName);
}
else if (fieldType == typeof(Hotkey))
{
Hotkey res;
if (Hotkey.TryParse(value, out res))
if (Hotkey.TryParse(value, out var res))
return res;
return InvalidValueAction(value, fieldType, fieldName);
}
else if (fieldType == typeof(HotkeyReference))
{
return Game.ModData.Hotkeys[value];
}
else if (fieldType == typeof(WDist))
{
WDist res;
if (WDist.TryParse(value, out res))
if (WDist.TryParse(value, out var res))
return res;
return InvalidValueAction(value, fieldType, fieldName);
@@ -288,8 +250,7 @@ namespace OpenRA
var parts = value.Split(',');
if (parts.Length == 3)
{
WDist rx, ry, rz;
if (WDist.TryParse(parts[0], out rx) && WDist.TryParse(parts[1], out ry) && WDist.TryParse(parts[2], out rz))
if (WDist.TryParse(parts[0], out var rx) && WDist.TryParse(parts[1], out var ry) && WDist.TryParse(parts[2], out var rz))
return new WVec(rx, ry, rz);
}
}
@@ -309,8 +270,7 @@ namespace OpenRA
for (var i = 0; i < vecs.Length; ++i)
{
WDist rx, ry, rz;
if (WDist.TryParse(parts[3 * i], out rx) && WDist.TryParse(parts[3 * i + 1], out ry) && WDist.TryParse(parts[3 * i + 2], out rz))
if (WDist.TryParse(parts[3 * i], out var rx) && WDist.TryParse(parts[3 * i + 1], out var ry) && WDist.TryParse(parts[3 * i + 2], out var rz))
vecs[i] = new WVec(rx, ry, rz);
}
@@ -326,8 +286,7 @@ namespace OpenRA
var parts = value.Split(',');
if (parts.Length == 3)
{
WDist rx, ry, rz;
if (WDist.TryParse(parts[0], out rx) && WDist.TryParse(parts[1], out ry) && WDist.TryParse(parts[2], out rz))
if (WDist.TryParse(parts[0], out var rx) && WDist.TryParse(parts[1], out var ry) && WDist.TryParse(parts[2], out var rz))
return new WPos(rx, ry, rz);
}
}
@@ -336,8 +295,7 @@ namespace OpenRA
}
else if (fieldType == typeof(WAngle))
{
int res;
if (Exts.TryParseIntegerInvariant(value, out res))
if (Exts.TryParseIntegerInvariant(value, out var res))
return new WAngle(res);
return InvalidValueAction(value, fieldType, fieldName);
}
@@ -348,8 +306,7 @@ namespace OpenRA
var parts = value.Split(',');
if (parts.Length == 3)
{
int rr, rp, ry;
if (Exts.TryParseIntegerInvariant(value, out rr) && Exts.TryParseIntegerInvariant(value, out rp) && Exts.TryParseIntegerInvariant(value, out ry))
if (Exts.TryParseIntegerInvariant(parts[0], out var rr) && Exts.TryParseIntegerInvariant(parts[1], out var rp) && Exts.TryParseIntegerInvariant(parts[2], out var ry))
return new WRot(new WAngle(rr), new WAngle(rp), new WAngle(ry));
}
}
@@ -388,8 +345,7 @@ namespace OpenRA
var vecs = new CVec[parts.Length / 2];
for (var i = 0; i < vecs.Length; i++)
{
int rx, ry;
if (int.TryParse(parts[2 * i], out rx) && int.TryParse(parts[2 * i + 1], out ry))
if (int.TryParse(parts[2 * i], out var rx) && int.TryParse(parts[2 * i + 1], out var ry))
vecs[i] = new CVec(rx, ry);
}
@@ -398,13 +354,29 @@ namespace OpenRA
return InvalidValueAction(value, fieldType, fieldName);
}
else if (fieldType == typeof(ConditionExpression))
else if (fieldType == typeof(BooleanExpression))
{
if (value != null)
{
try
{
return new ConditionExpression(value);
return BooleanExpressionCache[value];
}
catch (InvalidDataException e)
{
throw new YamlException(e.Message);
}
}
return InvalidValueAction(value, fieldType, fieldName);
}
else if (fieldType == typeof(IntegerExpression))
{
if (value != null)
{
try
{
return IntegerExpressionCache[value];
}
catch (InvalidDataException e)
{
@@ -425,31 +397,30 @@ namespace OpenRA
return InvalidValueAction(value, fieldType, fieldName);
}
}
else if (fieldType == typeof(ImageFormat))
else if (fieldType == typeof(bool))
{
if (bool.TryParse(value.ToLowerInvariant(), out var result))
return result;
return InvalidValueAction(value, fieldType, fieldName);
}
else if (fieldType == typeof(int2[]))
{
if (value != null)
{
switch (value.ToLowerInvariant())
{
case "bmp":
return ImageFormat.Bmp;
case "gif":
return ImageFormat.Gif;
case "jpg":
case "jpeg":
return ImageFormat.Jpeg;
case "tif":
case "tiff":
return ImageFormat.Tiff;
default:
return ImageFormat.Png;
}
var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length % 2 != 0)
return InvalidValueAction(value, fieldType, fieldName);
var ints = new int2[parts.Length / 2];
for (var i = 0; i < ints.Length; i++)
ints[i] = new int2(Exts.ParseIntegerInvariant(parts[2 * i]), Exts.ParseIntegerInvariant(parts[2 * i + 1]));
return ints;
}
return InvalidValueAction(value, fieldType, fieldName);
}
else if (fieldType == typeof(bool))
return ParseYesNo(value, fieldType, fieldName);
else if (fieldType.IsArray && fieldType.GetArrayRank() == 1)
{
if (value == null)
@@ -506,6 +477,9 @@ namespace OpenRA
if (value != null)
{
var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length != 2)
return InvalidValueAction(value, fieldType, fieldName);
return new int2(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]));
}
@@ -518,8 +492,7 @@ namespace OpenRA
var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
float xx = 0;
float yy = 0;
float res;
if (float.TryParse(parts[0].Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res))
if (float.TryParse(parts[0].Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out var res))
xx = res * (parts[0].Contains('%') ? 0.01f : 1f);
if (float.TryParse(parts[1].Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res))
yy = res * (parts[1].Contains('%') ? 0.01f : 1f);
@@ -533,13 +506,11 @@ namespace OpenRA
if (value != null)
{
var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
float x = 0;
float y = 0;
float z = 0;
float.TryParse(parts[0], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out x);
float.TryParse(parts[1], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out y);
float.TryParse(parts[0], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out var x);
float.TryParse(parts[1], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out var y);
// z component is optional for compatibility with older float2 definitions
float z = 0;
if (parts.Length > 2)
float.TryParse(parts[2], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out z);
@@ -562,28 +533,29 @@ namespace OpenRA
return InvalidValueAction(value, fieldType, fieldName);
}
else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Bits<>))
else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(BitSet<>))
{
if (value != null)
{
var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
var argTypes = new Type[] { typeof(string[]) };
var argValues = new object[] { parts };
return fieldType.GetConstructor(argTypes).Invoke(argValues);
var ctor = fieldType.GetConstructor(new[] { typeof(string[]) });
return ctor.Invoke(new object[] { parts.Select(p => p.Trim()).ToArray() });
}
return InvalidValueAction(value, fieldType, fieldName);
}
else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
if (string.IsNullOrEmpty(value))
return null;
var innerType = fieldType.GetGenericArguments().First();
var innerValue = GetValue("Nullable<T>", innerType, value, field);
return fieldType.GetConstructor(new[] { innerType }).Invoke(new[] { innerValue });
}
else if (fieldType == typeof(DateTime))
{
DateTime dt;
if (DateTime.TryParseExact(value, "yyyy-MM-dd HH-mm-ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out dt))
if (DateTime.TryParseExact(value, "yyyy-MM-dd HH-mm-ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out var dt))
return dt;
return InvalidValueAction(value, fieldType, fieldName);
}
@@ -607,20 +579,6 @@ namespace OpenRA
return null;
}
static object ParseYesNo(string p, Type fieldType, string field)
{
if (string.IsNullOrEmpty(p))
return InvalidValueAction(p, fieldType, field);
p = p.ToLowerInvariant();
if (p == "yes") return true;
if (p == "true") return true;
if (p == "no") return false;
if (p == "false") return false;
return InvalidValueAction(p, fieldType, field);
}
public sealed class FieldLoadInfo
{
public readonly FieldInfo Field;
@@ -747,8 +705,7 @@ namespace OpenRA
if (translations == null)
return key;
string value;
if (!translations.TryGetValue(key, out value))
if (!translations.TryGetValue(key, out var value))
return key;
return value;

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,12 +12,10 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.Linq;
using System.Reflection;
using OpenRA.Graphics;
using OpenRA.Primitives;
namespace OpenRA
{
@@ -75,21 +73,9 @@ namespace OpenRA
var t = v.GetType();
// Color.ToString() does the wrong thing; force it to format as rgb[a] hex
if (t == typeof(Color))
{
return HSLColor.ToHexString((Color)v);
}
// HSLColor.ToString() does the wrong thing; force it to format as rgb[a] hex
if (t == typeof(HSLColor))
{
return ((HSLColor)v).ToHexString();
}
if (t == typeof(ImageFormat))
{
return ((ImageFormat)v).ToString();
return ((Color)v).ToString();
}
if (t == typeof(Rectangle))
@@ -98,6 +84,11 @@ namespace OpenRA
return "{0},{1},{2},{3}".F(r.X, r.Y, r.Width, r.Height);
}
if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(BitSet<>))
{
return ((IEnumerable<string>)v).Select(FormatValue).JoinWith(", ");
}
if (t.IsArray && t.GetArrayRank() == 1)
{
return ((Array)v).Cast<object>().Select(FormatValue).JoinWith(", ");

View File

@@ -0,0 +1,355 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 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
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using ICSharpCode.SharpZipLib.Checksum;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using OpenRA.Primitives;
namespace OpenRA.FileFormats
{
public class Png
{
static readonly byte[] Signature = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
public int Width { get; set; }
public int Height { get; set; }
public Color[] Palette { get; set; }
public byte[] Data { get; set; }
public Dictionary<string, string> EmbeddedData = new Dictionary<string, string>();
public Png(Stream s)
{
if (!Verify(s))
throw new InvalidDataException("PNG Signature is bogus");
s.Position += 8;
var headerParsed = false;
var isPaletted = false;
var is24Bit = false;
var data = new List<byte>();
while (true)
{
var length = IPAddress.NetworkToHostOrder(s.ReadInt32());
var type = Encoding.UTF8.GetString(s.ReadBytes(4));
var content = s.ReadBytes(length);
/*var crc = */s.ReadInt32();
if (!headerParsed && type != "IHDR")
throw new InvalidDataException("Invalid PNG file - header does not appear first.");
using (var ms = new MemoryStream(content))
{
switch (type)
{
case "IHDR":
{
if (headerParsed)
throw new InvalidDataException("Invalid PNG file - duplicate header.");
Width = IPAddress.NetworkToHostOrder(ms.ReadInt32());
Height = IPAddress.NetworkToHostOrder(ms.ReadInt32());
var bitDepth = ms.ReadUInt8();
var colorType = (PngColorType)ms.ReadByte();
isPaletted = IsPaletted(bitDepth, colorType);
is24Bit = colorType == PngColorType.Color;
var dataLength = Width * Height;
if (!isPaletted)
dataLength *= 4;
Data = new byte[dataLength];
var compression = ms.ReadByte();
/*var filter = */ms.ReadByte();
var interlace = ms.ReadByte();
if (compression != 0)
throw new InvalidDataException("Compression method not supported");
if (interlace != 0)
throw new InvalidDataException("Interlacing not supported");
headerParsed = true;
break;
}
case "PLTE":
{
Palette = new Color[256];
for (var i = 0; i < length / 3; i++)
{
var r = ms.ReadByte(); var g = ms.ReadByte(); var b = ms.ReadByte();
Palette[i] = Color.FromArgb(r, g, b);
}
break;
}
case "tRNS":
{
if (Palette == null)
throw new InvalidDataException("Non-Palette indexed PNG are not supported.");
for (var i = 0; i < length; i++)
Palette[i] = Color.FromArgb(ms.ReadByte(), Palette[i]);
break;
}
case "IDAT":
{
data.AddRange(content);
break;
}
case "tEXt":
{
var key = ms.ReadASCIIZ();
EmbeddedData.Add(key, ms.ReadASCII(length - key.Length - 1));
break;
}
case "IEND":
{
using (var ns = new MemoryStream(data.ToArray()))
{
using (var ds = new InflaterInputStream(ns))
{
var pxStride = isPaletted ? 1 : is24Bit ? 3 : 4;
var srcStride = Width * pxStride;
var destStride = Width * (isPaletted ? 1 : 4);
var prevLine = new byte[srcStride];
for (var y = 0; y < Height; y++)
{
var filter = (PngFilter)ds.ReadByte();
var line = ds.ReadBytes(srcStride);
for (var i = 0; i < srcStride; i++)
line[i] = i < pxStride
? UnapplyFilter(filter, line[i], 0, prevLine[i], 0)
: UnapplyFilter(filter, line[i], line[i - pxStride], prevLine[i], prevLine[i - pxStride]);
if (is24Bit)
{
// Fold alpha channel into RGB data
for (var i = 0; i < line.Length / 3; i++)
{
Array.Copy(line, 3 * i, Data, y * destStride + 4 * i, 3);
Data[y * destStride + 4 * i + 3] = 255;
}
}
else
Array.Copy(line, 0, Data, y * destStride, line.Length);
prevLine = line;
}
}
}
if (isPaletted && Palette == null)
throw new InvalidDataException("Non-Palette indexed PNG are not supported.");
return;
}
}
}
}
}
public Png(byte[] data, int width, int height, Color[] palette = null,
Dictionary<string, string> embeddedData = null)
{
var expectLength = width * height;
if (palette == null)
expectLength *= 4;
if (data.Length != expectLength)
throw new InvalidDataException("Input data does not match expected length");
Width = width;
Height = height;
Palette = palette;
Data = data;
if (embeddedData != null)
EmbeddedData = embeddedData;
}
public static bool Verify(Stream s)
{
var pos = s.Position;
var isPng = Signature.Aggregate(true, (current, t) => current && s.ReadUInt8() == t);
s.Position = pos;
return isPng;
}
static byte UnapplyFilter(PngFilter f, byte x, byte a, byte b, byte c)
{
switch (f)
{
case PngFilter.None: return x;
case PngFilter.Sub: return (byte)(x + a);
case PngFilter.Up: return (byte)(x + b);
case PngFilter.Average: return (byte)(x + (a + b) / 2);
case PngFilter.Paeth: return (byte)(x + Paeth(a, b, c));
default:
throw new InvalidOperationException("Unsupported Filter");
}
}
static byte Paeth(byte a, byte b, byte c)
{
var p = a + b - c;
var pa = Math.Abs(p - a);
var pb = Math.Abs(p - b);
var pc = Math.Abs(p - c);
return (pa <= pb && pa <= pc) ? a :
(pb <= pc) ? b : c;
}
[Flags]
enum PngColorType { Indexed = 1, Color = 2, Alpha = 4 }
enum PngFilter { None, Sub, Up, Average, Paeth }
static bool IsPaletted(byte bitDepth, PngColorType colorType)
{
if (bitDepth == 8 && colorType == (PngColorType.Indexed | PngColorType.Color))
return true;
if (bitDepth == 8 && colorType == (PngColorType.Color | PngColorType.Alpha))
return false;
if (bitDepth == 8 && colorType == PngColorType.Color)
return false;
throw new InvalidDataException("Unknown pixel format");
}
void WritePngChunk(Stream output, string type, Stream input)
{
input.Position = 0;
var typeBytes = Encoding.ASCII.GetBytes(type);
output.Write(IPAddress.HostToNetworkOrder((int)input.Length));
output.WriteArray(typeBytes);
var data = input.ReadAllBytes();
output.WriteArray(data);
var crc32 = new Crc32();
crc32.Update(typeBytes);
crc32.Update(data);
output.Write(IPAddress.NetworkToHostOrder((int)crc32.Value));
}
public byte[] Save()
{
using (var output = new MemoryStream())
{
output.WriteArray(Signature);
using (var header = new MemoryStream())
{
header.Write(IPAddress.HostToNetworkOrder(Width));
header.Write(IPAddress.HostToNetworkOrder(Height));
header.WriteByte(8); // Bit depth
var colorType = Palette != null
? PngColorType.Indexed | PngColorType.Color
: PngColorType.Color | PngColorType.Alpha;
header.WriteByte((byte)colorType);
header.WriteByte(0); // Compression
header.WriteByte(0); // Filter
header.WriteByte(0); // Interlacing
WritePngChunk(output, "IHDR", header);
}
bool alphaPalette = false;
if (Palette != null)
{
using (var palette = new MemoryStream())
{
foreach (var c in Palette)
{
palette.WriteByte(c.R);
palette.WriteByte(c.G);
palette.WriteByte(c.B);
alphaPalette |= c.A > 0;
}
WritePngChunk(output, "PLTE", palette);
}
}
if (alphaPalette)
{
using (var alpha = new MemoryStream())
{
foreach (var c in Palette)
alpha.WriteByte(c.A);
WritePngChunk(output, "tRNS", alpha);
}
}
using (var data = new MemoryStream())
{
using (var compressed = new DeflaterOutputStream(data))
{
var stride = Width * (Palette != null ? 1 : 4);
for (var y = 0; y < Height; y++)
{
// Write uncompressed scanlines for simplicity
compressed.WriteByte(0);
compressed.Write(Data, y * stride, stride);
}
compressed.Flush();
compressed.Finish();
WritePngChunk(output, "IDAT", data);
}
}
foreach (var kv in EmbeddedData)
{
using (var text = new MemoryStream())
{
text.WriteArray(Encoding.ASCII.GetBytes(kv.Key + (char)0 + kv.Value));
WritePngChunk(output, "tEXt", text);
}
}
WritePngChunk(output, "IEND", new MemoryStream());
return output.ToArray();
}
}
public void Save(string path)
{
File.WriteAllBytes(path, Save());
}
}
}

View File

@@ -1,206 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 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
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
namespace OpenRA.FileFormats
{
public static class PngLoader
{
public static Bitmap Load(string filename)
{
using (var s = File.OpenRead(filename))
return Load(s);
}
public static Bitmap Load(Stream s)
{
using (var br = new BinaryReader(s))
{
var signature = new byte[] { 137, 80, 78, 71, 13, 10, 26, 10 };
foreach (var b in signature)
if (br.ReadByte() != b)
throw new InvalidDataException("PNG Signature is bogus");
Bitmap bitmap = null;
Color[] palette = null;
var data = new List<byte>();
try
{
for (;;)
{
var length = IPAddress.NetworkToHostOrder(br.ReadInt32());
var type = Encoding.UTF8.GetString(br.ReadBytes(4));
var content = br.ReadBytes(length);
/*var crc = */br.ReadInt32();
if (bitmap == null && type != "IHDR")
throw new InvalidDataException("Invalid PNG file - header does not appear first.");
using (var ms = new MemoryStream(content))
using (var cr = new BinaryReader(ms))
switch (type)
{
case "IHDR":
{
if (bitmap != null)
throw new InvalidDataException("Invalid PNG file - duplicate header.");
var width = IPAddress.NetworkToHostOrder(cr.ReadInt32());
var height = IPAddress.NetworkToHostOrder(cr.ReadInt32());
var bitDepth = cr.ReadByte();
var colorType = (PngColorType)cr.ReadByte();
var compression = cr.ReadByte();
/*var filter = */cr.ReadByte();
var interlace = cr.ReadByte();
if (compression != 0) throw new InvalidDataException("Compression method not supported");
if (interlace != 0) throw new InvalidDataException("Interlacing not supported");
bitmap = new Bitmap(width, height, MakePixelFormat(bitDepth, colorType));
}
break;
case "PLTE":
{
palette = new Color[256];
for (var i = 0; i < 256; i++)
{
var r = cr.ReadByte(); var g = cr.ReadByte(); var b = cr.ReadByte();
palette[i] = Color.FromArgb(r, g, b);
}
}
break;
case "tRNS":
{
if (palette == null)
throw new InvalidDataException("Non-Palette indexed PNG are not supported.");
for (var i = 0; i < length; i++)
palette[i] = Color.FromArgb(cr.ReadByte(), palette[i]);
}
break;
case "IDAT":
{
data.AddRange(content);
}
break;
case "IEND":
{
var bits = bitmap.LockBits(bitmap.Bounds(),
ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
using (var ns = new MemoryStream(data.ToArray()))
{
// 'zlib' flags bytes; confuses the DeflateStream.
/*var flags = (byte)*/ns.ReadByte();
/*var moreFlags = (byte)*/ns.ReadByte();
using (var ds = new DeflateStream(ns, CompressionMode.Decompress))
using (var dr = new BinaryReader(ds))
{
var prevLine = new byte[bitmap.Width]; // all zero
for (var y = 0; y < bitmap.Height; y++)
{
var filter = (PngFilter)dr.ReadByte();
var line = dr.ReadBytes(bitmap.Width);
for (var i = 0; i < bitmap.Width; i++)
line[i] = i > 0
? UnapplyFilter(filter, line[i], line[i - 1], prevLine[i], prevLine[i - 1])
: UnapplyFilter(filter, line[i], 0, prevLine[i], 0);
Marshal.Copy(line, 0, new IntPtr(bits.Scan0.ToInt64() + y * bits.Stride), line.Length);
prevLine = line;
}
}
}
bitmap.UnlockBits(bits);
if (palette == null)
throw new InvalidDataException("Non-Palette indexed PNG are not supported.");
using (var temp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))
{
var cp = temp.Palette;
for (var i = 0; i < 256; i++)
cp.Entries[i] = palette[i]; // finalize the palette.
bitmap.Palette = cp;
return bitmap;
}
}
}
}
}
catch
{
if (bitmap != null)
bitmap.Dispose();
throw;
}
}
}
static byte UnapplyFilter(PngFilter f, byte x, byte a, byte b, byte c)
{
switch (f)
{
case PngFilter.None: return x;
case PngFilter.Sub: return (byte)(x + a);
case PngFilter.Up: return (byte)(x + b);
case PngFilter.Average: return (byte)(x + (a + b) / 2);
case PngFilter.Paeth: return (byte)(x + Paeth(a, b, c));
default:
throw new InvalidOperationException("Unsupported Filter");
}
}
static byte Paeth(byte a, byte b, byte c)
{
var p = a + b - c;
var pa = Math.Abs(p - a);
var pb = Math.Abs(p - b);
var pc = Math.Abs(p - c);
return (pa <= pb && pa <= pc) ? a :
(pb <= pc) ? b : c;
}
[Flags]
enum PngColorType { Indexed = 1, Color = 2, Alpha = 4 }
enum PngFilter { None, Sub, Up, Average, Paeth }
static PixelFormat MakePixelFormat(byte bitDepth, PngColorType colorType)
{
if (bitDepth == 8 && colorType == (PngColorType.Indexed | PngColorType.Color))
return PixelFormat.Format8bppIndexed;
throw new InvalidDataException("Unknown pixel format");
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,127 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 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
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using OpenRA.FileFormats;
using OpenRA.Primitives;
namespace OpenRA.FileSystem
{
public sealed class BagFile : IReadOnlyPackage
{
public string Name { get; private set; }
public IEnumerable<string> Contents { get { return index.Keys; } }
readonly Stream s;
readonly Dictionary<string, IdxEntry> index;
public BagFile(FileSystem context, string filename)
{
Name = filename;
// A bag file is always accompanied with an .idx counterpart
// For example: audio.bag requires the audio.idx file
var indexFilename = Path.ChangeExtension(filename, ".idx");
// Build the index and dispose the stream, it is no longer needed after this
List<IdxEntry> entries;
using (var indexStream = context.Open(indexFilename))
entries = new IdxReader(indexStream).Entries;
index = entries.ToDictionaryWithConflictLog(x => x.Filename,
"{0} (bag format)".F(filename),
null, x => "(offs={0}, len={1})".F(x.Offset, x.Length));
s = context.Open(filename);
}
public Stream GetStream(string filename)
{
IdxEntry entry;
if (!index.TryGetValue(filename, out entry))
return null;
s.Seek(entry.Offset, SeekOrigin.Begin);
var waveHeaderMemoryStream = new MemoryStream();
var channels = (entry.Flags & 1) > 0 ? 2 : 1;
if ((entry.Flags & 2) > 0)
{
// PCM
waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("RIFF"));
waveHeaderMemoryStream.Write(BitConverter.GetBytes(entry.Length + 36));
waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("WAVE"));
waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("fmt "));
waveHeaderMemoryStream.Write(BitConverter.GetBytes(16));
waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)1));
waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)channels));
waveHeaderMemoryStream.Write(BitConverter.GetBytes(entry.SampleRate));
waveHeaderMemoryStream.Write(BitConverter.GetBytes(2 * channels * entry.SampleRate));
waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)(2 * channels)));
waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)16));
waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("data"));
waveHeaderMemoryStream.Write(BitConverter.GetBytes(entry.Length));
}
if ((entry.Flags & 8) > 0)
{
// IMA ADPCM
var samplesPerChunk = (2 * (entry.ChunkSize - 4)) + 1;
var bytesPerSec = (int)Math.Floor(((double)(2 * entry.ChunkSize) / samplesPerChunk) * ((double)entry.SampleRate / 2));
var chunkSize = entry.ChunkSize > entry.Length ? entry.Length : entry.ChunkSize;
waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("RIFF"));
waveHeaderMemoryStream.Write(BitConverter.GetBytes(entry.Length + 52));
waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("WAVE"));
waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("fmt "));
waveHeaderMemoryStream.Write(BitConverter.GetBytes(20));
waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)17));
waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)channels));
waveHeaderMemoryStream.Write(BitConverter.GetBytes(entry.SampleRate));
waveHeaderMemoryStream.Write(BitConverter.GetBytes(bytesPerSec));
waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)chunkSize));
waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)4));
waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)2));
waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)samplesPerChunk));
waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("fact"));
waveHeaderMemoryStream.Write(BitConverter.GetBytes(4));
waveHeaderMemoryStream.Write(BitConverter.GetBytes(4 * entry.Length));
waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("data"));
waveHeaderMemoryStream.Write(BitConverter.GetBytes(entry.Length));
}
waveHeaderMemoryStream.Seek(0, SeekOrigin.Begin);
// Construct a merged stream
var mergedStream = new MergedStream(waveHeaderMemoryStream, s);
mergedStream.SetLength(waveHeaderMemoryStream.Length + entry.Length);
return mergedStream;
}
public bool Contains(string filename)
{
return index.ContainsKey(filename);
}
public void Dispose()
{
s.Dispose();
}
}
}

View File

@@ -1,105 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 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
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace OpenRA.FileSystem
{
public sealed class BigFile : IReadOnlyPackage
{
public string Name { get; private set; }
public IEnumerable<string> Contents { get { return index.Keys; } }
readonly Dictionary<string, Entry> index = new Dictionary<string, Entry>();
readonly Stream s;
public BigFile(FileSystem context, string filename)
{
Name = filename;
s = context.Open(filename);
try
{
if (s.ReadASCII(4) != "BIGF")
throw new InvalidDataException("Header is not BIGF");
// Total archive size.
s.ReadUInt32();
var entryCount = s.ReadUInt32();
if (BitConverter.IsLittleEndian)
entryCount = int2.Swap(entryCount);
// First entry offset? This is apparently bogus for EA's .big files
// and we don't have to try seeking there since the entries typically start next in EA's .big files.
s.ReadUInt32();
for (var i = 0; i < entryCount; i++)
{
var entry = new Entry(s);
index.Add(entry.Path, entry);
}
}
catch
{
Dispose();
throw;
}
}
class Entry
{
readonly Stream s;
readonly uint offset;
readonly uint size;
public readonly string Path;
public Entry(Stream s)
{
this.s = s;
offset = s.ReadUInt32();
size = s.ReadUInt32();
if (BitConverter.IsLittleEndian)
{
offset = int2.Swap(offset);
size = int2.Swap(size);
}
Path = s.ReadASCIIZ();
}
public Stream GetData()
{
s.Position = offset;
return new MemoryStream(s.ReadBytes((int)size));
}
}
public Stream GetStream(string filename)
{
return index[filename].GetData();
}
public bool Contains(string filename)
{
return index.ContainsKey(filename);
}
public void Dispose()
{
s.Dispose();
}
}
}

View File

@@ -1,81 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 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
using System.Collections.Generic;
using System.IO;
using OpenRA.Primitives;
namespace OpenRA.FileSystem
{
public sealed class D2kSoundResources : IReadOnlyPackage
{
struct Entry
{
public readonly uint Offset;
public readonly uint Length;
public Entry(uint offset, uint length)
{
Offset = offset;
Length = length;
}
}
public string Name { get; private set; }
public IEnumerable<string> Contents { get { return index.Keys; } }
readonly Stream s;
readonly Dictionary<string, Entry> index = new Dictionary<string, Entry>();
public D2kSoundResources(FileSystem context, string filename)
{
Name = filename;
s = context.Open(filename);
try
{
var headerLength = s.ReadUInt32();
while (s.Position < headerLength + 4)
{
var name = s.ReadASCIIZ();
var offset = s.ReadUInt32();
var length = s.ReadUInt32();
index.Add(name, new Entry(offset, length));
}
}
catch
{
Dispose();
throw;
}
}
public Stream GetStream(string filename)
{
Entry e;
if (!index.TryGetValue(filename, out e))
return null;
s.Seek(e.Offset, SeekOrigin.Begin);
return new MemoryStream(s.ReadBytes((int)e.Length));
}
public bool Contains(string filename)
{
return index.ContainsKey(filename);
}
public void Dispose()
{
s.Dispose();
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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
@@ -23,6 +23,7 @@ namespace OpenRA.FileSystem
bool TryGetPackageContaining(string path, out IReadOnlyPackage package, out string filename);
bool TryOpen(string filename, out Stream s);
bool Exists(string filename);
bool IsExternalModFile(string filename);
}
public class FileSystem : IReadOnlyFileSystem
@@ -30,91 +31,70 @@ namespace OpenRA.FileSystem
public IEnumerable<IReadOnlyPackage> MountedPackages { get { return mountedPackages.Keys; } }
readonly Dictionary<IReadOnlyPackage, int> mountedPackages = new Dictionary<IReadOnlyPackage, int>();
readonly Dictionary<string, IReadOnlyPackage> explicitMounts = new Dictionary<string, IReadOnlyPackage>();
readonly string modID;
// Mod packages that should not be disposed
readonly List<IReadOnlyPackage> modPackages = new List<IReadOnlyPackage>();
readonly IReadOnlyDictionary<string, Manifest> installedMods;
readonly IPackageLoader[] packageLoaders;
Cache<string, List<IReadOnlyPackage>> fileIndex = new Cache<string, List<IReadOnlyPackage>>(_ => new List<IReadOnlyPackage>());
public FileSystem(IReadOnlyDictionary<string, Manifest> installedMods)
public FileSystem(string modID, IReadOnlyDictionary<string, Manifest> installedMods, IPackageLoader[] packageLoaders)
{
this.modID = modID;
this.installedMods = installedMods;
this.packageLoaders = packageLoaders
.Append(new ZipFileLoader())
.ToArray();
}
public bool TryParsePackage(Stream stream, string filename, out IReadOnlyPackage package)
{
package = null;
foreach (var packageLoader in packageLoaders)
if (packageLoader.TryParsePackage(stream, filename, this, out package))
return true;
return false;
}
public IReadOnlyPackage OpenPackage(string filename)
{
if (filename.EndsWith(".mix", StringComparison.InvariantCultureIgnoreCase))
return new MixFile(this, filename);
if (filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase))
return new ZipFile(this, filename);
if (filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase))
return new ZipFile(this, filename);
if (filename.EndsWith(".oramod", StringComparison.InvariantCultureIgnoreCase))
return new ZipFile(this, filename);
if (filename.EndsWith(".RS", StringComparison.InvariantCultureIgnoreCase))
return new D2kSoundResources(this, filename);
if (filename.EndsWith(".Z", StringComparison.InvariantCultureIgnoreCase))
return new InstallShieldPackage(this, filename);
if (filename.EndsWith(".PAK", StringComparison.InvariantCultureIgnoreCase))
return new PakFile(this, filename);
if (filename.EndsWith(".big", StringComparison.InvariantCultureIgnoreCase))
return new BigFile(this, filename);
if (filename.EndsWith(".bag", StringComparison.InvariantCultureIgnoreCase))
return new BagFile(this, filename);
// Raw directories are the easiest and one of the most common cases, so try these first
var resolvedPath = Platform.ResolvePath(filename);
if (!filename.Contains("|") && Directory.Exists(resolvedPath))
return new Folder(resolvedPath);
IReadOnlyPackage parent;
string subPath = null;
if (TryGetPackageContaining(filename, out parent, out subPath))
return OpenPackage(subPath, parent);
// Children of another package require special handling
if (TryGetPackageContaining(filename, out var parent, out var subPath))
return parent.OpenPackage(subPath, this);
return new Folder(Platform.ResolvePath(filename));
}
// Try and open it normally
var stream = Open(filename);
if (TryParsePackage(stream, filename, out var package))
return package;
public IReadOnlyPackage OpenPackage(string filename, IReadOnlyPackage parent)
{
// HACK: limit support to zip and folder until we generalize the PackageLoader support
if (filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase) ||
filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase))
{
using (var s = parent.GetStream(filename))
return new ZipFile(s, filename, parent);
}
if (parent is ZipFile)
return new ZipFolder(this, (ZipFile)parent, filename, filename);
if (parent is ZipFolder)
{
var folder = (ZipFolder)parent;
return new ZipFolder(this, folder.Parent, folder.Name + "/" + filename, filename);
}
if (parent is Folder)
{
var subFolder = Platform.ResolvePath(Path.Combine(parent.Name, filename));
if (Directory.Exists(subFolder))
return new Folder(subFolder);
}
// No package loaders took ownership of the stream, so clean it up
stream.Dispose();
return null;
}
public void Mount(string name, string explicitName = null)
{
var optional = name.StartsWith("~");
var optional = name.StartsWith("~", StringComparison.Ordinal);
if (optional)
name = name.Substring(1);
try
{
IReadOnlyPackage package;
if (name.StartsWith("$"))
if (name.StartsWith("$", StringComparison.Ordinal))
{
name = name.Substring(1);
Manifest mod;
if (!installedMods.TryGetValue(name, out mod))
if (!installedMods.TryGetValue(name, out var mod))
throw new InvalidOperationException("Could not load mod '{0}'. Available mods: {1}".F(name, installedMods.Keys.JoinWith(", ")));
package = mod.Package;
@@ -138,8 +118,7 @@ namespace OpenRA.FileSystem
public void Mount(IReadOnlyPackage package, string explicitName = null)
{
var mountCount = 0;
if (mountedPackages.TryGetValue(package, out mountCount))
if (mountedPackages.TryGetValue(package, out var mountCount))
{
// Package is already mounted
// Increment the mount count and bump up the file loading priority
@@ -165,8 +144,7 @@ namespace OpenRA.FileSystem
public bool Unmount(IReadOnlyPackage package)
{
var mountCount = 0;
if (!mountedPackages.TryGetValue(package, out mountCount))
if (!mountedPackages.TryGetValue(package, out var mountCount))
return false;
if (--mountCount <= 0)
@@ -219,16 +197,12 @@ namespace OpenRA.FileSystem
var package = fileIndex[filename]
.LastOrDefault(x => x.Contains(filename));
if (package != null)
return package.GetStream(filename);
return null;
return package?.GetStream(filename);
}
public Stream Open(string filename)
{
Stream s;
if (!TryOpen(filename, out s))
if (!TryOpen(filename, out var s))
throw new FileNotFoundException("File not found: {0}".F(filename), filename);
return s;
@@ -254,8 +228,7 @@ namespace OpenRA.FileSystem
var explicitSplit = filename.IndexOf('|');
if (explicitSplit > 0)
{
IReadOnlyPackage explicitPackage;
if (explicitMounts.TryGetValue(filename.Substring(0, explicitSplit), out explicitPackage))
if (explicitMounts.TryGetValue(filename.Substring(0, explicitSplit), out var explicitPackage))
{
s = explicitPackage.GetStream(filename.Substring(explicitSplit + 1));
if (s != null)
@@ -290,14 +263,68 @@ namespace OpenRA.FileSystem
{
var explicitSplit = filename.IndexOf('|');
if (explicitSplit > 0)
{
IReadOnlyPackage explicitPackage;
if (explicitMounts.TryGetValue(filename.Substring(0, explicitSplit), out explicitPackage))
if (explicitMounts.TryGetValue(filename.Substring(0, explicitSplit), out var explicitPackage))
if (explicitPackage.Contains(filename.Substring(explicitSplit + 1)))
return true;
}
return fileIndex.ContainsKey(filename);
}
/// <summary>
/// Returns true if the given filename references an external mod via an explicit mount
/// </summary>
public bool IsExternalModFile(string filename)
{
var explicitSplit = filename.IndexOf('|');
if (explicitSplit < 0)
return false;
if (!explicitMounts.TryGetValue(filename.Substring(0, explicitSplit), out var explicitPackage))
return false;
if (installedMods[modID].Package == explicitPackage)
return false;
return modPackages.Contains(explicitPackage);
}
/// <summary>
/// Resolves a filesystem for an assembly, accounting for explicit and mod mounts.
/// Assemblies must exist in the native OS file system (not inside an OpenRA-defined package).
/// </summary>
public static string ResolveAssemblyPath(string path, Manifest manifest, InstalledMods installedMods)
{
var explicitSplit = path.IndexOf('|');
if (explicitSplit > 0)
{
var parent = path.Substring(0, explicitSplit);
var filename = path.Substring(explicitSplit + 1);
var parentPath = manifest.Packages.FirstOrDefault(kv => kv.Value == parent).Key;
if (parentPath == null)
return null;
if (parentPath.StartsWith("$", StringComparison.Ordinal))
{
if (!installedMods.TryGetValue(parentPath.Substring(1), out var mod))
return null;
if (!(mod.Package is Folder))
return null;
path = Path.Combine(mod.Package.Name, filename);
}
else
path = Path.Combine(parentPath, filename);
}
var resolvedPath = Platform.ResolvePath(path);
return File.Exists(resolvedPath) ? resolvedPath : null;
}
public string GetPrefix(IReadOnlyPackage package)
{
return explicitMounts.ContainsValue(package) ? explicitMounts.First(f => f.Value == package).Key : null;
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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
@@ -51,6 +51,28 @@ namespace OpenRA.FileSystem
return combined.StartsWith(path, StringComparison.Ordinal) && File.Exists(combined);
}
public IReadOnlyPackage OpenPackage(string filename, FileSystem context)
{
var resolvedPath = Platform.ResolvePath(Path.Combine(Name, filename));
if (Directory.Exists(resolvedPath))
return new Folder(resolvedPath);
// Zip files loaded from Folders (and *only* from Folders) can be read-write
if (ZipFileLoader.TryParseReadWritePackage(resolvedPath, out var readWritePackage))
return readWritePackage;
// Other package types can be loaded normally
var s = GetStream(filename);
if (s == null)
return null;
if (context.TryParsePackage(s, filename, out var package))
return package;
s.Dispose();
return null;
}
public void Update(string filename, byte[] contents)
{
// HACK: ZipFiles can't be loaded as read-write from a stream, so we are

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,12 +15,23 @@ using System.IO;
namespace OpenRA.FileSystem
{
public interface IPackageLoader
{
/// <summary>
/// Attempt to parse a stream as this type of package.
/// If successful, the loader is expected to take ownership of `s` and dispose it once done.
/// If unsuccessful, the loader is expected to return the stream position to where it started.
/// </summary>
bool TryParsePackage(Stream s, string filename, FileSystem context, out IReadOnlyPackage package);
}
public interface IReadOnlyPackage : IDisposable
{
string Name { get; }
IEnumerable<string> Contents { get; }
Stream GetStream(string filename);
bool Contains(string filename);
IReadOnlyPackage OpenPackage(string filename, FileSystem context);
}
public interface IReadWritePackage : IReadOnlyPackage

View File

@@ -1,137 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 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
using System;
using System.Collections.Generic;
using System.IO;
using OpenRA.FileFormats;
namespace OpenRA.FileSystem
{
public sealed class InstallShieldPackage : IReadOnlyPackage
{
public struct Entry
{
public readonly uint Offset;
public readonly uint Length;
public Entry(uint offset, uint length)
{
Offset = offset;
Length = length;
}
}
public string Name { get; private set; }
public IEnumerable<string> Contents { get { return index.Keys; } }
readonly Dictionary<string, Entry> index = new Dictionary<string, Entry>();
readonly Stream s;
readonly long dataStart = 255;
public InstallShieldPackage(FileSystem context, string filename)
{
Name = filename;
s = context.Open(filename);
try
{
// Parse package header
var signature = s.ReadUInt32();
if (signature != 0x8C655D13)
throw new InvalidDataException("Not an Installshield package");
s.Position += 8;
/*var FileCount = */s.ReadUInt16();
s.Position += 4;
/*var ArchiveSize = */s.ReadUInt32();
s.Position += 19;
var tocAddress = s.ReadInt32();
s.Position += 4;
var dirCount = s.ReadUInt16();
// Parse the directory list
s.Position = tocAddress;
// Parse directories
var directories = new Dictionary<string, uint>();
for (var i = 0; i < dirCount; i++)
{
// Parse directory header
var fileCount = s.ReadUInt16();
var chunkSize = s.ReadUInt16();
var nameLength = s.ReadUInt16();
var dirName = s.ReadASCII(nameLength);
// Skip to the end of the chunk
s.ReadBytes(chunkSize - nameLength - 6);
directories.Add(dirName, fileCount);
}
// Parse files
foreach (var dir in directories)
for (var i = 0; i < dir.Value; i++)
ParseFile(s, dir.Key);
}
catch
{
Dispose();
throw;
}
}
uint accumulatedData = 0;
void ParseFile(Stream s, string dirName)
{
s.Position += 7;
var compressedSize = s.ReadUInt32();
s.Position += 12;
var chunkSize = s.ReadUInt16();
s.Position += 4;
var nameLength = s.ReadByte();
var fileName = dirName + "\\" + s.ReadASCII(nameLength);
// Use index syntax to overwrite any duplicate entries with the last value
index[fileName] = new Entry(accumulatedData, compressedSize);
accumulatedData += compressedSize;
// Skip to the end of the chunk
s.Position += chunkSize - nameLength - 30;
}
public Stream GetStream(string filename)
{
Entry e;
if (!index.TryGetValue(filename, out e))
return null;
s.Seek(dataStart + e.Offset, SeekOrigin.Begin);
var ret = new MemoryStream();
Blast.Decompress(s, ret);
ret.Seek(0, SeekOrigin.Begin);
return ret;
}
public bool Contains(string filename)
{
return index.ContainsKey(filename);
}
public IReadOnlyDictionary<string, Entry> Index { get { return new ReadOnlyDictionary<string, Entry>(index); } }
public void Dispose()
{
s.Dispose();
}
}
}

View File

@@ -1,243 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 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
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Primitives;
namespace OpenRA.FileSystem
{
public sealed class MixFile : IReadOnlyPackage
{
public string Name { get; private set; }
public IEnumerable<string> Contents { get { return index.Keys; } }
readonly Dictionary<string, PackageEntry> index;
readonly long dataStart;
readonly Stream s;
readonly FileSystem context;
public MixFile(FileSystem context, string filename)
{
Name = filename;
this.context = context;
s = context.Open(filename);
try
{
// Detect format type
var isCncMix = s.ReadUInt16() != 0;
// The C&C mix format doesn't contain any flags or encryption
var isEncrypted = false;
if (!isCncMix)
isEncrypted = (s.ReadUInt16() & 0x2) != 0;
List<PackageEntry> entries;
if (isEncrypted)
{
long unused;
entries = ParseHeader(DecryptHeader(s, 4, out dataStart), 0, out unused);
}
else
entries = ParseHeader(s, isCncMix ? 0 : 4, out dataStart);
index = ParseIndex(entries.ToDictionaryWithConflictLog(x => x.Hash,
"{0} ({1} format, Encrypted: {2}, DataStart: {3})".F(filename, isCncMix ? "C&C" : "RA/TS/RA2", isEncrypted, dataStart),
null, x => "(offs={0}, len={1})".F(x.Offset, x.Length)));
}
catch (Exception)
{
Dispose();
throw;
}
}
Dictionary<string, PackageEntry> ParseIndex(Dictionary<uint, PackageEntry> entries)
{
var classicIndex = new Dictionary<string, PackageEntry>();
var crcIndex = new Dictionary<string, PackageEntry>();
var allPossibleFilenames = new HashSet<string>();
// Try and find a local mix database
var dbNameClassic = PackageEntry.HashFilename("local mix database.dat", PackageHashType.Classic);
var dbNameCRC = PackageEntry.HashFilename("local mix database.dat", PackageHashType.CRC32);
foreach (var kv in entries)
{
if (kv.Key == dbNameClassic || kv.Key == dbNameCRC)
{
using (var content = GetContent(kv.Value))
{
var db = new XccLocalDatabase(content);
foreach (var e in db.Entries)
allPossibleFilenames.Add(e);
}
break;
}
}
// Load the global mix database
// TODO: This should be passed to the mix file ctor
if (context.Exists("global mix database.dat"))
{
using (var db = new XccGlobalDatabase(context.Open("global mix database.dat")))
{
foreach (var e in db.Entries)
allPossibleFilenames.Add(e);
}
}
foreach (var filename in allPossibleFilenames)
{
var classicHash = PackageEntry.HashFilename(filename, PackageHashType.Classic);
var crcHash = PackageEntry.HashFilename(filename, PackageHashType.CRC32);
PackageEntry e;
if (entries.TryGetValue(classicHash, out e))
classicIndex.Add(filename, e);
if (entries.TryGetValue(crcHash, out e))
crcIndex.Add(filename, e);
}
var bestIndex = crcIndex.Count > classicIndex.Count ? crcIndex : classicIndex;
var unknown = entries.Count - bestIndex.Count;
if (unknown > 0)
Log.Write("debug", "{0}: failed to resolve filenames for {1} unknown hashes".F(Name, unknown));
return bestIndex;
}
static List<PackageEntry> ParseHeader(Stream s, long offset, out long headerEnd)
{
s.Seek(offset, SeekOrigin.Begin);
var numFiles = s.ReadUInt16();
/*uint dataSize = */s.ReadUInt32();
var items = new List<PackageEntry>();
for (var i = 0; i < numFiles; i++)
items.Add(new PackageEntry(s));
headerEnd = offset + 6 + numFiles * PackageEntry.Size;
return items;
}
static MemoryStream DecryptHeader(Stream s, long offset, out long headerEnd)
{
s.Seek(offset, SeekOrigin.Begin);
// Decrypt blowfish key
var keyblock = s.ReadBytes(80);
var blowfishKey = new BlowfishKeyProvider().DecryptKey(keyblock);
var fish = new Blowfish(blowfishKey);
// Decrypt first block to work out the header length
var ms = Decrypt(ReadBlocks(s, offset + 80, 1), fish);
var numFiles = ms.ReadUInt16();
// Decrypt the full header - round bytes up to a full block
var blockCount = (13 + numFiles * PackageEntry.Size) / 8;
headerEnd = offset + 80 + blockCount * 8;
return Decrypt(ReadBlocks(s, offset + 80, blockCount), fish);
}
static MemoryStream Decrypt(uint[] h, Blowfish fish)
{
var decrypted = fish.Decrypt(h);
var ms = new MemoryStream();
var writer = new BinaryWriter(ms);
foreach (var t in decrypted)
writer.Write(t);
writer.Flush();
ms.Seek(0, SeekOrigin.Begin);
return ms;
}
static uint[] ReadBlocks(Stream s, long offset, int count)
{
if (offset < 0)
throw new ArgumentOutOfRangeException("offset", "Non-negative number required.");
if (count < 0)
throw new ArgumentOutOfRangeException("count", "Non-negative number required.");
if (offset + (count * 2) > s.Length)
throw new ArgumentException("Bytes to read {0} and offset {1} greater than stream length {2}.".F(count * 2, offset, s.Length));
s.Seek(offset, SeekOrigin.Begin);
// A block is a single encryption unit (represented as two 32-bit integers)
var ret = new uint[2 * count];
for (var i = 0; i < ret.Length; i++)
ret[i] = s.ReadUInt32();
return ret;
}
public Stream GetContent(PackageEntry entry)
{
Stream parentStream;
var baseOffset = dataStart + entry.Offset;
var nestedOffset = baseOffset + SegmentStream.GetOverallNestedOffset(s, out parentStream);
// Special case FileStream - instead of creating an in-memory copy,
// just reference the portion of the on-disk file that we need to save memory.
// We use GetType instead of 'is' here since we can't handle any derived classes of FileStream.
if (parentStream.GetType() == typeof(FileStream))
{
var path = ((FileStream)parentStream).Name;
return new SegmentStream(File.OpenRead(path), nestedOffset, entry.Length);
}
// For all other streams, create a copy in memory.
// This uses more memory but is the only way in general to ensure the returned streams won't clash.
s.Seek(baseOffset, SeekOrigin.Begin);
return new MemoryStream(s.ReadBytes((int)entry.Length));
}
public Stream GetStream(string filename)
{
PackageEntry e;
if (!index.TryGetValue(filename, out e))
return null;
return GetContent(e);
}
public IReadOnlyDictionary<string, PackageEntry> Index
{
get
{
var absoluteIndex = index.ToDictionary(e => e.Key, e => new PackageEntry(e.Value.Hash, (uint)(e.Value.Offset + dataStart), e.Value.Length));
return new ReadOnlyDictionary<string, PackageEntry>(absoluteIndex);
}
}
public bool Contains(string filename)
{
return index.ContainsKey(filename);
}
public void Dispose()
{
s.Dispose();
}
}
}

View File

@@ -1,84 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 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
using System.Collections.Generic;
using System.IO;
namespace OpenRA.FileSystem
{
struct Entry
{
public uint Offset;
public uint Length;
public string Filename;
}
public sealed class PakFile : IReadOnlyPackage
{
public string Name { get; private set; }
public IEnumerable<string> Contents { get { return index.Keys; } }
readonly Dictionary<string, Entry> index;
readonly Stream stream;
public PakFile(FileSystem context, string filename)
{
Name = filename;
index = new Dictionary<string, Entry>();
stream = context.Open(filename);
try
{
index = new Dictionary<string, Entry>();
var offset = stream.ReadUInt32();
while (offset != 0)
{
var file = stream.ReadASCIIZ();
var next = stream.ReadUInt32();
var length = (next == 0 ? (uint)stream.Length : next) - offset;
// Ignore duplicate files
if (index.ContainsKey(file))
continue;
index.Add(file, new Entry { Offset = offset, Length = length, Filename = file });
offset = next;
}
}
catch
{
Dispose();
throw;
}
}
public Stream GetStream(string filename)
{
Entry entry;
if (!index.TryGetValue(filename, out entry))
return null;
stream.Seek(entry.Offset, SeekOrigin.Begin);
var data = stream.ReadBytes((int)entry.Length);
return new MemoryStream(data);
}
public bool Contains(string filename)
{
return index.ContainsKey(filename);
}
public void Dispose()
{
stream.Dispose();
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,152 +9,228 @@
*/
#endregion
using System.Collections;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using ICSharpCode.SharpZipLib.Zip;
using SZipFile = ICSharpCode.SharpZipLib.Zip.ZipFile;
namespace OpenRA.FileSystem
{
public sealed class ZipFile : IReadWritePackage
public class ZipFileLoader : IPackageLoader
{
public IReadWritePackage Parent { get; private set; }
public string Name { get; private set; }
readonly Stream pkgStream;
readonly SZipFile pkg;
static readonly string[] Extensions = { ".zip", ".oramap" };
static ZipFile()
class ReadOnlyZipFile : IReadOnlyPackage
{
ZipConstants.DefaultCodePage = Encoding.UTF8.CodePage;
}
public string Name { get; protected set; }
protected ZipFile pkg;
public ZipFile(Stream stream, string name, IReadOnlyPackage parent = null)
{
// SharpZipLib breaks when asked to update archives loaded from outside streams or files
// We can work around this by creating a clean in-memory-only file, cutting all outside references
pkgStream = new MemoryStream();
stream.CopyTo(pkgStream);
pkgStream.Position = 0;
// Dummy constructor for use with ReadWriteZipFile
protected ReadOnlyZipFile() { }
Name = name;
Parent = parent as IReadWritePackage;
pkg = new SZipFile(pkgStream);
}
public ReadOnlyZipFile(Stream s, string filename)
{
Name = filename;
pkg = new ZipFile(s);
}
public ZipFile(IReadOnlyFileSystem context, string filename)
{
string name;
IReadOnlyPackage p;
if (!context.TryGetPackageContaining(filename, out p, out name))
throw new FileNotFoundException("Unable to find parent package for " + filename);
public Stream GetStream(string filename)
{
var entry = pkg.GetEntry(filename);
if (entry == null)
return null;
Name = name;
Parent = p as IReadWritePackage;
using (var z = pkg.GetInputStream(entry))
{
var ms = new MemoryStream((int)entry.Size);
z.CopyTo(ms);
ms.Seek(0, SeekOrigin.Begin);
return ms;
}
}
// SharpZipLib breaks when asked to update archives loaded from outside streams or files
// We can work around this by creating a clean in-memory-only file, cutting all outside references
pkgStream = new MemoryStream();
using (var sourceStream = p.GetStream(name))
sourceStream.CopyTo(pkgStream);
pkgStream.Position = 0;
public IEnumerable<string> Contents
{
get
{
foreach (ZipEntry entry in pkg)
yield return entry.Name;
}
}
pkg = new SZipFile(pkgStream);
}
public bool Contains(string filename)
{
return pkg.GetEntry(filename) != null;
}
ZipFile(string filename, IReadWritePackage parent)
{
pkgStream = new MemoryStream();
public void Dispose()
{
pkg?.Close();
}
Name = filename;
Parent = parent;
pkg = SZipFile.Create(pkgStream);
}
public IReadOnlyPackage OpenPackage(string filename, FileSystem context)
{
// Directories are stored with a trailing "/" in the index
var entry = pkg.GetEntry(filename) ?? pkg.GetEntry(filename + "/");
if (entry == null)
return null;
public static ZipFile Create(string filename, IReadWritePackage parent)
{
return new ZipFile(filename, parent);
}
if (entry.IsDirectory)
return new ZipFolder(this, filename);
public Stream GetStream(string filename)
{
var entry = pkg.GetEntry(filename);
if (entry == null)
// Other package types can be loaded normally
var s = GetStream(filename);
if (s == null)
return null;
if (context.TryParsePackage(s, filename, out var package))
return package;
s.Dispose();
return null;
using (var z = pkg.GetInputStream(entry))
{
var ms = new MemoryStream();
z.CopyTo(ms);
ms.Seek(0, SeekOrigin.Begin);
return ms;
}
}
public IEnumerable<string> Contents
sealed class ReadWriteZipFile : ReadOnlyZipFile, IReadWritePackage
{
get
readonly MemoryStream pkgStream = new MemoryStream();
public ReadWriteZipFile(string filename, bool create = false)
{
foreach (ZipEntry entry in pkg)
yield return entry.Name;
// SharpZipLib breaks when asked to update archives loaded from outside streams or files
// We can work around this by creating a clean in-memory-only file, cutting all outside references
if (!create)
{
using (var copy = new MemoryStream(File.ReadAllBytes(filename)))
{
pkgStream.Capacity = (int)copy.Length;
copy.CopyTo(pkgStream);
}
}
pkgStream.Position = 0;
pkg = new ZipFile(pkgStream);
Name = filename;
}
void Commit()
{
var pos = pkgStream.Position;
pkgStream.Position = 0;
File.WriteAllBytes(Name, pkgStream.ReadBytes((int)pkgStream.Length));
pkgStream.Position = pos;
}
public void Update(string filename, byte[] contents)
{
pkg.BeginUpdate();
pkg.Add(new StaticStreamDataSource(new MemoryStream(contents)), filename);
pkg.CommitUpdate();
Commit();
}
public void Delete(string filename)
{
pkg.BeginUpdate();
pkg.Delete(filename);
pkg.CommitUpdate();
Commit();
}
}
public bool Contains(string filename)
sealed class ZipFolder : IReadOnlyPackage
{
return pkg.GetEntry(filename) != null;
public string Name { get { return path; } }
public ReadOnlyZipFile Parent { get; private set; }
readonly string path;
public ZipFolder(ReadOnlyZipFile parent, string path)
{
if (path.EndsWith("/", StringComparison.Ordinal))
path = path.Substring(0, path.Length - 1);
Parent = parent;
this.path = path;
}
public Stream GetStream(string filename)
{
// Zip files use '/' as a path separator
return Parent.GetStream(path + '/' + filename);
}
public IEnumerable<string> Contents
{
get
{
foreach (var entry in Parent.Contents)
{
if (entry.StartsWith(path, StringComparison.Ordinal) && entry != path)
{
var filename = entry.Substring(path.Length + 1);
var dirLevels = filename.Split('/').Count(c => !string.IsNullOrEmpty(c));
if (dirLevels == 1)
yield return filename;
}
}
}
}
public bool Contains(string filename)
{
return Parent.Contains(path + '/' + filename);
}
public IReadOnlyPackage OpenPackage(string filename, FileSystem context)
{
return Parent.OpenPackage(path + '/' + filename, context);
}
public void Dispose() { /* nothing to do */ }
}
void Commit()
class StaticStreamDataSource : IStaticDataSource
{
if (Parent == null)
throw new InvalidDataException("Cannot update ZipFile without writable parent");
readonly Stream s;
public StaticStreamDataSource(Stream s)
{
this.s = s;
}
var pos = pkgStream.Position;
pkgStream.Position = 0;
Parent.Update(Name, pkgStream.ReadBytes((int)pkgStream.Length));
pkgStream.Position = pos;
public Stream GetSource()
{
return s;
}
}
public void Update(string filename, byte[] contents)
public bool TryParsePackage(Stream s, string filename, FileSystem context, out IReadOnlyPackage package)
{
pkg.BeginUpdate();
pkg.Add(new StaticStreamDataSource(new MemoryStream(contents)), filename);
pkg.CommitUpdate();
Commit();
if (!Extensions.Any(e => filename.EndsWith(e, StringComparison.InvariantCultureIgnoreCase)))
{
package = null;
return false;
}
package = new ReadOnlyZipFile(s, filename);
return true;
}
public void Delete(string filename)
public static bool TryParseReadWritePackage(string filename, out IReadWritePackage package)
{
pkg.BeginUpdate();
pkg.Delete(filename);
pkg.CommitUpdate();
Commit();
if (!Extensions.Any(e => filename.EndsWith(e, StringComparison.InvariantCultureIgnoreCase)))
{
package = null;
return false;
}
package = new ReadWriteZipFile(filename);
return true;
}
public void Dispose()
public static IReadWritePackage Create(string filename)
{
if (pkg != null)
pkg.Close();
if (pkgStream != null)
pkgStream.Dispose();
}
}
class StaticStreamDataSource : IStaticDataSource
{
readonly Stream s;
public StaticStreamDataSource(Stream s)
{
this.s = s;
}
public Stream GetSource()
{
return s;
return new ReadWriteZipFile(filename, true);
}
}
}

View File

@@ -1,76 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 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
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using ICSharpCode.SharpZipLib.Zip;
using SZipFile = ICSharpCode.SharpZipLib.Zip.ZipFile;
namespace OpenRA.FileSystem
{
public sealed class ZipFolder : IReadOnlyPackage
{
public string Name { get; private set; }
public ZipFile Parent { get; private set; }
readonly string path;
static ZipFolder()
{
ZipConstants.DefaultCodePage = Encoding.UTF8.CodePage;
}
public ZipFolder(FileSystem context, ZipFile parent, string path, string filename)
{
if (filename.EndsWith("/"))
filename = filename.Substring(0, filename.Length - 1);
Name = filename;
Parent = parent;
if (path.EndsWith("/"))
path = path.Substring(0, path.Length - 1);
this.path = path;
}
public Stream GetStream(string filename)
{
// Zip files use '/' as a path separator
return Parent.GetStream(path + '/' + filename);
}
public IEnumerable<string> Contents
{
get
{
foreach (var entry in Parent.Contents)
{
if (entry.StartsWith(path) && entry != path)
{
var filename = entry.Substring(path.Length + 1);
var dirLevels = filename.Split('/').Count(c => !string.IsNullOrEmpty(c));
if (dirLevels == 1)
yield return filename;
}
}
}
}
public bool Contains(string filename)
{
return Parent.Contains(path + '/' + filename);
}
public void Dispose() { /* nothing to do */ }
}
}

37
OpenRA.Game/Fonts.cs Normal file
View File

@@ -0,0 +1,37 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 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
using System.Collections.Generic;
namespace OpenRA
{
public class FontData
{
public readonly string Font;
public readonly int Size;
public readonly int Ascender;
}
public class Fonts : IGlobalModData
{
[FieldLoader.LoadUsing("LoadFonts")]
public readonly Dictionary<string, FontData> FontList;
static object LoadFonts(MiniYaml y)
{
var ret = new Dictionary<string, FontData>();
foreach (var node in y.Nodes)
ret.Add(node.Key, FieldLoader.Load<FontData>(node.Value));
return ret;
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,8 +12,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -21,10 +19,10 @@ using System.Net;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using OpenRA.Chat;
using OpenRA.Graphics;
using OpenRA.Network;
using OpenRA.Primitives;
using OpenRA.Server;
using OpenRA.Support;
using OpenRA.Widgets;
@@ -41,8 +39,10 @@ namespace OpenRA
public static ModData ModData;
public static Settings Settings;
public static ICursor Cursor;
public static CursorManager Cursor;
public static bool HideCursor;
static WorldRenderer worldRenderer;
static string modLaunchWrapper;
internal static OrderManager OrderManager;
static Server.Server server;
@@ -51,21 +51,23 @@ namespace OpenRA
public static Renderer Renderer;
public static Sound Sound;
public static bool HasInputFocus = false;
public static bool BenchmarkMode = false;
public static GlobalChat GlobalChat;
public static string EngineVersion { get; private set; }
public static LocalPlayerProfile LocalPlayerProfile;
static Task discoverNat;
static bool takeScreenshot = false;
static Benchmark benchmark = null;
public static OrderManager JoinServer(string host, int port, string password, bool recordReplay = true)
public static event Action OnShellmapLoaded = () => { };
public static OrderManager JoinServer(ConnectionTarget endpoint, string password, bool recordReplay = true)
{
var connection = new NetworkConnection(host, port);
var connection = new NetworkConnection(endpoint);
if (recordReplay)
connection.StartRecording(() => { return TimestampedFilename(); });
var om = new OrderManager(host, port, password, connection);
var om = new OrderManager(endpoint, password, connection);
JoinInner(om);
return om;
}
@@ -73,12 +75,12 @@ namespace OpenRA
static string TimestampedFilename(bool includemilliseconds = false)
{
var format = includemilliseconds ? "yyyy-MM-ddTHHmmssfffZ" : "yyyy-MM-ddTHHmmssZ";
return "OpenRA-" + DateTime.UtcNow.ToString(format, CultureInfo.InvariantCulture);
return ModData.Manifest.Id + "-" + DateTime.UtcNow.ToString(format, CultureInfo.InvariantCulture);
}
static void JoinInner(OrderManager om)
{
if (OrderManager != null) OrderManager.Dispose();
OrderManager?.Dispose();
OrderManager = om;
lastConnectionState = ConnectionState.PreConnecting;
ConnectionStateChanged(OrderManager);
@@ -86,12 +88,12 @@ namespace OpenRA
public static void JoinReplay(string replayFile)
{
JoinInner(new OrderManager("<no server>", -1, "", new ReplayConnection(replayFile)));
JoinInner(new OrderManager(new ConnectionTarget(), "", new ReplayConnection(replayFile)));
}
static void JoinLocal()
{
JoinInner(new OrderManager("<no server>", -1, "", new EchoConnection()));
JoinInner(new OrderManager(new ConnectionTarget(), "", new EchoConnection()));
}
// More accurate replacement for Environment.TickCount
@@ -102,14 +104,14 @@ namespace OpenRA
public static int NetFrameNumber { get { return OrderManager.NetFrameNumber; } }
public static int LocalTick { get { return OrderManager.LocalFrameNumber; } }
public static event Action<string, int> OnRemoteDirectConnect = (a, b) => { };
public static event Action<ConnectionTarget> OnRemoteDirectConnect = _ => { };
public static event Action<OrderManager> ConnectionStateChanged = _ => { };
static ConnectionState lastConnectionState = ConnectionState.PreConnecting;
public static int LocalClientId { get { return OrderManager.Connection.LocalClientId; } }
public static void RemoteDirectConnect(string host, int port)
public static void RemoteDirectConnect(ConnectionTarget endpoint)
{
OnRemoteDirectConnect(host, port);
OnRemoteDirectConnect(endpoint);
}
// Hacky workaround for orderManager visibility
@@ -152,8 +154,7 @@ namespace OpenRA
internal static void StartGame(string mapUID, WorldType type)
{
// Dispose of the old world before creating a new one.
if (worldRenderer != null)
worldRenderer.Dispose();
worldRenderer?.Dispose();
Cursor.SetCursor(null);
BeforeGameStart();
@@ -163,13 +164,19 @@ namespace OpenRA
using (new PerfTimer("PrepareMap"))
map = ModData.PrepareMap(mapUID);
using (new PerfTimer("NewWorld"))
OrderManager.World = new World(map, OrderManager, type);
OrderManager.World = new World(ModData, map, OrderManager, type);
OrderManager.World.GameOver += FinishBenchmark;
worldRenderer = new WorldRenderer(ModData, OrderManager.World);
GC.Collect();
using (new PerfTimer("LoadComplete"))
OrderManager.World.LoadComplete(worldRenderer);
GC.Collect();
if (OrderManager.GameStarted)
return;
@@ -190,7 +197,12 @@ namespace OpenRA
var replay = OrderManager.Connection as ReplayConnection;
var replayName = replay != null ? replay.Filename : null;
var lobbyInfo = OrderManager.LobbyInfo;
var orders = new[] {
// Reseed the RNG so this isn't an exact repeat of the last game
lobbyInfo.GlobalSettings.RandomSeed = CosmeticRandom.Next();
var orders = new[]
{
Order.Command("sync_lobby {0}".F(lobbyInfo.Serialize())),
Order.Command("startgame")
};
@@ -220,7 +232,7 @@ namespace OpenRA
LobbyInfoChanged += lobbyReady;
om = JoinServer(IPAddress.Loopback.ToString(), CreateLocalServer(mapUID), "");
om = JoinServer(CreateLocalServer(mapUID), "");
}
public static bool IsHost
@@ -239,33 +251,56 @@ namespace OpenRA
public static void InitializeSettings(Arguments args)
{
Settings = new Settings(Platform.ResolvePath(Path.Combine("^", "settings.yaml")), args);
Settings = new Settings(Platform.ResolvePath(Path.Combine(Platform.SupportDirPrefix, "settings.yaml")), args);
}
internal static void Initialize(Arguments args)
public static RunStatus InitializeAndRun(string[] args)
{
Initialize(new Arguments(args));
GC.Collect();
return Run();
}
static void Initialize(Arguments args)
{
var supportDirArg = args.GetValue("Engine.SupportDir", null);
if (!string.IsNullOrEmpty(supportDirArg))
Platform.OverrideSupportDir(supportDirArg);
Console.WriteLine("Platform is {0}", Platform.CurrentPlatform);
// Load the engine version as early as possible so it can be written to exception logs
try
{
EngineVersion = File.ReadAllText(Platform.ResolvePath(Path.Combine(".", "VERSION"))).Trim();
}
catch { }
if (string.IsNullOrEmpty(EngineVersion))
EngineVersion = "Unknown";
Console.WriteLine("Engine version is {0}", EngineVersion);
// 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 modArgument = args.GetValue("Game.Mod", null);
var modID = args.GetValue("Game.Mod", null);
var explicitModPaths = new string[0];
if (modArgument != null && (File.Exists(modArgument) || Directory.Exists(modArgument)))
if (modID != null && (File.Exists(modID) || Directory.Exists(modID)))
{
explicitModPaths = new[] { modArgument };
args.ReplaceValue("Game.Mod", Path.GetFileNameWithoutExtension(modArgument));
explicitModPaths = new[] { modID };
modID = Path.GetFileNameWithoutExtension(modID);
}
InitializeSettings(args);
Log.AddChannel("perf", "perf.log");
Log.AddChannel("debug", "debug.log");
Log.AddChannel("server", "server.log");
Log.AddChannel("server", "server.log", true);
Log.AddChannel("sound", "sound.log");
Log.AddChannel("graphics", "graphics.log");
Log.AddChannel("geoip", "geoip.log");
Log.AddChannel("irc", "irc.log");
Log.AddChannel("nat", "nat.log");
Log.AddChannel("client", "client.log");
var platforms = new[] { Settings.Game.Platform, "Default", null };
foreach (var p in platforms)
@@ -294,55 +329,49 @@ namespace OpenRA
Log.Write("graphics", "{0}", e);
Console.WriteLine("Renderer initialization failed. Check graphics.log for details.");
if (Renderer != null)
Renderer.Dispose();
Renderer?.Dispose();
if (Sound != null)
Sound.Dispose();
Sound?.Dispose();
}
}
GeoIP.Initialize();
if (!Settings.Server.DiscoverNatDevices)
Settings.Server.AllowPortForward = false;
else
{
if (Settings.Server.DiscoverNatDevices)
discoverNat = UPnP.DiscoverNatDevices(Settings.Server.NatDiscoveryTimeout);
Settings.Server.AllowPortForward = true;
}
GlobalChat = new GlobalChat();
var modSearchArg = args.GetValue("Engine.ModSearchPaths", null);
var modSearchPaths = modSearchArg != null ?
FieldLoader.GetValue<string[]>("Engine.ModsPath", modSearchArg) :
new[] { Path.Combine(".", "mods"), Path.Combine("^", "mods") };
new[] { Path.Combine(".", "mods") };
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);
var launchPath = args.GetValue("Engine.LaunchPath", Assembly.GetEntryAssembly().Location);
ExternalMods = new ExternalMods(launchPath);
modLaunchWrapper = args.GetValue("Engine.LaunchWrapper", null);
ExternalMods = new ExternalMods();
if (modID != null && Mods.TryGetValue(modID, out _))
{
var launchPath = args.GetValue("Engine.LaunchPath", Assembly.GetEntryAssembly().Location);
// Sanitize input from platform-specific launchers
// Process.Start requires paths to not be quoted, even if they contain spaces
if (launchPath.First() == '"' && launchPath.Last() == '"')
launchPath = launchPath.Substring(1, launchPath.Length - 2);
ExternalMods.Register(Mods[modID], launchPath, ModRegistration.User);
if (ExternalMods.TryGetValue(ExternalMod.MakeKey(Mods[modID]), out var activeMod))
ExternalMods.ClearInvalidRegistrations(activeMod, 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);
InitializeMod(Settings.Game.Mod, args);
}
public static bool IsModInstalled(string modId)
{
return Mods.ContainsKey(modId) && Mods[modId].RequiresMods.All(IsModInstalled);
}
public static bool IsModInstalled(KeyValuePair<string, string> mod)
{
return Mods.ContainsKey(mod.Key)
&& Mods[mod.Key].Metadata.Version == mod.Value
&& IsModInstalled(mod.Key);
InitializeMod(modID, args);
}
public static void InitializeMod(string mod, Arguments args)
@@ -351,18 +380,15 @@ namespace OpenRA
LobbyInfoChanged = () => { };
ConnectionStateChanged = om => { };
BeforeGameStart = () => { };
OnRemoteDirectConnect = (a, b) => { };
OnRemoteDirectConnect = endpoint => { };
delayedActions = new ActionQueue();
Ui.ResetAll();
if (worldRenderer != null)
worldRenderer.Dispose();
worldRenderer?.Dispose();
worldRenderer = null;
if (server != null)
server.Shutdown();
if (OrderManager != null)
OrderManager.Dispose();
server?.Shutdown();
OrderManager?.Dispose();
if (ModData != null)
{
@@ -372,17 +398,19 @@ namespace OpenRA
ModData = null;
// Fall back to default if the mod doesn't exist or has missing prerequisites.
if (mod == null || !IsModInstalled(mod))
mod = args.GetValue("Engine.DefaultMod", "modchooser");
if (mod == null)
throw new InvalidOperationException("Game.Mod argument missing.");
if (!Mods.ContainsKey(mod))
throw new InvalidOperationException("Unknown or invalid mod '{0}'.".F(mod));
Console.WriteLine("Loading mod: {0}", mod);
Settings.Game.Mod = mod;
Sound.StopVideo();
ModData = new ModData(Mods[mod], Mods, true);
ExternalMods.Register(ModData.Manifest);
LocalPlayerProfile = new LocalPlayerProfile(Platform.ResolvePath(Path.Combine("^", Settings.Game.AuthProfile)), ModData.Manifest.Get<PlayerDatabase>());
if (!ModData.LoadScreen.BeforeLoad())
return;
@@ -396,48 +424,32 @@ namespace OpenRA
var grid = ModData.Manifest.Contains<MapGrid>() ? ModData.Manifest.Get<MapGrid>() : null;
Renderer.InitializeDepthBuffer(grid);
if (Cursor != null)
Cursor.Dispose();
Cursor?.Dispose();
if (Settings.Graphics.HardwareCursors)
{
try
{
Cursor = new HardwareCursor(ModData.CursorProvider);
}
catch (Exception e)
{
Log.Write("debug", "Failed to initialize hardware cursors. Falling back to software cursors.");
Log.Write("debug", "Error was: " + e.Message);
Console.WriteLine("Failed to initialize hardware cursors. Falling back to software cursors.");
Console.WriteLine("Error was: " + e.Message);
Cursor = new SoftwareCursor(ModData.CursorProvider);
}
}
else
Cursor = new SoftwareCursor(ModData.CursorProvider);
Cursor = new CursorManager(ModData.CursorProvider);
PerfHistory.Items["render"].HasNormalTick = false;
PerfHistory.Items["batches"].HasNormalTick = false;
PerfHistory.Items["render_world"].HasNormalTick = false;
PerfHistory.Items["render_widgets"].HasNormalTick = false;
PerfHistory.Items["render_flip"].HasNormalTick = false;
PerfHistory.Items["terrain_lighting"].HasNormalTick = false;
JoinLocal();
try
{
if (discoverNat != null)
discoverNat.Wait();
discoverNat?.Wait();
}
catch (Exception e)
{
Console.WriteLine("NAT discovery failed: {0}", e.Message);
Log.Write("nat", e.ToString());
Settings.Server.AllowPortForward = false;
}
ChromeMetrics.TryGet("ChatMessageColor", out chatMessageColor);
ChromeMetrics.TryGet("SystemMessageColor", out systemMessageColor);
ModData.LoadScreen.StartGame(args);
}
@@ -451,7 +463,10 @@ namespace OpenRA
var shellmap = ChooseShellmap();
using (new PerfTimer("StartGame"))
{
StartGame(shellmap, WorldType.Shellmap);
OnShellmapLoaded();
}
}
static string ChooseShellmap()
@@ -470,8 +485,15 @@ namespace OpenRA
{
try
{
var path = mod.LaunchPath;
var args = launchArguments != null ? mod.LaunchArgs.Append(launchArguments) : mod.LaunchArgs;
var p = Process.Start(mod.LaunchPath, args.Select(a => "\"" + a + "\"").JoinWith(" "));
if (modLaunchWrapper != null)
{
path = modLaunchWrapper;
args = new[] { mod.LaunchPath }.Concat(args);
}
var p = Process.Start(path, args.Select(a => "\"" + a + "\"").JoinWith(" "));
if (p == null || p.HasExited)
onFailed();
else
@@ -494,36 +516,26 @@ namespace OpenRA
// Note: These delayed actions should only be used by widgets or disposing objects
// - things that depend on a particular world should be queuing them on the world actor.
static volatile ActionQueue delayedActions = new ActionQueue();
static Color systemMessageColor = Color.White;
static Color chatMessageColor = Color.White;
public static void RunAfterTick(Action a) { delayedActions.Add(a, RunTime); }
public static void RunAfterDelay(int delayMilliseconds, Action a) { delayedActions.Add(a, RunTime + delayMilliseconds); }
static void TakeScreenshotInner()
{
Log.Write("debug", "Taking screenshot");
Bitmap bitmap;
using (new PerfTimer("Renderer.TakeScreenshot"))
bitmap = Renderer.Device.TakeScreenshot();
ThreadPool.QueueUserWorkItem(_ =>
using (new PerfTimer("Renderer.SaveScreenshot"))
{
var mod = ModData.Manifest.Metadata;
var directory = Platform.ResolvePath("^", "Screenshots", ModData.Manifest.Id, mod.Version);
var directory = Platform.ResolvePath(Platform.SupportDirPrefix, "Screenshots", ModData.Manifest.Id, mod.Version);
Directory.CreateDirectory(directory);
var filename = TimestampedFilename(true);
var format = Settings.Graphics.ScreenshotFormat;
var extension = ImageCodecInfo.GetImageEncoders().FirstOrDefault(x => x.FormatID == format.Guid)
.FilenameExtension.Split(';').First().ToLowerInvariant().Substring(1);
var destination = Path.Combine(directory, string.Concat(filename, extension));
var path = Path.Combine(directory, string.Concat(filename, ".png"));
Log.Write("debug", "Taking screenshot " + path);
using (new PerfTimer("Save Screenshot ({0})".F(format)))
bitmap.Save(destination, format);
bitmap.Dispose();
RunAfterTick(() => Debug("Saved screenshot " + filename));
});
Renderer.SaveScreenshot(path);
Debug("Saved screenshot " + filename);
}
}
static void InnerLogicTick(OrderManager orderManager)
@@ -539,13 +551,11 @@ namespace OpenRA
var integralTickTimestep = (uiTickDelta / Timestep) * Timestep;
Ui.LastTickTime += integralTickTimestep >= TimestepJankThreshold ? integralTickTimestep : Timestep;
Viewport.TicksSinceLastMove += uiTickDelta / Timestep;
Sync.CheckSyncUnchanged(world, Ui.Tick);
Sync.RunUnsynced(Settings.Debug.SyncCheckUnsyncedCode, world, Ui.Tick);
Cursor.Tick();
}
var worldTimestep = world == null ? Timestep : world.Timestep;
var worldTimestep = world == null ? Timestep : world.IsLoadingGameSave ? 1 : world.Timestep;
var worldTickDelta = tick - orderManager.LastTickTime;
if (worldTimestep != 0 && worldTickDelta >= worldTimestep)
{
@@ -559,7 +569,7 @@ namespace OpenRA
orderManager.LastTickTime += integralTickTimestep >= TimestepJankThreshold ? integralTickTimestep : worldTimestep;
Sound.Tick();
Sync.CheckSyncUnchanged(world, orderManager.TickImmediate);
Sync.RunUnsynced(Settings.Debug.SyncCheckUnsyncedCode, world, orderManager.TickImmediate);
if (world == null)
return;
@@ -572,16 +582,12 @@ namespace OpenRA
Log.Write("debug", "--Tick: {0} ({1})", LocalTick, isNetTick ? "net" : "local");
if (BenchmarkMode)
Log.Write("cpu", "{0};{1}".F(LocalTick, PerfHistory.Items["tick_time"].LastValue));
if (isNetTick)
orderManager.Tick();
Sync.CheckSyncUnchanged(world, () =>
Sync.RunUnsynced(Settings.Debug.SyncCheckUnsyncedCode, world, () =>
{
world.OrderGenerator.Tick(world);
world.Selection.Tick(world);
});
world.Tick();
@@ -593,14 +599,16 @@ namespace OpenRA
// Wait until we have done our first world Tick before TickRendering
if (orderManager.LocalFrameNumber > 0)
Sync.CheckSyncUnchanged(world, () => world.TickRender(worldRenderer));
Sync.RunUnsynced(Settings.Debug.SyncCheckUnsyncedCode, world, () => world.TickRender(worldRenderer));
}
benchmark?.Tick(LocalTick);
}
}
static void LogicTick()
{
delayedActions.PerformActions(RunTime);
PerformDelayedActions();
if (OrderManager.Connection.ConnectionState != lastConnectionState)
{
@@ -613,7 +621,15 @@ namespace OpenRA
InnerLogicTick(worldRenderer.World.OrderManager);
}
public static bool TakeScreenshot = false;
public static void PerformDelayedActions()
{
delayedActions.PerformActions(RunTime);
}
public static void TakeScreenshot()
{
takeScreenshot = true;
}
static void RenderTick()
{
@@ -621,48 +637,70 @@ namespace OpenRA
{
++RenderFrame;
// worldRenderer is null during the initial install/download screen
if (worldRenderer != null)
// Prepare renderables (i.e. render voxels) before calling BeginFrame
using (new PerfSample("render_prepare"))
{
Renderer.BeginFrame(worldRenderer.Viewport.TopLeft, worldRenderer.Viewport.Zoom);
Sound.SetListenerPosition(worldRenderer.Viewport.CenterPosition);
worldRenderer.Draw();
Renderer.WorldModelRenderer.BeginFrame();
// World rendering is disabled while the loading screen is displayed
if (worldRenderer != null && !worldRenderer.World.IsLoadingGameSave)
{
worldRenderer.Viewport.Tick();
worldRenderer.PrepareRenderables();
}
Ui.PrepareRenderables();
Renderer.WorldModelRenderer.EndFrame();
}
// worldRenderer is null during the initial install/download screen
// World rendering is disabled while the loading screen is displayed
// Use worldRenderer.World instead of OrderManager.World to avoid a rendering mismatch while processing orders
if (worldRenderer != null && !worldRenderer.World.IsLoadingGameSave)
{
Renderer.BeginWorld(worldRenderer.Viewport.Rectangle);
Sound.SetListenerPosition(worldRenderer.Viewport.CenterPosition);
using (new PerfSample("render_world"))
worldRenderer.Draw();
}
else
Renderer.BeginFrame(int2.Zero, 1f);
using (new PerfSample("render_widgets"))
{
Renderer.WorldVoxelRenderer.BeginFrame();
Ui.PrepareRenderables();
Renderer.WorldVoxelRenderer.EndFrame();
Renderer.BeginUI();
if (worldRenderer != null && !worldRenderer.World.IsLoadingGameSave)
worldRenderer.DrawAnnotations();
Ui.Draw();
if (ModData != null && ModData.CursorProvider != null)
{
Cursor.SetCursor(Ui.Root.GetCursorOuter(Viewport.LastMousePos) ?? "default");
Cursor.Render(Renderer);
if (HideCursor)
Cursor.SetCursor(null);
else
{
Cursor.SetCursor(Ui.Root.GetCursorOuter(Viewport.LastMousePos) ?? "default");
Cursor.Render(Renderer);
}
}
}
using (new PerfSample("render_flip"))
Renderer.EndFrame(new DefaultInputHandler(OrderManager.World));
if (TakeScreenshot)
if (takeScreenshot)
{
TakeScreenshot = false;
takeScreenshot = false;
TakeScreenshotInner();
}
}
PerfHistory.Items["render"].Tick();
PerfHistory.Items["batches"].Tick();
PerfHistory.Items["render_world"].Tick();
PerfHistory.Items["render_widgets"].Tick();
PerfHistory.Items["render_flip"].Tick();
if (BenchmarkMode)
Log.Write("render", "{0};{1}".F(RenderFrame, PerfHistory.Items["render"].LastValue));
PerfHistory.Items["terrain_lighting"].Tick();
}
static void Loop()
@@ -708,6 +746,7 @@ namespace OpenRA
var nextLogic = RunTime;
var nextRender = RunTime;
var forcedNextRender = RunTime;
var renderBeforeNextTick = false;
while (state == RunStatus.Running)
{
@@ -719,6 +758,13 @@ namespace OpenRA
var maxFramerate = Settings.Graphics.CapFramerate ? Settings.Graphics.MaxFramerate.Clamp(1, 1000) : 1000;
var renderInterval = 1000 / maxFramerate;
// Tick as fast as possible while restoring game saves, capping rendering at 5 FPS
if (OrderManager.World != null && OrderManager.World.IsLoadingGameSave)
{
logicInterval = 1;
renderInterval = 200;
}
var now = RunTime;
// If the logic has fallen behind too much, skip it and catch up
@@ -729,17 +775,17 @@ namespace OpenRA
var nextUpdate = Math.Min(nextLogic, nextRender);
if (now >= nextUpdate)
{
var forceRender = now >= forcedNextRender;
var forceRender = renderBeforeNextTick || now >= forcedNextRender;
if (now >= nextLogic)
if (now >= nextLogic && !renderBeforeNextTick)
{
nextLogic += logicInterval;
LogicTick();
// Force at least one render per tick during regular gameplay
if (OrderManager.World != null && !OrderManager.World.IsReplay)
forceRender = true;
if (OrderManager.World != null && !OrderManager.World.IsLoadingGameSave && !OrderManager.World.IsReplay)
renderBeforeNextTick = true;
}
var haveSomeTimeUntilNextLogic = now < nextLogic;
@@ -758,6 +804,7 @@ namespace OpenRA
forcedNextRender = now + maxRenderInterval;
RenderTick();
renderBeforeNextTick = false;
}
}
else
@@ -765,7 +812,7 @@ namespace OpenRA
}
}
internal static RunStatus Run()
static RunStatus Run()
{
if (Settings.Graphics.MaxFramerate < 1)
{
@@ -780,16 +827,13 @@ namespace OpenRA
finally
{
// Ensure that the active replay is properly saved
if (OrderManager != null)
OrderManager.Dispose();
OrderManager?.Dispose();
}
if (worldRenderer != null)
worldRenderer.Dispose();
worldRenderer?.Dispose();
ModData.Dispose();
ChromeProvider.Deinitialize();
GlobalChat.Dispose();
Sound.Dispose();
Renderer.Dispose();
@@ -803,20 +847,29 @@ namespace OpenRA
state = RunStatus.Success;
}
public static void AddChatLine(Color color, string name, string text)
public static void AddSystemLine(string text)
{
OrderManager.AddChatLine(color, name, text);
AddSystemLine("Battlefield Control", text);
}
public static void AddSystemLine(string name, string text)
{
OrderManager.AddChatLine(name, systemMessageColor, text, systemMessageColor);
}
public static void AddChatLine(string name, Color nameColor, string text)
{
OrderManager.AddChatLine(name, nameColor, text, chatMessageColor);
}
public static void Debug(string s, params object[] args)
{
AddChatLine(Color.White, "Debug", string.Format(s, args));
AddSystemLine("Debug", string.Format(s, args));
}
public static void Disconnect()
{
if (OrderManager.World != null)
OrderManager.World.TraitDict.PrintReport();
OrderManager.World?.TraitDict.PrintReport();
OrderManager.Dispose();
CloseServer();
@@ -825,8 +878,7 @@ namespace OpenRA
public static void CloseServer()
{
if (server != null)
server.Shutdown();
server?.Shutdown();
}
public static T CreateObject<T>(string name)
@@ -834,29 +886,77 @@ namespace OpenRA
return ModData.ObjectCreator.CreateObject<T>(name);
}
public static void CreateServer(ServerSettings settings)
public static ConnectionTarget CreateServer(ServerSettings settings)
{
server = new Server.Server(new IPEndPoint(IPAddress.Any, settings.ListenPort), settings, ModData, false);
var endpoints = new List<IPEndPoint>
{
new IPEndPoint(IPAddress.IPv6Any, settings.ListenPort),
new IPEndPoint(IPAddress.Any, settings.ListenPort)
};
server = new Server.Server(endpoints, settings, ModData, ServerType.Multiplayer);
return server.GetEndpointForLocalConnection();
}
public static int CreateLocalServer(string map)
public static ConnectionTarget CreateLocalServer(string map)
{
var settings = new ServerSettings()
{
Name = "Skirmish Game",
Map = map,
AdvertiseOnline = false,
AllowPortForward = false
AdvertiseOnline = false
};
server = new Server.Server(new IPEndPoint(IPAddress.Loopback, 0), settings, ModData, false);
var endpoints = new List<IPEndPoint>
{
new IPEndPoint(IPAddress.IPv6Loopback, 0),
new IPEndPoint(IPAddress.Loopback, 0)
};
server = new Server.Server(endpoints, settings, ModData, ServerType.Local);
return server.Port;
return server.GetEndpointForLocalConnection();
}
public static bool IsCurrentWorld(World world)
{
return OrderManager != null && OrderManager.World == world && !world.Disposing;
}
public static bool SetClipboardText(string text)
{
return Renderer.Window.SetClipboardText(text);
}
public static void BenchmarkMode(string prefix)
{
benchmark = new Benchmark(prefix);
}
public static void LoadMap(string launchMap)
{
var orders = new List<Order>
{
Order.Command("option gamespeed {0}".F("default")),
Order.Command("state {0}".F(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);
if (map == null)
throw new InvalidOperationException("Could not find map '{0}'.".F(launchMap));
CreateAndStartLocalServer(map.Uid, orders);
}
public static void FinishBenchmark()
{
if (benchmark != null)
{
benchmark.Write();
Exit();
}
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,8 +12,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Network;
using OpenRA.Primitives;
namespace OpenRA
{
@@ -24,6 +24,7 @@ namespace OpenRA
public string MapUid;
public string MapTitle;
public int FinalGameTick;
/// <summary>Game start timestamp (when the recoding started).</summary>
public DateTime StartTimeUtc;
@@ -121,7 +122,8 @@ namespace OpenRA
Team = client.Team,
SpawnPoint = runtimePlayer.SpawnPoint,
IsRandomFaction = runtimePlayer.Faction.InternalName != client.Faction,
IsRandomSpawnPoint = runtimePlayer.SpawnPoint != client.SpawnPoint
IsRandomSpawnPoint = runtimePlayer.SpawnPoint != client.SpawnPoint,
Fingerprint = client.Fingerprint
};
playersByRuntime.Add(runtimePlayer, player);
@@ -131,9 +133,7 @@ namespace OpenRA
/// <summary>Gets the player information for the specified runtime player instance.</summary>
public Player GetPlayer(OpenRA.Player runtimePlayer)
{
Player player;
playersByRuntime.TryGetValue(runtimePlayer, out player);
playersByRuntime.TryGetValue(runtimePlayer, out var player);
return player;
}
@@ -154,7 +154,7 @@ namespace OpenRA
/// <summary>The faction ID, a.k.a. the faction's internal name.</summary>
public string FactionId;
public HSLColor Color;
public Color Color;
/// <summary>The team ID on start-up, or 0 if the player is not part of a team.</summary>
public int Team;
@@ -166,6 +166,9 @@ namespace OpenRA
/// <summary>True if the spawn point was chosen at random; otherwise, false.</summary>
public bool IsRandomSpawnPoint;
/// <summary>Player authentication fingerprint for the OpenRA forum.</summary>
public string Fingerprint;
#endregion
#region

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,6 +22,9 @@ namespace OpenRA
/// </summary>
public class ActorInfo
{
public const string AbstractActorPrefix = "^";
public const char TraitInstanceSeparator = '@';
/// <summary>
/// The actor name can be anything, but the sprites used in the Render*: traits default to this one.
/// If you add an ^ in front of the name, the engine will recognize this as a collection of traits
@@ -30,7 +33,7 @@ namespace OpenRA
/// </summary>
public readonly string Name;
readonly TypeDictionary traits = new TypeDictionary();
List<ITraitInfo> constructOrderCache = null;
List<TraitInfo> constructOrderCache = null;
public ActorInfo(ObjectCreator creator, string name, MiniYaml node)
{
@@ -38,19 +41,23 @@ namespace OpenRA
{
Name = name;
var abstractActorType = name.StartsWith("^");
foreach (var t in node.Nodes)
{
try
{
traits.Add(LoadTraitInfo(creator, t.Key.Split('@')[0], t.Value));
// HACK: The linter does not want to crash when a trait doesn't exist but only print an error instead
// LoadTraitInfo will only return null to signal us to abort here if the linter is running
var trait = LoadTraitInfo(creator, t.Key, t.Value);
if (trait != null)
traits.Add(trait);
}
catch (FieldLoader.MissingFieldsException e)
{
if (!abstractActorType)
throw new YamlException(e.Message);
throw new YamlException(e.Message);
}
}
traits.TrimExcess();
}
catch (YamlException e)
{
@@ -58,21 +65,32 @@ namespace OpenRA
}
}
public ActorInfo(string name, params ITraitInfo[] traitInfos)
public ActorInfo(string name, params TraitInfo[] traitInfos)
{
Name = name;
foreach (var t in traitInfos)
traits.Add(t);
traits.TrimExcess();
}
static ITraitInfo LoadTraitInfo(ObjectCreator creator, string traitName, MiniYaml my)
static TraitInfo LoadTraitInfo(ObjectCreator creator, string traitName, MiniYaml my)
{
if (!string.IsNullOrEmpty(my.Value))
throw new YamlException("Junk value `{0}` on trait node {1}"
.F(my.Value, traitName));
var info = creator.CreateObject<ITraitInfo>(traitName + "Info");
// HACK: The linter does not want to crash when a trait doesn't exist but only print an error instead
// ObjectCreator will only return null to signal us to abort here if the linter is running
var traitInstance = traitName.Split(TraitInstanceSeparator);
var info = creator.CreateObject<TraitInfo>(traitInstance[0] + "Info");
if (info == null)
return null;
try
{
if (traitInstance.Length > 1)
info.GetType().GetField("InstanceName").SetValue(info, traitInstance[1]);
FieldLoader.Load(info, my);
}
catch (FieldLoader.MissingFieldsException e)
@@ -84,12 +102,12 @@ namespace OpenRA
return info;
}
public IEnumerable<ITraitInfo> TraitsInConstructOrder()
public IEnumerable<TraitInfo> TraitsInConstructOrder()
{
if (constructOrderCache != null)
return constructOrderCache;
var source = traits.WithInterface<ITraitInfo>().Select(i => new
var source = traits.WithInterface<TraitInfo>().Select(i => new
{
Trait = i,
Type = i.GetType(),
@@ -135,7 +153,7 @@ namespace OpenRA
return constructOrderCache;
}
public static IEnumerable<Type> PrerequisitesOf(ITraitInfo info)
public static IEnumerable<Type> PrerequisitesOf(TraitInfo info)
{
return info
.GetType()
@@ -144,23 +162,18 @@ namespace OpenRA
.Select(t => t.GetGenericArguments()[0]);
}
public IEnumerable<Pair<string, Type>> GetInitKeys()
{
var inits = traits.WithInterface<ITraitInfo>().SelectMany(
t => t.GetType().GetInterfaces()
.Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(UsesInit<>))
.Select(i => i.GetGenericArguments()[0])).ToList();
inits.Add(typeof(OwnerInit)); /* not exposed by a trait; this is used by the Actor itself */
return inits.Select(
i => Pair.New(
i.Name.Replace("Init", ""), i));
}
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>(); }
public IEnumerable<T> TraitInfos<T>() where T : ITraitInfoInterface { return traits.WithInterface<T>(); }
public BitSet<TargetableType> GetAllTargetTypes()
{
// PERF: Avoid LINQ.
var targetTypes = default(BitSet<TargetableType>);
foreach (var targetable in TraitInfos<ITargetableInfo>())
targetTypes = targetTypes.Union(targetable.GetTargetTypes());
return targetTypes;
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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.IO;
using OpenRA.FileFormats;
using OpenRA.FileSystem;
namespace OpenRA.GameRules
@@ -20,6 +19,7 @@ namespace OpenRA.GameRules
public readonly string Filename;
public readonly string Title;
public readonly bool Hidden;
public readonly float VolumeModifier = 1f;
public int Length { get; private set; } // seconds
public bool Exists { get; private set; }
@@ -32,14 +32,16 @@ namespace OpenRA.GameRules
if (nd.ContainsKey("Hidden"))
bool.TryParse(nd["Hidden"].Value, out Hidden);
if (nd.ContainsKey("VolumeModifier"))
VolumeModifier = FieldLoader.GetValue<float>("VolumeModifier", nd["VolumeModifier"].Value);
var ext = nd.ContainsKey("Extension") ? nd["Extension"].Value : "aud";
Filename = (nd.ContainsKey("Filename") ? nd["Filename"].Value : key) + "." + ext;
}
public void Load(IReadOnlyFileSystem fileSystem)
{
Stream stream;
if (!fileSystem.TryOpen(Filename, out stream))
if (!fileSystem.TryOpen(Filename, out var stream))
return;
try
@@ -47,8 +49,7 @@ namespace OpenRA.GameRules
Exists = true;
foreach (var loader in Game.ModData.SoundLoaders)
{
ISoundFormat soundFormat;
if (loader.TryParseSound(stream, out soundFormat))
if (loader.TryParseSound(stream, out var soundFormat))
{
Length = (int)soundFormat.LengthInSeconds;
soundFormat.Dispose();

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,6 +29,7 @@ namespace OpenRA
public readonly IReadOnlyDictionary<string, MusicInfo> Music;
public readonly TileSet TileSet;
public readonly SequenceProvider Sequences;
public readonly IReadOnlyDictionary<string, MiniYamlNode> ModelSequences;
public Ruleset(
IReadOnlyDictionary<string, ActorInfo> actors,
@@ -37,7 +38,8 @@ namespace OpenRA
IReadOnlyDictionary<string, SoundInfo> notifications,
IReadOnlyDictionary<string, MusicInfo> music,
TileSet tileSet,
SequenceProvider sequences)
SequenceProvider sequences,
IReadOnlyDictionary<string, MiniYamlNode> modelSequences)
{
Actors = actors;
Weapons = weapons;
@@ -46,6 +48,7 @@ namespace OpenRA
Music = music;
TileSet = tileSet;
Sequences = sequences;
ModelSequences = modelSequences;
foreach (var a in Actors.Values)
{
@@ -64,6 +67,19 @@ namespace OpenRA
foreach (var weapon in Weapons)
{
var projectileLoaded = weapon.Value.Projectile as IRulesetLoaded<WeaponInfo>;
if (projectileLoaded != null)
{
try
{
projectileLoaded.RulesetLoaded(this, weapon.Value);
}
catch (YamlException e)
{
throw new YamlException("Projectile type {0}: {1}".F(weapon.Key, e.Message));
}
}
foreach (var warhead in weapon.Value.Warheads)
{
var cacher = warhead as IRulesetLoaded<WeaponInfo>;
@@ -84,16 +100,24 @@ namespace OpenRA
public IEnumerable<KeyValuePair<string, MusicInfo>> InstalledMusic { get { return Music.Where(m => m.Value.Exists); } }
static IReadOnlyDictionary<string, T> MergeOrDefault<T>(string name, IReadOnlyFileSystem fileSystem, IEnumerable<string> files, MiniYaml additional,
IReadOnlyDictionary<string, T> defaults, Func<MiniYamlNode, T> makeObject)
static IReadOnlyDictionary<string, T> MergeOrDefault<T>(string name,
IReadOnlyFileSystem fileSystem,
IEnumerable<string> files,
MiniYaml additional,
IReadOnlyDictionary<string, T> defaults,
Func<MiniYamlNode, T> makeObject,
Func<MiniYamlNode, bool> filterNode = null)
{
if (additional == null && defaults != null)
return defaults;
var result = MiniYaml.Load(fileSystem, files, additional)
.ToDictionaryWithConflictLog(k => k.Key.ToLowerInvariant(), makeObject, "LoadFromManifest<" + name + ">");
IEnumerable<MiniYamlNode> yamlNodes = MiniYaml.Load(fileSystem, files, additional);
return new ReadOnlyDictionary<string, T>(result);
// Optionally, the caller can filter out elements from the loaded set of nodes. Default behavior is unfiltered.
if (filterNode != null)
yamlNodes = yamlNodes.Where(k => !filterNode(k));
return new ReadOnlyDictionary<string, T>(yamlNodes.ToDictionaryWithConflictLog(k => k.Key.ToLowerInvariant(), makeObject, "LoadFromManifest<" + name + ">"));
}
public static Ruleset LoadDefaults(ModData modData)
@@ -105,7 +129,8 @@ namespace OpenRA
Action f = () =>
{
var actors = MergeOrDefault("Manifest,Rules", fs, m.Rules, null, null,
k => new ActorInfo(modData.ObjectCreator, k.Key.ToLowerInvariant(), k.Value));
k => new ActorInfo(modData.ObjectCreator, k.Key.ToLowerInvariant(), k.Value),
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));
@@ -119,8 +144,11 @@ namespace OpenRA
var music = MergeOrDefault("Manifest,Music", fs, m.Music, null, null,
k => new MusicInfo(k.Key, k.Value));
var modelSequences = MergeOrDefault("Manifest,ModelSequences", fs, m.ModelSequences, null, null,
k => k);
// The default ruleset does not include a preferred tileset or sequence set
ruleset = new Ruleset(actors, weapons, voices, notifications, music, null, null);
ruleset = new Ruleset(actors, weapons, voices, notifications, music, null, null, modelSequences);
};
if (modData.IsOnMainThread)
@@ -145,12 +173,13 @@ namespace OpenRA
var dr = modData.DefaultRules;
var ts = modData.DefaultTileSets[tileSet];
var sequences = modData.DefaultSequences[tileSet];
return new Ruleset(dr.Actors, dr.Weapons, dr.Voices, dr.Notifications, dr.Music, ts, sequences);
return new Ruleset(dr.Actors, dr.Weapons, dr.Voices, dr.Notifications, dr.Music, ts, sequences, dr.ModelSequences);
}
public static Ruleset Load(ModData modData, IReadOnlyFileSystem fileSystem, string tileSet,
MiniYaml mapRules, MiniYaml mapWeapons, MiniYaml mapVoices, MiniYaml mapNotifications,
MiniYaml mapMusic, MiniYaml mapSequences)
MiniYaml mapMusic, MiniYaml mapSequences, MiniYaml mapModelSequences)
{
var m = modData.Manifest;
var dr = modData.DefaultRules;
@@ -159,7 +188,8 @@ namespace OpenRA
Action f = () =>
{
var actors = MergeOrDefault("Rules", fileSystem, m.Rules, mapRules, dr.Actors,
k => new ActorInfo(modData.ObjectCreator, k.Key.ToLowerInvariant(), k.Value));
k => new ActorInfo(modData.ObjectCreator, k.Key.ToLowerInvariant(), k.Value),
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));
@@ -180,8 +210,12 @@ namespace OpenRA
var sequences = mapSequences == null ? modData.DefaultSequences[tileSet] :
new SequenceProvider(fileSystem, modData, ts, mapSequences);
// TODO: Add support for custom voxel sequences
ruleset = new Ruleset(actors, weapons, voices, notifications, music, ts, sequences);
var modelSequences = dr.ModelSequences;
if (mapModelSequences != null)
modelSequences = MergeOrDefault("ModelSequences", fileSystem, m.ModelSequences, mapModelSequences, dr.ModelSequences,
k => k);
ruleset = new Ruleset(actors, weapons, voices, notifications, music, ts, sequences, modelSequences);
};
if (modData.IsOnMainThread)
@@ -216,10 +250,13 @@ namespace OpenRA
{
var traitName = traitNode.Key.Split('@')[0];
var traitType = modData.ObjectCreator.FindType(traitName + "Info");
if (traitType.GetInterface("ILobbyCustomRulesIgnore") == null)
if (traitType != null && traitType.GetInterface("ILobbyCustomRulesIgnore") == null)
return true;
}
catch { }
catch (Exception ex)
{
Log.Write("debug", "Error in AnyFlaggedTraits\r\n" + ex.ToString());
}
}
}
@@ -230,7 +267,7 @@ namespace OpenRA
MiniYaml mapRules, MiniYaml mapWeapons, MiniYaml mapVoices, MiniYaml mapNotifications, MiniYaml mapSequences)
{
// Maps that define any weapon, voice, notification, or sequence overrides are always flagged
if (AnyCustomYaml(mapWeapons) || AnyCustomYaml(mapVoices) || AnyCustomYaml(mapNotifications) || AnyCustomYaml(mapSequences))
if (AnyCustomYaml(mapWeapons) || AnyCustomYaml(mapVoices) || AnyCustomYaml(mapNotifications) || AnyCustomYaml(mapSequences))
return true;
// Any trait overrides that aren't explicitly whitelisted are flagged

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,18 +33,39 @@ namespace OpenRA.GameRules
{
FieldLoader.Load(this, y);
VoicePools = Exts.Lazy(() => Voices.ToDictionary(a => a.Key, a => new SoundPool(a.Value)));
NotificationsPools = Exts.Lazy(() => Notifications.ToDictionary(a => a.Key, a => new SoundPool(a.Value)));
VoicePools = Exts.Lazy(() => Voices.ToDictionary(a => a.Key, a => new SoundPool(1f, a.Value)));
NotificationsPools = Exts.Lazy(() => ParseSoundPool(y, "Notifications"));
}
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");
if (volumeModifierNode != null)
volumeModifier = FieldLoader.GetValue<float>(volumeModifierNode.Key, volumeModifierNode.Value.Value);
var names = FieldLoader.GetValue<string[]>(t.Key, t.Value.Value);
var sp = new SoundPool(volumeModifier, names);
ret.Add(t.Key, sp);
}
return ret;
}
}
public class SoundPool
{
public readonly float VolumeModifier;
readonly string[] clips;
readonly List<string> liveclips = new List<string>();
public SoundPool(params string[] clips)
public SoundPool(float volumeModifier, params string[] clips)
{
VolumeModifier = volumeModifier;
this.clips = clips;
}
@@ -53,8 +74,9 @@ namespace OpenRA.GameRules
if (liveclips.Count == 0)
liveclips.AddRange(clips);
// Avoid crashing if there's no clips at all
if (liveclips.Count == 0)
return null; /* avoid crashing if there's no clips at all */
return null;
var i = Game.CosmeticRandom.Next(liveclips.Count);
var s = liveclips[i];

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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
@@ -13,6 +13,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Effects;
using OpenRA.Primitives;
using OpenRA.Traits;
namespace OpenRA.GameRules
@@ -23,7 +24,8 @@ namespace OpenRA.GameRules
public int[] DamageModifiers;
public int[] InaccuracyModifiers;
public int[] RangeModifiers;
public int Facing;
public WAngle Facing;
public Func<WAngle> CurrentMuzzleFacing;
public WPos Source;
public Func<WPos> CurrentSource;
public Actor SourceActor;
@@ -31,6 +33,40 @@ namespace OpenRA.GameRules
public Target GuidedTarget;
}
public class WarheadArgs
{
public WeaponInfo Weapon;
public int[] DamageModifiers = { };
public WPos? Source;
public WRot ImpactOrientation;
public WPos ImpactPosition;
public Actor SourceActor;
public Target WeaponTarget;
public WarheadArgs(ProjectileArgs args)
{
Weapon = args.Weapon;
DamageModifiers = args.DamageModifiers;
ImpactPosition = args.PassiveTarget;
Source = args.Source;
SourceActor = args.SourceActor;
WeaponTarget = args.GuidedTarget;
}
// For places that only want to update some of the fields (usually DamageModifiers)
public WarheadArgs(WarheadArgs args)
{
Weapon = args.Weapon;
DamageModifiers = args.DamageModifiers;
Source = args.Source;
SourceActor = args.SourceActor;
WeaponTarget = args.WeaponTarget;
}
// Default empty constructor for callers that want to initialize fields themselves
public WarheadArgs() { }
}
public interface IProjectile : IEffect { }
public interface IProjectileInfo { IProjectile Create(ProjectileArgs args); }
@@ -39,9 +75,24 @@ namespace OpenRA.GameRules
[Desc("The maximum range the weapon can fire.")]
public readonly WDist Range = WDist.Zero;
[Desc("The sound played when the weapon is fired.")]
[Desc("First burst is aimed at this offset relative to target position.")]
public readonly WVec FirstBurstTargetOffset = WVec.Zero;
[Desc("Each burst after the first lands by this offset away from the previous burst.")]
public readonly WVec FollowingBurstTargetOffset = WVec.Zero;
[Desc("The sound played each time the weapon is fired.")]
public readonly string[] Report = null;
[Desc("Sound played only on first burst in a salvo.")]
public readonly string[] StartBurstReport = null;
[Desc("The sound played when the weapon is reloaded.")]
public readonly string[] AfterFireSound = null;
[Desc("Delay in ticks to play reloading sound.")]
public readonly int AfterFireSoundDelay = 0;
[Desc("Delay in ticks between reloading ammo magazines.")]
public readonly int ReloadDelay = 1;
@@ -49,17 +100,27 @@ namespace OpenRA.GameRules
public readonly int Burst = 1;
[Desc("What types of targets are affected.")]
public readonly HashSet<string> ValidTargets = new HashSet<string> { "Ground", "Water" };
public readonly BitSet<TargetableType> ValidTargets = new BitSet<TargetableType>("Ground", "Water");
[Desc("What types of targets are unaffected.", "Overrules ValidTargets.")]
public readonly HashSet<string> InvalidTargets = new HashSet<string>();
public readonly BitSet<TargetableType> InvalidTargets;
[Desc("Delay in ticks between firing shots from the same ammo magazine.")]
public readonly int BurstDelay = 5;
static readonly BitSet<TargetableType> TargetTypeAir = new BitSet<TargetableType>("Air");
[Desc("If weapon is not directly targeting an actor and targeted position is above this altitude,",
"the weapon will ignore terrain target types and only check TargetTypeAir for validity.")]
public readonly WDist AirThreshold = new WDist(128);
[Desc("Delay in ticks between firing shots from the same ammo magazine. If one entry, it will be used for all bursts.",
"If multiple entries, their number needs to match Burst - 1.")]
public readonly int[] BurstDelays = { 5 };
[Desc("The minimum range the weapon can fire.")]
public readonly WDist MinRange = WDist.Zero;
[Desc("Does this weapon aim at the target's center regardless of other targetable offsets?")]
public readonly bool TargetActorCenter = false;
[FieldLoader.LoadUsing("LoadProjectile")]
public readonly IProjectileInfo Projectile;
@@ -76,8 +137,7 @@ namespace OpenRA.GameRules
static object LoadProjectile(MiniYaml yaml)
{
MiniYaml proj;
if (!yaml.ToDictionary().TryGetValue("Projectile", out proj))
if (!yaml.ToDictionary().TryGetValue("Projectile", out var proj))
return null;
var ret = Game.CreateObject<IProjectileInfo>(proj.Value + "Info");
FieldLoader.Load(ret, proj);
@@ -97,7 +157,7 @@ namespace OpenRA.GameRules
return retList;
}
public bool IsValidTarget(IEnumerable<string> targetTypes)
public bool IsValidTarget(BitSet<TargetableType> targetTypes)
{
return ValidTargets.Overlaps(targetTypes) && !InvalidTargets.Overlaps(targetTypes);
}
@@ -113,6 +173,10 @@ namespace OpenRA.GameRules
if (target.Type == TargetType.Terrain)
{
var dat = world.Map.DistanceAboveTerrain(target.CenterPosition);
if (dat > AirThreshold)
return IsValidTarget(TargetTypeAir);
var cell = world.Map.CellContaining(target.CenterPosition);
if (!world.Map.Contains(cell))
return false;
@@ -156,17 +220,33 @@ namespace OpenRA.GameRules
}
/// <summary>Applies all the weapon's warheads to the target.</summary>
public void Impact(Target target, Actor firedBy, IEnumerable<int> damageModifiers)
public void Impact(Target target, WarheadArgs args)
{
var world = args.SourceActor.World;
foreach (var warhead in Warheads)
{
var wh = warhead; // force the closure to bind to the current warhead
if (wh.Delay > 0)
firedBy.World.AddFrameEndTask(w => w.Add(new DelayedImpact(wh.Delay, wh, target, firedBy, damageModifiers)));
if (warhead.Delay > 0)
world.AddFrameEndTask(w => w.Add(new DelayedImpact(warhead.Delay, warhead, target, args)));
else
wh.DoImpact(target, firedBy, damageModifiers);
warhead.DoImpact(target, args);
}
}
/// <summary>Applies all the weapon's warheads to the target. Only use for projectile-less, special-case impacts.</summary>
public void Impact(Target target, Actor firedBy)
{
// The impact will happen immediately at target.CenterPosition.
var args = new WarheadArgs
{
Weapon = this,
SourceActor = firedBy,
WeaponTarget = target
};
if (firedBy.OccupiesSpace != null)
args.Source = firedBy.CenterPosition;
Impact(target, args);
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,391 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 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
using System;
using System.Collections;
using System.Linq;
using System.Threading;
using Meebey.SmartIrc4net;
using OpenRA.Primitives;
namespace OpenRA.Chat
{
public enum ChatConnectionStatus { Disconnected, Connecting, Connected, Disconnecting, Joined, Error }
public enum ChatMessageType { Message, Notification }
public sealed class ChatUser
{
public readonly string Name;
public bool IsOp;
public bool IsVoiced;
public ChatUser(string name, bool isOp, bool isVoice)
{
Name = name;
IsOp = isOp;
IsVoiced = isVoice;
}
}
public sealed class ChatMessage
{
static long nextUID;
public readonly DateTime Time;
public readonly ChatMessageType Type;
public readonly string Nick;
public readonly string Message;
public readonly string UID;
public ChatMessage(DateTime time, ChatMessageType type, string nick, string message)
{
Time = time;
Type = type;
Nick = nick;
Message = message;
UID = Interlocked.Increment(ref nextUID).ToString();
}
public override string ToString()
{
var time = Time.ToString(Game.Settings.Chat.TimestampFormat);
if (Type == ChatMessageType.Notification)
return "{0} {1}".F(time, Message);
return "{0} {1}: {2}".F(time, Nick, Message);
}
}
public sealed class GlobalChat : IDisposable
{
readonly IrcClient client = new IrcClient();
volatile Channel channel;
public readonly ObservableSortedDictionary<string, ChatUser> Users = new ObservableSortedDictionary<string, ChatUser>(StringComparer.InvariantCultureIgnoreCase);
public readonly ObservableList<ChatMessage> History = new ObservableList<ChatMessage>();
volatile string topic;
public string Topic { get { return topic; } }
volatile ChatConnectionStatus connectionStatus = ChatConnectionStatus.Disconnected;
public ChatConnectionStatus ConnectionStatus { get { return connectionStatus; } }
public GlobalChat()
{
client.Encoding = System.Text.Encoding.UTF8;
client.SendDelay = 100;
client.ActiveChannelSyncing = true;
client.OnConnecting += OnConnecting;
client.OnConnected += OnConnected;
client.OnDisconnecting += OnDisconnecting;
client.OnDisconnected += OnDisconnected;
client.OnError += OnError;
client.OnKick += OnKick;
client.OnRawMessage += (_, e) => Game.RunAfterTick(() => Log.Write("irc", e.Data.RawMessage));
client.OnJoin += OnJoin;
client.OnChannelActiveSynced += OnChannelActiveSynced;
client.OnTopic += (_, e) => topic = e.Topic;
client.OnTopicChange += (_, e) => topic = e.NewTopic;
client.OnNickChange += OnNickChange;
client.OnChannelMessage += (_, e) => AddMessage(e.Data.Nick, e.Data.Message);
client.OnOp += (_, e) => SetUserOp(e.Whom, true);
client.OnDeop += (_, e) => SetUserOp(e.Whom, false);
client.OnVoice += (_, e) => SetUserVoiced(e.Whom, true);
client.OnDevoice += (_, e) => SetUserVoiced(e.Whom, false);
client.OnPart += OnPart;
client.OnQuit += OnQuit;
TrySetNickname(Game.Settings.Player.Name);
}
void SetUserOp(string whom, bool isOp)
{
Game.RunAfterTick(() =>
{
ChatUser user;
if (Users.TryGetValue(whom, out user))
user.IsOp = isOp;
});
}
void SetUserVoiced(string whom, bool isVoiced)
{
Game.RunAfterTick(() =>
{
ChatUser user;
if (Users.TryGetValue(whom, out user))
user.IsVoiced = isVoiced;
});
}
public void Connect()
{
if (client.IsConnected)
return;
new Thread(() =>
{
try
{
client.Connect(Game.Settings.Chat.Hostname, Game.Settings.Chat.Port);
}
catch (Exception e)
{
connectionStatus = ChatConnectionStatus.Error;
AddNotification(e.Message);
Game.RunAfterTick(() => Log.Write("irc", e.ToString()));
return;
}
client.Listen();
}) { Name = "IrcListenThread", IsBackground = true }.Start();
}
void AddNotification(string text)
{
var message = new ChatMessage(DateTime.Now, ChatMessageType.Notification, null, text);
Game.RunAfterTick(() =>
{
History.Add(message);
Log.Write("irc", text);
});
}
void AddMessage(string nick, string text)
{
var message = new ChatMessage(DateTime.Now, ChatMessageType.Message, nick, text);
Game.RunAfterTick(() =>
{
History.Add(message);
Log.Write("irc", text);
});
}
void OnConnecting(object sender, EventArgs e)
{
AddNotification("Connecting to {0}:{1}...".F(Game.Settings.Chat.Hostname, Game.Settings.Chat.Port));
connectionStatus = ChatConnectionStatus.Connecting;
}
void OnConnected(object sender, EventArgs e)
{
AddNotification("Connected.");
connectionStatus = ChatConnectionStatus.Connected;
// Guard against settings.yaml modification
var nick = SanitizedName(Game.Settings.Chat.Nickname);
if (nick != Game.Settings.Chat.Nickname)
Game.RunAfterTick(() => Game.Settings.Chat.Nickname = nick);
client.Login(nick, "in-game IRC client", 0, "OpenRA");
client.RfcJoin("#" + Game.Settings.Chat.Channel);
}
void OnDisconnecting(object sender, EventArgs e)
{
if (connectionStatus != ChatConnectionStatus.Error)
connectionStatus = ChatConnectionStatus.Disconnecting;
}
void OnDisconnected(object sender, EventArgs e)
{
Game.RunAfterTick(Users.Clear);
// Keep the chat window open if there is an error
// It will be cleared by the Disconnect button
if (connectionStatus != ChatConnectionStatus.Error)
{
Game.RunAfterTick(History.Clear);
topic = null;
connectionStatus = ChatConnectionStatus.Disconnected;
}
}
void OnError(object sender, ErrorEventArgs e)
{
// Ignore any errors that happen during disconnect
if (connectionStatus != ChatConnectionStatus.Disconnecting)
{
connectionStatus = ChatConnectionStatus.Error;
AddNotification("Error: " + e.ErrorMessage);
}
}
void OnKick(object sender, KickEventArgs e)
{
if (e.Whom == client.Nickname)
{
Disconnect();
connectionStatus = ChatConnectionStatus.Error;
AddNotification("You were kicked from the chat by {0}. ({1})".F(e.Who, e.KickReason));
}
else
{
Users.Remove(e.Whom);
AddNotification("{0} was kicked from the chat by {1}. ({2})".F(e.Whom, e.Who, e.KickReason));
}
}
void OnJoin(object sender, JoinEventArgs e)
{
if (e.Who == client.Nickname || channel == null || e.Channel != channel.Name)
return;
AddNotification("{0} joined the chat.".F(e.Who));
Game.RunAfterTick(() => Users.Add(e.Who, new ChatUser(e.Who, false, false)));
}
void OnChannelActiveSynced(object sender, IrcEventArgs e)
{
channel = client.GetChannel(e.Data.Channel);
AddNotification("{0} users online".F(channel.Users.Count));
connectionStatus = ChatConnectionStatus.Joined;
foreach (DictionaryEntry user in channel.Users)
{
var u = (ChannelUser)user.Value;
Game.RunAfterTick(() => Users.Add(u.Nick, new ChatUser(u.Nick, u.IsOp, u.IsVoice)));
}
}
void OnNickChange(object sender, NickChangeEventArgs e)
{
AddNotification("{0} is now known as {1}.".F(e.OldNickname, e.NewNickname));
Game.RunAfterTick(() =>
{
ChatUser user;
if (!Users.TryGetValue(e.OldNickname, out user))
return;
Users.Remove(e.OldNickname);
Users.Add(e.NewNickname, new ChatUser(e.NewNickname, user.IsOp, user.IsVoiced));
});
}
void OnQuit(object sender, QuitEventArgs e)
{
AddNotification("{0} left the chat.".F(e.Who));
Game.RunAfterTick(() => Users.Remove(e.Who));
}
void OnPart(object sender, PartEventArgs e)
{
if (channel == null || e.Data.Channel != channel.Name)
return;
AddNotification("{0} left the chat.".F(e.Who));
Game.RunAfterTick(() => Users.Remove(e.Who));
}
public string SanitizedName(string dirty)
{
if (string.IsNullOrEmpty(dirty))
return null;
// There is no need to mangle the nick if it is already valid
if (Rfc2812.IsValidNickname(dirty))
return dirty;
// TODO: some special chars are allowed as well, but not at every position
var clean = new string(dirty.Where(c => char.IsLetterOrDigit(c)).ToArray());
if (string.IsNullOrEmpty(clean))
return null;
if (char.IsDigit(clean[0]))
return SanitizedName(clean.Substring(1));
// Source: https://tools.ietf.org/html/rfc2812#section-1.2.1
if (clean.Length > 9)
clean = clean.Substring(0, 9);
return clean;
}
public bool IsValidNickname(string name)
{
return Rfc2812.IsValidNickname(name);
}
public void SendMessage(string text)
{
if (connectionStatus != ChatConnectionStatus.Joined)
return;
// Guard against a last-moment disconnection
try
{
client.SendMessage(SendType.Message, channel.Name, text);
AddMessage(client.Nickname, text);
}
catch (NotConnectedException) { }
}
public bool TrySetNickname(string nick)
{
// TODO: This is inconsistent with the other check
if (Rfc2812.IsValidNickname(nick))
{
client.RfcNick(nick);
Game.Settings.Chat.Nickname = nick;
return true;
}
return false;
}
public void Disconnect()
{
// Error is an alias for disconnect, but keeps the panel open
// so that clients can see the error
if (connectionStatus == ChatConnectionStatus.Error)
{
Game.RunAfterTick(History.Clear);
topic = null;
connectionStatus = ChatConnectionStatus.Disconnected;
}
else
connectionStatus = ChatConnectionStatus.Disconnecting;
if (!client.IsConnected)
return;
client.RfcQuit(Game.Settings.Chat.QuitMessage);
AddNotification("Disconnecting from {0}...".F(client.Address));
Game.RunAfterTick(() => Game.Settings.Chat.ConnectAutomatically = false);
}
public void Dispose()
{
// HACK: The IRC library we are using has terrible thread-handling code that relies on Thread.Abort.
// There is a thread reading from the network socket which is aborted, however on Windows this is inside
// native code so this abort call hangs until the network socket reads something and returns to managed
// code where it can then be aborted.
//
// This means we may hang for several seconds during shutdown (until we receive something over IRC!) before
// closing.
//
// Since our IRC client currently lives forever, the only time we call this Dispose method is during the
// shutdown of our process. Therefore, we can work around the problem by just not bothering to disconnect
// properly. Since our process is about to die anyway, it's not like anyone will care.
////if (client.IsConnected)
//// client.Disconnect();
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,8 +10,8 @@
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Primitives;
using OpenRA.Support;
namespace OpenRA.Graphics
@@ -23,7 +23,7 @@ namespace OpenRA.Graphics
public bool IsDecoration { get; set; }
readonly SequenceProvider sequenceProvider;
readonly Func<int> facingFunc;
readonly Func<WAngle> facingFunc;
readonly Func<bool> paused;
int frame;
@@ -33,15 +33,15 @@ namespace OpenRA.Graphics
Action tickFunc = () => { };
public Animation(World world, string name)
: this(world, name, () => 0) { }
: this(world, name, () => WAngle.Zero) { }
public Animation(World world, string name, Func<int> facingFunc)
public Animation(World world, string name, Func<WAngle> facingFunc)
: this(world, name, facingFunc, null) { }
public Animation(World world, string name, Func<bool> paused)
: this(world, name, () => 0, paused) { }
: this(world, name, () => WAngle.Zero, paused) { }
public Animation(World world, string name, Func<int> facingFunc, Func<bool> paused)
public Animation(World world, string name, Func<WAngle> facingFunc, Func<bool> paused)
{
sequenceProvider = world.Map.Rules.Sequences;
Name = name.ToLowerInvariant();
@@ -49,24 +49,52 @@ namespace OpenRA.Graphics
this.paused = paused;
}
public int CurrentFrame { get { return backwards ? CurrentSequence.Start + CurrentSequence.Length - frame - 1 : frame; } }
public int CurrentFrame { get { return backwards ? CurrentSequence.Length - frame - 1 : frame; } }
public Sprite Image { get { return CurrentSequence.GetSprite(CurrentFrame, facingFunc()); } }
public IEnumerable<IRenderable> Render(WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale)
public IRenderable[] Render(WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale)
{
var imageRenderable = new SpriteRenderable(Image, pos, offset, CurrentSequence.ZOffset + zOffset, palette, scale, IsDecoration);
var imageRenderable = new SpriteRenderable(Image, pos, offset, CurrentSequence.ZOffset + zOffset, palette, scale, IsDecoration, CurrentSequence.IgnoreWorldTint);
if (CurrentSequence.ShadowStart >= 0)
{
var shadow = CurrentSequence.GetShadow(CurrentFrame, facingFunc());
var shadowRenderable = new SpriteRenderable(shadow, pos, offset, CurrentSequence.ShadowZOffset + zOffset, palette, scale, true);
var shadowRenderable = new SpriteRenderable(shadow, pos, offset, CurrentSequence.ShadowZOffset + zOffset, palette, scale, true, CurrentSequence.IgnoreWorldTint);
return new IRenderable[] { shadowRenderable, imageRenderable };
}
return new IRenderable[] { imageRenderable };
}
public IEnumerable<IRenderable> Render(WPos pos, PaletteReference palette)
public IRenderable[] RenderUI(WorldRenderer wr, int2 pos, WVec offset, int zOffset, PaletteReference palette, float 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 imageRenderable = new UISpriteRenderable(Image, WPos.Zero + offset, imagePos, CurrentSequence.ZOffset + zOffset, palette, scale);
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);
return new IRenderable[] { shadowRenderable, imageRenderable };
}
return new IRenderable[] { imageRenderable };
}
public Rectangle ScreenBounds(WorldRenderer wr, WPos pos, WVec offset, float scale)
{
var xy = wr.ScreenPxPosition(pos) + wr.ScreenPxOffset(offset);
var cb = CurrentSequence.Bounds;
return Rectangle.FromLTRB(
xy.X + (int)(cb.Left * scale),
xy.Y + (int)(cb.Top * scale),
xy.X + (int)(cb.Right * scale),
xy.Y + (int)(cb.Bottom * scale));
}
public IRenderable[] Render(WPos pos, PaletteReference palette)
{
return Render(pos, WVec.Zero, 0, palette, 1f);
}
@@ -128,7 +156,7 @@ namespace OpenRA.Graphics
{
frame = CurrentSequence.Length - 1;
tickFunc = () => { };
if (after != null) after();
after?.Invoke();
}
};
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,7 @@
#endregion
using System;
using System.Collections.Generic;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
@@ -35,7 +35,7 @@ namespace OpenRA.Graphics
ZOffset = zOffset;
}
public IEnumerable<IRenderable> Render(Actor self, WorldRenderer wr, PaletteReference pal, float scale)
public IRenderable[] Render(Actor self, WorldRenderer wr, PaletteReference pal, float scale)
{
var center = self.CenterPosition;
var offset = OffsetFunc != null ? OffsetFunc() : WVec.Zero;
@@ -44,9 +44,17 @@ namespace OpenRA.Graphics
return Animation.Render(center, offset, z, pal, scale);
}
public Rectangle ScreenBounds(Actor self, WorldRenderer wr, float scale)
{
var center = self.CenterPosition;
var offset = OffsetFunc != null ? OffsetFunc() : WVec.Zero;
return Animation.ScreenBounds(wr, center, offset, scale);
}
public static implicit operator AnimationWithOffset(Animation a)
{
return new AnimationWithOffset(a, null, null, null);
}
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,81 +9,140 @@
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.FileSystem;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
[Flags]
public enum PanelSides
{
Left = 1,
Top = 2,
Right = 4,
Bottom = 8,
Center = 16,
Edges = Left | Top | Right | Bottom,
All = Edges | Center,
}
public static class PanelSidesExts
{
public static bool HasSide(this PanelSides self, PanelSides m)
{
// PERF: Enum.HasFlag is slower and requires allocations.
return (self & m) == m;
}
}
public static class ChromeProvider
{
struct Collection
public class Collection
{
public string Src;
public Dictionary<string, MappedImage> Regions;
public readonly string Image = null;
public readonly string Image2x = null;
public readonly string Image3x = null;
public readonly int[] PanelRegion = null;
public readonly PanelSides PanelSides = PanelSides.All;
public readonly Dictionary<string, Rectangle> Regions = new Dictionary<string, Rectangle>();
}
public static IReadOnlyDictionary<string, Collection> Collections { get; private set; }
static Dictionary<string, Collection> collections;
static Dictionary<string, Sheet> cachedSheets;
static Dictionary<string, (Sheet Sheet, int Density)> cachedSheets;
static Dictionary<string, Dictionary<string, Sprite>> cachedSprites;
static Dictionary<string, Sprite[]> cachedPanelSprites;
static Dictionary<Collection, (Sheet Sheet, int)> cachedCollectionSheets;
static IReadOnlyFileSystem fileSystem;
static float dpiScale = 1;
public static void Initialize(ModData modData)
{
Deinitialize();
// Load higher resolution images if available on HiDPI displays
if (Game.Renderer != null)
dpiScale = Game.Renderer.WindowScale;
fileSystem = modData.DefaultFileSystem;
collections = new Dictionary<string, Collection>();
cachedSheets = new Dictionary<string, Sheet>();
cachedSheets = new Dictionary<string, (Sheet, int)>();
cachedSprites = new Dictionary<string, Dictionary<string, Sprite>>();
cachedPanelSprites = new Dictionary<string, Sprite[]>();
cachedCollectionSheets = new Dictionary<Collection, (Sheet, int)>();
Collections = new ReadOnlyDictionary<string, Collection>(collections);
var chrome = MiniYaml.Merge(modData.Manifest.Chrome
.Select(s => MiniYaml.FromStream(fileSystem.Open(s), s)));
foreach (var c in chrome)
LoadCollection(c.Key, c.Value);
if (!c.Key.StartsWith("^", StringComparison.Ordinal))
LoadCollection(c.Key, c.Value);
}
public static void Deinitialize()
{
if (cachedSheets != null)
foreach (var sheet in cachedSheets.Values)
sheet.Dispose();
sheet.Sheet.Dispose();
collections = null;
cachedSheets = null;
cachedSprites = null;
}
public static void Save(string file)
{
var root = new List<MiniYamlNode>();
foreach (var kv in collections)
root.Add(new MiniYamlNode(kv.Key, SaveCollection(kv.Value)));
root.WriteToFile(file);
}
static MiniYaml SaveCollection(Collection collection)
{
var root = new List<MiniYamlNode>();
foreach (var kv in collection.Regions)
root.Add(new MiniYamlNode(kv.Key, kv.Value.Save(collection.Src)));
return new MiniYaml(collection.Src, root);
cachedPanelSprites = null;
cachedCollectionSheets = null;
}
static void LoadCollection(string name, MiniYaml yaml)
{
if (Game.ModData.LoadScreen != null)
Game.ModData.LoadScreen.Display();
var collection = new Collection()
{
Src = yaml.Value,
Regions = yaml.Nodes.ToDictionary(n => n.Key, n => new MappedImage(yaml.Value, n.Value))
};
collections.Add(name, collection);
collections.Add(name, FieldLoader.Load<Collection>(yaml));
}
static (Sheet Sheet, int Density) SheetForCollection(Collection c)
{
// Outer cache avoids recalculating image names
if (!cachedCollectionSheets.TryGetValue(c, out (Sheet, int) sheetDensity))
{
var image = c.Image;
var density = 1;
if (dpiScale > 2 && !string.IsNullOrEmpty(c.Image3x))
{
image = c.Image3x;
density = 3;
}
else if (dpiScale > 1 && !string.IsNullOrEmpty(c.Image2x))
{
image = c.Image2x;
density = 2;
}
// Inner cache makes sure we share sheets between collections
if (!cachedSheets.TryGetValue(image, out sheetDensity))
{
Sheet sheet;
using (var stream = fileSystem.Open(image))
sheet = new Sheet(SheetType.BGRA, stream);
sheet.GetTexture().ScaleFilter = TextureScaleFilter.Linear;
sheetDensity = (sheet, density);
cachedSheets.Add(image, sheetDensity);
}
cachedCollectionSheets.Add(c, sheetDensity);
}
return sheetDensity;
}
public static Sprite GetImage(string collectionName, string imageName)
@@ -92,45 +151,135 @@ namespace OpenRA.Graphics
return null;
// Cached sprite
Dictionary<string, Sprite> cachedCollection;
Sprite sprite;
if (cachedSprites.TryGetValue(collectionName, out cachedCollection) && cachedCollection.TryGetValue(imageName, out sprite))
if (cachedSprites.TryGetValue(collectionName, out var cachedCollection) && cachedCollection.TryGetValue(imageName, out var sprite))
return sprite;
Collection collection;
if (!collections.TryGetValue(collectionName, out collection))
if (!collections.TryGetValue(collectionName, out var collection))
{
Log.Write("debug", "Could not find collection '{0}'", collectionName);
return null;
}
MappedImage mi;
if (!collection.Regions.TryGetValue(imageName, out mi))
if (!collection.Regions.TryGetValue(imageName, out var mi))
return null;
// Cached sheet
Sheet sheet;
if (cachedSheets.ContainsKey(mi.Src))
sheet = cachedSheets[mi.Src];
else
{
using (var stream = fileSystem.Open(mi.Src))
sheet = new Sheet(SheetType.BGRA, stream);
cachedSheets.Add(mi.Src, sheet);
}
// Cache the sprite
var sheetDensity = SheetForCollection(collection);
if (cachedCollection == null)
{
cachedCollection = new Dictionary<string, Sprite>();
cachedSprites.Add(collectionName, cachedCollection);
}
var image = mi.GetImage(sheet);
var image = new Sprite(sheetDensity.Sheet, sheetDensity.Density * mi, TextureChannel.RGBA, 1f / sheetDensity.Density);
cachedCollection.Add(imageName, image);
return image;
}
public static Sprite[] GetPanelImages(string collectionName)
{
if (string.IsNullOrEmpty(collectionName))
return null;
// Cached sprite
if (cachedPanelSprites.TryGetValue(collectionName, out var cachedSprites))
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);
return null;
}
// Cache the sprites
var sheetDensity = SheetForCollection(collection);
var pr = collection.PanelRegion;
var ps = collection.PanelSides;
var sides = new (PanelSides PanelSides, Rectangle Bounds)[]
{
(PanelSides.Top | PanelSides.Left, new Rectangle(pr[0], pr[1], pr[2], pr[3])),
(PanelSides.Top, new Rectangle(pr[0] + pr[2], pr[1], pr[4], pr[3])),
(PanelSides.Top | PanelSides.Right, new Rectangle(pr[0] + pr[2] + pr[4], pr[1], pr[6], pr[3])),
(PanelSides.Left, new Rectangle(pr[0], pr[1] + pr[3], pr[2], pr[5])),
(PanelSides.Center, new Rectangle(pr[0] + pr[2], pr[1] + pr[3], pr[4], pr[5])),
(PanelSides.Right, new Rectangle(pr[0] + pr[2] + pr[4], pr[1] + pr[3], pr[6], pr[5])),
(PanelSides.Bottom | PanelSides.Left, new Rectangle(pr[0], pr[1] + pr[3] + pr[5], pr[2], pr[7])),
(PanelSides.Bottom, new Rectangle(pr[0] + pr[2], pr[1] + pr[3] + pr[5], pr[4], pr[7])),
(PanelSides.Bottom | PanelSides.Right, new Rectangle(pr[0] + pr[2] + pr[4], pr[1] + pr[3] + pr[5], pr[6], pr[7]))
};
sprites = sides.Select(x => ps.HasSide(x.PanelSides) ? new Sprite(sheetDensity.Sheet, sheetDensity.Density * x.Bounds, TextureChannel.RGBA, 1f / sheetDensity.Density) : null)
.ToArray();
}
else
{
// 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")
};
}
cachedPanelSprites.Add(collectionName, sprites);
return sprites;
}
public static Size GetMinimumPanelSize(string collectionName)
{
if (string.IsNullOrEmpty(collectionName))
return new Size(0, 0);
if (!collections.TryGetValue(collectionName, out var collection))
{
Log.Write("debug", "Could not find collection '{0}'", collectionName);
return new Size(0, 0);
}
if (collection.PanelRegion == null || collection.PanelRegion.Length != 8)
{
Log.Write("debug", "Collection '{0}' does not define a valid PanelRegion", collectionName);
return new Size(0, 0);
}
var pr = collection.PanelRegion;
return new Size(pr[2] + pr[6], pr[3] + pr[7]);
}
public static void SetDPIScale(float scale)
{
if (dpiScale == scale)
return;
dpiScale = scale;
// Clear the sprite caches so the new artwork can be loaded
// Sheets are not cleared: we assume that the extra memory overhead
// of having the same sheet in memory in multiple DPIs is better than
// the overhead of having to dispose and reload everything.
// Changing the DPI scale is rare, but if it does happen then there
// is a reasonable chance that it may happen again this session.
cachedSprites.Clear();
cachedPanelSprites.Clear();
cachedCollectionSheets.Clear();
}
}
}

View File

@@ -0,0 +1,299 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 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
using System;
using System.Collections.Generic;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
public sealed class CursorManager
{
class Cursor
{
public string Name;
public int2 PaddedSize;
public Rectangle Bounds;
public int Length;
public Sprite[] Sprites;
public IHardwareCursor[] Cursors;
}
readonly Dictionary<string, Cursor> cursors = new Dictionary<string, Cursor>();
readonly SheetBuilder sheetBuilder;
readonly GraphicSettings graphicSettings;
Cursor cursor;
bool isLocked = false;
int2 lockedPosition;
bool hardwareCursorsDisabled = false;
bool hardwareCursorsDoubled = false;
public CursorManager(CursorProvider cursorProvider)
{
hardwareCursorsDisabled = Game.Settings.Graphics.DisableHardwareCursors;
graphicSettings = Game.Settings.Graphics;
sheetBuilder = new SheetBuilder(SheetType.BGRA);
foreach (var kv in cursorProvider.Cursors)
{
var frames = kv.Value.Frames;
var palette = !string.IsNullOrEmpty(kv.Value.Palette) ? cursorProvider.Palettes[kv.Value.Palette] : null;
var c = new Cursor
{
Name = kv.Key,
Bounds = Rectangle.FromLTRB(0, 0, 1, 1),
Length = 0,
Sprites = new Sprite[frames.Length],
Cursors = new IHardwareCursor[frames.Length]
};
// Hardware cursors have a number of odd platform-specific bugs/limitations.
// Reduce the number of edge cases by padding the individual frames such that:
// - the hotspot is inside the frame bounds (enforced by SDL)
// - all frames within a sequence have the same size (needed for macOS 10.15)
// - the frame size is a multiple of 8 (needed for Windows)
foreach (var f in frames)
{
// Hotspot is specified relative to the center of the frame
var hotspot = f.Offset.ToInt2() - kv.Value.Hotspot - new int2(f.Size) / 2;
// SheetBuilder expects data in BGRA
var data = FrameToBGRA(kv.Key, f, palette);
c.Sprites[c.Length++] = sheetBuilder.Add(data, f.Size, 0, hotspot);
// Bounds relative to the hotspot
c.Bounds = Rectangle.Union(c.Bounds, new Rectangle(hotspot, f.Size));
}
// Pad bottom-right edge to make the frame size a multiple of 8
c.PaddedSize = 8 * new int2((c.Bounds.Width + 7) / 8, (c.Bounds.Height + 7) / 8);
cursors.Add(kv.Key, c);
}
CreateOrUpdateHardwareCursors();
foreach (var s in sheetBuilder.AllSheets)
s.ReleaseBuffer();
Update();
}
void CreateOrUpdateHardwareCursors()
{
if (hardwareCursorsDisabled)
return;
// Dispose any existing cursors to avoid leaking native resources
ClearHardwareCursors();
try
{
foreach (var kv in cursors)
{
var template = kv.Value;
for (var i = 0; i < template.Sprites.Length; i++)
{
if (template.Cursors[i] != null)
template.Cursors[i].Dispose();
// Calculate the padding to position the frame within sequenceBounds
var paddingTL = -(template.Bounds.Location - template.Sprites[i].Offset.XY.ToInt2());
var paddingBR = template.PaddedSize - new int2(template.Sprites[i].Bounds.Size) - paddingTL;
template.Cursors[i] = CreateHardwareCursor(kv.Key, template.Sprites[i], paddingTL, paddingBR, -template.Bounds.Location);
}
}
}
catch (Exception e)
{
Log.Write("debug", "Failed to initialize hardware cursors. Falling back to software cursors.");
Log.Write("debug", "Error was: " + e.Message);
Console.WriteLine("Failed to initialize hardware cursors. Falling back to software cursors.");
Console.WriteLine("Error was: " + e.Message);
ClearHardwareCursors();
}
hardwareCursorsDoubled = graphicSettings.CursorDouble;
}
public void SetCursor(string cursorName)
{
if ((cursorName == null && cursor == null) || (cursor != null && cursorName == cursor.Name))
return;
if (cursorName == null || !cursors.TryGetValue(cursorName, out cursor))
cursor = null;
Update();
}
int frame;
int ticks;
public void Tick()
{
if (hardwareCursorsDoubled != graphicSettings.CursorDouble)
{
CreateOrUpdateHardwareCursors();
Update();
}
if (cursor == null || cursor.Cursors.Length == 1)
return;
if (++ticks > 2)
{
ticks -= 2;
frame++;
Update();
}
}
void Update()
{
if (cursor != null && frame >= cursor.Cursors.Length)
frame %= cursor.Cursors.Length;
if (cursor == null || isLocked)
Game.Renderer.Window.SetHardwareCursor(null);
else
Game.Renderer.Window.SetHardwareCursor(cursor.Cursors[frame]);
}
public void Render(Renderer renderer)
{
// Cursor is hidden
if (cursor == null)
return;
// Hardware cursor is enabled
if (!isLocked && cursor.Cursors[frame % cursor.Length] != null)
return;
// Render cursor in software
var doubleCursor = graphicSettings.CursorDouble;
var cursorSprite = cursor.Sprites[frame % cursor.Length];
var cursorSize = doubleCursor ? 2.0f * cursorSprite.Size : cursorSprite.Size;
// Cursor is rendered in native window coordinates
// Apply same scaling rules as hardware cursors
if (Game.Renderer.NativeWindowScale > 1.5f)
cursorSize = 2 * cursorSize;
var mousePos = isLocked ? lockedPosition : Viewport.LastMousePos;
renderer.RgbaSpriteRenderer.DrawSprite(cursorSprite,
mousePos,
cursorSize / Game.Renderer.WindowScale);
}
public void Lock()
{
lockedPosition = Viewport.LastMousePos;
Game.Renderer.Window.SetRelativeMouseMode(true);
isLocked = true;
Update();
}
public void Unlock()
{
Game.Renderer.Window.SetRelativeMouseMode(false);
isLocked = false;
Update();
}
public static byte[] FrameToBGRA(string name, ISpriteFrame frame, ImmutablePalette palette)
{
// Data is already in BGRA format
if (frame.Type == SpriteFrameType.BGRA)
return frame.Data;
// Cursors may be either native BGRA or Indexed.
// Indexed sprites are converted to BGRA using the referenced palette.
// All palettes must be explicitly referenced, even if they are embedded in the sprite.
if (frame.Type == SpriteFrameType.Indexed && palette == null)
throw new InvalidOperationException("Cursor sequence `{0}` attempted to load an indexed sprite but does not define Palette".F(name));
var width = frame.Size.Width;
var height = frame.Size.Height;
var data = new byte[4 * width * height];
for (var j = 0; j < height; j++)
{
for (var i = 0; i < width; i++)
{
var bytes = BitConverter.GetBytes(palette[frame.Data[j * width + i]]);
var c = palette[frame.Data[j * width + i]];
var k = 4 * (j * width + i);
// Convert RGBA to BGRA
data[k] = bytes[2];
data[k + 1] = bytes[1];
data[k + 2] = bytes[0];
data[k + 3] = bytes[3];
}
}
return data;
}
IHardwareCursor CreateHardwareCursor(string name, Sprite data, int2 paddingTL, int2 paddingBR, int2 hotspot)
{
var size = data.Bounds.Size;
var srcStride = data.Sheet.Size.Width;
var srcData = data.Sheet.GetData();
var newWidth = paddingTL.X + size.Width + paddingBR.X;
var newHeight = paddingTL.Y + size.Height + paddingBR.Y;
var rgbaData = new byte[4 * newWidth * newHeight];
for (var j = 0; j < size.Height; j++)
{
for (var i = 0; i < size.Width; i++)
{
var src = 4 * ((j + data.Bounds.Top) * srcStride + data.Bounds.Left + i);
var dest = 4 * ((j + paddingTL.Y) * newWidth + i + paddingTL.X);
Array.Copy(srcData, src, rgbaData, dest, 4);
}
}
return Game.Renderer.Window.CreateHardwareCursor(name, new Size(newWidth, newHeight), rgbaData, hotspot, graphicSettings.CursorDouble);
}
void ClearHardwareCursors()
{
foreach (var c in cursors.Values)
{
for (var i = 0; i < c.Cursors.Length; i++)
{
if (c.Cursors[i] != null)
{
c.Cursors[i].Dispose();
c.Cursors[i] = null;
}
}
}
}
public void Dispose()
{
ClearHardwareCursors();
cursors.Clear();
sheetBuilder.Dispose();
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,6 +12,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Traits;
namespace OpenRA.Graphics
{
@@ -26,21 +27,19 @@ namespace OpenRA.Graphics
var sequenceYaml = MiniYaml.Merge(modData.Manifest.Cursors.Select(
s => MiniYaml.FromStream(fileSystem.Open(s), s)));
var shadowIndex = new int[] { };
var nodesDict = new MiniYaml(null, sequenceYaml).ToDictionary();
if (nodesDict.ContainsKey("ShadowIndex"))
{
Array.Resize(ref shadowIndex, shadowIndex.Length + 1);
Exts.TryParseIntegerInvariant(nodesDict["ShadowIndex"].Value,
out shadowIndex[shadowIndex.Length - 1]);
}
var palettes = new Dictionary<string, ImmutablePalette>();
foreach (var p in nodesDict["Palettes"].Nodes)
palettes.Add(p.Key, new ImmutablePalette(fileSystem.Open(p.Value.Value), shadowIndex));
// Overwrite previous definitions if there are duplicates
var pals = new Dictionary<string, IProvidesCursorPaletteInfo>();
foreach (var p in modData.DefaultRules.Actors["world"].TraitInfos<IProvidesCursorPaletteInfo>())
if (p.Palette != null)
pals[p.Palette] = p;
Palettes = palettes.AsReadOnly();
Palettes = nodesDict["Cursors"].Nodes.Select(n => n.Value.Value)
.Where(p => p != null)
.Distinct()
.ToDictionary(p => p, p => pals[p].ReadPalette(modData.DefaultFileSystem))
.AsReadOnly();
var frameCache = new FrameCache(fileSystem, modData.SpriteLoaders);
var cursors = new Dictionary<string, CursorSequence>();
@@ -51,8 +50,6 @@ namespace OpenRA.Graphics
Cursors = cursors.AsReadOnly();
}
public static bool CursorViewportZoomed { get { return Game.Settings.Graphics.CursorDouble && Game.Settings.Graphics.PixelDouble; } }
public bool HasCursorSequence(string cursor)
{
return Cursors.ContainsKey(cursor);

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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
@@ -47,15 +47,13 @@ namespace OpenRA.Graphics
if (d.ContainsKey("X"))
{
int x;
Exts.TryParseIntegerInvariant(d["X"].Value, out x);
Exts.TryParseIntegerInvariant(d["X"].Value, out var x);
Hotspot = Hotspot.WithX(x);
}
if (d.ContainsKey("Y"))
{
int y;
Exts.TryParseIntegerInvariant(d["Y"].Value, out y);
Exts.TryParseIntegerInvariant(d["Y"].Value, out var y);
Hotspot = Hotspot.WithY(y);
}
}

View File

@@ -1,146 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 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
using System.Drawing;
using System.Globalization;
using OpenRA.Scripting;
namespace OpenRA.Graphics
{
public struct HSLColor : IScriptBindable
{
public readonly byte H;
public readonly byte S;
public readonly byte L;
public readonly Color RGB;
public static HSLColor FromHSV(float h, float s, float v)
{
var ll = 0.5f * (2 - s) * v;
var ss = (ll >= 1 || v <= 0) ? 0 : 0.5f * s * v / (ll <= 0.5f ? ll : 1 - ll);
return new HSLColor((byte)(255 * h), (byte)(255 * ss), (byte)(255 * ll));
}
public HSLColor(Color color)
{
RGB = color;
H = (byte)((color.GetHue() / 360.0f) * 255);
S = (byte)(color.GetSaturation() * 255);
L = (byte)(color.GetBrightness() * 255);
}
public static HSLColor FromRGB(int r, int g, int b)
{
return new HSLColor(Color.FromArgb(r, g, b));
}
public static Color RGBFromHSL(float h, float s, float l)
{
// Convert from HSL to RGB
var q = (l < 0.5f) ? l * (1 + s) : l + s - (l * s);
var p = 2 * l - q;
float[] trgb = { h + 1 / 3.0f, h, h - 1 / 3.0f };
float[] rgb = { 0, 0, 0 };
for (var k = 0; k < 3; k++)
{
while (trgb[k] < 0) trgb[k] += 1.0f;
while (trgb[k] > 1) trgb[k] -= 1.0f;
}
for (var k = 0; k < 3; k++)
{
if (trgb[k] < 1 / 6.0f)
rgb[k] = p + ((q - p) * 6 * trgb[k]);
else if (trgb[k] >= 1 / 6.0f && trgb[k] < 0.5)
rgb[k] = q;
else if (trgb[k] >= 0.5f && trgb[k] < 2.0f / 3)
rgb[k] = p + ((q - p) * 6 * (2.0f / 3 - trgb[k]));
else
rgb[k] = p;
}
return Color.FromArgb((int)(rgb[0] * 255), (int)(rgb[1] * 255), (int)(rgb[2] * 255));
}
public static bool TryParseRGB(string value, out Color color)
{
color = new Color();
value = value.Trim();
if (value.Length != 6 && value.Length != 8)
return false;
byte red, green, blue, alpha = 255;
if (!byte.TryParse(value.Substring(0, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out red)
|| !byte.TryParse(value.Substring(2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out green)
|| !byte.TryParse(value.Substring(4, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out blue))
return false;
if (value.Length == 8
&& !byte.TryParse(value.Substring(6, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out alpha))
return false;
color = Color.FromArgb(alpha, red, green, blue);
return true;
}
public static bool operator ==(HSLColor me, HSLColor other)
{
return me.H == other.H && me.S == other.S && me.L == other.L;
}
public static bool operator !=(HSLColor me, HSLColor other) { return !(me == other); }
public HSLColor(byte h, byte s, byte l)
{
H = h;
S = s;
L = l;
RGB = RGBFromHSL(H / 255f, S / 255f, L / 255f);
}
public void ToHSV(out float h, out float s, out float v)
{
var ll = 2 * L / 255f;
var ss = S / 255f * ((ll <= 1) ? ll : 2 - ll);
h = H / 255f;
s = (2 * ss) / (ll + ss);
v = (ll + ss) / 2;
}
public override string ToString()
{
return "{0},{1},{2}".F(H, S, L);
}
public static string ToHexString(Color color)
{
if (color.A == 255)
return color.R.ToString("X2") + color.G.ToString("X2") + color.B.ToString("X2");
return color.R.ToString("X2") + color.G.ToString("X2") + color.B.ToString("X2") + color.A.ToString("X2");
}
public string ToHexString()
{
return ToHexString(RGB);
}
public override int GetHashCode() { return H.GetHashCode() ^ S.GetHashCode() ^ L.GetHashCode(); }
public override bool Equals(object obj)
{
var o = obj as HSLColor?;
return o != null && o == this;
}
}
}

View File

@@ -1,137 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 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
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
namespace OpenRA.Graphics
{
public sealed class HardwareCursor : ICursor
{
readonly Dictionary<string, IHardwareCursor[]> hardwareCursors = new Dictionary<string, IHardwareCursor[]>();
readonly CursorProvider cursorProvider;
CursorSequence cursor;
public HardwareCursor(CursorProvider cursorProvider)
{
this.cursorProvider = cursorProvider;
foreach (var kv in cursorProvider.Cursors)
{
var palette = cursorProvider.Palettes[kv.Value.Palette];
var hc = kv.Value.Frames
.Select(f => CreateCursor(f, palette, kv.Key, kv.Value))
.ToArray();
hardwareCursors.Add(kv.Key, hc);
}
Update();
}
IHardwareCursor CreateCursor(ISpriteFrame f, ImmutablePalette palette, string name, CursorSequence sequence)
{
var hotspot = sequence.Hotspot - f.Offset.ToInt2() + new int2(f.Size) / 2;
// Expand the frame if required to include the hotspot
var frameWidth = f.Size.Width;
var dataWidth = f.Size.Width;
var dataX = 0;
if (hotspot.X < 0)
{
dataX = -hotspot.X;
dataWidth += dataX;
hotspot = hotspot.WithX(0);
}
else if (hotspot.X >= frameWidth)
dataWidth = hotspot.X + 1;
var frameHeight = f.Size.Height;
var dataHeight = f.Size.Height;
var dataY = 0;
if (hotspot.Y < 0)
{
dataY = -hotspot.Y;
dataHeight += dataY;
hotspot = hotspot.WithY(0);
}
else if (hotspot.Y >= frameHeight)
dataHeight = hotspot.Y + 1;
var data = new byte[4 * dataWidth * dataHeight];
for (var j = 0; j < frameHeight; j++)
{
for (var i = 0; i < frameWidth; i++)
{
var bytes = BitConverter.GetBytes(palette[f.Data[j * frameWidth + i]]);
var start = 4 * ((j + dataY) * dataWidth + dataX + i);
for (var k = 0; k < 4; k++)
data[start + k] = bytes[k];
}
}
return Game.Renderer.Device.CreateHardwareCursor(name, new Size(dataWidth, dataHeight), data, hotspot);
}
public void SetCursor(string cursorName)
{
if ((cursorName == null && cursor == null) || (cursor != null && cursorName == cursor.Name))
return;
if (cursorName == null || !cursorProvider.Cursors.TryGetValue(cursorName, out cursor))
cursor = null;
Update();
}
int frame;
int ticks;
public void Tick()
{
if (cursor == null || cursor.Length == 1)
return;
if (++ticks > 2)
{
ticks -= 2;
frame++;
Update();
}
}
void Update()
{
if (cursor == null)
Game.Renderer.Device.SetHardwareCursor(null);
else
{
if (frame >= cursor.Length)
frame = frame % cursor.Length;
Game.Renderer.Device.SetHardwareCursor(hardwareCursors[cursor.Name][frame]);
}
}
public void Render(Renderer renderer) { }
public void Dispose()
{
foreach (var cursors in hardwareCursors)
foreach (var cursor in cursors.Value)
cursor.Dispose();
hardwareCursors.Clear();
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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
@@ -27,7 +27,7 @@ namespace OpenRA.Graphics
public HardwarePalette()
{
Texture = Game.Renderer.Device.CreateTexture();
Texture = Game.Renderer.Context.CreateTexture();
readOnlyModifiablePalettes = modifiablePalettes.AsReadOnly();
}
@@ -38,19 +38,16 @@ namespace OpenRA.Graphics
public IPalette GetPalette(string name)
{
MutablePalette mutable;
if (modifiablePalettes.TryGetValue(name, out mutable))
if (modifiablePalettes.TryGetValue(name, out var mutable))
return mutable.AsReadOnly();
ImmutablePalette immutable;
if (palettes.TryGetValue(name, out immutable))
if (palettes.TryGetValue(name, out var immutable))
return immutable;
throw new InvalidOperationException("Palette `{0}` does not exist".F(name));
}
public int GetPaletteIndex(string name)
{
int ret;
if (!indices.TryGetValue(name, out ret))
if (!indices.TryGetValue(name, out var ret))
throw new InvalidOperationException("Palette `{0}` does not exist".F(name));
return ret;
}

View File

@@ -1,44 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 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
using System.Collections.Generic;
using System.Drawing;
namespace OpenRA.Graphics
{
class MappedImage
{
readonly Rectangle rect = Rectangle.Empty;
public readonly string Src;
public MappedImage(string defaultSrc, MiniYaml info)
{
FieldLoader.LoadField(this, "rect", info.Value);
FieldLoader.Load(this, info);
if (Src == null)
Src = defaultSrc;
}
public Sprite GetImage(Sheet s)
{
return new Sprite(s, rect, TextureChannel.Alpha);
}
public MiniYaml Save(string defaultSrc)
{
var root = new List<MiniYamlNode>();
if (defaultSrc != Src)
root.Add(new MiniYamlNode("Src", Src));
return new MiniYaml(FieldSaver.FormatValue(this, GetType().GetField("rect")), root);
}
}
}

View File

@@ -0,0 +1,87 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 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
using System;
using OpenRA.FileSystem;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
public interface IModel
{
uint Frames { get; }
uint Sections { get; }
float[] TransformationMatrix(uint section, uint frame);
float[] Size { get; }
float[] Bounds(uint frame);
ModelRenderData RenderData(uint section);
/// <summary>Returns the smallest rectangle that covers all rotations of all frames in a model</summary>
Rectangle AggregateBounds { get; }
}
public struct ModelRenderData
{
public readonly int Start;
public readonly int Count;
public readonly Sheet Sheet;
public ModelRenderData(int start, int count, Sheet sheet)
{
Start = start;
Count = count;
Sheet = sheet;
}
}
public interface IModelCache : IDisposable
{
IModel GetModelSequence(string model, string sequence);
bool HasModelSequence(string model, string sequence);
IVertexBuffer<Vertex> VertexBuffer { get; }
}
public interface IModelSequenceLoader
{
Action<string> OnMissingModelError { get; set; }
IModelCache CacheModels(IReadOnlyFileSystem fileSystem, ModData modData, IReadOnlyDictionary<string, MiniYamlNode> modelDefinitions);
}
public class PlaceholderModelSequenceLoader : IModelSequenceLoader
{
public Action<string> OnMissingModelError { get; set; }
class PlaceholderModelCache : IModelCache
{
public IVertexBuffer<Vertex> VertexBuffer { get { throw new NotImplementedException(); } }
public void Dispose() { }
public IModel GetModelSequence(string model, string sequence)
{
throw new NotImplementedException();
}
public bool HasModelSequence(string model, string sequence)
{
throw new NotImplementedException();
}
}
public PlaceholderModelSequenceLoader(ModData modData) { }
public IModelCache CacheModels(IReadOnlyFileSystem fileSystem, ModData modData, IReadOnlyDictionary<string, MiniYamlNode> modelDefinitions)
{
return new PlaceholderModelCache();
}
}
}

View File

@@ -0,0 +1,57 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 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
using System;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
public struct ModelAnimation
{
public readonly IModel Model;
public readonly Func<WVec> OffsetFunc;
public readonly Func<WRot> RotationFunc;
public readonly Func<bool> DisableFunc;
public readonly Func<uint> FrameFunc;
public readonly bool ShowShadow;
public ModelAnimation(IModel model, Func<WVec> offset, Func<WRot> rotation, Func<bool> disable, Func<uint> frame, bool showshadow)
{
Model = model;
OffsetFunc = offset;
RotationFunc = rotation;
DisableFunc = disable;
FrameFunc = frame;
ShowShadow = showshadow;
}
public Rectangle ScreenBounds(WPos pos, WorldRenderer wr, float scale)
{
var r = Model.AggregateBounds;
var offset = OffsetFunc != null ? OffsetFunc() : WVec.Zero;
var xy = wr.ScreenPxPosition(pos) + wr.ScreenPxOffset(offset);
return Rectangle.FromLTRB(
xy.X + (int)(r.Left * scale),
xy.Y + (int)(r.Top * scale),
xy.X + (int)(r.Right * scale),
xy.Y + (int)(r.Bottom * scale));
}
public bool IsVisible
{
get
{
return DisableFunc == null || !DisableFunc();
}
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,20 +11,19 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
public class VoxelRenderProxy
public class ModelRenderProxy
{
public readonly Sprite Sprite;
public readonly Sprite ShadowSprite;
public readonly float ShadowDirection;
public readonly float3[] ProjectedShadowBounds;
public VoxelRenderProxy(Sprite sprite, Sprite shadowSprite, float3[] projectedShadowBounds, float shadowDirection)
public ModelRenderProxy(Sprite sprite, Sprite shadowSprite, float3[] projectedShadowBounds, float shadowDirection)
{
Sprite = sprite;
ShadowSprite = shadowSprite;
@@ -33,7 +32,7 @@ namespace OpenRA.Graphics
}
}
public sealed class VoxelRenderer : IDisposable
public sealed class ModelRenderer : IDisposable
{
// Static constants
static readonly float[] ShadowDiffuse = new float[] { 0, 0, 0 };
@@ -49,11 +48,12 @@ namespace OpenRA.Graphics
readonly Dictionary<Sheet, IFrameBuffer> mappedBuffers = new Dictionary<Sheet, IFrameBuffer>();
readonly Stack<KeyValuePair<Sheet, IFrameBuffer>> unmappedBuffers = new Stack<KeyValuePair<Sheet, IFrameBuffer>>();
readonly List<Pair<Sheet, Action>> doRender = new List<Pair<Sheet, Action>>();
readonly List<(Sheet Sheet, Action Func)> doRender = new List<(Sheet, Action)>();
SheetBuilder sheetBuilder;
SheetBuilder sheetBuilderForFrame;
bool isInFrame;
public VoxelRenderer(Renderer renderer, IShader shader)
public ModelRenderer(Renderer renderer, IShader shader)
{
this.renderer = renderer;
this.shader = shader;
@@ -64,10 +64,10 @@ namespace OpenRA.Graphics
shader.SetTexture("Palette", palette);
}
public void SetViewportParams(Size screen, float zoom, int2 scroll)
public void SetViewportParams(Size screen, int2 scroll)
{
var a = 2f / renderer.SheetSize;
var view = new float[]
var view = new[]
{
a, 0, 0, 0,
0, -a, 0, 0,
@@ -78,11 +78,14 @@ namespace OpenRA.Graphics
shader.SetMatrix("View", view);
}
public VoxelRenderProxy RenderAsync(
WorldRenderer wr, IEnumerable<VoxelAnimation> voxels, WRot camera, float scale,
public ModelRenderProxy RenderAsync(
WorldRenderer wr, IEnumerable<ModelAnimation> models, WRot camera, float scale,
float[] groundNormal, WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor,
PaletteReference color, PaletteReference normals, PaletteReference shadowPalette)
{
if (!isInFrame)
throw new InvalidOperationException("BeginFrame has not been called. You cannot render until a frame has been started.");
// Correct for inverted y-axis
var scaleTransform = Util.ScaleMatrix(scale, scale, scale);
@@ -105,18 +108,17 @@ namespace OpenRA.Graphics
var stl = new float2(float.MaxValue, float.MaxValue);
var sbr = new float2(float.MinValue, float.MinValue);
foreach (var v in voxels)
foreach (var m in models)
{
// Convert screen offset back to world coords
var offsetVec = Util.MatrixVectorMultiply(invCameraTransform, wr.ScreenVector(v.OffsetFunc()));
var offsetVec = Util.MatrixVectorMultiply(invCameraTransform, wr.ScreenVector(m.OffsetFunc()));
var offsetTransform = Util.TranslationMatrix(offsetVec[0], offsetVec[1], offsetVec[2]);
var worldTransform = v.RotationFunc().Aggregate(Util.IdentityMatrix(),
(x, y) => Util.MatrixMultiply(Util.MakeFloatMatrix(y.AsMatrix()), x));
var worldTransform = Util.MakeFloatMatrix(m.RotationFunc().AsMatrix());
worldTransform = Util.MatrixMultiply(scaleTransform, worldTransform);
worldTransform = Util.MatrixMultiply(offsetTransform, worldTransform);
var bounds = v.Voxel.Bounds(v.FrameFunc());
var bounds = m.Model.Bounds(m.FrameFunc());
var worldBounds = Util.MatrixAABBMultiply(worldTransform, bounds);
var screenBounds = Util.MatrixAABBMultiply(cameraTransform, worldBounds);
var shadowBounds = Util.MatrixAABBMultiply(shadowTransform, worldBounds);
@@ -158,13 +160,14 @@ namespace OpenRA.Graphics
}
// Shadows are rendered at twice the resolution to reduce artifacts
Size spriteSize, shadowSpriteSize;
int2 spriteOffset, shadowSpriteOffset;
CalculateSpriteGeometry(tl, br, 1, out spriteSize, out spriteOffset);
CalculateSpriteGeometry(stl, sbr, 2, out shadowSpriteSize, out shadowSpriteOffset);
CalculateSpriteGeometry(tl, br, 1, out var spriteSize, out var spriteOffset);
CalculateSpriteGeometry(stl, sbr, 2, out var shadowSpriteSize, out var shadowSpriteOffset);
var sprite = sheetBuilder.Allocate(spriteSize, 0, spriteOffset);
var shadowSprite = sheetBuilder.Allocate(shadowSpriteSize, 0, shadowSpriteOffset);
if (sheetBuilderForFrame == null)
sheetBuilderForFrame = new SheetBuilder(SheetType.BGRA, AllocateSheet);
var sprite = sheetBuilderForFrame.Allocate(spriteSize, 0, spriteOffset);
var shadowSprite = sheetBuilderForFrame.Allocate(shadowSpriteSize, 0, shadowSpriteOffset);
var sb = sprite.Bounds;
var ssb = shadowSprite.Bounds;
var spriteCenter = new float2(sb.Left + sb.Width / 2, sb.Top + sb.Height / 2);
@@ -175,16 +178,15 @@ namespace OpenRA.Graphics
var correctionTransform = Util.MatrixMultiply(translateMtx, FlipMtx);
var shadowCorrectionTransform = Util.MatrixMultiply(shadowTranslateMtx, ShadowScaleFlipMtx);
doRender.Add(Pair.New<Sheet, Action>(sprite.Sheet, () =>
doRender.Add((sprite.Sheet, () =>
{
foreach (var v in voxels)
foreach (var m in models)
{
// Convert screen offset to world offset
var offsetVec = Util.MatrixVectorMultiply(invCameraTransform, wr.ScreenVector(v.OffsetFunc()));
var offsetVec = Util.MatrixVectorMultiply(invCameraTransform, wr.ScreenVector(m.OffsetFunc()));
var offsetTransform = Util.TranslationMatrix(offsetVec[0], offsetVec[1], offsetVec[2]);
var rotations = v.RotationFunc().Aggregate(Util.IdentityMatrix(),
(x, y) => Util.MatrixMultiply(Util.MakeFloatMatrix(y.AsMatrix()), x));
var rotations = Util.MakeFloatMatrix(m.RotationFunc().AsMatrix());
var worldTransform = Util.MatrixMultiply(scaleTransform, rotations);
worldTransform = Util.MatrixMultiply(offsetTransform, worldTransform);
@@ -196,11 +198,11 @@ namespace OpenRA.Graphics
var lightTransform = Util.MatrixMultiply(Util.MatrixInverse(rotations), invShadowTransform);
var frame = v.FrameFunc();
for (uint i = 0; i < v.Voxel.Limbs; i++)
var frame = m.FrameFunc();
for (uint i = 0; i < m.Model.Sections; i++)
{
var rd = v.Voxel.RenderData(i);
var t = v.Voxel.TransformationMatrix(i, frame);
var rd = m.Model.RenderData(i);
var t = m.Model.TransformationMatrix(i, frame);
var it = Util.MatrixInverse(t);
if (it == null)
throw new InvalidOperationException("Failed to invert the transformed matrix of frame {0} during RenderAsync.".F(i));
@@ -208,12 +210,12 @@ namespace OpenRA.Graphics
// Transform light vector from shadow -> world -> limb coords
var lightDirection = ExtractRotationVector(Util.MatrixMultiply(it, lightTransform));
Render(rd, Util.MatrixMultiply(transform, t), lightDirection,
Render(rd, wr.World.ModelCache, Util.MatrixMultiply(transform, t), lightDirection,
lightAmbientColor, lightDiffuseColor, color.TextureMidIndex, normals.TextureMidIndex);
// Disable shadow normals by forcing zero diffuse and identity ambient light
if (v.ShowShadow)
Render(rd, Util.MatrixMultiply(shadow, t), lightDirection,
if (m.ShowShadow)
Render(rd, wr.World.ModelCache, Util.MatrixMultiply(shadow, t), lightDirection,
ShadowAmbient, ShadowDiffuse, shadowPalette.TextureMidIndex, normals.TextureMidIndex);
}
}
@@ -221,7 +223,7 @@ namespace OpenRA.Graphics
var screenLightVector = Util.MatrixVectorMultiply(invShadowTransform, ZVector);
screenLightVector = Util.MatrixVectorMultiply(cameraTransform, screenLightVector);
return new VoxelRenderProxy(sprite, shadowSprite, screenCorners, -screenLightVector[2] / screenLightVector[1]);
return new ModelRenderProxy(sprite, shadowSprite, screenCorners, -screenLightVector[2] / screenLightVector[1]);
}
static void CalculateSpriteGeometry(float2 tl, float2 br, float scale, out Size size, out int2 offset)
@@ -258,7 +260,8 @@ namespace OpenRA.Graphics
}
void Render(
VoxelRenderData renderData,
ModelRenderData renderData,
IModelCache cache,
float[] t, float[] lightDirection,
float[] ambientLight, float[] diffuseLight,
float colorPaletteTextureMidIndex, float normalsPaletteTextureMidIndex)
@@ -270,17 +273,20 @@ namespace OpenRA.Graphics
shader.SetVec("AmbientLight", ambientLight, 3);
shader.SetVec("DiffuseLight", diffuseLight, 3);
shader.Render(() => renderer.DrawBatch(Game.ModData.VoxelLoader.VertexBuffer, renderData.Start, renderData.Count, PrimitiveType.TriangleList));
shader.PrepareRender();
renderer.DrawBatch(cache.VertexBuffer, renderData.Start, renderData.Count, PrimitiveType.TriangleList);
}
public void BeginFrame()
{
if (isInFrame)
throw new InvalidOperationException("BeginFrame has already been called. A new frame cannot be started until EndFrame has been called.");
isInFrame = true;
foreach (var kv in mappedBuffers)
unmappedBuffers.Push(kv);
mappedBuffers.Clear();
sheetBuilder = new SheetBuilder(SheetType.BGRA, AllocateSheet);
doRender.Clear();
}
IFrameBuffer EnableFrameBuffer(Sheet s)
@@ -289,19 +295,25 @@ namespace OpenRA.Graphics
Game.Renderer.Flush();
fbo.Bind();
Game.Renderer.Device.EnableDepthBuffer();
Game.Renderer.Context.EnableDepthBuffer();
return fbo;
}
void DisableFrameBuffer(IFrameBuffer fbo)
{
Game.Renderer.Flush();
Game.Renderer.Device.DisableDepthBuffer();
Game.Renderer.Context.DisableDepthBuffer();
fbo.Unbind();
}
public void EndFrame()
{
if (!isInFrame)
throw new InvalidOperationException("BeginFrame has not been called. There is no frame to end.");
isInFrame = false;
sheetBuilderForFrame = null;
if (doRender.Count == 0)
return;
@@ -310,20 +322,22 @@ namespace OpenRA.Graphics
foreach (var v in doRender)
{
// Change sheet
if (v.First != currentSheet)
if (v.Sheet != currentSheet)
{
if (fbo != null)
DisableFrameBuffer(fbo);
currentSheet = v.First;
currentSheet = v.Sheet;
fbo = EnableFrameBuffer(currentSheet);
}
v.Second();
v.Func();
}
if (fbo != null)
DisableFrameBuffer(fbo);
doRender.Clear();
}
public Sheet AllocateSheet()
@@ -337,7 +351,7 @@ namespace OpenRA.Graphics
}
var size = new Size(renderer.SheetSize, renderer.SheetSize);
var framebuffer = renderer.Device.CreateFrameBuffer(size);
var framebuffer = renderer.Context.CreateFrameBuffer(size);
var sheet = new Sheet(SheetType.BGRA, framebuffer.Texture);
mappedBuffers.Add(sheet, framebuffer);

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,11 +11,8 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
@@ -36,35 +33,6 @@ namespace OpenRA.Graphics
return Color.FromArgb((int)palette[index]);
}
public static ColorPalette AsSystemPalette(this IPalette palette)
{
ColorPalette pal;
using (var b = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))
pal = b.Palette;
for (var i = 0; i < Size; i++)
pal.Entries[i] = palette.GetColor(i);
// hack around a mono bug -- the palette flags get set wrong.
if (Platform.CurrentPlatform != PlatformType.Windows)
typeof(ColorPalette).GetField("flags",
BindingFlags.Instance | BindingFlags.NonPublic).SetValue(pal, 1);
return pal;
}
public static Bitmap AsBitmap(this IPalette palette)
{
var b = new Bitmap(Size, 1, PixelFormat.Format32bppArgb);
var data = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
var temp = new uint[Size];
palette.CopyToArray(temp, 0);
Marshal.Copy((int[])(object)temp, 0, data.Scan0, Size);
b.UnlockBits(data);
return b;
}
public static IPalette AsReadOnly(this IPalette palette)
{
if (palette is ImmutablePalette)
@@ -117,6 +85,12 @@ namespace OpenRA.Graphics
var r = (byte)(reader.ReadByte() << 2);
var g = (byte)(reader.ReadByte() << 2);
var b = (byte)(reader.ReadByte() << 2);
// Replicate high bits into the (currently zero) low bits.
r |= (byte)(r >> 6);
g |= (byte)(g >> 6);
b |= (byte)(b >> 6);
colors[i] = (uint)((255 << 24) | (r << 16) | (g << 8) | b);
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,15 +10,23 @@
#endregion
using System;
using System.Drawing;
using OpenRA.Graphics;
using OpenRA.Primitives;
namespace OpenRA
{
public enum GLProfile
{
Modern,
Embedded,
Legacy
}
public interface IPlatform
{
IGraphicsDevice CreateGraphics(Size size, WindowMode windowMode);
IPlatformWindow CreateWindow(Size size, WindowMode windowMode, float scaleModifier, int batchSize, int videoDisplay, GLProfile profile);
ISoundEngine CreateSound(string device);
IFont CreateFont(byte[] data);
}
public interface IHardwareCursor : IDisposable { }
@@ -31,44 +39,61 @@ namespace OpenRA
Subtractive,
Multiply,
Multiplicative,
DoubleMultiplicative
DoubleMultiplicative,
LowAdditive,
Screen,
Translucent
}
public interface IGraphicsDevice : IDisposable
public interface IPlatformWindow : IDisposable
{
IVertexBuffer<Vertex> CreateVertexBuffer(int length);
ITexture CreateTexture(Bitmap bitmap);
ITexture CreateTexture();
IFrameBuffer CreateFrameBuffer(Size s);
IShader CreateShader(string name);
IGraphicsContext Context { get; }
Size WindowSize { get; }
float WindowScale { get; }
event Action<float, float> OnWindowScaleChanged;
Size NativeWindowSize { get; }
Size EffectiveWindowSize { get; }
float NativeWindowScale { get; }
float EffectiveWindowScale { get; }
Size SurfaceSize { get; }
int DisplayCount { get; }
int CurrentDisplay { get; }
bool HasInputFocus { get; }
event Action<float, float, float, float> OnWindowScaleChanged;
void Clear();
void Present();
Bitmap TakeScreenshot();
void PumpInput(IInputHandler inputHandler);
string GetClipboardText();
bool SetClipboardText(string text);
void DrawPrimitives(PrimitiveType type, int firstVertex, int numVertices);
void EnableScissor(int left, int top, int width, int height);
void DisableScissor();
void EnableDepthBuffer();
void DisableDepthBuffer();
void ClearDepthBuffer();
void SetBlendMode(BlendMode mode);
void GrabWindowMouseFocus();
void ReleaseWindowMouseFocus();
IHardwareCursor CreateHardwareCursor(string name, Size size, byte[] data, int2 hotspot);
IHardwareCursor CreateHardwareCursor(string name, Size size, byte[] data, int2 hotspot, bool pixelDouble);
void SetHardwareCursor(IHardwareCursor cursor);
void SetRelativeMouseMode(bool mode);
void SetScaleModifier(float scale);
GLProfile GLProfile { get; }
GLProfile[] SupportedGLProfiles { get; }
}
public interface IGraphicsContext : IDisposable
{
IVertexBuffer<Vertex> CreateVertexBuffer(int size);
ITexture CreateTexture();
IFrameBuffer CreateFrameBuffer(Size s);
IFrameBuffer CreateFrameBuffer(Size s, Color clearColor);
IShader CreateShader(string name);
void EnableScissor(int x, int y, int width, int height);
void DisableScissor();
void Present();
void DrawPrimitives(PrimitiveType pt, int firstVertex, int numVertices);
void Clear();
void EnableDepthBuffer();
void DisableDepthBuffer();
void ClearDepthBuffer();
void SetBlendMode(BlendMode mode);
void SetVSyncEnabled(bool enabled);
string GLVersion { get; }
}
@@ -89,14 +114,13 @@ namespace OpenRA
void SetVec(string name, float[] vec, int length);
void SetTexture(string param, ITexture texture);
void SetMatrix(string param, float[] mtx);
void Render(Action a);
void PrepareRender();
}
public enum TextureScaleFilter { Nearest, Linear }
public interface ITexture : IDisposable
{
void SetData(Bitmap bitmap);
void SetData(uint[,] colors);
void SetData(byte[] colors, int width, int height);
byte[] GetData();
@@ -108,6 +132,8 @@ namespace OpenRA
{
void Bind();
void Unbind();
void EnableScissor(Rectangle rect);
void DisableScissor();
ITexture Texture { get; }
}
@@ -130,4 +156,17 @@ namespace OpenRA
Fullscreen,
PseudoFullscreen,
}
public interface IFont : IDisposable
{
FontGlyph CreateGlyph(char c, int size, float deviceScale);
}
public struct FontGlyph
{
public int2 Offset;
public Size Size;
public float Advance;
public byte[] Data;
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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.Drawing;
using System.Linq;
using OpenRA.Primitives;
@@ -26,12 +25,16 @@ namespace OpenRA.Graphics
return ramp[i];
}
public PlayerColorRemap(int[] ramp, HSLColor c, float rampFraction)
public PlayerColorRemap(int[] ramp, Color c, float rampFraction)
{
var h = c.GetHue() / 360.0f;
var s = c.GetSaturation();
var l = c.GetBrightness();
// Increase luminosity if required to represent the full ramp
var rampRange = (byte)((1 - rampFraction) * c.L);
var c1 = new HSLColor(c.H, c.S, Math.Max(rampRange, c.L)).RGB;
var c2 = new HSLColor(c.H, c.S, (byte)Math.Max(0, c.L - rampRange)).RGB;
var rampRange = (byte)((1 - rampFraction) * l);
var c1 = Color.FromAhsl(h, s, Math.Max(rampRange, l));
var c2 = Color.FromAhsl(h, s, (byte)Math.Max(0, l - rampRange));
var baseIndex = ramp[0];
var remapRamp = ramp.Select(r => r - ramp[0]);
var rampMaxIndex = ramp.Length - 1;
@@ -44,14 +47,13 @@ namespace OpenRA.Graphics
remapRamp = ramp.Select(r => r - ramp[rampMaxIndex]);
}
remapColors = remapRamp.Select((x, i) => Pair.New(baseIndex + i, Exts.ColorLerp(x / (float)ramp.Length, c1, c2)))
.ToDictionary(u => u.First, u => u.Second);
remapColors = remapRamp.Select((x, i) => (baseIndex + i, Exts.ColorLerp(x / (float)ramp.Length, c1, c2)))
.ToDictionary(u => u.Item1, u => u.Item2);
}
public Color GetRemappedColor(Color original, int index)
{
Color c;
return remapColors.TryGetValue(index, out c)
return remapColors.TryGetValue(index, out var c)
? c : original;
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,7 @@
*/
#endregion
using System.Drawing;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
@@ -28,6 +28,11 @@ namespace OpenRA.Graphics
IFinalizedRenderable PrepareRender(WorldRenderer wr);
}
public interface ITintableRenderable
{
IRenderable WithTint(float3 newTint);
}
public interface IFinalizedRenderable
{
void Render(WorldRenderer wr);

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,49 +11,25 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
public class RgbaColorRenderer : Renderer.IBatchRenderer
public class RgbaColorRenderer
{
static readonly float2 Offset = new float2(0.5f, 0.5f);
static readonly float3 Offset = new float3(0.5f, 0.5f, 0f);
readonly Renderer renderer;
readonly IShader shader;
readonly Action renderAction;
readonly SpriteRenderer parent;
readonly Vertex[] vertices = new Vertex[6];
readonly Vertex[] vertices;
int nv = 0;
public RgbaColorRenderer(Renderer renderer, IShader shader)
public RgbaColorRenderer(SpriteRenderer parent)
{
this.renderer = renderer;
this.shader = shader;
vertices = new Vertex[renderer.TempBufferSize];
renderAction = () => renderer.DrawBatch(vertices, nv, PrimitiveType.TriangleList);
}
public void Flush()
{
if (nv > 0)
{
renderer.Device.SetBlendMode(BlendMode.Alpha);
shader.Render(renderAction);
renderer.Device.SetBlendMode(BlendMode.None);
nv = 0;
}
this.parent = parent;
}
public void DrawLine(float3 start, float3 end, float width, Color startColor, Color endColor)
{
renderer.CurrentBatchRenderer = this;
if (nv + 6 > renderer.TempBufferSize)
Flush();
var delta = (end - start) / (end - start).XY.Length;
var corner = width / 2 * new float3(-delta.Y, delta.X, delta.Z);
@@ -69,21 +45,18 @@ namespace OpenRA.Graphics
var eb = endColor.B / 255.0f;
var ea = endColor.A / 255.0f;
vertices[nv++] = new Vertex(start - corner + Offset, sr, sg, sb, sa, 0, 0);
vertices[nv++] = new Vertex(start + corner + Offset, sr, sg, sb, sa, 0, 0);
vertices[nv++] = new Vertex(end + corner + Offset, er, eg, eb, ea, 0, 0);
vertices[nv++] = new Vertex(end + corner + Offset, er, eg, eb, ea, 0, 0);
vertices[nv++] = new Vertex(end - corner + Offset, er, eg, eb, ea, 0, 0);
vertices[nv++] = new Vertex(start - corner + Offset, sr, sg, sb, sa, 0, 0);
vertices[0] = new Vertex(start - corner + Offset, sr, sg, sb, sa, 0, 0);
vertices[1] = new Vertex(start + corner + Offset, sr, sg, sb, sa, 0, 0);
vertices[2] = new Vertex(end + corner + Offset, er, eg, eb, ea, 0, 0);
vertices[3] = new Vertex(end + corner + Offset, er, eg, eb, ea, 0, 0);
vertices[4] = new Vertex(end - corner + Offset, er, eg, eb, ea, 0, 0);
vertices[5] = new Vertex(start - corner + Offset, sr, sg, sb, sa, 0, 0);
parent.DrawRGBAVertices(vertices);
}
public void DrawLine(float3 start, float3 end, float width, Color color)
{
renderer.CurrentBatchRenderer = this;
if (nv + 6 > renderer.TempBufferSize)
Flush();
var delta = (end - start) / (end - start).XY.Length;
var corner = width / 2 * new float2(-delta.Y, delta.X);
@@ -93,12 +66,13 @@ namespace OpenRA.Graphics
var b = color.B / 255.0f;
var a = color.A / 255.0f;
vertices[nv++] = new Vertex(start - corner + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(start + corner + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(end + corner + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(end + corner + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(end - corner + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(start - corner + Offset, r, g, b, a, 0, 0);
vertices[0] = new Vertex(start - corner + Offset, r, g, b, a, 0, 0);
vertices[1] = new Vertex(start + corner + Offset, r, g, b, a, 0, 0);
vertices[2] = new Vertex(end + corner + Offset, r, g, b, a, 0, 0);
vertices[3] = new Vertex(end + corner + Offset, r, g, b, a, 0, 0);
vertices[4] = new Vertex(end - corner + Offset, r, g, b, a, 0, 0);
vertices[5] = new Vertex(start - corner + Offset, r, g, b, a, 0, 0);
parent.DrawRGBAVertices(vertices);
}
/// <summary>
@@ -146,7 +120,6 @@ namespace OpenRA.Graphics
return;
}
renderer.CurrentBatchRenderer = this;
color = Util.PremultiplyAlpha(color);
var r = color.R / 255.0f;
var g = color.G / 255.0f;
@@ -180,19 +153,17 @@ namespace OpenRA.Graphics
var nextCorner = width / 2 * new float3(-nextDir.Y, nextDir.X, nextDir.Z);
// Vertices for the corners joining start-end to end-next
var cc = closed || i < limit ? IntersectionOf(end + corner, dir, end + nextCorner, nextDir) : end + corner;
var cd = closed || i < limit ? IntersectionOf(end - corner, dir, end - nextCorner, nextDir) : end - corner;
var cc = closed || i < limit - 1 ? IntersectionOf(end + corner, dir, end + nextCorner, nextDir) : end + corner;
var cd = closed || i < limit - 1 ? IntersectionOf(end - corner, dir, end - nextCorner, nextDir) : end - corner;
// Fill segment
if (nv + 6 > renderer.TempBufferSize)
Flush();
vertices[nv++] = new Vertex(ca + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(cb + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(cc + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(cc + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(cd + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(ca + Offset, r, g, b, a, 0, 0);
vertices[0] = new Vertex(ca + Offset, r, g, b, a, 0, 0);
vertices[1] = new Vertex(cb + Offset, r, g, b, a, 0, 0);
vertices[2] = new Vertex(cc + Offset, r, g, b, a, 0, 0);
vertices[3] = new Vertex(cc + Offset, r, g, b, a, 0, 0);
vertices[4] = new Vertex(cd + Offset, r, g, b, a, 0, 0);
vertices[5] = new Vertex(ca + Offset, r, g, b, a, 0, 0);
parent.DrawRGBAVertices(vertices);
// Advance line segment
end = next;
@@ -204,11 +175,6 @@ namespace OpenRA.Graphics
}
}
public void DrawLine(IEnumerable<float2> points, float width, Color color, bool connectSegments = false)
{
DrawLine(points.Select(p => new float3(p, 0)), width, color, connectSegments);
}
public void DrawLine(IEnumerable<float3> points, float width, Color color, bool connectSegments = false)
{
if (!connectSegments)
@@ -234,6 +200,20 @@ namespace OpenRA.Graphics
DrawPolygon(new[] { tl, tr, br, bl }, width, color);
}
public void FillTriangle(float3 a, float3 b, float3 c, Color color)
{
color = Util.PremultiplyAlpha(color);
var cr = color.R / 255.0f;
var cg = color.G / 255.0f;
var cb = color.B / 255.0f;
var ca = color.A / 255.0f;
vertices[0] = new Vertex(a + Offset, cr, cg, cb, ca, 0, 0);
vertices[1] = new Vertex(b + Offset, cr, cg, cb, ca, 0, 0);
vertices[2] = new Vertex(c + Offset, cr, cg, cb, ca, 0, 0);
parent.DrawRGBAVertices(vertices);
}
public void FillRect(float3 tl, float3 br, Color color)
{
var tr = new float3(br.X, tl.Y, tl.Z);
@@ -243,23 +223,42 @@ namespace OpenRA.Graphics
public void FillRect(float3 a, float3 b, float3 c, float3 d, Color color)
{
renderer.CurrentBatchRenderer = this;
if (nv + 6 > renderer.TempBufferSize)
Flush();
color = Util.PremultiplyAlpha(color);
var cr = color.R / 255.0f;
var cg = color.G / 255.0f;
var cb = color.B / 255.0f;
var ca = color.A / 255.0f;
vertices[nv++] = new Vertex(a + Offset, cr, cg, cb, ca, 0, 0);
vertices[nv++] = new Vertex(b + Offset, cr, cg, cb, ca, 0, 0);
vertices[nv++] = new Vertex(c + Offset, cr, cg, cb, ca, 0, 0);
vertices[nv++] = new Vertex(c + Offset, cr, cg, cb, ca, 0, 0);
vertices[nv++] = new Vertex(d + Offset, cr, cg, cb, ca, 0, 0);
vertices[nv++] = new Vertex(a + Offset, cr, cg, cb, ca, 0, 0);
vertices[0] = new Vertex(a + Offset, cr, cg, cb, ca, 0, 0);
vertices[1] = new Vertex(b + Offset, cr, cg, cb, ca, 0, 0);
vertices[2] = new Vertex(c + Offset, cr, cg, cb, ca, 0, 0);
vertices[3] = new Vertex(c + Offset, cr, cg, cb, ca, 0, 0);
vertices[4] = new Vertex(d + Offset, cr, cg, cb, ca, 0, 0);
vertices[5] = new Vertex(a + Offset, cr, cg, cb, ca, 0, 0);
parent.DrawRGBAVertices(vertices);
}
public void FillRect(float3 a, float3 b, float3 c, float3 d, Color topLeftColor, Color topRightColor, Color bottomRightColor, Color bottomLeftColor)
{
vertices[0] = VertexWithColor(a + Offset, topLeftColor);
vertices[1] = VertexWithColor(b + Offset, topRightColor);
vertices[2] = VertexWithColor(c + Offset, bottomRightColor);
vertices[3] = VertexWithColor(c + Offset, bottomRightColor);
vertices[4] = VertexWithColor(d + Offset, bottomLeftColor);
vertices[5] = VertexWithColor(a + Offset, topLeftColor);
parent.DrawRGBAVertices(vertices);
}
static Vertex VertexWithColor(float3 xyz, Color color)
{
color = Util.PremultiplyAlpha(color);
var cr = color.R / 255.0f;
var cg = color.G / 255.0f;
var cb = color.B / 255.0f;
var ca = color.A / 255.0f;
return new Vertex(xyz, cr, cg, cb, ca, 0, 0);
}
public void FillEllipse(float3 tl, float3 br, Color color, int vertices = 32)
@@ -276,20 +275,5 @@ namespace OpenRA.Graphics
DrawLine(new float3(xc - dx, y, z), new float3(xc + dx, y, z), 1, color);
}
}
public void SetViewportParams(Size screen, float depthScale, float depthOffset, float zoom, int2 scroll)
{
shader.SetVec("Scroll", scroll.X, scroll.Y, scroll.Y);
shader.SetVec("r1",
zoom * 2f / screen.Width,
-zoom * 2f / screen.Height,
-depthScale * zoom / screen.Height);
shader.SetVec("r2", -1, 1, 1 - depthOffset);
}
public void SetDepthPreviewEnabled(bool enabled)
{
shader.SetBool("EnableDepthPreview", enabled);
}
}
}

View File

@@ -0,0 +1,65 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 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
using System;
namespace OpenRA.Graphics
{
public class RgbaSpriteRenderer
{
readonly SpriteRenderer parent;
public RgbaSpriteRenderer(SpriteRenderer parent)
{
this.parent = parent;
}
public void DrawSprite(Sprite s, float3 location, float3 size)
{
if (s.Channel != TextureChannel.RGBA)
throw new InvalidOperationException("DrawRGBASprite requires a RGBA sprite.");
parent.DrawSprite(s, location, 0, size);
}
public void DrawSprite(Sprite s, float3 location)
{
if (s.Channel != TextureChannel.RGBA)
throw new InvalidOperationException("DrawRGBASprite requires a RGBA sprite.");
parent.DrawSprite(s, location, 0, s.Size);
}
public void DrawSprite(Sprite s, float3 a, float3 b, float3 c, float3 d)
{
if (s.Channel != TextureChannel.RGBA)
throw new InvalidOperationException("DrawRGBASprite requires a RGBA sprite.");
parent.DrawSprite(s, a, b, c, d);
}
public void DrawSpriteWithTint(Sprite s, float3 location, float3 size, float3 tint)
{
if (s.Channel != TextureChannel.RGBA)
throw new InvalidOperationException("DrawRGBASprite requires a RGBA sprite.");
parent.DrawSpriteWithTint(s, location, 0, size, tint);
}
public void DrawSpriteWithTint(Sprite s, float3 a, float3 b, float3 c, float3 d, float3 tint)
{
if (s.Channel != TextureChannel.RGBA)
throw new InvalidOperationException("DrawRGBASprite requires a RGBA sprite.");
parent.DrawSpriteWithTint(s, a, b, c, d, tint);
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,8 +11,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.FileSystem;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
@@ -31,10 +31,12 @@ namespace OpenRA.Graphics
int ShadowStart { get; }
int ShadowZOffset { get; }
int[] Frames { get; }
Rectangle Bounds { get; }
bool IgnoreWorldTint { get; }
Sprite GetSprite(int frame);
Sprite GetSprite(int frame, int facing);
Sprite GetShadow(int frame, int facing);
Sprite GetSprite(int frame, WAngle facing);
Sprite GetShadow(int frame, WAngle facing);
}
public interface ISpriteSequenceLoader
@@ -63,17 +65,15 @@ namespace OpenRA.Graphics
return Load(fileSystem, additionalSequences);
});
spriteCache = Exts.Lazy(() => new SpriteCache(fileSystem, modData.SpriteLoaders, new SheetBuilder(SheetType.Indexed)));
spriteCache = Exts.Lazy(() => new SpriteCache(fileSystem, modData.SpriteLoaders));
}
public ISpriteSequence GetSequence(string unitName, string sequenceName)
{
UnitSequences unitSeq;
if (!sequences.Value.TryGetValue(unitName, out unitSeq))
if (!sequences.Value.TryGetValue(unitName, out var unitSeq))
throw new InvalidOperationException("Unit `{0}` does not have any sequences defined.".F(unitName));
ISpriteSequence seq;
if (!unitSeq.Value.TryGetValue(sequenceName, out seq))
if (!unitSeq.Value.TryGetValue(sequenceName, out var seq))
throw new InvalidOperationException("Unit `{0}` does not have a sequence named `{1}`".F(unitName, sequenceName));
return seq;
@@ -86,8 +86,7 @@ namespace OpenRA.Graphics
public bool HasSequence(string unitName, string sequenceName)
{
UnitSequences unitSeq;
if (!sequences.Value.TryGetValue(unitName, out unitSeq))
if (!sequences.Value.TryGetValue(unitName, out var unitSeq))
throw new InvalidOperationException("Unit `{0}` does not have any sequences defined.".F(unitName));
return unitSeq.Value.ContainsKey(sequenceName);
@@ -95,8 +94,7 @@ namespace OpenRA.Graphics
public IEnumerable<string> Sequences(string unitName)
{
UnitSequences unitSeq;
if (!sequences.Value.TryGetValue(unitName, out unitSeq))
if (!sequences.Value.TryGetValue(unitName, out var unitSeq))
throw new InvalidOperationException("Unit `{0}` does not have any sequences defined.".F(unitName));
return unitSeq.Value.Keys;
@@ -113,8 +111,7 @@ namespace OpenRA.Graphics
var key = node.Value.ToLines(node.Key).JoinWith("|");
UnitSequences t;
if (sequenceCache.TryGetValue(key, out t))
if (sequenceCache.TryGetValue(key, out var t))
items.Add(node.Key, t);
else
{
@@ -129,16 +126,21 @@ namespace OpenRA.Graphics
public void Preload()
{
SpriteCache.SheetBuilder.Current.CreateBuffer();
foreach (var sb in SpriteCache.SheetBuilders.Values)
sb.Current.CreateBuffer();
foreach (var unitSeq in sequences.Value.Values)
foreach (var seq in unitSeq.Value.Values) { }
SpriteCache.SheetBuilder.Current.ReleaseBuffer();
foreach (var sb in SpriteCache.SheetBuilders.Values)
sb.Current.ReleaseBuffer();
}
public void Dispose()
{
if (spriteCache.IsValueCreated)
spriteCache.Value.SheetBuilder.Dispose();
foreach (var sb in SpriteCache.SheetBuilders.Values)
sb.Dispose();
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,10 +10,9 @@
#endregion
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using OpenRA.FileFormats;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
@@ -50,13 +49,10 @@ namespace OpenRA.Graphics
public Sheet(SheetType type, Stream stream)
{
using (var bitmap = (Bitmap)Image.FromStream(stream))
{
Size = bitmap.Size;
data = new byte[4 * Size.Width * Size.Height];
Util.FastCopyIntoSprite(new Sprite(this, bitmap.Bounds(), TextureChannel.Red), bitmap);
}
var png = new Png(stream);
Size = new Size(png.Width, png.Height);
data = new byte[4 * Size.Width * Size.Height];
Util.FastCopyIntoSprite(new Sprite(this, new Rectangle(0, 0, png.Width, png.Height), TextureChannel.Red), png);
Type = type;
ReleaseBuffer();
@@ -66,7 +62,7 @@ namespace OpenRA.Graphics
{
if (texture == null)
{
texture = Game.Renderer.Device.CreateTexture();
texture = Game.Renderer.Context.CreateTexture();
dirty = true;
}
@@ -81,48 +77,37 @@ namespace OpenRA.Graphics
return texture;
}
public Bitmap AsBitmap()
public Png AsPng()
{
var d = GetData();
var dataStride = 4 * Size.Width;
var bitmap = new Bitmap(Size.Width, Size.Height);
var data = GetData();
var bd = bitmap.LockBits(bitmap.Bounds(),
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
for (var y = 0; y < Size.Height; y++)
Marshal.Copy(d, y * dataStride, IntPtr.Add(bd.Scan0, y * bd.Stride), dataStride);
bitmap.UnlockBits(bd);
return bitmap;
}
public Bitmap AsBitmap(TextureChannel channel, IPalette pal)
{
var d = GetData();
var dataStride = 4 * Size.Width;
var bitmap = new Bitmap(Size.Width, Size.Height);
var channelOffset = (int)channel;
var bd = bitmap.LockBits(bitmap.Bounds(),
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
unsafe
// Convert BGRA to RGBA
for (var i = 0; i < Size.Width * Size.Height; i++)
{
var colors = (uint*)bd.Scan0;
for (var y = 0; y < Size.Height; y++)
{
var dataRowIndex = y * dataStride + channelOffset;
var bdRowIndex = y * bd.Stride / 4;
for (var x = 0; x < Size.Width; x++)
{
var paletteIndex = d[dataRowIndex + 4 * x];
colors[bdRowIndex + x] = pal[paletteIndex];
}
}
var temp = data[i * 4];
data[i * 4] = data[i * 4 + 2];
data[i * 4 + 2] = temp;
}
bitmap.UnlockBits(bd);
return new Png(data, Size.Width, Size.Height);
}
return bitmap;
public Png AsPng(TextureChannel channel, IPalette pal)
{
var d = GetData();
var plane = new byte[Size.Width * Size.Height];
var dataStride = 4 * Size.Width;
var channelOffset = (int)channel;
for (var y = 0; y < Size.Height; y++)
for (var x = 0; x < Size.Width; x++)
plane[y * Size.Width + x] = d[y * dataStride + channelOffset + 4 * x];
var palColors = new Color[Palette.Size];
for (var i = 0; i < Palette.Size; i++)
palColors[i] = pal.GetColor(i);
return new Png(plane, Size.Width, Size.Height, palColors);
}
public void CreateBuffer()
@@ -153,12 +138,15 @@ namespace OpenRA.Graphics
return;
dirty = true;
releaseBufferOnCommit = true;
// Commit data from the buffer to the texture, allowing the buffer to be released and reclaimed by GC.
if (Game.Renderer != null)
GetTexture();
}
public void Dispose()
{
if (texture != null)
texture.Dispose();
texture?.Dispose();
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,8 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using OpenRA.FileFormats;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
@@ -35,30 +36,42 @@ namespace OpenRA.Graphics
public readonly SheetType Type;
readonly List<Sheet> sheets = new List<Sheet>();
readonly Func<Sheet> allocateSheet;
readonly int margin;
Sheet current;
TextureChannel channel;
int rowHeight = 0;
Point p;
int2 p;
public static Sheet AllocateSheet(SheetType type, int sheetSize)
{
return new Sheet(type, new Size(sheetSize, sheetSize));
}
public static SheetType FrameTypeToSheetType(SpriteFrameType t)
{
switch (t)
{
case SpriteFrameType.Indexed: return SheetType.Indexed;
case SpriteFrameType.BGRA: return SheetType.BGRA;
default: throw new NotImplementedException("Unknown SpriteFrameType {0}".F(t));
}
}
public SheetBuilder(SheetType t)
: this(t, Game.Settings.Graphics.SheetSize) { }
public SheetBuilder(SheetType t, int sheetSize)
: this(t, () => AllocateSheet(t, sheetSize)) { }
public SheetBuilder(SheetType t, int sheetSize, int margin = 1)
: this(t, () => AllocateSheet(t, sheetSize), margin) { }
public SheetBuilder(SheetType t, Func<Sheet> allocateSheet)
public SheetBuilder(SheetType t, Func<Sheet> allocateSheet, int margin = 1)
{
channel = TextureChannel.Red;
channel = t == SheetType.Indexed ? TextureChannel.Red : TextureChannel.RGBA;
Type = t;
current = allocateSheet();
sheets.Add(current);
this.allocateSheet = allocateSheet;
this.margin = margin;
}
public Sprite Add(ISpriteFrame frame) { return Add(frame.Data, frame.Size, 0, frame.Offset); }
@@ -75,9 +88,9 @@ namespace OpenRA.Graphics
return rect;
}
public Sprite Add(Bitmap src)
public Sprite Add(Png src, float scale = 1f)
{
var rect = Allocate(src.Size);
var rect = Allocate(new Size(src.Width, src.Height), scale);
Util.FastCopyIntoSprite(rect, src);
current.CommitBufferedData();
return rect;
@@ -101,19 +114,19 @@ namespace OpenRA.Graphics
return (TextureChannel)nextChannel;
}
public Sprite Allocate(Size imageSize) { return Allocate(imageSize, 0, float3.Zero); }
public Sprite Allocate(Size imageSize, float zRamp, float3 spriteOffset)
public Sprite Allocate(Size imageSize, float scale = 1f) { return Allocate(imageSize, 0, float3.Zero, scale); }
public Sprite Allocate(Size imageSize, float zRamp, float3 spriteOffset, float scale = 1f)
{
if (imageSize.Width + p.X > current.Size.Width)
if (imageSize.Width + p.X + margin > current.Size.Width)
{
p = new Point(0, p.Y + rowHeight);
p = new int2(0, p.Y + rowHeight + margin);
rowHeight = imageSize.Height;
}
if (imageSize.Height > rowHeight)
rowHeight = imageSize.Height;
if (p.Y + imageSize.Height > current.Size.Height)
if (p.Y + imageSize.Height + margin > current.Size.Height)
{
var next = NextChannel(channel);
if (next == null)
@@ -121,22 +134,24 @@ namespace OpenRA.Graphics
current.ReleaseBuffer();
current = allocateSheet();
sheets.Add(current);
channel = TextureChannel.Red;
channel = Type == SheetType.Indexed ? TextureChannel.Red : TextureChannel.RGBA;
}
else
channel = next.Value;
rowHeight = imageSize.Height;
p = new Point(0, 0);
p = int2.Zero;
}
var rect = new Sprite(current, new Rectangle(p, imageSize), zRamp, spriteOffset, channel, BlendMode.Alpha);
p.X += imageSize.Width;
var rect = new Sprite(current, new Rectangle(p.X + margin, p.Y + margin, imageSize.Width, imageSize.Height), zRamp, spriteOffset, channel, BlendMode.Alpha, scale);
p += new int2(imageSize.Width + margin, 0);
return rect;
}
public Sheet Current { get { return current; } }
public TextureChannel CurrentChannel { get { return channel; } }
public IEnumerable<Sheet> AllSheets { get { return sheets; } }
public void Dispose()
{

View File

@@ -1,100 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 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
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
public interface ICursor : IDisposable
{
void Render(Renderer renderer);
void SetCursor(string cursor);
void Tick();
}
public sealed class SoftwareCursor : ICursor
{
readonly HardwarePalette palette = new HardwarePalette();
readonly Cache<string, PaletteReference> paletteReferences;
readonly Dictionary<string, Sprite[]> sprites = new Dictionary<string, Sprite[]>();
readonly CursorProvider cursorProvider;
readonly SheetBuilder sheetBuilder;
public SoftwareCursor(CursorProvider cursorProvider)
{
this.cursorProvider = cursorProvider;
paletteReferences = new Cache<string, PaletteReference>(CreatePaletteReference);
foreach (var p in cursorProvider.Palettes)
palette.AddPalette(p.Key, p.Value, false);
palette.Initialize();
sheetBuilder = new SheetBuilder(SheetType.Indexed);
foreach (var kv in cursorProvider.Cursors)
{
var s = kv.Value.Frames.Select(a => sheetBuilder.Add(a)).ToArray();
sprites.Add(kv.Key, s);
}
sheetBuilder.Current.ReleaseBuffer();
Game.Renderer.Device.SetHardwareCursor(null);
}
PaletteReference CreatePaletteReference(string name)
{
var pal = palette.GetPalette(name);
return new PaletteReference(name, palette.GetPaletteIndex(name), pal, palette);
}
string cursorName;
public void SetCursor(string cursor)
{
cursorName = cursor;
}
float cursorFrame;
public void Tick()
{
cursorFrame += 0.5f;
}
public void Render(Renderer renderer)
{
if (cursorName == null)
return;
var cursorSequence = cursorProvider.GetCursorSequence(cursorName);
var cursorSprite = sprites[cursorName][((int)cursorFrame % cursorSequence.Length)];
var cursorSize = CursorProvider.CursorViewportZoomed ? 2.0f * cursorSprite.Size : cursorSprite.Size;
var cursorOffset = CursorProvider.CursorViewportZoomed ?
(2 * cursorSequence.Hotspot) + cursorSprite.Size.XY.ToInt2() :
cursorSequence.Hotspot + (0.5f * cursorSprite.Size.XY).ToInt2();
renderer.SetPalette(palette);
renderer.SpriteRenderer.DrawSprite(cursorSprite,
Viewport.LastMousePos - cursorOffset,
paletteReferences[cursorSequence.Palette],
cursorSize);
}
public void Dispose()
{
palette.Dispose();
sheetBuilder.Dispose();
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,7 @@
#endregion
using System;
using System.Drawing;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
@@ -26,17 +26,17 @@ namespace OpenRA.Graphics
public readonly float3 FractionalOffset;
public readonly float Top, Left, Bottom, Right;
public Sprite(Sheet sheet, Rectangle bounds, TextureChannel channel)
: this(sheet, bounds, 0, float2.Zero, channel) { }
public Sprite(Sheet sheet, Rectangle bounds, TextureChannel channel, float scale = 1)
: this(sheet, bounds, 0, float2.Zero, channel, BlendMode.Alpha, scale) { }
public Sprite(Sheet sheet, Rectangle bounds, float zRamp, float3 offset, TextureChannel channel, BlendMode blendMode = BlendMode.Alpha)
public Sprite(Sheet sheet, Rectangle bounds, float zRamp, float3 offset, TextureChannel channel, BlendMode blendMode = BlendMode.Alpha, float scale = 1f)
{
Sheet = sheet;
Bounds = bounds;
Offset = offset;
ZRamp = zRamp;
Channel = channel;
Size = new float3(bounds.Size.Width, bounds.Size.Height, bounds.Size.Height * zRamp);
Size = scale * new float3(bounds.Size.Width, bounds.Size.Height, bounds.Size.Height * zRamp);
BlendMode = blendMode;
FractionalOffset = Size.Z != 0 ? offset / Size :
new float3(offset.X / Size.X, offset.Y / Size.Y, 0);
@@ -50,13 +50,15 @@ namespace OpenRA.Graphics
public class SpriteWithSecondaryData : Sprite
{
public readonly Sheet SecondarySheet;
public readonly Rectangle SecondaryBounds;
public readonly TextureChannel SecondaryChannel;
public readonly float SecondaryTop, SecondaryLeft, SecondaryBottom, SecondaryRight;
public SpriteWithSecondaryData(Sprite s, Rectangle secondaryBounds, TextureChannel secondaryChannel)
public SpriteWithSecondaryData(Sprite s, Sheet secondarySheet, Rectangle secondaryBounds, TextureChannel secondaryChannel)
: base(s.Sheet, s.Bounds, s.ZRamp, s.Offset, s.Channel, s.BlendMode)
{
SecondarySheet = secondarySheet;
SecondaryBounds = secondaryBounds;
SecondaryChannel = secondaryChannel;
SecondaryLeft = (float)Math.Min(secondaryBounds.Left, secondaryBounds.Right) / s.Sheet.Size.Width;
@@ -72,5 +74,6 @@ namespace OpenRA.Graphics
Green = 1,
Blue = 2,
Alpha = 3,
RGBA = 4
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,28 +10,26 @@
#endregion
using System;
using System.Drawing;
using System.Linq;
using OpenRA.Primitives;
using OpenRA.Support;
using OpenRA.Widgets;
using SharpFont;
namespace OpenRA.Graphics
{
public sealed class SpriteFont : IDisposable
{
static readonly Library Library = new Library();
public int TopOffset { get; private set; }
readonly int size;
readonly SheetBuilder builder;
readonly Func<string, float> lineWidth;
readonly Face face;
readonly Cache<Pair<char, Color>, GlyphInfo> glyphs;
readonly IFont font;
readonly Cache<char, GlyphInfo> glyphs;
readonly Cache<(char C, int Radius), Sprite> contrastGlyphs;
readonly Cache<int, float[]> dilationElements;
float deviceScale;
public SpriteFont(string name, byte[] data, int size, float scale, SheetBuilder builder)
public SpriteFont(string name, byte[] data, int size, int ascender, float scale, SheetBuilder builder)
{
if (builder.Type != SheetType.BGRA)
throw new ArgumentException("The sheet builder must create BGRA sheets.", "builder");
@@ -40,87 +38,199 @@ namespace OpenRA.Graphics
this.size = size;
this.builder = builder;
face = new Face(Library, data, 0);
face.SetPixelSizes((uint)(size * deviceScale), (uint)(size * deviceScale));
glyphs = new Cache<Pair<char, Color>, GlyphInfo>(CreateGlyph, Pair<char, Color>.EqualityComparer);
font = Game.Renderer.CreateFont(data);
glyphs = new Cache<char, GlyphInfo>(CreateGlyph);
contrastGlyphs = new Cache<(char, int), Sprite>(CreateContrastGlyph);
dilationElements = new Cache<int, float[]>(CreateCircularWeightMap);
// PERF: Cache these delegates for Measure calls.
Func<char, float> characterWidth = character => glyphs[Pair.New(character, Color.White)].Advance;
Func<char, float> characterWidth = character => glyphs[character].Advance;
lineWidth = line => line.Sum(characterWidth) / deviceScale;
PrecacheColor(Color.White, name);
PrecacheColor(Color.Red, name);
// Pre-cache small font sizes so glyphs are immediately available when we need them
if (size <= 24)
using (new PerfTimer("Precache {0} {1}px".F(name, size)))
for (var n = (char)0x20; n < (char)0x7f; n++)
if (glyphs[n] == null)
throw new InvalidOperationException();
TopOffset = size - ascender;
}
public void SetScale(float scale)
{
deviceScale = scale;
face.SetPixelSizes((uint)(size * deviceScale), (uint)(size * deviceScale));
glyphs.Clear();
contrastGlyphs.Clear();
}
void PrecacheColor(Color c, string name)
void DrawTextContrast(string text, float2 location, Color contrastColor, int contrastOffset)
{
using (new PerfTimer("PrecacheColor {0} {1}px {2}".F(name, size, c.Name)))
for (var n = (char)0x20; n < (char)0x7f; n++)
if (glyphs[Pair.New(n, c)] == null)
throw new InvalidOperationException();
}
// Offset from the baseline position to the top-left of the glyph for rendering
location += new float2(0, size);
public void DrawText(string text, float2 location, Color c)
{
location.Y += size; // baseline vs top
var p = location;
// Calculate positions in screen pixel coordinates
var screenContrast = (int)(contrastOffset * deviceScale);
var screen = new int2((int)(location.X * deviceScale + 0.5f), (int)(location.Y * deviceScale + 0.5f));
var contrastVector = new float2(screenContrast, screenContrast);
var tint = new float3(contrastColor.R / 255f, contrastColor.G / 255f, contrastColor.B / 255f);
foreach (var s in text)
{
if (s == '\n')
{
location.Y += size;
p = location;
location += new float2(0, size);
screen = new int2((int)(location.X * deviceScale + 0.5f), (int)(location.Y * deviceScale + 0.5f));
continue;
}
var g = glyphs[Pair.New(s, c)];
Game.Renderer.RgbaSpriteRenderer.DrawSprite(g.Sprite,
new float2(
(int)Math.Round(p.X * deviceScale + g.Offset.X, 0) / deviceScale,
p.Y + g.Offset.Y / deviceScale),
g.Sprite.Size / deviceScale);
p.X += g.Advance / deviceScale;
var g = glyphs[s];
// Convert screen coordinates back to UI coordinates for drawing
if (g.Sprite != null)
{
var contrastSprite = contrastGlyphs[(s, screenContrast)];
Game.Renderer.RgbaSpriteRenderer.DrawSpriteWithTint(contrastSprite,
(screen + g.Offset - contrastVector) / deviceScale,
contrastSprite.Size / deviceScale,
tint);
}
screen += new int2((int)(g.Advance + 0.5f), 0);
}
}
public void DrawText(string text, float2 location, Color c)
{
// Offset from the baseline position to the top-left of the glyph for rendering
location += new float2(0, size);
// Calculate positions in screen pixel coordinates
var screen = new int2((int)(location.X * deviceScale + 0.5f), (int)(location.Y * deviceScale + 0.5f));
var tint = new float3(c.R / 255f, c.G / 255f, c.B / 255f);
foreach (var s in text)
{
if (s == '\n')
{
location += new float2(0, size);
screen = new int2((int)(location.X * deviceScale + 0.5f), (int)(location.Y * deviceScale + 0.5f));
continue;
}
var g = glyphs[s];
// Convert screen coordinates back to UI coordinates for drawing
if (g.Sprite != null)
Game.Renderer.RgbaSpriteRenderer.DrawSpriteWithTint(g.Sprite,
(screen + g.Offset).ToFloat2() / deviceScale,
g.Sprite.Size / deviceScale,
tint);
screen += new int2((int)(g.Advance + 0.5f), 0);
}
}
float2 Rotate(float2 v, float sina, float cosa, float2 offset)
{
return new float2(
v.X * cosa - v.Y * sina + offset.X,
v.X * sina + v.Y * cosa + offset.Y);
}
public void DrawText(string text, float2 location, Color c, float angle)
{
// Offset from the baseline position to the top-left of the glyph for rendering
// All positions are calculated in UI coordinates
var offset = new float2(0, size);
var cosa = (float)Math.Cos(-angle);
var sina = (float)Math.Sin(-angle);
var tint = new float3(c.R / 255f, c.G / 255f, c.B / 255f);
var p = offset;
foreach (var s in text)
{
if (s == '\n')
{
offset += new float2(0, size);
p = offset;
continue;
}
var g = glyphs[s];
if (g.Sprite != null)
{
var tl = new float2(
p.X + g.Offset.X / deviceScale,
p.Y + g.Offset.Y / deviceScale);
var br = tl + g.Sprite.Size.XY / deviceScale;
var tr = new float2(br.X, tl.Y);
var bl = new float2(tl.X, br.Y);
var ra = Rotate(tl, sina, cosa, location);
var rb = Rotate(tr, sina, cosa, location);
var rc = Rotate(br, sina, cosa, location);
var rd = Rotate(bl, sina, cosa, location);
// Offset rotated glyph to align the top-left corner with the screen pixel grid
var screenOffset = new float2((int)(ra.X * deviceScale + 0.5f), (int)(ra.Y * deviceScale + 0.5f)) / deviceScale - ra;
Game.Renderer.RgbaSpriteRenderer.DrawSpriteWithTint(g.Sprite,
ra + screenOffset,
rb + screenOffset,
rc + screenOffset,
rd + screenOffset,
tint);
}
p += new float2(g.Advance / deviceScale, 0);
}
}
public void DrawTextWithContrast(string text, float2 location, Color fg, Color bg, int offset)
{
if (offset > 0)
{
DrawText(text, location + new float2(-offset / deviceScale, 0), bg);
DrawText(text, location + new float2(offset / deviceScale, 0), bg);
DrawText(text, location + new float2(0, -offset / deviceScale), bg);
DrawText(text, location + new float2(0, offset / deviceScale), bg);
}
DrawTextContrast(text, location, bg, offset);
DrawText(text, location, fg);
}
public void DrawTextWithContrast(string text, float2 location, Color fg, Color bgDark, Color bgLight, int offset)
{
DrawTextWithContrast(text, location, fg, WidgetUtils.GetContrastColor(fg, bgDark, bgLight), offset);
DrawTextWithContrast(text, location, fg, GetContrastColor(fg, bgDark, bgLight), offset);
}
public void DrawTextWithShadow(string text, float2 location, Color fg, Color bg, int offset)
{
if (offset != 0)
DrawText(text, location + new float2(offset, offset), bg);
{
// Shadow offsets are rounded to an integer number of screen pixels.
// This makes sure the shadow will be positioned consistently everywhere on the screen.
var screenOffset = (int)(offset * deviceScale) / deviceScale;
DrawText(text, location + new float2(screenOffset, screenOffset), bg);
}
DrawText(text, location, fg);
}
public void DrawTextWithShadow(string text, float2 location, Color fg, Color bgDark, Color bgLight, int offset)
{
DrawTextWithShadow(text, location, fg, WidgetUtils.GetContrastColor(fg, bgDark, bgLight), offset);
DrawTextWithShadow(text, location, fg, GetContrastColor(fg, bgDark, bgLight), offset);
}
public void DrawTextWithShadow(string text, float2 location, Color fg, Color bg, int offset, float angle)
{
if (offset != 0)
{
// Shadow offsets are rounded to an integer number of screen pixels.
// This makes sure the shadow will be positioned consistently everywhere on the screen.
var screenOffset = (int)(offset * deviceScale) / deviceScale;
DrawText(text, location + new float2(screenOffset, screenOffset), bg, angle);
}
DrawText(text, location, fg, angle);
}
public void DrawTextWithShadow(string text, float2 location, Color fg, Color bgDark, Color bgLight, int offset, float angle)
{
DrawTextWithShadow(text, location, fg, GetContrastColor(fg, bgDark, bgLight), offset, angle);
}
public int2 Measure(string text)
@@ -132,47 +242,42 @@ namespace OpenRA.Graphics
return new int2((int)Math.Ceiling(lines.Max(lineWidth)), lines.Length * size);
}
GlyphInfo CreateGlyph(Pair<char, Color> c)
GlyphInfo CreateGlyph(char c)
{
face.LoadChar(c.First, LoadFlags.Default, LoadTarget.Normal);
face.Glyph.RenderGlyph(RenderMode.Normal);
var size = new Size((int)face.Glyph.Metrics.Width, (int)face.Glyph.Metrics.Height);
var s = builder.Allocate(size);
var glyph = font.CreateGlyph(c, size, deviceScale);
if (glyph.Data == null)
{
return new GlyphInfo
{
Sprite = null,
Advance = 0,
Offset = int2.Zero
};
}
var s = builder.Allocate(glyph.Size);
var g = new GlyphInfo
{
Sprite = s,
Advance = (float)face.Glyph.Metrics.HorizontalAdvance,
Offset = new int2(face.Glyph.BitmapLeft, -face.Glyph.BitmapTop)
Advance = glyph.Advance,
Offset = glyph.Offset
};
// A new bitmap is generated each time this property is accessed, so we do need to dispose it.
using (var bitmap = face.Glyph.Bitmap)
var dest = s.Sheet.GetData();
var destStride = s.Sheet.Size.Width * 4;
for (var j = 0; j < s.Size.Y; j++)
{
unsafe
for (var i = 0; i < s.Size.X; i++)
{
var p = (byte*)bitmap.Buffer;
var dest = s.Sheet.GetData();
var destStride = s.Sheet.Size.Width * 4;
for (var j = 0; j < s.Size.Y; j++)
var p = glyph.Data[j * glyph.Size.Width + i];
if (p != 0)
{
for (var i = 0; i < s.Size.X; i++)
{
if (p[i] != 0)
{
var q = destStride * (j + s.Bounds.Top) + 4 * (i + s.Bounds.Left);
var pmc = Util.PremultiplyAlpha(Color.FromArgb(p[i], c.Second));
dest[q] = pmc.B;
dest[q + 1] = pmc.G;
dest[q + 2] = pmc.R;
dest[q + 3] = pmc.A;
}
}
p += bitmap.Pitch;
var q = destStride * (j + s.Bounds.Top) + 4 * (i + s.Bounds.Left);
dest[q] = p;
dest[q + 1] = p;
dest[q + 2] = p;
dest[q + 3] = p;
}
}
}
@@ -182,9 +287,131 @@ namespace OpenRA.Graphics
return g;
}
float[] CreateCircularWeightMap(int r)
{
// Create circular weight maps that are used by CreateContrastGlyph for
// both the structuring element and to weight the resulting pixel value.
// The output is a 2 * r + 1 square array giving the pixel intersection
// with a circle of radius (r + 0.5).
//
// Example output for r=1:
// 0.60 1.00 0.60
// 1.00 1.00 1.00
// 0.60 1.00 0.60
//
// Example output for r=3:
// 0.00 0.44 0.80 1.00 0.80 0.44 0.00
// 0.44 1.00 1.00 1.00 1.00 1.00 0.44
// 0.80 1.00 1.00 1.00 1.00 1.00 0.80
// 1.00 1.00 1.00 1.00 1.00 1.00 1.00
// 0.80 1.00 1.00 1.00 1.00 1.00 0.80
// 0.44 1.00 1.00 1.00 1.00 1.00 0.44
// 0.00 0.44 0.80 1.00 0.80 0.44 0.00
var stride = 2 * r + 1;
var elem = new float[stride * stride];
for (var j = 0; j <= 2 * r; j++)
{
for (var i = 0; i <= 2 * r; i++)
{
var di = i - r;
var dj = j - r;
// No intersection with circle
if (di * di + dj * dj > (r + 1) * (r + 1))
continue;
// Fully contained within circle
if (di * di + dj * dj < (r - 1) * (r - 1))
{
elem[j * stride + i] = 1;
continue;
}
// Approximate sub-pixel intersection using a 5x5 grid
for (var jj = 0; jj < 5; jj++)
{
for (var ii = 0; ii < 5; ii++)
{
var si = di - (float)Math.Sign(di) * ii / 5;
var sj = dj - (float)Math.Sign(dj) * jj / 5;
if (si * si + sj * sj <= r * r)
elem[j * stride + i] += 0.04f;
}
}
}
}
return elem;
}
Sprite CreateContrastGlyph((char C, int Radius) c)
{
var glyph = glyphs[c.C];
var r = c.Radius;
var s = builder.Allocate(new Size(glyph.Sprite.Bounds.Width + 2 * r, glyph.Sprite.Bounds.Height + 2 * r));
var dest = s.Sheet.GetData();
var destStride = s.Sheet.Size.Width * 4;
var glyphData = glyph.Sprite.Sheet.GetData();
var glyphStride = glyph.Sprite.Sheet.Size.Width * 4;
var glyphBounds = glyph.Sprite.Bounds;
var elem = dilationElements[r];
var elemStride = 2 * r + 1;
// Expand the glyph by applying the greyscale dilation operator to the source glyph's alpha channel
for (var j = 0; j < s.Size.Y; j++)
{
for (var i = 0; i < s.Size.X; i++)
{
// Apply the weight map to the source glyph and find the largest weighted alpha
var first = true;
var alpha = (byte)0;
for (var wj = 0; wj <= 2 * r; wj++)
{
for (var wi = 0; wi <= 2 * r; wi++)
{
// Ignore pixels that are outside the source glyph bounds
var ii = i + wi - 2 * r;
var jj = j + wj - 2 * r;
if (ii < 0 || ii >= glyphBounds.Width || jj < 0 || jj >= glyphBounds.Height)
continue;
// Weighted alpha for this pixel
var weighted = (byte)(elem[wj * elemStride + wi] * glyphData[glyphStride * (jj + glyphBounds.Top) + 4 * (ii + glyphBounds.Left) + 3]);
if (first || weighted > alpha)
{
alpha = weighted;
first = false;
}
}
}
if (alpha > 0)
{
var q = destStride * (j + s.Bounds.Top) + 4 * (i + s.Bounds.Left);
dest[q] = alpha;
dest[q + 1] = alpha;
dest[q + 2] = alpha;
dest[q + 3] = alpha;
}
}
}
s.Sheet.CommitBufferedData();
return s;
}
static Color GetContrastColor(Color fgColor, Color bgDark, Color bgLight)
{
return fgColor == Color.White || fgColor.GetBrightness() > 0.33 ? bgDark : bgLight;
}
public void Dispose()
{
face.Dispose();
font.Dispose();
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,8 +9,8 @@
*/
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using OpenRA.FileSystem;
@@ -18,13 +18,17 @@ using OpenRA.Primitives;
namespace OpenRA.Graphics
{
public enum SpriteFrameType { Indexed, BGRA }
public interface ISpriteLoader
{
bool TryParseSprite(Stream s, out ISpriteFrame[] frames);
bool TryParseSprite(Stream s, out ISpriteFrame[] frames, out TypeDictionary metadata);
}
public interface ISpriteFrame
{
SpriteFrameType Type { get; }
/// <summary>
/// Size of the frame's `Data`.
/// </summary>
@@ -43,47 +47,89 @@ namespace OpenRA.Graphics
public class SpriteCache
{
public readonly SheetBuilder SheetBuilder;
public readonly Cache<SpriteFrameType, SheetBuilder> SheetBuilders;
readonly ISpriteLoader[] loaders;
readonly IReadOnlyFileSystem fileSystem;
readonly Dictionary<string, List<Sprite[]>> sprites = new Dictionary<string, List<Sprite[]>>();
readonly Dictionary<string, ISpriteFrame[]> unloadedFrames = new Dictionary<string, ISpriteFrame[]>();
readonly Dictionary<string, TypeDictionary> metadata = new Dictionary<string, TypeDictionary>();
public SpriteCache(IReadOnlyFileSystem fileSystem, ISpriteLoader[] loaders, SheetBuilder sheetBuilder)
public SpriteCache(IReadOnlyFileSystem fileSystem, ISpriteLoader[] loaders)
{
SheetBuilder = sheetBuilder;
SheetBuilders = new Cache<SpriteFrameType, SheetBuilder>(t => new SheetBuilder(SheetBuilder.FrameTypeToSheetType(t)));
this.fileSystem = fileSystem;
this.loaders = loaders;
}
Sprite[] LoadSprite(string filename, List<Sprite[]> cache)
{
var sprite = SpriteLoader.GetSprites(fileSystem, filename, loaders, SheetBuilder);
cache.Add(sprite);
return sprite;
}
/// <summary>Returns the first set of sprites with the given filename.</summary>
public Sprite[] this[string filename]
/// <summary>
/// Returns the first set of sprites with the given filename.
/// If getUsedFrames is defined then the indices returned by the function call
/// are guaranteed to be loaded. The value of other indices in the returned
/// array are undefined and should never be accessed.
/// </summary>
public Sprite[] this[string filename, Func<int, IEnumerable<int>> getUsedFrames = null]
{
get
{
var allSprites = sprites.GetOrAdd(filename);
var sprite = allSprites.FirstOrDefault();
return sprite ?? LoadSprite(filename, allSprites);
if (!unloadedFrames.TryGetValue(filename, out var unloaded))
unloaded = null;
// This is the first time that the file has been requested
// Load all of the frames into the unused buffer and initialize
// the loaded cache (initially empty)
if (sprite == null)
{
unloaded = FrameLoader.GetFrames(fileSystem, filename, loaders, out var fileMetadata);
unloadedFrames[filename] = unloaded;
metadata[filename] = fileMetadata;
sprite = new Sprite[unloaded.Length];
allSprites.Add(sprite);
}
// HACK: The sequence code relies on side-effects from getUsedFrames
var indices = getUsedFrames != null ? getUsedFrames(sprite.Length) :
Enumerable.Range(0, sprite.Length);
// Load any unused frames into the SheetBuilder
if (unloaded != null)
{
foreach (var i in indices)
{
if (unloaded[i] != null)
{
sprite[i] = SheetBuilders[unloaded[i].Type].Add(unloaded[i]);
unloaded[i] = null;
}
}
// All frames have been loaded
if (unloaded.All(f => f == null))
unloadedFrames.Remove(filename);
}
return sprite;
}
}
/// <summary>Returns all instances of sets of sprites with the given filename</summary>
public IEnumerable<Sprite[]> AllCached(string filename)
/// <summary>
/// Returns a TypeDictionary containing any metadata defined by the frame
/// or null if the frame does not define metadata.
/// </summary>
public TypeDictionary FrameMetadata(string filename)
{
return sprites.GetOrAdd(filename);
}
if (!metadata.TryGetValue(filename, out var fileMetadata))
{
FrameLoader.GetFrames(fileSystem, filename, loaders, out fileMetadata);
metadata[filename] = fileMetadata;
}
/// <summary>Loads and caches a new instance of sprites with the given filename</summary>
public Sprite[] Reload(string filename)
{
return LoadSprite(filename, sprites.GetOrAdd(filename));
return fileMetadata;
}
}
@@ -93,24 +139,19 @@ namespace OpenRA.Graphics
public FrameCache(IReadOnlyFileSystem fileSystem, ISpriteLoader[] loaders)
{
frames = new Cache<string, ISpriteFrame[]>(filename => SpriteLoader.GetFrames(fileSystem, filename, loaders));
frames = new Cache<string, ISpriteFrame[]>(filename => FrameLoader.GetFrames(fileSystem, filename, loaders, out _));
}
public ISpriteFrame[] this[string filename] { get { return frames[filename]; } }
}
public static class SpriteLoader
public static class FrameLoader
{
public static Sprite[] GetSprites(IReadOnlyFileSystem fileSystem, string filename, ISpriteLoader[] loaders, SheetBuilder sheetBuilder)
{
return GetFrames(fileSystem, filename, loaders).Select(a => sheetBuilder.Add(a)).ToArray();
}
public static ISpriteFrame[] GetFrames(IReadOnlyFileSystem fileSystem, string filename, ISpriteLoader[] loaders)
public static ISpriteFrame[] GetFrames(IReadOnlyFileSystem fileSystem, string filename, ISpriteLoader[] loaders, out TypeDictionary metadata)
{
using (var stream = fileSystem.Open(filename))
{
var spriteFrames = GetFrames(stream, loaders);
var spriteFrames = GetFrames(stream, loaders, out metadata);
if (spriteFrames == null)
throw new InvalidDataException(filename + " is not a valid sprite file!");
@@ -118,11 +159,12 @@ namespace OpenRA.Graphics
}
}
public static ISpriteFrame[] GetFrames(Stream stream, ISpriteLoader[] loaders)
public static ISpriteFrame[] GetFrames(Stream stream, ISpriteLoader[] loaders, out TypeDictionary metadata)
{
ISpriteFrame[] frames;
metadata = null;
foreach (var loader in loaders)
if (loader.TryParseSprite(stream, out frames))
if (loader.TryParseSprite(stream, out var frames, out metadata))
return frames;
return null;

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,14 +10,13 @@
#endregion
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
public struct SpriteRenderable : IRenderable, IFinalizedRenderable
public struct SpriteRenderable : IRenderable, ITintableRenderable, IFinalizedRenderable
{
public static readonly IEnumerable<IRenderable> None = new IRenderable[0].AsEnumerable();
public static readonly IEnumerable<IRenderable> None = new IRenderable[0];
readonly Sprite sprite;
readonly WPos pos;
@@ -25,9 +24,17 @@ namespace OpenRA.Graphics
readonly int zOffset;
readonly PaletteReference palette;
readonly float scale;
readonly float3 tint;
readonly bool isDecoration;
readonly bool ignoreWorldTint;
public SpriteRenderable(Sprite sprite, WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale, bool isDecoration)
: this(sprite, pos, offset, zOffset, palette, scale, float3.Ones, isDecoration, false) { }
public SpriteRenderable(Sprite sprite, WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale, bool isDecoration, bool ignoreWorldTint)
: this(sprite, pos, offset, zOffset, palette, scale, float3.Ones, isDecoration, ignoreWorldTint) { }
public SpriteRenderable(Sprite sprite, WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale, float3 tint, bool isDecoration, bool ignoreWorldTint)
{
this.sprite = sprite;
this.pos = pos;
@@ -35,7 +42,9 @@ namespace OpenRA.Graphics
this.zOffset = zOffset;
this.palette = palette;
this.scale = scale;
this.tint = tint;
this.isDecoration = isDecoration;
this.ignoreWorldTint = ignoreWorldTint;
}
public WPos Pos { get { return pos + offset; } }
@@ -44,10 +53,12 @@ namespace OpenRA.Graphics
public int ZOffset { get { return zOffset; } }
public bool IsDecoration { get { return isDecoration; } }
public IRenderable WithPalette(PaletteReference newPalette) { return new SpriteRenderable(sprite, pos, offset, zOffset, newPalette, scale, isDecoration); }
public IRenderable WithZOffset(int newOffset) { return new SpriteRenderable(sprite, pos, offset, newOffset, palette, scale, isDecoration); }
public IRenderable OffsetBy(WVec vec) { return new SpriteRenderable(sprite, pos + vec, offset, zOffset, palette, scale, isDecoration); }
public IRenderable AsDecoration() { return new SpriteRenderable(sprite, pos, offset, zOffset, palette, scale, true); }
public IRenderable WithPalette(PaletteReference newPalette) { return new SpriteRenderable(sprite, pos, offset, zOffset, newPalette, scale, tint, isDecoration, ignoreWorldTint); }
public IRenderable WithZOffset(int newOffset) { return new SpriteRenderable(sprite, pos, offset, newOffset, palette, scale, tint, isDecoration, ignoreWorldTint); }
public IRenderable OffsetBy(WVec vec) { return new SpriteRenderable(sprite, pos + vec, offset, zOffset, palette, scale, tint, isDecoration, ignoreWorldTint); }
public IRenderable AsDecoration() { return new SpriteRenderable(sprite, pos, offset, zOffset, palette, scale, tint, true, ignoreWorldTint); }
public IRenderable WithTint(float3 newTint) { return new SpriteRenderable(sprite, pos, offset, zOffset, palette, scale, newTint, isDecoration, ignoreWorldTint); }
float3 ScreenPosition(WorldRenderer wr)
{
@@ -60,13 +71,25 @@ namespace OpenRA.Graphics
public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; }
public void Render(WorldRenderer wr)
{
Game.Renderer.WorldSpriteRenderer.DrawSprite(sprite, ScreenPosition(wr), palette, scale * sprite.Size);
var wsr = Game.Renderer.WorldSpriteRenderer;
if (ignoreWorldTint)
wsr.DrawSprite(sprite, ScreenPosition(wr), palette, scale * sprite.Size);
else
{
var t = tint;
if (wr.TerrainLighting != null)
t *= wr.TerrainLighting.TintAt(pos);
wsr.DrawSpriteWithTint(sprite, ScreenPosition(wr), palette, scale * sprite.Size, t);
}
}
public void RenderDebugGeometry(WorldRenderer wr)
{
var screenOffset = ScreenPosition(wr) + sprite.Offset;
Game.Renderer.WorldRgbaColorRenderer.DrawRect(screenOffset, screenOffset + sprite.Size, 1 / wr.Viewport.Zoom, Color.Red);
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);
}
public Rectangle ScreenBounds(WorldRenderer wr)

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,7 @@
#endregion
using System;
using System.Drawing;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
@@ -18,45 +18,97 @@ namespace OpenRA.Graphics
{
readonly Renderer renderer;
readonly IShader shader;
readonly Action renderAction;
readonly Vertex[] vertices;
Sheet currentSheet;
readonly Sheet[] sheets = new Sheet[7];
BlendMode currentBlend = BlendMode.Alpha;
int nv = 0;
int ns = 0;
public SpriteRenderer(Renderer renderer, IShader shader)
{
this.renderer = renderer;
this.shader = shader;
vertices = new Vertex[renderer.TempBufferSize];
renderAction = () => renderer.DrawBatch(vertices, nv, PrimitiveType.TriangleList);
}
public void Flush()
{
if (nv > 0)
{
shader.SetTexture("DiffuseTexture", currentSheet.GetTexture());
for (var i = 0; i < ns; i++)
{
shader.SetTexture("Texture{0}".F(i), sheets[i].GetTexture());
sheets[i] = null;
}
renderer.Device.SetBlendMode(currentBlend);
shader.Render(renderAction);
renderer.Device.SetBlendMode(BlendMode.None);
renderer.Context.SetBlendMode(currentBlend);
shader.PrepareRender();
renderer.DrawBatch(vertices, nv, PrimitiveType.TriangleList);
renderer.Context.SetBlendMode(BlendMode.None);
nv = 0;
currentSheet = null;
ns = 0;
}
}
void SetRenderStateForSprite(Sprite s)
int2 SetRenderStateForSprite(Sprite s)
{
renderer.CurrentBatchRenderer = this;
if (s.BlendMode != currentBlend || s.Sheet != currentSheet || nv + 6 > renderer.TempBufferSize)
if (s.BlendMode != currentBlend || nv + 6 > renderer.TempBufferSize)
Flush();
currentBlend = s.BlendMode;
currentSheet = s.Sheet;
// Check if the sheet (or secondary data sheet) have already been mapped
var sheet = s.Sheet;
var sheetIndex = 0;
for (; sheetIndex < ns; sheetIndex++)
if (sheets[sheetIndex] == sheet)
break;
var secondarySheetIndex = 0;
var ss = s as SpriteWithSecondaryData;
if (ss != null)
{
var secondarySheet = ss.SecondarySheet;
for (; secondarySheetIndex < ns; secondarySheetIndex++)
if (sheets[secondarySheetIndex] == secondarySheet)
break;
}
// Make sure that we have enough free samplers to map both if needed, otherwise flush
var needSamplers = (sheetIndex == ns ? 1 : 0) + (secondarySheetIndex == ns ? 1 : 0);
if (ns + needSamplers >= sheets.Length)
{
Flush();
sheetIndex = 0;
if (ss != null)
secondarySheetIndex = 1;
}
if (sheetIndex >= ns)
{
sheets[sheetIndex] = sheet;
ns += 1;
}
if (secondarySheetIndex >= ns && ss != null)
{
sheets[secondarySheetIndex] = ss.SecondarySheet;
ns += 1;
}
return new int2(sheetIndex, secondarySheetIndex);
}
internal void DrawSprite(Sprite s, float3 location, float paletteTextureIndex, float3 size)
{
var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, location + s.FractionalOffset * size, s, samplers, paletteTextureIndex, nv, size, float3.Ones);
nv += 6;
}
public void DrawSprite(Sprite s, float3 location, PaletteReference pal)
@@ -69,44 +121,52 @@ namespace OpenRA.Graphics
DrawSprite(s, location, pal.TextureIndex, size);
}
void DrawSprite(Sprite s, float3 location, float paletteTextureIndex, float3 size)
{
SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, location + s.FractionalOffset * size, s, paletteTextureIndex, nv, size);
nv += 6;
}
// For RGBASpriteRenderer, which doesn't use palettes
public void DrawSprite(Sprite s, float3 location)
{
DrawSprite(s, location, 0, s.Size);
}
public void DrawSprite(Sprite s, float3 location, float3 size)
{
DrawSprite(s, location, 0, size);
}
public void DrawSprite(Sprite s, float3 a, float3 b, float3 c, float3 d)
{
SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, a, b, c, d, s, 0, nv);
var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, a, b, c, d, s, samplers, 0, float3.Ones, nv);
nv += 6;
}
public void DrawSprite(Sprite s, Vertex[] sourceVertices, int offset)
internal void DrawSpriteWithTint(Sprite s, float3 location, float paletteTextureIndex, float3 size, float3 tint)
{
SetRenderStateForSprite(s);
Array.Copy(sourceVertices, offset, vertices, nv, 6);
var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, location + s.FractionalOffset * size, s, samplers, paletteTextureIndex, nv, size, tint);
nv += 6;
}
public void DrawSpriteWithTint(Sprite s, float3 location, PaletteReference pal, float3 size, float3 tint)
{
DrawSpriteWithTint(s, location, pal.TextureIndex, size, tint);
}
public void DrawSpriteWithTint(Sprite s, float3 a, float3 b, float3 c, float3 d, float3 tint)
{
var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, a, b, c, d, s, samplers, 0, tint, nv);
nv += 6;
}
public void DrawVertexBuffer(IVertexBuffer<Vertex> buffer, int start, int length, PrimitiveType type, Sheet sheet, BlendMode blendMode)
{
shader.SetTexture("DiffuseTexture", sheet.GetTexture());
renderer.Device.SetBlendMode(blendMode);
shader.Render(() => renderer.DrawBatch(buffer, start, length, type));
renderer.Device.SetBlendMode(BlendMode.None);
shader.SetTexture("Texture0", sheet.GetTexture());
renderer.Context.SetBlendMode(blendMode);
shader.PrepareRender();
renderer.DrawBatch(buffer, start, length, type);
renderer.Context.SetBlendMode(BlendMode.None);
}
// For RGBAColorRenderer
internal void DrawRGBAVertices(Vertex[] v)
{
renderer.CurrentBatchRenderer = this;
if (currentBlend != BlendMode.Alpha || nv + v.Length > renderer.TempBufferSize)
Flush();
currentBlend = BlendMode.Alpha;
Array.Copy(v, 0, vertices, nv, v.Length);
nv += v.Length;
}
public void SetPalette(ITexture palette)
@@ -114,22 +174,27 @@ namespace OpenRA.Graphics
shader.SetTexture("Palette", palette);
}
public void SetViewportParams(Size screen, float depthScale, float depthOffset, float zoom, int2 scroll)
public void SetViewportParams(Size screen, float depthScale, float depthOffset, int2 scroll)
{
shader.SetVec("Scroll", scroll.X, scroll.Y, scroll.Y);
shader.SetVec("r1",
zoom * 2f / screen.Width,
-zoom * 2f / screen.Height,
-depthScale * zoom / screen.Height);
shader.SetVec("r2", -1, 1, 1 - depthOffset);
2f / screen.Width,
2f / screen.Height,
-depthScale / screen.Height);
shader.SetVec("r2", -1, -1, 1 - depthOffset);
// Texture index is sampled as a float, so convert to pixels then scale
shader.SetVec("DepthTextureScale", 128 * depthScale * zoom / screen.Height);
shader.SetVec("DepthTextureScale", 128 * depthScale / screen.Height);
}
public void SetDepthPreviewEnabled(bool enabled)
{
shader.SetBool("EnableDepthPreview", enabled);
}
public void SetAntialiasingPixelsPerTexel(float pxPerTx)
{
shader.SetVec("AntialiasPixelsPerTexel", pxPerTx);
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,8 +10,8 @@
#endregion
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
@@ -19,11 +19,15 @@ namespace OpenRA.Graphics
{
readonly IEnumerable<WPos> waypoints;
readonly Color color;
readonly int width;
readonly int markerSize;
public TargetLineRenderable(IEnumerable<WPos> waypoints, Color color)
public TargetLineRenderable(IEnumerable<WPos> waypoints, Color color, int width = 1, int markerSize = 1)
{
this.waypoints = waypoints;
this.color = color;
this.width = width;
this.markerSize = markerSize;
}
public WPos Pos { get { return waypoints.First(); } }
@@ -42,26 +46,24 @@ namespace OpenRA.Graphics
if (!waypoints.Any())
return;
var iz = 1 / wr.Viewport.Zoom;
var first = wr.Screen3DPosition(waypoints.First());
var first = wr.Viewport.WorldToViewPx(wr.Screen3DPosition(waypoints.First()));
var a = first;
foreach (var b in waypoints.Skip(1).Select(pos => wr.Screen3DPosition(pos)))
foreach (var b in waypoints.Skip(1).Select(pos => wr.Viewport.WorldToViewPx(wr.Screen3DPosition(pos))))
{
Game.Renderer.WorldRgbaColorRenderer.DrawLine(a, b, iz, color);
DrawTargetMarker(wr, color, b);
Game.Renderer.RgbaColorRenderer.DrawLine(a, b, width, color);
DrawTargetMarker(wr, color, b, markerSize);
a = b;
}
DrawTargetMarker(wr, color, first);
}
public static void DrawTargetMarker(WorldRenderer wr, Color color, float3 location)
public static void DrawTargetMarker(WorldRenderer wr, Color color, int2 screenPos, int size = 1)
{
var iz = 1 / wr.Viewport.Zoom;
var offset = new float2(iz, iz);
var tl = location - offset;
var br = location + offset;
Game.Renderer.WorldRgbaColorRenderer.FillRect(tl, br, color);
var offset = new int2(size, size);
var tl = screenPos - offset;
var br = screenPos + offset;
Game.Renderer.RgbaColorRenderer.FillRect(tl, br, color);
}
public void RenderDebugGeometry(WorldRenderer wr) { }

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,13 +11,15 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
public sealed class TerrainSpriteLayer : IDisposable
{
static readonly int[] CornerVertexMap = { 0, 1, 2, 2, 3, 0 };
public readonly Sheet Sheet;
public readonly BlendMode BlendMode;
@@ -25,6 +27,7 @@ namespace OpenRA.Graphics
readonly IVertexBuffer<Vertex> vertexBuffer;
readonly Vertex[] vertices;
readonly bool[] ignoreTint;
readonly HashSet<int> dirtyRows = new HashSet<int>();
readonly int rowStride;
readonly bool restrictToBounds;
@@ -46,10 +49,16 @@ namespace OpenRA.Graphics
rowStride = 6 * map.MapSize.X;
vertices = new Vertex[rowStride * map.MapSize.Y];
vertexBuffer = Game.Renderer.Device.CreateVertexBuffer(vertices.Length);
vertexBuffer = Game.Renderer.Context.CreateVertexBuffer(vertices.Length);
emptySprite = new Sprite(sheet, Rectangle.Empty, TextureChannel.Alpha);
wr.PaletteInvalidated += UpdatePaletteIndices;
if (wr.TerrainLighting != null)
{
ignoreTint = new bool[rowStride * map.MapSize.Y];
wr.TerrainLighting.CellChanged += UpdateTint;
}
}
void UpdatePaletteIndices()
@@ -59,22 +68,76 @@ namespace OpenRA.Graphics
for (var i = 0; i < vertices.Length; i++)
{
var v = vertices[i];
vertices[i] = new Vertex(v.X, v.Y, v.Z, v.S, v.T, v.U, v.V, palette.TextureIndex, v.C);
vertices[i] = new Vertex(v.X, v.Y, v.Z, v.S, v.T, v.U, v.V, palette.TextureIndex, v.C, v.R, v.G, v.B);
}
for (var row = 0; row < map.MapSize.Y; row++)
dirtyRows.Add(row);
}
public void Update(CPos cell, Sprite sprite)
public void Clear(CPos cell)
{
var xyz = sprite == null ? float3.Zero :
worldRenderer.Screen3DPosition(map.CenterOfCell(cell)) + sprite.Offset - 0.5f * sprite.Size;
Update(cell.ToMPos(map.Grid.Type), sprite, xyz);
Update(cell, null, true);
}
public void Update(MPos uv, Sprite sprite, float3 pos)
public void Update(CPos cell, ISpriteSequence sequence, int frame)
{
Update(cell, sequence.GetSprite(frame), sequence.IgnoreWorldTint);
}
public void Update(CPos cell, Sprite sprite, bool ignoreTint)
{
var xyz = float3.Zero;
if (sprite != null)
{
var cellOrigin = map.CenterOfCell(cell) - new WVec(0, 0, map.Grid.Ramps[map.Ramp[cell]].CenterHeightOffset);
xyz = worldRenderer.Screen3DPosition(cellOrigin) + sprite.Offset - 0.5f * sprite.Size;
}
Update(cell.ToMPos(map.Grid.Type), sprite, xyz, ignoreTint);
}
void UpdateTint(MPos uv)
{
var offset = rowStride * uv.V + 6 * uv.U;
if (ignoreTint[offset])
{
var noTint = float3.Ones;
for (var i = 0; i < 6; i++)
{
var v = vertices[offset + i];
vertices[offset + i] = new Vertex(v.X, v.Y, v.Z, v.S, v.T, v.U, v.V, palette.TextureIndex, v.C, noTint);
}
return;
}
// Allow the terrain tint to vary linearly across the cell to smooth out the staircase effect
// This is done by sampling the lighting the corners of the sprite, even though those pixels are
// transparent for isometric tiles
var tl = worldRenderer.TerrainLighting;
var pos = map.CenterOfCell(uv.ToCPos(map));
var step = map.Grid.Type == MapGridType.RectangularIsometric ? 724 : 512;
var weights = new[]
{
tl.TintAt(pos + new WVec(-step, -step, 0)),
tl.TintAt(pos + new WVec(step, -step, 0)),
tl.TintAt(pos + new WVec(step, step, 0)),
tl.TintAt(pos + new WVec(-step, step, 0))
};
// Apply tint directly to the underlying vertices
// This saves us from having to re-query the sprite information, which has not changed
for (var i = 0; i < 6; i++)
{
var v = vertices[offset + i];
vertices[offset + i] = new Vertex(v.X, v.Y, v.Z, v.S, v.T, v.U, v.V, palette.TextureIndex, v.C, weights[CornerVertexMap[i]]);
}
dirtyRows.Add(uv.V);
}
public void Update(MPos uv, Sprite sprite, float3 pos, bool ignoreTint)
{
if (sprite != null)
{
@@ -92,7 +155,13 @@ namespace OpenRA.Graphics
return;
var offset = rowStride * uv.V + 6 * uv.U;
Util.FastCreateQuad(vertices, pos, sprite, palette.TextureIndex, offset, sprite.Size);
Util.FastCreateQuad(vertices, pos, sprite, int2.Zero, palette.TextureIndex, offset, sprite.Size, float3.Ones);
if (worldRenderer.TerrainLighting != null)
{
this.ignoreTint[offset] = ignoreTint;
UpdateTint(uv);
}
dirtyRows.Add(uv.V);
}
@@ -135,6 +204,9 @@ namespace OpenRA.Graphics
public void Dispose()
{
worldRenderer.PaletteInvalidated -= UpdatePaletteIndices;
if (worldRenderer.TerrainLighting != null)
worldRenderer.TerrainLighting.CellChanged -= UpdateTint;
vertexBuffer.Dispose();
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,8 +11,9 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using OpenRA.Primitives;
using OpenRA.Support;
namespace OpenRA.Graphics
@@ -34,7 +35,7 @@ namespace OpenRA.Graphics
public sealed class Theater : IDisposable
{
readonly Dictionary<ushort, TheaterTemplate> templates = new Dictionary<ushort, TheaterTemplate>();
readonly SheetBuilder sheetBuilder;
SheetBuilder sheetBuilder;
readonly Sprite missingTile;
readonly MersenneTwister random;
TileSet tileset;
@@ -53,7 +54,6 @@ namespace OpenRA.Graphics
return new Sheet(SheetType.Indexed, new Size(tileset.SheetSize, tileset.SheetSize));
};
sheetBuilder = new SheetBuilder(SheetType.Indexed, allocate);
random = new MersenneTwister();
var frameCache = new FrameCache(Game.ModData.DefaultFileSystem, Game.ModData.SpriteLoaders);
@@ -75,6 +75,15 @@ namespace OpenRA.Graphics
var zOffset = tile != null ? -tile.ZOffset : 0;
var zRamp = tile != null ? tile.ZRamp : 1f;
var offset = new float3(f.Offset, zOffset);
var type = SheetBuilder.FrameTypeToSheetType(f.Type);
// Defer SheetBuilder creation until we know what type of frames we are loading!
// TODO: Support mixed indexed and BGRA frames
if (sheetBuilder == null)
sheetBuilder = new SheetBuilder(SheetBuilder.FrameTypeToSheetType(f.Type), allocate);
else if (type != sheetBuilder.Type)
throw new InvalidDataException("Sprite type mismatch. Terrain sprites must all be either Indexed or RGBA.");
var s = sheetBuilder.Allocate(f.Size, zRamp, offset);
Util.FastCopyIntoChannel(s, f.Data);
@@ -85,7 +94,7 @@ namespace OpenRA.Graphics
// s and ss are guaranteed to use the same sheet
// because of the custom terrain sheet allocation
s = new SpriteWithSecondaryData(s, ss.Bounds, ss.Channel);
s = new SpriteWithSecondaryData(s, s.Sheet, ss.Bounds, ss.Channel);
}
return s;
@@ -102,15 +111,14 @@ namespace OpenRA.Graphics
}
// 1x1px transparent tile
missingTile = sheetBuilder.Add(new byte[1], new Size(1, 1));
missingTile = sheetBuilder.Add(new byte[sheetBuilder.Type == SheetType.BGRA ? 4 : 1], new Size(1, 1));
Sheet.ReleaseBuffer();
}
public Sprite TileSprite(TerrainTile r, int? variant = null)
{
TheaterTemplate template;
if (!templates.TryGetValue(r.Type, out template))
if (!templates.TryGetValue(r.Type, out var template))
return missingTile;
if (r.Index >= template.Stride)

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,7 @@
*/
#endregion
using System.Drawing;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,8 +10,8 @@
#endregion
using System;
using System.Drawing;
using System.Drawing.Imaging;
using OpenRA.FileFormats;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
@@ -19,24 +19,28 @@ namespace OpenRA.Graphics
{
// yes, our channel order is nuts.
static readonly int[] ChannelMasks = { 2, 1, 0, 3 };
static readonly float[] ChannelSelect = { 0.2f, 0.4f, 0.6f, 0.8f };
public static void FastCreateQuad(Vertex[] vertices, float3 o, Sprite r, float paletteTextureIndex, int nv, float3 size)
public static void FastCreateQuad(Vertex[] vertices, float3 o, Sprite r, int2 samplers, float paletteTextureIndex, int nv, float3 size, float3 tint)
{
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, paletteTextureIndex, nv);
FastCreateQuad(vertices, o, b, c, d, r, samplers, paletteTextureIndex, tint, nv);
}
public static void FastCreateQuad(Vertex[] vertices, float3 a, float3 b, float3 c, float3 d, Sprite r, float paletteTextureIndex, int nv)
public static void FastCreateQuad(Vertex[] vertices,
float3 a, float3 b, float3 c, float3 d,
Sprite r, int2 samplers, float paletteTextureIndex,
float3 tint, int nv)
{
float sl = 0;
float st = 0;
float sr = 0;
float sb = 0;
var attribC = ChannelSelect[(int)r.Channel];
// See shp.vert for documentation on the channel attribute format
var attribC = r.Channel == TextureChannel.RGBA ? 0x02 : ((byte)r.Channel) << 1 | 0x01;
attribC |= samplers.X << 6;
var ss = r as SpriteWithSecondaryData;
if (ss != null)
{
@@ -44,62 +48,31 @@ namespace OpenRA.Graphics
st = ss.SecondaryTop;
sr = ss.SecondaryRight;
sb = ss.SecondaryBottom;
attribC = -(attribC + ChannelSelect[(int)ss.SecondaryChannel] / 10);
attribC |= ((byte)ss.SecondaryChannel) << 4 | 0x08;
attribC |= samplers.Y << 9;
}
vertices[nv] = new Vertex(a, r.Left, r.Top, sl, st, paletteTextureIndex, attribC);
vertices[nv + 1] = new Vertex(b, r.Right, r.Top, sr, st, paletteTextureIndex, attribC);
vertices[nv + 2] = new Vertex(c, r.Right, r.Bottom, sr, sb, paletteTextureIndex, attribC);
vertices[nv + 3] = new Vertex(c, r.Right, r.Bottom, sr, sb, paletteTextureIndex, attribC);
vertices[nv + 4] = new Vertex(d, r.Left, r.Bottom, sl, sb, paletteTextureIndex, attribC);
vertices[nv + 5] = new Vertex(a, r.Left, r.Top, sl, st, paletteTextureIndex, attribC);
var fAttribC = (float)attribC;
vertices[nv] = new Vertex(a, r.Left, r.Top, sl, st, paletteTextureIndex, fAttribC, tint);
vertices[nv + 1] = new Vertex(b, r.Right, r.Top, sr, st, paletteTextureIndex, fAttribC, tint);
vertices[nv + 2] = new Vertex(c, r.Right, r.Bottom, sr, sb, paletteTextureIndex, fAttribC, tint);
vertices[nv + 3] = new Vertex(c, r.Right, r.Bottom, sr, sb, paletteTextureIndex, fAttribC, tint);
vertices[nv + 4] = new Vertex(d, r.Left, r.Bottom, sl, sb, paletteTextureIndex, fAttribC, tint);
vertices[nv + 5] = new Vertex(a, r.Left, r.Top, sl, st, paletteTextureIndex, fAttribC, tint);
}
public static void FastCopyIntoChannel(Sprite dest, byte[] src)
{
var data = dest.Sheet.GetData();
var srcStride = dest.Bounds.Width;
var destStride = dest.Sheet.Size.Width * 4;
var destOffset = destStride * dest.Bounds.Top + dest.Bounds.Left * 4 + ChannelMasks[(int)dest.Channel];
var destSkip = destStride - 4 * srcStride;
var destData = dest.Sheet.GetData();
var width = dest.Bounds.Width;
var height = dest.Bounds.Height;
var srcOffset = 0;
for (var j = 0; j < height; j++)
if (dest.Channel == TextureChannel.RGBA)
{
for (var i = 0; i < srcStride; i++, srcOffset++)
{
data[destOffset] = src[srcOffset];
destOffset += 4;
}
destOffset += destSkip;
}
}
public static void FastCopyIntoSprite(Sprite dest, Bitmap src)
{
var createdTempBitmap = false;
if (src.PixelFormat != PixelFormat.Format32bppArgb)
{
src = src.CloneWith32bbpArgbPixelFormat();
createdTempBitmap = true;
}
try
{
var destData = dest.Sheet.GetData();
var destStride = dest.Sheet.Size.Width;
var width = dest.Bounds.Width;
var height = dest.Bounds.Height;
var srcData = src.LockBits(src.Bounds(),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
unsafe
{
var c = (int*)srcData.Scan0;
// Cast the data to an int array so we can copy the src data directly
fixed (byte* bd = &destData[0])
{
@@ -107,23 +80,80 @@ namespace OpenRA.Graphics
var x = dest.Bounds.Left;
var y = dest.Bounds.Top;
var k = 0;
for (var j = 0; j < height; j++)
{
for (var i = 0; i < width; i++)
{
var cc = Color.FromArgb(*(c + (j * srcData.Stride >> 2) + i));
var r = src[k++];
var g = src[k++];
var b = src[k++];
var a = src[k++];
var cc = Color.FromArgb(a, r, g, b);
data[(y + j) * destStride + x + i] = PremultiplyAlpha(cc).ToArgb();
}
}
}
}
src.UnlockBits(srcData);
}
finally
else
{
if (createdTempBitmap)
src.Dispose();
var destStride = dest.Sheet.Size.Width * 4;
var destOffset = destStride * dest.Bounds.Top + dest.Bounds.Left * 4 + ChannelMasks[(int)dest.Channel];
var destSkip = destStride - 4 * width;
var srcOffset = 0;
for (var j = 0; j < height; j++)
{
for (var i = 0; i < width; i++, srcOffset++)
{
destData[destOffset] = src[srcOffset];
destOffset += 4;
}
destOffset += destSkip;
}
}
}
public static void FastCopyIntoSprite(Sprite dest, Png src)
{
var destData = dest.Sheet.GetData();
var destStride = dest.Sheet.Size.Width;
var width = dest.Bounds.Width;
var height = dest.Bounds.Height;
unsafe
{
// Cast the data to an int array so we can copy the src data directly
fixed (byte* bd = &destData[0])
{
var data = (int*)bd;
var x = dest.Bounds.Left;
var y = dest.Bounds.Top;
var k = 0;
for (var j = 0; j < height; j++)
{
for (var i = 0; i < width; i++)
{
Color cc;
if (src.Palette == null)
{
var r = src.Data[k++];
var g = src.Data[k++];
var b = src.Data[k++];
var a = src.Data[k++];
cc = Color.FromArgb(a, r, g, b);
}
else
cc = src.Palette[src.Data[k++]];
data[(y + j) * destStride + x + i] = PremultiplyAlpha(cc).ToArgb();
}
}
}
}
}
@@ -323,12 +353,31 @@ namespace OpenRA.Graphics
return mtx;
}
public static float[] MakeFloatMatrix(int[] imtx)
public static float[] MakeFloatMatrix(Int32Matrix4x4 imtx)
{
var fmtx = new float[16];
for (var i = 0; i < 16; i++)
fmtx[i] = imtx[i] * 1f / imtx[15];
return fmtx;
var multipler = 1f / imtx.M44;
return new[]
{
imtx.M11 * multipler,
imtx.M12 * multipler,
imtx.M13 * multipler,
imtx.M14 * multipler,
imtx.M21 * multipler,
imtx.M22 * multipler,
imtx.M23 * multipler,
imtx.M24 * multipler,
imtx.M31 * multipler,
imtx.M32 * multipler,
imtx.M33 * multipler,
imtx.M34 * multipler,
imtx.M41 * multipler,
imtx.M42 * multipler,
imtx.M43 * multipler,
imtx.M44 * multipler,
};
}
public static float[] MatrixAABBMultiply(float[] mtx, float[] bounds)
@@ -339,13 +388,16 @@ namespace OpenRA.Graphics
var iz = new uint[] { 2, 5, 2, 5, 2, 5, 2, 5 };
// Vectors to opposing corner
var ret = new float[] { float.MaxValue, float.MaxValue, float.MaxValue,
float.MinValue, float.MinValue, float.MinValue };
var ret = new[]
{
float.MaxValue, float.MaxValue, float.MaxValue,
float.MinValue, float.MinValue, float.MinValue
};
// Transform vectors and find new bounding box
for (var i = 0; i < 8; i++)
{
var vec = new float[] { bounds[ix[i]], bounds[iy[i]], bounds[iz[i]], 1 };
var vec = new[] { bounds[ix[i]], bounds[iy[i]], bounds[iz[i]], 1 };
var tvec = MatrixVectorMultiply(mtx, vec);
ret[0] = Math.Min(ret[0], tvec[0] / tvec[3]);

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,17 +16,34 @@ namespace OpenRA.Graphics
[StructLayout(LayoutKind.Sequential)]
public struct Vertex
{
public readonly float X, Y, Z, S, T, U, V, P, C;
// 3d position
public readonly float X, Y, Z;
// Primary and secondary texture coordinates or RGBA color
public readonly float S, T, U, V;
// Palette and channel flags
public readonly float P, C;
// Color tint
public readonly float R, G, B;
public Vertex(float3 xyz, float s, float t, float u, float v, float p, float c)
: this(xyz.X, xyz.Y, xyz.Z, s, t, u, v, p, c) { }
: this(xyz.X, xyz.Y, xyz.Z, s, t, u, v, p, c, float3.Ones) { }
public Vertex(float x, float y, float z, float s, float t, float u, float v, float p, float c)
public Vertex(float3 xyz, float s, float t, float u, float v, float p, float c, float3 tint)
: this(xyz.X, xyz.Y, xyz.Z, s, t, u, v, p, c, tint.X, tint.Y, tint.Z) { }
public Vertex(float x, float y, float z, float s, float t, float u, float v, float p, float c, float3 tint)
: this(x, y, z, s, t, u, v, p, c, tint.X, tint.Y, tint.Z) { }
public Vertex(float x, float y, float z, float s, float t, float u, float v, float p, float c, float r, float g, float b)
{
X = x; Y = y; Z = z;
S = s; T = t;
U = u; V = v;
P = p; C = c;
R = r; G = g; B = b;
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,14 +11,19 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.Primitives;
namespace OpenRA.Graphics
{
[Flags]
public enum ScrollDirection { None = 0, Up = 1, Left = 2, Down = 4, Right = 8 }
public interface INotifyViewportZoomExtentsChanged
{
void ViewportZoomExtentsChanged(float minZoom, float maxZoom);
}
public static class ViewportExts
{
public static bool Includes(this ScrollDirection d, ScrollDirection s)
@@ -36,6 +41,8 @@ namespace OpenRA.Graphics
public class Viewport
{
readonly WorldRenderer worldRenderer;
readonly WorldViewportSizes viewportSizes;
readonly GraphicSettings graphicSettings;
// Map bounds (world-px)
readonly Rectangle mapBounds;
@@ -46,6 +53,7 @@ namespace OpenRA.Graphics
public WPos CenterPosition { get { return worldRenderer.ProjectedPosition(CenterLocation); } }
public Rectangle Rectangle { get { return new Rectangle(TopLeft, new Size(viewportSize.X, viewportSize.Y)); } }
public int2 TopLeft { get { return CenterLocation - viewportSize / 2; } }
public int2 BottomRight { get { return CenterLocation + viewportSize / 2; } }
int2 viewportSize;
@@ -54,14 +62,16 @@ namespace OpenRA.Graphics
ProjectedCellRegion allCells;
bool allCellsDirty = true;
readonly float[] availableZoomSteps = new[] { 2f, 1f, 0.5f, 0.25f };
WorldViewport lastViewportDistance;
float zoom = 1f;
float minZoom = 1f;
float maxZoom = 2f;
public float[] AvailableZoomSteps
{
get { return availableZoomSteps; }
}
bool unlockMinZoom;
float unlockedMinZoomScale;
float unlockedMinZoom = 1f;
public float Zoom
{
@@ -70,17 +80,48 @@ namespace OpenRA.Graphics
return zoom;
}
set
private set
{
var newValue = ClosestTo(AvailableZoomSteps, value);
zoom = newValue;
viewportSize = (1f / zoom * new float2(Game.Renderer.Resolution)).ToInt2();
zoom = value;
viewportSize = (1f / zoom * new float2(Game.Renderer.NativeResolution)).ToInt2();
cellsDirty = true;
allCellsDirty = true;
}
}
public static long TicksSinceLastMove = 0;
public float MinZoom { get { return minZoom; } }
public void AdjustZoom(float dz)
{
// Exponential ensures that equal positive and negative steps have the same effect
Zoom = (zoom * (float)Math.Exp(dz)).Clamp(unlockMinZoom ? unlockedMinZoom : minZoom, maxZoom);
}
public void AdjustZoom(float dz, int2 center)
{
var oldCenter = worldRenderer.Viewport.ViewToWorldPx(center);
AdjustZoom(dz);
var newCenter = worldRenderer.Viewport.ViewToWorldPx(center);
CenterLocation += oldCenter - newCenter;
}
public void ToggleZoom()
{
// Unlocked zooms always reset to the default zoom
if (zoom < minZoom)
Zoom = minZoom;
else
Zoom = zoom > minZoom ? minZoom : maxZoom;
}
public void UnlockMinimumZoom(float scale)
{
unlockMinZoom = true;
unlockedMinZoomScale = scale;
UpdateViewportZooms(false);
}
public static long LastMoveRunTime = 0;
public static int2 LastMousePos;
float ClosestTo(float[] collection, float target)
@@ -119,6 +160,8 @@ namespace OpenRA.Graphics
{
worldRenderer = wr;
var grid = Game.ModData.Manifest.Get<MapGrid>();
viewportSizes = Game.ModData.Manifest.Get<WorldViewportSizes>();
graphicSettings = Game.Settings.Graphics;
// Calculate map bounds in world-px
if (wr.World.Type == WorldType.Editor)
@@ -140,8 +183,78 @@ namespace OpenRA.Graphics
CenterLocation = (tl + br) / 2;
}
Zoom = Game.Settings.Graphics.PixelDouble ? 2 : 1;
tileSize = grid.TileSize;
UpdateViewportZooms();
}
public void Tick()
{
if (lastViewportDistance != graphicSettings.ViewportDistance)
UpdateViewportZooms();
}
float CalculateMinimumZoom(float minHeight, float maxHeight)
{
var h = Game.Renderer.NativeResolution.Height;
// Check the easy case: the native resolution is within the maximum limit
// Also catches the case where the user may force a resolution smaller than the minimum window size
if (h <= maxHeight)
return 1;
// Find a clean fraction that brings us within the desired range to reduce aliasing
var step = 1f;
while (true)
{
var testZoom = 1f;
while (true)
{
var nextZoom = testZoom + step;
if (h < minHeight * nextZoom)
break;
testZoom = nextZoom;
}
if (h < maxHeight * testZoom)
return testZoom;
step /= 2;
}
}
void UpdateViewportZooms(bool resetCurrentZoom = true)
{
lastViewportDistance = graphicSettings.ViewportDistance;
var vd = graphicSettings.ViewportDistance;
if (viewportSizes.AllowNativeZoom && vd == WorldViewport.Native)
minZoom = 1;
else
{
var range = viewportSizes.GetSizeRange(vd);
minZoom = CalculateMinimumZoom(range.X, range.Y);
}
maxZoom = Math.Min(minZoom * viewportSizes.MaxZoomScale, Game.Renderer.NativeResolution.Height * 1f / viewportSizes.MaxZoomWindowHeight);
if (unlockMinZoom)
{
// Specators 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
unlockedMinZoom = minZoom * unlockedMinZoomScale;
}
if (resetCurrentZoom)
Zoom = minZoom;
else
Zoom = Zoom.Clamp(minZoom, maxZoom);
foreach (var t in worldRenderer.World.WorldActor.TraitsImplementing<INotifyViewportZoomExtentsChanged>())
t.ViewportZoomExtentsChanged(minZoom, maxZoom);
}
public CPos ViewToWorld(int2 view)
@@ -149,7 +262,6 @@ namespace OpenRA.Graphics
var world = worldRenderer.Viewport.ViewToWorldPx(view);
var map = worldRenderer.World.Map;
var candidates = CandidateMouseoverCells(world).ToList();
var tileSet = worldRenderer.World.Map.Rules.TileSet;
foreach (var uv in candidates)
{
@@ -158,18 +270,9 @@ namespace OpenRA.Graphics
var s = worldRenderer.ScreenPxPosition(p);
if (Math.Abs(s.X - world.X) <= tileSize.Width && Math.Abs(s.Y - world.Y) <= tileSize.Height)
{
var ramp = 0;
if (map.Contains(uv))
{
var ti = tileSet.GetTileInfo(map.Tiles[uv]);
if (ti != null)
ramp = ti.RampType;
}
var corners = map.Grid.CellCorners[ramp];
var pos = map.CenterOfCell(uv.ToCPos(map));
var screen = corners.Select(c => worldRenderer.ScreenPxPosition(pos + c)).ToArray();
var ramp = map.Grid.Ramps[map.Ramp.Contains(uv) ? map.Ramp[uv] : 0];
var pos = map.CenterOfCell(uv.ToCPos(map)) - new WVec(0, 0, ramp.CenterHeightOffset);
var screen = ramp.Corners.Select(c => worldRenderer.ScreenPxPosition(pos + c)).ToArray();
if (screen.PolygonContains(world))
return uv.ToCPos(map);
}
@@ -209,8 +312,9 @@ namespace OpenRA.Graphics
yield return new MPos(u, v);
}
public int2 ViewToWorldPx(int2 view) { return (1f / Zoom * view.ToFloat2()).ToInt2() + TopLeft; }
public int2 WorldToViewPx(int2 world) { return (Zoom * (world - TopLeft).ToFloat2()).ToInt2(); }
public int2 ViewToWorldPx(int2 view) { return (graphicSettings.UIScale / Zoom * view.ToFloat2()).ToInt2() + TopLeft; }
public int2 WorldToViewPx(int2 world) { return ((Zoom / graphicSettings.UIScale) * (world - TopLeft).ToFloat2()).ToInt2(); }
public int2 WorldToViewPx(float3 world) { return ((Zoom / graphicSettings.UIScale) * (world - TopLeft).XY).ToInt2(); }
public void Center(IEnumerable<Actor> actors)
{
@@ -239,7 +343,6 @@ namespace OpenRA.Graphics
}
// Rectangle (in viewport coords) that contains things to be drawn
static readonly Rectangle ScreenClip = Rectangle.FromLTRB(0, 0, Game.Renderer.Resolution.Width, Game.Renderer.Resolution.Height);
public Rectangle GetScissorBounds(bool insideBounds)
{
// Visible rectangle in world coordinates (expanded to the corners of the cells)
@@ -249,12 +352,12 @@ namespace OpenRA.Graphics
var cbr = map.CenterOfCell(((MPos)bounds.BottomRight).ToCPos(map)) + new WVec(512, 512, 0);
// Convert to screen coordinates
var tl = WorldToViewPx(worldRenderer.ScreenPxPosition(ctl - new WVec(0, 0, ctl.Z))).Clamp(ScreenClip);
var br = WorldToViewPx(worldRenderer.ScreenPxPosition(cbr - new WVec(0, 0, cbr.Z))).Clamp(ScreenClip);
var tl = worldRenderer.ScreenPxPosition(ctl - new WVec(0, 0, ctl.Z)) - TopLeft;
var br = worldRenderer.ScreenPxPosition(cbr - new WVec(0, 0, cbr.Z)) - TopLeft;
// Add an extra one cell fudge in each direction for safety
return Rectangle.FromLTRB(tl.X - tileSize.Width, tl.Y - tileSize.Height,
br.X + tileSize.Width, br.Y + tileSize.Height);
// Add an extra half-cell fudge to avoid clipping isometric tiles
return Rectangle.FromLTRB(tl.X - tileSize.Width / 2, tl.Y - tileSize.Height / 2,
br.X + tileSize.Width / 2, br.Y + tileSize.Height / 2);
}
ProjectedCellRegion CalculateVisibleCells(bool insideBounds)
@@ -311,4 +414,4 @@ namespace OpenRA.Graphics
}
}
}
}
}

View File

@@ -1,36 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 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
using System;
using System.Collections.Generic;
namespace OpenRA.Graphics
{
public struct VoxelAnimation
{
public readonly Voxel Voxel;
public readonly Func<WVec> OffsetFunc;
public readonly Func<IEnumerable<WRot>> RotationFunc;
public readonly Func<bool> DisableFunc;
public readonly Func<uint> FrameFunc;
public readonly bool ShowShadow;
public VoxelAnimation(Voxel voxel, Func<WVec> offset, Func<IEnumerable<WRot>> rotation, Func<bool> disable, Func<uint> frame, bool showshadow)
{
Voxel = voxel;
OffsetFunc = offset;
RotationFunc = rotation;
DisableFunc = disable;
FrameFunc = frame;
ShowShadow = showshadow;
}
}
}

View File

@@ -1,84 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 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
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using OpenRA.FileSystem;
namespace OpenRA.Graphics
{
public static class VoxelProvider
{
static Dictionary<string, Dictionary<string, Voxel>> units;
public static void Initialize(VoxelLoader loader, IReadOnlyFileSystem fileSystem, List<MiniYamlNode> sequences)
{
units = new Dictionary<string, Dictionary<string, Voxel>>();
foreach (var s in sequences)
LoadVoxelsForUnit(loader, s.Key, s.Value);
loader.RefreshBuffer();
}
static Voxel LoadVoxel(VoxelLoader voxelLoader, string unit, MiniYaml info)
{
var vxl = unit;
var hva = unit;
if (info.Value != null)
{
var fields = info.Value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (fields.Length >= 1)
vxl = hva = fields[0].Trim();
if (fields.Length >= 2)
hva = fields[1].Trim();
}
return voxelLoader.Load(vxl, hva);
}
static void LoadVoxelsForUnit(VoxelLoader loader, string unit, MiniYaml sequences)
{
Game.ModData.LoadScreen.Display();
try
{
var seq = sequences.ToDictionary(my => LoadVoxel(loader, unit, my));
units.Add(unit, seq);
}
catch (FileNotFoundException) { } // Do nothing; we can crash later if we actually wanted art
}
public static Voxel GetVoxel(string unitName, string voxelName)
{
try { return units[unitName][voxelName]; }
catch (KeyNotFoundException)
{
if (units.ContainsKey(unitName))
throw new InvalidOperationException(
"Unit `{0}` does not have a voxel `{1}`".F(unitName, voxelName));
else
throw new InvalidOperationException(
"Unit `{0}` does not have any voxels defined.".F(unitName));
}
}
public static bool HasVoxel(string unit, string seq)
{
if (!units.ContainsKey(unit))
throw new InvalidOperationException(
"Unit `{0}` does not have any voxels defined.".F(unit));
return units[unit].ContainsKey(seq);
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2020 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,9 +11,9 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.Effects;
using OpenRA.Primitives;
using OpenRA.Traits;
namespace OpenRA.Graphics
@@ -24,23 +24,35 @@ namespace OpenRA.Graphics
r => ZPosition(r.Pos, r.ZOffset);
public readonly Size TileSize;
public readonly int TileScale;
public readonly World World;
public readonly Theater Theater;
public Viewport Viewport { get; private set; }
public readonly ITerrainLighting TerrainLighting;
public event Action PaletteInvalidated = null;
readonly HashSet<Actor> onScreenActors = new HashSet<Actor>();
readonly HardwarePalette palette = new HardwarePalette();
readonly Dictionary<string, PaletteReference> palettes = new Dictionary<string, PaletteReference>();
readonly TerrainRenderer terrainRenderer;
readonly Lazy<DeveloperMode> devTrait;
readonly IRenderTerrain terrainRenderer;
readonly Lazy<DebugVisualizations> debugVis;
readonly Func<string, PaletteReference> createPaletteReference;
readonly bool enableDepthBuffer;
readonly List<IFinalizedRenderable> preparedRenderables = new List<IFinalizedRenderable>();
readonly List<IFinalizedRenderable> preparedOverlayRenderables = new List<IFinalizedRenderable>();
readonly List<IFinalizedRenderable> preparedAnnotationRenderables = new List<IFinalizedRenderable>();
readonly List<IRenderable> renderablesBuffer = new List<IRenderable>();
bool lastDepthPreviewEnabled;
internal WorldRenderer(ModData modData, World world)
{
World = world;
TileSize = World.Map.Grid.TileSize;
TileScale = World.Map.Grid.Type == MapGridType.RectangularIsometric ? 1448 : 1024;
Viewport = new Viewport(this, world.Map);
createPaletteReference = CreatePaletteReference;
@@ -57,12 +69,13 @@ namespace OpenRA.Graphics
palette.Initialize();
Theater = new Theater(world.Map.Rules.TileSet);
terrainRenderer = new TerrainRenderer(world, this);
TerrainLighting = world.WorldActor.TraitOrDefault<ITerrainLighting>();
terrainRenderer = world.WorldActor.TraitOrDefault<IRenderTerrain>();
devTrait = Exts.Lazy(() => world.LocalPlayer != null ? world.LocalPlayer.PlayerActor.Trait<DeveloperMode>() : null);
debugVis = Exts.Lazy(() => world.WorldActor.TraitOrDefault<DebugVisualizations>());
}
public void UpdatePalettesForPlayer(string internalName, HSLColor color, bool replaceExisting)
public void UpdatePalettesForPlayer(string internalName, Color color, bool replaceExisting)
{
foreach (var pal in World.WorldActor.TraitsImplementing<ILoadsPlayerPalettes>())
pal.LoadPlayerPalettes(this, internalName, color, replaceExisting);
@@ -84,8 +97,8 @@ namespace OpenRA.Graphics
var oldHeight = palette.Height;
palette.AddPalette(name, pal, allowModifiers);
if (oldHeight != palette.Height && PaletteInvalidated != null)
PaletteInvalidated();
if (oldHeight != palette.Height)
PaletteInvalidated?.Invoke();
}
}
@@ -98,24 +111,134 @@ namespace OpenRA.Graphics
palettes[name].Palette = pal;
}
List<IFinalizedRenderable> GenerateRenderables()
// PERF: Avoid LINQ.
void GenerateRenderables()
{
var actors = World.ScreenMap.ActorsInBox(Viewport.TopLeft, Viewport.BottomRight).Append(World.WorldActor);
foreach (var actor in onScreenActors)
renderablesBuffer.AddRange(actor.Render(this));
renderablesBuffer.AddRange(World.WorldActor.Render(this));
if (World.RenderPlayer != null)
actors = actors.Append(World.RenderPlayer.PlayerActor);
renderablesBuffer.AddRange(World.RenderPlayer.PlayerActor.Render(this));
var worldRenderables = actors.SelectMany(a => a.Render(this));
if (World.OrderGenerator != null)
worldRenderables = worldRenderables.Concat(World.OrderGenerator.Render(this, World));
renderablesBuffer.AddRange(World.OrderGenerator.Render(this, World));
worldRenderables = worldRenderables.Concat(World.Effects.SelectMany(e => e.Render(this)));
worldRenderables = worldRenderables.OrderBy(RenderableScreenZPositionComparisonKey);
// Unpartitioned effects
foreach (var e in World.UnpartitionedEffects)
renderablesBuffer.AddRange(e.Render(this));
Game.Renderer.WorldVoxelRenderer.BeginFrame();
var renderables = worldRenderables.Select(r => r.PrepareRender(this)).ToList();
Game.Renderer.WorldVoxelRenderer.EndFrame();
// Partitioned, currently on-screen effects
foreach (var e in World.ScreenMap.RenderableEffectsInBox(Viewport.TopLeft, Viewport.BottomRight))
renderablesBuffer.AddRange(e.Render(this));
return renderables;
foreach (var renderable in renderablesBuffer.OrderBy(RenderableScreenZPositionComparisonKey))
preparedRenderables.Add(renderable.PrepareRender(this));
// PERF: Reuse collection to avoid allocations.
renderablesBuffer.Clear();
}
// PERF: Avoid LINQ.
void GenerateOverlayRenderables()
{
foreach (var a in World.ActorsWithTrait<IRenderAboveShroud>())
{
if (!a.Actor.IsInWorld || a.Actor.Disposed || (a.Trait.SpatiallyPartitionable && !onScreenActors.Contains(a.Actor)))
continue;
foreach (var renderable in a.Trait.RenderAboveShroud(a.Actor, this))
preparedOverlayRenderables.Add(renderable.PrepareRender(this));
}
foreach (var a in World.Selection.Actors)
{
if (!a.IsInWorld || a.Disposed)
continue;
foreach (var t in a.TraitsImplementing<IRenderAboveShroudWhenSelected>())
{
if (t.SpatiallyPartitionable && !onScreenActors.Contains(a))
continue;
foreach (var renderable in t.RenderAboveShroud(a, this))
preparedOverlayRenderables.Add(renderable.PrepareRender(this));
}
}
foreach (var e in World.Effects)
{
var ea = e as IEffectAboveShroud;
if (ea == null)
continue;
foreach (var renderable in ea.RenderAboveShroud(this))
preparedOverlayRenderables.Add(renderable.PrepareRender(this));
}
if (World.OrderGenerator != null)
foreach (var renderable in World.OrderGenerator.RenderAboveShroud(this, World))
preparedOverlayRenderables.Add(renderable.PrepareRender(this));
}
// PERF: Avoid LINQ.
void GenerateAnnotationRenderables()
{
foreach (var a in World.ActorsWithTrait<IRenderAnnotations>())
{
if (!a.Actor.IsInWorld || a.Actor.Disposed || (a.Trait.SpatiallyPartitionable && !onScreenActors.Contains(a.Actor)))
continue;
foreach (var renderAnnotation in a.Trait.RenderAnnotations(a.Actor, this))
preparedAnnotationRenderables.Add(renderAnnotation.PrepareRender(this));
}
foreach (var a in World.Selection.Actors)
{
if (!a.IsInWorld || a.Disposed)
continue;
foreach (var t in a.TraitsImplementing<IRenderAnnotationsWhenSelected>())
{
if (t.SpatiallyPartitionable && !onScreenActors.Contains(a))
continue;
foreach (var renderAnnotation in t.RenderAnnotations(a, this))
preparedAnnotationRenderables.Add(renderAnnotation.PrepareRender(this));
}
}
foreach (var e in World.Effects)
{
var ea = e as IEffectAnnotation;
if (ea == null)
continue;
foreach (var renderAnnotation in ea.RenderAnnotation(this))
preparedAnnotationRenderables.Add(renderAnnotation.PrepareRender(this));
}
if (World.OrderGenerator != null)
foreach (var renderAnnotation in World.OrderGenerator.RenderAnnotations(this, World))
preparedAnnotationRenderables.Add(renderAnnotation.PrepareRender(this));
}
public void PrepareRenderables()
{
if (World.WorldActor.Disposed)
return;
RefreshPalette();
// PERF: Reuse collection to avoid allocations.
onScreenActors.UnionWith(World.ScreenMap.RenderableActorsInBox(Viewport.TopLeft, Viewport.BottomRight));
GenerateRenderables();
GenerateOverlayRenderables();
GenerateAnnotationRenderables();
onScreenActors.Clear();
}
public void Draw()
@@ -123,27 +246,24 @@ namespace OpenRA.Graphics
if (World.WorldActor.Disposed)
return;
if (devTrait.Value != null)
if (debugVis.Value != null && lastDepthPreviewEnabled != debugVis.Value.DepthBuffer)
{
Game.Renderer.WorldSpriteRenderer.SetDepthPreviewEnabled(devTrait.Value.ShowDepthPreview);
Game.Renderer.WorldRgbaSpriteRenderer.SetDepthPreviewEnabled(devTrait.Value.ShowDepthPreview);
Game.Renderer.WorldRgbaColorRenderer.SetDepthPreviewEnabled(devTrait.Value.ShowDepthPreview);
lastDepthPreviewEnabled = debugVis.Value.DepthBuffer;
Game.Renderer.WorldSpriteRenderer.SetDepthPreviewEnabled(lastDepthPreviewEnabled);
}
RefreshPalette();
var renderables = GenerateRenderables();
var bounds = Viewport.GetScissorBounds(World.Type != WorldType.Editor);
Game.Renderer.EnableScissor(bounds);
if (enableDepthBuffer)
Game.Renderer.Device.EnableDepthBuffer();
Game.Renderer.Context.EnableDepthBuffer();
terrainRenderer?.RenderTerrain(this, Viewport);
terrainRenderer.Draw(this, Viewport);
Game.Renderer.Flush();
for (var i = 0; i < renderables.Count; i++)
renderables[i].Render(this);
for (var i = 0; i < preparedRenderables.Count; i++)
preparedRenderables[i].Render(this);
if (enableDepthBuffer)
Game.Renderer.ClearDepthBuffer();
@@ -152,59 +272,73 @@ namespace OpenRA.Graphics
if (a.Actor.IsInWorld && !a.Actor.Disposed)
a.Trait.RenderAboveWorld(a.Actor, this);
var renderShroud = World.RenderPlayer != null ? World.RenderPlayer.Shroud : null;
if (enableDepthBuffer)
Game.Renderer.ClearDepthBuffer();
foreach (var a in World.ActorsWithTrait<IRenderShroud>())
a.Trait.RenderShroud(renderShroud, this);
a.Trait.RenderShroud(this);
if (enableDepthBuffer)
Game.Renderer.Device.DisableDepthBuffer();
Game.Renderer.Context.DisableDepthBuffer();
Game.Renderer.DisableScissor();
var aboveShroud = World.ActorsWithTrait<IRenderAboveShroud>().Where(a => a.Actor.IsInWorld && !a.Actor.Disposed)
.SelectMany(a => a.Trait.RenderAboveShroud(a.Actor, this));
var aboveShroudSelected = World.Selection.Actors.Where(a => !a.Disposed)
.SelectMany(a => a.TraitsImplementing<IRenderAboveShroudWhenSelected>()
.SelectMany(t => t.RenderAboveShroud(a, this)));
var aboveShroudEffects = World.Effects.Select(e => e as IEffectAboveShroud)
.Where(e => e != null)
.SelectMany(e => e.RenderAboveShroud(this));
var aboveShroudOrderGenerator = SpriteRenderable.None;
if (World.OrderGenerator != null)
aboveShroudOrderGenerator = World.OrderGenerator.RenderAboveShroud(this, World);
Game.Renderer.WorldVoxelRenderer.BeginFrame();
var finalOverlayRenderables = aboveShroud
.Concat(aboveShroudSelected)
.Concat(aboveShroudEffects)
.Concat(aboveShroudOrderGenerator)
.Select(r => r.PrepareRender(this))
.ToList();
Game.Renderer.WorldVoxelRenderer.EndFrame();
// HACK: Keep old grouping behaviour
foreach (var g in finalOverlayRenderables.GroupBy(prs => prs.GetType()))
var groupedOverlayRenderables = preparedOverlayRenderables.GroupBy(prs => prs.GetType());
foreach (var g in groupedOverlayRenderables)
foreach (var r in g)
r.Render(this);
if (devTrait.Value != null && devTrait.Value.ShowDebugGeometry)
{
for (var i = 0; i < renderables.Count; i++)
renderables[i].RenderDebugGeometry(this);
Game.Renderer.Flush();
}
foreach (var g in finalOverlayRenderables.GroupBy(prs => prs.GetType()))
foreach (var r in g)
r.RenderDebugGeometry(this);
public void DrawAnnotations()
{
Game.Renderer.EnableAntialiasingFilter();
for (var i = 0; i < preparedAnnotationRenderables.Count; i++)
preparedAnnotationRenderables[i].Render(this);
Game.Renderer.DisableAntialiasingFilter();
// Engine debugging overlays
if (debugVis.Value != null && debugVis.Value.RenderGeometry)
{
for (var i = 0; i < preparedRenderables.Count; i++)
preparedRenderables[i].RenderDebugGeometry(this);
for (var i = 0; i < preparedOverlayRenderables.Count; i++)
preparedOverlayRenderables[i].RenderDebugGeometry(this);
for (var i = 0; i < preparedAnnotationRenderables.Count; i++)
preparedAnnotationRenderables[i].RenderDebugGeometry(this);
}
if (debugVis.Value != null && debugVis.Value.ScreenMap)
{
foreach (var r in World.ScreenMap.RenderBounds(World.RenderPlayer))
{
var tl = Viewport.WorldToViewPx(new float2(r.Left, r.Top));
var br = Viewport.WorldToViewPx(new float2(r.Right, r.Bottom));
Game.Renderer.RgbaColorRenderer.DrawRect(tl, br, 1, Color.MediumSpringGreen);
}
foreach (var b in World.ScreenMap.MouseBounds(World.RenderPlayer))
{
var points = new float2[b.Vertices.Length];
for (var index = 0; index < b.Vertices.Length; index++)
{
var vertex = b.Vertices[index];
points[index] = Viewport.WorldToViewPx(vertex).ToFloat2();
}
Game.Renderer.RgbaColorRenderer.DrawPolygon(points, 1, Color.OrangeRed);
}
}
Game.Renderer.Flush();
preparedRenderables.Clear();
preparedOverlayRenderables.Clear();
preparedAnnotationRenderables.Clear();
}
public void RefreshPalette()
@@ -216,13 +350,13 @@ namespace OpenRA.Graphics
// Conversion between world and screen coordinates
public float2 ScreenPosition(WPos pos)
{
return new float2(TileSize.Width * pos.X / 1024f, TileSize.Height * (pos.Y - pos.Z) / 1024f);
return new float2((float)TileSize.Width * pos.X / TileScale, (float)TileSize.Height * (pos.Y - pos.Z) / TileScale);
}
public float3 Screen3DPosition(WPos pos)
{
var z = ZPosition(pos, 0) * TileSize.Height / 1024f;
return new float3(TileSize.Width * pos.X / 1024f, TileSize.Height * (pos.Y - pos.Z) / 1024f, z);
var z = ZPosition(pos, 0) * (float)TileSize.Height / TileScale;
return new float3((float)TileSize.Width * pos.X / TileScale, (float)TileSize.Height * (pos.Y - pos.Z) / TileScale, z);
}
public int2 ScreenPxPosition(WPos pos)
@@ -239,16 +373,16 @@ namespace OpenRA.Graphics
return new float3((float)Math.Round(px.X), (float)Math.Round(px.Y), px.Z);
}
// For scaling vectors to pixel sizes in the voxel renderer
// For scaling vectors to pixel sizes in the model renderer
public float3 ScreenVectorComponents(WVec vec)
{
return new float3(
TileSize.Width * vec.X / 1024f,
TileSize.Height * (vec.Y - vec.Z) / 1024f,
TileSize.Height * vec.Z / 1024f);
(float)TileSize.Width * vec.X / TileScale,
(float)TileSize.Height * (vec.Y - vec.Z) / TileScale,
(float)TileSize.Height * vec.Z / TileScale);
}
// For scaling vectors to pixel sizes in the voxel renderer
// For scaling vectors to pixel sizes in the model renderer
public float[] ScreenVector(WVec vec)
{
var xyz = ScreenVectorComponents(vec);
@@ -264,7 +398,7 @@ namespace OpenRA.Graphics
public float ScreenZPosition(WPos pos, int offset)
{
return ZPosition(pos, offset) * TileSize.Height / 1024f;
return ZPosition(pos, offset) * (float)TileSize.Height / TileScale;
}
static int ZPosition(WPos pos, int offset)
@@ -278,7 +412,7 @@ namespace OpenRA.Graphics
/// </summary>
public WPos ProjectedPosition(int2 screenPx)
{
return new WPos(1024 * screenPx.X / TileSize.Width, 1024 * screenPx.Y / TileSize.Height, 0);
return new WPos(TileScale * screenPx.X / TileSize.Width, TileScale * screenPx.Y / TileSize.Height, 0);
}
public void Dispose()
@@ -291,7 +425,6 @@ namespace OpenRA.Graphics
palette.Dispose();
Theater.Dispose();
terrainRenderer.Dispose();
}
}
}

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