Compare commits

...

216 Commits

Author SHA1 Message Date
James Dunne
1d4f1c657f Fix for crash after selling all refineries. 2012-06-30 16:37:50 +12:00
James Dunne
9a66d7b530 Harvesters will return to ordered-to location if told to harvest a specific cell while full after delivery instead of the last successfully harvested cell which may be far away. 2012-06-30 16:37:50 +12:00
Chris Forbes
3a87b934a6 fixed #2257 - reenable PrimaryBuilding support for afld/hpad 2012-06-30 16:10:13 +12:00
Chris Forbes
9845d0e035 fixed #2260 - spec chat should use contrast 2012-06-30 16:05:33 +12:00
James Dunne
3754e791e5 Fix for null ref exception after refinery is sold. 2012-06-29 22:55:45 -05:00
James Dunne
643154de15 Harvesters obey player when told to stop or move somewhere else. 2012-06-29 22:38:24 -05:00
ScottNZ
af8b29aee5 Map polishing: removed mpspawn. Removed unneeded YAML. 3tnk now starts facing north. Changed soldier next to barrels from e1 to e2. Adjusted the player colour to a lighter blue. Adjusted the chinook despawn location. e2 now always explode when they die to make the barrel chain reaction reliable. Reduced HP of barrels also. 2012-06-29 09:09:39 +12:00
ScottNZ
36c0ec753d Move viewport to where the player starts 2012-06-29 09:09:39 +12:00
Matthias Mailänder
9115fc4397 fixes #2157
Tooltip descriptions now showup in CnC.
2012-06-29 09:06:15 +12:00
Matthias Mailänder
0d59a4dcd7 fixes #2005
Don't save floats in settings.yaml using country-specific
decimal separators which can be misunderstood as
group seperators which will put values out-of-range.
2012-06-29 09:00:28 +12:00
Chris Forbes
e0c3c53c00 fix up music error 2012-06-29 09:00:28 +12:00
Generalcamo
11654cc893 More Strings Corrected.
Some tracks are missing, however I don't know the file name of those.
2012-06-29 08:45:45 +12:00
Generalcamo
bb85ea75e4 More Strings Corrected. I notice a few Counterstrike tracks are missing, they might be in the aftermath file though. Will check. 2012-06-29 08:45:44 +12:00
Generalcamo
2450576dbe Once Again, corrected strings. Also added a track 2012-06-29 08:45:44 +12:00
Generalcamo
dd81b6d872 Corrected Music Strings, added a voiced track
The music strings have been taken from Frank Klepacki's Website and the CD. In some cases, I have added parenthesis to show the names that many people give them
2012-06-29 08:45:44 +12:00
James Dunne
3160034d66 Now checking AcceptsSmudgeType for all cells to smudge and picking appropriate SmudgeLayer to render with. 2012-06-27 23:54:49 -05:00
James Dunne
d0d3813173 Water will not be smudged/scorched any more from nukes. All resources in range of nuke are destroyed now, not just the ones on the edge of the circle. 2012-06-27 22:56:48 -05:00
James Dunne
2ff4a76955 Fixed zombie aircraft flying around after being told to fall to earth. 2012-06-27 22:02:29 -05:00
Matthias Mailänder
9626ed356c fixed crash when mod not found, don't save broken settings
default mod is Red Alert
2012-06-28 13:10:41 +12:00
Matthias Mailänder
5ecf8d3b7f added real allyrepair, fixed flagfly shadow 2012-06-28 13:10:41 +12:00
Matthias Mailänder
8041b17032 fixed turret facing order, added rocket turret 2012-06-28 13:10:41 +12:00
Matthias Mailänder
b9cda8fcca relative altitude for carryall cargo 2012-06-28 13:10:41 +12:00
Matthias Mailänder
ed6a625c69 nonstandard build time value for a cnc classic mod fixes #2164
remove the testcase in structures.yaml if unwanted for cnc mod
2012-06-28 13:10:41 +12:00
Matthias Mailänder
d498ff1085 +RenderBuildingSeparateTurret 2012-06-28 13:10:40 +12:00
James Dunne
f8a0dd59b7 Fixed null reference bug. 2012-06-27 18:38:12 -05:00
James Dunne
8e602104af Harvesters - made search radius configurable for both initial search from proc and search from harvest location. 2012-06-27 18:00:42 -05:00
James Dunne
aac78773f4 Upgraded to VS2010 2012-06-26 20:39:56 -05:00
Matthias Mailänder
d3915ad291 string AcceptsSmudgeType replaces boolean AcceptSmudge
because Dune 2000 has different craters for rock and sand
2012-06-27 13:19:52 +12:00
Matthias Mailänder
b61e4a6083 don't mount unneeded RA game files
voices and tilesets already completely replaced
2012-06-27 13:19:52 +12:00
Matthias Mailänder
5318380bfa auto-restart the game after getting the game-files 2012-06-27 13:19:52 +12:00
Matthias Mailänder
a64629f1c5 remove ready/hold/group pip from BuildPaletteWidget
and render as text instead
2012-06-27 13:19:52 +12:00
Matthias Mailänder
5231da1ea3 READY/ON HOLD as DrawText instead of SHP 2012-06-27 13:13:55 +12:00
Chris Forbes
aa06751de5 categorize the rest of the temperat tileset 2012-06-26 20:12:01 +12:00
Chris Forbes
f10eb9e082 add category headers in editor 2012-06-26 19:58:04 +12:00
Chris Forbes
9966b4efd1 group tiles by category 2012-06-26 19:33:11 +12:00
Chris Forbes
0ec3e8b227 add Category to tileset entries 2012-06-26 19:33:02 +12:00
Chris Forbes
984a498ed2 Finish fixing #2136 2012-06-26 19:24:59 +12:00
Igor Popov
c122e6f54d indicate-admin: implementation (ra) 2012-06-26 18:58:31 +12:00
Chris Forbes
1924cc71f1 fix canceling of WaitFor 2012-06-26 11:48:15 +12:00
Chris Forbes
220473bf74 remove duplication in UOG 2012-06-26 11:31:13 +12:00
James Dunne
4373f577d8 Added ResourceClaimLayer trait to World for cnc and d2k. 2012-06-24 21:41:16 -05:00
James Dunne
2f773e49ef Fixed null ref exception while playing cnc. 2012-06-24 21:41:16 -05:00
James Dunne
03ec1f08cf Made ResourceClaimLayer trait optional on World actor to fix cnc and d2k. 2012-06-24 21:41:16 -05:00
James Dunne
a0f9f98b1c Removed unnecessary mobile local. 2012-06-24 21:00:25 -05:00
James Dunne
b59a0e8c0d Fixed harvesters for AI to search the entire map when no more resources nearby. 2012-06-24 20:26:01 -05:00
James Dunne
1fa70d259f Removed INudge in favor of INotifyBlockingMove. 2012-06-24 20:26:01 -05:00
James Dunne
1f0da42a15 Refineries now show which harvesters are linked by holding down ALT key. 2012-06-24 20:26:01 -05:00
James Dunne
845379e577 Harvesters no longer block each other during low-ore contention and wait for a random amount of time while idle to search for more resources. 2012-06-24 20:26:00 -05:00
James Dunne
80123b6aa4 Many harvester behavior improvements; summary below.
Implemented Harvester territory marking with a simple resource claim system in ResourceClaimLayer trait added to World.
Added customCost for PathSearch to support new Harvester search preferences.
Explicit delivery order forces harvester to always deliver to that refinery.
Explicit harvest order frees harvester from forced delivery refinery and allows for auto-balancing.
Harvesters auto-balance refinery choice such that no more than 3 harvesters are linked to any one refinery at a time.
Harvesters try very hard to not block the refinery dock location.
Harvesters try to avoid enemy territory when searching for resources.
Group-select harvest order intelligently disperses harvesters around the order location.
Fixed PathFinder caching to not be a sliding window. This is a correctness issue. Sliding window causes no-route paths to be cached permanently in tight move loops and doesn't allow eventual progress to be made. This may have negative performance implications.
2012-06-24 20:26:00 -05:00
Matthias Mailänder
1aafc9f726 fix utilty remap, remapped flag/poweroff to d2k.pal 2012-06-25 10:21:39 +12:00
Chris Forbes
8607575e2b Merge remote-tracking branch 'matt/patch-2' 2012-06-25 09:52:24 +12:00
Chris Forbes
162c386bdd Merge remote-tracking branch 'matt/bleed' 2012-06-25 09:40:22 +12:00
Chris Forbes
445e5ec84b fix #2215 - add shadow.shp based on RA but with proper size for d2k 2012-06-25 09:27:39 +12:00
Matthias Mailänder
54c35e3721 fixed some selection boxes 2012-06-25 09:07:44 +12:00
Chris Forbes
a2b92d0fe4 Merge commit 'matt/dune^'
Conflicts:
	.gitignore
	mods/d2k/rules/system.yaml
2012-06-25 09:05:49 +12:00
Chris Forbes
2ed12f1d95 Merge remote-tracking branch 'scott/bleed'
Conflicts:
	OpenRA.Mods.RA/Missions/Allies01Script.cs
2012-06-25 08:45:16 +12:00
James Dunne
fe5bcdeab9 Fix for PaletteFormat break in Editor. 2012-06-24 13:58:49 -05:00
ScottNZ
9c6bc45f8f Fix whitespace 2012-06-25 05:34:06 +12:00
ScottNZ
2cc749118f Make it more overwhelming at the fifth wave and each wave after that 2012-06-25 05:19:25 +12:00
ScottNZ
331388bfe8 Merge pull request #1 from Mailaender/patch-5
Added Prof. Einstein sequences and rules
2012-06-24 09:31:38 -07:00
Matthias Mailänder
079a52ee65 added Einstein 2012-06-24 19:27:05 +03:00
Matthias Mailänder
5b470650b7 added Einstein 2012-06-24 19:26:03 +03:00
Matthias Mailänder
380875ad3e added Einstein 2012-06-24 19:24:26 +03:00
Matthias Mailänder
79976a4bfe transpose infantry/ornithocopter 2012-06-24 15:48:11 +02:00
Matthias Mailänder
769b5d7dc6 fixed OpenRA.Utility --remap
now uses the mod parameter again
2012-06-24 12:32:52 +02:00
Matthias Mailänder
2a95c5f668 fix PlayerColorPalette in Editor 2012-06-24 11:56:52 +02:00
Chris Forbes
1bf649d27d Merge remote-tracking branch 'matt/bleed' 2012-06-24 21:34:37 +12:00
ScottNZ
bda92f3898 Only send the heavy tank on the last wave, this is the first mission after all 2012-06-24 21:28:46 +12:00
Matthias Mailänder
7220025a62 make orni flap slower 2012-06-24 11:21:50 +02:00
Matthias Mailänder
0b6eda0815 replaced RA sounds by Dune 2000 ones 2012-06-23 16:00:20 +02:00
Matthias Mailänder
e70e778775 make ornithocopter flap (broken)
needs frame resorting similiar to the infantry
2012-06-23 14:20:34 +02:00
ScottNZ
7fb659bd3a Make the mission a bit harder - add a heavy tank to each wave 2012-06-23 20:41:43 +12:00
Matthias Mailänder
b109436cc3 race specific BaseAttackNotifier 2012-06-22 18:21:29 +02:00
ScottNZ
6ba0c448c8 Remove killing of player when they fail the mission, this is more fun and it's also really loud when all the units die at once 2012-06-22 15:27:07 +12:00
ScottNZ
ed5ff9cd31 Bleep when objective shown 2012-06-22 13:39:36 +12:00
ScottNZ
1146790dc1 Reworked the left side of the map to make it useful, and moved one of the spawnpoints there. 2012-06-22 13:07:24 +12:00
James Dunne
cf1d4d0efb Fixed radar click position - was not respecting zoom setting for emulating the mouse coordinate. 2012-06-21 19:41:23 -05:00
James Dunne
b127ae8027 Added sub-pixel position/vector types.
Updated Sync code to handle new sub-pixel types.
2012-06-21 19:41:12 -05:00
James Dunne
9c49143534 New types for cell and pixel coordinate position/vectors. 2012-06-21 15:36:59 -05:00
Matthias Mailänder
6bc3249685 voices now support prefixes
required for d2k
2012-06-21 15:31:12 +02:00
ScottNZ
3ab197f400 Buff the Allies a bit - give them some riflemen. 2012-06-21 23:34:34 +12:00
ScottNZ
9ff69b7946 Add EVA voices
Use new WaitFor when waiting for Einstein
Have a small delay before the Soviets counterattack
Have the Soviets Attack-Move towards Einstein during the counterattack, this makes them much more damaging
Spawn the signal flare only after Einstein has been spawned, also add EVA voice for this
2012-06-21 22:53:20 +12:00
Chris Forbes
0b98a8ce5e Merge remote-tracking branch 'scott/bleed' 2012-06-21 11:54:54 +12:00
James Dunne
2e26047b23 Added myself to AUTHORS. 2012-06-20 18:20:26 -05:00
Chris Forbes
2cdd1f7376 fix #2126 - crash on spawning a corpse for an actor which has already been destroyed 2012-06-21 09:50:02 +12:00
Matthias Mailänder
033dd10192 git ignore some KDE crap 2012-06-20 23:46:53 +02:00
Matthias Mailänder
9f5a8512d2 race specific ProductionQueue audio 2012-06-20 23:40:08 +02:00
Chris Forbes
5c4e49cc3f fix #2196 - crash when cycling stances while a unit dies 2012-06-21 09:33:47 +12:00
James Dunne
8eb4782a49 Fixed socket code constantly throwing exceptions about non-blocking. 2012-06-21 09:29:02 +12:00
Chris Forbes
99eb3b046d fix #2239 - add WaitFor(predicate) 2012-06-21 09:26:05 +12:00
Matthias Mailänder
ac0389d04f race specific notifications/mcv-crate 2012-06-20 21:35:23 +02:00
Matthias Mailänder
6929ed024a added harvester unload, thumper which spawns sandworms
worm won't attack, dogjaw is stupid and moving mine did not work
2012-06-20 16:57:09 +02:00
Matthias Mailänder
f4cb798c8b small code optimisations as suggested 2012-06-20 09:51:00 +02:00
ScottNZ
8f6b8b75bc Remove redundant call to InternalName when mission failed 2012-06-20 18:17:13 +12:00
ScottNZ
cb3daab5fa Tabify lines 2012-06-20 17:48:03 +12:00
James Dunne
4d16ca238c Fixed broken Install from CD code in RA. 2012-06-20 09:47:19 +12:00
Matthias Mailänder
84d623397b made PaletteFormat configurable
as suggested in issue #2219
2012-06-19 21:36:10 +02:00
Matthias Mailänder
26b75f406f new settings Transparent for cursors.yaml 2012-06-19 07:43:06 +02:00
ScottNZ
b30e4ab432 Use SharedRandom to stop desync 2012-06-19 14:43:11 +12:00
ScottNZ
b0e10c9ada Don't need lzRange 2012-06-19 12:57:45 +12:00
Matthias Mailänder
c6a1031ab7 fix cnc palette issues
cursor not supporting transparency which is only needed for d2k
2012-06-18 17:44:03 +02:00
Matthias Mailänder
7cbed30dc6 fix cnc palette issues
cursor not supporting transparency; wrong icon, fx palette
2012-06-18 17:40:22 +02:00
Matthias Mailänder
ce0099f5d2 fix settings for d2k and cnc
no UPnP for CnC singleplayer skirmishes, use RA chromes at D2k
2012-06-18 17:07:56 +02:00
Matthias Mailänder
45a5e317c0 Merge remote-tracking branch 'openra/bleed' into bleed 2012-06-18 16:38:17 +02:00
ScottNZ
11ddd88d60 Remove more unneeded code, use CallFunc activity to make Tanya laugh when she disembarks. 2012-06-19 01:45:46 +12:00
ScottNZ
ce05b8dfec Use IsInMap & IsInWorld to detect whether Einstein has been saved 2012-06-19 01:27:42 +12:00
ScottNZ
f5d397030c Remove unneeded UnitsNearExtractionLZ code 2012-06-19 01:19:09 +12:00
ScottNZ
874799c2c3 Made Soviet attack waves a bit saner 2012-06-19 01:04:18 +12:00
ScottNZ
20af089fcd Added Allies 01 SP map and Allies01Script.cs 2012-06-18 22:13:24 +12:00
unknown
21ab0b461c Added straightforward hover behavior for all units. Give a unit a nonzero Altitude: in its Mobile: block and the WithShadow: trait to make it hover. 2012-06-18 20:53:38 +12:00
Chris Forbes
7af0e64708 allow --transpose to do multiple operations in one pass 2012-06-18 20:38:37 +12:00
Matthias Mailänder
527c6dc36b "repair" infantry at hospital 2012-06-18 03:30:53 +03:00
Matthias Mailänder
8831a93375 make the hospital become a repairunit (for infantry) 2012-06-18 03:29:17 +03:00
Matthias Mailänder
677efcbced add notifications 2012-06-18 02:18:01 +02:00
Chris Forbes
4f1a7ff5fb add --transpose option to utility 2012-06-18 11:22:24 +12:00
Matthias Mailänder
c9edf7d0dc added Renderer Dropdown in RA Settings 2012-06-18 09:30:52 +12:00
Chris Forbes
d64ecac74e Merge pull request #2223 from Mailaender/dune
Latest updates from the Dune 2000 mod
2012-06-16 22:30:00 -07:00
Matthias Mailänder
c804be6f01 fix passable edges in Cliff terrain tiles
made all special units equally expensive, found harvester unload
2012-06-16 21:19:46 +02:00
Matthias Mailänder
959875c709 added special infantry, fixed UI, added new map 2012-06-16 14:17:35 +02:00
Igor Popov
4d94cb5593 2 maps: Bomber John(minigame->new); Free Coasts(conquest->replace) 2012-06-16 14:46:32 +12:00
Matthias Mailänder
c1fb5dd5f5 added engineer, bazooka 2012-06-15 22:43:03 +02:00
Matthias Mailänder
db0e1eabc7 replace RA conyard with D2k carryall for colorpicker 2012-06-15 17:03:40 +02:00
Matthias Mailänder
801ff5cc17 make cursor always transparent, fix Arrakis tileset
transparency bugs some cnc cursors, slice BLOXBASE better
2012-06-15 11:06:59 +02:00
Chris Forbes
94f7f1c473 clean up game timeout 2012-06-15 15:14:56 +12:00
Chris Forbes
9862b8ccee remove sequence save junk 2012-06-15 15:06:52 +12:00
Matthias Mailänder
722c7a5f7d +resampled sounds, readded and completed Arrakis tileset
all tilesets combined into one without redundancy
2012-06-14 21:09:44 +02:00
Matthias Mailänder
72d038e04e fixes mouse cursor not being transparent 2012-06-11 23:28:42 +02:00
Matthias Mailänder
b83188d435 add the first Sounds
manually resampled to 16 bit 22050 Hz and converted to AUD
2012-06-11 21:19:40 +02:00
Matthias Mailänder
f9cbd1bbbf experimenting with auto-downloader, sandworm 2012-06-10 21:13:40 +02:00
Curtis Shmyr
4e88166673 Added two new RA maps by Tirili: Ice Woods & Nishnekolymsk 2012-06-10 12:56:24 -06:00
Chris Forbes
f3d68f4944 remove some junk ai profiles 2012-06-10 19:52:25 +12:00
Chris Forbes
3827a5436a #2191 fixed -- custom OGs canceled on win/lose 2012-06-10 17:17:38 +12:00
Igor Popov
4a7417347a fix #2199; Game Timer (min 10 seconds) 2012-06-10 17:08:49 +12:00
Matthias Mailänder
dc6b286d25 remove unneccessary dependencies, make SendTo less spammy 2012-06-10 16:46:19 +12:00
Matthias Mailänder
aa36a56b27 UPnP source code fixes
as suggested by Chris Forbes
2012-06-10 16:46:19 +12:00
Chris Forbes
a831e72fa2 Merge remote-tracking branch 'tuc/simplepause' 2012-06-10 16:35:41 +12:00
Matthias Mailänder
b96158adcb new AI with optimized build order
Eisenhower builds less refineries, more units and techs faster
2012-06-10 16:34:31 +12:00
Chris Forbes
5414875d00 update .gitignore; remove spurious mono file 2012-06-10 16:32:02 +12:00
Chris Forbes
fd4b10c6bd Merge remote-tracking branch 'matt/dune' 2012-06-10 16:27:19 +12:00
Matthias Mailänder
d110b45679 added install rules for d2k mod, fixes carryall landing 2012-06-09 22:46:13 +02:00
Matthias Mailänder
22e0828566 fixing BLOXBASE problems
t264 not found and BASE.tsx gets deleted too early
2012-06-09 20:57:22 +02:00
Matthias Mailänder
c3052d863a tsbuilder is required for mod_d2k
adding it to core
2012-06-09 20:39:06 +02:00
Matthias Mailänder
0b4455515d added utility reference to Makefile for d2k mod 2012-06-09 20:33:50 +02:00
Matthias Mailänder
4ed74c6cc0 adding in-game GUI gamefile extractor/converter
also fixing EOL for TilesetBuilder with monoDevelop
2012-06-09 19:53:59 +02:00
Matthias Mailänder
ebf64f67cf updated BLOXBAT terrain 2012-06-09 11:43:39 +02:00
Matthias Mailänder
b16849768d adding chrome/settings.yaml
was in gitignore
2012-06-08 21:07:20 +02:00
Matthias Mailänder
f140c6ec9c added TilesetBuilder command line, added Tileset extractor
removing all copyrighted raw tileset files
2012-06-08 19:31:10 +02:00
Matthias Mailänder
8f1d06ff31 added TilesetBuilder2 and fixed it for Dune 2000
does not support TerrainTypes other than "clear" yet
2012-06-07 19:22:45 +02:00
Igor Popov
3f0fafb380 Add banlist (Server.Ban settings item) support to game servers 2012-06-07 12:14:26 +12:00
Remco van der Zon
84124de79d Game can now be paused by pressing f3 as well. 2012-06-06 11:22:46 +02:00
Remco van der Zon
8ad4e08651 Unit order client != null check fixed (int != null -> always true!) .
Removed if-else branch in favour of sugar construct a?b:c.

Note: One should (at least) consider to move var client = ... to the
start of the switch construct. 4 branches of this switch are using this.
(DRY)
2012-06-06 10:54:21 +02:00
Remco van der Zon
8f981977e0 TimeWidget does not collide anymore with koth layout.
Screen resolution should be 1024x786+
2012-06-06 10:47:13 +02:00
Matthias Mailänder
676210422f added spice bloom
indestructable, seeds ressources like mine or blossom tree
2012-06-05 19:50:44 +02:00
Matthias Mailänder
749301899e added smudge
palette problems and engine does not care for terrain type
2012-06-05 18:14:17 +02:00
Chris Forbes
1bb1e00a0d fix #2195 - barrels should not be capturable or sellable 2012-06-05 19:41:30 +12:00
Matthias Mailänder
83ee6b758e fix CD rip logic a little
will still fail on setup.z
2012-06-02 21:17:42 +02:00
Matthias Mailänder
accaf027fe added (broken) content installer, moved instruction to GUI
still depends on the hacky bash script and CD extractor crashes
2012-06-02 17:46:31 +02:00
Matthias Mailänder
9b1e798b35 added spice as a ressource
still needs work though
2012-06-02 15:36:31 +02:00
Matthias Mailänder
cffaabb3bf added d2k mouse pointer, fixed aircrafts 2012-06-02 11:41:18 +02:00
Matthias Mailänder
5ab5bc9f7c removed need to define Harvester/BaseBuildingUnit manually 2012-05-28 23:36:46 +02:00
Matthias Mailänder
d9c4aada8a updated the README
so people can try this on their own
2012-05-28 20:29:15 +02:00
Matthias Mailänder
27fa99852b add D2k crates, started fixing infantry
infantry directions are correct, but movement is still wrong
2012-05-28 20:14:56 +02:00
Matthias Mailänder
ec7795fa99 added more Dune 2000 EVA voices
currently Atreides only
2012-05-28 14:00:43 +02:00
Matthias Mailänder
8e74df6155 fixing RALint.exe d2k and ordos missing defense buildings 2012-05-28 10:37:10 +02:00
Matthias Mailänder
4984d07960 made HackyAI more flexible for Dune 2000 mod 2012-05-28 10:36:17 +02:00
Matthias Mailänder
2a312911cb fixes repair pad
and update TODO
2012-05-27 18:28:52 +02:00
Matthias Mailänder
a20e30312e added Ordos 2012-05-27 15:17:03 +02:00
Matthias Mailänder
e0e1011d30 added Harkonnen 2012-05-27 12:45:35 +02:00
Matthias Mailänder
1fcf044980 added flags, worked on the UI
looks crappy, needs someone who is good at this
2012-05-27 10:40:08 +02:00
Matthias Mailänder
2287f1f662 inherit units that differ only slightly for each faction 2012-05-26 20:20:01 +02:00
Matthias Mailänder
ffbc76919e make Dune 2000 an independent mod
Arrakis tileset now loads properly
2012-05-26 18:13:51 +02:00
Matthias Mailänder
083952a531 added Dune 2000 music, voices 2012-05-26 13:06:02 +02:00
Curtis Shmyr
bd29d382c7 fix #2080 - added option to toggle shellmap in CNC 2012-05-26 18:40:55 +12:00
Curtis Shmyr
8df09da816 Spy - add voice when sending infiltrate order 2012-05-26 18:40:55 +12:00
Curtis Shmyr
4778ef803e Spy - don't reset exploration if team has GPS 2012-05-26 18:40:55 +12:00
Curtis Shmyr
37f91542a9 Change cargo ownership when capturing actors with cargo 2012-05-26 18:40:55 +12:00
Curtis Shmyr
e1907364e6 Fix #2086 - don't let player capture if that same player (or friendly ally) is already capturing 2012-05-26 18:40:55 +12:00
Matthias Mailänder
7f48a242db fixed refinery, factories
a little hacky though
2012-05-25 22:27:26 +02:00
Matthias Mailänder
4362a215d9 fixed wall, silo; add ornithocopter, sonic tank, infantry
orni does not flap, no sonic wave weapon, infantry frames broken
2012-05-25 17:46:58 +02:00
Matthias Mailänder
72b2e03dd0 added tech buildings, repair pad, startport, tanks 2012-05-24 16:26:38 +02:00
Matthias Mailänder
f7c1eb2933 +heavy factory, radar outpost, brick wall 2012-05-23 20:04:45 +02:00
psydev
5dd46b1b16 Give Mammoth 8-sec. cooldown for heal, like in RA. 2012-05-23 09:35:34 +12:00
Matthias Mailänder
68a731ed5e fixing MCV facings and flickering bug 2012-05-22 23:19:05 +02:00
Matthias Mailänder
4c667be946 fixed vehicles driving backwards
also fixed the bazooka for quad
2012-05-22 22:17:48 +02:00
Matthias Mailänder
66f82c6c2a added harvester, trike/quad now working, fixed mod inheritances
RenderCargo: works, moved R8Reader to Utility namespace
2012-05-22 21:02:25 +02:00
Chris Forbes
ff32864b47 #2160 fixed - RenderCargo support for relative altitude 2012-05-22 19:42:51 +12:00
Chris Forbes
e9656795a2 RenderCargo depends on IMove on the containing actor 2012-05-22 19:24:53 +12:00
Chris Forbes
3fbb81b4fc remove more spurious trait lookups in RenderCargo 2012-05-22 19:19:49 +12:00
Chris Forbes
442138e1f8 clean up spurious trait lookup in RenderCargo 2012-05-22 19:18:28 +12:00
Chris Forbes
2d39b1dfac #2089 fixed - Explodes filtering on InfDeath 2012-05-22 19:14:25 +12:00
Chris Forbes
3b704e25fa #2159 fixed -- missiles lose guidance and run out their remaining fuel if the target dies 2012-05-22 19:01:49 +12:00
Chris Forbes
c068be453a #2119 fixed - better error message for multiple definitions of the same yaml field 2012-05-22 18:17:03 +12:00
Chris Forbes
6f8f940f31 #2130 fixed -- #comments can be used at the end of any lines 2012-05-22 18:05:04 +12:00
Chris Forbes
c000640928 remove dead function from LobbyLogic 2012-05-22 17:42:19 +12:00
earthpig
059347af40 bots (once again) build pillboxes. 2012-05-22 17:20:23 +12:00
earthpig
f0001856bc To go along with introducing the 'cloaked hbox', ensure that the cloak is disabled if at low power. 2012-05-22 17:18:54 +12:00
earthpig
8c218b67ab Bring back hbox, with both the new garrison stuff and with stealth until firing. 2012-05-22 17:18:26 +12:00
Matthias Mailänder
5426a5fd3c put d2k mod stuff into it's own branch 2012-05-20 15:50:39 +02:00
psydev
d1241c438a Helicopters targetable when landed 2012-05-18 10:45:39 +12:00
Chris Forbes
bc7aa9a491 make Health.MaxHP not readonly; some people want to frob it at runtime 2012-05-17 10:04:06 +12:00
Remco van der Zon
ae94d7ecc7 Chat-text displayed when the game is paused and unpaused.
: The game is (un-)paused by <PLAYERNAME>
2012-05-16 19:11:46 +02:00
Remco van der Zon
7e1986ecbc Timer shows text "(paused)" when game is in pause. 2012-05-16 19:04:43 +02:00
Remco van der Zon
a07697be03 Pause the game option.
Game is paused when PAUSE on the keyboard has been hit. It can also be unpaused this way.
2012-05-16 17:35:10 +02:00
Remco van der Zon
b99e664726 A Game-tick can execute viewport.Tick itself,
removed this dependency from World.
2012-05-10 19:54:57 +02:00
psydev
881b4ba277 cnc - changed various unit speeds; gave increased sight to MCV and MSAM. 2012-05-07 07:42:48 +12:00
psydev
3058bfbc17 cnc - updated several building hitpoints 2012-05-07 07:42:48 +12:00
Remco van der Zon
8a08365666 Fixed bug in cash ticks, normal settings.
No sound was heared when repairing buildings or on low power.
Fixed.
2012-05-07 07:42:48 +12:00
Remco van der Zon
6c96a106e7 Red Alert CashTicks
Three options for cash ticks:
Extreme: current behavoir (every cash countdown tick is heard)
Normal: RedAlert countdown style (only one cash countdown tick every ~1 or 2 seconds)
Disabled: No cash tickdown or tickup is heard.

Thanks to Tirili for hints on the settings system.
2012-05-06 20:03:09 +12:00
psydev
6291c8396b cnc - add new explosion: chemball 2012-05-06 19:59:53 +12:00
psydev
79afa07118 cnc - made helicopter selection bounds a bit smaller 2012-05-06 19:58:13 +12:00
Chris Forbes
0e43043a33 cnc: fix crash loading yaml for ArtilleryShell.ContrailLength 2012-05-06 11:27:03 +12:00
psydev
c06fc02915 Changed production menu hotkeys from YUIOP to QWERT (what they are in C&C3). It's more ergonomic and close to the other command keys like A, S, Z, F. It is hard to use the YUIOP keys, because they're too far, even though they are very efficient.
The QWERT setup is a good way to run a menu. I think should reserve them for that and use other keys for unit commands.
2012-05-04 17:11:09 +12:00
psydev
8badbb3d60 Re-ordering the build menu a bit. Seems like guard tower should go before gun turret since it's more basic, cheaper and more often used. 2012-05-04 16:54:45 +12:00
psydev
57283b4a80 Increase range, cost and a modified damage on the MRLS (up vs. light armor, down vs. wood; 2 more bursts). Inaccuracy doubled from 30 to 60. Also increased MinRange from 2 to 4, and added burst delay while increasing rate of fire slightly (burst delay will add 24 to the rate of fire value, making it 70). Justification for these changes is to help fight against recon bike spam and stealth tank spam.
Increase APC gun damage from 6 to 12 (is currently pathetic against helis)

misc:
Made Artillery shell explosion appear bigger
Added contrail to Artillery shell
2012-05-04 16:54:36 +12:00
earthpig
d9992eea6a cnc - Increase rocket launcher cost from 800 to 1200 to reflect changes in range. 2012-05-04 16:51:52 +12:00
earthpig
c8c4507acf Few things with Zhukov AI. 2012-05-01 14:51:21 -07:00
446 changed files with 22466 additions and 7505 deletions

16
.gitignore vendored
View File

@@ -10,6 +10,9 @@ obj
*.manifest
mods/*/*.dll
# ReSharper crap
_ReSharper.*/
# Red Alert binary files
mods/*/packages/*.[mM][iI][xX]
@@ -22,6 +25,8 @@ mods/*/packages/*.[mM][iI][xX]
# backup files by various editors
*~
*.orig
\#*
.*.sw?
# dependency DLLs (different for every platform!)
cg.dll
cgGL.dll
@@ -32,8 +37,6 @@ cgGL.dll
*.pidb
*.userprefs
packaging/windows/*.exe
# osx crap
.DS_Store
@@ -52,9 +55,6 @@ OpenRA.Launcher.Mac/OpenRA.xcodeproj/*.mode1v3
*.config
*.resources
# other crap
Logs/
Replays/
settings.yaml
\#*
.*.sw?
# KDE crap
*.kate-swp
*.directory

View File

@@ -12,16 +12,19 @@ The OpenRA developers are:
Also thanks to:
* Akseli Virtanen (RAGEQUIT)
* Andrew Riedi
* Barnaby Smith (mvi)
* Bellator
* Christer Ulfsparre (Holloweye)
* Erasmus Schroder (rasco)
* Igor Popov (ihptru)
* James Dunne (jsd)
* Jeff Harris (jeff_1amstudios)
* Joakim Lindberg (booom3)
* Kenny Hoxworth (hoxworth)
* Lawrence Wang
* Mark Olson (markolson)
* Matthew Gatland (mgatland)
* Matthias Mailänder (Mailaender)
* Max Ugrumov (katzsmile)
* Max621
* Nukem

View File

@@ -5,10 +5,10 @@ COMMON_LIBS = System.dll System.Core.dll System.Drawing.dll System.Xml.dll third
PHONY = core tools package all mods clean distclean
.SUFFIXES:
core: game renderers mod_ra mod_cnc utility
core: game renderers mods utility tsbuild
tools: editor ralint tsbuild
package: core editor
mods: mod_ra mod_cnc
mods: mod_ra mod_cnc mod_d2k
all: core tools
clean:
@-rm -f *.exe *.dll *.mdb mods/**/*.dll mods/**/*.mdb *.resources
@@ -97,6 +97,16 @@ mod_cnc_EXTRA_CMDS = mono --debug RALint.exe cnc
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_ra_TARGET) $(utility_TARGET)
mod_d2k_LIBS = $(COMMON_LIBS) $(STD_MOD_LIBS) $(mod_ra_TARGET) $(utility_TARGET)
mod_d2k_EXTRA_CMDS = mono --debug RALint.exe d2k
PROGRAMS += mod_d2k
mod_d2k: $(mod_d2k_TARGET)
#
# Tools
#
@@ -127,15 +137,19 @@ ralint: $(ralint_TARGET)
# Builds and exports tilesets from a bitmap
tsbuild_SRCS := $(shell find OpenRA.TilesetBuilder/ -iname '*.cs')
tsbuild_TARGET = TilesetBuilder.exe
tsbuild_TARGET = OpenRA.TilesetBuilder.exe
tsbuild_KIND = winexe
tsbuild_DEPS = $(fileformats_TARGET) $(game_TARGET)
tsbuild_LIBS = $(COMMON_LIBS) $(tsbuild_DEPS) System.Windows.Forms.dll
tsbuild_EXTRA = -resource:OpenRA.TilesetBuilder.Form1.resources
tsbuild_EXTRA = -resource:OpenRA.TilesetBuilder.frmBuilder.resources -resource:OpenRA.TilesetBuilder.frmNew.resources -resource:OpenRA.TilesetBuilder.Surface.resources
PROGRAMS += tsbuild
OpenRA.TilesetBuilder.Form1.resources:
resgen2 OpenRA.TilesetBuilder/Form1.resx OpenRA.TilesetBuilder.Form1.resources 1> /dev/null
tsbuild: OpenRA.TilesetBuilder.Form1.resources $(tsbuild_TARGET)
OpenRA.TilesetBuilder.frmBuilder.resources:
resgen2 OpenRA.TilesetBuilder/frmBuilder.resx OpenRA.TilesetBuilder.frmBuilder.resources 1> /dev/null
OpenRA.TilesetBuilder.frmNew.resources:
resgen2 OpenRA.TilesetBuilder/frmNew.resx OpenRA.TilesetBuilder.frmNew.resources 1> /dev/null
OpenRA.TilesetBuilder.Surface.resources:
resgen2 OpenRA.TilesetBuilder/Surface.resx OpenRA.TilesetBuilder.Surface.resources 1> /dev/null
tsbuild: OpenRA.TilesetBuilder.frmBuilder.resources OpenRA.TilesetBuilder.frmNew.resources OpenRA.TilesetBuilder.Surface.resources $(tsbuild_TARGET)
#
# Launchers / Utilities
@@ -188,7 +202,7 @@ BIN_INSTALL_DIR = $(DESTDIR)$(bindir)
INSTALL_DIR = $(DESTDIR)$(datadir)/openra
INSTALL = install
INSTALL_PROGRAM = $(INSTALL)
CORE = fileformats rcg rgl rsdl rnull game editor utility
CORE = fileformats rcg rgl rsdl rnull game editor utility tsbuild
install: all
@-echo "Installing OpenRA to $(INSTALL_DIR)"
@@ -196,6 +210,10 @@ install: all
@$(INSTALL_PROGRAM) $(foreach prog,$(CORE),$($(prog)_TARGET)) $(INSTALL_DIR)
@$(INSTALL_PROGRAM) -d $(INSTALL_DIR)/mods/cnc
@$(INSTALL_PROGRAM) $(mod_cnc_TARGET) $(INSTALL_DIR)/mods/cnc
@$(INSTALL_PROGRAM) -d $(INSTALL_DIR)/mods/ra
@$(INSTALL_PROGRAM) $(mod_ra_TARGET) $(INSTALL_DIR)/mods/ra
@$(INSTALL_PROGRAM) -d $(INSTALL_DIR)/mods/d2k
@$(INSTALL_PROGRAM) $(mod_d2k_TARGET) $(INSTALL_DIR)/mods/d2k
@-cp $(foreach f,$(shell ls mods/cnc --hide=*.dll),mods/cnc/$(f)) $(INSTALL_DIR)/mods/cnc
@cp -r mods/cnc/maps $(INSTALL_DIR)/mods/cnc
@@ -205,8 +223,6 @@ install: all
@cp -r mods/cnc/sequences $(INSTALL_DIR)/mods/cnc
@cp -r mods/cnc/tilesets $(INSTALL_DIR)/mods/cnc
@cp -r mods/cnc/uibits $(INSTALL_DIR)/mods/cnc
@$(INSTALL_PROGRAM) -d $(INSTALL_DIR)/mods/ra
@$(INSTALL_PROGRAM) $(mod_ra_TARGET) $(INSTALL_DIR)/mods/ra
@-cp $(foreach f,$(shell ls mods/ra --hide=*.dll),mods/ra/$(f)) $(INSTALL_DIR)/mods/ra
@cp -r mods/ra/maps $(INSTALL_DIR)/mods/ra
@@ -215,6 +231,14 @@ install: all
@cp -r mods/ra/rules $(INSTALL_DIR)/mods/ra
@cp -r mods/ra/tilesets $(INSTALL_DIR)/mods/ra
@cp -r mods/ra/uibits $(INSTALL_DIR)/mods/ra
@-cp $(foreach f,$(shell ls mods/d2k --hide=*.dll),mods/d2k/$(f)) $(INSTALL_DIR)/mods/d2k
@cp -r mods/d2k/maps $(INSTALL_DIR)/mods/d2k
@cp -r mods/d2k/bits $(INSTALL_DIR)/mods/d2k
@cp -r mods/d2k/chrome $(INSTALL_DIR)/mods/d2k
@cp -r mods/d2k/rules $(INSTALL_DIR)/mods/d2k
@cp -r mods/d2k/tilesets $(INSTALL_DIR)/mods/d2k
@cp -r mods/d2k/uibits $(INSTALL_DIR)/mods/d2k
@cp -r glsl $(INSTALL_DIR)
@cp -r cg $(INSTALL_DIR)
@@ -237,3 +261,4 @@ install: all
uninstall:
@-rm -r $(INSTALL_DIR)
@-rm $(DESTDIR)$(bindir)/openra
@-rm $(DESTDIR)$(bindir)/openra-editor

View File

@@ -39,7 +39,7 @@ namespace OpenRA.Editor
for (var u = 0; u < template.Size.X; u++)
for (var v = 0; v < template.Size.Y; v++)
{
if (surface.Map.IsInMap(new int2(u, v) + pos))
if (surface.Map.IsInMap(new CVec(u, v) + pos))
{
var z = u + v * template.Size.X;
if (tile.TileBitmapBytes[z] != null)
@@ -69,17 +69,17 @@ namespace OpenRA.Editor
Brush.Bitmap.Height * surface.Zoom);
}
void FloodFillWithBrush(Surface s, int2 pos)
void FloodFillWithBrush(Surface s, CPos pos)
{
var queue = new Queue<int2>();
var queue = new Queue<CPos>();
var replace = s.Map.MapTiles.Value[pos.X, pos.Y];
var touched = new bool[s.Map.MapSize.X, s.Map.MapSize.Y];
Action<int, int> MaybeEnqueue = (x, y) =>
Action<int, int> maybeEnqueue = (x, y) =>
{
if (s.Map.IsInMap(x, y) && !touched[x, y])
{
queue.Enqueue(new int2(x, y));
queue.Enqueue(new CPos(x, y));
touched[x, y] = true;
}
};
@@ -91,16 +91,16 @@ namespace OpenRA.Editor
if (!s.Map.MapTiles.Value[p.X, p.Y].Equals(replace))
continue;
var a = FindEdge(s, p, new int2(-1, 0), replace);
var b = FindEdge(s, p, new int2(1, 0), replace);
var a = FindEdge(s, p, new CVec(-1, 0), replace);
var b = FindEdge(s, p, new CVec(1, 0), replace);
for (var x = a.X; x <= b.X; x++)
{
s.Map.MapTiles.Value[x, p.Y] = new TileReference<ushort, byte> { type = Brush.N, index = (byte)0 };
if (s.Map.MapTiles.Value[x, p.Y - 1].Equals(replace))
MaybeEnqueue(x, p.Y - 1);
maybeEnqueue(x, p.Y - 1);
if (s.Map.MapTiles.Value[x, p.Y + 1].Equals(replace))
MaybeEnqueue(x, p.Y + 1);
maybeEnqueue(x, p.Y + 1);
}
}
@@ -109,7 +109,7 @@ namespace OpenRA.Editor
s.Chunks.Clear();
}
int2 FindEdge(Surface s, int2 p, int2 d, TileReference<ushort, byte> replace)
CPos FindEdge(Surface s, CPos p, CVec d, TileReference<ushort, byte> replace)
{
for (; ; )
{

View File

@@ -144,32 +144,55 @@ namespace OpenRA.Editor
// construct the palette of tiles
var palettes = new[] { tilePalette, actorPalette, resourcePalette };
foreach (var p in palettes) { p.Visible = false; p.SuspendLayout(); }
foreach (var t in tileset.Templates)
foreach (var tc in tileset.Templates.GroupBy(t => t.Value.Category))
{
try
var category = tc.Key ?? "(Uncategorized)";
var categoryHeader = new Label
{
var bitmap = tileset.RenderTemplate((ushort)t.Key, palette);
var ibox = new PictureBox
BackColor = SystemColors.Highlight,
ForeColor = SystemColors.HighlightText,
Text = category,
AutoSize = false,
Height = 24,
TextAlign = ContentAlignment.MiddleLeft,
Width = tilePalette.ClientSize.Width,
};
// hook this manually, anchoring inside FlowLayoutPanel is flaky.
tilePalette.Resize += (_,e) => categoryHeader.Width = tilePalette.ClientSize.Width;
if (tilePalette.Controls.Count > 0)
tilePalette.SetFlowBreak(
tilePalette.Controls[tilePalette.Controls.Count - 1], true);
tilePalette.Controls.Add(categoryHeader);
foreach( var t in tc )
{
try
{
Image = bitmap,
Width = bitmap.Width / 2,
Height = bitmap.Height / 2,
SizeMode = PictureBoxSizeMode.StretchImage
};
var brushTemplate = new BrushTemplate { Bitmap = bitmap, N = t.Key };
ibox.Click += (_, e) => surface1.SetTool(new BrushTool(brushTemplate));
var template = t.Value;
tilePalette.Controls.Add(ibox);
tt.SetToolTip(ibox,
"{1}:{0} ({2}x{3})".F(
template.Image,
template.Id,
template.Size.X,
template.Size.Y));
var bitmap = tileset.RenderTemplate((ushort)t.Key, palette);
var ibox = new PictureBox
{
Image = bitmap,
Width = bitmap.Width / 2,
Height = bitmap.Height / 2,
SizeMode = PictureBoxSizeMode.StretchImage
};
var brushTemplate = new BrushTemplate { Bitmap = bitmap, N = t.Key };
ibox.Click += (_, e) => surface1.SetTool(new BrushTool(brushTemplate));
var template = t.Value;
tilePalette.Controls.Add(ibox);
tt.SetToolTip(ibox,
"{1}:{0} ({2}x{3})".F(
template.Image,
template.Id,
template.Size.X,
template.Size.Y));
}
catch { }
}
catch { }
}
var actorTemplates = new List<ActorTemplate>();

View File

@@ -175,7 +175,7 @@ namespace OpenRA.Editor
foreach( var kv in wps )
{
var a = new ActorReference("mpspawn");
a.Add(new LocationInit(kv.Second));
a.Add(new LocationInit((CPos)kv.Second));
a.Add(new OwnerInit("Neutral"));
Map.Actors.Value.Add("spawn" + kv.First, a);
}
@@ -276,7 +276,7 @@ namespace OpenRA.Editor
Map.Actors.Value.Add("Actor" + ActorCount++,
new ActorReference(overlayActorMapping[raOverlayNames[o]])
{
new LocationInit( new int2(i, j) ),
new LocationInit( new CPos(i, j) ),
new OwnerInit( "Neutral" )
});
}
@@ -294,7 +294,7 @@ namespace OpenRA.Editor
Map.Actors.Value.Add("Actor" + ActorCount++,
new ActorReference(kv.Value.ToLowerInvariant())
{
new LocationInit(new int2(loc % MapSize, loc / MapSize)),
new LocationInit(new CPos(loc % MapSize, loc / MapSize)),
new OwnerInit("Neutral")
});
}
@@ -323,7 +323,7 @@ namespace OpenRA.Editor
foreach (KeyValuePair<string, string> kv in overlay)
{
var loc = int.Parse(kv.Key);
var cell = new int2(loc % MapSize, loc / MapSize);
var cell = new CPos(loc % MapSize, loc / MapSize);
var res = Pair.New((byte)0, (byte)0);
if (overlayResourceMapping.ContainsKey(kv.Value.ToLower()))
@@ -353,7 +353,7 @@ namespace OpenRA.Editor
Map.Actors.Value.Add("Actor" + ActorCount++,
new ActorReference(kv.Value.Split(',')[0].ToLowerInvariant())
{
new LocationInit(new int2(loc % MapSize, loc / MapSize)),
new LocationInit(new CPos(loc % MapSize, loc / MapSize)),
new OwnerInit("Neutral")
});
}
@@ -380,7 +380,7 @@ namespace OpenRA.Editor
var actor = new ActorReference(parts[1].ToLowerInvariant())
{
new LocationInit(new int2(loc % MapSize, loc / MapSize)),
new LocationInit(new CPos(loc % MapSize, loc / MapSize)),
new OwnerInit(parts[0]),
new HealthInit(float.Parse(parts[2], NumberFormatInfo.InvariantInfo)/256),
new FacingInit((section == "INFANTRY") ? int.Parse(parts[6]) : int.Parse(parts[4])),
@@ -432,7 +432,7 @@ namespace OpenRA.Editor
(byte)(color.Second.GetBrightness() * 255))
};
var Neutral = new [] {"Neutral"};
var neutral = new [] {"Neutral"};
foreach (var s in file.GetSection(section, true))
{
Console.WriteLine(s.Key);
@@ -442,8 +442,8 @@ namespace OpenRA.Editor
pr.InitialCash = int.Parse(s.Value);
break;
case "Allies":
pr.Allies = s.Value.Split(',').Intersect(Players).Except(Neutral).ToArray();
pr.Enemies = s.Value.Split(',').SymmetricDifference(Players).Except(Neutral).ToArray();
pr.Allies = s.Value.Split(',').Intersect(Players).Except(neutral).ToArray();
pr.Enemies = s.Value.Split(',').SymmetricDifference(Players).Except(neutral).ToArray();
break;
}
}

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -13,6 +13,25 @@
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ApplicationIcon>OpenRA.Editor.Icon.ico</ApplicationIcon>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation />
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -25,6 +44,7 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -35,6 +55,7 @@
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@@ -122,6 +143,7 @@
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
@@ -157,6 +179,23 @@
<ItemGroup>
<Content Include="OpenRA.Editor.Icon.ico" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View File

@@ -1,71 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.4927
// Runtime Version:4.0.30319.269
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace OpenRA.Editor.Properties
{
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OpenRA.Editor.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
namespace OpenRA.Editor.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OpenRA.Editor.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@@ -1,30 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.4927
// Runtime Version:4.0.30319.269
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace OpenRA.Editor.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
namespace OpenRA.Editor.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@@ -157,23 +157,23 @@ namespace OpenRA.Editor
void Erase()
{
// Crash preventing
var BrushLocation = GetBrushLocation();
var brushLocation = GetBrushLocation();
if (Map == null || BrushLocation.X >= Map.MapSize.X ||
BrushLocation.Y >= Map.MapSize.Y ||
BrushLocation.X < 0 ||
BrushLocation.Y < 0)
if (Map == null || brushLocation.X >= Map.MapSize.X ||
brushLocation.Y >= Map.MapSize.Y ||
brushLocation.X < 0 ||
brushLocation.Y < 0)
return;
Tool = null;
var key = Map.Actors.Value.FirstOrDefault(a => a.Value.Location() == BrushLocation);
var key = Map.Actors.Value.FirstOrDefault(a => a.Value.Location() == brushLocation);
if (key.Key != null) Map.Actors.Value.Remove(key.Key);
if (Map.MapResources.Value[BrushLocation.X, BrushLocation.Y].type != 0)
if (Map.MapResources.Value[brushLocation.X, brushLocation.Y].type != 0)
{
Map.MapResources.Value[BrushLocation.X, BrushLocation.Y] = new TileReference<byte, byte>();
var ch = new int2((BrushLocation.X) / ChunkSize, (BrushLocation.Y) / ChunkSize);
Map.MapResources.Value[brushLocation.X, brushLocation.Y] = new TileReference<byte, byte>();
var ch = new int2((brushLocation.X) / ChunkSize, (brushLocation.Y) / ChunkSize);
if (Chunks.ContainsKey(ch))
{
Chunks[ch].Dispose();
@@ -267,31 +267,31 @@ namespace OpenRA.Editor
return bitmap;
}
public int2 GetBrushLocation()
public CPos GetBrushLocation()
{
var vX = (int)Math.Floor((MousePos.X - Offset.X) / Zoom);
var vY = (int)Math.Floor((MousePos.Y - Offset.Y) / Zoom);
return new int2(vX / TileSet.TileSize, vY / TileSet.TileSize);
return new CPos(vX / TileSet.TileSize, vY / TileSet.TileSize);
}
public void DrawActor(SGraphics g, int2 p, ActorTemplate t, ColorPalette cp)
public void DrawActor(SGraphics g, CPos p, ActorTemplate t, ColorPalette cp)
{
var centered = t.Appearance == null || !t.Appearance.RelativeToTopLeft;
DrawImage(g, t.Bitmap, p, centered, cp);
}
float2 GetDrawPosition(int2 location, Bitmap bmp, bool centered)
float2 GetDrawPosition(CPos location, Bitmap bmp, bool centered)
{
float OffsetX = centered ? bmp.Width / 2 - TileSet.TileSize / 2 : 0;
float DrawX = TileSet.TileSize * location.X * Zoom + Offset.X - OffsetX;
float offsetX = centered ? bmp.Width / 2 - TileSet.TileSize / 2 : 0;
float drawX = TileSet.TileSize * location.X * Zoom + Offset.X - offsetX;
float OffsetY = centered ? bmp.Height / 2 - TileSet.TileSize / 2 : 0;
float DrawY = TileSet.TileSize * location.Y * Zoom + Offset.Y - OffsetY;
float offsetY = centered ? bmp.Height / 2 - TileSet.TileSize / 2 : 0;
float drawY = TileSet.TileSize * location.Y * Zoom + Offset.Y - offsetY;
return new float2(DrawX, DrawY);
return new float2(drawX, drawY);
}
public void DrawImage(SGraphics g, Bitmap bmp, int2 location, bool centered, ColorPalette cp)
public void DrawImage(SGraphics g, Bitmap bmp, CPos location, bool centered, ColorPalette cp)
{
var drawPos = GetDrawPosition(location, bmp, centered);
@@ -304,7 +304,7 @@ namespace OpenRA.Editor
if (cp != null) bmp.Palette = restorePalette;
}
void DrawActorBorder(SGraphics g, int2 p, ActorTemplate t)
void DrawActorBorder(SGraphics g, CPos p, ActorTemplate t)
{
var centered = t.Appearance == null || !t.Appearance.RelativeToTopLeft;
var drawPos = GetDrawPosition(p, t.Bitmap, centered);
@@ -318,7 +318,7 @@ namespace OpenRA.Editor
{
var pr = Map.Players[name];
var pcpi = Rules.Info["player"].Traits.Get<PlayerColorPaletteInfo>();
var remap = new PlayerColorRemap(pcpi.PaletteFormat, pr.ColorRamp);
var remap = new PlayerColorRemap(pcpi.RemapIndex, pr.ColorRamp);
return new Palette(Palette, remap).AsSystemPalette();
}
@@ -399,9 +399,9 @@ namespace OpenRA.Editor
static class ActorReferenceExts
{
public static int2 Location(this ActorReference ar)
public static CPos Location(this ActorReference ar)
{
return ar.InitDict.Get<LocationInit>().value;
return (CPos)ar.InitDict.Get<LocationInit>().value;
}
public static void DrawStringContrast(this SGraphics g, Font f, string s, int x, int y, Brush fg, Brush bg)

View File

@@ -56,6 +56,11 @@ namespace OpenRA.FileFormats
ret = GetValue( fieldName, fieldType, n[ 0 ].Value.Value );
return true;
}
else if ( n.Count > 1 )
{
throw new InvalidOperationException("The field {0} has multiple definitions:\n{1}"
.F(fieldName, n.Select(m => "\t- " + m.Location).JoinWith("\n")));
}
throw new InvalidOperationException( "TryGetValueFromYaml: unable to load field {0} (of type {1})".F( fieldName, fieldType ) );
}
@@ -320,6 +325,10 @@ namespace OpenRA.FileFormats
((int)c.B).Clamp(0, 255));
}
// Don't save floats in settings.yaml using country-specific decimal separators which can be misunderstood as group seperators.
if (t == typeof(float))
return ((float)v).ToString(CultureInfo.InvariantCulture);
if (t == typeof(Rectangle))
{
var r = (Rectangle)v;

View File

@@ -20,7 +20,7 @@ namespace OpenRA.FileFormats
public class TerrainTypeInfo
{
public string Type;
public bool AcceptSmudge = true;
public string[] AcceptsSmudgeType = { };
public bool IsWater = false;
public Color Color;
@@ -36,6 +36,7 @@ namespace OpenRA.FileFormats
public string Image;
public int2 Size;
public bool PickAny;
public string Category;
[FieldLoader.LoadUsing( "LoadTiles" )]
public Dictionary<byte, string> Tiles = new Dictionary<byte, string>();

View File

@@ -105,11 +105,14 @@ namespace OpenRA.FileFormats
levels.Add(new List<MiniYamlNode>());
var lineNo = 0;
foreach (var line in lines)
foreach (var ll in lines)
{
var line = ll;
++lineNo;
if (line.Contains('#'))
line = line.Substring(0, line.IndexOf('#')).TrimEnd(' ', '\t');
var t = line.TrimStart(' ', '\t');
if (t.Length == 0 || t[0] == '#')
if (t.Length == 0)
continue;
var level = line.Length - t.Length;
var location = new MiniYamlNode.SourceLocation { Filename = filename, Line = lineNo };

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -12,10 +12,25 @@
<AssemblyName>OpenRA.FileFormats</AssemblyName>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>2.0</OldToolsVersion>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -27,6 +42,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath>bin\Release\</OutputPath>
@@ -37,6 +53,7 @@
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@@ -116,6 +133,23 @@
<Compile Include="Thirdparty\Random.cs" />
<Compile Include="TypeDictionary.cs" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
@@ -124,4 +158,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>

View File

@@ -14,40 +14,31 @@ using System.Linq;
namespace OpenRA.FileFormats
{
// TODO: ship this out of here.
public enum PaletteFormat { ra, cnc, d2k }
public class PlayerColorRemap : IPaletteRemap
{
Dictionary<int, Color> remapColors;
static readonly int[] CncRemapRamp = new[] { 0, 2, 4, 6, 8, 10, 13, 15, 1, 3, 5, 7, 9, 11, 12, 14 };
static readonly int[] NormalRemapRamp = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
static int GetRemapBase(PaletteFormat fmt)
static int[] GetRemapRamp(int[] Ramp)
{
return (fmt == PaletteFormat.cnc) ? 0xb0 : (fmt == PaletteFormat.d2k) ? 240 : 80;
var RemapRamp = Ramp.Select(r => r - Ramp[0]).ToArray();
return RemapRamp;
}
static int[] GetRemapRamp(PaletteFormat fmt)
public static int GetRemapIndex(int[] Ramp, int i)
{
return (fmt == PaletteFormat.cnc) ? CncRemapRamp : NormalRemapRamp;
return Ramp[i];
}
public static int GetRemapIndex(PaletteFormat fmt, int i)
{
return GetRemapBase(fmt) + GetRemapRamp(fmt)[i];
}
public PlayerColorRemap(PaletteFormat fmt, ColorRamp c)
public PlayerColorRemap(int[] Ramp, ColorRamp c)
{
var c1 = c.GetColor(0);
var c2 = c.GetColor(1); /* temptemp: this can be expressed better */
var baseIndex = GetRemapBase(fmt);
var ramp = GetRemapRamp(fmt);
var baseIndex = Ramp[0];
var RemapRamp = GetRemapRamp(Ramp);
remapColors = ramp.Select((x, i) => Pair.New(baseIndex + i, Exts.ColorLerp(x / 16f, c1, c2)))
remapColors = RemapRamp.Select((x, i) => Pair.New(baseIndex + i, Exts.ColorLerp(x / 16f, c1, c2)))
.ToDictionary(u => u.First, u => u.Second);
}

View File

@@ -32,9 +32,9 @@ namespace OpenRA
public IOccupySpace OccupiesSpace { get { return occupySpace.Value; } }
public int2 Location { get { return occupySpace.Value.TopLeft; } }
public CPos Location { get { return occupySpace.Value.TopLeft; } }
public int2 CenterLocation
public PPos CenterLocation
{
get
{
@@ -123,22 +123,30 @@ namespace OpenRA
// at its current altitude
Rectangle CalculateBounds(bool useAltitude)
{
var size = Size.Value;
var size = (PVecInt)(Size.Value);
var loc = CenterLocation - size / 2;
var si = Info.Traits.GetOrDefault<SelectableInfo>();
if (si != null && si.Bounds != null && si.Bounds.Length > 2)
{
#if true
loc += new PVecInt(si.Bounds[2], si.Bounds[3]);
#else
loc.X += si.Bounds[2];
loc.Y += si.Bounds[3];
#endif
}
var move = Move.Value;
if (move != null)
{
#if true
loc -= new PVecInt(0, move.Altitude);
#else
loc.Y -= move.Altitude;
#endif
if (useAltitude)
size = new int2(size.X, size.Y + move.Altitude);
size = new PVecInt(size.X, size.Y + move.Altitude);
}
return new Rectangle(loc.X, loc.Y, size.X, size.Y);

View File

@@ -62,12 +62,12 @@ namespace OpenRA
public int Value( World world ) { return value; }
}
public class LocationInit : IActorInit<int2>
public class LocationInit : IActorInit<CPos>
{
[FieldFromYamlKey] public readonly int2 value = int2.Zero;
public LocationInit() { }
public LocationInit( int2 init ) { value = init; }
public int2 Value( World world ) { return value; }
public LocationInit( CPos init ) { value = init.ToInt2(); }
public CPos Value(World world) { return (CPos)value; }
}
public class SubCellInit : IActorInit<SubCell>
@@ -78,12 +78,12 @@ namespace OpenRA
public SubCell Value(World world) { return (SubCell)value; }
}
public class CenterLocationInit : IActorInit<int2>
public class CenterLocationInit : IActorInit<PPos>
{
[FieldFromYamlKey] public readonly int2 value = int2.Zero;
public CenterLocationInit() { }
public CenterLocationInit( int2 init ) { value = init; }
public int2 Value( World world ) { return value; }
public CenterLocationInit(PPos init) { value = init.ToInt2(); }
public PPos Value(World world) { return (PPos)value; }
}
public class OwnerInit : IActorInit<Player>

View File

@@ -37,7 +37,7 @@ namespace OpenRA
world.ActorRemoved += a => Remove( a, a.OccupiesSpace );
}
public IEnumerable<Actor> GetUnitsAt( int2 a )
public IEnumerable<Actor> GetUnitsAt(CPos a)
{
if (!map.IsInMap(a)) yield break;
@@ -46,7 +46,7 @@ namespace OpenRA
yield return i.actor;
}
public IEnumerable<Actor> GetUnitsAt( int2 a, SubCell sub )
public IEnumerable<Actor> GetUnitsAt(CPos a, SubCell sub)
{
if (!map.IsInMap(a)) yield break;
@@ -55,7 +55,7 @@ namespace OpenRA
yield return i.actor;
}
public bool HasFreeSubCell(int2 a)
public bool HasFreeSubCell(CPos a)
{
if (!AnyUnitsAt(a))
return true;
@@ -64,12 +64,12 @@ namespace OpenRA
SubCell.BottomLeft, SubCell.BottomRight }.Any(b => !AnyUnitsAt(a,b));
}
public bool AnyUnitsAt(int2 a)
public bool AnyUnitsAt(CPos a)
{
return influence[ a.X, a.Y ] != null;
}
public bool AnyUnitsAt(int2 a, SubCell sub)
public bool AnyUnitsAt(CPos a, SubCell sub)
{
for( var i = influence[ a.X, a.Y ] ; i != null ; i = i.next )
if (i.subCell == sub || i.subCell == SubCell.FullCell)

71
OpenRA.Game/CPos.cs Normal file
View File

@@ -0,0 +1,71 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 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. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Drawing;
namespace OpenRA
{
/// <summary>
/// Cell coordinate position in the world (coarse).
/// </summary>
public struct CPos
{
public readonly int X, Y;
public CPos(int x, int y) { X = x; Y = y; }
public static readonly CPos Zero = new CPos(0, 0);
public static explicit operator CPos(int2 a) { return new CPos(a.X, a.Y); }
public static CPos operator +(CVec a, CPos b) { return new CPos(a.X + b.X, a.Y + b.Y); }
public static CPos operator +(CPos a, CVec b) { return new CPos(a.X + b.X, a.Y + b.Y); }
public static CPos operator -(CPos a, CVec b) { return new CPos(a.X - b.X, a.Y - b.Y); }
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); }
public static bool operator !=(CPos me, CPos other) { return !(me == other); }
public static CPos Max(CPos a, CPos b) { return new CPos(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
public static CPos Min(CPos a, CPos b) { return new CPos(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
public float2 ToFloat2() { return new float2(X, Y); }
public int2 ToInt2() { return new int2(X, Y); }
public PPos ToPPos() { return new PPos(Game.CellSize * X, Game.CellSize * Y); }
public CPos Clamp(Rectangle r)
{
return new CPos(Math.Min(r.Right, Math.Max(X, r.Left)),
Math.Min(r.Bottom, Math.Max(Y, r.Top)));
}
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
public override bool Equals(object obj)
{
if (obj == null)
return false;
CPos o = (CPos)obj;
return o == this;
}
public override string ToString() { return "{0},{1}".F(X, Y); }
}
public static class RectangleExtensions
{
public static CPos TopLeftAsCPos(this Rectangle r) { return new CPos(r.Left, r.Top); }
public static CPos BottomRightAsCPos(this Rectangle r) { return new CPos(r.Right, r.Bottom); }
}
}

76
OpenRA.Game/CVec.cs Normal file
View File

@@ -0,0 +1,76 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 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. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Drawing;
namespace OpenRA
{
/// <summary>
/// Cell coordinate vector (coarse).
/// </summary>
public struct CVec
{
public readonly int X, Y;
public CVec(int x, int y) { X = x; Y = y; }
public CVec(Size p) { X = p.Width; Y = p.Height; }
public static readonly CVec Zero = new CVec(0, 0);
public static explicit operator CVec(int2 a) { return new CVec(a.X, a.Y); }
public static explicit operator CVec(float2 a) { return new CVec((int)a.X, (int)a.Y); }
public static CVec operator +(CVec a, CVec b) { return new CVec(a.X + b.X, a.Y + b.Y); }
public static CVec operator -(CVec a, CVec b) { return new CVec(a.X - b.X, a.Y - b.Y); }
public static CVec operator *(int a, CVec b) { return new CVec(a * b.X, a * b.Y); }
public static CVec operator *(CVec b, int a) { return new CVec(a * b.X, a * b.Y); }
public static CVec operator /(CVec a, int b) { return new CVec(a.X / b, a.Y / b); }
public static CVec operator -(CVec a) { return new CVec(-a.X, -a.Y); }
public static bool operator ==(CVec me, CVec other) { return (me.X == other.X && me.Y == other.Y); }
public static bool operator !=(CVec me, CVec other) { return !(me == other); }
public static CVec Max(CVec a, CVec b) { return new CVec(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
public static CVec Min(CVec a, CVec b) { return new CVec(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
public static int Dot(CVec a, CVec b) { return a.X * b.X + a.Y * b.Y; }
public CVec Sign() { return new CVec(Math.Sign(X), Math.Sign(Y)); }
public CVec Abs() { return new CVec(Math.Abs(X), Math.Abs(Y)); }
public int LengthSquared { get { return X * X + Y * Y; } }
public int Length { get { return (int)Math.Sqrt(LengthSquared); } }
public float2 ToFloat2() { return new float2(X, Y); }
public int2 ToInt2() { return new int2(X, Y); }
public CVec Clamp(Rectangle r)
{
return new CVec(
Math.Min(r.Right, Math.Max(X, r.Left)),
Math.Min(r.Bottom, Math.Max(Y, r.Top))
);
}
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
public override bool Equals(object obj)
{
if (obj == null)
return false;
CVec o = (CVec)obj;
return o == this;
}
public override string ToString() { return "{0},{1}".F(X, Y); }
}
}

View File

@@ -166,7 +166,7 @@ namespace OpenRA
{
var isNetTick = LocalTick % NetTickScale == 0;
if (!isNetTick || orderManager.IsReadyForNextFrame)
if ((!isNetTick || orderManager.IsReadyForNextFrame) && !orderManager.GamePaused )
{
++orderManager.LocalFrameNumber;
@@ -188,6 +188,8 @@ namespace OpenRA
else
if (orderManager.NetFrameNumber == 0)
orderManager.LastTickTime = Environment.TickCount;
viewport.Tick();
}
}
}
@@ -244,7 +246,6 @@ namespace OpenRA
AppDomain.CurrentDomain.AssemblyResolve += FileSystem.ResolveAssembly;
Settings = new Settings(Platform.SupportDir + "settings.yaml", args);
Settings.Save();
Log.LogPath = Platform.SupportDir + "Logs" + Path.DirectorySeparatorChar;
Log.AddChannel("perf", "perf.log");
@@ -278,11 +279,11 @@ namespace OpenRA
if (orderManager != null)
orderManager.Dispose();
// Discard any invalid mods
// Discard any invalid mods, set RA as default
var mm = mods.Where( m => Mod.AllMods.ContainsKey( m ) ).ToArray();
if (mm.Length == 0) mm = new[] { "ra" };
Console.WriteLine("Loading mods: {0}", mm.JoinWith(","));
Settings.Game.Mods = mm;
Settings.Save();
Sound.StopMusic();
Sound.StopVideo();
@@ -302,6 +303,7 @@ namespace OpenRA
viewport = new Viewport(new int2(Renderer.Resolution), Rectangle.Empty, Renderer);
modData.LoadScreen.StartGame();
Settings.Save();
}
public static void LoadShellMap()
@@ -390,6 +392,7 @@ namespace OpenRA
// Work around a miscompile in mono 2.6.7:
// booleans that default to true cannot be set false by an initializer
settings.AdvertiseOnline = false;
settings.AllowUPnP = false;
server = new Server.Server(new IPEndPoint(IPAddress.Loopback, 0),
Game.Settings.Game.Mods, settings, modData);

View File

@@ -19,6 +19,9 @@ using OpenRA.Server;
namespace OpenRA.GameRules
{
public enum MouseScrollType { Disabled, Standard, Inverted }
public enum SoundCashTicks { Disabled, Normal, Extreme }
public class ServerSettings
{
public string Name = "OpenRA Game";
@@ -26,8 +29,11 @@ namespace OpenRA.GameRules
public int ExternalPort = 1234;
public bool AdvertiseOnline = true;
public string MasterServer = "http://master.open-ra.org/";
public bool AllowUPnP = true;
public bool AllowCheats = false;
public string Map = null;
public string[] Ban = null;
public int TimeOut = 0;
public ServerSettings() { }
@@ -38,8 +44,11 @@ namespace OpenRA.GameRules
ExternalPort = other.ExternalPort;
AdvertiseOnline = other.AdvertiseOnline;
MasterServer = other.MasterServer;
AllowUPnP = other.AllowUPnP;
AllowCheats = other.AllowCheats;
Map = other.Map;
Ban = other.Ban;
TimeOut = other.TimeOut;
}
}
@@ -77,6 +86,8 @@ namespace OpenRA.GameRules
public bool Repeat = false;
public bool ShellmapMusic = true;
public string Engine = "AL";
public SoundCashTicks SoundCashTickType = SoundCashTicks.Extreme;
}
public class PlayerSettings
@@ -86,8 +97,6 @@ namespace OpenRA.GameRules
public string LastServer = "localhost:1234";
}
public enum MouseScrollType { Disabled, Standard, Inverted }
public class GameSettings
{
public string[] Mods = { "ra" };

View File

@@ -18,9 +18,12 @@ namespace OpenRA.GameRules
public class VoiceInfo
{
[FieldLoader.Ignore] public readonly Dictionary<string,string[]> Variants;
[FieldLoader.Ignore] public readonly Dictionary<string,string[]> Prefixes;
[FieldLoader.Ignore] public readonly Dictionary<string,string[]> Voices;
public readonly string DefaultVariant = ".aud" ;
public readonly string DefaultPrefix = "" ;
public readonly string[] DisableVariants = { };
public readonly string[] DisablePrefixes = { };
static Dictionary<string, string[]> Load( MiniYaml y, string name )
{
@@ -37,6 +40,7 @@ namespace OpenRA.GameRules
{
FieldLoader.Load( this, y );
Variants = Load(y, "Variants");
Prefixes = Load(y, "Prefixes");
Voices = Load(y, "Voices");
if (!Voices.ContainsKey("Attack"))

View File

@@ -24,7 +24,7 @@ namespace OpenRA.GameRules
public readonly bool Ore = false; // can this damage ore?
public readonly string Explosion = null; // explosion effect to use
public readonly string WaterExplosion = null; // explosion effect on hitting water (usually a splash)
public readonly string SmudgeType = null; // type of smudge to apply
public readonly string[] SmudgeType = { }; // type of smudge to apply
public readonly int[] Size = { 0, 0 }; // size of the explosion. provide 2 values for a ring effect (outer/inner)
public readonly int InfDeath = 0; // infantry death animation to use
public readonly string ImpactSound = null; // sound to play on impact
@@ -72,11 +72,11 @@ namespace OpenRA.GameRules
{
public WeaponInfo weapon;
public Actor firedBy;
public int2 src;
public PPos src;
public int srcAltitude;
public int facing;
public Target target;
public int2 dest;
public PPos dest;
public int destAltitude;
public float firepowerModifier = 1.0f;
}

View File

@@ -35,7 +35,7 @@ namespace OpenRA.Graphics
public Renderable Image(Actor self, string pal)
{
var p = self.CenterLocation;
var loc = p - 0.5f * Animation.Image.size
var loc = p.ToFloat2() - 0.5f * Animation.Image.size
+ (OffsetFunc != null ? OffsetFunc() : float2.Zero);
var r = new Renderable(Animation.Image, loc, pal, p.Y);

View File

@@ -25,9 +25,13 @@ namespace OpenRA.Graphics
{
cursors = new Dictionary<string, CursorSequence>();
var sequences = new MiniYaml(null, sequenceFiles.Select(s => MiniYaml.FromFile(s)).Aggregate(MiniYaml.MergeLiberal));
var transparent = false;
if (sequences.NodesDict.ContainsKey("Transparent"))
transparent = true;
foreach (var s in sequences.NodesDict["Palettes"].Nodes)
Game.modData.Palette.AddPalette(s.Key, new Palette(FileSystem.Open(s.Value.Value), false));
Game.modData.Palette.AddPalette(s.Key, new Palette(FileSystem.Open(s.Value.Value), transparent));
foreach (var s in sequences.NodesDict["Cursors"].Nodes)
LoadSequencesForCursor(s.Key, s.Value);

View File

@@ -27,10 +27,9 @@ namespace OpenRA.Graphics
public int Facings { get { return facings; } }
public int Tick { get { return tick; } }
string srcOverride;
public Sequence(string unit, string name, MiniYaml info)
{
srcOverride = info.Value;
var srcOverride = info.Value;
Name = name;
var d = info.NodesDict;
@@ -62,26 +61,6 @@ namespace OpenRA.Graphics
info.Nodes[0].Location));
}
public MiniYaml Save()
{
var root = new List<MiniYamlNode>();
root.Add(new MiniYamlNode("Start", start.ToString()));
if (length > 1 && (start != 0 || length != sprites.Length - start))
root.Add(new MiniYamlNode("Length", length.ToString()));
else if (length > 1 && length == sprites.Length - start)
root.Add(new MiniYamlNode("Length", "*"));
if (facings > 1)
root.Add(new MiniYamlNode("Facings", facings.ToString()));
if (tick != 40)
root.Add(new MiniYamlNode("Tick", tick.ToString()));
return new MiniYaml(srcOverride, root);
}
public Sprite GetSprite( int frame )
{
return GetSprite( frame, 0 );

View File

@@ -149,18 +149,18 @@ namespace OpenRA.Graphics
}
// Convert from viewport coords to cell coords (not px)
public float2 ViewToWorld(MouseInput mi) { return ViewToWorld(mi.Location); }
public float2 ViewToWorld(int2 loc)
public CPos ViewToWorld(MouseInput mi) { return ViewToWorld(mi.Location); }
public CPos ViewToWorld(int2 loc)
{
return (1f / Game.CellSize) * (1f/Zoom*loc.ToFloat2() + Location);
return (CPos)( (1f / Game.CellSize) * (1f/Zoom*loc.ToFloat2() + Location) ).ToInt2();
}
public int2 ViewToWorldPx(int2 loc) { return (1f/Zoom*loc.ToFloat2() + Location).ToInt2(); }
public int2 ViewToWorldPx(MouseInput mi) { return ViewToWorldPx(mi.Location); }
public PPos ViewToWorldPx(int2 loc) { return (PPos)(1f/Zoom*loc.ToFloat2() + Location).ToInt2(); }
public PPos ViewToWorldPx(MouseInput mi) { return ViewToWorldPx(mi.Location); }
public void Center(float2 loc)
{
scrollPosition = NormalizeScrollPosition((Game.CellSize*loc - 1f/(2*Zoom)*screenSize.ToFloat2()).ToInt2());
scrollPosition = NormalizeScrollPosition((Game.CellSize * loc - 1f/(2*Zoom)*screenSize.ToFloat2()).ToInt2());
}
public void Center(IEnumerable<Actor> actors)
@@ -168,9 +168,9 @@ namespace OpenRA.Graphics
if (!actors.Any()) return;
var avgPos = actors
.Select(a => a.CenterLocation)
.Select(a => (PVecInt)a.CenterLocation)
.Aggregate((a, b) => a + b) / actors.Count();
scrollPosition = NormalizeScrollPosition((avgPos - 1f/(2*Zoom)*screenSize.ToFloat2()).ToInt2());
scrollPosition = NormalizeScrollPosition(((PVecFloat)avgPos - (PVecFloat)(1f / (2 * Zoom) * screenSize.ToFloat2())).ToInt2());
}
// Rectangle (in viewport coords) that contains things to be drawn

View File

@@ -53,8 +53,9 @@ namespace OpenRA.Graphics
var comparer = new SpriteComparer();
var actors = world.FindUnits(
new int2(Game.CellSize*bounds.Left, Game.CellSize*bounds.Top),
new int2(Game.CellSize*bounds.Right, Game.CellSize*bounds.Bottom));
bounds.TopLeftAsCPos().ToPPos(),
bounds.BottomRightAsCPos().ToPPos()
);
var renderables = actors.SelectMany(a => a.Render())
.OrderBy(r => r, comparer);
@@ -140,25 +141,21 @@ namespace OpenRA.Graphics
selectable.DrawRollover(this, unit);
}
public void DrawLocus(Color c, int2[] cells)
public void DrawLocus(Color c, CPos[] cells)
{
var dict = cells.ToDictionary(a => a, a => 0);
var wlr = Game.Renderer.WorldLineRenderer;
foreach (var t in dict.Keys)
{
if (!dict.ContainsKey(t + new int2(-1, 0)))
wlr.DrawLine(Game.CellSize * t, Game.CellSize * (t + new int2(0, 1)),
c, c);
if (!dict.ContainsKey(t + new int2(1, 0)))
wlr.DrawLine(Game.CellSize * (t + new int2(1, 0)), Game.CellSize * (t + new int2(1, 1)),
c, c);
if (!dict.ContainsKey(t + new int2(0, -1)))
wlr.DrawLine(Game.CellSize * t, Game.CellSize * (t + new int2(1, 0)),
c, c);
if (!dict.ContainsKey(t + new int2(0, 1)))
wlr.DrawLine(Game.CellSize * (t + new int2(0, 1)), Game.CellSize * (t + new int2(1, 1)),
c, c);
if (!dict.ContainsKey(t + new CVec(-1, 0)))
wlr.DrawLine(t.ToPPos().ToFloat2(), (t + new CVec(0, 1)).ToPPos().ToFloat2(), c, c);
if (!dict.ContainsKey(t + new CVec(1, 0)))
wlr.DrawLine((t + new CVec(1, 0)).ToPPos().ToFloat2(), (t + new CVec(1, 1)).ToPPos().ToFloat2(), c, c);
if (!dict.ContainsKey(t + new CVec(0, -1)))
wlr.DrawLine(t.ToPPos().ToFloat2(), (t + new CVec(1, 0)).ToPPos().ToFloat2(), c, c);
if (!dict.ContainsKey(t + new CVec(0, 1)))
wlr.DrawLine((t + new CVec(0, 1)).ToPPos().ToFloat2(), (t + new CVec(1, 1)).ToPPos().ToFloat2(), c, c);
}
}

View File

@@ -338,7 +338,7 @@ namespace OpenRA
return dataStream.ToArray();
}
public bool IsInMap(int2 xy) { return IsInMap(xy.X, xy.Y); }
public bool IsInMap(CPos xy) { return IsInMap(xy.X, xy.Y); }
public bool IsInMap(int x, int y) { return Bounds.Contains(x,y); }
static T[,] ResizeArray<T>(T[,] ts, T t, int width, int height)

View File

@@ -39,15 +39,15 @@ namespace OpenRA
public readonly Actor Subject;
public readonly bool Queued;
public Actor TargetActor;
public int2 TargetLocation;
public CPos TargetLocation;
public string TargetString;
public int2 ExtraLocation;
public CPos ExtraLocation;
public bool IsImmediate;
public Player Player { get { return Subject.Owner; } }
Order(string orderString, Actor subject,
Actor targetActor, int2 targetLocation, string targetString, bool queued, int2 extraLocation)
Actor targetActor, CPos targetLocation, string targetString, bool queued, CPos extraLocation)
{
this.OrderString = orderString;
this.Subject = subject;
@@ -60,10 +60,10 @@ namespace OpenRA
// For scripting special powers
public Order()
: this(null, null, null, int2.Zero, null, false, int2.Zero) { }
: this(null, null, null, CPos.Zero, null, false, CPos.Zero) { }
public Order(string orderString, Actor subject, bool queued)
: this(orderString, subject, null, int2.Zero, null, queued, int2.Zero) { }
: this(orderString, subject, null, CPos.Zero, null, queued, CPos.Zero) { }
public Order(string orderstring, Order order)
: this(orderstring, order.Subject, order.TargetActor, order.TargetLocation,
@@ -98,21 +98,21 @@ namespace OpenRA
OrderFields fields = 0;
if (TargetActor != null) fields |= OrderFields.TargetActor;
if (TargetLocation != int2.Zero) fields |= OrderFields.TargetLocation;
if (TargetLocation != CPos.Zero) fields |= OrderFields.TargetLocation;
if (TargetString != null) fields |= OrderFields.TargetString;
if (Queued) fields |= OrderFields.Queued;
if (ExtraLocation != int2.Zero) fields |= OrderFields.ExtraLocation;
if (ExtraLocation != CPos.Zero) fields |= OrderFields.ExtraLocation;
w.Write((byte)fields);
if (TargetActor != null)
w.Write(UIntFromActor(TargetActor));
if (TargetLocation != int2.Zero)
w.Write(TargetLocation);
if (TargetLocation != CPos.Zero)
w.Write(TargetLocation.ToInt2());
if (TargetString != null)
w.Write(TargetString);
if (ExtraLocation != int2.Zero)
w.Write(ExtraLocation);
if (ExtraLocation != CPos.Zero)
w.Write(ExtraLocation.ToInt2());
return ret.ToArray();
}
@@ -130,10 +130,10 @@ namespace OpenRA
var flags = (OrderFields)r.ReadByte();
var targetActorId = flags.HasField(OrderFields.TargetActor) ? r.ReadUInt32() : 0xffffffff;
var targetLocation = flags.HasField(OrderFields.TargetLocation) ? r.ReadInt2() : int2.Zero;
var targetLocation = (CPos)( flags.HasField(OrderFields.TargetLocation) ? r.ReadInt2() : int2.Zero );
var targetString = flags.HasField(OrderFields.TargetString) ? r.ReadString() : null;
var queued = flags.HasField(OrderFields.Queued);
var extraLocation = flags.HasField(OrderFields.ExtraLocation) ? r.ReadInt2() : int2.Zero;
var extraLocation = (CPos)(flags.HasField(OrderFields.ExtraLocation) ? r.ReadInt2() : int2.Zero);
Actor subject, targetActor;
if( !TryGetActorFromUInt( world, subjectId, out subject ) || !TryGetActorFromUInt( world, targetActorId, out targetActor ) )
@@ -199,7 +199,18 @@ namespace OpenRA
{
return new Order("HandshakeResponse", null, false) { IsImmediate = true, TargetString = text };
}
public static Order PauseRequest()
{
return new Order("PauseRequest", null, false) { IsImmediate = true, TargetString="" }; //TODO: targetbool?
}
public static Order PauseGame()
{
return new Order("PauseGame", null, false) { IsImmediate = true, TargetString=""}; //TODO: targetbool?
}
public static Order Command(string text)
{
return new Order("Command", null, false) { IsImmediate = true, TargetString = text };
@@ -207,17 +218,17 @@ namespace OpenRA
public static Order StartProduction(Actor subject, string item, int count)
{
return new Order("StartProduction", subject, false) { TargetLocation = new int2(count, 0), TargetString = item };
return new Order("StartProduction", subject, false) { TargetLocation = new CPos(count, 0), TargetString = item };
}
public static Order PauseProduction(Actor subject, string item, bool pause)
{
return new Order("PauseProduction", subject, false) { TargetLocation = new int2(pause ? 1 : 0, 0), TargetString = item };
return new Order("PauseProduction", subject, false) { TargetLocation = new CPos(pause ? 1 : 0, 0), TargetString = item };
}
public static Order CancelProduction(Actor subject, string item, int count)
{
return new Order("CancelProduction", subject, false) { TargetLocation = new int2(count, 0), TargetString = item };
return new Order("CancelProduction", subject, false) { TargetLocation = new CPos(count, 0), TargetString = item };
}
}
}

View File

@@ -36,6 +36,7 @@ namespace OpenRA.Network
public int LastTickTime = Environment.TickCount;
public bool GameStarted { get { return NetFrameNumber != 0; } }
public bool GamePaused {get; set;}
public IConnection Connection { get; private set; }
public readonly int SyncHeaderSize = 9;

View File

@@ -70,6 +70,7 @@ namespace OpenRA.Network
{
public string ServerName;
public string Map;
public string[] Ban;
public string[] Mods = { "ra" }; // mod names
public int OrderLatency = 3;
public int RandomSeed = 0;

View File

@@ -94,6 +94,19 @@ namespace OpenRA.Network
Game.StartGame(orderManager.LobbyInfo.GlobalSettings.Map, false);
break;
}
case "PauseGame":
{
var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
if(client != null)
{
orderManager.GamePaused = !orderManager.GamePaused;
var pausetext = "The game is {0} by {1}".F( orderManager.GamePaused ? "paused" : "un-paused", client.Name );
Game.AddChatLine(Color.White, "", pausetext);
}
break;
}
case "HandshakeRequest":
{

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
@@ -12,9 +12,12 @@
<AssemblyName>OpenRA.Game</AssemblyName>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>2.0</OldToolsVersion>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<IsWebBootstrapper>false</IsWebBootstrapper>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<ApplicationIcon>OpenRA.ico</ApplicationIcon>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
@@ -27,11 +30,8 @@
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<ApplicationIcon>OpenRA.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
@@ -44,6 +44,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>bin\Release\</OutputPath>
@@ -55,6 +56,7 @@
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@@ -78,6 +80,11 @@
<Compile Include="ActorInitializer.cs" />
<Compile Include="ActorMap.cs" />
<Compile Include="ActorReference.cs" />
<Compile Include="PSubVec.cs" />
<Compile Include="PSubPos.cs" />
<Compile Include="PVecInt.cs" />
<Compile Include="PVecFloat.cs" />
<Compile Include="PPos.cs" />
<Compile Include="Download.cs" />
<Compile Include="Effects\DelayedAction.cs" />
<Compile Include="Effects\FlashTarget.cs" />
@@ -114,6 +121,8 @@
<Compile Include="Graphics\WorldRenderer.cs" />
<Compile Include="Group.cs" />
<Compile Include="InputHandler.cs" />
<Compile Include="CVec.cs" />
<Compile Include="CPos.cs" />
<Compile Include="Map.cs" />
<Compile Include="ModData.cs" />
<Compile Include="Network\Connection.cs" />
@@ -142,6 +151,7 @@
<Compile Include="Server\Server.cs" />
<Compile Include="Server\ServerOrder.cs" />
<Compile Include="Server\TraitInterfaces.cs" />
<Compile Include="Server\UPnP.cs" />
<Compile Include="Sound.cs" />
<Compile Include="Support\Arguments.cs" />
<Compile Include="Support\PerfHistory.cs" />
@@ -214,6 +224,11 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
<Visible>False</Visible>
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
@@ -229,6 +244,11 @@
<ProductName>.NET Framework 3.5</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Content Include="OpenRA.ico" />

View File

@@ -48,14 +48,14 @@ namespace OpenRA.Orders
}
public IEnumerable<Order> Order(World world, int2 xy, MouseInput mi)
public IEnumerable<Order> Order(World world, CPos xy, MouseInput mi)
{
if (mi.Button != expectedButton)
world.CancelInputMode();
return OrderInner(world, xy, mi);
}
IEnumerable<Order> OrderInner(World world, int2 xy, MouseInput mi)
IEnumerable<Order> OrderInner(World world, CPos xy, MouseInput mi)
{
if (mi.Button == expectedButton && world.Map.IsInMap(xy))
{
@@ -68,6 +68,6 @@ namespace OpenRA.Orders
public virtual void Tick(World world) { }
public void RenderBeforeWorld(WorldRenderer wr, World world) { }
public void RenderAfterWorld(WorldRenderer wr, World world) { }
public string GetCursor(World world, int2 xy, MouseInput mi) { return world.Map.IsInMap(xy) ? cursor : "generic-blocked"; }
public string GetCursor(World world, CPos xy, MouseInput mi) { return world.Map.IsInMap(xy) ? cursor : "generic-blocked"; }
}
}

View File

@@ -15,10 +15,10 @@ namespace OpenRA
{
public interface IOrderGenerator
{
IEnumerable<Order> Order(World world, int2 xy, MouseInput mi);
IEnumerable<Order> Order(World world, CPos xy, MouseInput mi);
void Tick(World world);
void RenderBeforeWorld(WorldRenderer wr, World world);
void RenderAfterWorld(WorldRenderer wr, World world);
string GetCursor(World world, int2 xy, MouseInput mi);
string GetCursor(World world, CPos xy, MouseInput mi);
}
}

View File

@@ -17,7 +17,7 @@ namespace OpenRA.Orders
{
class UnitOrderGenerator : IOrderGenerator
{
public IEnumerable<Order> Order( World world, int2 xy, MouseInput mi )
public IEnumerable<Order> Order( World world, CPos xy, MouseInput mi )
{
var underCursor = world.FindUnitsAtMouse(mi.Location)
.Where(a => a.HasTrait<ITargetable>())
@@ -45,7 +45,7 @@ namespace OpenRA.Orders
public void RenderBeforeWorld( WorldRenderer wr, World world ) { }
public void RenderAfterWorld( WorldRenderer wr, World world ) { }
public string GetCursor( World world, int2 xy, MouseInput mi )
public string GetCursor(World world, CPos xy, MouseInput mi)
{
bool useSelect = false;
@@ -63,12 +63,11 @@ namespace OpenRA.Orders
.Where(o => o != null)
.ToArray();
if( orders.Length == 0 ) return (useSelect) ? "select" : "default";
return orders[0].cursor ?? ((useSelect) ? "select" : "default");
var cursorName = orders.Select(o => o.cursor).FirstOrDefault();
return cursorName ?? (useSelect ? "select" : "default");
}
static UnitOrderResult OrderForUnit( Actor self, int2 xy, MouseInput mi, Actor underCursor )
static UnitOrderResult OrderForUnit(Actor self, CPos xy, MouseInput mi, Actor underCursor)
{
if (self.Owner != self.World.LocalPlayer)
return null;

71
OpenRA.Game/PPos.cs Normal file
View File

@@ -0,0 +1,71 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 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. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Drawing;
namespace OpenRA
{
/// <summary>
/// Pixel coordinate position in the world (fine).
/// </summary>
public struct PPos
{
public readonly int X, Y;
public PPos(int x, int y) { X = x; Y = y; }
public static readonly PPos Zero = new PPos(0, 0);
public static explicit operator PPos(int2 a) { return new PPos(a.X, a.Y); }
public static explicit operator PVecInt(PPos a) { return new PVecInt(a.X, a.Y); }
public static explicit operator PVecFloat(PPos a) { return new PVecFloat(a.X, a.Y); }
public static PPos operator +(PPos a, PVecInt b) { return new PPos(a.X + b.X, a.Y + b.Y); }
public static PVecInt operator -(PPos a, PPos b) { return new PVecInt(a.X - b.X, a.Y - b.Y); }
public static PPos operator -(PPos a, PVecInt b) { return new PPos(a.X - b.X, a.Y - b.Y); }
public static bool operator ==(PPos me, PPos other) { return (me.X == other.X && me.Y == other.Y); }
public static bool operator !=(PPos me, PPos other) { return !(me == other); }
public static PPos Max(PPos a, PPos b) { return new PPos(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
public static PPos Min(PPos a, PPos b) { return new PPos(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
public static PPos Lerp(PPos a, PPos b, int mul, int div)
{
return a + ((PVecInt)(b - a) * mul / div);
}
public float2 ToFloat2() { return new float2(X, Y); }
public int2 ToInt2() { return new int2(X, Y); }
public CPos ToCPos() { return new CPos((int)(1f / Game.CellSize * X), (int)(1f / Game.CellSize * Y)); }
public PSubPos ToPSubPos() { return new PSubPos(X * PSubPos.PerPx, Y * PSubPos.PerPx); }
public PPos Clamp(Rectangle r)
{
return new PPos(Math.Min(r.Right, Math.Max(X, r.Left)),
Math.Min(r.Bottom, Math.Max(Y, r.Top)));
}
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
public override bool Equals(object obj)
{
if (obj == null)
return false;
PPos o = (PPos)obj;
return o == this;
}
public override string ToString() { return "{0},{1}".F(X, Y); }
}
}

73
OpenRA.Game/PSubPos.cs Normal file
View File

@@ -0,0 +1,73 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 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. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Drawing;
namespace OpenRA
{
/// <summary>
/// Sub-pixel coordinate position in the world (very fine).
/// </summary>
public struct PSubPos
{
public readonly int X, Y;
public PSubPos(int x, int y) { X = x; Y = y; }
public const int PerPx = 1024;
public static readonly PSubPos Zero = new PSubPos(0, 0);
public static explicit operator PSubPos(int2 a) { return new PSubPos(a.X, a.Y); }
public static explicit operator PSubVec(PSubPos a) { return new PSubVec(a.X, a.Y); }
public static explicit operator PVecFloat(PSubPos a) { return new PVecFloat(a.X, a.Y); }
public static PSubPos operator +(PSubPos a, PSubVec b) { return new PSubPos(a.X + b.X, a.Y + b.Y); }
public static PSubVec operator -(PSubPos a, PSubPos b) { return new PSubVec(a.X - b.X, a.Y - b.Y); }
public static PSubPos operator -(PSubPos a, PSubVec b) { return new PSubPos(a.X - b.X, a.Y - b.Y); }
public static bool operator ==(PSubPos me, PSubPos other) { return (me.X == other.X && me.Y == other.Y); }
public static bool operator !=(PSubPos me, PSubPos other) { return !(me == other); }
public static PSubPos Max(PSubPos a, PSubPos b) { return new PSubPos(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
public static PSubPos Min(PSubPos a, PSubPos b) { return new PSubPos(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
public static PSubPos Lerp(PSubPos a, PSubPos b, int mul, int div)
{
return a + ((PSubVec)(b - a) * mul / div);
}
public float2 ToFloat2() { return new float2(X, Y); }
public int2 ToInt2() { return new int2(X, Y); }
public PPos ToPPos() { return new PPos(X / PerPx, Y / PerPx); }
public CPos ToCPos() { return ToPPos().ToCPos(); }
public PSubPos Clamp(Rectangle r)
{
return new PSubPos(Math.Min(r.Right, Math.Max(X, r.Left)),
Math.Min(r.Bottom, Math.Max(Y, r.Top)));
}
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
public override bool Equals(object obj)
{
if (obj == null)
return false;
PSubPos o = (PSubPos)obj;
return o == this;
}
public override string ToString() { return "{0},{1}".F(X, Y); }
}
}

103
OpenRA.Game/PSubVec.cs Normal file
View File

@@ -0,0 +1,103 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 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. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Drawing;
namespace OpenRA
{
/// <summary>
/// Sub-pixel coordinate vector (very fine)
/// </summary>
public struct PSubVec
{
public readonly int X, Y;
public PSubVec(int x, int y) { X = x; Y = y; }
public PSubVec(Size p) { X = p.Width; Y = p.Height; }
public static readonly PSubVec Zero = new PSubVec(0, 0);
public static PSubVec OneCell { get { return new PSubVec(Game.CellSize, Game.CellSize); } }
public static explicit operator PSubVec(int2 a) { return new PSubVec(a.X, a.Y); }
public static explicit operator PSubVec(float2 a) { return new PSubVec((int)a.X, (int)a.Y); }
public static PSubVec FromRadius(int r) { return new PSubVec(r, r); }
public static PSubVec operator +(PSubVec a, PSubVec b) { return new PSubVec(a.X + b.X, a.Y + b.Y); }
public static PSubVec operator -(PSubVec a, PSubVec b) { return new PSubVec(a.X - b.X, a.Y - b.Y); }
public static PSubVec operator *(int a, PSubVec b) { return new PSubVec(a * b.X, a * b.Y); }
public static PSubVec operator *(PSubVec b, int a) { return new PSubVec(a * b.X, a * b.Y); }
public static PSubVec operator /(PSubVec a, int b) { return new PSubVec(a.X / b, a.Y / b); }
public static PSubVec operator -(PSubVec a) { return new PSubVec(-a.X, -a.Y); }
public static bool operator ==(PSubVec me, PSubVec other) { return (me.X == other.X && me.Y == other.Y); }
public static bool operator !=(PSubVec me, PSubVec other) { return !(me == other); }
public static PSubVec Max(PSubVec a, PSubVec b) { return new PSubVec(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
public static PSubVec Min(PSubVec a, PSubVec b) { return new PSubVec(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
public static int Dot(PSubVec a, PSubVec b) { return a.X * b.X + a.Y * b.Y; }
public PSubVec Sign() { return new PSubVec(Math.Sign(X), Math.Sign(Y)); }
public PSubVec Abs() { return new PSubVec(Math.Abs(X), Math.Abs(Y)); }
public int LengthSquared { get { return X * X + Y * Y; } }
public int Length { get { return (int)Math.Sqrt(LengthSquared); } }
public float2 ToFloat2() { return new float2(X, Y); }
public int2 ToInt2() { return new int2(X, Y); }
public PVecInt ToPVecInt() { return new PVecInt(X / PSubPos.PerPx, Y / PSubPos.PerPx); }
public PSubVec Clamp(Rectangle r)
{
return new PSubVec(
Math.Min(r.Right, Math.Max(X, r.Left)),
Math.Min(r.Bottom, Math.Max(Y, r.Top))
);
}
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
public override bool Equals(object obj)
{
if (obj == null)
return false;
PSubVec o = (PSubVec)obj;
return o == this;
}
public override string ToString() { return "{0},{1}".F(X, Y); }
}
public static class PSubVecExtensions
{
/// <summary>
/// Scales the float2 vector up to a subpixel vector.
/// </summary>
/// <param name="vec"></param>
/// <returns></returns>
public static PSubVec ToPSubVec(this float2 vec)
{
return new PSubVec((int)(vec.X * PSubPos.PerPx), (int)(vec.Y * PSubPos.PerPx));
}
public static PSubVec ToPSubVec(this PVecInt vec)
{
return new PSubVec((vec.X * PSubPos.PerPx), (vec.Y * PSubPos.PerPx));
}
public static PSubVec ToPSubVec(this PVecFloat vec)
{
return new PSubVec((int)(vec.X * PSubPos.PerPx), (int)(vec.Y * PSubPos.PerPx));
}
}
}

97
OpenRA.Game/PVecFloat.cs Normal file
View File

@@ -0,0 +1,97 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 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. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Drawing;
namespace OpenRA
{
/// <summary>
/// Pixel coordinate vector (fine; float)
/// </summary>
public struct PVecFloat
{
public readonly float X, Y;
public PVecFloat(float x, float y) { X = x; Y = y; }
public PVecFloat(Size p) { X = p.Width; Y = p.Height; }
public static readonly PVecFloat Zero = new PVecFloat(0, 0);
public static explicit operator PVecInt(PVecFloat a) { return new PVecInt((int)a.X, (int)a.Y); }
public static explicit operator PVecFloat(float2 a) { return new PVecFloat(a.X, a.Y); }
public static PVecFloat operator +(PVecFloat a, PVecFloat b) { return new PVecFloat(a.X + b.X, a.Y + b.Y); }
public static PVecFloat operator -(PVecFloat a, PVecFloat b) { return new PVecFloat(a.X - b.X, a.Y - b.Y); }
public static PVecFloat operator *(float a, PVecFloat b) { return new PVecFloat(a * b.X, a * b.Y); }
public static PVecFloat operator *(PVecFloat b, float a) { return new PVecFloat(a * b.X, a * b.Y); }
public static PVecFloat operator /(PVecFloat a, float b) { return new PVecFloat(a.X / b, a.Y / b); }
public static PVecFloat operator -(PVecFloat a) { return new PVecFloat(-a.X, -a.Y); }
public static bool operator ==(PVecFloat me, PVecFloat other) { return (me.X == other.X && me.Y == other.Y); }
public static bool operator !=(PVecFloat me, PVecFloat other) { return !(me == other); }
public static PVecFloat Max(PVecFloat a, PVecFloat b) { return new PVecFloat(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
public static PVecFloat Min(PVecFloat a, PVecFloat b) { return new PVecFloat(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
public static float Dot(PVecFloat a, PVecFloat b) { return a.X * b.X + a.Y * b.Y; }
public static PVecFloat FromAngle(float a) { return new PVecFloat((float)Math.Sin(a), (float)Math.Cos(a)); }
public static PVecFloat Lerp(PVecFloat a, PVecFloat b, float t)
{
return new PVecFloat(
float2.Lerp(a.X, b.X, t),
float2.Lerp(a.Y, b.Y, t)
);
}
public static PVecFloat Lerp(PVecFloat a, PVecFloat b, PVecFloat t)
{
return new PVecFloat(
float2.Lerp(a.X, b.X, t.X),
float2.Lerp(a.Y, b.Y, t.Y)
);
}
public PVecFloat Sign() { return new PVecFloat(Math.Sign(X), Math.Sign(Y)); }
public PVecFloat Abs() { return new PVecFloat(Math.Abs(X), Math.Abs(Y)); }
public PVecFloat Round() { return new PVecFloat((float)Math.Round(X), (float)Math.Round(Y)); }
public float LengthSquared { get { return X * X + Y * Y; } }
public float Length { get { return (float)Math.Sqrt(LengthSquared); } }
public float2 ToFloat2() { return new float2(X, Y); }
public int2 ToInt2() { return new int2((int)X, (int)Y); }
static float Constrain(float x, float a, float b) { return x < a ? a : x > b ? b : x; }
public PVecFloat Constrain(PVecFloat min, PVecFloat max)
{
return new PVecFloat(
Constrain(X, min.X, max.X),
Constrain(Y, min.Y, max.Y)
);
}
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
public override bool Equals(object obj)
{
if (obj == null)
return false;
PVecFloat o = (PVecFloat)obj;
return o == this;
}
public override string ToString() { return "({0},{1})".F(X, Y); }
}
}

80
OpenRA.Game/PVecInt.cs Normal file
View File

@@ -0,0 +1,80 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 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. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Drawing;
namespace OpenRA
{
/// <summary>
/// Pixel coordinate vector (fine; integer)
/// </summary>
public struct PVecInt
{
public readonly int X, Y;
public PVecInt(int x, int y) { X = x; Y = y; }
public PVecInt(Size p) { X = p.Width; Y = p.Height; }
public static readonly PVecInt Zero = new PVecInt(0, 0);
public static PVecInt OneCell { get { return new PVecInt(Game.CellSize, Game.CellSize); } }
public static implicit operator PVecFloat(PVecInt a) { return new PVecFloat((float)a.X, (float)a.Y); }
public static explicit operator PVecInt(int2 a) { return new PVecInt(a.X, a.Y); }
public static PVecInt FromRadius(int r) { return new PVecInt(r, r); }
public static PVecInt operator +(PVecInt a, PVecInt b) { return new PVecInt(a.X + b.X, a.Y + b.Y); }
public static PVecInt operator -(PVecInt a, PVecInt b) { return new PVecInt(a.X - b.X, a.Y - b.Y); }
public static PVecInt operator *(int a, PVecInt b) { return new PVecInt(a * b.X, a * b.Y); }
public static PVecInt operator *(PVecInt b, int a) { return new PVecInt(a * b.X, a * b.Y); }
public static PVecInt operator /(PVecInt a, int b) { return new PVecInt(a.X / b, a.Y / b); }
public static PVecInt operator -(PVecInt a) { return new PVecInt(-a.X, -a.Y); }
public static bool operator ==(PVecInt me, PVecInt other) { return (me.X == other.X && me.Y == other.Y); }
public static bool operator !=(PVecInt me, PVecInt other) { return !(me == other); }
public static PVecInt Max(PVecInt a, PVecInt b) { return new PVecInt(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
public static PVecInt Min(PVecInt a, PVecInt b) { return new PVecInt(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
public static int Dot(PVecInt a, PVecInt b) { return a.X * b.X + a.Y * b.Y; }
public PVecInt Sign() { return new PVecInt(Math.Sign(X), Math.Sign(Y)); }
public PVecInt Abs() { return new PVecInt(Math.Abs(X), Math.Abs(Y)); }
public int LengthSquared { get { return X * X + Y * Y; } }
public int Length { get { return (int)Math.Sqrt(LengthSquared); } }
public float2 ToFloat2() { return new float2(X, Y); }
public int2 ToInt2() { return new int2(X, Y); }
public CVec ToCVec() { return new CVec(X / Game.CellSize, Y / Game.CellSize); }
public PVecInt Clamp(Rectangle r)
{
return new PVecInt(
Math.Min(r.Right, Math.Max(X, r.Left)),
Math.Min(r.Bottom, Math.Max(Y, r.Top))
);
}
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
public override bool Equals(object obj)
{
if (obj == null)
return false;
PVecInt o = (PVecInt)obj;
return o == this;
}
public override string ToString() { return "{0},{1}".F(X, Y); }
}
}

View File

@@ -44,6 +44,11 @@ namespace OpenRA.Server
{
try
{
// NOTE(jsd): Poll the socket first to see if there's anything there.
// This avoids the exception with SocketErrorCode == `SocketError.WouldBlock` thrown
// from `socket.Receive(rx)`.
if (!socket.Poll(0, SelectMode.SelectRead)) break;
if (0 < (len = socket.Receive(rx)))
data.AddRange(rx.Take(len));
else
@@ -52,11 +57,12 @@ namespace OpenRA.Server
server.DropClient(this);
break;
}
}
catch (SocketException e)
{
// NOTE(jsd): This should no longer be needed with the socket.Poll call above.
if (e.SocketErrorCode == SocketError.WouldBlock) break;
server.DropClient(this);
return false;
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2012 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. For more information,
@@ -15,11 +15,15 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using UPnP;
using System.Threading;
using OpenRA.FileFormats;
using OpenRA.GameRules;
using OpenRA.Network;
using XTimer = System.Timers.Timer;
namespace OpenRA.Server
{
public class Server
@@ -45,6 +49,7 @@ namespace OpenRA.Server
public ServerSettings Settings;
public ModData ModData;
public Map Map;
XTimer gameTimeout;
volatile bool shutdown = false;
public void Shutdown() { shutdown = true; }
@@ -64,6 +69,9 @@ namespace OpenRA.Server
randomSeed = (int)DateTime.Now.ToBinary();
if (settings.AllowUPnP)
PortForward();
foreach (var trait in modData.Manifest.ServerTraits)
ServerTraits.Add( modData.ObjectCreator.CreateObject<ServerTrait>(trait) );
@@ -71,6 +79,7 @@ namespace OpenRA.Server
lobbyInfo.GlobalSettings.RandomSeed = randomSeed;
lobbyInfo.GlobalSettings.Map = settings.Map;
lobbyInfo.GlobalSettings.ServerName = settings.Name;
lobbyInfo.GlobalSettings.Ban = settings.Ban;
foreach (var t in ServerTraits.WithInterface<INotifyServerStart>())
t.ServerStarted(this);
@@ -122,6 +131,20 @@ namespace OpenRA.Server
} ) { IsBackground = true }.Start();
}
void PortForward()
{
if (UPnP.NAT.Discover())
{
Log.Write("server", "UPnP-enabled router discovered.");
UPnP.NAT.ForwardPort(Port, ProtocolType.Tcp, "OpenRA"); //might timeout after second try
Log.Write("server", "Port {0} (TCP) has been forwarded.", Port);
Log.Write("server", "Your IP is: {0}", UPnP.NAT.GetExternalIP() );
}
else
Log.Write("server", "No UPnP-enabled router detected.");
return;
}
/* lobby rework todo:
* - "teams together" option for team games -- will eliminate most need
* for manual spawnpoint choosing.
@@ -205,6 +228,21 @@ namespace OpenRA.Server
return;
}
// Check if IP is banned
if (lobbyInfo.GlobalSettings.Ban != null)
{
var remote_addr = ((IPEndPoint)newConn.socket.RemoteEndPoint).Address.ToString();
if (lobbyInfo.GlobalSettings.Ban.Contains(remote_addr))
{
Console.WriteLine("Rejected connection from "+client.Name+"("+newConn.socket.RemoteEndPoint+"); Banned.");
Log.Write("server", "Rejected connection from {0}; Banned.",
newConn.socket.RemoteEndPoint);
SendOrderTo(newConn, "ServerError", "You are banned from the server!");
DropClient(newConn);
return;
}
}
// Promote connection to a valid client
preConns.Remove(newConn);
conns.Add(newConn);
@@ -332,6 +370,9 @@ namespace OpenRA.Server
void InterpretServerOrder(Connection conn, ServerOrder so)
{
var fromClient = GetClient(conn);
var fromIndex = fromClient != null ? fromClient.Index : 0;
switch (so.Name)
{
case "Command":
@@ -347,17 +388,23 @@ namespace OpenRA.Server
}
break;
case "HandshakeResponse":
ValidateClient(conn, so.Data);
break;
case "Chat":
case "TeamChat":
var fromClient = GetClient(conn);
var fromIndex = fromClient != null ? fromClient.Index : 0;
foreach (var c in conns.Except(conn).ToArray())
DispatchOrdersToClient(c, fromIndex, 0, so.Serialize());
break;
break;
case "PauseRequest":
foreach (var c in conns.ToArray())
{ var x = Order.PauseGame();
DispatchOrdersToClient(c, fromIndex, 0, x.Serialize());
}
break;
}
}
@@ -406,6 +453,9 @@ namespace OpenRA.Server
public void StartGame()
{
GameStarted = true;
listener.Stop();
Console.WriteLine("Game started");
foreach( var c in conns )
foreach( var d in conns )
DispatchOrdersToClient( c, d.PlayerIndex, 0x7FFFFFFF, new byte[] { 0xBF } );
@@ -419,6 +469,18 @@ namespace OpenRA.Server
foreach (var t in ServerTraits.WithInterface<IStartGame>())
t.GameStarted(this);
// Check TimeOut
if ( Settings.TimeOut > 10000 )
{
gameTimeout = new XTimer(Settings.TimeOut);
gameTimeout.Elapsed += (_,e) =>
{
Console.WriteLine("Timeout at {0}!!!", e.SignalTime);
Environment.Exit(0);
};
gameTimeout.Enabled = true;
}
}
}
}

137
OpenRA.Game/Server/UPnP.cs Normal file
View File

@@ -0,0 +1,137 @@
#region Copyright & License Information
/*
* Copyright 2008-2009 http://www.codeproject.com/Members/Harold-Aptroot
* Source: http://www.codeproject.com/Articles/27992/NAT-Traversal-with-UPnP-in-C
* This file is licensed under A Public Domain dedication.
* For more information, see http://creativecommons.org/licenses/publicdomain/
*/
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Xml;
using System.IO;
namespace UPnP
{
public class NAT
{
public static TimeSpan _timeout = new TimeSpan(0, 0, 0, 3);
static string _serviceUrl;
public static bool Discover()
{
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
string req = "M-SEARCH * HTTP/1.1\r\n" +
"HOST: 239.255.255.250:1900\r\n" +
"ST:upnp:rootdevice\r\n" +
"MAN:\"ssdp:discover\"\r\n" +
"MX:3\r\n\r\n";
byte[] data = Encoding.ASCII.GetBytes(req);
IPEndPoint ipe = new IPEndPoint(IPAddress.Broadcast, 1900);
byte[] buffer = new byte[0x1000];
DateTime start = DateTime.Now;
do
{
s.SendTo(data, ipe);
int length = 0;
do
{
length = s.Receive(buffer);
string resp = Encoding.ASCII.GetString(buffer, 0, length).ToLower();
if (resp.Contains("upnp:rootdevice"))
{
resp = resp.Substring(resp.ToLower().IndexOf("location:") + 9);
resp = resp.Substring(0, resp.IndexOf("\r")).Trim();
if (!string.IsNullOrEmpty(_serviceUrl = GetServiceUrl(resp)))
return true;
}
} while (length > 0);
} while ((start - DateTime.Now) < _timeout);
return false;
}
private static String GetServiceUrl(string resp)
{
XmlDocument desc = new XmlDocument();
desc.Load(WebRequest.Create(resp).GetResponse().GetResponseStream());
XmlNamespaceManager nsMgr = new XmlNamespaceManager(desc.NameTable);
nsMgr.AddNamespace("tns", "urn:schemas-upnp-org:device-1-0");
XmlNode typen = desc.SelectSingleNode("//tns:device/tns:deviceType/text()", nsMgr);
if (!typen.Value.Contains("InternetGatewayDevice"))
return null;
XmlNode node = desc.SelectSingleNode("//tns:service[tns:serviceType=\"urn:schemas-upnp-org:service:WANIPConnection:1\"]/tns:controlURL/text()", nsMgr);
if (node == null)
return null;
Uri respUri = new Uri(resp);
Uri combinedUri = new Uri(respUri, node.Value);
return combinedUri.AbsoluteUri;
}
public static void ForwardPort(int port, ProtocolType protocol, string description)
{
if (string.IsNullOrEmpty(_serviceUrl))
throw new Exception("No UPnP service available or Discover() has not been called");
string body = String.Format("<u:AddPortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">"+
"<NewRemoteHost></NewRemoteHost><NewExternalPort>{0}</NewExternalPort>"+
"<NewProtocol>{1}</NewProtocol><NewInternalPort>{0}</NewInternalPort>" +
"<NewInternalClient>{2}</NewInternalClient><NewEnabled>1</NewEnabled>" +
"<NewPortMappingDescription>{3}</NewPortMappingDescription>"+
"<NewLeaseDuration>0</NewLeaseDuration></u:AddPortMapping>",
port, protocol.ToString().ToUpper(),Dns.GetHostAddresses(Dns.GetHostName())[0], description);
SOAPRequest(_serviceUrl, body, "AddPortMapping");
}
public static void DeleteForwardingRule(int port, ProtocolType protocol)
{
if (string.IsNullOrEmpty(_serviceUrl))
throw new Exception("No UPnP service available or Discover() has not been called");
string body = String.Format("<u:DeletePortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" +
"<NewRemoteHost></NewRemoteHost><NewExternalPort>{0}</NewExternalPort>"+
"<NewProtocol>{1}</NewProtocol></u:DeletePortMapping>", port, protocol.ToString().ToUpper() );
SOAPRequest(_serviceUrl, body, "DeletePortMapping");
}
public static IPAddress GetExternalIP()
{
if (string.IsNullOrEmpty(_serviceUrl))
throw new Exception("No UPnP service available or Discover() has not been called");
XmlDocument xdoc = SOAPRequest(_serviceUrl, "<u:GetExternalIPAddress xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" +
"</u:GetExternalIPAddress>", "GetExternalIPAddress");
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xdoc.NameTable);
nsMgr.AddNamespace("tns", "urn:schemas-upnp-org:device-1-0");
string IP = xdoc.SelectSingleNode("//NewExternalIPAddress/text()", nsMgr).Value;
return IPAddress.Parse(IP);
}
private static XmlDocument SOAPRequest(string url, string soap, string function)
{
string req = "<?xml version=\"1.0\"?>" +
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" +
"<s:Body>" +
soap +
"</s:Body>" +
"</s:Envelope>";
WebRequest r = HttpWebRequest.Create(url);
r.Method = "POST";
byte[] b = Encoding.UTF8.GetBytes(req);
r.Headers.Add("SOAPACTION", "\"urn:schemas-upnp-org:service:WANIPConnection:1#" + function + "\"");
r.ContentType = "text/xml; charset=\"utf-8\"";
r.ContentLength = b.Length;
r.GetRequestStream().Write(b, 0, b.Length);
XmlDocument resp = new XmlDocument();
WebResponse wres = r.GetResponse();
Stream ress = wres.GetResponseStream();
resp.Load(ress);
return resp;
}
}
}

View File

@@ -64,7 +64,7 @@ namespace OpenRA
public static void SetListenerPosition(float2 position) { soundEngine.SetListenerPosition(position); }
static ISound Play(Player player, string name, bool headRelative, float2 pos, float volumeModifier)
static ISound Play(Player player, string name, bool headRelative, PPos pos, float volumeModifier)
{
if (player != null && player != player.World.LocalPlayer)
return null;
@@ -72,16 +72,16 @@ namespace OpenRA
return null;
return soundEngine.Play2D(sounds[name],
false, headRelative, pos,
false, headRelative, pos.ToFloat2(),
InternalSoundVolume * volumeModifier);
}
public static ISound Play(string name) { return Play(null, name, true, float2.Zero, 1); }
public static ISound Play(string name, float2 pos) { return Play(null, name, false, pos, 1); }
public static ISound Play(string name, float volumeModifier) { return Play(null, name, true, float2.Zero, volumeModifier); }
public static ISound Play(string name, float2 pos, float volumeModifier) { return Play(null, name, false, pos, volumeModifier); }
public static ISound PlayToPlayer(Player player, string name) { return Play( player, name, true, float2.Zero, 1); }
public static ISound PlayToPlayer(Player player, string name, float2 pos) { return Play(player, name, false, pos, 1); }
public static ISound Play(string name) { return Play(null, name, true, PPos.Zero, 1); }
public static ISound Play(string name, PPos pos) { return Play(null, name, false, pos, 1); }
public static ISound Play(string name, float volumeModifier) { return Play(null, name, true, PPos.Zero, volumeModifier); }
public static ISound Play(string name, PPos pos, float volumeModifier) { return Play(null, name, false, pos, volumeModifier); }
public static ISound PlayToPlayer(Player player, string name) { return Play(player, name, true, PPos.Zero, 1); }
public static ISound PlayToPlayer(Player player, string name, PPos pos) { return Play(player, name, false, pos, 1); }
public static void PlayVideo(byte[] raw)
{
@@ -259,7 +259,9 @@ namespace OpenRA
var variantExt = (vi.Variants.ContainsKey(variant) && !vi.DisableVariants.Contains(phrase)) ?
vi.Variants[variant][voicedUnit.ActorID % vi.Variants[variant].Length] : vi.DefaultVariant;
Play(clip + variantExt);
var prefix = (vi.Prefixes.ContainsKey(variant) && !vi.DisablePrefixes.Contains(phrase)) ?
vi.Prefixes[variant][voicedUnit.ActorID % vi.Prefixes[variant].Length] : vi.DefaultPrefix;
Play(prefix + clip + variantExt);
return true;
}
}

View File

@@ -50,6 +50,36 @@ namespace OpenRA
il.EmitCall(OpCodes.Call, ((Func<int2, int>)hash_int2).Method, null);
il.Emit(OpCodes.Xor);
}
else if (type == typeof(CPos))
{
il.EmitCall(OpCodes.Call, ((Func<CPos, int>)hash_CPos).Method, null);
il.Emit(OpCodes.Xor);
}
else if (type == typeof(CVec))
{
il.EmitCall(OpCodes.Call, ((Func<CVec, int>)hash_CVec).Method, null);
il.Emit(OpCodes.Xor);
}
else if (type == typeof(PPos))
{
il.EmitCall(OpCodes.Call, ((Func<PPos, int>)hash_PPos).Method, null);
il.Emit(OpCodes.Xor);
}
else if (type == typeof(PVecInt))
{
il.EmitCall(OpCodes.Call, ((Func<PVecInt, int>)hash_PVecInt).Method, null);
il.Emit(OpCodes.Xor);
}
else if (type == typeof(PSubPos))
{
il.EmitCall(OpCodes.Call, ((Func<PSubPos, int>)hash_PSubPos).Method, null);
il.Emit(OpCodes.Xor);
}
else if (type == typeof(PSubVec))
{
il.EmitCall(OpCodes.Call, ((Func<PSubVec, int>)hash_PSubVec).Method, null);
il.Emit(OpCodes.Xor);
}
else if (type == typeof(TypeDictionary))
{
il.EmitCall(OpCodes.Call, ((Func<TypeDictionary, int>)hash_tdict).Method, null);
@@ -110,6 +140,36 @@ namespace OpenRA
return ( ( i2.X * 5 ) ^ ( i2.Y * 3 ) ) / 4;
}
public static int hash_CPos( CPos i2 )
{
return ( ( i2.X * 5) ^ ( i2.Y * 3 ) ) / 4;
}
public static int hash_CVec( CVec i2 )
{
return ( ( i2.X * 5) ^ ( i2.Y * 3 ) ) / 4;
}
public static int hash_PPos( PPos i2 )
{
return ( ( i2.X * 5) ^ ( i2.Y * 3 ) ) / 4;
}
public static int hash_PVecInt( PVecInt i2 )
{
return ( ( i2.X * 5) ^ ( i2.Y * 3 ) ) / 4;
}
public static int hash_PSubPos(PSubPos i2)
{
return ((i2.X * 5) ^ (i2.Y * 3)) / 4;
}
public static int hash_PSubVec(PSubVec i2)
{
return ((i2.X * 5) ^ (i2.Y * 3)) / 4;
}
public static int hash_tdict( TypeDictionary d )
{
int ret = 0;

View File

@@ -11,6 +11,7 @@
using System.Drawing;
using OpenRA.Graphics;
using OpenRA.Effects;
using System.Collections.Generic;
namespace OpenRA.Traits
{
@@ -25,7 +26,7 @@ namespace OpenRA.Traits
{
Actor self;
DrawLineToTargetInfo Info;
Target target;
List<Target> targets;
Color c;
int lifetime;
@@ -33,7 +34,16 @@ namespace OpenRA.Traits
public void SetTarget(Actor self, Target target, Color c, bool display)
{
this.target = target;
this.targets = new List<Target> { target };
this.c = c;
if (display)
lifetime = Info.Ticks;
}
public void SetTargets(Actor self, List<Target> targets, Color c, bool display)
{
this.targets = targets;
this.c = c;
if (display)
@@ -42,23 +52,29 @@ namespace OpenRA.Traits
public void RenderAfterWorld(WorldRenderer wr)
{
if (self.IsIdle) return;
//if (self.IsIdle) return;
var force = Game.GetModifierKeys().HasModifier(Modifiers.Alt);
if ((lifetime <= 0 || --lifetime <= 0) && !force)
return;
if (!target.IsValid)
if (targets == null || targets.Count == 0)
return;
var move = self.TraitOrDefault<IMove>();
var origin = move != null ? self.CenterLocation - new int2(0, move.Altitude) : self.CenterLocation;
var origin = (move != null ? self.CenterLocation - new PVecInt(0, move.Altitude) : self.CenterLocation).ToFloat2();
var wlr = Game.Renderer.WorldLineRenderer;
wlr.DrawLine(origin, target.CenterLocation, c, c);
DrawTargetMarker(wlr, target.CenterLocation);
DrawTargetMarker(wlr, origin);
foreach (var target in targets)
{
if (!target.IsValid)
continue;
wlr.DrawLine(origin, target.CenterLocation.ToFloat2(), c, c);
DrawTargetMarker(wlr, target.CenterLocation.ToFloat2());
DrawTargetMarker(wlr, origin);
}
}
void DrawTargetMarker(LineRenderer wlr, float2 p)
@@ -72,6 +88,18 @@ namespace OpenRA.Traits
public static class LineTargetExts
{
public static void SetTargetLines(this Actor self, List<Target> targets, Color color)
{
var line = self.TraitOrDefault<DrawLineToTarget>();
if (line != null)
{
self.World.AddFrameEndTask(w =>
{
line.SetTargets(self, targets, color, false);
});
}
}
public static void SetTargetLine(this Actor self, Target target, Color color)
{
self.SetTargetLine(target, color, true);

View File

@@ -41,7 +41,7 @@ namespace OpenRA.Traits
}
public int HP { get { return hp; } }
public readonly int MaxHP;
public int MaxHP;
public bool IsDead { get { return hp <= 0; } }
public bool RemoveOnDeath = true;

View File

@@ -10,6 +10,7 @@
using System;
using System.Linq;
using OpenRA.GameRules;
namespace OpenRA.Traits
{
@@ -62,6 +63,8 @@ namespace OpenRA.Traits
{
readonly Player Owner;
int AdviceInterval;
int cashtickallowed = 0;
public PlayerResources(Actor self, PlayerResourcesInfo info)
{
@@ -134,7 +137,11 @@ namespace OpenRA.Traits
public void Tick(Actor self)
{
var eva = self.World.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
if(cashtickallowed > 0) {
cashtickallowed = cashtickallowed - 1;
}
OreCapacity = self.World.ActorsWithTrait<IStoreOre>()
.Where(a => a.Actor.Owner == Owner)
.Sum(a => a.Trait.Capacity);
@@ -158,12 +165,12 @@ namespace OpenRA.Traits
if (DisplayCash < Cash)
{
DisplayCash += move;
Sound.PlayToPlayer(self.Owner, eva.CashTickUp);
playCashTickUp(self);
}
else if (DisplayCash > Cash)
{
DisplayCash -= move;
Sound.PlayToPlayer(self.Owner, eva.CashTickDown);
playCashTickDown(self);
}
diff = Math.Abs(Ore - DisplayOre);
@@ -173,13 +180,36 @@ namespace OpenRA.Traits
if (DisplayOre < Ore)
{
DisplayOre += move;
Sound.PlayToPlayer(self.Owner, eva.CashTickUp);
playCashTickUp(self);
}
else if (DisplayOre > Ore)
{
DisplayOre -= move;
Sound.PlayToPlayer(self.Owner, eva.CashTickDown);
playCashTickDown(self);
}
}
public void playCashTickUp(Actor self)
{
var eva = self.World.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
if (Game.Settings.Sound.SoundCashTickType != SoundCashTicks.Disabled)
{
Sound.PlayToPlayer(self.Owner, eva.CashTickUp);
}
}
public void playCashTickDown(Actor self)
{
var eva = self.World.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
if (
Game.Settings.Sound.SoundCashTickType == SoundCashTicks.Extreme ||
(Game.Settings.Sound.SoundCashTickType == SoundCashTicks.Normal && cashtickallowed == 0)
) {
Sound.PlayToPlayer(self.Owner, eva.CashTickDown);
cashtickallowed = 3;
}
}
}
}

View File

@@ -19,7 +19,7 @@ namespace OpenRA.Traits
class RevealsShroud : ITick
{
RevealsShroudInfo Info;
int2 previousLocation;
CPos previousLocation;
public RevealsShroud(RevealsShroudInfo info)
{

View File

@@ -146,12 +146,12 @@ namespace OpenRA.Traits
{
var alt = new float2(0, -mobile.Altitude);
var targets = activity.GetTargets(self);
var start = self.CenterLocation + alt;
var start = self.CenterLocation.ToFloat2() + alt;
var c = Color.Green;
var wlr = Game.Renderer.WorldLineRenderer;
foreach (var step in targets.Select(p => p.CenterLocation))
foreach (var step in targets.Select(p => p.CenterLocation.ToFloat2()))
{
var stp = step + alt;
wlr.DrawLine(stp + new float2(-1, -1), stp + new float2(-1, 1), c, c);

View File

@@ -16,7 +16,7 @@ namespace OpenRA.Traits
Actor actor;
Player owner;
int2 pos;
PPos pos;
bool valid;
public static Target FromActor(Actor a)
@@ -28,8 +28,8 @@ namespace OpenRA.Traits
owner = (a != null) ? a.Owner : null
};
}
public static Target FromPos(int2 p) { return new Target { pos = p, valid = true }; }
public static Target FromCell(int2 c) { return new Target { pos = Util.CenterOfCell(c), valid = true }; }
public static Target FromPos(PPos p) { return new Target { pos = p, valid = true }; }
public static Target FromCell(CPos c) { return new Target { pos = Util.CenterOfCell(c), valid = true }; }
public static Target FromOrder(Order o)
{
return o.TargetActor != null
@@ -40,8 +40,8 @@ namespace OpenRA.Traits
public static readonly Target None = new Target();
public bool IsValid { get { return valid && (actor == null || (actor.IsInWorld && actor.Owner == owner)); } }
public int2 PxPosition { get { return IsActor ? actor.Trait<IHasLocation>().PxPosition : pos; } }
public int2 CenterLocation { get { return PxPosition; } }
public PPos PxPosition { get { return IsActor ? actor.Trait<IHasLocation>().PxPosition : pos; } }
public PPos CenterLocation { get { return PxPosition; } }
public Actor Actor { get { return IsActor ? actor : null; } }
public bool IsActor { get { return actor != null && !actor.Destroyed; } }

View File

@@ -47,7 +47,7 @@ namespace OpenRA.Traits
string OrderID { get; }
int OrderPriority { get; }
bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueue, ref string cursor);
bool CanTargetLocation(Actor self, int2 location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueue, ref string cursor);
bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueue, ref string cursor);
bool IsQueued { get; }
}
@@ -60,7 +60,7 @@ namespace OpenRA.Traits
public interface INotifyKilled { void Killed(Actor self, AttackInfo e); }
public interface INotifyAppliedDamage { void AppliedDamage(Actor self, Actor damaged, AttackInfo e); }
public interface INotifyBuildComplete { void BuildingComplete(Actor self); }
public interface INotifyProduction { void UnitProduced(Actor self, Actor other, int2 exit); }
public interface INotifyProduction { void UnitProduced(Actor self, Actor other, CPos exit); }
public interface INotifyCapture { void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner); }
public interface INotifyOtherCaptured { void OnActorCaptured(Actor self, Actor captured, Actor captor, Player oldOwner, Player newOwner); }
public interface IAcceptSpy { void OnInfiltrate(Actor self, Actor spy); }
@@ -75,27 +75,26 @@ namespace OpenRA.Traits
public interface IDisable { bool Disabled { get; } }
public interface IExplodeModifier { bool ShouldExplode(Actor self); }
public interface IHuskModifier { string HuskActor(Actor self); }
public interface INudge { void OnNudge(Actor self, Actor nudger, bool force); }
public interface IRadarSignature
{
IEnumerable<int2> RadarSignatureCells(Actor self);
IEnumerable<CPos> RadarSignatureCells(Actor self);
Color RadarSignatureColor(Actor self);
}
public interface IVisibilityModifier { bool IsVisible(Actor self); }
public interface IRadarColorModifier { Color RadarColorOverride(Actor self); }
public interface IHasLocation { int2 PxPosition { get; } }
public interface IHasLocation { PPos PxPosition { get; } }
public interface IOccupySpace : IHasLocation
{
int2 TopLeft { get; }
IEnumerable<Pair<int2, SubCell>> OccupiedCells();
CPos TopLeft { get; }
IEnumerable<Pair<CPos, SubCell>> OccupiedCells();
}
public static class IOccupySpaceExts
{
public static int2 NearestCellTo(this IOccupySpace ios, int2 other)
public static CPos NearestCellTo(this IOccupySpace ios, CPos other)
{
var nearest = ios.TopLeft;
var nearestDistance = int.MaxValue;
@@ -125,13 +124,14 @@ namespace OpenRA.Traits
public interface ITeleportable : IHasLocation /* crap name! */
{
bool CanEnterCell(int2 location);
void SetPosition(Actor self, int2 cell);
void SetPxPosition(Actor self, int2 px);
void AdjustPxPosition(Actor self, int2 px); /* works like SetPxPosition, but visual only */
bool CanEnterCell(CPos location);
void SetPosition(Actor self, CPos cell);
void SetPxPosition(Actor self, PPos px);
void AdjustPxPosition(Actor self, PPos px); /* works like SetPxPosition, but visual only */
}
public interface IMove : ITeleportable { int Altitude { get; set; } }
public interface INotifyBlockingMove { void OnNotifyBlockingMove(Actor self, Actor blocking); }
public interface IFacing
{
@@ -212,7 +212,7 @@ namespace OpenRA.Traits
public interface ITargetable
{
string[] TargetTypes { get; }
IEnumerable<int2> TargetableCells(Actor self);
IEnumerable<CPos> TargetableCells(Actor self);
bool TargetableBy(Actor self, Actor byActor);
}

View File

@@ -30,6 +30,16 @@ namespace OpenRA.Traits
return ( facing - rot ) & 0xFF;
}
public static int GetFacing(PVecInt d, int currentFacing)
{
return GetFacing(d.ToInt2(), currentFacing);
}
public static int GetFacing(CVec d, int currentFacing)
{
return GetFacing(d.ToInt2(), currentFacing);
}
public static int GetFacing( int2 d, int currentFacing )
{
if (d == int2.Zero)
@@ -80,14 +90,14 @@ namespace OpenRA.Traits
ecc * (cosAngle * v.Y - sinAngle * v.X));
}
public static int2 CenterOfCell(int2 loc)
public static PPos CenterOfCell(CPos loc)
{
return new int2( Game.CellSize / 2, Game.CellSize / 2 ) + Game.CellSize * loc;
return loc.ToPPos() + new PVecInt(Game.CellSize / 2, Game.CellSize / 2);
}
public static int2 BetweenCells(int2 from, int2 to)
public static PPos BetweenCells(CPos from, CPos to)
{
return int2.Lerp( CenterOfCell( from ), CenterOfCell( to ), 1, 2 );
return PPos.Lerp(CenterOfCell(from), CenterOfCell(to), 1, 2);
}
public static int2 AsInt2(this int[] xs) { return new int2(xs[0], xs[1]); }
@@ -120,6 +130,7 @@ namespace OpenRA.Traits
public static Color ArrayToColor(int[] x) { return Color.FromArgb(x[0], x[1], x[2]); }
[Obsolete("Use ToCPos() method", true)]
public static int2 CellContaining(float2 pos) { return (1f / Game.CellSize * pos).ToInt2(); }
/* pretty crap */
@@ -134,39 +145,39 @@ namespace OpenRA.Traits
}
}
static IEnumerable<int2> Neighbours(int2 c, bool allowDiagonal)
static IEnumerable<CPos> Neighbours(CPos c, bool allowDiagonal)
{
yield return c;
yield return new int2(c.X - 1, c.Y);
yield return new int2(c.X + 1, c.Y);
yield return new int2(c.X, c.Y - 1);
yield return new int2(c.X, c.Y + 1);
yield return new CPos(c.X - 1, c.Y);
yield return new CPos(c.X + 1, c.Y);
yield return new CPos(c.X, c.Y - 1);
yield return new CPos(c.X, c.Y + 1);
if (allowDiagonal)
{
yield return new int2(c.X - 1, c.Y - 1);
yield return new int2(c.X + 1, c.Y - 1);
yield return new int2(c.X - 1, c.Y + 1);
yield return new int2(c.X + 1, c.Y + 1);
yield return new CPos(c.X - 1, c.Y - 1);
yield return new CPos(c.X + 1, c.Y - 1);
yield return new CPos(c.X - 1, c.Y + 1);
yield return new CPos(c.X + 1, c.Y + 1);
}
}
public static IEnumerable<int2> ExpandFootprint(IEnumerable<int2> cells, bool allowDiagonal)
public static IEnumerable<CPos> ExpandFootprint(IEnumerable<CPos> cells, bool allowDiagonal)
{
var result = new Dictionary<int2, bool>();
var result = new Dictionary<CPos, bool>();
foreach (var c in cells.SelectMany(c => Neighbours(c, allowDiagonal)))
result[c] = true;
return result.Keys;
}
public static IEnumerable<int2> AdjacentCells( Target target )
public static IEnumerable<CPos> AdjacentCells(Target target)
{
var cells = target.IsActor
? target.Actor.OccupiesSpace.OccupiedCells().Select(c => c.First).ToArray()
: new int2[] {};
: new CPos[] {};
if (cells.Length == 0)
cells = new [] { Util.CellContaining(target.CenterLocation) };
cells = new CPos[] { target.CenterLocation.ToCPos() };
return Util.ExpandFootprint(cells, true);
}
@@ -208,264 +219,264 @@ namespace OpenRA.Traits
};
public static readonly int2[] SubPxVector =
public static readonly PSubVec[] SubPxVector =
{
new int2( 0, 1024 ),
new int2( 25, 1023 ),
new int2( 50, 1022 ),
new int2( 75, 1021 ),
new int2( 100, 1019 ),
new int2( 125, 1016 ),
new int2( 150, 1012 ),
new int2( 175, 1008 ),
new int2( 199, 1004 ),
new int2( 224, 999 ),
new int2( 248, 993 ),
new int2( 273, 986 ),
new int2( 297, 979 ),
new int2( 321, 972 ),
new int2( 344, 964 ),
new int2( 368, 955 ),
new int2( 391, 946 ),
new int2( 414, 936 ),
new int2( 437, 925 ),
new int2( 460, 914 ),
new int2( 482, 903 ),
new int2( 504, 890 ),
new int2( 526, 878 ),
new int2( 547, 865 ),
new int2( 568, 851 ),
new int2( 589, 837 ),
new int2( 609, 822 ),
new int2( 629, 807 ),
new int2( 649, 791 ),
new int2( 668, 775 ),
new int2( 687, 758 ),
new int2( 706, 741 ),
new int2( 724, 724 ),
new int2( 741, 706 ),
new int2( 758, 687 ),
new int2( 775, 668 ),
new int2( 791, 649 ),
new int2( 807, 629 ),
new int2( 822, 609 ),
new int2( 837, 589 ),
new int2( 851, 568 ),
new int2( 865, 547 ),
new int2( 878, 526 ),
new int2( 890, 504 ),
new int2( 903, 482 ),
new int2( 914, 460 ),
new int2( 925, 437 ),
new int2( 936, 414 ),
new int2( 946, 391 ),
new int2( 955, 368 ),
new int2( 964, 344 ),
new int2( 972, 321 ),
new int2( 979, 297 ),
new int2( 986, 273 ),
new int2( 993, 248 ),
new int2( 999, 224 ),
new int2( 1004, 199 ),
new int2( 1008, 175 ),
new int2( 1012, 150 ),
new int2( 1016, 125 ),
new int2( 1019, 100 ),
new int2( 1021, 75 ),
new int2( 1022, 50 ),
new int2( 1023, 25 ),
new int2( 1024, 0 ),
new int2( 1023, -25 ),
new int2( 1022, -50 ),
new int2( 1021, -75 ),
new int2( 1019, -100 ),
new int2( 1016, -125 ),
new int2( 1012, -150 ),
new int2( 1008, -175 ),
new int2( 1004, -199 ),
new int2( 999, -224 ),
new int2( 993, -248 ),
new int2( 986, -273 ),
new int2( 979, -297 ),
new int2( 972, -321 ),
new int2( 964, -344 ),
new int2( 955, -368 ),
new int2( 946, -391 ),
new int2( 936, -414 ),
new int2( 925, -437 ),
new int2( 914, -460 ),
new int2( 903, -482 ),
new int2( 890, -504 ),
new int2( 878, -526 ),
new int2( 865, -547 ),
new int2( 851, -568 ),
new int2( 837, -589 ),
new int2( 822, -609 ),
new int2( 807, -629 ),
new int2( 791, -649 ),
new int2( 775, -668 ),
new int2( 758, -687 ),
new int2( 741, -706 ),
new int2( 724, -724 ),
new int2( 706, -741 ),
new int2( 687, -758 ),
new int2( 668, -775 ),
new int2( 649, -791 ),
new int2( 629, -807 ),
new int2( 609, -822 ),
new int2( 589, -837 ),
new int2( 568, -851 ),
new int2( 547, -865 ),
new int2( 526, -878 ),
new int2( 504, -890 ),
new int2( 482, -903 ),
new int2( 460, -914 ),
new int2( 437, -925 ),
new int2( 414, -936 ),
new int2( 391, -946 ),
new int2( 368, -955 ),
new int2( 344, -964 ),
new int2( 321, -972 ),
new int2( 297, -979 ),
new int2( 273, -986 ),
new int2( 248, -993 ),
new int2( 224, -999 ),
new int2( 199, -1004 ),
new int2( 175, -1008 ),
new int2( 150, -1012 ),
new int2( 125, -1016 ),
new int2( 100, -1019 ),
new int2( 75, -1021 ),
new int2( 50, -1022 ),
new int2( 25, -1023 ),
new int2( 0, -1024 ),
new int2( -25, -1023 ),
new int2( -50, -1022 ),
new int2( -75, -1021 ),
new int2( -100, -1019 ),
new int2( -125, -1016 ),
new int2( -150, -1012 ),
new int2( -175, -1008 ),
new int2( -199, -1004 ),
new int2( -224, -999 ),
new int2( -248, -993 ),
new int2( -273, -986 ),
new int2( -297, -979 ),
new int2( -321, -972 ),
new int2( -344, -964 ),
new int2( -368, -955 ),
new int2( -391, -946 ),
new int2( -414, -936 ),
new int2( -437, -925 ),
new int2( -460, -914 ),
new int2( -482, -903 ),
new int2( -504, -890 ),
new int2( -526, -878 ),
new int2( -547, -865 ),
new int2( -568, -851 ),
new int2( -589, -837 ),
new int2( -609, -822 ),
new int2( -629, -807 ),
new int2( -649, -791 ),
new int2( -668, -775 ),
new int2( -687, -758 ),
new int2( -706, -741 ),
new int2( -724, -724 ),
new int2( -741, -706 ),
new int2( -758, -687 ),
new int2( -775, -668 ),
new int2( -791, -649 ),
new int2( -807, -629 ),
new int2( -822, -609 ),
new int2( -837, -589 ),
new int2( -851, -568 ),
new int2( -865, -547 ),
new int2( -878, -526 ),
new int2( -890, -504 ),
new int2( -903, -482 ),
new int2( -914, -460 ),
new int2( -925, -437 ),
new int2( -936, -414 ),
new int2( -946, -391 ),
new int2( -955, -368 ),
new int2( -964, -344 ),
new int2( -972, -321 ),
new int2( -979, -297 ),
new int2( -986, -273 ),
new int2( -993, -248 ),
new int2( -999, -224 ),
new int2( -1004, -199 ),
new int2( -1008, -175 ),
new int2( -1012, -150 ),
new int2( -1016, -125 ),
new int2( -1019, -100 ),
new int2( -1021, -75 ),
new int2( -1022, -50 ),
new int2( -1023, -25 ),
new int2( -1024, 0 ),
new int2( -1023, 25 ),
new int2( -1022, 50 ),
new int2( -1021, 75 ),
new int2( -1019, 100 ),
new int2( -1016, 125 ),
new int2( -1012, 150 ),
new int2( -1008, 175 ),
new int2( -1004, 199 ),
new int2( -999, 224 ),
new int2( -993, 248 ),
new int2( -986, 273 ),
new int2( -979, 297 ),
new int2( -972, 321 ),
new int2( -964, 344 ),
new int2( -955, 368 ),
new int2( -946, 391 ),
new int2( -936, 414 ),
new int2( -925, 437 ),
new int2( -914, 460 ),
new int2( -903, 482 ),
new int2( -890, 504 ),
new int2( -878, 526 ),
new int2( -865, 547 ),
new int2( -851, 568 ),
new int2( -837, 589 ),
new int2( -822, 609 ),
new int2( -807, 629 ),
new int2( -791, 649 ),
new int2( -775, 668 ),
new int2( -758, 687 ),
new int2( -741, 706 ),
new int2( -724, 724 ),
new int2( -706, 741 ),
new int2( -687, 758 ),
new int2( -668, 775 ),
new int2( -649, 791 ),
new int2( -629, 807 ),
new int2( -609, 822 ),
new int2( -589, 837 ),
new int2( -568, 851 ),
new int2( -547, 865 ),
new int2( -526, 878 ),
new int2( -504, 890 ),
new int2( -482, 903 ),
new int2( -460, 914 ),
new int2( -437, 925 ),
new int2( -414, 936 ),
new int2( -391, 946 ),
new int2( -368, 955 ),
new int2( -344, 964 ),
new int2( -321, 972 ),
new int2( -297, 979 ),
new int2( -273, 986 ),
new int2( -248, 993 ),
new int2( -224, 999 ),
new int2( -199, 1004 ),
new int2( -175, 1008 ),
new int2( -150, 1012 ),
new int2( -125, 1016 ),
new int2( -100, 1019 ),
new int2( -75, 1021 ),
new int2( -50, 1022 ),
new int2( -25, 1023 )
new PSubVec( 0, 1024 ),
new PSubVec( 25, 1023 ),
new PSubVec( 50, 1022 ),
new PSubVec( 75, 1021 ),
new PSubVec( 100, 1019 ),
new PSubVec( 125, 1016 ),
new PSubVec( 150, 1012 ),
new PSubVec( 175, 1008 ),
new PSubVec( 199, 1004 ),
new PSubVec( 224, 999 ),
new PSubVec( 248, 993 ),
new PSubVec( 273, 986 ),
new PSubVec( 297, 979 ),
new PSubVec( 321, 972 ),
new PSubVec( 344, 964 ),
new PSubVec( 368, 955 ),
new PSubVec( 391, 946 ),
new PSubVec( 414, 936 ),
new PSubVec( 437, 925 ),
new PSubVec( 460, 914 ),
new PSubVec( 482, 903 ),
new PSubVec( 504, 890 ),
new PSubVec( 526, 878 ),
new PSubVec( 547, 865 ),
new PSubVec( 568, 851 ),
new PSubVec( 589, 837 ),
new PSubVec( 609, 822 ),
new PSubVec( 629, 807 ),
new PSubVec( 649, 791 ),
new PSubVec( 668, 775 ),
new PSubVec( 687, 758 ),
new PSubVec( 706, 741 ),
new PSubVec( 724, 724 ),
new PSubVec( 741, 706 ),
new PSubVec( 758, 687 ),
new PSubVec( 775, 668 ),
new PSubVec( 791, 649 ),
new PSubVec( 807, 629 ),
new PSubVec( 822, 609 ),
new PSubVec( 837, 589 ),
new PSubVec( 851, 568 ),
new PSubVec( 865, 547 ),
new PSubVec( 878, 526 ),
new PSubVec( 890, 504 ),
new PSubVec( 903, 482 ),
new PSubVec( 914, 460 ),
new PSubVec( 925, 437 ),
new PSubVec( 936, 414 ),
new PSubVec( 946, 391 ),
new PSubVec( 955, 368 ),
new PSubVec( 964, 344 ),
new PSubVec( 972, 321 ),
new PSubVec( 979, 297 ),
new PSubVec( 986, 273 ),
new PSubVec( 993, 248 ),
new PSubVec( 999, 224 ),
new PSubVec( 1004, 199 ),
new PSubVec( 1008, 175 ),
new PSubVec( 1012, 150 ),
new PSubVec( 1016, 125 ),
new PSubVec( 1019, 100 ),
new PSubVec( 1021, 75 ),
new PSubVec( 1022, 50 ),
new PSubVec( 1023, 25 ),
new PSubVec( 1024, 0 ),
new PSubVec( 1023, -25 ),
new PSubVec( 1022, -50 ),
new PSubVec( 1021, -75 ),
new PSubVec( 1019, -100 ),
new PSubVec( 1016, -125 ),
new PSubVec( 1012, -150 ),
new PSubVec( 1008, -175 ),
new PSubVec( 1004, -199 ),
new PSubVec( 999, -224 ),
new PSubVec( 993, -248 ),
new PSubVec( 986, -273 ),
new PSubVec( 979, -297 ),
new PSubVec( 972, -321 ),
new PSubVec( 964, -344 ),
new PSubVec( 955, -368 ),
new PSubVec( 946, -391 ),
new PSubVec( 936, -414 ),
new PSubVec( 925, -437 ),
new PSubVec( 914, -460 ),
new PSubVec( 903, -482 ),
new PSubVec( 890, -504 ),
new PSubVec( 878, -526 ),
new PSubVec( 865, -547 ),
new PSubVec( 851, -568 ),
new PSubVec( 837, -589 ),
new PSubVec( 822, -609 ),
new PSubVec( 807, -629 ),
new PSubVec( 791, -649 ),
new PSubVec( 775, -668 ),
new PSubVec( 758, -687 ),
new PSubVec( 741, -706 ),
new PSubVec( 724, -724 ),
new PSubVec( 706, -741 ),
new PSubVec( 687, -758 ),
new PSubVec( 668, -775 ),
new PSubVec( 649, -791 ),
new PSubVec( 629, -807 ),
new PSubVec( 609, -822 ),
new PSubVec( 589, -837 ),
new PSubVec( 568, -851 ),
new PSubVec( 547, -865 ),
new PSubVec( 526, -878 ),
new PSubVec( 504, -890 ),
new PSubVec( 482, -903 ),
new PSubVec( 460, -914 ),
new PSubVec( 437, -925 ),
new PSubVec( 414, -936 ),
new PSubVec( 391, -946 ),
new PSubVec( 368, -955 ),
new PSubVec( 344, -964 ),
new PSubVec( 321, -972 ),
new PSubVec( 297, -979 ),
new PSubVec( 273, -986 ),
new PSubVec( 248, -993 ),
new PSubVec( 224, -999 ),
new PSubVec( 199, -1004 ),
new PSubVec( 175, -1008 ),
new PSubVec( 150, -1012 ),
new PSubVec( 125, -1016 ),
new PSubVec( 100, -1019 ),
new PSubVec( 75, -1021 ),
new PSubVec( 50, -1022 ),
new PSubVec( 25, -1023 ),
new PSubVec( 0, -1024 ),
new PSubVec( -25, -1023 ),
new PSubVec( -50, -1022 ),
new PSubVec( -75, -1021 ),
new PSubVec( -100, -1019 ),
new PSubVec( -125, -1016 ),
new PSubVec( -150, -1012 ),
new PSubVec( -175, -1008 ),
new PSubVec( -199, -1004 ),
new PSubVec( -224, -999 ),
new PSubVec( -248, -993 ),
new PSubVec( -273, -986 ),
new PSubVec( -297, -979 ),
new PSubVec( -321, -972 ),
new PSubVec( -344, -964 ),
new PSubVec( -368, -955 ),
new PSubVec( -391, -946 ),
new PSubVec( -414, -936 ),
new PSubVec( -437, -925 ),
new PSubVec( -460, -914 ),
new PSubVec( -482, -903 ),
new PSubVec( -504, -890 ),
new PSubVec( -526, -878 ),
new PSubVec( -547, -865 ),
new PSubVec( -568, -851 ),
new PSubVec( -589, -837 ),
new PSubVec( -609, -822 ),
new PSubVec( -629, -807 ),
new PSubVec( -649, -791 ),
new PSubVec( -668, -775 ),
new PSubVec( -687, -758 ),
new PSubVec( -706, -741 ),
new PSubVec( -724, -724 ),
new PSubVec( -741, -706 ),
new PSubVec( -758, -687 ),
new PSubVec( -775, -668 ),
new PSubVec( -791, -649 ),
new PSubVec( -807, -629 ),
new PSubVec( -822, -609 ),
new PSubVec( -837, -589 ),
new PSubVec( -851, -568 ),
new PSubVec( -865, -547 ),
new PSubVec( -878, -526 ),
new PSubVec( -890, -504 ),
new PSubVec( -903, -482 ),
new PSubVec( -914, -460 ),
new PSubVec( -925, -437 ),
new PSubVec( -936, -414 ),
new PSubVec( -946, -391 ),
new PSubVec( -955, -368 ),
new PSubVec( -964, -344 ),
new PSubVec( -972, -321 ),
new PSubVec( -979, -297 ),
new PSubVec( -986, -273 ),
new PSubVec( -993, -248 ),
new PSubVec( -999, -224 ),
new PSubVec( -1004, -199 ),
new PSubVec( -1008, -175 ),
new PSubVec( -1012, -150 ),
new PSubVec( -1016, -125 ),
new PSubVec( -1019, -100 ),
new PSubVec( -1021, -75 ),
new PSubVec( -1022, -50 ),
new PSubVec( -1023, -25 ),
new PSubVec( -1024, 0 ),
new PSubVec( -1023, 25 ),
new PSubVec( -1022, 50 ),
new PSubVec( -1021, 75 ),
new PSubVec( -1019, 100 ),
new PSubVec( -1016, 125 ),
new PSubVec( -1012, 150 ),
new PSubVec( -1008, 175 ),
new PSubVec( -1004, 199 ),
new PSubVec( -999, 224 ),
new PSubVec( -993, 248 ),
new PSubVec( -986, 273 ),
new PSubVec( -979, 297 ),
new PSubVec( -972, 321 ),
new PSubVec( -964, 344 ),
new PSubVec( -955, 368 ),
new PSubVec( -946, 391 ),
new PSubVec( -936, 414 ),
new PSubVec( -925, 437 ),
new PSubVec( -914, 460 ),
new PSubVec( -903, 482 ),
new PSubVec( -890, 504 ),
new PSubVec( -878, 526 ),
new PSubVec( -865, 547 ),
new PSubVec( -851, 568 ),
new PSubVec( -837, 589 ),
new PSubVec( -822, 609 ),
new PSubVec( -807, 629 ),
new PSubVec( -791, 649 ),
new PSubVec( -775, 668 ),
new PSubVec( -758, 687 ),
new PSubVec( -741, 706 ),
new PSubVec( -724, 724 ),
new PSubVec( -706, 741 ),
new PSubVec( -687, 758 ),
new PSubVec( -668, 775 ),
new PSubVec( -649, 791 ),
new PSubVec( -629, 807 ),
new PSubVec( -609, 822 ),
new PSubVec( -589, 837 ),
new PSubVec( -568, 851 ),
new PSubVec( -547, 865 ),
new PSubVec( -526, 878 ),
new PSubVec( -504, 890 ),
new PSubVec( -482, 903 ),
new PSubVec( -460, 914 ),
new PSubVec( -437, 925 ),
new PSubVec( -414, 936 ),
new PSubVec( -391, 946 ),
new PSubVec( -368, 955 ),
new PSubVec( -344, 964 ),
new PSubVec( -321, 972 ),
new PSubVec( -297, 979 ),
new PSubVec( -273, 986 ),
new PSubVec( -248, 993 ),
new PSubVec( -224, 999 ),
new PSubVec( -199, 1004 ),
new PSubVec( -175, 1008 ),
new PSubVec( -150, 1012 ),
new PSubVec( -125, 1016 ),
new PSubVec( -100, 1019 ),
new PSubVec( -75, 1021 ),
new PSubVec( -50, 1022 ),
new PSubVec( -25, 1023 )
};
}
}

View File

@@ -20,16 +20,16 @@ namespace OpenRA.Traits
class Waypoint : IOccupySpace, ISync
{
[Sync] int2 location;
[Sync] CPos location;
public Waypoint(ActorInitializer init)
{
this.location = init.Get<LocationInit,int2>();
this.location = init.Get<LocationInit, CPos>();
}
public int2 TopLeft { get { return location; } }
public CPos TopLeft { get { return location; } }
public IEnumerable<Pair<int2, SubCell>> OccupiedCells() { yield break; }
public int2 PxPosition { get { return Util.CenterOfCell( location ); } }
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { yield break; }
public PPos PxPosition { get { return Util.CenterOfCell(location); } }
}
}

View File

@@ -17,7 +17,7 @@ namespace OpenRA.Traits
{
public readonly string BasePalette = null;
public readonly string BaseName = "player";
public readonly PaletteFormat PaletteFormat = PaletteFormat.ra;
public readonly int[] RemapIndex = {};
public object Create( ActorInitializer init ) { return new PlayerColorPalette( init.self.Owner, this ); }
}
@@ -37,7 +37,7 @@ namespace OpenRA.Traits
{
var paletteName = "{0}{1}".F( info.BaseName, owner.InternalName );
var newpal = new Palette(wr.GetPalette(info.BasePalette),
new PlayerColorRemap(info.PaletteFormat, owner.ColorRamp));
new PlayerColorRemap(info.RemapIndex, owner.ColorRamp));
wr.AddPalette(paletteName, newpal);
}
}

View File

@@ -12,12 +12,13 @@ using System;
using System.Drawing;
using System.Linq;
using OpenRA.Graphics;
using System.Collections.Generic;
namespace OpenRA.Traits
{
public class ResourceLayerInfo : TraitInfo<ResourceLayer> { }
public class ResourceLayer: IRenderOverlay, IWorldLoaded
public class ResourceLayer : IRenderOverlay, IWorldLoaded
{
World world;
@@ -26,12 +27,12 @@ namespace OpenRA.Traits
bool hasSetupPalettes;
public void Render( WorldRenderer wr )
public void Render(WorldRenderer wr)
{
if (!hasSetupPalettes)
{
hasSetupPalettes = true;
foreach( var rt in world.WorldActor.TraitsImplementing<ResourceType>() )
foreach (var rt in world.WorldActor.TraitsImplementing<ResourceType>())
rt.info.PaletteIndex = wr.GetPaletteIndex(rt.info.Palette);
}
@@ -39,13 +40,13 @@ namespace OpenRA.Traits
for (int x = clip.Left; x < clip.Right; x++)
for (int y = clip.Top; y < clip.Bottom; y++)
{
if (!world.LocalShroud.IsExplored(new int2(x, y)))
if (!world.LocalShroud.IsExplored(new CPos(x, y)))
continue;
var c = content[x, y];
if (c.image != null)
c.image[c.density].DrawAt(
Game.CellSize * new int2(x, y),
new CPos(x, y).ToPPos().ToFloat2(),
c.type.info.PaletteIndex);
}
}
@@ -70,7 +71,7 @@ namespace OpenRA.Traits
if (type == null)
continue;
if (!AllowResourceAt(type, new int2(x,y)))
if (!AllowResourceAt(type, new CPos(x,y)))
continue;
content[x, y].type = type;
@@ -86,7 +87,7 @@ namespace OpenRA.Traits
}
}
public bool AllowResourceAt(ResourceType rt, int2 a)
public bool AllowResourceAt(ResourceType rt, CPos a)
{
if (!world.Map.IsInMap(a.X, a.Y)) return false;
if (!rt.info.AllowedTerrainTypes.Contains(world.GetTerrainInfo(a).Type)) return false;
@@ -104,7 +105,7 @@ namespace OpenRA.Traits
int sum = 0;
for (var u = -1; u < 2; u++)
for (var v = -1; v < 2; v++)
if (content[i+u, j+v].type == t)
if (content[i + u, j + v].type == t)
++sum;
return sum;
}
@@ -131,14 +132,14 @@ namespace OpenRA.Traits
content[i, j].image.Length - 1,
content[i, j].density + n);
world.Map.CustomTerrain[i,j] = t.info.TerrainType;
world.Map.CustomTerrain[i, j] = t.info.TerrainType;
}
public bool IsFull(int i, int j) { return content[i, j].density == content[i, j].image.Length - 1; }
public ResourceType Harvest(int2 p)
public ResourceType Harvest(CPos p)
{
var type = content[p.X,p.Y].type;
var type = content[p.X, p.Y].type;
if (type == null) return null;
if (--content[p.X, p.Y].density < 0)
@@ -150,7 +151,7 @@ namespace OpenRA.Traits
return type;
}
public void Destroy(int2 p)
public void Destroy(CPos p)
{
// Don't break other users of CustomTerrain if there are no resources
if (content[p.X, p.Y].type == null)
@@ -162,7 +163,13 @@ namespace OpenRA.Traits
world.Map.CustomTerrain[p.X, p.Y] = null;
}
public ResourceType GetResource(int2 p) { return content[p.X, p.Y].type; }
public ResourceType GetResource(CPos p) { return content[p.X, p.Y].type; }
public int GetResourceDensity(CPos p) { return content[p.X, p.Y].density; }
public int GetMaxResourceDensity(CPos p)
{
if (content[p.X, p.Y].image == null) return 0;
return content[p.X, p.Y].image.Length - 1;
}
public struct CellContents
{

View File

@@ -54,22 +54,22 @@ namespace OpenRA.Traits
// cache of positions that were added, so no matter what crazy trait code does, it
// can't make us invalid.
class ActorVisibility { public int range; public int2[] vis; }
class ActorVisibility { public int range; public CPos[] vis; }
Dictionary<Actor, ActorVisibility> vis = new Dictionary<Actor, ActorVisibility>();
static IEnumerable<int2> FindVisibleTiles(World world, int2 a, int r)
static IEnumerable<CPos> FindVisibleTiles(World world, CPos a, int r)
{
var min = a - new int2(r, r);
var max = a + new int2(r, r);
if (min.X < world.Map.Bounds.Left - 1) min.X = world.Map.Bounds.Left - 1;
if (min.Y < world.Map.Bounds.Top - 1) min.Y = world.Map.Bounds.Top - 1;
if (max.X > world.Map.Bounds.Right) max.X = world.Map.Bounds.Right;
if (max.Y > world.Map.Bounds.Bottom) max.Y = world.Map.Bounds.Bottom;
var min = a - new CVec(r, r);
var max = a + new CVec(r, r);
if (min.X < world.Map.Bounds.Left - 1) min = new CPos(world.Map.Bounds.Left - 1, min.Y);
if (min.Y < world.Map.Bounds.Top - 1) min = new CPos(min.X, world.Map.Bounds.Top - 1);
if (max.X > world.Map.Bounds.Right) max = new CPos(world.Map.Bounds.Right, max.Y);
if (max.Y > world.Map.Bounds.Bottom) max = new CPos(max.X, world.Map.Bounds.Bottom);
for (var j = min.Y; j <= max.Y; j++)
for (var i = min.X; i <= max.X; i++)
if (r * r >= (new int2(i, j) - a).LengthSquared)
yield return new int2(i, j);
if (r * r >= (new CPos(i, j) - a).LengthSquared)
yield return new CPos(i, j);
}
void AddActor(Actor a)
@@ -148,7 +148,7 @@ namespace OpenRA.Traits
AddActor(a);
}
public static IEnumerable<int2> GetVisOrigins(Actor a)
public static IEnumerable<CPos> GetVisOrigins(Actor a)
{
var ios = a.OccupiesSpace;
if (ios != null)
@@ -157,7 +157,7 @@ namespace OpenRA.Traits
if (cells.Any()) return cells.Select(c => c.First);
}
return new[] { a.CenterLocation / Game.CellSize };
return new[] { a.CenterLocation.ToCPos() };
}
void RemoveActor(Actor a)
@@ -183,7 +183,7 @@ namespace OpenRA.Traits
RemoveActor(a); AddActor(a);
}
public void Explore(World world, int2 center, int range)
public void Explore(World world, CPos center, int range)
{
foreach (var q in FindVisibleTiles(world, center, range))
exploredCells[q.X, q.Y] = true;
@@ -216,7 +216,7 @@ namespace OpenRA.Traits
Dirty();
}
public bool IsExplored(int2 xy) { return IsExplored(xy.X, xy.Y); }
public bool IsExplored(CPos xy) { return IsExplored(xy.X, xy.Y); }
public bool IsExplored(int x, int y)
{
if (!map.IsInMap(x, y))
@@ -228,7 +228,7 @@ namespace OpenRA.Traits
return exploredCells[x,y];
}
public bool IsVisible(int2 xy) { return IsVisible(xy.X, xy.Y); }
public bool IsVisible(CPos xy) { return IsVisible(xy.X, xy.Y); }
public bool IsVisible(int x, int y)
{
if (Disabled)

View File

@@ -75,7 +75,7 @@ namespace OpenRA.Traits
yield return a;
}
public IEnumerable<Actor> ActorsInBox(int2 a, int2 b)
public IEnumerable<Actor> ActorsInBox(PPos a, PPos b)
{
var r = Rectangle.FromLTRB(a.X, a.Y, b.X, b.Y);

View File

@@ -16,11 +16,11 @@ namespace OpenRA.Widgets
{
public override void Draw()
{
var s = WidgetUtils.FormatTime(Game.LocalTick);
var font = Game.Renderer.Fonts["Title"];
var rb = RenderBounds;
var s = WidgetUtils.FormatTime(Game.LocalTick) + (Game.orderManager.GamePaused?" (paused)":"");
var pos = new float2(rb.Left - font.Measure(s).X / 2, rb.Top);
font.DrawTextWithContrast(s, pos, Color.White, Color.Black, 1);
}
}

View File

@@ -42,12 +42,12 @@ namespace OpenRA.Widgets
return;
}
Game.Renderer.WorldLineRenderer.DrawRect(selbox.Value.First, selbox.Value.Second, Color.White);
Game.Renderer.WorldLineRenderer.DrawRect(selbox.Value.First.ToFloat2(), selbox.Value.Second.ToFloat2(), Color.White);
foreach (var u in SelectActorsInBox(world, selbox.Value.First, selbox.Value.Second, _ => true))
worldRenderer.DrawRollover(u);
}
int2 dragStart, dragEnd;
PPos dragStart, dragEnd;
public override bool HandleMouseInput(MouseInput mi)
{
@@ -101,7 +101,7 @@ namespace OpenRA.Widgets
return true;
}
public Pair<int2, int2>? SelectionBox
public Pair<PPos, PPos>? SelectionBox
{
get
{
@@ -110,11 +110,11 @@ namespace OpenRA.Widgets
}
}
public void ApplyOrders(World world, int2 xy, MouseInput mi)
public void ApplyOrders(World world, PPos xy, MouseInput mi)
{
if (world.OrderGenerator == null) return;
var orders = world.OrderGenerator.Order(world, Traits.Util.CellContaining(xy), mi).ToArray();
var orders = world.OrderGenerator.Order(world, xy.ToCPos(), mi).ToArray();
orders.Do( o => world.IssueOrder( o ) );
world.PlayVoiceForOrders(orders);
@@ -135,7 +135,7 @@ namespace OpenRA.Widgets
};
// TODO: fix this up.
return world.OrderGenerator.GetCursor( world, Game.viewport.ViewToWorld(mi).ToInt2(), mi );
return world.OrderGenerator.GetCursor( world, Game.viewport.ViewToWorld(mi), mi );
} );
}
@@ -148,6 +148,10 @@ namespace OpenRA.Widgets
world.Selection.DoControlGroup(world, e.KeyName[0] - '0', e.Modifiers);
return true;
}
else if(e.KeyName == "pause" || e.KeyName == "f3")
{
world.IssueOrder(Order.PauseRequest());
}
bool handled = false;
@@ -157,7 +161,7 @@ namespace OpenRA.Widgets
}
static readonly Actor[] NoActors = {};
IEnumerable<Actor> SelectActorsInBox(World world, int2 a, int2 b, Func<Actor, bool> cond)
IEnumerable<Actor> SelectActorsInBox(World world, PPos a, PPos b, Func<Actor, bool> cond)
{
return world.FindUnits(a, b)
.Where( x => x.HasTrait<Selectable>() && world.LocalShroud.IsVisible(x) && cond(x) )

View File

@@ -183,7 +183,7 @@ namespace OpenRA
while (frameEndActions.Count != 0)
frameEndActions.Dequeue()(this);
Game.viewport.Tick();
}
public IEnumerable<Actor> Actors { get { return actors; } }

View File

@@ -27,24 +27,24 @@ namespace OpenRA
return FindUnits(world, loc, loc).Where(a => world.LocalShroud.IsVisible(a));
}
public static IEnumerable<Actor> FindUnits(this World world, int2 a, int2 b)
public static IEnumerable<Actor> FindUnits(this World world, PPos a, PPos b)
{
var u = float2.Min(a, b).ToInt2();
var v = float2.Max(a, b).ToInt2();
var u = PPos.Min(a, b);
var v = PPos.Max(a, b);
return world.WorldActor.Trait<SpatialBins>().ActorsInBox(u,v);
}
public static Actor ClosestTo( this IEnumerable<Actor> actors, int2 px )
public static Actor ClosestTo(this IEnumerable<Actor> actors, PPos px)
{
return actors.OrderBy( a => (a.CenterLocation - px).LengthSquared ).FirstOrDefault();
}
public static IEnumerable<Actor> FindUnitsInCircle(this World world, int2 a, int r)
public static IEnumerable<Actor> FindUnitsInCircle(this World world, PPos a, int r)
{
using (new PerfSample("FindUnitsInCircle"))
{
var min = a - new int2(r, r);
var max = a + new int2(r, r);
var min = a - PVecInt.FromRadius(r);
var max = a + PVecInt.FromRadius(r);
var actors = world.FindUnits(min, max);
@@ -56,48 +56,48 @@ namespace OpenRA
}
}
public static IEnumerable<int2> FindTilesInCircle(this World world, int2 a, int r)
public static IEnumerable<CPos> FindTilesInCircle(this World world, CPos a, int r)
{
var min = world.ClampToWorld(a - new int2(r, r));
var max = world.ClampToWorld(a + new int2(r, r));
var min = world.ClampToWorld(a - new CVec(r, r));
var max = world.ClampToWorld(a + new CVec(r, r));
for (var j = min.Y; j <= max.Y; j++)
for (var i = min.X; i <= max.X; i++)
if (r * r >= (new int2(i, j) - a).LengthSquared)
yield return new int2(i, j);
if (r * r >= (new CPos(i, j) - a).LengthSquared)
yield return new CPos(i, j);
}
public static string GetTerrainType(this World world, int2 cell)
public static string GetTerrainType(this World world, CPos cell)
{
var custom = world.Map.CustomTerrain[cell.X, cell.Y];
return custom != null ? custom : world.TileSet.GetTerrainType(world.Map.MapTiles.Value[cell.X, cell.Y]);
}
public static TerrainTypeInfo GetTerrainInfo(this World world, int2 cell)
public static TerrainTypeInfo GetTerrainInfo(this World world, CPos cell)
{
return world.TileSet.Terrain[world.GetTerrainType(cell)];
}
public static int2 ClampToWorld( this World world, int2 xy )
public static CPos ClampToWorld(this World world, CPos xy)
{
var r = world.Map.Bounds;
return xy.Clamp(new Rectangle(r.X,r.Y,r.Width-1, r.Height-1));
}
public static int2 ChooseRandomEdgeCell(this World w)
public static CPos ChooseRandomEdgeCell(this World w)
{
var isX = w.SharedRandom.Next(2) == 0;
var edge = w.SharedRandom.Next(2) == 0;
return new int2(
return new CPos(
isX ? w.SharedRandom.Next(w.Map.Bounds.Left, w.Map.Bounds.Right)
: (edge ? w.Map.Bounds.Left : w.Map.Bounds.Right),
!isX ? w.SharedRandom.Next(w.Map.Bounds.Top, w.Map.Bounds.Bottom)
: (edge ? w.Map.Bounds.Top : w.Map.Bounds.Bottom));
}
public static int2 ChooseRandomCell(this World w, Thirdparty.Random r)
public static CPos ChooseRandomCell(this World w, Thirdparty.Random r)
{
return new int2(
return new CPos(
r.Next(w.Map.Bounds.Left, w.Map.Bounds.Right),
r.Next(w.Map.Bounds.Top, w.Map.Bounds.Bottom));
}

View File

@@ -27,8 +27,8 @@ namespace OpenRA.Mods.Cnc
readonly RenderUnit ru;
State state;
int2 startDock;
int2 endDock;
PPos startDock;
PPos endDock;
public HarvesterDockSequence(Actor self, Actor proc)
{
this.proc = proc;
@@ -36,7 +36,7 @@ namespace OpenRA.Mods.Cnc
harv = self.Trait<Harvester>();
ru = self.Trait<RenderUnit>();
startDock = self.Trait<IHasLocation>().PxPosition;
endDock = proc.Trait<IHasLocation>().PxPosition + new int2(-15,8);
endDock = proc.Trait<IHasLocation>().PxPosition + new PVecInt(-15,8);
}
public override Activity Tick(Actor self)

View File

@@ -22,7 +22,7 @@ namespace OpenRA.Mods.Cnc.Effects
Animation anim;
Actor firedBy;
public IonCannon(Actor firedBy, World world, int2 location)
public IonCannon(Actor firedBy, World world, CPos location)
{
this.firedBy = firedBy;
target = Target.FromCell(location);
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.Cnc.Effects
public IEnumerable<Renderable> Render()
{
yield return new Renderable(anim.Image,
target.CenterLocation - new float2(.5f * anim.Image.size.X, anim.Image.size.Y - Game.CellSize),
target.CenterLocation.ToFloat2() - new float2(.5f * anim.Image.size.X, anim.Image.size.Y - Game.CellSize),
"effect", (int)target.CenterLocation.Y);
}

View File

@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Cnc
{
self.World.AddFrameEndTask(w =>
{
Sound.Play(Info.LaunchSound, Game.CellSize * order.TargetLocation.ToFloat2());
Sound.Play(Info.LaunchSound, order.TargetLocation.ToPPos());
w.Add(new IonCannon(self, w, order.TargetLocation));
});
}

View File

@@ -22,13 +22,13 @@ namespace OpenRA.Mods.RA
class CncShellmapScript: IWorldLoaded, ITick
{
Dictionary<string, Actor> Actors;
static int2 ViewportOrigin;
static CPos ViewportOrigin;
public void WorldLoaded(World w)
{
var b = w.Map.Bounds;
ViewportOrigin = new int2(b.Left + b.Width/2, b.Top + b.Height/2);
Game.MoveViewport(ViewportOrigin);
ViewportOrigin = new CPos(b.Left + b.Width/2, b.Top + b.Height/2);
Game.MoveViewport(ViewportOrigin.ToFloat2());
Actors = w.WorldActor.Trait<SpawnMapActors>().Actors;
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA
void SetViewport()
{
var t = (ticks + 45) % (360f * speed) * (Math.PI / 180) * 1f / speed;
var loc = ViewportOrigin + new float2(-15,4) * float2.FromAngle( (float)t );
var loc = ViewportOrigin.ToFloat2() + (new float2(-15,4) * float2.FromAngle( (float)t ));
Game.viewport.Center(loc);
}
@@ -78,7 +78,7 @@ namespace OpenRA.Mods.RA
}));
}
void LoopTrack(Actor self, int2 left, int2 right)
void LoopTrack(Actor self, CPos left, CPos right)
{
var mobile = self.Trait<Mobile>();
self.QueueActivity(mobile.ScriptedMove(left));

View File

@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Cnc
Players = w.Players.ToDictionary(p => p.InternalName);
Actors = w.WorldActor.Trait<SpawnMapActors>().Actors;
var b = w.Map.Bounds;
Game.MoveViewport(new int2(b.Left + b.Width/2, b.Top + b.Height/2));
Game.MoveViewport(new CPos(b.Left + b.Width/2, b.Top + b.Height/2).ToFloat2());
Scripting.Media.PlayFMVFullscreen(w, "gdi1.vqa",
() => Scripting.Media.PlayFMVFullscreen(w, "landing.vqa", () =>
@@ -130,7 +130,7 @@ namespace OpenRA.Mods.Cnc
ReinforceFromSea(self.World,
Actors["lstStart"].Location,
Actors["lstEnd"].Location,
new int2(53,53),
new CPos(53, 53),
new string[] {"e1","e1","e1"},
Players["GoodGuy"]);
}
@@ -140,7 +140,7 @@ namespace OpenRA.Mods.Cnc
ReinforceFromSea(self.World,
Actors["lstStart"].Location,
Actors["lstEnd"].Location,
new int2(53,53),
new CPos(53, 53),
new string[] {"e1","e1","e1"},
Players["GoodGuy"]);
}
@@ -150,7 +150,7 @@ namespace OpenRA.Mods.Cnc
ReinforceFromSea(self.World,
Actors["lstStart"].Location,
Actors["lstEnd"].Location,
new int2(53,53),
new CPos(53, 53),
new string[] {"jeep"},
Players["GoodGuy"]);
}
@@ -160,7 +160,7 @@ namespace OpenRA.Mods.Cnc
ReinforceFromSea(self.World,
Actors["lstStart"].Location,
Actors["lstEnd"].Location,
new int2(53,53),
new CPos(53, 53),
new string[] {"jeep"},
Players["GoodGuy"]);
}
@@ -177,7 +177,7 @@ namespace OpenRA.Mods.Cnc
self.QueueActivity(new CallFunc(() => SetGunboatPath()));
}
void ReinforceFromSea(World world, int2 startPos, int2 endPos, int2 unload, string[] items, Player player)
void ReinforceFromSea(World world, CPos startPos, CPos endPos, CPos unload, string[] items, Player player)
{
world.AddFrameEndTask(w =>
{

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -12,6 +12,25 @@
<AssemblyName>OpenRA.Mods.Cnc</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation />
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -27,6 +46,7 @@
<Command type="AfterBuild" command="mono RALint.exe cnc" workingdir="${ProjectDir}/../" />
</CustomCommands>
</CustomCommands>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -35,6 +55,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@@ -113,6 +134,23 @@
<Private>False</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View File

@@ -36,8 +36,8 @@ namespace OpenRA.Mods.Cnc
// Start a fixed distance away: the width of the map.
// This makes the production timing independent of spawnpoint
var startPos = self.Location + new int2(owner.World.Map.Bounds.Width, 0);
var endPos = new int2(owner.World.Map.Bounds.Left - 5, self.Location.Y);
var startPos = self.Location + new CVec(owner.World.Map.Bounds.Width, 0);
var endPos = new CPos(owner.World.Map.Bounds.Left - 5, self.Location.Y);
// Assume a single exit point for simplicity
var exit = self.Info.Traits.WithInterface<ExitInfo>().First();
@@ -57,7 +57,7 @@ namespace OpenRA.Mods.Cnc
new AltitudeInit( Rules.Info[actorType].Traits.Get<PlaneInfo>().CruiseAltitude ),
});
a.QueueActivity(Fly.ToCell(self.Location + new int2(6,0)));
a.QueueActivity(Fly.ToCell(self.Location + new CVec(6, 0)));
a.QueueActivity(new Land(Target.FromActor(self)));
a.QueueActivity(new CallFunc(() =>
{

View File

@@ -15,31 +15,43 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Cnc
{
class RenderCargoInfo : ITraitInfo, Requires<CargoInfo>
public class RenderCargoInfo : ITraitInfo, Requires<CargoInfo>
{
public object Create(ActorInitializer init) { return new RenderCargo(init.self); }
/* altitude of the cargo, relative to us. -ve is underneath us */
public readonly int RelativeAltitude = 0;
public object Create(ActorInitializer init) { return new RenderCargo(init.self, this); }
}
public class RenderCargo : IRenderModifier
{
Cargo cargo;
IFacing facing;
IMove move;
RenderCargoInfo Info;
public RenderCargo(Actor self)
public RenderCargo(Actor self, RenderCargoInfo info)
{
cargo = self.Trait<Cargo>();
facing = self.TraitOrDefault<IFacing>();
move = self.Trait<IMove>();
Info = info;
}
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
{
foreach (var c in cargo.Passengers)
{
c.Trait<ITeleportable>().SetPxPosition( c, self.Trait<IHasLocation>().PxPosition );
if (facing != null && c.HasTrait<IFacing>())
c.Trait<IFacing>().Facing = facing.Facing;
c.Trait<ITeleportable>().SetPxPosition( c, move.PxPosition );
var cargoFacing = c.TraitOrDefault<IFacing>();
if (facing != null && cargoFacing != null)
cargoFacing.Facing = facing.Facing;
}
return r.Concat(cargo.Passengers.SelectMany(a => a.Render()));
return r.Concat(cargo.Passengers.SelectMany(a => a.Render())
.Select(a => a.WithPos(a.Pos - new float2(0, Info.RelativeAltitude))
.WithZOffset(a.ZOffset + Info.RelativeAltitude)));
}
}
}

View File

@@ -62,7 +62,7 @@ namespace OpenRA.Mods.Cnc.Widgets
public void UpdateMouseover()
{
TooltipType = WorldTooltipType.None;
var cell = Game.viewport.ViewToWorld(Viewport.LastMousePos).ToInt2();
var cell = Game.viewport.ViewToWorld(Viewport.LastMousePos);
if (!world.Map.IsInMap(cell))
return;

View File

@@ -86,6 +86,10 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
Game.viewport.Zoom = graphicsSettings.PixelDouble ? 2 : 1;
};
var showShellmapCheckbox = generalPane.Get<CheckboxWidget>("SHOW_SHELLMAP");
showShellmapCheckbox.IsChecked = () => gameSettings.ShowShellmap;
showShellmapCheckbox.OnClick = () => gameSettings.ShowShellmap ^= true;
generalPane.Get("WINDOW_RESOLUTION").IsVisible = () => graphicsSettings.Mode == WindowMode.Windowed;
var windowWidth = generalPane.Get<TextFieldWidget>("WINDOW_WIDTH");
windowWidth.Text = graphicsSettings.WindowedSize.X.ToString();

View File

@@ -32,8 +32,10 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
var powerLabel = widget.Get<LabelWidget>("POWER");
var timeLabel = widget.Get<LabelWidget>("TIME");
var costLabel = widget.Get<LabelWidget>("COST");
var descLabel = widget.Get<LabelWidget>("DESC");
var font = Game.Renderer.Fonts[nameLabel.Font];
var descFont = Game.Renderer.Fonts[descLabel.Font];
var requiresFont = Game.Renderer.Fonts[requiresLabel.Font];
string lastActor = null;
@@ -70,12 +72,18 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
costLabel.GetColor = () => pr.DisplayCash + pr.DisplayOre >= cost
? Color.White : Color.Red;
var leftWidth = Math.Max(font.Measure(tooltip.Name).X, requiresFont.Measure(requiresString).X);
var descString = tooltip.Description.Replace("\\n", "\n");
descLabel.GetText = () => descString;
var leftWidth = new [] {font.Measure(tooltip.Name).X, requiresFont.Measure(requiresString).X, descFont.Measure(descString).X}.Aggregate(Math.Max);
var rightWidth = new [] {font.Measure(powerString).X, font.Measure(timeString).X, font.Measure(costString).X}.Aggregate(Math.Max);
timeLabel.Bounds.X = powerLabel.Bounds.X = costLabel.Bounds.X = leftWidth + 2*nameLabel.Bounds.X;
widget.Bounds.Width = leftWidth + rightWidth + 3*nameLabel.Bounds.X;
widget.Bounds.Height = power != 0 ? 65 : 45;
var leftHeight = font.Measure(tooltip.Name).Y + requiresFont.Measure(requiresString).Y + descFont.Measure(descString).Y;
var rightHeight = font.Measure(powerString).Y + font.Measure(timeString).Y + font.Measure(costString).Y;
widget.Bounds.Height = Math.Max(leftHeight, rightHeight)*3/2 + 3*nameLabel.Bounds.Y;
lastActor = actor;
};
}

View File

@@ -0,0 +1,43 @@
#region Copyright & License Information
/*
* Copyright 2007-2012 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. For more information,
* see COPYING.
*/
#endregion
using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
class CaptureNotificationInfo : ITraitInfo
{
public readonly string Race = null;
public readonly string Notification = null;
public object Create(ActorInitializer init) { return new CaptureNotification(this); }
}
class CaptureNotification : INotifyCapture
{
CaptureNotificationInfo Info;
public CaptureNotification(CaptureNotificationInfo info)
{
Info = info;
}
public void OnCapture (Actor self, Actor captor, Player oldOwner, Player newOwner)
{
if (captor.World.LocalPlayer != captor.Owner)
return;
if (Info.Race != null && Info.Race != newOwner.Country.Race)
return;
Sound.PlayToPlayer(captor.World.LocalPlayer, Info.Notification);
}
}
}

View File

@@ -0,0 +1,93 @@
#region Copyright & License Information
/*
* Copyright 2012 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. For more information,
* see COPYING.
*/
#endregion
using System.Collections.Generic;
using System.IO;
using System.Drawing;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Network;
using OpenRA.Support;
using OpenRA.Widgets;
namespace OpenRA.Mods.D2k
{
public class D2kLoadScreen : ILoadScreen
{
Dictionary<string, string> Info;
static string[] Comments = new[] {"Filling Crates...", "Breeding Sandworms..."};
Stopwatch lastLoadScreen = new Stopwatch();
Rectangle StripeRect;
Sprite Stripe, Logo;
float2 LogoPos;
Renderer r;
public void Init(Dictionary<string, string> info)
{
Info = info;
// Avoid standard loading mechanisms so we
// can display loadscreen as early as possible
r = Game.Renderer;
if (r == null) return;
var s = new Sheet("mods/d2k/uibits/loadscreen.png");
Logo = new Sprite(s, new Rectangle(0,0,256,256), TextureChannel.Alpha);
Stripe = new Sprite(s, new Rectangle(256,0,256,256), TextureChannel.Alpha);
StripeRect = new Rectangle(0, Renderer.Resolution.Height/2 - 128, Renderer.Resolution.Width, 256);
LogoPos = new float2(Renderer.Resolution.Width/2 - 128, Renderer.Resolution.Height/2 - 128);
}
public void Display()
{
if (r == null)
return;
// Update text at most every 0.5 seconds
if (lastLoadScreen.ElapsedTime() < 0.5)
return;
lastLoadScreen.Reset();
var text = Comments.Random(Game.CosmeticRandom);
var textSize = r.Fonts["Bold"].Measure(text);
r.BeginFrame(float2.Zero, 1f);
WidgetUtils.FillRectWithSprite(StripeRect, Stripe);
r.RgbaSpriteRenderer.DrawSprite(Logo, LogoPos);
r.Fonts["Bold"].DrawText(text, new float2(Renderer.Resolution.Width - textSize.X - 20, Renderer.Resolution.Height - textSize.Y - 20), Color.White);
r.EndFrame( new NullInputHandler() );
}
public void StartGame()
{
TestAndContinue();
Game.JoinExternalGame();
}
void TestAndContinue()
{
Ui.ResetAll();
if (!FileSystem.Exists(Info["TestFile"]))
{
var args = new WidgetArgs()
{
{ "continueLoading", () => TestAndContinue() },
{ "installData", Info }
};
Ui.OpenWindow(Info["InstallerMenuWidget"], args);
}
else
{
Game.LoadShellMap();
Ui.ResetAll();
Ui.OpenWindow("MAINMENU_BG");
}
}
}
}

View File

@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{C0B0465C-6BE2-409C-8770-3A9BF64C4344}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>OpenRA.Mods.D2k</RootNamespace>
<AssemblyName>OpenRA.Mods.D2k</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation />
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<OutputPath>bin\Debug</OutputPath>
<CustomCommands>
<CustomCommands>
<Command type="AfterBuild" command="cp ${TargetFile} ../mods/d2k" workingdir="${ProjectDir}" />
<Command type="AfterBuild" command="mono RALint.exe d2k" workingdir="${ProjectDir}/../" />
</CustomCommands>
</CustomCommands>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="System.Drawing" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="D2kLoadScreen.cs" />
<Compile Include="Widgets\Logic\D2kInstallLogic.cs" />
<Compile Include="Widgets\Logic\D2kExtractGameFilesLogic.cs" />
<Compile Include="Widgets\Logic\D2kInstallFromCDLogic.cs" />
<Compile Include="Widgets\Logic\D2kDownloadPackagesLogic.cs" />
<Compile Include="BuildingCaptureNotification.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>mkdir "$(SolutionDir)mods/d2k/"
copy "$(TargetPath)" "$(SolutionDir)mods/d2k/"
cd "$(SolutionDir)"</PostBuildEvent>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\OpenRA.Utility\OpenRA.Utility.csproj">
<Project>{F33337BE-CB69-4B24-850F-07D23E408DDF}</Project>
<Name>OpenRA.Utility</Name>
</ProjectReference>
<ProjectReference Include="..\OpenRA.Game\OpenRA.Game.csproj">
<Project>{0DFB103F-2962-400F-8C6D-E2C28CCBA633}</Project>
<Name>OpenRA.Game</Name>
</ProjectReference>
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
<Project>{BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}</Project>
<Name>OpenRA.FileFormats</Name>
</ProjectReference>
<ProjectReference Include="..\OpenRA.TilesetBuilder\OpenRA.TilesetBuilder.csproj">
<Project>{1A8E50CC-EE32-4E57-8842-0C39C8EA7541}</Project>
<Name>OpenRA.TilesetBuilder</Name>
</ProjectReference>
<ProjectReference Include="..\OpenRA.Mods.RA\OpenRA.Mods.RA.csproj">
<Project>{4A8A43B5-A9EF-4ED0-99DD-4BAB10A0DB6E}</Project>
<Name>OpenRA.Mods.RA</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRA.Mods.D2k", "OpenRA.Mods.D2k.csproj", "{C0B0465C-6BE2-409C-8770-3A9BF64C4344}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C0B0465C-6BE2-409C-8770-3A9BF64C4344}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C0B0465C-6BE2-409C-8770-3A9BF64C4344}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C0B0465C-6BE2-409C-8770-3A9BF64C4344}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C0B0465C-6BE2-409C-8770-3A9BF64C4344}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = OpenRA.Mods.D2k.csproj
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,39 @@
#region Copyright & License Information
/*
* Copyright 2012 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. For more information,
* see COPYING.
*/
#endregion
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("OpenRA.Mods.D2k")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OpenRA.Mods.D2k")]
[assembly: AssemblyCopyright("Copyright © 2012")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

View File

@@ -0,0 +1,111 @@
#region Copyright & License Information
/*
* Copyright 2007-2012 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. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using OpenRA.FileFormats;
using OpenRA.Widgets;
namespace OpenRA.Mods.D2k.Widgets.Logic
{
public class D2kDownloadPackagesLogic
{
Widget panel;
Dictionary<string,string> installData;
ProgressBarWidget progressBar;
LabelWidget statusLabel;
Action afterInstall;
[ObjectCreator.UseCtor]
public D2kDownloadPackagesLogic(Widget widget, Dictionary<string,string> installData, Action afterInstall)
{
this.installData = installData;
this.afterInstall = afterInstall;
panel = widget.Get("INSTALL_DOWNLOAD_PANEL");
progressBar = panel.Get<ProgressBarWidget>("PROGRESS_BAR");
statusLabel = panel.Get<LabelWidget>("STATUS_LABEL");
ShowDownloadDialog();
}
void ShowDownloadDialog()
{
statusLabel.GetText = () => "Initializing...";
progressBar.SetIndeterminate(true);
var retryButton = panel.Get<ButtonWidget>("RETRY_BUTTON");
retryButton.IsVisible = () => false;
var cancelButton = panel.Get<ButtonWidget>("CANCEL_BUTTON");
// Save the package to a temp file
var file = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
var dest = new string[] { Platform.SupportDir, "Content", Game.modData.Manifest.Mods[0] }.Aggregate(Path.Combine);
Action<DownloadProgressChangedEventArgs> onDownloadProgress = i =>
{
if (progressBar.Indeterminate)
progressBar.SetIndeterminate(false);
progressBar.Percentage = i.ProgressPercentage;
statusLabel.GetText = () => "Downloading {1}/{2} kB ({0}%)".F(i.ProgressPercentage, i.BytesReceived / 1024, i.TotalBytesToReceive / 1024);
};
Action<string> onExtractProgress = s =>
{
Game.RunAfterTick(() => statusLabel.GetText = () => s);
};
Action<string> onError = s =>
{
Game.RunAfterTick(() =>
{
statusLabel.GetText = () => "Error: "+s;
retryButton.IsVisible = () => true;
});
};
Action<AsyncCompletedEventArgs, bool> onDownloadComplete = (i, cancelled) =>
{
if (i.Error != null)
{
onError(Download.FormatErrorMessage(i.Error));
return;
}
else if (cancelled)
{
onError("Download cancelled");
return;
}
// Automatically extract
statusLabel.GetText = () => "Extracting...";
progressBar.SetIndeterminate(true);
if (InstallUtils.ExtractZip(file, dest, onExtractProgress, onError))
{
Game.RunAfterTick(() =>
{
Ui.CloseWindow();
afterInstall();
});
}
};
var dl = new Download(installData["PackageURL"], file, onDownloadProgress, onDownloadComplete);
cancelButton.OnClick = () => { dl.Cancel(); Ui.CloseWindow(); };
retryButton.OnClick = () => { dl.Cancel(); ShowDownloadDialog(); };
}
}
}

View File

@@ -0,0 +1,561 @@
#region Copyright & License Information
/*
* Copyright 2007-2012 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. For more information,
* see COPYING.
*/
#endregion
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Diagnostics;
using OpenRA.FileFormats;
using OpenRA.FileFormats.Graphics;
using OpenRA.Widgets;
using OpenRA.Utility;
namespace OpenRA.Mods.D2k.Widgets.Logic
{
public class D2kExtractGameFilesLogic
{
Widget panel;
ProgressBarWidget progressBar;
LabelWidget statusLabel;
Action continueLoading;
ButtonWidget retryButton, backButton;
Widget extractingContainer, copyFilesContainer;
[ObjectCreator.UseCtor]
public D2kExtractGameFilesLogic(Widget widget, Action continueLoading)
{
panel = widget.Get("EXTRACT_GAMEFILES_PANEL");
progressBar = panel.Get<ProgressBarWidget>("PROGRESS_BAR");
statusLabel = panel.Get<LabelWidget>("STATUS_LABEL");
backButton = panel.Get<ButtonWidget>("BACK_BUTTON");
backButton.OnClick = Ui.CloseWindow;
retryButton = panel.Get<ButtonWidget>("RETRY_BUTTON");
retryButton.OnClick = Extract;
extractingContainer = panel.Get("EXTRACTING");
copyFilesContainer = panel.Get("COPY_FILES");
Extract();
this.continueLoading = continueLoading;
}
void Extract()
{
backButton.IsDisabled = () => true;
retryButton.IsDisabled = () => true;
copyFilesContainer.IsVisible = () => false;
extractingContainer.IsVisible = () => true;
var PathToDataR8 = Path.Combine(Platform.SupportDir, "Content/d2k/DATA.R8");
var PathToPalette = "mods/d2k/bits/d2k.pal";
var PathToSHPs = Path.Combine(Platform.SupportDir, "Content/d2k/SHPs");
var PathToTilesets = Path.Combine(Platform.SupportDir, "Content/d2k/Tilesets");
var ExtractGameFiles = new string[][]
{
new string[] {"--r8", PathToDataR8, PathToPalette, "0", "2", Path.Combine(PathToSHPs, "overlay")},
new string[] {"--r8", PathToDataR8, PathToPalette, "3", "3", Path.Combine(PathToSHPs, "repairing")},
new string[] {"--r8", PathToDataR8, PathToPalette, "15", "16", Path.Combine(PathToSHPs, "dots")},
new string[] {"--r8", PathToDataR8, PathToPalette, "17", "26", Path.Combine(PathToSHPs, "numbers")},
//new string[] {"--r8", PathToDataR8, PathToPalette, "40", "101", Path.Combine(PathToSHPs, "shadow")},
new string[] {"--r8", PathToDataR8, PathToPalette, "102", "105", Path.Combine(PathToSHPs, "crates")},
new string[] {"--r8", PathToDataR8, PathToPalette, "107", "109", Path.Combine(PathToSHPs, "spicebloom")},
new string[] {"--r8", PathToDataR8, PathToPalette, "110", "111", Path.Combine(PathToSHPs, "stars")},
new string[] {"--r8", PathToDataR8, PathToPalette, "112", "112", Path.Combine(PathToSHPs, "greenuparrow")},
new string[] {"--r8", PathToDataR8, PathToPalette, "114", "129", Path.Combine(PathToSHPs, "rockcrater1")},
new string[] {"--r8", PathToDataR8, PathToPalette, "130", "145", Path.Combine(PathToSHPs, "rockcrater2")},
new string[] {"--r8", PathToDataR8, PathToPalette, "146", "161", Path.Combine(PathToSHPs, "sandcrater1")},
new string[] {"--r8", PathToDataR8, PathToPalette, "162", "177", Path.Combine(PathToSHPs, "sandcrater2")},
// ?
new string[] {"--r8", PathToDataR8, PathToPalette, "206", "381", Path.Combine(PathToSHPs, "rifle"), "--infantry"},
new string[] {"--r8", PathToDataR8, PathToPalette, "382", "457", Path.Combine(PathToSHPs, "rifledeath"), "--infantrydeath"},
new string[] {"--r8", PathToDataR8, PathToPalette, "458", "693", Path.Combine(PathToSHPs, "bazooka"), "--infantry"},
new string[] {"--r8", PathToDataR8, PathToPalette, "694", "929", Path.Combine(PathToSHPs, "fremen"), "--infantry"},
new string[] {"--r8", PathToDataR8, PathToPalette, "930", "1165", Path.Combine(PathToSHPs, "sardaukar"), "--infantry"},
new string[] {"--r8", PathToDataR8, PathToPalette, "1166", "1221", Path.Combine(PathToSHPs, "engineer"), "--infantry"},
new string[] {"--r8", PathToDataR8, PathToPalette, "1342", "1401", Path.Combine(PathToSHPs, "engineerdeath"), "--infantrydeath"},
new string[] {"--r8", PathToDataR8, PathToPalette, "1402", "1502", Path.Combine(PathToSHPs, "thumper"), "--infantry"},
new string[] {"--r8", PathToDataR8, PathToPalette, "1543", "1602", Path.Combine(PathToSHPs, "thumperdeath"), "--infantrydeath"},
new string[] {"--r8", PathToDataR8, PathToPalette, "1603", "1634", Path.Combine(PathToSHPs, "missiletank"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "1635", "1666", Path.Combine(PathToSHPs, "trike"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "1667", "1698", Path.Combine(PathToSHPs, "quad"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "1699", "1730", Path.Combine(PathToSHPs, "harvester"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "1731", "1762", Path.Combine(PathToSHPs, "combata"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "1763", "1794", Path.Combine(PathToSHPs, "siegetank"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "1795", "1826", Path.Combine(PathToSHPs, "dmcv"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "1827", "1858", Path.Combine(PathToSHPs, "sonictank"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "1859", "1890", Path.Combine(PathToSHPs, "combataturret"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "1891", "1922", Path.Combine(PathToSHPs, "siegeturret"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "1923", "1954", Path.Combine(PathToSHPs, "carryall"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "1955", "2050", Path.Combine(PathToSHPs, "orni"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2051", "2082", Path.Combine(PathToSHPs, "combath"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2083", "2114", Path.Combine(PathToSHPs, "devast"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2115", "2146", Path.Combine(PathToSHPs, "combathturret"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2147", "2148", Path.Combine(PathToSHPs, "deathhandmissile")},
new string[] {"--r8", PathToDataR8, PathToPalette, "2245", "2284", Path.Combine(PathToSHPs, "saboteur"), "--infantry"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2325", "2388", Path.Combine(PathToSHPs, "saboteurdeath"), "--infantrydeath"},
//rifleinfantry repetitions?
new string[] {"--r8", PathToDataR8, PathToPalette, "2389", "2420", Path.Combine(PathToSHPs, "deviatortank"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2421", "2452", Path.Combine(PathToSHPs, "raider"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2453", "2484", Path.Combine(PathToSHPs, "combato"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2485", "2516", Path.Combine(PathToSHPs, "combatoturret"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2517", "2517", Path.Combine(PathToSHPs, "frigate"), "--vehicle"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2518", "2520", Path.Combine(PathToSHPs, "heavya"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2521", "2522", Path.Combine(PathToSHPs, "radara"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2523", "2524", Path.Combine(PathToSHPs, "pwra"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2525", "2526", Path.Combine(PathToSHPs, "barra"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2527", "2558", Path.Combine(PathToSHPs, "walla"), "--wall"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2559", "2560", Path.Combine(PathToSHPs, "conyarda"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2561", "2563", Path.Combine(PathToSHPs, "refa"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2564", "2565", Path.Combine(PathToSHPs, "hightecha"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2566", "2570", Path.Combine(PathToSHPs, "siloa"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2571", "2572", Path.Combine(PathToSHPs, "repaira"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2573", "2588", Path.Combine(PathToSHPs, "guntowera"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2589", "2620", Path.Combine(PathToSHPs, "gunturreta"), "--turret"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2621", "2636", Path.Combine(PathToSHPs, "rockettowera"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2637", "2668", Path.Combine(PathToSHPs, "rocketturreta"), "--turret"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2669", "2670", Path.Combine(PathToSHPs, "researcha"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2671", "2672", Path.Combine(PathToSHPs, "starporta"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2673", "2675", Path.Combine(PathToSHPs, "lighta"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2676", "2677", Path.Combine(PathToSHPs, "palacea"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2678", "2680", Path.Combine(PathToSHPs, "heavyh"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2681", "2682", Path.Combine(PathToSHPs, "radarh"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2683", "2684", Path.Combine(PathToSHPs, "pwrh"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2685", "2686", Path.Combine(PathToSHPs, "barrh"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2687", "2718", Path.Combine(PathToSHPs, "wallh"), "--wall"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2719", "2720", Path.Combine(PathToSHPs, "conyardh"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2721", "2723", Path.Combine(PathToSHPs, "refh"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2724", "2725", Path.Combine(PathToSHPs, "hightechh"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2726", "2730", Path.Combine(PathToSHPs, "siloh"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2731", "2732", Path.Combine(PathToSHPs, "repairh"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2733", "2748", Path.Combine(PathToSHPs, "guntowerh"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2749", "2780", Path.Combine(PathToSHPs, "gunturreth"), "--turret"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2781", "2796", Path.Combine(PathToSHPs, "rockettowerh"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2797", "2828", Path.Combine(PathToSHPs, "rocketturreth"), "--turret"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2829", "2830", Path.Combine(PathToSHPs, "researchh"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2831", "2832", Path.Combine(PathToSHPs, "starporth"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2833", "2835", Path.Combine(PathToSHPs, "lighth"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2836", "2837", Path.Combine(PathToSHPs, "palaceh"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2838", "2840", Path.Combine(PathToSHPs, "heavyo"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2841", "2842", Path.Combine(PathToSHPs, "radaro"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2843", "2844", Path.Combine(PathToSHPs, "pwro"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2845", "2846", Path.Combine(PathToSHPs, "barro"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2847", "2878", Path.Combine(PathToSHPs, "wallo"), "--wall"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2879", "2880", Path.Combine(PathToSHPs, "conyardo"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2881", "2883", Path.Combine(PathToSHPs, "refo"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2884", "2885", Path.Combine(PathToSHPs, "hightecho"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2886", "2890", Path.Combine(PathToSHPs, "siloo"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2891", "2892", Path.Combine(PathToSHPs, "repairo"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2893", "2908", Path.Combine(PathToSHPs, "guntowero"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2909", "2940", Path.Combine(PathToSHPs, "gunturreto"), "--turret"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2941", "2956", Path.Combine(PathToSHPs, "rockettowero"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2957", "2988", Path.Combine(PathToSHPs, "rocketturreto"), "--turret"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2989", "2990", Path.Combine(PathToSHPs, "researcho"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2991", "2992", Path.Combine(PathToSHPs, "starporto"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2993", "2995", Path.Combine(PathToSHPs, "lighto"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "2996", "2997", Path.Combine(PathToSHPs, "palaceo"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "3370", "3380", Path.Combine(PathToSHPs, "unload"), "--vehicle"},
//explosions
new string[] {"--r8", PathToDataR8, PathToPalette, "3549", "3564", Path.Combine(PathToSHPs, "wormjaw")},
new string[] {"--r8", PathToDataR8, PathToPalette, "3565", "3585", Path.Combine(PathToSHPs, "wormdust")},
new string[] {"--r8", PathToDataR8, PathToPalette, "3586", "3600", Path.Combine(PathToSHPs, "wormsigns1")},
new string[] {"--r8", PathToDataR8, PathToPalette, "3601", "3610", Path.Combine(PathToSHPs, "wormsigns2")},
new string[] {"--r8", PathToDataR8, PathToPalette, "3611", "3615", Path.Combine(PathToSHPs, "wormsigns3")},
new string[] {"--r8", PathToDataR8, PathToPalette, "3616", "3620", Path.Combine(PathToSHPs, "wormsigns4")},
//new string[] {"--r8", PathToDataR8, PathToPalette, "3679", "3686", "sell"},
//explosions and muzzle flash
new string[] {"--r8", PathToDataR8, PathToPalette, "4011", "4011", Path.Combine(PathToSHPs, "rifleicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4012", "4012", Path.Combine(PathToSHPs, "bazookaicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4013", "4013", Path.Combine(PathToSHPs, "engineericon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4014", "4014", Path.Combine(PathToSHPs, "thumpericon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4015", "4015", Path.Combine(PathToSHPs, "sardaukaricon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4016", "4016", Path.Combine(PathToSHPs, "trikeicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4017", "4017", Path.Combine(PathToSHPs, "raidericon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4018", "4018", Path.Combine(PathToSHPs, "quadicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4019", "4019", Path.Combine(PathToSHPs, "harvestericon")}, // == 4044
new string[] {"--r8", PathToDataR8, PathToPalette, "4020", "4020", Path.Combine(PathToSHPs, "combataicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4021", "4021", Path.Combine(PathToSHPs, "combathicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4022", "4022", Path.Combine(PathToSHPs, "combatoicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4023", "4023", Path.Combine(PathToSHPs, "mcvicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4024", "4024", Path.Combine(PathToSHPs, "missiletankicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4025", "4025", Path.Combine(PathToSHPs, "deviatortankicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4026", "4026", Path.Combine(PathToSHPs, "siegetankicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4027", "4027", Path.Combine(PathToSHPs, "sonictankicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4028", "4028", Path.Combine(PathToSHPs, "devasticon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4029", "4029", Path.Combine(PathToSHPs, "carryallicon")}, // == 4030
new string[] {"--r8", PathToDataR8, PathToPalette, "4031", "4031", Path.Combine(PathToSHPs, "orniicon")}, // == 4062
new string[] {"--r8", PathToDataR8, PathToPalette, "4032", "4032", Path.Combine(PathToSHPs, "fremenicon")}, // == 4033
new string[] {"--r8", PathToDataR8, PathToPalette, "4034", "4034", Path.Combine(PathToSHPs, "saboteuricon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4035", "4035", Path.Combine(PathToSHPs, "deathhandicon")},
// "4036..4045 = repetitions
new string[] {"--r8", PathToDataR8, PathToPalette, "4046", "4046", Path.Combine(PathToSHPs, "conyardaicon")}, // == 4049
new string[] {"--r8", PathToDataR8, PathToPalette, "4047", "4047", Path.Combine(PathToSHPs, "conyardhicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4048", "4048", Path.Combine(PathToSHPs, "conyardoicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4050", "4050", Path.Combine(PathToSHPs, "4plateicon")}, // == 4051..4052
new string[] {"--r8", PathToDataR8, PathToPalette, "4053", "4053", Path.Combine(PathToSHPs, "6plateicon")}, // == 4054..4055
new string[] {"--r8", PathToDataR8, PathToPalette, "4056", "4056", Path.Combine(PathToSHPs, "pwraicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4057", "4057", Path.Combine(PathToSHPs, "pwrhicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4058", "4058", Path.Combine(PathToSHPs, "pwroicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4059", "4059", Path.Combine(PathToSHPs, "barraicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4060", "4060", Path.Combine(PathToSHPs, "barrhicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4061", "4061", Path.Combine(PathToSHPs, "barroicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4063", "4063", Path.Combine(PathToSHPs, "wallicon")}, // == 4061..4062
new string[] {"--r8", PathToDataR8, PathToPalette, "4066", "4066", Path.Combine(PathToSHPs, "refaicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4067", "4067", Path.Combine(PathToSHPs, "refhicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4068", "4068", Path.Combine(PathToSHPs, "refoicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4069", "4069", Path.Combine(PathToSHPs, "turreticon")}, // == 4070..4071
new string[] {"--r8", PathToDataR8, PathToPalette, "4072", "4072", Path.Combine(PathToSHPs, "radaraicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4072", "4072", Path.Combine(PathToSHPs, "radaraicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4073", "4073", Path.Combine(PathToSHPs, "radarhicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4074", "4074", Path.Combine(PathToSHPs, "radaroicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4075", "4075", Path.Combine(PathToSHPs, "rturreticon")}, // == 4076..4077
new string[] {"--r8", PathToDataR8, PathToPalette, "4078", "4078", Path.Combine(PathToSHPs, "hightechaicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4079", "4079", Path.Combine(PathToSHPs, "hightechhicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4080", "4080", Path.Combine(PathToSHPs, "hightechoicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4081", "4081", Path.Combine(PathToSHPs, "lightaicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4082", "4082", Path.Combine(PathToSHPs, "lighthicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4083", "4083", Path.Combine(PathToSHPs, "lightoicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4084", "4084", Path.Combine(PathToSHPs, "siloaicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4085", "4085", Path.Combine(PathToSHPs, "silohicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4086", "4086", Path.Combine(PathToSHPs, "silooicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4087", "4087", Path.Combine(PathToSHPs, "heavyaicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4088", "4088", Path.Combine(PathToSHPs, "heavyhicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4089", "4089", Path.Combine(PathToSHPs, "heavyoicon")},
// 4090 == orniicon
// 4091 == heavyhicon
new string[] {"--r8", PathToDataR8, PathToPalette, "4092", "4092", Path.Combine(PathToSHPs, "starportaicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4093", "4093", Path.Combine(PathToSHPs, "starporthicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4094", "4094", Path.Combine(PathToSHPs, "starportoicon")},
// 4095 = orniicon
new string[] {"--r8", PathToDataR8, PathToPalette, "4096", "4096", Path.Combine(PathToSHPs, "repairaicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4097", "4097", Path.Combine(PathToSHPs, "repairhicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4098", "4098", Path.Combine(PathToSHPs, "repairoicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4099", "4099", Path.Combine(PathToSHPs, "researchaicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4100", "4100", Path.Combine(PathToSHPs, "researchhicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4101", "4101", Path.Combine(PathToSHPs, "researchoicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4102", "4102", Path.Combine(PathToSHPs, "palaceaicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4103", "4103", Path.Combine(PathToSHPs, "palacehicon")},
new string[] {"--r8", PathToDataR8, PathToPalette, "4104", "4104", Path.Combine(PathToSHPs, "palaceoicon")},
// 4105 = orniicon
// 4106..4107 = radaraicon
// 4108 = conyardaicon
new string[] {"--r8", PathToDataR8, PathToPalette, "4109", "4150", Path.Combine(PathToSHPs, "conmake"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "4151", "4174", Path.Combine(PathToSHPs, "wtrpmake"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "4175", "4194", Path.Combine(PathToSHPs, "barramake"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "4231", "4253", Path.Combine(PathToSHPs, "refmake"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "4254", "4273", Path.Combine(PathToSHPs, "radarmake"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "4274", "4294", Path.Combine(PathToSHPs, "highmake"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "4295", "4312", Path.Combine(PathToSHPs, "lightmake"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "4313", "4327", Path.Combine(PathToSHPs, "silomake"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "4328", "4346", Path.Combine(PathToSHPs, "heavymake"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "4347", "4369", Path.Combine(PathToSHPs, "starportmake"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "4370", "4390", Path.Combine(PathToSHPs, "repairmake"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "4391", "4412", Path.Combine(PathToSHPs, "researchmake"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "4413", "4435", Path.Combine(PathToSHPs, "palacemake"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "4436", "4449", Path.Combine(PathToSHPs, "cranea"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "4450", "4463", Path.Combine(PathToSHPs, "craneh"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "4463", "4477", Path.Combine(PathToSHPs, "craneo"), "--building"},
new string[] {"--r8", PathToDataR8, PathToPalette, "4760", "4819", Path.Combine(PathToSHPs, "windtrap_anim"), "--building"}, //?
new string[] {"--r8", PathToDataR8, PathToPalette, "4820", "4840", Path.Combine(PathToSHPs, "missile_launch"), "--building"},
new string[] {"--r8", Path.Combine(Platform.SupportDir, "Content/d2k/MOUSE.R8"), PathToPalette, "0", "264", Path.Combine(PathToSHPs, "mouse"), "--transparent"},
new string[] {"--r8", Path.Combine(Platform.SupportDir, "Content/d2k/BLOXBASE.R8"), PathToPalette, "0", "799", Path.Combine(PathToTilesets, "BASE"), "--tileset"},
new string[] {"--r8", Path.Combine(Platform.SupportDir, "Content/d2k/BLOXBASE.R8"), PathToPalette, "748", "749", Path.Combine(PathToSHPs, "spice0")},
new string[] {"--r8", Path.Combine(Platform.SupportDir, "Content/d2k/BLOXBAT.R8"), PathToPalette, "0", "799", Path.Combine(PathToTilesets, "BAT"), "--tileset"},
new string[] {"--r8", Path.Combine(Platform.SupportDir, "Content/d2k/BLOXBGBS.R8"), PathToPalette, "0", "799", Path.Combine(PathToTilesets, "BGBS"), "--tileset"},
new string[] {"--r8", Path.Combine(Platform.SupportDir, "Content/d2k/BLOXICE.R8"), PathToPalette, "0", "799", Path.Combine(PathToTilesets, "ICE"), "--tileset"},
new string[] {"--r8", Path.Combine(Platform.SupportDir, "Content/d2k/BLOXTREE.R8"), PathToPalette, "0", "799", Path.Combine(PathToTilesets, "TREE"), "--tileset"},
new string[] {"--r8", Path.Combine(Platform.SupportDir, "Content/d2k/BLOXWAST.R8"), PathToPalette, "0", "799", Path.Combine(PathToTilesets, "WAST"), "--tileset"},
//new string[] {"--r8", Path.Combine(Platform.SupportDir, "Content/d2k/BLOXXMAS.R8"), PathToPalette, "0", "799", Path.Combine(PathToTilesets, "XMAS"), "--tileset"},
};
var SHPsToCreate = new string[][]
{
new string[] {"--shp", Path.Combine(PathToSHPs, "overlay.png"), "32"},
new string[] {"--shp", Path.Combine(PathToSHPs, "repairing.png"), "24"},
new string[] {"--shp", Path.Combine(PathToSHPs, "numbers.png"), "8"},
new string[] {"--shp", Path.Combine(PathToSHPs, "dots.png"), "4"},
new string[] {"--shp", Path.Combine(PathToSHPs, "crates.png"), "32"},
//new string[] {"--shp", Path.Combine(PathToSHPs, "shadow.png"), "32"},
new string[] {"--shp", Path.Combine(PathToSHPs, "spicebloom.png"), "32"},
new string[] {"--shp", Path.Combine(PathToSHPs, "stars.png"), "16"},
new string[] {"--shp", Path.Combine(PathToSHPs, "greenuparrow.png"), "16"},
new string[] {"--shp", Path.Combine(PathToSHPs, "rockcrater1.png"), "32"},
new string[] {"--shp", Path.Combine(PathToSHPs, "rockcrater2.png"), "32"},
new string[] {"--shp", Path.Combine(PathToSHPs, "sandcrater1.png"), "32"},
new string[] {"--shp", Path.Combine(PathToSHPs, "sandcrater2.png"), "32"},
new string[] {"--shp", Path.Combine(PathToSHPs, "rifle.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "rifledeath.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "bazooka.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "fremen.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "sardaukar.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "engineer.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "engineerdeath.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "thumper.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "thumperdeath.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "missiletank.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "trike.png"), "32"},
new string[] {"--shp", Path.Combine(PathToSHPs, "quad.png"), "32"},
new string[] {"--shp", Path.Combine(PathToSHPs, "harvester.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "combata.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "siegetank.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "dmcv.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "sonictank.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "combataturret.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "siegeturret.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "carryall.png"), "64"},
new string[] {"--shp", Path.Combine(PathToSHPs, "orni.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "combath.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "devast.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "combathturret.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "deathhandmissile.png"), "24"},
new string[] {"--shp", Path.Combine(PathToSHPs, "saboteur.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "saboteurdeath.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "deviatortank.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "raider.png"), "32"},
new string[] {"--shp", Path.Combine(PathToSHPs, "combato.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "combatoturret.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "frigate.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "heavya.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "radara.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "pwra.png"), "64"},
new string[] {"--shp", Path.Combine(PathToSHPs, "barra.png"), "80"},
new string[] {"--shp", Path.Combine(PathToSHPs, "walla.png"), "32"},
new string[] {"--shp", Path.Combine(PathToSHPs, "conyarda.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "refa.png"), "120"},
new string[] {"--shp", Path.Combine(PathToSHPs, "hightecha.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "siloa.png"), "32"},
new string[] {"--shp", Path.Combine(PathToSHPs, "repaira.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "guntowera.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "gunturreta.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "rockettowera.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "rocketturreta.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "researcha.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "starporta.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "lighta.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "palacea.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "heavyh.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "radarh.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "pwrh.png"), "64"},
new string[] {"--shp", Path.Combine(PathToSHPs, "wallh.png"), "32"},
new string[] {"--shp", Path.Combine(PathToSHPs, "barrh.png"), "64"},
new string[] {"--shp", Path.Combine(PathToSHPs, "conyardh.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "refh.png"), "120"},
new string[] {"--shp", Path.Combine(PathToSHPs, "hightechh.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "siloh.png"), "32"},
new string[] {"--shp", Path.Combine(PathToSHPs, "repairh.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "guntowerh.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "gunturreth.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "rockettowerh.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "rocketturreth.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "researchh.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "starporth.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "lighth.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "palaceh.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "heavyo.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "radaro.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "pwro.png"), "64"},
new string[] {"--shp", Path.Combine(PathToSHPs, "barro.png"), "64"},
new string[] {"--shp", Path.Combine(PathToSHPs, "wallo.png"), "32"},
new string[] {"--shp", Path.Combine(PathToSHPs, "conyardo.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "refo.png"), "120"},
new string[] {"--shp", Path.Combine(PathToSHPs, "hightecho.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "siloo.png"), "32"},
new string[] {"--shp", Path.Combine(PathToSHPs, "repairo.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "guntowero.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "gunturreto.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "rockettowero.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "rocketturreto.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "researcho.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "starporto.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "lighto.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "palaceo.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "unload.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "wormjaw.png"), "68"},
new string[] {"--shp", Path.Combine(PathToSHPs, "wormdust.png"), "68"},
new string[] {"--shp", Path.Combine(PathToSHPs, "wormsigns1.png"), "16"},
new string[] {"--shp", Path.Combine(PathToSHPs, "wormsigns2.png"), "16"},
new string[] {"--shp", Path.Combine(PathToSHPs, "wormsigns3.png"), "16"},
new string[] {"--shp", Path.Combine(PathToSHPs, "wormsigns4.png"), "16"},
//new string[] {"--shp", Path.Combine(PathToSHPs, "sell.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "rifleicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "bazookaicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "engineericon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "thumpericon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "sardaukaricon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "trikeicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "raidericon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "quadicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "harvestericon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "combataicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "combathicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "combatoicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "mcvicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "missiletankicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "deviatortankicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "siegetankicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "sonictankicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "devasticon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "carryallicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "orniicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "fremenicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "saboteuricon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "deathhandicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "conyardaicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "conyardhicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "conyardoicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "4plateicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "6plateicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "pwraicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "pwrhicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "pwroicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "barraicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "barrhicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "barroicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "wallicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "refaicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "refhicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "refoicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "turreticon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "radaraicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "radarhicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "radaroicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "rturreticon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "hightechaicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "hightechhicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "hightechoicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "lightaicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "lighthicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "lightoicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "siloaicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "silohicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "silooicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "heavyaicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "heavyhicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "heavyoicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "starportaicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "starporthicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "starportoicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "repairaicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "repairhicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "repairoicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "researchaicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "researchhicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "researchoicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "palaceaicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "palacehicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "palaceoicon.png"), "60"},
new string[] {"--shp", Path.Combine(PathToSHPs, "conmake.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "wtrpmake.png"), "64"},
new string[] {"--shp", Path.Combine(PathToSHPs, "barramake.png"), "80"},
new string[] {"--shp", Path.Combine(PathToSHPs, "refmake.png"), "120"},
new string[] {"--shp", Path.Combine(PathToSHPs, "radarmake.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "highmake.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "lightmake.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "silomake.png"), "32"},
new string[] {"--shp", Path.Combine(PathToSHPs, "heavymake.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "starportmake.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "repairmake.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "researchmake.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "palacemake.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "cranea.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "craneh.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "craneo.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "windtrap_anim.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "missile_launch.png"), "96"},
new string[] {"--shp", Path.Combine(PathToSHPs, "mouse.png"), "48"},
new string[] {"--shp", Path.Combine(PathToSHPs, "spice0.png"), "32"},
};
var SHPsToTranspose = new string[][]
{
new string[] {"--transpose", Path.Combine(PathToSHPs, "orni.shp"), Path.Combine(PathToSHPs, "orni.shp"), "0", "32", "3"},
new string[] {"--transpose", Path.Combine(PathToSHPs, "rifle.shp"), Path.Combine(PathToSHPs, "rifle.shp"), "8", "8", "6", "56", "8", "5", "112", "8", "3", "136", "8", "5"},
new string[] {"--transpose", Path.Combine(PathToSHPs, "bazooka.shp"), Path.Combine(PathToSHPs, "bazooka.shp"), "8", "8", "6", "56", "8", "5", "112", "8", "3", "136", "8", "5"},
new string[] {"--transpose", Path.Combine(PathToSHPs, "fremen.shp"), Path.Combine(PathToSHPs, "fremen.shp"), "8", "8", "6", "56", "8", "5", "112", "8", "3", "136", "8", "5"},
new string[] {"--transpose", Path.Combine(PathToSHPs, "sardaukar.shp"), Path.Combine(PathToSHPs, "sardaukar.shp"), "8", "8", "6", "56", "8", "5", "112", "8", "3", "136", "8", "5"},
new string[] {"--transpose", Path.Combine(PathToSHPs, "thumper.shp"), Path.Combine(PathToSHPs, "thumper.shp"), "8", "8", "6"},
new string[] {"--transpose", Path.Combine(PathToSHPs, "engineer.shp"), Path.Combine(PathToSHPs, "engineer.shp"), "8", "8", "6"},
new string[] {"--transpose", Path.Combine(PathToSHPs, "saboteur.shp"), Path.Combine(PathToSHPs, "saboteur.shp"), "8", "8", "4"},
};
var onError = (Action<string>)(s => Game.RunAfterTick(() =>
{
statusLabel.GetText = () => "Error: "+s;
backButton.IsDisabled = () => false;
retryButton.IsDisabled = () => false;
}));
var t = new Thread( _ =>
{
try
{
for (int i = 0; i < ExtractGameFiles.Length; i++)
{
progressBar.Percentage = i*100/ExtractGameFiles.Count();
statusLabel.GetText = () => "Extracting...";
Utility.Command.ConvertR8ToPng(ExtractGameFiles[i]);
}
for (int i = 0; i < SHPsToCreate.Length; i++)
{
progressBar.Percentage = i*100/SHPsToCreate.Count();
statusLabel.GetText = () => "Converting...";
Utility.Command.ConvertPngToShp(SHPsToCreate[i]);
File.Delete(SHPsToCreate[i][1]);
}
for (int i = 0; i < SHPsToTranspose.Length; i++)
{
progressBar.Percentage = i*100/SHPsToTranspose.Count();
statusLabel.GetText = () => "Transposing...";
Utility.Command.TransposeShp(SHPsToTranspose[i]);
}
statusLabel.GetText = () => "Building tilesets...";
int c = 0;
string[] TilesetArray = new string[] { "BASE", "BAT", "BGBS", "ICE", "TREE", "WAST" };
foreach (string set in TilesetArray)
{
progressBar.Percentage = c*100/TilesetArray.Count();
File.Delete(Path.Combine(PathToTilesets, "{0}.tsx".F(set)));
File.Copy("mods/d2k/tilesets/{0}.tsx".F(set), Path.Combine(PathToTilesets, "{0}.tsx".F(set)));
// this is ugly: a GUI will open and close immediately after some delay
Process p = new Process();
ProcessStartInfo TilesetBuilderProcessStartInfo = new ProcessStartInfo("OpenRA.TilesetBuilder.exe", Path.Combine(PathToTilesets, "{0}.png".F(set))+" 32 --export Content/d2k/Tilesets");
p.StartInfo = TilesetBuilderProcessStartInfo;
p.Start();
p.WaitForExit();
File.Delete(Path.Combine(PathToTilesets, "{0}.tsx".F(set)));
File.Delete(Path.Combine(PathToTilesets, "{0}.png".F(set)));
File.Delete(Path.Combine(PathToTilesets, "{0}.yaml".F(set.ToLower())));
File.Delete(Path.Combine(PathToTilesets, "{0}.pal".F(set.ToLower())));
c++;
}
Game.RunAfterTick(() =>
{
progressBar.Percentage = 100;
statusLabel.GetText = () => "Extraction and conversion complete.";
backButton.IsDisabled = () => false;
continueLoading();
});
}
catch
{
onError("Installation failed");
}
}) { IsBackground = true };
t.Start();
}
}
}

View File

@@ -0,0 +1,131 @@
#region Copyright & License Information
/*
* Copyright 2007-2012 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. For more information,
* see COPYING.
*/
#endregion
using System;
using System.IO;
using System.Linq;
using System.Threading;
using OpenRA.FileFormats;
using OpenRA.FileFormats.Graphics;
using OpenRA.Widgets;
using OpenRA.Utility;
namespace OpenRA.Mods.D2k.Widgets.Logic
{
public class D2kInstallFromCDLogic
{
Widget panel;
ProgressBarWidget progressBar;
LabelWidget statusLabel;
Action continueLoading;
ButtonWidget retryButton, backButton;
Widget installingContainer, insertDiskContainer;
[ObjectCreator.UseCtor]
public D2kInstallFromCDLogic(Widget widget, Action continueLoading)
{
panel = widget.Get("INSTALL_FROMCD_PANEL");
progressBar = panel.Get<ProgressBarWidget>("PROGRESS_BAR");
statusLabel = panel.Get<LabelWidget>("STATUS_LABEL");
backButton = panel.Get<ButtonWidget>("BACK_BUTTON");
backButton.OnClick = Ui.CloseWindow;
retryButton = panel.Get<ButtonWidget>("RETRY_BUTTON");
retryButton.OnClick = CheckForDisk;
installingContainer = panel.Get("INSTALLING");
insertDiskContainer = panel.Get("INSERT_DISK");
CheckForDisk();
this.continueLoading = continueLoading;
}
public static bool IsValidDisk(string diskRoot)
{
var files = new string[][] {
new [] { diskRoot, "music", "ambush.aud" },
new [] { diskRoot, "setup", "setup.z" },
};
return files.All(f => File.Exists(f.Aggregate(Path.Combine)));
}
void CheckForDisk()
{
var path = InstallUtils.GetMountedDisk(IsValidDisk);
if (path != null)
Install(path);
else
{
insertDiskContainer.IsVisible = () => true;
installingContainer.IsVisible = () => false;
}
}
void Install(string source)
{
backButton.IsDisabled = () => true;
retryButton.IsDisabled = () => true;
insertDiskContainer.IsVisible = () => false;
installingContainer.IsVisible = () => true;
var dest = new string[] { Platform.SupportDir, "Content", "d2k", "Music" }.Aggregate(Path.Combine);
var copyFiles = new string[] { "music/ambush.aud", "music/arakatak.aud", "music/atregain.aud", "music/entordos.aud", "music/fightpwr.aud", "music/fremen.aud", "music/hark_bat.aud", "music/landsand.aud", "music/options.aud", "music/plotting.aud", "music/risehark.aud", "music/robotix.aud", "music/score.aud", "music/soldappr.aud", "music/spicesct.aud", "music/undercon.aud", "music/waitgame.aud" };
// TODO: won't work yet:
//var extractPackage = "setup/setup.z";
//var extractFiles = new string[] { "DATA.R8", "MOUSE.R8", "BLOXBASE.R8", "BLOXBAT.R8", "BLOXBGBS.R8", "BLOXICE.R8", "BLOXTREE.R8", "BLOXWAST.R8" };
var installCounter = 0;
var installTotal = copyFiles.Count(); //+ extractFiles.Count();
var onProgress = (Action<string>)(s => Game.RunAfterTick(() =>
{
progressBar.Percentage = installCounter*100/installTotal;
installCounter++;
statusLabel.GetText = () => s;
}));
var onError = (Action<string>)(s => Game.RunAfterTick(() =>
{
statusLabel.GetText = () => "Error: "+s;
backButton.IsDisabled = () => false;
retryButton.IsDisabled = () => false;
}));
var t = new Thread( _ =>
{
try
{
if (!InstallUtils.CopyFiles(source, copyFiles, dest, onProgress, onError))
return;
//if (!InstallUtils.ExtractFromPackage(source, extractPackage, extractFiles, dest, onProgress, onError))
// return;
Game.RunAfterTick(() =>
{
statusLabel.GetText = () => "Music has been copied.";
backButton.IsDisabled = () => false;
continueLoading();
});
}
catch
{
onError("Installation failed");
}
}) { IsBackground = true };
t.Start();
}
}
}

View File

@@ -0,0 +1,42 @@
#region Copyright & License Information
/*
* Copyright 2007-2012 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. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Collections.Generic;
using OpenRA.Widgets;
namespace OpenRA.Mods.D2k.Widgets.Logic
{
public class D2kInstallLogic
{
[ObjectCreator.UseCtor]
public D2kInstallLogic(Widget widget, Dictionary<string,string> installData, Action continueLoading)
{
var panel = widget.Get("INSTALL_PANEL");
var args = new WidgetArgs()
{
{ "afterInstall", () => { Ui.CloseWindow(); continueLoading(); } },
{ "installData", installData },
{ "continueLoading", continueLoading }
};
panel.Get<ButtonWidget>("DOWNLOAD_BUTTON").OnClick = () =>
Ui.OpenWindow("INSTALL_DOWNLOAD_PANEL", args);
panel.Get<ButtonWidget>("COPY_BUTTON").OnClick = () =>
Ui.OpenWindow("INSTALL_FROMCD_PANEL", args);
panel.Get<ButtonWidget>("EXTRACT_BUTTON").OnClick = () =>
Ui.OpenWindow("EXTRACT_GAMEFILES_PANEL", args);
panel.Get<ButtonWidget>("QUIT_BUTTON").OnClick = Game.Exit;
}
}
}

View File

@@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA.AI
public readonly int SquadSize = 8;
public readonly int AssignRolesInterval = 20;
public readonly string RallypointTestBuilding = "fact"; // temporary hack to maintain previous rallypoint behavior.
public readonly string[] UnitQueues = { "Vehicle", "Infantry", "Plane" };
public readonly string[] UnitQueues = {"Vehicle", "Infantry", "Plane"};
public readonly bool ShouldRepairBuildings = true;
string IBotInfo.Name { get { return this.Name; } }
@@ -72,7 +72,7 @@ namespace OpenRA.Mods.RA.AI
readonly HackyAIInfo Info;
Cache<Player,Enemy> aggro = new Cache<Player, Enemy>( _ => new Enemy() );
int2 baseCenter;
CPos baseCenter;
XRandom random = new XRandom(); //we do not use the synced random number generator.
BaseBuilder[] builders;
@@ -116,7 +116,7 @@ namespace OpenRA.Mods.RA.AI
ActorInfo ChooseRandomUnitToBuild(ProductionQueue queue)
{
var buildableThings = queue.BuildableItems();
if (buildableThings.Count() == 0) return null;
if (!buildableThings.Any()) return null;
return buildableThings.ElementAtOrDefault(random.Next(buildableThings.Count()));
}
@@ -154,13 +154,13 @@ namespace OpenRA.Mods.RA.AI
return null;
}
bool NoBuildingsUnder(IEnumerable<int2> cells)
bool NoBuildingsUnder(IEnumerable<CPos> cells)
{
var bi = world.WorldActor.Trait<BuildingInfluence>();
return cells.All(c => bi.GetBuildingAt(c) == null);
}
public int2? ChooseBuildLocation(string actorType)
public CPos? ChooseBuildLocation(string actorType)
{
var bi = Rules.Info[actorType].Traits.Get<BuildingInfo>();
@@ -182,7 +182,7 @@ namespace OpenRA.Mods.RA.AI
ticks++;
if (ticks == 10)
if (ticks == 1)
DeployMcv(self);
if (ticks % feedbackTime == 0)
@@ -200,12 +200,12 @@ namespace OpenRA.Mods.RA.AI
//A bunch of hardcoded lists to keep track of which units are doing what.
List<Actor> unitsHangingAroundTheBase = new List<Actor>();
List<Actor> attackForce = new List<Actor>();
int2? attackTarget;
CPos? attackTarget;
//Units that the ai already knows about. Any unit not on this list needs to be given a role.
List<Actor> activeUnits = new List<Actor>();
int2? ChooseEnemyTarget()
CPos? ChooseEnemyTarget()
{
var liveEnemies = world.Players
.Where(q => p != q && p.Stances[q] == Stance.Enemy)
@@ -219,14 +219,14 @@ namespace OpenRA.Mods.RA.AI
if (leastLikedEnemies == null)
return null;
var enemy = leastLikedEnemies != null ? leastLikedEnemies.Random(random) : null;
var enemy = leastLikedEnemies.Random(random);
/* pick something worth attacking owned by that player */
var targets = world.Actors
.Where(a => a.Owner == enemy && a.HasTrait<IOccupySpace>());
Actor target=null;
Actor target = null;
if (targets.Count()>0)
if (targets.Any())
target = targets.Random(random);
if (target == null)
@@ -260,27 +260,46 @@ namespace OpenRA.Mods.RA.AI
else
assignRolesTicks = Info.AssignRolesInterval;
// Find idle harvesters and give them orders:
foreach (var a in activeUnits)
{
var harv = a.TraitOrDefault<Harvester>();
if (harv == null) continue;
if (!a.IsIdle)
{
Activity act = a.GetCurrentActivity();
// A Wait activity is technically idle:
if ((act.GetType() != typeof(OpenRA.Mods.RA.Activities.Wait)) &&
(act.NextActivity == null || act.NextActivity.GetType() != typeof(OpenRA.Mods.RA.Activities.FindResources)))
continue;
}
if (!harv.IsEmpty) continue;
// Tell the idle harvester to quit slacking:
world.IssueOrder(new Order("Harvest", a, false));
}
var newUnits = self.World.ActorsWithTrait<IMove>()
.Where(a => a.Actor.Owner == p && a.Actor.Info != Rules.Info["mcv"]
.Where(a => a.Actor.Owner == p && !a.Actor.HasTrait<BaseBuilding>()
&& !activeUnits.Contains(a.Actor))
.Select(a => a.Actor).ToArray();
foreach (var a in newUnits)
{
BotDebug("AI: Found a newly built unit");
if (a.Info == Rules.Info["harv"])
if (a.HasTrait<Harvester>())
world.IssueOrder( new Order( "Harvest", a, false ) );
else
unitsHangingAroundTheBase.Add(a);
activeUnits.Add(a);
}
/* Create an attack force when we have enough units around our base. */
// (don't bother leaving any behind for defense.)
int randomizedSquadSize = Info.SquadSize - 4 + random.Next(200);
if (unitsHangingAroundTheBase.Count >= randomizedSquadSize)
{
BotDebug("Launch an attack.");
@@ -346,7 +365,7 @@ namespace OpenRA.Mods.RA.AI
}
}
bool IsRallyPointValid(int2 x)
bool IsRallyPointValid(CPos x)
{
// this is actually WRONG as soon as HackyAI is building units with a variety of
// movement capabilities. (has always been wrong)
@@ -363,16 +382,15 @@ namespace OpenRA.Mods.RA.AI
BotDebug("Bot {0} needs to find rallypoints for {1} buildings.",
p.PlayerName, buildings.Length);
foreach (var a in buildings)
{
int2 newRallyPoint = ChooseRallyLocationNear(a.Actor.Location);
CPos newRallyPoint = ChooseRallyLocationNear(a.Actor.Location);
world.IssueOrder(new Order("SetRallyPoint", a.Actor, false) { TargetLocation = newRallyPoint });
}
}
//won't work for shipyards...
int2 ChooseRallyLocationNear(int2 startPos)
CPos ChooseRallyLocationNear(CPos startPos)
{
var possibleRallyPoints = world.FindTilesInCircle(startPos, 8).Where(IsRallyPointValid).ToArray();
if (possibleRallyPoints.Length == 0)
@@ -384,18 +402,18 @@ namespace OpenRA.Mods.RA.AI
return possibleRallyPoints.Random(random);
}
int2? ChooseDestinationNear(Actor a, int2 desiredMoveTarget)
CPos? ChooseDestinationNear(Actor a, CPos desiredMoveTarget)
{
var move = a.TraitOrDefault<IMove>();
if (move == null) return null;
int2 xy;
CPos xy;
int loopCount = 0; //avoid infinite loops.
int range = 2;
do
{
//loop until we find a valid move location
xy = new int2(desiredMoveTarget.X + random.Next(-range, range), desiredMoveTarget.Y + random.Next(-range, range));
xy = new CPos(desiredMoveTarget.X + random.Next(-range, range), desiredMoveTarget.Y + random.Next(-range, range));
loopCount++;
range = Math.Max(range, loopCount / 2);
if (loopCount > 10) return null;
@@ -406,7 +424,7 @@ namespace OpenRA.Mods.RA.AI
//try very hard to find a valid move destination near the target.
//(Don't accept a move onto the subject's current position. maybe this is already not allowed? )
bool TryToMove(Actor a, int2 desiredMoveTarget, bool attackMove)
bool TryToMove(Actor a, CPos desiredMoveTarget, bool attackMove)
{
var xy = ChooseDestinationNear(a, desiredMoveTarget);
if (xy == null)
@@ -419,7 +437,7 @@ namespace OpenRA.Mods.RA.AI
{
/* find our mcv and deploy it */
var mcv = self.World.Actors
.FirstOrDefault(a => a.Owner == p && a.Info == Rules.Info["mcv"]);
.FirstOrDefault(a => a.Owner == p && a.HasTrait<BaseBuilding>());
if (mcv != null)
{
@@ -427,7 +445,7 @@ namespace OpenRA.Mods.RA.AI
world.IssueOrder(new Order("DeployTransform", mcv, false));
}
else
BotDebug("AI: Can't find the MCV.");
BotDebug("AI: Can't find BaseBuildUnit.");
}
internal IEnumerable<ProductionQueue> FindQueues(string category)

View File

@@ -28,8 +28,13 @@ namespace OpenRA.Mods.RA.Activities
if( !target.OccupiesSpace.OccupiedCells().Any( x => x.First == self.Location ) )
return NextActivity;
var capturable = target.TraitOrDefault<Capturable>();
if (capturable != null && capturable.CaptureInProgress && capturable.Captor.Owner.Stances[self.Owner] == Stance.Ally)
return NextActivity;
var sellable = target.TraitOrDefault<Sellable>();
if (sellable != null && sellable.Selling) return NextActivity;
if (sellable != null && sellable.Selling)
return NextActivity;
target.Trait<Capturable>().BeginCapture(target, self);
self.World.AddFrameEndTask(w => self.Destroy());

View File

@@ -18,29 +18,48 @@ namespace OpenRA.Mods.RA.Activities
public class DeliverResources : Activity
{
bool isDocking;
int chosenTicks;
const int NextChooseTime = 100;
public DeliverResources() { }
public override Activity Tick( Actor self )
public override Activity Tick(Actor self)
{
if( NextActivity != null )
if (NextActivity != null)
return NextActivity;
var mobile = self.Trait<Mobile>();
var harv = self.Trait<Harvester>();
// Find the nearest best refinery if not explicitly ordered to a specific refinery:
if (harv.OwnerLinkedProc == null || !harv.OwnerLinkedProc.IsInWorld)
{
// Maybe we lost the owner-linked refinery:
harv.OwnerLinkedProc = null;
if (self.World.FrameNumber - chosenTicks > NextChooseTime)
{
harv.ChooseNewProc(self, null);
chosenTicks = self.World.FrameNumber;
}
}
else
{
harv.LinkProc(self, harv.OwnerLinkedProc);
}
if (harv.LinkedProc == null || !harv.LinkedProc.IsInWorld)
harv.ChooseNewProc(self, null);
if (harv.LinkedProc == null) // no procs exist; check again in 1s.
return Util.SequenceActivities( new Wait(25), this );
return Util.SequenceActivities(new Wait(25), this);
var proc = harv.LinkedProc;
var iao = proc.Trait<IAcceptOre>();
self.SetTargetLine(Target.FromActor(proc), Color.Green, false);
if( self.Location != proc.Location + iao.DeliverOffset )
return Util.SequenceActivities( mobile.MoveTo(proc.Location + iao.DeliverOffset, 0), this );
if (self.Location != proc.Location + iao.DeliverOffset)
return Util.SequenceActivities(mobile.MoveTo(proc.Location + iao.DeliverOffset, 0), this);
if (!isDocking)
{
@@ -48,7 +67,7 @@ namespace OpenRA.Mods.RA.Activities
iao.OnDock(self, this);
}
return Util.SequenceActivities( new Wait(10), this );
return Util.SequenceActivities(new Wait(10), this);
}
// Cannot be cancelled

View File

@@ -14,37 +14,122 @@ using System.Linq;
using OpenRA.Mods.RA.Move;
using OpenRA.Mods.RA.Render;
using OpenRA.Traits;
using System;
namespace OpenRA.Mods.RA.Activities
{
public class FindResources : Activity
{
CPos? avoidCell;
public FindResources()
{
}
public FindResources(CPos avoidCell)
{
this.avoidCell = avoidCell;
}
public override Activity Tick(Actor self)
{
if (IsCanceled || NextActivity != null) return NextActivity;
var harv = self.Trait<Harvester>();
if (harv.IsFull)
return Util.SequenceActivities(new DeliverResources(), NextActivity);
var harvInfo = self.Info.Traits.Get<HarvesterInfo>();
var mobile = self.Trait<Mobile>();
var mobileInfo = self.Info.Traits.Get<MobileInfo>();
var res = self.World.WorldActor.Trait<ResourceLayer>();
var path = self.World.WorldActor.Trait<PathFinder>().FindPath(PathSearch.Search(self.World, mobileInfo, self.Owner, true)
.WithHeuristic(loc => (res.GetResource(loc) != null && harvInfo.Resources.Contains(res.GetResource(loc).info.Name)) ? 0 : 1)
.FromPoint(self.Location));
var resLayer = self.World.WorldActor.Trait<ResourceLayer>();
var territory = self.World.WorldActor.TraitOrDefault<ResourceClaimLayer>();
// Determine where to search from and how far to search:
var searchFromLoc = harv.LastOrderLocation ?? (harv.LastLinkedProc ?? harv.LinkedProc ?? self).Location;
int searchRadius = harv.LastOrderLocation.HasValue ? harvInfo.SearchFromOrderRadius : harvInfo.SearchFromProcRadius;
int searchRadiusSquared = searchRadius * searchRadius;
// Find harvestable resources nearby:
var path = self.World.WorldActor.Trait<PathFinder>().FindPath(
PathSearch.Search(self.World, mobileInfo, self.Owner, true)
.WithCustomCost(loc =>
{
// Avoid enemy territory:
int safetycost = (
// TODO: calculate weapons ranges of units and factor those in instead of hard-coding 8.
from u in self.World.FindUnitsInCircle(loc.ToPPos(), Game.CellSize * 8)
where !u.Destroyed
where self.Owner.Stances[u.Owner] == Stance.Enemy
select Math.Max(0, 64 - (loc - u.Location).LengthSquared)
).Sum();
return safetycost;
})
.WithHeuristic(loc =>
{
// Avoid this cell:
if (avoidCell.HasValue && loc == avoidCell.Value) return 1;
// Don't harvest out of range:
int distSquared = (loc - searchFromLoc).LengthSquared;
if (distSquared > searchRadiusSquared)
return int.MaxValue;
// Get the resource at this location:
var resType = resLayer.GetResource(loc);
if (resType == null) return 1;
// Can the harvester collect this kind of resource?
if (!harvInfo.Resources.Contains(resType.info.Name)) return 1;
if (territory != null)
{
// Another harvester has claimed this resource:
ResourceClaim claim;
if (territory.IsClaimedByAnyoneElse(self, loc, out claim)) return 1;
}
return 0;
})
.FromPoint(self.Location)
);
if (path.Count == 0)
return NextActivity;
{
if (!harv.IsEmpty)
return new DeliverResources();
else
{
// Get out of the way if we are:
harv.UnblockRefinery(self);
int randFrames = 125 + self.World.SharedRandom.Next(-35, 35);
if (NextActivity != null)
return Util.SequenceActivities(NextActivity, new Wait(randFrames), new FindResources());
else
return Util.SequenceActivities(new Wait(randFrames), new FindResources());
}
}
// Attempt to claim a resource as ours:
if (territory != null)
{
if (!territory.ClaimResource(self, path[0]))
return Util.SequenceActivities(new Wait(25), new FindResources());
}
// If not given a direct order, assume ordered to the first resource location we find:
if (harv.LastOrderLocation == null)
harv.LastOrderLocation = path[0];
self.SetTargetLine(Target.FromCell(path[0]), Color.Red, false);
return Util.SequenceActivities(mobile.MoveTo(path[0], 1), new HarvestResource(), this);
return Util.SequenceActivities(mobile.MoveTo(path[0], 1), new HarvestResource(), new FindResources());
}
public override IEnumerable<Target> GetTargets(Actor self)
{
yield return Target.FromPos(self.Location);
yield return Target.FromCell(self.Location);
}
}
@@ -55,23 +140,38 @@ namespace OpenRA.Mods.RA.Activities
public override Activity Tick(Actor self)
{
if (isHarvesting) return this;
if (IsCanceled) return NextActivity;
var territory = self.World.WorldActor.TraitOrDefault<ResourceClaimLayer>();
if (IsCanceled)
{
if (territory != null) territory.UnclaimByActor(self);
return NextActivity;
}
var harv = self.Trait<Harvester>();
harv.LastHarvestedCell = self.Location;
if (harv.IsFull)
{
if (territory != null) territory.UnclaimByActor(self);
return NextActivity;
}
var resLayer = self.World.WorldActor.Trait<ResourceLayer>();
var resource = resLayer.Harvest(self.Location);
if (resource == null)
{
if (territory != null) territory.UnclaimByActor(self);
return NextActivity;
}
var renderUnit = self.Trait<RenderUnit>(); /* better have one of these! */
var resource = self.World.WorldActor.Trait<ResourceLayer>().Harvest(self.Location);
if (resource == null)
return NextActivity;
if (renderUnit.anim.CurrentSequence.Name != "harvest")
{
isHarvesting = true;
renderUnit.PlayCustomAnimation(self, "harvest", () => isHarvesting = false);
}
harv.AcceptResource(resource);
return this;
}

View File

@@ -33,7 +33,7 @@ namespace OpenRA.Mods.RA.Activities
if (IsCanceled) return NextActivity;
if (!Target.IsValid) return NextActivity;
var inRange = ( Util.CellContaining( Target.CenterLocation ) - self.Location ).LengthSquared < Range * Range;
var inRange = ( Target.CenterLocation.ToCPos() - self.Location ).LengthSquared < Range * Range;
if( inRange ) return this;
if (--nextPathTime > 0) return this;

View File

@@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA.Activities
return Util.SequenceActivities(
new MoveAdjacentTo(Target.FromActor(rearmTarget)),
mobile.MoveTo(Traits.Util.CellContaining(rearmTarget.CenterLocation), rearmTarget),
mobile.MoveTo(rearmTarget.CenterLocation.ToCPos(), rearmTarget),
new Rearm(self),
new Repair(rearmTarget),
this );
@@ -65,11 +65,10 @@ namespace OpenRA.Mods.RA.Activities
return new Wait(20); // nothing to do here
}
bool ShouldLayMine(Actor self, int2 p)
bool ShouldLayMine(Actor self, CPos p)
{
// if there is no unit (other than me) here, we want to place a mine here
return !self.World.ActorMap
.GetUnitsAt(p).Any(a => a != self);
return !self.World.ActorMap.GetUnitsAt(p).Any(a => a != self);
}
void LayMine(Actor self)

View File

@@ -18,7 +18,7 @@ namespace OpenRA.Mods.RA.Activities
class Leap : Activity
{
Target target;
int2 initialLocation;
PPos initialLocation;
int moveFraction;
const int delay = 6;
@@ -26,7 +26,7 @@ namespace OpenRA.Mods.RA.Activities
public Leap(Actor self, Target target)
{
this.target = target;
initialLocation = self.Trait<Mobile>().PxPosition;
initialLocation = (PPos) self.Trait<Mobile>().PxPosition;
self.Trait<RenderInfantry>().Attacking(self, target);
Sound.Play("dogg5p.aud", self.CenterLocation);
@@ -41,12 +41,12 @@ namespace OpenRA.Mods.RA.Activities
var mobile = self.Trait<Mobile>();
++moveFraction;
mobile.PxPosition = int2.Lerp(initialLocation, target.PxPosition, moveFraction, delay);
mobile.PxPosition = PPos.Lerp(initialLocation, target.PxPosition, moveFraction, delay);
if (moveFraction >= delay)
{
self.TraitsImplementing<IMove>().FirstOrDefault()
.SetPosition(self, Util.CellContaining(target.CenterLocation));
.SetPosition(self, target.CenterLocation.ToCPos());
if (target.IsActor)
target.Actor.Kill(self);

View File

@@ -40,7 +40,7 @@ namespace OpenRA.Mods.RA.Activities
ps1.heuristic = PathSearch.DefaultEstimator( mobile.toCell );
var ps2 = PathSearch.FromPoint( self.World, mobile.Info, self.Owner, mobile.toCell, Util.CellContaining(target.CenterLocation), true );
var ps2 = PathSearch.FromPoint( self.World, mobile.Info, self.Owner, mobile.toCell, target.CenterLocation.ToCPos(), true );
var ret = self.World.WorldActor.Trait<PathFinder>().FindBidiPath( ps1, ps2 );
return Util.SequenceActivities( mobile.MoveTo( () => ret ), this );

View File

@@ -55,6 +55,8 @@ namespace OpenRA.Mods.RA
state = State.Wait;
return this;
case State.Complete:
harv.LastLinkedProc = harv.LinkedProc;
harv.LinkProc(self, null);
return NextActivity;
}
throw new InvalidOperationException("Invalid harvester dock state");

View File

@@ -15,9 +15,9 @@ namespace OpenRA.Mods.RA.Activities
{
public class Teleport : Activity
{
int2 destination;
CPos destination;
public Teleport(int2 destination)
public Teleport(CPos destination)
{
this.destination = destination;
}

View File

@@ -17,7 +17,7 @@ namespace OpenRA.Mods.RA.Activities
class Transform : Activity
{
public readonly string ToActor = null;
public int2 Offset = new int2(0,0);
public CVec Offset = new CVec(0, 0);
public int Facing = 96;
public string[] Sounds = {};
public int ForceHealthPercentage = 0;

View File

@@ -18,7 +18,7 @@ namespace OpenRA.Mods.RA.Activities
{
public class UnloadCargo : Activity
{
int2? ChooseExitTile(Actor self, Actor cargo)
CPos? ChooseExitTile(Actor self, Actor cargo)
{
// is anyone still hogging this tile?
if (self.World.ActorMap.GetUnitsAt(self.Location).Count() > 1)
@@ -29,8 +29,8 @@ namespace OpenRA.Mods.RA.Activities
for (var i = -1; i < 2; i++)
for (var j = -1; j < 2; j++)
if ((i != 0 || j != 0) &&
mobile.CanEnterCell(self.Location + new int2(i, j)))
return self.Location + new int2(i, j);
mobile.CanEnterCell(self.Location + new CVec(i, j)))
return self.Location + new CVec(i, j);
return null;
}
@@ -70,7 +70,7 @@ namespace OpenRA.Mods.RA.Activities
if (actor.Destroyed) return;
var mobile = actor.Trait<Mobile>();
mobile.Facing = Util.GetFacing( exitPx - currentPx, mobile.Facing );
mobile.Facing = Util.GetFacing( (exitPx - currentPx).ToInt2(), mobile.Facing );
mobile.SetPosition(actor, exitTile.Value);
mobile.AdjustPxPosition(actor, currentPx);
var speed = mobile.MovementSpeedForCell(actor, exitTile.Value);

View File

@@ -8,6 +8,7 @@
*/
#endregion
using System;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities
@@ -26,7 +27,7 @@ namespace OpenRA.Mods.RA.Activities
public override Activity Tick(Actor self)
{
return (remainingTicks-- == 0) ? NextActivity: this;
return (remainingTicks-- == 0) ? NextActivity : this;
}
public override void Cancel( Actor self )
@@ -38,4 +39,31 @@ namespace OpenRA.Mods.RA.Activities
base.Cancel(self);
}
}
public class WaitFor : Activity
{
Func<bool> f;
bool interruptable = true;
public WaitFor(Func<bool> f) { this.f = f; }
public WaitFor(Func<bool> f, bool interruptable)
{
this.f = f;
this.interruptable = interruptable;
}
public override Activity Tick(Actor self)
{
return (f == null || f()) ? NextActivity : this;
}
public override void Cancel( Actor self )
{
if (!interruptable)
return;
f = null;
base.Cancel(self);
}
}
}

View File

@@ -14,6 +14,7 @@ namespace OpenRA.Mods.RA
{
class ActorLostNotificationInfo : ITraitInfo
{
public readonly string Race = null;
public readonly string Notification = null;
public readonly bool NotifyAll = false;
@@ -31,6 +32,8 @@ namespace OpenRA.Mods.RA
public void Killed(Actor self, AttackInfo e)
{
var player = (Info.NotifyAll) ? self.World.LocalPlayer : self.Owner;
if (Info.Race != null && Info.Race != self.Owner.Country.Race)
return;
Sound.PlayToPlayer(player, Info.Notification);
}
}

View File

@@ -107,9 +107,9 @@ namespace OpenRA.Mods.RA.Air
[Sync]
public int Altitude { get; set; }
[Sync]
public int2 SubPxPosition;
public int2 PxPosition { get { return new int2( SubPxPosition.X / 1024, SubPxPosition.Y / 1024 ); } }
public int2 TopLeft { get { return Util.CellContaining( PxPosition ); } }
public PSubPos SubPxPosition;
public PPos PxPosition { get { return SubPxPosition.ToPPos(); } }
public CPos TopLeft { get { return PxPosition.ToCPos(); } }
readonly AircraftInfo Info;
@@ -117,7 +117,7 @@ namespace OpenRA.Mods.RA.Air
{
this.self = init.self;
if( init.Contains<LocationInit>() )
this.SubPxPosition = 1024 * Util.CenterOfCell( init.Get<LocationInit, int2>() );
this.SubPxPosition = Util.CenterOfCell( init.Get<LocationInit, CPos>() ).ToPSubPos();
this.Facing = init.Contains<FacingInit>() ? init.Get<FacingInit,int>() : info.InitialFacing;
this.Altitude = init.Contains<AltitudeInit>() ? init.Get<AltitudeInit,int>() : 0;
@@ -151,17 +151,17 @@ namespace OpenRA.Mods.RA.Air
public int InitialFacing { get { return Info.InitialFacing; } }
public void SetPosition(Actor self, int2 cell)
public void SetPosition(Actor self, CPos cell)
{
SetPxPosition( self, Util.CenterOfCell( cell ) );
}
public void SetPxPosition( Actor self, int2 px )
public void SetPxPosition( Actor self, PPos px )
{
SubPxPosition = px * 1024;
SubPxPosition = px.ToPSubPos();
}
public void AdjustPxPosition(Actor self, int2 px) { SetPxPosition(self, px); }
public void AdjustPxPosition(Actor self, PPos px) { SetPxPosition(self, px); }
public bool AircraftCanEnter(Actor a)
{
@@ -170,7 +170,7 @@ namespace OpenRA.Mods.RA.Air
|| Info.RepairBuildings.Contains( a.Info.Name );
}
public bool CanEnterCell(int2 location) { return true; }
public bool CanEnterCell(CPos location) { return true; }
public int MovementSpeed
{
@@ -183,16 +183,16 @@ namespace OpenRA.Mods.RA.Air
}
}
Pair<int2, SubCell>[] noCells = new Pair<int2, SubCell>[] { };
public IEnumerable<Pair<int2, SubCell>> OccupiedCells() { return noCells; }
Pair<CPos, SubCell>[] noCells = new Pair<CPos, SubCell>[] { };
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { return noCells; }
public void TickMove( int speed, int facing )
{
var rawspeed = speed * 7 / (32 * 1024);
var rawspeed = speed * 7 / (32 * PSubPos.PerPx);
SubPxPosition += rawspeed * -Util.SubPxVector[facing];
}
public bool CanLand(int2 cell)
public bool CanLand(CPos cell)
{
if (!self.World.Map.IsInMap(cell))
return false;
@@ -230,7 +230,7 @@ namespace OpenRA.Mods.RA.Air
return new Order(order.OrderID, self, queued) { TargetActor = target.Actor };
if (order.OrderID == "Move")
return new Order(order.OrderID, self, queued) { TargetLocation = Util.CellContaining(target.CenterLocation) };
return new Order(order.OrderID, self, queued) { TargetLocation = target.CenterLocation.ToCPos() };
return null;
}
@@ -273,7 +273,7 @@ namespace OpenRA.Mods.RA.Air
return false;
}
public bool CanTargetLocation(Actor self, int2 location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueued, ref string cursor)
public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueued, ref string cursor)
{
IsQueued = forceQueued;
cursor = self.World.Map.IsInMap(location) ? "move" : "move-blocked";

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