Compare commits

...

1002 Commits

Author SHA1 Message Date
Matthew Bowra-Dean
8a3868abd0 Updated web pages and fixed OS X download script. 2010-09-05 00:10:07 +12:00
Matthew
112047d2b3 Changed downloading scripts to point to mirror script. Added open-ra.org to mirror list. 2010-09-04 22:42:55 +12:00
Matthew
cd9f584729 Mod package mirroring scripts. 2010-09-04 22:26:11 +12:00
Matthew
31741a1ab3 Fix rebuilding of project in packaging. 2010-09-04 20:57:34 +12:00
Matthew
eb6440694a Packaging script updated to use sub-packaging scripts in freshly checkedout copy of repo. 2010-09-04 20:57:34 +12:00
Paolo Chiodi
2c388308c7 avoid calling Viewport.Scroll on every ScreenShaker.Tick 2010-09-04 10:45:09 +02:00
Paolo Chiodi
1c8f744719 allow camera shaking to exit map borders 2010-09-04 10:45:09 +02:00
Paul Chote
dfdc893d63 Fix incorrect sequence + cnc support 2010-09-04 11:46:15 +12:00
Paolo Chiodi
669aaab6b4 change mouse sequence to blocked whene map borders are reached 2010-09-04 11:46:14 +12:00
Paolo Chiodi
73017d3f5c lock viewport scrolling into map size 2010-09-04 11:46:14 +12:00
Paolo Chiodi
38fa809656 added .DS_Store to gitignore 2010-09-04 11:46:13 +12:00
Paul Chote
0ed21a4acb Fix ra defenses 2010-09-03 21:47:25 +12:00
Paul Chote
9ae7d98193 Fix ra spawns 2010-09-03 21:47:25 +12:00
Paul Chote
07e60286f2 whoops 2010-09-03 21:47:25 +12:00
Paul Chote
7f918b8a69 fix FIX footprint 2010-09-03 21:47:24 +12:00
Paul Chote
4e0ace6ec5 Tidy production exits, cnc only 2010-09-03 21:47:24 +12:00
Paul Chote
dca5f8d27b Tidy up Mobile yaml / loading 2010-09-03 21:47:24 +12:00
alzeih
6478276064 make cnc nuke leave full area of smudge 2010-09-03 21:47:24 +12:00
alzeih
7d603f97fe cnc bib and footprint fixes (some of #83) 2010-09-03 21:47:24 +12:00
Paul Chote
112fdb32af Another dead actor crashfix 2010-09-03 17:20:30 +12:00
Paul Chote
5a78df0318 Fix flashtarget crash 2010-09-03 16:37:02 +12:00
Paul Chote
6ac4266847 Allow people to join mp games 2010-09-03 16:13:03 +12:00
Paul Chote
91487b85d0 gunboat wake 2010-08-30 22:29:47 +12:00
Paul Chote
178af8b849 cnc afld polish 2010-08-30 21:56:21 +12:00
alzeih
853ef12c8f Don't flash if already dead 2010-08-30 13:57:37 +12:00
alzeih
62cc2fa4cb unbitrot cnc wrt Projectile 2010-08-30 13:20:51 +12:00
Bob
1f4991833d use LoadAttribute in WeaponInfo 2010-08-30 12:22:13 +12:00
Bob
9fedeefdbc attribute individual fields, not the class 2010-08-30 12:22:12 +12:00
Bob
29a77f7c5c removed FieldLoader.LoadFields 2010-08-30 12:22:11 +12:00
Bob
a751b8c49d FieldLoader can run arbitrary code while loading fields 2010-08-30 12:22:11 +12:00
Bob
baacfc96bb remove unused map overrides 2010-08-30 12:22:10 +12:00
Bob
8dcd1e8fd1 line numbers work in MiniYaml.Merge, too 2010-08-30 12:22:10 +12:00
Bob
2a7857570a line numbers in yaml 2010-08-30 12:22:09 +12:00
Bob
2f92b873e8 make yaml into a list, rather than a dict 2010-08-30 12:22:09 +12:00
Chris Forbes
bce52e989f Revert "make WeaponInfo suck a bit less"
This reverts commit 7b7b9d3319.
2010-08-30 12:21:53 +12:00
Chris Forbes
a917086969 cnc: fix htnk not being able to collect crates 2010-08-28 13:56:32 +12:00
Chris Forbes
34913ab077 polish both rocket trucks 2010-08-28 13:54:03 +12:00
Paul Chote
9de22add08 Fix ra queue visibility 2010-08-28 01:29:23 +12:00
Paul Chote
b2f535d2e0 Fix ProductionQueue-on-player init 2010-08-28 00:56:15 +12:00
Paul Chote
3e7b9a7b5a Fix developer menu yaml 2010-08-28 00:55:46 +12:00
Paul Chote
29d03fb133 ra buildable/tooltip/valued fixes 2010-08-28 00:45:12 +12:00
Paul Chote
d4aeb157cc ra Category fixes 2010-08-28 00:03:51 +12:00
Paul Chote
853e60f76e Tech tree changes to support non-buildable prerequisites, capturable superweapons, "hidden tech" for tech buildings, scripted tech unlocks, "build everything" developer toggle. 2010-08-27 23:51:12 +12:00
Paul Chote
7f3e491ecc Fix AI attacking 2010-08-27 11:46:54 +12:00
Paul Chote
88dfbe657c Route "Can i build X" queries via the appropriate ProductionQueue 2010-08-27 01:18:09 +12:00
Paul Chote
226fd167e7 Category dies in a fire 2010-08-27 00:32:00 +12:00
Paul Chote
cedfeab63c PrimaryBuilding is no longer necessary in cnc; remove cruft from BuildPaletteWidget 2010-08-26 23:49:14 +12:00
Paul Chote
a882735deb Fix build tab selection 2010-08-26 23:47:03 +12:00
Paul Chote
61ebe0d0a0 Per-structure queues for cnc 2010-08-26 23:11:54 +12:00
Paul Chote
ee546750b2 Remove some duplication 2010-08-26 23:11:54 +12:00
Paul Chote
267d89a459 Remove BS from ProductionQueue. Move ProductionQueue onto a structure for queue-per-building. 2010-08-26 23:11:53 +12:00
Paul Chote
3b59afcd4f Fix ralint 2010-08-26 23:11:53 +12:00
Paul Chote
8b98448090 Restricted GDI01 tech tree 2010-08-26 23:11:53 +12:00
Paul Chote
1d7ca206f4 Clean up Buildable vs Tooltip vs Valued. cnc only. 2010-08-26 23:11:53 +12:00
Chris Forbes
7b7b9d3319 make WeaponInfo suck a bit less 2010-08-26 22:12:08 +12:00
Chris Forbes
e5d45a6961 fix spurious extra spawn in ra:Equal Opportunity 2010-08-26 21:33:07 +12:00
Chris Forbes
c7f8921cea fix crash in Missile.Tick when the target is killed while the missile is enroute 2010-08-26 21:22:23 +12:00
Chris Forbes
58ebd68478 fail to deliver ore to a proc which has just died. 2010-08-26 20:30:44 +12:00
Chris Forbes
6234f53e2c hack around the buggy AI. 2010-08-26 20:12:29 +12:00
Chris Forbes
ce0e671ac5 fix obvious failures. 2010-08-26 19:53:21 +12:00
Bob
739c38d3d8 more. doesn't run. may not compile 2010-08-26 19:33:56 +12:00
Bob
5561ac458b finished TraitDictionary. Refactored permanent actor-removal. 2010-08-26 19:33:56 +12:00
Bob
c0d0636e08 store traits differently (index on trait class rather than actor) 2010-08-26 19:32:59 +12:00
Chris Forbes
f4da83e920 start cleaning up IWorldLoadHook vs IGameStarted -- IGameStarted dies. 2010-08-25 21:53:54 +12:00
Chris Forbes
50066ec238 merge CreateMapPlayers into CreateMPPlayers 2010-08-25 21:44:54 +12:00
Paul Chote
dbd076543b Low level loadscreen displays earlier 2010-08-25 21:17:05 +12:00
Chris Forbes
2d4ed56f76 make it work, but there's some issues 2010-08-25 20:35:22 +12:00
Paul Chote
03cdcdd4aa Start cleaning up sp player init; doesn't work 2010-08-25 20:15:49 +12:00
Paul Chote
0cc440aa1f Fix ralint 2010-08-25 20:15:49 +12:00
Paul Chote
f635835b1c Refactor common fmv playing code 2010-08-25 20:15:49 +12:00
alzeih
3f08f16b9b some Nod triggers 2010-08-25 20:15:49 +12:00
alzeih
c433ca77c4 Scripted lose condition 2010-08-25 20:15:49 +12:00
alzeih
70a92b80cf Gunboat non-orderable (move)
- Give Mobile OnRails property
- Make hax Move not cancellable
2010-08-25 20:15:49 +12:00
Paul Chote
b3fbefe968 Victory conditions 2010-08-25 20:15:48 +12:00
Paul Chote
f38e4d27be Disable lane bias on gunboat and lst 2010-08-25 20:15:48 +12:00
Paul Chote
c35e3b4bd7 Fix victory conditions 2010-08-25 20:15:48 +12:00
Paul Chote
b0608936d8 Let Gunboat autotarget 2010-08-25 20:15:48 +12:00
Paul Chote
56b9d1add7 Fullscreen video 2010-08-25 20:15:48 +12:00
Paul Chote
5ce531f2d5 Begin fleshing out mission scriping 2010-08-25 20:15:48 +12:00
Paul Chote
c7e76cc26d Visible cargo for LST 2010-08-25 20:15:48 +12:00
Paul Chote
142be86934 Import infantry subcell and actor stance 2010-08-25 20:15:47 +12:00
Paul Chote
73dadbc873 Fix gunboat 2010-08-25 20:15:47 +12:00
Paul Chote
50d5936846 Scripted gdi1 mission intro 2010-08-25 20:15:47 +12:00
Paul Chote
4e86f5b252 Unbreak cnc, defaultmod 2010-08-25 20:15:46 +12:00
Paul Chote
b6b4df703a Shift loadscreen into mods 2010-08-25 20:15:46 +12:00
Paul Chote
b17e6900ec Awesome loadscreen for ra; crashfixes 2010-08-25 20:15:45 +12:00
Paul Chote
08a60ca336 Initial loadscreen impl; draws a black screen. 2010-08-25 20:15:45 +12:00
Paul Chote
d8c053253d wtf? 2010-08-25 20:15:44 +12:00
Paul Chote
e4271b35dc shader params can stay inside Renderer 2010-08-25 20:15:44 +12:00
Paul Chote
95c34c30ba Don't die after render if the world doesn't exist 2010-08-25 20:15:44 +12:00
Paul Chote
8e42dd95fc RGBASpriteRender doesn't care about palettes 2010-08-25 20:15:44 +12:00
Chris Forbes
f2dd0de1ea working game with bots; stop bots from trying to order husks around 2010-08-25 20:05:02 +12:00
Chris Forbes
701ef05562 fix one stupid crash on using bots 2010-08-25 19:36:22 +12:00
Chris Forbes
c3228cecd0 helps to get the command syntax right 2010-08-25 19:35:14 +12:00
Chris Forbes
47eacc5b80 make bot slot usage actually work 2010-08-25 19:34:20 +12:00
Chris Forbes
909152c662 move HackyAI bot from world to player context 2010-08-25 19:25:19 +12:00
Chris Forbes
0f9221dc5a mostly sensible init for real players and bots 2010-08-25 19:23:25 +12:00
Chris Forbes
cfc937e8eb add PlayerReference.DefaultStartingUnits flag (set for autogenerated playerrefs; don't set this if you have custom stuff. 2010-08-25 18:28:36 +12:00
Chris Forbes
def0580078 don't create players for playable slots which are empty 2010-08-25 18:24:23 +12:00
alzeih
3c7015567e Open/Closed toggle includes Bot now 2010-08-25 00:13:41 +12:00
alzeih
a00f0b18a0 smite some compile errors 2010-08-24 23:44:22 +12:00
alzeih
703f3b8c13 right beep in ra 2010-08-24 23:30:41 +12:00
mgatland
bf9bcfed68 bot builds units and sends them out. Crude + fragile... 2010-08-24 23:19:33 +12:00
alzeih
f6dac1fe83 Fix rebase 2010-08-24 22:56:31 +12:00
mgatland
731c64c1a7 add a bot player, make ai apply to the bot not the local player 2010-08-24 22:56:31 +12:00
Chris Forbes
19494c3262 much better ai bases 2010-08-24 22:52:41 +12:00
Chris Forbes
cf9a2ee0ef tune base fractions a bit 2010-08-24 22:52:41 +12:00
Chris Forbes
93e8bd6644 build a base successfully. 2010-08-24 22:52:40 +12:00
Chris Forbes
4d0f75353b spam powr 2010-08-24 22:52:40 +12:00
Chris Forbes
fb035756a0 better handling of 'needing power' 2010-08-24 22:52:40 +12:00
Chris Forbes
e0a00940af initial buildqueue ai 2010-08-24 22:52:40 +12:00
Chris Forbes
e74c3eeb2e hook in an ai stub. all it does for now is deploy the mcv. 2010-08-24 22:52:40 +12:00
Chris Forbes
05bf6d83f2 clean up one silly use of world.players 2010-08-24 20:02:20 +12:00
Chris Forbes
e4b65256de remove a bit of duplication from UnitOrders 2010-08-24 20:02:19 +12:00
Chris Forbes
d744cfe21b change exploit order check to cope with PlayerId not matching ClientId, because it doesnt. 2010-08-24 20:02:19 +12:00
Chris Forbes
6ae7da77ae fix wtf in PlayerResources 2010-08-24 20:02:18 +12:00
Chris Forbes
0352884205 blah 2010-08-24 20:02:18 +12:00
Chris Forbes
7c6edab04e work for ra too 2010-08-24 20:02:17 +12:00
Chris Forbes
997501bb12 ui for opening and closing slots 2010-08-24 20:02:17 +12:00
Chris Forbes
d4f43a399e add slot open/close server commands with boot on close 2010-08-24 20:02:16 +12:00
Chris Forbes
f6ec2163de fix some dumb issues 2010-08-24 20:02:16 +12:00
Chris Forbes
3428b3c4c2 add slot command 2010-08-24 20:02:15 +12:00
Chris Forbes
8ec16fdbbe fail fail fail 2010-08-24 20:02:15 +12:00
Chris Forbes
39f699916c start hacking up lobby to work with slots (cnc only) 2010-08-24 20:02:14 +12:00
Chris Forbes
4a337185f5 if there are no Playable playerrefs in the map, make as many as there are spawnpoints (hack) 2010-08-24 20:02:14 +12:00
Chris Forbes
298f5ec24f some notes 2010-08-24 20:02:13 +12:00
Chris Forbes
16402f26fe start breaking things 2010-08-24 20:02:13 +12:00
Paul Chote
825743b225 Fix packaged startup on windows and osx. 2010-08-24 19:53:05 +12:00
Paul Chote
c3b3947b9d Rename some settings 2010-08-24 19:53:05 +12:00
Paul Chote
1143f496db Part 2 of 3: Split Settings into logical units.
Syntax for command line overrides is now <section>.<setting>=<value>
eg `General.InitialMods=cnc'
2010-08-24 19:53:05 +12:00
Paul Chote
46d0ce89e9 Fix silly naming conventions 2010-08-24 19:53:05 +12:00
Chris Forbes
79ced35010 make InfiltrateForSonarPulse work for any support power 2010-08-24 17:37:06 +12:00
Chris Forbes
18a06eb3bf wtf 2010-08-23 20:58:56 +12:00
Chris Forbes
d8c5f1aed3 extract serialize code from Server; deserialize code from Game; add Slot collection. 2010-08-23 19:08:09 +12:00
Chris Forbes
3880326787 ship out ChooseInitialStance from Game 2010-08-23 18:34:47 +12:00
Chris Forbes
09d9396123 move Session back to Game 2010-08-23 18:31:43 +12:00
Chris Forbes
aeccf53e97 squash some spurious warnings 2010-08-23 18:23:55 +12:00
Chris Forbes
b1b8b2c14a remove N params from ServerMain 2010-08-23 18:19:36 +12:00
Chris Forbes
fd9a31168d server loads the map (part 1) 2010-08-23 18:09:37 +12:00
Chris Forbes
3f11c32c4a blah 2010-08-23 17:58:25 +12:00
Chris Forbes
d65626e87c move Manifest into its own file 2010-08-23 17:51:08 +12:00
Chris Forbes
ccb77dee12 rename ChoosePaletteOnSelect 2010-08-23 17:47:46 +12:00
Paul Chote
952da4efec Fix wrong-palette in first tick 2010-08-21 20:39:15 +12:00
Paul Chote
49f2bfb460 Only reload sprites on theatre change; kill cruft 2010-08-21 20:34:59 +12:00
Paul Chote
9db92ed8ba Shift the nasty bits of map loading into ModData 2010-08-21 20:23:14 +12:00
Paul Chote
4e2d76f6ed Move AvailableMaps into ModData 2010-08-21 20:11:05 +12:00
Bob
94dd73cb48 fixed world to run ALL of the frameEndActions 2010-08-21 19:24:17 +12:00
Bob
aeb9f4e441 moved call to FindMaps into ChangeMods 2010-08-21 19:20:06 +12:00
Bob
1a4e3053ce inlined InitializeEngineWithMods; cleaned trailing whitespace in Game; removed non-working Replay code 2010-08-21 19:16:43 +12:00
Bob
18914447aa fixed Renderer init (separated device creation from shader load) 2010-08-21 18:59:05 +12:00
Bob
7e67a5bb2d move calls to manifest ctor into ModData 2010-08-21 18:26:16 +12:00
Bob
9eaa0e5765 extract SyncReport class from Game 2010-08-21 17:59:17 +12:00
Bob
0e16aa339d move SheetBuilder singleton onto ModData 2010-08-21 17:44:06 +12:00
Bob
c7b650d6ec de-static'd CursorSheetBuilder 2010-08-21 17:36:58 +12:00
Bob
bcc3cd32ae merge call of FileSystem.LoadFromManifest into modData ctor 2010-08-21 17:28:51 +12:00
Bob
38ffd30b28 removing duplication wrt mounting FS packages 2010-08-21 17:27:54 +12:00
Bob
15bd58ddce extracting world-specific data from Game 2010-08-21 17:11:26 +12:00
Bob
7247bd1078 changed UIM to use less memory 2010-08-21 15:10:54 +12:00
Chris Forbes
ac31767aef some random housekeeping (ScreenShaker) 2010-08-21 15:10:53 +12:00
Bob
3f68330c70 pruning refs to Game.world 2010-08-20 17:46:58 +12:00
Bob
0e71af25f4 remove Game.skipMakeAnims 2010-08-20 17:14:20 +12:00
Chris Forbes
e610c4d7fc ffs, fix beedee's upload script so it uploads. 2010-08-19 21:07:31 +12:00
Chris Forbes
0a041fe425 use byte[] backing for Sheet. bitmap backing is still available for Chrome RGBA hack. 2010-08-19 19:22:03 +12:00
Chris Forbes
1595c6a0ed interim hack to support use of raw data in Sheet 2010-08-19 18:42:45 +12:00
Chris Forbes
db7a11e8a6 some random bits 2010-08-19 18:33:52 +12:00
Chris Forbes
53df4c4bfb remove batch fail 2010-08-19 18:10:38 +12:00
Paul Chote
1afcd2b98a Move rules and SSB init out of world 2010-08-19 00:09:48 +12:00
Paul Chote
08ffe1d44d Reload chrome images only on mod change 2010-08-18 23:57:18 +12:00
Paul Chote
66359b7058 Speed up FileSystem 2010-08-18 23:40:05 +12:00
Paul Chote
30ab5c33ea Fast checking for file existance 2010-08-18 22:56:16 +12:00
Paul Chote
0c5fb4c6b0 Kill LoadShellMap 2010-08-18 22:41:00 +12:00
Paul Chote
21b0b12948 Fix MP gamestart 2010-08-18 22:21:08 +12:00
Paul Chote
cb3f6435ad Kill broken log uploading 2010-08-18 20:45:30 +12:00
Paul Chote
235ae1fad7 osx packaging fixes: Runs when name contains spaces, fixes "Cannot connect to master server". 2010-08-18 20:35:55 +12:00
Chris Forbes
1c6470eff3 add movement-free autotarget option 2010-08-18 17:47:38 +12:00
Paul Chote
0cf51d8142 Skip movies with `esc' 2010-08-17 22:59:41 +12:00
Paul Chote
38e5f70cbe Ingame briefing support 2010-08-17 22:59:41 +12:00
Paul Chote
56b0da0b13 Singleplayer campaign support: player/world init 2010-08-17 22:59:41 +12:00
Paul Chote
d6f0a03270 Ignore orders sent to other players' actors (fixes an entire class of exploits). 2010-08-17 22:59:41 +12:00
Chris Forbes
b1b75ecf2f fix wtf in spy 2010-08-17 21:42:25 +12:00
Caleb Anderson
228852a55d Inverse Drag Scrolling 2010-08-17 21:02:51 +12:00
Chris Forbes
f6a880e524 line way too long. 2010-08-17 20:32:10 +12:00
Chris Forbes
7e82dc729b fix mouse/tree and mouse/crate interactions. 2010-08-17 19:58:51 +12:00
Matthew
d91a7c6b35 Increasing robustness of packaging script. 2010-08-16 01:03:14 +12:00
Chris Forbes
b4068f0ac7 msam polish -- contains some dirty hacks 2010-08-15 21:11:38 +12:00
Chris Forbes
b336a1e478 make cnc fact significantly harder to kill 2010-08-15 20:53:36 +12:00
Chris Forbes
55afcddce0 fix alignment on gdi rocket truck 2010-08-15 20:50:21 +12:00
Chris Forbes
ac7bb3c71b use activity cursor rather than deploy for disguise 2010-08-15 20:36:29 +12:00
Chris Forbes
3aa7ff5a6b fix various bugs in prev 2 2010-08-15 20:29:09 +12:00
Chris Forbes
0b3414c46f disguise on self to lose it. 2010-08-15 20:22:59 +12:00
Chris Forbes
fdcad8710b first cut at disguise 2010-08-15 20:21:27 +12:00
Paul Chote
02a7b092dc Use map-defined stances 2010-08-15 20:15:45 +12:00
Paul Chote
d43781c604 Import legacy players 2010-08-15 20:15:45 +12:00
Chris Forbes
cfbededcc4 a quick hack to set the 32bit flag in corheader 2010-08-15 18:26:58 +12:00
Paul Chote
9ba50a9c5e Set turret facings correctly 2010-08-15 18:03:13 +12:00
Paul Chote
6377269a14 BOAT and LST work ingame (need special render hax, but don't crash) 2010-08-15 18:00:27 +12:00
Paul Chote
a8be81ea2b Import actor facing and health from legacy maps 2010-08-15 17:47:04 +12:00
Paul Chote
50950cba22 Scripted map format docs 2010-08-15 17:23:19 +12:00
Paul Chote
210e847904 cnc BOAT template 2010-08-15 16:59:14 +12:00
Paul Chote
54f7b6430d Fix map importer 2010-08-15 16:58:46 +12:00
Paul Chote
26e823fc25 EVW2 basically playable. Needs tweaking (too much tib?) and tech structures. 2010-08-15 16:14:14 +12:00
Paul Chote
10ea035b42 Fix #41 2010-08-15 15:34:27 +12:00
Paul Chote
58fb7178ad cnc Balance tweaks 2010-08-15 07:14:10 +12:00
alzeih
cd358eb985 Fix #24 2010-08-15 06:32:12 +12:00
Paul Chote
39d4b80323 Tweak sub stats 2010-08-15 06:18:47 +12:00
Paul Chote
45a4935b01 Cannot cloak if critical health 2010-08-15 06:18:47 +12:00
Paul Chote
824e2a7b0b Auto-target detected subs 2010-08-15 06:18:47 +12:00
Paul Chote
230d59f655 Tweak visibility; hopefully allows targeting of detected units 2010-08-15 06:18:46 +12:00
Paul Chote
7f191887ec Revamp cloak model 2010-08-15 06:18:46 +12:00
Paul Chote
499613f105 Depthcharges only work against subs 2010-08-15 06:18:46 +12:00
Paul Chote
20af2b5c0a Heli's don't land when idle 2010-08-15 06:18:46 +12:00
alzeih
cbc9d66bee SYRD + SPEN have rally points 2010-08-15 05:39:45 +12:00
alzeih
c338612b9f Fully laden harv's are too slow now 2010-08-15 04:38:53 +12:00
Paul Chote
edd0a7c614 Marooned tweaks 2010-08-15 03:16:26 +12:00
Paul Chote
1d259e4bc7 Nowhere to hide tweaks 2010-08-15 03:13:47 +12:00
Paul Chote
6c651e9d02 Halve fact/mcv value 2010-08-15 03:03:05 +12:00
Paul Chote
a29e0bf4b1 Lower proc cost 2010-08-15 03:03:05 +12:00
Paul Chote
9d403d3072 Unfail `Marooned' map slightly 2010-08-15 03:03:04 +12:00
Paul Chote
184d044f26 Run packaged version with --debug on osx 2010-08-15 03:03:04 +12:00
Chris Forbes
0473aed2c3 fix crash when civilians die 2010-08-15 02:45:20 +12:00
Matthew
db5920e83a Minor fixes to packaging. 2010-08-15 02:08:49 +12:00
Matthew
80555235d7 Fixes for Windows packaging. 2010-08-15 02:08:49 +12:00
Matthew
acd842f178 Windows support added to general packager. 2010-08-15 02:08:49 +12:00
Matthew
a5dacd52e8 OSX support added to general packager. 2010-08-15 02:08:49 +12:00
Matthew
6e045e864a Further RPM fixes 2010-08-15 02:08:49 +12:00
Matthew
0541b04c3a RPM packaging fixes. 2010-08-15 02:08:49 +12:00
Matthew
07b2bcbfdf RPM support in general packaging script. 2010-08-15 02:08:49 +12:00
Matthew
0e2b4bb721 General package script works for Arch-Linux packages. 2010-08-15 02:08:49 +12:00
Paul Chote
ab3c06cd04 Fail 2010-08-15 01:59:23 +12:00
Chris Forbes
299ee7f82c remove redundant devmode checkbox in settings -- 'enable cheats' does it 2010-08-15 01:44:38 +12:00
Paul Chote
ddd56e6f9b Reveal-map crate 2010-08-15 01:43:24 +12:00
Paul Chote
839043ea1b Disable music player until its finished 2010-08-15 01:13:49 +12:00
Paul Chote
1e8aea616b Hook up music seek 2010-08-15 01:07:05 +12:00
Paul Chote
727a88d82a Listbox content shouldn't steal clicks if they're clipped 2010-08-15 00:44:19 +12:00
alzeih
1f54ad3238 Oops 2010-08-15 00:38:31 +12:00
Paul Chote
694fd84188 Clean up custom color palette 2010-08-15 00:18:06 +12:00
alzeih
271be551b0 Add Voices and DisableVariants to VoiceInfo, remove the ".aud" for die sounds. 2010-08-15 00:07:27 +12:00
alzeih
fe481d7445 Fix #36
- add to ra
- add default variant
2010-08-15 00:07:27 +12:00
alzeih
7a10ae3dea Some of fixing #36 2010-08-15 00:07:27 +12:00
Chris Forbes
8c39e372e3 throttle mouse motion events to one per frame 2010-08-14 23:48:12 +12:00
Paul Chote
af6660d6ca Fix palette remaps 2010-08-14 23:36:41 +12:00
Paul Chote
d0da9d11bf Fix palettes and all palettemods. Remap palettes broken. 2010-08-14 23:29:01 +12:00
Paul Chote
0a2d39f15b More correct, still doesn't work. 2010-08-14 22:23:22 +12:00
Paul Chote
8118a17e3c foo 2010-08-14 21:53:24 +12:00
Paul Chote
0f6564f31a more or less fail 2010-08-14 21:36:13 +12:00
Paul Chote
dda6556e17 non-working palette fail 2010-08-14 21:07:19 +12:00
Paul Chote
5c1408d4d7 cnc water palette rotation 2010-08-14 17:52:59 +12:00
Chris Forbes
aa6e671d89 cnc tran unloadfacing=initialfacing 2010-08-14 17:44:36 +12:00
alzeih
e0de1427e9 Die sanely when a widget doesn't exist. 2010-08-14 17:39:50 +12:00
alzeih
db16ab4cdc Add VideoVolume 2010-08-14 17:39:50 +12:00
Bob
ae703d50b2 Actor.traits is implementation detail 2010-08-14 17:39:49 +12:00
Paul Chote
f6c6255f64 Custom tiberium pathing cost 2010-08-14 17:37:36 +12:00
Paul Chote
a569c712f0 Video pausing support; sync video to audio nicer. 2010-08-14 17:21:54 +12:00
Paul Chote
5c8c8d5e6e Support more video types. 2010-08-14 15:59:40 +12:00
alzeih
3f4f1ff75e MusicSeekPosition 2010-08-14 14:24:25 +12:00
Paul Chote
1aa4f57a68 Prototype new music player 2010-08-14 14:05:32 +12:00
Paul Chote
3f3ac377b2 Backend changes for new music player 2010-08-13 19:46:13 +12:00
Paul Chote
de12233edc cnc movie list 2010-08-13 00:30:46 +12:00
Paul Chote
b36b101392 Soviet movie definitions 2010-08-12 21:07:38 +12:00
Chris Forbes
726449b6fb fix it so it works when have no movies 2010-08-12 20:47:38 +12:00
Paul Chote
a0d7435550 Overlay with black lines for authentic ra feel 2010-08-12 20:47:38 +12:00
Paul Chote
11aed465a8 Populate the list from yaml; Define ra-allies movies; Additional polish. 2010-08-12 20:47:37 +12:00
Paul Chote
0f953226a6 Populate and use the listbox 2010-08-12 20:47:37 +12:00
Chris Forbes
ad181544cd give cnc towers significantly more hp 2010-08-12 20:44:03 +12:00
Chris Forbes
df19163ce5 fix #18 -- harvs built at weap choose a proc when trying to return now 2010-08-12 19:54:37 +12:00
Chris Forbes
4328fbc350 fix color picker again 2010-08-12 19:35:36 +12:00
Chris Forbes
7cd9afb6d2 remove some sillyness from the masterserver -- it shouldnt hold up the works. 2010-08-12 19:27:11 +12:00
Chris Forbes
1ad8b58f1b blah 2010-08-12 18:34:48 +12:00
Matthew
62e3d548c8 Makefile generated start-up script altered to allow command line switches to be passed to executable. 2010-08-12 18:11:06 +12:00
Matthew
ea7abcb585 Makefile install target fix. 2010-08-12 18:11:06 +12:00
Chris Forbes
441bffecfc fix #262 -- harv should move slower when full 2010-08-12 18:10:23 +12:00
Paul Chote
2c1ab33893 Add a "Video Player" menu with basic impl; kill the music player widget. 2010-08-12 18:06:12 +12:00
Paul Chote
74500c369c Stop video soundtrack when video stops 2010-08-12 00:44:53 +12:00
Paul Chote
6e0158039a Support uncompressed audio (ally1.vqa) 2010-08-12 00:37:19 +12:00
Paul Chote
c600239c54 Begin making video player widget useful; steal (othewise useless) musicplayer controls for now 2010-08-12 00:31:30 +12:00
Paul Chote
93a48c0cf1 Tweaks 2010-08-12 00:06:08 +12:00
Paul Chote
b88512df43 Keep video in sync with audio 2010-08-11 23:58:30 +12:00
Chris Forbes
ca6debde66 buffer up all the audio upfront 2010-08-11 22:56:32 +12:00
Chris Forbes
8dd9848636 preserve aud codec state across blocks, so the gain isnt completely bogus 2010-08-11 22:19:49 +12:00
Chris Forbes
ec9da154ad add crap broken sound support for vqa 2010-08-11 22:04:55 +12:00
Chris Forbes
46fc0ef563 add ignore for vqas; disable the vqaplayer in the mainmenu for now 2010-08-11 21:44:42 +12:00
Paul Chote
514c92a998 FAST vqa render 2010-08-11 19:54:24 +12:00
Paul Chote
96f9f33776 Tweaks 2010-08-11 19:04:03 +12:00
Paul Chote
20553a112d Don't hide the original crash if the master server is inaccessible 2010-08-11 18:20:50 +12:00
Paul Chote
9e49cad1c2 .vqp format doc 2010-08-11 14:56:16 +12:00
Paul Chote
5c6e2a5e42 Fix crash when cnc videos loop 2010-08-11 11:53:01 +12:00
Paul Chote
44d7aa14a4 Hacky ingame video widget 2010-08-11 11:45:37 +12:00
Paul Chote
bf8e3645cb cnc support (doesn't use format80) 2010-08-11 01:34:05 +12:00
Paul Chote
6ea8d4e6d3 Test a different video; fix a stupid crash. All works except for sound. 2010-08-11 00:57:49 +12:00
Paul Chote
16c3223f3e Fix 8-frame glitch 2010-08-11 00:57:49 +12:00
Paul Chote
b98e180361 Dump the animation to a set of bitmaps; glitches every 8 frames. 2010-08-11 00:57:49 +12:00
Paul Chote
80aade857e Start removing fail 2010-08-11 00:57:49 +12:00
Paul Chote
58700e4c07 Save the hax pixels too 2010-08-11 00:57:49 +12:00
Paul Chote
d364472862 Write the pixels that don't need further hax to a bitmap 2010-08-11 00:57:49 +12:00
Paul Chote
5d688a2e27 CBFZ, CBPZ, CPL0 chunks 2010-08-11 00:57:49 +12:00
Paul Chote
f4fa053a35 Add a null parser for VQFR chunk 2010-08-11 00:57:49 +12:00
Paul Chote
90373529b0 Parse FINF and (skip) SND2 2010-08-11 00:57:49 +12:00
Paul Chote
0416b6b429 Format docs 2010-08-11 00:57:48 +12:00
Paul Chote
bd991e33ca Begin vqa support; load and display FORM header 2010-08-11 00:57:48 +12:00
Chris Forbes
f162c5956e cleanup wtf 2010-08-10 21:51:06 +12:00
Chris Forbes
e6f717ff04 FAST 2010-08-10 21:26:50 +12:00
Chris Forbes
eb0c895e2c fix prev 2010-08-10 21:26:44 +12:00
Chris Forbes
3af0d2f6a4 noise reduction 2010-08-09 17:29:50 +12:00
Chris Forbes
8f6fe8344b split PrimaryBuilding from Production 2010-08-09 17:20:34 +12:00
Paul Chote
cb5307bb17 nerf e1 (stole ra damage stats) 2010-08-08 21:47:31 +12:00
Paul Chote
d9acf1a3e5 Don't teleport into transport's. 2010-08-08 19:30:49 +12:00
Paul Chote
6fc945ac91 Fix cargo/passenger interaction 2010-08-08 19:16:37 +12:00
Paul Chote
e5878e8207 Fix Color Picker 2010-08-08 18:45:05 +12:00
Paul Chote
b982a52086 stop .net clients taking out the server on drop 2010-08-08 18:26:55 +12:00
Matthew
f28ec846e7 WindowsBase.dll added to thirdparty DLLs to work around distributions with outdated versions of Mono. 2010-08-07 16:11:18 +12:00
Chris Forbes
551814fc32 fix crash when a bridge is destroyed, and has a husk on it. 2010-08-06 21:02:46 +12:00
Chris Forbes
f64a6e273e fix sub -> ground crash 2010-08-06 20:11:49 +12:00
Matthew
1a428186e9 Minor fix to arch-linux post install script. 2010-08-06 14:15:53 +12:00
Matthew
609abb7719 Fixes to include extra mod dirs in Makefile and correct paths in post install scripts. 2010-08-06 14:03:37 +12:00
Matthew
aee0728a73 SupportDir path fixed. 2010-08-06 12:37:21 +12:00
Matthew
120a5fa66b Packaging and Makefile fixes. 2010-08-06 12:28:09 +12:00
Chris Forbes
71792a8f09 fix crash on telling {sam,agun} to attack ground 2010-08-04 18:23:06 +12:00
Chris Forbes
0f20133af0 fix crash in retry 2010-08-03 20:40:27 +12:00
Paul Chote
40b16e33ba Fix and polish all ra production structures; remove some obsoleted Production subclasses 2010-08-03 18:29:32 +12:00
Paul Chote
8e82f6fa1a Fix a retarded crash with husks; remove some debug 2010-08-03 01:16:24 +12:00
Paul Chote
053f0f5c7f Refactoring + cnc weap 2010-08-03 01:03:31 +12:00
Paul Chote
7c562059c2 Fix cnc afld 2010-08-03 00:17:11 +12:00
Paul Chote
cf5cb80c61 Restore cnc helicopters (reservable etc changes deferred) 2010-08-02 23:57:19 +12:00
Paul Chote
711378d352 Polish cnc pyle & hand inf production; lays groundwork for future polish. Likely breaks every other production structure (untested). 2010-08-02 23:35:35 +12:00
Paul Chote
7d044a9e1b Remove custom cnc behavior 2010-08-02 20:43:56 +12:00
Paul Chote
bc93e8cac0 Health as an ActorInit 2010-08-02 20:12:04 +12:00
alzeih
578d42614b Convert all CreateActor calls to use TypeDictionary 2010-08-02 01:51:13 +12:00
alzeih
4ea66ea309 Added FacingInit and AltitudeInit. Used in Mobile/Aircraft/Husks. Refactored Production, SpyPlane, Paratroopers and LeavesHusk 2010-08-02 00:49:26 +12:00
alzeih
2cc6e197fa fix makefile 2010-08-02 00:36:18 +12:00
Chris Forbes
2ea0907d66 convert ra maps to format3 2010-08-01 23:46:16 +12:00
Chris Forbes
d50d26350e upgrade caffeinated as a test. 2010-08-01 21:02:12 +12:00
Chris Forbes
b77bddddbc fix maploader to be backwards compatible. InitDict-based format is now 3. Formats 1,2 are translated on load, and will be saved back as Format 3 if saved in the editor. 2010-08-01 21:00:17 +12:00
Chris Forbes
3521319095 editor compiles again 2010-08-01 20:40:23 +12:00
Bob
dfc24233f7 fix broken rebase 2010-08-01 19:38:44 +12:00
Bob
970eb4d6e1 use the new actorinit stuff when loading map yaml 2010-08-01 19:38:42 +12:00
Bob
10b7ece62e new mapactor init stuff 2010-08-01 19:38:39 +12:00
Bob
f789aef892 map format change: move mapactor Type onto header line 2010-08-01 19:38:37 +12:00
Bob
bceaecf031 change map format to remove redundant crap 2010-08-01 19:38:35 +12:00
Bob
74155812d0 don't merge yaml in chrome; just load sequentially 2010-08-01 19:38:32 +12:00
Bob
f49ec8d6b9 don't mention rootwidget in chrome yaml 2010-08-01 19:38:30 +12:00
Chris Forbes
fd5d441086 fix all the broken maps 2010-08-01 18:46:46 +12:00
Chris Forbes
eb85189c24 transparently upgrade maps produced by buggy converter 2010-08-01 18:42:48 +12:00
Chris Forbes
9bd808fcb8 generate a neutral player 2010-08-01 18:38:38 +12:00
Chris Forbes
968387eab2 converted all the cnc maps 2010-08-01 18:28:45 +12:00
Chris Forbes
f8f1e2a531 add warning on window close with modified map 2010-08-01 18:12:03 +12:00
Chris Forbes
8707bbd569 remove standalone MapConverter 2010-08-01 18:03:03 +12:00
Chris Forbes
724df5ad54 add central-conflict and marooned-ii via new importer 2010-08-01 18:02:02 +12:00
Chris Forbes
0f33913bf6 force x86 on MapConverter project 2010-08-01 17:15:51 +12:00
Chris Forbes
d856eb5905 move bits around in MapConverter 2010-08-01 17:10:05 +12:00
Chris Forbes
ab9e7ce672 replace editor toolbar with menus 2010-08-01 16:59:19 +12:00
Chris Forbes
741e43ab14 disable vshost for editor; move tabs back to top edge 2010-08-01 16:19:35 +12:00
Chris Forbes
4b0f66496c blah 2010-08-01 16:11:47 +12:00
Chris Forbes
260fe70e5f remove 'Middle of Hell' map, it's garbage 2010-08-01 16:07:55 +12:00
Chris Forbes
ae3d7bbe24 disable vshost 2010-08-01 16:02:32 +12:00
Chris Forbes
990eeb844a ChooseAirfield chooses closest, rather than first. 2010-08-01 15:49:52 +12:00
Chris Forbes
4567bad251 make Activities.Land work with Targets. 2010-08-01 14:57:07 +12:00
Chris Forbes
aafbeed703 ffs, doing it the hard way as usual 2010-08-01 14:36:53 +12:00
Chris Forbes
002bc20d50 some improvement to alfd/plane interaction 2010-08-01 14:32:59 +12:00
Chris Forbes
19c5c56ab2 ra.ss, ra.msub, cnc.stnk all spawn cloaked/submerged 2010-08-01 14:07:15 +12:00
Chris Forbes
718b0e7613 fix mslo nuke offset 2010-08-01 13:03:53 +12:00
Chris Forbes
5b5378ae6c make tmpl capturable 2010-08-01 12:54:39 +12:00
Chris Forbes
67418e0b9d fix capturing of neutral buildings 2010-08-01 12:23:45 +12:00
Chris Forbes
ca986688a1 fix primary building & building fallback when busy 2010-08-01 12:11:48 +12:00
Chris Forbes
97e43cfe40 add ReservableProduction, to start fixing afld behavior. 2010-08-01 11:57:33 +12:00
Chris Forbes
a0ca52491e add some debug to Reservable so we can see what retardage is happening 2010-08-01 11:49:55 +12:00
Chris Forbes
039a42cfef fix spyplane (it doesnt want Mobile) 2010-08-01 11:49:23 +12:00
Chris Forbes
e2ab99c0cc remove dead crap from Plane 2010-08-01 11:49:00 +12:00
Chris Forbes
5daaa99108 start cleaning up reservations 2010-08-01 11:35:26 +12:00
Chris Forbes
13244d17f1 format and clean up DrawLineToTarget 2010-08-01 11:32:09 +12:00
Chris Forbes
e8604d172c add levelup crates to cnc 2010-08-01 11:17:27 +12:00
Chris Forbes
9e0f0d2074 fix cloaking crate 2010-08-01 10:40:26 +12:00
Chris Forbes
3dae071f41 drop aftermath support from the installer 2010-08-01 09:59:53 +12:00
Paul Chote
d5dbd1b7da Fix Monodevelop build 2010-08-01 01:48:12 +12:00
Chris Forbes
b1736e5efd fix VS build 2010-08-01 01:40:37 +12:00
Paul Chote
bd979f65b8 Kill Unit trait; Radar signature tweaks 2010-08-01 01:26:59 +12:00
Paul Chote
d416f0be5c Shift "XXX Lost" notification onto a trait. Hook up "Structure Lost" (cnc) and "Airborne Unit Lost" (ra). 2010-08-01 01:01:31 +12:00
Paul Chote
45e54e1ca8 Kill some spurious references to Unit 2010-08-01 01:01:31 +12:00
Paul Chote
d29e3f3f0e Split facing into its own interface; fix husks 2010-08-01 01:01:31 +12:00
Paul Chote
207ee49da3 Move Facing and Altitude onto IMove impls, with associated pile of cleanups 2010-08-01 01:01:31 +12:00
Paul Chote
88cb942430 Cleaner access to InitialFacing and ROT 2010-08-01 01:01:31 +12:00
Chris Forbes
765bedb592 add cloak crate action to cnc 2010-08-01 00:21:20 +12:00
Chris Forbes
2c73d8a48d remove some dead files 2010-07-31 23:37:56 +12:00
Chris Forbes
750275d08f reduce crap a little more 2010-07-31 23:24:32 +12:00
Chris Forbes
491d38cafe move Weapon & friends into own file 2010-07-31 23:21:22 +12:00
Chris Forbes
6c6da12dd6 fix local offset -> screen space transform to work as advertised 2010-07-31 23:01:56 +12:00
Chris Forbes
0b20d1366a eliminate old form of GetTurretPosition 2010-07-31 22:33:54 +12:00
Chris Forbes
fa245aaa08 introduce collection of Turrets on AttackBase, too -- turret sharing w/ recoil works again 2010-07-31 22:19:29 +12:00
Chris Forbes
9a218f7b52 GetPrimaryWeapon() dies too. 2010-07-31 21:34:24 +12:00
Chris Forbes
d202e27f79 more tesla hax? 2010-07-31 21:34:24 +12:00
Chris Forbes
960dddc048 AttackTesla hax 2010-07-31 21:34:23 +12:00
Chris Forbes
9fcc739cd5 more... Combat.GetSecondaryWeapon() dies, etc 2010-07-31 21:34:23 +12:00
Chris Forbes
449cc4a42d remove old buff crates 2010-07-31 21:34:22 +12:00
Chris Forbes
b8421ba655 move more combat bits around 2010-07-31 21:34:22 +12:00
Chris Forbes
2ac261c15b remove other param spam from CheckFire 2010-07-31 21:34:22 +12:00
Chris Forbes
2bd9cd32f6 remove WeaponInfo param from CheckFire 2010-07-31 21:34:21 +12:00
Chris Forbes
693c8d96b1 introduce a Barrel object, unhacking the local offsets. 2010-07-31 21:34:21 +12:00
Chris Forbes
42683f5966 start refactoring AttackBase 2010-07-31 21:34:20 +12:00
Chris Forbes
2478b26a05 GetOrDefault can die. 2010-07-31 12:41:11 +12:00
Chris Forbes
2608ab3bf6 fix crash on building ttnk 2010-07-31 12:23:09 +12:00
Chris Forbes
9fc8b81362 disable speed/armor/firepower crates in favour of levelup crate 2010-07-31 12:23:09 +12:00
Chris Forbes
5093d531bc tweak unit crate shares 2010-07-31 12:23:08 +12:00
Chris Forbes
08d75cb55c add GiveMcvCrateAction, and wire unit crates / mcv crates / etc 2010-07-31 12:23:08 +12:00
Chris Forbes
4c24547c26 add GiveUnitCrateAction 2010-07-31 12:23:07 +12:00
Bob
53b9b63ae5 change Mobile, Move to use Mobile.toCell instead of Actor.Location 2010-07-31 12:23:07 +12:00
Chris Forbes
cd40b27357 fix bitrot in cnc and ra 2010-07-31 12:23:06 +12:00
Chris Forbes
3c10d14f60 add shok 2010-07-31 09:27:13 +12:00
Chris Forbes
035bc96b37 various bits 2010-07-31 09:27:09 +12:00
Chris Forbes
357e74573c fix .gitignore, which banned .aud by default for some reason 2010-07-31 09:25:41 +12:00
Chris Forbes
668c5c7bdd add missing sounds 2010-07-31 09:25:41 +12:00
Chris Forbes
7a0d898b1a integrate ttnk into ra; also art for shok; all am pieces are now in ra/extras 2010-07-31 09:25:40 +12:00
alzeih
33b6f590e9 move ROT, InitialFacing and Speed to Mobile and Aircraft. 2010-07-31 02:06:30 +12:00
Paul Chote
dd7008d7ee Make crates collectable; make cnc walls targetable. 2010-07-31 01:50:14 +12:00
Paul Chote
9b051a6624 Remove some bs from buildings with multiple damage states; cnc civilian structure rubble persists after death. 2010-07-31 01:50:09 +12:00
Paul Chote
62c2c3a1c6 Fix damage transition sounds 2010-07-30 22:24:43 +12:00
Paul Chote
8528c5d3a3 Correct the ordering on DamageState 2010-07-30 22:24:43 +12:00
Paul Chote
4cf0610fd9 Change DamageState names 2010-07-30 22:24:43 +12:00
Paul Chote
1459ec483c Rename ExtendedDamageState -> DamageState 2010-07-30 22:24:43 +12:00
Paul Chote
028c5b5201 Merge the two DamageState types 2010-07-30 22:24:43 +12:00
Chris Forbes
41c0d175bd fix paradrop being broken (again!) 2010-07-30 21:20:13 +12:00
Paul Chote
9280dd9f2f Add some polish 2010-07-30 21:00:23 +12:00
Paul Chote
bde16e4e15 Remove a pile of duplication on mcv undeploy 2010-07-30 21:00:23 +12:00
Paul Chote
119f85dbf4 Unfail mcv deploy 2010-07-30 21:00:23 +12:00
Bob
ede160f1b6 move some more (gameplay related) widgets into mods/ 2010-07-30 20:55:03 +12:00
Bob
b4c84a11f2 changes to allow widgets to be in mods/; moved BuildPaletteWidget into mods/ 2010-07-30 20:15:14 +12:00
Bob
2dd558a065 move LastMousePosition et al from Widget to Viewport 2010-07-30 20:07:39 +12:00
Chris Forbes
3cd9a1e0e4 fix player color blocks not showing up in MapPreviewWidget 2010-07-30 18:54:46 +12:00
Chris Forbes
ef92e004c0 set the correct template on destroying long bridges 2010-07-30 18:48:59 +12:00
Chris Forbes
290a44440c cnc should run 'ralint cnc' after build, not 'ralint ra'. ralint no longer allows exceptions to escape. 2010-07-30 18:41:09 +12:00
Chris Forbes
5d1ee145e1 make (some) RALint errors nonfatal 2010-07-30 18:41:08 +12:00
Chris Forbes
aba9942a85 selling should not cause the building to explode first. 2010-07-30 18:39:21 +12:00
Chris Forbes
3aa2bab99f crate needs Unit. 2010-07-30 18:39:03 +12:00
Chris Forbes
d6b8b327d9 fix Bridge init 2010-07-30 18:24:12 +12:00
alzeih
e1a0d40530 RA Yaml changes 2010-07-30 18:14:00 +12:00
Paul Chote
48c5803198 Zombie prevention 2010-07-30 10:21:19 +12:00
Paul Chote
0580dc4adf Fix damaged-building artwork and don't show healthbar for dead units (cnc critical-building state) 2010-07-30 10:11:33 +12:00
Paul Chote
98ac5a036f Add an `Undamaged' damagestate to simplify things related to healing. 2010-07-30 01:22:41 +12:00
Paul Chote
87d2071007 Fix health bar colors. Todo: Merge DamageState & ExtendedDamageState 2010-07-30 00:46:00 +12:00
Paul Chote
bce9791b56 Fix building repair; Kill GlobalDefaults. 2010-07-30 00:41:55 +12:00
Paul Chote
6fba888d45 Shift Actor.Health onto a trait.
Known regressions:
 - cnc only
 - health bar colors
 - can't repair buildings
2010-07-30 00:33:44 +12:00
Chris Forbes
1e08dc6301 fix crate weirdness 2010-07-29 19:31:05 +12:00
Chris Forbes
2d4efc7942 crate should only choose water/land type on landing, not every tick. 2010-07-29 18:49:41 +12:00
Chris Forbes
bb0531b80f convert Crate to use crushable support again 2010-07-29 18:48:25 +12:00
Chris Forbes
e325b5954c split ITeleportable off as a base interface from IMove; Crate no longer pretends to be moveable. 2010-07-29 18:16:26 +12:00
Paul Chote
2be6cf35ac Add extra spawnpoints to "Middle Mayhem" 2010-07-28 23:23:39 +12:00
Paul Chote
7a4fa93ce9 Introduce a Targetable trait; Subs can attack bridges; May introduce subtle bugs due to previous stupid assumption that !selectable == !attackable. 2010-07-28 22:57:14 +12:00
Paul Chote
f9f6720437 Hook up Building.Capturable and remove unused field 2010-07-28 22:28:52 +12:00
Paul Chote
cfee4405c7 ra too 2010-07-28 22:26:30 +12:00
Paul Chote
eaa80fab74 Shift Sight onto its own trait. Only cnc for now. 2010-07-28 21:37:43 +12:00
Paul Chote
8fab45ae39 Move Cloak, HiddenUnderFog, FrozenUnderFog into Mods.RA; Simplify a pile of related stuff. 2010-07-28 21:11:50 +12:00
Paul Chote
6854d9853b Kill Crewed and move WaterBound onto building 2010-07-28 20:48:50 +12:00
Chris Forbes
5ca7218eb6 integrate scrollbar and checkbox art. fixes #215. 2010-07-28 18:16:47 +12:00
Chris Forbes
72d6a211af disable vshost 2010-07-28 11:26:46 +12:00
Paul Chote
f10e3a4d2d Always update player info on server join 2010-07-27 21:52:21 +12:00
Paul Chote
cfd0e045cb Add Edge Scroll setting 2010-07-27 21:28:40 +12:00
Chris Forbes
4386970bd3 add standalone PNGs for checkbox & scrollbar use 2010-07-27 21:19:17 +12:00
Paul Chote
c6f0b792d3 Do the right thing when stances change 2010-07-27 21:19:17 +12:00
Paul Chote
966f607230 Only show the diplomacy window if its useful 2010-07-27 21:19:17 +12:00
Paul Chote
9a704e69b2 Shift RevealsShroud onto Unit; fix "vehicles don't update shroud" regression in last 2010-07-27 21:19:16 +12:00
Paul Chote
a91ebb4eda Allies share sight 2010-07-27 11:34:28 +12:00
Paul Chote
9fe6671ace Fix retarded crash on server create; redirect server console spam into a logfile. 2010-07-27 10:48:37 +12:00
Paul Chote
386211df8c Update correct download size for deps-v2. 2010-07-26 22:40:25 +12:00
alzeih
ce513ed61a oops 2010-07-26 22:23:25 +12:00
alzeih
3f75e655ce Set Allow Cheats on server creation 2010-07-26 22:23:25 +12:00
alzeih
d9a423b596 Smite Indexdebug, tidy up dev mode 2010-07-26 22:23:24 +12:00
alzeih
30241ddccc Locate devmode code largely in the trait, reduce exploitability. 2010-07-26 22:23:24 +12:00
alzeih
10c7674433 Add to cnc, tidy up ingame menus 2010-07-26 22:23:24 +12:00
alzeih
c749fcfce3 Nearly There 2010-07-26 22:23:24 +12:00
alzeih
fe527c1297 Some of DeveloperMode trait (not working yet) 2010-07-26 22:23:24 +12:00
alzeih
3b72af2e9b AllowCheats 2010-07-26 22:23:24 +12:00
alzeih
2d916e60d9 Remove Developer Settings from Settings > Debug. Adjust Widget layout in DeveloperMode. In preparation for DeveloperMode trait. 2010-07-26 22:23:23 +12:00
Paul Chote
d8d731b321 Don't draw target line when idle 2010-07-26 22:18:40 +12:00
Chris Forbes
4cc021adfe fix dumb crash in minimap -- actors outside the map accessed memory that wasnt part of the bitmap. 2010-07-26 22:16:23 +12:00
Chris Forbes
56e929014d slightly faster again (map.IsInMap isnt free) -- but be careful 2010-07-26 21:42:11 +12:00
Chris Forbes
e0a5350ed6 slightly faster again 2010-07-26 21:39:23 +12:00
Chris Forbes
d774817b0e remaining dumbness removed. 2010-07-26 21:35:00 +12:00
Chris Forbes
3526c05dc8 a bit more 2010-07-26 21:30:23 +12:00
Chris Forbes
69a74425d9 a free 40% or so. 2010-07-26 21:23:19 +12:00
Paul Chote
eb1e325fe2 More caching 2010-07-26 20:44:47 +12:00
Paul Chote
ffa0c16ab9 Ignore opendiff files 2010-07-26 20:36:48 +12:00
Paul Chote
30f16e1a7a Fix cnc 2010-07-26 20:36:48 +12:00
Chris Forbes
0d0353f8f3 a little faster -- don't look up the Mobile every expand either. 2010-07-26 20:33:42 +12:00
Paul Chote
637fae87cd Remove a bunch of unused stuff. May help pathfinder perf a little. 2010-07-26 20:27:56 +12:00
Paul Chote
c39116df84 DefaultInputController -> WorldInteractionController; Tooltip tweaks. 2010-07-26 20:14:36 +12:00
Paul Chote
dcef8770a7 Edge scrolling 2010-07-26 20:14:36 +12:00
Paul Chote
816722256b Split viewport scrolling into its own widget 2010-07-26 20:14:36 +12:00
Chris Forbes
2b890bdb2f make backspace 'cycle bases' binding more obvious. not all of us know the whole character set, or care to. 2010-07-26 20:14:36 +12:00
Chris Forbes
882d94a22a DefaultInputControllerWidget should not ever consume input it doesnt want 2010-07-26 20:14:36 +12:00
Paul Chote
43a488ed6d Rebase fixes 2010-07-26 20:14:35 +12:00
Paul Chote
305fa03355 Kill Controller 2010-07-26 20:14:35 +12:00
Paul Chote
e677be7908 Remove more cruft from Game.controller 2010-07-26 20:14:35 +12:00
Paul Chote
eac49ca641 Refactor existing hodgepodge of hardcoded mouse/keyboard events into DefaultInputController. 2010-07-26 20:14:35 +12:00
Paul Chote
2248320af7 Move Game.Controller.HandleInput into a widget; works but is hacky 2010-07-26 20:14:35 +12:00
Chris Forbes
f61421edd0 gain ~20% faster pathing perf 2010-07-26 19:14:54 +12:00
Chris Forbes
9bb5e49058 draw building grid under actors too 2010-07-26 18:32:29 +12:00
Chris Forbes
16c9f2b873 render range circle and detection circle under actors 2010-07-26 18:27:02 +12:00
Chris Forbes
69d30ac71b RenderBeforeWorld/RenderAfterWorld split. still need to sort out which behavior belongs where. 2010-07-26 18:19:39 +12:00
Chris Forbes
9cf8ac0c3d remove dead IVictoryConditions interface 2010-07-26 18:07:48 +12:00
Chris Forbes
f1a5998049 remove dead ChooseFreePalette crap 2010-07-26 17:54:18 +12:00
Chris Forbes
41b76144da force the socket closed so the client thread will die pretty fast. dirty hack, but teh read timeout is nuts otherwise. 2010-07-26 17:49:08 +12:00
Chris Forbes
e30e97037f squash warning 2010-07-26 17:40:36 +12:00
Chris Forbes
102f1dd858 blah 2010-07-26 17:33:56 +12:00
alzeih
925ca2bb73 SetTargetSilently for DrawLineToTarget 2010-07-26 13:57:53 +12:00
alzeih
526bb3e042 Use Targets 2010-07-26 12:33:54 +12:00
Paul Chote
e8adc357e9 Draw targeting lines for player-issued orders. Can force-display targets with [alt]. 2010-07-26 12:01:13 +12:00
alzeih
130b4d29b4 Move SelectedUnit drawing stuff out of WorldRenderer into Selectable with IRenderSelection 2010-07-26 02:25:52 +12:00
alzeih
5f357288ee layout tidyup - start game now forces game start, ready checkboxes behave as before. 2010-07-25 22:16:21 +12:00
alzeih
26b5fbe9bb startgame order and lobby changes 2010-07-25 21:31:17 +12:00
Paul Chote
4650642311 Keep selection on mcv deploy/undeploy. Bonus: build tab opens on mcv deploy 2010-07-25 20:02:23 +12:00
Chris Forbes
e850cb7ff8 assign a palette to the cursor for basemod 2010-07-25 16:36:29 +12:00
alzeih
9fcb0577a5 default mod (pchote: squashed + amended) 2010-07-25 16:10:35 +12:00
Chris Forbes
df7dad8aaa add ra_perf mod, which exposes the performance test maps 2010-07-25 15:57:54 +12:00
Chris Forbes
3080e19bf2 add visualization of minefields when MNLY is selected 2010-07-25 15:56:40 +12:00
Chris Forbes
f2bfa8e2ee reinstate range circles; IRenderSelection allows arb. plugging in of these things 2010-07-25 15:56:40 +12:00
alzeih
2254e48f65 little bit better threading [pchote: picked/amended] 2010-07-25 15:56:40 +12:00
Chris Forbes
443f2bb6b9 fix msbuild project files. thanks, monodevelop: what was there worked JUST FINE 2010-07-25 15:52:09 +12:00
Paul Chote
c82cc7b301 Update osx packaging script for WindowsBase.dll and mono 2.6.7 2010-07-25 15:34:13 +12:00
Paul Chote
63951ac134 Run ralint after building 2010-07-25 15:11:08 +12:00
Paul Chote
301007e225 Fix compile errors/warnings 2010-07-25 15:02:01 +12:00
Paul Chote
5776d351b4 Fix Monodevelop build; remove Aftermath project. 2010-07-25 14:55:44 +12:00
alzeih
484bea106b OpenRA works nicely with monodevelop 2010-07-24 16:19:54 +12:00
alzeih
4fd5d9e0c3 Cloak Changes: appear semitransparent to localplayer, not at all to others. Same for mines.
( Also fix compile warning in LimitedAmmo )
2010-07-24 15:17:29 +12:00
Chris Forbes
5375692f1f remove spam on planes doing stuff 2010-07-24 00:09:54 +12:00
Paul Chote
20c0419782 Don't leak information on the underlying terrain via the mouse cursor. Cursor and voice response always "move" for terrain under shroud.
Needs pathfinder changes before being mergeable
2010-07-23 22:53:38 +12:00
Paul Chote
c74fe87fc8 Fix voice on unpathable terrain 2010-07-23 22:45:11 +12:00
Paul Chote
d5c43c9fda Remove unused code 2010-07-23 22:44:59 +12:00
Paul Chote
5344e60e3d Forgot a file 2010-07-23 22:44:48 +12:00
Paul Chote
52c8c93b30 Building capture eva + wtf on silo capture 2010-07-23 22:29:27 +12:00
Chris Forbes
31cb2081c6 rude hack to make planes associate with the airfield which spawned them 2010-07-23 21:40:07 +12:00
alzeih
cad1418199 use Range as a *range*, not as a nearenough. 2010-07-23 21:40:06 +12:00
alzeih
984e081f3b threadsafe 2010-07-23 21:40:06 +12:00
alzeih
282d26b844 Remember to disconnect ingame too, and mark the game as not started.
Also fix a compiler warning
2010-07-23 21:40:05 +12:00
alzeih
9516235707 Chat lines vanish after a set time in game
Also, Clear chat on join server
2010-07-23 21:40:05 +12:00
alzeih
409416b55c Host closing server closes all connections and closes the listener. 2010-07-23 21:40:04 +12:00
Chris Forbes
05d0e825fd unfail reservations for planes a bit 2010-07-23 21:40:04 +12:00
Paul Chote
c14f1aa996 Chronotank 2010-07-23 21:37:43 +12:00
Paul Chote
05953d0d6b Building capture 2010-07-23 21:26:26 +12:00
Paul Chote
fdf57b1e63 Cargo 2010-07-23 21:17:21 +12:00
Paul Chote
7f640fd701 MCV deploy and FIX. 2010-07-23 21:08:05 +12:00
Paul Chote
4016b81208 c4 and goldwrench voices / flashes / fixed movement 2010-07-23 20:13:41 +12:00
Paul Chote
7a06ddb8d1 Harvester voices / cursors / flashes 2010-07-23 19:56:22 +12:00
Paul Chote
c90317fb35 Aircraft/Helicopter move/dock flashing and cursor fixes 2010-07-23 19:10:10 +12:00
Paul Chote
55e59e0b53 Unhardcode voice/order interaction; reimplement for move and attack 2010-07-23 18:41:35 +12:00
Chris Forbes
1186d40fda quick hack to fix unclickable tabs on buildpalette 2010-07-23 18:26:59 +12:00
Paul Chote
1fc3ca284e Fix "Unit Lost" in cnc; remove related cruft 2010-07-23 17:33:39 +12:00
Paul Chote
f4e66a3d7a Fix power bar 2010-07-23 17:28:21 +12:00
Paul Chote
71420df0f3 Fix CursorForOrderString to work with orders + preliminary e6 fixes 2010-07-23 17:16:02 +12:00
Paul Chote
5019bb8b6e Animated move cursors for cnc 2010-07-23 16:01:53 +12:00
Paul Chote
61006ee73b For now, use ra cursors to fill some of the gaps in cnc 2010-07-23 15:15:21 +12:00
Paul Chote
9ebdef043c Allow custom/multiple cursor palettes 2010-07-23 14:49:45 +12:00
Paul Chote
93e629584b Use GoldWrench cursor for engineer repair 2010-07-23 00:29:46 +12:00
Paul Chote
1061f1138f Fix ra minimap cursors 2010-07-23 00:21:45 +12:00
Paul Chote
5c7e278b93 Draw viewport rect on radar 2010-07-23 00:03:04 +12:00
Paul Chote
a42ef6b3ea Update Minimap at ~2Hz, staggering layers. Minimap is faster than ever before. 2010-07-22 23:01:27 +12:00
Paul Chote
ac526f9762 Split the radar into multiple bitmaps 2010-07-22 22:54:12 +12:00
Paul Chote
d21e9fe093 Kill ITerrainTypeModifier for explicit updating of a custom layer in the map. Functionally equivalent, but MUCH faster. 2010-07-22 22:22:53 +12:00
Paul Chote
3e493cb93c Fix cursors over closed radarbin 2010-07-22 21:44:45 +12:00
Paul Chote
37a55715d0 Shift the hard work into Tick 2010-07-22 21:41:30 +12:00
Paul Chote
5198ced5aa Remove unnecessary check 2010-07-22 20:44:14 +12:00
Paul Chote
5ce8a643a7 ... 2010-07-22 20:40:24 +12:00
Paul Chote
53304b3de2 Cloaked units (not) on radar; untested but is simple enough that it should work 2010-07-22 20:33:54 +12:00
Paul Chote
a09a6997b4 Radar takes into account visibility under fog 2010-07-22 20:26:19 +12:00
Paul Chote
f7212ef757 Correct bridge / tree / mine color 2010-07-22 19:50:41 +12:00
Paul Chote
5f36933837 Fix custom terrain location 2010-07-22 19:50:41 +12:00
Paul Chote
a234dd4382 New interface for things that show on radar; groundwork for future patches. 2010-07-22 19:50:41 +12:00
Chris Forbes
31d5d18d65 undo ProjectileArgs stuff 2010-07-22 18:59:41 +12:00
Chris Forbes
6d527c3668 unbreak Target 2010-07-22 18:36:56 +12:00
alzeih
1497c31908 some more hax 2010-07-22 18:01:32 +12:00
alzeih
6be4e5c266 Combat.DoExplosion now takes a Target
(needs more refactoring)
2010-07-22 16:00:14 +12:00
alzeih
4e22e37192 Fix the in range check 2010-07-22 15:54:42 +12:00
alzeih
3395f97b20 Attacking is working again 2010-07-22 13:07:15 +12:00
Chris Forbes
73b6eb568b more of attack-ground (order wiring, etc); doesn't work. 2010-07-22 08:26:52 +12:00
Chris Forbes
5c61c9d3a9 migrating most things to use the Target struct rather than Actor directly. 2010-07-22 08:26:51 +12:00
Chris Forbes
88b705c8ef add Target type, in prep for allowing attack-ground 2010-07-22 08:26:51 +12:00
Chris Forbes
a78001a5cc strip some redundancy from UnitOrders, but it still sucks; fix nudges breaking everything 2010-07-22 08:03:44 +12:00
alzeih
b2454c8b8d instead, fix DumpSyncReport warning properly
(? maybe)
2010-07-22 01:40:44 +12:00
alzeih
3f9ffbac80 smite some compiler warnings, hide those that are to stay.
Hide some makefile output too
2010-07-22 01:39:44 +12:00
Paul Chote
55fd5c3b9b Halve the perf fail of custom terrain (down to ~4ms) 2010-07-22 01:21:36 +12:00
Paul Chote
db9cfb9ddd More refactoring and a TODO on custom terrain perf 2010-07-22 01:13:03 +12:00
Paul Chote
2d2362a1a6 Minimap refactoring; don't render the minimap unless we have radar. 2010-07-22 00:15:33 +12:00
Paul Chote
fdc033a63f Fix teamchat in lobby 2010-07-22 00:02:30 +12:00
Paul Chote
b8eab0614f Fix spawn point rendering 2010-07-21 23:49:24 +12:00
Paul Chote
78aff37fe4 Minimap sanity; part 1: rewrite the core radar logic 2010-07-21 23:44:23 +12:00
Paul Chote
58aed632a1 Add sanity to minimap; part 0 2010-07-21 20:50:40 +12:00
Paul Chote
3969dc9fb6 Tweak cnc walls; less extreme than ra 2010-07-21 20:50:40 +12:00
alzeih
ac27b40f7a Oops 2010-07-21 20:44:58 +12:00
alzeih
8e2d422054 Improvements to VictoryConditions, and Dead = Chat to all 2010-07-21 20:21:02 +12:00
Paul Chote
d69267f71c Remove Minimap from world 2010-07-21 19:48:43 +12:00
Chris Forbes
3a7bec1eef implement INudge on Mobile 2010-07-21 19:37:24 +12:00
Chris Forbes
8006e20dd3 however, we *do* need to know who nudged us, so we can tell them where to shove it if required. 2010-07-21 19:27:49 +12:00
Chris Forbes
5ef651ce6d return value not required. 2010-07-21 19:25:32 +12:00
Chris Forbes
e426d50cc2 add INudge interface; Move tries to nudge things that are in the way as a good first option 2010-07-21 19:24:45 +12:00
alzeih
2f9f539857 big pile of Render refactoring 2010-07-21 18:59:33 +12:00
Chris Forbes
84e1ed1cf9 fix helis landing where they shouldnt 2010-07-21 18:52:24 +12:00
Chris Forbes
8cb6e0b229 make walls sortof worth using 2010-07-21 18:42:28 +12:00
Chris Forbes
2584aad0c7 make UOG actually use FindUnitsAtMouse rather than homebrewing it 2010-07-21 18:24:29 +12:00
alzeih
4065a4f6a2 WorldRenderer now uses the global renderers too 2010-07-21 18:17:43 +12:00
Paul Chote
c2197b0adb Hopefully fix some of our pathing issues. Untested. 2010-07-21 18:01:15 +12:00
alzeih
222b29cec6 Bye Bye Chrome! 2010-07-21 17:57:06 +12:00
alzeih
0ac91d3c5e Widget IHandleInputs now 2010-07-21 16:51:00 +12:00
alzeih
d0b4761e07 actually remove the rootWidget from Chrome 2010-07-21 16:18:45 +12:00
alzeih
647252b0cb Chrome.rootWidget -> Widget.RootWidget 2010-07-21 16:14:31 +12:00
alzeih
795da1b088 unhacking IChromeButton. 2010-07-21 16:00:26 +12:00
alzeih
846971836a adjust path debug for altitude 2010-07-21 14:17:14 +12:00
Paul Chote
578f47d3b2 Fix crates. Untested but should work. 2010-07-21 12:21:56 +12:00
Paul Chote
d53a765971 Fix default cursor (cnc) 2010-07-21 11:53:47 +12:00
Paul Chote
ca2c9991fe Kill PostGameWidget 2010-07-21 11:51:15 +12:00
Paul Chote
47ca19e37d Fix cnc minimap cursors and document needed artwork 2010-07-21 11:20:42 +12:00
Paul Chote
86b66b91dd Fix seqed under mono 2010-07-21 11:20:42 +12:00
Chris Forbes
06bc14f690 fix a bunch of bad cursor hotspots in ra 2010-07-21 08:21:45 +12:00
Paul Chote
d3df8e6abd Remove debug spam 2010-07-21 00:28:14 +12:00
Paul Chote
7d02a801ad minicursors for minimap.
Bugs: ra doesn't define a sequence for move-blocked-minimap; cursor hotspot is wrong.
2010-07-21 00:26:32 +12:00
Paul Chote
bd69047e8c Fix cursor interaction with widgets 2010-07-20 23:51:55 +12:00
Paul Chote
5abe52607d Apply the same hack to BuildPaletteWidget 2010-07-20 23:30:05 +12:00
Paul Chote
46d502e053 Remove blatant abuse of RenderBounds 2010-07-20 23:22:09 +12:00
alzeih
0d489e638e send message to EVERYONE... 2010-07-20 21:48:09 +12:00
alzeih
b8a335a88f put back in --just-die 2010-07-20 21:38:21 +12:00
alzeih
0d671ae407 layout tweaks 2010-07-20 21:28:58 +12:00
alzeih
e10074d153 Actually give cash, add cheating message 2010-07-20 21:20:03 +12:00
alzeih
f92b59e6db Developer Mode (pchote: amended) 2010-07-20 21:20:03 +12:00
Chris Forbes
f39f7fc23e fix mouse input breakage on radarbin 2010-07-20 20:49:10 +12:00
Chris Forbes
02e4de61eb only play 'unit lost' etc to owner 2010-07-20 20:17:30 +12:00
Chris Forbes
cedcb3d84f fix stupid crash on husks dying 2010-07-20 19:48:54 +12:00
Chris Forbes
80d1b46c04 improve ftur a bit 2010-07-20 18:30:58 +12:00
Chris Forbes
19fda0b98e kill most of GlobalDefaults 2010-07-20 18:26:09 +12:00
Chris Forbes
1918c125ec ^Ship was a better place to put those. 2010-07-20 18:17:49 +12:00
Chris Forbes
b3aaacf16b don't drop crates in stupid places 2010-07-20 18:05:20 +12:00
alzeih
416e892897 it compiles again 2010-07-20 18:04:16 +12:00
Chris Forbes
1cbc3dd60f paradrop now asks its *cargo* whether a cell is suitable, rather than itself. 2010-07-20 17:55:10 +12:00
Chris Forbes
2684284c27 unit-lost sounds through voice 2010-07-20 17:39:35 +12:00
Chris Forbes
cb44844639 fix impotent mig 2010-07-19 19:56:11 +12:00
Chris Forbes
fa0d6b3e72 move LimitedAmmo to RA dll; reduce pips for YAK 2010-07-19 19:44:18 +12:00
Chris Forbes
92f4442941 nerf ca and msub a bit more 2010-07-19 19:34:00 +12:00
Chris Forbes
de02a374b4 add msub metadata 2010-07-19 18:02:51 +12:00
Chris Forbes
19d607489d add msub art (temp; will replace with custom art) 2010-07-19 18:02:50 +12:00
Chris Forbes
e4639adc3e cnc: much nicer msam 2010-07-19 18:02:49 +12:00
Chris Forbes
902c2c7832 fix special power bin 2010-07-19 18:02:49 +12:00
Chris Forbes
f45de5de45 throw out some unused server code 2010-07-19 12:36:48 +12:00
Chris Forbes
83dc6bd576 wire up CompressedPackage to be used if extension is .zip 2010-07-18 17:42:44 +12:00
Chris Forbes
a08dacc9c2 add support for compressed packages (zip); strip unnecessary SharpZipLib dll. req reference to WindowsBase for System.IO.Packaging support (apparently Mono has it) 2010-07-18 17:39:19 +12:00
Chris Forbes
27ef3483ec add thirdparty/ICSharpCode.SharpZipLib.dll; remove ConnectedComponents (unused); move DisposableAction into Primitives folder 2010-07-18 17:05:32 +12:00
Chris Forbes
d5f12dd8ee trim down license spam in all files 2010-07-18 16:48:21 +12:00
Paul Chote
6427a6dc33 Export tilesets into a mix 2010-07-17 19:03:05 +12:00
Paul Chote
04758bacde Create a mix file with a list of files 2010-07-17 19:01:03 +12:00
Paul Chote
a6ba5ec453 Update tilesetbuilder to new tileset format 2010-07-17 13:42:53 +12:00
Chris Forbes
8da7bfcf3c add sources for tileset 2010-07-17 12:18:07 +12:00
Paul Chote
37ba46fa54 Add TilesetBuilder to makefile 2010-07-17 12:16:53 +12:00
Paul Chote
9875a968bc Map ctor no longer assumes anything about mods (fixes cnc custom-map crash) 2010-07-17 12:03:25 +12:00
Paul Chote
239fff20f4 Fix a couple of nits 2010-07-17 11:57:59 +12:00
Paul Chote
5b333f4bba Store last color setting; hook server join in a cleaner way 2010-07-17 00:21:11 +12:00
Paul Chote
8b3a65717e Hook up the range slider 2010-07-17 00:01:29 +12:00
Paul Chote
2272b6688e cnc support 2010-07-16 23:56:01 +12:00
Paul Chote
bce5f2c681 Use custom colors ingame; requires a map format change to kill the obsoleted "palette" field 2010-07-16 23:47:33 +12:00
Paul Chote
c4442f07da Sliders change the preview palette and update client data; Need a better algorithm for picking color2 2010-07-16 23:34:42 +12:00
Paul Chote
4fb3f67a9d Hook up the HSL sliders 2010-07-16 22:34:30 +12:00
Paul Chote
44e1b8311f Color picker panel; sliders don't work yet 2010-07-16 21:54:35 +12:00
Paul Chote
8abc8e03cb Shift player palette definitions onto the player/client. Needs ui; for now everyone is teal. 2010-07-16 20:51:20 +12:00
Paul Chote
84ac8d9d16 Remove some duplication 2010-07-16 19:03:32 +12:00
Chris Forbes
4c8f85b36b split renderer into a file per class 2010-07-16 18:22:19 +12:00
Chris Forbes
d821dd011f move RALint's InitializeEngineWithMods into Game. 2010-07-16 18:15:50 +12:00
Chris Forbes
a2262df843 start stripping down MapConverter 2010-07-16 18:03:05 +12:00
Chris Forbes
e1031e36b2 some more 2010-07-16 18:01:26 +12:00
Chris Forbes
9bbb2f78de some fileformats cleanup 2010-07-16 17:50:09 +12:00
Paul Chote
ebec75be0e Fix server browser 2010-07-15 23:24:54 +12:00
Paul Chote
57a315a243 cnc tweaks 2010-07-15 23:24:54 +12:00
alzeih
96d7f8da3f Fixes
Lower cost of NUK2 to 500
Put clock in the right place
2010-07-15 23:18:29 +12:00
Chris Forbes
1242a2c39b avoid exploding in UnitOrders.cs 2010-07-15 22:09:13 +12:00
Paul Chote
59f931b2f8 Rip out preview.pngs 2010-07-15 21:47:03 +12:00
Paul Chote
b3413dc783 Faster bitmap editing 2010-07-15 21:25:02 +12:00
Paul Chote
45061cdf37 Cleaner attempt at rendering map previews on the fly 2010-07-15 21:16:35 +12:00
Chris Forbes
d274c10e95 fix missing .ini files breaking installer 2010-07-15 21:07:01 +12:00
Chris Forbes
73abf68d01 sensibly represent times >= 1h (important for game timer) 2010-07-15 21:02:28 +12:00
Chris Forbes
2622ee7171 don't overlay the timer on the perf widget; make it big; measure game time, not wallclock time 2010-07-15 20:55:01 +12:00
alzeih
69f499936b Resources are annoying 2010-07-15 20:38:13 +12:00
alzeih
db4c18b520 Timer Widget
Added a new Timer Widget
Made one to display the ingame time elapsed
Hooked up to reset on Game Start
Added a setting for it in Settings Menu (default true)
2010-07-15 20:38:12 +12:00
alzeih
80a91de1be fix prev for cnc 2010-07-15 20:38:12 +12:00
Chris Forbes
da348fa2d0 fix windows installer to include mod chrome folders 2010-07-15 20:35:28 +12:00
Chris Forbes
f6f13dd021 fix buildpalette stealing all the input 2010-07-15 20:30:45 +12:00
Chris Forbes
ea825ff2b5 proper keydown/keyup handlers 2010-07-15 20:12:57 +12:00
Chris Forbes
071c790097 clean up low-level keyboard input 2010-07-15 20:06:00 +12:00
Chris Forbes
bf50a2961e fix weirdness with modifiers being held during startup (C-F5 in particular broke things) 2010-07-15 18:49:24 +12:00
alzeih
aeefc94fe0 BuildPaletteWidget: don't click on buttons if the palette isn't open. Don't allow hotkeys unless palette is open. Move key handling into widget. 2010-07-15 18:24:54 +12:00
Chris Forbes
a02fd48597 RA does not use split ore and cash displays 2010-07-15 08:19:58 +12:00
Paul Chote
d01b3a25c4 Fix some initial nits 2010-07-14 23:39:14 +12:00
Chris Forbes
fbf94f9f43 noone needed that ctor 2010-07-14 21:14:53 +12:00
Chris Forbes
5e912a316d emulation of old chat system 2010-07-14 21:11:06 +12:00
Chris Forbes
093e445564 fix chat (1/2) 2010-07-14 20:55:07 +12:00
Chris Forbes
fed33fdb00 remove plenty of redundant junk 2010-07-14 19:00:03 +12:00
Chris Forbes
17bf4610f1 fix prev so it compiles with csc 2010-07-14 17:34:55 +12:00
alzeih
c3532fc9ea Change Settings defaults 2010-07-14 16:53:06 +12:00
alzeih
c9c2071db6 Settings Menu: Save once, and on OK 2010-07-14 13:58:13 +12:00
alzeih
6b4a193c7c SoundVolume distinct from GlobalVolume. Move sound values into UserSettings. 2010-07-14 13:57:42 +12:00
Paul Chote
f28eb7971b Split widget definitions into smaller files 2010-07-14 12:25:44 +12:00
Paul Chote
9ed57cc297 Fix spawnpoint rendering 2010-07-14 12:06:07 +12:00
Chris Forbes
65d2a5bb3c remove addpkg crap from server, since we don't use it. 2010-07-14 01:10:10 +12:00
Chris Forbes
3e0f850309 fix repair canceling itself 2010-07-14 01:10:10 +12:00
alzeih
7902a5e050 Settings menu (pchote: fix alzeihs broken world) 2010-07-14 01:09:49 +12:00
alzeih
992c1eec88 Slider Widget (thanks to pchote) 2010-07-14 00:43:12 +12:00
Paul Chote
6e8dd19800 Fancy server browser 2010-07-14 00:42:29 +12:00
Paul Chote
f7a6ed78ec You don't belong there 2010-07-13 23:19:38 +12:00
Paul Chote
7764302ac3 Fix cursor blink on mousemove 2010-07-13 20:50:35 +12:00
Paul Chote
8d2693019d Remove some unnecessary fields from chrome 2010-07-13 20:49:04 +12:00
Paul Chote
4a7c19cf93 Better temp artwork for listboxes 2010-07-12 21:16:37 +12:00
Paul Chote
7d2a5d6f42 Better listbox rows 2010-07-12 21:10:00 +12:00
Paul Chote
e23ee6d892 Better mouse input handling 2010-07-12 19:50:31 +12:00
alzeih
bd096436d9 New Command Order. GUI changes to settings no longer produce messages in chat. Can't enter commands in chat any more. 2010-07-12 19:35:08 +12:00
Paul Chote
9b5df39a04 Basic listbox for map list 2010-07-12 18:30:53 +12:00
Paul Chote
f70ac60135 Widget refactoring to support listboxes 2010-07-12 17:41:25 +12:00
alzeih
d740cf9fcd Paul, you noob 2010-07-12 03:28:31 +12:00
alzeih
5925453ab8 PaletteFromCurrentTheatre (pchote: amended) 2010-07-12 03:09:51 +12:00
alzeih
c4759b4130 Settings has Tabs (pchote: squashed + amended) 2010-07-12 03:09:14 +12:00
alzeih
89a77f7402 FileExtractor tool, remove default mod deps on mix files (pchote: squashed) 2010-07-12 03:05:56 +12:00
alzeih
dc1e36f653 smite some more compile warnings (amended to add minimap changes) 2010-07-12 00:51:58 +12:00
alzeih
7d18937415 better instance logging support 2010-07-12 00:48:29 +12:00
alzeih
d0d3f1434e Fix Perf-text 2010-07-12 00:46:37 +12:00
Paul Chote
d680956b02 Override FieldLoader to not crash on invalid input; Implemented for settings loading. 2010-07-11 17:52:01 +12:00
Paul Chote
af71f564e9 Whoops 2010-07-11 16:18:52 +12:00
Paul Chote
6d49dcece1 Remove BS from Viewport 2010-07-11 16:17:20 +12:00
Paul Chote
b4a84deb86 RA Support. Need a proper listbox widget to prevent map list overflow. 2010-07-11 15:46:10 +12:00
Paul Chote
b0e1d37789 Goodbye hardcoded chrome! 2010-07-11 15:43:32 +12:00
Paul Chote
74383fee47 Remove references to chrome.currentMap from LobbyDelegate 2010-07-11 14:42:12 +12:00
Paul Chote
7591434987 Remove hardcoded map references from MapPreviewWidget; prevents information leakage between lobby and map selector and provides groundwork for future patches 2010-07-11 14:25:29 +12:00
Paul Chote
ca07318dc5 Move the easy things from the hardcoded map chooser into widgets 2010-07-11 12:52:41 +12:00
Paul Chote
424aa5c2d2 Persist server settings 2010-07-11 12:23:24 +12:00
Paul Chote
96c80f357c Polish 2010-07-11 01:59:37 +12:00
Paul Chote
788e99fc7f Copy changes over to ra 2010-07-11 01:18:44 +12:00
Paul Chote
8c141c7b5e Expose port settings to server dialog 2010-07-11 01:08:36 +12:00
Paul Chote
900335b08c Direct Connect dialog & saves last server 2010-07-11 00:34:54 +12:00
Paul Chote
b6fc28023d Add a "Game Name" textfield to server creation 2010-07-11 00:04:42 +12:00
Paul Chote
3296cc2ec1 MaxLength on textfields 2010-07-10 23:50:42 +12:00
Paul Chote
62995ffad8 Tweak focus on name entering 2010-07-10 23:25:55 +12:00
Paul Chote
a29198c237 Layout/font weight polish 2010-07-10 23:19:55 +12:00
Paul Chote
56fb711fc6 Textfield editable names 2010-07-10 22:30:28 +12:00
Paul Chote
dcf13e52c2 Vertically align labels 2010-07-10 21:38:47 +12:00
Paul Chote
e063f5e271 Add forgotten file; teamchat polish 2010-07-10 21:26:19 +12:00
Paul Chote
d91fc0d8e7 Make TextFieldWidget generic; Hook up teamchat and make it actually work in the lobby 2010-07-10 21:15:21 +12:00
Paul Chote
50f3aecf53 Move chat display into a widget 2010-07-10 20:43:29 +12:00
Paul Chote
fdf570398a Replace the lobby chat textfield with the widget; teamchat and ingame chat don't work yet 2010-07-10 19:25:00 +12:00
Paul Chote
8c59b582d9 Handle text overflow nicely 2010-07-10 18:45:25 +12:00
Paul Chote
5dba8842de Fix focus issues and show a blinky cursor 2010-07-10 18:09:38 +12:00
Paul Chote
faf5e7bbf1 Beginnings of textfield widget 2010-07-10 17:48:46 +12:00
Chris Forbes
19f74e1d3e fix c&c crash on startup 2010-07-10 17:46:42 +12:00
Matthew
cfb37476c7 Modified packaging scripts to remove binary generation. 2010-07-10 16:27:09 +12:00
Matthew
6a3de5dee6 Have to force path to binary. 2010-07-10 16:27:09 +12:00
Matthew
bce2bcec9c Make sure bin dir exists in fake root environments. 2010-07-10 16:27:08 +12:00
Matthew
50c5c51d4b Bin path still needed fixing. 2010-07-10 16:27:07 +12:00
Matthew
ff0a90af0a Fixed bin path. 2010-07-10 16:27:07 +12:00
Matthew
2037c89cdb Binary generation moved to Makefile. 2010-07-10 16:27:06 +12:00
Chris Forbes
a372ba2080 make it work 2010-07-10 16:24:29 +12:00
Chris Forbes
2169f32a79 add (nonfunctional) checkbox for lock-teams 2010-07-10 16:24:28 +12:00
Chris Forbes
8d68bd026d add 'lock teams' feature backend -- still needs UI 2010-07-10 16:24:28 +12:00
Paul Chote
77405a7700 Fullscreen toggle & don't crash when saving null fields 2010-07-10 15:42:50 +12:00
Paul Chote
636bfd5e0a Tweaks 2010-07-10 15:05:17 +12:00
Paul Chote
0206f70ab8 Remove obsolete settings and tweak windows shortcuts 2010-07-10 15:00:00 +12:00
Paul Chote
04bb5b0a4b Load/Save settings from <support dir>/settings.yaml 2010-07-10 14:58:50 +12:00
Paul Chote
b7eb4193d4 Don't target c17 2010-07-10 13:36:18 +12:00
Paul Chote
862cab9cbe Disable Hazards and 5-per-cell infantry until they work properly 2010-07-10 13:28:52 +12:00
Paul Chote
e6d5d1492e Fix starting cash 2010-07-10 13:18:04 +12:00
Paul Chote
ce677bf3dc Package uploading script (replaces OpenRAUploader) 2010-07-10 12:40:00 +12:00
Paul Chote
529ce4bc6a Makefile tweaks 2010-07-10 00:12:48 +12:00
Paul Chote
968ab06135 makefile for build uploader 2010-07-10 00:12:48 +12:00
Chris Forbes
20785a6585 clean up bullets somewhat 2010-07-09 21:44:38 +12:00
Chris Forbes
5e1c63ebb5 change BulletInfo.Arcing to BulletInfo.Angle to allow more control over trajectories 2010-07-09 21:05:00 +12:00
Chris Forbes
40ae25c895 remove silly exploit on undeploying MCV 2010-07-08 21:49:25 +12:00
Paul Chote
3093928d95 Move lint checking to the mods themselves; don't compile aftermath (the rules have bitrotted so lint always fails) 2010-07-08 20:28:05 +12:00
Paul Chote
df3581237e Remove hardcoded cursor bs; move TransformsOnDeploy to Mods.RA. 2010-07-08 20:23:19 +12:00
Paul Chote
ac3924e660 Restore sane buildspeed to cnc 2010-07-08 19:32:37 +12:00
Paul Chote
476d40b317 Move StoresOre into Mods.RA 2010-07-08 19:32:07 +12:00
Paul Chote
d9ba7ff90c Fix packaged osx SupportDir 2010-07-08 19:12:49 +12:00
Paul Chote
a383f8873c SupportDir supports absolute or relative paths; default to ~/OpenRA 2010-07-08 19:10:34 +12:00
Paul Chote
3508e71168 Automatically run ralint when building from makefile. Also fixes external-tool logging crash 2010-07-08 18:45:54 +12:00
Paul Chote
513769f131 Remove the need for a trailing separator 2010-07-08 18:11:29 +12:00
Paul Chote
fdc85b6e48 Don't spam logs and replays all over my home directory kthx.
Logs and replays are written to subdirectories of the "Support" folder. Default location is <game dir>/Support/; Can be overridden on game start.
2010-07-08 18:11:28 +12:00
Bob
fb6c44bce3 move render{building,buildingturreted,unit} into mods.ra; move all render traits into mods.ra.render 2010-07-08 17:24:12 +12:00
Bob
281d013c3b move Combat, AttackBase, and associates into mod 2010-07-08 16:38:58 +12:00
Bob
bd74b29ea3 move projectile effects into mod 2010-07-08 16:04:18 +12:00
Bob
7a738ed6af move CYard trait and UndeployMCV activity into mod 2010-07-08 15:34:21 +12:00
Bob
1eedae2c7b fix window origin in pseudofullscreen 2010-07-08 15:20:55 +12:00
Bob
6a840dff4c move ActorGroupProxy to mod; move SupportPower traits into directory 2010-07-08 14:01:44 +12:00
Paul Chote
9054f10b83 Sane crate defaults for cnc 2010-07-07 23:16:24 +12:00
Paul Chote
d04d943fe5 Remove some redundant logging 2010-07-07 23:13:27 +12:00
Paul Chote
02e4d7d270 Remove "Version: " from the version string display 2010-07-07 23:13:27 +12:00
Paul Chote
5fba682fe0 Fullscreen -> WindowMode; defaults to pseudofullscreen which does hax on windows, falls back to normal fullscreen for everyone else. 2010-07-07 23:13:27 +12:00
Paul Chote
731e7af45a Point the downloader at the right package 2010-07-07 23:13:27 +12:00
Paul Chote
b11719d34a Re-enable zip generation 2010-07-07 23:13:27 +12:00
Paul Chote
066c28b0e8 Point the download urls at the master server 2010-07-07 23:13:27 +12:00
Paul Chote
bc016fd76d More polish; pull terminal/finder windows to the front when stuff happens; include unzip progress in terminal 2010-07-07 23:13:26 +12:00
Paul Chote
4dd25d4936 Polish 2010-07-07 23:13:26 +12:00
Paul Chote
a5d90a542b Split the functions out into their own files 2010-07-07 23:13:26 +12:00
Paul Chote
9d70bb24a6 Package osx dependencies separately from the main download; Game is now run from inside app bundle; Support dir used to cache downloads only 2010-07-07 23:13:26 +12:00
Chris Forbes
12a350b89f fix crash on selecting husks (and other things with Unit but Selectable.Voice = null) 2010-07-07 21:27:34 +12:00
Chris Forbes
fb1d37ae53 use explosion *names*, not *numbers* like RA. 2010-07-07 19:44:14 +12:00
Paul Chote
c17a63a434 Add icons to the osx launcher 2010-07-07 19:09:52 +12:00
Paul Chote
bc84e33222 Add more resolution to version string 2010-07-07 19:09:50 +12:00
Paul Chote
2835fd66fe Show version on shellmap (via alzeih) 2010-07-07 19:09:46 +12:00
Paul Chote
1b38c4a6cb Upgrade install if newer version is run 2010-07-07 19:09:41 +12:00
Paul Chote
a74705f34d Tweaks 2010-07-07 19:09:38 +12:00
Paul Chote
2fa0ac99dd Install game in ~/Library/Application Support/OpenRA/; Download packages only when needed; Display a dialog on crash 2010-07-07 19:09:36 +12:00
Paul Chote
247576277f Select mod on game start (TODO: kill this in favor of a proper ingame mod manager) 2010-07-07 19:09:34 +12:00
Paul Chote
6359674d27 Override UserSettings from the commandline 2010-07-07 19:09:30 +12:00
Paul Chote
4671e6b261 Script to package a game build into a zip 2010-07-07 19:09:27 +12:00
Paul Chote
cfa4820379 Package Cg and SDL too 2010-07-07 19:09:25 +12:00
Paul Chote
4c8575b1f5 Custom game wrapper for osx. Point it at a standard game dir, and it will run it without needing any other dependencies installed.
Internal mono works; still uses system SDL and Cg
2010-07-07 19:09:22 +12:00
Chris Forbes
ec9bdb03c5 slower-moving but much nicer v2 projectile 2010-07-07 19:00:10 +12:00
Chris Forbes
ae671369b6 fix descriptions for 2tnk/3tnk; tweak damage types for 1tnk. 2010-07-07 18:36:08 +12:00
Chris Forbes
2ed8045736 remove DeathWeapon; IExplodeModifier implemented for resource actors (and for V2, which was the original purpose) 2010-07-07 18:32:45 +12:00
Chris Forbes
68b63dc89e ralint: verify voices, support (and still verify) @-form prerequisites. 2010-07-04 14:50:26 +12:00
Chris Forbes
8e68449af1 voices are no longer tied to having Unit; default is to have no voice; defaults.yaml set up appropriately for units that should have one. 2010-07-04 14:25:34 +12:00
Chris Forbes
35b6f5c38b don't download the mixes if you already have them; split cg deps into /releases/windows/cg-win32.zip (1.5M) 2010-07-04 10:23:18 +12:00
Chris Forbes
8d88d73e53 hack windows installer to NOT reinstall freetype,zlib,sdl on upgrade 2010-07-03 10:56:06 +12:00
Chris Forbes
8018fa0aec please don't have insane options as the hardcoded default. that's what your personal settings file is for. 2010-07-01 19:04:07 +12:00
Chris Forbes
5bec019d55 add RALint checking to nearly everything 2010-07-01 18:57:10 +12:00
Chris Forbes
8974fb7ae8 hack the RALint output format so VS shows errors as errors. Source position would be nice too, but that requires actual work. 2010-07-01 18:34:27 +12:00
Chris Forbes
2d9e5c6fcd remove spam on loading RA MIX headers; add some more bits to RALint 2010-07-01 18:31:13 +12:00
Chris Forbes
c310713cd5 beginning of RALint 2010-07-01 13:11:32 +12:00
Paul Chote
521e6b8549 Log when something hits the path cache 2010-06-30 20:39:52 +12:00
Paul Chote
4c3930043e Reenable path cache to catch the most stupid path fails (doesn't help the most common fails) 2010-06-30 20:25:32 +12:00
Paul Chote
202d1a38d5 Specify valid filetypes in tilesets 2010-06-30 20:25:32 +12:00
Paul Chote
9ca9d9a47e Fix country names in lobby 2010-06-30 20:25:32 +12:00
Paul Chote
e5ce9196fa Nicer tooltips 2010-06-30 20:25:32 +12:00
Chris Forbes
51079f0876 add LevelUpCrateAction 2010-06-30 18:33:19 +12:00
Chris Forbes
c605a35ab0 only kill units on bridge death which cannot exist on their cell(s)' new terrain types 2010-06-30 18:11:39 +12:00
alzeih
aa64803f84 hacky chat line wrapping 2010-06-30 18:00:47 +12:00
Chris Forbes
7070b04cc9 new 1tnk concept; 2tnk/3tnk owners swapped back 2010-06-30 17:59:52 +12:00
Paul Chote
272e03603a Kill any units on a bridge piece when it dies. Todo: need to mask the death regions for cnc bridges 2010-06-28 13:05:52 +12:00
Paul Chote
797b1b4a84 Non-selectable fields in ra 2010-06-28 12:41:45 +12:00
Paul Chote
915c9460cf Theater specific artwork done properly 2010-06-28 12:38:35 +12:00
Paul Chote
b46cec91a8 Fix cnc shellmap uid 2010-06-28 00:24:04 +12:00
Paul Chote
15a72e893b Quick hack for theater-specific artwork. Should probably be done better; editor support required. 2010-06-28 00:23:58 +12:00
Paul Chote
560c3ce5af Regress the editor so it actually works 2010-06-27 23:59:54 +12:00
Paul Chote
dfb6d19646 Add missing road end to oasis 2010-06-27 23:19:41 +12:00
Paul Chote
4def9e0eae Fix Editor 2010-06-27 23:14:43 +12:00
Paul Chote
703d536e46 Map object polish (tooltips + pruning) 2010-06-27 23:13:30 +12:00
Paul Chote
b12b774deb Kill some obsoleted data 2010-06-27 22:39:02 +12:00
Paul Chote
f37a4ec9ed Add bridges to cnc 2010-06-27 17:50:05 +12:00
Paul Chote
25f2268f58 Bridge destruction etc works 2010-06-27 15:58:57 +12:00
Paul Chote
cdbe2d3a34 Friendly tree tooltips 2010-06-27 11:02:54 +12:00
Paul Chote
c5718456fd First half of bridge overhaul 2010-06-27 10:59:01 +12:00
Paul Chote
9a34b049a8 Reverse ra bridge metadata 2010-06-26 22:23:05 +12:00
Paul Chote
49d7833b04 Fix editor 2010-06-26 14:56:51 +12:00
Paul Chote
920b4f6856 Fix ra 2010-06-26 13:41:50 +12:00
Paul Chote
d275c72cb8 Cleaner TileSet init 2010-06-26 13:33:46 +12:00
Paul Chote
08ee425415 Fix some stupid bugs; remove hardcoded references to water/ore/tree terraintypes 2010-06-26 12:02:30 +12:00
Paul Chote
bf6b2da1a8 Unhardcode terrain types. Needs a bit more work re initialization and bridges 2010-06-26 10:55:29 +12:00
Paul Chote
8fbbaddce9 Merge all 4 tileset files together 2010-06-26 09:21:11 +12:00
Paul Chote
9cf6d8970a Merge templates.ini and tileset.til into theatre-specific yaml files.
Game doesn't use them yet.
2010-06-26 00:19:34 +12:00
Paul Chote
cf265c8b58 Fix ra 2010-06-25 23:07:11 +12:00
Paul Chote
2373528ad9 Kill UnitMovementType; bs-free crate spawning; fix "DOME crash" (caused by crate not IOccupying space); add money and hide-map crates to cnc 2010-06-25 21:58:09 +12:00
Paul Chote
7c3a10396c New crush code, now with less bs 2010-06-25 20:57:06 +12:00
Paul Chote
00b91bd7ad Reimplement ICustomTerrain with far less bs 2010-06-25 19:26:08 +12:00
Paul Chote
29fa9e3aeb Shift movement cost/speed into IMove; regressions in a few areas 2010-06-25 17:05:56 +12:00
Paul Chote
6a5869f2c6 Begin cleaning up terraintypes/movetypes 2010-06-25 15:52:12 +12:00
Paul Chote
7ac8d0cf59 Units automatically path around known hazards (eg static base defenses). Test using SAM and TRAN.
Todo: Ignore hazards when force-moving; Apply only to known enemy hazards; Implement more hazard classes

Also add a few files I forgot from previous patches
2010-06-25 13:53:37 +12:00
Paul Chote
0aeca2aadc Helicopters use pathfinder 2010-06-24 21:51:22 +12:00
Paul Chote
37cf30a097 Refactor Mobile.TeleportTo -> IMove.SetPosition 2010-06-24 21:51:22 +12:00
Paul Chote
3e664779ef Remove a bunch of unnecessary caching 2010-06-24 21:51:22 +12:00
Paul Chote
b42589b479 Fix vehicle production; Basic 5-to-a-cell logic. cnc only. Infantry stack; need to give a graphical offset. 2010-06-24 21:51:22 +12:00
Paul Chote
b7c8e55d14 Some initial hacks towards multiple-infantry-per-cell. Make the pathfinder smart enough to do what we need, and remove a *lot* of stupid duplication. Needs more work. 2010-06-24 21:51:22 +12:00
Chris Forbes
308a7b0cf6 remove hardcoded magic number 2010-06-24 21:51:22 +12:00
Chris Forbes
0cf39991db new range circle renderer; faster minefield renderer 2010-06-24 21:51:21 +12:00
Chris Forbes
b8093b7f6c removing a bunch of excessively low-level pixel -> cell conversions 2010-06-24 21:51:21 +12:00
Chris Forbes
2dcc85f608 fix aircraft so it actually works again 2010-06-24 21:51:21 +12:00
Chris Forbes
e56339897f add additional debug to WorldRenderer.DrawUnitPath so we can see waypoint density, etc 2010-06-24 21:51:21 +12:00
Paul Chote
7d717592c7 Rename IMovement -> IMove; Move GetCurrentPath from Mobile to IMove and implement for aircraft; fix regressions in Helicopter (ITick) and remove unused cruft from Aircraft (IOccupySpace). 2010-06-24 21:51:21 +12:00
Paul Chote
3be5b946ad Flesh out center of the map 2010-06-24 21:51:21 +12:00
Paul Chote
1592225855 WIP cnc map (note: editor needs better work-loss prevention) 2010-06-24 21:51:21 +12:00
Paul Chote
bdb77501f7 More Helicopter polish 2010-06-24 21:51:21 +12:00
alzeih
37ffd2207f Fix game locking up on crash. 2010-06-23 22:04:17 +12:00
Chris Forbes
5dcc7782d9 make editor use pickany metadata 2010-06-20 18:45:47 +12:00
Paul Chote
aff357db0b Actually render resources when shroud is disabled 2010-06-20 18:34:06 +12:00
Chris Forbes
c1aa25e307 add 'pickany' flag in TileTemplate 2010-06-20 18:32:21 +12:00
Chris Forbes
a4f694e51a that was horrible. beef up v2 so it can fill that role better 2010-06-20 18:15:04 +12:00
alzeih
a1ffb68e22 bugfix 2010-06-20 17:48:20 +12:00
Booom3
a00a5433e4 balance stick 2010-06-20 17:31:37 +12:00
Chris Forbes
5242854892 unfail crates 2010-06-20 13:22:23 +12:00
Chris Forbes
17a45a0d6c fix destroyer missile range 2010-06-19 20:26:29 +12:00
Booom3
0195e54c8c Updated testmap 2010-06-19 10:24:57 +02:00
Chris Forbes
04c07ed88b fix prereqs for 3tnk 2010-06-19 19:58:29 +12:00
Chris Forbes
542ec65f10 buff 3tnk hp to match its new role 2010-06-19 19:56:40 +12:00
Chris Forbes
a457b1f133 swap 2tnk and 3tnk owners 2010-06-19 19:55:17 +12:00
Chris Forbes
8f897f7840 nerf CA a bit, esp vs unarmored 2010-06-19 19:47:50 +12:00
Chris Forbes
68ce0d89e6 more jeep tuning 2010-06-19 19:33:57 +12:00
Chris Forbes
b719271f6f make jeep decent vs infantry and crap vs everything else 2010-06-19 19:24:06 +12:00
Chris Forbes
4d8238cd32 reintroduce dome for soviet 2010-06-19 19:20:55 +12:00
Chris Forbes
87973f9ef3 fix bug in prev 2010-06-19 15:23:30 +12:00
Chris Forbes
c3490fcb66 buildings under fog 2010-06-19 15:17:48 +12:00
Chris Forbes
75bfedecb2 more heli polish (paul) 2010-06-19 15:06:02 +12:00
Chris Forbes
66adbee2a6 moving Actor.Location onto the appropriate traits (bob) 2010-06-19 14:37:06 +12:00
Chris Forbes
db465e1fdd ActorInitializer, in preparation for next change (bob) 2010-06-19 14:28:30 +12:00
Chris Forbes
572cdc9dbf vacate cells earlier 2010-06-18 22:36:24 +12:00
Chris Forbes
0ef91ecc2d hack around crash on boat repair 2010-06-18 20:55:06 +12:00
Chris Forbes
0c25924789 the Tao.SDL docs are wrong; the params are backwards. working keyrepeat, kthx. 2010-06-18 20:21:45 +12:00
Booom3
d58f2de090 Test map 2010-06-18 19:58:25 +12:00
Chris Forbes
c83f78f259 fix it on nonwindows too 2010-06-18 18:34:33 +12:00
Chris Forbes
8afb17c3f5 default somewhere sensible in editor (by not failing at '\') 2010-06-18 18:33:06 +12:00
Chris Forbes
abc7b21994 add logos to cnc 2010-06-18 18:18:02 +12:00
alzeih
beec39daa4 fixing bug on loading shellmap 2010-06-18 17:42:19 +12:00
alzeih
2da06d3744 Avoid Sharing Violations in logs 2010-06-18 16:25:12 +12:00
alzeih
5922a6c446 Stop printing arrow keys etc , and print repeated keys faster 2010-06-18 16:04:30 +12:00
alzeih
981a6b65a7 Fix server crashing when server order fails to deserialise. 2010-06-18 16:03:24 +12:00
alzeih
d6c83eddbd truncate name if longer than 10 chars 2010-06-18 14:46:16 +12:00
Paul Chote
331706d75e Fix crash on repair non-buildables (fact,proc). Allow special powers to depend on them too. 2010-06-17 23:48:00 +12:00
Paul Chote
4b124950b9 Unlimit heli ammo; may make orca OP 2010-06-17 23:19:34 +12:00
Paul Chote
212b3259fe Try some tweaks 2010-06-17 22:25:30 +12:00
Chris Forbes
33971c06a6 fix crash in Activities.Repair 2010-06-16 22:42:22 +12:00
Paul Chote
81d5b9bc6a Fix stupid crash 2010-06-16 21:48:15 +12:00
Paul Chote
a0e4e40eaf Fix e6 2010-06-16 21:13:20 +12:00
Chris Forbes
1088e30158 fix small bug in BuildPaletteWidget - incorrectly used cash rather than cash+ore 2010-06-16 20:27:51 +12:00
Paul Chote
f3dc3b1da0 Recover gracefully if proc goes away while harv is docking 2010-06-16 20:22:11 +12:00
Chris Forbes
5f58379f5b reenable cash sounds; if you want to disable them for your mod, don't set those evaAlerts properties. (as done in cnc); add SplitOreAndCash property to MoneyBinWidget, restoring old RA behavior (cnc is unchanged) 2010-06-16 20:18:01 +12:00
Paul Chote
01e95b67d6 Restore ra proc behavior 2010-06-16 20:00:38 +12:00
Paul Chote
5ed8113d8e Steal docked harv on proc capture (needs multiplayer testing); framework for canceling dock on proc death/sell (needs further activity changes) 2010-06-16 19:47:15 +12:00
Paul Chote
f0a2bf128c Harvesters return to last used field 2010-06-16 19:22:59 +12:00
Paul Chote
5822caf7a8 Fix cancellation issues and animation flicker 2010-06-16 10:37:54 +12:00
Paul Chote
40ba80b1e3 Use palette indices that map to sane colors in both games. 2010-06-16 01:18:09 +12:00
Paul Chote
88df9ecaa2 Implement cnc harv/proc dock sequence and kill unnecessary duplication. Bad things happen if sequence is interrupted by another order (eg invisible harv).
Still todo: Make sequence non-interruptible; engineer steals harv docked with proc; the "right thing" if proc is sold/destroyed with harv docked.
2010-06-16 00:33:09 +12:00
Paul Chote
5f83f97747 Link harvesters with refineries. 2010-06-15 20:05:49 +12:00
Paul Chote
f4421d89ea Fix tooltip crash on non-buildable prereq 2010-06-15 18:17:40 +12:00
Paul Chote
48cf08dc7d proc comes with 2 free silos; fix silo/proc prereq 2010-06-15 11:17:36 +12:00
Paul Chote
e3de3cc0d2 Make c17 invulnerable 2010-06-15 11:17:36 +12:00
Chris Forbes
c3e15aab7d hacky fix for productionqueue desync (e3, etc) 2010-06-15 08:42:40 +12:00
Chris Forbes
0e0a8802ab enhance sync to work with nested syncable types, and properties 2010-06-15 01:15:41 +12:00
Paul Chote
06a78cd73d Deathweapon capability, refactoring, and Pip polishing on Silo, Proc, Harv. Lose ore on silo death. 2010-06-14 22:15:43 +12:00
Paul Chote
d36c8deb97 Fix Explodes 2010-06-14 21:36:52 +12:00
Paul Chote
24edba34a7 Remove thief; transfer ore along with stolen silo/proc. 2010-06-14 20:59:35 +12:00
Paul Chote
283512f314 Spend ore before cash; lose ore > capacity. 2010-06-14 20:59:35 +12:00
Chris Forbes
6f3667971a remove targeting of husks. has map design impact, since chokepoints can be filled now 2010-06-14 20:48:49 +12:00
Chris Forbes
24d9b44a66 non-crap music player buttons 2010-06-14 20:44:35 +12:00
alzeih
9425fb1def Fix unnecessary duplication and get a better UI out of it 2010-06-14 14:05:20 +12:00
alzeih
889d736d35 Use images for music player (public domain - but find better ones) 2010-06-14 01:37:58 +12:00
alzeih
7b837fd6c4 Prevent changes when marked as ready 2010-06-14 00:55:22 +12:00
alzeih
3ac0ca6a65 BuildPalette tooltips show build time (+ in red if in low power) 2010-06-14 00:18:36 +12:00
Paul Chote
fbeadb9869 Increase vehicle sight; don't crash on production 2010-06-13 22:00:39 +12:00
Paul Chote
2e094d3279 Add fuel to missiles 2010-06-13 22:00:39 +12:00
Paul Chote
a771e63603 Revamp tech tree and build palette ordering 2010-06-13 22:00:39 +12:00
Paul Chote
de6434c0f1 Use the same model for ra (but let proc hold ore as before) 2010-06-13 22:00:39 +12:00
Paul Chote
dc8178f984 Tweaks 2010-06-13 22:00:39 +12:00
Paul Chote
aba5c777db The original method worked better; take the best of both worlds 2010-06-13 22:00:39 +12:00
Paul Chote
640ac9b8e6 Trial a new resource model in cnc 2010-06-13 22:00:05 +12:00
Paul Chote
19ed7428c4 Reorder build palette 2010-06-13 21:59:10 +12:00
Paul Chote
6afc34e5c1 SAM Site 2010-06-13 21:59:10 +12:00
Paul Chote
48bc029174 Set building health to cncrules.ini values 2010-06-13 21:59:09 +12:00
Chris Forbes
09b58f46d9 remove some spikes 2010-06-13 21:42:14 +12:00
alzeih
3001d58ba0 text has colour 2010-06-13 21:39:08 +12:00
alzeih
f0ea329b2c Fix crash if no music 2010-06-13 21:10:23 +12:00
Chris Forbes
2890d29e7d ra faction flags prototype 2010-06-13 21:07:27 +12:00
Chris Forbes
5b40d4444a add soviet logo 2010-06-13 19:39:08 +12:00
Chris Forbes
215ca80713 adjust ra ui layout so flags are not flush with left of button 2010-06-13 19:15:28 +12:00
Chris Forbes
27902bc48a clickable spawnpoint polish 2010-06-13 19:09:08 +12:00
alzeih
5d66c6b7ba Tweak flag size, kill Spawn button. 2010-06-13 19:03:02 +12:00
alzeih
1a20249f44 Basic ImageButton for drawing flags 2010-06-13 18:03:17 +12:00
Paul Chote
5e630768a2 Missed a file 2010-06-13 17:01:52 +12:00
Paul Chote
a273f7f07e Defense queue 2010-06-13 17:00:18 +12:00
Paul Chote
3b4753d9a8 Fix aircraft targeting; add veterancy 2010-06-13 17:00:18 +12:00
Paul Chote
8397bc12b5 Tweak special powers 2010-06-13 17:00:18 +12:00
Paul Chote
77510b4bef STNK desc 2010-06-13 17:00:18 +12:00
Paul Chote
b0802466b2 tib tree animations 2010-06-13 17:00:18 +12:00
Chris Forbes
c4d143b729 completing alzeih's patch 2010-06-13 16:34:01 +12:00
alzeih
d2da37f026 start of clicking on spawn points, compile fail still 2010-06-13 16:17:00 +12:00
Chris Forbes
6774486027 cnc: htnk.husk looks like a htnk now, not ltnk. 2010-06-13 15:57:56 +12:00
Paul Chote
2f99bf5ba5 FACT tooltip 2010-06-13 15:42:46 +12:00
Paul Chote
e5ee2b9479 Heli pips and separation 2010-06-13 15:39:00 +12:00
Paul Chote
3edbfc3345 Fix TMPL footprint 2010-06-13 14:32:55 +12:00
Paul Chote
b168bc2365 FIX after vehicle structure; NUK2 after HQ 2010-06-13 14:25:56 +12:00
Paul Chote
196316f36c Fix tib tree sequences 2010-06-13 11:45:19 +12:00
Paul Chote
b50ad94efb Tweak helicopter movement / attack 2010-06-13 11:34:33 +12:00
Paul Chote
a7f5c4b03a Hack a screenshot key in 2010-06-13 00:33:13 +12:00
Chris Forbes
7812e1c314 don't fail with offscreen impacts 2010-06-13 00:25:14 +12:00
Chris Forbes
3c95a2886c hack hack 2010-06-13 00:04:14 +12:00
Paul Chote
7c34252cff cnc GDI gets e3, exclusive RMBO; increase building sight; starting cash to 5000 2010-06-12 23:34:49 +12:00
Chris Forbes
4c955c36e7 fix retarded crash in WorldUtils.IsVisible 2010-06-12 23:07:55 +12:00
Chris Forbes
bcf7328d77 a bit of cleanup 2010-06-12 21:48:52 +12:00
Chris Forbes
02350e6ac8 unbitrot cnc (editor); add mod name to editor title 2010-06-11 18:23:03 +12:00
Chris Forbes
ee0f90708f put perf in its own channel 2010-06-11 18:15:59 +12:00
Chris Forbes
5d823d8e6e fix some debug-channel stuff that beedee missed in rebase 2010-06-11 18:00:36 +12:00
Chris Forbes
3870be5122 fix various breakage in nuke code 2010-06-11 17:55:42 +12:00
Chris Forbes
1bd7a9b590 visualize minefields in OG 2010-06-11 17:53:35 +12:00
Chris Forbes
e60acc682a add logging to ProductionItem 2010-06-11 17:53:34 +12:00
Matthew Bowra-Dean
aa239d172d Log channels, PHP script diffs when told. 2010-06-10 12:50:22 +12:00
Matthew Bowra-Dean
5f48577ebc upload.php now groups log files into zip files by game ID. 2010-06-10 12:48:06 +12:00
Matthew Bowra-Dean
fd014e15a5 Support for master game ID. 2010-06-10 12:45:58 +12:00
Matthew Bowra-Dean
1839655eb5 Master server changes to add ID to schema. 2010-06-10 12:43:46 +12:00
Matthew Bowra-Dean
e7c7a117a8 Log uploading. 2010-06-10 12:43:45 +12:00
Chris Forbes
a6d0adbab3 fix perf of uim overlay so it's usable again 2010-06-03 20:54:44 +12:00
alzeih
52c69addc6 RA AFLD requires power and can be powered down 2010-05-31 20:28:39 +12:00
Bob
493dec031b allow queueing on Mobile 2010-05-31 14:24:35 +12:00
Bob
1e570b5edb added Queued field to order 2010-05-31 14:20:25 +12:00
unknown
f2bcf1afae Added support for keyboard scrolling 2010-05-30 14:27:53 +12:00
alzeih
b45c74fa0b meh 2010-05-30 14:12:10 +12:00
alzeih
f946382e38 Split Radar and Power widgets 2010-05-30 14:06:50 +12:00
Chris Forbes
5a5fa37397 fix up cnc nuke enough that it should WORK 2010-05-30 13:45:03 +12:00
Chris Forbes
c531343481 fix GUN sequences 2010-05-30 13:45:03 +12:00
Chris Forbes
b57ebcffea fix damaged state for agun 2010-05-30 13:45:02 +12:00
Chris Forbes
f89e9f6d06 unbitrot cnc 2010-05-30 13:45:02 +12:00
Chris Forbes
b5327a2cb7 add tire particle sprite (4 frames) 2010-05-30 13:45:01 +12:00
Chris Forbes
d379a1f78b increase barr/tent cost to 500 2010-05-30 13:45:01 +12:00
Chris Forbes
90e1e0e796 make 4tnk meatier 2010-05-30 13:45:00 +12:00
Chris Forbes
f3a0c94eb5 change starting cash to 5k 2010-05-30 13:45:00 +12:00
Chris Forbes
540a2da82a fix stupid desync in minelayer 2010-05-30 13:44:59 +12:00
Bob
8285c7d158 refactoring Widget 2010-05-29 18:01:36 +12:00
Chris Forbes
ac10ca3fad add some more logging to help track down this jealous desync bug 2010-05-29 12:13:09 +12:00
Chris Forbes
d824373853 housekeeping in paradrop 2010-05-29 11:59:55 +12:00
Chris Forbes
94e8edb1cd fix crash in TeslaInstantKills 2010-05-29 09:43:07 +12:00
827 changed files with 53830 additions and 31116 deletions

11
.gitignore vendored
View File

@@ -11,7 +11,6 @@ mods/*/*.dll
# Red Alert binary files
*.[mM][iI][xX]
*.[aA][uU][dD]
# Crap generated by OpenRa
sheet-*.png
@@ -23,12 +22,14 @@ log.txt
/*.dll
*.pdb
*.mdb
/*.exe
*.exe
OpenRA
OpenRA.app
*.vqa
# backup files by various editors
*~
*.orig
# dependency DLLs (different for every platform!)
cg.dll
cgGL.dll
@@ -43,6 +44,9 @@ settings.ini
packaging/windows/*.exe
# osx crap
.DS_Store
# osx build crap
packaging/osx/launcher/build/
packaging/osx/launcher/OpenRA.xcodeproj/*.pbxuser
@@ -51,3 +55,6 @@ packaging/osx/launcher/OpenRA.xcodeproj/*.mode1v3
temp.c
temp.o
temp.s
*.config
*.resources

9
AUTHORS Normal file
View File

@@ -0,0 +1,9 @@
AUTHORS
The OpenRA developers are:
* Chris Forbes
* Robert Pepperell
* Matthew Bowra-Dean
* Paul Chote
* Alli Witheford
* Joakim Lindberg

View File

@@ -0,0 +1,52 @@
using System;
using System.IO;
using OpenRA.FileFormats;
namespace FileExtractor
{
public class FileExtractor
{
int Length = 256;
public FileExtractor (string[] args)
{
if (args.Length != 2)
{
Console.WriteLine("usage: FileExtractor mod[,mod]* filename");
return;
}
var mods = args[0].Split(',');
var manifest = new Manifest(mods);
FileSystem.LoadFromManifest( manifest );
try
{
var readStream = FileSystem.Open(args[1]);
var writeStream = new FileStream(args[1], FileMode.OpenOrCreate, FileAccess.Write);
WriteOutFile(readStream, writeStream);
}
catch (FileNotFoundException)
{
Console.WriteLine(String.Format("No Such File {0}", args[1]));
}
}
void WriteOutFile (Stream readStream, Stream writeStream)
{
Byte[] buffer = new Byte[Length];
int bytesRead = readStream.Read(buffer,0,Length);
while( bytesRead > 0 )
{
writeStream.Write(buffer,0,bytesRead);
bytesRead = readStream.Read(buffer,0,Length);
}
readStream.Close();
writeStream.Close();
}
}
}

View File

@@ -1,48 +1,43 @@
<Project DefaultTargets="Build" ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{BA2B4C61-D5EE-4C3E-9BA1-EB32C531FA36}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>MapConverter</RootNamespace>
<AssemblyName>MapConverter</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Drawing" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Main.cs" />
<Compile Include="AssemblyInfo.cs" />
<Compile Include="MapConverter.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
<Project>{BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}</Project>
<Name>OpenRA.FileFormats</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="3.5" 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>{210645C7-E99E-46B6-863E-E211AE6C7D70}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>FileExtractor</RootNamespace>
<AssemblyName>FileExtractor</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
<Project>{BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}</Project>
<Name>OpenRA.FileFormats</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Include="Main.cs" />
<Compile Include="FileExtractor.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

13
FileExtractor/Main.cs Normal file
View File

@@ -0,0 +1,13 @@
using System;
namespace FileExtractor
{
public class MainClass
{
public static void Main (string[] args)
{
new FileExtractor(args);
}
}
}

100
Makefile
View File

@@ -1,23 +1,22 @@
CSC = gmcs
CSFLAGS = -nologo -warn:4 -debug:+ -debug:full -optimize- -codepage:utf8 -unsafe
DEFINE = DEBUG;TRACE
PROGRAMS =fileformats gl game ra cnc aftermath seqed mapcvtr editor
PROGRAMS =fileformats gl game ra cnc seqed editor ralint filex tsbuild
prefix = /usr/local
datarootdir = $(prefix)/share
datadir = $(datarootdir)
bindir = $(prefix)/bin
BIN_INSTALL_DIR = $(DESTDIR)$(bindir)
INSTALL_DIR = $(DESTDIR)$(datadir)/openra
INSTALL = install
INSTALL_PROGRAM = $(INSTALL)
COMMON_LIBS = System.dll System.Core.dll System.Drawing.dll System.Xml.dll
CORE = fileformats gl game seqed mapcvtr
fileformats_SRCS = $(shell find OpenRA.FileFormats/ -iname '*.cs')
fileformats_TARGET = OpenRA.FileFormats.dll
fileformats_KIND = library
fileformats_LIBS = $(COMMON_LIBS) thirdparty/Tao/Tao.Sdl.dll
fileformats_LIBS = $(COMMON_LIBS) thirdparty/Tao/Tao.Sdl.dll thirdparty/WindowsBase.dll
gl_SRCS = $(shell find OpenRA.Gl/ -iname '*.cs')
gl_TARGET = OpenRA.Gl.dll
@@ -47,71 +46,85 @@ cnc_KIND = library
cnc_DEPS = $(fileformats_TARGET) $(game_TARGET) $(ra_TARGET)
cnc_LIBS = $(COMMON_LIBS) $(cnc_DEPS)
aftermath_SRCS = $(shell find OpenRA.Mods.Aftermath/ -iname '*.cs')
aftermath_TARGET = mods/aftermath/OpenRA.Mods.Aftermath.dll
aftermath_KIND = library
aftermath_DEPS = $(fileformats_TARGET) $(game_TARGET) $(ra_TARGET)
aftermath_LIBS = $(COMMON_LIBS) $(aftermath_DEPS)
seqed_SRCS = $(shell find SequenceEditor/ -iname '*.cs')
seqed_TARGET = SequenceEditor.exe
seqed_KIND = winexe
seqed_DEPS = $(fileformats_TARGET)
seqed_LIBS = $(COMMON_LIBS) System.Windows.Forms.dll $(seqed_DEPS)
seqed_EXTRA = -resource:SequenceEditor.Form1.resources
editor_SRCS = $(shell find OpenRA.Editor/ -iname '*.cs')
editor_TARGET = OpenRA.Editor.exe
editor_KIND = winexe
editor_DEPS = $(fileformats_TARGET) $(game_TARGET)
editor_LIBS = $(COMMON_LIBS) System.Windows.Forms.dll System.Data.dll $(editor_DEPS)
editor_EXTRA = -resource:OpenRA.Editor.Form1.resources
mapcvtr_SRCS = $(shell find MapConverter/ -iname '*.cs')
mapcvtr_TARGET = MapConverter.exe
mapcvtr_KIND = winexe
mapcvtr_DEPS = $(fileformats_TARGET)
mapcvtr_LIBS = $(COMMON_LIBS) $(mapcvtr_DEPS)
ralint_SRCS = $(shell find RALint/ -iname '*.cs')
ralint_TARGET = RALint.exe
ralint_KIND = winexe
ralint_DEPS = $(fileformats_TARGET) $(game_TARGET)
ralint_LIBS = $(COMMON_LIBS) $(ralint_DEPS)
filex_SRCS = $(shell find FileExtractor/ -iname '*.cs')
filex_TARGET = FileExtractor.exe
filex_KIND = winexe
filex_DEPS = $(fileformats_TARGET)
filex_LIBS = $(COMMON_LIBS) $(filex_DEPS)
tsbuild_SRCS = $(shell find OpenRA.TilesetBuilder/ -iname '*.cs')
tsbuild_TARGET = 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
# -platform:x86
.SUFFIXES:
.PHONY: clean all default mods seqed mapcvtr install uninstall
.PHONY: clean all game tool default mods mod_ra mod_cnc install uninstall editor_res editor tsbuild ralint seqed filex
all: $(fileformats_TARGET) $(gl_TARGET) $(game_TARGET) $(ra_TARGET) $(cnc_TARGET) $(aftermath_TARGET) $(seqed_TARGET) $(mapcvtr_TARGET)
game: $(fileformats_TARGET) $(gl_TARGET) $(game_TARGET) $(ra_TARGET) $(cnc_TARGET)
clean:
@-rm *.exe *.dll *.mdb mods/**/*.dll mods/**/*.mdb
@-rm *.exe *.dll *.mdb mods/**/*.dll mods/**/*.mdb *.resources
distclean: clean
CORE = fileformats gl game seqed
install: all
@-echo "Installing OpenRA to $(INSTALL_DIR)"
@$(INSTALL_PROGRAM) -d $(INSTALL_DIR)
@$(INSTALL_PROGRAM) $(foreach prog,$(CORE),$($(prog)_TARGET)) $(INSTALL_DIR)
@$(INSTALL_PROGRAM) -d $(INSTALL_DIR)/mods/aftermath
@$(INSTALL_PROGRAM) $(aftermath_TARGET) $(INSTALL_DIR)/mods/aftermath
@-cp $(foreach f,$(shell ls mods/aftermath --hide=*.dll),mods/aftermath/$(f)) $(INSTALL_DIR)/mods/aftermath
@cp -r mods/aftermath/packages $(INSTALL_DIR)/mods/aftermath
@$(INSTALL_PROGRAM) -d $(INSTALL_DIR)/mods/cnc
@$(INSTALL_PROGRAM) $(cnc_TARGET) $(INSTALL_DIR)/mods/cnc
@-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
@cp -r mods/cnc/chrome $(INSTALL_DIR)/mods/cnc
@$(INSTALL_PROGRAM) -d $(INSTALL_DIR)/mods/ra
@$(INSTALL_PROGRAM) $(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
@cp -r mods/ra/extras $(INSTALL_DIR)/mods/ra
@cp -r mods/ra/chrome $(INSTALL_DIR)/mods/ra
@cp -r shaders $(INSTALL_DIR)
@cp *.ttf $(INSTALL_DIR)
@-cp *.ini $(INSTALL_DIR)
@cp -r thirdparty $(INSTALL_DIR)
@cp --parents -r thirdparty/Tao $(INSTALL_DIR)
@$(INSTALL_PROGRAM) thirdparty/WindowsBase.dll $(INSTALL_DIR)
@echo "#!/bin/sh" > openra
@echo "cd "$(datadir)"/openra" >> openra
@echo "mono "$(datadir)"/openra/OpenRA.Game.exe SupportDir=~/.openra \"$$""@\"" >> openra
@$(INSTALL_PROGRAM) -d $(BIN_INSTALL_DIR)
@$(INSTALL_PROGRAM) -m +rx openra $(BIN_INSTALL_DIR)
@echo "OpenRA is now installed. You will now want to download"
@echo "http://open-ra.org/packages/ra-packages.zip and"
@echo "http://open-ra.org/packages/cnc-packages.zip"
@echo "http://open-ra.org/packages/ra-packages.php and"
@echo "http://open-ra.org/packages/cnc-packages.php"
@echo "and extract their contents to"
@echo "$(INSTALL_DIR)/mods/ra/packages and "
@echo "$(INSTALL_DIR)/mods/cnc/packages respectively."
@@ -122,14 +135,32 @@ uninstall:
@-rm -r $(INSTALL_DIR)
@-rm $(DESTDIR)$(bindir)/openra
mods: $(ra_TARGET) $(cnc_TARGET) $(aftermath_TARGET)
seqed: $(seqed_TARGET)
mapcvtr: $(mapcvtr_TARGET)
editor: $(editor_TARGET)
mod_ra: $(ra_TARGET) $(ralint_TARGET)
mono RALint.exe ra
mod_cnc: $(cnc_TARGET) $(ralint_TARGET)
mono RALint.exe cnc
mods: mod_ra mod_cnc
OpenRA.Editor.Form1.resources:
resgen2 OpenRA.Editor/Form1.resx OpenRA.Editor.Form1.resources 1> /dev/null
editor: OpenRA.Editor.Form1.resources $(editor_TARGET)
ralint: $(ralint_TARGET)
seqed: SequenceEditor.Form1.resources $(seqed_TARGET)
SequenceEditor.Form1.resources:
resgen2 SequenceEditor/Form1.resx SequenceEditor.Form1.resources 1> /dev/null
filex: $(filex_TARGET)
tsbuild: OpenRA.TilesetBuilder.Form1.resources $(tsbuild_TARGET)
OpenRA.TilesetBuilder.Form1.resources:
resgen2 OpenRA.TilesetBuilder/Form1.resx OpenRA.TilesetBuilder.Form1.resources 1> /dev/null
tools: editor ralint seqed filex tsbuild
all: game tools
fixheader: packaging/fixheader.cs
@$(CSC) packaging/fixheader.cs $(CSFLAGS) -out:fixheader.exe -t:exe $(COMMON_LIBS:%=-r:%)
define BUILD_ASSEMBLY
$$($(1)_TARGET): $$($(1)_SRCS) Makefile $$($(1)_DEPS)
$$($(1)_TARGET): $$($(1)_SRCS) Makefile $$($(1)_DEPS) fixheader
@echo CSC $$(@)
@$(CSC) $$($(1)_LIBS:%=-r:%) \
-out:$$(@) $(CSFLAGS) $$($(1)_FLAGS) \
@@ -137,6 +168,7 @@ $$($(1)_TARGET): $$($(1)_SRCS) Makefile $$($(1)_DEPS)
-t:"$$($(1)_KIND)" \
$$($(1)_EXTRA) \
$$($(1)_SRCS)
@mono fixheader.exe $$(@)
endef
$(foreach prog,$(PROGRAMS),$(eval $(call BUILD_ASSEMBLY,$(prog))))

View File

@@ -1,26 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("MapConverter")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[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.*")]
// 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

@@ -1,13 +0,0 @@
using System;
using OpenRA.FileFormats;
namespace MapConverter
{
class MainClass
{
public static void Main (string[] args)
{
new MapConverter(args);
}
}
}

View File

@@ -1,404 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using OpenRA;
using OpenRA.FileFormats;
namespace MapConverter
{
public class MapConverter
{
// Mapping from ra overlay index to type string
static string[] raOverlayNames =
{
"sbag", "cycl", "brik", "fenc", "wood",
"gold01", "gold02", "gold03", "gold04",
"gem01", "gem02", "gem03", "gem04",
"v12", "v13", "v14", "v15", "v16", "v17", "v18",
"fpls", "wcrate", "scrate", "barb", "sbag",
};
static Dictionary< string, Pair<byte,byte> > overlayResourceMapping = new Dictionary<string, Pair<byte, byte>>()
{
// RA Gems, Gold
{ "gold01", new Pair<byte,byte>(1,0) },
{ "gold02", new Pair<byte,byte>(1,1) },
{ "gold03", new Pair<byte,byte>(1,2) },
{ "gold04", new Pair<byte,byte>(1,3) },
{ "gem01", new Pair<byte,byte>(2,0) },
{ "gem02", new Pair<byte,byte>(2,1) },
{ "gem03", new Pair<byte,byte>(2,2) },
{ "gem04", new Pair<byte,byte>(2,3) },
// cnc tiberium
{ "ti1", new Pair<byte,byte>(1,0) },
{ "ti2", new Pair<byte,byte>(1,1) },
{ "ti3", new Pair<byte,byte>(1,2) },
{ "ti4", new Pair<byte,byte>(1,3) },
{ "ti5", new Pair<byte,byte>(1,4) },
{ "ti6", new Pair<byte,byte>(1,5) },
{ "ti7", new Pair<byte,byte>(1,6) },
{ "ti8", new Pair<byte,byte>(1,7) },
{ "ti9", new Pair<byte,byte>(1,8) },
{ "ti10", new Pair<byte,byte>(1,9) },
{ "ti11", new Pair<byte,byte>(1,10) },
{ "ti12", new Pair<byte,byte>(1,11) },
};
static Dictionary<string, string> overlayActorMapping = new Dictionary<string,string>() {
// Fences
{"sbag","sbag"},
{"cycl","cycl"},
{"brik","brik"},
{"fenc","fenc"},
{"wood","wood"},
// Fields
{"v12","v12"},
{"v13","v13"},
{"v14","v14"},
{"v15","v15"},
{"v16","v16"},
{"v17","v17"},
{"v18","v18"},
// Crates
{"wcrate","crate"},
{"scrate","crate"},
};
int MapSize;
int ActorCount = 0;
Map Map = new Map();
Manifest manifest;
public MapConverter(string[] args)
{
if (args.Length != 3)
{
Console.WriteLine("usage: MapConverter mod[,mod]* input-map.ini output-map.yaml");
return;
}
var mods = args[0].Split(',');
manifest = new Manifest(mods);
foreach (var folder in manifest.Folders) FileSystem.Mount(folder);
foreach (var pkg in manifest.Packages) FileSystem.Mount(pkg);
ConvertIniMap(args[1]);
Save(args[2]);
}
static Dictionary<Pair<string,string>,Pair<string,string> > fileMapping = new Dictionary<Pair<string,string>,Pair<string,string> >()
{
{Pair.New("ra","TEMPERAT"),Pair.New("tem","temperat.col")},
{Pair.New("ra","SNOW"),Pair.New("sno","snow.col")},
{Pair.New("ra","INTERIOR"),Pair.New("int","temperat.col")},
{Pair.New("cnc","DESERT"),Pair.New("des","desert.col")},
{Pair.New("cnc","TEMPERAT"),Pair.New("tem","temperat.col")},
{Pair.New("cnc","WINTER"),Pair.New("win","winter.col")},
};
TerrainColorSet terrainTypeColors;
TileSet tileset;
public void ConvertIniMap(string iniFile)
{
IniFile file = new IniFile(FileSystem.Open(iniFile));
IniSection basic = file.GetSection("Basic");
IniSection map = file.GetSection("Map");
var INIFormat = int.Parse(basic.GetValue("NewINIFormat", "0"));
var XOffset = int.Parse(map.GetValue("X", "0"));
var YOffset = int.Parse(map.GetValue("Y", "0"));
var Width = int.Parse(map.GetValue("Width", "0"));
var Height = int.Parse(map.GetValue("Height", "0"));
MapSize = (INIFormat == 3) ? 128 : 64;
Map.Title = basic.GetValue("Name", "(null)");
Map.Author = "Westwood Studios";
Map.Tileset = Truncate(map.GetValue("Theater", "TEMPERAT"), 8);
Map.MapSize.X = MapSize;
Map.MapSize.Y = MapSize;
Map.TopLeft = new int2 (XOffset, YOffset);
Map.BottomRight = new int2(XOffset+Width,YOffset+Height);
Map.Selectable = true;
if (INIFormat == 3) // RA map
{
UnpackRATileData(ReadPackedSection(file.GetSection("MapPack")));
UnpackRAOverlayData(ReadPackedSection(file.GetSection("OverlayPack")));
ReadRATrees(file);
terrainTypeColors = new TerrainColorSet(fileMapping[Pair.New("ra",Map.Tileset)].Second);
tileset = new TileSet("tileSet.til","templates.ini",fileMapping[Pair.New("ra",Map.Tileset)].First);
}
else // CNC
{
UnpackCncTileData(FileSystem.Open(iniFile.Substring(0,iniFile.Length-4)+".bin"));
ReadCncOverlay(file);
ReadCncTrees(file);
terrainTypeColors = new TerrainColorSet(fileMapping[Pair.New("cnc",Map.Tileset)].Second);
tileset = new TileSet("tileSet.til","templates.ini",fileMapping[Pair.New("cnc",Map.Tileset)].First);
}
LoadActors(file, "STRUCTURES");
LoadActors(file, "UNITS");
LoadActors(file, "INFANTRY");
LoadSmudges(file, "SMUDGE");
var wp = file.GetSection("Waypoints")
.Where(kv => int.Parse(kv.Value) > 0)
.Select(kv => Pair.New(int.Parse(kv.Key), new int2(int.Parse(kv.Value) % MapSize, int.Parse(kv.Value) / MapSize)))
.Where(a => a.First < 8)
.ToArray();
Map.PlayerCount = wp.Count();
foreach (var kv in wp)
Map.Waypoints.Add("spawn"+kv.First, kv.Second);
}
static MemoryStream ReadPackedSection(IniSection mapPackSection)
{
StringBuilder sb = new StringBuilder();
for (int i = 1; ; i++)
{
string line = mapPackSection.GetValue(i.ToString(), null);
if (line == null)
break;
sb.Append(line.Trim());
}
byte[] data = Convert.FromBase64String(sb.ToString());
List<byte[]> chunks = new List<byte[]>();
BinaryReader reader = new BinaryReader(new MemoryStream(data));
try
{
while (true)
{
uint length = reader.ReadUInt32() & 0xdfffffff;
byte[] dest = new byte[8192];
byte[] src = reader.ReadBytes((int)length);
/*int actualLength =*/ Format80.DecodeInto(src, dest);
chunks.Add(dest);
}
}
catch (EndOfStreamException) { }
MemoryStream ms = new MemoryStream();
foreach (byte[] chunk in chunks)
ms.Write(chunk, 0, chunk.Length);
ms.Position = 0;
return ms;
}
static byte ReadByte( Stream s )
{
int ret = s.ReadByte();
if( ret == -1 )
throw new NotImplementedException();
return (byte)ret;
}
static ushort ReadWord(Stream s)
{
ushort ret = ReadByte(s);
ret |= (ushort)(ReadByte(s) << 8);
return ret;
}
void UnpackRATileData( MemoryStream ms )
{
Map.MapTiles = new TileReference<ushort, byte>[ MapSize, MapSize ];
for( int i = 0 ; i < MapSize ; i++ )
for( int j = 0 ; j < MapSize ; j++ )
Map.MapTiles[i,j] = new TileReference<ushort,byte>();
for( int j = 0 ; j < MapSize ; j++ )
for( int i = 0 ; i < MapSize ; i++ )
Map.MapTiles[i,j].type = ReadWord(ms);
for( int j = 0 ; j < MapSize ; j++ )
for( int i = 0 ; i < MapSize ; i++ )
{
Map.MapTiles[i,j].index = ReadByte(ms);
if( Map.MapTiles[i,j].type == 0xff || Map.MapTiles[i,j].type == 0xffff )
Map.MapTiles[i,j].index = byte.MaxValue;
}
}
void UnpackRAOverlayData( MemoryStream ms )
{
Map.MapResources = new TileReference<byte, byte>[ MapSize, MapSize ];
for( int j = 0 ; j < MapSize ; j++ )
for( int i = 0 ; i < MapSize ; i++ )
{
byte o = ReadByte( ms );
var res = Pair.New((byte)0,(byte)0);
if (o != 255 && overlayResourceMapping.ContainsKey(raOverlayNames[o]))
res = overlayResourceMapping[raOverlayNames[o]];
Map.MapResources[i,j] = new TileReference<byte,byte>(res.First, res.Second);
if (o != 255 && overlayActorMapping.ContainsKey(raOverlayNames[o]))
Map.Actors.Add("Actor"+ActorCount, new ActorReference("Actor"+ActorCount++, overlayActorMapping[raOverlayNames[o]], new int2(i,j), "Neutral"));
}
}
void ReadRATrees( IniFile file )
{
IniSection terrain = file.GetSection( "TERRAIN", true );
if( terrain == null )
return;
foreach( KeyValuePair<string, string> kv in terrain )
{
var loc = int.Parse( kv.Key );
Map.Actors.Add("Actor"+ActorCount, new ActorReference("Actor"+ActorCount++,kv.Value.ToLowerInvariant(), new int2(loc % MapSize, loc / MapSize), "Neutral" ) );
}
}
void UnpackCncTileData( Stream ms )
{
Map.MapTiles = new TileReference<ushort, byte>[ MapSize, MapSize ];
for( int i = 0 ; i < MapSize ; i++ )
for( int j = 0 ; j < MapSize ; j++ )
Map.MapTiles[i,j] = new TileReference<ushort,byte>();
for( int j = 0 ; j < MapSize ; j++ )
for( int i = 0 ; i < MapSize ; i++ )
{
Map.MapTiles[i,j].type = ReadByte(ms);
Map.MapTiles[i,j].index = ReadByte(ms);
if( Map.MapTiles[i,j].type == 0xff )
Map.MapTiles[i,j].index = byte.MaxValue;
}
}
void ReadCncOverlay( IniFile file )
{
IniSection overlay = file.GetSection( "OVERLAY", true );
if( overlay == null )
return;
Map.MapResources = new TileReference<byte, byte>[ MapSize, MapSize ];
foreach( KeyValuePair<string, string> kv in overlay )
{
var loc = int.Parse( kv.Key );
int2 cell = new int2(loc % MapSize, loc / MapSize);
var res = Pair.New((byte)0,(byte)0);
if (overlayResourceMapping.ContainsKey(kv.Value.ToLower()))
res = overlayResourceMapping[kv.Value.ToLower()];
Map.MapResources[ cell.X, cell.Y ] = new TileReference<byte,byte>(res.First, res.Second);
if (overlayActorMapping.ContainsKey(kv.Value.ToLower()))
Map.Actors.Add("Actor"+ActorCount, new ActorReference("Actor"+ActorCount++, overlayActorMapping[kv.Value.ToLower()], new int2(cell.X,cell.Y), "Neutral"));
}
}
void ReadCncTrees( IniFile file )
{
IniSection terrain = file.GetSection( "TERRAIN", true );
if( terrain == null )
return;
foreach( KeyValuePair<string, string> kv in terrain )
{
var loc = int.Parse( kv.Key );
Map.Actors.Add("Actor"+ActorCount, new ActorReference("Actor"+ActorCount++, kv.Value.Split(',')[0].ToLowerInvariant(), new int2(loc % MapSize, loc / MapSize),"Neutral"));
}
}
void LoadActors(IniFile file, string section)
{
foreach (var s in file.GetSection(section, true))
{
//num=owner,type,health,location,facing,...
var parts = s.Value.Split( ',' );
var loc = int.Parse(parts[3]);
if (parts[0] == "")
parts[0] = "Neutral";
Map.Actors.Add("Actor"+ActorCount, new ActorReference("Actor"+ActorCount++, parts[1].ToLowerInvariant(), new int2(loc % MapSize, loc / MapSize), parts[0]));
}
}
void LoadSmudges(IniFile file, string section)
{
foreach (var s in file.GetSection(section, true))
{
//loc=type,loc,depth
var parts = s.Value.Split( ',' );
var loc = int.Parse(parts[1]);
Map.Smudges.Add(new SmudgeReference(parts[0].ToLowerInvariant(),new int2(loc % MapSize, loc / MapSize),int.Parse(parts[2])));
}
}
static string Truncate( string s, int maxLength )
{
return s.Length <= maxLength ? s : s.Substring(0,maxLength );
}
public void SavePreviewImage(string filepath)
{
var xs = Map.TopLeft.X;
var ys = Map.TopLeft.Y;
var bitmap = new Bitmap(Map.Width, Map.Height);
for (var x = 0; x < Map.Width; x++)
for (var y = 0; y < Map.Height; y++)
bitmap.SetPixel(x, y, terrainTypeColors.ColorForTerrainType(tileset.GetTerrainType(Map.MapTiles[x+xs, y+ys])));
for (var x = 0; x < Map.Width; x++)
for (var y = 0; y < Map.Height; y++)
if (Map.MapResources[x+xs, y+ys].type > 0)
bitmap.SetPixel(x, y, terrainTypeColors.ColorForTerrainType(TerrainType.Ore));
bitmap.Save(filepath,ImageFormat.Png);
}
public void Save(string filepath)
{
Directory.CreateDirectory(filepath);
Map.Package = new Folder(filepath);
SavePreviewImage(Path.Combine(filepath,"preview.png"));
Map.Save(filepath);
}
}
}

View File

@@ -1,4 +1,14 @@
using System.Drawing;
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System.Drawing;
using OpenRA.GameRules;
using OpenRA.Traits;

View File

@@ -39,14 +39,24 @@
this.actorPalette = new System.Windows.Forms.FlowLayoutPanel();
this.tabPage3 = new System.Windows.Forms.TabPage();
this.resourcePalette = new System.Windows.Forms.FlowLayoutPanel();
this.toolStrip1 = new System.Windows.Forms.ToolStrip();
this.toolStripButton3 = new System.Windows.Forms.ToolStripButton();
this.toolStripButton5 = new System.Windows.Forms.ToolStripButton();
this.toolStripButton4 = new System.Windows.Forms.ToolStripButton();
this.toolStripButton1 = new System.Windows.Forms.ToolStripButton();
this.toolStripButton6 = new System.Windows.Forms.ToolStripButton();
this.toolStripButton7 = new System.Windows.Forms.ToolStripButton();
this.toolStripButton2 = new System.Windows.Forms.ToolStripButton();
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.newToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.saveAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.cCRedAlertMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.bitmapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
this.exotToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.propertiesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.resizeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
this.spawnpointsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.tt = new System.Windows.Forms.ToolTip(this.components);
this.folderBrowser = new System.Windows.Forms.FolderBrowserDialog();
this.surface1 = new OpenRA.Editor.Surface();
@@ -60,7 +70,7 @@
this.tabPage1.SuspendLayout();
this.tabPage2.SuspendLayout();
this.tabPage3.SuspendLayout();
this.toolStrip1.SuspendLayout();
this.menuStrip1.SuspendLayout();
this.SuspendLayout();
//
// toolStripContainer1
@@ -69,7 +79,7 @@
// toolStripContainer1.ContentPanel
//
this.toolStripContainer1.ContentPanel.Controls.Add(this.splitContainer1);
this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size(985, 680);
this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size(985, 681);
this.toolStripContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.toolStripContainer1.Location = new System.Drawing.Point(0, 0);
this.toolStripContainer1.Name = "toolStripContainer1";
@@ -79,7 +89,7 @@
//
// toolStripContainer1.TopToolStripPanel
//
this.toolStripContainer1.TopToolStripPanel.Controls.Add(this.toolStrip1);
this.toolStripContainer1.TopToolStripPanel.Controls.Add(this.menuStrip1);
//
// splitContainer1
//
@@ -94,13 +104,12 @@
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.surface1);
this.splitContainer1.Size = new System.Drawing.Size(985, 680);
this.splitContainer1.Size = new System.Drawing.Size(985, 681);
this.splitContainer1.SplitterDistance = 198;
this.splitContainer1.TabIndex = 0;
//
// tabControl1
//
this.tabControl1.Alignment = System.Windows.Forms.TabAlignment.Left;
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Controls.Add(this.tabPage3);
@@ -109,16 +118,16 @@
this.tabControl1.Multiline = true;
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(198, 680);
this.tabControl1.Size = new System.Drawing.Size(198, 681);
this.tabControl1.TabIndex = 0;
//
// tabPage1
//
this.tabPage1.Controls.Add(this.tilePalette);
this.tabPage1.Location = new System.Drawing.Point(23, 4);
this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(171, 672);
this.tabPage1.Size = new System.Drawing.Size(190, 655);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "Templates";
this.tabPage1.UseVisualStyleBackColor = true;
@@ -130,16 +139,16 @@
this.tilePalette.Dock = System.Windows.Forms.DockStyle.Fill;
this.tilePalette.Location = new System.Drawing.Point(3, 3);
this.tilePalette.Name = "tilePalette";
this.tilePalette.Size = new System.Drawing.Size(165, 666);
this.tilePalette.Size = new System.Drawing.Size(184, 649);
this.tilePalette.TabIndex = 1;
//
// tabPage2
//
this.tabPage2.Controls.Add(this.actorPalette);
this.tabPage2.Location = new System.Drawing.Point(23, 4);
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(171, 672);
this.tabPage2.Size = new System.Drawing.Size(190, 655);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Actors";
this.tabPage2.UseVisualStyleBackColor = true;
@@ -151,15 +160,15 @@
this.actorPalette.Dock = System.Windows.Forms.DockStyle.Fill;
this.actorPalette.Location = new System.Drawing.Point(3, 3);
this.actorPalette.Name = "actorPalette";
this.actorPalette.Size = new System.Drawing.Size(165, 666);
this.actorPalette.Size = new System.Drawing.Size(184, 649);
this.actorPalette.TabIndex = 2;
//
// tabPage3
//
this.tabPage3.Controls.Add(this.resourcePalette);
this.tabPage3.Location = new System.Drawing.Point(23, 4);
this.tabPage3.Location = new System.Drawing.Point(4, 22);
this.tabPage3.Name = "tabPage3";
this.tabPage3.Size = new System.Drawing.Size(171, 672);
this.tabPage3.Size = new System.Drawing.Size(190, 655);
this.tabPage3.TabIndex = 2;
this.tabPage3.Text = "Resources";
this.tabPage3.UseVisualStyleBackColor = true;
@@ -171,87 +180,154 @@
this.resourcePalette.Dock = System.Windows.Forms.DockStyle.Fill;
this.resourcePalette.Location = new System.Drawing.Point(0, 0);
this.resourcePalette.Name = "resourcePalette";
this.resourcePalette.Size = new System.Drawing.Size(171, 672);
this.resourcePalette.Size = new System.Drawing.Size(190, 655);
this.resourcePalette.TabIndex = 3;
//
// toolStrip1
// menuStrip1
//
this.toolStrip1.Dock = System.Windows.Forms.DockStyle.None;
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripButton3,
this.toolStripButton5,
this.toolStripButton4,
this.toolStripButton1,
this.toolStripButton6,
this.toolStripButton7,
this.toolStripButton2});
this.toolStrip1.Location = new System.Drawing.Point(3, 0);
this.toolStrip1.Name = "toolStrip1";
this.toolStrip1.Size = new System.Drawing.Size(480, 25);
this.toolStrip1.TabIndex = 0;
this.menuStrip1.Dock = System.Windows.Forms.DockStyle.None;
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.mapToolStripMenuItem});
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Size = new System.Drawing.Size(985, 24);
this.menuStrip1.TabIndex = 1;
this.menuStrip1.Text = "menuStrip1";
//
// toolStripButton3
// fileToolStripMenuItem
//
this.toolStripButton3.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton3.Image")));
this.toolStripButton3.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripButton3.Name = "toolStripButton3";
this.toolStripButton3.Size = new System.Drawing.Size(51, 22);
this.toolStripButton3.Text = "New";
this.toolStripButton3.Click += new System.EventHandler(this.NewClicked);
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.newToolStripMenuItem,
this.toolStripSeparator1,
this.openToolStripMenuItem,
this.saveToolStripMenuItem,
this.saveAsToolStripMenuItem,
this.toolStripSeparator2,
this.toolStripMenuItem1,
this.toolStripSeparator3,
this.exotToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "&File";
//
// toolStripButton5
// newToolStripMenuItem
//
this.toolStripButton5.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton5.Image")));
this.toolStripButton5.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripButton5.Name = "toolStripButton5";
this.toolStripButton5.Size = new System.Drawing.Size(56, 22);
this.toolStripButton5.Text = "Open";
this.toolStripButton5.Click += new System.EventHandler(this.OpenClicked);
this.newToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("newToolStripMenuItem.Image")));
this.newToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Fuchsia;
this.newToolStripMenuItem.Name = "newToolStripMenuItem";
this.newToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.newToolStripMenuItem.Text = "&New...";
this.newToolStripMenuItem.Click += new System.EventHandler(this.NewClicked);
//
// toolStripButton4
// toolStripSeparator1
//
this.toolStripButton4.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton4.Image")));
this.toolStripButton4.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripButton4.Name = "toolStripButton4";
this.toolStripButton4.Size = new System.Drawing.Size(51, 22);
this.toolStripButton4.Text = "Save";
this.toolStripButton4.Click += new System.EventHandler(this.SaveClicked);
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(149, 6);
//
// toolStripButton1
// openToolStripMenuItem
//
this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image")));
this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripButton1.Name = "toolStripButton1";
this.toolStripButton1.Size = new System.Drawing.Size(76, 22);
this.toolStripButton1.Text = "Save As...";
this.toolStripButton1.Click += new System.EventHandler(this.SaveAsClicked);
this.openToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("openToolStripMenuItem.Image")));
this.openToolStripMenuItem.Name = "openToolStripMenuItem";
this.openToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.openToolStripMenuItem.Text = "&Open...";
this.openToolStripMenuItem.Click += new System.EventHandler(this.OpenClicked);
//
// toolStripButton6
// saveToolStripMenuItem
//
this.toolStripButton6.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton6.Image")));
this.toolStripButton6.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripButton6.Name = "toolStripButton6";
this.toolStripButton6.Size = new System.Drawing.Size(59, 22);
this.toolStripButton6.Text = "Resize";
this.toolStripButton6.Click += new System.EventHandler(this.ResizeClicked);
this.saveToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("saveToolStripMenuItem.Image")));
this.saveToolStripMenuItem.Name = "saveToolStripMenuItem";
this.saveToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.saveToolStripMenuItem.Text = "&Save";
this.saveToolStripMenuItem.Click += new System.EventHandler(this.SaveClicked);
//
// toolStripButton7
// saveAsToolStripMenuItem
//
this.toolStripButton7.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton7.Image")));
this.toolStripButton7.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripButton7.Name = "toolStripButton7";
this.toolStripButton7.Size = new System.Drawing.Size(80, 22);
this.toolStripButton7.Text = "Properties";
this.toolStripButton7.Click += new System.EventHandler(this.PropertiesClicked);
this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem";
this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.saveAsToolStripMenuItem.Text = "Save &As...";
this.saveAsToolStripMenuItem.Click += new System.EventHandler(this.SaveAsClicked);
//
// toolStripButton2
// toolStripSeparator2
//
this.toolStripButton2.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton2.Image")));
this.toolStripButton2.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripButton2.Name = "toolStripButton2";
this.toolStripButton2.Size = new System.Drawing.Size(95, 22);
this.toolStripButton2.Text = "Spawnpoints";
this.toolStripButton2.Click += new System.EventHandler(this.SpawnPointsClicked);
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(149, 6);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.cCRedAlertMapToolStripMenuItem,
this.bitmapToolStripMenuItem});
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(152, 22);
this.toolStripMenuItem1.Text = "&Import";
//
// cCRedAlertMapToolStripMenuItem
//
this.cCRedAlertMapToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("cCRedAlertMapToolStripMenuItem.Image")));
this.cCRedAlertMapToolStripMenuItem.Name = "cCRedAlertMapToolStripMenuItem";
this.cCRedAlertMapToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
this.cCRedAlertMapToolStripMenuItem.Text = "&C&&C / Red Alert Map...";
this.cCRedAlertMapToolStripMenuItem.Click += new System.EventHandler(this.ImportLegacyMapClicked);
//
// bitmapToolStripMenuItem
//
this.bitmapToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("bitmapToolStripMenuItem.Image")));
this.bitmapToolStripMenuItem.Name = "bitmapToolStripMenuItem";
this.bitmapToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
this.bitmapToolStripMenuItem.Text = "&Bitmap...";
//
// toolStripSeparator3
//
this.toolStripSeparator3.Name = "toolStripSeparator3";
this.toolStripSeparator3.Size = new System.Drawing.Size(149, 6);
//
// exotToolStripMenuItem
//
this.exotToolStripMenuItem.Name = "exotToolStripMenuItem";
this.exotToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.exotToolStripMenuItem.Text = "E&xit";
this.exotToolStripMenuItem.Click += new System.EventHandler(this.CloseClicked);
//
// mapToolStripMenuItem
//
this.mapToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.propertiesToolStripMenuItem,
this.resizeToolStripMenuItem,
this.toolStripSeparator4,
this.spawnpointsToolStripMenuItem});
this.mapToolStripMenuItem.Name = "mapToolStripMenuItem";
this.mapToolStripMenuItem.Size = new System.Drawing.Size(43, 20);
this.mapToolStripMenuItem.Text = "&Map";
//
// propertiesToolStripMenuItem
//
this.propertiesToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("propertiesToolStripMenuItem.Image")));
this.propertiesToolStripMenuItem.Name = "propertiesToolStripMenuItem";
this.propertiesToolStripMenuItem.Size = new System.Drawing.Size(142, 22);
this.propertiesToolStripMenuItem.Text = "&Properties...";
this.propertiesToolStripMenuItem.Click += new System.EventHandler(this.PropertiesClicked);
//
// resizeToolStripMenuItem
//
this.resizeToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("resizeToolStripMenuItem.Image")));
this.resizeToolStripMenuItem.Name = "resizeToolStripMenuItem";
this.resizeToolStripMenuItem.Size = new System.Drawing.Size(142, 22);
this.resizeToolStripMenuItem.Text = "&Resize...";
this.resizeToolStripMenuItem.Click += new System.EventHandler(this.ResizeClicked);
//
// toolStripSeparator4
//
this.toolStripSeparator4.Name = "toolStripSeparator4";
this.toolStripSeparator4.Size = new System.Drawing.Size(139, 6);
//
// spawnpointsToolStripMenuItem
//
this.spawnpointsToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("spawnpointsToolStripMenuItem.Image")));
this.spawnpointsToolStripMenuItem.Name = "spawnpointsToolStripMenuItem";
this.spawnpointsToolStripMenuItem.Size = new System.Drawing.Size(142, 22);
this.spawnpointsToolStripMenuItem.Text = "&Spawnpoints";
this.spawnpointsToolStripMenuItem.Click += new System.EventHandler(this.SpawnPointsClicked);
//
// tt
//
@@ -263,7 +339,7 @@
this.surface1.Dock = System.Windows.Forms.DockStyle.Fill;
this.surface1.Location = new System.Drawing.Point(0, 0);
this.surface1.Name = "surface1";
this.surface1.Size = new System.Drawing.Size(783, 680);
this.surface1.Size = new System.Drawing.Size(783, 681);
this.surface1.TabIndex = 5;
this.surface1.Text = "surface1";
//
@@ -274,9 +350,11 @@
this.ClientSize = new System.Drawing.Size(985, 705);
this.Controls.Add(this.toolStripContainer1);
this.KeyPreview = true;
this.MainMenuStrip = this.menuStrip1;
this.Name = "Form1";
this.Text = "OpenRA Editor";
this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyUp);
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OnFormClosing);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
this.toolStripContainer1.ContentPanel.ResumeLayout(false);
this.toolStripContainer1.TopToolStripPanel.ResumeLayout(false);
@@ -290,8 +368,8 @@
this.tabPage1.ResumeLayout(false);
this.tabPage2.ResumeLayout(false);
this.tabPage3.ResumeLayout(false);
this.toolStrip1.ResumeLayout(false);
this.toolStrip1.PerformLayout();
this.menuStrip1.ResumeLayout(false);
this.menuStrip1.PerformLayout();
this.ResumeLayout(false);
}
@@ -301,23 +379,33 @@
private System.Windows.Forms.ToolStripContainer toolStripContainer1;
private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.ToolTip tt;
private System.Windows.Forms.ToolStrip toolStrip1;
private System.Windows.Forms.ToolStripButton toolStripButton1;
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.FlowLayoutPanel tilePalette;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.ToolStripButton toolStripButton2;
private System.Windows.Forms.FlowLayoutPanel actorPalette;
private System.Windows.Forms.TabPage tabPage3;
private System.Windows.Forms.FlowLayoutPanel resourcePalette;
private System.Windows.Forms.ToolStripButton toolStripButton3;
private System.Windows.Forms.ToolStripButton toolStripButton5;
private System.Windows.Forms.ToolStripButton toolStripButton4;
private System.Windows.Forms.FolderBrowserDialog folderBrowser;
private System.Windows.Forms.ToolStripButton toolStripButton6;
private System.Windows.Forms.ToolStripButton toolStripButton7;
private Surface surface1;
private System.Windows.Forms.MenuStrip menuStrip1;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem newToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem saveAsToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
private System.Windows.Forms.ToolStripMenuItem exotToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem cCRedAlertMapToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem bitmapToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
private System.Windows.Forms.ToolStripMenuItem mapToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem propertiesToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem resizeToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;
private System.Windows.Forms.ToolStripMenuItem spawnpointsToolStripMenuItem;
}
}

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
@@ -40,22 +30,24 @@ namespace OpenRA.Editor
currentMod = mods.FirstOrDefault() ?? "ra";
var manifest = new Manifest(new[] { currentMod });
Game.LoadModAssemblies(manifest);
Text = "OpenRA Editor (mod:{0})".F(currentMod);
FileSystem.UnmountAll();
foreach (var folder in manifest.Folders) FileSystem.Mount(folder);
foreach (var pkg in manifest.Packages) FileSystem.Mount(pkg);
Game.modData = new ModData( currentMod );
Rules.LoadRules(manifest, new Map());
Rules.LoadRules(Game.modData.Manifest, new Map());
folderBrowser.SelectedPath = Environment.CurrentDirectory + "mods\\" + currentMod + "\\maps";
folderBrowser.SelectedPath = new string[] { Environment.CurrentDirectory, "mods", currentMod, "maps" }
.Aggregate(Path.Combine);
surface1.AfterChange += MakeDirty;
}
void MakeDirty() { dirty = true; }
string loadedMapName;
string colors;
string currentMod = "ra";
TileSet tileset;
bool dirty = false;
void LoadMap(string mapname)
{
@@ -65,17 +57,20 @@ namespace OpenRA.Editor
loadedMapName = mapname;
var manifest = new Manifest(new[] { currentMod });
Game.LoadModAssemblies(manifest);
FileSystem.UnmountAll();
foreach (var folder in manifest.Folders) FileSystem.Mount(folder);
foreach (var pkg in manifest.Packages) FileSystem.Mount(pkg);
Game.modData = new ModData( currentMod );
// load the map
var map = new Map(new Folder(mapname));
PrepareMapResources(manifest, map);
// upgrade maps that have no player definitions. editor doesnt care,
// but this breaks the game pretty badly.
if (map.Players.Count == 0)
map.Players.Add("Neutral", new PlayerReference("Neutral",
Rules.Info["world"].Traits.WithInterface<CountryInfo>().First().Race, true, true));
PrepareMapResources(Game.modData.Manifest, map);
dirty = false;
}
void NewMap(Map map)
@@ -86,41 +81,31 @@ namespace OpenRA.Editor
loadedMapName = null;
var manifest = new Manifest(new[] { currentMod });
Game.LoadModAssemblies(manifest);
Game.modData = new ModData( currentMod );
FileSystem.UnmountAll();
foreach (var folder in manifest.Folders) FileSystem.Mount(folder);
foreach (var pkg in manifest.Packages) FileSystem.Mount(pkg);
PrepareMapResources(Game.modData.Manifest, map);
PrepareMapResources(manifest, map);
MakeDirty();
}
void PrepareMapResources(Manifest manifest, Map map)
{
Rules.LoadRules(manifest, map);
// we're also going to need a tileset...
var theaterInfo = Rules.Info["world"].Traits.WithInterface<TheaterInfo>()
.FirstOrDefault(t => t.Theater == map.Theater);
tileset = new TileSet(theaterInfo.Tileset, theaterInfo.Templates, theaterInfo.Suffix);
colors = theaterInfo.MapColors;
var palette = new Palette(FileSystem.Open(map.Theater.ToLowerInvariant() + ".pal"), true);
Rules.LoadRules(manifest, map);
tileset = Rules.TileSets[map.Theater];
tileset.LoadTiles();
var palette = new Palette(FileSystem.Open(tileset.Palette), true);
surface1.Bind(map, tileset, palette);
// construct the palette of tiles
var palettes = new[] { tilePalette, actorPalette, resourcePalette };
foreach (var p in palettes) { p.Visible = false; p.SuspendLayout(); }
foreach (var n in tileset.tiles.Keys)
foreach (var t in tileset.Templates)
{
try
{
var bitmap = RenderTemplate(tileset, (ushort)n, palette);
var bitmap = RenderTemplate(tileset, (ushort)t.Key, palette);
var ibox = new PictureBox
{
Image = bitmap,
@@ -129,17 +114,16 @@ namespace OpenRA.Editor
SizeMode = PictureBoxSizeMode.StretchImage
};
var brushTemplate = new BrushTemplate { Bitmap = bitmap, N = n };
var brushTemplate = new BrushTemplate { Bitmap = bitmap, N = t.Key };
ibox.Click += (_, e) => surface1.SetBrush(brushTemplate);
var template = tileset.walk[n];
var template = t.Value;
tilePalette.Controls.Add(ibox);
tt.SetToolTip(ibox,
"{1}:{0} ({3}x{4} {2})".F(
template.Name,
template.Index,
template.Bridge,
"{1}:{0} ({2}x{3})".F(
template.Image,
template.Id,
template.Size.X,
template.Size.Y));
}
@@ -153,7 +137,8 @@ namespace OpenRA.Editor
try
{
var info = Rules.Info[a];
var template = RenderActor(info, theaterInfo.Suffix, palette);
if( !info.Traits.Contains<RenderSimpleInfo>() ) continue;
var template = RenderActor(info, tileset, palette);
var ibox = new PictureBox
{
Image = template.Bitmap,
@@ -167,9 +152,8 @@ namespace OpenRA.Editor
actorPalette.Controls.Add(ibox);
tt.SetToolTip(ibox,
"{0}:{1}".F(
info.Name,
info.Category));
"{0}".F(
info.Name));
actorTemplates.Add(template);
}
@@ -184,7 +168,7 @@ namespace OpenRA.Editor
{
try
{
var template = RenderResourceType(a, theaterInfo.Suffix, palette);
var template = RenderResourceType(a, tileset.Extensions, palette);
var ibox = new PictureBox
{
Image = template.Bitmap,
@@ -214,8 +198,8 @@ namespace OpenRA.Editor
static Bitmap RenderTemplate(TileSet ts, ushort n, Palette p)
{
var template = ts.walk[n];
var tile = ts.tiles[n];
var template = ts.Templates[n];
var tile = ts.Tiles[n];
var bitmap = new Bitmap(24 * template.Size.X, 24 * template.Size.Y);
var data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
@@ -247,10 +231,17 @@ namespace OpenRA.Editor
return bitmap;
}
static ActorTemplate RenderActor(ActorInfo info, string ext, Palette p)
static ActorTemplate RenderActor(ActorInfo info, TileSet tileset, Palette p)
{
var image = info.Traits.Get<RenderSimpleInfo>().Image ?? info.Name;
using (var s = FileSystem.OpenWithExts(image, "." + ext, ".shp"))
var ri = info.Traits.Get<RenderSimpleInfo>();
string image = null;
if (ri.OverrideTheater != null)
for (int i = 0; i < ri.OverrideTheater.Length; i++)
if (ri.OverrideTheater[i] == tileset.Id)
image = ri.OverrideImage[i];
image = image ?? ri.Image ?? info.Name;
using (var s = FileSystem.OpenWithExts(image, tileset.Extensions))
{
var shp = new ShpReader(s);
var frame = shp[0];
@@ -274,10 +265,10 @@ namespace OpenRA.Editor
}
}
static ResourceTemplate RenderResourceType(ResourceTypeInfo info, string ext, Palette p)
static ResourceTemplate RenderResourceType(ResourceTypeInfo info, string[] exts, Palette p)
{
var image = info.SpriteNames[0];
using (var s = FileSystem.OpenWithExts(image, "." + ext, ".shp"))
using (var s = FileSystem.OpenWithExts(image, exts))
{
var shp = new ShpReader(s);
var frame = shp[shp.ImageCount - 1];
@@ -327,30 +318,7 @@ namespace OpenRA.Editor
surface1.Invalidate();
}
}
void SavePreviewImage(string filepath)
{
var Map = surface1.Map;
var xs = Map.TopLeft.X;
var ys = Map.TopLeft.Y;
var terrainTypeColors = new TerrainColorSet(colors);
var bitmap = new Bitmap(Map.Width, Map.Height);
for (var x = 0; x < Map.Width; x++)
for (var y = 0; y < Map.Height; y++)
bitmap.SetPixel(x, y, terrainTypeColors.ColorForTerrainType(
tileset.GetTerrainType(Map.MapTiles[x + xs, y + ys])));
for (var x = 0; x < Map.Width; x++)
for (var y = 0; y < Map.Height; y++)
if (Map.MapResources[x + xs, y + ys].type > 0)
bitmap.SetPixel(x, y, terrainTypeColors.ColorForTerrainType(TerrainType.Ore));
bitmap.Save(filepath, ImageFormat.Png);
}
void SaveClicked(object sender, EventArgs e)
{
if (loadedMapName == null)
@@ -359,17 +327,18 @@ namespace OpenRA.Editor
{
surface1.Map.PlayerCount = surface1.Map.Waypoints.Count;
surface1.Map.Package = new Folder(loadedMapName);
SavePreviewImage(Path.Combine(loadedMapName, "preview.png"));
surface1.Map.Save(loadedMapName);
dirty = false;
}
}
void SaveAsClicked(object sender, EventArgs e)
{
folderBrowser.ShowNewFolderButton = true;
if (DialogResult.OK == folderBrowser.ShowDialog())
{
loadedMapName = folderBrowser.SelectedPath;
SaveClicked(sender, e);
}
@@ -378,6 +347,7 @@ namespace OpenRA.Editor
void OpenClicked(object sender, EventArgs e)
{
folderBrowser.ShowNewFolderButton = true;
if (DialogResult.OK == folderBrowser.ShowDialog())
LoadMap(folderBrowser.SelectedPath);
}
@@ -387,8 +357,7 @@ namespace OpenRA.Editor
using (var nmd = new NewMapDialog())
{
nmd.theater.Items.Clear();
nmd.theater.Items.AddRange(Rules.Info["world"].Traits.WithInterface<TheaterInfo>()
.Select(a => a.Theater).ToArray());
nmd.theater.Items.AddRange(Rules.TileSets.Select(a => a.Value.Id).ToArray());
nmd.theater.SelectedIndex = 0;
if (DialogResult.OK == nmd.ShowDialog())
@@ -400,8 +369,7 @@ namespace OpenRA.Editor
map.TopLeft = new int2((int)nmd.cordonLeft.Value, (int)nmd.cordonTop.Value);
map.BottomRight = new int2((int)nmd.cordonRight.Value, (int)nmd.cordonBottom.Value);
map.Tileset = nmd.theater.SelectedItem as string;
map.Players.Add("Neutral", new PlayerReference("Neutral", Rules.Info["world"].Traits.WithInterface<CountryInfo>().First().Race, true, true));
NewMap(map);
}
}
@@ -429,5 +397,48 @@ namespace OpenRA.Editor
void SpawnPointsClicked(object sender, EventArgs e) { surface1.SetWaypoint(new WaypointTemplate()); }
void Form1_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Space) surface1.IsPanning = true; }
void Form1_KeyUp(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Space) surface1.IsPanning = false; }
void CloseClicked(object sender, EventArgs e)
{
Close();
}
void ImportLegacyMapClicked(object sender, EventArgs e)
{
using (var ofd = new OpenFileDialog { Filter = "Legacy maps (*.ini;*.mpr)|*.ini;*.mpr" })
if (DialogResult.OK == ofd.ShowDialog())
{
/* massive hack: we should be able to call NewMap() with the imported Map object,
* but something's not right internally in it, unless loaded via the real maploader */
var savePath = Path.Combine(Path.GetTempPath(), "OpenRA.Import");
Directory.CreateDirectory(savePath);
var map = LegacyMapImporter.Import(ofd.FileName);
map.Package = new Folder(savePath);
map.Players.Add("Neutral", new PlayerReference("Neutral",
Rules.Info["world"].Traits.WithInterface<CountryInfo>().First().Race, true, true));
map.Save(savePath);
LoadMap(savePath);
loadedMapName = null; /* editor needs to think this hasnt been saved */
Directory.Delete(savePath, true);
MakeDirty();
}
}
void OnFormClosing(object sender, FormClosingEventArgs e)
{
if (!dirty) return;
switch (MessageBox.Show("The map has been modified since it was last saved. Save changes now?",
"Unsaved Changes", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation))
{
case DialogResult.Yes: SaveClicked(null, EventArgs.Empty); break;
case DialogResult.No: break;
case DialogResult.Cancel: e.Cancel = true; break;
}
}
}
}

View File

@@ -117,113 +117,175 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>77, 17</value>
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>309, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="toolStripButton3.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<data name="newToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIISURBVDhPpZP7S1NxGMbPPxKaXVUkMEq8IpKUCoY/hGgI
ymqkDYYXcCjDZOANURSjCNGFQUTsl4GXVMxKk62YU4fXQpaIlygHQxBRH8/zwvyaIAYe+HLgnPN8nue9
HA3nvDTq63oW/jm13XOwvPTB3DYFY5MH+bXfcN8ygfTSMSSXfESicQDxBqdYHwH29g9w2tnZ3UcguIvN
rR3417exuBJE5N1n/wfwLgXEOc38Bc6xNRHb+/y4nm49G0Bnit2zf9H6bkliE/jKuYxrd6oVgDWfjB+K
TWeKMyrGEVfowITvD9re/9ABVQrAhh0HHK+ZselMMaN/mvwtDb+aVqkA7HYIwIj3ysfluPTorJnP6Ezx
oHsD1s5ZXEktUwCOioB5f1CEPR9+wTG6iuiserTo8dkwng7HT/R+XUPF8xlcTjErAOdMcW6NW8STiwG8
7vej8oUPN/PsEv3t8Ao0TZP3T1u8uJRkUgAuSYHtO97oLxmXd5t9Ho8aPTK+GzntqNfrLm2fFoihwYOI
xGIF4KjoGBLzY1OrF9k6OOFxnwDC4wxIMX1G0pMhgVyMNyoA13PAtS7OrJk1PrC69LUdQWxuF6IybHrX
LRI7JrtZdoDAo1XmbjMyD+tjSXxGcXRmnYg5ttD9QuxDhN0uUgDOmbvNTpPOJaGAo2K36cyaGZvOFIfd
KlSA8/zRh9ABIDUG+1JpAAAAAElFTkSuQmCC
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHNSURBVDhPjZNdTxNREIb5LV54azSRxJ8gt95445XGa/8A
CU0MMVgIWNmgRSioGN0AapQaISAWrEaITQTkQyhL2WbbWtt1+7ll+7h7SDdBocskk3Mm58xzZt7JaWmx
bTdyk9/rPsz0fbYmz2JqfvSdHhJLPpxzTzMUid13F0D3k/h41V57iU+dI7/dfTqA8zKGBLUohjpurxER
7/24i/RkSnj/47csLsWOB27IZ1DmrlDQJrHIU8q8EbE63UrD7oVe09p243iIqEAPQGVOQJxKRJwfdgE9
gxO8X1wRkIWv/1Ri7A0QD5/HSrWT/HTNTgwIDapayAV0DTwXyQ0/IqwSvXU4hWQn6uwl4usPKCl9pGI+
F2DV6zwaX2BQjgjIiZPpHXrpJjU2di7lao2sXmLiwwYXL18/GeB/KP8HqJgH5Iwy++k/yDOrzQF3+p8d
AZi1A/RCleQvg81ElrHwt+aA232jLqBmWRjFKlq2wM/9HLGtFCOvPjcHdHQPCYBl1SmWTdK5IvFknu/b
GaIrKsEX880B7V1B6rZq5cqhaIqms7aT4cuqyuyygvR0xhvgiOao7Qjm9Byyyw7K80hj0wRGw94tOGPy
cs8fetoLfwGP5fd9L1vD4gAAAABJRU5ErkJggg==
</value>
</data>
<data name="toolStripButton5.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<data name="openToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIISURBVDhPpZP7S1NxGMbPPxKaXVUkMEq8IpKUCoY/hGgI
ymqkDYYXcCjDZOANURSjCNGFQUTsl4GXVMxKk62YU4fXQpaIlygHQxBRH8/zwvyaIAYe+HLgnPN8nue9
HA3nvDTq63oW/jm13XOwvPTB3DYFY5MH+bXfcN8ygfTSMSSXfESicQDxBqdYHwH29g9w2tnZ3UcguIvN
rR3417exuBJE5N1n/wfwLgXEOc38Bc6xNRHb+/y4nm49G0Bnit2zf9H6bkliE/jKuYxrd6oVgDWfjB+K
TWeKMyrGEVfowITvD9re/9ABVQrAhh0HHK+ZselMMaN/mvwtDb+aVqkA7HYIwIj3ysfluPTorJnP6Ezx
oHsD1s5ZXEktUwCOioB5f1CEPR9+wTG6iuiserTo8dkwng7HT/R+XUPF8xlcTjErAOdMcW6NW8STiwG8
7vej8oUPN/PsEv3t8Ao0TZP3T1u8uJRkUgAuSYHtO97oLxmXd5t9Ho8aPTK+GzntqNfrLm2fFoihwYOI
xGIF4KjoGBLzY1OrF9k6OOFxnwDC4wxIMX1G0pMhgVyMNyoA13PAtS7OrJk1PrC69LUdQWxuF6IybHrX
LRI7JrtZdoDAo1XmbjMyD+tjSXxGcXRmnYg5ttD9QuxDhN0uUgDOmbvNTpPOJaGAo2K36cyaGZvOFIfd
KlSA8/zRh9ABIDUG+1JpAAAAAElFTkSuQmCC
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAACeklE
QVQ4T6WTWUiUURiG/4suurJIjUIwskQsEANDqosQpUVNKbdCSRPKrQVDMddmXEedGdcpFXNGnUYdrSzF
sEIoFInQcqHE1CwoKsXUUMnt6Z+RLMtA8OK5OZz3Oe/5OEcAhPWwpnBaodZZmqfjWmY5GSo98XJNwq9D
1yQIilLhFaYIMIQuxZaZJ4uy6FS1T2BUIUKdNsdPhL9pqpEp/ne18PiiE94RCjzDco0C+rs1zIzXGvkx
pmNuRI2+XEG9NjV5NYlXuBLP0DzcQwoQaiuUTI9VrQgvfC5irjeSqrJMKovTURcmU5KbxE15HAWyGNH5
e/BCtSab6a+a5ZMXxTD9cdAbsir/CG6Xyvj+qcRY2xBurss28lCfRYNOxr3KdPTqFHQlUspV17mVl0Cx
Mg5VdqyxjVBZks7k+3wMtYdaJdRXKVkYksJw6kreiWuD8dAXBa8j6Krx5UqwR4WgVqUwMZAJH+Tcr1bQ
/ki+tOnPK7wKhA5v5tvcmHnsxNsKOy6ePTohCvYKpXkSvr2RMtyWSL1OzuKgBHpClwRdwWLwNPPtHsy0
HGGy6RCjdfuQhllzxsUs1zBMoUiZyGh3LHe02XQ+E5v0RYqC89AZwOLzk8w+Pc5U82HG6h34Um1LR9pm
/N2scLAxsTEKVFlx9LQkcVebBQNJ8FKs+8KH2VZ3pp44Md7gyIjejo+a3fTKTZGE7MJ+j0Xj8lPOz4ih
tjyT3gfhdOQIy7TLN9Ai20hj8iZqEsxRx1hw4+oO/F13LjraW7ouC3JSo8mRXCAjNoj4y36GyXLO14VT
xw7gfNCO/XbW2FpZYLndjK1bTNhmarLyIa3nKxuyPwG9D9E7Fbto+QAAAABJRU5ErkJggg==
</value>
</data>
<data name="toolStripButton4.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<data name="saveToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIISURBVDhPpZP7S1NxGMbPPxKaXVUkMEq8IpKUCoY/hGgI
ymqkDYYXcCjDZOANURSjCNGFQUTsl4GXVMxKk62YU4fXQpaIlygHQxBRH8/zwvyaIAYe+HLgnPN8nue9
HA3nvDTq63oW/jm13XOwvPTB3DYFY5MH+bXfcN8ygfTSMSSXfESicQDxBqdYHwH29g9w2tnZ3UcguIvN
rR3417exuBJE5N1n/wfwLgXEOc38Bc6xNRHb+/y4nm49G0Bnit2zf9H6bkliE/jKuYxrd6oVgDWfjB+K
TWeKMyrGEVfowITvD9re/9ABVQrAhh0HHK+ZselMMaN/mvwtDb+aVqkA7HYIwIj3ysfluPTorJnP6Ezx
oHsD1s5ZXEktUwCOioB5f1CEPR9+wTG6iuiserTo8dkwng7HT/R+XUPF8xlcTjErAOdMcW6NW8STiwG8
7vej8oUPN/PsEv3t8Ao0TZP3T1u8uJRkUgAuSYHtO97oLxmXd5t9Ho8aPTK+GzntqNfrLm2fFoihwYOI
xGIF4KjoGBLzY1OrF9k6OOFxnwDC4wxIMX1G0pMhgVyMNyoA13PAtS7OrJk1PrC69LUdQWxuF6IybHrX
LRI7JrtZdoDAo1XmbjMyD+tjSXxGcXRmnYg5ttD9QuxDhN0uUgDOmbvNTpPOJaGAo2K36cyaGZvOFIfd
KlSA8/zRh9ABIDUG+1JpAAAAAElFTkSuQmCC
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAACMklE
QVQ4T6WT3UuTcRTH9y90303QRbc1NYZrMRs86hzKsmFoIb09kqZpunxJUqxMxZYvkK1w6sTlahJOKvIF
TJEUMZaSlZkrWuJQU3QiGHz7nZ+wn0vrQh84Nw98Puc553wfBQDFXorDL18EQOXuXEGHaxlPHItoafbj
kXUW9XU/YLnnxd3yaZSWfEZR4Qfk5Y7japaHoVBwAYF9vUBd7Tq9/Oeztr4BfVIfTic95xUUuJ4tcUFl
xa//wv7FNRw3voJSKcN0yikEjrYFLigt+bmjgDoT/NW3hDCDG4UFMzhpbBUCW+McF1w3f9km2Aq/n/Lj
kORCTvYkEuJtQtDwwMcFmVfGQwR/w0MeH/ZrHZDlURgMViGorfnOBfKl0aBgJ7h35Bv2RTYj5cwbxMbW
C0FV5Qx6usFOCaSeH4bp7CDfNi2MZqbPps6bcD8STa8hSRYhuFU2hS43WAaAVvtvdvdVlN+Z50ulhdHM
GemeIByX0AmdrkIIbhRNwtkONNk2WHAC0Cdnh5TxnBnJl4t557h4Bsc4odWWCYE5b4LBQM39AO9MAgXL
WJhawtinOUxMz0POvY0T+g4Oq6Ps0GiKhYBiaX2I4GeTgOC0/Gp89C7AO7uMazctCNfaGdyC8GOPoY7M
F4KM9Hds7hU+80GdEweOSHjaNQB39xB6+kcw+HYM0QYTlJpGRDD4sKoBKlVOiCDx4oUBHk9KGIWE7kyn
om3Twmhm6kpF8NGITCGgn2K39QfkKu4LIHJHnwAAAABJRU5ErkJggg==
</value>
</data>
<data name="toolStripButton1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<data name="cCRedAlertMapToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIISURBVDhPpZP7S1NxGMbPPxKaXVUkMEq8IpKUCoY/hGgI
ymqkDYYXcCjDZOANURSjCNGFQUTsl4GXVMxKk62YU4fXQpaIlygHQxBRH8/zwvyaIAYe+HLgnPN8nue9
HA3nvDTq63oW/jm13XOwvPTB3DYFY5MH+bXfcN8ygfTSMSSXfESicQDxBqdYHwH29g9w2tnZ3UcguIvN
rR3417exuBJE5N1n/wfwLgXEOc38Bc6xNRHb+/y4nm49G0Bnit2zf9H6bkliE/jKuYxrd6oVgDWfjB+K
TWeKMyrGEVfowITvD9re/9ABVQrAhh0HHK+ZselMMaN/mvwtDb+aVqkA7HYIwIj3ysfluPTorJnP6Ezx
oHsD1s5ZXEktUwCOioB5f1CEPR9+wTG6iuiserTo8dkwng7HT/R+XUPF8xlcTjErAOdMcW6NW8STiwG8
7vej8oUPN/PsEv3t8Ao0TZP3T1u8uJRkUgAuSYHtO97oLxmXd5t9Ho8aPTK+GzntqNfrLm2fFoihwYOI
xGIF4KjoGBLzY1OrF9k6OOFxnwDC4wxIMX1G0pMhgVyMNyoA13PAtS7OrJk1PrC69LUdQWxuF6IybHrX
LRI7JrtZdoDAo1XmbjMyD+tjSXxGcXRmnYg5ttD9QuxDhN0uUgDOmbvNTpPOJaGAo2K36cyaGZvOFIfd
KlSA8/zRh9ABIDUG+1JpAAAAAElFTkSuQmCC
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAACH
DwAAjA8AAP1SAACBQAAAfXkAAOmLAAA85QAAGcxzPIV3AAAKOWlDQ1BQaG90b3Nob3AgSUNDIHByb2Zp
bGUAAEjHnZZ3VFTXFofPvXd6oc0wAlKG3rvAANJ7k15FYZgZYCgDDjM0sSGiAhFFRJoiSFDEgNFQJFZE
sRAUVLAHJAgoMRhFVCxvRtaLrqy89/Ly++Osb+2z97n77L3PWhcAkqcvl5cGSwGQyhPwgzyc6RGRUXTs
AIABHmCAKQBMVka6X7B7CBDJy82FniFyAl8EAfB6WLwCcNPQM4BOB/+fpFnpfIHomAARm7M5GSwRF4g4
JUuQLrbPipgalyxmGCVmvihBEcuJOWGRDT77LLKjmNmpPLaIxTmns1PZYu4V8bZMIUfEiK+ICzO5nCwR
3xKxRoowlSviN+LYVA4zAwAUSWwXcFiJIjYRMYkfEuQi4uUA4EgJX3HcVyzgZAvEl3JJS8/hcxMSBXQd
li7d1NqaQffkZKVwBALDACYrmcln013SUtOZvBwAFu/8WTLi2tJFRbY0tba0NDQzMv2qUP91829K3NtF
ehn4uWcQrf+L7a/80hoAYMyJarPziy2uCoDOLQDI3fti0zgAgKSobx3Xv7oPTTwviQJBuo2xcVZWlhGX
wzISF/QP/U+Hv6GvvmckPu6P8tBdOfFMYYqALq4bKy0lTcinZ6QzWRy64Z+H+B8H/nUeBkGceA6fwxNF
hImmjMtLELWbx+YKuGk8Opf3n5r4D8P+pMW5FonS+BFQY4yA1HUqQH7tBygKESDR+8Vd/6NvvvgwIH55
4SqTi3P/7zf9Z8Gl4iWDm/A5ziUohM4S8jMX98TPEqABAUgCKpAHykAd6ABDYAasgC1wBG7AG/iDEBAJ
VgMWSASpgA+yQB7YBApBMdgJ9oBqUAcaQTNoBcdBJzgFzoNL4Bq4AW6D+2AUTIBnYBa8BgsQBGEhMkSB
5CEVSBPSh8wgBmQPuUG+UBAUCcVCCRAPEkJ50GaoGCqDqqF6qBn6HjoJnYeuQIPQXWgMmoZ+h97BCEyC
qbASrAUbwwzYCfaBQ+BVcAK8Bs6FC+AdcCXcAB+FO+Dz8DX4NjwKP4PnEIAQERqiihgiDMQF8UeikHiE
j6xHipAKpAFpRbqRPuQmMorMIG9RGBQFRUcZomxRnqhQFAu1BrUeVYKqRh1GdaB6UTdRY6hZ1Ec0Ga2I
1kfboL3QEegEdBa6EF2BbkK3oy+ib6Mn0K8xGAwNo42xwnhiIjFJmLWYEsw+TBvmHGYQM46Zw2Kx8lh9
rB3WH8vECrCF2CrsUexZ7BB2AvsGR8Sp4Mxw7rgoHA+Xj6vAHcGdwQ3hJnELeCm8Jt4G749n43PwpfhG
fDf+On4Cv0CQJmgT7AghhCTCJkIloZVwkfCA8JJIJKoRrYmBRC5xI7GSeIx4mThGfEuSIemRXEjRJCFp
B+kQ6RzpLuklmUzWIjuSo8gC8g5yM/kC+RH5jQRFwkjCS4ItsUGiRqJDYkjiuSReUlPSSXK1ZK5kheQJ
yeuSM1J4KS0pFymm1HqpGqmTUiNSc9IUaVNpf+lU6RLpI9JXpKdksDJaMm4ybJkCmYMyF2TGKQhFneJC
YVE2UxopFykTVAxVm+pFTaIWU7+jDlBnZWVkl8mGyWbL1sielh2lITQtmhcthVZKO04bpr1borTEaQln
yfYlrUuGlszLLZVzlOPIFcm1yd2WeydPl3eTT5bfJd8p/1ABpaCnEKiQpbBf4aLCzFLqUtulrKVFS48v
vacIK+opBimuVTyo2K84p6Ss5KGUrlSldEFpRpmm7KicpFyufEZ5WoWiYq/CVSlXOavylC5Ld6Kn0Cvp
vfRZVUVVT1Whar3qgOqCmrZaqFq+WpvaQ3WCOkM9Xr1cvUd9VkNFw08jT6NF454mXpOhmai5V7NPc15L
Wytca6tWp9aUtpy2l3audov2Ax2yjoPOGp0GnVu6GF2GbrLuPt0berCehV6iXo3edX1Y31Kfq79Pf9AA
bWBtwDNoMBgxJBk6GWYathiOGdGMfI3yjTqNnhtrGEcZ7zLuM/5oYmGSYtJoct9UxtTbNN+02/R3Mz0z
llmN2S1zsrm7+QbzLvMXy/SXcZbtX3bHgmLhZ7HVosfig6WVJd+y1XLaSsMq1qrWaoRBZQQwShiXrdHW
ztYbrE9Zv7WxtBHYHLf5zdbQNtn2iO3Ucu3lnOWNy8ft1OyYdvV2o/Z0+1j7A/ajDqoOTIcGh8eO6o5s
xybHSSddpySno07PnU2c+c7tzvMuNi7rXM65Iq4erkWuA24ybqFu1W6P3NXcE9xb3Gc9LDzWepzzRHv6
eO7yHPFS8mJ5NXvNelt5r/Pu9SH5BPtU+zz21fPl+3b7wX7efrv9HqzQXMFb0ekP/L38d/s/DNAOWBPw
YyAmMCCwJvBJkGlQXlBfMCU4JvhI8OsQ55DSkPuhOqHC0J4wybDosOaw+XDX8LLw0QjjiHUR1yIVIrmR
XVHYqLCopqi5lW4r96yciLaILoweXqW9KnvVldUKq1NWn46RjGHGnIhFx4bHHol9z/RnNjDn4rziauNm
WS6svaxnbEd2OXuaY8cp40zG28WXxU8l2CXsTphOdEisSJzhunCruS+SPJPqkuaT/ZMPJX9KCU9pS8Wl
xqae5Mnwknm9acpp2WmD6frphemja2zW7Fkzy/fhN2VAGasyugRU0c9Uv1BHuEU4lmmfWZP5Jiss60S2
dDYvuz9HL2d7zmSue+63a1FrWWt78lTzNuWNrXNaV78eWh+3vmeD+oaCDRMbPTYe3kTYlLzpp3yT/LL8
V5vDN3cXKBVsLBjf4rGlpVCikF84stV2a9021DbutoHt5turtn8sYhddLTYprih+X8IqufqN6TeV33za
Eb9joNSydP9OzE7ezuFdDrsOl0mX5ZaN7/bb3VFOLy8qf7UnZs+VimUVdXsJe4V7Ryt9K7uqNKp2Vr2v
Tqy+XeNc01arWLu9dn4fe9/Qfsf9rXVKdcV17w5wD9yp96jvaNBqqDiIOZh58EljWGPft4xvm5sUmoqb
PhziHRo9HHS4t9mqufmI4pHSFrhF2DJ9NProje9cv+tqNWytb6O1FR8Dx4THnn4f+/3wcZ/jPScYJ1p/
0Pyhtp3SXtQBdeR0zHYmdo52RXYNnvQ+2dNt293+o9GPh06pnqo5LXu69AzhTMGZT2dzz86dSz83cz7h
/HhPTM/9CxEXbvUG9g5c9Ll4+ZL7pQt9Tn1nL9tdPnXF5srJq4yrndcsr3X0W/S3/2TxU/uA5UDHdavr
XTesb3QPLh88M+QwdP6m681Lt7xuXbu94vbgcOjwnZHokdE77DtTd1PuvriXeW/h/sYH6AdFD6UeVjxS
fNTws+7PbaOWo6fHXMf6Hwc/vj/OGn/2S8Yv7ycKnpCfVEyqTDZPmU2dmnafvvF05dOJZ+nPFmYKf5X+
tfa5zvMffnP8rX82YnbiBf/Fp99LXsq/PPRq2aueuYC5R69TXy/MF72Rf3P4LeNt37vwd5MLWe+x7ys/
6H7o/ujz8cGn1E+f/gUDmPP8usTo0wAAAAlwSFlzAAALDAAACwwBP0AiyAAAAN5JREFUOE+FUwEOAyEI
8+k+7X7GoFBWmZdtISYgtS3csrXsFtvzf2Mv8/8d4Hkec2SLM+IHzJsjdwVAcxQrtl8OsDgBxPMGgKJG
SQkwMlI2zSCS+cuL0YCceHEDAcBbM6gTQOhDDpnBxHqVOsmgdYvmfCxk7q+JpDZN4yQOJhOAOtmslGna
MYE3AN2HeBEmyvhYZ44mL5rRXkijgoAZAA3nCVBzbzM5vuE8x8xmbGIzqE1LkNwHOO2RZmZOjQYTjoWF
g/YYr+qn2QBQSl2ofL8oC6Wb2hIOM8WD+bXOex/mMAFDkP1eQgAAAABJRU5ErkJggg==
</value>
</data>
<data name="toolStripButton6.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<data name="bitmapToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIISURBVDhPpZP7S1NxGMbPPxKaXVUkMEq8IpKUCoY/hGgI
ymqkDYYXcCjDZOANURSjCNGFQUTsl4GXVMxKk62YU4fXQpaIlygHQxBRH8/zwvyaIAYe+HLgnPN8nue9
HA3nvDTq63oW/jm13XOwvPTB3DYFY5MH+bXfcN8ygfTSMSSXfESicQDxBqdYHwH29g9w2tnZ3UcguIvN
rR3417exuBJE5N1n/wfwLgXEOc38Bc6xNRHb+/y4nm49G0Bnit2zf9H6bkliE/jKuYxrd6oVgDWfjB+K
TWeKMyrGEVfowITvD9re/9ABVQrAhh0HHK+ZselMMaN/mvwtDb+aVqkA7HYIwIj3ysfluPTorJnP6Ezx
oHsD1s5ZXEktUwCOioB5f1CEPR9+wTG6iuiserTo8dkwng7HT/R+XUPF8xlcTjErAOdMcW6NW8STiwG8
7vej8oUPN/PsEv3t8Ao0TZP3T1u8uJRkUgAuSYHtO97oLxmXd5t9Ho8aPTK+GzntqNfrLm2fFoihwYOI
xGIF4KjoGBLzY1OrF9k6OOFxnwDC4wxIMX1G0pMhgVyMNyoA13PAtS7OrJk1PrC69LUdQWxuF6IybHrX
LRI7JrtZdoDAo1XmbjMyD+tjSXxGcXRmnYg5ttD9QuxDhN0uUgDOmbvNTpPOJaGAo2K36cyaGZvOFIfd
KlSA8/zRh9ABIDUG+1JpAAAAAElFTkSuQmCC
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAACR0lE
QVQ4T6WTXUiTARSGdxkRRBdB0IUREV1EKRFEYYuQAklL8sKQfphUoJSUWJbLxAVZWqyBio5WajorM1PL
xExUlLQfbU5n0lygRerMP/qxOZ92vpjfCKLAi3P5Puc957xHA2gWUoo49147gWUqbSPrdjOXChrQm56S
lFVFvKEcXaqV2OQiohMt7Esw+6Ro5gGeWfhbff0BY9NzDI3N0f/JS6fLy7rd6f8HcNsdOI6EYD8cjK3V
roiLawdYu+vivwHSWcQM1THz/DQv96+ixeHlVvU71oQFAGTmP+37bdsPBf8WZ4fRFhVEXdcsBQ9srN6Z
pjqQhQUCAmcW29JZxA8fvaWyY5YcawdBOy6oANm2H9A3MMypDLNS7b1flJnFtnQWcVmrB2NhMytD9SpA
TiUA5+CYInQOjWPrH2V7RBzmijdo9x5VKr+yj6ImD9nmelZsS1UBcme/+OPIJIOfv/Gi201ZXQ/hMfFU
Peuktqnbd3QN+U/cXM6tYfmW8ypAQiKdh91TTE7PYHNOYKl6z916F3m+eSNjT1B4vxHjzWoFYrhRwbLN
51SAJOynx8vo5Ay9rimKHzu5XtJDpuU1WZY2Eg1WgrXRJOpNxKdcUyBLN6WoAInnyPh3XvW6KW/4MC9O
z2ki+Wo1CWklROkMCiT8wEm0kXEsCTmrAiTbDtcEpTVdZOS1oDfWk5xZ6RPeQZeUR8zxK0Qe1BO65xjr
t0YotXhjAEAeQ7It8ZSESUjkznIq2bYsTGYW29JZxIs2nFEdLOSdfwFwpvLxRKIY2AAAAABJRU5ErkJg
gg==
</value>
</data>
<data name="toolStripButton7.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<data name="propertiesToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIISURBVDhPpZP7S1NxGMbPPxKaXVUkMEq8IpKUCoY/hGgI
ymqkDYYXcCjDZOANURSjCNGFQUTsl4GXVMxKk62YU4fXQpaIlygHQxBRH8/zwvyaIAYe+HLgnPN8nue9
HA3nvDTq63oW/jm13XOwvPTB3DYFY5MH+bXfcN8ygfTSMSSXfESicQDxBqdYHwH29g9w2tnZ3UcguIvN
rR3417exuBJE5N1n/wfwLgXEOc38Bc6xNRHb+/y4nm49G0Bnit2zf9H6bkliE/jKuYxrd6oVgDWfjB+K
TWeKMyrGEVfowITvD9re/9ABVQrAhh0HHK+ZselMMaN/mvwtDb+aVqkA7HYIwIj3ysfluPTorJnP6Ezx
oHsD1s5ZXEktUwCOioB5f1CEPR9+wTG6iuiserTo8dkwng7HT/R+XUPF8xlcTjErAOdMcW6NW8STiwG8
7vej8oUPN/PsEv3t8Ao0TZP3T1u8uJRkUgAuSYHtO97oLxmXd5t9Ho8aPTK+GzntqNfrLm2fFoihwYOI
xGIF4KjoGBLzY1OrF9k6OOFxnwDC4wxIMX1G0pMhgVyMNyoA13PAtS7OrJk1PrC69LUdQWxuF6IybHrX
LRI7JrtZdoDAo1XmbjMyD+tjSXxGcXRmnYg5ttD9QuxDhN0uUgDOmbvNTpPOJaGAo2K36cyaGZvOFIfd
KlSA8/zRh9ABIDUG+1JpAAAAAElFTkSuQmCC
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAACCklE
QVQ4T6WT30tTUQDHz39QD0UQSpAPIkgPyR60AiUiyoGBL4qZjOyt0tZP9tBDk1AsXIhj93ILdd27DPPH
3VwrUrdK2ioJHAgVOdoPaQsarBg43L6ec+akuRsEPnw5D4fP5/vlXg4BQHaSf8LjjwdqaTA2cg+y1Ith
qxmi5Tas/SYWk+QRoPgmtNsLcPq7GYX8+XoTqaUL+KR2cAmDxeBgqeBv2NhWzwUFOBk4g5/zRxB3V8Es
38AtbzuIw/0RLMrMeyhTs2CzGdRtaOTn1dajvLkAR9VKLNvLcHmoExddzSDKzAfkcjkkEtEiOLxoQpdB
z+Er7ScQUg/DL5TD2bsfl5oPoKWnCZ3jehDZGeAC1hwL3uXNs55Jep7Gis/AJWxyTeVe1FXvhq5qH6oP
7nlw/NoxGByNIKPT77CezSEeD6Pn+jlEIiGk6X8N+F9zyfLYIZzUVUCwT0J36jy9yX83KjDq7zSADE8t
cGB7kpksFt76YDzbgMWVFLzBX0WCTcku8mjiTSm8lkUslcHnH2kK/+aw6k+UCJiESE+9XCApz2Gzu5Gk
sEVy4r6got82vRV5blVbIDyZ21rAZrPmL7w5P5s1KxQWXRFtgU15lV8ge2AbdXPY8pAuEIsXWJ6FtAVW
+SWSmXWssuZ4vnl+s5nNFl1hMLjP8U1bMGR/wS/+N9tf7o6eMpNtADko6xybtEXLAAAAAElFTkSuQmCC
</value>
</data>
<data name="toolStripButton2.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<data name="resizeToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIISURBVDhPpZP7S1NxGMbPPxKaXVUkMEq8IpKUCoY/hGgI
ymqkDYYXcCjDZOANURSjCNGFQUTsl4GXVMxKk62YU4fXQpaIlygHQxBRH8/zwvyaIAYe+HLgnPN8nue9
HA3nvDTq63oW/jm13XOwvPTB3DYFY5MH+bXfcN8ygfTSMSSXfESicQDxBqdYHwH29g9w2tnZ3UcguIvN
rR3417exuBJE5N1n/wfwLgXEOc38Bc6xNRHb+/y4nm49G0Bnit2zf9H6bkliE/jKuYxrd6oVgDWfjB+K
TWeKMyrGEVfowITvD9re/9ABVQrAhh0HHK+ZselMMaN/mvwtDb+aVqkA7HYIwIj3ysfluPTorJnP6Ezx
oHsD1s5ZXEktUwCOioB5f1CEPR9+wTG6iuiserTo8dkwng7HT/R+XUPF8xlcTjErAOdMcW6NW8STiwG8
7vej8oUPN/PsEv3t8Ao0TZP3T1u8uJRkUgAuSYHtO97oLxmXd5t9Ho8aPTK+GzntqNfrLm2fFoihwYOI
xGIF4KjoGBLzY1OrF9k6OOFxnwDC4wxIMX1G0pMhgVyMNyoA13PAtS7OrJk1PrC69LUdQWxuF6IybHrX
LRI7JrtZdoDAo1XmbjMyD+tjSXxGcXRmnYg5ttD9QuxDhN0uUgDOmbvNTpPOJaGAo2K36cyaGZvOFIfd
KlSA8/zRh9ABIDUG+1JpAAAAAElFTkSuQmCC
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAADLklE
QVQ4T3WS60/ScRjFf39CL3rR1ovurduWbbU2t7ZqdlkXt7Lrym6O1VoXcdYqQ54wKlGxABE1CzWF0nIm
lZcoTbyUNJFIzDJSJK+E0qy8wInvz+i2erazfd+cz3m+zw4nTS+FLOeZNim3Vp6UU5sqvf5MSZqnyjhV
pfKUvEx54kqp8rCkWHVQVKSJPHtbs+tUgSYiOicVAMfEqfR1dVFCGSqrX94cHQeN/aXhbyD3Zz91uf3U
9tFHTQ4fzVtH9BOQVdKcW2F6/eKkWA1zcxu6vUAQMmCzk/3AErLtDyFrrY035z16T3PXin8B5LfqZE6P
HyZzKw5FX+Yh4XtjwZKZGV3lNPIkhhojplON3Uc3S9/Q7LDfADKtKYklMsgTkwV7joixKHQr2Nq2fSET
5uQwqtsyjcot45R510ozV8f/2iAhsyolCNh9WIyFoRGYHbIGfYN+SVd7Nznzk8ll0FLzKxdZO3xkaOjG
GYUxcIIfRxSlPU4N/rn1fS8JJVlU1WCT3npggVLfAIWuHjJtNRIyjIhTPEKM7D6OSop4RcXpwZ2Wl11l
gHanmze/c36ioc8jyRlFjSzljxl2daI9Pwuv1Cnw9PRjZeQ1cCcSS68Fza6+IXL2fCG7w0ssmc3o2IR8
gbc1PQU9NUp48sNRcUyAkPBL4AIlUbLk3gEvS6YXrW6p0dx9UZ5n4gHjzBmYAAPPYwRwazeiMXYWqjcs
wLSVInAHRYWq0TEf9Q+NUEsg+fr9t2nF1U71leyqn+u3vPuIl2298HZ2wnxkO5q2LYOtxoKpK86D23tW
r+7zfCVzywAVGT/QVV2LvNDo0Eo0j3mAtbUTiRnFOJ94Axp9LfIKK5Ctq0RDmw9TQuPAsW7bHYNUYLCQ
JL2GRAqjtMDYwV+8wzUAWeY9eIfHYW0fxNodxyGWZeOSPBvzl27C5OXnwG0T5irmr79wgdWTNYyVJFL8
kAeo8wyBA/rx2jGErBIH0nXPsWmPEHcM9YgURGPS0jMTZfiXGKDfM4Y0fVOgA/UgRQWECTpExaqxUyDF
wuUbJjb4H0AQfxtrDqiweLMUc8LEmLEqnv9zUMzM9B1/cM83lepxTAAAAABJRU5ErkJggg==
</value>
</data>
<data name="spawnpointsToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAABrUlE
QVQ4T6WTWyhDcRzHl8g1D/IkxZ4mjcgDB0U5ubbVbJLkkubJSt7w6M1eENHUENrktmzJ3HKEiSh7US5l
QiK5JUXpy/9f/9O2zhY59at//c/n87uc35EBkP0nAsL6Bi33E9CpeBINJElHthIkvBNKChh8YVPi1Cpn
Eo7ANSnJwQUMfnLEobVejZbaCnis8VRiyFSgXJ4QWOAPO5fXYJ2xo1HD48QcRSV5CfHSAn94fV0gL9Jn
eVWAtjgXRwPhrJ18Ngc6g2AwkzhXBJTmZ+GgN8xHwgRgPXtnZvDH5xde3j6x6BTAcxk47JFRCUnOBAWF
2WkQhC2xbH/49uEd59evGLfYoJAnEkGjKCCHyjqDDzw72YOpUSMmTF0w93VS2H32iLmlXSSlcuIgxT1Q
VTf7CAj87IjFgy2Gfk4Cu9x3sNhd0oIyXZMoID2TzPez0biyREKvK6bw6t4NxuYDCEo0ZFsBNjBStmci
Asb2Kmj4HAovbF5ieHpHugJeXUfhja19rGzsYai7DcemULj7Q1DEpWNkzgXTDzxo3ZYWFKlq6cVvw2eR
vP+uv56/AehVvkSccelEAAAAAElFTkSuQmCC
</value>
</data>
<metadata name="tt.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">

View File

@@ -0,0 +1,469 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using OpenRA;
using OpenRA.FileFormats;
using OpenRA.Traits;
using System.Drawing;
namespace OpenRA.Editor
{
public class LegacyMapImporter
{
// Mapping from ra overlay index to type string
static string[] raOverlayNames =
{
"sbag", "cycl", "brik", "fenc", "wood",
"gold01", "gold02", "gold03", "gold04",
"gem01", "gem02", "gem03", "gem04",
"v12", "v13", "v14", "v15", "v16", "v17", "v18",
"fpls", "wcrate", "scrate", "barb", "sbag",
};
static Dictionary<string, Pair<byte, byte>> overlayResourceMapping = new Dictionary<string, Pair<byte, byte>>()
{
// RA Gems, Gold
{ "gold01", new Pair<byte,byte>(1,0) },
{ "gold02", new Pair<byte,byte>(1,1) },
{ "gold03", new Pair<byte,byte>(1,2) },
{ "gold04", new Pair<byte,byte>(1,3) },
{ "gem01", new Pair<byte,byte>(2,0) },
{ "gem02", new Pair<byte,byte>(2,1) },
{ "gem03", new Pair<byte,byte>(2,2) },
{ "gem04", new Pair<byte,byte>(2,3) },
// cnc tiberium
{ "ti1", new Pair<byte,byte>(1,0) },
{ "ti2", new Pair<byte,byte>(1,1) },
{ "ti3", new Pair<byte,byte>(1,2) },
{ "ti4", new Pair<byte,byte>(1,3) },
{ "ti5", new Pair<byte,byte>(1,4) },
{ "ti6", new Pair<byte,byte>(1,5) },
{ "ti7", new Pair<byte,byte>(1,6) },
{ "ti8", new Pair<byte,byte>(1,7) },
{ "ti9", new Pair<byte,byte>(1,8) },
{ "ti10", new Pair<byte,byte>(1,9) },
{ "ti11", new Pair<byte,byte>(1,10) },
{ "ti12", new Pair<byte,byte>(1,11) },
};
static Dictionary<string, string> overlayActorMapping = new Dictionary<string, string>() {
// Fences
{"sbag","sbag"},
{"cycl","cycl"},
{"brik","brik"},
{"fenc","fenc"},
{"wood","wood"},
// Fields
{"v12","v12"},
{"v13","v13"},
{"v14","v14"},
{"v15","v15"},
{"v16","v16"},
{"v17","v17"},
{"v18","v18"},
// Crates
// {"wcrate","crate"},
// {"scrate","crate"},
};
static Dictionary<string,Pair<Color,Color>> namedColorMapping = new Dictionary<string, Pair<Color, Color>>()
{
{"gold",Pair.New(Color.FromArgb(246,214,121),Color.FromArgb(40,32,8))},
{"blue",Pair.New(Color.FromArgb(226,230,246),Color.FromArgb(8,20,52))},
{"red",Pair.New(Color.FromArgb(255,20,0),Color.FromArgb(56,0,0))},
{"neutral",Pair.New(Color.FromArgb(238,238,238),Color.FromArgb(44,28,24))},
{"orange",Pair.New(Color.FromArgb(255,230,149),Color.FromArgb(56,0,0))},
{"teal",Pair.New(Color.FromArgb(93,194,165),Color.FromArgb(0,32,32))},
{"salmon",Pair.New(Color.FromArgb(210,153,125),Color.FromArgb(56,0,0))},
{"green",Pair.New(Color.FromArgb(160,240,140),Color.FromArgb(20,20,20))},
{"white",Pair.New(Color.FromArgb(255,255,255),Color.FromArgb(75,75,75))},
{"black",Pair.New(Color.FromArgb(80,80,80),Color.FromArgb(5,5,5))},
};
int MapSize;
int ActorCount = 0;
Map Map = new Map();
List<string> Players = new List<string>();
LegacyMapImporter(string filename)
{
ConvertIniMap(filename);
}
public static Map Import(string filename)
{
var converter = new LegacyMapImporter(filename);
return converter.Map;
}
enum IniMapFormat { RedAlert = 3, /* otherwise, cnc (2 variants exist, we don't care to differentiate) */ };
public void ConvertIniMap(string iniFile)
{
var file = new IniFile(FileSystem.Open(iniFile));
var basic = file.GetSection("Basic");
var map = file.GetSection("Map");
var legacyMapFormat = (IniMapFormat)int.Parse(basic.GetValue("NewINIFormat", "0"));
var XOffset = int.Parse(map.GetValue("X", "0"));
var YOffset = int.Parse(map.GetValue("Y", "0"));
var Width = int.Parse(map.GetValue("Width", "0"));
var Height = int.Parse(map.GetValue("Height", "0"));
MapSize = (legacyMapFormat == IniMapFormat.RedAlert) ? 128 : 64;
Map.Title = basic.GetValue("Name", "(null)");
Map.Author = "Westwood Studios";
Map.Tileset = Truncate(map.GetValue("Theater", "TEMPERAT"), 8);
Map.MapSize.X = MapSize;
Map.MapSize.Y = MapSize;
Map.TopLeft = new int2(XOffset, YOffset);
Map.BottomRight = new int2(XOffset + Width, YOffset + Height);
Map.Selectable = true;
if (legacyMapFormat == IniMapFormat.RedAlert)
{
UnpackRATileData(ReadPackedSection(file.GetSection("MapPack")));
UnpackRAOverlayData(ReadPackedSection(file.GetSection("OverlayPack")));
ReadRATrees(file);
}
else // CNC
{
UnpackCncTileData(FileSystem.Open(iniFile.Substring(0, iniFile.Length - 4) + ".bin"));
ReadCncOverlay(file);
ReadCncTrees(file);
}
LoadActors(file, "STRUCTURES");
LoadActors(file, "UNITS");
LoadActors(file, "INFANTRY");
LoadSmudges(file, "SMUDGE");
foreach (var p in Players)
LoadPlayer(file, p, (legacyMapFormat == IniMapFormat.RedAlert));
var wp = file.GetSection("Waypoints")
.Where(kv => int.Parse(kv.Value) > 0)
.Select(kv => Pair.New(int.Parse(kv.Key),
LocationFromMapOffset(int.Parse(kv.Value), MapSize)))
.ToArray();
Map.PlayerCount = wp.Count();
foreach (var kv in wp)
Map.Waypoints.Add("spawn" + kv.First, kv.Second);
}
static int2 LocationFromMapOffset(int offset, int mapSize)
{
return new int2(offset % mapSize, offset / mapSize);
}
static MemoryStream ReadPackedSection(IniSection mapPackSection)
{
StringBuilder sb = new StringBuilder();
for (int i = 1; ; i++)
{
string line = mapPackSection.GetValue(i.ToString(), null);
if (line == null)
break;
sb.Append(line.Trim());
}
byte[] data = Convert.FromBase64String(sb.ToString());
List<byte[]> chunks = new List<byte[]>();
BinaryReader reader = new BinaryReader(new MemoryStream(data));
try
{
while (true)
{
uint length = reader.ReadUInt32() & 0xdfffffff;
byte[] dest = new byte[8192];
byte[] src = reader.ReadBytes((int)length);
/*int actualLength =*/
Format80.DecodeInto(src, dest);
chunks.Add(dest);
}
}
catch (EndOfStreamException) { }
MemoryStream ms = new MemoryStream();
foreach (byte[] chunk in chunks)
ms.Write(chunk, 0, chunk.Length);
ms.Position = 0;
return ms;
}
static byte ReadByte(Stream s)
{
int ret = s.ReadByte();
if (ret == -1)
throw new NotImplementedException();
return (byte)ret;
}
static ushort ReadWord(Stream s)
{
ushort ret = ReadByte(s);
ret |= (ushort)(ReadByte(s) << 8);
return ret;
}
void UnpackRATileData(MemoryStream ms)
{
Map.MapTiles = new TileReference<ushort, byte>[MapSize, MapSize];
for (int i = 0; i < MapSize; i++)
for (int j = 0; j < MapSize; j++)
Map.MapTiles[i, j] = new TileReference<ushort, byte>();
for (int j = 0; j < MapSize; j++)
for (int i = 0; i < MapSize; i++)
Map.MapTiles[i, j].type = ReadWord(ms);
for (int j = 0; j < MapSize; j++)
for (int i = 0; i < MapSize; i++)
{
Map.MapTiles[i, j].index = ReadByte(ms);
if (Map.MapTiles[i, j].type == 0xff || Map.MapTiles[i, j].type == 0xffff)
Map.MapTiles[i, j].index = byte.MaxValue;
}
}
void UnpackRAOverlayData(MemoryStream ms)
{
Map.MapResources = new TileReference<byte, byte>[MapSize, MapSize];
for (int j = 0; j < MapSize; j++)
for (int i = 0; i < MapSize; i++)
{
byte o = ReadByte(ms);
var res = Pair.New((byte)0, (byte)0);
if (o != 255 && overlayResourceMapping.ContainsKey(raOverlayNames[o]))
res = overlayResourceMapping[raOverlayNames[o]];
Map.MapResources[i, j] = new TileReference<byte, byte>(res.First, res.Second);
if (o != 255 && overlayActorMapping.ContainsKey(raOverlayNames[o]))
Map.Actors.Add("Actor" + ActorCount++,
new ActorReference(overlayActorMapping[raOverlayNames[o]])
{
new LocationInit( new int2(i, j) ),
new OwnerInit( "Neutral" )
});
}
}
void ReadRATrees(IniFile file)
{
IniSection terrain = file.GetSection("TERRAIN", true);
if (terrain == null)
return;
foreach (KeyValuePair<string, string> kv in terrain)
{
var loc = int.Parse(kv.Key);
Map.Actors.Add("Actor" + ActorCount++,
new ActorReference(kv.Value.ToLowerInvariant())
{
new LocationInit(new int2(loc % MapSize, loc / MapSize)),
new OwnerInit("Neutral")
});
}
}
void UnpackCncTileData(Stream ms)
{
Map.MapTiles = new TileReference<ushort, byte>[MapSize, MapSize];
for (int i = 0; i < MapSize; i++)
for (int j = 0; j < MapSize; j++)
Map.MapTiles[i, j] = new TileReference<ushort, byte>();
for (int j = 0; j < MapSize; j++)
for (int i = 0; i < MapSize; i++)
{
Map.MapTiles[i, j].type = ReadByte(ms);
Map.MapTiles[i, j].index = ReadByte(ms);
if (Map.MapTiles[i, j].type == 0xff)
Map.MapTiles[i, j].index = byte.MaxValue;
}
}
void ReadCncOverlay(IniFile file)
{
IniSection overlay = file.GetSection("OVERLAY", true);
if (overlay == null)
return;
Map.MapResources = new TileReference<byte, byte>[MapSize, MapSize];
foreach (KeyValuePair<string, string> kv in overlay)
{
var loc = int.Parse(kv.Key);
int2 cell = new int2(loc % MapSize, loc / MapSize);
var res = Pair.New((byte)0, (byte)0);
if (overlayResourceMapping.ContainsKey(kv.Value.ToLower()))
res = overlayResourceMapping[kv.Value.ToLower()];
Map.MapResources[cell.X, cell.Y] = new TileReference<byte, byte>(res.First, res.Second);
if (overlayActorMapping.ContainsKey(kv.Value.ToLower()))
Map.Actors.Add("Actor" + ActorCount++,
new ActorReference(overlayActorMapping[kv.Value.ToLower()])
{
new LocationInit(cell),
new OwnerInit("Neutral")
});
}
}
void ReadCncTrees(IniFile file)
{
IniSection terrain = file.GetSection("TERRAIN", true);
if (terrain == null)
return;
foreach (KeyValuePair<string, string> kv in terrain)
{
var loc = int.Parse(kv.Key);
Map.Actors.Add("Actor" + ActorCount++,
new ActorReference(kv.Value.Split(',')[0].ToLowerInvariant())
{
new LocationInit(new int2(loc % MapSize, loc / MapSize)),
new OwnerInit("Neutral")
});
}
}
void LoadActors(IniFile file, string section)
{
foreach (var s in file.GetSection(section, true))
{
//Structures: num=owner,type,health,location,turret-facing,trigger
//Units: num=owner,type,health,location,facing,action,trigger
//Infantry: num=owner,type,health,location,subcell,action,facing,trigger
var parts = s.Value.Split(',');
var loc = int.Parse(parts[3]);
if (parts[0] == "")
parts[0] = "Neutral";
if (!Players.Contains(parts[0]))
Players.Add(parts[0]);
var stance = ActorStance.Stance.None;
switch(parts[5])
{
case "Area Guard":
case "Guard":
stance = ActorStance.Stance.Guard;
break;
case "Defend Base":
stance = ActorStance.Stance.Defend;
break;
case "Hunt":
case "Rampage":
case "Attack Base":
case "Attack Units":
case "Attack Civil.":
case "Attack Tarcom":
stance = ActorStance.Stance.Hunt;
break;
case "Retreat":
case "Return":
stance = ActorStance.Stance.Retreat;
break;
// do we care about `Harvest' and `Sticky'?
}
var actor = new ActorReference(parts[1].ToLowerInvariant())
{
new LocationInit(new int2(loc % MapSize, loc / MapSize)),
new OwnerInit(parts[0]),
new HealthInit(float.Parse(parts[2])/256),
new FacingInit((section == "INFANTRY") ? int.Parse(parts[6]) : int.Parse(parts[4])),
new ActorStanceInit(stance),
};
if (section == "INFANTRY")
actor.Add(new SubcellInit(int.Parse(parts[4])));
Map.Actors.Add("Actor" + ActorCount++,actor);
}
}
void LoadSmudges(IniFile file, string section)
{
foreach (var s in file.GetSection(section, true))
{
//loc=type,loc,depth
var parts = s.Value.Split(',');
var loc = int.Parse(parts[1]);
Map.Smudges.Add(new SmudgeReference(parts[0].ToLowerInvariant(), new int2(loc % MapSize, loc / MapSize), int.Parse(parts[2])));
}
}
void LoadPlayer(IniFile file, string section, bool isRA)
{
var c = (section == "BadGuy") ? "red" :
(isRA) ? "blue" : "gold";
var color = namedColorMapping[c];
var pr = new PlayerReference
{
Name = section,
OwnsWorld = (section == "Neutral"),
NonCombatant = (section == "Neutral"),
Race = (isRA) ? ((section == "BadGuy") ? "soviet" : "allies") : ((section == "BadGuy") ? "nod" : "gdi"),
Color = color.First,
Color2 = color.Second,
};
var Neutral = new List<string>(){"Neutral"};
foreach (var s in file.GetSection(section, true))
{
Console.WriteLine(s.Key);
switch(s.Key)
{
case "Credits":
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();
break;
}
}
Map.Players.Add(section, pr);
}
static string Truncate(string s, int maxLength)
{
return s.Length <= maxLength ? s : s.Substring(0, maxLength);
}
}
}

View File

@@ -1,10 +1,13 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System.Windows.Forms;
namespace OpenRA.Editor

View File

@@ -23,6 +23,7 @@
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -31,6 +32,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@@ -44,7 +46,6 @@
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
@@ -57,6 +58,7 @@
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="LegacyMapImporter.cs" />
<Compile Include="NewMapDialog.cs">
<SubType>Form</SubType>
</Compile>
@@ -121,7 +123,7 @@
<Name>OpenRA.Game</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<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.
<Target Name="BeforeBuild">

View File

@@ -1,4 +1,14 @@
using System;
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System;
using System.Globalization;
using System.Windows.Forms;
@@ -12,6 +22,7 @@ namespace OpenRA.Editor
Application.CurrentCulture = CultureInfo.InvariantCulture;
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1(args));
}
}

View File

@@ -1,4 +1,14 @@
using System.Windows.Forms;
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System.Windows.Forms;
namespace OpenRA.Editor
{

View File

@@ -1,10 +1,13 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System.Windows.Forms;
namespace OpenRA.Editor

View File

@@ -1,11 +1,20 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Windows.Forms;
using OpenRA.FileFormats;
using OpenRA.Thirdparty;
using System.Collections;
namespace OpenRA.Editor
{
@@ -22,6 +31,7 @@ namespace OpenRA.Editor
WaypointTemplate Waypoint;
public bool IsPanning;
public event Action AfterChange = () => { };
Dictionary<string, ActorTemplate> ActorTemplates = new Dictionary<string, ActorTemplate>();
Dictionary<int, ResourceTemplate> ResourceTemplates = new Dictionary<int, ResourceTemplate>();
@@ -120,6 +130,8 @@ namespace OpenRA.Editor
/* todo: optimize */
foreach (var ch in Chunks.Values) ch.Dispose();
Chunks.Clear();
AfterChange();
}
int2 FindEdge(int2 p, int2 d, TileReference<ushort, byte> replace)
@@ -136,8 +148,8 @@ namespace OpenRA.Editor
void DrawWithBrush()
{
// change the bits in the map
var tile = TileSet.tiles[Brush.N];
var template = TileSet.walk[Brush.N];
var tile = TileSet.Tiles[Brush.N];
var template = TileSet.Templates[Brush.N];
var pos = GetBrushLocation();
if (ModifierKeys == Keys.Shift)
@@ -154,7 +166,12 @@ namespace OpenRA.Editor
var z = u + v * template.Size.X;
if (tile.TileBitmapBytes[z] != null)
Map.MapTiles[u + pos.X, v + pos.Y] =
new TileReference<ushort, byte> { type = Brush.N, image = (byte)z, index = (byte)z };
new TileReference<ushort, byte>
{
type = Brush.N,
index = template.PickAny ? byte.MaxValue : (byte)z,
image = template.PickAny ? (byte)((u + pos.X) % 4 + ((v + pos.Y) % 4)*4) : (byte)z,
};
var ch = new int2((pos.X + u) / ChunkSize, (pos.Y + v) / ChunkSize);
if (Chunks.ContainsKey(ch))
@@ -164,6 +181,8 @@ namespace OpenRA.Editor
}
}
}
AfterChange();
}
int wpid;
@@ -183,6 +202,8 @@ namespace OpenRA.Editor
if (k.Key != null) Map.Waypoints.Remove(k.Key);
Map.Waypoints.Add(NextWpid(), GetBrushLocation());
AfterChange();
}
void Erase()
@@ -192,7 +213,7 @@ namespace OpenRA.Editor
Resource = null;
Waypoint = null;
var key = Map.Actors.FirstOrDefault(a => a.Value.Location == GetBrushLocation());
var key = Map.Actors.FirstOrDefault(a => a.Value.Location() == GetBrushLocation());
if (key.Key != null) Map.Actors.Remove(key.Key);
if (Map.MapResources[GetBrushLocation().X, GetBrushLocation().Y].type != 0)
@@ -208,6 +229,8 @@ namespace OpenRA.Editor
var k = Map.Waypoints.FirstOrDefault(a => a.Value == GetBrushLocation());
if (k.Key != null) Map.Waypoints.Remove(k.Key);
AfterChange();
}
void Draw()
@@ -216,6 +239,8 @@ namespace OpenRA.Editor
if (Actor != null) DrawWithActor();
if (Resource != null) DrawWithResource();
if (Waypoint != null) DrawWithWaypoint();
AfterChange();
}
int id;
@@ -230,15 +255,21 @@ namespace OpenRA.Editor
void DrawWithActor()
{
if (Map.Actors.Any(a => a.Value.Location == GetBrushLocation()))
if (Map.Actors.Any(a => a.Value.Location() == GetBrushLocation()))
return;
var owner = "Neutral";
var id = NextActorName();
Map.Actors[id] = new ActorReference(id,Actor.Info.Name.ToLowerInvariant(), GetBrushLocation(), owner);
Map.Actors[id] = new ActorReference(Actor.Info.Name.ToLowerInvariant())
{
new LocationInit( GetBrushLocation() ),
new OwnerInit( owner)
};
AfterChange();
}
Random r = new Random();
System.Random r = new System.Random();
void DrawWithResource()
{
Map.MapResources[GetBrushLocation().X, GetBrushLocation().Y]
@@ -255,6 +286,8 @@ namespace OpenRA.Editor
Chunks[ch].Dispose();
Chunks.Remove(ch);
}
AfterChange();
}
protected override void OnMouseDown(MouseEventArgs e)
@@ -274,10 +307,11 @@ namespace OpenRA.Editor
Bitmap RenderChunk(int u, int v)
{
var bitmap = new Bitmap(ChunkSize * 24, ChunkSize * 24);
bitmap.SetPixel(0, 0, Color.Green);
var data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
var data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
unsafe
@@ -289,12 +323,12 @@ namespace OpenRA.Editor
for (var j = 0; j < ChunkSize; j++)
{
var tr = Map.MapTiles[u * ChunkSize + i, v * ChunkSize + j];
var tile = TileSet.tiles[tr.type];
var index = (tr.index < tile.TileBitmapBytes.Count) ? tr.index : (byte)0;
var tile = TileSet.Tiles[tr.type];
var index = (tr.image < tile.TileBitmapBytes.Count) ? tr.image : (byte)0;
var rawImage = tile.TileBitmapBytes[index];
for (var x = 0; x < 24; x++)
for (var y = 0; y < 24; y++)
p[ (j * 24 + y) * stride + i * 24 + x ] = Palette.GetColor(rawImage[x + 24 * y]).ToArgb();
p[(j * 24 + y) * stride + i * 24 + x] = Palette.GetColor(rawImage[x + 24 * y]).ToArgb();
if (Map.MapResources[u * ChunkSize + i, v * ChunkSize + j].type != 0)
{
@@ -365,7 +399,7 @@ namespace OpenRA.Editor
new Rectangle(Map.XOffset * 24 + Offset.X, Map.YOffset * 24 + Offset.Y, Map.Width * 24, Map.Height * 24));
foreach (var ar in Map.Actors)
DrawActor(e.Graphics, ar.Value.Location, ActorTemplates[ar.Value.Type]);
DrawActor(e.Graphics, ar.Value.Location(), ActorTemplates[ar.Value.Type]);
foreach (var wp in Map.Waypoints)
e.Graphics.DrawRectangle(Pens.LimeGreen, new Rectangle(
@@ -392,10 +426,18 @@ namespace OpenRA.Editor
if (Brush == null && Actor == null && Resource == null)
{
var x = Map.Actors.FirstOrDefault(a => a.Value.Location == GetBrushLocation());
var x = Map.Actors.FirstOrDefault(a => a.Value.Location() == GetBrushLocation());
if (x.Key != null)
DrawActorBorder(e.Graphics, x.Value.Location, ActorTemplates[x.Value.Type]);
DrawActorBorder(e.Graphics, x.Value.Location(), ActorTemplates[x.Value.Type]);
}
}
}
static class ActorReferenceExts
{
public static int2 Location(this ActorReference ar)
{
return ar.InitDict.Get<LocationInit>().value;
}
}
}

View File

@@ -0,0 +1,45 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Packaging;
using System.Linq;
namespace OpenRA.FileFormats
{
public class CompressedPackage : IFolder
{
readonly uint[] hashes;
readonly Stream s;
readonly ZipPackage pkg;
public CompressedPackage(string filename)
{
s = FileSystem.Open(filename);
pkg = (ZipPackage)ZipPackage.Open(s, FileMode.Open);
hashes = pkg.GetParts()
.Select(p => PackageEntry.HashFilename(p.Uri.LocalPath)).ToArray();
}
public Stream GetContent(string filename)
{
return pkg.GetPart(new Uri(filename)).GetStream(FileMode.Open);
}
public IEnumerable<uint> AllFileHashes() { return hashes; }
public bool Exists(string filename)
{
return hashes.Contains(PackageEntry.HashFilename(filename));
}
}
}

View File

@@ -1,97 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System;
using System.Collections.Generic;
namespace OpenRA.FileFormats
{
public static class ConnectedComponents
{
static readonly int2[] Neighbors
= { new int2(-1, -1), new int2(0, -1), new int2(1, -1), new int2(-1, 0) };
public static int[,] Extract(Map m, Func<int, int, int> f)
{
var result = new int[m.MapSize.X, m.MapSize.Y];
var types = new int[m.MapSize.X, m.MapSize.Y];
var d = new Dictionary<int, Node>();
var n = 1;
for( var j = m.YOffset; j < m.YOffset + m.Height; j++ )
for (var i = m.XOffset; i < m.XOffset + m.Width; i++)
{
types[i, j] = f(i, j);
var k = n;
foreach (var a in Neighbors)
if (types[i + a.X, j + a.Y] == types[i, j])
k = (k == n)
? result[i + a.X, j + a.Y]
: Union( d, k, result[i+a.X, j+a.Y] );
result[i,j] = k;
if (k == n) MakeSet(d, n++);
}
for (var j = m.YOffset; j < m.YOffset + m.Height; j++)
for (var i = m.XOffset; i < m.XOffset + m.Width; i++)
result[i, j] = Find(d, result[i, j]);
return result;
}
// disjoint-set forest stuff
class Node { public int a, b; public Node(int a, int b) { this.a = a; this.b = b; } }
static int MakeSet(Dictionary<int, Node> d, int x)
{
d[x] = new Node(x, 0);
return x;
}
static int Union(Dictionary<int, Node> d, int x, int y)
{
var xr = Find(d, x);
var yr = Find(d, y);
var xa = d[xr].b;
var ya = d[yr].b;
if (xa > ya) d[yr].a = xr;
else if (xa < ya) d[xr].a = yr;
else if (xr != yr)
{
d[yr].a = xr;
++d[xr].b;
}
return xr;
}
static int Find(Dictionary<int, Node> d, int x)
{
if (d[x].a == x) return x;
return d[x].a = Find(d, d[x].a);
}
}
}

View File

@@ -1,45 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System;
namespace OpenRA
{
public class DisposableAction : IDisposable
{
public DisposableAction(Action a) { this.a = a; }
Action a;
bool disposed;
public void Dispose()
{
if (disposed) return;
disposed = true;
a();
GC.SuppressFinalize(this);
}
~DisposableAction()
{
Dispose();
}
}
}

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
@@ -61,6 +51,11 @@ namespace OpenRA
}
}
public static void Write(this Stream s, byte[] data)
{
s.Write(data, 0, data.Length);
}
public static IEnumerable<string> ReadAllLines(this Stream s)
{
using (var sr = new StreamReader(s))
@@ -73,5 +68,10 @@ namespace OpenRA
yield return line;
}
}
public static bool HasAttribute<T>(this MemberInfo mi)
{
return mi.GetCustomAttributes(typeof(T), true).Length != 0;
}
}
}

View File

@@ -1,25 +1,16 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection;
@@ -27,17 +18,44 @@ namespace OpenRA.FileFormats
{
public static class FieldLoader
{
public static void Load(object self, IniSection ini)
public static Func<string,Type,string,object> InvalidValueAction = (s,t,f) =>
{
foreach (var x in ini)
LoadField(self, x.Key, x.Value);
throw new InvalidOperationException("FieldLoader: Cannot parse `{0}` into `{1}.{2}` ".F(s,f,t) );
};
public static Action<string,Type> UnknownFieldAction = (s,f) =>
{
throw new NotImplementedException( "FieldLoader: Missing field `{0}` on `{1}`".F( s, f.Name ) );
};
public static void Load( object self, MiniYaml my )
{
var loadDict = typeLoadInfo[ self.GetType() ];
foreach( var kv in loadDict )
{
object val;
if( kv.Value != null )
val = kv.Value( kv.Key.Name, kv.Key.FieldType, my );
else if( !TryGetValueFromYaml( kv.Key.Name, kv.Key.FieldType, my, out val ) )
continue;
kv.Key.SetValue( self, val );
}
}
public static void Load(object self, MiniYaml my)
static bool TryGetValueFromYaml( string fieldName, Type fieldType, MiniYaml yaml, out object ret )
{
foreach (var x in my.Nodes)
if (!x.Key.StartsWith("-"))
LoadField( self, x.Key, x.Value.Value );
ret = null;
var n = yaml.Nodes.Where( x=>x.Key == fieldName ).ToList();
if( n.Count == 0 )
return false;
if( n.Count == 1 && n[ 0 ].Value.Nodes.Count == 0 )
{
ret = GetValue( fieldName, fieldType, n[ 0 ].Value.Value );
return true;
}
throw new InvalidOperationException( "TryGetValueFromYaml: unable to load field {0} (of type {1})".F( fieldName, fieldType ) );
}
public static T Load<T>(MiniYaml y) where T : new()
@@ -46,41 +64,68 @@ namespace OpenRA.FileFormats
Load(t, y);
return t;
}
public static void LoadFields( object self, Dictionary<string,MiniYaml> my, IEnumerable<string> fields )
{
foreach (var field in fields)
{
if (!my.ContainsKey(field)) continue;
FieldLoader.LoadField(self,field,my[field].Value);
}
}
public static void LoadField( object self, string key, string value )
{
var field = self.GetType().GetField( key.Trim() );
if( field == null )
throw new NotImplementedException( "Missing field `{0}` on `{1}`".F( key.Trim(), self.GetType().Name ) );
field.SetValue( self, GetValue( field.FieldType, value ) );
UnknownFieldAction( key.Trim(), self.GetType() );
else if( field.HasAttribute<FieldFromYamlKeyAttribute>() )
return;
else
field.SetValue( self, GetValue( field.Name, field.FieldType, value ) );
}
public static object GetValue( Type fieldType, string x )
public static object GetValue( string field, Type fieldType, string x )
{
if (x != null) x = x.Trim();
if( fieldType == typeof( int ) )
return int.Parse( x );
{
int res;
if (int.TryParse(x,out res))
return res;
return InvalidValueAction(x,fieldType, field);
}
else if( fieldType == typeof( ushort ) )
{
ushort res;
if (ushort.TryParse(x,out res))
return res;
return InvalidValueAction(x,fieldType, field);
}
else if (fieldType == typeof(float))
return float.Parse(x.Replace("%","")) * (x.Contains( '%' ) ? 0.01f : 1f);
{
float res;
if (float.TryParse(x.Replace("%",""), out res))
return res * (x.Contains( '%' ) ? 0.01f : 1f);
return InvalidValueAction(x,fieldType, field);
}
else if (fieldType == typeof(string))
return x;
else if (fieldType == typeof(Color))
{
var parts = x.Split(',');
if (parts.Length == 3)
return Color.FromArgb(int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2]));
if (parts.Length == 4)
return Color.FromArgb(int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2]), int.Parse(parts[3]));
return InvalidValueAction(x,fieldType, field);
}
else if (fieldType.IsEnum)
{
if (!Enum.GetNames(fieldType).Select(a => a.ToLower()).Contains(x.ToLower()))
return InvalidValueAction(x,fieldType, field);
return Enum.Parse(fieldType, x, true);
}
else if (fieldType == typeof(bool))
return ParseYesNo(x);
return ParseYesNo(x, fieldType, field);
else if (fieldType.IsArray)
{
@@ -91,7 +136,7 @@ namespace OpenRA.FileFormats
var ret = Array.CreateInstance(fieldType.GetElementType(), parts.Length);
for (int i = 0; i < parts.Length; i++)
ret.SetValue(GetValue(fieldType.GetElementType(), parts[i].Trim()), i);
ret.SetValue(GetValue(field, fieldType.GetElementType(), parts[i].Trim()), i);
return ret;
}
else if (fieldType == typeof(int2))
@@ -99,18 +144,80 @@ namespace OpenRA.FileFormats
var parts = x.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
return new int2(int.Parse(parts[0]), int.Parse(parts[1]));
}
else
throw new InvalidOperationException("FieldLoader: don't know how to load field of type " + fieldType.ToString());
else if (fieldType == typeof(float2))
{
var parts = x.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
float xx = 0;
float yy = 0;
float res;
if (float.TryParse(parts[0].Replace("%",""), out res))
xx = res * (parts[0].Contains( '%' ) ? 0.01f : 1f);
if (float.TryParse(parts[1].Replace("%",""), out res))
yy = res * (parts[1].Contains( '%' ) ? 0.01f : 1f);
return new float2(xx,yy);
}
UnknownFieldAction("[Type] {0}".F(x),fieldType);
return null;
}
static bool ParseYesNo( string p )
static object ParseYesNo( string p, System.Type fieldType, string field )
{
p = p.ToLowerInvariant();
if( p == "yes" ) return true;
if( p == "true" ) return true;
if( p == "no" ) return false;
if( p == "false" ) return false;
throw new InvalidOperationException();
return InvalidValueAction(p,fieldType, field);
}
static Cache<Type, Dictionary<FieldInfo, Func<string, Type, MiniYaml, object>>> typeLoadInfo = new Cache<Type, Dictionary<FieldInfo, Func<string, Type, MiniYaml, object>>>( GetTypeLoadInfo );
static Dictionary<FieldInfo, Func<string, Type, MiniYaml, object>> GetTypeLoadInfo( Type type )
{
var ret = new Dictionary<FieldInfo, Func<string, Type, MiniYaml, object>>();
foreach( var field in type.GetFields() )
{
var load = (LoadAttribute[])field.GetCustomAttributes( typeof( LoadAttribute ), false );
var loadUsing = (LoadUsingAttribute[])field.GetCustomAttributes( typeof( LoadUsingAttribute ), false );
var fromYamlKey = (FieldFromYamlKeyAttribute[])field.GetCustomAttributes( typeof( FieldFromYamlKeyAttribute ), false );
if( loadUsing.Length != 0 )
ret[ field ] = ( _1, fieldType, yaml ) => loadUsing[ 0 ].LoaderFunc( field )( yaml );
else if( fromYamlKey.Length != 0 )
ret[ field ] = ( f, ft, yaml ) => GetValue( f, ft, yaml.Value );
else if( load.Length != 0 )
ret[ field ] = null;
}
if( ret.Count == 0 )
foreach( var f in type.GetFields() )
ret.Add( f, null );
return ret;
}
[AttributeUsage( AttributeTargets.Field )]
public class LoadAttribute : Attribute { }
[AttributeUsage( AttributeTargets.Field )]
public class LoadUsingAttribute : Attribute
{
Func<MiniYaml, object> loaderFuncCache;
public readonly string Loader;
public LoadUsingAttribute( string loader )
{
Loader = loader;
}
internal Func<MiniYaml, object> LoaderFunc( FieldInfo field )
{
const BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
if( loaderFuncCache == null )
loaderFuncCache = (Func<MiniYaml, object>)Delegate.CreateDelegate( typeof( Func<MiniYaml, object> ), field.DeclaringType.GetMethod( Loader, bf ) );
return loaderFuncCache;
}
}
}
@@ -118,18 +225,51 @@ namespace OpenRA.FileFormats
{
public static MiniYaml Save(object o)
{
return new MiniYaml(null, o.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance)
.ToDictionary(
f => f.Name,
f => new MiniYaml(FormatValue(o, f))));
var nodes = new List<MiniYamlNode>();
string root = null;
foreach( var f in o.GetType().GetFields( BindingFlags.Public | BindingFlags.Instance ) )
{
if( f.HasAttribute<FieldFromYamlKeyAttribute>() )
root = FormatValue( o, f );
else
nodes.Add( new MiniYamlNode( f.Name, FormatValue( o, f ) ) );
}
return new MiniYaml( root, nodes );
}
public static MiniYaml SaveDifferences(object o, object from)
{
if (o.GetType() != from.GetType())
throw new InvalidOperationException("FieldLoader: can't diff objects of different types");
var fields = o.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance)
.Where(f => FormatValue(o,f) != FormatValue(from,f));
return new MiniYaml( null, fields.Select( f => new MiniYamlNode(
f.Name,
FormatValue( o, f ) ) ).ToList() );
}
public static string FormatValue(object o, FieldInfo f)
{
var v = f.GetValue(o);
if (v == null)
return "";
// Color.ToString() does the wrong thing; force it to format as an array
if (f.FieldType == typeof(Color))
{
var c = (Color)v;
return "{0},{1},{2},{3}".F(c.A,c.R,c.G,c.B);
}
return f.FieldType.IsArray
? string.Join(",", ((Array)v).OfType<object>().Select(a => a.ToString()).ToArray())
: v.ToString();
}
}
public class FieldFromYamlKeyAttribute : Attribute { }
}

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
@@ -86,6 +76,32 @@ namespace OpenRA.FileFormats
return (short)current;
}
public static byte[] LoadSound(byte[] raw, ref int index)
{
var br = new BinaryReader(new MemoryStream(raw));
var dataSize = raw.Length;
var outputSize = raw.Length * 4;
var output = new byte[outputSize];
var offset = 0;
var currentSample = 0;
while (dataSize-- > 0)
{
var b = br.ReadByte();
var t = DecodeSample(b, ref index, ref currentSample);
output[offset++] = (byte)t;
output[offset++] = (byte)(t >> 8);
t = DecodeSample((byte)(b >> 4), ref index, ref currentSample);
output[offset++] = (byte)t;
output[offset++] = (byte)(t >> 8);
}
return output;
}
public static byte[] LoadSound(Stream s)
{
var br = new BinaryReader(s);

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
@@ -43,15 +33,23 @@ namespace OpenRA.FileFormats
}
}
static IFolder OpenPackage(string filename)
{
if (filename.EndsWith(".mix"))
return new Package(filename);
else if (filename.EndsWith(".zip"))
return new CompressedPackage(filename);
else
return new Folder(filename);
}
public static void Mount(string name)
{
name = name.ToLowerInvariant();
var optional = name.StartsWith("~");
if (optional) name = name.Substring(1);
var a = name.EndsWith(".mix")
? (Action)(() => FileSystem.MountInner(new Package(name)))
: () => FileSystem.MountInner(new Folder(name));
var a = (Action)(() => FileSystem.MountInner(OpenPackage(name)));
if (optional)
try { a(); }
@@ -66,14 +64,18 @@ namespace OpenRA.FileFormats
allFiles = new Cache<uint, List<IFolder>>( _ => new List<IFolder>() );
}
public static void LoadFromManifest( Manifest manifest )
{
UnmountAll();
foreach (var dir in manifest.Folders) Mount(dir);
foreach (var pkg in manifest.Packages) Mount(pkg);
}
static Stream GetFromCache( Cache<uint, List<IFolder>> index, string filename )
{
foreach( var folder in index[ PackageEntry.HashFilename( filename ) ] )
{
Stream s = folder.GetContent(filename);
if( s != null )
return s;
}
if (folder.Exists(filename))
return folder.GetContent(filename);
return null;
}
@@ -88,9 +90,8 @@ namespace OpenRA.FileFormats
foreach( IFolder folder in mountedFolders )
{
Stream s = folder.GetContent(filename);
if( s != null )
return s;
if (folder.Exists(filename))
return folder.GetContent(filename);
}
throw new FileNotFoundException( string.Format( "File not found: {0}", filename ), filename );
@@ -111,11 +112,8 @@ namespace OpenRA.FileFormats
foreach( var ext in exts )
{
foreach( IFolder folder in mountedFolders )
{
Stream s = folder.GetContent( filename + ext );
if( s != null )
return s;
}
if (folder.Exists(filename + ext))
return folder.GetContent( filename + ext );
}
throw new FileNotFoundException( string.Format( "File not found: {0}", filename ), filename );
@@ -124,15 +122,8 @@ namespace OpenRA.FileFormats
public static bool Exists(string filename)
{
foreach (var folder in mountedFolders)
{
var s = folder.GetContent(filename);
if (s != null)
{
s.Dispose();
return true;
}
}
if (folder.Exists(filename))
return true;
return false;
}

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
@@ -40,5 +30,10 @@ namespace OpenRA.FileFormats
foreach( var filename in Directory.GetFiles( path, "*", SearchOption.TopDirectoryOnly ) )
yield return PackageEntry.HashFilename( filename );
}
public bool Exists(string filename)
{
return File.Exists(Path.Combine(path,filename));
}
}
}

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
@@ -42,6 +32,7 @@ namespace OpenRA.FileFormats.Graphics
IVertexBuffer<Vertex> CreateVertexBuffer( int length );
IIndexBuffer CreateIndexBuffer( int length );
ITexture CreateTexture( Bitmap bitmap );
ITexture CreateTexture();
IShader CreateShader( Stream stream );
Size WindowSize { get; }
@@ -80,14 +71,9 @@ namespace OpenRA.FileFormats.Graphics
public interface ITexture
{
void SetData( Bitmap bitmap );
}
public interface IFont
{
void DrawText( string text, int2 pos, Color c );
int2 Measure( string text );
void SetData(Bitmap bitmap);
void SetData(uint[,] colors);
void SetData(byte[] colors, int width, int height);
}
public enum PrimitiveType
@@ -102,4 +88,11 @@ namespace OpenRA.FileFormats.Graphics
public readonly T Start, End;
public Range( T start, T end ) { Start = start; End = end; }
}
public enum WindowMode
{
Windowed,
Fullscreen,
PseudoFullscreen,
}
}

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -0,0 +1,294 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System;
using System.IO;
namespace OpenRA.FileFormats
{
public class VqaReader
{
public readonly ushort Frames;
public readonly byte Framerate;
public readonly ushort Width;
public readonly ushort Height;
Stream stream;
int currentFrame;
ushort numColors;
ushort blockWidth;
ushort blockHeight;
byte cbParts;
int2 blocks;
UInt32[] offsets;
uint[] palette;
// Stores a list of subpixels, referenced by the VPTZ chunk
byte[] cbf;
byte[] cbp;
int cbChunk = 0;
int cbOffset = 0;
// Top half contains block info, bottom half contains references to cbf array
byte[] origData;
// Final frame output
uint[,] frameData;
byte[] audioData; // audio for this frame: 22050Hz 16bit mono pcm, uncompressed.
public byte[] AudioData { get { return audioData; } }
public int CurrentFrame { get { return currentFrame; } }
public VqaReader( Stream stream )
{
this.stream = stream;
BinaryReader reader = new BinaryReader( stream );
// Decode FORM chunk
if (new String(reader.ReadChars(4)) != "FORM")
throw new InvalidDataException("Invalid vqa (invalid FORM section)");
/*var length = */ reader.ReadUInt32();
if (new String(reader.ReadChars(8)) != "WVQAVQHD")
throw new InvalidDataException("Invalid vqa (not WVQAVQHD)");
/* var length = */reader.ReadUInt32();
/*var version = */reader.ReadUInt16();
/*var flags = */reader.ReadUInt16();
Frames = reader.ReadUInt16();
Width = reader.ReadUInt16();
Height = reader.ReadUInt16();
blockWidth = reader.ReadByte();
blockHeight = reader.ReadByte();
Framerate = reader.ReadByte();
cbParts = reader.ReadByte();
blocks = new int2(Width / blockWidth, Height / blockHeight);
numColors = reader.ReadUInt16();
/*var maxBlocks = */reader.ReadUInt16();
/*var unknown1 = */reader.ReadUInt16();
/*var unknown2 = */reader.ReadUInt32();
// Audio
/*var freq = */reader.ReadUInt16();
/*var channels = */reader.ReadByte();
/*var bits = */reader.ReadByte();
/*var unknown3 = */reader.ReadChars(14);
var frameSize = NextPowerOf2(Math.Max(Width,Height));
cbf = new byte[Width*Height];
cbp = new byte[Width*Height];
palette = new uint[numColors];
origData = new byte[2*blocks.X*blocks.Y];
frameData = new uint[frameSize,frameSize];
var type = new String(reader.ReadChars(4));
if (type != "FINF")
{
reader.ReadBytes(27);
type = new String(reader.ReadChars(4));
}
/*var length = */reader.ReadUInt16();
/*var unknown4 = */reader.ReadUInt16();
// Frame offsets
offsets = new UInt32[Frames];
for (int i = 0; i < Frames; i++)
{
offsets[i] = reader.ReadUInt32();
if (offsets[i] > 0x40000000) offsets[i] -= 0x40000000;
offsets[i] <<= 1;
}
CollectAudioData();
Reset();
}
public void Reset()
{
currentFrame = cbOffset = cbChunk = 0;
LoadFrame();
}
void CollectAudioData()
{
var ms = new MemoryStream();
var adpcmIndex = 0;
bool compressed = false;
for (var i = 0; i < Frames; i++)
{
stream.Seek(offsets[i], SeekOrigin.Begin);
BinaryReader reader = new BinaryReader(stream);
var end = (i < Frames - 1) ? offsets[i + 1] : stream.Length;
while (reader.BaseStream.Position < end)
{
var type = new String(reader.ReadChars(4));
var length = int2.Swap(reader.ReadUInt32());
switch (type)
{
case "SND0":
case "SND2":
var rawAudio = reader.ReadBytes((int)length);
ms.Write(rawAudio);
compressed = (type == "SND2");
break;
default:
reader.ReadBytes((int)length);
break;
}
if (reader.PeekChar() == 0) reader.ReadByte();
}
}
audioData = (compressed) ? AudLoader.LoadSound(ms.ToArray(), ref adpcmIndex) : ms.ToArray();
}
public void AdvanceFrame()
{
currentFrame++;
LoadFrame();
}
void LoadFrame()
{
if (currentFrame >= Frames)
return;
// Seek to the start of the frame
stream.Seek(offsets[currentFrame], SeekOrigin.Begin);
BinaryReader reader = new BinaryReader(stream);
var end = (currentFrame < Frames - 1) ? offsets[currentFrame+1] : stream.Length;
while(reader.BaseStream.Position < end)
{
var type = new String(reader.ReadChars(4));
var length = int2.Swap(reader.ReadUInt32());
switch(type)
{
case "VQFR":
DecodeVQFR(reader);
break;
default:
// Don't parse sound here.
reader.ReadBytes((int)length);
break;
}
// Chunks are aligned on even bytes; advance by a byte if the next one is null
if (reader.PeekChar() == 0) reader.ReadByte();
}
}
// VQA Frame
public void DecodeVQFR(BinaryReader reader)
{
while(true)
{
// Chunks are aligned on even bytes; may be padded with a single null
if (reader.PeekChar() == 0) reader.ReadByte();
var type = new String(reader.ReadChars(4));
int subchunkLength = (int)int2.Swap(reader.ReadUInt32());
switch(type)
{
// Full frame-modifier
case "CBFZ":
Format80.DecodeInto( reader.ReadBytes(subchunkLength), cbf );
break;
case "CBF0":
cbf = reader.ReadBytes(subchunkLength);
break;
// frame-modifier chunk
case "CBP0":
case "CBPZ":
// Partial buffer is full; dump and recreate
if (cbChunk == cbParts)
{
if (type == "CBP0")
cbf = (byte[])cbp.Clone();
else
Format80.DecodeInto( cbp, cbf );
cbOffset = cbChunk = 0;
}
var bytes = reader.ReadBytes(subchunkLength);
bytes.CopyTo(cbp,cbOffset);
cbOffset += subchunkLength;
cbChunk++;
break;
// Palette
case "CPL0":
for (int i = 0; i < numColors; i++)
{
byte r = (byte)(reader.ReadByte() << 2);
byte g = (byte)(reader.ReadByte() << 2);
byte b = (byte)(reader.ReadByte() << 2);
palette[i] = (uint)((255 << 24) | (r << 16) | (g << 8) | b);
}
break;
// Frame data
case "VPTZ":
Format80.DecodeInto( reader.ReadBytes(subchunkLength), origData );
// This is the last subchunk
return;
default:
throw new InvalidDataException("Unknown sub-chunk {0}".F(type));
}
}
}
int cachedFrame = -1;
public uint[,] FrameData { get
{
if (cachedFrame != currentFrame)
{
cachedFrame = currentFrame;
for (var y = 0; y < blocks.Y; y++)
for (var x = 0; x < blocks.X; x++)
{
var px = origData[x + y*blocks.X];
var mod = origData[x + (y + blocks.Y)*blocks.X];
for (var j = 0; j < blockHeight; j++)
for (var i = 0; i < blockWidth; i++)
{
var cbfi = (mod*256 + px)*8 + j*blockWidth + i;
byte color = (mod == 0x0f) ? px : cbf[cbfi];
frameData[y*blockHeight + j, x*blockWidth + i] = palette[color];
}
}
}
return frameData;
}}
int NextPowerOf2(int v)
{
--v;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
++v;
return v;
}
}
}

View File

@@ -1,29 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System.Drawing;
namespace OpenRA.FileFormats
{
public interface IPaletteRemap
{
Color GetRemappedColor(Color original, int index);
}
}

View File

@@ -0,0 +1,59 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System.Collections.Generic;
using System.Linq;
namespace OpenRA.FileFormats
{
/* describes what is to be loaded in order to run a set of mods */
public class Manifest
{
public readonly string[]
Folders, Packages, Rules,
Sequences, Chrome, Assemblies, ChromeLayout,
Weapons, Voices, Music, Movies, TileSets;
public readonly string ShellmapUid, LoadScreen;
public Manifest(string[] mods)
{
var yaml = mods
.Select(m => MiniYaml.FromFile("mods/" + m + "/mod.yaml"))
.Aggregate(MiniYaml.Merge);
Folders = YamlList(yaml, "Folders");
Packages = YamlList(yaml, "Packages");
Rules = YamlList(yaml, "Rules");
Sequences = YamlList(yaml, "Sequences");
Chrome = YamlList(yaml, "Chrome");
Assemblies = YamlList(yaml, "Assemblies");
ChromeLayout = YamlList(yaml, "ChromeLayout");
Weapons = YamlList(yaml, "Weapons");
Voices = YamlList(yaml, "Voices");
Music = YamlList(yaml, "Music");
Movies = YamlList(yaml, "Movies");
TileSets = YamlList(yaml, "TileSets");
ShellmapUid = yaml.First( x => x.Key == "ShellmapUid" ).Value.Value;
LoadScreen = yaml.First( x => x.Key == "LoadScreen" ).Value.Value;
}
static string[] YamlList(List<MiniYamlNode> ys, string key)
{
var y = ys.FirstOrDefault( x => x.Key == key );
if( y == null )
return new string[ 0 ];
return y.Value.NodesDict.Keys.ToArray();
}
}
}

View File

@@ -1,44 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
namespace OpenRA.FileFormats
{
public class ActorReference
{
public readonly string Id;
public readonly string Type;
public readonly int2 Location;
public readonly string Owner;
public ActorReference(MiniYaml my)
{
FieldLoader.Load(this, my);
}
// Legacy construtor for old format maps
public ActorReference(string id, string type, int2 location, string owner )
{
Id = id;
Type = type;
Location = location;
Owner = owner;
}
}
}

View File

@@ -1,97 +1,61 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
namespace OpenRA.FileFormats
{
public class MapStub
{
public IFolder Package;
public readonly IFolder Package;
// Yaml map data
public string Uid;
public bool Selectable;
public readonly string Uid;
[FieldLoader.Load] public bool Selectable;
public string Title;
public string Description;
public string Author;
public int PlayerCount;
public string Tileset;
public Dictionary<string, int2> Waypoints = new Dictionary<string, int2>();
[FieldLoader.Load] public string Title;
[FieldLoader.Load] public string Description;
[FieldLoader.Load] public string Author;
[FieldLoader.Load] public int PlayerCount;
[FieldLoader.Load] public string Tileset;
public int2 TopLeft;
public int2 BottomRight;
[FieldLoader.LoadUsing( "LoadWaypoints" )]
public Dictionary<string, int2> Waypoints = new Dictionary<string, int2>();
public IEnumerable<int2> SpawnPoints { get { return Waypoints.Select(kv => kv.Value); } }
[FieldLoader.Load] public int2 TopLeft;
[FieldLoader.Load] public int2 BottomRight;
public int Width { get { return BottomRight.X - TopLeft.X; } }
public int Height { get { return BottomRight.Y - TopLeft.Y; } }
public Lazy<Bitmap> Preview;
static List<string> Fields = new List<string>() {
"Selectable", "Title", "Description", "Author", "PlayerCount", "Tileset", "TopLeft", "BottomRight"
};
public MapStub() { }
public MapStub(IFolder package)
{
Package = package;
var yaml = MiniYaml.FromStream(Package.GetContent("map.yaml"));
FieldLoader.LoadFields(this, yaml, Fields);
FieldLoader.Load( this, new MiniYaml( null, yaml ) );
// Waypoints
foreach (var wp in yaml["Waypoints"].Nodes)
{
string[] loc = wp.Value.Value.Split(',');
Waypoints.Add(wp.Key, new int2(int.Parse(loc[0]), int.Parse(loc[1])));
}
Preview = Lazy.New(
() => { return new Bitmap(Package.GetContent("preview.png")); }
);
Uid = Package.GetContent("map.uid").ReadAllText();
}
public int2 ConvertToPreview(int2 point, Rectangle container)
{
float scale = Math.Min(container.Width * 1.0f / Width, container.Height * 1.0f / Height);
var size = Math.Max(Width, Height);
var dw = (int)(scale * (size - Width)) / 2;
var dh = (int)(scale * (size - Height)) / 2;
return new int2(container.X + dw + (int)(scale*(point.X - TopLeft.X)) , container.Y + dh + (int)(scale*(point.Y - TopLeft.Y)));
}
public Rectangle PreviewBounds(Rectangle container)
static object LoadWaypoints( MiniYaml y )
{
float scale = Math.Min(container.Width * 1.0f / Width, container.Height * 1.0f / Height);
var size = Math.Max(Width, Height);
var dw = (int)(scale * (size - Width)) / 2;
var dh = (int)(scale * (size - Height)) / 2;
return new Rectangle(container.X + dw, container.Y + dh, (int)(Width * scale), (int)(Height * scale));
var ret = new Dictionary<string, int2>();
foreach( var wp in y.NodesDict[ "Waypoints" ].NodesDict )
{
string[] loc = wp.Value.Value.Split( ',' );
ret.Add( wp.Key, new int2( int.Parse( loc[ 0 ] ), int.Parse( loc[ 1 ] ) ) );
}
return ret;
}
}
}

View File

@@ -1,42 +1,42 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System.Drawing;
namespace OpenRA.FileFormats
{
public class PlayerReference
{
public readonly string Name;
public readonly string Palette;
public readonly string Race;
public readonly bool OwnsWorld = false;
public readonly bool NonCombatant = false;
public string Name;
public string Palette;
public string Race;
public bool OwnsWorld = false;
public bool NonCombatant = false;
public bool Playable = false;
public bool DefaultStartingUnits = false;
public Color Color = Color.FromArgb(238,238,238);
public Color Color2 = Color.FromArgb(44,28,24);
public int InitialCash = 0;
public string[] Allies = {};
public string[] Enemies = {};
public PlayerReference() {}
public PlayerReference(MiniYaml my)
{
FieldLoader.Load(this, my);
}
public PlayerReference(string name, string palette, string race, bool ownsworld, bool noncombatant)
public PlayerReference(string name, string race, bool ownsworld, bool noncombatant)
{
Name = name;
Palette = palette;
Race = race;
OwnsWorld = ownsworld;
NonCombatant = noncombatant;

View File

@@ -1,21 +1,11 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
namespace OpenRA.FileFormats

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,51 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
namespace OpenRA.FileFormats
{
public class TerrainColorSet
{
readonly Dictionary<TerrainType, Color> colors;
public TerrainColorSet(string colorFile)
{
var lines = FileSystem.Open(colorFile).ReadAllLines()
.Select(l => l.Trim())
.Where(l => !l.StartsWith(";") && l.Length > 0);
colors = lines.Select(l => l.Split('=')).ToDictionary(
kv => (TerrainType)Enum.Parse(typeof(TerrainType), kv[0]),
kv => ColorFromRgbString(kv[1]));
}
static Color ColorFromRgbString(string s)
{
var parts = s.Split(',');
return Color.FromArgb(int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2]));
}
public Color ColorForTerrainType(TerrainType type) { return colors[type]; }
}
}

View File

@@ -1,21 +1,11 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
namespace OpenRA.FileFormats

View File

@@ -1,94 +1,147 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System.Collections.Generic;
using System.Globalization;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
namespace OpenRA.FileFormats
{
public class TerrainTypeInfo
{
public string Type;
public bool Buildable = true;
public bool AcceptSmudge = true;
public bool IsWater = false;
public Color Color;
public TerrainTypeInfo() {}
public TerrainTypeInfo(MiniYaml my) { FieldLoader.Load(this, my); }
public MiniYaml Save() { return FieldSaver.Save(this); }
}
public class TileTemplate
{
[FieldLoader.Load] public ushort Id;
[FieldLoader.Load] public string Image;
[FieldLoader.Load] public int2 Size;
[FieldLoader.Load] public bool PickAny;
[FieldLoader.LoadUsing( "LoadTiles" )]
public Dictionary<byte, string> Tiles = new Dictionary<byte, string>();
public TileTemplate() {}
public TileTemplate(MiniYaml my)
{
FieldLoader.Load( this, my );
}
static object LoadTiles( MiniYaml y )
{
return y.NodesDict["Tiles"].NodesDict.ToDictionary(
t => byte.Parse(t.Key),
t => t.Value.Value );
}
public MiniYaml Save()
{
var root = new List<MiniYamlNode>();
foreach (var field in new string[] {"Id", "Image", "Size", "PickAny"})
{
FieldInfo f = this.GetType().GetField(field);
if (f.GetValue(this) == null) continue;
root.Add( new MiniYamlNode( field, FieldSaver.FormatValue( this, f ) ) );
}
root.Add( new MiniYamlNode( "Tiles", null,
Tiles.Select( x => new MiniYamlNode( x.Key.ToString(), x.Value ) ).ToList() ) );
return new MiniYaml(null, root);
}
}
public class TileSet
{
public readonly Dictionary<ushort, Terrain> tiles = new Dictionary<ushort, Terrain>();
public string Name;
public string Id;
public string Palette;
public string[] Extensions;
public Dictionary<string, TerrainTypeInfo> Terrain = new Dictionary<string, TerrainTypeInfo>();
public Dictionary<ushort, Terrain> Tiles = new Dictionary<ushort, Terrain>();
public Dictionary<ushort, TileTemplate> Templates = new Dictionary<ushort, TileTemplate>();
static List<string> fields = new List<string>() {"Name", "Id", "Palette", "Extensions"};
public readonly Walkability Walkability;
public readonly Dictionary<ushort, TileTemplate> walk
= new Dictionary<ushort, TileTemplate>();
string NextLine( StreamReader reader )
public TileSet() {}
public TileSet( string filepath )
{
string ret;
do
{
ret = reader.ReadLine();
if( ret == null )
return null;
ret = ret.Trim();
}
while( ret.Length == 0 || ret[ 0 ] == ';' );
return ret;
var yaml = MiniYaml.DictFromFile( filepath );
// General info
FieldLoader.Load(this, yaml["General"]);
// TerrainTypes
Terrain = yaml["Terrain"].NodesDict.Values
.Select(y => new TerrainTypeInfo(y)).ToDictionary(t => t.Type);
// Templates
Templates = yaml["Templates"].NodesDict.Values
.Select(y => new TileTemplate(y)).ToDictionary(t => t.Id);
}
public TileSet( string tilesetFile, string templatesFile, string suffix )
public void LoadTiles()
{
Walkability = new Walkability(templatesFile);
char tileSetChar = char.ToUpperInvariant( suffix[ 0 ] );
StreamReader tileIdFile = new StreamReader( FileSystem.Open(tilesetFile) );
while( true )
{
string tileSetStr = NextLine( tileIdFile );
string countStr = NextLine( tileIdFile );
string startStr = NextLine( tileIdFile );
string pattern = NextLine( tileIdFile );
if( tileSetStr == null || countStr == null || startStr == null || pattern == null )
break;
if( tileSetStr.IndexOf( tileSetChar.ToString() ) == -1 )
continue;
int count = int.Parse( countStr );
int start = int.Parse( startStr, NumberStyles.HexNumber );
for( int i = 0 ; i < count ; i++ )
foreach (var t in Templates)
using( Stream s = FileSystem.OpenWithExts(t.Value.Image, Extensions) )
{
string tilename = string.Format(pattern, i + 1);
if (!walk.ContainsKey((ushort)(start + i)))
walk.Add((ushort)(start + i), Walkability.GetTileTemplate(tilename));
using( Stream s = FileSystem.Open( tilename + "." + suffix ) )
{
if( !tiles.ContainsKey( (ushort)( start + i ) ) )
tiles.Add( (ushort)( start + i ), new Terrain( s ) );
}
if( !Tiles.ContainsKey( t.Key ) )
Tiles.Add( t.Key, new Terrain( s ) );
}
}
tileIdFile.Close();
}
public void Save(string filepath)
{
var root = new List<MiniYamlNode>();
foreach (var field in fields)
{
FieldInfo f = this.GetType().GetField(field);
if (f.GetValue(this) == null) continue;
root.Add( new MiniYamlNode( field, FieldSaver.FormatValue( this, f ) ) );
}
var gen = new List<MiniYamlNode>();
foreach (var field in fields)
{
FieldInfo f = this.GetType().GetField(field);
if (f.GetValue(this) == null) continue;
gen.Add( new MiniYamlNode( field, FieldSaver.FormatValue( this, f ) ) );
}
root.Add( new MiniYamlNode( "General", null, gen ) );
root.Add( new MiniYamlNode( "Terrain", null,
Terrain.Select( t => new MiniYamlNode(
"TerrainType@{0}".F( t.Value.Type ),
t.Value.Save() ) ).ToList() ) );
root.Add( new MiniYamlNode( "Templates", null,
Templates.Select( t => new MiniYamlNode(
"Template@{0}".F( t.Value.Id ),
t.Value.Save() ) ).ToList() ) );
root.WriteToFile(filepath);
}
public byte[] GetBytes(TileReference<ushort,byte> r)
{
Terrain tile;
if( tiles.TryGetValue( r.type, out tile ) )
if( Tiles.TryGetValue( r.type, out tile ) )
return tile.TileBitmapBytes[ r.image ];
byte[] missingTile = new byte[ 24 * 24 ];
@@ -98,12 +151,12 @@ namespace OpenRA.FileFormats
return missingTile;
}
public TerrainType GetTerrainType( TileReference<ushort, byte> r )
public string GetTerrainType(TileReference<ushort, byte> r)
{
var tt = walk[ r.type ].TerrainType;
TerrainType ret;
if( !tt.TryGetValue( r.image, out ret ) )
return 0;// Default zero (walkable)
var tt = Templates[r.type].Tiles;
string ret;
if (!tt.TryGetValue(r.image, out ret))
return "Clear"; // Default walkable
return ret;
}
}

View File

@@ -1,95 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
namespace OpenRA.FileFormats
{
public enum TerrainType : byte
{
Clear = 0,
Water = 1,
Road = 2,
Rock = 3,
Tree = 4,
River = 5,
Rough = 6,
Wall = 7,
Beach = 8,
Ore = 9,
Special = 10,
}
public class TileTemplate
{
public int Index; // not valid for `interior` stuff. only used for bridges.
public string Name;
public int2 Size;
public string Bridge;
public float HP;
public Dictionary<int, TerrainType> TerrainType = new Dictionary<int, TerrainType>();
}
public class Walkability
{
Dictionary<string, TileTemplate> templates
= new Dictionary<string,TileTemplate>();
public Walkability(string templatesFile)
{
var file = new IniFile( FileSystem.Open( templatesFile ) );
foreach (var section in file.Sections)
{
var name = section.GetValue("Name", null).ToLowerInvariant();
if (!section.Contains("width") || !section.Contains("height"))
throw new InvalidOperationException("no width/height for template `{0}`".F(name));
var tile = new TileTemplate
{
Name = name,
Size = new int2(
int.Parse(section.GetValue("width", "--")),
int.Parse(section.GetValue("height", "--"))),
TerrainType = section
.Where(p => p.Key.StartsWith("tiletype"))
.ToDictionary(
p => int.Parse(p.Key.Substring(8)),
p => (TerrainType)Enum.Parse(typeof(TerrainType),p.Value)),
Bridge = section.GetValue("bridge", null),
HP = float.Parse(section.GetValue("hp", "0"))
};
tile.Index = -1;
int.TryParse(section.Name.Substring(3), out tile.Index);
templates[tile.Name] = tile;
}
}
public TileTemplate GetTileTemplate(string terrainName)
{
return templates[terrainName];
}
}
}

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
@@ -25,38 +15,80 @@ using System.Linq;
namespace OpenRA.FileFormats
{
using MiniYamlNodes = Dictionary<string, MiniYaml>;
using MiniYamlNodes = List<MiniYamlNode>;
public class MiniYamlNode
{
public struct SourceLocation
{
public string Filename; public int Line;
}
public SourceLocation Location;
public string Key;
public MiniYaml Value;
public MiniYamlNode( string k, MiniYaml v )
{
Key = k;
Value = v;
}
public MiniYamlNode( string k, MiniYaml v, SourceLocation loc )
: this( k, v )
{
Location = loc;
}
public MiniYamlNode( string k, string v )
: this( k, v, null )
{
}
public MiniYamlNode( string k, string v, List<MiniYamlNode> n )
: this( k, new MiniYaml( v, n ) )
{
}
public MiniYamlNode( string k, string v, List<MiniYamlNode> n, SourceLocation loc )
: this( k, new MiniYaml( v, n ), loc )
{
}
}
public class MiniYaml
{
public string Value;
public Dictionary<string, MiniYaml> Nodes = new Dictionary<string,MiniYaml>();
public List<MiniYamlNode> Nodes;
public MiniYaml( string value ) : this( value, new Dictionary<string, MiniYaml>() ) { }
public Dictionary<string, MiniYaml> NodesDict { get { return Nodes.ToDictionary( x => x.Key, x => x.Value ); } }
public MiniYaml( string value, Dictionary<string, MiniYaml> nodes )
public MiniYaml( string value ) : this( value, null ) { }
public MiniYaml( string value, List<MiniYamlNode> nodes )
{
Value = value;
Nodes = nodes;
Nodes = nodes ?? new List<MiniYamlNode>();
}
public static MiniYaml FromDictionary<K,V>(Dictionary<K,V>dict)
{
return new MiniYaml( null, dict.ToDictionary( x=>x.Key.ToString(), x=>new MiniYaml(x.Value.ToString())));
}
public static MiniYaml FromList<T>(List<T>list)
{
return new MiniYaml( null, list.ToDictionary( x=>x.ToString(), x=>new MiniYaml(null)));
}
static Dictionary<string, MiniYaml> FromLines(string[] lines)
{
var levels = new List<Dictionary<string, MiniYaml>>();
levels.Add(new Dictionary<string, MiniYaml>());
public static MiniYaml FromDictionary<K, V>( Dictionary<K, V> dict )
{
return new MiniYaml( null, dict.Select( x => new MiniYamlNode( x.Key.ToString(), new MiniYaml( x.Value.ToString() ) ) ).ToList() );
}
public static MiniYaml FromList<T>( List<T> list )
{
return new MiniYaml( null, list.Select( x => new MiniYamlNode( x.ToString(), new MiniYaml( null ) ) ).ToList() );
}
static List<MiniYamlNode> FromLines(string[] lines, string filename)
{
var levels = new List<List<MiniYamlNode>>();
levels.Add(new List<MiniYamlNode>());
var lineNo = 0;
foreach (var line in lines)
{
++lineNo;
var t = line.TrimStart(' ', '\t');
if (t.Length == 0 || t[0] == '#')
continue;
@@ -67,28 +99,28 @@ namespace OpenRA.FileFormats
while (levels.Count > level + 1)
levels.RemoveAt(levels.Count - 1);
var colon = t.IndexOf(':');
var d = new Dictionary<string, MiniYaml>();
try
{
if (colon == -1)
levels[level].Add(t.Trim(), new MiniYaml(null, d));
else
{
var value = t.Substring(colon + 1).Trim();
if (value.Length == 0)
value = null;
levels[level].Add(t.Substring(0, colon).Trim(), new MiniYaml(value, d));
}
}
catch (ArgumentException) { throw new InvalidDataException("Duplicate Identifier:`{0}`".F(t)); }
var d = new List<MiniYamlNode>();
var rhs = SplitAtColon( ref t );
levels[ level ].Add( new MiniYamlNode( t, rhs, d, new MiniYamlNode.SourceLocation { Filename = filename, Line = lineNo } ) );
levels.Add(d);
}
return levels[0];
return levels[ 0 ];
}
public static Dictionary<string, MiniYaml> FromFileInPackage( string path )
static string SplitAtColon( ref string t )
{
var colon = t.IndexOf(':');
if( colon == -1 )
return null;
var ret = t.Substring( colon + 1 ).Trim();
if( ret.Length == 0 )
ret = null;
t = t.Substring( 0, colon ).Trim();
return ret;
}
public static List<MiniYamlNode> FromFileInPackage( string path )
{
StreamReader reader = new StreamReader( FileSystem.Open(path) );
List<string> lines = new List<string>();
@@ -97,54 +129,67 @@ namespace OpenRA.FileFormats
lines.Add(reader.ReadLine());
reader.Close();
return FromLines(lines.ToArray());
}
public static Dictionary<string, MiniYaml> FromFile( string path )
{
return FromLines(File.ReadAllLines( path ));
return FromLines(lines.ToArray(), path);
}
public static Dictionary<string, MiniYaml> FromStream(Stream s)
public static Dictionary<string, MiniYaml> DictFromFile( string path )
{
return FromFile( path ).ToDictionary( x => x.Key, x => x.Value );
}
public static Dictionary<string, MiniYaml> DictFromStream( Stream stream )
{
return FromStream( stream ).ToDictionary( x => x.Key, x => x.Value );
}
public static List<MiniYamlNode> FromFile( string path )
{
return FromLines(File.ReadAllLines( path ), path);
}
public static List<MiniYamlNode> FromStream(Stream s)
{
using (var reader = new StreamReader(s))
return FromString(reader.ReadToEnd());
}
public static Dictionary<string, MiniYaml> FromString(string text)
public static List<MiniYamlNode> FromString(string text)
{
return FromLines(text.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries));
return FromLines(text.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries), "<no filename available>");
}
public static Dictionary<string, MiniYaml> Merge( Dictionary<string, MiniYaml> a, Dictionary<string, MiniYaml> b )
public static List<MiniYamlNode> Merge( List<MiniYamlNode> a, List<MiniYamlNode> b )
{
if( a.Count == 0 )
return b;
if( b.Count == 0 )
return a;
var ret = new Dictionary<string, MiniYaml>();
var ret = new List<MiniYamlNode>();
var keys = a.Keys.Union( b.Keys ).ToList();
var aDict = a.ToDictionary( x => x.Key );
var bDict = b.ToDictionary( x => x.Key );
var keys = aDict.Keys.Union( bDict.Keys ).ToList();
var noInherit = keys.Where( x => x.Length > 0 && x[ 0 ] == '-' ).Select( x => x.Substring( 1 ) ).ToList();
foreach( var key in keys )
{
MiniYaml aa, bb;
a.TryGetValue( key, out aa );
b.TryGetValue( key, out bb );
MiniYamlNode aa, bb;
aDict.TryGetValue( key, out aa );
bDict.TryGetValue( key, out bb );
// if( key.Length > 0 && key[ 0 ] == '-' )
// continue;
// else
if( noInherit.Contains( key ) )
{
if( aa != null )
ret.Add( key, aa );
ret.Add( aa );
}
else
ret.Add( key, Merge( aa, bb ) );
{
var loc = aa == null ? default( MiniYamlNode.SourceLocation ) : aa.Location;
var merged = ( aa == null || bb == null ) ? aa ?? bb : new MiniYamlNode( key, Merge( aa.Value, bb.Value ), loc );
ret.Add( merged );
}
}
return ret;

View File

@@ -50,10 +50,11 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\thirdparty\Tao\Tao.Sdl.dll</HintPath>
</Reference>
<Reference Include="WindowsBase">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ConnectedComponents.cs" />
<Compile Include="DisposableAction.cs" />
<Compile Include="Evaluator.cs" />
<Compile Include="Exts.cs" />
<Compile Include="FieldLoader.cs" />
@@ -61,31 +62,25 @@
<Compile Include="Folder.cs" />
<Compile Include="Graphics\IGraphicsDevice.cs" />
<Compile Include="Graphics\Vertex.cs" />
<Compile Include="IPaletteRemap.cs" />
<Compile Include="Manifest.cs" />
<Compile Include="MiniYaml.cs" />
<Compile Include="PackageEntry.cs" />
<Compile Include="Package.cs" />
<Compile Include="PackageWriter.cs" />
<Compile Include="Palette.cs" />
<Compile Include="PlayerColorRemap.cs" />
<Compile Include="Primitives\DisposableAction.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ProtocolVersion.cs" />
<Compile Include="Thirdparty\Random.cs" />
<Compile Include="Session.cs" />
<Compile Include="ShroudPaletteRemap.cs" />
<Compile Include="SingleColorRemap.cs" />
<Compile Include="Support\Log.cs" />
<Compile Include="Support\Stopwatch.cs" />
<Compile Include="Support\Timer.cs" />
<Compile Include="TypeDictionary.cs" />
<Compile Include="Map\ActorReference.cs" />
<Compile Include="Map\Map.cs" />
<Compile Include="Map\TileReference.cs" />
<Compile Include="Map\Walkability.cs" />
<Compile Include="Map\Terrain.cs" />
<Compile Include="Primitives\Cache.cs" />
<Compile Include="Primitives\float2.cs" />
<Compile Include="Primitives\Pair.cs" />
<Compile Include="Map\TerrainColorSet.cs" />
<Compile Include="Map\TileSet.cs" />
<Compile Include="Primitives\PriorityQueue.cs" />
<Compile Include="Primitives\Lazy.cs" />
@@ -103,6 +98,8 @@
<Compile Include="Map\MapStub.cs" />
<Compile Include="Map\SmudgeReference.cs" />
<Compile Include="Map\PlayerReference.cs" />
<Compile Include="CompressedPackage.cs" />
<Compile Include="Graphics\VqaReader.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
@@ -28,6 +18,7 @@ namespace OpenRA.FileFormats
public interface IFolder
{
Stream GetContent(string filename);
bool Exists(string filename);
IEnumerable<uint> AllFileHashes();
}
@@ -78,9 +69,7 @@ namespace OpenRA.FileFormats
BinaryReader reader2 = new BinaryReader(ms);
ushort numFiles = reader2.ReadUInt16();
uint datasize = reader2.ReadUInt32();
Console.WriteLine("{0} files, {1} kb", numFiles, datasize >> 10);
reader2.ReadUInt32(); /*datasize*/
s.Position = headerStart;
reader = new BinaryReader(s);
@@ -133,7 +122,7 @@ namespace OpenRA.FileFormats
dataStart = s.Position;
return items;
}
public Stream GetContent(uint hash)
{
PackageEntry e;
@@ -155,6 +144,11 @@ namespace OpenRA.FileFormats
{
return index.Keys;
}
public bool Exists(string filename)
{
return index.ContainsKey(PackageEntry.HashFilename(filename));
}
}
[Flags]

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
@@ -30,12 +20,27 @@ namespace OpenRA.FileFormats
public readonly uint Offset;
public readonly uint Length;
public PackageEntry(uint hash, uint offset, uint length)
{
Hash = hash;
Offset = offset;
Length = length;
}
public PackageEntry(BinaryReader r)
{
Hash = r.ReadUInt32();
Offset = r.ReadUInt32();
Length = r.ReadUInt32();
}
public void Write(BinaryWriter w)
{
w.Write(Hash);
w.Write(Offset);
w.Write(Length);
}
public override string ToString()
{

View File

@@ -0,0 +1,48 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System.Collections.Generic;
using System.IO;
namespace OpenRA.FileFormats
{
public static class PackageWriter
{
public static void CreateMix(string filename, List<string> contents)
{
// Construct a list of entries for the file header
uint dataSize = 0;
var items = new List<PackageEntry>();
foreach (var file in contents)
{
uint length = (uint)new FileInfo(file).Length;
uint hash = PackageEntry.HashFilename(Path.GetFileName(file));
items.Add(new PackageEntry(hash, dataSize, length));
dataSize += length;
}
using (var s = File.Create(filename))
using (var writer = new BinaryWriter(s))
{
// Write file header
writer.Write((ushort)items.Count);
writer.Write(dataSize);
foreach (var item in items)
item.Write(writer);
writer.Flush();
// Copy file data
foreach (var file in contents)
s.Write(File.ReadAllBytes(file));
}
}
}
}

View File

@@ -1,40 +1,48 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System;
namespace OpenRA.FileFormats
{
public class Palette
{
List<Color> colors = new List<Color>();
uint[] colors;
public Color GetColor(int index)
{
return colors[index];
return Color.FromArgb((int)colors[index]);
}
public void SetColor(int index, Color color)
{
colors[index] = (uint)color.ToArgb();
}
public void SetColor(int index, uint color)
{
colors[index] = (uint)color;
}
public uint[] Values
{
get { return colors; }
}
public Palette(Stream s, bool remapTransparent)
{
colors = new uint[256];
using (BinaryReader reader = new BinaryReader(s))
{
for (int i = 0; i < 256; i++)
@@ -42,24 +50,30 @@ namespace OpenRA.FileFormats
byte r = (byte)(reader.ReadByte() << 2);
byte g = (byte)(reader.ReadByte() << 2);
byte b = (byte)(reader.ReadByte() << 2);
colors.Add(Color.FromArgb(r, g, b));
colors[i] = (uint)((255 << 24) | (r << 16) | (g << 8) | b);
}
}
colors[0] = Color.FromArgb(0, 0, 0, 0);
colors[0] = 0;
if (remapTransparent)
{
colors[3] = Color.FromArgb(178, 0, 0, 0);
colors[4] = Color.FromArgb(140, 0, 0, 0);
colors[3] = 178u << 24;
colors[4] = 140u << 24;
}
}
public Palette(Palette p, IPaletteRemap r)
{
for (int i = 0; i < 256; i++)
colors.Add(r.GetRemappedColor(p.GetColor(i), i));
colors = new uint[256];
for(int i = 0; i < 256; i++)
colors[i] = (uint)r.GetRemappedColor(Color.FromArgb((int)p.colors[i]),i).ToArgb();
}
public Palette(Palette p)
{
colors = (uint[])p.colors.Clone();
}
}
public interface IPaletteRemap { Color GetRemappedColor(Color original, int index); }
}

View File

@@ -1,30 +1,21 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
namespace OpenRA.FileFormats
{
// TODO: ship this out of here.
public class PlayerColorRemap : IPaletteRemap
{
Dictionary<int, Color> remapColors;

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -0,0 +1,35 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System;
namespace OpenRA
{
public class DisposableAction : IDisposable
{
public DisposableAction(Action a) { this.a = a; }
Action a;
bool disposed;
public void Dispose()
{
if (disposed) return;
disposed = true;
a();
GC.SuppressFinalize(this);
}
~DisposableAction()
{
Dispose();
}
}
}

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
@@ -63,5 +53,11 @@ namespace OpenRA
public float2 ToFloat2() { return new float2(X, Y); }
public override string ToString() { return string.Format("{0},{1}", X, Y); }
// Change endianness of a uint32
public static uint Swap(uint orig)
{
return (uint)((orig & 0xff000000) >> 24) | ((orig & 0x00ff0000) >> 8) | ((orig & 0x0000ff00) << 8) | ((orig & 0x000000ff) << 24);
}
}
}

View File

@@ -1,28 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
namespace OpenRA.FileFormats
{
public static class ProtocolVersion
{
// you *must* increment this whenever you make an incompatible protocol change
public static readonly int Version = 4;
}
}

View File

@@ -1,94 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System.Collections.Generic;
using System.Linq;
namespace OpenRA.FileFormats
{
public class Session
{
public List<Client> Clients = new List<Client>();
public Global GlobalSettings = new Global();
public enum ClientState
{
NotReady,
Downloading,
Ready
}
public class Client
{
public int Index;
public int PaletteIndex;
public string Country;
public int SpawnPoint;
public string Name;
public ClientState State;
public int Team;
}
public class Global
{
public string Map;
public string[] Packages = {}; // filename:sha1 pairs.
public string[] Mods = { "ra" }; // mod names
public int OrderLatency = 3;
public int RandomSeed = 0;
}
}
public class Manifest
{
public readonly string[]
Folders, Packages, Rules,
Sequences, Chrome, Assemblies, ChromeLayout,
Weapons, Voices, Music, Terrain;
public readonly string ShellmapUid;
public Manifest(string[] mods)
{
var yaml = mods
.Select(m => MiniYaml.FromFile("mods/" + m + "/mod.yaml"))
.Aggregate(MiniYaml.Merge);
Folders = YamlList(yaml, "Folders");
Packages = YamlList(yaml, "Packages");
Rules = YamlList(yaml, "Rules");
Sequences = YamlList(yaml, "Sequences");
Chrome = YamlList(yaml, "Chrome");
Assemblies = YamlList(yaml, "Assemblies");
ChromeLayout = YamlList(yaml, "ChromeLayout");
Weapons = YamlList(yaml, "Weapons");
Voices = YamlList(yaml, "Voices");
Music = YamlList(yaml, "Music");
Terrain = YamlList(yaml, "Terrain");
ShellmapUid = yaml["ShellmapUid"].Value;
}
static string[] YamlList(Dictionary<string, MiniYaml> ys, string key)
{
return ys.ContainsKey(key) ? ys[key].Nodes.Keys.ToArray() : new string[] { };
}
}
}

View File

@@ -1,60 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System.Drawing;
namespace OpenRA.FileFormats
{
public class ShroudPaletteRemap : IPaletteRemap
{
bool isFog;
public ShroudPaletteRemap(bool isFog) { this.isFog = isFog; }
public Color GetRemappedColor(Color original, int index)
{
// false-color version for debug
//return new[] {
// Color.FromArgb(64,0,0,0), Color.Green,
// Color.Blue, Color.Yellow,
// Color.Green,
// Color.Red,
// Color.Purple,
// Color.Cyan}[index % 8];
if (isFog)
return new[] {
Color.Transparent, Color.Green,
Color.Blue, Color.Yellow,
Color.FromArgb(128,0,0,0),
Color.FromArgb(128,0,0,0),
Color.FromArgb(128,0,0,0),
Color.FromArgb(64,0,0,0)}[index % 8];
else
return new[] {
Color.Transparent, Color.Green,
Color.Blue, Color.Yellow,
Color.Black,
Color.FromArgb(128,0,0,0),
Color.Transparent,
Color.Transparent}[index % 8];
}
}
}

View File

@@ -1,38 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System.Drawing;
namespace OpenRA.FileFormats
{
public class SingleColorRemap : IPaletteRemap
{
Color c;
public SingleColorRemap(Color c)
{
this.c = c;
}
public Color GetRemappedColor(Color original, int index)
{
return original.A > 0 ? c : original;
}
}
}

View File

@@ -1,40 +1,74 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System.IO;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
namespace OpenRA
{
public struct ChannelInfo
{
public string Filename;
public StreamWriter Writer;
}
public static class Log
{
static StreamWriter writer = File.CreateText(Environment.GetFolderPath(Environment.SpecialFolder.Personal) + Path.DirectorySeparatorChar + "openra.log.txt");
static string LogPathPrefix = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + Path.DirectorySeparatorChar;
static Dictionary<string, ChannelInfo> channels = new Dictionary<string,ChannelInfo>();
static Log()
public static string LogPath
{
writer.AutoFlush = true;
get { return LogPathPrefix; }
set
{
LogPathPrefix = value;
if (!Directory.Exists(LogPathPrefix))
Directory.CreateDirectory(LogPathPrefix);
}
}
public static void AddChannel(string channelName, string filename)
{
if (channels.ContainsKey(channelName)) return;
var i = 0;
var f = filename;
while (File.Exists(LogPathPrefix + filename))
try
{
StreamWriter writer = File.CreateText(LogPathPrefix + filename);
writer.AutoFlush = true;
channels.Add(channelName, new ChannelInfo() { Filename = filename, Writer = writer });
return;
}
catch (IOException) { filename = f + ".{0}".F(++i); }
//if no logs exist, just make it
StreamWriter w = File.CreateText(LogPathPrefix + filename);
w.AutoFlush = true;
channels.Add(channelName, new ChannelInfo() { Filename = filename, Writer = w });
}
public static void Write(string format, params object[] args)
public static void Write(string channel, string format, params object[] args)
{
writer.WriteLine(format, args);
ChannelInfo info;
if (!channels.TryGetValue(channel, out info))
throw new Exception("Tried logging to non-existant channel " + channel);
info.Writer.WriteLine(format, args);
}
}
}

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
@@ -30,7 +20,7 @@ namespace OpenRA.Support
var time = sw.ElapsedTime();
var dt = time - lastTime;
if( dt > 0.0001 )
Log.Write( message, dt );
Log.Write("perf", message, dt );
lastTime = time;
}
}

View File

@@ -1,3 +1,13 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System;
namespace OpenRA.Thirdparty

View File

@@ -1,30 +1,21 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace OpenRA.FileFormats
{
public class TypeDictionary
public class TypeDictionary : IEnumerable
{
Dictionary<Type, object> dataSingular = new Dictionary<Type, object>();
Dictionary<Type, List<object>> dataMultiple = new Dictionary<Type, List<object>>();
@@ -95,13 +86,13 @@ namespace OpenRA.FileFormats
return new T[ 0 ];
}
public IEnumerator<object> GetEnumerator()
public IEnumerator GetEnumerator()
{
return WithInterface<object>().GetEnumerator();
}
}
static class TypeExts
public static class TypeExts
{
public static IEnumerable<Type> BaseTypes( this Type t )
{

View File

@@ -1,21 +1,11 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System;
@@ -31,30 +21,26 @@ namespace OpenRA
{
public class Actor
{
[Sync]
public readonly TypeDictionary traits = new TypeDictionary();
public readonly ActorInfo Info;
public readonly World World;
public readonly uint ActorID;
[Sync]
public int2 Location;
public readonly uint ActorID;
public int2 Location { get { return Trait<IOccupySpace>().TopLeft; } }
[Sync]
public Player Owner;
[Sync]
public int Health;
IActivity currentActivity;
public Group Group;
public Group Group;
internal Actor(World world, string name, TypeDictionary initDict )
{
var init = new ActorInitializer( this, initDict );
public Actor(World world, string name, int2 location, Player owner)
{
World = world;
ActorID = world.NextAID();
Location = location;
CenterLocation = Traits.Util.CenterOfCell(Location);
Owner = owner;
ActorID = world.NextAID();
if( initDict.Contains<OwnerInit>() )
Owner = init.Get<OwnerInit,Player>();
if (name != null)
{
@@ -62,12 +48,13 @@ namespace OpenRA
throw new NotImplementedException("No rules definition for unit {0}".F(name.ToLowerInvariant()));
Info = Rules.Info[name.ToLowerInvariant()];
Health = this.GetMaxHP();
foreach (var trait in Info.TraitsInConstructOrder())
traits.Add(trait.Create(this));
}
AddTrait(trait.Create(init));
}
if( CenterLocation == float2.Zero && HasTrait<IOccupySpace>() )
CenterLocation = Traits.Util.CenterOfCell(Location);
Size = Lazy.New(() =>
{
var si = Info.Traits.GetOrDefault<SelectableInfo>();
@@ -75,14 +62,14 @@ namespace OpenRA
return new float2(si.Bounds[0], si.Bounds[1]);
// auto size from render
var firstSprite = traits.WithInterface<IRender>().SelectMany(x => x.Render(this)).FirstOrDefault();
var firstSprite = TraitsImplementing<IRender>().SelectMany(x => x.Render(this)).FirstOrDefault();
if (firstSprite.Sprite == null) return float2.Zero;
return firstSprite.Sprite.size;
});
}
public void Tick()
{
{
var wasIdle = currentActivity is Idle;
while (currentActivity != null)
{
@@ -94,7 +81,7 @@ namespace OpenRA
if (currentActivity is Idle)
{
if (!wasIdle)
foreach (var ni in traits.WithInterface<INotifyIdle>())
foreach (var ni in TraitsImplementing<INotifyIdle>())
ni.Idle(this);
break;
@@ -113,8 +100,8 @@ namespace OpenRA
public IEnumerable<Renderable> Render()
{
var mods = traits.WithInterface<IRenderModifier>();
var sprites = traits.WithInterface<IRender>().SelectMany(x => x.Render(this));
var mods = TraitsImplementing<IRenderModifier>();
var sprites = TraitsImplementing<IRender>().SelectMany(x => x.Render(this));
return mods.Aggregate(sprites, (m, p) => p.ModifyRender(this, m));
}
@@ -124,14 +111,17 @@ namespace OpenRA
return null;
if (!World.Map.IsInMap(xy.X, xy.Y))
return null;
if (Destroyed)
return null;
var underCursor = World.FindUnitsAtMouse(mi.Location)
.Where(a => a.Info.Traits.Contains<SelectableInfo>())
.OrderByDescending(a => a.Info.Traits.Get<SelectableInfo>().Priority)
.Where(a => a.Info.Traits.Contains<TargetableInfo>())
.OrderByDescending(a => a.Info.Traits.Contains<SelectableInfo>() ? a.Info.Traits.Get<SelectableInfo>().Priority : int.MinValue)
.FirstOrDefault();
return traits.WithInterface<IIssueOrder>()
return TraitsImplementing<IIssueOrder>()
.Select( x => x.IssueOrder( this, xy, mi, underCursor ) )
.FirstOrDefault( x => x != null );
}
@@ -148,72 +138,14 @@ namespace OpenRA
if (useAltitude)
{
var unit = traits.GetOrDefault<Unit>();
if (unit != null) loc -= new float2(0, unit.Altitude);
var move = TraitOrDefault<IMove>();
if (move != null) loc -= new float2(0, move.Altitude);
}
return new RectangleF(loc.X, loc.Y, size.X, size.Y);
}
public bool IsDead { get { return Health <= 0; } }
public bool IsInWorld { get; set; }
public bool RemoveOnDeath = true;
public DamageState GetDamageState()
{
if (Health <= 0)
return DamageState.Dead;
if (Health < this.GetMaxHP() * World.Defaults.ConditionYellow)
return DamageState.Half;
return DamageState.Normal;
}
public void InflictDamage(Actor attacker, int damage, WarheadInfo warhead)
{
if (IsDead) return; /* overkill! don't count extra hits as more kills! */
var rawDamage = damage;
var oldState = GetDamageState();
/* apply the damage modifiers, if we have any. */
var modifier = (float)traits.WithInterface<IDamageModifier>()
.Select(t => t.GetDamageModifier(warhead)).Product();
damage = (int)(damage * modifier);
Health -= damage;
if (Health <= 0)
{
Health = 0;
attacker.Owner.Kills++;
Owner.Deaths++;
if (RemoveOnDeath)
World.AddFrameEndTask(w => w.Remove(this));
}
var maxHP = this.GetMaxHP();
if (Health > maxHP) Health = maxHP;
Log.Write("InflictDamage: {0} #{1} -> {2} #{3} raw={4} adj={5} hp={6} mod={7}",
attacker.Info.Name, attacker.ActorID, Info.Name, ActorID, rawDamage, damage, Health, modifier);
var newState = GetDamageState();
foreach (var nd in traits.WithInterface<INotifyDamage>())
nd.Damaged(this, new AttackInfo
{
Attacker = attacker,
Damage = damage,
DamageState = newState,
DamageStateChanged = newState != oldState,
Warhead = warhead
});
}
public bool IsInWorld { get; internal set; }
public void QueueActivity( IActivity nextActivity )
{
@@ -252,5 +184,47 @@ namespace OpenRA
var o = obj as Actor;
return ( o != null && o.ActorID == ActorID );
}
}
public override string ToString()
{
return "{0} {1}{2}".F( Info.Name, ActorID, IsInWorld ? "" : " (not in world)" );
}
public T Trait<T>()
{
return World.traitDict.Get<T>( this );
}
public T TraitOrDefault<T>()
{
return World.traitDict.GetOrDefault<T>( this );
}
public IEnumerable<T> TraitsImplementing<T>()
{
return World.traitDict.WithInterface<T>( this );
}
public bool HasTrait<T>()
{
return World.traitDict.Contains<T>( this );
}
public void AddTrait( object trait )
{
World.traitDict.AddTrait( this, trait );
}
public bool Destroyed { get; private set; }
public void Destroy()
{
World.AddFrameEndTask( w =>
{
World.Remove( this );
World.traitDict.RemoveActor( this );
Destroyed = true;
} );
}
}
}

134
OpenRA.Game/ActorInitializer.cs Executable file
View File

@@ -0,0 +1,134 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System.Linq;
using OpenRA.FileFormats;
namespace OpenRA
{
public class ActorInitializer
{
public readonly Actor self;
public World world { get { return self.World; } }
internal TypeDictionary dict;
public ActorInitializer( Actor actor, TypeDictionary dict )
{
this.self = actor;
this.dict = dict;
}
public T Get<T>()
where T : IActorInit
{
return dict.Get<T>();
}
public U Get<T,U>()
where T : IActorInit<U>
{
return dict.Get<T>().Value( world );
}
public bool Contains<T>()
where T : IActorInit
{
return dict.Contains<T>();
}
}
public interface IActorInit {}
public interface IActorInit<T> : IActorInit
{
T Value( World world );
}
public class FacingInit : IActorInit<int>
{
[FieldFromYamlKey]
public readonly int value = 128;
public FacingInit() { }
public FacingInit( int init )
{
value = init;
}
public int Value( World world )
{
return value;
}
}
public class AltitudeInit : IActorInit<int>
{
[FieldFromYamlKey]
public readonly int value = 0;
public AltitudeInit() { }
public AltitudeInit( int init )
{
value = init;
}
public int Value( World world )
{
return value;
}
}
public class LocationInit : IActorInit<int2>
{
[FieldFromYamlKey]
public readonly int2 value = int2.Zero;
public LocationInit() { }
public LocationInit( int2 init )
{
value = init;
}
public int2 Value( World world )
{
return value;
}
}
public class OwnerInit : IActorInit<Player>
{
[FieldFromYamlKey]
public readonly string PlayerName = "Neutral";
Player player;
public OwnerInit() { }
public OwnerInit( string playerName )
{
this.PlayerName = playerName;
}
public OwnerInit( Player player )
{
this.player = player;
this.PlayerName = player.InternalName;
}
public Player Value( World world )
{
if( player != null )
return player;
return world.players.Values.First( x => x.InternalName == PlayerName );
}
}
}

57
OpenRA.Game/ActorReference.cs Executable file
View File

@@ -0,0 +1,57 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System.Collections.Generic;
using System.Collections;
using System.IO;
namespace OpenRA.FileFormats
{
public class ActorReference : IEnumerable
{
public readonly string Type;
public readonly TypeDictionary InitDict;
public ActorReference( string type ) : this( type, new Dictionary<string, MiniYaml>() ) { }
public ActorReference( string type, Dictionary<string, MiniYaml> inits )
{
if (Rules.Info != null && !Rules.Info.ContainsKey(type))
throw new InvalidDataException("Unknown actor: `{0}'".F(type));
Type = type;
InitDict = new TypeDictionary();
foreach( var i in inits )
InitDict.Add( LoadInit( i.Key, i.Value ) );
}
static IActorInit LoadInit(string traitName, MiniYaml my)
{
var info = Game.CreateObject<IActorInit>(traitName + "Init");
FieldLoader.Load(info, my);
return info;
}
public MiniYaml Save()
{
var ret = new MiniYaml( Type );
foreach( var init in InitDict )
{
var initName = init.GetType().Name;
ret.NodesDict.Add( initName.Substring( 0, initName.Length - 4 ), FieldSaver.Save( init ) );
}
return ret;
}
// for initialization syntax
public void Add( object o ) { InitDict.Add( o ); }
public IEnumerator GetEnumerator() { return InitDict.GetEnumerator(); }
}
}

View File

@@ -1,80 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System.Collections.Generic;
using System.Drawing;
using OpenRA.FileFormats;
using OpenRA.Traits;
namespace OpenRA
{
class Chat
{
const int logLength = 10;
public List<ChatLine> recentLines = new List<ChatLine>();
public string typing = "";
public bool isChatting = true;
public bool isTeamChat = false;
public void Toggle()
{
if( isChatting && typing.Length > 0 )
Game.IssueOrder( isTeamChat ? Order.TeamChat( typing ) : Order.Chat( typing ) );
typing = "";
if( Game.orderManager.GameStarted )
isChatting ^= true;
}
public void Reset()
{
typing = "";
isChatting = false;
recentLines.Clear();
}
public void TypeChar(char c)
{
if (c == '\b' || c == 0x7f)
{
if (typing.Length > 0)
typing = typing.Remove(typing.Length - 1);
}
else if (!char.IsControl(c))
typing += c;
}
public void AddLine(Session.Client p, string text)
{
AddLine(Game.world.PlayerColors()[p.PaletteIndex].Color, p.Name, text);
}
public void AddLine(Color c, string from, string text)
{
recentLines.Add(new ChatLine { Color = c, Owner = from, Text = text });
var eva = Rules.Info["world"].Traits.Get<EvaAlertsInfo>();
Sound.Play(eva.ChatBeep);
while (recentLines.Count > logLength) recentLines.RemoveAt(0);
}
}
class ChatLine { public Color Color = Color.White; public string Owner, Text; }
}

View File

@@ -1,261 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA
{
class Chrome : IHandleInput
{
public readonly Renderer renderer;
public readonly LineRenderer lineRenderer;
SpriteRenderer rgbaRenderer { get { return renderer.RgbaSpriteRenderer; } }
SpriteRenderer shpRenderer { get { return renderer.WorldSpriteRenderer; } }
readonly List<Pair<RectangleF, Action<bool>>> buttons = new List<Pair<RectangleF, Action<bool>>>();
internal MapStub currentMap;
public Chrome(Renderer r, Manifest m)
{
this.renderer = r;
lineRenderer = new LineRenderer(renderer);
var widgetYaml = m.ChromeLayout.Select(a => MiniYaml.FromFile(a)).Aggregate(MiniYaml.Merge);
if (rootWidget == null)
{
rootWidget = WidgetLoader.LoadWidget( widgetYaml.FirstOrDefault() );
rootWidget.Initialize();
rootWidget.InitDelegates();
Widget.WindowList.Push("MAINMENU_BG");
}
}
public static Widget rootWidget = null;
public static Widget selectedWidget;
public void Tick(World world)
{
if (!world.GameHasStarted) return;
if (world.LocalPlayer == null) return;
++ticksSinceLastMove;
rootWidget.Tick(world);
}
public void Draw( World world )
{
buttons.Clear();
renderer.Device.DisableScissor();
var typingArea = new Rectangle(240, Game.viewport.Height - 30, Game.viewport.Width - 420, 30);
var chatLogArea = new Rectangle(240, Game.viewport.Height - 500, Game.viewport.Width - 420, 500 - 40);
DrawChat(typingArea, chatLogArea);
}
void AddUiButton(int2 pos, string text, Action<bool> a)
{
var rect = new Rectangle(pos.X - 160 / 2, pos.Y - 4, 160, 24);
DrawDialogBackground( rect, "dialog2");
DrawCentered(text, new int2(pos.X, pos.Y), Color.White);
rgbaRenderer.Flush();
AddButton(rect, a);
}
public void DrawMapChooser()
{
buttons.Clear();
var w = 800;
var h = 600;
var r = new Rectangle( (Game.viewport.Width - w) / 2, (Game.viewport.Height - h) / 2, w, h );
AddUiButton(new int2(r.Left + 200, r.Bottom - 40), "OK",
_ =>
{
Game.IssueOrder(Order.Chat("/map " + currentMap.Uid));
Chrome.rootWidget.CloseWindow();
});
AddUiButton(new int2(r.Right - 200, r.Bottom - 40), "Cancel",
_ =>
{
Chrome.rootWidget.CloseWindow();
});
var mapContainer = new Rectangle(r.Right - 280, r.Top + 30, 256, 256);
var y = r.Top + 50;
// Don't bother showing a subset of the data
// This will be fixed properly when we move the map list to widgets
foreach (var kv in Game.AvailableMaps)
{
var map = kv.Value;
if (!map.Selectable)
continue;
var itemRect = new Rectangle(r.Left + 50, y - 2, r.Width - 340, 20);
if (map == currentMap)
{
rgbaRenderer.Flush();
DrawDialogBackground(itemRect, "dialog2");
}
renderer.RegularFont.DrawText(map.Title, new int2(r.Left + 60, y), Color.White);
rgbaRenderer.Flush();
var closureMap = map;
AddButton(itemRect, _ => { currentMap = closureMap; });
y += 20;
}
y = mapContainer.Bottom + 20;
DrawCentered("Title: {0}".F(currentMap.Title),
new int2(mapContainer.Left + mapContainer.Width / 2, y), Color.White);
y += 20;
DrawCentered("Size: {0}x{1}".F(currentMap.Width, currentMap.Height),
new int2(mapContainer.Left + mapContainer.Width / 2, y), Color.White);
y += 20;
var theaterInfo = Rules.Info["world"].Traits.WithInterface<TheaterInfo>().FirstOrDefault(t => t.Theater == currentMap.Tileset);
DrawCentered("Theater: {0}".F(theaterInfo.Name),
new int2(mapContainer.Left + mapContainer.Width / 2, y), Color.White);
y += 20;
DrawCentered("Spawnpoints: {0}".F(currentMap.PlayerCount),
new int2(mapContainer.Left + mapContainer.Width / 2, y), Color.White);
AddButton(r, _ => { });
}
public void DrawWidgets(World world) { rootWidget.Draw(world); shpRenderer.Flush(); rgbaRenderer.Flush(); lineRenderer.Flush(); }
public void DrawLobby()
{
buttons.Clear();
if( Game.LobbyInfo.GlobalSettings.Map == null )
currentMap = null;
else
currentMap = Game.AvailableMaps[ Game.LobbyInfo.GlobalSettings.Map ];
var w = 800;
var h = 600;
var r = new Rectangle( (Game.viewport.Width - w) / 2, (Game.viewport.Height - h) / 2, w, h );
var typingBox = new Rectangle(r.Left + 20, r.Bottom - 77, r.Width - 40, 27);
var chatBox = new Rectangle(r.Left + 20, r.Bottom - 269, r.Width - 40, 190);
DrawDialogBackground(typingBox, "dialog2");
DrawDialogBackground(chatBox, "dialog3");
DrawChat(typingBox, chatBox);
}
void AddButton(RectangleF r, Action<bool> b) { buttons.Add(Pair.New(r, b)); }
void DrawDialogBackground(Rectangle r, string collection)
{
WidgetUtils.DrawPanel(collection, r);
}
void DrawChat(Rectangle typingArea, Rectangle chatLogArea)
{
var chatpos = new int2(chatLogArea.X + 10, chatLogArea.Bottom - 6);
renderer.Device.EnableScissor(typingArea.Left, typingArea.Top, typingArea.Width, typingArea.Height);
if (Game.chat.isChatting)
RenderChatLine(new ChatLine { Owner = Game.chat.isTeamChat ? "TeamChat:" : "Chat:", Text = Game.chat.typing },
new int2(typingArea.X + 10, typingArea.Y + 6));
rgbaRenderer.Flush();
renderer.Device.DisableScissor();
renderer.Device.EnableScissor(chatLogArea.Left, chatLogArea.Top, chatLogArea.Width, chatLogArea.Height);
foreach (var line in Game.chat.recentLines.AsEnumerable().Reverse())
{
chatpos.Y -= 20;
RenderChatLine(line, chatpos);
}
rgbaRenderer.Flush();
renderer.Device.DisableScissor();
}
void RenderChatLine(ChatLine line, int2 p)
{
var size = renderer.RegularFont.Measure(line.Owner);
renderer.RegularFont.DrawText(line.Owner, p, line.Color);
renderer.RegularFont.DrawText(line.Text, p + new int2(size.X + 10, 0), Color.White);
}
public int ticksSinceLastMove = 0;
public int2 lastMousePos;
public bool HandleInput(World world, MouseInput mi)
{
if (selectedWidget != null)
return selectedWidget.HandleInput(mi);
if (rootWidget.HandleInput(mi))
return true;
if (mi.Event == MouseInputEvent.Move)
{
lastMousePos = mi.Location;
ticksSinceLastMove = 0;
}
var action = buttons.Where(a => a.First.Contains(mi.Location.ToPoint()))
.Select(a => a.Second).FirstOrDefault();
if (action == null)
return false;
if (mi.Event == MouseInputEvent.Down)
action(mi.Button == MouseButton.Left);
return true;
}
public bool HitTest(int2 mousePos)
{
if (selectedWidget != null)
return true;
return rootWidget.HitTest(mousePos)
|| buttons.Any(a => a.First.Contains(mousePos.ToPoint()));
}
void DrawCentered(string text, int2 pos, Color c)
{
renderer.BoldFont.DrawText(text, pos - new int2(renderer.BoldFont.Measure(text).X / 2, 0), c);
}
}
}

View File

@@ -1,193 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System;
using System.Linq;
using OpenRA.Effects;
using OpenRA.GameRules;
using OpenRA.Traits;
using OpenRA.FileFormats;
namespace OpenRA
{
public static class Combat /* some utility bits that are shared between various things */
{
static string GetImpactSound(WarheadInfo warhead, bool isWater)
{
if (isWater && warhead.WaterImpactSound != null)
return warhead.WaterImpactSound + ".aud";
if (warhead.ImpactSound != null)
return warhead.ImpactSound + ".aud";
return null;
}
public static void DoImpact(WarheadInfo warhead, ProjectileArgs args)
{
var world = args.firedBy.World;
var targetTile = ((1f / Game.CellSize) * args.dest.ToFloat2()).ToInt2();
var isWater = world.GetTerrainType(targetTile) == TerrainType.Water;
if (warhead.Explosion != 0)
world.AddFrameEndTask(
w => w.Add(new Explosion(w, args.dest, warhead.Explosion, isWater)));
Sound.Play(GetImpactSound(warhead, isWater), args.dest);
if (warhead.SmudgeType != null)
{
var smudgeLayer = world.WorldActor.traits.WithInterface<SmudgeLayer>()
.FirstOrDefault(x => x.Info.Type == warhead.SmudgeType);
if (smudgeLayer == null)
throw new NotImplementedException("Unknown smudge type `{0}`".F(warhead.SmudgeType));
if (warhead.Size[0] > 0)
{
var smudgeCells = world.FindTilesInCircle(targetTile, warhead.Size[0])
.Except(world.FindTilesInCircle(targetTile, warhead.Size[1]));
foreach (var sc in smudgeCells)
smudgeLayer.AddSmudge(sc);
}
else
smudgeLayer.AddSmudge(targetTile);
}
if (warhead.Ore)
world.WorldActor.traits.Get<ResourceLayer>().Destroy(targetTile);
var firepowerModifier = args.firedBy.traits
.WithInterface<IFirepowerModifier>()
.Select(a => a.GetFirepowerModifier())
.Product();
switch (warhead.DamageModel)
{
case DamageModel.Normal:
{
var maxSpread = warhead.Spread * (float)Math.Log(Math.Abs(warhead.Damage), 2);
var hitActors = world.FindUnitsInCircle(args.dest, maxSpread);
foreach (var victim in hitActors)
{
var damage = (int)GetDamageToInflict(victim, args, warhead, firepowerModifier);
victim.InflictDamage(args.firedBy, damage, warhead);
}
} break;
case DamageModel.PerCell:
{
foreach (var t in world.FindTilesInCircle(targetTile, warhead.Size[0]))
foreach (var unit in world.FindUnits(Game.CellSize * t, Game.CellSize * (t + new float2(1,1))))
unit.InflictDamage(args.firedBy,
(int)(warhead.Damage * warhead.EffectivenessAgainst(
unit.Info.Traits.Get<OwnedActorInfo>().Armor)), warhead);
} break;
}
}
public static void DoImpacts(ProjectileArgs args)
{
foreach (var warhead in args.weapon.Warheads)
{
Action a = () => DoImpact(warhead, args);
if (warhead.Delay > 0)
args.firedBy.World.AddFrameEndTask(
w => w.Add(new DelayedAction(warhead.Delay, a)));
else
a();
}
}
public static void DoExplosion(Actor attacker, string weapontype, int2 location, int altitude)
{
var args = new ProjectileArgs
{
src = location,
dest = location,
srcAltitude = altitude,
destAltitude = altitude,
firedBy = attacker,
target = null,
weapon = Rules.Weapons[ weapontype.ToLowerInvariant() ],
facing = 0
};
DoImpacts(args);
}
static readonly float[] falloff =
{
1f, 0.3678795f, 0.1353353f, 0.04978707f,
0.01831564f, 0.006737947f, 0.002478752f, 0.000911882f
};
static float GetDamageFalloff(float x)
{
var u = (int)x;
if (u >= falloff.Length - 1) return 0;
var t = x - u;
return (falloff[u] * (1 - t)) + (falloff[u + 1] * t);
}
static float GetDamageToInflict(Actor target, ProjectileArgs args, WarheadInfo warhead, float modifier)
{
// don't hit air units with splash from ground explosions, etc
if (!WeaponValidForTarget(args.weapon, target)) return 0f;
var selectable = target.Info.Traits.GetOrDefault<SelectableInfo>();
var radius = selectable != null ? selectable.Radius : 0;
var distance = (int)Math.Max(0, (target.CenterLocation - args.dest).Length - radius);
var falloff = (float)GetDamageFalloff(distance / warhead.Spread);
var rawDamage = (float)(warhead.Damage * modifier * falloff);
var multiplier = (float)warhead.EffectivenessAgainst(target.Info.Traits.Get<OwnedActorInfo>().Armor);
return (float)(rawDamage * multiplier);
}
public static bool WeaponValidForTarget(WeaponInfo weapon, Actor target)
{
var ownedInfo = target.Info.Traits.GetOrDefault<OwnedActorInfo>();
if (!weapon.ValidTargets.Contains(ownedInfo.TargetType))
return false;
if (weapon.Warheads.All( w => w.EffectivenessAgainst(ownedInfo.Armor) <= 0))
return false;
if (weapon.Underwater && !ownedInfo.WaterBound)
return false;
return true;
}
public static bool HasAnyValidWeapons(Actor self, Actor target)
{
var info = self.Info.Traits.Get<AttackBaseInfo>();
if (info.PrimaryWeapon != null &&
WeaponValidForTarget(self.GetPrimaryWeapon(), target)) return true;
if (info.SecondaryWeapon != null &&
WeaponValidForTarget(self.GetSecondaryWeapon(), target)) return true;
return false;
}
}
}

View File

@@ -1,167 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Orders;
using OpenRA.Traits;
namespace OpenRA
{
public class Controller : IHandleInput
{
public IOrderGenerator orderGenerator = new UnitOrderGenerator();
public Selection selection = new Selection();
public void CancelInputMode() { orderGenerator = new UnitOrderGenerator(); }
public bool ToggleInputMode<T>() where T : IOrderGenerator, new()
{
if (orderGenerator is T)
{
CancelInputMode();
return false;
}
else
{
orderGenerator = new T();
return true;
}
}
void ApplyOrders(World world, float2 xy, MouseInput mi)
{
if (orderGenerator == null) return;
var orders = orderGenerator.Order(world, xy.ToInt2(), mi).ToArray();
Game.orderManager.IssueOrders( orders );
var voicedActor = orders.Select(o => o.Subject)
.FirstOrDefault(a => a.Owner == world.LocalPlayer && a.traits.Contains<Unit>());
var isMove = orders.Any(o => o.OrderString == "Move");
var isAttack = orders.Any( o => o.OrderString == "Attack" );
if (voicedActor != null)
{
if(voicedActor.traits.GetOrDefault<IMovement>().CanEnterCell(xy.ToInt2()))
Sound.PlayVoice(isAttack ? "Attack" : "Move", voicedActor);
if (isMove)
world.Add(new Effects.MoveFlash(world, Game.CellSize * xy));
}
}
float2 dragStart, dragEnd;
public bool HandleInput(World world, MouseInput mi)
{
var xy = Game.viewport.ViewToWorld(mi);
if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down)
{
dragStart = dragEnd = xy;
ApplyOrders(world, xy, mi);
}
if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Move)
dragEnd = xy;
if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up)
{
if (orderGenerator is UnitOrderGenerator)
{
var newSelection = world.SelectActorsInBox(Game.CellSize * dragStart, Game.CellSize * xy);
selection.Combine(world, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy);
}
dragStart = dragEnd = xy;
}
if (mi.Button == MouseButton.None && mi.Event == MouseInputEvent.Move)
dragStart = dragEnd = xy;
if (mi.Button == MouseButton.Right && mi.Event == MouseInputEvent.Down)
ApplyOrders(world, xy, mi);
return true;
}
public Pair<float2, float2>? SelectionBox
{
get
{
if (dragStart == dragEnd) return null;
return Pair.New(Game.CellSize * dragStart, Game.CellSize * dragEnd);
}
}
public float2 MousePosition { get { return dragEnd; } }
Modifiers modifiers;
public string ChooseCursor( World world )
{
int sync = world.SyncHash();
try
{
if (!world.GameHasStarted)
return "default";
var mi = new MouseInput
{
Location = ( Game.CellSize * MousePosition - Game.viewport.Location ).ToInt2(),
Button = MouseButton.Right,
Modifiers = modifiers
};
return orderGenerator.GetCursor( world, MousePosition.ToInt2(), mi );
}
finally
{
if( sync != world.SyncHash() )
throw new InvalidOperationException( "Desync in Controller.ChooseCursor" );
}
}
public void SetModifiers(Modifiers mods) { modifiers = mods; }
public Modifiers GetModifiers() { return modifiers; }
public void GotoNextBase()
{
var bases = Game.world.Queries.OwnedBy[Game.world.LocalPlayer].WithTrait<BaseBuilding>().ToArray();
if (!bases.Any()) return;
var next = bases
.Select( b => b.Actor )
.SkipWhile(b => Game.controller.selection.Actors.Contains(b))
.Skip(1)
.FirstOrDefault();
if (next == null)
next = bases.Select(b => b.Actor).First();
Game.controller.selection.Combine(Game.world, new Actor[] { next }, false, true);
Game.viewport.Center(Game.controller.selection.Actors);
}
}
}

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
@@ -29,8 +19,10 @@ namespace OpenRA
{
sequence = SequenceProvider.GetCursorSequence(cursor);
}
public Sprite GetSprite(int frame) { return sequence.GetSprite(frame); }
public int2 GetHotspot() { return sequence.Hotspot; }
public void Draw(int frame, float2 pos)
{
Game.Renderer.SpriteRenderer.DrawSprite(sequence.GetSprite(frame), pos - sequence.Hotspot, sequence.Palette);
}
}
}

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,50 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System.Collections.Generic;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Effects
{
public class Explosion : IEffect
{
Animation anim;
int2 pos;
public Explosion(World world, int2 pixelPos, int style, bool isWater)
{
this.pos = pixelPos;
var variantSuffix = isWater ? "w" : "";
anim = new Animation("explosion");
anim.PlayThen(style.ToString() + variantSuffix,
() => world.AddFrameEndTask(w => w.Remove(this)));
}
public void Tick( World world ) { anim.Tick(); }
public IEnumerable<Renderable> Render()
{
yield return new Renderable(anim.Image, pos - .5f * anim.Image.size, "effect");
}
public Player Owner { get { return null; } }
}
}

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
@@ -24,7 +14,7 @@ using OpenRA.Traits;
namespace OpenRA.Effects
{
class FlashTarget : IEffect
public class FlashTarget : IEffect
{
Actor target;
int remainingTicks = 4;
@@ -38,12 +28,15 @@ namespace OpenRA.Effects
public void Tick( World world )
{
if (--remainingTicks == 0)
if (--remainingTicks == 0 || !target.IsInWorld)
world.AddFrameEndTask(w => w.Remove(this));
}
public IEnumerable<Renderable> Render()
{
if (!target.IsInWorld)
yield break;
if (remainingTicks % 2 == 0)
foreach (var r in target.Render())
yield return r.WithPalette("highlight");

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
@@ -24,11 +14,20 @@ using OpenRA.Traits;
namespace OpenRA.Effects
{
class MoveFlash : IEffect
public class MoveFlash : IEffect
{
Animation anim = new Animation("moveflsh");
float2 pos;
public MoveFlash( World world, int2 cell )
{
this.pos = Game.CellSize * (cell + new float2(0.5f, 0.5f));
anim.PlayThen( "idle",
() => world.AddFrameEndTask(
w => w.Remove( this ) ) );
}
public MoveFlash( World world, float2 pos )
{
this.pos = pos;

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
@@ -33,12 +23,12 @@ namespace OpenRA.Effects
public RepairIndicator(Actor a)
{
this.a = a; anim.PlayRepeating("repair");
framesLeft = (int)(a.World.Defaults.RepairRate * 25 * 60 / 2);
framesLeft = (int)(a.Info.Traits.Get<RepairableBuildingInfo>().RepairRate * 25 * 60 / 2);
}
public void Tick( World world )
{
if (--framesLeft == 0 || a.IsDead)
if (--framesLeft == 0 || a.IsDead())
world.AddFrameEndTask(w => w.Remove(this));
}

View File

@@ -1,50 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System.Collections.Generic;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Effects
{
class Smoke : IEffect
{
readonly int2 pos;
readonly Animation anim;
public Smoke(World world, int2 pos, string trail)
{
this.pos = pos;
anim = new Animation(trail);
anim.PlayThen("idle",
() => world.AddFrameEndTask(w => w.Remove(this)));
}
public void Tick( World world )
{
anim.Tick();
}
public IEnumerable<Renderable> Render()
{
yield return new Renderable(anim.Image, pos - .5f * anim.Image.size, "effect");
}
}
}

View File

@@ -1,29 +1,18 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.GameRules;
using OpenRA.Traits;
using OpenRA.Support;
using OpenRA.Traits;
namespace OpenRA
{
@@ -45,35 +34,6 @@ namespace OpenRA
return xs.Aggregate(1f, (a, x) => a * x);
}
public static WeaponInfo GetPrimaryWeapon(this Actor self)
{
var info = self.Info.Traits.GetOrDefault<AttackBaseInfo>();
if (info == null) return null;
var weapon = info.PrimaryWeapon;
if (weapon == null) return null;
return Rules.Weapons[weapon.ToLowerInvariant()];
}
public static WeaponInfo GetSecondaryWeapon(this Actor self)
{
var info = self.Info.Traits.GetOrDefault<AttackBaseInfo>();
if (info == null) return null;
var weapon = info.SecondaryWeapon;
if (weapon == null) return null;
return Rules.Weapons[weapon.ToLowerInvariant()];
}
public static int GetMaxHP(this Actor self)
{
var oai = self.Info.Traits.GetOrDefault<OwnedActorInfo>();
if (oai == null) return 0;
return oai.HP;
}
public static V GetOrAdd<K, V>( this Dictionary<K, V> d, K k )
where V : new()
{
@@ -104,7 +64,7 @@ namespace OpenRA
a( x );
var dt = sw.ElapsedTime() - t;
if( dt > time )
Log.Write( text, x, dt*1000 );
Log.Write("perf", text, x, dt * 1000);
} );
}
}

View File

@@ -1,41 +1,28 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms;
using OpenRA.FileFormats;
using OpenRA.GameRules;
using OpenRA.Graphics;
using OpenRA.Network;
using OpenRA.Server;
using OpenRA.Support;
using OpenRA.Traits;
using OpenRA.Widgets;
using Timer = OpenRA.Support.Timer;
using OpenRA.GameRules;
using OpenRA.Graphics;
using OpenRA.Network;
using OpenRA.Server;
using OpenRA.Support;
using OpenRA.Traits;
using OpenRA.Widgets;
using Timer = OpenRA.Support.Timer;
using XRandom = OpenRA.Thirdparty.Random;
namespace OpenRA
@@ -44,122 +31,27 @@ namespace OpenRA
{
public static readonly int CellSize = 24;
public static ModData modData;
public static World world;
internal static Viewport viewport;
public static Controller controller;
internal static Chrome chrome;
internal static UserSettings Settings;
public static Viewport viewport;
public static Settings Settings;
internal static OrderManager orderManager;
public static bool skipMakeAnims = true;
public static XRandom CosmeticRandom = new XRandom(); // not synced
internal static Renderer renderer;
static int2 clientSize;
static string mapName;
public static Renderer Renderer;
public static Session LobbyInfo = new Session();
static bool packageChangePending;
static bool mapChangePending;
static Pair<Assembly, string>[] ModAssemblies;
static void LoadModPackages(Manifest manifest)
static void LoadMap(string uid)
{
FileSystem.UnmountAll();
Timer.Time("reset: {0}");
foreach (var dir in manifest.Folders) FileSystem.Mount(dir);
foreach (var pkg in manifest.Packages) FileSystem.Mount(pkg);
Timer.Time("mount temporary packages: {0}");
}
public static void LoadModAssemblies(Manifest m)
{
// All the core namespaces
var asms = typeof(Game).Assembly.GetNamespaces()
.Select(c => Pair.New(typeof(Game).Assembly, c))
.ToList();
// Namespaces from each mod assembly
foreach (var a in m.Assemblies)
{
var asm = Assembly.LoadFile(Path.GetFullPath(a));
asms.AddRange(asm.GetNamespaces().Select(ns => Pair.New(asm, ns)));
}
ModAssemblies = asms.ToArray();
}
public static T CreateObject<T>(string classname)
{
foreach (var mod in ModAssemblies)
{
var fullTypeName = mod.Second + "." + classname;
var obj = mod.First.CreateInstance(fullTypeName);
if (obj != null)
return (T)obj;
}
throw new InvalidOperationException("Cannot locate type: {0}".F(classname));
}
public static Dictionary<string, MapStub> AvailableMaps;
// TODO: Do this nicer
static Dictionary<string, MapStub> FindMaps(string[] mods)
{
Console.WriteLine("Finding maps");
foreach (var mod in mods)
Console.WriteLine(mod);
var paths = new[] { "maps/" }.Concat(mods.Select(m => "mods/" + m + "/maps/"))
.Where(p => Directory.Exists(p))
.SelectMany(p => Directory.GetDirectories(p)).ToList();
return paths.Select(p => new MapStub(new Folder(p))).ToDictionary(m => m.Uid);
}
static void ChangeMods()
{
Timer.Time("----ChangeMods");
var manifest = new Manifest(LobbyInfo.GlobalSettings.Mods);
Timer.Time("manifest: {0}");
LoadModAssemblies(manifest);
SheetBuilder.Initialize(renderer);
LoadModPackages(manifest);
Timer.Time("load assemblies, packages: {0}");
packageChangePending = false;
}
static void LoadMap(string mapName)
{
Timer.Time("----LoadMap");
SheetBuilder.Initialize(renderer);
var manifest = new Manifest(LobbyInfo.GlobalSettings.Mods);
Timer.Time("manifest: {0}");
if (!Game.AvailableMaps.ContainsKey(mapName))
throw new InvalidDataException("Cannot find map with Uid {0}".F(mapName));
var map = new Map(Game.AvailableMaps[mapName].Package);
viewport = new Viewport(clientSize, map.TopLeft, map.BottomRight, renderer);
var map = modData.PrepareMap(uid);
viewport = new Viewport(new float2(Renderer.Resolution), map.TopLeft, map.BottomRight, Renderer);
world = null; // trying to access the old world will NRE, rather than silently doing it wrong.
ChromeProvider.Initialize(manifest.Chrome);
Timer.Time("viewport, ChromeProvider: {0}");
world = new World(manifest, map);
Timer.Time("viewport: {0}");
world = new World(modData.Manifest, map);
Timer.Time("world: {0}");
SequenceProvider.Initialize(manifest.Sequences);
Timer.Time("ChromeProv, SeqProv: {0}");
chrome = new Chrome(renderer, manifest);
Timer.Time("chrome: {0}");
Timer.Time("----end LoadMap");
Debug("Map change {0} -> {1}".F(Game.mapName, mapName));
}
public static void MoveViewport(int2 loc)
@@ -177,6 +69,9 @@ namespace OpenRA
CurrentHost = host;
CurrentPort = port;
lastConnectionState = ConnectionState.PreConnecting;
ConnectionStateChanged();
orderManager = new OrderManager(new NetworkConnection(host, port), ChooseReplayFilename());
}
@@ -187,6 +82,9 @@ namespace OpenRA
static void JoinLocal()
{
lastConnectionState = ConnectionState.PreConnecting;
ConnectionStateChanged();
if (orderManager != null) orderManager.Dispose();
orderManager = new OrderManager(new EchoConnection());
}
@@ -199,91 +97,29 @@ namespace OpenRA
}
internal static int RenderFrame = 0;
internal static Chat chat = new Chat();
internal static int LocalTick = 0;
const int NetTickScale = 3; // 120ms net tick for 40ms local tick
static Queue<Pair<int, string>> syncReports = new Queue<Pair<int, string>>();
const int numSyncReports = 5;
internal static void UpdateSyncReport()
{
if (!Settings.RecordSyncReports)
return;
while (syncReports.Count >= numSyncReports) syncReports.Dequeue();
syncReports.Enqueue(Pair.New(orderManager.FrameNumber, GenerateSyncReport()));
}
static string GenerateSyncReport()
{
var sb = new StringBuilder();
sb.AppendLine("Actors:");
foreach (var a in world.Actors)
sb.AppendLine("\t {0} {1} {2} ({3})".F(
a.ActorID,
a.Info.Name,
(a.Owner == null) ? "null" : a.Owner.InternalName,
Sync.CalculateSyncHash(a)));
sb.AppendLine("Tick Actors:");
foreach (var a in world.Queries.WithTraitMultiple<object>())
{
var sync = Sync.CalculateSyncHash(a.Trait);
if (sync != 0)
sb.AppendLine("\t {0} {1} {2} {3} ({4})".F(
a.Actor.ActorID,
a.Actor.Info.Name,
(a.Actor.Owner == null) ? "null" : a.Actor.Owner.InternalName,
a.Trait.GetType().Name,
sync));
}
return sb.ToString();
}
internal static void DumpSyncReport(int frame)
{
var f = syncReports.FirstOrDefault(a => a.First == frame);
if (f == null)
{
Log.Write("No sync report available!");
return;
}
Log.Write("Sync for net frame {0} -------------", f.First);
Log.Write("{0}", f.Second);
}
public static event Action ConnectionStateChanged = () => { };
static ConnectionState lastConnectionState = ConnectionState.PreConnecting;
public static int LocalClientId { get { return orderManager.Connection.LocalClientId; } }
static void Tick()
{
if (packageChangePending)
{
// TODO: Only do this on mod change
Timer.Time("----begin maplist");
AvailableMaps = FindMaps(LobbyInfo.GlobalSettings.Mods);
Timer.Time("maplist: {0}");
ChangeMods();
return;
}
if (mapChangePending)
{
mapName = LobbyInfo.GlobalSettings.Map;
mapChangePending = false;
return;
}
if (orderManager.Connection.ConnectionState != lastConnectionState)
{
lastConnectionState = orderManager.Connection.ConnectionState;
ConnectionStateChanged();
}
int t = Environment.TickCount;
int dt = t - lastTime;
if (dt >= Settings.Timestep)
if (dt >= Settings.Game.Timestep)
{
using (new PerfSample("tick_time"))
{
lastTime += Settings.Timestep;
chrome.Tick(world);
lastTime += Settings.Game.Timestep;
Widget.DoTick(world);
orderManager.TickImmediate(world);
@@ -295,9 +131,8 @@ namespace OpenRA
if (isNetTick) orderManager.Tick(world);
controller.orderGenerator.Tick(world);
controller.selection.Tick(world);
world.OrderGenerator.Tick(world);
world.Selection.Tick(world);
world.Tick();
PerfHistory.Tick();
@@ -327,33 +162,10 @@ namespace OpenRA
internal static void SyncLobbyInfo(string data)
{
var oldLobbyInfo = LobbyInfo;
LobbyInfo = Session.Deserialize(data);
var session = new Session();
session.GlobalSettings.Mods = Settings.InitialMods;
var ys = MiniYaml.FromString(data);
foreach (var y in ys)
{
if (y.Key == "GlobalSettings")
{
FieldLoader.Load(session.GlobalSettings, y.Value);
continue;
}
int index;
if (!int.TryParse(y.Key, out index))
continue; // not a player.
var client = new Session.Client();
FieldLoader.Load(client, y.Value);
session.Clients.Add(client);
}
LobbyInfo = session;
if (!world.GameHasStarted)
world.SharedRandom = new OpenRA.Thirdparty.Random(LobbyInfo.GlobalSettings.RandomSeed);
if( !world.GameHasStarted )
world.SharedRandom = new XRandom( LobbyInfo.GlobalSettings.RandomSeed );
if (orderManager.Connection.ConnectionState == ConnectionState.Connected)
world.SetLocalPlayer(orderManager.Connection.LocalClientId);
@@ -365,97 +177,48 @@ namespace OpenRA
Debug("Order lag is now {0} frames.".F(LobbyInfo.GlobalSettings.OrderLatency));
}
if (mapName != LobbyInfo.GlobalSettings.Map)
mapChangePending = true;
if (string.Join(",", oldLobbyInfo.GlobalSettings.Mods)
!= string.Join(",", LobbyInfo.GlobalSettings.Mods))
{
Debug("Mods list changed, reloading: {0}".F(string.Join(",", LobbyInfo.GlobalSettings.Mods)));
packageChangePending = true;
}
LobbyInfoChanged();
}
public static void IssueOrder(Order o) { orderManager.IssueOrder(o); } /* avoid exposing the OM to mod code */
static void LoadShellMap(string map)
public static event Action AfterGameStart = () => {};
public static event Action BeforeGameStart = () => {};
internal static void StartGame(string map)
{
BeforeGameStart();
LoadMap(map);
world.Queries = new World.AllQueries(world);
foreach (var gs in world.WorldActor.traits.WithInterface<IGameStarted>())
gs.GameStarted(world);
orderManager.StartGame();
}
internal static void StartGame()
{
LoadMap(LobbyInfo.GlobalSettings.Map);
if (orderManager.GameStarted) return;
chat.Reset();
Widget.SelectedWidget = null;
world.Queries = new World.AllQueries(world);
foreach (var gs in world.WorldActor.traits.WithInterface<IGameStarted>())
gs.GameStarted(world);
viewport.GoToStartLocation(world.LocalPlayer);
orderManager.StartGame();
orderManager.StartGame();
viewport.RefreshPalette();
AfterGameStart();
}
public static Stance ChooseInitialStance(Player p, Player q)
{
if (p == q) return Stance.Ally;
// Hack: All map players are neutral wrt everyone else
if (p.Index < 0 || q.Index < 0) return Stance.Neutral;
var pc = GetClientForPlayer(p);
var qc = GetClientForPlayer(q);
return pc.Team != 0 && pc.Team == qc.Team
? Stance.Ally : Stance.Enemy;
}
static Session.Client GetClientForPlayer(Player p)
{
return LobbyInfo.Clients.Single(c => c.Index == p.Index);
}
static int2 lastPos;
public static void DispatchMouseInput(MouseInputEvent ev, MouseEventArgs e, Modifiers modifierKeys)
{
if (world == null)
return;
int sync = world.SyncHash();
var initialWorld = world;
if (ev == MouseInputEvent.Down)
lastPos = new int2(e.Location);
if (ev == MouseInputEvent.Move &&
(e.Button == MouseButtons.Middle ||
e.Button == (MouseButtons.Left | MouseButtons.Right)))
var mi = new MouseInput
{
var p = new int2(e.Location);
viewport.Scroll(lastPos - p);
lastPos = p;
}
viewport.DispatchMouseInput(world,
new MouseInput
{
Button = (MouseButton)(int)e.Button,
Event = ev,
Location = new int2(e.Location),
Modifiers = modifierKeys,
});
Button = (MouseButton)(int)e.Button,
Event = ev,
Location = new int2(e.Location),
Modifiers = modifierKeys,
};
Widget.HandleInput(world, mi);
if (sync != world.SyncHash() && world == initialWorld)
throw new InvalidOperationException("Desync in DispatchMouseInput");
}
internal static bool IsHost
public static bool IsHost
{
get { return orderManager.Connection.LocalClientId == 0; }
}
@@ -465,120 +228,59 @@ namespace OpenRA
get { return LobbyInfo.Clients.FirstOrDefault(c => c.Index == orderManager.Connection.LocalClientId); }
}
static Dictionary<char, char> RemapKeys = new Dictionary<char, char>
public static void HandleKeyEvent(KeyInput e)
{
{ '!', '1' },
{ '@', '2' },
{ '#', '3' },
{ '$', '4' },
{ '%', '5' },
{ '^', '6' },
{ '&', '7' },
{ '*', '8' },
{ '(', '9' },
{ ')', '0' },
};
public static void HandleKeyPress(KeyPressEventArgs e, Modifiers modifiers)
{
int sync = world.SyncHash();
if (e.KeyChar == '\r')
{
chat.Toggle();
chat.isTeamChat = modifiers.HasModifier(Modifiers.Shift);
}
else if (Game.chat.isChatting)
chat.TypeChar(e.KeyChar);
else
{
var c = RemapKeys.ContainsKey(e.KeyChar) ? RemapKeys[e.KeyChar] : e.KeyChar;
if (c >= '0' && c <= '9')
Game.controller.selection.DoControlGroup(world,
c - '0', modifiers);
if (c == 08)
Game.controller.GotoNextBase();
if (c == 09)
BuildPaletteWidget.TabChange((Control.ModifierKeys & Keys.Shift) == Keys.Shift ? true : false);
BuildPaletteWidget.DoBuildingHotkey(c, world);
}
if (world == null)
return;
int sync = world.SyncHash();
if (Widget.HandleKeyPress(e))
return;
if (sync != Game.world.SyncHash())
throw new InvalidOperationException("Desync in OnKeyPress");
}
public static void HandleModifierKeys(Modifiers mods)
static Modifiers modifiers;
public static Modifiers GetModifierKeys() { return modifiers; }
public static void HandleModifierKeys(Modifiers mods) { modifiers = mods; }
internal static void Initialize(Arguments args)
{
controller.SetModifiers(mods);
}
static Size GetResolution(Settings settings)
{
var desktopResolution = Screen.PrimaryScreen.Bounds.Size;
if (Settings.Width > 0 && Settings.Height > 0)
{
desktopResolution.Width = Settings.Width;
desktopResolution.Height = Settings.Height;
}
return new Size(
desktopResolution.Width,
desktopResolution.Height);
}
internal static void Initialize(Settings settings)
{
AppDomain.CurrentDomain.AssemblyResolve += FileSystem.ResolveAssembly;
LoadUserSettings(settings);
LobbyInfo.GlobalSettings.Mods = Settings.InitialMods;
// Load the default mod to access required files
LoadModPackages(new Manifest(LobbyInfo.GlobalSettings.Mods));
Renderer.SheetSize = Settings.SheetSize;
bool windowed = !Game.Settings.Fullscreen;
var resolution = GetResolution(settings);
renderer = new Renderer(resolution, windowed);
resolution = renderer.Resolution;
controller = new Controller();
clientSize = new int2(resolution);
AppDomain.CurrentDomain.AssemblyResolve += FileSystem.ResolveAssembly;
var defaultSupport = Environment.GetFolderPath(Environment.SpecialFolder.Personal)
+ Path.DirectorySeparatorChar + "OpenRA";
SupportDir = args.GetValue("SupportDir", defaultSupport);
Settings = new Settings(SupportDir + "settings.yaml", args);
Log.LogPath = SupportDir + "Logs" + Path.DirectorySeparatorChar;
Log.AddChannel("perf", "perf.log");
Log.AddChannel("debug", "debug.log");
Log.AddChannel("sync", "syncreport.log");
FileSystem.Mount("."); // Needed to access shaders
Renderer.Initialize( Game.Settings.Graphics.Mode );
Renderer.SheetSize = Settings.Game.SheetSize;
Renderer = new Renderer();
LobbyInfo.GlobalSettings.Mods = Settings.Game.Mods;
modData = new ModData( LobbyInfo.GlobalSettings.Mods );
Sound.Initialize();
PerfHistory.items["render"].hasNormalTick = false;
PerfHistory.items["batches"].hasNormalTick = false;
PerfHistory.items["text"].hasNormalTick = false;
PerfHistory.items["cursor"].hasNormalTick = false;
AvailableMaps = FindMaps(LobbyInfo.GlobalSettings.Mods);
ChangeMods();
if (Settings.Replay != "")
orderManager = new OrderManager(new ReplayConnection(Settings.Replay));
else
JoinLocal();
LoadShellMap(new Manifest(LobbyInfo.GlobalSettings.Mods).ShellmapUid);
PerfHistory.items["cursor"].hasNormalTick = false;
JoinLocal();
StartGame(modData.Manifest.ShellmapUid);
ResetTimer();
}
static void LoadUserSettings(Settings settings)
{
Settings = new UserSettings();
var settingsFile = settings.GetValue("settings", "settings.ini");
FileSystem.Mount("./");
if (FileSystem.Exists(settingsFile))
FieldLoader.Load(Settings,
new IniFile(FileSystem.Open(settingsFile)).GetSection("Settings"));
FileSystem.UnmountAll();
}
static bool quit;
internal static void Run()
@@ -589,19 +291,50 @@ namespace OpenRA
Application.DoEvents();
}
}
public static void Exit() { quit = true; }
public static void Exit() { quit = true; }
public static Action<Color,string,string> AddChatLine = (c,n,s) => {};
public static void Debug(string s) { chat.AddLine(Color.White, "Debug", s); }
public static void Debug(string s)
{
AddChatLine(Color.White, "Debug", s);
}
public static void Disconnect()
var shellmap = new Manifest(LobbyInfo.GlobalSettings.Mods).ShellmapUid;
{
orderManager.Dispose();
var shellmap = modData.Manifest.ShellmapUid;
LobbyInfo = new Session();
LobbyInfo.GlobalSettings.Mods = Settings.Game.Mods;
LoadShellMap(shellmap);
JoinLocal();
StartGame(shellmap);
Chrome.rootWidget.CloseWindow();
Chrome.rootWidget.OpenWindow("MAINMENU_BG");
Widget.RootWidget.CloseWindow();
Widget.RootWidget.OpenWindow("MAINMENU_BG");
}
static string baseSupportDir = null;
public static string SupportDir
{
set
{
var dir = value;
// Expand paths relative to the personal directory
if (dir.ElementAt(0) == '~')
dir = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + dir.Substring(1);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
baseSupportDir = dir + Path.DirectorySeparatorChar;
}
get { return baseSupportDir; }
}
public static T CreateObject<T>( string name )
{
return modData.ObjectCreator.CreateObject<T>( name );
}
}
}

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
@@ -24,32 +14,27 @@ using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Traits;
namespace OpenRA.GameRules
namespace OpenRA
{
public class ActorInfo
{
public readonly string Name;
public readonly string Category;
public readonly TypeDictionary Traits = new TypeDictionary();
public ActorInfo( string name, MiniYaml node, Dictionary<string, MiniYaml> allUnits )
{
var mergedNode = MergeWithParent( node, allUnits ).Nodes;
var mergedNode = MergeWithParent( node, allUnits ).NodesDict;
Name = name;
MiniYaml categoryNode;
if( mergedNode.TryGetValue( "Category", out categoryNode ) )
Category = categoryNode.Value;
foreach( var t in mergedNode )
if( t.Key != "Inherits" && t.Key != "Category" && !t.Key.StartsWith("-") )
if( t.Key != "Inherits" && !t.Key.StartsWith("-") )
Traits.Add( LoadTraitInfo( t.Key.Split('@')[0], t.Value ) );
}
static MiniYaml GetParent( MiniYaml node, Dictionary<string, MiniYaml> allUnits )
{
MiniYaml inherits;
node.Nodes.TryGetValue( "Inherits", out inherits );
node.NodesDict.TryGetValue( "Inherits", out inherits );
if( inherits == null || string.IsNullOrEmpty( inherits.Value ) )
return null;

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion

View File

@@ -1,44 +1,28 @@
using System;
using System.Collections.Generic;
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using OpenRA.FileFormats;
namespace OpenRA.GameRules
{
public class MusicInfo
{
public readonly MusicPool Pool;
public readonly string[] Music = { };
{
[FieldLoader.Load] public readonly string Filename = null;
[FieldLoader.Load] public readonly string Title = null;
[FieldLoader.Load] public readonly int Length = 0; // seconds
public MusicInfo( MiniYaml y )
public MusicInfo( string key, MiniYaml value )
{
FieldLoader.Load(this, y);
Pool = new MusicPool(Music);
FieldLoader.Load(this, value);
if (Filename == null)
Filename = key+".aud";
}
}
public class MusicPool
{
readonly string[] clips;
int playing = 0;
public MusicPool(params string[] clips)
{
this.clips = clips;
}
public string GetNext()
{
playing = (playing + 1) % clips.Length;
return clips[playing];
}
public string GetPrev()
{
playing = (playing + clips.Length - 1) % clips.Length;
return clips[playing];
}
public string GetCurrent(){ return clips[playing];}
}
}

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
@@ -34,35 +24,32 @@ namespace OpenRA
public static Dictionary<string, WeaponInfo> Weapons;
public static Dictionary<string, VoiceInfo> Voices;
public static Dictionary<string, MusicInfo> Music;
public static Dictionary<TerrainType, TerrainCost> TerrainTypes;
public static Dictionary<string, string> Movies;
public static Dictionary<string, TileSet> TileSets;
public static void LoadRules(Manifest m, Map map)
{
Log.Write("Using rules files: ");
foreach (var y in m.Rules)
Log.Write(" -- {0}", y);
Log.Write("Using Map: {0}",map.Uid);
Info = LoadYamlRules(m.Rules, map.Rules, (k, y) => new ActorInfo(k.Key.ToLowerInvariant(), k.Value, y));
Weapons = LoadYamlRules(m.Weapons, map.Weapons, (k, _) => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value));
Voices = LoadYamlRules(m.Voices, map.Voices, (k, _) => new VoiceInfo(k.Value));
Music = LoadYamlRules(m.Music, map.Music, (k, _) => new MusicInfo(k.Value));
TerrainTypes = LoadYamlRules(m.Terrain, map.Terrain, (k, _) => new TerrainCost(k.Value))
.ToDictionary(kv => (TerrainType)Enum.Parse(typeof(TerrainType), kv.Key, true), kv => kv.Value);
Weapons = LoadYamlRules(m.Weapons, new List<MiniYamlNode>(), (k, _) => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value));
Voices = LoadYamlRules(m.Voices, new List<MiniYamlNode>(), (k, _) => new VoiceInfo(k.Value));
Music = LoadYamlRules(m.Music, new List<MiniYamlNode>(), (k, _) => new MusicInfo(k.Key, k.Value));
Movies = LoadYamlRules(m.Movies, new List<MiniYamlNode>(), (k, v) => k.Value.Value);
TileSets = new Dictionary<string, TileSet>();
foreach (var file in m.TileSets)
{
var t = new TileSet(file);
TileSets.Add(t.Id,t);
}
TechTree = new TechTree();
}
static Dictionary<string, T> LoadYamlRules<T>(string[] files, Dictionary<string,MiniYaml>dict, Func<KeyValuePair<string, MiniYaml>, Dictionary<string, MiniYaml>, T> f)
static Dictionary<string, T> LoadYamlRules<T>(string[] files, List<MiniYamlNode> dict, Func<MiniYamlNode, Dictionary<string, MiniYaml>, T> f)
{
var y = files.Select(a => MiniYaml.FromFile(a)).Aggregate(dict,MiniYaml.Merge);
return y.ToDictionary(kv => kv.Key.ToLowerInvariant(), kv => f(kv, y));
}
public static IEnumerable<string> Categories()
{
return Info.Values.Select( x => x.Category ).Distinct().Where( g => g != null ).ToList();
var yy = y.ToDictionary( x => x.Key, x => x.Value );
return y.ToDictionary(kv => kv.Key.ToLowerInvariant(), kv => f(kv, yy));
}
}
}

156
OpenRA.Game/GameRules/Settings.cs Executable file
View File

@@ -0,0 +1,156 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using OpenRA.FileFormats;
using OpenRA.FileFormats.Graphics;
using System;
namespace OpenRA.GameRules
{
public class ServerSettings
{
public string Name = "OpenRA Game";
public int ListenPort = 1234;
public int ExternalPort = 1234;
public bool AdvertiseOnline = true;
public string MasterServer = "http://open-ra.org/master/";
public bool AllowCheats = false;
}
public class DebugSettings
{
public bool PerfGraph = false;
public bool RecordSyncReports = true;
public bool ShowCollisions = false;
}
public class GraphicSettings
{
public WindowMode Mode = WindowMode.PseudoFullscreen;
public int2 FullscreenSize = new int2(Screen.PrimaryScreen.Bounds.Width,Screen.PrimaryScreen.Bounds.Height);
public int2 WindowedSize = new int2(1024,768);
public readonly int2 MinResolution = new int2(800, 600);
}
public class SoundSettings
{
public float SoundVolume = 0.5f;
public float MusicVolume = 0.5f;
public float VideoVolume = 0.5f;
}
public class PlayerSettings
{
public string Name = "Newbie";
public Color Color1 = Color.FromArgb(255,160,238);
public Color Color2 = Color.FromArgb(68,0,56);
public string LastServer = "localhost:1234";
}
public class GameSettings
{
public string[] Mods = { "ra" };
public bool MatchTimer = true;
// Behaviour settings
public bool ViewportEdgeScroll = true;
public bool InverseDragScroll = false;
// Internal game settings
public int Timestep = 40;
public int SheetSize = 2048;
}
public class Settings
{
string SettingsFile;
public PlayerSettings Player = new PlayerSettings();
public GameSettings Game = new GameSettings();
public SoundSettings Sound = new SoundSettings();
public GraphicSettings Graphics = new GraphicSettings();
public ServerSettings Server = new ServerSettings();
public DebugSettings Debug = new DebugSettings();
Dictionary<string, object> Sections;
public Settings(string file, Arguments args)
{
SettingsFile = file;
Sections = new Dictionary<string, object>()
{
{"Player", Player},
{"Game", Game},
{"Sound", Sound},
{"Graphics", Graphics},
{"Server", Server},
{"Debug", Debug}
};
// Override fieldloader to ignore invalid entries
var err1 = FieldLoader.UnknownFieldAction;
var err2 = FieldLoader.InvalidValueAction;
FieldLoader.UnknownFieldAction = (s,f) =>
{
System.Console.WriteLine( "Ignoring unknown field `{0}` on `{1}`".F( s, f.Name ) );
};
if (File.Exists(SettingsFile))
{
System.Console.WriteLine("Loading settings file {0}",SettingsFile);
var yaml = MiniYaml.DictFromFile(SettingsFile);
foreach (var kv in Sections)
if (yaml.ContainsKey(kv.Key))
LoadSectionYaml(yaml[kv.Key], kv.Value);
}
// Override with commandline args
foreach (var kv in Sections)
foreach (var f in kv.Value.GetType().GetFields())
if (args.Contains(kv.Key+"."+f.Name))
OpenRA.FileFormats.FieldLoader.LoadField( kv.Value, f.Name, args.GetValue(kv.Key+"."+f.Name, "") );
FieldLoader.UnknownFieldAction = err1;
FieldLoader.InvalidValueAction = err2;
}
public void Save()
{
var root = new List<MiniYamlNode>();
foreach( var kv in Sections )
root.Add( new MiniYamlNode( kv.Key, SectionYaml( kv.Value ) ) );
root.WriteToFile(SettingsFile);
}
MiniYaml SectionYaml(object section)
{
return FieldSaver.SaveDifferences(section, Activator.CreateInstance(section.GetType()));
}
void LoadSectionYaml(MiniYaml yaml, object section)
{
object defaults = Activator.CreateInstance(section.GetType());
FieldLoader.InvalidValueAction = (s,t,f) =>
{
object ret = defaults.GetType().GetField(f).GetValue(defaults);
System.Console.WriteLine("FieldLoader: Cannot parse `{0}` into `{2}:{1}`; substituting default `{3}`".F(s,t.Name,f,ret) );
return ret;
};
FieldLoader.Load(section, yaml);
}
}
}

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
@@ -49,9 +39,9 @@ namespace OpenRA.GameRules
foreach( var b in player.World.Queries.OwnedBy[player].Where( x=>x.Info.Traits.Contains<BuildingInfo>() ) )
{
ret[ b.Info.Name ].Add( b );
var buildable = b.Info.Traits.GetOrDefault<BuildableInfo>();
if( buildable != null )
foreach( var alt in buildable.AlternateName )
var tt = b.Info.Traits.GetOrDefault<TooltipInfo>();
if( tt != null )
foreach( var alt in tt.AlternateName )
ret[ alt ].Add( b );
}
return ret;
@@ -72,7 +62,7 @@ namespace OpenRA.GameRules
if( playerBuildings[ p ].Count == 0 )
return false;
if( producesIndex[ info.Category ].All( x => playerBuildings[ x.Name ].Count == 0 ) )
if( producesIndex[ bi.Queue ].All( x => playerBuildings[ x.Name ].Count == 0 ) )
return false;
return true;
@@ -93,17 +83,18 @@ namespace OpenRA.GameRules
{
return Rules.Info.Values
.Where( x => x.Name[ 0 ] != '^' )
.Where( x => categories.Contains( x.Category ) )
.Where( x => x.Traits.Contains<BuildableInfo>() );
.Where( x => x.Traits.Contains<BuildableInfo>() )
.Where( x => categories.Contains(x.Traits.Get<BuildableInfo>().Queue) );
}
public IEnumerable<ActorInfo> UnitBuiltAt( ActorInfo info )
{
var builtAt = info.Traits.Get<BuildableInfo>().BuiltAt;
var bi = info.Traits.Get<BuildableInfo>();
var builtAt = bi.BuiltAt;
if( builtAt.Length != 0 )
return builtAt.Select( x => Rules.Info[ x.ToLowerInvariant() ] );
else
return producesIndex[ info.Category ];
return producesIndex[ bi.Queue ];
}
}
}

View File

@@ -1,72 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System;
using OpenRA.FileFormats;
using OpenRA.Graphics;
namespace OpenRA.GameRules
{
public enum UnitMovementType : byte
{
Foot = 0,
Track = 1,
Wheel = 2,
Float = 3,
Fly = 4,
}
public class TerrainCost
{
public readonly bool Buildable = true;
public readonly float Foot = 0, Track = 0, Wheel = 0, Float = 0;
public readonly bool AcceptSmudge = true;
public TerrainCost(MiniYaml y) { FieldLoader.Load(this, y); }
public float GetSpeedModifier(UnitMovementType umt)
{
switch (umt) /* todo: make this nice */
{
case UnitMovementType.Fly: return 1;
case UnitMovementType.Foot: return Foot;
case UnitMovementType.Wheel: return Wheel;
case UnitMovementType.Track: return Track;
case UnitMovementType.Float: return Float;
default:
throw new InvalidOperationException("wtf?");
}
}
public float GetCost(UnitMovementType umt)
{
switch (umt) /* todo: make this nice */
{
case UnitMovementType.Fly: return 1;
case UnitMovementType.Foot: return 1 / Foot;
case UnitMovementType.Wheel: return 1 / Wheel;
case UnitMovementType.Track: return 1 / Track;
case UnitMovementType.Float: return 1 / Float;
default:
throw new InvalidOperationException("wtf?");
}
}
}
}

View File

@@ -1,56 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
namespace OpenRA.GameRules
{
public class UserSettings
{
// Debug settings
public bool UnitDebug = false;
public bool PathDebug = false;
public bool PerfDebug = true;
public bool IndexDebug = false;
public bool RecordSyncReports = true;
// Window settings
public readonly int Width = 0;
public readonly int Height = 0;
public readonly bool Fullscreen = false;
public bool MusicPlayer = true;
// Internal game settings
public readonly int Timestep = 40;
public readonly int SheetSize = 2048;
// External game settings
public readonly string NetworkHost = "";
public readonly int NetworkPort = 0;
public readonly int Player = 1;
public readonly string Replay = "";
public readonly string PlayerName = "";
public readonly string[] InitialMods = { "ra" };
public readonly string GameName = "OpenRA Game";
public readonly int ListenPort = 1234;
public readonly int ExternalPort = 1234;
public readonly bool InternetServer = true;
public readonly string MasterServer = "http://open-ra.org/master/";
}
}

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