Compare commits

...

1365 Commits

Author SHA1 Message Date
Matthias Mailänder
ba7310d0a0 Merge pull request #2859 from ihptru/bleed
fix #2193
2013-03-27 02:38:35 -07:00
Igor Popov
0bf79635ec fix #2193
the most common reason of "Operation is not valid due to the current state of the object"
2013-03-27 06:08:01 -03:00
Matthias Mailänder
9ca391c814 Merge pull request #2817 from Mailaender/radoc-update
Update RADOC
2013-03-27 01:51:52 -07:00
Matthias Mailänder
0a82bfe552 format TODO: uniformly to auto-generate task list in MonoDevelop 2013-03-27 09:45:17 +01:00
Matthias Mailänder
a682670b97 update developer commentary
for weapon traits, crates and palettes
clarify that you don't need to update the wiki page manually
2013-03-27 09:22:23 +01:00
Matthias Mailänder
fc1a3f9916 Merge pull request #2857 from Mailaender/fix-game-start-sound-nullreference-exception
Fix NullReferenceException for spectator mode
2013-03-27 00:14:39 -07:00
Matthias Mailänder
5927bce7b5 no country specific game start announcer voice
it will crash for spectators who have none
no mod supports it at the moment anyway
2013-03-27 08:11:12 +01:00
Matthias Mailänder
d153f3f74f Merge pull request #2855 from Mailaender/greenpeace
Don't burn down the forest in Allies04...
2013-03-26 15:45:14 -07:00
Matthias Mailänder
039589c739 let the soviets in allies04 not furiously attack mother nature
regression due to trees being destructible now
2013-03-26 23:40:03 +01:00
Matthias Mailänder
3f20415aff Merge pull request #2821 from Mailaender/ra-desert-palette-rotation-fix
fix RA Desert palette rotation regressions
2013-03-26 14:39:40 -07:00
Matthias Mailänder
e795ab9174 Merge pull request #2770 from pchote/turret-cleanup
Weapon / Turret refactoring
2013-03-26 14:38:56 -07:00
Matthias Mailänder
0ab57c9abc Merge pull request #2813 from Mailaender/desura
Desura compatibilty
2013-03-26 14:37:42 -07:00
Matthias Mailänder
c993140fe7 Merge pull request #2822 from Mailaender/shroud-selector
Added Shroud selector to spectator mode
2013-03-26 14:34:06 -07:00
Matthias Mailänder
715e7a010f Merge pull request #2845 from ihptru/bots
option to disable bots on server + disable bots on any dedicated server
2013-03-26 14:32:29 -07:00
Matthias Mailänder
328c81e07b Merge pull request #2848 from Mailaender/int-damage-modifier
Witch hunting against desyncs...
2013-03-26 14:30:27 -07:00
Matthias Mailänder
8509505c01 Merge pull request #2851 from Mailaender/editor-toolbar
Map Editor Beautification, fixes #2825
2013-03-26 14:29:54 -07:00
Matthias Mailänder
28f24cd03a Merge pull request #2801 from Mailaender/hotkey-cleanup
Remove inconsistencies that crash C&C mod
2013-03-26 14:28:49 -07:00
Matthias Mailänder
ead0da4161 Merge pull request #2844 from Mailaender/game-asset-download-crash-hotfix
Hotfix: Don't Crash on First-Start when Game Assets are missing
2013-03-26 14:27:20 -07:00
Matthias Mailänder
a3c0b1b9f6 Merge pull request #2814 from Mailaender/desync-debug
Yet Another Desync Debug Pull Request
2013-03-26 14:26:09 -07:00
Matthias Mailänder
ca2f48a439 Update lobby.yaml
it is also used for the single-player GUI
2013-03-26 22:24:16 +01:00
Matthias Mailänder
04a1b56e03 Merge pull request #2369 from ihptru/cnc-server-name
fix cnc menu/multiplayer titles overrides by server's title;
2013-03-26 14:23:06 -07:00
Matthias Mailänder
a0bd6f0d46 Map Editor beautification
- show full name + version of the loaded mod in titlebar
- added a help menu with useful links
- added icons to to the menu with tooltips
- added a toolbar to the editor, closes #2825
2013-03-26 15:42:44 +01:00
Matthias Mailänder
813faee4aa avoid unneccessary float calculations and conversions 2013-03-25 12:38:57 +01:00
Matthias Mailänder
851512a84e eliminate public CursorProvider.Palettes
don't hand over the cursor palette to the world renderer at all
still update worldrender palette (set and apply modifiers)
2013-03-25 06:30:39 +01:00
Matthias Mailänder
ba12aafd78 refactor cursor rendering
create a new cursor palette only once and not in WorldRenderer
move cusrsor sequence lookup and drawing to CursorProvider
2013-03-24 21:21:30 +01:00
Igor Popov
41d0860db4 option to disable bots on server + disable bots on any dedicated server due to #2540 2013-03-24 19:35:44 +04:00
Matthias Mailänder
227a7a61eb don't crash when trying to get the game assets on first start
wr is null at that stage
2013-03-24 15:16:49 +01:00
Matthias Mailänder
baacad8432 add Shroud selector to spectator mode, closes #2463 2013-03-24 10:42:58 +01:00
Chris Forbes
eb4f7a046f Merge pull request #2818 from Mailaender/diplomacy-renovation
Bring the Diplomacy menu back to life...
2013-03-24 01:07:20 -07:00
Chris Forbes
14468b4895 Merge pull request #2819 from Mailaender/game-start-sound
Battlecontrol initialized!
2013-03-24 00:49:04 -07:00
Matthias Mailänder
91442a0414 add a close button with hotkey to diplomacy widget 2013-03-24 08:37:38 +01:00
Paul Chote
0167bbfbaa Move weapon/turret definitions out of AttackBase.
Weapons are now defined with the Armament trait
and turret parameters live in Turreted.
This has the side effect of allowing any number
and distribution of weapons and turrets.
2013-03-24 11:58:45 +13:00
Matthias Mailänder
3e63751960 fix RA Desert palette rotation regressions 2013-03-23 22:13:35 +01:00
Matthias Mailänder
7f6eaf8d5e move order button hotkey logic to ingame chrome logic
removes power-down again from cnc mod as it is not wanted there
2013-03-23 09:47:35 +01:00
Matthias Mailänder
7e9c20df71 remove bashisms for extended portability 2013-03-22 23:42:54 +01:00
Matthias Mailänder
c00eee835f package .desktop files for map editor on Linux, too
move desura scripts into packaging sub-directory
2013-03-22 23:42:47 +01:00
Matthias Mailänder
0880c1241d fixes #2190 added announcer voice upon game start
Thanks to @Nyerguds for mixing this together for the RA mod!
2013-03-22 22:54:45 +01:00
Matthias Mailänder
6307e51991 put NextAutoTargetScanTime into syncreport.log 2013-03-22 19:19:16 +01:00
Matthias Mailänder
43bb75c135 sync carpet bombing 2013-03-22 19:19:16 +01:00
Matthias Mailänder
6cedc424ed dump the actor the unit tried to retiliate against to syncreport 2013-03-22 19:19:16 +01:00
Matthias Mailänder
15324b1f1a bring the Diplomacy menu back to life, but
- rename LockTeams to FragileAlliances to avoid confusion
- only allow it in Free-For-All, not Team games or Missions
- grey out non-functional buttons and disabled checkboxes
2013-03-22 18:34:52 +01:00
Matthias Mailänder
2d6200792d recommend Cg-Toolkit as soft dependency for Fedora/SUSE
it is in the non-free / RPMfusion repositories
2013-03-22 08:32:33 +01:00
Matthias Mailänder
28d740dfc3 Desura compatibility
- create launch scripts for Desura
- that access local installation launch scripts
- clean up /usr/* launch scripts created during make install
2013-03-22 08:32:33 +01:00
Chris Forbes
aa6f12f0a1 Merge pull request #2816 from ScottNZ/radoc
radoc tidy
2013-03-21 23:28:51 -07:00
Scott_NZ
a25aa23805 radoc tidy 2013-03-22 18:12:47 +13:00
Chris Forbes
9b1555d3a1 Merge pull request #2809 from bidifx/dblclick
double click on server to join
2013-03-21 10:54:22 -07:00
Sascha Biedermann
594e3c14e6 fixes #2799: double click on server to join 2013-03-21 18:14:57 +01:00
Chris Forbes
942cbb2fe2 Merge pull request #2808 from Mailaender/trait-documentation
Auto-Generated Trait Documentation
2013-03-20 17:31:18 -07:00
Chris Forbes
38f0d722c6 Merge pull request #2810 from bidifx/cancel-chat
cancel ingame-chat with esc
2013-03-20 17:18:18 -07:00
Sascha Biedermann
d53dcc859f fixes #2795: cancel chat with esc 2013-03-20 23:55:12 +01:00
Matthias Mailänder
65c9d4295b automatically update the wiki documentation each release 2013-03-20 23:27:53 +01:00
Matthias Mailänder
c731a7960e embed the previously manually edited outdated documentation
from https://github.com/OpenRA/OpenRA/wiki/Trait-Documentation
2013-03-20 21:20:27 +01:00
Sascha Biedermann
ed0e0a8a41 added Sascha Biedermann to AUTHORS 2013-03-20 20:48:02 +01:00
Chris Forbes
89228cd484 Merge pull request #2804 from bidifx/range-circle
added contrast to range circle
2013-03-20 11:06:41 -07:00
Sascha Biedermann
35f4230984 added contrast to range circle 2013-03-20 18:53:28 +01:00
Matthias Mailänder
8226fd21f9 ship a proper SDK for modders
including the OpenRA.TilesetBuilder.exe fixes #2316
and auto-generated trait documentation fixes #2437
compile Markdown to HTML for offline use
purge external files from the doc folder (moved to Wiki)
remove unused non-free Dune 2000 font
2013-03-20 17:04:38 +01:00
Chris Forbes
d0cf627b23 add --docs flag for utility 2013-03-20 15:12:58 +01:00
Matthias Mailänder
57d85e2c97 fixes #2785 don't crash when last player leaves game in cnc 2013-03-20 12:44:47 +01:00
Matthias Mailänder
e9602ca4e9 pull cnc sell/repair button hotkeys from settings 2013-03-20 12:06:51 +01:00
Matthias Mailänder
f0876828f4 fixes #2791 don't crash on powerdown hotkey when playing cnc 2013-03-20 11:54:15 +01:00
Matthias Mailänder
99c3272a81 add tab cycle key to setting GUI 2013-03-20 08:24:51 +01:00
Chris Forbes
7c31a8f28e Merge pull request #2789 from bidifx/lobby
update player list in lobby gracefully for better user experience
2013-03-19 12:26:51 -07:00
Chris Forbes
989dd7eef4 Merge pull request #2796 from Mailaender/attack-sync
Put attack traits into the syncreport.log
2013-03-19 12:26:21 -07:00
Chris Forbes
8c811ed21d Merge pull request #2798 from bidifx/contrail
smooth contrails
2013-03-19 12:24:50 -07:00
Sascha Biedermann
e562f8d2cc refactored Average method in PPos 2013-03-19 19:58:30 +01:00
Matthias Mailänder
c41ad3d600 put attack traits into the syncreport.log 2013-03-19 19:40:14 +01:00
Sascha Biedermann
021e1116b8 added moving average to contrails to smooth them when aircraft are circling 2013-03-19 18:41:36 +01:00
Sascha Biedermann
b6d09b8829 fixed child removal
fixed relayout on draw
refactored child remove/replace into ScrollPanelWidget
fixed scrolling on child remove
2013-03-19 17:39:07 +01:00
Chris Forbes
78f961f653 Merge pull request #2782 from ihptru/clear-master-list
fix #2780 ; Send state=3 to master server when it's not dedicated and ad...
2013-03-18 15:15:46 -07:00
Chris Forbes
3e787315d2 Merge pull request #2788 from psydev/patch-3
Flamethrower range reduced to 2.5
2013-03-18 15:12:58 -07:00
Sascha Biedermann
770d79da0b update player list in lobby gracefully for better user experience 2013-03-18 22:25:31 +01:00
psydev
0172c5e5ce Flamethrower range reduced to 2.5
Flamethrower seems OP, and flamethrower spam can dominate early game without much to counter it. Reduced range back to earlier levels (in C&C 95 it was 2).
2013-03-18 13:16:40 -07:00
ScottNZ
1fb2796ada Update cheats.yaml
We're an American game
2013-03-18 22:59:43 +13:00
Matthias Mailänder
46465da483 Merge pull request #2781 from ScottNZ/ui
Pause the game when users navigate to the options menu in SP mode
2013-03-17 04:00:33 -07:00
Igor Popov
751b6594a8 fix #2780 ; Send state=3 to master server when it's not dedicated and admin presses disconnect 2013-03-17 13:48:40 +04:00
Matthias Mailänder
ff04d0fa8f Merge pull request #2779 from psydev/patch-9
cnc infantry anims running ticks corrected and heli explosions added
2013-03-17 02:29:36 -07:00
psydev
ff983157a6 removed FlamethrowerExplode for now
Removed FlamethrowerExplode for now, until it is certain what the damage stats should be and the probability of exploding.
2013-03-17 01:57:52 -07:00
psydev
604854f22d added helicopter explosions; a10 hp boost
Helicopters get explosions, when they fall from the sky, and then when they collide with the ground (and do damage).
A-10 HP raised from a very small 60 to 150.
2013-03-17 01:35:51 -07:00
psydev
5381b1fbac added explosion for helicopters crashing on ground 2013-03-17 01:30:36 -07:00
Scott_NZ
2722fc5434 Pause the game when users navigate to the options menu in SP mode 2013-03-17 21:14:49 +13:00
psydev
5ac47b49ce Helicopters do HeliExplode when they die
Helicopters give off a nice explosion before falling to the ground.
2013-03-16 22:23:06 -07:00
psydev
acf779ace3 Flame Tank gets FlametankExplode when it dies
Flame Tank gets FlametankExplode when it dies (big explosion that hurts nearby units)
2013-03-16 22:20:42 -07:00
psydev
451c453442 added unit explosions for flametank, helis
added unit explosions for flametank, helis and flamethrower e4
changed GrenadierExplode and UnitExplodeSmall a bit
2013-03-16 22:17:30 -07:00
psydev
b8b258c6f9 construction yard does crane animation slower
when building other buildings, construction yard crane should go slower, at ~100 tick.
2013-03-16 21:56:35 -07:00
psydev
9fe429aeb8 infantry anims: running ticks corrected
I guess nobody noticed, but in CNC and RA, the legs of infantry move way too fast. It should be ~100 Tick.
2013-03-16 21:48:55 -07:00
Chris Forbes
86b55a6444 Merge pull request #2776 from psydev/patch-8
vehicles: MCV enabled; msam use patriot; shroud
2013-03-16 21:28:14 -07:00
psydev
5d564e2378 vehicles: MCV enabled; msam use patriot; shroud
MCV re-enabled. A construction yard build radius will be included in a later release to rein in basewalking.
Mobile SAM launcher's weapon is Patriot missile instead of HonestJohn.
Shroud reveal ranges on a few units adjusted
2013-03-16 21:19:00 -07:00
Chris Forbes
d54282be14 Merge pull request #2775 from psydev/patch-7
Adjustments for cnc
2013-03-16 21:01:04 -07:00
psydev
bb31654289 Tower adjustments
ATWR HP reduced from 800 to 600
ATWR power consumptions inreased from 20 to 30
Increased sight range of towers to match their range. 
Silo moved over in build queue
2013-03-16 20:47:21 -07:00
Chris Forbes
0680b06383 Merge pull request #2771 from Mailaender/bleed
add Valkirie to AUTHORS
2013-03-14 17:12:06 -07:00
Matthias Mailänder
2dd8426dec add @Valkirie to AUTHORS
he contributed the initial HackyAI extensions
2013-03-14 22:15:27 +01:00
Chris Forbes
b1eef4ec55 Merge pull request #2769 from Mailaender/bleed
Adds a Travis build check button to the repository frontpage
2013-03-14 11:40:14 -07:00
Chris Forbes
b36d83b7cd Merge pull request #2768 from Mailaender/bot-hotfixes
Fix Desync when Bots fire Super Weapons
2013-03-14 11:35:52 -07:00
Matthias Mailänder
75a1115685 add a Travis build check button 2013-03-14 12:40:26 +01:00
Matthias Mailänder
36e820308f AI support power activation needs to go through order manager
fixes a desync whenever it will do so only on the host

+island map AI which will only build navy / air force to test
it and have a suitable bot for those map types (fixes pathfinder
eating up all CPU because it can't reach you with ground units)
2013-03-14 10:48:36 +01:00
Matthias Mailänder
431961401f Merge pull request #2765 from BugraC/myPatch
I added myself to the Authors file
2013-03-13 00:46:51 -07:00
Bugra Cuhadaroglu
d6953b88ea I added myself the Authors.
Thank you very much guys!
2013-03-12 23:00:47 -04:00
Scott_NZ
6bbef8d33f Fix crash in CaptureActor.Tick when trying to capture a dead actor 2013-03-13 11:14:45 +13:00
Chris Forbes
e4806e4d39 Merge pull request #2761 from Mailaender/production-speedup-hotfix
Fixes #2753 ClassicProductionQueue related crashes
2013-03-12 11:35:58 -07:00
Matthias Mailänder
6d6664d930 make classic production queue speedup less error prone
- avoid float modifiers because of rounding errors and desync
- try not to crash when the last production building is gone
- don't do LINQ queries on selfsame buildings if not required
2013-03-12 12:49:16 +01:00
Matthias Mailänder
7676ef6a14 Merge pull request #2760 from ScottNZ/devmode
Make FACT buildable when "Build Everything" is turned on
2013-03-12 01:42:55 -07:00
Scott_NZ
712b29d233 Make FACT buildable when "Build Everything" is turned on 2013-03-12 21:13:21 +13:00
Matthias Mailänder
65455ee1ca Merge pull request #2556 from ihptru/maptitle
return mapTitle in ra and d2k lobby
2013-03-12 00:46:58 -07:00
Bugra Cuhadaroglu
0d86595ba8 Ranks not showing in Replay Viewer
This will fix the problem.
2013-03-12 12:37:26 +13:00
Matthias Mailänder
4ab2fa21eb Merge pull request #2756 from chrisforbes/master
Fix desync on win or lose
2013-03-11 14:43:03 -07:00
Chris Forbes
1f3710b90e Merge pull request #2757 from Mailaender/desktop-fix
Fix missing .desktop file in latest playtests
2013-03-11 14:20:42 -07:00
Matthias Mailänder
c8a457bdce simplify desktop file installation on Linux
the old Ubuntu build machine is unable to do it
2013-03-11 22:18:53 +01:00
Chris Forbes
67ca37326e fix desync on win/lose 2013-03-12 10:15:04 +13:00
Chris Forbes
2dd53e6d99 Merge pull request #2612 from Mailaender/burning-trees
Destructible trees for both CnC and RA mod
2013-03-11 13:16:49 -07:00
Chris Forbes
623fce3cdf Merge pull request #2754 from Mailaender/auto-target-desync-hotfix
Hotfix: Addresses Desync Issues in AutoTarget Trait
2013-03-11 13:08:10 -07:00
Matthias Mailänder
97d850e481 use integer math to calculate next auto-target scan-time
to combat random desync problem because of rounding problems
2013-03-11 14:02:28 +01:00
Bugra Cuhadaroglu
7cbc4a29bf Fix #2720 - Diagonal scrolling area in viewport corners are too small
I added two options, one is for EdgeScrollThreshold and the other one is
EdgeCornerScrollThreshold. You can modify these threshold as much as you
want.

[Squashed down into one commit -- chrisf]
2013-03-11 16:32:42 +13:00
Chris Forbes
9db06ca222 Merge pull request #2748 from BugraC/bleed
Csproj BuildEvents problem in both Linux and Windows
2013-03-10 19:23:26 -07:00
Chris Forbes
63e5ce2bc5 Merge pull request #2749 from Mailaender/chrome-yaml-fixes
Chrome yaml fixes
2013-03-10 19:23:09 -07:00
Matthias Mailänder
8bb1d83fb7 add new lobby buttons to d2k chrome as well 2013-03-11 03:18:02 +01:00
Matthias Mailänder
947c9d73ce add new developer cheats to cnc chrome
fixes a crash
2013-03-11 03:13:25 +01:00
Matthias Mailänder
66855072de update changelog for new playtest release 2013-03-11 02:53:32 +01:00
Bugra Cuhadaroglu
c145dc2379 Csproj BuildEvents problem in both Linux and Windows
I have found this error with the OpenRa.Mods.RA csproj: copy
"thirdparty/FuzzyLogicLibrary.dll" "$(SolutionDir)", this should be: cd
"$(SolutionDir)thirdparty/"
copy "FuzzyLogicLibrary.dll" "$(SolutionDir)" in two seperated codes,
this FuzzyLogicLibrary.dll copy error can be fixed in both Windows and
Linux environment
2013-03-10 21:17:54 -04:00
Chris Forbes
f2b7c2c2ad Merge pull request #2715 from xaionaro/bleed
Adapted to dpkg's "--instdir"-like options.
2013-03-10 18:13:31 -07:00
Chris Forbes
6bfeb12d33 Merge pull request #2747 from psydev/patch-6
added a blue tiberium blossom tree.
2013-03-10 18:13:05 -07:00
psydev
09bef2d4c2 Gave blue tiberium blossom a sequence; changed #2
Blossom tree has a sequence. 
There are two blossom trees in C&C, so I will use the first one (split2) for green tiberium and the 2nd one (split3) for blue tiberium. The old split3 still exists for backwards-compatibility, but will now show the split2 image. Only the blue tiberium blossom tree will show the split3 image.
2013-03-10 18:00:21 -07:00
psydev
53fec13183 added a blue tiberium blossom tree. 2013-03-10 17:55:54 -07:00
Chris Forbes
6427ad1cf9 Merge pull request #2683 from Mailaender/survival01
Survival01 by @NukemBro
2013-03-10 16:20:59 -07:00
Chris Forbes
c5d97fea69 Merge pull request #2738 from Mailaender/a-star
A-star debug overlay
2013-03-10 16:20:34 -07:00
Chris Forbes
7a41b10618 Merge pull request #2744 from ScottNZ/lobby
Add "Assign Teams" lobby drop down button
2013-03-10 16:20:19 -07:00
Chris Forbes
2032a7efa4 Merge pull request #2745 from Mailaender/more-settings
Add hidden settings to the GUI
2013-03-10 16:20:04 -07:00
Scott_NZ
bd292b56cf Ignore spectators when counting clients for the assignteams command 2013-03-11 01:20:08 +13:00
Scott_NZ
7af91f1747 Disable the button/order when there aren't enough clients to assign 2013-03-11 00:29:23 +13:00
Matthias Mailänder
17d032b190 destructible trees for both CnC and RA mod
- move DeadBuildingState to OpenRA.Mods.RA
- don't loop sequences with length > 1
2013-03-10 10:08:59 +01:00
Matthias Mailänder
9d6c8453fd add hidden MaxFPS settings to ra/d2k GUI 2013-03-10 09:42:05 +01:00
Matthias Mailänder
6bbe5f633c expose hidden Debug settings to ra/d2k GUI
- performance text switch
- performace text update rate
- AI debug messages
- trait report threshold ticks
2013-03-10 09:40:08 +01:00
Matthias Mailänder
ba8c9bb1b1 added hidden audio settings to ra/d2k GUI
- video volume
- map music (was shellmap music)
- sound engine
2013-03-10 09:34:15 +01:00
Scott_NZ
8c46b421de Add "Assign Teams" lobby drop down button 2013-03-10 20:46:29 +13:00
Matthias Mailänder
1a6a7da9c1 apply recent refactoring to quad renderer 2013-03-10 07:47:00 +01:00
James Dunne
d8c752ecb9 DebugOverlay improvements to only render inside viewing range. 2013-03-10 07:35:36 +01:00
James Dunne
7e913c4bb7 Lame attempts to improve A*. 2013-03-10 07:33:31 +01:00
Matthias Mailänder
2abde381a7 Exposed PathSearch.owner and removed Player argument from PathFinder functions. 2013-03-10 07:33:31 +01:00
Matthias Mailänder
493eb10b96 Now coloring A* cells by owning player color. Added checkbox to cheats menu. 2013-03-10 07:33:25 +01:00
Matthias Mailänder
7d0de5645f Added QuadRenderer to render shaded/colored quads. Added DebugOverlay to World to show A* bidi search cost per cell. 2013-03-10 07:32:35 +01:00
Matthias Mailänder
290310fbe8 Added Mission Survival01 mission 2013-03-10 07:28:21 +01:00
Chris Forbes
19e6a588b8 Merge pull request #2589 from Mailaender/travis
Travis CI support
2013-03-09 21:11:54 -08:00
Chris Forbes
b39f540e4b Merge pull request #2736 from Mailaender/better-bots
Better AI Bots
2013-03-09 21:11:29 -08:00
Chris Forbes
e45fc0079c Merge pull request #2729 from Mailaender/sync
Dump some more values into the debug log to investigate desyncs
2013-03-09 21:10:42 -08:00
Chris Forbes
25971bf98f Merge pull request #2725 from psydev/patch-5
defaults.yaml: unit speeds fix; husk burn; tanks explode small
2013-03-09 21:09:51 -08:00
Chris Forbes
3f273674f7 Merge pull request #2737 from Mailaender/shroud-sync
add Shroud, CreatesShroud and RevealsShroud to syncreport.log
2013-03-09 21:09:31 -08:00
Chris Forbes
da566f3648 Merge pull request #2731 from pchote/renderer-cleanup2
Renderer refactoring - Duplication
2013-03-09 21:08:34 -08:00
Chris Forbes
70e823f526 Merge pull request #2739 from Mailaender/shroud-dev-cheats
Additional Developer Shroud Cheats
2013-03-09 21:07:41 -08:00
Chris Forbes
0411b34bbd Merge pull request #2741 from Mailaender/classic-mods
Classic mods
2013-03-09 21:06:41 -08:00
Matthias Mailänder
49cfa21ddb separate spy disguise and infiltrate
- add thief to classic-ra & monster tank madness
- remove crude workarounds for allies04
2013-03-09 13:48:31 +01:00
Matthias Mailänder
7675a69cec add copy FuzzyLogicLibrary.dll to csproj files for msbuild 2013-03-08 19:27:11 +01:00
Matthias Mailänder
ca6cc3fbe1 add unused Red Alert actors for legacy map import
- thief
- chan
- general
- mobile radar jammer
2013-03-08 11:22:59 +01:00
Matthias Mailänder
455c66e2eb fix HPAD renaming in GDI01 2013-03-08 09:40:12 +01:00
Matthias Mailänder
de30f0a917 make fog of war rendering optional for classic mods 2013-03-08 09:40:12 +01:00
Matthias Mailänder
b16b171b1e cnc classic helis rearm at hpad and repair at fix
don't crash due to missing sequences for GDI/NOD hpads
2013-03-08 09:40:12 +01:00
Matthias Mailänder
804729deac remove line build feature for walls in classic mods 2013-03-08 09:40:12 +01:00
Matthias Mailänder
f3e0ff8758 fix #2709 CustomBuildTimeValue should not desync
remove redundant code by outsourcing raw build time calculation
2013-03-08 09:40:11 +01:00
Matthias Mailänder
e3fbd40278 added classic engineer capture rules 2013-03-08 09:40:11 +01:00
Matthias Mailänder
f2703dd65d apply recent palette refactoring changes to classic mods 2013-03-08 09:40:11 +01:00
Matthias Mailänder
2f917982fd add a quick RA classic loadscreen replacement to avoid confusion 2013-03-08 09:40:11 +01:00
Matthias Mailänder
f29238df6e add production queue speedup to classic mods 2013-03-08 09:40:11 +01:00
Matthias Mailänder
71b1cf9cb2 move Nod01 to cnc-classic mod; fix FMV, music; avoid menu crash 2013-03-08 09:40:11 +01:00
Dan9550
20737415fa started work on NOD_01 2013-03-08 09:40:11 +01:00
Matthias Mailänder
6e9ac71168 fix GDI01 FMV problems and gunboat crash
- show video not only the sound
- start the game after video playback
- don't crash after the win/loose movies are played
- don't crash when moving the gunboat
2013-03-08 09:40:11 +01:00
Cody Brittain
15032e3a40 Update mods/cnc-classic/rules/defaults.yaml
Fix a building explosion sound
2013-03-08 09:40:10 +01:00
Cody Brittain
eed8cf2cf0 Update mods/cnc-classic/mod.yaml
Update mod Name and Description
2013-03-08 09:40:10 +01:00
Cody Brittain
27235df950 Update mods/cnc-classic/rules/structures.yaml
Turret no longer buildable by GDI, Guard Tower no longer buildable by Nod
2013-03-08 09:40:10 +01:00
Cody Brittain
0902dcb7f3 Update mods/cnc-classic/rules/vehicles.yaml
Just a compromise
2013-03-08 09:40:10 +01:00
Cody Brittain
8bdcbe727f Update mods/cnc-classic/rules/system.yaml
Fix sound
2013-03-08 09:40:10 +01:00
Matthias Mailänder
e4a7e9716e Add contributers of cnc-classic 2013-03-08 09:40:10 +01:00
Matthias Mailänder
7052b72f48 remove roof from classic hover craft to fix rendering of cargo 2013-03-08 09:40:10 +01:00
Matthias Mailänder
3e5ee4dc1b add movement flash sequence to cnc-classic 2013-03-08 09:40:10 +01:00
Matthias Mailänder
190342a2c8 remove traits we don't need in cnc-classic 2013-03-08 09:40:10 +01:00
Matthias Mailänder
82568376a0 move GDI01 to classic mod and fix crash on startup 2013-03-08 09:40:10 +01:00
Matthias Mailänder
e47cc68ee2 fix RALint cnc-classic errors 2013-03-08 09:40:09 +01:00
Matthias Mailänder
d56bf2ee34 added a few explosion animations 2013-03-08 09:40:09 +01:00
psydev
07f0fcde33 created weapons.yaml
I'm can't remember what differences, if any, there are between cnc and cnc-classic for this file. I edited it ~6 months ago.
2013-03-08 09:40:09 +01:00
psydev
de3814dcd2 Create explosions.yaml
CNC Classic uses many different explosion types (imitating C&C Gold). Decided they should get their own file. 
Explosions are not perfect renditions of C&C Gold's (in particular, I have not estimated precisely how much damage they do to surrounding units). Graphics are mostly identical, though.
2013-03-08 09:40:09 +01:00
psydev
cc2440d0a2 added explosions.yaml to mod 2013-03-08 09:40:09 +01:00
psydev
3123f6672b replaced vehicles.yaml
Completely replaced vehicles.yaml. All values should correspond with C&C Gold. 
(Cost, HP, speed, armor type, vision, pre-reqs, explosion type...)
-Re-ordered units list from basic at the top to advanced at the bottom.
2013-03-08 09:40:09 +01:00
psydev
382997086d re-write defaults.yaml
Re-writing defaults.yaml to enter values from C&C Gold. 
Vehicles & tanks have a small explosion by default now.
2013-03-08 09:40:09 +01:00
psydev
43995ebb28 re-wrote structures.yaml
Structures should now have same values C&C Gold now. 
Helipad is not perfect (unit does not spawn in the center)
There may be issues with how the ion cannon does damage differently to weapons factory vs. airfield (also an issue in regular CNC fork).
List of buildings has been organized from basic to advanced, and in-game build menu has been changed to be more logical.
2013-03-08 09:40:09 +01:00
psydev
1725fdcf8a re-wrote infantry.yaml
Unit values are now same as C&C Gold, including new unit dependencies.
(vision range is approximate, due to rendering differences for sight range)
2013-03-08 09:40:09 +01:00
psydev
e0362f3c36 made some minor money changes (start, crate)
Starting money now 5000 instead of 10,000
Crates now give 2000 instead of 1000
Warning audio (low power, silos needed) 20 seconds instead of 10.
2013-03-08 09:40:08 +01:00
Matthias Mailänder
53fefa7c10 cnc-classic mod with ClassicProductionQueue and skin by Harisson 2013-03-08 09:40:08 +01:00
Matthias Mailänder
1d0ae1a39b move classic maps to classic mod 2013-03-08 09:40:08 +01:00
Dan9550
b6a3d1c2ae just tweaked a spawn point 2013-03-08 09:40:08 +01:00
Dan9550
11dcabae73 added maps converted from c&c and covert ops 2013-03-08 09:40:08 +01:00
Matthias Mailänder
d61cc913c0 don't hardcode the RALoadScreenImage 2013-03-08 09:40:08 +01:00
Matthias Mailänder
527790f962 move SpeedUp to ClassicProductionQueueInfo 2013-03-08 09:40:08 +01:00
Matthias Mailänder
ecd4ff68a4 speed up production if multiple buildings of the same type exist 2013-03-08 09:40:07 +01:00
Matthias Mailänder
d4ea8aad8d fix mysterious ralint problem in ra-classic weapon yaml 2013-03-08 09:40:07 +01:00
Matthias Mailänder
f44a14c81e added classic-ra dialog reskin & improved allies chrome by JOo 2013-03-08 09:40:07 +01:00
Matthias Mailänder
7caf2956d7 merge RA Classic 0.1 yaml rules by @Iran 2013-03-08 09:40:07 +01:00
Matthias Mailänder
7398914af9 add a classic allies chrome reskin prototype by JOo 2013-03-08 09:40:07 +01:00
Matthias Mailänder
fb82d554fa add contributers of ra-classic to AUTHORS 2013-03-08 09:40:02 +01:00
Paul Chote
8a53819f50 Redirect IShader calls via respective *Renderers. 2013-03-08 18:21:35 +13:00
Matthias Mailänder
58c3b52a1a add reset exploration developer cheat 2013-03-07 20:32:00 +01:00
Matthias Mailänder
4a26d3f36e fix AutoTarget sync
- ISync interface was missing
- UnitStance enum was unhashable
2013-03-07 13:00:41 +01:00
Paul Chote
21e8e3a78d Remove unnecessary duplication between renderers. 2013-03-08 00:07:26 +13:00
Matthias Mailänder
7bf00a766f add a stripped down ra-classic mod cloning the current ra rules 2013-03-07 11:25:42 +01:00
Matthias Mailänder
8f69ea9da6 added classic map pack converted by @dan9550 2013-03-07 11:25:41 +01:00
Matthias Mailänder
60923e3413 log panicking infantry to the syncreport.log 2013-03-07 08:33:02 +01:00
Matthias Mailänder
72841a51e6 add shroud, creates shroud and reveals shroud to syncreport 2013-03-06 16:05:31 +01:00
Matthias Mailänder
5d441d2591 add Vladimir Komarov to AUTHORS
he contributed the fuzzy-ai
2013-03-06 11:53:26 +01:00
Matthias Mailänder
b001c83bd5 backport rallypoint changes to ai update branch 2013-03-06 11:53:19 +01:00
Vladimir Komarov
b1afeb4408 fix comparing with null 2013-03-06 11:49:45 +01:00
Matthias Mailänder
f6d4b860ee husks are invalid targets 2013-03-06 11:49:45 +01:00
Matthias Mailänder
5d2b704608 fix Makefile, prepare FuzzyLogicLibrary for packaging 2013-03-06 11:49:45 +01:00
Matthias Mailänder
d0f61faf4a add generalized ai variables 2013-03-06 11:49:45 +01:00
Matthias Mailänder
0e1229e8d1 fix air 2013-03-06 11:49:45 +01:00
Matthias Mailänder
d785430db5 fix refinery production 2013-03-06 11:49:45 +01:00
Matthias Mailänder
59d0cff410 rename lists in HackyAI.cs and fix function 2013-03-06 11:49:40 +01:00
Matthias Mailänder
e0b7242f1b adding new ai functional 2013-03-06 11:17:02 +01:00
Matthias Mailänder
3f56e00173 Merge pull request #2721 from psydev/patch-1
weapons.yaml update for CNC
2013-03-05 10:59:03 -08:00
psydev
f8fd6681c8 fixed APC gun mistkae -- now shoots at air too 2013-03-04 09:01:10 -08:00
Matthias Mailänder
a02fddd1a0 log the nextScanTime for ChooseTarget in AutoTarget
for debugging purposes to investigate desyncs
2013-03-04 10:25:20 +01:00
Paul Chote
786c3b1f1a Rename uniform setters to avoid future ambiguity. 2013-03-04 19:06:42 +13:00
psydev
01cb3a40d7 scaled back tank firing rate a bit
Originally I increased the tank firing rate by 2x, but I think 1.5x makes more sense. (Now fairly comparable to RA values). Going to leave it here.
Reduced Artillery damage vs. wood from 75% to 50%.
Slight tweak to recon bike damage 
Slight tweak to Stealth Tank damage vs. heavy armor
2013-03-03 19:31:33 -08:00
Chris Forbes
8931a1f4c1 Merge pull request #2722 from psydev/patch-2
vehicles.yaml update; a few smaller updates.
2013-03-03 17:46:39 -08:00
Chris Forbes
daa8e087f3 Merge pull request #2724 from psydev/patch-4
system.yaml: blue tiberium fix; crate fix (no mcvs)
2013-03-03 17:46:21 -08:00
Matthias Mailänder
29e917ae88 division through cell size to coarse cell coordinate vector 2013-03-03 23:11:03 +01:00
Matthias Mailänder
ef36c446bd log projectile dest as it is affected by inaccuracy calc
want to debug if this is the source of problems
2013-03-03 22:31:23 +01:00
Matthias Mailänder
76644537e2 give the users some hints when crashing due to desync 2013-03-03 19:34:10 +01:00
psydev
db521dad74 unit speeds fix; husk burn; tanks explode small
Vehicle speeds adjusted, now 80% on clear, like tanks. Intended to coincide with speed changes here: https://github.com/OpenRA/OpenRA/pull/2722
Husks burn 10 seconds now instead of 40. More fitting for cnc.
Tanks UnitExplodeSmall now by default.
2013-03-03 05:41:04 -08:00
psydev
8b504bc4b1 blue tiberium fix. crate fix (no mcvs)
Blue tiberium now poisons infantry
Crates no longer provide MCVs
levelup crate removed
crate lifetime increased
2013-03-03 05:35:01 -08:00
psydev
7503de33a5 vehicles.yaml update
see https://github.com/OpenRA/OpenRA/pull/2671 for details and rationales
2013-03-03 05:27:44 -08:00
psydev
9df613ee27 weapons.yaml update for CNC
See https://github.com/OpenRA/OpenRA/pull/2655 for details and rationales.
2013-03-03 05:03:04 -08:00
Scott_NZ
2f3def3f86 Updated CHANGELOG 2013-03-04 01:08:55 +13:00
Chris Forbes
5426e2c831 Merge pull request #2718 from Mailaender/admin-indicator
remove admin indicator icon to avoid confusion/overlapping
2013-03-03 01:35:15 -08:00
Chris Forbes
38b2b6cb4e Merge pull request #2557 from ihptru/fix2480
fix #2480; Direct Connect to different mod causes crash (saying 'missing...
2013-03-02 13:45:28 -08:00
Chris Forbes
94415d9cfb Merge pull request #2717 from Mailaender/gems-terrain
fixes #2716
2013-03-02 13:37:06 -08:00
Chris Forbes
2fb822e1c1 Merge pull request #2719 from Mailaender/hotkeys
Additional Hotkeys
2013-03-02 13:35:38 -08:00
Matthias Mailänder
0978d21439 fix problems in MultiTapDetection 2013-03-02 16:52:59 +01:00
Matthias Mailänder
775b0409c4 don't hard-code the pause-key 2013-03-02 15:56:13 +01:00
Matthias Mailänder
1083f8cf55 double-tap 0-9: select and center the control group 2013-03-02 15:55:42 +01:00
Matthias Mailänder
4cf8f9a434 remove admin indicator icon to avoid confusion/overlapping
print admin names in bold text instead
2013-03-02 15:01:11 +01:00
Matthias Mailänder
6152fa2890 fixes #2716
Gems were non-pathable and therefore also uncollectible
2013-03-02 14:58:17 +01:00
Matthias Mailänder
c0a702a386 new hotkey to center your view on the current selection 2013-03-02 11:53:45 +01:00
xaionaro
a332f3189b Adapted to dpkg's "--instdir"-like options.
For example, this may be useful if it is used a lot of versions of openra on debian
2013-03-02 13:36:33 +04:00
Okunev Yu Dmitry
e042ec5f3f Merge pull request #1 from OpenRA/bleed
Bleed
2013-03-02 00:19:25 -08:00
Chris Forbes
336076c248 Merge pull request #2665 from Mailaender/pvecfloat-combat
Fix floating point inconsistencies to reduce desyncs
2013-03-02 00:01:53 -08:00
Chris Forbes
c21b60f555 Merge pull request #2675 from Mailaender/simple-hotkey-config
user-configurable hotkey via in-game settings
2013-03-02 00:01:01 -08:00
Chris Forbes
efd0d81dca Merge pull request #2714 from ScottNZ/lobby
Revert client colours to their preferred colours after the map is changed
2013-03-02 00:00:04 -08:00
Scott_NZ
63467cd000 Revert client colours to their preferred colours after the map is changed to a map which doesn't lock colours. 2013-03-02 16:18:09 +13:00
Chris Forbes
46f4685eec Merge pull request #2712 from Mailaender/gems-minimap-color
Render crystals in a different color on the mini-map
2013-03-01 15:06:07 -08:00
Chris Forbes
af3a5cf939 Merge pull request #2713 from pchote/parachute-fix
Fix crash when an opponent uses Paratroopers.
2013-03-01 14:41:23 -08:00
Paul Chote
fb0ce8c06a Fix crash when an opponent uses Paratroopers. 2013-03-02 10:09:38 +13:00
Matthias Mailänder
8358597fd2 render crystals in a different color on the mini-map 2013-03-01 21:06:09 +01:00
Matthias Mailänder
b31f830cb1 key config settings code cleanup
- move label and textfield widget lookup into SetupKeyBinding
- fix wonkey indentions
- remove explicit private in WorldCommandWidget
2013-03-01 19:13:21 +01:00
Chris Forbes
561d47a6a1 Merge pull request #2705 from Mailaender/low-power-gap-crashfix
Fix NullReferenceException in UnHideActor
2013-03-01 01:57:23 -08:00
Chris Forbes
b8b0111aa2 Merge pull request #2706 from Mailaender/cnc-proc-desync-fix
Remove custom build time for Tiberium refinery to fix desyncs
2013-03-01 01:54:51 -08:00
Chris Forbes
f204f25474 Merge pull request #2707 from Mailaender/cnc-lobby-crashfix
Fix #2663 Crash when displaying the spawn tooltip in cnc mod
2013-03-01 01:54:18 -08:00
Matthias Mailänder
47075e1cd0 generate random numbers as floats
as they get converted from double before use anyway
2013-03-01 10:53:41 +01:00
Matthias Mailänder
793dfa5748 don't convert cell size to float for bullet inaccuracy
change it back to int / int / float
from int / float / float
was int / int / float before
2013-03-01 10:49:51 +01:00
Matthias Mailänder
0b493bcb09 remove redundant int to int conversion in rendered circles 2013-03-01 10:48:28 +01:00
Matthias Mailänder
dd476bbf5c add the total number of values extracted from RNG to sync report 2013-03-01 10:48:28 +01:00
Matthias Mailänder
fc5350c9f8 fix #2663 crash when displaying the spawn tooltip in cnc
don't hard-code ra border chrome in shared lobbyutils
2013-03-01 10:30:41 +01:00
Matthias Mailänder
b2c867bf2b remove custom build time for tiberium refinery
- this can be enabled again in cnc-classic
- needs a fix as it causes desyncs
2013-03-01 10:10:26 +01:00
Matthias Mailänder
3d8d116106 fix NullReferenceException in UnHideActor 2013-03-01 10:07:33 +01:00
Matthias Mailänder
4b2f08f21f convert start to int2 as CellContaining() spit that out before 2013-02-28 21:59:18 +01:00
Matthias Mailänder
233088077b don't convert to float2 in ReturnToBase as it was int2 before 2013-02-28 21:59:18 +01:00
Matthias Mailänder
a59621910e avoid floating point operation with heli fly int coordinates 2013-02-28 21:59:18 +01:00
Matthias Mailänder
05b6b59dad use Combat.IsInRange instead of float2.WithinEpsilon for heli 2013-02-28 21:59:18 +01:00
Matthias Mailänder
2bc7570674 remove conditional compile left-over junk 2013-02-28 21:59:18 +01:00
Matthias Mailänder
0085ac130b use PVecFloat in Combat sub-routines 2013-02-28 21:59:18 +01:00
Chris Forbes
7e1ee0e2e5 fix #2661: desyncs with shroud/exploration cheats 2013-03-01 09:29:03 +13:00
Chris Forbes
6bd3de8ec8 Fixed #2696: Sequences: Allow stride to be specified.
This allows you to use just some of the frames of an animation
which has multiple facings.

For example, if you have an animation which has 8 facings, and 6 frames
of animation per facing, but you only want to show 3 of them, you can now do:

    Facings: 8
    Length: 3       # the number of frames in each facing to actually use
    Stride: 6       # the number of frames per facing present in the SHP

If Stride is not specified, it defaults to Length, which is the old behavior.
It is an error to specify a stride less than the length -- this would produce
overlapping facings, or weirder.
2013-02-28 09:08:41 +13:00
Chris Forbes
fab7f2c4b6 Merge pull request #2684 from xaionaro/bleed
fixed a issue with pinging Master-server
2013-02-27 11:50:18 -08:00
Chris Forbes
ea799e5735 Merge pull request #2701 from psydev/patch-49
[cnc] structure sequences tick-rates corrected
2013-02-27 11:49:37 -08:00
Chris Forbes
3ab4112631 Merge remote-tracking branch 'pchote/cleanup' 2013-02-28 08:45:47 +13:00
Scott_NZ
817e6f1ec1 Have Tanya not shoot her pistols at buildings, and have her shoot pistols at barrels instead of using C4 on them 2013-02-27 17:57:53 +13:00
Scott_NZ
81c8f0360f Let's not crash if WeaponInfo.Report[] is empty 2013-02-26 18:08:55 +13:00
psydev
bec29d81c5 cnc-structure sequences tickrate fixed
Strucutre animations were too fast in many cases. These values seem to match up correctly to C&C 95.

Obelisk - Have not yet fixed (will do so when I fix how it fires)
SAM site - Someone may later decide to speed up how fast it pops up, for gameplay purposes
2013-02-25 16:05:11 -08:00
Paul Chote
3a11aeb434 Cache PaletteReference in RenderSimple. 2013-02-26 09:35:41 +13:00
Paul Chote
dddec1ec61 Add INotifyOwnerChanged interface 2013-02-26 09:35:41 +13:00
Paul Chote
82426e0e45 Move Palette from ModData to WorldRenderer. 2013-02-26 09:35:41 +13:00
Paul Chote
3033eb8be0 Die with a helpful error if a palette doesn't exist. 2013-02-26 09:35:41 +13:00
Paul Chote
e9665cf9f3 Remove WorldRenderer.GetPaletteIndex. 2013-02-26 09:35:41 +13:00
Paul Chote
9bc743068a Remove WorldRenderer.GetPalette. 2013-02-26 09:35:41 +13:00
Paul Chote
72a9954491 Simplify PaletteReference interface. 2013-02-26 09:35:40 +13:00
Paul Chote
f2fe30a7bb Remove PaletteReference.FromName from TeslaZap. 2013-02-26 09:35:39 +13:00
Paul Chote
ce39c79477 Apply consistent formatting to PBOG (no code changes). 2013-02-26 09:32:16 +13:00
Paul Chote
6fc4807a10 Remove PaletteReference.FromName from PBOG. 2013-02-26 09:31:19 +13:00
Paul Chote
f890ea010e Pass WorldRenderer to RenderAsTerrain for palette lookup. 2013-02-26 09:24:43 +13:00
Paul Chote
5b360a7fe2 Use PaletteReferences in ShroudRenderer. 2013-02-26 09:24:43 +13:00
Paul Chote
55efd53ef7 Make RenderSimple.Palette protected. 2013-02-26 09:24:43 +13:00
Paul Chote
fa5cf96f40 Ditto for Corpse. 2013-02-26 09:24:43 +13:00
Paul Chote
e33c783fc1 Ditto for GpsDot. 2013-02-26 09:24:42 +13:00
Scott_NZ
1438030e82 Add mood haze effect for Allies 04 2013-02-26 00:10:03 +13:00
Scott_NZ
09e4d64f99 Fix Allies 02 warnings 2013-02-25 23:40:31 +13:00
Scott_NZ
b5bd6191c2 Don't crash (due to replay file being in use) if we have two instances of the game playing 2013-02-25 21:24:17 +13:00
Scott_NZ
e57de0ebce Allies 02 code maintenance. Add FreeActorInit so free harvesters with procs can be disabled etc 2013-02-25 21:24:17 +13:00
Scott_NZ
3bc9e7d2e4 Fix some playerstatistics related crashes for other mods 2013-02-25 21:24:17 +13:00
Scott_NZ
6b636b166c Check Crates setting in CrateSpawner too 2013-02-25 21:24:17 +13:00
Scott_NZ
026a86ba75 Add 'Crates' lobby checkbox and setting for enabling/disabling crate drops 2013-02-25 21:24:17 +13:00
Paul Chote
5a4bd14835 Ditto for RallyPoint. 2013-02-25 21:12:01 +13:00
Paul Chote
43159a0e05 Remove RepairIndicator dependence on target RenderSimple.
This also fixes the case where the building palette doesn't
match the indicator, and saves 2 trait lookups per tick.
2013-02-25 21:12:01 +13:00
Paul Chote
3380817865 Pass WorldRenderer to Render(). 2013-02-25 21:11:33 +13:00
Paul Chote
d6fcaafd78 Let parachute cargo render themselves.
This allows for tanks and other multi-sprite
actors to render correctly while dropping.
2013-02-25 21:10:16 +13:00
Paul Chote
0703f3f164 Extract auto-selection-size into its own interface. 2013-02-25 21:10:08 +13:00
Chris Forbes
a083554218 Merge pull request #2669 from Generalcamo/patch-7
Add support for Nyergud's Music Upgrade pack
2013-02-24 18:20:31 -08:00
Chris Forbes
c34c62ad42 Merge pull request #2672 from psydev/patch-48
[cnc] inftry detect cloaked in next tile(C&C orig)
2013-02-24 18:16:24 -08:00
Chris Forbes
fc3c091a48 Merge pull request #2670 from psydev/patch-47
[cnc] added names for explosions
2013-02-24 18:14:00 -08:00
Paul Chote
000a5eaa56 Pass WorldRenderer to IRenderModifiers and replace more palette lookups. 2013-02-24 15:45:03 +13:00
Paul Chote
48d713aafd Pass a PaletteReference to RenderPreview. 2013-02-24 15:43:20 +13:00
Paul Chote
885eec7444 Move effects to WorldRenderer palette lookup. 2013-02-24 15:43:20 +13:00
Paul Chote
95871e6cc1 Add a cache of PaletteReferences to WorldRenderer.
I don't expect any perf improvements by using this
cache, as you're simply moving the row lookup from
render-time to fetch-time. However, this is a
cleaner abstraction, and allows us to fail early
if the palette doesn't exist.
2013-02-24 15:43:19 +13:00
Paul Chote
f0ba0ce2e8 Wrap palette references with a PaletteRef object. 2013-02-24 15:43:15 +13:00
Paul Chote
a166815348 Remove duplication between world/chrome shaders. 2013-02-23 09:53:46 +13:00
Paul Chote
35a149ea87 Apply consistent formatting to Renderer (no code changes). 2013-02-23 09:46:16 +13:00
Paul Chote
0287993c31 Add bitmap export to palette (for debugging). 2013-02-22 17:11:18 +13:00
Paul Chote
2d10f6b739 Remove unnecessary indirection from palette creation. 2013-02-22 17:06:29 +13:00
Paul Chote
db7887687b Remove hardcoded list of palette mod exclusions. 2013-02-22 15:04:41 +13:00
Paul Chote
f593807617 Rework color picker palette modification.
The old method had the lobby code dig around inside
the palette modification machinery, which was a giant
hack preventing necessary streamlining.
2013-02-22 15:04:41 +13:00
Chris Forbes
6da02b7b92 Merge pull request #2662 from psydev/patch-40
[cnc] Obelisk AutoTargeted, airstrike cooldown, +misc.
2013-02-20 12:24:57 -08:00
xaionaro
86c99c47c9 https://github.com/OpenRA/OpenRA/issues/2564
fixed a issue with pinging Master-server

Sometimes initial TickCount is less than zero, so (Environment.TickCount - lastPing) can be less than "MasterPingInterval * 1000". That's why PingMasterServer() is not calling for a long time until somebody connected.
2013-02-13 20:51:37 +04:00
Scott_NZ
3b3e39b375 Don't allow MCV/FACT to be sold
This is almost always done to exploit the `free mcv` logic in the crates.
2013-02-13 15:25:47 +13:00
Scott_NZ
4b3feed324 Make a lack of random map yaml be non-fatal 2013-02-12 22:47:34 +13:00
Scott_NZ
57dd8bb91e Add Random Map lobby button 2013-02-12 22:21:34 +13:00
Scott_NZ
34b1f90200 Anti-basewalk balance adjustments. Includes moving fact over to wood and giving it 500 more health, increasing superweapon healths and moving mslo to wood, moving pbox to heavy 2013-02-11 18:00:30 +13:00
Scott_NZ
128e2c9e1f Add objectives to MonsterTankMadness 2013-02-11 00:54:53 +13:00
psydev
d0669823a2 changing name of big_poof, for consistency
Changed "big_poof" to simply "poof". 

The word "big" will only appear if there are small, medium and large versions of the explosion.
Otherwise, it will just be "explosion" and "small_explosion".
2013-02-09 15:26:41 -08:00
Matthias Mailänder
1f99b1ec8e make hotkey user-configurable via in-game settings 2013-02-09 14:08:36 +01:00
Scott_NZ
2c5eeb551e Adjust MonsterTankMadnessScript super tank movement times 2013-02-09 12:19:41 +13:00
Scott_NZ
54906702bd Fix alliedBaseProc unused variable warning 2013-02-09 12:19:41 +13:00
Scott_NZ
ec56311a3d Fix victory on start of MMM 2013-02-09 12:19:41 +13:00
Scott_NZ
cdd09ea24f Finish early version of Monster Tank Madness 2013-02-09 12:19:40 +13:00
Scott_NZ
1ecdbc1d90 Fix spyvoice/reveal range for truk.hijackable in Allies 04 2013-02-09 12:19:40 +13:00
Scott_NZ
b1a5195c51 Let's not fail right at the beginning, count units too ;) 2013-02-09 12:19:40 +13:00
Scott_NZ
03f03ff501 More MonsterTankMadness work. Add routines for super tanks, civilian evacuees, proving grounds camera, base transfer, Demitri extraction 2013-02-09 12:19:40 +13:00
Scott_NZ
3c5967a623 Add ore capping to MissionUtils. Add world.CreateActor extension in MissionUtils. 2013-02-09 12:19:40 +13:00
Scott_NZ
9013e8376c Start work on Monster Tank Madness mission 2013-02-09 12:19:40 +13:00
Scott_NZ
9b5b054297 Add delphi. Have einstein/delphi panic 2013-02-09 12:19:39 +13:00
Scott_NZ
4e161f0c91 Change V19 tooltip to Oil Pump 2013-02-09 12:19:39 +13:00
Scott_NZ
6bbd54ab93 Put e1 inside the soviet 01 classic pillboxes. Add check for mission complete 2013-02-09 12:19:39 +13:00
Scott_NZ
87190762d1 Add V19 civilian building 2013-02-09 12:19:39 +13:00
Scott_NZ
f4da36065f Add ability to have randomised reports for weapons 2013-02-09 12:19:39 +13:00
Scott_NZ
e71135b511 Better error messages when merging duplicate yaml 2013-02-09 12:17:16 +13:00
psydev
dfc880807e [cnc] Airstrike cooldown 3 mins. (from 4). tweaks.
Air Strike cooldown time reduced from 4 minutes to 3. (Ion Cannon is 3). [games are short in CNC, and waiting 4 minutes for your first airstrike is a long time.]
HQ's hitpoints reduced to 750, so it can be nuked in one shot. (but not Ion Cannon'd) 
Airfield HP reduced to 1500, so Ion + Airstrike can destroy it. (For some reason, it doesn't die as easily as Weapons Factory, despite having the same HP)
2013-02-06 16:06:47 -08:00
psydev
d12853ddf7 [cnc] inftry detect cloaked in next tile(C&C orig)
Infantry can detect cloaked units in the next tile. This behaviour was in the original C&C Gold.
(Even though it says range=2, it is actually just in the next tile)

Fixed GrenadierExplode.
2013-02-06 14:20:09 -08:00
psydev
f1019ab332 [cnc] added names for explosions
Easier-to-understand names for explosions, which can be used in the future. Can phase out old names/numbers slowly.
Also included some explosions from the C&C Content which were not in use and did not have names.
2013-02-06 12:21:04 -08:00
Cody Brittain
96d1f8d83b Update mods/cnc/mod.yaml
Add support for Nyergud's Music Upgrade Pack
2013-02-06 08:35:27 -05:00
psydev
c4fc0e57b3 [cnc] Obelisk now AutoTargeted by units, etc.
Obelisk of light was missing "-AutoTargetIgnore". All the guard towers have it, but for some reason the Obelisk didn't.
2013-02-04 18:39:26 -08:00
Chris Forbes
6403c5e6af Fixed #2651: Units not in world should not be added to the attack force
Otherwise, a pillbox's e1 passenger is counted as part of the attack
force and ends up jamming HackyAI's attack logic until it is destroyed.
2013-02-05 07:09:05 +13:00
Scott_NZ
b3fbafad59 Use Action<bool> for objective delegate type 2013-02-03 14:27:43 +13:00
Scott_NZ
7594c4eab2 Clamp reveal range to 0-50 in PlayerStatistics to stop crashes for actors with reveal ranges > 50 2013-02-03 14:27:43 +13:00
Scott_NZ
4163f1d6b0 Clean up Allies 04 yaml. Adjust hero spy reveal range from 5 to 6. Add TRUK as buildable unit 2013-02-03 14:27:43 +13:00
Scott_NZ
ea716200a7 Allies 04: Fix multiple waves of spies being able to infiltrate the lab 2013-02-03 14:27:43 +13:00
Kenny
2bd9b7a640 Enabling mobile gap generators. 2013-01-31 16:57:04 +13:00
Kenny
4f670d516d Shroud creators now only temporarily block explored shroud.
On powerdown or removal from the game, any previously explored terrain will become visible once again.
2013-01-31 16:57:04 +13:00
Matthias Mailänder
f5835244c7 use markdown for readme and contributing guidelines
- https://github.com/github/markup
- https://github.com/blog/1184-contributing-guidelines
2013-01-31 16:32:46 +13:00
psydev
b00b1c36bc Helipad reduced to $1000. Palette order fixed.
Helipad price reduced to $1000. Should make helicopter transports more accessible. Should also make having a few "support helis" flying around a more viable strategy, for non-standard builds.
Fixed palette order to be better grouped and in more progressive order. 
Re-arranged document so that it's sorted better.
2013-01-31 16:30:48 +13:00
psydev
b2ddc6cfd8 [CNC] Chinook priced reduced to $750
Halved Chinook price, $1500 to $750.
Infantry should be a more feasible strategy, and transporting them quickly will make them more usable.
This should be good for Nod especially since they don't have APCs.
2013-01-31 16:29:52 +13:00
Matthias Mailänder
0d6dbdc58b increment debian copyright year 2013-01-31 16:28:14 +13:00
Matthias Mailänder
78baf76ae1 adhere to SPDX for RPM 2013-01-31 16:28:14 +13:00
Matthias Mailänder
43c43e25c4 adhere to opendesktop menu-spec
Version= is the version of the .desktop file specification!
2013-01-31 16:28:14 +13:00
Cody Brittain
32daf025ab cnc: Update cloaking, building destroyed sounds
- Use trans1.aud as the cloak sound, on both STNK and cloak
  given from crates

- Use crumble.aud rather than xplobig4.aud for building destruction
2013-01-31 16:23:03 +13:00
ScottNZ
750bdb7bba Update CHANGELOG
Some typos/wording issues fixed
2013-01-28 19:47:31 +13:00
Scott_NZ
8a796416a4 Remove AutoTargetIgnore for stek after Einstein is freed 2013-01-28 00:33:09 +13:00
Scott_NZ
691e6cf9e8 Have the Soviets build infantry after Einstein is found. Remove jeep cargo limit 2013-01-28 00:33:08 +13:00
Scott_NZ
de208e7a2f Fix nonworking attack code in Allies 01 2013-01-28 00:33:08 +13:00
Scott_NZ
63a72c5d28 Remove unused variable 2013-01-28 00:33:08 +13:00
Scott_NZ
b6b4b89008 Refactor cash code in Allies campaign. Adjust starting cash to 10000 in SP Allies 03 2013-01-28 00:33:08 +13:00
Scott_NZ
0b65735d86 Make the LSTs unbuildable 2013-01-28 00:33:07 +13:00
Scott_NZ
44215ae6f1 Add new trait interface INotifyTransformed and use it in Allies 04 to make the transport remove its cargo capacity after it unloads its passengers 2013-01-28 00:33:07 +13:00
Scott_NZ
fba5b80980 Allies 04: Add more town stuff. Remove leftover hind stuff. Only have patrol 3 on hard difficulty 2013-01-28 00:33:07 +13:00
Scott_NZ
3f6af59612 Add AutoTargetIgnore for the new bridges 2013-01-28 00:33:07 +13:00
Scott_NZ
693a622322 Fix Soviets not attacking town properly. Remove hind patrol. 2013-01-28 00:33:07 +13:00
Scott_NZ
60e9d3f660 Add c3 civilian, made by JOo 2013-01-28 00:33:06 +13:00
Scott_NZ
1d40858f70 Have the Soviets attack the town in Allies 04 2013-01-28 00:33:06 +13:00
Scott_NZ
5188529ff6 Allies 04: Adjust one of the patrol routes 2013-01-28 00:33:06 +13:00
Scott_NZ
2079db79f7 Allies 04: Hack in a fix to stop player hero spies infiltrating buildings they shouldn't 2013-01-28 00:33:05 +13:00
Scott_NZ
d73eec068f Fix some bad Allies 01 bounty yaml 2013-01-28 00:33:05 +13:00
Scott_NZ
8a32e5761c Change map player clientindex to 0 2013-01-28 00:33:05 +13:00
Scott_NZ
12e1a531fe Tidy campaign stuff 2013-01-28 00:33:05 +13:00
Scott_NZ
32830da3c2 Remove bounties from things in Allies 01 2013-01-28 00:33:05 +13:00
Scott_NZ
9f47e75492 Allies 01: only set eligible units to defensive stance 2013-01-28 00:33:04 +13:00
Scott_NZ
e975681c16 Add more time to complete Allies 04 - the bridge destruction makes the mission more difficult 2013-01-28 00:33:04 +13:00
Scott_NZ
a968d296bb Remove v01.sniper from Allies 04 2013-01-28 00:33:04 +13:00
Scott_NZ
031240ffc1 Campaign: reduce failed/accomplished code duplication 2013-01-28 00:33:04 +13:00
Scott_NZ
dfc4b07b1a Campaign: Don't rely on world.issueorder anymore 2013-01-28 00:33:04 +13:00
Scott_NZ
63241dbf69 Allies 04. Make the v01.sniper trivial so players can ignore it. 2013-01-28 00:33:03 +13:00
Scott_NZ
5b7523b9e0 Allies 04: Make Soviets sell buildings when they are low on health. Have the bridge be destroyed by a Soviet tank 2013-01-28 00:33:03 +13:00
Matthias Mailänder
4b228a71ef Update CHANGELOG
- Dune 2000
- Editor/Remapping
- GUI improvements by Carko
- More verbose about Volkov changes
- Preparations for i18n
2013-01-27 12:17:20 +01:00
Matthias Mailänder
0f864c3192 treat compiler warnings as errors 2013-01-18 00:23:50 +01:00
Matthias Mailänder
e475d0d0b9 Added travis script 2013-01-18 00:23:19 +01:00
Cody Brittain
1635ace182 Update CHANGELOG
Just a couple things added
2013-01-18 11:09:26 +13:00
Matthias Mailänder
b4e3ce5de6 fix make for mono 3
error CS1902: Invalid debug option `+'.
Valid options are `full' or `pdbonly'
2013-01-18 11:08:10 +13:00
Carko
50ceb7c4dd Fixed the asynchronous map loading behavior when changing filter 2013-01-18 11:00:56 +13:00
Carko
4395a04d57 Asynchronous loading of map previews in the map chooser dialog 2013-01-18 11:00:56 +13:00
Matthias Mailänder
c5313375f0 pull mouse button preference from global property 2013-01-18 10:57:41 +13:00
Matthias Mailänder
2503ddfde4 let Chronotank/Minelayer accept left-click-orders 2013-01-18 10:57:41 +13:00
Matthias Mailänder
b356cca528 improve the classic mouse behaivor
- don't require to deselect units to change selection
- fix issue with broken building placement on right-click orders
- don't select enemy units when left-click attacking
- build palette won't interfere with unit orders anymore
2013-01-18 10:57:41 +13:00
Matthias Mailänder
d52394bb47 add classic left-click orders 2013-01-18 10:57:40 +13:00
Scott_NZ
1da2d89ced Only play movies in Allies 01 and Soviet 01 Classic if there's one client 2013-01-15 17:43:39 +13:00
ScottNZ
a88a7d9834 Update CHANGELOG 2013-01-13 16:06:05 +13:00
Scott_NZ
9507fde91d Fix untargetable barrel in Soviet 01 2013-01-13 00:24:28 +13:00
Scott_NZ
742a27158a Make oil derricks repairable by engineers 2013-01-12 18:55:59 +13:00
Scott_NZ
5ed383e3e2 Change mech hotkey to c 2013-01-12 18:35:01 +13:00
Scott_NZ
1679837e46 Fix mechanic being able to repair infantry. Adjust mechanic repair damage from 20 to 10 2013-01-11 17:17:14 +13:00
Scott_NZ
eb3685fe67 Fix a lack of difficulty dropdown yaml in other mods (d2k/cnc) causing crashes 2013-01-09 21:50:20 +13:00
Carko
50f8465d1e Removed mouse capture while composing text in chat (fixes #2486) 2013-01-09 16:47:39 +13:00
Cody Brittain
5502864a1f Update mods/ra/music.yaml
Mud no longer crashes: Bring it back in.
2013-01-09 07:56:30 +13:00
Carko
d572e59d2e Checking for build prerequisites before showing them in a tooltip 2013-01-09 07:54:01 +13:00
Carko
e313bbfb31 Added a build limit of 1 to Tanya and Volkov
Added the build limit of 1 to MSLO
2013-01-09 07:54:01 +13:00
Carko
a51c5fd9ca Added Buildable->BuildLimit option to limit the number of actors a player can build of the type 2013-01-09 07:54:01 +13:00
Sam Hegarty
0c104cfc3a Add a 'Shutting down' state to the gameserver.
Tell the masterserver about it, so it can quickly remove games
from the list when they are finished, rather than waiting for the
5 minute TTL to expire.
2013-01-08 23:02:28 +13:00
Chris Forbes
3a77082c66 silence warnings in allies03/04 2013-01-08 22:54:38 +13:00
Scott_NZ
975e4db452 Change facing of the 2 guarding heavy tanks in Allies 04 2013-01-08 22:44:10 +13:00
Scott_NZ
d92f184bc9 Add civilian movement and balance changes in Allies 04 2013-01-08 22:44:10 +13:00
Scott_NZ
2eea5cc3b2 Give SAM sites turret facings in Allies 04 2013-01-08 22:44:09 +13:00
Scott_NZ
0e8cb14099 Allies 04: Give money to players after they receive mcvs 2013-01-08 22:44:09 +13:00
Scott_NZ
1ec3b2ffe2 Fix whitespace in objectives 2013-01-08 22:44:09 +13:00
Scott_NZ
c836d69385 Add easy mode to Allies 01 which is like the classic mission 2013-01-08 22:44:09 +13:00
Scott_NZ
11c45e4388 Start unbreaking ScaredyCat 2013-01-08 22:44:08 +13:00
Scott_NZ
3b9fac9c84 Prevent warning in Allies 04 code 2013-01-08 22:44:08 +13:00
Scott_NZ
185558985e Have civilians come out of disturbed buildings 2013-01-08 22:44:08 +13:00
Scott_NZ
e3d25f6fed Give MISS a tooltip 2013-01-08 22:44:07 +13:00
Scott_NZ
200071e713 Add reinforcements paradrops 2013-01-08 22:44:07 +13:00
Scott_NZ
bdb7bb97cd Split long objective strings over several lines 2013-01-08 22:44:07 +13:00
Scott_NZ
82809f27f7 Reduce mission music code duplication 2013-01-08 22:44:06 +13:00
Scott_NZ
c8e84b3a11 Add license notice 2013-01-08 22:44:06 +13:00
Scott_NZ
9581f07242 Add first version of Soviet 01 classic 2013-01-08 22:44:06 +13:00
Scott_NZ
411aedafa0 Setup c3-c10 placeholder civilians. 2013-01-08 22:44:05 +13:00
Scott_NZ
f7f307c3bf LegacyMapImporter: Remove Italy as it's a bogus country. Change Germany to black. Collapse some duplicate cases. 2013-01-08 22:44:05 +13:00
Scott_NZ
c10df031bd Convert classic waypoints to waypoint not mpspawn 2013-01-08 22:44:05 +13:00
Scott_NZ
a56228aba1 Add Italy country 2013-01-08 22:44:05 +13:00
Scott_NZ
1b09544314 Default to allies for neutral in ra, gdi in cnc 2013-01-08 22:44:04 +13:00
Scott_NZ
2dc18594a2 Handle RA with GoodGuy/BadGuy players 2013-01-08 22:44:04 +13:00
Scott_NZ
baa7a58a10 Don't blow up if classic maps have Multi{0} in them either 2013-01-08 22:44:04 +13:00
Scott_NZ
bb5212d2bb Fix classic SP maps failing to import into the editor 2013-01-08 22:44:03 +13:00
Scott_NZ
38db7d1e50 Make the Soviets repair their buildings in Allies 04 2013-01-08 22:44:03 +13:00
Scott_NZ
3371085da0 Move viewport to reinforcements location after infiltration 2013-01-08 22:44:03 +13:00
Scott_NZ
5c688370ed Add difficulty options to Allies 04 2013-01-08 22:44:03 +13:00
Scott_NZ
ab01722d96 Clean up the patrol code 2013-01-08 22:44:02 +13:00
Scott_NZ
ae5cb9864a Adjust timer text 2013-01-08 22:44:02 +13:00
Scott_NZ
43e5838555 Adjusted wording of objectives 2013-01-08 22:44:02 +13:00
Scott_NZ
cf8b02de26 Add 25 min countdown timer for destroying the enemy base. 2013-01-08 22:44:01 +13:00
Scott_NZ
d3ede583c2 Make OILB trivial too 2013-01-08 22:44:01 +13:00
Scott_NZ
cda871d2eb Add missing colon 2013-01-08 22:44:01 +13:00
Scott_NZ
2ea3b77b7a Create new actors so the effects aren't carried over to built units in Allies 04. Make yak buildable by Allies again in Allies 02. Make STEK autotargetignore in Allies 01. Make MISS autotargetignore in Allies 04. 2013-01-08 22:44:00 +13:00
Scott_NZ
3ab04e4c30 Fix crash with patrols. Add more room for the Allied base 2013-01-08 22:44:00 +13:00
Scott_NZ
3b2190d720 Fixed the supply truck not being able to carry 2 passengers 2013-01-08 22:44:00 +13:00
Scott_NZ
b3691dcce9 Add base guard, hind and second objective 2013-01-08 22:44:00 +13:00
Scott_NZ
722bc00c9b Add checkpoint at the large base 2013-01-08 22:43:59 +13:00
Scott_NZ
fe07da8634 Give control of the hijacked vehicle to another passenger if the driver leaves 2013-01-08 22:43:59 +13:00
Scott_NZ
54feab66e0 Add hijackable truck to Allies 04 2013-01-08 22:43:59 +13:00
Scott_NZ
fda897c69e Add more patrols 2013-01-08 22:43:58 +13:00
Scott_NZ
31d3616b8d Actually add the Allies 04 script. Also we have dog patrols now 2013-01-08 22:43:58 +13:00
Scott_NZ
eb6bab36a0 Begin Allies 04 script 2013-01-08 22:43:58 +13:00
Scott_NZ
81f9798307 More mapping of Allies 04 2013-01-08 22:43:58 +13:00
Scott_NZ
d1dafd5782 More Allies 04 mapping 2013-01-08 22:43:57 +13:00
Scott_NZ
799a2ea541 Fixed difficulty code indentation 2013-01-08 22:43:57 +13:00
Scott_NZ
4b2e45bbae Refactor default difficulty setting into its own method 2013-01-08 22:43:57 +13:00
Scott_NZ
32721ac8cb Reposition info widgets/countdown timer widgets in centre top of vp 2013-01-08 22:43:56 +13:00
Scott_NZ
6871d2ed37 Have paradrops and mammoths come sooner if we're on hard difficulty 2013-01-08 22:43:56 +13:00
Scott_NZ
bdfa6f6ecc Slight refactor 2013-01-08 22:43:56 +13:00
Scott_NZ
c59fbd5f9d Adjust Allies 03 difficulties 2013-01-08 22:43:56 +13:00
Scott_NZ
54916cc548 Add Easy difficulty to Allies 03 2013-01-08 22:43:55 +13:00
Scott_NZ
3ff3ed39fb Fix slight logic error with difficulty 2013-01-08 22:43:55 +13:00
Scott_NZ
a8dbedd486 Fix default difficulty not being serialised 2013-01-08 22:43:55 +13:00
Scott_NZ
988a68dae5 Attempt to fix NRE that hamb got 2013-01-08 22:43:55 +13:00
Scott_NZ
9a9c5911a6 Hard difficulty for allies 03 2013-01-08 22:43:54 +13:00
Scott_NZ
bfb07e9948 Add support for mission difficulties 2013-01-08 22:43:54 +13:00
Scott_NZ
dda4e2c33a Add objective for MGG 2013-01-08 22:42:50 +13:00
Scott_NZ
05e143662d Make Allies 02 easier in SP mode 2013-01-08 22:42:50 +13:00
Scott_NZ
9e2f15bde4 Allies 03 code cleanup 2013-01-08 22:42:50 +13:00
Scott_NZ
8f90423793 Update units evacuated immediately in Allies 03 2013-01-08 22:42:50 +13:00
Scott_NZ
eecc002236 More balancing improvements to Allies 03: remove arty, agun, reduce number of yaks and paradrops 2013-01-08 22:42:49 +13:00
Scott_NZ
4167d3291a Offset MGG husk spinner 2013-01-08 22:42:49 +13:00
Scott_NZ
3be6229cf2 Add MGG husk 2013-01-08 22:42:49 +13:00
Scott_NZ
5f693945f0 Take all ore/cash from Allies 01 player 2013-01-08 22:42:49 +13:00
Scott_NZ
82f478716c Add AutoTargetIgnore to barrels 2013-01-08 22:42:48 +13:00
Scott_NZ
6544069aa2 More Allies 03 balancing adjustments 2013-01-08 22:42:48 +13:00
Scott_NZ
8486a4fbae Adjust Allies 03 balancing 2013-01-08 22:42:48 +13:00
Scott_NZ
edd1138556 Use classic RA country colours in missions 2013-01-08 22:42:48 +13:00
Scott_NZ
14ed3ae816 Add paradropping at endgame in Allies 03 2013-01-08 22:42:47 +13:00
Scott_NZ
d5db9e88d4 Put bridge across water 2013-01-08 22:42:47 +13:00
Scott_NZ
f0a4fa7712 Add more airfields to destroy in Allies 03, and have reinforcements in Allies 02 and Allies 03 come in gradually. 2013-01-08 22:42:47 +13:00
Scott_NZ
1f92768193 Remove FirstUnshroudedOrDefault from MissionUtils.cs 2013-01-08 22:42:46 +13:00
Scott_NZ
ccfcf0a1ee Have the minimum difference between attack frames in Allies 03 be lower for 2 players 2013-01-08 22:42:46 +13:00
Scott_NZ
51626bf0db Outlined Allies 04 map 2013-01-08 22:42:46 +13:00
Scott_NZ
be6da2452a Change Allies map types to Campaign 2013-01-08 22:42:46 +13:00
Scott_NZ
ec423db4e5 Don't hog the CPU trying to path to the enemy base in Allies 03, to line up with Allies 02 2013-01-08 22:42:45 +13:00
Scott_NZ
4c7f215559 Rename 'economic' to 'economy' in stats panel 2013-01-08 22:42:45 +13:00
Scott_NZ
0f9da06309 Have graph lines not draw over the axes 2013-01-08 22:42:45 +13:00
Scott_NZ
4ce6cabc46 Better numbers for the LineGraph y axis 2013-01-08 22:42:45 +13:00
Scott_NZ
b2b13b98b7 Use a default max value of 5000 on the line graph if it's too low 2013-01-08 22:42:44 +13:00
Scott_NZ
4c729ca5ed Refactored GraphWidget to LineGraphWidget 2013-01-08 22:42:44 +13:00
Scott_NZ
a78f8865b8 Moved the graph widget into OpenRA.Game - it doesn't really have any dependencies on the RA mod 2013-01-08 22:42:44 +13:00
Scott_NZ
d5b37d4343 Cleanup, refactoring of stats graph widget. 2013-01-08 22:42:44 +13:00
Scott_NZ
e424883857 Improve graph. Add things like scales/axis labelling. 2013-01-08 22:42:43 +13:00
Scott_NZ
b6e8c9c9ea Start implementing graphs for the stats panel 2013-01-08 22:42:43 +13:00
Scott_NZ
ed9bb72dbe Add more things to the Combat tab 2013-01-08 22:42:43 +13:00
Scott_NZ
9753808936 Renamed OrderCounter to PlayerStatistics. Simplify income to simply earned/min. 2013-01-08 22:42:43 +13:00
Scott_NZ
82fdbc4bc6 Move OrderCounter into Orders subnamespace 2013-01-08 22:42:42 +13:00
Scott_NZ
d7f3b81e4c Add Map Control statistic 2013-01-08 22:42:42 +13:00
Scott_NZ
36f349ecba Add Order counter for rough APM estimation. Rename Support to Production and move the production icons there 2013-01-08 22:42:42 +13:00
Scott_NZ
30a374b9e9 Add total earned/spent tracking 2013-01-08 22:42:42 +13:00
Scott_NZ
2a0b9a8596 Display support powers 2013-01-08 22:42:41 +13:00
Scott_NZ
9a9324946f Add dropdown for economic information 2013-01-08 22:42:41 +13:00
Scott_NZ
babf1556e3 Refactor the stats YAML and logic to more easily support swapping in data 2013-01-08 22:42:41 +13:00
Scott_NZ
bb1c87b084 Add clocks and text overlays for the production icons 2013-01-08 22:42:41 +13:00
Scott_NZ
1c584fb158 Consolidate the production icons into a single widget. Add income tracking for players. 2013-01-08 22:42:40 +13:00
Scott_NZ
83e1855919 Add indication of what players are building 2013-01-08 22:42:40 +13:00
Scott_NZ
4bc04769ec Subscribe to click event directly in the setup method 2013-01-08 22:42:40 +13:00
Scott_NZ
178358c29a Fixed Stats panel player selection silliness 2013-01-08 22:42:40 +13:00
Scott_NZ
42b16f74a1 Slightly adjust the width of the templates 2013-01-08 22:42:39 +13:00
Scott_NZ
9b493ad9e7 Remove unused usings 2013-01-08 22:42:39 +13:00
Scott_NZ
d7d5baae0e Add an observer stats panel 2013-01-08 22:42:39 +13:00
Scott_NZ
a8e434b74d Add radar for spectators 2013-01-08 22:42:39 +13:00
Scott_NZ
07d5ba8405 Remove Soviet econ hacks and power checks in Allies 02. 2013-01-08 22:42:39 +13:00
Scott_NZ
a5141f9908 proc.nofreeactor was causing harv to not unload properly. Just spawn a normal proc after we've changed the owner of the Allied base. 2013-01-08 22:42:38 +13:00
Scott_NZ
d15fb82b08 Allies 02 SP mode bug fixes 2013-01-08 22:42:38 +13:00
Scott_NZ
947b27a227 Make Allies 02 work in SP mode 2013-01-08 22:42:38 +13:00
Scott_NZ
b49110bf5c Ignore spies if they are disguised in Allies 03 2013-01-08 22:42:38 +13:00
Scott_NZ
8578958e40 Difficulty/balance changes 2013-01-08 22:42:37 +13:00
Scott_NZ
65e78ca8b0 Additional ore mines 2013-01-08 22:42:37 +13:00
Scott_NZ
608bf9ada1 Have the mggs come offmap, we don't want the player building too many. 2013-01-08 22:42:37 +13:00
Scott_NZ
4373831317 Remove econ hacks in Allies 03 and have the Soviets actually build their yaks. 2013-01-08 22:42:37 +13:00
Scott_NZ
aa78d63d72 Increased minimum attack increment 2013-01-08 22:42:36 +13:00
Scott_NZ
400d94caba Give the Soviets a Soviet construction yard in case the Allies lose theirs - they can capture this as a last resort. Make yaks buildable by Allies if they capture the Airfield buildings. 2013-01-08 22:42:36 +13:00
Scott_NZ
1660c4fe7c Reduce some code duplication 2013-01-08 22:42:36 +13:00
Scott_NZ
e643f12371 Attempted fix for Allies 03 crash (#2471) 2013-01-08 22:42:36 +13:00
Scott_NZ
339c0bc520 Fix weird plane spawn/management logic. Have Soviets ignore units that are concealed by gap generators 2013-01-08 22:42:36 +13:00
Scott_NZ
e15c240a8f Remove some old noise from the map 2013-01-08 22:42:35 +13:00
Scott_NZ
7bd66c2560 Render the shroud range circle for mgg 2013-01-08 22:42:35 +13:00
Scott_NZ
1f8fd404e5 Much better yak management. Map improvements. 2013-01-08 22:42:35 +13:00
Scott_NZ
93e951eb75 Added mobile gap generator. It is currently unbuildable and it does not generate shroud - this requires some additional shroud work since you can paint shroud across the map by moving it. 2013-01-08 22:42:35 +13:00
Scott_NZ
c52cd77c4c Add mechanic 2013-01-08 22:42:34 +13:00
Scott_NZ
0da911c9f8 Delete mods/d2k/bits/turret1.aud (not mods/d2k/bits/TURRET1.aud). This old, unused file was causing oddities for users with NTFS since we had two different files in the repository with filenames that differ only by case, and NTFS has case-insensitive filenames. 2013-01-08 22:42:34 +13:00
Igor Popov
395aa0fc10 dedicated: never let Bot become an admin 2013-01-08 22:34:03 +13:00
Carko
e10920d4ea Added the spawnpoint map tooltip that displays players name in the lobby (closes #2024) 2013-01-08 22:22:25 +13:00
Carko
914afa2dee Removed StringSplitOptions.RemoveEmptyEntries when counting wrapped text lines 2013-01-08 22:11:56 +13:00
Carko
ca1e0b4c48 Added word wrapping to in-game chat (fixes #2093) 2013-01-08 22:11:56 +13:00
Carko
70cf48dcaf Added a power bin tooltip that shows provided and drained power 2013-01-08 22:08:12 +13:00
Igor Popov
68130c85f3 fix #2453; MOTD for lobby (to be fetched from file); different motd for each mod 2013-01-08 21:57:25 +13:00
Chris Forbes
d0aea18b3e Added new map: "Bad Neighbors" from Nukem 2013-01-08 21:57:09 +13:00
Curtis Shmyr
ac301b22e2 Editor - Template categories are now ordered by whats specified in the tileset yaml 2013-01-08 20:11:22 +13:00
Curtis Shmyr
b56125fa39 Added terrain category types to RA Snow tileset 2013-01-08 20:11:22 +13:00
Curtis Shmyr
b362ddac15 Fixed terrain categories for two river tiles in RA Temperat 2013-01-08 20:11:22 +13:00
Curtis Shmyr
5f2aa810b1 Add terrain category types to RA desert tileset 2013-01-08 20:11:22 +13:00
Curtis Shmyr
189a6c337e Fix Water Cliff terrain types in temperate / desert tilesets 2013-01-08 20:11:22 +13:00
Curtis Shmyr
9c552839ea update CHANGELOG 2013-01-08 20:11:22 +13:00
Curtis Shmyr
79aa7901cf Added RA map: ghost town 2013-01-08 20:11:22 +13:00
Igor Popov
ad2dbffe75 fix #2480; Direct Connect to different mod causes crash (saying 'missing map') 2013-01-07 00:27:45 +04:00
Igor Popov
3b77b04b95 return mapTitle in ra and d2k lobby 2013-01-06 23:25:24 +04:00
Carko
88959b2e6c Changed scroll velocity in the map chooser to be better suited for mouse scrolling 2013-01-03 11:37:59 +13:00
Carko
f256742a0d Fixed repairing landed airplanes (most likely #2365)
When an airplane was landed and ordered to another airstrip or service depot, the aproach distance was not properly calculated since it was not taken into effect that its current altitude is zero.
2013-01-03 11:36:11 +13:00
Chris Forbes
22e2d3d0f4 Merge pull request #2507 from Lookingglass/per-player-shrouds
Per-player shrouds
2012-12-22 12:26:40 -08:00
Chris Forbes
3eed137117 Merge pull request #2526 from Mailaender/strings
made all in-game strings customisable via .yaml files
2012-12-22 12:25:33 -08:00
Chris Forbes
e28be10dd4 Merge pull request #2525 from Mailaender/custom-tech
don't hardcode custom prerequisites anymore
2012-12-22 12:25:03 -08:00
Chris Forbes
90361cb631 Merge pull request #2524 from hunnybunny95/patch-1
Fixed airfield name.
2012-12-22 12:24:42 -08:00
Matthias Mailänder
c3b959846c customisable Ready/Hold text for CnC mod
make those strings also translatable
2012-12-22 19:21:05 +01:00
Matthias Mailänder
39884e16fa customisable text printed on RA support power icons 2012-12-22 18:59:45 +01:00
Matthias Mailänder
f107f8a87b expose strings from build palette widget to chrome yaml
prepare for localisation efforts
2012-12-22 18:25:18 +01:00
Matthias Mailänder
8246b2f35f don't hardcode custom prerequisites anymore
to make those strings translatable
2012-12-22 17:42:57 +01:00
hunnybunny95
f13d12acec Fixed airfield name.
The name of the airfield was airstrip... which is wrong since the icon says airfield whilte the building is called airstrip... its even called AFLD in the code so... just a simple fix :)
2012-12-21 21:57:19 +01:00
Kenny
4090be72d4 Adding Shroud trait to CNC / D2K mods 2012-12-16 20:00:17 -08:00
Chris Forbes
90d30005f6 Merge pull request #2498 from Mailaender/volkov
make Volkov a true Cyborg
2012-12-16 18:16:39 -08:00
Chris Forbes
7c968a8f88 Merge pull request #2509 from Lookingglass/lg-maps
Three new 5-player RA maps
2012-12-16 12:35:04 -08:00
Kenny
e4ab86e6f9 Three new 5-player RA maps:
- The White Pentagon - snow based land/water map with minimal obstructions.
- Black Gold - Resource starved map with each starting position receiving 8 oil derricks.
- Texas Sea - Similar to Black Gold, but every starting position is on a tiny island.
2012-12-13 15:39:14 -08:00
Kenny
f41fb32d60 Introducing per-player shrouds.
- Each player has their own shroud and their visibility does not extend outside of the shroud. 
- Units and buildings can no longer target other units outside of their visibility. Buildings can still be targetted if they have been explored.
- GPS will provide visibility in the fog-of-war.
- Spies that infiltrate radar domes will gain their victim's exploration and reset it on all clients (if the victim does not have GPS)
2012-12-13 15:16:56 -08:00
Matthias Mailänder
5249a17d48 d2k: add Tuck's Sietch remake
by DraLUSAD from
http://www.sleipnirstuff.com/forum/viewtopic.php?f=83&t=16009
2012-12-12 09:46:26 +13:00
Matthias Mailänder
99256bcad0 cnc: fix wrong civilian field remapping at least in-game
the editor hack is RA specific
2012-12-12 09:43:45 +13:00
Matthias Mailänder
f402c37b14 Don't remap civilian buildings/fields in-game.
V16 field was mostly affected because it consists mostly of remapped colors.
2012-12-12 09:43:45 +13:00
Matthias Mailänder
494ab2db4d add @Generalcamo to AUTHORS
original Volkov contribution came from
http://content.open-ra.org/index.php?p=detail&table=units&id=132
2012-12-10 23:12:49 +01:00
Matthias Mailänder
5d4160bc82 make Volkov a true Cyborg
- Added new Armor value: Cybernetic
- Use sounds/graphics from DE censored version
- Heals near repair pad (instead of hospital)
- Medic can't heal him
- Dogs can't eat him
- Tanks need to attempts to crush him
- +25% HP (now same factor as 4tnk:1tnk compared to e1)
2012-12-10 16:42:43 +01:00
Chris Forbes
b9194e4305 d2k: fix crash on attackmove medic 2012-12-04 11:39:37 +13:00
Chris Forbes
8ab1fbe83a Merge pull request #2482 from reaperrr/patch-1
Update mods/cnc/music.yaml
2012-12-03 13:11:11 -08:00
Matthias Mailänder
96a088f998 merge Dune 2000 "Rounded Edges" mod
Changes include:
 - bibs have been removed
 - building offset and selection boxes adapted
 - units and turrets leave husks
 - siege tank barrel won't rotate anymore
 - AI capable of building all units using all queues
 - bullet traces
 - windtrap animations
 - unit balance (mix of Dune II, Dune 2000 and Red Alert)
 - repair pad animation
 - no more obsessive "silos needed"
 - defense building queue → heavy armor queue
 - medics (using thumper graphics)
 - no buildable aircrafts anymore
 - harvesting has been slowed down
2012-12-04 10:08:14 +13:00
Matthias Mailänder
7d4399d7cc fixes #2481
Don't save in system pathes because UNIX needs root and shipped maps
should not be changed. Use $HOME/maps/$MOD instead.
2012-12-04 10:06:42 +13:00
Matthias Mailänder
107c37f33d RA: Snow craters fix by MrFlibble
Small graphical patch fixing some snow craters and scorch marks
2012-12-04 10:05:31 +13:00
Matthias Mailänder
88949024e6 RA: add shadow to supply truck
copied from the demolition truck
2012-12-04 10:04:12 +13:00
Matthias Mailänder
aad0b3d2d8 fixed wrong palette remapping for neutral buildings in editor
for TEMPERAT (fields) and DESERT (buildings, trees, rocks)
2012-11-26 12:21:50 +01:00
Matthias Mailänder
4e0e53c714 Merge pull request #8 from cjshmyr/desert
RA Desert patches by Curtis
2012-11-26 01:04:53 -08:00
Curtis Shmyr
87a2817234 RA Desert - Use ExcludeTileset instead of RequiresTileset for specific tileset actors (looks cleaner) 2012-11-25 18:16:08 -07:00
Curtis Shmyr
f3e796e972 RA Desert - Removed fenc.des which was another barbed wire shp 2012-11-25 17:33:29 -07:00
Curtis Shmyr
7d5a843684 RA Desert - Added a missing shrub. Added building yaml definitions. Hide Temperate and Snow actors from Desert tileset editor. 2012-11-25 17:30:19 -07:00
Matthias Mailänder
f914929eb7 Merge pull request #7 from cjshmyr/desert
Add patches by Curtis:
- fixes desert shorelines
- found missing wc13.des
- remove ice redundancy in sequences.yaml
2012-11-25 09:09:24 -08:00
Curtis Shmyr
8f7b776556 Desert tileset - use proper wc13.des tile 2012-11-21 20:51:33 -07:00
reaperrr
aeaa58a01b Update mods/cnc/music.yaml
'I Am' was the name of the band that made this song (with Mr. Klepacki on drums), the track is actually called Destructible Times. Also brought titles of Warfare/Full Stop as well as Heavy Gear/Demolition in line with other double-named tracks.
2012-11-22 00:21:41 +01:00
Curtis Shmyr
4dacd3be26 Fix up shoreline pieces to have beach terrain types (for water transport use) 2012-11-20 21:21:31 -07:00
Curtis Shmyr
05929bdfe9 Remove extra sequence entries for ice01 ice02 ice03 ice04 ice05 2012-11-20 21:14:52 -07:00
Matthias Mailänder
0690041347 fix most of the palette issues with RA desert in OpenRA.Editor
TODO: use the palette as defined in YAML;
defaults are wrong for DESERT rocks, trees, walls and ore mine
2012-11-19 14:53:25 +01:00
Matthias Mailänder
842fd8b4e5 update VS project file 2012-11-17 13:16:34 +01:00
Matthias Mailänder
7a89e3d67a added DESERT rocks 2012-11-17 13:16:26 +01:00
Matthias Mailänder
5ecc6224b0 add bridges to DESERT 2012-11-17 13:15:16 +01:00
Matthias Mailänder
f5c592291c add Harisson to AUTHORS 2012-11-17 13:15:16 +01:00
Matthias Mailänder
7f229a3fde add ice sequences, fixes related crash 2012-11-17 13:15:16 +01:00
Matthias Mailänder
c859fb1186 fix the remaining issues with the ra desert terrain
- extract mix file as it is easier to work with SHPs
- light palette rotator now excludes terrain palette
- water palette rotator now excludes player palette
- use wire fence, sand bags and brick wall from cnc
- draw ressources with player palette (workaround)
- delete all test maps
2012-11-17 13:15:16 +01:00
Matthias Mailänder
6dceb30632 add 2 testmaps for desert tileset 2012-11-17 13:15:16 +01:00
Matthias Mailänder
f3dc31be40 add PlayerPaletteFromCurrentTileset and desert tileset for RA
some things left to do:
ore, walls and silo/hbox need some work
2012-11-17 13:15:06 +01:00
Matthias Mailänder
a2f5ffd59e made WaterPaletteRotation more configurable
Base is now configurable per terrain
ExcludePalettes is now exposed to yaml
2012-11-17 13:13:32 +01:00
hunnybunny95
a2c66a32b0 Fixed hotkeys for aircraft 2012-11-16 04:47:50 +01:00
hunnybunny95
72139675ac Fixed hotkeys for vehicles 2012-11-16 04:46:00 +01:00
hunnybunny95
2b57f04dc0 Fixed hotkeys for ships 2012-11-16 04:45:15 +01:00
hunnybunny95
15e09fa83b Fixed hotkeys for infantry 2012-11-16 04:44:34 +01:00
Sunny Sproket
55ee1d41f3 Added "room-convergence" map 2012-11-13 09:38:26 +13:00
Matthias Mailänder
2e7908366a fixes #2465
gpsdot.shp shadow uses index 3
2012-11-13 09:26:59 +13:00
Chris Forbes
6ab4fda9a6 Balanced "Bombardment Islands" map (from czech army) 2012-11-13 09:26:59 +13:00
Curtis Shmyr
a5ba41cae8 Make ctnks missiles explode a bit sooner (still reaching their target) 2012-11-10 19:53:10 -07:00
Curtis Shmyr
5e9cdad044 No more sound attentuation for PlayNotification - fixes #2466 2012-11-10 19:52:21 -07:00
Curtis Shmyr
c14de26c07 Actually fixed RA map bomber-john 2012-11-04 10:27:45 -07:00
Curtis Shmyr
e5f506c81d update CHANGELOG 2012-11-03 23:06:27 -06:00
Curtis Shmyr
4160f08c6c Fix bomber-john RA map crash #2439 2012-11-03 22:53:11 -06:00
Curtis Shmyr
4ad0d1682e Improve ctnk health and damage vs heavy armor, reduce damage vs inf 2012-11-04 17:47:03 +13:00
NukemBro
8fb4fc9a14 Re-add RA map Chaos Canyon now with proper cordon - fixes #2432 2012-11-04 17:47:03 +13:00
Curtis Shmyr
5a0187e1db Temporarily drop RA map chaos canyon 2012-11-04 17:47:03 +13:00
Curtis Shmyr
7f5141c338 #2447 - Disguised spies are now hidden under GPS 2012-11-04 17:47:03 +13:00
Iran
354cabf8d1 -- add ice tile entries to sequences.yaml
fixes crashes on maps using these ice tiles.
2012-11-04 17:47:03 +13:00
Scott_NZ
fd734c8553 Improve the Soviet attacks more 2012-11-04 16:20:46 +13:00
Scott_NZ
9238de6a47 Add airbase and airbase secondary objective. Improve Soviet attacks. Enable players to capture sam sites as well as destroy them to complete the objective in Allies 02 2012-11-03 21:41:46 +13:00
Scott_NZ
b2c5f488a7 Rename Evacuees player to Allies. Make AA gun buildable. 2012-11-03 13:33:38 +13:00
Scott_NZ
c634867cdd Reduce threshold, unused variables 2012-11-03 13:33:38 +13:00
Scott_NZ
d7f2273788 Increase duration between spawn for SP 2012-11-03 13:33:38 +13:00
Scott_NZ
5c1a982fdd Remove evacuee buildings to stop the players building on the other side of the map 2012-11-03 13:33:38 +13:00
Scott_NZ
0300a67da8 The Allies 02 Soviet reinforcements at 16 minutes are a bit too insane 2012-11-03 13:33:37 +13:00
Scott_NZ
862dfb3275 Improvements to map layout 2012-11-03 13:33:37 +13:00
Scott_NZ
03121ed826 Add yak strafing, support for SP as well as MP, additional Soviet spawn point 2012-11-03 13:33:37 +13:00
Scott_NZ
0cdff00cb6 First version of Allies 03 2012-11-03 13:33:36 +13:00
Scott_NZ
787facec65 Allies02: Make Allied infantry buildable by the Allies1 player when they capture the Soviet barracks. Remove ctnk from the build menu 2012-11-03 13:33:36 +13:00
Scott_NZ
44d63b9103 Barrels were not scorching the terrain 2012-11-03 13:33:36 +13:00
Scott_NZ
49571fc78a Increase deaths threshold to 200 2012-11-03 13:33:35 +13:00
Scott_NZ
60569bc97c Fix open areas for allies maps 2012-11-03 13:33:35 +13:00
Chris Forbes
b37510c30e nerf dtrk speed from 8 to 6 2012-10-23 19:26:51 +13:00
Kenny
343b7bf3e1 Increasing cost to $2500 as well as reducing armor to 50 hit points. 2012-10-22 14:42:36 +13:00
Curtis Shmyr
7a2423a742 Fix #2449 - ctnk line of sight improved 2012-10-21 16:50:01 -06:00
Curtis Shmyr
57dfc739c6 Fix #2433 - crash when ctnk order generator was active if ctnk dies 2012-10-21 16:46:58 -06:00
Curtis Shmyr
f3d4b6541c Fixed ctnk desync #2448 2012-10-21 15:43:30 -06:00
Curtis Shmyr
d1c20d6c72 Fix #2434 and #2442 2012-10-21 14:55:25 -06:00
Curtis Shmyr
e4beb8236e Update CHANGELOG 2012-10-20 12:28:45 -06:00
Chris Forbes
7574124ff0 added forest-path map for tournament 2012-10-19 11:56:39 +13:00
Scott_NZ
e1cb4d60c4 Fix crash when spectators are present 2012-10-15 16:28:38 +13:00
Igor Popov
1d62329969 fix #2425; Bots should be removed when switching to a map which doesn't allow them 2012-10-15 08:17:04 +13:00
Curtis Shmyr
36813ff52f Fix chronotank's missiles from exploding too soon 2012-10-13 17:31:12 -06:00
Curtis Shmyr
267141749d Chronotank charge pips down from 5->2, pips are blue and jump radius is blue 2012-10-13 16:50:11 -06:00
Curtis Shmyr
edd41c5be1 Chronotank jump cooldown lowered from 60 seconds to 30 2012-10-13 16:50:10 -06:00
Curtis Shmyr
5dc0439173 Fix flak truck description 2012-10-13 16:50:10 -06:00
Curtis Shmyr
4dbee1c0e3 Lower cost of TTNK (1500->1350) and update description to reflect current balance 2012-10-13 16:50:09 -06:00
Curtis Shmyr
76baba89c1 Retune chronotank's weapons to match its description 2012-10-13 16:50:08 -06:00
Curtis Shmyr
5da96941e1 Fix demo truck description 2012-10-13 16:50:07 -06:00
Curtis Shmyr
c2ec8cd372 Fix Volkov's description 2012-10-13 16:50:06 -06:00
Chris Forbes
b73a0a9720 fix off-by-one in new tile query 2012-10-14 10:07:08 +13:00
Chris Forbes
6f3b21616f fix warnings in allies scripts 2012-10-13 14:31:45 +13:00
Chris Forbes
1792f16929 Merge remote-tracking branch 'scott/allies' 2012-10-13 13:52:21 +13:00
Chris Forbes
8dfd02e69e fix HackyAI's husk fetish 2012-10-13 13:45:35 +13:00
Chris Forbes
c8b1c1b999 tidy slightly in idle harv handler 2012-10-13 13:42:34 +13:00
Curtis Shmyr
da9422824a Trans heli now costs 900, increased health, increased cargo count to 8 2012-10-13 13:30:36 +13:00
Chris Forbes
403b51ca4b remove duplication in Mobile 2012-10-13 12:55:51 +13:00
Chris Forbes
3fad0983b9 simplify Mobile using new ordering from FindTilesInCircle 2012-10-13 12:55:51 +13:00
Chris Forbes
bbab5237d1 get rid of crazy wasted work in HackyAI 2012-10-13 12:55:51 +13:00
Chris Forbes
699838332d Order results from FindTilesInCircle by distance 2012-10-13 12:55:51 +13:00
Chris Forbes
6e237b53e1 remove unused trait lookup in ChronoshiftDeploy.ResolveOrder 2012-10-13 11:43:06 +13:00
Curtis Shmyr
36990601db Remove extra newline on Volkov's description 2012-10-13 11:38:00 +13:00
Curtis Shmyr
82f9549f01 Improve mammoth tank tusk turn rate (5->10) 2012-10-13 11:37:55 +13:00
Curtis Shmyr
656503c0c5 Increase range of Tanya's colt45 from 5.75 to 7 2012-10-13 11:37:52 +13:00
Curtis Shmyr
83fc70f415 Added Chrono Tank to Allies 2012-10-13 11:37:46 +13:00
Scott_NZ
bd8ba636c9 Shift v2s to 4 minutes; improve the additional units code 2012-10-12 20:59:35 +13:00
Scott_NZ
6eb2f2bffe Don't hard code 100 into the objectives string 2012-10-12 16:06:43 +13:00
Scott_NZ
d9a6cc6b1c Should be greater than or equal to when comparing with death threshold 2012-10-11 22:57:19 +13:00
Scott_NZ
8c3aabb215 Support for updating objectives without flashing the objectives button. Added a secondary objective: lose fewer than 100 units. 2012-10-11 22:55:02 +13:00
Scott_NZ
d44d9f67f2 Promote the 'MainPresence' objective to primary. 2012-10-11 22:36:40 +13:00
Scott_NZ
8f8800803b Make the Soviet V2s buildable immediately. Fix the Soviet reinforcements not arriving properly. Remove the Soviet reinforcements timer. Rework the bottom left of the map. 2012-10-11 22:35:13 +13:00
Scott_NZ
52007b6277 Move the timer positions 2012-10-09 20:56:11 +13:00
Scott_NZ
795008011e Explosive barrel explosions now cascade with a small delay between each explosion. 2012-10-09 01:51:25 +13:00
Scott_NZ
ec6b8646e9 Improve barrel explosions in Allies 01 by increasing the explosion damage and the health of the power plants/oil derrick. 2012-10-09 00:25:49 +13:00
Scott_NZ
40206f8280 Improved control over the 'final' Soviet wave 2012-10-08 23:34:38 +13:00
Scott_NZ
887a9e7c9c Make medic/spy available to the Allies1 player 2012-10-08 23:34:02 +13:00
Scott_NZ
e4218ede41 Improve the Soviet base, and rebalance the power. 2012-10-08 21:16:30 +13:00
Scott_NZ
f4d0f80cd3 Increase the difficulty of the final wave and shift some of the Soviet power plants around 2012-10-08 20:51:03 +13:00
Scott_NZ
8661fb6b8d Add final attack for Soviets 2012-10-08 19:39:18 +13:00
Scott_NZ
c212095a40 Improve the stability of CountdownTimer 2012-10-08 17:16:42 +13:00
Chris Forbes
f337c7fb40 fix 2422; tesla ignoring weapon offset 2012-10-07 19:23:50 +13:00
Scott_NZ
073a8ee079 Sync up the countdown timer and the objectives button flash with the game speed 2012-10-05 22:03:35 +13:00
Scott_NZ
a4b01cf114 Improved the Allies 02 map layout 2012-10-05 22:02:51 +13:00
Scott_NZ
cba069a039 Improve the effectiveness of the parabombs 2012-10-05 16:23:58 +13:00
Scott_NZ
bf4829205c Have the parabomber come from a different direction. Have the Soviet tanks go straight for the enemy base structures. 2012-10-04 23:59:33 +13:00
Scott_NZ
328dce26ba Add some dogs around the Soviet base to make it harder to use spies 2012-10-04 22:57:34 +13:00
Scott_NZ
0524708e05 Add Yak harrassment 2012-10-02 21:52:45 +13:00
Scott_NZ
7e376330d0 Have the reinforcements money come in as supply trucks instead 2012-10-02 21:52:45 +13:00
Scott_NZ
762db8b304 Have the countdown timer flash in the last 10 seconds, and increase the money amount when reinforcements arrive 2012-10-02 21:52:44 +13:00
Scott_NZ
37479b3cfd Tank wave at 11 minutes, just before the reinforcements arrive 2012-10-02 21:52:44 +13:00
Scott_NZ
07c2330245 Add 2 additional paradrop badgers to the paradrop attack, and a parabomb attack 2012-10-02 21:52:44 +13:00
Scott_NZ
0c6daf191c Add button highlighting/glow effect, to be used for the objective button when the objectives update 2012-10-02 21:52:43 +13:00
Scott_NZ
b897579a20 Send the waves instantly 2012-10-02 21:52:43 +13:00
Scott_NZ
fcc0bcf438 Improve the Soviet attack routines for Allies 01 2012-10-02 21:52:43 +13:00
Scott_NZ
0cd258f24f Dynamically position the timer so that it isn't cut off 2012-10-02 21:52:43 +13:00
Scott_NZ
43e99bf9f5 Add heal animation for the heal crate 2012-10-02 21:52:42 +13:00
Scott_NZ
83d10ba838 Add mission objectives logic/backend 2012-10-02 21:52:42 +13:00
Scott_NZ
48997725c3 Don't let tran reveal shroud 2012-10-02 21:52:42 +13:00
Scott_NZ
631f899f18 Begin work on objectives UI 2012-10-02 21:52:42 +13:00
Scott_NZ
2a4a9d778f Redo some of the fencing near the Soviet base 2012-10-02 21:52:41 +13:00
Scott_NZ
2e2b4d04db Small map/behaviour adjustments 2012-10-02 21:52:41 +13:00
Scott_NZ
deede92fbc Update objective code for Einstein helicopter, avoid race condition with checking if allies2 has been killed 2012-10-02 21:52:41 +13:00
Scott_NZ
e3b2e84792 Focus on the town more; create additional crash site there and and move Einstein there for players to save. 2012-10-02 21:52:41 +13:00
Scott_NZ
e07d55f5f4 Open up the rear of the Soviet base for infiltration by the allies1 player. 2012-10-02 21:52:40 +13:00
Scott_NZ
1803b412c3 Convert Allies 02 over to enum objectives 2012-10-02 21:52:40 +13:00
Scott_NZ
8dd7bfdb67 Move the objective flag stuff to MissionUtils 2012-10-02 21:52:40 +13:00
Scott_NZ
d1400ab4fa Set the enum values explicitly 2012-10-02 21:52:40 +13:00
Scott_NZ
67c40f3119 Use enum-based objectives for Allies 01 2012-10-02 21:52:39 +13:00
Scott_NZ
68d0201538 Add more utils to MissionUtils. Extract Allies 02 countdown timer to its own class file 2012-10-02 21:52:39 +13:00
Scott_NZ
d30d3ed05a Create MissionUtils.cs for shared mission code 2012-10-02 21:52:39 +13:00
Scott_NZ
43f2895eb8 Put reinf ticks back to 12 minutes 2012-10-02 21:52:39 +13:00
Scott_NZ
185e3cffb4 Repackage maps 2012-10-02 21:52:38 +13:00
Scott_NZ
d68196a3b0 Fixed some constant naming 2012-10-02 21:52:38 +13:00
Scott_NZ
4551302c09 Reduce Tanya's and Einstein's weights to 0 so they can still board chinook helicopters if they are full 2012-10-02 21:52:38 +13:00
Scott_NZ
56f36e45db New crate type 'HealUnitsCrateAction' which heals all of the units that the collecting player has. Very rare. New 'ContainsCrate' trait which goes along with this - could be used to hide crates inside churches for example like in the original RA missions. 2012-10-02 21:52:38 +13:00
Scott_NZ
8fabf1504a Add a nearEnough field for RallyPoints (to be used as an argument for their AttackMove activities) so the Soviets don't get stuck on their rally point, and scatter the units a bit before they attack 2012-10-02 21:52:37 +13:00
Scott_NZ
fd96d08ce8 Smoke effect for the chinook husk 2012-10-02 21:52:37 +13:00
Scott_NZ
0e801f9d3a Rework bottom right of Allies 2 map: add more space, more Soviet soldiers, put the captive Engineer outside. Move the southern Soviet outpost up to where the second SAM site is. Move the Soviet rally point up a bit. 2012-10-02 21:52:37 +13:00
Scott_NZ
e5ab56e843 Rework bottom right of the Allies 02 map, move captive Engineer outside. Set Tanya's stance to ReturnFire so attack-move works. 2012-10-02 21:52:37 +13:00
Scott_NZ
ff0ad9cb41 Set fcom tooltip to Forward Command 2012-10-02 21:52:36 +13:00
Chris Forbes
3e81a4bd70 remove PowerBarWidget entirely 2012-09-25 19:51:03 +12:00
Chris Forbes
84f7aa56e1 make ResourceBarWidget generic 2012-09-25 19:44:20 +12:00
Chris Forbes
c42f270ce0 move all databinding for the silobar into ui logic 2012-09-25 19:39:33 +12:00
Chris Forbes
af31ae4931 tidy up SiloBarWidget to be almost completely independent of ore 2012-09-25 19:27:33 +12:00
Chris Forbes
8b6308d3a2 reduce differences between PowerBarWidget and SiloBarWidget 2012-09-25 18:56:24 +12:00
Chris Forbes
6ecc4c18dc fixed 2036 -- add targetlines for defenses 2012-09-25 18:42:36 +12:00
Chris Forbes
56557b8766 convert dtrk to use MiniNuke 2012-09-24 21:07:16 +12:00
Chris Forbes
83ba80f4c9 add MiniNuke weapon for dtrk 2012-09-24 21:06:49 +12:00
Chris Forbes
65227c3c09 remove nuke crate 2012-09-24 21:03:33 +12:00
Chris Forbes
1b5474f377 retune nuke 2012-09-24 21:02:22 +12:00
Chris Forbes
38b5e2f7ca set up demo truck to explode on chronoshift 2012-09-24 20:36:03 +12:00
Chris Forbes
0ff3c56d4f add Chronoshiftable:ExplodeInstead option 2012-09-24 20:34:54 +12:00
Chris Forbes
4888732fb7 fix reversed ordernames in DemoTruck 2012-09-24 20:24:35 +12:00
Chris Forbes
3079e2b488 fixed Explodes dep on demotruck 2012-09-24 20:22:36 +12:00
Curtis Shmyr
34d96878b8 Added demo truck to soviet's arensal; still problems to fix 2012-09-24 20:08:56 +12:00
Chris Forbes
61e548151b clear queue-per-building production queue on mcv repack 2012-09-23 18:00:06 +12:00
Chris Forbes
7cc7dcc559 add INotifyTransform hook for just before something transforms 2012-09-23 17:58:53 +12:00
Chris Forbes
757c9ca63c Fixed 2387 - dont shade possible build items in cnc just because something else is building 2012-09-23 17:45:13 +12:00
Chris Forbes
5cb86f8937 repair cost for units is always at least 1 per tick 2012-09-23 17:38:23 +12:00
Chris Forbes
cd1a29f1ea repair cost is always at least 1 per tick 2012-09-23 17:37:35 +12:00
Igor Popov
79b4765d9f fix: port in Direct Connect was dumped to default by force 2012-09-23 17:27:19 +12:00
Igor Popov
05e9dcd5ce dedicated: load another initial map if current key is not present in dictionary 2012-09-23 17:20:47 +12:00
Igor Popov
4c915ce8fe dedicated: configurable MOTD 2012-09-23 17:20:47 +12:00
Igor Popov
5d5fe3f5a1 dedicated: proper reason why DEV_VERSION is kicked. 2012-09-23 17:20:46 +12:00
Igor Popov
5bacf69445 dedicated: cleaner 2012-09-23 17:20:46 +12:00
Igor Popov
0a858ac353 cleaner 2012-09-23 17:20:46 +12:00
Igor Popov
b7258e61f3 remove bogus comment 2012-09-23 17:20:46 +12:00
Igor Popov
bd45ffa022 dedicated: start a new server instance once previous game is finished (configurable) 2012-09-23 17:20:46 +12:00
Igor Popov
b45f9568d0 dedicated: force tell master server if amount of clients is 0 2012-09-23 17:20:46 +12:00
Igor Popov
f8290b8a7e dedicated: handle admin 2012-09-23 17:20:46 +12:00
Igor Popov
21b002ce22 dedicated: drop DEV_VERSION 2012-09-23 17:20:45 +12:00
Igor Popov
1fbd8f6cc6 dedicated: null SoundEngine 2012-09-23 17:20:45 +12:00
Igor Popov
2798f0d841 dedicated: handle non-existing map 2012-09-23 17:20:45 +12:00
Igor Popov
bf73cdbd01 basic dedicated server support 2012-09-23 17:20:45 +12:00
Chris Forbes
03229eca0c remove sounds from sniper cloak/uncloak; enable uncloak-on-move for sniper. 2012-09-23 17:17:07 +12:00
Chris Forbes
489fdc1893 add CloakInfo.UncloakOnMove option 2012-09-23 17:15:16 +12:00
Chris Forbes
e2b2082660 fix armor types on war factory and airfield 2012-09-20 10:14:44 +12:00
Chris Forbes
5ab2e2b225 adjust building prices 2012-09-20 10:13:14 +12:00
Chris Forbes
caa58e46c3 buff 4tank self-heal; nerf turret rotation 2012-09-19 17:35:06 +12:00
Chris Forbes
e9f4338852 remove vestigial mods/*/packages handling from installer 2012-09-16 14:13:24 +12:00
Scott_NZ
f146cedad5 Improve the thresholds a bit 2012-09-16 12:27:33 +12:00
Scott_NZ
cc449f81f8 Describe the map size in words 2012-09-16 12:27:33 +12:00
Chris Forbes
085e29d22b dead things are no longer valid targets 2012-09-16 11:24:36 +12:00
Chris Forbes
f8427fa242 refuse to start the game unless required slots are full. 2012-09-16 11:05:00 +12:00
Chris Forbes
eb9b6a3842 propagate Required flag to Slot 2012-09-16 10:58:48 +12:00
Chris Forbes
43fc1219f0 add Required field to PlayerReference 2012-09-16 10:51:49 +12:00
Igor Popov
1469620831 new interior map by sunny_s: room-warzone 2012-09-16 10:43:40 +12:00
Chris Forbes
036997a7a0 update authors file 2012-09-16 10:17:51 +12:00
Kyrre Soerensen
b4d9c40dc8 maps: Replace Baywatch with Hasselhoff (better ore distribution)
Signed-off-by: Kyrre Soerensen <kyrre@ksorensen.net>
2012-09-16 10:14:32 +12:00
Chris Forbes
62257459fd fix NRE in ReturnToBase bailout if no suitable building is found 2012-09-14 23:20:39 +12:00
Chris Forbes
ea641f081f use ChooseAirfield in ReturnToBase.Tick bailout 2012-09-14 23:20:18 +12:00
Chris Forbes
a641c7a87d add parameter to ReturnToBase.ChooseAirfield for whether the building must be unreserved 2012-09-14 23:14:02 +12:00
Chris Forbes
605a1eacf6 fix Gl renderer; texture binding was totally busted 2012-09-13 08:14:21 +12:00
Chris Forbes
da3adf4f8e fix bogus extra death sounds in ra VolkovVoice 2012-09-13 07:35:25 +12:00
Chris Forbes
8680405b68 show no-deploy cursor if locked 2012-09-13 07:27:15 +12:00
Chris Forbes
5ad2d1892f take lock in DeployTransform if we're a building 2012-09-13 07:25:39 +12:00
Chris Forbes
b723e350c8 remove spurious interlock in Sell 2012-09-13 07:16:04 +12:00
Chris Forbes
0b665bc35b move counter-capture logic down into Capturable; remove spurious interlock on CaptureInProgress 2012-09-13 07:14:56 +12:00
Chris Forbes
c012ea90dd get rid of capturing lock in Sellable 2012-09-13 07:10:28 +12:00
Chris Forbes
b0b0fac847 get rid of Sellable.Selling state 2012-09-13 07:09:44 +12:00
Chris Forbes
c253e59c57 take lock while capture in progress 2012-09-13 07:08:02 +12:00
Chris Forbes
952e277d35 take lock in Sellable.ResolveOrder 2012-09-13 07:05:58 +12:00
Chris Forbes
f984934270 add Building.Locked, and Lock()/Unlock() conveniences 2012-09-13 07:05:58 +12:00
Chris Forbes
fb58840cea ignore spectators for readiness check 2012-09-04 11:24:59 +12:00
Chris Forbes
3d8dc80f03 complain about junk values like the recent volkov breakage 2012-09-04 10:55:26 +12:00
Chris Forbes
d970195394 fix bogus armor definition for Volkov 2012-09-03 09:26:27 +12:00
Scott_NZ
c33c9e9f69 Fixes #2386 (Add map size to map list) 2012-08-28 16:18:15 +12:00
Chris Forbes
6d3a932453 Revert "Removed the "tip" jutting out of 3 buildings, so they are rectangular instead of awkwardly shaped."
This reverts commit 22bddf9645.
2012-08-25 15:32:29 +12:00
Scott_NZ
622650785c Set Allied units to defensive stance in Allies 01 2012-08-25 15:20:59 +12:00
Scott_NZ
362dc8128e Don't crash and burn if vqa files aren't found 2012-08-25 15:20:58 +12:00
Scott_NZ
f8e73afbee Improve the music-playing code - crash prevention and some polish 2012-08-25 15:20:58 +12:00
Scott_NZ
dbbe026b88 Actually fix the desync issues 2012-08-25 15:20:58 +12:00
Scott_NZ
4b36a9bf7f Fix desync issues 2012-08-25 15:20:58 +12:00
Matthias Mailänder
70a5333b40 fixes #2363
typo leading to a crash when clicking a disabled tab
2012-08-22 12:40:38 +12:00
Igor Popov
e8359b08c6 change IsAdmin indicator to d2k like 2012-08-22 12:38:10 +12:00
Scott_NZ
cebc0b66a5 Make the Viewport code easier to follow 2012-08-20 20:45:56 +12:00
Scott_NZ
6ac86cbc1a Fix UnitsNearActor basing itself off the Soviet WP, instead of the actual actor. Move the power code to the unit building method so the Soviets don't build units completely, even if they have enough money. 2012-08-20 20:45:54 +12:00
Curtis Shmyr
60ceb800e1 Remove contrails from pbox vulcan - was not working as intended 2012-08-20 15:06:36 +12:00
Igor Popov
5f47b7b7fc add 3v3 d2k map by Combine; add 2 ra maps by Holloweye (conquest + minigame) 2012-08-20 13:54:11 +12:00
Scott_NZ
7e2866714c Overhaul Soviet base 2012-08-20 03:32:09 +12:00
Scott_NZ
7e8313b808 Add music to Allies 02 2012-08-19 17:19:45 +12:00
Scott_NZ
bfd28abb70 FMV videos for Allies 01, also adjust music to play a random track 2012-08-19 17:00:03 +12:00
Scott_NZ
1afc0cbfce Remove fast unit production for Soviets, this is too overwhelming 2012-08-19 13:05:05 +12:00
Scott_NZ
82bcd19d2e Fix crash when Media.PlayFMVFullscreen is called 2012-08-19 12:56:12 +12:00
Scott_NZ
49049a715b Give allies base more reinforcements after 12 mins 2012-08-19 12:55:38 +12:00
Scott_NZ
3114a5b85e Add Soviet apc/flamer rush after 7 minutes 2012-08-18 17:26:18 +12:00
Scott_NZ
222f17a586 Minor refactor 2012-08-18 01:45:05 +12:00
Scott_NZ
91027e9961 Use FirstOrDefault when getting closest building 2012-08-18 00:01:35 +12:00
Scott_NZ
a06a7a8ccb Replace arty with fix/2tnk 2012-08-18 00:00:44 +12:00
Scott_NZ
a8bae22dd3 Give arty back so the allies stand a chance 2012-08-17 23:27:19 +12:00
Scott_NZ
daa89f52b6 Add lethal Soviet attacks and increase heavy tank production 2012-08-17 23:13:35 +12:00
Scott_NZ
22c1059904 Rework water area near the town 2012-08-17 20:28:05 +12:00
Scott_NZ
c0138966e7 Rework Allied base a bit 2012-08-17 20:02:39 +12:00
Scott_NZ
0f14263b82 Make walls not contribute to allied building check 2012-08-17 17:48:47 +12:00
Scott_NZ
dfc6304efa Increase the difficulty 2012-08-17 17:31:18 +12:00
Igor Popov
99a8aa6868 spelling fix 2012-08-17 00:35:51 +04:00
Igor Popov
983fc1a7b6 fix cnc menu/multiplayer titles overrides by server's title; 2012-08-16 21:22:10 +04:00
Scott_NZ
632d717af8 Fix HeliLand constructor 2012-08-16 22:04:10 +12:00
Scott_NZ
a74a3aa3b5 Disable bots 2012-08-16 21:47:22 +12:00
Scott_NZ
c90c351692 Spaces in csproj 2012-08-16 21:47:21 +12:00
Scott_NZ
5612a57842 and some more 2012-08-16 21:47:20 +12:00
Scott_NZ
6e3c8c9745 Fix some old VS-induced nastiess 2012-08-16 21:47:19 +12:00
Scott_NZ
0920c67017 Require ra mod, pack allies 02 2012-08-16 21:47:18 +12:00
Scott_NZ
1ed0d80348 Fix static readonly field capitalisation conventions 2012-08-16 21:47:17 +12:00
Scott_NZ
c41fcb15b0 Fail Allies01/Allies02 if the extraction helicopter is destroyed 2012-08-16 21:47:16 +12:00
Scott_NZ
6c79b454bf Improve Allies base 2012-08-16 21:47:16 +12:00
Scott_NZ
610e40b8d6 Give Allies2 player some cash when they receive reinforcements 2012-08-16 21:47:15 +12:00
Scott_NZ
5038018aa5 Give the Soviets money as they need it. 2012-08-16 21:47:14 +12:00
Scott_NZ
cce12e781f Kill the allied players if they fail the mission. Also fail the mission if the Allies2 player loses all of their buildings. 2012-08-16 21:47:13 +12:00
Scott_NZ
245de3abcb Making HBOX unbuildable was crashing the game 2012-08-16 21:47:12 +12:00
Scott_NZ
11f9fa1942 Some code polish 2012-08-16 21:47:11 +12:00
Scott_NZ
85fa7eb8c4 Modify tech tree, disable bots 2012-08-16 21:47:10 +12:00
Scott_NZ
62d7168d41 Make the mission not unwinnable if Einstein can't cross the bridge because it is destroyed 2012-08-16 21:47:09 +12:00
Scott_NZ
2a053daa2e Add Soviet attacks, scrap chinook timer since we might have pathing issues if Tanya is on the island and we have off-map attacks. Counter this by bringing back reinforcements timer 2012-08-16 21:47:09 +12:00
Scott_NZ
21a903fe2d Remove an ai activation check, we want it to always activate even if the host is a spectator 2012-08-16 21:47:08 +12:00
Scott_NZ
83fc546fbe Reposition Soviet barracks/kennel 2012-08-16 21:47:07 +12:00
Scott_NZ
f648223c39 Improve the deploy routine so that baseCenter is still set even if the mcv is a fact 2012-08-16 21:47:06 +12:00
Scott_NZ
583c3f9a64 Produce dogs, adjust allied building positions 2012-08-16 21:47:05 +12:00
Scott_NZ
0d9c78670e Basic Soviet AI. This is flawed right now as it will just charge all of its starting units towards Tanya 2012-08-16 21:47:04 +12:00
Scott_NZ
32a37d8c0f Stop the hacky AI unpacking the fact into a mcv if it starts with a fact instead of a mcv 2012-08-16 21:47:03 +12:00
Scott_NZ
168ff6dc82 Remove "timer started" conflict 2012-08-16 21:47:03 +12:00
Scott_NZ
03f904155e Reinforcements voice with chopper extraction 2012-08-16 21:47:02 +12:00
Scott_NZ
f479f9a32d Have reinforcements come immediately.. 2012-08-16 21:47:01 +12:00
Scott_NZ
bdbb9d2a9f Add oil facility outside allies2 2012-08-16 21:47:00 +12:00
Scott_NZ
e3ae0ceae3 Add some more map detail 2012-08-16 21:46:59 +12:00
Scott_NZ
34ea82e267 Improved Soviet base layout further 2012-08-16 21:46:58 +12:00
Scott_NZ
fe7e016e33 Improved layout of Soviet base 2012-08-16 21:46:57 +12:00
Scott_NZ
f901355bef Make tran unselectable 2012-08-16 21:46:56 +12:00
Scott_NZ
60fb45c909 Move the sam site around to make a new outpost on the top left, add engineer rescue 2012-08-16 21:46:56 +12:00
Scott_NZ
9ccfb2c322 Make the mission actually winnable 2012-08-16 21:46:55 +12:00
Scott_NZ
0c9f39df78 Clean up allies01/allies02 code by storing world object 2012-08-16 21:46:54 +12:00
Scott_NZ
7fffb71ac4 Clean up timer code, add chinook extraction of Einstein 2012-08-16 21:46:53 +12:00
Scott_NZ
bf0cee9057 Redo outpost: move it into the town and put a miss in the old position. The player can rescue engineers from miss to capture the outpost. 2012-08-16 21:46:52 +12:00
Scott_NZ
55b17f70a8 Adjust to 6 mins 2012-08-16 21:46:51 +12:00
Scott_NZ
c9318cd2dd Chinook timer 2012-08-16 21:46:50 +12:00
Scott_NZ
ffd2588f50 Improved the soviet base 2012-08-16 21:46:49 +12:00
Scott_NZ
c3b9b37122 Bit of cleanup, add position parameter 2012-08-16 21:46:48 +12:00
Scott_NZ
a30d82b333 Convert timer actions to be properties 2012-08-16 21:46:47 +12:00
Scott_NZ
81e2c1d2d7 Implement basic reinforcements for allies2 2012-08-16 21:46:46 +12:00
Scott_NZ
5f2ffc0508 Clean up the timer widget code 2012-08-16 21:46:45 +12:00
Scott_NZ
00297b607b Add drawing widget for reinforcements 2012-08-16 21:46:45 +12:00
Scott_NZ
1c702048a1 Make allies 01 less loud 2012-08-16 21:46:44 +12:00
Scott_NZ
fdd356c2e7 Improve allied base, stop tanya autotargeting 2012-08-16 21:46:43 +12:00
Scott_NZ
1e64a63fa4 Have the starting camera viewport position be determined by the local player 2012-08-16 21:46:42 +12:00
Scott_NZ
05f079758a Begin building basic Allies 02 framework 2012-08-16 21:46:41 +12:00
Scott_NZ
b220bbeda2 Wire up SAM 4 2012-08-16 21:46:40 +12:00
Scott_NZ
0a358a8846 Soviet base: construction yard, sam site, silos 2012-08-16 21:46:39 +12:00
Scott_NZ
ed43c1b482 Modified the bridge to stop crossing with sea units, and opened up the mountain for an alternative route to the Soviet outpost 2012-08-16 21:46:39 +12:00
Scott_NZ
c505954b07 bleh, tabify 2012-08-16 21:46:38 +12:00
Scott_NZ
d5279d123f Start work on Allies 02 script, reveal sam site locations 2012-08-16 21:46:37 +12:00
Scott_NZ
9be501fc3d Improve the objective text in Allies 01 - Einstein/Tanya can't be killed 2012-08-16 21:46:36 +12:00
Scott_NZ
1721d7e025 Add Kennel to allies 02 2012-08-16 21:46:35 +12:00
Scott_NZ
881484d06a Some allies 02 map work - add sub pen and rework the Soviet base a bit 2012-08-16 21:46:34 +12:00
Scott_NZ
537cfb8fd3 Add Kennel to Allies 01 2012-08-16 21:46:33 +12:00
Scott_NZ
41f1ea36fe Add Kennel structure 2012-08-16 21:46:32 +12:00
Scott_NZ
486d340028 Bridges 2012-08-16 21:46:32 +12:00
Scott_NZ
e2bbd22144 Add allies-02 map yaml/bin 2012-08-16 21:46:31 +12:00
Scott_NZ
43d0363a55 Formatting improvements from Husk/Allies01 2012-08-16 21:46:30 +12:00
NukemBro
b253de508b Added new RA map: Chaos Canyon 2012-08-16 09:34:24 +12:00
Chris Forbes
1da82aeba9 slow sniper rof to 70 2012-08-16 09:30:03 +12:00
Chris Forbes
db4d6aaf22 sniper requires dome 2012-08-15 21:55:18 +12:00
Matthias Mailänder
5ea86873c6 fixes #2360, fixes #2227
use notifications.yaml for biolab production queue (crash fix)
remove bio prerequisite for visceroid (won't work after capture)
2012-08-15 08:52:03 +12:00
Chris Forbes
0f126fd630 tidy in defaults.yaml 2012-08-15 08:51:15 +12:00
Chris Forbes
ecc2a7241f fix case on WastedAfterwards 2012-08-15 08:51:14 +12:00
Matthias Mailänder
fbf68db0c0 change some d2k weapon sounds 2012-08-15 08:51:12 +12:00
Matthias Mailänder
9ce8c90d25 added Harissons high-quality temperate terrain expansion
new brigdes, fjords, debris, cliffs
2012-08-15 08:51:01 +12:00
Matthias Mailänder
affa9ca336 revert CaptureActor.Range, PascalCase conventions, compatibilty
the hardcoded Range=3 was crap for smaller/bigger buildings
try not to break TransformOnCapture as it is used for cnc husks
2012-08-15 08:49:49 +12:00
Chris Forbes
3a1c4d1e6f sniper is soviet-only; use initial stance correctly 2012-08-15 08:49:20 +12:00
Matthias Mailänder
45fbecbcd0 sniper can go into pillbox and garrision church 2012-08-15 08:49:16 +12:00
Matthias Mailänder
02f28f54c7 add sniper to ra 2012-08-15 08:49:12 +12:00
Matthias Mailänder
81f035904e remove TODO list, use bug-tracker 2012-08-15 08:48:48 +12:00
Matthias Mailänder
8e2d712688 fix cnc snow theatre crash 2012-08-14 11:01:36 +12:00
Matthias Mailänder
29b63bc3c0 add hospital and biolab sequences 2012-08-14 11:01:34 +12:00
Matthias Mailänder
d98cdd5331 new d2k map: Venac ditch by Combine
http://content.open-ra.org/?p=detail&table=maps&id=635
2012-08-14 11:01:18 +12:00
Matthias Mailänder
94905afa3c better cropped volkov icon, thanks to BaronOfStuff 2012-08-14 10:45:09 +12:00
Matthias Mailänder
a659892227 added emperor palace icon, thanks to D2k Sardaukar and Grand Leo 2012-08-14 10:44:51 +12:00
Chris Forbes
82eddfdf98 #2354 fixed - multiple collection of crates 2012-08-09 10:25:45 +12:00
Chris Forbes
063191b09e fix #2353 - missing dep between d2k and cnc mods broke parallel make 2012-08-08 07:36:49 +12:00
Curtis Shmyr
3fc6f62aea Conflicts:
OpenRA.Mods.RA/SupportPowers/IronCurtainPower.cs
2012-07-31 09:20:22 +12:00
Scott_NZ
48f934f188 Set up tran husks, and stop husk placement causing crashes 2012-07-31 09:12:22 +12:00
psydev
192af5d60f Tank shells do 100% vs. armor again. Buff turret. MRLS fixed.
Conflicts:

	mods/cnc/weapons.yaml
2012-07-31 09:10:32 +12:00
psydev
53a7b0987b Fixed structure build menus
Made the building menu more logical. Rows according to tech tree. 

power / refinery / silos       0/10/15
barracks / outpost / starport    20/30/40
light factory / heavy factory / repair bay   50/60/70
high-tech factory / ix tech center / palace    80/90/100

If you want to move silos to the Defense queue, then I would re-arrange it slightly.
2012-07-31 08:24:54 +12:00
psydev
a3897dbc15 Sonic tank moved to end of build menu (100)
Sonic tank moved to bottom of vehicle build menu (set palette order to 100)
2012-07-31 08:23:08 +12:00
Chris Forbes
55651738a7 add heli crash shps 2012-07-30 09:22:36 +12:00
psydev
22bddf9645 Removed the "tip" jutting out of 3 buildings, so they are rectangular instead of awkwardly shaped.
- heavy factory
- high tech factory
- ix research center
2012-07-25 08:58:18 +12:00
psydev
2a37e6233e Added "AutoTargetIgnore:" to ^Building: 2012-07-25 08:57:50 +12:00
Matthias Mailänder
c1722e1270 remove broken sandworm and thumper, fixes #2332 2012-07-25 08:57:05 +12:00
Matthias Mailänder
95c27ef943 deviatortank should require tech building 2012-07-25 08:57:01 +12:00
Matthias Mailänder
3aafde7e18 slower infantry feet animation 2012-07-25 08:56:54 +12:00
Matthias Mailänder
85678de9f0 made silos more flexible for d2k mod 2012-07-24 08:29:18 +12:00
Matthias Mailänder
bda4bfa4f3 d2k: tooltip for $ icon is now starport instead of ship 2012-07-23 09:34:16 +12:00
Matthias Mailänder
481624e3f0 fixed d2k crash: Unit pips does not have a sequence pip-red 2012-07-23 09:34:06 +12:00
ew07002
d1f12ff801 Add some usability features to the TilesetBuilder
- title bar shows tile position (x, y and tile nr (from left top))
 - make 'overlays' button a toggle button and properly sync state with
   tileset surface
 - add export option for 'Template CellID <-> tile number' mapping
 - overlay pen color is now white (todo: make configurable)
2012-07-23 09:33:57 +12:00
Matthias Mailänder
eae482d413 tweak d2k aircrafts a little 2012-07-23 09:33:53 +12:00
Matthias Mailänder
abd774d017 d2k: faster aircrafts, slower trikes, concrete buildings
avoid capturing light buildings by deviator weapon
2012-07-23 09:33:51 +12:00
Matthias Mailänder
f2c630731e added some files from content.open-ra.org, fixes #2182
adds Volkov with some minor changes (no C4, range fixes)
adds soviet forward command center build animation
adds icon for mines (not visible in-game yet)
2012-07-23 09:33:46 +12:00
Matthias Mailänder
3e3977776d fixes #2322 (stuck units when leaving repair pad)
by adding bibs and defining a sane default rallypoint exit cell
2012-07-21 00:01:26 +02:00
Matthias Mailänder
36fbddbb5c fix d2k production queues
ClassicProductionQueue gets support for new notification system
d2k now uses the ClassicProductionQueue system to avoid spamming
Starport has cheaper threshold prices
adds a new production queue but has long delivery times
also no starport price fluctuation to improve balancing
2012-07-20 23:05:28 +02:00
Matthias Mailänder
e33d988301 d2k UI reskinning complete, thanks to @JOoGraphics 2012-07-20 20:00:09 +02:00
Matthias Mailänder
a55167c9ac another d2k loadscreen made by @katzsmile 2012-07-19 23:16:05 +02:00
Matthias Mailänder
d0a4555a1f new admin icon that does fit and some more icons for the future 2012-07-19 21:37:24 +02:00
Matthias Mailänder
4724ac6b00 experimenting with concrete plates
pretty useless at the moment, removed by default
2012-07-19 20:08:59 +02:00
Matthias Mailänder
d998367d35 d2k UI improvements by @JOoGraphics 2012-07-19 17:56:41 +02:00
Matthias Mailänder
0e9e7d0a9d added http://dunefont.co.nr/ to artsrc
maybe used for logos, splashscreens or menus later
2012-07-18 22:08:46 +02:00
Matthias Mailänder
5e1e5903d6 reworked d2k dialog UI, thanks to @JOoGraphics 2012-07-18 19:11:06 +02:00
Matthias Mailänder
25fae5d109 fixed d2k harvester dock animation 2012-07-17 22:03:30 +02:00
Matthias Mailänder
44b8630c71 support reversed remapping for d2k 2012-07-17 17:01:37 +02:00
Matthias Mailänder
6204bfcabf added hospital/bio lab to RA 2012-07-17 14:18:10 +02:00
Matthias Mailänder
1355a9f837 added extra d2k buildings for creeps/neutral
new SHPs, needs update for d2k-packages.zip
2012-07-17 14:02:22 +02:00
Matthias Mailänder
db8f22cdbf d2k harvester unload a little less ugly, RALint fixes
frames were swapped, offset and turnaround still wrong
remember: this changes unload.shp (copy to dl-mirrors)
2012-07-16 22:23:56 +02:00
Matthias Mailänder
860ec9d85f added passenger seat to trike/raider 2012-07-16 21:11:27 +02:00
Matthias Mailänder
5f2f25b758 added d2k superweapons, fixed c4/nuke cursor 2012-07-16 21:02:55 +02:00
Matthias Mailänder
3728685c67 fixed UPnP more crashes
proper timeout: does not crash/lag if no UPnP devices are found
close all ports, sockets, responses after they have been used
so it does not crash when port forwarding for the 2nd time
put all exceptions logs into OpenRA sourcecode
2012-07-15 22:31:02 +02:00
Matthias Mailänder
5e6b8deec1 remove ugly test map again 2012-07-15 18:39:48 +02:00
Matthias Mailänder
21f2b0df43 fixed a crash when siege tanks are built 2012-07-15 18:39:17 +02:00
Chris Forbes
2100484598 fix name of the-duell map for d2k; space breaks rpm build 2012-07-15 12:40:58 +12:00
James Dunne
ba1a36f26e Units heading in generally opposite directions are now considered blockers; this fixes pathing deadlocks. 2012-07-05 23:53:31 -05:00
James Dunne
9c9a16d80e Path planning no longer considers moving friendly units as blockers. 2012-07-05 23:52:34 -05:00
Chris Forbes
3d8e215598 Merge pull request #2296 from ScottNZ/bleed
Allies 01 fixes
2012-07-05 20:06:44 -07:00
James Dunne
ce806fdbe6 Prevent too many instances of a single sound starting at once in an absolute location and attenuate volume of new sounds based on number active sounds already playing. 2012-07-06 14:41:24 +12:00
Matthias Mailänder
208a3a47fe don't crash when sound rules are not loaded
e.g. when trying to get the gamefiles
2012-07-06 14:37:24 +12:00
Matthias Mailänder
f0708ecfb2 cut out the black tile 2012-07-06 14:37:17 +12:00
Matthias Mailänder
653d72086c A10 crash site to terrain
it is not transparent and will look wrong in desert/winter
2012-07-06 14:37:14 +12:00
Matthias Mailänder
9258ba3ec7 new spice shp with 20 densities
hopefully nicer looking spices tiles
and less insane growth rate
avoided edge tiles because of #2247
2012-07-06 14:36:56 +12:00
Matthias Mailänder
d851c5646e a10cr dimensions fixed 2012-07-06 14:36:52 +12:00
Matthias Mailänder
ac0d3779f1 added @Nyerguds awesome cnc A10 crash site
ripped from a Westwood beta screenshot
2012-07-06 14:36:49 +12:00
Matthias Mailänder
9a0d62dc85 removed pyle again (no changes) 2012-07-06 14:36:44 +12:00
James Dunne
59e1703b41 Added mouse-wheel support for flipping tabs in build palette. 2012-07-06 14:32:26 +12:00
James Dunne
e49a439c79 You win chrisf =P 2012-07-03 19:05:46 -05:00
James Dunne
b2e9085371 More detailed exception reporting on crash. 2012-07-03 15:37:37 -05:00
Matthias Mailänder
8cea309ec6 more SHP fixes by Nyerguds
- The SSM Launcher (mlrs.shp) was updated because the very last
  turret frame without missiles had messed up house colours
- buildings that showed remap color instead of real yellow:
* Civilian Oil Derrick (Made correct remap for v19.shp)
* Advanced Communications Center (shadow under the big dish
  turned to remap, in both eye.shp and eyemake.shp)
* Tiberium Silo (random remap pixels in the collapse frame
  of silo.shp, and the entire lower right edge on silomake.shp)
* Barracks (remap pixels showing up in the
  normally gray buildup on pylemake.shp)
2012-07-03 09:21:54 +12:00
Matthias Mailänder
a59dfa555c map clear radar color for interior to black 2012-07-03 09:21:54 +12:00
Matthias Mailänder
e22126ca02 added ice floes to ra 2012-07-03 09:21:54 +12:00
Matthias Mailänder
867f112dfe base cnc snow on temperat to remove snowy greenland tiles 2012-07-03 09:21:54 +12:00
Matthias Mailänder
24e6e23000 fixed building dimensions as d2k now has bibs 2012-07-03 09:21:54 +12:00
Matthias Mailänder
498adc86a9 add bibs for d2k
copy & paste with gimp and OpenRA.Utility
2012-07-03 09:21:54 +12:00
Matthias Mailänder
a20d1c95c8 noticable SHP fixes from C&C 1.06c rev3
including a snow theatre now fixed with few backfalls to winter
hand of nod with logo (like in the beta)
fence fixes (one frame did not fit to the rest)
factory retains the shadow of the make animation
nicer ion cannon icon from a westwood render
2012-07-03 09:21:54 +12:00
ScottNZ
4a101cf1b1 Convert line endings 2012-07-02 16:19:57 +12:00
ScottNZ
583b11a2b2 Remove bad/duplicate UnloadCargo line 2012-07-02 14:03:26 +12:00
ScottNZ
b3c5137add Merge 2012-07-02 13:46:28 +12:00
Chris Forbes
3dc39b2c9d fixed #2167 -- silly inconsistency between InfDeath and dieN sequence numbering 2012-07-02 09:42:20 +12:00
ScottNZ
5897a44fc5 Remove unneeded barrel YAML overrides 2012-07-02 04:22:23 +12:00
ScottNZ
8b0f15f80b Bring Soviet patrol back a bit 2012-07-02 04:21:10 +12:00
ScottNZ
1262cf0f29 Bit of cleanup 2012-07-02 03:54:55 +12:00
ScottNZ
b74e63f42d Drain Soviet resources so the ore truck doesn't stay at the refinery 2012-07-01 20:30:25 +12:00
Matthias Mailänder
e89ee2c131 new AttackLoyalty, range and stay alive option for Capture
AttackLoyalty for d2k Deviator which captures units
also shooting a fake missile (see issue #2251)

CaptureActor now supports Generals styles gameplay
but is disabled by default (see issue #2274)
fixes the annoyance that engineers will not take
the shortest root to the building by the way

removing ProvidesCustomPrerequisite because it's
tooltip messages relies on hardcoded hacks
2012-07-01 20:26:25 +12:00
Chris Forbes
c2321e3eea fixed #2284 - crash in upnp when device found but it doesnt want to talk upnp 2012-07-01 20:14:14 +12:00
Matthias Mailänder
22a49ba7c6 added HarvesterAttackNotifier.cs to .csproj
Conflicts:
	mods/d2k/rules/system.yaml
2012-07-01 20:00:57 +12:00
Chris Forbes
4d614e9122 include d2k mod in official packages 2012-07-01 20:00:12 +12:00
Chris Forbes
e0069fd62a make UnloadCargo.unloadAll configurable; go back to all by default 2012-07-01 19:45:31 +12:00
Matthias Mailänder
c75c72b525 made palette shadowindex configurable 2012-07-01 19:37:57 +12:00
Chris Forbes
007b2c5434 make click-without-drag feel better in editor 2012-07-01 18:37:46 +12:00
Chris Forbes
b8a932a084 try to make selection feel better 2012-07-01 18:31:46 +12:00
Curtis Shmyr
61c3932340 Selection tool / copy paste for editor 2012-07-01 18:23:46 +12:00
Chris Forbes
c2029e9d5c fixed #2166 - filtering of passengers to show with RenderCargo 2012-07-01 18:22:19 +12:00
Chris Forbes
d0548d6766 Drop EvaAlerts from OpenRA.Game.csproj 2012-07-01 18:10:17 +12:00
Chris Forbes
5a40c5df03 tidy health transfer 2012-07-01 18:08:10 +12:00
Matthias Mailänder
f5ba36a735 Unload only 1 cargo per mouseclick, for more control 2012-07-01 18:07:33 +12:00
Matthias Mailänder
efe2f2e043 UnloadCargo rallypoint fixes #2016 2012-07-01 18:07:05 +12:00
Matthias Mailänder
6681382819 unclock factory exits 2012-07-01 14:53:45 +12:00
Matthias Mailänder
7a578a0679 notifications (formerly EVAalerts) centralized and race specific
outsourced into notifications.yaml
triggered with PlayNotification(...)

(v2: less redundant code for PlayVoice/Notifications)

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

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

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

misc:
Made Artillery shell explosion appear bigger
Added contrail to Artillery shell
2012-05-04 16:54:36 +12:00
earthpig
d9992eea6a cnc - Increase rocket launcher cost from 800 to 1200 to reflect changes in range. 2012-05-04 16:51:52 +12:00
earthpig
c8c4507acf Few things with Zhukov AI. 2012-05-01 14:51:21 -07:00
psydev
5a37c84a8b improve chem warrior, flamethrower, grenadier and napalm drop 2012-05-02 09:10:53 +12:00
Chris Forbes
63898820f1 ra: drop mjolnir-1 map 2012-05-02 09:08:28 +12:00
psydev
63359e156c Increasing speed of flamethrowers and grenadiers 2012-05-02 09:01:26 +12:00
psydev
d683d69f3c Increase A-10 speed from 25 to 40 2012-05-02 09:01:05 +12:00
Chris Forbes
609d5bd611 ra: fix Flame Turret -> Flame Tower in unit name 2012-05-02 08:32:43 +12:00
psydev
0b894d3b31 Make silo first item in support/defense queue. 2012-05-02 08:30:38 +12:00
psydev
3a838a05cd Remove bib from HPAD 2012-05-02 08:29:06 +12:00
psydev
0a0b136b80 See ground beneath A-10 airstrike's flightpath 2012-05-02 08:27:26 +12:00
psydev
82549c6407 Increase Chinook capacity to 10 2012-05-02 08:26:27 +12:00
Chris Forbes
d737930bb0 #2076 fixed - missing widget id for WICW 2012-05-01 19:59:48 +12:00
Curtis Shmyr
dad67713fb Fix recent break in SupportPowerManager 2012-04-30 16:35:56 -06:00
psydev
a1082152a4 Urgent! Include in this release (fixes non-targeting of defensive towers/turrets). I made units no longer target ordinary buildings, but forgot to re-include targeting of the structures that shoot at you. 2012-05-01 07:26:06 +12:00
psydev
9f729b0c45 Made Chem Warriors walk through tiberium instead of around it and reduced their penalty for running through it to what would normally be "rough" terrain (80% instead of 70%).
Gave Commando Red Pip while passenger in APC/helicopter (can we get a more distinct color for engineer? Bright yellow or orange that contrasts from regular green, and/or pale blue).
Increased Commando shroud reveal to 6, since that will equal what 5 ought to be (infantry and vehicles have differences in sight range even when they have the same value, it seems http://i.imgur.com/Z6nWG.jpg)
2012-04-30 22:15:21 +12:00
psydev
ee7d8659d5 Removed bib from repair bay, to make it like the one from Red Alert.
Increased sight range of Construction Yard to 10.
2012-04-30 22:14:23 +12:00
psydev
4448c3e51b cnc: various balance changes, part 2
Infantry sight range +1 -- it seems that they have lower sight range than vehicles for some reason. See http://i.imgur.com/Z6nWG.jpg for infantry and vehicle, both with RevealsShroud: 5, but vehicle sees further. So, effectively 5 for infantry becomes 4, which seems reasonable.
Reduced probability of SpawnViceroid from 10% to 2%. 2% will still happen often enough if Chem Warriors are used predominantly, but with 10%, units were constantly turning to Viceroids, which was a pain. You could also send 10 infantry to opponent's tib field in early game and spawn a viceroid and kill their harvester or harass them.
Turned off units auto-targeting regular buildings, because often will attack silo over an obelisk or enemy unit. Auto-target should remain on for defensive towers/turrets, though.
2012-04-30 22:07:48 +12:00
psydev
174e925e5a cnc: various balance changes
As usual I'm trying to be conservative and only apply what I feel is suitable / minimally necessary.
Weapons:
Biggest change: Increased artillery range from 6 to 12, added contrail to bullet and changed impact sound to default C&C. Minimum range 2 given.
Napalm is currently very ineffective; increased spread to 20 range to make more likely to kill targets, ROF slightly increased
MRLS rocket ranged increased from 8 to 12, with minimum range 2.
Guard tower range increased from 4 to 5 (Pillbox is 6, for comparison) and damage increased from 20 to 40.
Grenadier death explosion reduced in damage from 25-10 and in blast radius.
2012-04-30 22:07:32 +12:00
earthpig
e7a8cdf951 Normal AI: Gone.
Zhukov AI: Bit of a turtle, but sends large attacks with arty/v2.
Rommel AI: Modified Hard AI.
2012-04-30 21:51:46 +12:00
Curtis Shmyr
45f5c054d5 Fix #2070; cannot sell when building is being captured 2012-04-30 21:37:09 +12:00
psydev
15dcd6a9f6 Harvester armor heavy 2012-04-30 21:35:35 +12:00
Chris Forbes
9c86196b16 fix crash in ChooseBuildTabOnSelect in replay 2012-04-30 21:32:57 +12:00
Curtis Shmyr
9185dc65d5 Initial pbox pax changes 2012-04-30 21:18:10 +12:00
Chris Forbes
e0bfa287ee new flamer integrated 2012-04-30 21:13:15 +12:00
Chris Forbes
80f142c8ea flamer that doesnt suck 2012-04-30 20:51:10 +12:00
Chris Forbes
7050fbc6e1 add napalm1 SHP and wiring in ra/sequences 2012-04-30 20:38:42 +12:00
Chris Forbes
2c938bc305 add sniper SHP 2012-04-30 20:33:36 +12:00
Chris Forbes
cd6bfb1b9a add better flame projectile SHP 2012-04-30 20:33:21 +12:00
Chris Forbes
11b253e4c3 add gate SHPs 2012-04-30 20:33:03 +12:00
earthpig
d625e2624a Fixed #2010 - arty in line now only has only 75% chance of exploding
When an arty in a group of them dies, each individual arty only has a 75% chance of perpetuating the genocide of arty.... so usually, it'll stop before killing your whole line but not before seriously hurting it.
2012-04-29 19:20:46 +12:00
earthpig
a544bc966b #2048 fixed: make AI behavior more varied 2012-04-29 19:15:55 +12:00
psydev
9a3aae6586 cnc: change AI to not be totally useless 2012-04-29 10:56:47 +12:00
psydev
390e607e66 cnc: remove nuke crate 2012-04-29 10:55:46 +12:00
psydev
22b18f99db cnc: remove hide-map crate 2012-04-29 10:54:51 +12:00
Chris Forbes
c30d46c014 #2051 fixed -- Widget.Get() throws by default 2012-04-27 19:39:07 +12:00
Chris Forbes
5d1a071287 fix crash in colorpicker 2012-04-26 21:42:07 +12:00
Chris Forbes
16e00c1f12 shimmering cloak in cnc 2012-04-25 22:24:38 +12:00
Chris Forbes
87271a0a56 make cloak palette configurable 2012-04-25 21:45:38 +12:00
Chris Forbes
dadc496c19 beef up OpenRA.FileFormats.Set a little; use it in CncMenuPaletteEffect rather than making new List<string> every frame 2012-04-25 21:43:00 +12:00
Chris Forbes
a0940e7ae5 unify water palette rotation 2012-04-25 21:32:33 +12:00
Chris Forbes
ca1fbb187b misc whitespace tidyups 2012-04-25 21:31:27 +12:00
Chris Forbes
89025a3042 make attackmove on spawn work properly for things that cant attackmove 2012-04-25 21:11:31 +12:00
earthpig
49f3f740e3 New units now AttackMove to their designated rally point. 2012-04-25 20:52:51 +12:00
Chris Forbes
4b4bbdf626 fix recent breakage in support powers 2012-04-25 01:58:37 +12:00
Chris Forbes
cebf908bb2 Fixed #2041 -- Force attack always targeted ground
Revert "Force attacks always go through, regardless of what is beneath them."

This reverts commit b2c72d6990.
2012-04-25 00:22:07 +12:00
Chris Forbes
75c105cb85 fix right edge of cheats close button 2012-04-25 00:06:48 +12:00
Chris Forbes
6669a66292 #2028 fixed - observer and dead map in cnc works again 2012-04-24 20:29:46 +12:00
Chris Forbes
6e3aa46008 #2039 fixed - add Sound.Engine config item, default is "AL" for OpenAL sound engine; "Null" gives you no sound 2012-04-24 20:23:41 +12:00
Chris Forbes
84a50e8e86 unify cheats panels 2012-04-24 20:04:21 +12:00
Chris Forbes
6559d8d8bc fix cnc direct connect panel 2012-04-24 19:47:04 +12:00
Chris Forbes
926686beff fix cnc cheats panel 2012-04-24 19:44:06 +12:00
Chris Forbes
6ab171af8b #2027 fixed - allow custom starting units for each faction 2012-04-24 19:29:53 +12:00
Chris Forbes
c4916bd997 #2038 fixed - add shadow to crates on the ground 2012-04-24 19:17:41 +12:00
Chris Forbes
f86332fd99 change pillbox hotkey to p 2012-04-20 14:41:45 +12:00
Chris Forbes
8d843cd8ad dropped map No Fly Zone 2012-04-19 11:04:51 +12:00
Chris Forbes
0904ac3a70 remove spurious trait lookup 2012-04-13 13:32:59 +12:00
Chris Forbes
8488223eee fix misspelling of Received 2012-04-13 13:28:31 +12:00
Chris Forbes
da3ba159db make failure of a lintpass nonfatal 2012-04-13 12:47:42 +12:00
Chris Forbes
3e0f52db1a fix cnc chrome yaml issues 2012-04-09 13:10:40 +12:00
Chris Forbes
062c49dac3 fix bogus widget id setup for resolution picker 2012-04-09 13:10:40 +12:00
Chris Forbes
533f9044cc strip redundant Id: elements from chrome yaml 2012-04-09 13:10:40 +12:00
Chris Forbes
b9eb3a0ad0 Patch widget loader to convert @key into Id member of widgets 2012-04-09 13:10:40 +12:00
Chris Forbes
dbd09ea843 Add building infiltrated sound to owner of spy on infiltrate 2012-04-09 10:33:39 +12:00
Chris Forbes
a4e1915aff warn the lobby when a client joins with DEV_VERSION 2012-04-09 09:40:22 +12:00
Chris Forbes
9d2833fc2b fix spelling error in comment 2012-04-09 09:39:57 +12:00
Chris Forbes
ab4c21f80c fix crash in server in StartGame if there are unvalidated connections 2012-04-09 09:18:54 +12:00
Chris Forbes
f7fea5ffce fix spelling error in Crate* comments 2012-04-07 11:06:26 +12:00
Chris Forbes
87e9a69ae0 fixed #2001: passengers shooting while in transports 2012-04-07 11:05:59 +12:00
Chris Forbes
25fb2a7be3 tidy 2012-04-07 10:29:25 +12:00
Chris Forbes
10c1b996ed tidy up disabled handling 2012-04-06 19:34:43 +12:00
Nukem
aa21ddaa4d Added new RA map: Tainted Peak 2012-04-06 18:36:50 +12:00
Chris Forbes
eab0e7ddf9 add range circle for gap generator 2012-04-06 18:35:04 +12:00
Curtis Shmyr
891cba456b give Gap Generator to allies 2012-04-06 18:23:30 +12:00
Chris Forbes
beb6b01796 show cashticks for DonateSupplies in spec 2012-04-06 18:14:58 +12:00
Chris Forbes
a52af4843e add cashtick for InfiltrateForCash 2012-04-06 18:14:11 +12:00
Chris Forbes
8dec48fee3 add spy reward for infiltrating refinery 2012-04-06 18:07:39 +12:00
Chris Forbes
b081103866 add infiltrate for exploration(reset) ability 2012-04-06 17:47:17 +12:00
Chris Forbes
4a76e2ad33 slight tidy in InfiltrateForSupportPower 2012-04-06 17:36:39 +12:00
Chris Forbes
b39eeddb45 adjust priority of Spy actions to prefer disguise/infiltrate when they match 2012-04-06 16:37:12 +12:00
Chris Forbes
7d4186c236 add SilencedPPK weapon for spy 2012-04-06 16:27:04 +12:00
Chris Forbes
01a724d632 only allow SpyInfiltrate/Disguise orders on Spy when not doing ForceAttack 2012-04-06 16:13:33 +12:00
Chris Forbes
ca1549df2a allow forceattack to be allowed/banned on UnitOrderTargeter 2012-04-06 16:05:35 +12:00
hasufell
0ae8e41612 add music themes which are available on cd-content 2012-04-06 14:47:04 +12:00
Curtis Shmyr
bc8c433a72 Modified Capturable to have a capture time; fixes #2002 2012-04-06 14:47:04 +12:00
Chris Forbes
7187b14459 drop Daejeon map 2012-04-03 16:21:19 +12:00
Chris Forbes
07d25d97ab fix missing escape keybinds in ra 2012-04-03 09:54:40 +12:00
Chris Forbes
4d5f89909e tanya is only available to allies 2012-04-03 09:54:29 +12:00
Chris Forbes
60fa61840d Spy drops disguise on attacking 2012-04-02 13:28:58 +12:00
Curtis Shmyr
499234e5dd Fixed #1321; no main menu after lobby disconnect/failed retry 2012-04-02 10:13:17 +12:00
hasufell
1010276cd5 make paths modifiable, fix broken install-rules, fix INSTALL 2012-04-02 09:21:51 +12:00
Curtis Shmyr
fdef80c53a Modify Cargo trait to support initial passengers 2012-03-23 15:16:48 +13:00
Kenny Hoxworth
22d3709967 Allow the targeting of water tiles by default. This still doesn't allow targeting of underwater, which is they way it should be. Now ground based units will be allowed to force-attack water tiles. 2012-03-23 10:07:11 +13:00
Kenny Hoxworth
b2c72d6990 Force attacks always go through, regardless of what is beneath them. 2012-03-23 10:06:59 +13:00
Chris Forbes
6f688275c5 include source location when complaining about bad miniyaml indents 2012-03-16 18:43:41 +13:00
Chris Forbes
5b8334b26d drop ILogicWithInit, no longer used 2012-03-16 18:43:41 +13:00
Chris Forbes
23ea8493ba fix crash in cnc replay viewing with radar 2012-03-16 18:43:40 +13:00
Chris Forbes
cc9dbd43c3 fix permissions on apc turrets 2012-03-13 09:11:35 +13:00
Chris Forbes
8308f82926 use the correct user for deployment 2012-03-04 13:08:50 +13:00
Chris Forbes
11f322a758 Fix smoke being triggered by healing as well as damage 2012-03-04 12:54:35 +13:00
Chris Forbes
6376615781 make 4tnk use damage cooldown for heal 2012-03-04 12:44:44 +13:00
Chris Forbes
f4b302e01a add support for damage cooldown on SelfHealing 2012-03-04 12:39:46 +13:00
Chris Forbes
703d6648d7 fix C2 ProximityCaptor sillyness 2012-03-04 12:31:02 +13:00
Curtis Shmyr
f19807f0ca Changed TTNK cost to 1500, hit points to 150 2012-03-03 16:18:11 -07:00
Curtis Shmyr
a523510922 Changed E4 (flamethrower) build prerequisite to FTUR 2012-03-03 16:12:13 -07:00
Chris Forbes
47194fab71 Add defend stance support for turreted units 2012-03-04 11:42:21 +13:00
Chris Forbes
75e32c0573 don't fetch IFacing unless we actually need it, in Attack 2012-03-04 11:17:46 +13:00
Chris Forbes
38b5a8d4f8 Fix #1327 - div/0 in Drag with extreme movement speeds 2012-03-03 18:17:21 +13:00
wuschel
522c88dcda Added map by wuschel: Ares National Park 2012-03-03 18:07:47 +13:00
Curtis Shmyr
3375a5de51 Oil derricks are not required to be destroyed when eliminating a player 2012-03-03 18:07:29 +13:00
Chris Forbes
68933880b9 Fix #1349 - Add configurable threshold for RepairableNear, default is 4 cells. 2012-03-03 18:05:31 +13:00
Chris Forbes
469a393585 give RepairableNear access to its info 2012-03-03 18:01:50 +13:00
Chris Forbes
be1fdbdd56 Fix #1348 -- Tesla Coils now support Stop (S) order 2012-03-03 17:44:41 +13:00
Curtis Shmyr
2972728b5e Ctrl-Shift-numkey performs unit grouping into existing groups 2012-02-19 08:47:43 +13:00
Sam Hegarty
78ba76250d Remove dependency on mesa-dri-drivers-experimental for the rpm package
- this package is no longer available in recent releases of Fedora
      and shouldn't be REQUIRED anymore.
2012-02-17 19:58:18 +13:00
Curtis Shmyr
603014b163 Added 3 maps by wuschel: Poseidon, Ares and Apollo 2012-02-13 09:11:54 +13:00
Nukem
6b85518b74 Added new map by Nukem: Breaking Point 2012-02-13 09:11:54 +13:00
Blarget2
d3578273db Added new map by Blarget2: Temperal 2012-02-13 09:11:54 +13:00
Curtis Shmyr
54f3c76da8 Removed random sbag in Mjolnir-2 2012-02-13 09:11:54 +13:00
Curtis Shmyr
95b908b234 Fixed bug where bots weren't given proper client index 2012-02-13 09:11:54 +13:00
Curtis Shmyr
3b94728869 Reduced amount of mines MNLY.AT carries from 5 to 3 2012-02-13 09:11:32 +13:00
Curtis Shmyr
b8b9d34404 Aircraft can use friendly service depots/airfields/helipads 2012-02-13 09:11:32 +13:00
Chris Forbes
a5cfc20e0b dont reinvent base64 decoding 2012-02-13 09:10:01 +13:00
Chris Forbes
3cf09e656f Add support for negative prerequisites (#1323) 2012-02-13 09:10:01 +13:00
Chris Forbes
1f8859f26b remove useless TUtil type alias from IronCurtainPower 2012-02-13 09:10:01 +13:00
Chris Forbes
6555bc9dbc use curl instead of wget 2012-02-13 09:10:01 +13:00
Chris Forbes
49fb0228fa fix upload script to use scp rather than ftp; ftp no longer available on the webserver 2012-02-13 09:10:00 +13:00
Nikita Tsukanov
ad29926391 Removed Connection.PlayerIndex == 0 checks if favor of Session.Player.IsAdmin 2012-01-09 15:37:55 +04:00
Chris Forbes
85293a482e remove spurious allowMovement parameter from ScanAndAttack 2012-01-07 20:33:56 +13:00
Chris Forbes
6315864f84 add Defend unit stance 2012-01-07 20:33:56 +13:00
Chris Forbes
c169bc3c51 fix #1320 bogus use of Game.CosmeticRandom from server thread 2012-01-07 20:33:56 +13:00
Chris Forbes
1de3db0903 Don't take a NRE in GiveUnitCrateAction.GetSuitableCells if not Mobile 2012-01-07 20:33:56 +13:00
Chris Forbes
965fe88755 #1284 fixed; don't show spawnpoints on serverbrowser thumbnails 2011-12-31 11:32:59 +13:00
Chris Forbes
809b716d0d tidy silly Enum.GetValues type nonsense 2011-12-31 11:02:38 +13:00
Chris Forbes
004c59d273 sort the serverlist by whether we can join the game 2011-12-31 10:58:31 +13:00
Chris Forbes
c34b254fd8 stop repairing a building if we don't like its owner (fixes interaction with capture) 2011-12-31 10:50:18 +13:00
Chris Forbes
0d25b6b5c9 use spacebar to go to last attack event 2011-12-31 10:48:30 +13:00
Chris Forbes
85eeb8b819 tidy 2011-12-28 08:16:51 +13:00
Chris Forbes
e84d90fc3a more general tidying 2011-12-28 08:13:36 +13:00
Chris Forbes
418b8d40f9 improve TraitDictionary error messages 2011-12-28 08:02:09 +13:00
Chris Forbes
9581595a3d remove spurious null checks in Shroud -- all actors have an owner, always. 2011-12-27 21:53:31 +13:00
Chris Forbes
0aa7ba6bd4 remove sillyness in DelayedAction.CompareTo 2011-12-27 21:48:42 +13:00
Chris Forbes
2793d1076a clean up inconsistency in InvisibleToEnemy 2011-12-27 21:23:25 +13:00
Chris Forbes
d57dfd1997 tidy 2011-12-27 21:23:25 +13:00
Chris Forbes
f8122047b6 ShpLoader is no longer IEnumerable 2011-12-27 18:10:52 +13:00
Chris Forbes
d115c6305c general tidying in ShpReader 2011-12-27 18:02:32 +13:00
Chris Forbes
f63cdf37d7 tidy usings in Graphics.Util 2011-12-27 14:53:18 +13:00
Chris Forbes
dd88a1269a move MakeArray to FileFormats.Exts 2011-12-27 14:52:11 +13:00
Chris Forbes
523183431b remove some duplication and dead code 2011-12-27 14:48:10 +13:00
Chris Forbes
132c678594 add --remap cmdlet to OpenRA Utility, remaps between ra/cnc/etc palettes. 2011-12-27 11:48:22 +13:00
Chris Forbes
f8127ab9df don't start writing replays until gamestart 2011-12-24 21:07:53 +13:00
Chris Forbes
d61055af8f work toward deferrable start of replay saving 2011-12-24 20:39:33 +13:00
Chris Forbes
4e6ff7616c tidy in FileSystem 2011-12-24 19:41:45 +13:00
Chris Forbes
f2dd5eb0a3 simplify UOG 2011-12-24 12:19:59 +13:00
Chris Forbes
f7e35899cf tidy ReplayConnection 2011-12-24 10:11:31 +13:00
Chris Forbes
727b897994 split ReplayRecorderConnection out into its own file 2011-12-24 10:05:14 +13:00
Chris Forbes
8029973e33 cull RA maps Paramount and Pandemonium, not played enough 2011-12-23 18:30:26 +13:00
1635 changed files with 79254 additions and 25203 deletions

10
.gitattributes vendored Normal file
View File

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

21
.gitignore vendored
View File

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

22
.travis.yml Normal file
View File

@@ -0,0 +1,22 @@
# Travis-CI Build for OpenRA
# see travis-ci.org for details
# Mono/.NET are not officially supported. The following is a workaround.
language: c
# Make sure build dependencies are installed.
install:
- sudo apt-get install mono-gmcs cli-common-dev libgl1-mesa-dev libsdl1.2-dev libsdl-gfx1.2-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-net1.2-dev libsdl-ttf2.0-dev libsmpeg-dev libopenal-dev libalut-dev
# Run the build script which will automatically call RALint.
script:
- make all
# Only watch the development branch.
branches:
only:
- bleed
# Notify developers when needed.
notifications:
irc: "irc.freenode.net#openra"

20
AUTHORS
View File

@@ -12,25 +12,43 @@ The OpenRA developers are:
Also thanks to:
* Akseli Virtanen (RAGEQUIT)
* Andrew Riedi
* Barnaby Smith (mvi)
* Bellator
* Bugra Cuhadaroglu (BugraC)
* Christer Ulfsparre (Holloweye)
* Cody Brittain (Generalcamo)
* Daniel Derejvanik (Harisson)
* Danny (Dan9550)
* Erasmus Schroder (rasco)
* Igor Popov (ihptru)
* Iran
* James Dunne (jsd)
* Jeff Harris (jeff_1amstudios)
* Jes (-Jes-)
* Joakim Lindberg (booom3)
* JOo
* Kenny Hoxworth (hoxworth)
* Krishnakanth Mallik
* Kyrre Soerensen (zypres)
* Lawrence Wang
* Lesueur Benjamin (Valkirie)
* Mark Olson (markolson)
* Matthew Gatland (mgatland)
* Matthias Mailänder (Mailaender)
* Maarten Meuris (Nyerguds)
* Max Ugrumov (katzsmile)
* Max621
* Nukem
* Paolo Chiodi (paolochiodi)
* Paul Dovydaitis (pdovy)
* Psydev
* Raymond Martineau (mart0258)
* Riderr3
* Sascha Biedermann (bidifx)
* Tim Mylemans (gecko)
* Tirili
* Vladimir Komarov (VrKomarov)
Past developers included:
* Paul Chote (pchote)
* Robert Pepperell (ytinasni)

1209
CHANGELOG

File diff suppressed because it is too large Load Diff

19
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,19 @@
# OpenRA Contributing Guidelines
## Bug reports
* Have you read the [FAQ](https://github.com/OpenRA/OpenRA/wiki/FAQ)?
* Add the appropriate log files on crashes.
* Please be specific on how to reproduce the problem.
## Patches
* [Coding standard](https://github.com/OpenRA/OpenRA/wiki/Coding-Standard)
* [Branches and Releases](https://github.com/OpenRA/OpenRA/wiki/Branches-and-Releases)
* [Licensing](http://www.gnu.org/licenses/quick-guide-gplv3.html)
Please `git rebase` to the latest revision of the bleed branch.
Don't forget to add youself to [AUTHORS](https://github.com/OpenRA/OpenRA/blob/bleed/AUTHORS).
While your pull-request is in review it will be helpful if you join [IRC](irc://chat.freenode.net/openra) to discuss the changes.

20
INSTALL
View File

@@ -41,23 +41,19 @@ UBUNTU (substitute comparable packages for other linux distros):
OpenRA does not work with some older versions of Compiz. On affected systems, disable desktop effects before playing. This is fixed in Ubuntu Natty and later.
You will additionally need to copy the third party dependencies (.dll and .config) from the
thirdparty and thirdparty/Tao directories into the game root:
cp -v thirdparty/*.dll thirdparty/Tao/* .
Alternatively, the dlls can be installed into your system GAC. This is not
The following dlls can also be installed into your system GAC. This is not
recommended because we ship a custom Tao.FreeType that can conflict with
other applications that use Tao:
gacutil -i thirdparty/Tao/Tao.Cg.dll
gacutil -i thirdparty/Tao/Tao.OpenGl.dll
gacutil -i thirdparty/Tao/Tao.OpenAl.dll
gacutil -i thirdparty/Tao/Tao.Sdl.dll
gacutil -i thirdparty/Tao/Tao.FreeType.dll
gacutil -i thirdparty/ICSharpCode.SharpZipLib.dll
gacutil -i Tao.Cg.dll
gacutil -i Tao.OpenGl.dll
gacutil -i Tao.OpenAl.dll
gacutil -i Tao.Sdl.dll
gacutil -i Tao.FreeType.dll
gacutil -i ICSharpCode.SharpZipLib.dll
To compile OpenRA, run `make' from the command line.
To install run 'make install'.
Run the game with `mono OpenRA.Game.exe Game.Mods=ra` for Red Alert
or `mono OpenRA.Game.exe Game.Mods=cnc` for Command & Conquer

View File

@@ -1,14 +1,14 @@
CSC = gmcs
CSFLAGS = -nologo -warn:4 -debug:+ -debug:full -optimize- -codepage:utf8 -unsafe
CSFLAGS = -nologo -warn:4 -debug:full -optimize- -codepage:utf8 -unsafe -warnaserror
DEFINE = DEBUG;TRACE
COMMON_LIBS = System.dll System.Core.dll System.Drawing.dll System.Xml.dll thirdparty/ICSharpCode.SharpZipLib.dll
PHONY = core tools package all mods clean distclean
COMMON_LIBS = System.dll System.Core.dll System.Drawing.dll System.Xml.dll thirdparty/ICSharpCode.SharpZipLib.dll thirdparty/FuzzyLogicLibrary.dll
PHONY = core tools package all mods clean distclean
.SUFFIXES:
core: game renderers mod_ra mod_cnc utility
core: game renderers mods utility tsbuild
tools: editor ralint tsbuild
package: core editor
mods: mod_ra mod_cnc
package: core editor docs
mods: mod_ra mod_cnc mod_d2k
all: core tools
clean:
@-rm -f *.exe *.dll *.mdb mods/**/*.dll mods/**/*.mdb *.resources
@@ -97,6 +97,16 @@ mod_cnc_EXTRA_CMDS = mono --debug RALint.exe cnc
PROGRAMS += mod_cnc
mod_cnc: $(mod_cnc_TARGET)
# Dune 2000
mod_d2k_SRCS := $(shell find OpenRA.Mods.D2k/ -iname '*.cs')
mod_d2k_TARGET = mods/d2k/OpenRA.Mods.D2k.dll
mod_d2k_KIND = library
mod_d2k_DEPS = $(STD_MOD_DEPS) $(mod_ra_TARGET) $(mod_cnc_TARGET) $(utility_TARGET)
mod_d2k_LIBS = $(COMMON_LIBS) $(STD_MOD_LIBS) $(mod_ra_TARGET) $(utility_TARGET)
mod_d2k_EXTRA_CMDS = mono --debug RALint.exe d2k
PROGRAMS += mod_d2k
mod_d2k: $(mod_d2k_TARGET)
#
# Tools
#
@@ -122,20 +132,25 @@ ralint_TARGET = RALint.exe
ralint_KIND = exe
ralint_DEPS = $(fileformats_TARGET) $(game_TARGET)
ralint_LIBS = $(COMMON_LIBS) $(ralint_DEPS)
ralint_EXTRA_CMDS = cp thirdparty/FuzzyLogicLibrary.dll .
PROGRAMS += ralint
ralint: $(ralint_TARGET)
# Builds and exports tilesets from a bitmap
tsbuild_SRCS := $(shell find OpenRA.TilesetBuilder/ -iname '*.cs')
tsbuild_TARGET = TilesetBuilder.exe
tsbuild_TARGET = OpenRA.TilesetBuilder.exe
tsbuild_KIND = winexe
tsbuild_DEPS = $(fileformats_TARGET) $(game_TARGET)
tsbuild_LIBS = $(COMMON_LIBS) $(tsbuild_DEPS) System.Windows.Forms.dll
tsbuild_EXTRA = -resource:OpenRA.TilesetBuilder.Form1.resources
tsbuild_EXTRA = -resource:OpenRA.TilesetBuilder.frmBuilder.resources -resource:OpenRA.TilesetBuilder.frmNew.resources -resource:OpenRA.TilesetBuilder.Surface.resources
PROGRAMS += tsbuild
OpenRA.TilesetBuilder.Form1.resources:
resgen2 OpenRA.TilesetBuilder/Form1.resx OpenRA.TilesetBuilder.Form1.resources 1> /dev/null
tsbuild: OpenRA.TilesetBuilder.Form1.resources $(tsbuild_TARGET)
OpenRA.TilesetBuilder.frmBuilder.resources:
resgen2 OpenRA.TilesetBuilder/frmBuilder.resx OpenRA.TilesetBuilder.frmBuilder.resources 1> /dev/null
OpenRA.TilesetBuilder.frmNew.resources:
resgen2 OpenRA.TilesetBuilder/frmNew.resx OpenRA.TilesetBuilder.frmNew.resources 1> /dev/null
OpenRA.TilesetBuilder.Surface.resources:
resgen2 OpenRA.TilesetBuilder/Surface.resx OpenRA.TilesetBuilder.Surface.resources 1> /dev/null
tsbuild: OpenRA.TilesetBuilder.frmBuilder.resources OpenRA.TilesetBuilder.frmNew.resources OpenRA.TilesetBuilder.Surface.resources $(tsbuild_TARGET)
#
# Launchers / Utilities
@@ -180,15 +195,19 @@ $(foreach prog,$(PROGRAMS),$(eval $(call BUILD_ASSEMBLY,$(prog))))
#
# Install / Uninstall for *nix
#
prefix = /usr/local
datarootdir = $(prefix)/share
datadir = $(datarootdir)
bindir = $(prefix)/bin
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)
CORE = fileformats rcg rgl rsdl rnull game editor utility
CORE = fileformats rcg rgl rsdl rnull game editor utility tsbuild
# Documentation (d2k depends on all mod libraries)
docs:
@mono --debug OpenRA.Utility.exe --docs d2k > DOCUMENTATION.md
install: all
@-echo "Installing OpenRA to $(INSTALL_DIR)"
@@ -196,6 +215,10 @@ install: all
@$(INSTALL_PROGRAM) $(foreach prog,$(CORE),$($(prog)_TARGET)) $(INSTALL_DIR)
@$(INSTALL_PROGRAM) -d $(INSTALL_DIR)/mods/cnc
@$(INSTALL_PROGRAM) $(mod_cnc_TARGET) $(INSTALL_DIR)/mods/cnc
@$(INSTALL_PROGRAM) -d $(INSTALL_DIR)/mods/ra
@$(INSTALL_PROGRAM) $(mod_ra_TARGET) $(INSTALL_DIR)/mods/ra
@$(INSTALL_PROGRAM) -d $(INSTALL_DIR)/mods/d2k
@$(INSTALL_PROGRAM) $(mod_d2k_TARGET) $(INSTALL_DIR)/mods/d2k
@-cp $(foreach f,$(shell ls mods/cnc --hide=*.dll),mods/cnc/$(f)) $(INSTALL_DIR)/mods/cnc
@cp -r mods/cnc/maps $(INSTALL_DIR)/mods/cnc
@@ -205,8 +228,6 @@ install: all
@cp -r mods/cnc/sequences $(INSTALL_DIR)/mods/cnc
@cp -r mods/cnc/tilesets $(INSTALL_DIR)/mods/cnc
@cp -r mods/cnc/uibits $(INSTALL_DIR)/mods/cnc
@$(INSTALL_PROGRAM) -d $(INSTALL_DIR)/mods/ra
@$(INSTALL_PROGRAM) $(mod_ra_TARGET) $(INSTALL_DIR)/mods/ra
@-cp $(foreach f,$(shell ls mods/ra --hide=*.dll),mods/ra/$(f)) $(INSTALL_DIR)/mods/ra
@cp -r mods/ra/maps $(INSTALL_DIR)/mods/ra
@@ -215,20 +236,44 @@ install: all
@cp -r mods/ra/rules $(INSTALL_DIR)/mods/ra
@cp -r mods/ra/tilesets $(INSTALL_DIR)/mods/ra
@cp -r mods/ra/uibits $(INSTALL_DIR)/mods/ra
@-cp $(foreach f,$(shell ls mods/d2k --hide=*.dll),mods/d2k/$(f)) $(INSTALL_DIR)/mods/d2k
@cp -r mods/d2k/maps $(INSTALL_DIR)/mods/d2k
@cp -r mods/d2k/bits $(INSTALL_DIR)/mods/d2k
@cp -r mods/d2k/chrome $(INSTALL_DIR)/mods/d2k
@cp -r mods/d2k/rules $(INSTALL_DIR)/mods/d2k
@cp -r mods/d2k/tilesets $(INSTALL_DIR)/mods/d2k
@cp -r mods/d2k/uibits $(INSTALL_DIR)/mods/d2k
@cp -r glsl $(INSTALL_DIR)
@cp -r cg $(INSTALL_DIR)
@cp *.ttf $(INSTALL_DIR)
@cp --parents -r thirdparty/Tao $(INSTALL_DIR)
@cp thirdparty/Tao/* $(INSTALL_DIR)
@$(INSTALL_PROGRAM) thirdparty/ICSharpCode.SharpZipLib.dll $(INSTALL_DIR)
@$(INSTALL_PROGRAM) thirdparty/FuzzyLogicLibrary.dll $(INSTALL_DIR)
@echo "#!/bin/sh" > openra
@echo "cd "$(datadir)"/openra" >> openra
@echo "mono "$(datadir)"/openra/OpenRA.Game.exe \"$$""@\"" >> openra
@echo "#!/bin/sh" > openra
@echo 'BINDIR=$$(dirname $$(readlink -f $$0))' >> openra
@echo 'ROOTDIR="$${BINDIR%'"$(bindir)"'}"' >> openra
@echo 'DATADIR="$${ROOTDIR}/'"$(datadir)"'"' >> openra
@echo 'cd "$${DATADIR}/openra"' >> openra
@echo 'exec mono OpenRA.Game.exe "$$@"' >> openra
@echo "#!/bin/sh" > openra-editor
@echo 'BINDIR=$$(dirname $$(readlink -f $$0))' >> openra-editor
@echo 'ROOTDIR="$${BINDIR%'"$(bindir)"'}"' >> openra-editor
@echo 'DATADIR="$${ROOTDIR}/'"$(datadir)"'"' >> openra-editor
@echo 'cd "$${DATADIR}/openra"' >> openra-editor
@echo 'exec mono OpenRA.Editor.exe "$$@"' >> openra-editor
@$(INSTALL_PROGRAM) -d $(BIN_INSTALL_DIR)
@$(INSTALL_PROGRAM) -m +rx openra $(BIN_INSTALL_DIR)
@$(INSTALL_PROGRAM) -m +rx openra-editor $(BIN_INSTALL_DIR)
@-rm openra
@-rm openra-editor
uninstall:
@-rm -r $(INSTALL_DIR)
@-rm $(DESTDIR)$(bindir)/openra
@-rm $(DESTDIR)$(bindir)/openra-editor

View File

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

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2013 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,
@@ -55,6 +55,23 @@ namespace OpenRA.Editor
this.surface1 = new OpenRA.Editor.Surface();
this.tt = new System.Windows.Forms.ToolTip(this.components);
this.splitContainer3 = new System.Windows.Forms.SplitContainer();
this.toolStrip1 = new System.Windows.Forms.ToolStrip();
this.toolStripMenuItemNew = new System.Windows.Forms.ToolStripButton();
this.toolStripMenuItemOpen = new System.Windows.Forms.ToolStripButton();
this.toolStripMenuItemSave = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator = new System.Windows.Forms.ToolStripSeparator();
this.toolStripMenuItemProperties = new System.Windows.Forms.ToolStripButton();
this.toolStripMenuItemResize = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator8 = new System.Windows.Forms.ToolStripSeparator();
this.toolStripMenuItemShowActorNames = new System.Windows.Forms.ToolStripButton();
this.toolStripMenuItemShowGrid = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator10 = new System.Windows.Forms.ToolStripSeparator();
this.toolStripMenuItemFixOpenAreas = new System.Windows.Forms.ToolStripButton();
this.toolStripMenuItemSetupDefaultPlayers = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator11 = new System.Windows.Forms.ToolStripSeparator();
this.toolStripMenuItemCopySelection = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator();
this.QuickhelpToolStripButton = 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();
@@ -65,23 +82,43 @@ namespace OpenRA.Editor
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.mnuExport = new System.Windows.Forms.ToolStripMenuItem();
this.mnuMinimapToPNG = new System.Windows.Forms.ToolStripMenuItem();
this.fullMapRenderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
this.exitToolStripMenuItem = 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.toolStripSeparator9 = new System.Windows.Forms.ToolStripSeparator();
this.showActorNamesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.showGridToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
this.fixOpenAreasToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.setupDefaultPlayersMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
this.copySelectionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripComboBox1 = new System.Windows.Forms.ToolStripComboBox();
this.toolStripLabel1 = new System.Windows.Forms.ToolStripLabel();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.openRAWebsiteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.openRAResourcesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.wikiDocumentationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.discussionForumsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.sourceCodeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.issueTrackerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.developerBountiesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.toolStripStatusLabelFiller = new System.Windows.Forms.ToolStripStatusLabel();
this.toolStripStatusLabelMousePosition = new System.Windows.Forms.ToolStripStatusLabel();
this.BottomToolStripPanel = new System.Windows.Forms.ToolStripPanel();
this.TopToolStripPanel = new System.Windows.Forms.ToolStripPanel();
this.RightToolStripPanel = new System.Windows.Forms.ToolStripPanel();
this.LeftToolStripPanel = new System.Windows.Forms.ToolStripPanel();
this.ContentPanel = new System.Windows.Forms.ToolStripContentPanel();
this.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
@@ -97,8 +134,13 @@ namespace OpenRA.Editor
this.splitContainer3.Panel1.SuspendLayout();
this.splitContainer3.Panel2.SuspendLayout();
this.splitContainer3.SuspendLayout();
this.toolStrip1.SuspendLayout();
this.menuStrip1.SuspendLayout();
this.statusStrip1.SuspendLayout();
this.toolStripContainer1.BottomToolStripPanel.SuspendLayout();
this.toolStripContainer1.ContentPanel.SuspendLayout();
this.toolStripContainer1.TopToolStripPanel.SuspendLayout();
this.toolStripContainer1.SuspendLayout();
this.SuspendLayout();
//
// splitContainer1
@@ -114,7 +156,7 @@ namespace OpenRA.Editor
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.surface1);
this.splitContainer1.Size = new System.Drawing.Size(985, 744);
this.splitContainer1.Size = new System.Drawing.Size(985, 695);
this.splitContainer1.SplitterDistance = 198;
this.splitContainer1.TabIndex = 0;
//
@@ -132,8 +174,8 @@ namespace OpenRA.Editor
// splitContainer2.Panel2
//
this.splitContainer2.Panel2.Controls.Add(this.tabControl1);
this.splitContainer2.Size = new System.Drawing.Size(198, 744);
this.splitContainer2.SplitterDistance = 164;
this.splitContainer2.Size = new System.Drawing.Size(198, 695);
this.splitContainer2.SplitterDistance = 153;
this.splitContainer2.TabIndex = 1;
//
// pmMiniMap
@@ -143,7 +185,7 @@ namespace OpenRA.Editor
this.pmMiniMap.Dock = System.Windows.Forms.DockStyle.Fill;
this.pmMiniMap.Location = new System.Drawing.Point(0, 0);
this.pmMiniMap.Name = "pmMiniMap";
this.pmMiniMap.Size = new System.Drawing.Size(198, 164);
this.pmMiniMap.Size = new System.Drawing.Size(198, 153);
this.pmMiniMap.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pmMiniMap.TabIndex = 1;
this.pmMiniMap.TabStop = false;
@@ -160,7 +202,7 @@ namespace OpenRA.Editor
this.tabControl1.Name = "tabControl1";
this.tabControl1.Padding = new System.Drawing.Point(6, 0);
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(198, 576);
this.tabControl1.Size = new System.Drawing.Size(198, 538);
this.tabControl1.TabIndex = 0;
//
// tabPage1
@@ -169,7 +211,7 @@ namespace OpenRA.Editor
this.tabPage1.Location = new System.Drawing.Point(4, 20);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(190, 552);
this.tabPage1.Size = new System.Drawing.Size(190, 514);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "Templates";
this.tabPage1.UseVisualStyleBackColor = true;
@@ -181,7 +223,7 @@ namespace OpenRA.Editor
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(184, 546);
this.tilePalette.Size = new System.Drawing.Size(184, 508);
this.tilePalette.TabIndex = 1;
//
// tabPage2
@@ -191,7 +233,7 @@ namespace OpenRA.Editor
this.tabPage2.Location = new System.Drawing.Point(4, 20);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(190, 552);
this.tabPage2.Size = new System.Drawing.Size(190, 514);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Actors";
this.tabPage2.UseVisualStyleBackColor = true;
@@ -202,7 +244,7 @@ namespace OpenRA.Editor
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(3, 24);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(184, 525);
this.panel1.Size = new System.Drawing.Size(184, 487);
this.panel1.TabIndex = 4;
//
// actorPalette
@@ -212,7 +254,7 @@ namespace OpenRA.Editor
this.actorPalette.Dock = System.Windows.Forms.DockStyle.Fill;
this.actorPalette.Location = new System.Drawing.Point(0, 0);
this.actorPalette.Name = "actorPalette";
this.actorPalette.Size = new System.Drawing.Size(184, 525);
this.actorPalette.Size = new System.Drawing.Size(184, 487);
this.actorPalette.TabIndex = 3;
//
// actorOwnerChooser
@@ -233,7 +275,7 @@ namespace OpenRA.Editor
this.tabPage3.Controls.Add(this.resourcePalette);
this.tabPage3.Location = new System.Drawing.Point(4, 20);
this.tabPage3.Name = "tabPage3";
this.tabPage3.Size = new System.Drawing.Size(190, 552);
this.tabPage3.Size = new System.Drawing.Size(190, 514);
this.tabPage3.TabIndex = 2;
this.tabPage3.Text = "Resources";
this.tabPage3.UseVisualStyleBackColor = true;
@@ -245,7 +287,7 @@ namespace OpenRA.Editor
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(190, 552);
this.resourcePalette.Size = new System.Drawing.Size(190, 514);
this.resourcePalette.TabIndex = 3;
//
// surface1
@@ -254,7 +296,7 @@ namespace OpenRA.Editor
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, 744);
this.surface1.Size = new System.Drawing.Size(783, 695);
this.surface1.TabIndex = 5;
this.surface1.Text = "surface1";
//
@@ -273,24 +315,193 @@ namespace OpenRA.Editor
//
// splitContainer3.Panel1
//
this.splitContainer3.Panel1.Controls.Add(this.menuStrip1);
this.splitContainer3.Panel1.Controls.Add(this.toolStrip1);
//
// splitContainer3.Panel2
//
this.splitContainer3.Panel2.Controls.Add(this.splitContainer1);
this.splitContainer3.Size = new System.Drawing.Size(985, 773);
this.splitContainer3.Size = new System.Drawing.Size(985, 724);
this.splitContainer3.SplitterDistance = 25;
this.splitContainer3.TabIndex = 6;
//
// toolStrip1
//
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripMenuItemNew,
this.toolStripMenuItemOpen,
this.toolStripMenuItemSave,
this.toolStripSeparator,
this.toolStripMenuItemProperties,
this.toolStripMenuItemResize,
this.toolStripSeparator8,
this.toolStripMenuItemShowActorNames,
this.toolStripMenuItemShowGrid,
this.toolStripSeparator10,
this.toolStripMenuItemFixOpenAreas,
this.toolStripMenuItemSetupDefaultPlayers,
this.toolStripSeparator11,
this.toolStripMenuItemCopySelection,
this.toolStripSeparator7,
this.QuickhelpToolStripButton});
this.toolStrip1.Location = new System.Drawing.Point(0, 0);
this.toolStrip1.Name = "toolStrip1";
this.toolStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional;
this.toolStrip1.Size = new System.Drawing.Size(985, 25);
this.toolStrip1.TabIndex = 0;
this.toolStrip1.Text = "toolStrip1";
//
// toolStripMenuItemNew
//
this.toolStripMenuItemNew.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolStripMenuItemNew.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItemNew.Image")));
this.toolStripMenuItemNew.ImageTransparentColor = System.Drawing.Color.Fuchsia;
this.toolStripMenuItemNew.Name = "toolStripMenuItemNew";
this.toolStripMenuItemNew.Size = new System.Drawing.Size(23, 22);
this.toolStripMenuItemNew.Text = "&New...";
this.toolStripMenuItemNew.ToolTipText = "Create a new blank map.";
this.toolStripMenuItemNew.Click += new System.EventHandler(this.toolStripMenuItemNewClick);
//
// toolStripMenuItemOpen
//
this.toolStripMenuItemOpen.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolStripMenuItemOpen.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItemOpen.Image")));
this.toolStripMenuItemOpen.Name = "toolStripMenuItemOpen";
this.toolStripMenuItemOpen.Size = new System.Drawing.Size(23, 22);
this.toolStripMenuItemOpen.Text = "&Open...";
this.toolStripMenuItemOpen.ToolTipText = "Open an existing map.";
this.toolStripMenuItemOpen.Click += new System.EventHandler(this.toolStripMenuItemOpenClick);
//
// toolStripMenuItemSave
//
this.toolStripMenuItemSave.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolStripMenuItemSave.Enabled = false;
this.toolStripMenuItemSave.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItemSave.Image")));
this.toolStripMenuItemSave.Name = "toolStripMenuItemSave";
this.toolStripMenuItemSave.Size = new System.Drawing.Size(23, 22);
this.toolStripMenuItemSave.Text = "&Save";
this.toolStripMenuItemSave.ToolTipText = "Quicksave current map.";
this.toolStripMenuItemSave.Click += new System.EventHandler(this.toolStripMenuItemSaveClick);
//
// toolStripSeparator
//
this.toolStripSeparator.Name = "toolStripSeparator";
this.toolStripSeparator.Size = new System.Drawing.Size(6, 25);
//
// toolStripMenuItemProperties
//
this.toolStripMenuItemProperties.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolStripMenuItemProperties.Enabled = false;
this.toolStripMenuItemProperties.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItemProperties.Image")));
this.toolStripMenuItemProperties.Name = "toolStripMenuItemProperties";
this.toolStripMenuItemProperties.Size = new System.Drawing.Size(23, 22);
this.toolStripMenuItemProperties.Text = "&Properties...";
this.toolStripMenuItemProperties.ToolTipText = "Edit Metadata";
this.toolStripMenuItemProperties.Click += new System.EventHandler(this.toolStripMenuItemPropertiesClick);
//
// toolStripMenuItemResize
//
this.toolStripMenuItemResize.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolStripMenuItemResize.Enabled = false;
this.toolStripMenuItemResize.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItemResize.Image")));
this.toolStripMenuItemResize.Name = "toolStripMenuItemResize";
this.toolStripMenuItemResize.Size = new System.Drawing.Size(23, 22);
this.toolStripMenuItemResize.Text = "&Resize...";
this.toolStripMenuItemResize.ToolTipText = "Change the map borders and dimensions.";
this.toolStripMenuItemResize.Click += new System.EventHandler(this.toolStripMenuItemResizeClick);
//
// toolStripSeparator8
//
this.toolStripSeparator8.Name = "toolStripSeparator8";
this.toolStripSeparator8.Size = new System.Drawing.Size(6, 25);
//
// toolStripMenuItemShowActorNames
//
this.toolStripMenuItemShowActorNames.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolStripMenuItemShowActorNames.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItemShowActorNames.Image")));
this.toolStripMenuItemShowActorNames.Name = "toolStripMenuItemShowActorNames";
this.toolStripMenuItemShowActorNames.Size = new System.Drawing.Size(23, 22);
this.toolStripMenuItemShowActorNames.Text = "Show Actor &Names";
this.toolStripMenuItemShowActorNames.ToolTipText = "If the actor has a custom name, display it.";
this.toolStripMenuItemShowActorNames.Click += new System.EventHandler(this.toolStripMenuItemShowActorNamesClick);
//
// toolStripMenuItemShowGrid
//
this.toolStripMenuItemShowGrid.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolStripMenuItemShowGrid.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItemShowGrid.Image")));
this.toolStripMenuItemShowGrid.Name = "toolStripMenuItemShowGrid";
this.toolStripMenuItemShowGrid.Size = new System.Drawing.Size(23, 22);
this.toolStripMenuItemShowGrid.Text = "Show &Grid";
this.toolStripMenuItemShowGrid.ToolTipText = "Enable a grid overlay for better orientation.";
this.toolStripMenuItemShowGrid.Click += new System.EventHandler(this.toolStripMenuItemShowGridClick);
//
// toolStripSeparator10
//
this.toolStripSeparator10.Name = "toolStripSeparator10";
this.toolStripSeparator10.Size = new System.Drawing.Size(6, 25);
//
// toolStripMenuItemFixOpenAreas
//
this.toolStripMenuItemFixOpenAreas.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolStripMenuItemFixOpenAreas.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItemFixOpenAreas.Image")));
this.toolStripMenuItemFixOpenAreas.Name = "toolStripMenuItemFixOpenAreas";
this.toolStripMenuItemFixOpenAreas.Size = new System.Drawing.Size(23, 22);
this.toolStripMenuItemFixOpenAreas.Text = "&Fix Open Areas";
this.toolStripMenuItemFixOpenAreas.ToolTipText = "Add some randomness into clear tiles.";
this.toolStripMenuItemFixOpenAreas.Click += new System.EventHandler(this.toolStripMenuItemFixOpenAreasClick);
//
// toolStripMenuItemSetupDefaultPlayers
//
this.toolStripMenuItemSetupDefaultPlayers.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolStripMenuItemSetupDefaultPlayers.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItemSetupDefaultPlayers.Image")));
this.toolStripMenuItemSetupDefaultPlayers.Name = "toolStripMenuItemSetupDefaultPlayers";
this.toolStripMenuItemSetupDefaultPlayers.Size = new System.Drawing.Size(23, 22);
this.toolStripMenuItemSetupDefaultPlayers.Text = "&Setup Default Players";
this.toolStripMenuItemSetupDefaultPlayers.ToolTipText = "Setup the players for each spawnpoint placed.";
this.toolStripMenuItemSetupDefaultPlayers.Click += new System.EventHandler(this.toolStripMenuItemSetupDefaultPlayersClick);
//
// toolStripSeparator11
//
this.toolStripSeparator11.Name = "toolStripSeparator11";
this.toolStripSeparator11.Size = new System.Drawing.Size(6, 25);
//
// toolStripMenuItemCopySelection
//
this.toolStripMenuItemCopySelection.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolStripMenuItemCopySelection.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItemCopySelection.Image")));
this.toolStripMenuItemCopySelection.Name = "toolStripMenuItemCopySelection";
this.toolStripMenuItemCopySelection.Size = new System.Drawing.Size(23, 22);
this.toolStripMenuItemCopySelection.Text = "Copy Selection";
this.toolStripMenuItemCopySelection.ToolTipText = "Copy the current selection and paste it again on left-click.";
this.toolStripMenuItemCopySelection.Click += new System.EventHandler(this.toolStripMenuItemCopySelectionClick);
//
// toolStripSeparator7
//
this.toolStripSeparator7.Name = "toolStripSeparator7";
this.toolStripSeparator7.Size = new System.Drawing.Size(6, 25);
//
// QuickhelpToolStripButton
//
this.QuickhelpToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.QuickhelpToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("QuickhelpToolStripButton.Image")));
this.QuickhelpToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
this.QuickhelpToolStripButton.Name = "QuickhelpToolStripButton";
this.QuickhelpToolStripButton.Size = new System.Drawing.Size(23, 22);
this.QuickhelpToolStripButton.Text = "Help";
this.QuickhelpToolStripButton.ToolTipText = "Display the mapping tutorial in the OpenRA wiki.";
this.QuickhelpToolStripButton.Click += new System.EventHandler(this.helpToolStripButton_Click);
//
// menuStrip1
//
this.menuStrip1.Dock = System.Windows.Forms.DockStyle.None;
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.mapToolStripMenuItem,
this.toolStripComboBox1,
this.toolStripLabel1});
this.fileToolStripMenuItem,
this.mapToolStripMenuItem,
this.toolStripComboBox1,
this.toolStripLabel1,
this.helpToolStripMenuItem});
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional;
this.menuStrip1.Size = new System.Drawing.Size(985, 27);
this.menuStrip1.TabIndex = 1;
this.menuStrip1.Text = "menuStrip1";
@@ -298,16 +509,16 @@ namespace OpenRA.Editor
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.newToolStripMenuItem,
this.toolStripSeparator1,
this.openToolStripMenuItem,
this.saveToolStripMenuItem,
this.saveAsToolStripMenuItem,
this.toolStripSeparator2,
this.toolStripMenuItem1,
this.mnuExport,
this.toolStripSeparator3,
this.exitToolStripMenuItem});
this.newToolStripMenuItem,
this.toolStripSeparator1,
this.openToolStripMenuItem,
this.saveToolStripMenuItem,
this.saveAsToolStripMenuItem,
this.toolStripSeparator2,
this.toolStripMenuItem1,
this.mnuExport,
this.toolStripSeparator3,
this.exitToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 23);
this.fileToolStripMenuItem.Text = "&File";
@@ -317,21 +528,23 @@ namespace OpenRA.Editor
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(123, 22);
this.newToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.newToolStripMenuItem.Text = "&New...";
this.newToolStripMenuItem.ToolTipText = "Create a new blank map.";
this.newToolStripMenuItem.Click += new System.EventHandler(this.NewClicked);
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(120, 6);
this.toolStripSeparator1.Size = new System.Drawing.Size(149, 6);
//
// openToolStripMenuItem
//
this.openToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("openToolStripMenuItem.Image")));
this.openToolStripMenuItem.Name = "openToolStripMenuItem";
this.openToolStripMenuItem.Size = new System.Drawing.Size(123, 22);
this.openToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.openToolStripMenuItem.Text = "&Open...";
this.openToolStripMenuItem.ToolTipText = "Open an existing map.";
this.openToolStripMenuItem.Click += new System.EventHandler(this.OpenClicked);
//
// saveToolStripMenuItem
@@ -339,54 +552,54 @@ namespace OpenRA.Editor
this.saveToolStripMenuItem.Enabled = false;
this.saveToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("saveToolStripMenuItem.Image")));
this.saveToolStripMenuItem.Name = "saveToolStripMenuItem";
this.saveToolStripMenuItem.Size = new System.Drawing.Size(123, 22);
this.saveToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.saveToolStripMenuItem.Text = "&Save";
this.saveToolStripMenuItem.ToolTipText = "Quicksave current map.";
this.saveToolStripMenuItem.Click += new System.EventHandler(this.SaveClicked);
//
// saveAsToolStripMenuItem
//
this.saveAsToolStripMenuItem.Enabled = false;
this.saveAsToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("saveAsToolStripMenuItem.Image")));
this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem";
this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(123, 22);
this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.saveAsToolStripMenuItem.Text = "Save &As...";
this.saveAsToolStripMenuItem.ToolTipText = "Save the map while choosing a filename.";
this.saveAsToolStripMenuItem.Click += new System.EventHandler(this.SaveAsClicked);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(120, 6);
this.toolStripSeparator2.Size = new System.Drawing.Size(149, 6);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.cCRedAlertMapToolStripMenuItem,
this.bitmapToolStripMenuItem});
this.cCRedAlertMapToolStripMenuItem});
this.toolStripMenuItem1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem1.Image")));
this.toolStripMenuItem1.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(123, 22);
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.Size = new System.Drawing.Size(188, 22);
this.cCRedAlertMapToolStripMenuItem.Text = "&Legacy Map Format...";
this.cCRedAlertMapToolStripMenuItem.ToolTipText = "Import an original C&C / Red Alert and convert it to the .oramap format.";
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...";
this.bitmapToolStripMenuItem.Visible = false;
//
// mnuExport
//
this.mnuExport.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuMinimapToPNG});
this.mnuMinimapToPNG,
this.fullMapRenderToolStripMenuItem});
this.mnuExport.Image = ((System.Drawing.Image)(resources.GetObject("mnuExport.Image")));
this.mnuExport.ImageTransparentColor = System.Drawing.Color.Magenta;
this.mnuExport.Name = "mnuExport";
this.mnuExport.Size = new System.Drawing.Size(123, 22);
this.mnuExport.Size = new System.Drawing.Size(152, 22);
this.mnuExport.Text = "&Export";
//
// mnuMinimapToPNG
@@ -396,29 +609,45 @@ namespace OpenRA.Editor
this.mnuMinimapToPNG.Name = "mnuMinimapToPNG";
this.mnuMinimapToPNG.Size = new System.Drawing.Size(163, 22);
this.mnuMinimapToPNG.Text = "Minimap to PNG";
this.mnuMinimapToPNG.ToolTipText = "Save the map radar display as an image.";
this.mnuMinimapToPNG.Click += new System.EventHandler(this.ExportMinimap);
//
// fullMapRenderToolStripMenuItem
//
this.fullMapRenderToolStripMenuItem.Enabled = false;
this.fullMapRenderToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("fullMapRenderToolStripMenuItem.Image")));
this.fullMapRenderToolStripMenuItem.Name = "fullMapRenderToolStripMenuItem";
this.fullMapRenderToolStripMenuItem.Size = new System.Drawing.Size(163, 22);
this.fullMapRenderToolStripMenuItem.Text = "Full Map Render";
//
// toolStripSeparator3
//
this.toolStripSeparator3.Name = "toolStripSeparator3";
this.toolStripSeparator3.Size = new System.Drawing.Size(120, 6);
this.toolStripSeparator3.Size = new System.Drawing.Size(149, 6);
//
// exitToolStripMenuItem
//
this.exitToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("exitToolStripMenuItem.Image")));
this.exitToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta;
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
this.exitToolStripMenuItem.Size = new System.Drawing.Size(123, 22);
this.exitToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.exitToolStripMenuItem.Text = "E&xit";
this.exitToolStripMenuItem.ToolTipText = "Quit the map editor.";
this.exitToolStripMenuItem.Click += new System.EventHandler(this.CloseClicked);
//
// mapToolStripMenuItem
//
this.mapToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.propertiesToolStripMenuItem,
this.resizeToolStripMenuItem,
this.showActorNamesToolStripMenuItem,
this.showGridToolStripMenuItem,
this.fixOpenAreasToolStripMenuItem,
this.setupDefaultPlayersMenuItem});
this.propertiesToolStripMenuItem,
this.resizeToolStripMenuItem,
this.toolStripSeparator9,
this.showActorNamesToolStripMenuItem,
this.showGridToolStripMenuItem,
this.toolStripSeparator5,
this.fixOpenAreasToolStripMenuItem,
this.setupDefaultPlayersMenuItem,
this.toolStripSeparator4,
this.copySelectionToolStripMenuItem});
this.mapToolStripMenuItem.Name = "mapToolStripMenuItem";
this.mapToolStripMenuItem.Size = new System.Drawing.Size(43, 23);
this.mapToolStripMenuItem.Text = "&Map";
@@ -430,6 +659,7 @@ namespace OpenRA.Editor
this.propertiesToolStripMenuItem.Name = "propertiesToolStripMenuItem";
this.propertiesToolStripMenuItem.Size = new System.Drawing.Size(185, 22);
this.propertiesToolStripMenuItem.Text = "&Properties...";
this.propertiesToolStripMenuItem.ToolTipText = "Edit Metadata";
this.propertiesToolStripMenuItem.Click += new System.EventHandler(this.PropertiesClicked);
//
// resizeToolStripMenuItem
@@ -439,36 +669,69 @@ namespace OpenRA.Editor
this.resizeToolStripMenuItem.Name = "resizeToolStripMenuItem";
this.resizeToolStripMenuItem.Size = new System.Drawing.Size(185, 22);
this.resizeToolStripMenuItem.Text = "&Resize...";
this.resizeToolStripMenuItem.ToolTipText = "Change the map borders and dimensions.";
this.resizeToolStripMenuItem.Click += new System.EventHandler(this.ResizeClicked);
//
// toolStripSeparator9
//
this.toolStripSeparator9.Name = "toolStripSeparator9";
this.toolStripSeparator9.Size = new System.Drawing.Size(182, 6);
//
// showActorNamesToolStripMenuItem
//
this.showActorNamesToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("showActorNamesToolStripMenuItem.Image")));
this.showActorNamesToolStripMenuItem.Name = "showActorNamesToolStripMenuItem";
this.showActorNamesToolStripMenuItem.Size = new System.Drawing.Size(185, 22);
this.showActorNamesToolStripMenuItem.Text = "Show Actor &Names";
this.showActorNamesToolStripMenuItem.Text = "Show &Actor Names";
this.showActorNamesToolStripMenuItem.ToolTipText = "If the actor has a custom name, display it.";
this.showActorNamesToolStripMenuItem.Click += new System.EventHandler(this.ShowActorNamesClicked);
//
// showGridToolStripMenuItem
//
this.showGridToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("showGridToolStripMenuItem.Image")));
this.showGridToolStripMenuItem.Name = "showGridToolStripMenuItem";
this.showGridToolStripMenuItem.Size = new System.Drawing.Size(185, 22);
this.showGridToolStripMenuItem.Text = "Show &Grid";
this.showGridToolStripMenuItem.ToolTipText = "Enable a grid overlay for better orientation.";
this.showGridToolStripMenuItem.Click += new System.EventHandler(this.ShowGridClicked);
//
// toolStripSeparator5
//
this.toolStripSeparator5.Name = "toolStripSeparator5";
this.toolStripSeparator5.Size = new System.Drawing.Size(182, 6);
//
// fixOpenAreasToolStripMenuItem
//
this.fixOpenAreasToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("fixOpenAreasToolStripMenuItem.Image")));
this.fixOpenAreasToolStripMenuItem.Name = "fixOpenAreasToolStripMenuItem";
this.fixOpenAreasToolStripMenuItem.Size = new System.Drawing.Size(185, 22);
this.fixOpenAreasToolStripMenuItem.Text = "&Fix Open Areas";
this.fixOpenAreasToolStripMenuItem.ToolTipText = "Add some randomness into clear tiles.";
this.fixOpenAreasToolStripMenuItem.Click += new System.EventHandler(this.FixOpenAreas);
//
// setupDefaultPlayersMenuItem
//
this.setupDefaultPlayersMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("setupDefaultPlayersMenuItem.Image")));
this.setupDefaultPlayersMenuItem.Name = "setupDefaultPlayersMenuItem";
this.setupDefaultPlayersMenuItem.Size = new System.Drawing.Size(185, 22);
this.setupDefaultPlayersMenuItem.Text = "&Setup Default Players";
this.setupDefaultPlayersMenuItem.ToolTipText = "Setup the players for each spawnpoint placed.";
this.setupDefaultPlayersMenuItem.Click += new System.EventHandler(this.SetupDefaultPlayers);
//
// toolStripSeparator4
//
this.toolStripSeparator4.Name = "toolStripSeparator4";
this.toolStripSeparator4.Size = new System.Drawing.Size(182, 6);
//
// copySelectionToolStripMenuItem
//
this.copySelectionToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("copySelectionToolStripMenuItem.Image")));
this.copySelectionToolStripMenuItem.Name = "copySelectionToolStripMenuItem";
this.copySelectionToolStripMenuItem.Size = new System.Drawing.Size(185, 22);
this.copySelectionToolStripMenuItem.Text = "Copy Selection";
this.copySelectionToolStripMenuItem.ToolTipText = "Copy the current selection and paste it again on left-click.";
this.copySelectionToolStripMenuItem.Click += new System.EventHandler(this.copySelectionToolStripMenuItemClick);
//
// toolStripComboBox1
//
this.toolStripComboBox1.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
@@ -479,16 +742,114 @@ namespace OpenRA.Editor
// toolStripLabel1
//
this.toolStripLabel1.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
this.toolStripLabel1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripLabel1.Image")));
this.toolStripLabel1.Name = "toolStripLabel1";
this.toolStripLabel1.Size = new System.Drawing.Size(71, 20);
this.toolStripLabel1.Size = new System.Drawing.Size(87, 20);
this.toolStripLabel1.Text = "Active Mod:";
this.toolStripLabel1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.toolStripLabel1.TextDirection = System.Windows.Forms.ToolStripTextDirection.Horizontal;
this.toolStripLabel1.ToolTipText = "Choose the OpenRA mod whose tilesets and actors shall be used.";
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.openRAWebsiteToolStripMenuItem,
this.openRAResourcesToolStripMenuItem,
this.wikiDocumentationToolStripMenuItem,
this.discussionForumsToolStripMenuItem,
this.sourceCodeToolStripMenuItem,
this.issueTrackerToolStripMenuItem,
this.developerBountiesToolStripMenuItem,
this.toolStripSeparator6,
this.aboutToolStripMenuItem});
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 23);
this.helpToolStripMenuItem.Text = "&Help";
//
// openRAWebsiteToolStripMenuItem
//
this.openRAWebsiteToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("openRAWebsiteToolStripMenuItem.Image")));
this.openRAWebsiteToolStripMenuItem.Name = "openRAWebsiteToolStripMenuItem";
this.openRAWebsiteToolStripMenuItem.Size = new System.Drawing.Size(183, 22);
this.openRAWebsiteToolStripMenuItem.Text = "OpenRA &Website";
this.openRAWebsiteToolStripMenuItem.ToolTipText = "Visit the OpenRA homepage.";
this.openRAWebsiteToolStripMenuItem.Click += new System.EventHandler(this.openRAWebsiteToolStripMenuItemClick);
//
// openRAResourcesToolStripMenuItem
//
this.openRAResourcesToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("openRAResourcesToolStripMenuItem.Image")));
this.openRAResourcesToolStripMenuItem.Name = "openRAResourcesToolStripMenuItem";
this.openRAResourcesToolStripMenuItem.Size = new System.Drawing.Size(183, 22);
this.openRAResourcesToolStripMenuItem.Text = "OpenRA &Resources";
this.openRAResourcesToolStripMenuItem.ToolTipText = "Share your maps and replays by uploading on this file exchange community.";
this.openRAResourcesToolStripMenuItem.Click += new System.EventHandler(this.openRAResourcesToolStripMenuItemClick);
//
// wikiDocumentationToolStripMenuItem
//
this.wikiDocumentationToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("wikiDocumentationToolStripMenuItem.Image")));
this.wikiDocumentationToolStripMenuItem.Name = "wikiDocumentationToolStripMenuItem";
this.wikiDocumentationToolStripMenuItem.Size = new System.Drawing.Size(183, 22);
this.wikiDocumentationToolStripMenuItem.Text = "Wiki &Documentation";
this.wikiDocumentationToolStripMenuItem.ToolTipText = "Read and contribute to the developer documentation.";
this.wikiDocumentationToolStripMenuItem.Click += new System.EventHandler(this.wikiDocumentationToolStripMenuItemClick);
//
// discussionForumsToolStripMenuItem
//
this.discussionForumsToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("discussionForumsToolStripMenuItem.Image")));
this.discussionForumsToolStripMenuItem.Name = "discussionForumsToolStripMenuItem";
this.discussionForumsToolStripMenuItem.Size = new System.Drawing.Size(183, 22);
this.discussionForumsToolStripMenuItem.Text = "Discussion &Forums";
this.discussionForumsToolStripMenuItem.ToolTipText = "Discuss OpenRA related matters in a bulletin board forum.";
this.discussionForumsToolStripMenuItem.Click += new System.EventHandler(this.discussionForumsToolStripMenuItemClick);
//
// sourceCodeToolStripMenuItem
//
this.sourceCodeToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("sourceCodeToolStripMenuItem.Image")));
this.sourceCodeToolStripMenuItem.Name = "sourceCodeToolStripMenuItem";
this.sourceCodeToolStripMenuItem.Size = new System.Drawing.Size(183, 22);
this.sourceCodeToolStripMenuItem.Text = "Source &Code";
this.sourceCodeToolStripMenuItem.ToolTipText = "Browse and download the source code. Fix what annoys you. Patches are welcome.";
this.sourceCodeToolStripMenuItem.Click += new System.EventHandler(this.sourceCodeToolStripMenuItemClick);
//
// issueTrackerToolStripMenuItem
//
this.issueTrackerToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("issueTrackerToolStripMenuItem.Image")));
this.issueTrackerToolStripMenuItem.Name = "issueTrackerToolStripMenuItem";
this.issueTrackerToolStripMenuItem.Size = new System.Drawing.Size(183, 22);
this.issueTrackerToolStripMenuItem.Text = "Issue &Tracker";
this.issueTrackerToolStripMenuItem.ToolTipText = "Report problems and request features.";
this.issueTrackerToolStripMenuItem.Click += new System.EventHandler(this.issueTrackerToolStripMenuItemClick);
//
// developerBountiesToolStripMenuItem
//
this.developerBountiesToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("developerBountiesToolStripMenuItem.Image")));
this.developerBountiesToolStripMenuItem.Name = "developerBountiesToolStripMenuItem";
this.developerBountiesToolStripMenuItem.Size = new System.Drawing.Size(183, 22);
this.developerBountiesToolStripMenuItem.Text = "Developer &Bounties";
this.developerBountiesToolStripMenuItem.ToolTipText = "Hire a developer to get OpenRA modified to your wishes.";
this.developerBountiesToolStripMenuItem.Click += new System.EventHandler(this.developerBountiesToolStripMenuItemClick);
//
// toolStripSeparator6
//
this.toolStripSeparator6.Name = "toolStripSeparator6";
this.toolStripSeparator6.Size = new System.Drawing.Size(180, 6);
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("aboutToolStripMenuItem.Image")));
this.aboutToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta;
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(183, 22);
this.aboutToolStripMenuItem.Text = "&About";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItemClick);
//
// statusStrip1
//
this.statusStrip1.Dock = System.Windows.Forms.DockStyle.None;
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripStatusLabelFiller,
this.toolStripStatusLabelMousePosition});
this.statusStrip1.Location = new System.Drawing.Point(0, 751);
this.toolStripStatusLabelFiller,
this.toolStripStatusLabelMousePosition});
this.statusStrip1.Location = new System.Drawing.Point(0, 0);
this.statusStrip1.Name = "statusStrip1";
this.statusStrip1.Size = new System.Drawing.Size(985, 22);
this.statusStrip1.TabIndex = 7;
@@ -497,32 +858,95 @@ namespace OpenRA.Editor
// toolStripStatusLabelFiller
//
this.toolStripStatusLabelFiller.Name = "toolStripStatusLabelFiller";
this.toolStripStatusLabelFiller.Size = new System.Drawing.Size(948, 17);
this.toolStripStatusLabelFiller.Size = new System.Drawing.Size(932, 17);
this.toolStripStatusLabelFiller.Spring = true;
//
// toolStripStatusLabelMousePosition
//
this.toolStripStatusLabelMousePosition.Image = ((System.Drawing.Image)(resources.GetObject("toolStripStatusLabelMousePosition.Image")));
this.toolStripStatusLabelMousePosition.Name = "toolStripStatusLabelMousePosition";
this.toolStripStatusLabelMousePosition.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
this.toolStripStatusLabelMousePosition.Size = new System.Drawing.Size(22, 17);
this.toolStripStatusLabelMousePosition.RightToLeft = System.Windows.Forms.RightToLeft.No;
this.toolStripStatusLabelMousePosition.Size = new System.Drawing.Size(38, 17);
this.toolStripStatusLabelMousePosition.Text = "0,0";
//
// BottomToolStripPanel
//
this.BottomToolStripPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
this.BottomToolStripPanel.Location = new System.Drawing.Point(0, 25);
this.BottomToolStripPanel.Name = "BottomToolStripPanel";
this.BottomToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
this.BottomToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.BottomToolStripPanel.Size = new System.Drawing.Size(985, 0);
//
// TopToolStripPanel
//
this.TopToolStripPanel.Dock = System.Windows.Forms.DockStyle.Top;
this.TopToolStripPanel.Location = new System.Drawing.Point(0, 0);
this.TopToolStripPanel.Name = "TopToolStripPanel";
this.TopToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
this.TopToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.TopToolStripPanel.Size = new System.Drawing.Size(985, 0);
//
// RightToolStripPanel
//
this.RightToolStripPanel.Dock = System.Windows.Forms.DockStyle.Right;
this.RightToolStripPanel.Location = new System.Drawing.Point(985, 0);
this.RightToolStripPanel.Name = "RightToolStripPanel";
this.RightToolStripPanel.Orientation = System.Windows.Forms.Orientation.Vertical;
this.RightToolStripPanel.RowMargin = new System.Windows.Forms.Padding(0, 3, 0, 0);
this.RightToolStripPanel.Size = new System.Drawing.Size(0, 25);
//
// LeftToolStripPanel
//
this.LeftToolStripPanel.Dock = System.Windows.Forms.DockStyle.Left;
this.LeftToolStripPanel.Location = new System.Drawing.Point(0, 0);
this.LeftToolStripPanel.Name = "LeftToolStripPanel";
this.LeftToolStripPanel.Orientation = System.Windows.Forms.Orientation.Vertical;
this.LeftToolStripPanel.RowMargin = new System.Windows.Forms.Padding(0, 3, 0, 0);
this.LeftToolStripPanel.Size = new System.Drawing.Size(0, 25);
//
// ContentPanel
//
this.ContentPanel.Size = new System.Drawing.Size(985, 25);
//
// toolStripContainer1
//
//
// toolStripContainer1.BottomToolStripPanel
//
this.toolStripContainer1.BottomToolStripPanel.Controls.Add(this.statusStrip1);
//
// toolStripContainer1.ContentPanel
//
this.toolStripContainer1.ContentPanel.AutoScroll = true;
this.toolStripContainer1.ContentPanel.Controls.Add(this.splitContainer3);
this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size(985, 724);
this.toolStripContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.toolStripContainer1.Location = new System.Drawing.Point(0, 0);
this.toolStripContainer1.Name = "toolStripContainer1";
this.toolStripContainer1.Size = new System.Drawing.Size(985, 773);
this.toolStripContainer1.TabIndex = 8;
this.toolStripContainer1.Text = "toolStripContainer1";
//
// toolStripContainer1.TopToolStripPanel
//
this.toolStripContainer1.TopToolStripPanel.Controls.Add(this.menuStrip1);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(985, 773);
this.Controls.Add(this.statusStrip1);
this.Controls.Add(this.splitContainer3);
this.Controls.Add(this.toolStripContainer1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.KeyPreview = true;
this.MainMenuStrip = this.menuStrip1;
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
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.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyUp);
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel2.ResumeLayout(false);
this.splitContainer1.ResumeLayout(false);
@@ -539,12 +963,20 @@ namespace OpenRA.Editor
this.splitContainer3.Panel1.PerformLayout();
this.splitContainer3.Panel2.ResumeLayout(false);
this.splitContainer3.ResumeLayout(false);
this.toolStrip1.ResumeLayout(false);
this.toolStrip1.PerformLayout();
this.menuStrip1.ResumeLayout(false);
this.menuStrip1.PerformLayout();
this.statusStrip1.ResumeLayout(false);
this.statusStrip1.PerformLayout();
this.toolStripContainer1.BottomToolStripPanel.ResumeLayout(false);
this.toolStripContainer1.BottomToolStripPanel.PerformLayout();
this.toolStripContainer1.ContentPanel.ResumeLayout(false);
this.toolStripContainer1.TopToolStripPanel.ResumeLayout(false);
this.toolStripContainer1.TopToolStripPanel.PerformLayout();
this.toolStripContainer1.ResumeLayout(false);
this.toolStripContainer1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
@@ -575,7 +1007,6 @@ namespace OpenRA.Editor
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem cCRedAlertMapToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem bitmapToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem mnuExport;
private System.Windows.Forms.ToolStripMenuItem mnuMinimapToPNG;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
@@ -592,7 +1023,44 @@ namespace OpenRA.Editor
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.FlowLayoutPanel actorPalette;
private System.Windows.Forms.ComboBox actorOwnerChooser;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator5;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;
private System.Windows.Forms.ToolStripMenuItem copySelectionToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem openRAWebsiteToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem issueTrackerToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem developerBountiesToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem discussionForumsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem wikiDocumentationToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem openRAResourcesToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator6;
private System.Windows.Forms.ToolStripMenuItem sourceCodeToolStripMenuItem;
private System.Windows.Forms.ToolStripContainer toolStripContainer1;
private System.Windows.Forms.ToolStrip toolStrip1;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator7;
private System.Windows.Forms.ToolStripButton QuickhelpToolStripButton;
private System.Windows.Forms.ToolStripPanel BottomToolStripPanel;
private System.Windows.Forms.ToolStripPanel TopToolStripPanel;
private System.Windows.Forms.ToolStripPanel RightToolStripPanel;
private System.Windows.Forms.ToolStripPanel LeftToolStripPanel;
private System.Windows.Forms.ToolStripContentPanel ContentPanel;
private System.Windows.Forms.ToolStripButton toolStripMenuItemNew;
private System.Windows.Forms.ToolStripButton toolStripMenuItemOpen;
private System.Windows.Forms.ToolStripButton toolStripMenuItemSave;
private System.Windows.Forms.ToolStripButton toolStripMenuItemProperties;
private System.Windows.Forms.ToolStripButton toolStripMenuItemResize;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator8;
private System.Windows.Forms.ToolStripButton toolStripMenuItemShowActorNames;
private System.Windows.Forms.ToolStripButton toolStripMenuItemShowGrid;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator10;
private System.Windows.Forms.ToolStripButton toolStripMenuItemFixOpenAreas;
private System.Windows.Forms.ToolStripButton toolStripMenuItemSetupDefaultPlayers;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator11;
private System.Windows.Forms.ToolStripButton toolStripMenuItemCopySelection;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator9;
private System.Windows.Forms.ToolStripMenuItem fullMapRenderToolStripMenuItem;
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2013 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,
@@ -42,14 +42,17 @@ namespace OpenRA.Editor
tilePalette.ResumeLayout();
actorPalette.ResumeLayout();
resourcePalette.ResumeLayout();
surface1.Bind(null, null, null);
surface1.Bind(null, null, null, null);
pmMiniMap.Image = null;
currentMod = toolStripComboBox1.SelectedItem as string;
Text = "OpenRA Editor (mod:{0})".F(currentMod);
Game.modData = new ModData(currentMod);
FileSystem.LoadFromManifest(Game.modData.Manifest);
Rules.LoadRules(Game.modData.Manifest, new Map());
var mod = Game.modData.Manifest.Mods[0];
Text = "{0} Mod Version: {1} - OpenRA Editor".F(Mod.AllMods[mod].Title, Mod.AllMods[mod].Version);
loadedMapName = null;
};
@@ -138,38 +141,67 @@ namespace OpenRA.Editor
Rules.LoadRules(manifest, map);
tileset = Rules.TileSets[map.Tileset];
tileset.LoadTiles();
var palette = new Palette(FileSystem.Open(tileset.Palette), true);
int[] ShadowIndex = { 3, 4 };
var palette = new Palette(FileSystem.Open(tileset.Palette), ShadowIndex);
surface1.Bind(map, tileset, palette);
// required for desert terrain in RA
var playerPalette = tileset.PlayerPalette ?? tileset.Palette;
var PlayerPalette = new Palette(FileSystem.Open(playerPalette), ShadowIndex);
surface1.Bind(map, tileset, palette, PlayerPalette);
// construct the palette of tiles
var palettes = new[] { tilePalette, actorPalette, resourcePalette };
foreach (var p in palettes) { p.Visible = false; p.SuspendLayout(); }
foreach (var t in tileset.Templates)
string[] templateOrder = tileset.EditorTemplateOrder ?? new string[]{};
foreach (var tc in tileset.Templates.GroupBy(t => t.Value.Category).OrderBy(t => templateOrder.ToList().IndexOf(t.Key)))
{
try
var category = tc.Key ?? "(Uncategorized)";
var categoryHeader = new Label
{
var bitmap = tileset.RenderTemplate((ushort)t.Key, palette);
var ibox = new PictureBox
BackColor = SystemColors.Highlight,
ForeColor = SystemColors.HighlightText,
Text = category,
AutoSize = false,
Height = 24,
TextAlign = ContentAlignment.MiddleLeft,
Width = tilePalette.ClientSize.Width,
};
// hook this manually, anchoring inside FlowLayoutPanel is flaky.
tilePalette.Resize += (_,e) => categoryHeader.Width = tilePalette.ClientSize.Width;
if (tilePalette.Controls.Count > 0)
tilePalette.SetFlowBreak(
tilePalette.Controls[tilePalette.Controls.Count - 1], true);
tilePalette.Controls.Add(categoryHeader);
foreach( var t in tc )
{
try
{
Image = bitmap,
Width = bitmap.Width / 2,
Height = bitmap.Height / 2,
SizeMode = PictureBoxSizeMode.StretchImage
};
var brushTemplate = new BrushTemplate { Bitmap = bitmap, N = t.Key };
ibox.Click += (_, e) => surface1.SetTool(new BrushTool(brushTemplate));
var template = t.Value;
tilePalette.Controls.Add(ibox);
tt.SetToolTip(ibox,
"{1}:{0} ({2}x{3})".F(
template.Image,
template.Id,
template.Size.X,
template.Size.Y));
var bitmap = tileset.RenderTemplate((ushort)t.Key, palette);
var ibox = new PictureBox
{
Image = bitmap,
Width = bitmap.Width / 2,
Height = bitmap.Height / 2,
SizeMode = PictureBoxSizeMode.StretchImage
};
var brushTemplate = new BrushTemplate { Bitmap = bitmap, N = t.Key };
ibox.Click += (_, e) => surface1.SetTool(new BrushTool(brushTemplate));
var template = t.Value;
tilePalette.Controls.Add(ibox);
tt.SetToolTip(ibox,
"{1}:{0} ({2}x{3})".F(
template.Image,
template.Id,
template.Size.X,
template.Size.Y));
}
catch { }
}
catch { }
}
var actorTemplates = new List<ActorTemplate>();
@@ -187,7 +219,13 @@ namespace OpenRA.Editor
if (etf != null && etf.RequireTilesets != null
&& !etf.RequireTilesets.Contains(tileset.Id)) continue;
var template = RenderUtils.RenderActor(info, tileset, palette);
var TemplatePalette = PlayerPalette;
var rsi = info.Traits.GetOrDefault<RenderSimpleInfo>();
// exception for desert buildings
if (rsi != null && rsi.Palette != null && rsi.Palette.Contains("terrain"))
TemplatePalette = palette;
var template = RenderUtils.RenderActor(info, tileset, TemplatePalette);
var ibox = new PictureBox
{
Image = template.Bitmap,
@@ -218,7 +256,7 @@ namespace OpenRA.Editor
{
try
{
var template = RenderUtils.RenderResourceType(a, tileset.Extensions, palette);
var template = RenderUtils.RenderResourceType(a, tileset.Extensions, PlayerPalette);
var ibox = new PictureBox
{
Image = template.Bitmap,
@@ -255,10 +293,13 @@ namespace OpenRA.Editor
pmMiniMap.Image = Minimap.AddStaticResources(surface1.Map, Minimap.TerrainBitmap(surface1.Map, true));
propertiesToolStripMenuItem.Enabled = true;
toolStripMenuItemProperties.Enabled = true;
resizeToolStripMenuItem.Enabled = true;
toolStripMenuItemResize.Enabled = true;
saveToolStripMenuItem.Enabled = true;
toolStripMenuItemSave.Enabled = true;
saveAsToolStripMenuItem.Enabled = true;
mnuMinimapToPNG.Enabled = true; // todo: what is this VB naming bullshit doing here?
mnuMinimapToPNG.Enabled = true; // TODO: what is this VB naming bullshit doing here?
PopulateActorOwnerChooser();
}
@@ -293,7 +334,7 @@ namespace OpenRA.Editor
if ((int)rd.width.Value != surface1.Map.MapSize.X || (int)rd.height.Value != surface1.Map.MapSize.Y)
{
surface1.Map.Resize((int)rd.width.Value, (int)rd.height.Value);
surface1.Bind(surface1.Map, surface1.TileSet, surface1.Palette); // rebind it to invalidate all caches
surface1.Bind(surface1.Map, surface1.TileSet, surface1.Palette, surface1.PlayerPalette); // rebind it to invalidate all caches
}
surface1.Invalidate();
@@ -362,6 +403,7 @@ namespace OpenRA.Editor
map.ResizeCordon((int)nmd.cordonLeft.Value, (int)nmd.cordonTop.Value,
(int)nmd.cordonRight.Value, (int)nmd.cordonBottom.Value);
map.Players.Clear();
map.MakeDefaultPlayers();
NewMap(map);
@@ -458,12 +500,14 @@ namespace OpenRA.Editor
void ShowActorNamesClicked(object sender, EventArgs e)
{
showActorNamesToolStripMenuItem.Checked ^= true;
toolStripMenuItemShowActorNames.Checked ^= true;
surface1.ShowActorNames = showActorNamesToolStripMenuItem.Checked;
}
void ShowGridClicked(object sender, EventArgs e)
{
showGridToolStripMenuItem.Checked ^= true;
toolStripMenuItemShowGrid.Checked ^= true;
surface1.ShowGrid = showGridToolStripMenuItem.Checked;
surface1.Chunks.Clear();
}
@@ -491,6 +535,7 @@ namespace OpenRA.Editor
void SetupDefaultPlayers(object sender, EventArgs e)
{
dirty = true;
surface1.Map.Players.Clear();
surface1.Map.MakeDefaultPlayers();
surface1.Chunks.Clear();
@@ -522,5 +567,108 @@ namespace OpenRA.Editor
var player = actorOwnerChooser.SelectedItem as PlayerReference;
surface1.NewActorOwner = player.Name;
}
private void copySelectionToolStripMenuItemClick(object sender, EventArgs e)
{
surface1.CopySelection();
}
private void openRAWebsiteToolStripMenuItemClick(object sender, EventArgs e)
{
System.Diagnostics.Process.Start("http://www.open-ra.org");
}
private void openRAResourcesToolStripMenuItemClick(object sender, EventArgs e)
{
System.Diagnostics.Process.Start("http://content.open-ra.org");
}
private void wikiDocumentationToolStripMenuItemClick(object sender, EventArgs e)
{
System.Diagnostics.Process.Start("http://github.com/OpenRA/OpenRA/wiki");
}
private void discussionForumsToolStripMenuItemClick(object sender, EventArgs e)
{
System.Diagnostics.Process.Start("http://www.sleipnirstuff.com/forum/viewforum.php?f=80");
}
private void issueTrackerToolStripMenuItemClick(object sender, EventArgs e)
{
System.Diagnostics.Process.Start("http://github.com/OpenRA/OpenRA/issues");
}
private void developerBountiesToolStripMenuItemClick(object sender, EventArgs e)
{
System.Diagnostics.Process.Start("https://www.bountysource.com/#repos/OpenRA/OpenRA");
}
private void sourceCodeToolStripMenuItemClick(object sender, EventArgs e)
{
System.Diagnostics.Process.Start("http://github.com/OpenRA/OpenRA");
}
private void aboutToolStripMenuItemClick(object sender, EventArgs e)
{
MessageBox.Show("OpenRA and OpenRA Editor are Free/Libre Open Source Software released under the GNU General Public License version 3. See AUTHORS and COPYING for details.",
"About",
MessageBoxButtons.OK,
MessageBoxIcon.Asterisk);
}
private void helpToolStripButton_Click(object sender, EventArgs e)
{
System.Diagnostics.Process.Start("http://github.com/OpenRA/OpenRA/wiki/Mapping");
}
private void toolStripMenuItemNewClick(object sender, EventArgs e)
{
NewClicked(sender, e);
}
private void toolStripMenuItemOpenClick(object sender, EventArgs e)
{
OpenClicked(sender, e);
}
private void toolStripMenuItemSaveClick(object sender, EventArgs e)
{
SaveClicked(sender, e);
}
private void toolStripMenuItemPropertiesClick(object sender, EventArgs e)
{
PropertiesClicked(sender, e);
}
private void toolStripMenuItemResizeClick(object sender, EventArgs e)
{
ResizeClicked(sender, e);
}
private void toolStripMenuItemShowActorNamesClick(object sender, EventArgs e)
{
ShowActorNamesClicked(sender, e);
}
private void toolStripMenuItemFixOpenAreasClick(object sender, EventArgs e)
{
FixOpenAreas(sender, e);
}
private void toolStripMenuItemSetupDefaultPlayersClick(object sender, EventArgs e)
{
SetupDefaultPlayers(sender, e);
}
private void toolStripMenuItemCopySelectionClick(object sender, EventArgs e)
{
copySelectionToolStripMenuItemClick(sender, e);
}
private void toolStripMenuItemShowGridClick(object sender, EventArgs e)
{
ShowGridClicked(sender, e);
}
}
}

View File

@@ -120,58 +120,230 @@
<metadata name="tt.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="saveFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>76, 17</value>
<metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>429, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="toolStripMenuItemNew.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHPSURBVDhPpZFNTxNRFIb7W1y4NZpI4k/QrRs3rjSu/QMk
NjHGYCFgYYIWsaJidAKoUWqEgFiwGjE2ERREKEOZZtpa23H6OWX6OHN7CQaxNfFNTm5Oct7nnvten6fN
6AV+rPixM/2sTRzGNgKYGz0kF/2IgXayNIXNF8fADJB8fcY9e0lMHqGw3v1vAO9mLAXqMSx9zD2jot/6
cg3l3qSogbvPWViMHwxcVQ+hzZ6maEzgUKCcfSZ6faqDXV0PP6Xj1PmDIWIDMwjVWQHxNhF94ba0Q8/Q
OC8XlgRk/v0+iLU1SCJyFCfdSerNWdcYFBnUjLC0Q9fgQ2HeLWltSotdbP5C6gr6zAkSKzcoa32k435p
B6fR4NbYPENq9E/A7+odfiwte3K9VGp1cmaZ8VerHD957u+AwE1V2vZUtXfIWxW2Mz9Rp5dbA64OPJC2
puz6DmaxRuq7xddkjtHIx9aAy30j0up+huNglWoYuSLftvPE19LcefK2NeBS97AwO06DUsUmky+RSBX4
tJ4ltqQTejTXGtDZFXJDa1CpNkPTDJPPG1neLevMfNBQ7k+3B3iheWl7gXlvDrtrh9Q5lNEpgiOR9k/w
BtqVHP9f+Xy/AI/l932QyhfPAAAAAElFTkSuQmCC
</value>
</data>
<data name="toolStripMenuItemOpen.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAACeUlE
QVQ4T6WSWUiUURiG/4suurJIjUIwskQsEAMjqosQpUVNKbdCSRPKrQVDMddmXEedGdcpFXNGnUYdrSzF
sEIoFInQcqHE1CwoKsXUUMnt6XfEye0munjgnO+c9+HjO0cA/osNi2tJLdA6SXN13MwoI12lJ06uiV8+
W3d5IwIjVXiGKvwX11djSs2TRFlUito7ILIAoVab7SvCWhqrZYq1omXC4gpPe4Ur8AjNMQjo69IwPVZj
4PeojtlhNfoyBXXalKSNBJ5hSjxCcnELzkeoKVcyNVq5Kjz/rZDZnggqSzOoKEpDXZBEcU4id+Sx5Mui
RcdfmVClyWLqh8YYXhDD9MVCT/CGrBPcK5Hx62uxMdxUm2XgiT6Tep2MhxVp6NXJ6IqllKlucTc3niJl
LKqsGINMqChOY+JTnqHtwRYJdZVK5gelMJSymo9ibSAOeiPhXTid1T5cD3IvF9SqZMb7M+CznEdVCtqe
ypcurWz9bQC0ezHX6sr0M0c+lNtx5cKJcVGwXyjJlfDzvZSh1gTqdHIWBiTQHbIU7AwSg+eYa3Nnuvk4
E41HGak9gDTUmvPOZjmGGRQqExjpiuG+NouOl2InvRGi4BJ0+LPw6gwzL04x2XSM0ToHvlfZ0p66FT9X
KxxsTGwMAlVmLN3NiTzQZkJ/IrwR233tzUyLG5PPHRmrP8Sw3o4vmr30yE2RBO/Bfp9Fg/EV8tKjqSnL
oOdxGO3ZgpE2+SaaZZtpSNpCdbw56mgLbt/YhZ/L7oVD9pYuRkF2ShTZksukxwQSd813cbJc9HHm7MnD
OB2x46CdNbZWFljuNGP7NhN2mJqIuRX/YOXm30H4A70P0TsBWkcYAAAAAElFTkSuQmCC
</value>
</data>
<data name="toolStripMenuItemSave.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAACPklE
QVQ4T6WS70uTURTH9y/03jdBL3prU2O4FqvBU66hLB2GFtKvJ9Isfy3TJEXLVHT5A7QVLp20Wk3CiUb+
AH8gJmIsJSs1l7TEoabYRDD4ds99dI9Le1MHzvPi3OfzufeeexQA/iv5p7MjAEp32xpaXat45lhGc5Mf
j6zzqKv9BkuVF/dLZ1BU+Bn5eR+Qkz2OG9c9DN0SENjbA9TWbFDxr7G+sQl9Yi/OJL7iyUISuF6ucEF5
2Q8q7hkE+5fXcdT4GkqlCFOCk8qSwPF0iQuKCr9TcVdsw198K4gwuJF3axanjS20JAlsjQtccNM8TcWQ
2Am/n/LjoOBCZsYk4mJttCwJGup9XJB+bZyKwfgTHvL4EKZ1QBRHYTBY6RdJUFM9xwXi5VEq8tgL7hn5
in3RTUg+24+YmDr6TRJUlM+iuwvsKYGUC29hOjfIu00NozvTsWlnCe5DvOkNBMEiC0qKp9DuBpsBoMX+
i737T5TeW+RNpYbRndNSPUH4VFwbdLoyWXA7fxLO58AT2yYbnAD0SRkhaTxvRtLVAgmOZfBJJ7TaYllg
zplgMFD9IMB3JkjBliLUAsY+LWBiZhFi9l0c17dyWH3MDo2mQBbQWFofInhsEhB8JbcSH71L8M6vIuuO
BZFaO4ObEXnkMdTRubIgLfUdu/cahw/onNh/SMCL9gG4u4bQ3TeCweExnDCYoNQ0IorB4aoGqFSZIYL4
SxcH+HjShNGQ0DvTU1G3qWF0Z9qVkuDDUemy4N8Tit/kKu4LI/ykxwAAAABJRU5ErkJggg==
</value>
</data>
<data name="toolStripMenuItemProperties.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAAB/klE
QVQ4T6WQ30tTUQDHz39QD0UQRlAPIkgPxh6yhCRCykGBL0WZjOytLKdl7KGHJmFYtAjH7uUWy3XvMswf
d3Ou8MdWils1ggZCRQ43lbbAwYpB4vbtnDMzrrsMw4cvB87h8/l+OQTAlqJ7ydL/7MEhGvQ9vQdZ6oLT
boVouwV7t4XFIvkFKMGB0nB23rqeX187kPl0CR/VJi5hsBh9VBo2nzuqgdPh0/gxeRhJXwWs8g3cDDSC
uH0fwKKMvIMyNI6/8DVTPT/bzh7RwAtqOWZdZWjpacZlbwOIMvIe+XweqdSCBo5HLLhqMnK4tfE4YmoV
QsIeeLp240rDXpzpPIXmfiOI7AlzAYMXo3c4PO4fpOdJzAVNXMImHyzfierK7TBU7ELlvh0Pj7XXwOSu
B+kdnsFqLo9kMo7O6xeQSMSQpZ8RDr3hktm+A6gz7IfgGoThxEX6UvgrKjAbb9eCOIemObAx6ZUcpqeC
MJ+vRWQug0B0WSNgoZJt5MnA22L4dw6LmRV8/p6l8E8Oq6FUkYCFSC8CHJKUUThcPg7bJA/uCyq6HcPr
kSeW9AXC84l/zXQ2a/7CmwuzWbNCYdGb0Bc4lLHCAtkPR6+Pw7bHdIGoXWB7GdMX2OXXtHkVS6w5WWie
XGtms0VvnMN33d/0BT2uV/xhsykSbLz4v4D8ATko6xzt+1ySAAAAAElFTkSuQmCC
</value>
</data>
<data name="toolStripMenuItemResize.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAH3SURBVDhPrZJfSFNxFMf3rBk+iIH2oOCTIAlZSGCQPqgIqQ/5tHQpPiikBpIpCnuxYkWCokQg
qDcoNYZETZAhbII0dh92DdPNvJuj4f7epWa2vOvrzg/u8uqQkA4cztPn8/uee4/mv5RxgQfN2Xkbm9zc
EpujUyY2+w0TbJ5ZBL/9sAyCx2cWMcqZYHj5Dv3PJsF/FjE8aUZrH4eWXg7Njzjoeqb+ShU4/iee7MO4
jIB0gPsDI9B2PIYkScmORCK4Vt2iTkUvH4djhzI2fbsJeBC88EUl8Hg8aoESW1bg3zKiP2JY2/qO27pe
VGu7k3A4HIbL5TqdYIybZ/DPXzLCuwcQt/exIkZR0dAF3rHKYhMcDAbhcDjUAoKfvzJC2ovhayL2+tYO
hM0o+PUIbta349adDgYGAgH4/X7Y7fbTCfQvOHTqx9DY9QS19/oSL3eirK4NlwrKMD1nZqDX62UpLBaL
WqAfeo3VjW9oevAUn/gV1Nx9iGW7wCQEp2cXsSmKIhOkTNBjMLI9lV1DoVAysvG9GWlZheCmPyIzrzy1
gI6EvrIiIQHt7fP54Ha78WbWhAvZV5CRW5paQBd2/Fed7Mz8CmTkXMfFyzdSC+g86WU6EqfTCUEQYLPZ
YLVaGXCyr1bq1AK6bbL+SxeXa1FS1awWnK80miNVQhp+0k4xYAAAAABJRU5ErkJggg==
</value>
</data>
<data name="toolStripMenuItemShowActorNames.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAGOSURBVDhPY/j//z9FGKsgKRirIAiHFm92CyjctB+bHDLGKgjCGa37/gcWbvzftvBaCDZ5GMYq
6Je/XtQ3d81/35x1/23j5r7FpgaGsQq6Zaya7Zi8fLZFzML/xgH9QNznj00dCGMVdExa9sUqdqGoWdi0
00b+ff8N/LpvYFMHwhgCrmlLE+1iF54AsU3DZ7mZhE79r+fT+U/Pp8MFXS0IYwg4Ji68ahk1WwvGNw6d
/ApowH9dz9ZdyOpgGIXjEDdX2Sp61n/DgP4Let7tVw38+67q+fV+0fFs/a9knfNX0SpLBVk9CKNwbGNm
bwT6e5+6fZGJik2ulaZThZWmW6OWpmvDfxWbApAhG5HVgzCcYRczg9s4ZNoXTecKUWQFIKzuWDEFaPt/
BYsMjCgFExbh06SMgiZt13St+eoQUvoSWYGyXUmEvFnSf2WgC1RsC/4rWqR/UDBL44bJgwl9v25RoGYt
JatMLXmTBHgAgrCSTYGoLFBMUjtQS1zTV0tSJ0hL1jgB1QBKMFZB4vF/BgBJP5kepjxMJgAAAABJRU5E
rkJggg==
</value>
</data>
<data name="toolStripMenuItemShowGrid.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAFYSURBVDhPY6AqyJt9/z+UyZA1/TacHd93Cc4OaTwJZ2MAZAPSJt+Es2M6z8PZAbVHMQ0AaQTh
7Bn3/mcAbU6fcuN/ysSr/xOBNsd2nfsf0Xr6P8hmkGafyoP/PUr3/ncp3I5pUNZUhLNBmqFMhpDm43C2
R+luTI0wALIZykRxdmDtETjbpXAnpgEgZ2cgORukOaId5OzjQGcfBjvbDeTsgu3/7XK3/rfJ3PjfMm0d
pkEozgZqhjJRnA3SDGViAlCAQZnA0D4MZzshOdsifS2mAfE9VyDOBoc2wtkgm0F+dsje+t86c9N/89R1
/02TVv03jF/x3yB6KaZByKEN8jOUieJskGYoExMEITkbObSRA0wvBpvNcGfvBycSkJ8doKFtDtRskrQa
7Gy96GX/daIW/9eKWAjGUO0IgBLa2QhnG8Uvh7OxaoQBZGdbpCJCG9nZeA0gHTAwAACOffGU2o3WzAAA
AABJRU5ErkJggg==
</value>
</data>
<data name="toolStripMenuItemFixOpenAreas.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAE/SURBVDhPY0ACokCsBaVhAJsYVsBvbGzsD6T/Q2l+HGI4gTwQ/wcBEA3lYxMDGQKjUQAxLpDH
ogYFIJsOY8MwjI/uIjAABRBMEQjg8jt2cSAnC00Qp01AAJOHGQoG6IpxugCIMTRjcwEIoCvGZSgYoIcB
NiBv6q79v3Rmwv+0Pv//EU32Xzwr9GqgcnCAbisIgMViGzz6G1cn/t9yZer/C892/e/fnfU/vF/3v3m2
ZA9EGVAhFifCxWLanH9uvDzh/8Zrk8Dh1bMn9X//nnSQAd+B8mAAshksCaKhfLiYT7Xh/21X5oDZMLDp
0lSQASC1YIDXBRbZ0j+7dyX9b9+VANbcvjMB7AKzLIkfQHk4wBkGJqni3cE9Gv97d6WAbQbRIL5xivhU
iDIiANC5HUD8CeRsoM1fjJPFJzEwMDAAAD8wxIeEhxEyAAAAAElFTkSuQmCC
</value>
</data>
<data name="toolStripMenuItemSetupDefaultPlayers.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAD0SURBVDhPY0AD/9FoogEuDaQZdCzROe5YsvOJwwnODw7EO1S7KomLQaXwArAtIM33WrNef1ra
/f9NT/7/U/H2X9f6mXeCVRDjEpDNIM0/N876/3FS8f9byTb/Fzhp34ZK4wVg00HOBtkM0vyiKvT/1WDN
/z3G8q/AKohxAcjPIGeDbAZpXmch9mteYfb/Gct2EhWQ/0EBBvIzyNkgm8t8A/9X10/6DwLEGoICXCKK
/vfP2fr/2p1nJBkCUwSmHUMLwIZcv/ucJENQAMyQG3coMMQprBBsyO17T8k3xNgj+b9rZBF1DAFhqBDp
AGQIlEkNwMAAAP7JtzLCVbRNAAAAAElFTkSuQmCC
</value>
</data>
<data name="toolStripMenuItemCopySelection.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAJVSURBVDhPpZPdS5NhGMZ3LKJ/gzsrHg3sIFsm5A46cC3ImmnWOy0/lrMtpdbct5tbH5Op6eZH
6lrvtOYqTTdxrUyCTgoKlSwiAjHICAOro7VdPe+7aRSyhC64eeDhvn73/b4Xj+BvRcc8WRPDphKnUYG2
iwxam07AY6sqsTVXZKVa0itypyeHQrD63LhZ1MxVTqolvSZZF5ke7dwKQFIt6RUYvJLD9tm3AmxvA2rO
uO+1iv0ey6a52yIX0zMj1fJvsb02srEFB7Coy7a3/obYXjsPSLzVQlt3GNp6aXrAk4nBzEf3+oWRQA8J
+ztIcOiq1N/rQGKpCecZMTrN9VK2x0R8XQbi7dAJh10tmSmrQPD4bl/2s7CXmR0fBI0Q4ZEOTPraMe67
huCAA4EbbRj1tIJ1m0EBoADc6tIzbrs6CaFTc7ncvy3PAGtzfCW+zCL+OYqfn2YQ+xhCfDWyeb8yH8B1
ayOc+hohD5hiXYVc7rx5qRnxhUboa/OhO50HrXwnWqoJjA17EV9UIfayHu8eHIW+4QgMytLkfxkbsBfe
9lgRW5nC+sMSrE0dwPe5UhgUeyhoN3RnduHHUxnWoxJ8DRXjVX8+lBVFUJ0sTgL8bksul/nyCx/mhwqw
eHM/PkSq8H66EsrjO/AmKMHrETEWvCLeHGrLg0ImwtmyfclP8HWbsv1uU3W7vg4ODcOXjT4gmj2/qqb2
EJrkB3GuspifzJnV5QWM4pjodxKdZmWmU1cjvHypitgvnCIUQMwqGaEAoqmREAogFEAayosIN/kP8/9J
IPgFAlSB3U6URz4AAAAASUVORK5CYII=
</value>
</data>
<data name="QuickhelpToolStripButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIVSURBVDhPtVJNaxNRFM1PyE+Yn1AUXLjK0uWgDWQZwUUX
KsGFBEEcCkIwqBEpGiydsSo2kupsasdo7Yi2toh0sFZjG5JpiZo20/TpVOmH5njvm8BYahEXHji8+968
c+55l4n8F0zM+rhVWkHmdg29A/PoK1Yw8uIjOp/3xpvqBgrjLeilZbjNLXxZ34bwt6jexMVCGRndQenl
0p+NWHzPXoP3rQ3bAbQhQM0E5Np2BKprbZzrm8TIs8puE+68+r0NwwZiacCwALEBCVcAqet8JlAjk1PZ
JzsNJt6u4+FMS3ZmMV9mmFNAMhesbBZLC6oFdOsd8oVXocmdx018Ej9k1FgqiJ0zgS6qlR6BVI4iEFRN
IJlxMF/1cfTMcGiQvbskB6ZqgairJ6BCTJKYu9tlAUW1oSRsNDwfB+JXQ4PzN6s07W0ZPxDS5aSgJEFn
06Y9CaOqSauJRvMr9qmXQ4P8/RoWvU16eyBUEq5kbigwiKoOMTBQ0zbKlTq6TxihwejkZ1iOJwfEwmiC
BQ49yaW50J7Fh0xJw3IxbM3hwo2x0ICRHZzFgveTunYERK5lgo5YMxx8WPFw5Li+U8wYm66jNz+Naov+
Beqiao58N5NrPluoryJO0QeKU7sNGKPPazh9aRzGo/eYmVvEMk270fTlmzl2N3XW9xL/jv7iaxw7+wAH
E9ew//AVxE8OItv/9O/Cf0ck8gud2vKswuxNZgAAAABJRU5ErkJggg==
</value>
</data>
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>198, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="newToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
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==
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHPSURBVDhPpZFNTxNRFIb7W1y4NZpI4k/QrRs3rjSu/QMk
NjHGYCFgYYIWsaJidAKoUWqEgFiwGjE2ERREKEOZZtpa23H6OWX6OHN7CQaxNfFNTm5Oct7nnvten6fN
6AV+rPixM/2sTRzGNgKYGz0kF/2IgXayNIXNF8fADJB8fcY9e0lMHqGw3v1vAO9mLAXqMSx9zD2jot/6
cg3l3qSogbvPWViMHwxcVQ+hzZ6maEzgUKCcfSZ6faqDXV0PP6Xj1PmDIWIDMwjVWQHxNhF94ba0Q8/Q
OC8XlgRk/v0+iLU1SCJyFCfdSerNWdcYFBnUjLC0Q9fgQ2HeLWltSotdbP5C6gr6zAkSKzcoa32k435p
B6fR4NbYPENq9E/A7+odfiwte3K9VGp1cmaZ8VerHD957u+AwE1V2vZUtXfIWxW2Mz9Rp5dbA64OPJC2
puz6DmaxRuq7xddkjtHIx9aAy30j0up+huNglWoYuSLftvPE19LcefK2NeBS97AwO06DUsUmky+RSBX4
tJ4ltqQTejTXGtDZFXJDa1CpNkPTDJPPG1neLevMfNBQ7k+3B3iheWl7gXlvDrtrh9Q5lNEpgiOR9k/w
BtqVHP9f+Xy/AI/l932QyhfPAAAAAElFTkSuQmCC
</value>
</data>
<data name="openToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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==
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAACeUlE
QVQ4T6WSWUiUURiG/4suurJIjUIwskQsEAMjqosQpUVNKbdCSRPKrQVDMddmXEedGdcpFXNGnUYdrSzF
sEIoFInQcqHE1CwoKsXUUMnt6XfEye0munjgnO+c9+HjO0cA/osNi2tJLdA6SXN13MwoI12lJ06uiV8+
W3d5IwIjVXiGKvwX11djSs2TRFlUito7ILIAoVab7SvCWhqrZYq1omXC4gpPe4Ur8AjNMQjo69IwPVZj
4PeojtlhNfoyBXXalKSNBJ5hSjxCcnELzkeoKVcyNVq5Kjz/rZDZnggqSzOoKEpDXZBEcU4id+Sx5Mui
RcdfmVClyWLqh8YYXhDD9MVCT/CGrBPcK5Hx62uxMdxUm2XgiT6Tep2MhxVp6NXJ6IqllKlucTc3niJl
LKqsGINMqChOY+JTnqHtwRYJdZVK5gelMJSymo9ibSAOeiPhXTid1T5cD3IvF9SqZMb7M+CznEdVCtqe
ypcurWz9bQC0ezHX6sr0M0c+lNtx5cKJcVGwXyjJlfDzvZSh1gTqdHIWBiTQHbIU7AwSg+eYa3Nnuvk4
E41HGak9gDTUmvPOZjmGGRQqExjpiuG+NouOl2InvRGi4BJ0+LPw6gwzL04x2XSM0ToHvlfZ0p66FT9X
KxxsTGwMAlVmLN3NiTzQZkJ/IrwR233tzUyLG5PPHRmrP8Sw3o4vmr30yE2RBO/Bfp9Fg/EV8tKjqSnL
oOdxGO3ZgpE2+SaaZZtpSNpCdbw56mgLbt/YhZ/L7oVD9pYuRkF2ShTZksukxwQSd813cbJc9HHm7MnD
OB2x46CdNbZWFljuNGP7NhN2mJqIuRX/YOXm30H4A70P0TsBWkcYAAAAAElFTkSuQmCC
</value>
</data>
<data name="saveToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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==
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAACPklE
QVQ4T6WS70uTURTH9y/03jdBL3prU2O4FqvBU66hLB2GFtKvJ9Isfy3TJEXLVHT5A7QVLp20Wk3CiUb+
AH8gJmIsJSs1l7TEoabYRDD4ds99dI9Le1MHzvPi3OfzufeeexQA/iv5p7MjAEp32xpaXat45lhGc5Mf
j6zzqKv9BkuVF/dLZ1BU+Bn5eR+Qkz2OG9c9DN0SENjbA9TWbFDxr7G+sQl9Yi/OJL7iyUISuF6ucEF5
2Q8q7hkE+5fXcdT4GkqlCFOCk8qSwPF0iQuKCr9TcVdsw198K4gwuJF3axanjS20JAlsjQtccNM8TcWQ
2Am/n/LjoOBCZsYk4mJttCwJGup9XJB+bZyKwfgTHvL4EKZ1QBRHYTBY6RdJUFM9xwXi5VEq8tgL7hn5
in3RTUg+24+YmDr6TRJUlM+iuwvsKYGUC29hOjfIu00NozvTsWlnCe5DvOkNBMEiC0qKp9DuBpsBoMX+
i737T5TeW+RNpYbRndNSPUH4VFwbdLoyWXA7fxLO58AT2yYbnAD0SRkhaTxvRtLVAgmOZfBJJ7TaYllg
zplgMFD9IMB3JkjBliLUAsY+LWBiZhFi9l0c17dyWH3MDo2mQBbQWFofInhsEhB8JbcSH71L8M6vIuuO
BZFaO4ObEXnkMdTRubIgLfUdu/cahw/onNh/SMCL9gG4u4bQ3TeCweExnDCYoNQ0IorB4aoGqFSZIYL4
SxcH+HjShNGQ0DvTU1G3qWF0Z9qVkuDDUemy4N8Tit/kKu4LI/ykxwAAAABJRU5ErkJggg==
</value>
</data>
<data name="saveAsToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAABh0RVh0U29m
dHdhcmUAUGFpbnQuTkVUIHYyLjY0giIQKQAAAuxJREFUOE+Vk2lIlFEUho/1x6XUSiVBgqQQosgy0VRy
NxlcskSlQsUkcpd0bFxScy3Lbai0UMfGHJdRc5/QwEpaQFBrSEz9kUtqbqWmlYRv1+v8KPpTLxw4fPc+
z+Xcy0f/Eze3gwQMkDgxjRCfAAQFqVb+Id7exrS6GkNpWQepIE/447m4EIiKmueLivYVamtdpZbmZWpv
X6SmxgWqrZmlCuk0lZVOUGGBkmSyDjIzUyOFwguACPniTFSlpmdxmBXaWlfQ+GgJDQ2fUV01h3LJNIqL
PuK2eAw5Nz4gJaUBnZ0uDE5AT48fdHS3iIFmYqd+3TgZDfXreNK5xjb8ndHxl+jqcmedCP39PjAy0ryq
VIaSQGBPVF+3yOoL6uRraG5a2iR+y8zsLORyU9aJWIXA0NAEG2Nra2/j45OscoEqH86jtuY7ams/cWgj
6+vsvge7mXgDToTyjSf0d+/DWb82LtDS0uc8ScpmqLRkms29Aql0bJNm6VM+Q+NNC9YJ0dvrAQdXZ9id
6oafr1wlMOA83SuepKK7E6h4sASJZGiTZsnOy0L1FRNMFVnhpLMZEot6YOr6GGe8pH8KxIUTlHtrFK9f
AXn5U7C0a4O5Yyf09sexjYasDLD1qAR7beUICngBgeAeF2hqqkZgT0SZGSNQtIO9BFBasob83EVkZ01D
KBxGdNQAoiP6cP7cU7ifVsDFRawS6HGerqWOUFLiILtE4H4xEBxRjsO2DjB39kRIQjYikzPhcyENbh4d
cBLUw94+hws0NHZxnuJF70kY+w6SMiA35xvCYuqxfaceDhxzwPJPYHxuBb7B12FlL4e1oww2JzJUgp2c
p5jLAxQV+ZafHh47hkOOIoSLklBS04Lh0UkMjgzB0T0MR6xlMLORwtIqmQvU1XdwniLC+ig8tN85IqwH
3j6NsHMpREBgBS5eqkRgYAn8/e/A2iYOVjbpOM5gS4sYlUCX86Srs4f9ovzbP8fY2InU1LawjugX1Iz1
h1pVBKcAAAAASUVORK5CYII=
</value>
</data>
<data name="cCRedAlertMapToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
@@ -221,85 +393,353 @@
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==
6H7o/ujz8cGn1E+f/gUDmPP8usTo0wAAAAlwSFlzAAALDAAACwwBP0AiyAAAANZJREFUOE+NUAkOwyAM
4+k8rT9jthMHyqJpSG4gPkgZa4zVYf6DCXtnJp7nWdioEp2ZtQ2QGXUkKEajTFXJ22SIPMEewCCG3NNU
AA+xQqibD05inq8QBUio9TZzggrwNOxBoz2gABtFpMC3yWhzIvpzB1jMqtszRI+ZIdS1AWpwkyhhE/Iz
4ATF5ySewBx74gEFVAiIL1Hud3+pvgPQKGGKbTAfHNc27wCAxC3UfwLxDtGj2ZMR8QYHYTKCNmywFp89
gUyJIi6YP0OkKyIBpiDx3UvEeawP5jABQ7IsMkAAAAAASUVORK5CYII=
</value>
</data>
<data name="bitmapToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<data name="toolStripMenuItem1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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==
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAALOSURBVDhPfZPdS1NhHMdPWKREEhWE3fRXFBHUXS9ahnZV
kV2UvVx5UUQXZmnLJc5ZvmRN2YVhdBGsFxqjFU4jaIavIxWNHXWbb2c7U7c8m+n2yfO00hX0gS8858fv
931+z3N+j7SeJEn6An00f2nG2mul4kMF123XufbiGk0dTYwHx4n/iJNKT2dqYYr6z/W0DbahLCusJFaE
dHTj7oluDG8MmB1mIlok3USJKhhdRnzffaLgf7i+umh0NKZ3Yuo0IUfkVMoa7XI7tiFb6mu1k2SSxI8E
9q63XHpySXQojcyO0NxjSaWsoWoqe2r3kFGWgf2bPRWFaDSKFtE4Yz6NZ8KDZHbVIMf/3V3nmecZUqnE
1sqtdIx3iFgsFmNOncM94CavMhdJv+XfJJIJtBWN+HJcSL+8hq4GNpVuIseU88ckqATxjfs4db8QqaCu
QAR1+qf72f9oP3ste4X2WfZxoOUA2cZs0cmWu1twjDpYnF8kPBOm5EkJ0nFTHrGlmDBwB9zsMu5ie/V2
dlTvYGf1TnbX7CazMhPptsSGWxuwdFmIhqOEJlVKHq8anDIX0jncKQxiyzFGw6N4w16hycgkLT0tZN3J
YnP5Zp4OPIVlCAQC9Hr6KKotQjLY7nKj7YYw+Bun18m2e9vYWLaR1v5WEdPPPzE2wav2l+Qb85G8s14O
lR3Er/pJJBJCOtPRabIrV89+U8LabdXHkVAohCzL+L1+Lj64gOlV9a9humK5TJWtSvyihYUFtEWNpfgS
5e3l1H6qhfjqzsEg8pjM2Lcxnjuec7Ti8NpIq1GVs3VnqH9TjzavMReaIxwMoyoqISVEwB8Qbfu8Pl67
XnOk4ggfhzrT38Ps/CznG89T3FCM0/2OweFBpv0zKH5FrJ2fnJRaS8k1HMPe8za9eD3vPe+52nyVogfn
yDecIK88l5P38iluKqbO/pBgJLiuWJJ+AqhM3amQCvIQAAAAAElFTkSuQmCC
</value>
</data>
<data name="mnuMinimapToPNG.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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==
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAB+UlE
QVQ4T6WRX0hTYRjGve0iiAq6CovsphHWRaXrogshbEIgiEzbjFLQq266WZG76I8kRIRtIZJhW2NOq5Ga
uTkbrmZzf2gyTY8ipIwlYkJIIZP563xHZhtbF9YDz3l53vO9v/N93ykA/svKo883w5vRaZzeKV6NxOh1
R+keimB7G8TaF6DL6afzpY+OHi/tdg9PbG5M1iF5NAOwU53WNIiyBRBfFvpmbGJeX0bk3FFsxQdgc/OP
ZYnya30Dly+aDegdnhCBGV0ZX8+r8JwppPXIbqWXqeRGisTKmnwEVzbAPhgWgeGSw4yWHsJyfD/Gwl1K
b3ZZwuxro8nRwE2rAU90TDl/FkBclNBT1T7aj+1VhtOA+wN36ZFsNIcMXLbrqL1VqwBOXagXr7cAz15/
ECGvah5Wc3u8GV3/JSpM5aj1pbmADsd7EfKq7o6Oxu56Kswa1DfOojVocwHiv6aVkq/aE17F5Iyznkzx
6YufymsXOVFVTPX1KryxAOYXrmzAY8s7EbaHVXUhtMYwLc8l1n4mFS8u/WBqfoXI9FLuDtIAMVxUE+SR
I4W6McRJ/QAtXRJzi6vMLnwnKi3z8XMcsT4vYI/Gz9V7KXkHkxRVDnKw3ELJlX7cgThjEwnGYwlGggt/
B4ia6TbZDzqze2nnAERjp94G/Lsp+A2CB/zdurHUfAAAAABJRU5ErkJggg==
</value>
</data>
<data name="fullMapRenderToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsRAAALEQF/ZF+RAAACRElE
QVQ4T6WTXUiTcRSHdxkRRBdB0IUREV1ETSKIwoyQAsmV5IUhfaBUoJSUWJbLxAVZWixBRUcrNT8qM1PL
hpmoKGkf2pzOpLlAi9QtndKHzfm084a9uzCKujjv1Z7n/M85v2mA/yrlk3eng8DKKWsn62YLFwob0ec8
JimrhnhDJbGp5cQkFxOVaGZPgsmPBgi8M/y2Pn8D99Qsw+5ZBj746HL6WLMz/e8ELpsd+6FgbAe1WNts
ClxSP8jqHef/LJDOAjNsYfrpSZ7vXUGr3ceN2jesCgsQyMzzwfJs2wHtTzg7jPbIICzdMxTes7Jye5oq
kIXNB8vM8mzpLPD9B6+p7pwht7yToG3nVIFsew7uHxzhRIZJqY6+T8rM8mzpLHBFmxdjUQvLQ/SqQE4l
sGPIrYCO4XGsA2NsjYjDVPWK0N2HlSqo7qe42Uu2qYFlW1JVgdx5Dn4/6mHo4xee9biosPQSHh1PzZMu
6pt7/L/WUPDIxcW8OpZuOqsKJCQCj7gm8UxNY3VMYK55y+0GJ/n+eXUxxyi624Txeq0iMVyrYsnGM6pA
Evbd62PMM02fc5KShw6ulvaSaX5JlrmdREM52tAoEvU5xKdcUSSLN6SoAonn6PhXXvS5qGx89wtOz20m
+XItCWmlRMYaFEn4vuOE6uJYFHxaFUi27c4Jyuq6ychvRW9sIDmz2g/eIjYpn+ijl9Dt1xOy6whrN0co
tXB9gED+GJJtiackTEIid5ZTybZlYTKzPFs6C7xg3SlV8O+F5gdwpvLxKZ4mxAAAAABJRU5ErkJggg==
</value>
</data>
<data name="mnuExport.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAALTSURBVDhPdZJbbIthGMd77caFuHDhRkhwIdwhEXHIIhO2
kDiFTIYEsYkhs5DIxIYYY6fuvAljmaHWnbANOxjbugN2ajtVrbZbv21fuyrr168/XzunCv+b932f5/n9
87zP+6r+VoPOQa7WiLraQnaVjUtlQ1wr66auVc+Pkv+r+ImZu60Oeq3fGP8iMenxM+72obeI3Kl9S0p+
4/9NMqpM9FvdSHKAQIAwBY+SX8bqEDmSXE7pw9fhRvm1Jro+uRUwnBz4IPDR5gqLu1wiW4/k8PzN8G+T
vJqBsCJZ2XcP2Vm5t5K1sQ8x212huCTJ+Ka99PYb2LD/xoxBTmUPRqsYKggq6NNncBAVX8fSqCou5HUy
6f76IwuiKPJlSiAhtZzM289RXSx4gV+WQ8lgF4MmgV2J9SyMvE/SzTY+j7kYm/Rid3qwCx48nikE5ygF
5Q0cPHcb1anrT3+1b7RMEJ1QxfIdWjYfq2dHopbdSbVsP11NZJyGTUcrlUEKiBNjNDV3setEIar4K3VM
+/whg1dvrSzeXsqKnRo2x9Wy5kAFS5Tzoqhi5kXkM2ddBgazA9eEg5dtOrbF5aGKPn6L98qdgwoa1bQZ
WLbzFnPXqzmT9RLdoJ22PiuNHWaausyMCU5sVjP3NE3sSShClaxupPhRR8jgp6pb9MyPVLMgIpsiTS8+
n0xAmZPk+4btswWbxcTJlDJS8+pnXuJYigZxyhuC/X4ptGpbDMxelcas1WkMm0bxelwKbGVwSE9TSwdb
lL8QgoPKvNNMcnYNsiwhTc9MmoCfksc9ZJW34xQE7ApsNI7wolXH7uNqKup04b8xPqWCc9cf4By18dUz
zpQo4HWP454YxWFT2lbu/a5/gENnC7la9Cwc/qnD5++xISady7laml91MzJiRD+sp72zl/TCx2zcn861
koZ/w38qvbSRfadLWK+YRcTeJCaplMS0R/8AVarvzz+nF884LWEAAAAASUVORK5CYII=
</value>
</data>
<data name="exitToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAMVSURBVDhPZZOLT9N3FMX7vy1ZhiKttEh5zrpWJjgjsFF0
bGN0gmFzD7PF6AAlbDHLQghzBYuOltLW0lJmqVBaZ1sBBcOjtOIqfX12W0ic4SS//B753XPPufd8Ff9H
bm+Pbf88kf5BQj29BL+6jP9iJ/PfXGXN8YBcOs3Br4eRz+V4Zh4n9vUV4kODJAZvEv/uB5bbO/DpGrDV
6gkP3SafzR4mKXSOXO9jo+9n8gszsOgF8yiZH6+xefELYudaWdCfwX6iDs9nJtIvd98mWRkeYetmPzwP
8jrg4NXwbdLyvmPqZrXVyOIHHzJTUY2v/hQ2dRWezm7I5/dJ4otLRLp7IOrnpdeGX57npChmNLL6sZFA
7UlcJw087P0eh+40zspaLMc0REfu7BOEbgywLR1zITfRaz+xEQiSiMbwftSC44iKaW09a1MOCgjd+oUp
VQW2ci2T+sZ9KzMt7aT++B0mRkj2XyflEf8iL/n4H9xtn7JudxaLE745/I3ncGq0RRt3VdriZhTuhrNk
xW9u4AZxUxdPm1tZHx4lK4PNZ3PkpXjDZufvej0z0t0lFooE5VVECjZc7zeQ6Opmp8vE6idGHqqrcdXo
2AmHi52zmQy+C59je6cEz4kanHJNHhA8kUYK55nzPG5qZqWljUDdKZzVOqKSh4z4Sy4Eye7KPbbMbEcn
thKZiaaK+zKDcWUlkVEziqWBIZFVz5Khkfnzbaw9kBwINu5PMler48m3V8m92iW1HSfcd0sGWImlTMNd
TQ1bjxZR/Lv+AmudAY+QhEw9ZBIJNq1TzMr63EdVuI8oCX55Sb7v8MLh5J5SzZ/vleHpMJHbO4j2iuUv
JkrL8er0BCS6XgmOU1mBW1uHS63FXqZmVjLhPN3EWOlxxtU1bM7536Qxm0oR/vU3xkqUTMrPdimarqzG
XlHFlKzNqhbZosZcUsadUjXLYxOHz0SB5JnVjs1wViSqJG3lTIgKixCajx5n9N1jWA1NPLdNk5PNHJS9
jUKA0skkq/es+C5fYbq5HUfLBWYv9fLUbOH15tabM1CEQvEf0mmgVGzBvO0AAAAASUVORK5CYII=
</value>
</data>
<data name="propertiesToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAAB/klE
QVQ4T6WQ30tTUQDHz39QD0UQRlAPIkgPxh6yhCRCykGBL0WZjOytLKdl7KGHJmFYtAjH7uUWy3XvMswf
d3Ou8MdWils1ggZCRQ43lbbAwYpB4vbtnDMzrrsMw4cvB87h8/l+OQTAlqJ7ydL/7MEhGvQ9vQdZ6oLT
boVouwV7t4XFIvkFKMGB0nB23rqeX187kPl0CR/VJi5hsBh9VBo2nzuqgdPh0/gxeRhJXwWs8g3cDDSC
uH0fwKKMvIMyNI6/8DVTPT/bzh7RwAtqOWZdZWjpacZlbwOIMvIe+XweqdSCBo5HLLhqMnK4tfE4YmoV
QsIeeLp240rDXpzpPIXmfiOI7AlzAYMXo3c4PO4fpOdJzAVNXMImHyzfierK7TBU7ELlvh0Pj7XXwOSu
B+kdnsFqLo9kMo7O6xeQSMSQpZ8RDr3hktm+A6gz7IfgGoThxEX6UvgrKjAbb9eCOIemObAx6ZUcpqeC
MJ+vRWQug0B0WSNgoZJt5MnA22L4dw6LmRV8/p6l8E8Oq6FUkYCFSC8CHJKUUThcPg7bJA/uCyq6HcPr
kSeW9AXC84l/zXQ2a/7CmwuzWbNCYdGb0Bc4lLHCAtkPR6+Pw7bHdIGoXWB7GdMX2OXXtHkVS6w5WWie
XGtms0VvnMN33d/0BT2uV/xhsykSbLz4v4D8ATko6xzt+1ySAAAAAElFTkSuQmCC
</value>
</data>
<data name="resizeToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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==
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAH3SURBVDhPrZJfSFNxFMf3rBk+iIH2oOCTIAlZSGCQPqgIqQ/5tHQpPiikBpIpCnuxYkWCokQg
qDcoNYZETZAhbII0dh92DdPNvJuj4f7epWa2vOvrzg/u8uqQkA4cztPn8/uee4/mv5RxgQfN2Xkbm9zc
EpujUyY2+w0TbJ5ZBL/9sAyCx2cWMcqZYHj5Dv3PJsF/FjE8aUZrH4eWXg7Njzjoeqb+ShU4/iee7MO4
jIB0gPsDI9B2PIYkScmORCK4Vt2iTkUvH4djhzI2fbsJeBC88EUl8Hg8aoESW1bg3zKiP2JY2/qO27pe
VGu7k3A4HIbL5TqdYIybZ/DPXzLCuwcQt/exIkZR0dAF3rHKYhMcDAbhcDjUAoKfvzJC2ovhayL2+tYO
hM0o+PUIbta349adDgYGAgH4/X7Y7fbTCfQvOHTqx9DY9QS19/oSL3eirK4NlwrKMD1nZqDX62UpLBaL
WqAfeo3VjW9oevAUn/gV1Nx9iGW7wCQEp2cXsSmKIhOkTNBjMLI9lV1DoVAysvG9GWlZheCmPyIzrzy1
gI6EvrIiIQHt7fP54Ha78WbWhAvZV5CRW5paQBd2/Fed7Mz8CmTkXMfFyzdSC+g86WU6EqfTCUEQYLPZ
YLVaGXCyr1bq1AK6bbL+SxeXa1FS1awWnK80miNVQhp+0k4xYAAAAABJRU5ErkJggg==
</value>
</data>
<data name="showActorNamesToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAGOSURBVDhPY/j//z9FGKsgKRirIAiHFm92CyjctB+bHDLGKgjCGa37/gcWbvzftvBaCDZ5GMYq
6Je/XtQ3d81/35x1/23j5r7FpgaGsQq6Zaya7Zi8fLZFzML/xgH9QNznj00dCGMVdExa9sUqdqGoWdi0
00b+ff8N/LpvYFMHwhgCrmlLE+1iF54AsU3DZ7mZhE79r+fT+U/Pp8MFXS0IYwg4Ji68ahk1WwvGNw6d
/ApowH9dz9ZdyOpgGIXjEDdX2Sp61n/DgP4Let7tVw38+67q+fV+0fFs/a9knfNX0SpLBVk9CKNwbGNm
bwT6e5+6fZGJik2ulaZThZWmW6OWpmvDfxWbApAhG5HVgzCcYRczg9s4ZNoXTecKUWQFIKzuWDEFaPt/
BYsMjCgFExbh06SMgiZt13St+eoQUvoSWYGyXUmEvFnSf2WgC1RsC/4rWqR/UDBL44bJgwl9v25RoGYt
JatMLXmTBHgAgrCSTYGoLFBMUjtQS1zTV0tSJ0hL1jgB1QBKMFZB4vF/BgBJP5kepjxMJgAAAABJRU5E
rkJggg==
</value>
</data>
<data name="showGridToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAFYSURBVDhPY6AqyJt9/z+UyZA1/TacHd93Cc4OaTwJZ2MAZAPSJt+Es2M6z8PZAbVHMQ0AaQTh
7Bn3/mcAbU6fcuN/ysSr/xOBNsd2nfsf0Xr6P8hmkGafyoP/PUr3/ncp3I5pUNZUhLNBmqFMhpDm43C2
R+luTI0wALIZykRxdmDtETjbpXAnpgEgZ2cgORukOaId5OzjQGcfBjvbDeTsgu3/7XK3/rfJ3PjfMm0d
pkEozgZqhjJRnA3SDGViAlCAQZnA0D4MZzshOdsifS2mAfE9VyDOBoc2wtkgm0F+dsje+t86c9N/89R1
/02TVv03jF/x3yB6KaZByKEN8jOUieJskGYoExMEITkbObSRA0wvBpvNcGfvBycSkJ8doKFtDtRskrQa
7Gy96GX/daIW/9eKWAjGUO0IgBLa2QhnG8Uvh7OxaoQBZGdbpCJCG9nZeA0gHTAwAACOffGU2o3WzAAA
AABJRU5ErkJggg==
</value>
</data>
<data name="fixOpenAreasToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAE/SURBVDhPY0ACokCsBaVhAJsYVsBvbGzsD6T/Q2l+HGI4gTwQ/wcBEA3lYxMDGQKjUQAxLpDH
ogYFIJsOY8MwjI/uIjAABRBMEQjg8jt2cSAnC00Qp01AAJOHGQoG6IpxugCIMTRjcwEIoCvGZSgYoIcB
NiBv6q79v3Rmwv+0Pv//EU32Xzwr9GqgcnCAbisIgMViGzz6G1cn/t9yZer/C892/e/fnfU/vF/3v3m2
ZA9EGVAhFifCxWLanH9uvDzh/8Zrk8Dh1bMn9X//nnSQAd+B8mAAshksCaKhfLiYT7Xh/21X5oDZMLDp
0lSQASC1YIDXBRbZ0j+7dyX9b9+VANbcvjMB7AKzLIkfQHk4wBkGJqni3cE9Gv97d6WAbQbRIL5xivhU
iDIiANC5HUD8CeRsoM1fjJPFJzEwMDAAAD8wxIeEhxEyAAAAAElFTkSuQmCC
</value>
</data>
<data name="setupDefaultPlayersMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAD0SURBVDhPY0AD/9FoogEuDaQZdCzROe5YsvOJwwnODw7EO1S7KomLQaXwArAtIM33WrNef1ra
/f9NT/7/U/H2X9f6mXeCVRDjEpDNIM0/N876/3FS8f9byTb/Fzhp34ZK4wVg00HOBtkM0vyiKvT/1WDN
/z3G8q/AKohxAcjPIGeDbAZpXmch9mteYfb/Gct2EhWQ/0EBBvIzyNkgm8t8A/9X10/6DwLEGoICXCKK
/vfP2fr/2p1nJBkCUwSmHUMLwIZcv/ucJENQAMyQG3coMMQprBBsyO17T8k3xNgj+b9rZBF1DAFhqBDp
AGQIlEkNwMAAAP7JtzLCVbRNAAAAAElFTkSuQmCC
</value>
</data>
<data name="copySelectionToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAJVSURBVDhPpZPdS5NhGMZ3LKJ/gzsrHg3sIFsm5A46cC3ImmnWOy0/lrMtpdbct5tbH5Op6eZH
6lrvtOYqTTdxrUyCTgoKlSwiAjHICAOro7VdPe+7aRSyhC64eeDhvn73/b4Xj+BvRcc8WRPDphKnUYG2
iwxam07AY6sqsTVXZKVa0itypyeHQrD63LhZ1MxVTqolvSZZF5ke7dwKQFIt6RUYvJLD9tm3AmxvA2rO
uO+1iv0ey6a52yIX0zMj1fJvsb02srEFB7Coy7a3/obYXjsPSLzVQlt3GNp6aXrAk4nBzEf3+oWRQA8J
+ztIcOiq1N/rQGKpCecZMTrN9VK2x0R8XQbi7dAJh10tmSmrQPD4bl/2s7CXmR0fBI0Q4ZEOTPraMe67
huCAA4EbbRj1tIJ1m0EBoADc6tIzbrs6CaFTc7ncvy3PAGtzfCW+zCL+OYqfn2YQ+xhCfDWyeb8yH8B1
ayOc+hohD5hiXYVc7rx5qRnxhUboa/OhO50HrXwnWqoJjA17EV9UIfayHu8eHIW+4QgMytLkfxkbsBfe
9lgRW5nC+sMSrE0dwPe5UhgUeyhoN3RnduHHUxnWoxJ8DRXjVX8+lBVFUJ0sTgL8bksul/nyCx/mhwqw
eHM/PkSq8H66EsrjO/AmKMHrETEWvCLeHGrLg0ImwtmyfclP8HWbsv1uU3W7vg4ODcOXjT4gmj2/qqb2
EJrkB3GuspifzJnV5QWM4pjodxKdZmWmU1cjvHypitgvnCIUQMwqGaEAoqmREAogFEAayosIN/kP8/9J
IPgFAlSB3U6URz4AAAAASUVORK5CYII=
</value>
</data>
<data name="toolStripLabel1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAI3SURBVDhPpVBtT1JxHPUz9GHatDSlWfbIxEkCAQJe
DJUIKEBEx4OkIiiKPC10QS7XyrU2KRFQUKcBEup06hfoVc1euLVe6OnvbVdN75vWi/O7+5+dh91TBuC/
wEraS6Yta/EZuvP6I/Pqkxk2DYMLhL1kvGQvmjC1F0FsNwTDsvrbec1ZsJKWnO4gthtEcNMDXUY1z6Zh
QB/HeidsXwzoKTxFV04L04rmKLoTxPi2D49T1I+2Wfn31rh0X/FBtM8aYCXm13svMLkbRmwnhOhOABPb
fkS2fAhtDMO/7sZYyQXJ9AMiZwnoLujxipiPW/sKnTAuqaBfpKDNtpBvK7QZJQkYhPBNA5GzBJClYVxW
w5mz0K26LAVNRo6OeSlUaTGUSSG8pX6o40rwondxf7wOt8O1xHpuRE1aifCmF+qFZrSlJXiUEqElKYBs
jg/NAoXBNQcG8nb05624Eai5GNCeUCCw4YEq9adVMdeE5kQjxJ94aE/LidEG5+ce9BJwRqtOA8jSIEvD
nNHBR/61JdlEt0pnGyD6WA9BnIs+0ip/9xC1Y9W/OCOVuDZUcRpwbPYT4yhZWpdVYaj4HO61XrgKDrpV
mRTTrcRMm86CPtSMBCNkJFmCD0/RiY44RY/FnbgFxbQYjlULbCtdqPFeJXKWANl74UnrQN5BmxnBzQCH
mM2wLBlQ6Sk/4RnQR/yWD8EUD42TXNS/vIN7kbqfjOD6aNVh9fCVw0p3+UGF6/JXhmfw1+PfgbLfYY/G
d6iLJ+UAAAAASUVORK5CYII=
</value>
</data>
<data name="openRAWebsiteToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAANqSURBVDhPXZJvTNR1AIdv03KuXL2pteV8QbnVVmuU
xESolRtJG5GxZJIgaN75h0MZZOMMwoOSIPRohAiecnceIGjHcdyheHfA8efAu+Pu4OD412FIBhThKMxJ
29PvWJr24nn3fZ7fvt/fRwQ8QnpXapRAvcCkwJ8CdwVmBZqktpRt/z//sLha4EJQuPaTFudcK9Yb3TSP
ddPot3DJX8MBa9KyuDXRtMeU8OQjAUF6TKBLPfItM0suxuZ9DM73o5t0YwwMo/b5UHn6qfd0Udp3giRd
vHdnfdxTDwe01f4TBBbbGV60M7QwhHvWQ834EA2BCRSucYp7/Zzs6EM3ZKHULiNe875pJSDIkQL3pv5o
p3nByKXbRlrmO2i56ePsyCjfD44hNbqQGuwUOIxUTpbh+kVHbFX03zHl78YFA5eNgQqcvxqpXdBz8fc+
+ua8lLiHKHaMIm52ITGbyRiuJDMgJ2NChsZTyoXeQraeiroaDEwN/GZAPVVFyZxS+LoP+5yH9KtuxHon
n/U5kIwfJXZUTKx/H0mDaeRey8Q2ruWtws23goGlidtW8keOIx3/nMqf26iddJJUd500i43isSukjNSw
vzaSfedD+dC8k7SGvfRPN7FZHnZHJO1MufPjgpUcbyZpXgXnbphJrrWT3DhI/Jke0s09yLw6PlVv4bgh
kYSKl5BoEum/qScsN/Qv0cG25Gn3bCMKXz5FE23IHZ3sUDs5rI1CqolAogojVRnKF7qPqXeUktUQR/Sp
5zCPqHhd9tqMSBhGk87/Hc2Bao70FJDnqWOXtptDmnAa+8u57CpbEescChTmLFT2IvZrowkvXBsMtIlS
m3dEC8NYHpwzkmU+QIYlHanJyl7hvkH5ZOthvrlyiK9MYvIMqciNEips+eyqjmTjl6LllSEl1H2gL2k/
isF/hrz2bHJtZj6pepmL1xVoe0tQ9RRxrrtQiBzktE2OWLuNF3IeX3o+W7R2JfCRKmadMAzv1y1HsM/8
QPVAO9tPhxBTul7418+ypfhpks9HUN6Rxx5NNCE5a+6+Intxw4MpB3mv7J11wjBMbxdFLCu7q1DaDJzt
sKDstKIfaGRT4RPsVm0l5NiaxVdlG9ff9x4E7hNR8Ob28Lw3WjblhE4Lj7T0L7dCclbd23BsFc9ki1b/
dx7RPxe0rmcJTZoRAAAAAElFTkSuQmCC
</value>
</data>
<data name="openRAResourcesToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAI6SURBVDhPfZFtSFNRHMb3TQj61pe+VIJ9mPMGldcGyYJe1I2I1qbN6HVL2EJrKGzRmsWkJGaQ
RK8Mnc7MuVywNNmLLpNi0YtIm4X2NspkaC5LW7q1p3svbEzv1R88PJzDOT/+nMNzPX2PpXH2B2F3D6Ht
0Qs6ZgC85cIIlsPieIICyckVJbyH/hDV3Nxoc8PzLJiSNFBbbIHDO0w1MPYlguevx+DyDTFrmuutvczl
VCjYgvuPX1HNTTzxj5GkRBRsgc0VoHrxBNauQVxr7sVcbAGRH3OMgBSr6GNsQZNzkGo28wsJTM/EEJ6Y
WVlw195PNfcE3ydnMRqexm1/Nyq8Rsg7L0Fm8kFZ2wJhuXE1I7h5z8MIMon9jWMy+gefx39Ca7PBMHoG
jmgHYslZnHhzHLvMduQp6lu2yg1ZPHo8Gq4JrN4RlPaUw/DtGNp/taLntx+HOz9hj3UE2ZYK5FRpC9MC
mmQymX64D1+jUF4NQHReglJPMdRhGY4+CGJn4wQEPj3WuqRYp1N3LxJkPlzo4xTISg/233kHUa0U+wIl
KGp+i8LL48htUmNNxwFsqNEk0gK6l6ZY78aO+jh2N4RQ5CyBsF2DbYYIyHM+5JiV2Hha42cE9BdxJV9u
BFk9DGHdFLbbykCa9NhSHQShHIBAZQJxqErE+tfMCBRX1m8+cutlvnYApO4UCnRdIFRe8BUW8MW6s4RE
u4rzYmZyZXXZRNnFxk0HLwTzpMZ5/l5dn0BSIyXElVkAeP8B187ybforr3QAAAAASUVORK5CYII=
</value>
</data>
<data name="wikiDocumentationToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ4SURBVDhPpZN9SFNRGMZvBAVFUUFCQlEUUZBCnQoF
+6CMUiwNhUap2ebEr8BKlJKZqGEl1tRELaggNrGJZraKLaOv3TWnEU3ZAnOI5JhzG24T3Bg83XPiDqIJ
QX889+Oc9/2d533vezkA/yV2yX9gIqKkHTw53/aRZLe8I2JQxo0BklbTS45XdZMjFU/IgbKHJKGkg+2L
yajttaCm5ysU3V9QpTaj/DGPzFuv4tLrn8cVt+lRfO81CpQvIG3sQ26DBnvyW5BY2kk4WScP2f3PCIVC
ES0sLKCf/45Tdf3TqdU9032frAgGg39oV04jEorawQB57QaWODIygqGhIfA8D5/Ph2+2H7D/dCEcDmN4
eBgmkwmDg4MMsP1MPYis+Tcgu/U9A9Akr9eLmZkZjI2NQavVwm63Y35+HnNzc5idncXExAQDbM5QIC73
NjihaZDcecMA9BTqwGAwYHR0FF1dXbDZbAxgNpthNBqh1+tZibGpldghqQeX1/aBNosB6ClutxtOp5MB
1Gp1BECduVwujI+PM8D65EvYmnkdXHbzW9osZkuskzqwWCwRQCAQiPRGp9MxwJqDJdh08ho4SZMOKQoN
A4gOHA4HA6hUKlitVgbweDysN6KDlYkFiD1RDi7r5kscrVQxgCgaQGFTU1Pw+/3sXVyn5dH78n1SxCSX
gUuvewZhsiBMFoi8FfF5Tdh5tgHbsmpRrtTgyt2niDl2GWsPX8SqpCKsSJBj2d4LWLo7F+sOlYJLrdYg
p3EgqracVmBj2tWoe1SrkwrBCbO9qIPEwlbslysXdbAk/tzff5coAfBoQ0rFpPC5JoVnXbQYqqiL/y5w
vwBd8t4lLDBzngAAAABJRU5ErkJggg==
</value>
</data>
<data name="discussionForumsToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHISURBVDhPjZCxT1NRFMa7kpA4sRkSBxIGF535N0hY
hEH+Ao27LDDQkHTWRZk0QCIMIuYShjIZSghLIUVMrS3tq21fW1773rMef+e2j4TyGhx+ee+ee77v3PMl
5lZ2p2ENPo3gAzyHSRFJDKMGqf2Tgml6gXEjrvs0oNzwzGY6Z+h7PcpgW8V1mmvtwPxuBcZp+cZp+qbs
dm09X2mpwfuRBjpVxZWB6KrRNcV6xxRqHXu+z2Cn2QlMlcnaXEJ8cFr89vJNujaf/BougH7p86E+oADL
MK0GG1WEftizYp386u1hg1yE1YTX9bnuQy5CLkIugnZTDRaTGxmTyVVM8Kdneba6F6qY/YXVhFyEXIRc
hFfaOmupwbndg58Z+KiJfznK676hTlUxuVgRuQivE3Kx51sGA5N3exkr3oUWuQi52GZWuxHnq56U+P9V
bavBZSQegx34DFNwRS7SDXu3xPqKCnXykh/lphpkI4MJWIJHg/PK2taxnHx3hEwsavbTactFyZX1/ayK
PXhxs8IwXM6C63q+kIsK/kIOTiEFD7QvVhxB0xm5qLgLT+J67hQiEIyDCx14GtejxBYVRA9hCx7H3UfE
Fv8fSfwDwZ8JlGSjAbkAAAAASUVORK5CYII=
</value>
</data>
<data name="sourceCodeToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAAF+SURBVDhPrZDLSkJRGIWPiagPVO9QbxE1aWqjgkZNwmpQ
3lIkSI0wzcCo0MiiC6RdLFSQog5aKOaFtMQ0deX+PaJZBx204OfsffZaH2tv7t/kPonir3H5wrB7grDt
+NnMC/bfYuZuyVfk4NM8rc2OYwyNjItDto8iZGRSGpXgMzw4LUdrJp3NA+95uAVZEGJtOQ7uyBjPxSHR
SiAzyMAZOfifAvRfY9mncGuEWFsbe1dkVBgVkOqleC2kCcTWTF/VGkFaICHWltV9QcZaHRQa0A0QoFPF
UoUAg8Nj4gDWQKKTwHntIghTvV6ncCpbFAesuk7JzMTufxO7FXZAuVJFLl9CLJkXB5jsPsH+U9XGnQrF
MhLpD9zHcuIA/bqXAuZNHzRru5gzODGzaIFq1oSJ6SWMTqoRekiLA9hBt9jLv71/4jlVQJTP4jKS7A1g
DZapwVajgbXZYKrRQKXGWfClvwbs0TofLvKYgT+UwGEg1hvAvr1GFMAO+p1miuO+Ab7ZFVkV6pPjAAAA
AElFTkSuQmCC
</value>
</data>
<data name="issueTrackerToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAALnSURBVDhPdZDrL1txGMf3D+z13oqOUavSlp621Gq2
F7NiLhuZ2yRkExLDlNnMvSN0iE3EMKZza11Kx2hdasssWUhGsmwum5Bt6jI2jiLx3TlEU5u9+Jzf8+T3
+36f831OAPgvHj1CeHQLJHTt3sb3d1O5bv395kgj6RcxLHuxhoB7O18Tq/CxFjW7RAtf8H5Z3tMcac7R
E7WC5MPeTc03iVpcV2IeXFT65Qu3hNXcveDbogJLjbmgEXcRa+6dhImu3VXEurDJBQIlD4I6HjIMiTDM
tyO1KALSaM6dQ80RAyqnxK3VFeJmYs1bdQHqyRr0fmyAYiQPrEd2iOjxRctoBZyLz8KpwAGOeUxqaiex
TuU0Z6dy7nkoBWgaK0Huqyika4KRoomEuIIAq8AeUQ3X4OVnO3X4ns65Q+WEsNGlXqwkjFfVflC+L0am
NhxJal+EPfdEfmcQJoZuoWqwEI459hCF2LSbDeiPoIH3lqjjgqjhQjVejozuUCSqfBBWJ0F4oy8+9Edi
ZaoV+r44sDKYYKbZbtin2MSbDWiIp1xTSLM/inTxSGiRIrTWE4H1l9HbH48lag+7G9OY6AiCTzYbdkmn
984kMGAbZ30gpuE/5mzeVEehdECGsGdeCKj1RmV3IsbbrsC01A3TNwVWZ7SofSKGNNXhFK1hxFjdMxsI
y1zknCIWsrUyBNZIUdyVhrZGKZY/qWCaz4bhIRc7KyqM15zfG6uSBBzqzAY0XDl7mJFsheqhclSqovBF
n45tYz3I6RswyJ2xNSfD2uxL6EqIxXelxMl/DGgc05nDnLsO0NVewk9qcVtfk7H5OfiAqTAqSgnmhsvQ
kcsuOdaAJkvOHZ0zKLD9o2J/+ubUdSoCZ/8kZ2NBfu+EIYe1OJzlwDzWgPq9BXJ5BturepiM1A6MrRao
sft7EgujDRhIt2091uBNIWf5tdyJHMljk9Qksj+Tib4MewzetyMpEalPsyH1MgapS7Ee+QMga508U1fU
1wAAAABJRU5ErkJggg==
</value>
</data>
<data name="developerBountiesToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ8SURBVDhPhZLLT1NBGMW70K2JS7cmxrjU+A9oIGIg
FGhEUYkYRYIYaiyCUPqgD2p42hb6BkqLoKUWegt9UKm0JQrSGjdaQErRmLhzY4pE0OPcIRBKfSzO5M7M
/Z3vzDfDAfBftUdb06oZ2aE/7WUt7FdbRJE2x3VQhqQQBxqzTDIm+/UwLE+b4j3wffLAsKBFs68Bdczd
DJMMYK9I5LQxxsIMHCt2eNfGoXnZAYG7FjWjt3ZNskBWrS9a0oaYFr6Pbjz9YIdt0YyGCQEmUmPoiKpQ
7ajE9aFyapIFK0OStH5BAy+B26JKKMNSWBNGDCQMeLw0ACblREtQhKvWS+tZBvJp8brutZrEdSP5bQkb
W98x8nYIihnxNrzqhDQoxOWB0s0dhg7a+a5jsueiH73zj+hZ2yJKCusjvUh9TUIVkcG9OgrJlJCtjPLB
Mly08A5QA+18p0hGIvXMdVP4ybKNxJbQyiws90u34UATWxlzX2bR7H+AEmOhghqwkbRzXZgkDRpZHqRn
7X+vh5zEVoVlGE+OQhRoRJXrBoVnP4cRWguAZ+LivCb3MEcxLbESwfJGD0/qGeo8fPS908G+2EdgB61W
P3WPwFFMLjOo9VdvlPWXIk+dK8jpPnOKowhJjrAp2EeiX1DTuLaEZRsma5XOCjCLLqhn21GkLwgU9OSp
89Q5RzOa2OS9b7bGLRAwfGhedWJsxQGhtx4XzMUQEhOeqSjJ1eWfzdeeO7EDZhjUMfzjLcHmreCqD3ec
VSCGKDYU/iKd9vOM3Kb90F7RodZ1+yB5XWOVwxU/+a4aNupmqaXkNOn0btS/affj5nDFyWu2KzFyVfl7
f/i3wPkNOLzMGxqYvkUAAAAASUVORK5CYII=
</value>
</data>
<data name="aboutToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJnSURBVDhPbZLtS1NxFMfvf9F/EARBEEFEQdCrXgRGvTMM
ClN8URBYkaDUC31RCCZFkj3YnGhmpuh0s+FS51Nr6iLnfMB0W27uSe/udrfr7vp0vdtQs8+Ly+X7Pef8
Ducc4V98YYXhHyJ9DoneaYnu8Qg2Z4DNaIJ8yGH+AGNuEeNoBPuKzFJAYS2kshqQ+er0Yuibo2NgFjm9
c7BIVss0O2N0TkZQtSIFtpMqW8mM/i8m0rQPOKlu7EeUUnsFHIvbNPZ59aACgajMmduTnCr7Qjgm5VV4
0zVGbZOZ1G4HybTKq/4Vrb2tvJ1jJ5Ol1jBPbYuLtJJ7PUeasmoDo45lhG/uEPWt3/PGHhshmbnlMP5w
PK9oBRVF+6aw2Bzce9qN0GNb4vkHR87dx+eRX5wosVBUadUmnWtbzaioaQmPe5HSqvcIQ1PrvPw4o5v7
cXiCnC4e5fzNQXzhmK5lsyqppIh/bZXymlYEu2uDeqNDM3aXtcfcSohz16xcLDcR3BJ1LaOqSGIEj2eB
Gw9bEJa9UeqaR/QB7ce9HuXsFQuXSk1IiqxrcUlCjm9ittq5VW1E2E1q6pzCYl/UAwpM/Axx5GQnRy+0
4YvmhhYNbyKLfipq3vG6azy36xXt9UcvLIjJlB60S9ugh2NFbRy/bOCTdUGbltZ6Kkh79xDXH7QQ207u
HcqUa50nzWb8waCWukNWkUgoMRKJCFI0iBL302sa5uqdJmbmvYfvfNbto6qhh5qGLqadLlLSb7Yja9hG
J7hfZ+RuXScz7v8kFghpO+0wOah43E5x5VtKtBarn/UyPOU5eNOCIPwFCBKiGq2sGKsAAAAASUVORK5C
YII=
</value>
</data>
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>313, 17</value>
</metadata>
<data name="toolStripStatusLabelMousePosition.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAFNSURBVDhPxZDNSgJhGIW9hSCCbqRFl2B0CUKLoJWLQFoGCUKbVkURFlTQj9li6MckE81FgUqk
iUhWlP0Yk43ZjOOYzpzGz28ammwUNz1wePngPec7vBYDoLNr/iegYdLUwPheaTN/oJm6hgTsRjK4eeS+
lc0VkLx6xszyHjdin3T19vX3kO0WkAAmnIYRoSxhcTOAcedCyTE1N022/8IbSFCbDl+uwOFawoB1lIiu
/oIcZuMgRm06igLcPrBwe4IYsk2Y32qVOaU2nVpNBleqwB9JwmoSQBq4vWFqayKr3/NiFU8sj/3QhWkA
YX79iFqbSNU62KKI61wRzPF5+waza4fUCtRlGe+8hPt8CZfZV+z44+0baAGKWl2UPvFSEJC5e0M0lceW
euCOGnwIIiLRNIJnKfhOEqS6xxeDezvUWQOb3UkWW2lweIwGWCxff/dVb00F4NUAAAAASUVORK5CYII=
</value>
</data>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>45</value>
</metadata>

View File

@@ -82,7 +82,7 @@ namespace OpenRA.Editor
// {"scrate","crate"},
};
// todo: fix this -- will have bitrotted pretty badly.
// TODO: fix this -- will have bitrotted pretty badly.
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))},
@@ -174,10 +174,10 @@ namespace OpenRA.Editor
// Add waypoint actors
foreach( var kv in wps )
{
var a = new ActorReference("mpspawn");
a.Add(new LocationInit(kv.Second));
var a = new ActorReference("waypoint");
a.Add(new LocationInit((CPos)kv.Second));
a.Add(new OwnerInit("Neutral"));
Map.Actors.Value.Add("spawn" + kv.First, a);
Map.Actors.Value.Add("waypoint" + kv.First, a);
}
}
@@ -189,27 +189,27 @@ namespace OpenRA.Editor
static MemoryStream ReadPackedSection(IniSection mapPackSection)
{
StringBuilder sb = new StringBuilder();
var sb = new StringBuilder();
for (int i = 1; ; i++)
{
string line = mapPackSection.GetValue(i.ToString(), null);
var 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));
var data = Convert.FromBase64String(sb.ToString());
var chunks = new List<byte[]>();
var 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);
var length = reader.ReadUInt32() & 0xdfffffff;
var dest = new byte[8192];
var src = reader.ReadBytes((int)length);
/*int actualLength =*/
Format80.DecodeInto(src, dest);
@@ -219,8 +219,8 @@ namespace OpenRA.Editor
}
catch (EndOfStreamException) { }
MemoryStream ms = new MemoryStream();
foreach (byte[] chunk in chunks)
var ms = new MemoryStream();
foreach (var chunk in chunks)
ms.Write(chunk, 0, chunk.Length);
ms.Position = 0;
@@ -276,7 +276,7 @@ namespace OpenRA.Editor
Map.Actors.Value.Add("Actor" + ActorCount++,
new ActorReference(overlayActorMapping[raOverlayNames[o]])
{
new LocationInit( new int2(i, j) ),
new LocationInit( new CPos(i, j) ),
new OwnerInit( "Neutral" )
});
}
@@ -284,7 +284,7 @@ namespace OpenRA.Editor
void ReadRATrees(IniFile file)
{
IniSection terrain = file.GetSection("TERRAIN", true);
var terrain = file.GetSection("TERRAIN", true);
if (terrain == null)
return;
@@ -294,7 +294,7 @@ namespace OpenRA.Editor
Map.Actors.Value.Add("Actor" + ActorCount++,
new ActorReference(kv.Value.ToLowerInvariant())
{
new LocationInit(new int2(loc % MapSize, loc / MapSize)),
new LocationInit(new CPos(loc % MapSize, loc / MapSize)),
new OwnerInit("Neutral")
});
}
@@ -316,14 +316,14 @@ namespace OpenRA.Editor
void ReadCncOverlay(IniFile file)
{
IniSection overlay = file.GetSection("OVERLAY", true);
var overlay = file.GetSection("OVERLAY", true);
if (overlay == null)
return;
foreach (KeyValuePair<string, string> kv in overlay)
{
var loc = int.Parse(kv.Key);
int2 cell = new int2(loc % MapSize, loc / MapSize);
var cell = new CPos(loc % MapSize, loc / MapSize);
var res = Pair.New((byte)0, (byte)0);
if (overlayResourceMapping.ContainsKey(kv.Value.ToLower()))
@@ -343,7 +343,7 @@ namespace OpenRA.Editor
void ReadCncTrees(IniFile file)
{
IniSection terrain = file.GetSection("TERRAIN", true);
var terrain = file.GetSection("TERRAIN", true);
if (terrain == null)
return;
@@ -353,7 +353,7 @@ namespace OpenRA.Editor
Map.Actors.Value.Add("Actor" + ActorCount++,
new ActorReference(kv.Value.Split(',')[0].ToLowerInvariant())
{
new LocationInit(new int2(loc % MapSize, loc / MapSize)),
new LocationInit(new CPos(loc % MapSize, loc / MapSize)),
new OwnerInit("Neutral")
});
}
@@ -375,13 +375,12 @@ namespace OpenRA.Editor
if (parts[0] == "")
parts[0] = "Neutral";
if (!Players.Contains(parts[0]))
Players.Add(parts[0]);
var actor = new ActorReference(parts[1].ToLowerInvariant())
{
new LocationInit(new int2(loc % MapSize, loc / MapSize)),
new LocationInit(new CPos(loc % MapSize, loc / MapSize)),
new OwnerInit(parts[0]),
new HealthInit(float.Parse(parts[2], NumberFormatInfo.InvariantInfo)/256),
new FacingInit((section == "INFANTRY") ? int.Parse(parts[6]) : int.Parse(parts[4])),
@@ -415,8 +414,51 @@ namespace OpenRA.Editor
void LoadPlayer(IniFile file, string section, bool isRA)
{
var c = section == "BadGuy" ? "red" :
isRA ? "blue" : "gold";
string c;
string race;
switch (section)
{
case "Spain":
c = "gold";
race = "allies";
break;
case "England":
c = "green";
race = "allies";
break;
case "Ukraine":
c = "orange";
race = "soviet";
break;
case "Germany":
c = "black";
race = "allies";
break;
case "France":
c = "teal";
race = "allies";
break;
case "Turkey":
c = "salmon";
race = "allies";
break;
case "Greece":
case "GoodGuy":
c = isRA? "blue" : "gold";
race = isRA ? "allies" : "gdi";
break;
case "USSR":
case "BadGuy":
c = "red";
race = isRA ? "soviet" : "nod";
break;
case "Special":
case "Neutral":
default:
c = "neutral";
race = isRA ? "allies" : "gdi";
break;
}
var color = namedColorMapping[c];
@@ -425,7 +467,7 @@ namespace OpenRA.Editor
Name = section,
OwnsWorld = section == "Neutral",
NonCombatant = section == "Neutral",
Race = isRA ? (section == "BadGuy" ? "soviet" : "allies") : (section == "BadGuy" ? "nod" : "gdi"),
Race = race,
ColorRamp = new ColorRamp(
(byte)((color.First.GetHue() / 360.0f) * 255),
(byte)(color.First.GetSaturation() * 255),
@@ -433,7 +475,7 @@ namespace OpenRA.Editor
(byte)(color.Second.GetBrightness() * 255))
};
var Neutral = new [] {"Neutral"};
var neutral = new [] {"Neutral"};
foreach (var s in file.GetSection(section, true))
{
Console.WriteLine(s.Key);
@@ -443,8 +485,8 @@ namespace OpenRA.Editor
pr.InitialCash = int.Parse(s.Value);
break;
case "Allies":
pr.Allies = s.Value.Split(',').Intersect(Players).Except(Neutral).ToArray();
pr.Enemies = s.Value.Split(',').SymmetricDifference(Players).Except(Neutral).ToArray();
pr.Allies = s.Value.Split(',').Intersect(Players).Except(neutral).ToArray();
pr.Enemies = s.Value.Split(',').SymmetricDifference(Players).Except(neutral).ToArray();
break;
}
}

View File

@@ -12,15 +12,10 @@ namespace OpenRA.Editor
{
partial class MapSelect
{
/// <summary>
/// TODO
/// </summary>
// TODO:
private System.ComponentModel.IContainer components = null;
/// <summary>
/// TODO
/// </summary>
/// <param name="disposing">TODO</param>
// TODO:
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
@@ -32,9 +27,7 @@ namespace OpenRA.Editor
#region Код, автоматически созданный конструктором форм Windows
/// <summary>
/// TODO
/// </summary>
// TODO:
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();

View File

@@ -20,11 +20,19 @@ namespace OpenRA.Editor
{
public string MapFolderPath;
public bool DirectoryIsEmpty(string path)
{
return !Directory.GetFileSystemEntries(path).Any();
}
public MapSelect(string currentMod)
{
MapFolderPath = new string[] { Environment.CurrentDirectory, "mods", currentMod, "maps" }
MapFolderPath = new string[] { Platform.SupportDir, "maps", currentMod }
.Aggregate(Path.Combine);
if (!Directory.Exists(MapFolderPath))
Directory.CreateDirectory(MapFolderPath);
InitializeComponent();
MapIconsList.Images.Add(pictureBox1.Image);
}
@@ -34,6 +42,9 @@ namespace OpenRA.Editor
MapList.Items.Clear();
txtPathOut.Text = MapFolderPath;
if (DirectoryIsEmpty(MapFolderPath))
return;
foreach (var map in ModData.FindMapsIn(MapFolderPath))
{
ListViewItem map1 = new ListViewItem();

View File

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

View File

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

View File

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

View File

@@ -26,7 +26,7 @@ namespace OpenRA.Editor
bitmap.Palette = p.AsSystemPalette();
var data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
var data = bitmap.LockBits(bitmap.Bounds(),
ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
unsafe
@@ -84,7 +84,7 @@ namespace OpenRA.Editor
var bitmap = new Bitmap(shp.Width, shp.Height, PixelFormat.Format8bppIndexed);
bitmap.Palette = p.AsSystemPalette();
var data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
var data = bitmap.LockBits(bitmap.Bounds(),
ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
unsafe

View File

@@ -26,6 +26,7 @@ namespace OpenRA.Editor
public Map Map { get; private set; }
public TileSet TileSet { get; private set; }
public Palette Palette { get; private set; }
public Palette PlayerPalette { get; private set; }
public int2 Offset;
public int2 GetOffset() { return Offset; }
@@ -38,6 +39,12 @@ namespace OpenRA.Editor
public bool ShowActorNames;
public bool ShowGrid;
public bool IsPaste { get { return TileSelection != null && ResourceSelection != null; } }
public TileReference<ushort, byte>[,] TileSelection;
public TileReference<byte, byte>[,] ResourceSelection;
public CPos SelectionStart;
public CPos SelectionEnd;
public string NewActorOwner;
public event Action AfterChange = () => { };
@@ -49,17 +56,18 @@ namespace OpenRA.Editor
public Keys GetModifiers() { return ModifierKeys; }
public void Bind(Map m, TileSet ts, Palette p)
public void Bind(Map m, TileSet ts, Palette p, Palette pp)
{
Map = m;
TileSet = ts;
Palette = p;
PlayerPalette = pp;
PlayerPalettes = null;
Chunks.Clear();
Tool = null;
}
public void SetTool(ITool tool) { Tool = tool; }
public void SetTool(ITool tool) { Tool = tool; ClearSelection(); }
public void BindActorTemplates(IEnumerable<ActorTemplate> templates)
{
@@ -83,6 +91,8 @@ namespace OpenRA.Editor
UpdateStyles();
}
static readonly Pen SelectionPen = new Pen(Color.Blue);
static readonly Pen PastePen = new Pen(Color.Green);
static readonly Pen CordonPen = new Pen(Color.Red);
int2 MousePos;
@@ -157,23 +167,23 @@ namespace OpenRA.Editor
void Erase()
{
// Crash preventing
var BrushLocation = GetBrushLocation();
var brushLocation = GetBrushLocation();
if (Map == null || BrushLocation.X >= Map.MapSize.X ||
BrushLocation.Y >= Map.MapSize.Y ||
BrushLocation.X < 0 ||
BrushLocation.Y < 0)
if (Map == null || brushLocation.X >= Map.MapSize.X ||
brushLocation.Y >= Map.MapSize.Y ||
brushLocation.X < 0 ||
brushLocation.Y < 0)
return;
Tool = null;
var key = Map.Actors.Value.FirstOrDefault(a => a.Value.Location() == BrushLocation);
var key = Map.Actors.Value.FirstOrDefault(a => a.Value.Location() == brushLocation);
if (key.Key != null) Map.Actors.Value.Remove(key.Key);
if (Map.MapResources.Value[BrushLocation.X, BrushLocation.Y].type != 0)
if (Map.MapResources.Value[brushLocation.X, brushLocation.Y].type != 0)
{
Map.MapResources.Value[BrushLocation.X, BrushLocation.Y] = new TileReference<byte, byte>();
var ch = new int2((BrushLocation.X) / ChunkSize, (BrushLocation.Y) / ChunkSize);
Map.MapResources.Value[brushLocation.X, brushLocation.Y] = new TileReference<byte, byte>();
var ch = new int2((brushLocation.X) / ChunkSize, (brushLocation.Y) / ChunkSize);
if (Chunks.ContainsKey(ch))
{
Chunks[ch].Dispose();
@@ -182,12 +192,20 @@ namespace OpenRA.Editor
}
AfterChange();
ClearSelection();
}
void Draw()
{
if (Tool != null) Tool.Apply(this);
AfterChange();
if (Tool != null)
{
Tool.Apply(this);
AfterChange();
}
else if (IsPaste)
PasteSelection();
else
SelectionEnd = GetBrushLocationBR();
}
protected override void OnMouseDown(MouseEventArgs e)
@@ -199,7 +217,12 @@ namespace OpenRA.Editor
if (!IsPanning)
{
if (e.Button == MouseButtons.Right) Erase();
if (e.Button == MouseButtons.Left) Draw();
if (e.Button == MouseButtons.Left)
{
Draw();
if (!IsPaste)
SelectionStart = SelectionEnd = GetBrushLocation();
}
}
Invalidate();
@@ -212,7 +235,7 @@ namespace OpenRA.Editor
var bitmap = new Bitmap(ChunkSize * TileSet.TileSize, ChunkSize * TileSet.TileSize);
var data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
var data = bitmap.LockBits(bitmap.Bounds(),
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
unsafe
@@ -234,7 +257,7 @@ namespace OpenRA.Editor
if (Map.MapResources.Value[u * ChunkSize + i, v * ChunkSize + j].type != 0)
{
var resourceImage = ResourceTemplates[Map.MapResources.Value[u * ChunkSize + i, v * ChunkSize + j].type].Bitmap;
var srcdata = resourceImage.LockBits(new Rectangle(0, 0, resourceImage.Width, resourceImage.Height),
var srcdata = resourceImage.LockBits(resourceImage.Bounds(),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
int* q = (int*)srcdata.Scan0.ToPointer();
@@ -267,31 +290,42 @@ namespace OpenRA.Editor
return bitmap;
}
public int2 GetBrushLocation()
public CPos GetBrushLocation()
{
var vX = (int)Math.Floor((MousePos.X - Offset.X) / Zoom);
var vY = (int)Math.Floor((MousePos.Y - Offset.Y) / Zoom);
return new int2(vX / TileSet.TileSize, vY / TileSet.TileSize);
return new CPos(vX / TileSet.TileSize, vY / TileSet.TileSize);
}
public void DrawActor(SGraphics g, int2 p, ActorTemplate t, ColorPalette cp)
public CPos GetBrushLocationBR()
{
var vX = (int)Math.Floor((MousePos.X - Offset.X) / Zoom);
var vY = (int)Math.Floor((MousePos.Y - Offset.Y) / Zoom);
return new CPos((vX + TileSet.TileSize - 1) / TileSet.TileSize,
(vY + TileSet.TileSize - 1) / TileSet.TileSize);
}
public void DrawActor(SGraphics g, CPos p, ActorTemplate t, ColorPalette cp)
{
var centered = t.Appearance == null || !t.Appearance.RelativeToTopLeft;
DrawImage(g, t.Bitmap, p, centered, cp);
var actorPalette = cp;
if (t.Appearance != null && t.Appearance.UseTerrainPalette)
actorPalette = Palette.AsSystemPalette();
DrawImage(g, t.Bitmap, p, centered, actorPalette);
}
float2 GetDrawPosition(int2 location, Bitmap bmp, bool centered)
float2 GetDrawPosition(CPos location, Bitmap bmp, bool centered)
{
float OffsetX = centered ? bmp.Width / 2 - TileSet.TileSize / 2 : 0;
float DrawX = TileSet.TileSize * location.X * Zoom + Offset.X - OffsetX;
float offsetX = centered ? bmp.Width / 2 - TileSet.TileSize / 2 : 0;
float drawX = TileSet.TileSize * location.X * Zoom + Offset.X - offsetX;
float OffsetY = centered ? bmp.Height / 2 - TileSet.TileSize / 2 : 0;
float DrawY = TileSet.TileSize * location.Y * Zoom + Offset.Y - OffsetY;
float offsetY = centered ? bmp.Height / 2 - TileSet.TileSize / 2 : 0;
float drawY = TileSet.TileSize * location.Y * Zoom + Offset.Y - offsetY;
return new float2(DrawX, DrawY);
return new float2(drawX, drawY);
}
public void DrawImage(SGraphics g, Bitmap bmp, int2 location, bool centered, ColorPalette cp)
public void DrawImage(SGraphics g, Bitmap bmp, CPos location, bool centered, ColorPalette cp)
{
var drawPos = GetDrawPosition(location, bmp, centered);
@@ -304,7 +338,7 @@ namespace OpenRA.Editor
if (cp != null) bmp.Palette = restorePalette;
}
void DrawActorBorder(SGraphics g, int2 p, ActorTemplate t)
void DrawActorBorder(SGraphics g, CPos p, ActorTemplate t)
{
var centered = t.Appearance == null || !t.Appearance.RelativeToTopLeft;
var drawPos = GetDrawPosition(p, t.Bitmap, centered);
@@ -318,8 +352,8 @@ namespace OpenRA.Editor
{
var pr = Map.Players[name];
var pcpi = Rules.Info["player"].Traits.Get<PlayerColorPaletteInfo>();
var remap = new PlayerColorRemap(pcpi.PaletteFormat, pr.ColorRamp);
return new Palette(Palette, remap).AsSystemPalette();
var remap = new PlayerColorRemap(pcpi.RemapIndex, pr.ColorRamp);
return new Palette(PlayerPalette, remap).AsSystemPalette();
}
Cache<string, ColorPalette> PlayerPalettes;
@@ -352,7 +386,7 @@ namespace OpenRA.Editor
var x = new int2(u / ChunkSize, v / ChunkSize);
if (!Chunks.ContainsKey(x)) Chunks[x] = RenderChunk(u / ChunkSize, v / ChunkSize);
Bitmap bmp = Chunks[x];
var bmp = Chunks[x];
float DrawX = TileSet.TileSize * (float)ChunkSize * (float)x.X * Zoom + Offset.X;
float DrawY = TileSet.TileSize * (float)ChunkSize * (float)x.Y * Zoom + Offset.Y;
@@ -367,6 +401,25 @@ namespace OpenRA.Editor
Map.Bounds.Width * TileSet.TileSize * Zoom,
Map.Bounds.Height * TileSet.TileSize * Zoom);
e.Graphics.DrawRectangle(SelectionPen,
(SelectionStart.X * TileSet.TileSize * Zoom) + Offset.X,
(SelectionStart.Y * TileSet.TileSize * Zoom) + Offset.Y,
(SelectionEnd - SelectionStart).X * TileSet.TileSize * Zoom,
(SelectionEnd - SelectionStart).Y * TileSet.TileSize * Zoom);
if (IsPaste)
{
var loc = GetBrushLocation();
var width = Math.Abs((SelectionStart - SelectionEnd).X);
var height = Math.Abs((SelectionStart - SelectionEnd).Y);
e.Graphics.DrawRectangle(PastePen,
(loc.X * TileSet.TileSize * Zoom) + Offset.X,
(loc.Y * TileSet.TileSize * Zoom) + Offset.Y,
width * (TileSet.TileSize * Zoom),
height * (TileSet.TileSize * Zoom));
}
foreach (var ar in Map.Actors.Value)
{
if (ActorTemplates.ContainsKey(ar.Value.Type))
@@ -395,13 +448,74 @@ namespace OpenRA.Editor
DrawActorBorder(e.Graphics, x.Value.Location(), ActorTemplates[x.Value.Type]);
}
}
public void CopySelection()
{
// Grab tiles and resources within selection (doesn't do actors)
var start = SelectionStart;
var end = SelectionEnd;
if (start == end) return;
int width = Math.Abs((start - end).X);
int height = Math.Abs((start - end).Y);
TileSelection = new TileReference<ushort, byte>[width, height];
ResourceSelection = new TileReference<byte, byte>[width, height];
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
//TODO: crash prevention
TileSelection[x, y] = Map.MapTiles.Value[start.X + x, start.Y + y];
ResourceSelection[x, y] = Map.MapResources.Value[start.X + x, start.Y + y];
}
}
}
void PasteSelection()
{
var loc = GetBrushLocation();
var width = Math.Abs((SelectionStart - SelectionEnd).X);
var height = Math.Abs((SelectionStart - SelectionEnd).Y);
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
var mapX = loc.X + x;
var mapY = loc.Y + y;
//TODO: crash prevention for outside of bounds
Map.MapTiles.Value[mapX, mapY] = TileSelection[x, y];
Map.MapResources.Value[mapX, mapY] = ResourceSelection[x, y];
var ch = new int2(mapX / ChunkSize, mapY / ChunkSize);
if (Chunks.ContainsKey(ch))
{
Chunks[ch].Dispose();
Chunks.Remove(ch);
}
}
}
AfterChange();
}
void ClearSelection()
{
SelectionStart = CPos.Zero;
SelectionEnd = CPos.Zero;
TileSelection = null;
ResourceSelection = null;
}
}
static class ActorReferenceExts
{
public static int2 Location(this ActorReference ar)
public static CPos Location(this ActorReference ar)
{
return ar.InitDict.Get<LocationInit>().value;
return (CPos)ar.InitDict.Get<LocationInit>().value;
}
public static void DrawStringContrast(this SGraphics g, Font f, string s, int x, int y, Brush fg, Brush bg)

View File

@@ -21,8 +21,6 @@ namespace OpenRA.FileFormats
H = h; S = s; L = l; R = r;
}
public static readonly ColorRamp Empty = new ColorRamp(0,0,0,0);
/* returns a color along the Lum ramp */
public Color GetColor( float t )
{
@@ -35,7 +33,7 @@ namespace OpenRA.FileFormats
}
// hk is hue in the range [0,1] instead of [0,360]
public static Color ColorFromHSL(float hk, float s, float l)
static Color ColorFromHSL(float hk, float s, float l)
{
// Convert from HSL to RGB
var q = (l < 0.5f) ? l * (1 + s) : l + s - (l * s);

View File

@@ -172,6 +172,8 @@ namespace OpenRA
return v;
}
public static Size NextPowerOf2(this Size s) { return new Size(NextPowerOf2(s.Width), NextPowerOf2(s.Height)); }
public static string JoinWith<T>(this IEnumerable<T> ts, string j)
{
return string.Join(j, ts.Select(t => t.ToString()).ToArray());
@@ -181,5 +183,83 @@ namespace OpenRA
{
return ts.Concat(moreTs);
}
public static Dictionary<TKey, TSource> ToDictionaryWithConflictLog<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, string debugName, Func<TKey, string> logKey, Func<TSource, string> logValue)
{
return ToDictionaryWithConflictLog(source, keySelector, x => x, debugName, logKey, logValue);
}
public static Dictionary<TKey, TElement> ToDictionaryWithConflictLog<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, string debugName, Func<TKey, string> logKey, Func<TElement, string> logValue)
{
// Fall back on ToString() if null functions are provided:
logKey = logKey ?? (s => s.ToString());
logValue = logValue ?? (s => s.ToString());
// Try to build a dictionary and log all duplicates found (if any):
var dupKeys = new Dictionary<TKey, List<string>>();
var d = new Dictionary<TKey, TElement>();
foreach (var item in source)
{
TKey key = keySelector(item);
TElement element = elementSelector(item);
// Check for a key conflict:
if (d.ContainsKey(key))
{
List<string> dupKeyMessages;
if (!dupKeys.TryGetValue(key, out dupKeyMessages))
{
// Log the initial conflicting value already inserted:
dupKeyMessages = new List<string>();
dupKeyMessages.Add(logValue(d[key]));
dupKeys.Add(key, dupKeyMessages);
}
// Log this conflicting value:
dupKeyMessages.Add(logValue(element));
continue;
}
d.Add(key, element);
}
// If any duplicates were found, log it and throw a descriptive error
if (dupKeys.Count > 0)
{
string badKeysFormatted = String.Join(", ", dupKeys.Select(p => "{0}: [{1}]".F(logKey(p.Key), String.Join(",", p.Value.ToArray()))).ToArray());
string msg = "{0}, duplicate values found for the following keys: {1}".F(debugName, badKeysFormatted);
Log.Write("debug", msg);
throw new ArgumentException(msg);
}
// Return the dictionary we built:
return d;
}
public static Color ColorLerp(float t, Color c1, Color c2)
{
return Color.FromArgb(
(int)(t * c2.A + (1 - t) * c1.A),
(int)(t * c2.R + (1 - t) * c1.R),
(int)(t * c2.G + (1 - t) * c1.G),
(int)(t * c2.B + (1 - t) * c1.B));
}
public static T[] MakeArray<T>(int count, Func<int, T> f)
{
T[] result = new T[count];
for (int i = 0; i < count; i++)
result[i] = f(i);
return result;
}
public static Rectangle Bounds(this Bitmap b) { return new Rectangle(0, 0, b.Width, b.Height); }
}
public static class Enum<T>
{
public static T Parse(string s) { return (T)Enum.Parse(typeof(T), s); }
public static T[] GetValues() { return (T[])Enum.GetValues(typeof(T)); }
}
}

View File

@@ -56,6 +56,11 @@ namespace OpenRA.FileFormats
ret = GetValue( fieldName, fieldType, n[ 0 ].Value.Value );
return true;
}
else if ( n.Count > 1 )
{
throw new InvalidOperationException("The field {0} has multiple definitions:\n{1}"
.F(fieldName, n.Select(m => "\t- " + m.Location).JoinWith("\n")));
}
throw new InvalidOperationException( "TryGetValueFromYaml: unable to load field {0} (of type {1})".F( fieldName, fieldType ) );
}
@@ -320,6 +325,10 @@ namespace OpenRA.FileFormats
((int)c.B).Clamp(0, 255));
}
// Don't save floats in settings.yaml using country-specific decimal separators which can be misunderstood as group seperators.
if (t == typeof(float))
return ((float)v).ToString(CultureInfo.InvariantCulture);
if (t == typeof(Rectangle))
{
var r = (Rectangle)v;
@@ -342,4 +351,11 @@ namespace OpenRA.FileFormats
}
public class FieldFromYamlKeyAttribute : Attribute { }
// mirrors DescriptionAttribute from System.ComponentModel but we dont want to have to use that everywhere.
public class DescAttribute : Attribute
{
public readonly string[] Lines;
public DescAttribute(params string[] lines) { Lines = lines; }
}
}

View File

@@ -19,24 +19,6 @@ namespace OpenRA.FileFormats
{
const string pubkeyStr = "AihRvNoIbTn85FZRYNZRcT+i6KpU+maCsEqr3Q5q+LDB5tH7Tz2qQ38V";
static sbyte[] char2num = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
class PublicKey
{
public uint[] key1 = new uint[64];
@@ -128,25 +110,9 @@ namespace OpenRA.FileFormats
void init_pubkey()
{
int i = 0;
uint i2, tmp;
byte[] keytmp = new byte[256];
init_bignum(pubkey.key2, 0x10001, 64);
i2 = 0;
while (i < pubkeyStr.Length)
{
tmp = (uint)char2num[pubkeyStr[i++]];
tmp <<= 6; tmp |= (uint)(byte)char2num[pubkeyStr[i++]];
tmp <<= 6; tmp |= (uint)(byte)char2num[pubkeyStr[i++]];
tmp <<= 6; tmp |= (uint)(byte)char2num[pubkeyStr[i++]];
keytmp[i2++] = (byte)((tmp >> 16) & 0xff);
keytmp[i2++] = (byte)((tmp >> 8) & 0xff);
keytmp[i2++] = (byte)(tmp & 0xff);
}
key_to_bignum(pubkey.key1, keytmp, 64);
key_to_bignum(pubkey.key1, Convert.FromBase64String(pubkeyStr), 64);
pubkey.len = bitlen_bignum(pubkey.key1, 64) - 1;
}

View File

@@ -158,21 +158,20 @@ namespace OpenRA.FileFormats
public static Assembly ResolveAssembly(object sender, ResolveEventArgs e)
{
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
if (assembly.FullName == e.Name)
return assembly;
}
string[] frags = e.Name.Split(',');
var frags = e.Name.Split(',');
var filename = frags[0] + ".dll";
Assembly a;
if (assemblyCache.TryGetValue(filename, out a))
return a;
if (FileSystem.Exists(filename))
using (Stream s = FileSystem.Open(filename))
using (var s = FileSystem.Open(filename))
{
byte[] buf = new byte[s.Length];
var buf = new byte[s.Length];
s.Read(buf, 0, buf.Length);
a = Assembly.Load(buf);
assemblyCache.Add(filename, a);

View File

@@ -58,7 +58,9 @@ namespace OpenRA.FileFormats
isEncrypted = 0 != (signature & (uint)MixFileFlags.Encrypted);
if( isEncrypted )
{
index = ParseRaHeader( s, out dataStart ).ToDictionary(x => x.Hash);
index = ParseRaHeader(s, out dataStart).ToDictionaryWithConflictLog(x => x.Hash,
"MixFile.RaHeader", null, x => "(offs={0}, len={1})".F(x.Offset, x.Length)
);
return;
}
}
@@ -66,7 +68,9 @@ namespace OpenRA.FileFormats
s.Seek( 0, SeekOrigin.Begin );
isEncrypted = false;
index = ParseTdHeader(s, out dataStart).ToDictionary(x => x.Hash);
index = ParseTdHeader(s, out dataStart).ToDictionaryWithConflictLog(x => x.Hash,
"MixFile.TdHeader", null, x => "(offs={0}, len={1})".F(x.Offset, x.Length)
);
}
const long headerStart = 84;

View File

@@ -40,7 +40,6 @@ namespace OpenRA.FileFormats.Graphics
IShader CreateShader( string name );
Size WindowSize { get; }
int GpuMemoryUsed { get; }
void Clear();
void Present();
@@ -61,9 +60,9 @@ namespace OpenRA.FileFormats.Graphics
public interface IShader
{
void SetValue( string name, float x, float y );
void SetValue( string param, ITexture texture );
void Render( Action a );
void SetVec(string name, float x, float y);
void SetTexture(string param, ITexture texture);
void Render(Action a);
}
public interface ITexture

View File

@@ -97,7 +97,7 @@ namespace OpenRA.FileFormats.Graphics
case "IEND":
{
var bits = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
var bits = bitmap.LockBits(bitmap.Bounds(),
ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
using (var ns = new MemoryStream(data.ToArray()))

View File

@@ -8,10 +8,10 @@
*/
#endregion
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
namespace OpenRA.FileFormats
{
@@ -30,9 +30,9 @@ namespace OpenRA.FileFormats
public ImageHeader( BinaryReader reader )
{
Offset = reader.ReadUInt32();
Format = (Format)( Offset >> 24 );
Offset &= 0xFFFFFF;
var data = reader.ReadUInt32();
Offset = data & 0xffffff;
Format = (Format)(data >> 24);
RefOffset = reader.ReadUInt16();
RefFormat = (Format)reader.ReadUInt16();
@@ -48,14 +48,9 @@ namespace OpenRA.FileFormats
}
}
public enum Format
{
Format20 = 0x20,
Format40 = 0x40,
Format80 = 0x80,
}
public enum Format { Format20 = 0x20, Format40 = 0x40, Format80 = 0x80 }
public class ShpReader : IEnumerable<ImageHeader>
public class ShpReader
{
public readonly int ImageCount;
public readonly ushort Width;
@@ -69,40 +64,37 @@ namespace OpenRA.FileFormats
public ShpReader( Stream stream )
{
BinaryReader reader = new BinaryReader( stream );
ImageCount = reader.ReadUInt16();
reader.ReadUInt16();
reader.ReadUInt16();
Width = reader.ReadUInt16();
Height = reader.ReadUInt16();
reader.ReadUInt32();
for( int i = 0 ; i < ImageCount ; i++ )
headers.Add( new ImageHeader( reader ) );
new ImageHeader( reader ); // end-of-file header
new ImageHeader( reader ); // all-zeroes header
Dictionary<uint, ImageHeader> offsets = new Dictionary<uint, ImageHeader>();
foreach( ImageHeader h in headers )
offsets.Add( h.Offset, h );
for( int i = 0 ; i < ImageCount ; i++ )
using( var reader = new BinaryReader( stream ) )
{
ImageHeader h = headers[ i ];
if( h.Format == Format.Format20 )
h.RefImage = headers[ i - 1 ];
ImageCount = reader.ReadUInt16();
reader.ReadUInt16();
reader.ReadUInt16();
Width = reader.ReadUInt16();
Height = reader.ReadUInt16();
reader.ReadUInt32();
else if( h.Format == Format.Format40 )
for( int i = 0 ; i < ImageCount ; i++ )
headers.Add( new ImageHeader( reader ) );
new ImageHeader( reader ); // end-of-file header
new ImageHeader( reader ); // all-zeroes header
var offsets = headers.ToDictionary(h => h.Offset, h =>h);
for( int i = 0 ; i < ImageCount ; i++ )
{
if( !offsets.TryGetValue( h.RefOffset, out h.RefImage ) )
throw new InvalidDataException( "Reference doesnt point to image data {0}->{1}".F(h.Offset, h.RefOffset) );
}
}
var h = headers[ i ];
if( h.Format == Format.Format20 )
h.RefImage = headers[ i - 1 ];
foreach( ImageHeader h in headers )
Decompress( stream, h );
else if( h.Format == Format.Format40 )
if( !offsets.TryGetValue( h.RefOffset, out h.RefImage ) )
throw new InvalidDataException( "Reference doesnt point to image data {0}->{1}".F(h.Offset, h.RefOffset) );
}
foreach( ImageHeader h in headers )
Decompress( stream, h );
}
}
public ImageHeader this[ int index ]
@@ -133,7 +125,7 @@ namespace OpenRA.FileFormats
}
case Format.Format80:
{
byte[] imageBytes = new byte[ Width * Height ];
var imageBytes = new byte[ Width * Height ];
Format80.DecodeInto( ReadCompressedData( stream, h ), imageBytes );
h.Image = imageBytes;
break;
@@ -147,33 +139,24 @@ namespace OpenRA.FileFormats
{
stream.Position = h.Offset;
// Actually, far too big. There's no length field with the correct length though :(
int compressedLength = (int)( stream.Length - stream.Position );
var compressedLength = (int)( stream.Length - stream.Position );
byte[] compressedBytes = new byte[ compressedLength ];
var compressedBytes = new byte[ compressedLength ];
stream.Read( compressedBytes, 0, compressedLength );
//MemoryStream ms = new MemoryStream( compressedBytes );
return compressedBytes;
}
byte[] CopyImageData( byte[] baseImage )
{
byte[] imageData = new byte[ Width * Height ];
var imageData = new byte[ Width * Height ];
for( int i = 0 ; i < Width * Height ; i++ )
imageData[ i ] = baseImage[ i ];
return imageData;
}
public IEnumerator<ImageHeader> GetEnumerator()
{
return headers.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IEnumerable<ImageHeader> Frames { get { return headers; } }
public static ShpReader Load(string filename)
{

View File

@@ -20,7 +20,7 @@ namespace OpenRA.FileFormats
public readonly string[]
Mods, Folders, Packages, Rules, ServerTraits,
Sequences, Cursors, Chrome, Assemblies, ChromeLayout,
Weapons, Voices, Music, Movies, TileSets, ChromeMetrics;
Weapons, Voices, Notifications, Music, Movies, TileSets, ChromeMetrics;
public readonly MiniYaml LoadScreen;
public readonly Dictionary<string, Pair<string,int>> Fonts;
public readonly int TileSize = 24;
@@ -32,7 +32,7 @@ namespace OpenRA.FileFormats
.Select(m => MiniYaml.FromFile("mods/" + m + "/mod.yaml"))
.Aggregate(MiniYaml.MergeLiberal)).NodesDict;
// Todo: Use fieldloader
// TODO: Use fieldloader
Folders = YamlList(yaml, "Folders");
Packages = YamlList(yaml, "Packages");
Rules = YamlList(yaml, "Rules");
@@ -44,6 +44,7 @@ namespace OpenRA.FileFormats
ChromeLayout = YamlList(yaml, "ChromeLayout");
Weapons = YamlList(yaml, "Weapons");
Voices = YamlList(yaml, "Voices");
Notifications = YamlList(yaml, "Notifications");
Music = YamlList(yaml, "Music");
Movies = YamlList(yaml, "Movies");
TileSets = YamlList(yaml, "TileSets");

View File

@@ -23,6 +23,7 @@ namespace OpenRA.FileFormats
public string Bot = null;
public bool DefaultStartingUnits = false;
public bool AllowBots = true;
public bool Required = false;
public bool LockRace = false;
public string Race;

View File

@@ -20,9 +20,10 @@ namespace OpenRA.FileFormats
public class TerrainTypeInfo
{
public string Type;
public bool AcceptSmudge = true;
public string[] AcceptsSmudgeType = { };
public bool IsWater = false;
public Color Color;
public string CustomCursor;
public TerrainTypeInfo() {}
public TerrainTypeInfo(MiniYaml my) { FieldLoader.Load(this, my); }
@@ -36,6 +37,7 @@ namespace OpenRA.FileFormats
public string Image;
public int2 Size;
public bool PickAny;
public string Category;
[FieldLoader.LoadUsing( "LoadTiles" )]
public Dictionary<byte, string> Tiles = new Dictionary<byte, string>();
@@ -76,10 +78,13 @@ namespace OpenRA.FileFormats
public string Name;
public string Id;
public string Palette;
public string PlayerPalette;
public int TileSize = 24;
public string[] Extensions;
public int WaterPaletteRotationBase = 0x60;
public Dictionary<string, TerrainTypeInfo> Terrain = new Dictionary<string, TerrainTypeInfo>();
public Dictionary<ushort, TileTemplate> Templates = new Dictionary<ushort, TileTemplate>();
public string[] EditorTemplateOrder;
static readonly string[] fields = {"Name", "TileSize", "Id", "Palette", "Extensions"};
@@ -166,7 +171,7 @@ namespace OpenRA.FileFormats
bitmap.Palette = p.AsSystemPalette();
var data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
var data = bitmap.LockBits(bitmap.Bounds(),
ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
unsafe

View File

@@ -105,22 +105,26 @@ namespace OpenRA.FileFormats
levels.Add(new List<MiniYamlNode>());
var lineNo = 0;
foreach (var line in lines)
foreach (var ll in lines)
{
var line = ll;
++lineNo;
if (line.Contains('#'))
line = line.Substring(0, line.IndexOf('#')).TrimEnd(' ', '\t');
var t = line.TrimStart(' ', '\t');
if (t.Length == 0 || t[0] == '#')
if (t.Length == 0)
continue;
var level = line.Length - t.Length;
var location = new MiniYamlNode.SourceLocation { Filename = filename, Line = lineNo };
if (levels.Count <= level)
throw new YamlException("Bad indent in miniyaml");
throw new YamlException("Bad indent in miniyaml at {0}".F (location));
while (levels.Count > level + 1)
levels.RemoveAt(levels.Count - 1);
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[ level ].Add( new MiniYamlNode( t, rhs, d, location ) );
levels.Add(d);
}
@@ -196,8 +200,8 @@ namespace OpenRA.FileFormats
var ret = new List<MiniYamlNode>();
var aDict = a.ToDictionary( x => x.Key );
var bDict = b.ToDictionary( x => x.Key );
var aDict = a.ToDictionaryWithConflictLog(x => x.Key, "MiniYaml.Merge", null, x => "{0} (at {1})".F(x.Key, x.Location));
var bDict = b.ToDictionaryWithConflictLog(x => x.Key, "MiniYaml.Merge", null, x => "{0} (at {1})".F(x.Key, x.Location));
var keys = aDict.Keys.Union( bDict.Keys ).ToList();
var noInherit = keys.Where(x => x.Length > 0 && x[0] == '-')

View File

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

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2012 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
@@ -39,7 +39,13 @@ namespace OpenRA.FileFormats
get { return colors; }
}
public Palette(Stream s, bool remapTransparent)
public void ApplyRemap(IPaletteRemap r)
{
for(int i = 0; i < 256; i++)
colors[i] = (uint)r.GetRemappedColor(Color.FromArgb((int)colors[i]),i).ToArgb();
}
public Palette(Stream s, int[] remapShadow)
{
colors = new uint[256];
@@ -54,20 +60,15 @@ namespace OpenRA.FileFormats
}
}
colors[0] = 0;
if (remapTransparent)
{
colors[1] = 178u << 24; // Hack for d2k; may have side effects
colors[3] = 178u << 24;
colors[4] = 140u << 24;
}
colors[0] = 0; //convert black background to transparency
foreach (int i in remapShadow)
colors[i] = 140u << 24;
}
public Palette(Palette p, IPaletteRemap r)
{
colors = new uint[256];
for(int i = 0; i < 256; i++)
colors[i] = (uint)r.GetRemappedColor(Color.FromArgb((int)p.colors[i]),i).ToArgb();
colors = (uint[])p.colors.Clone();
ApplyRemap(r);
}
public Palette(Palette p)
@@ -75,6 +76,13 @@ namespace OpenRA.FileFormats
colors = (uint[])p.colors.Clone();
}
public Palette(uint[] data)
{
if (data.Length != 256)
throw new InvalidDataException("Attempting to create palette with incorrect array size");
colors = (uint[])data.Clone();
}
public ColorPalette AsSystemPalette()
{
ColorPalette pal;
@@ -92,12 +100,27 @@ namespace OpenRA.FileFormats
return pal;
}
public static Palette Load( string filename, bool remap )
public Bitmap AsBitmap()
{
var b = new Bitmap(256, 1, PixelFormat.Format32bppArgb);
var data = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
unsafe
{
uint* c = (uint*)data.Scan0;
for (var x = 0; x < 256; x++)
*(c + x) = colors[x];
}
b.UnlockBits(data);
return b;
}
public static Palette Load(string filename, int[] remap)
{
using(var s = File.OpenRead(filename))
return new Palette(s, remap);
}
}
public interface IPaletteRemap { Color GetRemappedColor(Color original, int index); }
public interface IPaletteRemap { Color GetRemappedColor(Color original, int index); }
}

View File

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

View File

@@ -56,7 +56,7 @@ namespace OpenRA.FileFormats
public int CompareTo(DelayedAction other)
{
return Math.Sign(Time - other.Time);
return Time.CompareTo(other.Time);
}
}
}

View File

@@ -12,7 +12,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
namespace OpenRA.Collections
namespace OpenRA.FileFormats
{
public class Set<T> : IEnumerable<T>
{
@@ -44,5 +44,13 @@ namespace OpenRA.Collections
{
return GetEnumerator();
}
public bool Contains( T obj ) { return data.ContainsKey(obj); }
public Set( params T[] ts )
{
foreach( var t in ts )
Add(t);
}
}
}

View File

@@ -101,4 +101,18 @@ namespace OpenRA
public float LengthSquared { get { return X * X + Y * Y; } }
public float Length { get { return (float)Math.Sqrt(LengthSquared); } }
}
public class EWMA
{
readonly float animRate;
float? value;
public EWMA(float animRate) { this.animRate = animRate; }
public float Update(float newValue)
{
value = float2.Lerp(value ?? newValue, newValue, animRate);
return value.Value;
}
}
}

View File

@@ -20,6 +20,7 @@ namespace OpenRA.Thirdparty
int index = 0;
public int Last;
public int TotalCount = 0;
public Random() : this(Environment.TickCount) { }
@@ -41,13 +42,14 @@ namespace OpenRA.Thirdparty
y ^= y >> 18;
index = (index + 1) % 624;
TotalCount++;
Last = (int)(y % int.MaxValue);
return Last;
}
public int Next(int low, int high) { return low + Next() % (high - low); }
public int Next(int high) { return Next() % high; }
public double NextDouble() { return Math.Abs(Next() / (double)0x7fffffff); }
public float NextFloat() { return Math.Abs(Next() / (float)0x7fffffff); }
void Generate()
{

View File

@@ -13,6 +13,7 @@ using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA
@@ -32,9 +33,9 @@ namespace OpenRA
public IOccupySpace OccupiesSpace { get { return occupySpace.Value; } }
public int2 Location { get { return occupySpace.Value.TopLeft; } }
public CPos Location { get { return occupySpace.Value.TopLeft; } }
public int2 CenterLocation
public PPos CenterLocation
{
get
{
@@ -43,9 +44,10 @@ namespace OpenRA
return HasLocation.PxPosition;
}
}
public Shroud.ActorVisibility Sight;
[Sync]
public Player Owner;
[Sync] public Player Owner;
Activity currentActivity;
public Group Group;
@@ -71,7 +73,7 @@ namespace OpenRA
AddTrait(trait.Create(init));
}
Move = Lazy.New( () => TraitOrDefault<IMove>() );
Move = Lazy.New(() => TraitOrDefault<IMove>());
Size = Lazy.New(() =>
{
@@ -79,17 +81,23 @@ namespace OpenRA
if (si != null && si.Bounds != null)
return new int2(si.Bounds[0], si.Bounds[1]);
// auto size from render
var firstSprite = TraitsImplementing<IRender>().SelectMany(ApplyIRender).FirstOrDefault();
if (firstSprite.Sprite == null) return int2.Zero;
return (firstSprite.Sprite.size * firstSprite.Scale).ToInt2();
return TraitsImplementing<IAutoSelectionSize>().Select(x => x.SelectionSize(this)).FirstOrDefault();
});
ApplyIRender = x => x.Render(this);
ApplyRenderModifier = (m, p) => p.ModifyRender(this, m);
if (this.HasTrait<RevealsShroud>())
{
Sight = new Shroud.ActorVisibility
{
range = this.Trait<RevealsShroud>().RevealRange,
vis = Shroud.GetVisOrigins(this).ToArray()
};
}
Bounds = Cached.New( () => CalculateBounds(false) );
ExtendedBounds = Cached.New( () => CalculateBounds(true) );
ApplyIRender = (x, wr) => x.Render(this, wr);
ApplyRenderModifier = (m, p, wr) => p.ModifyRender(this, wr, m);
Bounds = Cached.New(() => CalculateBounds(false));
ExtendedBounds = Cached.New(() => CalculateBounds(true));
}
public void Tick()
@@ -97,7 +105,12 @@ namespace OpenRA
Bounds.Invalidate();
ExtendedBounds.Invalidate();
currentActivity = Util.RunActivity( this, currentActivity );
currentActivity = Traits.Util.RunActivity( this, currentActivity );
}
public void UpdateSight()
{
Sight.vis = Shroud.GetVisOrigins(this).ToArray();
}
public bool IsIdle
@@ -108,13 +121,13 @@ namespace OpenRA
OpenRA.FileFormats.Lazy<int2> Size;
// note: these delegates are cached to avoid massive allocation.
Func<IRender, IEnumerable<Renderable>> ApplyIRender;
Func<IEnumerable<Renderable>, IRenderModifier, IEnumerable<Renderable>> ApplyRenderModifier;
public IEnumerable<Renderable> Render()
Func<IRender, WorldRenderer, IEnumerable<Renderable>> ApplyIRender;
Func<IEnumerable<Renderable>, IRenderModifier, WorldRenderer, IEnumerable<Renderable>> ApplyRenderModifier;
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
var mods = TraitsImplementing<IRenderModifier>();
var sprites = TraitsImplementing<IRender>().SelectMany(ApplyIRender);
return mods.Aggregate(sprites, ApplyRenderModifier);
var sprites = TraitsImplementing<IRender>().SelectMany(x => ApplyIRender(x, wr));
return mods.Aggregate(sprites, (m,p) => ApplyRenderModifier(m,p,wr));
}
// When useAltitude = true, the bounding box is extended
@@ -123,22 +136,22 @@ namespace OpenRA
// at its current altitude
Rectangle CalculateBounds(bool useAltitude)
{
var size = Size.Value;
var size = (PVecInt)(Size.Value);
var loc = CenterLocation - size / 2;
var si = Info.Traits.GetOrDefault<SelectableInfo>();
if (si != null && si.Bounds != null && si.Bounds.Length > 2)
{
loc.X += si.Bounds[2];
loc.Y += si.Bounds[3];
loc += new PVecInt(si.Bounds[2], si.Bounds[3]);
}
var move = Move.Value;
if (move != null)
{
loc.Y -= move.Altitude;
loc -= new PVecInt(0, move.Altitude);
if (useAltitude)
size = new int2(size.X, size.Y + move.Altitude);
size = new PVecInt(size.X, size.Y + move.Altitude);
}
return new Rectangle(loc.X, loc.Y, size.X, size.Y);
@@ -227,15 +240,20 @@ namespace OpenRA
} );
}
// todo: move elsewhere.
// TODO: move elsewhere.
public void ChangeOwner(Player newOwner)
{
World.AddFrameEndTask(w =>
{
var oldOwner = Owner;
// momentarily remove from world so the ownership queries don't get confused
w.Remove(this);
Owner = newOwner;
w.Add(this);
foreach (var t in this.TraitsImplementing<INotifyOwnerChanged>())
t.OnOwnerChanged(this, oldOwner, newOwner);
});
}
}

View File

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

View File

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

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

@@ -0,0 +1,71 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Drawing;
namespace OpenRA
{
/// <summary>
/// Cell coordinate position in the world (coarse).
/// </summary>
public struct CPos
{
public readonly int X, Y;
public CPos(int x, int y) { X = x; Y = y; }
public static readonly CPos Zero = new CPos(0, 0);
public static explicit operator CPos(int2 a) { return new CPos(a.X, a.Y); }
public static CPos operator +(CVec a, CPos b) { return new CPos(a.X + b.X, a.Y + b.Y); }
public static CPos operator +(CPos a, CVec b) { return new CPos(a.X + b.X, a.Y + b.Y); }
public static CPos operator -(CPos a, CVec b) { return new CPos(a.X - b.X, a.Y - b.Y); }
public static CVec operator -(CPos a, CPos b) { return new CVec(a.X - b.X, a.Y - b.Y); }
public static bool operator ==(CPos me, CPos other) { return (me.X == other.X && me.Y == other.Y); }
public static bool operator !=(CPos me, CPos other) { return !(me == other); }
public static CPos Max(CPos a, CPos b) { return new CPos(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
public static CPos Min(CPos a, CPos b) { return new CPos(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
public float2 ToFloat2() { return new float2(X, Y); }
public int2 ToInt2() { return new int2(X, Y); }
public PPos ToPPos() { return new PPos(Game.CellSize * X, Game.CellSize * Y); }
public CPos Clamp(Rectangle r)
{
return new CPos(Math.Min(r.Right, Math.Max(X, r.Left)),
Math.Min(r.Bottom, Math.Max(Y, r.Top)));
}
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
public override bool Equals(object obj)
{
if (obj == null)
return false;
CPos o = (CPos)obj;
return o == this;
}
public override string ToString() { return "{0},{1}".F(X, Y); }
}
public static class RectangleExtensions
{
public static CPos TopLeftAsCPos(this Rectangle r) { return new CPos(r.Left, r.Top); }
public static CPos BottomRightAsCPos(this Rectangle r) { return new CPos(r.Right, r.Bottom); }
}
}

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

@@ -0,0 +1,76 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Drawing;
namespace OpenRA
{
/// <summary>
/// Cell coordinate vector (coarse).
/// </summary>
public struct CVec
{
public readonly int X, Y;
public CVec(int x, int y) { X = x; Y = y; }
public CVec(Size p) { X = p.Width; Y = p.Height; }
public static readonly CVec Zero = new CVec(0, 0);
public static explicit operator CVec(int2 a) { return new CVec(a.X, a.Y); }
public static explicit operator CVec(float2 a) { return new CVec((int)a.X, (int)a.Y); }
public static CVec operator +(CVec a, CVec b) { return new CVec(a.X + b.X, a.Y + b.Y); }
public static CVec operator -(CVec a, CVec b) { return new CVec(a.X - b.X, a.Y - b.Y); }
public static CVec operator *(int a, CVec b) { return new CVec(a * b.X, a * b.Y); }
public static CVec operator *(CVec b, int a) { return new CVec(a * b.X, a * b.Y); }
public static CVec operator /(CVec a, int b) { return new CVec(a.X / b, a.Y / b); }
public static CVec operator -(CVec a) { return new CVec(-a.X, -a.Y); }
public static bool operator ==(CVec me, CVec other) { return (me.X == other.X && me.Y == other.Y); }
public static bool operator !=(CVec me, CVec other) { return !(me == other); }
public static CVec Max(CVec a, CVec b) { return new CVec(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
public static CVec Min(CVec a, CVec b) { return new CVec(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
public static int Dot(CVec a, CVec b) { return a.X * b.X + a.Y * b.Y; }
public CVec Sign() { return new CVec(Math.Sign(X), Math.Sign(Y)); }
public CVec Abs() { return new CVec(Math.Abs(X), Math.Abs(Y)); }
public int LengthSquared { get { return X * X + Y * Y; } }
public int Length { get { return (int)Math.Sqrt(LengthSquared); } }
public float2 ToFloat2() { return new float2(X, Y); }
public int2 ToInt2() { return new int2(X, Y); }
public CVec Clamp(Rectangle r)
{
return new CVec(
Math.Min(r.Right, Math.Max(X, r.Left)),
Math.Min(r.Bottom, Math.Max(Y, r.Top))
);
}
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
public override bool Equals(object obj)
{
if (obj == null)
return false;
CVec o = (CVec)obj;
return o == this;
}
public override string ToString() { return "{0},{1}".F(X, Y); }
}
}

View File

@@ -10,6 +10,7 @@
using System;
using System.Collections.Generic;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Effects
@@ -25,12 +26,12 @@ namespace OpenRA.Effects
this.delay = delay;
}
public void Tick( World world )
public void Tick(World world)
{
if (--delay <= 0)
world.AddFrameEndTask(w => { w.Remove(this); a(); });
}
public IEnumerable<Renderable> Render() { yield break; }
public IEnumerable<Renderable> Render(WorldRenderer wr) { yield break; }
}
}

View File

@@ -10,6 +10,7 @@
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Effects
@@ -32,14 +33,14 @@ namespace OpenRA.Effects
world.AddFrameEndTask(w => w.Remove(this));
}
public IEnumerable<Renderable> Render()
public IEnumerable<Renderable> Render(WorldRenderer wr)
{
if (!target.IsInWorld)
yield break;
if (remainingTicks % 2 == 0)
foreach (var r in target.Render())
yield return r.WithPalette("highlight");
foreach (var r in target.Render(wr))
yield return r.WithPalette(wr.Palette("highlight"));
}
}
}

View File

@@ -9,13 +9,14 @@
#endregion
using System.Collections.Generic;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Effects
{
public interface IEffect
{
void Tick( World world );
IEnumerable<Renderable> Render();
void Tick(World world);
IEnumerable<Renderable> Render(WorldRenderer r);
}
}

View File

@@ -29,6 +29,8 @@ namespace OpenRA
{
public static int CellSize { get { return modData.Manifest.TileSize; } }
public static MouseButtonPreference mouseButtonPreference = new MouseButtonPreference();
public static ModData modData;
static WorldRenderer worldRenderer;
@@ -50,18 +52,13 @@ namespace OpenRA
public static void JoinServer(string host, int port)
{
var replayFilename = ChooseReplayFilename();
string path = Path.Combine( Platform.SupportDir, "Replays" );
if( !Directory.Exists( path ) ) Directory.CreateDirectory( path );
var replayFile = File.Create( Path.Combine( path, replayFilename ) );
JoinInner(new OrderManager(host, port,
new ReplayRecorderConnection(new NetworkConnection(host, port), replayFile)));
new ReplayRecorderConnection(new NetworkConnection(host, port), ChooseReplayFilename)));
}
static string ChooseReplayFilename()
{
return DateTime.UtcNow.ToString("OpenRA-yyyy-MM-ddTHHmmssZ.rep");
return DateTime.UtcNow.ToString("OpenRA-yyyy-MM-ddTHHmmssZ");
}
static void JoinInner(OrderManager om)
@@ -171,7 +168,7 @@ namespace OpenRA
{
var isNetTick = LocalTick % NetTickScale == 0;
if (!isNetTick || orderManager.IsReadyForNextFrame)
if ((!isNetTick || orderManager.IsReadyForNextFrame) && !orderManager.GamePaused )
{
++orderManager.LocalFrameNumber;
@@ -193,6 +190,8 @@ namespace OpenRA
else
if (orderManager.NetFrameNumber == 0)
orderManager.LastTickTime = Environment.TickCount;
viewport.Tick();
}
}
}
@@ -221,11 +220,19 @@ namespace OpenRA
orderManager.LastTickTime = Environment.TickCount;
orderManager.StartGame();
worldRenderer.RefreshPalette();
if (!isShellmap)
Sound.PlayNotification(null, "Speech", "StartGame", null);
}
public static bool IsHost
{
get { return orderManager.Connection.LocalClientId == 0; }
get
{
var client= orderManager.LobbyInfo.ClientWithIndex (
orderManager.Connection.LocalClientId);
return ((client!=null) && client.IsAdmin);
}
}
public static Dictionary<String, Mod> CurrentMods
@@ -244,7 +251,6 @@ namespace OpenRA
AppDomain.CurrentDomain.AssemblyResolve += FileSystem.ResolveAssembly;
Settings = new Settings(Platform.SupportDir + "settings.yaml", args);
Settings.Save();
Log.LogPath = Platform.SupportDir + "Logs" + Path.DirectorySeparatorChar;
Log.AddChannel("perf", "perf.log");
@@ -259,7 +265,7 @@ namespace OpenRA
foreach(var mod in Mod.AllMods)
Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Title, mod.Value.Version);
Sound.Create();
Sound.Create(Settings.Sound.Engine);
InitializeWithMods(Settings.Game.Mods);
}
@@ -278,11 +284,11 @@ namespace OpenRA
if (orderManager != null)
orderManager.Dispose();
// Discard any invalid mods
// Discard any invalid mods, set RA as default
var mm = mods.Where( m => Mod.AllMods.ContainsKey( m ) ).ToArray();
if (mm.Length == 0) mm = new[] { "ra" };
Console.WriteLine("Loading mods: {0}", mm.JoinWith(","));
Settings.Game.Mods = mm;
Settings.Save();
Sound.StopMusic();
Sound.StopVideo();
@@ -301,7 +307,40 @@ namespace OpenRA
JoinLocal();
viewport = new Viewport(new int2(Renderer.Resolution), Rectangle.Empty, Renderer);
modData.LoadScreen.StartGame();
if (Game.Settings.Server.Dedicated)
{
while (true)
{
Game.Settings.Server.Map = WidgetUtils.ChooseInitialMap(Game.Settings.Server.Map);
Game.Settings.Save();
Game.CreateServer(new ServerSettings(Game.Settings.Server));
while(true)
{
System.Threading.Thread.Sleep(100);
if((server.State == Server.ServerState.GameStarted)
&& (server.conns.Count<=1))
{
Console.WriteLine("No one is playing, shutting down...");
server.Shutdown();
break;
}
}
if (Game.Settings.Server.DedicatedLoop)
{
Console.WriteLine("Starting a new server instance...");
continue;
}
else
break;
}
System.Environment.Exit(0);
}
else
{
modData.LoadScreen.StartGame();
Settings.Save();
}
}
public static void LoadShellMap()
@@ -390,6 +429,7 @@ namespace OpenRA
// Work around a miscompile in mono 2.6.7:
// booleans that default to true cannot be set false by an initializer
settings.AdvertiseOnline = false;
settings.AllowUPnP = false;
server = new Server.Server(new IPEndPoint(IPAddress.Loopback, 0),
Game.Settings.Game.Mods, settings, modData);

View File

@@ -16,8 +16,15 @@ using OpenRA.Traits;
namespace OpenRA
{
//TODO: This is not exported into the documentation yet.
[Desc("A unit/building inside the game. Every rules starts with one and adds trait to it.",
"Special actors like world or player are usually defined in system.yaml and affect everything.")]
public class ActorInfo
{
[Desc("The actor name can be anything, but the sprites used in the Render*: traits default to this one.",
"If you add an ^ in front of the name, the engine will recognize this as a collection of traits",
"that can be inherited by others (using Inherits:) and not a real unit.",
"You can remove inherited traits by adding a - infront of them as in -TraitName: to inherit everything, but this trait.")]
public readonly string Name;
public readonly TypeDictionary Traits = new TypeDictionary();
@@ -70,6 +77,9 @@ namespace OpenRA
static ITraitInfo LoadTraitInfo(string traitName, MiniYaml my)
{
if (!string.IsNullOrEmpty(my.Value))
throw new YamlException("Junk value `{0}` on trait node {1}"
.F(my.Value, traitName));
var info = Game.CreateObject<ITraitInfo>(traitName + "Info");
FieldLoader.Load(info, my);
return info;

View File

@@ -20,7 +20,8 @@ namespace OpenRA
{
public static Dictionary<string, ActorInfo> Info;
public static Dictionary<string, WeaponInfo> Weapons;
public static Dictionary<string, VoiceInfo> Voices;
public static Dictionary<string, SoundInfo> Voices;
public static Dictionary<string, SoundInfo> Notifications;
public static Dictionary<string, MusicInfo> Music;
public static Dictionary<string, string> Movies;
public static Dictionary<string, TileSet> TileSets;
@@ -30,7 +31,8 @@ namespace OpenRA
// Added support to extend the list of rules (add it to m.LocalRules)
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));
Voices = LoadYamlRules(m.Voices, map.Voices, (k, _) => new SoundInfo(k.Value));
Notifications = LoadYamlRules(m.Notifications, map.Notifications, (k, _) => new SoundInfo(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);

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2013 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,
@@ -19,6 +19,9 @@ using OpenRA.Server;
namespace OpenRA.GameRules
{
public enum MouseScrollType { Disabled, Standard, Inverted }
public enum SoundCashTicks { Disabled, Normal, Extreme }
public class ServerSettings
{
public string Name = "OpenRA Game";
@@ -26,8 +29,14 @@ namespace OpenRA.GameRules
public int ExternalPort = 1234;
public bool AdvertiseOnline = true;
public string MasterServer = "http://master.open-ra.org/";
public bool AllowUPnP = false;
public bool AllowCheats = false;
public string Map = null;
public string[] Ban = null;
public int TimeOut = 0;
public bool Dedicated = false;
public bool DedicatedLoop = true;
public bool LockBots = false;
public ServerSettings() { }
@@ -38,8 +47,14 @@ namespace OpenRA.GameRules
ExternalPort = other.ExternalPort;
AdvertiseOnline = other.AdvertiseOnline;
MasterServer = other.MasterServer;
AllowUPnP = other.AllowUPnP;
AllowCheats = other.AllowCheats;
Map = other.Map;
Ban = other.Ban;
TimeOut = other.TimeOut;
Dedicated = other.Dedicated;
DedicatedLoop = other.DedicatedLoop;
LockBots = other.LockBots;
}
}
@@ -75,7 +90,10 @@ namespace OpenRA.GameRules
public float VideoVolume = 0.5f;
public bool Shuffle = false;
public bool Repeat = false;
public bool ShellmapMusic = true;
public bool MapMusic = true;
public string Engine = "AL";
public SoundCashTicks SoundCashTickType = SoundCashTicks.Extreme;
}
public class PlayerSettings
@@ -85,8 +103,6 @@ namespace OpenRA.GameRules
public string LastServer = "localhost:1234";
}
public enum MouseScrollType { Disabled, Standard, Inverted }
public class GameSettings
{
public string[] Mods = { "ra" };
@@ -98,12 +114,35 @@ namespace OpenRA.GameRules
public MouseScrollType MouseScroll = MouseScrollType.Standard;
public float ViewportEdgeScrollStep = 10f;
public bool UseClassicMouseStyle = false;
// Internal game settings
public int Timestep = 40;
public string ConnectTo = "";
}
public class KeySettings
{
public string PauseKey = "f3";
public string CycleBaseKey = "backspace";
public string ToLastEventKey = "space";
public string ToSelectionKey = "home";
public string SellKey = "v";
public string PowerDownKey = "b";
public string RepairKey = "n";
public string AttackMoveKey = "a";
public string StopKey = "s";
public string ScatterKey = "x";
public string StanceCycleKey = "z";
public string DeployKey = "f";
public string CycleTabsKey = "tab";
}
public class Settings
{
string SettingsFile;
@@ -114,6 +153,7 @@ namespace OpenRA.GameRules
public GraphicSettings Graphics = new GraphicSettings();
public ServerSettings Server = new ServerSettings();
public DebugSettings Debug = new DebugSettings();
public KeySettings Keys = new KeySettings();
public Dictionary<string, object> Sections;
@@ -128,6 +168,7 @@ namespace OpenRA.GameRules
{"Graphics", Graphics},
{"Server", Server},
{"Debug", Debug},
{"Keys", Keys},
};
// Override fieldloader to ignore invalid entries

View File

@@ -1,4 +1,4 @@
#region Copyright & License Information
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
@@ -15,12 +15,16 @@ using OpenRA.FileFormats;
namespace OpenRA.GameRules
{
public class VoiceInfo
public class SoundInfo
{
[FieldLoader.Ignore] public readonly Dictionary<string,string[]> Variants;
[FieldLoader.Ignore] public readonly Dictionary<string,string[]> Prefixes;
[FieldLoader.Ignore] public readonly Dictionary<string,string[]> Voices;
[FieldLoader.Ignore] public readonly Dictionary<string,string[]> Notifications;
public readonly string DefaultVariant = ".aud" ;
public readonly string DefaultPrefix = "" ;
public readonly string[] DisableVariants = { };
public readonly string[] DisablePrefixes = { };
static Dictionary<string, string[]> Load( MiniYaml y, string name )
{
@@ -31,30 +35,28 @@ namespace OpenRA.GameRules
: new Dictionary<string, string[]>();
}
public readonly OpenRA.FileFormats.Lazy<Dictionary<string, VoicePool>> Pools;
public readonly OpenRA.FileFormats.Lazy<Dictionary<string, SoundPool>> VoicePools;
public readonly OpenRA.FileFormats.Lazy<Dictionary<string, SoundPool>> NotificationsPools;
public VoiceInfo( MiniYaml y )
public SoundInfo( MiniYaml y )
{
FieldLoader.Load( this, y );
Variants = Load(y, "Variants");
Prefixes = Load(y, "Prefixes");
Voices = Load(y, "Voices");
Notifications = Load(y, "Notifications");
if (!Voices.ContainsKey("Attack"))
Voices.Add("Attack", Voices["Move"]);
if (!Voices.ContainsKey("AttackMove"))
Voices.Add("AttackMove", Voices["Move"]);
Pools = Lazy.New(() => Voices.ToDictionary( a => a.Key, a => new VoicePool(a.Value) ));
VoicePools = Lazy.New(() => Voices.ToDictionary( a => a.Key, a => new SoundPool(a.Value) ));
NotificationsPools = Lazy.New(() => Notifications.ToDictionary( a => a.Key, a => new SoundPool(a.Value) ));
}
}
public class VoicePool
public class SoundPool
{
readonly string[] clips;
readonly List<string> liveclips = new List<string>();
public VoicePool(params string[] clips)
public SoundPool(params string[] clips)
{
this.clips = clips;
}

View File

@@ -18,21 +18,35 @@ namespace OpenRA.GameRules
{
public class WarheadInfo
{
public readonly int Spread = 1; // distance (in pixels) from the explosion center at which damage is 1/2.
[Desc("Distance (in pixels) from the explosion center at which damage is 1/2.")]
public readonly int Spread = 1;
[FieldLoader.LoadUsing( "LoadVersus" )]
public readonly Dictionary<string, float> Versus; // damage vs each armortype
public readonly bool Ore = false; // can this damage ore?
public readonly string Explosion = null; // explosion effect to use
public readonly string WaterExplosion = null; // explosion effect on hitting water (usually a splash)
public readonly string SmudgeType = null; // type of smudge to apply
public readonly int[] Size = { 0, 0 }; // size of the explosion. provide 2 values for a ring effect (outer/inner)
public readonly int InfDeath = 0; // infantry death animation to use
public readonly string ImpactSound = null; // sound to play on impact
public readonly string WaterImpactSound = null; // sound to play on impact with water
public readonly int Damage = 0; // how much (raw) damage to deal
public readonly int Delay = 0; // delay in ticks before dealing the damage. 0=instant (old model)
public readonly DamageModel DamageModel = DamageModel.Normal; // which damage model to use
public readonly bool PreventProne = false; // whether we should prevent prone response in infantry.
[Desc("Damage vs each armortype. 0% = can't target.")]
public readonly Dictionary<string, float> Versus;
[Desc("Can this damage ore?")]
public readonly bool Ore = false;
[Desc("Explosion effect to use.")]
public readonly string Explosion = null;
[Desc("Explosion effect on hitting water (usually a splash).")]
public readonly string WaterExplosion = null;
[Desc("Type of smudge to apply to terrain.")]
public readonly string[] SmudgeType = { };
[Desc("Size of the explosion. provide 2 values for a ring effect (outer/inner).")]
public readonly int[] Size = { 0, 0 };
[Desc("Infantry death animation to use")]
public readonly int InfDeath = 1;
[Desc("Sound to play on impact.")]
public readonly string ImpactSound = null;
[Desc("Sound to play on impact with water")]
public readonly string WaterImpactSound = null;
[Desc("How much (raw) damage to deal")]
public readonly int Damage = 0;
[Desc("Delay in ticks before dealing the damage, 0 = instant (old model).")]
public readonly int Delay = 0;
[Desc("Which damage model to use.")]
public readonly DamageModel DamageModel = DamageModel.Normal;
[Desc("Whether we should prevent prone response for infantry.")]
public readonly bool PreventProne = false;
public float EffectivenessAgainst(Actor self)
{
@@ -72,11 +86,11 @@ namespace OpenRA.GameRules
{
public WeaponInfo weapon;
public Actor firedBy;
public int2 src;
public PPos src;
public int srcAltitude;
public int facing;
public Target target;
public int2 dest;
public PPos dest;
public int destAltitude;
public float firepowerModifier = 1.0f;
}
@@ -86,12 +100,13 @@ namespace OpenRA.GameRules
public class WeaponInfo
{
public readonly float Range = 0;
public readonly string Report = null;
public readonly string[] Report = null;
[Desc("Rate of Fire")]
public readonly int ROF = 1;
public readonly int Burst = 1;
public readonly bool Charges = false;
public readonly bool Underwater = false;
public readonly string[] ValidTargets = { "Ground" };
public readonly string[] ValidTargets = { "Ground", "Water" };
public readonly int BurstDelay = 5;
public readonly float MinRange = 0;

View File

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

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2012 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
@@ -14,20 +14,37 @@ using System.IO;
using System.Linq;
using System.Xml;
using OpenRA.FileFormats;
using OpenRA.Traits;
namespace OpenRA.Graphics
{
public static class CursorProvider
{
public static HardwarePalette Palette;
static Dictionary<string, CursorSequence> cursors;
public static void Initialize(string[] sequenceFiles)
{
cursors = new Dictionary<string, CursorSequence>();
var sequences = new MiniYaml(null, sequenceFiles.Select(s => MiniYaml.FromFile(s)).Aggregate(MiniYaml.MergeLiberal));
int[] ShadowIndex = { };
if (sequences.NodesDict.ContainsKey("ShadowIndex"))
{
Array.Resize(ref ShadowIndex, ShadowIndex.Length + 1);
ShadowIndex[ShadowIndex.Length - 1] = Convert.ToInt32(sequences.NodesDict["ShadowIndex"].Value);
}
var palettes = new Dictionary<string, Palette>();
foreach (var s in sequences.NodesDict["Palettes"].Nodes)
Game.modData.Palette.AddPalette(s.Key, new Palette(FileSystem.Open(s.Value.Value), false));
palettes.Add(s.Key, new Palette(FileSystem.Open(s.Value.Value), ShadowIndex));
Palette = new HardwarePalette();
foreach (var p in palettes)
Palette.AddPalette(p.Key, p.Value, false);
// Generate initial palette texture
Palette.Update(new IPaletteModifier[] {});
foreach (var s in sequences.NodesDict["Cursors"].Nodes)
LoadSequencesForCursor(s.Key, s.Value);
@@ -46,6 +63,17 @@ namespace OpenRA.Graphics
return cursors.ContainsKey(cursor);
}
public static void DrawCursor(Renderer renderer, string cursorName, int2 lastMousePos, int cursorFrame)
{
var cursorSequence = CursorProvider.GetCursorSequence(cursorName);
var cursorSprite = cursorSequence.GetSprite(cursorFrame);
renderer.SpriteRenderer.DrawSprite(cursorSprite,
lastMousePos - cursorSequence.Hotspot,
Palette.GetPaletteIndex(cursorSequence.Palette),
cursorSprite.size);
}
public static CursorSequence GetCursorSequence(string cursor)
{
try { return cursors[cursor]; }

View File

@@ -25,11 +25,13 @@ namespace OpenRA.Graphics
ITexture texture;
Dictionary<string, Palette> palettes;
Dictionary<string, int> indices;
Dictionary<string, bool> allowsMods;
public HardwarePalette()
{
palettes = new Dictionary<string, Palette>();
indices = new Dictionary<string, int>();
allowsMods = new Dictionary<string, bool>();
texture = Game.Renderer.Device.CreateTexture();
}
@@ -49,22 +51,24 @@ namespace OpenRA.Graphics
return ret;
}
public void AddPalette(string name, Palette p)
public void AddPalette(string name, Palette p, bool allowModifiers)
{
if (palettes.ContainsKey(name))
throw new InvalidOperationException("Palette {0} has already been defined".F(name));
palettes.Add(name, p);
indices.Add(name, allocated++);
allowsMods.Add(name, allowModifiers);
}
uint[,] data = new uint[MaxPalettes, 256];
public void Update(IEnumerable<IPaletteModifier> paletteMods)
{
var copy = palettes.ToDictionary(p => p.Key, p => new Palette(p.Value));
var modifiable = copy.Where(p => allowsMods[p.Key]).ToDictionary(p => p.Key, p => p.Value);
foreach (var mod in paletteMods)
mod.AdjustPalette(copy);
mod.AdjustPalette(modifiable);
foreach (var pal in copy)
{

View File

@@ -77,5 +77,12 @@ namespace OpenRA.Graphics
for (float y = r.Top; y < r.Bottom; y++)
DrawLine(new float2(r.Left, y), new float2(r.Right, y), color, color);
}
public void SetShaderParams(ITexture palette, Size screen, float zoom, float2 scroll)
{
shader.SetVec("Scroll", (int)scroll.X, (int)scroll.Y);
shader.SetVec("r1", zoom*2f/screen.Width, -zoom*2f/screen.Height);
shader.SetVec("r2", -1, 1);
}
}
}

View File

@@ -32,13 +32,11 @@ namespace OpenRA.Graphics
var height = map.Bounds.Height;
if (!actualSize)
{
width = height = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height));
}
var terrain = new Bitmap(width, height);
var bitmapData = terrain.LockBits(new Rectangle(0, 0, terrain.Width, terrain.Height),
var bitmapData = terrain.LockBits(terrain.Bounds(),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
unsafe
@@ -69,7 +67,7 @@ namespace OpenRA.Graphics
Bitmap terrain = new Bitmap(terrainBitmap);
var tileset = Rules.TileSets[map.Tileset];
var bitmapData = terrain.LockBits(new Rectangle(0, 0, terrain.Width, terrain.Height),
var bitmapData = terrain.LockBits(terrain.Bounds(),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
unsafe
@@ -104,7 +102,7 @@ namespace OpenRA.Graphics
var map = world.Map;
var size = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height));
var bitmap = new Bitmap(size, size);
var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
var bitmapData = bitmap.LockBits(bitmap.Bounds(),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
unsafe
@@ -132,7 +130,7 @@ namespace OpenRA.Graphics
var map = world.Map;
var size = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height));
var bitmap = new Bitmap(size, size);
var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
var bitmapData = bitmap.LockBits(bitmap.Bounds(),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
unsafe
@@ -141,7 +139,7 @@ namespace OpenRA.Graphics
foreach (var t in world.ActorsWithTrait<IRadarSignature>())
{
if (!world.LocalShroud.IsVisible(t.Actor))
if (!world.RenderedShroud.IsVisible(t.Actor))
continue;
var color = t.Trait.RadarSignatureColor(t.Actor);
@@ -160,10 +158,10 @@ namespace OpenRA.Graphics
var map = world.Map;
var size = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height));
var bitmap = new Bitmap(size, size);
if (world.LocalShroud.Disabled)
if (world.RenderedShroud.Disabled)
return bitmap;
var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
var bitmapData = bitmap.LockBits(bitmap.Bounds(),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
var shroud = Color.Black.ToArgb();
@@ -178,9 +176,9 @@ namespace OpenRA.Graphics
{
var mapX = x + map.Bounds.Left;
var mapY = y + map.Bounds.Top;
if (!world.LocalShroud.IsExplored(mapX, mapY))
if (!world.RenderedShroud.IsExplored(mapX, mapY))
*(c + (y * bitmapData.Stride >> 2) + x) = shroud;
else if (!world.LocalShroud.IsVisible(mapX,mapY))
else if (!world.RenderedShroud.IsVisible(mapX,mapY))
*(c + (y * bitmapData.Stride >> 2) + x) = fog;
}
}

View File

@@ -0,0 +1,67 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System.Drawing;
using OpenRA.FileFormats.Graphics;
namespace OpenRA.Graphics
{
public class QuadRenderer : Renderer.IBatchRenderer
{
Renderer renderer;
IShader shader;
Vertex[] vertices = new Vertex[Renderer.TempBufferSize];
int nv = 0;
public QuadRenderer(Renderer renderer, IShader shader)
{
this.renderer = renderer;
this.shader = shader;
}
public void Flush()
{
if (nv > 0)
{
shader.Render(() =>
{
var vb = renderer.GetTempVertexBuffer();
vb.SetData(vertices, nv);
renderer.DrawBatch(vb, 0, nv, PrimitiveType.QuadList);
});
nv = 0;
}
}
public void FillRect(RectangleF r, Color color)
{
Renderer.CurrentBatchRenderer = this;
if (nv + 4 > Renderer.TempBufferSize)
Flush();
vertices[nv] = new Vertex(new float2(r.Left, r.Top), new float2(color.R / 255.0f, color.G / 255.0f), new float2(color.B / 255.0f, color.A / 255.0f));
vertices[nv + 1] = new Vertex(new float2(r.Right, r.Top), new float2(color.R / 255.0f, color.G / 255.0f), new float2(color.B / 255.0f, color.A / 255.0f));
vertices[nv + 2] = new Vertex(new float2(r.Right, r.Bottom), new float2(color.R / 255.0f, color.G / 255.0f), new float2(color.B / 255.0f, color.A / 255.0f));
vertices[nv + 3] = new Vertex(new float2(r.Left, r.Bottom), new float2(color.R / 255.0f, color.G / 255.0f), new float2(color.B / 255.0f, color.A / 255.0f));
nv += 4;
}
public void SetShaderParams(ITexture palette, Size screen, float zoom, float2 scroll)
{
shader.SetVec("Scroll", (int)scroll.X, (int)scroll.Y);
shader.SetVec("r1", zoom*2f/screen.Width, -zoom*2f/screen.Height);
shader.SetVec("r2", -1, 1);
}
}
}

View File

@@ -26,13 +26,9 @@ namespace OpenRA.Graphics
internal static int SheetSize;
internal static int TempBufferSize;
internal static int TempBufferCount;
internal IShader WorldSpriteShader { get; private set; }
internal IShader WorldLineShader { get; private set; }
internal IShader LineShader { get; private set; }
internal IShader RgbaSpriteShader { get; private set; }
internal IShader SpriteShader { get; private set; }
public SpriteRenderer WorldSpriteRenderer { get; private set; }
public QuadRenderer WorldQuadRenderer { get; private set; }
public LineRenderer WorldLineRenderer { get; private set; }
public LineRenderer LineRenderer { get; private set; }
public SpriteRenderer RgbaSpriteRenderer { get; private set; }
@@ -50,20 +46,15 @@ namespace OpenRA.Graphics
TempBufferCount = Game.Settings.Graphics.NumTempBuffers;
SheetSize = Game.Settings.Graphics.SheetSize;
WorldSpriteShader = device.CreateShader("world-shp");
WorldLineShader = device.CreateShader("world-line");
LineShader = device.CreateShader("chrome-line");
RgbaSpriteShader = device.CreateShader("chrome-rgba");
SpriteShader = device.CreateShader("chrome-shp");
WorldSpriteRenderer = new SpriteRenderer(this, device.CreateShader("shp"));
WorldLineRenderer = new LineRenderer(this, device.CreateShader("line"));
LineRenderer = new LineRenderer(this, device.CreateShader("line"));
WorldQuadRenderer = new QuadRenderer(this, device.CreateShader("line"));
RgbaSpriteRenderer = new SpriteRenderer(this, device.CreateShader("rgba"));
SpriteRenderer = new SpriteRenderer(this, device.CreateShader("shp"));
WorldSpriteRenderer = new SpriteRenderer( this, WorldSpriteShader );
WorldLineRenderer = new LineRenderer(this, WorldLineShader);
LineRenderer = new LineRenderer(this, LineShader);
RgbaSpriteRenderer = new SpriteRenderer( this, RgbaSpriteShader );
SpriteRenderer = new SpriteRenderer( this, SpriteShader );
for( int i = 0 ; i < TempBufferCount ; i++ )
tempBuffers.Enqueue( device.CreateVertexBuffer( TempBufferSize ) );
for (int i = 0; i < TempBufferCount; i++)
tempBuffers.Enqueue(device.CreateVertexBuffer(TempBufferSize));
}
public void InitializeFonts(Manifest m)
@@ -76,26 +67,15 @@ namespace OpenRA.Graphics
public void BeginFrame(float2 scroll, float zoom)
{
device.Clear();
float2 r1 = new float2(2f/Resolution.Width, -2f/Resolution.Height);
float2 r2 = new float2(-1, 1);
var zr1 = zoom*r1;
SetShaderParams( WorldSpriteShader, zr1, r2, scroll );
SetShaderParams( WorldLineShader, zr1, r2, scroll );
SetShaderParams( LineShader, r1, r2, scroll );
SetShaderParams( RgbaSpriteShader, r1, r2, scroll );
SetShaderParams( SpriteShader, r1, r2, scroll );
WorldSpriteRenderer.SetShaderParams(PaletteTexture, Resolution, zoom, scroll);
WorldLineRenderer.SetShaderParams(PaletteTexture, Resolution, zoom, scroll);
WorldQuadRenderer.SetShaderParams(PaletteTexture, Resolution, zoom, scroll);
SpriteRenderer.SetShaderParams(PaletteTexture, Resolution, 1f, float2.Zero);
LineRenderer.SetShaderParams(PaletteTexture, Resolution, 1f, float2.Zero);
RgbaSpriteRenderer.SetShaderParams(PaletteTexture, Resolution, 1f, float2.Zero);
}
void SetShaderParams( IShader s, float2 r1, float2 r2, float2 scroll )
{
s.SetValue( "Palette", PaletteTexture );
s.SetValue( "Scroll", (int) scroll.X, (int) scroll.Y );
s.SetValue( "r1", r1.X, r1.Y );
s.SetValue( "r2", r2.X, r2.Y );
}
public void EndFrame( IInputHandler inputHandler )
public void EndFrame(IInputHandler inputHandler)
{
Flush();
device.PumpInput(inputHandler);
@@ -129,14 +109,17 @@ namespace OpenRA.Graphics
// which makes the window non-interactive in Windowed/Pseudofullscreen mode.
static Screen FixOSX() { return Screen.PrimaryScreen; }
internal static void Initialize( WindowMode windowMode )
internal static void Initialize(WindowMode windowMode)
{
if (Platform.CurrentPlatform == PlatformType.OSX)
FixOSX();
var resolution = GetResolution( windowMode );
var rendererPath = Path.GetFullPath( "OpenRA.Renderer.{0}.dll".F(Game.Settings.Graphics.Renderer) );
device = CreateDevice( Assembly.LoadFile( rendererPath ), resolution.Width, resolution.Height, windowMode );
var resolution = GetResolution(windowMode);
string renderer = Game.Settings.Server.Dedicated ? "Null" : Game.Settings.Graphics.Renderer;
var rendererPath = Path.GetFullPath("OpenRA.Renderer.{0}.dll".F(renderer));
device = CreateDevice(Assembly.LoadFile(rendererPath), resolution.Width, resolution.Height, windowMode);
}
static Size GetResolution(WindowMode windowmode)
@@ -147,12 +130,12 @@ namespace OpenRA.Graphics
return new Size(size.X, size.Y);
}
static IGraphicsDevice CreateDevice( Assembly rendererDll, int width, int height, WindowMode window )
static IGraphicsDevice CreateDevice(Assembly rendererDll, int width, int height, WindowMode window)
{
foreach( RendererAttribute r in rendererDll.GetCustomAttributes( typeof( RendererAttribute ), false ) )
foreach (RendererAttribute r in rendererDll.GetCustomAttributes(typeof(RendererAttribute), false))
{
var factory = (IDeviceFactory) r.Type.GetConstructor( Type.EmptyTypes ).Invoke( null );
return factory.Create( new Size( width, height ), window );
var factory = (IDeviceFactory)r.Type.GetConstructor(Type.EmptyTypes).Invoke(null);
return factory.Create(new Size(width, height), window);
}
throw new InvalidOperationException("Renderer DLL is missing RendererAttribute to tell us what type to use!");
@@ -161,7 +144,7 @@ namespace OpenRA.Graphics
internal IVertexBuffer<Vertex> GetTempVertexBuffer()
{
var ret = tempBuffers.Dequeue();
tempBuffers.Enqueue( ret );
tempBuffers.Enqueue(ret);
return ret;
}
@@ -173,8 +156,8 @@ namespace OpenRA.Graphics
get { return currentBatchRenderer; }
set
{
if( currentBatchRenderer == value ) return;
if( currentBatchRenderer != null )
if (currentBatchRenderer == value) return;
if (currentBatchRenderer != null)
currentBatchRenderer.Flush();
currentBatchRenderer = value;
}
@@ -183,7 +166,7 @@ namespace OpenRA.Graphics
public void EnableScissor(int left, int top, int width, int height)
{
Flush();
Device.EnableScissor( left, top, width, height );
Device.EnableScissor(left, top, width, height);
}
public void DisableScissor()

View File

@@ -18,19 +18,19 @@ namespace OpenRA.Graphics
public class Sequence
{
readonly Sprite[] sprites;
readonly int start, length, facings, tick;
readonly int start, length, stride, facings, tick;
public readonly string Name;
public int Start { get { return start; } }
public int End { get { return start + length; } }
public int Length { get { return length; } }
public int Stride { get { return stride; } }
public int Facings { get { return facings; } }
public int Tick { get { return tick; } }
string srcOverride;
public Sequence(string unit, string name, MiniYaml info)
{
srcOverride = info.Value;
var srcOverride = info.Value;
Name = name;
var d = info.NodesDict;
@@ -44,6 +44,10 @@ namespace OpenRA.Graphics
else
length = int.Parse(d["Length"].Value);
if (d.ContainsKey("Stride"))
stride = int.Parse(d["Stride"].Value);
else
stride = length;
if(d.ContainsKey("Facings"))
facings = int.Parse(d["Facings"].Value);
@@ -55,33 +59,18 @@ namespace OpenRA.Graphics
else
tick = 40;
if (start < 0 || start + facings * length > sprites.Length)
if (length > stride)
throw new InvalidOperationException(
"{0}: Sequence {1}.{2}: Length must be <= stride"
.F(info.Nodes[0].Location, unit, name));
if (start < 0 || start + facings * stride > sprites.Length)
throw new InvalidOperationException(
"{6}: Sequence {0}.{1} uses frames [{2}..{3}] of SHP `{4}`, but only 0..{5} actually exist"
.F(unit, name, start, start + facings * length - 1, srcOverride ?? unit, sprites.Length - 1,
.F(unit, name, start, start + facings * stride - 1, srcOverride ?? unit, sprites.Length - 1,
info.Nodes[0].Location));
}
public MiniYaml Save()
{
var root = new List<MiniYamlNode>();
root.Add(new MiniYamlNode("Start", start.ToString()));
if (length > 1 && (start != 0 || length != sprites.Length - start))
root.Add(new MiniYamlNode("Length", length.ToString()));
else if (length > 1 && length == sprites.Length - start)
root.Add(new MiniYamlNode("Length", "*"));
if (facings > 1)
root.Add(new MiniYamlNode("Facings", facings.ToString()));
if (tick != 40)
root.Add(new MiniYamlNode("Tick", tick.ToString()));
return new MiniYaml(srcOverride, root);
}
public Sprite GetSprite( int frame )
{
return GetSprite( frame, 0 );
@@ -90,7 +79,7 @@ namespace OpenRA.Graphics
public Sprite GetSprite(int frame, int facing)
{
var f = Traits.Util.QuantizeFacing( facing, facings );
return sprites[ (f * length) + ( frame % length ) + start ];
return sprites[ (f * stride) + ( frame % length ) + start ];
}
}
}

View File

@@ -15,21 +15,25 @@ namespace OpenRA.Graphics
{
public class ShroudRenderer
{
Traits.Shroud shroud;
World world;
Traits.Shroud shroud {
get {
return world.RenderedShroud;
}
}
Sprite[] shadowBits = Game.modData.SpriteLoader.LoadAllSprites("shadow");
Sprite[,] sprites, fogSprites;
bool dirty = true;
Map map;
public ShroudRenderer(World world)
{
this.shroud = world.LocalShroud;
this.world = world;
this.map = world.Map;
sprites = new Sprite[map.MapSize.X, map.MapSize.Y];
fogSprites = new Sprite[map.MapSize.X, map.MapSize.Y];
shroud.Dirty += () => dirty = true;
}
static readonly byte[][] SpecialShroudTiles =
@@ -101,11 +105,20 @@ namespace OpenRA.Graphics
return shadowBits[SpecialShroudTiles[u ^ uSides][v]];
}
internal void Draw( WorldRenderer wr )
bool initializePalettes = true;
PaletteReference fogPalette, shroudPalette;
internal void Draw(WorldRenderer wr)
{
if (dirty)
if (initializePalettes)
{
dirty = false;
fogPalette = wr.Palette("fog");
shroudPalette = wr.Palette("shroud");
initializePalettes = false;
}
if (shroud != null && shroud.dirty)
{
shroud.dirty = false;
for (int i = map.Bounds.Left; i < map.Bounds.Right; i++)
for (int j = map.Bounds.Top; j < map.Bounds.Bottom; j++)
sprites[i, j] = ChooseShroud(i, j);
@@ -116,14 +129,13 @@ namespace OpenRA.Graphics
}
var clipRect = Game.viewport.WorldBounds(wr.world);
DrawShroud( wr, clipRect, fogSprites, "fog" );
DrawShroud( wr, clipRect, sprites, "shroud" );
DrawShroud(wr, clipRect, sprites, shroudPalette);
if (wr.world.WorldActor.HasTrait<Fog>())
DrawShroud(wr, clipRect, fogSprites, fogPalette);
}
void DrawShroud( WorldRenderer wr, Rectangle clip, Sprite[,] s, string pal )
void DrawShroud(WorldRenderer wr, Rectangle clip, Sprite[,] s, PaletteReference pal)
{
var shroudPalette = wr.GetPaletteIndex(pal);
for (var j = clip.Top; j < clip.Bottom; j++)
{
var starti = clip.Left;
@@ -138,14 +150,14 @@ namespace OpenRA.Graphics
{
s[starti, j].DrawAt(
Game.CellSize * new float2(starti, j),
shroudPalette,
pal.Index,
new float2(Game.CellSize * (i - starti), Game.CellSize));
starti = i + 1;
}
s[i, j].DrawAt(
Game.CellSize * new float2(i, j),
shroudPalette);
pal.Index);
starti = i + 1;
last = s[i, j];
}
@@ -153,7 +165,7 @@ namespace OpenRA.Graphics
if (starti < clip.Right)
s[starti, j].DrawAt(
Game.CellSize * new float2(starti, j),
shroudPalette,
pal.Index,
new float2(Game.CellSize * (clip.Right - starti), Game.CellSize));
}
}

View File

@@ -29,7 +29,7 @@ namespace OpenRA.Graphics
Sprite[] LoadSprites(string filename)
{
var shp = new ShpReader(FileSystem.OpenWithExts(filename, exts));
return shp.Select(a => SheetBuilder.Add(a.Image, shp.Size)).ToArray();
return shp.Frames.Select(a => SheetBuilder.Add(a.Image, shp.Size)).ToArray();
}
public Sprite[] LoadAllSprites(string filename) { return sprites[filename]; }

View File

@@ -8,6 +8,7 @@
*/
#endregion
using System.Drawing;
using OpenRA.FileFormats.Graphics;
namespace OpenRA.Graphics
@@ -27,14 +28,11 @@ namespace OpenRA.Graphics
this.shader = shader;
}
public SpriteRenderer(Renderer renderer)
: this(renderer, renderer.SpriteShader) { }
public void Flush()
{
if (nv > 0)
{
shader.SetValue( "DiffuseTexture", currentSheet.Texture );
shader.SetTexture("DiffuseTexture", currentSheet.Texture);
shader.Render(() =>
{
var vb = renderer.GetTempVertexBuffer();
@@ -49,12 +47,12 @@ namespace OpenRA.Graphics
public void DrawSprite(Sprite s, float2 location, WorldRenderer wr, string palette)
{
DrawSprite(s, location, wr.GetPaletteIndex(palette), s.size);
DrawSprite(s, location, wr.Palette(palette).Index, s.size);
}
public void DrawSprite(Sprite s, float2 location, WorldRenderer wr, string palette, float2 size)
{
DrawSprite(s, location, wr.GetPaletteIndex(palette), size);
DrawSprite(s, location, wr.Palette(palette).Index, size);
}
public void DrawSprite(Sprite s, float2 location, int paletteIndex, float2 size)
@@ -72,7 +70,6 @@ namespace OpenRA.Graphics
nv += 4;
}
// For RGBASpriteRenderer, which doesn't use palettes
public void DrawSprite(Sprite s, float2 location)
{
@@ -83,5 +80,19 @@ namespace OpenRA.Graphics
{
DrawSprite(s, location, 0, size);
}
public void DrawVertexBuffer(IVertexBuffer<Vertex> buffer, int start, int length, PrimitiveType type, Sheet sheet)
{
shader.SetTexture("DiffuseTexture", sheet.Texture);
shader.Render(() => renderer.DrawBatch(buffer, start, length, type));
}
public void SetShaderParams(ITexture palette, Size screen, float zoom, float2 scroll)
{
shader.SetTexture("Palette", palette);
shader.SetVec("Scroll", (int)scroll.X, (int)scroll.Y);
shader.SetVec("r1", zoom*2f/screen.Width, -zoom*2f/screen.Height);
shader.SetVec("r2", -1, 1);
}
}
}

View File

@@ -39,7 +39,7 @@ namespace OpenRA.Graphics
int nv = 0;
var terrainPalette = Game.modData.Palette.GetPaletteIndex("terrain");
var terrainPalette = wr.Palette("terrain").Index;
for( int j = map.Bounds.Top; j < map.Bounds.Bottom; j++ )
for( int i = map.Bounds.Left; i < map.Bounds.Right; i++ )
@@ -50,7 +50,7 @@ namespace OpenRA.Graphics
nv += 4;
if (tileMapping[map.MapTiles.Value[i, j]].sheet != terrainSheet)
throw new InvalidOperationException("Terrain sprites span multiple sheets");
throw new InvalidOperationException("Terrain sprites span multiple sheets. Try increasing Game.Settings.Graphics.SheetSize.");
}
vertexBuffer = Game.Renderer.Device.CreateVertexBuffer( vertices.Length );
@@ -72,9 +72,9 @@ namespace OpenRA.Graphics
if (firstRow < 0) firstRow = 0;
if (lastRow > map.Bounds.Height) lastRow = map.Bounds.Height;
if (world.LocalPlayer != null && !world.LocalShroud.Disabled && world.LocalShroud.Bounds.HasValue)
if (world.RenderedPlayer != null && !world.RenderedShroud.Disabled && world.RenderedShroud.Bounds.HasValue)
{
var r = world.LocalShroud.Bounds.Value;
var r = world.RenderedShroud.Bounds.Value;
if (firstRow < r.Top - map.Bounds.Top)
firstRow = r.Top - map.Bounds.Top;
@@ -84,11 +84,9 @@ namespace OpenRA.Graphics
if( lastRow < firstRow ) lastRow = firstRow;
Game.Renderer.WorldSpriteShader.SetValue( "DiffuseTexture", terrainSheet.Texture );
Game.Renderer.WorldSpriteShader.Render(() =>
Game.Renderer.DrawBatch(vertexBuffer,
verticesPerRow * firstRow, verticesPerRow * (lastRow - firstRow),
PrimitiveType.QuadList));
Game.Renderer.WorldSpriteRenderer.DrawVertexBuffer(
vertexBuffer, verticesPerRow * firstRow, verticesPerRow * (lastRow - firstRow),
PrimitiveType.QuadList, terrainSheet);
foreach (var r in world.WorldActor.TraitsImplementing<IRenderOverlay>())
r.Render( wr );

View File

@@ -8,40 +8,12 @@
*/
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using OpenRA.FileFormats.Graphics;
namespace OpenRA.Graphics
{
public static class Util
{
public static string[] ReadAllLines(Stream s)
{
List<string> result = new List<string>();
using (StreamReader reader = new StreamReader(s))
while(!reader.EndOfStream)
{
var line = reader.ReadLine();
if( !string.IsNullOrEmpty( line ) && line[0] != '#' )
result.Add( line );
}
return result.ToArray();
}
public static T[] MakeArray<T>(int count, Converter<int, T> f)
{
T[] result = new T[count];
for (int i = 0; i < count; i++)
result[i] = f(i);
return result;
}
static float[] channelSelect = { 0.75f, 0.25f, -0.25f, -0.75f };
public static void FastCreateQuad(Vertex[] vertices, float2 o, Sprite r, int palette, int nv, float2 size)
@@ -59,6 +31,7 @@ namespace OpenRA.Graphics
}
static readonly int[] channelMasks = { 2, 1, 0, 3 }; // yes, our channel order is nuts.
public static void FastCopyIntoChannel(Sprite dest, byte[] src)
{
var data = dest.sheet.Data;
@@ -79,28 +52,5 @@ namespace OpenRA.Graphics
destOffset += destSkip;
}
}
public static Color Lerp(float t, Color a, Color b)
{
return Color.FromArgb(
LerpChannel(t, a.A, b.A),
LerpChannel(t, a.R, b.R),
LerpChannel(t, a.G, b.G),
LerpChannel(t, a.B, b.B));
}
public static int LerpARGBColor(float t, int c1, int c2)
{
int a = LerpChannel(t, (c1 >> 24) & 255, (c2 >> 24) & 255);
int r = LerpChannel(t, (c1 >> 16) & 255, (c2 >> 16) & 255);
int g = LerpChannel(t, (c1 >> 8) & 255, (c2 >> 8) & 255);
int b = LerpChannel(t, c1 & 255, c2 & 255);
return (a << 24) | (r << 16) | (g << 8) | b;
}
public static int LerpChannel(float t, int a, int b)
{
return (int)((1 - t) * a + t * b);
}
}
}

View File

@@ -127,14 +127,9 @@ namespace OpenRA.Graphics
using( new PerfSample("render_widgets") )
{
Ui.Draw();
var cursorName = Ui.Root.GetCursorOuter(Viewport.LastMousePos) ?? "default";
var cursorSequence = CursorProvider.GetCursorSequence(cursorName);
var cursorSprite = cursorSequence.GetSprite((int)cursorFrame);
renderer.SpriteRenderer.DrawSprite(cursorSprite,
Viewport.LastMousePos - cursorSequence.Hotspot,
Game.modData.Palette.GetPaletteIndex(cursorSequence.Palette),
cursorSprite.size);
var cursorName = Ui.Root.GetCursorOuter(Viewport.LastMousePos) ?? "default";
CursorProvider.DrawCursor(renderer, cursorName, Viewport.LastMousePos, (int)cursorFrame);
}
using( new PerfSample("render_flip") )
@@ -149,18 +144,18 @@ namespace OpenRA.Graphics
}
// Convert from viewport coords to cell coords (not px)
public float2 ViewToWorld(MouseInput mi) { return ViewToWorld(mi.Location); }
public float2 ViewToWorld(int2 loc)
public CPos ViewToWorld(MouseInput mi) { return ViewToWorld(mi.Location); }
public CPos ViewToWorld(int2 loc)
{
return (1f / Game.CellSize) * (1f/Zoom*loc.ToFloat2() + Location);
return (CPos)( (1f / Game.CellSize) * (1f/Zoom*loc.ToFloat2() + Location) ).ToInt2();
}
public int2 ViewToWorldPx(int2 loc) { return (1f/Zoom*loc.ToFloat2() + Location).ToInt2(); }
public int2 ViewToWorldPx(MouseInput mi) { return ViewToWorldPx(mi.Location); }
public PPos ViewToWorldPx(int2 loc) { return (PPos)(1f/Zoom*loc.ToFloat2() + Location).ToInt2(); }
public PPos ViewToWorldPx(MouseInput mi) { return ViewToWorldPx(mi.Location); }
public void Center(float2 loc)
{
scrollPosition = NormalizeScrollPosition((Game.CellSize*loc - 1f/(2*Zoom)*screenSize.ToFloat2()).ToInt2());
scrollPosition = NormalizeScrollPosition((Game.CellSize * loc - 1f/(2*Zoom)*screenSize.ToFloat2()).ToInt2());
}
public void Center(IEnumerable<Actor> actors)
@@ -168,9 +163,9 @@ namespace OpenRA.Graphics
if (!actors.Any()) return;
var avgPos = actors
.Select(a => a.CenterLocation)
.Select(a => (PVecInt)a.CenterLocation)
.Aggregate((a, b) => a + b) / actors.Count();
scrollPosition = NormalizeScrollPosition((avgPos - 1f/(2*Zoom)*screenSize.ToFloat2()).ToInt2());
scrollPosition = NormalizeScrollPosition(((PVecFloat)avgPos - (PVecFloat)(1f / (2 * Zoom) * screenSize.ToFloat2())).ToInt2());
}
// Rectangle (in viewport coords) that contains things to be drawn
@@ -202,7 +197,7 @@ namespace OpenRA.Graphics
cachedScroll = scrollPosition;
}
var b = world.LocalShroud.Bounds;
var b = world.RenderedShroud.Bounds;
return (b.HasValue) ? Rectangle.Intersect(cachedRect, b.Value) : cachedRect;
}
}

View File

@@ -17,27 +17,54 @@ using OpenRA.Traits;
namespace OpenRA.Graphics
{
public class PaletteReference
{
public readonly string Name;
public readonly int Index;
public readonly Palette Palette;
public PaletteReference(string name, int index, Palette palette)
{
Name = name;
Index = index;
Palette = palette;
}
}
public class WorldRenderer
{
public readonly World world;
internal readonly TerrainRenderer terrainRenderer;
internal readonly ShroudRenderer shroudRenderer;
internal readonly HardwarePalette palette;
internal Cache<string, PaletteReference> palettes;
internal WorldRenderer(World world)
{
this.world = world;
this.palette = Game.modData.Palette;
foreach( var pal in world.traitDict.ActorsWithTraitMultiple<IPalette>( world ) )
palette = new HardwarePalette();
palettes = new Cache<string, PaletteReference>(CreatePaletteReference);
foreach (var pal in world.traitDict.ActorsWithTraitMultiple<IPalette>(world))
pal.Trait.InitPalette( this );
// Generate initial palette texture
palette.Update(new IPaletteModifier[] {});
terrainRenderer = new TerrainRenderer(world, this);
shroudRenderer = new ShroudRenderer(world);
}
public int GetPaletteIndex(string name) { return palette.GetPaletteIndex(name); }
public Palette GetPalette(string name) { return palette.GetPalette(name); }
public void AddPalette(string name, Palette pal) { palette.AddPalette(name, pal); }
PaletteReference CreatePaletteReference(string name)
{
var pal = palette.GetPalette(name);
if (pal == null)
throw new InvalidOperationException("Palette `{0}` does not exist".F(name));
return new PaletteReference(name, palette.GetPaletteIndex(name), pal);
}
public PaletteReference Palette(string name) { return palettes[name]; }
public void AddPalette(string name, Palette pal, bool allowModifiers) { palette.AddPalette(name, pal, allowModifiers); }
class SpriteComparer : IComparer<Renderable>
{
@@ -53,13 +80,14 @@ namespace OpenRA.Graphics
var comparer = new SpriteComparer();
var actors = world.FindUnits(
new int2(Game.CellSize*bounds.Left, Game.CellSize*bounds.Top),
new int2(Game.CellSize*bounds.Right, Game.CellSize*bounds.Bottom));
bounds.TopLeftAsCPos().ToPPos(),
bounds.BottomRightAsCPos().ToPPos()
);
var renderables = actors.SelectMany(a => a.Render())
var renderables = actors.SelectMany(a => a.Render(this))
.OrderBy(r => r, comparer);
var effects = world.Effects.SelectMany(e => e.Render());
var effects = world.Effects.SelectMany(e => e.Render(this));
return renderables.Concat(effects);
}
@@ -76,8 +104,8 @@ namespace OpenRA.Graphics
terrainRenderer.Draw(this, Game.viewport);
foreach (var a in world.traitDict.ActorsWithTraitMultiple<IRenderAsTerrain>(world))
foreach (var r in a.Trait.RenderAsTerrain(a.Actor))
r.Sprite.DrawAt(r.Pos, this.GetPaletteIndex(r.Palette), r.Scale);
foreach (var r in a.Trait.RenderAsTerrain(this, a.Actor))
r.Sprite.DrawAt(r.Pos, r.Palette.Index, r.Scale);
foreach (var a in world.Selection.Actors)
if (!a.Destroyed)
@@ -90,7 +118,7 @@ namespace OpenRA.Graphics
world.OrderGenerator.RenderBeforeWorld(this, world);
foreach (var image in SpritesToRender())
image.Sprite.DrawAt(image.Pos, this.GetPaletteIndex(image.Palette), image.Scale);
image.Sprite.DrawAt(image.Pos, image.Palette.Index, image.Scale);
// added for contrails
foreach (var a in world.ActorsWithTrait<IPostRender>())
@@ -140,25 +168,21 @@ namespace OpenRA.Graphics
selectable.DrawRollover(this, unit);
}
public void DrawLocus(Color c, int2[] cells)
public void DrawLocus(Color c, CPos[] cells)
{
var dict = cells.ToDictionary(a => a, a => 0);
var wlr = Game.Renderer.WorldLineRenderer;
foreach (var t in dict.Keys)
{
if (!dict.ContainsKey(t + new int2(-1, 0)))
wlr.DrawLine(Game.CellSize * t, Game.CellSize * (t + new int2(0, 1)),
c, c);
if (!dict.ContainsKey(t + new int2(1, 0)))
wlr.DrawLine(Game.CellSize * (t + new int2(1, 0)), Game.CellSize * (t + new int2(1, 1)),
c, c);
if (!dict.ContainsKey(t + new int2(0, -1)))
wlr.DrawLine(Game.CellSize * t, Game.CellSize * (t + new int2(1, 0)),
c, c);
if (!dict.ContainsKey(t + new int2(0, 1)))
wlr.DrawLine(Game.CellSize * (t + new int2(0, 1)), Game.CellSize * (t + new int2(1, 1)),
c, c);
if (!dict.ContainsKey(t + new CVec(-1, 0)))
wlr.DrawLine(t.ToPPos().ToFloat2(), (t + new CVec(0, 1)).ToPPos().ToFloat2(), c, c);
if (!dict.ContainsKey(t + new CVec(1, 0)))
wlr.DrawLine((t + new CVec(1, 0)).ToPPos().ToFloat2(), (t + new CVec(1, 1)).ToPPos().ToFloat2(), c, c);
if (!dict.ContainsKey(t + new CVec(0, -1)))
wlr.DrawLine(t.ToPPos().ToFloat2(), (t + new CVec(1, 0)).ToPPos().ToFloat2(), c, c);
if (!dict.ContainsKey(t + new CVec(0, 1)))
wlr.DrawLine((t + new CVec(0, 1)).ToPPos().ToFloat2(), (t + new CVec(1, 1)).ToPPos().ToFloat2(), c, c);
}
}
@@ -173,6 +197,16 @@ namespace OpenRA.Graphics
}
}
public void DrawRangeCircleWithContrast(Color fg, float2 location, float range, Color bg, int offset)
{
if (offset > 0) {
DrawRangeCircle(bg, location, range + (float) offset/Game.CellSize);
DrawRangeCircle(bg, location, range - (float) offset/Game.CellSize);
}
DrawRangeCircle(fg, location, range);
}
public void RefreshPalette()
{
palette.Update( world.WorldActor.TraitsImplementing<IPaletteModifier>() );

View File

@@ -39,6 +39,6 @@ namespace OpenRA
id, actors.Select(a => "#{0} {1}".F(a.ActorID, a.Info.Name)).JoinWith(",")));
}
/* todo: add lazy group path crap, groupleader, pruning, etc */
/* TODO: add lazy group path crap, groupleader, pruning, etc */
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
@@ -15,32 +15,53 @@ namespace OpenRA
public class NullInputHandler : IInputHandler
{
// ignore all input
public void ModifierKeys( Modifiers mods ) { }
public void OnKeyInput( KeyInput input ) { }
public void OnMouseInput( MouseInput input ) { }
public void ModifierKeys(Modifiers mods) { }
public void OnKeyInput(KeyInput input) { }
public void OnMouseInput(MouseInput input) { }
}
public class DefaultInputHandler : IInputHandler
{
readonly World world;
public DefaultInputHandler( World world )
public DefaultInputHandler(World world)
{
this.world = world;
}
public void ModifierKeys( Modifiers mods )
public void ModifierKeys(Modifiers mods)
{
Game.HandleModifierKeys( mods );
Game.HandleModifierKeys(mods);
}
public void OnKeyInput( KeyInput input )
public void OnKeyInput(KeyInput input)
{
Sync.CheckSyncUnchanged(world, () => Ui.HandleKeyPress(input));
}
public void OnMouseInput( MouseInput input )
public void OnMouseInput(MouseInput input)
{
Sync.CheckSyncUnchanged(world, () => Ui.HandleInput(input));
}
}
public class MouseButtonPreference
{
public MouseButton Action
{
get
{
return Game.Settings.Game.UseClassicMouseStyle ? MouseButton.Left : MouseButton.Right;
}
}
public MouseButton Cancel
{
get
{
return Game.Settings.Game.UseClassicMouseStyle ? MouseButton.Right : MouseButton.Left;
}
}
}
}

View File

@@ -37,6 +37,7 @@ namespace OpenRA
public string Description;
public string Author;
public string Tileset;
public string[] Difficulties;
[FieldLoader.Ignore] public Lazy<Dictionary<string, ActorReference>> Actors;
@@ -56,17 +57,11 @@ namespace OpenRA
[FieldLoader.Ignore] public Dictionary<string, PlayerReference> Players = new Dictionary<string, PlayerReference>();
[FieldLoader.Ignore] public Lazy<List<SmudgeReference>> Smudges;
// Rules overrides
[FieldLoader.Ignore] public List<MiniYamlNode> Rules = new List<MiniYamlNode>();
// Sequences overrides
[FieldLoader.Ignore] public List<MiniYamlNode> Sequences = new List<MiniYamlNode>();
// Weapon overrides
[FieldLoader.Ignore] public List<MiniYamlNode> Weapons = new List<MiniYamlNode>();
// Voices overrides
[FieldLoader.Ignore] public List<MiniYamlNode> Voices = new List<MiniYamlNode>();
[FieldLoader.Ignore] public List<MiniYamlNode> Notifications = new List<MiniYamlNode>();
// Binary map data
[FieldLoader.Ignore] public byte TileFormat = 1;
@@ -76,10 +71,7 @@ namespace OpenRA
[FieldLoader.Ignore] public Lazy<TileReference<byte, byte>[,]> MapResources;
[FieldLoader.Ignore] public string [,] CustomTerrain;
public Map()
{
// Do nothing; not a valid map (editor hack)
}
public Map() {} /* doesn't really produce a valid map, but enough for loading a mod */
public static Map FromTileset(string tileset)
{
@@ -160,6 +152,7 @@ namespace OpenRA
Sequences = NodesOrEmpty(yaml, "Sequences");
Weapons = NodesOrEmpty(yaml, "Weapons");
Voices = NodesOrEmpty(yaml, "Voices");
Notifications = NodesOrEmpty(yaml, "Notifications");
CustomTerrain = new string[MapSize.X, MapSize.Y];
@@ -186,6 +179,7 @@ namespace OpenRA
"Description",
"Author",
"Tileset",
"Difficulties",
"MapSize",
"Bounds",
"UseAsShellmap",
@@ -214,6 +208,7 @@ namespace OpenRA
root.Add(new MiniYamlNode("Sequences", null, Sequences));
root.Add(new MiniYamlNode("Weapons", null, Weapons));
root.Add(new MiniYamlNode("Voices", null, Voices));
root.Add(new MiniYamlNode("Notifications", null, Notifications));
var entries = new Dictionary<string, byte[]>();
entries.Add("map.bin", SaveBinaryData());
@@ -348,7 +343,7 @@ namespace OpenRA
return dataStream.ToArray();
}
public bool IsInMap(int2 xy) { return IsInMap(xy.X, xy.Y); }
public bool IsInMap(CPos xy) { return IsInMap(xy.X, xy.Y); }
public bool IsInMap(int x, int y) { return Bounds.Contains(x,y); }
static T[,] ResizeArray<T>(T[,] ts, T t, int width, int height)
@@ -390,22 +385,24 @@ namespace OpenRA
public void MakeDefaultPlayers()
{
Players.Clear();
var firstRace = OpenRA.Rules.Info["world"].Traits
.WithInterface<CountryInfo>().First(c => c.Selectable).Race;
Players.Add("Neutral", new PlayerReference
{
Name = "Neutral",
Race = firstRace,
OwnsWorld = true,
NonCombatant = true
});
if (!Players.ContainsKey("Neutral"))
Players.Add("Neutral", new PlayerReference
{
Name = "Neutral",
Race = firstRace,
OwnsWorld = true,
NonCombatant = true
});
var numSpawns = GetSpawnPoints().Length;
for (var index = 0; index < numSpawns; index++)
{
if (Players.ContainsKey("Multi{0}".F(index)))
continue;
var p = new PlayerReference
{
Name = "Multi{0}".F(index),

View File

@@ -28,7 +28,6 @@ namespace OpenRA
public ILoadScreen LoadScreen = null;
public SheetBuilder SheetBuilder;
public SpriteLoader SpriteLoader;
public HardwarePalette Palette { get; private set; }
public ModData( params string[] mods )
{
@@ -51,13 +50,11 @@ namespace OpenRA
AvailableMaps = FindMaps(Manifest.Mods);
Palette = new HardwarePalette();
ChromeMetrics.Initialize(Manifest.ChromeMetrics);
ChromeProvider.Initialize(Manifest.Chrome);
SheetBuilder = new SheetBuilder(TextureChannel.Red);
SpriteLoader = new SpriteLoader(new string[] { ".shp" }, SheetBuilder);
CursorProvider.Initialize(Manifest.Cursors);
Palette.Update(new IPaletteModifier[] { });
}
public Map PrepareMap(string uid)
@@ -100,6 +97,7 @@ namespace OpenRA
.Concat(mods.SelectMany(p => FindMapsIn("{1}maps{0}{2}{0}".F(Path.DirectorySeparatorChar, Platform.SupportDir, p))));
var ret = new Dictionary<string, Map>();
foreach (var path in paths)
{
try
@@ -113,6 +111,7 @@ namespace OpenRA
Console.WriteLine("Details: {0}", e.ToString());
}
}
return ret;
}

View File

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

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2013 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,
@@ -36,6 +36,7 @@ namespace OpenRA.Network
public int LastTickTime = Environment.TickCount;
public bool GameStarted { get { return NetFrameNumber != 0; } }
public bool GamePaused {get; set;}
public IConnection Connection { get; private set; }
public readonly int SyncHeaderSize = 9;
@@ -139,17 +140,17 @@ namespace OpenRA.Network
if (index >= orders.Count())
OutOfSync(frame);
throw new InvalidOperationException("Out of sync in frame {0}.\n {1}".F(frame, orders.ElementAt(index).Order.ToString()));
throw new InvalidOperationException("Out of sync in frame {0}.\n {1}\n Compare syncreport.log with other players.".F(frame, orders.ElementAt(index).Order.ToString()));
}
void OutOfSync(int frame)
{
throw new InvalidOperationException("Out of sync in frame {0}.\n".F(frame));
throw new InvalidOperationException("Out of sync in frame {0}.\n Compare syncreport.log with other players.".F(frame));
}
void OutOfSync(int frame, string blame)
{
throw new InvalidOperationException("Out of sync in frame {0}: Blame {1}.\n".F(frame, blame));
throw new InvalidOperationException("Out of sync in frame {0}: Blame {1}.\n Compare syncreport.log with other players.".F(frame, blame));
}
public bool IsReadyForNextFrame

View File

@@ -10,35 +10,26 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.IO;
namespace OpenRA.Network
{
public class ReplayConnection : IConnection
{
//uint nextFrame = 1;
FileStream replayStream;
List<byte[]> sync = new List<byte[]>();
public ReplayConnection( string replayFilename )
{
replayStream = File.OpenRead( replayFilename );
}
public ReplayConnection( string replayFilename ) { replayStream = File.OpenRead( replayFilename ); }
public int LocalClientId
{
get { return 0; }
}
public ConnectionState ConnectionState
{
get { return ConnectionState.Connected; }
}
public int LocalClientId { get { return 0; } }
public ConnectionState ConnectionState { get { return ConnectionState.Connected; } }
// do nothing; ignore locally generated orders
public void Send( int frame, List<byte[]> orders ) { }
public void SendImmediate( List<byte[]> orders ) { }
public void SendSync( int frame, byte[] syncData )
{
var ms = new MemoryStream();
@@ -47,8 +38,6 @@ namespace OpenRA.Network
sync.Add( ms.ToArray() );
}
List<byte[]> sync = new List<byte[]>();
public void Receive( Action<int, byte[]> packetFn )
{
while( sync.Count != 0 )
@@ -56,9 +45,11 @@ namespace OpenRA.Network
packetFn( LocalClientId, sync[ 0 ] );
sync.RemoveAt( 0 );
}
if( replayStream == null ) return;
var reader = new BinaryReader( replayStream );
while( replayStream.Position < replayStream.Length )
{
var client = reader.ReadInt32();
@@ -66,56 +57,10 @@ namespace OpenRA.Network
var packet = reader.ReadBytes( packetLen );
packetFn( client, packet );
}
replayStream = null;
}
public void Dispose() { }
}
class ReplayRecorderConnection : IConnection
{
IConnection inner;
BinaryWriter writer;
public ReplayRecorderConnection( IConnection inner, FileStream replayFile )
{
this.inner = inner;
this.writer = new BinaryWriter( replayFile );
}
public int LocalClientId { get { return inner.LocalClientId; } }
public ConnectionState ConnectionState { get { return inner.ConnectionState; } }
public void Send( int frame, List<byte[]> orders ) { inner.Send( frame, orders ); }
public void SendImmediate( List<byte[]> orders ) { inner.SendImmediate( orders ); }
public void SendSync( int frame, byte[] syncData ) { inner.SendSync( frame, syncData ); }
public void Receive( Action<int, byte[]> packetFn )
{
inner.Receive( ( client, data ) =>
{
writer.Write( client );
writer.Write( data.Length );
writer.Write( data );
packetFn( client, data );
} );
}
bool disposed;
public void Dispose()
{
if( disposed )
return;
writer.Close();
inner.Dispose();
disposed = true;
}
~ReplayRecorderConnection()
{
Dispose();
}
}
}

View File

@@ -0,0 +1,114 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace OpenRA.Network
{
class ReplayRecorderConnection : IConnection
{
IConnection inner;
BinaryWriter writer;
Func<string> chooseFilename;
MemoryStream preStartBuffer = new MemoryStream();
public ReplayRecorderConnection( IConnection inner, Func<string> chooseFilename )
{
this.chooseFilename = chooseFilename;
this.inner = inner;
writer = new BinaryWriter(preStartBuffer);
}
void StartSavingReplay(byte[] initialContent)
{
var filename = chooseFilename();
var replaysDirectory = Path.Combine(Platform.SupportDir, "Replays");
if (!Directory.Exists(replaysDirectory))
Directory.CreateDirectory(replaysDirectory);
string fullFilename;
var id = -1;
do
{
fullFilename = Path.Combine(replaysDirectory, id < 0
? "{0}.rep".F(filename)
: "{0}-{1}.rep".F(filename, id));
id++;
}
while (File.Exists(fullFilename));
var file = File.Create(fullFilename);
file.Write(initialContent);
this.writer = new BinaryWriter(file);
}
public int LocalClientId { get { return inner.LocalClientId; } }
public ConnectionState ConnectionState { get { return inner.ConnectionState; } }
public void Send( int frame, List<byte[]> orders ) { inner.Send( frame, orders ); }
public void SendImmediate( List<byte[]> orders ) { inner.SendImmediate( orders ); }
public void SendSync( int frame, byte[] syncData ) { inner.SendSync( frame, syncData ); }
public void Receive( Action<int, byte[]> packetFn )
{
inner.Receive((client, data) =>
{
if (preStartBuffer != null && IsGameStart(data))
{
writer.Flush();
var preStartData = preStartBuffer.ToArray();
preStartBuffer = null;
StartSavingReplay(preStartData);
}
writer.Write(client);
writer.Write(data.Length);
writer.Write(data);
packetFn(client, data);
} );
}
bool IsGameStart(byte[] data)
{
if (data.Length == 5 && data[4] == 0xbf)
return false;
if (data.Length >= 5 && data[4] == 0x65)
return false;
var frame = BitConverter.ToInt32(data, 0);
return frame == 0 && data.ToOrderList(null).Any(
o => o.OrderString == "StartGame");
}
bool disposed;
public void Dispose()
{
if( disposed )
return;
writer.Close();
inner.Dispose();
disposed = true;
}
~ReplayRecorderConnection()
{
Dispose();
}
}
}

View File

@@ -37,12 +37,19 @@ namespace OpenRA.Network
return Slots.FirstOrDefault(s => !s.Value.Closed && ClientInSlot(s.Key) == null).Key;
}
public bool IsSinglePlayer
{
get { return Clients.Count(c => c.Bot == null) == 1; }
}
public enum ClientState { NotReady, Ready, Disconnected = 1000 }
public class Client
{
public int Index;
public ColorRamp ColorRamp;
public ColorRamp PreferredColorRamp; // Color that the client normally uses from settings.yaml.
public ColorRamp ColorRamp; // Actual color that the client is using.
// Usually the same as PreferredColorRamp but can be different on maps with locked colors.
public string Country;
public int SpawnPoint;
public string Name;
@@ -50,7 +57,7 @@ namespace OpenRA.Network
public int Team;
public string Slot; // slot ID, or null for observer
public string Bot; // Bot type, null for real clients
public bool IsAdmin;
public bool IsReady { get { return State == ClientState.Ready; } }
}
@@ -64,17 +71,22 @@ namespace OpenRA.Network
public bool LockColor;
public bool LockTeam;
public bool LockSpawn;
public bool Required;
}
public class Global
{
public string ServerName;
public string Map;
public string[] Ban;
public string[] Mods = { "ra" }; // mod names
public int OrderLatency = 3;
public int RandomSeed = 0;
public bool LockTeams = true; // don't allow team changes after game start.
public bool FragileAlliances = false; // Allow diplomatic stance changes after game start.
public bool AllowCheats = false;
public bool Dedicated;
public string Difficulty;
public bool Crates = true;
}
public Session(string[] mods)

View File

@@ -36,6 +36,7 @@ namespace OpenRA.Network
{
report.Frame = orderManager.NetFrameNumber;
report.SyncedRandom = orderManager.world.SharedRandom.Last;
report.TotalCount = orderManager.world.SharedRandom.TotalCount;
report.Traits.Clear();
foreach (var a in orderManager.world.ActorsWithTrait<ISync>())
{
@@ -58,7 +59,7 @@ namespace OpenRA.Network
if (r.Frame == frame)
{
Log.Write("sync", "Sync for net frame {0} -------------", r.Frame);
Log.Write("sync", "SharedRandom: "+r.SyncedRandom);
Log.Write("sync", "SharedRandom: {0} (#{1})", r.SyncedRandom, r.TotalCount);
Log.Write("sync", "Synced Traits:");
foreach (var a in r.Traits)
Log.Write("sync", "\t {0} {1} {2} {3} ({4})".F(
@@ -77,6 +78,7 @@ namespace OpenRA.Network
{
public int Frame;
public int SyncedRandom;
public int TotalCount;
public List<TraitReport> Traits = new List<TraitReport>();
}

View File

@@ -20,7 +20,7 @@ namespace OpenRA.Network
{
static Player FindPlayerByClient(this World world, Session.Client c)
{
/* todo: this is still a hack.
/* TODO: this is still a hack.
* the cases we're trying to avoid are the extra players on the host's client -- Neutral, other MapPlayers,..*/
return world.Players.FirstOrDefault(
p => (p.ClientIndex == c.Index && p.PlayerReference.Playable));
@@ -94,11 +94,28 @@ namespace OpenRA.Network
Game.StartGame(orderManager.LobbyInfo.GlobalSettings.Map, false);
break;
}
case "PauseGame":
{
var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
if(client != null)
{
orderManager.GamePaused = !orderManager.GamePaused;
var pausetext = "The game is {0} by {1}".F( orderManager.GamePaused ? "paused" : "un-paused", client.Name );
Game.AddChatLine(Color.White, "", pausetext);
}
break;
}
case "HandshakeRequest":
{
var request = HandshakeRequest.Deserialize(order.TargetString);
var localMods = orderManager.LobbyInfo.GlobalSettings.Mods.Select(m => "{0}@{1}".F(m,Mod.AllMods[m].Version)).ToArray();
// Check if mods match
if (localMods.FirstOrDefault().ToString().Split('@')[0] != request.Mods.FirstOrDefault().ToString().Split('@')[0])
throw new InvalidOperationException("Server's mod ({0}) and yours ({1}) don't match".F(localMods.FirstOrDefault().ToString().Split('@')[0], request.Mods.FirstOrDefault().ToString().Split('@')[0]));
// Check that the map exists on the client
if (!Game.modData.AvailableMaps.ContainsKey(request.Map))
throw new InvalidOperationException("Missing map {0}".F(request.Map));
@@ -106,6 +123,7 @@ namespace OpenRA.Network
var info = new Session.Client()
{
Name = Game.Settings.Player.Name,
PreferredColorRamp = Game.Settings.Player.ColorRamp,
ColorRamp = Game.Settings.Player.ColorRamp,
Country = "random",
SpawnPoint = 0,
@@ -113,7 +131,6 @@ namespace OpenRA.Network
State = Session.ClientState.NotReady
};
var localMods = orderManager.LobbyInfo.GlobalSettings.Mods.Select(m => "{0}@{1}".F(m,Mod.AllMods[m].Version)).ToArray();
var response = new HandshakeResponse()
{
Client = info,
@@ -146,7 +163,7 @@ namespace OpenRA.Network
case "SetStance":
{
if (Game.orderManager.LobbyInfo.GlobalSettings.LockTeams)
if (!Game.orderManager.LobbyInfo.GlobalSettings.FragileAlliances)
return;
var targetPlayer = order.Player.World.Players.FirstOrDefault(p => p.InternalName == order.TargetString);
@@ -185,8 +202,7 @@ namespace OpenRA.Network
{
var oldStance = p.Stances[target];
p.Stances[target] = s;
if (target == w.LocalPlayer)
w.WorldActor.Trait<Shroud>().UpdatePlayerStance(w, p, oldStance, s);
target.Shroud.UpdatePlayerStance(w, p, oldStance, s);
foreach (var nsc in w.ActorsWithTrait<INotifyStanceChanged>())
nsc.Trait.StanceChanged(nsc.Actor, p, target, oldStance, s);

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
@@ -12,9 +12,12 @@
<AssemblyName>OpenRA.Game</AssemblyName>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>2.0</OldToolsVersion>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<IsWebBootstrapper>false</IsWebBootstrapper>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<ApplicationIcon>OpenRA.ico</ApplicationIcon>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
@@ -27,11 +30,8 @@
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<ApplicationIcon>OpenRA.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
@@ -44,6 +44,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>bin\Release\</OutputPath>
@@ -55,11 +56,11 @@
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
@@ -79,6 +80,12 @@
<Compile Include="ActorInitializer.cs" />
<Compile Include="ActorMap.cs" />
<Compile Include="ActorReference.cs" />
<Compile Include="Graphics\QuadRenderer.cs" />
<Compile Include="PSubVec.cs" />
<Compile Include="PSubPos.cs" />
<Compile Include="PVecInt.cs" />
<Compile Include="PVecFloat.cs" />
<Compile Include="PPos.cs" />
<Compile Include="Download.cs" />
<Compile Include="Effects\DelayedAction.cs" />
<Compile Include="Effects\FlashTarget.cs" />
@@ -88,7 +95,7 @@
<Compile Include="GameRules\MusicInfo.cs" />
<Compile Include="GameRules\Rules.cs" />
<Compile Include="GameRules\Settings.cs" />
<Compile Include="GameRules\VoiceInfo.cs" />
<Compile Include="GameRules\SoundInfo.cs" />
<Compile Include="GameRules\WeaponInfo.cs" />
<Compile Include="Graphics\Animation.cs" />
<Compile Include="Graphics\AnimationWithOffset.cs" />
@@ -115,6 +122,8 @@
<Compile Include="Graphics\WorldRenderer.cs" />
<Compile Include="Group.cs" />
<Compile Include="InputHandler.cs" />
<Compile Include="CVec.cs" />
<Compile Include="CPos.cs" />
<Compile Include="Map.cs" />
<Compile Include="ModData.cs" />
<Compile Include="Network\Connection.cs" />
@@ -143,6 +152,7 @@
<Compile Include="Server\Server.cs" />
<Compile Include="Server\ServerOrder.cs" />
<Compile Include="Server\TraitInterfaces.cs" />
<Compile Include="Server\UPnP.cs" />
<Compile Include="Sound.cs" />
<Compile Include="Support\Arguments.cs" />
<Compile Include="Support\PerfHistory.cs" />
@@ -151,25 +161,25 @@
<Compile Include="TraitDictionary.cs" />
<Compile Include="Traits\Activity.cs" />
<Compile Include="Traits\Armor.cs" />
<Compile Include="Traits\CreatesShroud.cs" />
<Compile Include="Traits\DrawLineToTarget.cs" />
<Compile Include="Traits\EditorAppearance.cs" />
<Compile Include="Traits\EditorTilesetFilter.cs" />
<Compile Include="Traits\Health.cs" />
<Compile Include="Traits\LintAttributes.cs" />
<Compile Include="Traits\Player\DeveloperMode.cs" />
<Compile Include="Traits\Player\EvaAlerts.cs" />
<Compile Include="Traits\Player\PlayerResources.cs" />
<Compile Include="Traits\Render\RenderSimple.cs" />
<Compile Include="Traits\RevealsShroud.cs" />
<Compile Include="Traits\Selectable.cs" />
<Compile Include="Traits\SelectionDecorations.cs" />
<Compile Include="Traits\SubcellInit.cs" />
<Compile Include="Traits\Target.cs" />
<Compile Include="Traits\TraitsInterfaces.cs" />
<Compile Include="Traits\Util.cs" />
<Compile Include="Traits\ValidateOrder.cs" />
<Compile Include="Traits\Waypoint.cs" />
<Compile Include="Traits\World\Country.cs" />
<Compile Include="Traits\World\Fog.cs" />
<Compile Include="Traits\World\PlayerColorPalette.cs" />
<Compile Include="Traits\World\ResourceLayer.cs" />
<Compile Include="Traits\World\ResourceType.cs" />
@@ -187,6 +197,7 @@
<Compile Include="Widgets\GridLayout.cs" />
<Compile Include="Widgets\ImageWidget.cs" />
<Compile Include="Widgets\LabelWidget.cs" />
<Compile Include="Widgets\LineGraphWidget.cs" />
<Compile Include="Widgets\ListLayout.cs" />
<Compile Include="Widgets\MapPreviewWidget.cs" />
<Compile Include="Widgets\PasswordFieldWidget.cs" />
@@ -206,6 +217,7 @@
<Compile Include="Widgets\WorldInteractionControllerWidget.cs" />
<Compile Include="World.cs" />
<Compile Include="WorldUtils.cs" />
<Compile Include="Network\ReplayRecorderConnection.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
@@ -214,6 +226,11 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
<Visible>False</Visible>
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
@@ -229,6 +246,11 @@
<ProductName>.NET Framework 3.5</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Content Include="OpenRA.ico" />

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2013 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,
@@ -17,15 +17,11 @@ namespace OpenRA.Orders
{
class UnitOrderGenerator : IOrderGenerator
{
public IEnumerable<Order> Order( World world, int2 xy, MouseInput mi )
public IEnumerable<Order> Order(World world, CPos xy, MouseInput mi)
{
var underCursor = world.FindUnitsAtMouse(mi.Location)
.Where(a => a.HasTrait<ITargetable>())
.OrderByDescending(
a =>
a.Info.Traits.Contains<SelectableInfo>()
? a.Info.Traits.Get<SelectableInfo>().Priority
: int.MinValue)
.OrderByDescending(a => a.SelectionPriority())
.FirstOrDefault();
var orders = world.Selection.Actors
@@ -45,17 +41,17 @@ namespace OpenRA.Orders
yield return CheckSameOrder(o.iot, o.trait.IssueOrder(o.self, o.iot, o.target, mi.Modifiers.HasModifier(Modifiers.Shift)));
}
public void Tick( World world ) { }
public void RenderBeforeWorld( WorldRenderer wr, World world ) { }
public void RenderAfterWorld( WorldRenderer wr, World world ) { }
public void Tick(World world) { }
public void RenderBeforeWorld(WorldRenderer wr, World world) { }
public void RenderAfterWorld(WorldRenderer wr, World world) { }
public string GetCursor( World world, int2 xy, MouseInput mi )
public string GetCursor(World world, CPos xy, MouseInput mi)
{
bool useSelect = false;
var underCursor = world.FindUnitsAtMouse(mi.Location)
.Where(a => a.HasTrait<ITargetable>())
.OrderByDescending(a => a.Info.Traits.Contains<SelectableInfo>() ? a.Info.Traits.Get<SelectableInfo>().Priority : int.MinValue)
.OrderByDescending(a => a.SelectionPriority())
.FirstOrDefault();
if (mi.Modifiers.HasModifier(Modifiers.Shift) || !world.Selection.Actors.Any())
@@ -67,12 +63,11 @@ namespace OpenRA.Orders
.Where(o => o != null)
.ToArray();
if( orders.Length == 0 ) return (useSelect) ? "select" : "default";
return orders[0].cursor ?? ((useSelect) ? "select" : "default");
var cursorName = orders.Select(o => o.cursor).FirstOrDefault();
return cursorName ?? (useSelect ? "select" : "default");
}
static UnitOrderResult OrderForUnit( Actor self, int2 xy, MouseInput mi, Actor underCursor )
static UnitOrderResult OrderForUnit(Actor self, CPos xy, MouseInput mi, Actor underCursor)
{
if (self.Owner != self.World.LocalPlayer)
return null;
@@ -80,35 +75,35 @@ namespace OpenRA.Orders
if (self.Destroyed)
return null;
if( mi.Button == MouseButton.Right )
if (mi.Button == Game.mouseButtonPreference.Action)
{
foreach( var o in self.TraitsImplementing<IIssueOrder>()
.SelectMany( trait => trait.Orders
.Select( x => new { Trait = trait, Order = x } ) )
.OrderByDescending( x => x.Order.OrderPriority ) )
.SelectMany(trait => trait.Orders
.Select(x => new { Trait = trait, Order = x } ))
.OrderByDescending(x => x.Order.OrderPriority))
{
var actorsAt = self.World.ActorMap.GetUnitsAt( xy ).ToList();
var actorsAt = self.World.ActorMap.GetUnitsAt(xy).ToList();
var forceAttack = mi.Modifiers.HasModifier(Modifiers.Ctrl);
var forceQueue = mi.Modifiers.HasModifier(Modifiers.Shift);
string cursor = null;
if( underCursor != null )
if (underCursor != null)
if (o.Order.CanTargetActor(self, underCursor, forceAttack, forceQueue, ref cursor))
return new UnitOrderResult( self, o.Order, o.Trait, cursor, Target.FromActor( underCursor ) );
return new UnitOrderResult(self, o.Order, o.Trait, cursor, Target.FromActor(underCursor));
if (o.Order.CanTargetLocation(self, xy, actorsAt, forceAttack, forceQueue, ref cursor))
return new UnitOrderResult( self, o.Order, o.Trait, cursor, Target.FromCell( xy ) );
return new UnitOrderResult(self, o.Order, o.Trait, cursor, Target.FromCell(xy));
}
}
return null;
}
static Order CheckSameOrder( IOrderTargeter iot, Order order )
static Order CheckSameOrder(IOrderTargeter iot, Order order)
{
if( order == null && iot.OrderID != null )
Game.Debug( "BUG: in order targeter - decided on {0} but then didn't order", iot.OrderID );
else if( iot.OrderID != order.OrderString )
Game.Debug( "BUG: in order targeter - decided on {0} but ordered {1}", iot.OrderID, order.OrderString );
if (order == null && iot.OrderID != null)
Game.Debug("BUG: in order targeter - decided on {0} but then didn't order", iot.OrderID);
else if (iot.OrderID != order.OrderString)
Game.Debug("BUG: in order targeter - decided on {0} but ordered {1}", iot.OrderID, order.OrderString);
return order;
}
@@ -120,7 +115,7 @@ namespace OpenRA.Orders
public readonly string cursor;
public readonly Target target;
public UnitOrderResult( Actor self, IOrderTargeter iot, IIssueOrder trait, string cursor, Target target )
public UnitOrderResult(Actor self, IOrderTargeter iot, IIssueOrder trait, string cursor, Target target)
{
this.self = self;
this.iot = iot;
@@ -130,4 +125,13 @@ namespace OpenRA.Orders
}
}
}
public static class SelectableExts
{
public static int SelectionPriority(this Actor a)
{
var selectableInfo = a.Info.Traits.GetOrDefault<SelectableInfo>();
return selectableInfo != null ? selectableInfo.Priority : int.MinValue;
}
}
}

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

@@ -0,0 +1,90 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Drawing;
namespace OpenRA
{
/// <summary>
/// Pixel coordinate position in the world (fine).
/// </summary>
public struct PPos
{
public readonly int X, Y;
public PPos(int x, int y) { X = x; Y = y; }
public static readonly PPos Zero = new PPos(0, 0);
public static explicit operator PPos(int2 a) { return new PPos(a.X, a.Y); }
public static explicit operator PVecInt(PPos a) { return new PVecInt(a.X, a.Y); }
public static explicit operator PVecFloat(PPos a) { return new PVecFloat(a.X, a.Y); }
public static PPos operator +(PPos a, PVecInt b) { return new PPos(a.X + b.X, a.Y + b.Y); }
public static PVecInt operator -(PPos a, PPos b) { return new PVecInt(a.X - b.X, a.Y - b.Y); }
public static PPos operator -(PPos a, PVecInt b) { return new PPos(a.X - b.X, a.Y - b.Y); }
public static bool operator ==(PPos me, PPos other) { return (me.X == other.X && me.Y == other.Y); }
public static bool operator !=(PPos me, PPos other) { return !(me == other); }
public static PPos Max(PPos a, PPos b) { return new PPos(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
public static PPos Min(PPos a, PPos b) { return new PPos(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
public static PPos Lerp(PPos a, PPos b, int mul, int div)
{
return a + ((PVecInt)(b - a) * mul / div);
}
public static PPos Average(params PPos[] list)
{
if (list == null || list.Length == 0)
throw new ArgumentException("PPos: Cannot calculate average of empty list.");
var x = 0;
var y = 0;
foreach(var pos in list)
{
x += pos.X;
y += pos.Y;
}
x /= list.Length;
y /= list.Length;
return new PPos(x,y);
}
public float2 ToFloat2() { return new float2(X, Y); }
public int2 ToInt2() { return new int2(X, Y); }
public CPos ToCPos() { return new CPos((int)(1f / Game.CellSize * X), (int)(1f / Game.CellSize * Y)); }
public PSubPos ToPSubPos() { return new PSubPos(X * PSubPos.PerPx, Y * PSubPos.PerPx); }
public PPos Clamp(Rectangle r)
{
return new PPos(Math.Min(r.Right, Math.Max(X, r.Left)),
Math.Min(r.Bottom, Math.Max(Y, r.Top)));
}
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
public override bool Equals(object obj)
{
if (obj == null)
return false;
PPos o = (PPos)obj;
return o == this;
}
public override string ToString() { return "{0},{1}".F(X, Y); }
}
}

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

@@ -0,0 +1,73 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Drawing;
namespace OpenRA
{
/// <summary>
/// Sub-pixel coordinate position in the world (very fine).
/// </summary>
public struct PSubPos
{
public readonly int X, Y;
public PSubPos(int x, int y) { X = x; Y = y; }
public const int PerPx = 1024;
public static readonly PSubPos Zero = new PSubPos(0, 0);
public static explicit operator PSubPos(int2 a) { return new PSubPos(a.X, a.Y); }
public static explicit operator PSubVec(PSubPos a) { return new PSubVec(a.X, a.Y); }
public static explicit operator PVecFloat(PSubPos a) { return new PVecFloat(a.X, a.Y); }
public static PSubPos operator +(PSubPos a, PSubVec b) { return new PSubPos(a.X + b.X, a.Y + b.Y); }
public static PSubVec operator -(PSubPos a, PSubPos b) { return new PSubVec(a.X - b.X, a.Y - b.Y); }
public static PSubPos operator -(PSubPos a, PSubVec b) { return new PSubPos(a.X - b.X, a.Y - b.Y); }
public static bool operator ==(PSubPos me, PSubPos other) { return (me.X == other.X && me.Y == other.Y); }
public static bool operator !=(PSubPos me, PSubPos other) { return !(me == other); }
public static PSubPos Max(PSubPos a, PSubPos b) { return new PSubPos(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
public static PSubPos Min(PSubPos a, PSubPos b) { return new PSubPos(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
public static PSubPos Lerp(PSubPos a, PSubPos b, int mul, int div)
{
return a + ((PSubVec)(b - a) * mul / div);
}
public float2 ToFloat2() { return new float2(X, Y); }
public int2 ToInt2() { return new int2(X, Y); }
public PPos ToPPos() { return new PPos(X / PerPx, Y / PerPx); }
public CPos ToCPos() { return ToPPos().ToCPos(); }
public PSubPos Clamp(Rectangle r)
{
return new PSubPos(Math.Min(r.Right, Math.Max(X, r.Left)),
Math.Min(r.Bottom, Math.Max(Y, r.Top)));
}
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
public override bool Equals(object obj)
{
if (obj == null)
return false;
PSubPos o = (PSubPos)obj;
return o == this;
}
public override string ToString() { return "{0},{1}".F(X, Y); }
}
}

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

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

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

@@ -0,0 +1,97 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Drawing;
namespace OpenRA
{
/// <summary>
/// Pixel coordinate vector (fine; float)
/// </summary>
public struct PVecFloat
{
public readonly float X, Y;
public PVecFloat(float x, float y) { X = x; Y = y; }
public PVecFloat(Size p) { X = p.Width; Y = p.Height; }
public static readonly PVecFloat Zero = new PVecFloat(0, 0);
public static explicit operator PVecInt(PVecFloat a) { return new PVecInt((int)a.X, (int)a.Y); }
public static explicit operator PVecFloat(float2 a) { return new PVecFloat(a.X, a.Y); }
public static PVecFloat operator +(PVecFloat a, PVecFloat b) { return new PVecFloat(a.X + b.X, a.Y + b.Y); }
public static PVecFloat operator -(PVecFloat a, PVecFloat b) { return new PVecFloat(a.X - b.X, a.Y - b.Y); }
public static PVecFloat operator *(float a, PVecFloat b) { return new PVecFloat(a * b.X, a * b.Y); }
public static PVecFloat operator *(PVecFloat b, float a) { return new PVecFloat(a * b.X, a * b.Y); }
public static PVecFloat operator /(PVecFloat a, float b) { return new PVecFloat(a.X / b, a.Y / b); }
public static PVecFloat operator -(PVecFloat a) { return new PVecFloat(-a.X, -a.Y); }
public static bool operator ==(PVecFloat me, PVecFloat other) { return (me.X == other.X && me.Y == other.Y); }
public static bool operator !=(PVecFloat me, PVecFloat other) { return !(me == other); }
public static PVecFloat Max(PVecFloat a, PVecFloat b) { return new PVecFloat(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
public static PVecFloat Min(PVecFloat a, PVecFloat b) { return new PVecFloat(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
public static float Dot(PVecFloat a, PVecFloat b) { return a.X * b.X + a.Y * b.Y; }
public static PVecFloat FromAngle(float a) { return new PVecFloat((float)Math.Sin(a), (float)Math.Cos(a)); }
public static PVecFloat Lerp(PVecFloat a, PVecFloat b, float t)
{
return new PVecFloat(
float2.Lerp(a.X, b.X, t),
float2.Lerp(a.Y, b.Y, t)
);
}
public static PVecFloat Lerp(PVecFloat a, PVecFloat b, PVecFloat t)
{
return new PVecFloat(
float2.Lerp(a.X, b.X, t.X),
float2.Lerp(a.Y, b.Y, t.Y)
);
}
public PVecFloat Sign() { return new PVecFloat(Math.Sign(X), Math.Sign(Y)); }
public PVecFloat Abs() { return new PVecFloat(Math.Abs(X), Math.Abs(Y)); }
public PVecFloat Round() { return new PVecFloat((float)Math.Round(X), (float)Math.Round(Y)); }
public float LengthSquared { get { return X * X + Y * Y; } }
public float Length { get { return (float)Math.Sqrt(LengthSquared); } }
public float2 ToFloat2() { return new float2(X, Y); }
public int2 ToInt2() { return new int2((int)X, (int)Y); }
static float Constrain(float x, float a, float b) { return x < a ? a : x > b ? b : x; }
public PVecFloat Constrain(PVecFloat min, PVecFloat max)
{
return new PVecFloat(
Constrain(X, min.X, max.X),
Constrain(Y, min.Y, max.Y)
);
}
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
public override bool Equals(object obj)
{
if (obj == null)
return false;
PVecFloat o = (PVecFloat)obj;
return o == this;
}
public override string ToString() { return "({0},{1})".F(X, Y); }
}
}

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

@@ -0,0 +1,80 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Drawing;
namespace OpenRA
{
/// <summary>
/// Pixel coordinate vector (fine; integer)
/// </summary>
public struct PVecInt
{
public readonly int X, Y;
public PVecInt(int x, int y) { X = x; Y = y; }
public PVecInt(Size p) { X = p.Width; Y = p.Height; }
public static readonly PVecInt Zero = new PVecInt(0, 0);
public static PVecInt OneCell { get { return new PVecInt(Game.CellSize, Game.CellSize); } }
public static implicit operator PVecFloat(PVecInt a) { return new PVecFloat((float)a.X, (float)a.Y); }
public static explicit operator PVecInt(int2 a) { return new PVecInt(a.X, a.Y); }
public static PVecInt FromRadius(int r) { return new PVecInt(r, r); }
public static PVecInt operator +(PVecInt a, PVecInt b) { return new PVecInt(a.X + b.X, a.Y + b.Y); }
public static PVecInt operator -(PVecInt a, PVecInt b) { return new PVecInt(a.X - b.X, a.Y - b.Y); }
public static PVecInt operator *(int a, PVecInt b) { return new PVecInt(a * b.X, a * b.Y); }
public static PVecInt operator *(PVecInt b, int a) { return new PVecInt(a * b.X, a * b.Y); }
public static PVecInt operator /(PVecInt a, int b) { return new PVecInt(a.X / b, a.Y / b); }
public static PVecInt operator -(PVecInt a) { return new PVecInt(-a.X, -a.Y); }
public static bool operator ==(PVecInt me, PVecInt other) { return (me.X == other.X && me.Y == other.Y); }
public static bool operator !=(PVecInt me, PVecInt other) { return !(me == other); }
public static PVecInt Max(PVecInt a, PVecInt b) { return new PVecInt(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
public static PVecInt Min(PVecInt a, PVecInt b) { return new PVecInt(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
public static int Dot(PVecInt a, PVecInt b) { return a.X * b.X + a.Y * b.Y; }
public PVecInt Sign() { return new PVecInt(Math.Sign(X), Math.Sign(Y)); }
public PVecInt Abs() { return new PVecInt(Math.Abs(X), Math.Abs(Y)); }
public int LengthSquared { get { return X * X + Y * Y; } }
public int Length { get { return (int)Math.Sqrt(LengthSquared); } }
public float2 ToFloat2() { return new float2(X, Y); }
public int2 ToInt2() { return new int2(X, Y); }
public CVec ToCVec() { return new CVec(X / Game.CellSize, Y / Game.CellSize); }
public PVecInt Clamp(Rectangle r)
{
return new PVecInt(
Math.Min(r.Right, Math.Max(X, r.Left)),
Math.Min(r.Bottom, Math.Max(Y, r.Top))
);
}
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
public override bool Equals(object obj)
{
if (obj == null)
return false;
PVecInt o = (PVecInt)obj;
return o == this;
}
public override string ToString() { return "{0},{1}".F(X, Y); }
}
}

View File

@@ -36,7 +36,7 @@ namespace OpenRA
public readonly PlayerReference PlayerReference;
public bool IsBot;
public Shroud Shroud { get { return World.LocalShroud; } }
public Shroud Shroud;
public World World { get; private set; }
static CountryInfo ChooseCountry(World world, string name)
@@ -68,7 +68,7 @@ namespace OpenRA
else
{
// Map player
ClientIndex = 0; // Owned by the host (todo: fix this)
ClientIndex = 0; // Owned by the host (TODO: fix this)
ColorRamp = pr.ColorRamp;
PlayerName = pr.Name;
NonCombatant = pr.NonCombatant;
@@ -76,7 +76,8 @@ namespace OpenRA
Country = ChooseCountry(world, pr.Race);
}
PlayerActor = world.CreateActor("Player", new TypeDictionary { new OwnerInit(this) });
Shroud = PlayerActor.Trait<Shroud>();
Shroud.Owner = this;
// Enable the bot logic on the host
IsBot = botType != null;
if (IsBot && Game.IsHost)
@@ -90,11 +91,6 @@ namespace OpenRA
}
}
public void GiveAdvice(string advice)
{
Sound.PlayToPlayer(this, advice);
}
public Dictionary<Player, Stance> Stances = new Dictionary<Player, Stance>();
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2013 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,
@@ -36,7 +36,7 @@ namespace OpenRA
if (isClick)
{
var adjNewSelection = newSelection.Take(1); /* todo: select BEST, not FIRST */
var adjNewSelection = newSelection.Take(1); /* TODO: select BEST, not FIRST */
actors = (isCombine ? oldSelection.SymmetricDifference(adjNewSelection) : adjNewSelection).ToList();
}
else
@@ -64,7 +64,7 @@ namespace OpenRA
Cache<int, List<Actor>> controlGroups = new Cache<int, List<Actor>>(_ => new List<Actor>());
public void DoControlGroup(World world, int group, Modifiers mods)
public void DoControlGroup(World world, int group, Modifiers mods, int MultiTapCount)
{
var addModifier = Platform.CurrentPlatform == PlatformType.OSX ? Modifiers.Meta : Modifiers.Ctrl;
if (mods.HasModifier(addModifier))
@@ -72,7 +72,8 @@ namespace OpenRA
if (actors.Count == 0)
return;
controlGroups[group].Clear();
if (!mods.HasModifier(Modifiers.Shift))
controlGroups[group].Clear();
for (var i = 0; i < 10; i++) /* all control groups */
controlGroups[i].RemoveAll(a => actors.Contains(a));
@@ -81,7 +82,7 @@ namespace OpenRA
return;
}
if (mods.HasModifier(Modifiers.Alt))
if (mods.HasModifier(Modifiers.Alt) || MultiTapCount >= 2)
{
Game.viewport.Center(controlGroups[group]);
return;

View File

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

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2012 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
@@ -15,13 +15,24 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using UPnP;
using System.Threading;
using OpenRA.FileFormats;
using OpenRA.GameRules;
using OpenRA.Network;
using XTimer = System.Timers.Timer;
namespace OpenRA.Server
{
public enum ServerState : int
{
WaitingPlayers = 1,
GameStarted = 2,
ShuttingDown = 3
}
public class Server
{
// Valid player connections
@@ -36,22 +47,42 @@ namespace OpenRA.Server
TypeDictionary ServerTraits = new TypeDictionary();
public Session lobbyInfo;
public bool GameStarted = false;
public readonly IPAddress Ip;
public readonly int Port;
int randomSeed;
public readonly Thirdparty.Random Random = new Thirdparty.Random();
public ServerSettings Settings;
public ModData ModData;
public Map Map;
XTimer gameTimeout;
volatile bool shutdown = false;
public void Shutdown() { shutdown = true; }
protected volatile ServerState pState = new ServerState();
public ServerState State
{
get { return pState; }
protected set { pState = value; }
}
public void Shutdown()
{
State = ServerState.ShuttingDown;
}
public void EndGame()
{
foreach (var t in ServerTraits.WithInterface<IEndGame>())
t.GameEnded(this);
if (Settings.AllowUPnP)
RemovePortforward();
}
public Server(IPEndPoint endpoint, string[] mods, ServerSettings settings, ModData modData)
{
Log.AddChannel("server", "server.log");
pState = ServerState.WaitingPlayers;
listener = new TcpListener(endpoint);
listener.Start();
var localEndpoint = (IPEndPoint)listener.LocalEndpoint;
@@ -63,6 +94,44 @@ namespace OpenRA.Server
randomSeed = (int)DateTime.Now.ToBinary();
if (Settings.AllowUPnP)
{
try
{
if (UPnP.NAT.Discover())
{
Log.Write("server", "UPnP-enabled router discovered.");
Log.Write("server", "Your IP is: {0}", UPnP.NAT.GetExternalIP() );
}
else
{
Log.Write("server", "No UPnP-enabled router detected.");
Settings.AllowUPnP = false;
}
}
catch (Exception e)
{
OpenRA.Log.Write("server", "Can't discover UPnP-enabled routers: {0}", e);
Settings.AllowUPnP = false;
}
}
if (Settings.AllowUPnP)
{
try
{
if (UPnP.NAT.ForwardPort(Port, ProtocolType.Tcp, "OpenRA"))
Log.Write("server", "Port {0} (TCP) has been forwarded.", Port);
else
Settings.AllowUPnP = false;
}
catch (Exception e)
{
OpenRA.Log.Write("server", "Can not forward ports via UPnP: {0}", e);
Settings.AllowUPnP = false;
}
}
foreach (var trait in modData.Manifest.ServerTraits)
ServerTraits.Add( modData.ObjectCreator.CreateObject<ServerTrait>(trait) );
@@ -70,6 +139,8 @@ namespace OpenRA.Server
lobbyInfo.GlobalSettings.RandomSeed = randomSeed;
lobbyInfo.GlobalSettings.Map = settings.Map;
lobbyInfo.GlobalSettings.ServerName = settings.Name;
lobbyInfo.GlobalSettings.Ban = settings.Ban;
lobbyInfo.GlobalSettings.Dedicated = settings.Dedicated;
foreach (var t in ServerTraits.WithInterface<INotifyServerStart>())
t.ServerStarted(this);
@@ -91,8 +162,11 @@ namespace OpenRA.Server
foreach( var c in preConns ) checkRead.Add( c.socket );
Socket.Select( checkRead, null, null, timeout );
if (shutdown)
if (State == ServerState.ShuttingDown)
{
EndGame();
break;
}
foreach( Socket s in checkRead )
if( s == listener.Server ) AcceptConnection();
@@ -101,16 +175,22 @@ namespace OpenRA.Server
var p = preConns.SingleOrDefault( c => c.socket == s );
if (p != null) p.ReadData( this );
}
else if (conns.Count > 0) conns.Single( c => c.socket == s ).ReadData( this );
else if (conns.Count > 0)
{
var conn = conns.SingleOrDefault( c => c.socket == s );
if (conn != null) conn.ReadData( this );
}
foreach (var t in ServerTraits.WithInterface<ITick>())
t.Tick(this);
if (shutdown)
if (State == ServerState.ShuttingDown)
{
EndGame();
break;
}
}
GameStarted = false;
foreach (var t in ServerTraits.WithInterface<INotifyServerShutdown>())
t.ServerShutdown(this);
@@ -119,21 +199,30 @@ namespace OpenRA.Server
try { listener.Stop(); }
catch { }
} ) { IsBackground = true }.Start();
}
/* lobby rework todo:
void RemovePortforward()
{
try
{
if (UPnP.NAT.DeleteForwardingRule(Port, ProtocolType.Tcp))
Log.Write("server", "Port {0} (TCP) forwarding rules has been removed.", Port);
}
catch (Exception e)
{
OpenRA.Log.Write("server", "Can not remove UPnP portforwarding rules: {0}", e);
}
}
/* lobby rework TODO:
* - "teams together" option for team games -- will eliminate most need
* for manual spawnpoint choosing.
* - 256 max players is a dirty hack
*/
int nextPlayerIndex = 0;
public int ChooseFreePlayerIndex()
{
for (var i = 0; i < 256; i++)
if (conns.All(c => c.PlayerIndex != i) && preConns.All(c => c.PlayerIndex != i)
&& lobbyInfo.Clients.All(c => c.Index != i))
return i;
throw new InvalidOperationException("Already got 256 players");
return nextPlayerIndex++;
}
void AcceptConnection()
@@ -179,7 +268,7 @@ namespace OpenRA.Server
{
try
{
if (GameStarted)
if (State == ServerState.GameStarted)
{
Log.Write("server", "Rejected connection from {0}; game is already started.",
newConn.socket.RemoteEndPoint);
@@ -193,11 +282,12 @@ namespace OpenRA.Server
var client = handshake.Client;
var mods = handshake.Mods;
// Check that the client has compatable mods
// Check that the client has compatible mods
var valid = mods.All( m => m.Contains('@')) && //valid format
mods.Count() == Game.CurrentMods.Count() && //same number
mods.Select( m => Pair.New(m.Split('@')[0], m.Split('@')[1])).All(kv => Game.CurrentMods.ContainsKey(kv.First) &&
(kv.Second == "{DEV_VERSION}" || Game.CurrentMods[kv.First].Version == "{DEV_VERSION}" || kv.Second == Game.CurrentMods[kv.First].Version));
if (!valid)
{
Log.Write("server", "Rejected connection from {0}; mods do not match.",
@@ -207,6 +297,32 @@ namespace OpenRA.Server
DropClient(newConn);
return;
}
// Drop DEV_VERSION if it's a Dedicated
if ( lobbyInfo.GlobalSettings.Dedicated && mods.Any(m => m.Contains("{DEV_VERSION}")) )
{
Log.Write("server", "Rejected connection from {0}; DEV_VERSION is not allowed here.",
newConn.socket.RemoteEndPoint);
SendOrderTo(newConn, "ServerError", "DEV_VERSION is not allowed here");
DropClient(newConn);
return;
}
// Check if IP is banned
if (lobbyInfo.GlobalSettings.Ban != null)
{
var remote_addr = ((IPEndPoint)newConn.socket.RemoteEndPoint).Address.ToString();
if (lobbyInfo.GlobalSettings.Ban.Contains(remote_addr))
{
Console.WriteLine("Rejected connection from "+client.Name+"("+newConn.socket.RemoteEndPoint+"); Banned.");
Log.Write("server", "Rejected connection from {0}; Banned.",
newConn.socket.RemoteEndPoint);
SendOrderTo(newConn, "ServerError", "You are banned from the server!");
DropClient(newConn);
return;
}
}
// Promote connection to a valid client
preConns.Remove(newConn);
@@ -220,7 +336,12 @@ namespace OpenRA.Server
SyncClientToPlayerReference(client, Map.Players[client.Slot]);
lobbyInfo.Clients.Add(client);
//Assume that first validated client is server admin
if(lobbyInfo.Clients.Where(c1 => c1.Bot == null).Count()==1)
client.IsAdmin=true;
OpenRA.Network.Session.Client clientAdmin = lobbyInfo.Clients.Where(c1 => c1.IsAdmin).Single();
Log.Write("server", "Client {0}: Accepted connection from {1}",
newConn.PlayerIndex, newConn.socket.RemoteEndPoint);
@@ -229,6 +350,24 @@ namespace OpenRA.Server
SyncLobbyInfo();
SendChat(newConn, "has joined the game.");
if ( File.Exists("{0}motd_{1}.txt".F(Platform.SupportDir, lobbyInfo.GlobalSettings.Mods[0])) )
{
var motd = System.IO.File.ReadAllText("{0}motd_{1}.txt".F(Platform.SupportDir, lobbyInfo.GlobalSettings.Mods[0]));
SendChatTo(newConn, motd);
}
if ( lobbyInfo.GlobalSettings.Dedicated )
{
if (client.IsAdmin)
SendChatTo(newConn, " You are admin now!");
else
SendChatTo(newConn, " Current admin is {0}".F(clientAdmin.Name));
}
if (mods.Any(m => m.Contains("{DEV_VERSION}")))
SendChat(newConn, "is running a development version, "+
"and may cause desync if they have any incompatible changes.");
}
catch (Exception) { DropClient(newConn); }
}
@@ -239,6 +378,8 @@ namespace OpenRA.Server
return;
if (pr.LockColor)
c.ColorRamp = pr.ColorRamp;
else
c.ColorRamp = c.PreferredColorRamp;
if (pr.LockRace)
c.Country = pr.Race;
if (pr.LockSpawn)
@@ -328,6 +469,9 @@ namespace OpenRA.Server
void InterpretServerOrder(Connection conn, ServerOrder so)
{
var fromClient = GetClient(conn);
var fromIndex = fromClient != null ? fromClient.Index : 0;
switch (so.Name)
{
case "Command":
@@ -343,17 +487,23 @@ namespace OpenRA.Server
}
break;
case "HandshakeResponse":
ValidateClient(conn, so.Data);
break;
case "Chat":
case "TeamChat":
var fromClient = GetClient(conn);
var fromIndex = fromClient != null ? fromClient.Index : 0;
foreach (var c in conns.Except(conn).ToArray())
DispatchOrdersToClient(c, fromIndex, 0, so.Serialize());
break;
break;
case "PauseRequest":
foreach (var c in conns.ToArray())
{ var x = Order.PauseGame();
DispatchOrdersToClient(c, fromIndex, 0, x.Serialize());
}
break;
}
}
@@ -370,16 +520,32 @@ namespace OpenRA.Server
{
conns.Remove(toDrop);
SendChat(toDrop, "Connection Dropped");
if (GameStarted)
OpenRA.Network.Session.Client dropClient = lobbyInfo.Clients.Where(c1 => c1.Index == toDrop.PlayerIndex).Single();
if (State == ServerState.GameStarted)
SendDisconnected(toDrop); /* Report disconnection */
lobbyInfo.Clients.RemoveAll(c => c.Index == toDrop.PlayerIndex);
// reassign admin if necessary
if ( lobbyInfo.GlobalSettings.Dedicated && dropClient.IsAdmin && State == ServerState.WaitingPlayers)
{
if (lobbyInfo.Clients.Where(c1 => c1.Bot == null).Count() > 0)
{
// client was not alone on the server but he was admin: set admin to the last connected client
OpenRA.Network.Session.Client lastClient = lobbyInfo.Clients.Where(c1 => c1.Bot == null).Last();
lastClient.IsAdmin = true;
SendChat(toDrop, "Admin left! {0} is a new admin now!".F(lastClient.Name));
}
}
DispatchOrders( toDrop, toDrop.MostRecentFrame, new byte[] { 0xbf } );
if (conns.Count != 0)
if (conns.Count != 0 || lobbyInfo.GlobalSettings.Dedicated)
SyncLobbyInfo();
if ( !lobbyInfo.GlobalSettings.Dedicated && dropClient.IsAdmin )
Shutdown();
}
try
@@ -391,7 +557,7 @@ namespace OpenRA.Server
public void SyncLobbyInfo()
{
if (!GameStarted) /* don't do this while the game is running, it breaks things. */
if (State != ServerState.GameStarted) /* don't do this while the game is running, it breaks things. */
DispatchOrders(null, 0,
new ServerOrder("SyncInfo", lobbyInfo.Serialize()).Serialize());
@@ -401,13 +567,17 @@ namespace OpenRA.Server
public void StartGame()
{
GameStarted = true;
State = ServerState.GameStarted;
listener.Stop();
Console.WriteLine("Game started");
foreach( var c in conns )
foreach( var d in conns )
DispatchOrdersToClient( c, d.PlayerIndex, 0x7FFFFFFF, new byte[] { 0xBF } );
// Drop any unvalidated clients
foreach (var c in preConns)
foreach (var c in preConns.ToArray())
DropClient(c);
DispatchOrders(null, 0,
@@ -415,6 +585,18 @@ namespace OpenRA.Server
foreach (var t in ServerTraits.WithInterface<IStartGame>())
t.GameStarted(this);
// Check TimeOut
if ( Settings.TimeOut > 10000 )
{
gameTimeout = new XTimer(Settings.TimeOut);
gameTimeout.Elapsed += (_,e) =>
{
Console.WriteLine("Timeout at {0}!!!", e.SignalTime);
Environment.Exit(0);
};
gameTimeout.Enabled = true;
}
}
}
}

View File

@@ -20,6 +20,7 @@ namespace OpenRA.Server
public interface INotifyServerShutdown { void ServerShutdown(Server server); }
public interface IStartGame { void GameStarted(Server server); }
public interface IClientJoined { void ClientJoined(Server server, Connection conn); }
public interface IEndGame { void GameEnded(Server server); }
public interface ITick
{
void Tick(Server server);
@@ -28,7 +29,7 @@ namespace OpenRA.Server
public abstract class ServerTrait {}
public class DebugServerTrait : ServerTrait, IInterpretCommand, IStartGame, INotifySyncLobbyInfo, INotifyServerStart, INotifyServerShutdown
public class DebugServerTrait : ServerTrait, IInterpretCommand, IStartGame, INotifySyncLobbyInfo, INotifyServerStart, INotifyServerShutdown, IEndGame
{
public bool InterpretCommand(Server server, Connection conn, Session.Client client, string cmd)
{
@@ -55,5 +56,10 @@ namespace OpenRA.Server
{
Console.WriteLine("ServerShutdown()");
}
public void GameEnded(Server server)
{
Console.WriteLine("GameEnded()");
}
}
}

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

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

View File

@@ -29,6 +29,12 @@ namespace OpenRA
static ISoundSource LoadSound(string filename)
{
if (!FileSystem.Exists(filename))
{
Log.Write("debug", "LoadSound, file does not exist: {0}", filename);
return null;
}
return LoadSoundRaw(AudLoader.LoadSound(FileSystem.Open(filename)));
}
@@ -37,9 +43,22 @@ namespace OpenRA
return soundEngine.AddSoundSourceFromMemory(rawData, 1, 16, 22050);
}
public static void Create()
static ISoundEngine CreateEngine(string engine)
{
soundEngine = new OpenAlSoundEngine();
engine = Game.Settings.Server.Dedicated?"Null":engine;
switch (engine)
{ /* TODO: if someone cares about pluggable crap here, ship this out */
case "AL": return new OpenAlSoundEngine();
case "Null": return new NullSoundEngine();
default:
throw new InvalidOperationException("Unsupported sound engine: {0}".F (engine));
}
}
public static void Create(string engine)
{
soundEngine = CreateEngine(engine);
}
public static void Initialize()
@@ -52,29 +71,29 @@ namespace OpenRA
public static void SetListenerPosition(float2 position) { soundEngine.SetListenerPosition(position); }
static ISound Play(Player player, string name, bool headRelative, float2 pos, float volumeModifier)
static ISound Play(Player player, string name, bool headRelative, PPos pos, float volumeModifier)
{
if (player != null && player != player.World.LocalPlayer)
if (String.IsNullOrEmpty(name))
return null;
if (name == "" || name == null)
if (player != null && player != player.World.LocalPlayer)
return null;
return soundEngine.Play2D(sounds[name],
false, headRelative, pos,
InternalSoundVolume * volumeModifier);
false, headRelative, pos.ToFloat2(),
InternalSoundVolume * volumeModifier, true);
}
public static ISound Play(string name) { return Play(null, name, true, float2.Zero, 1); }
public static ISound Play(string name, float2 pos) { return Play(null, name, false, pos, 1); }
public static ISound Play(string name, float volumeModifier) { return Play(null, name, true, float2.Zero, volumeModifier); }
public static ISound Play(string name, float2 pos, float volumeModifier) { return Play(null, name, false, pos, volumeModifier); }
public static ISound PlayToPlayer(Player player, string name) { return Play( player, name, true, float2.Zero, 1); }
public static ISound PlayToPlayer(Player player, string name, float2 pos) { return Play(player, name, false, pos, 1); }
public static ISound Play(string name) { return Play(null, name, true, PPos.Zero, 1); }
public static ISound Play(string name, PPos pos) { return Play(null, name, false, pos, 1); }
public static ISound Play(string name, float volumeModifier) { return Play(null, name, true, PPos.Zero, volumeModifier); }
public static ISound Play(string name, PPos pos, float volumeModifier) { return Play(null, name, false, pos, volumeModifier); }
public static ISound PlayToPlayer(Player player, string name) { return Play(player, name, true, PPos.Zero, 1); }
public static ISound PlayToPlayer(Player player, string name, PPos pos) { return Play(player, name, false, pos, 1); }
public static void PlayVideo(byte[] raw)
{
rawSource = LoadSoundRaw(raw);
video = soundEngine.Play2D(rawSource, false, true, float2.Zero, InternalSoundVolume);
video = soundEngine.Play2D(rawSource, false, true, float2.Zero, InternalSoundVolume, false);
}
public static void PlayVideo()
@@ -128,10 +147,12 @@ namespace OpenRA
}
StopMusic();
var sound = sounds[m.Filename];
if (sound == null) return;
music = soundEngine.Play2D(sound, false, true, float2.Zero, MusicVolume, false);
currentMusic = m;
MusicPlaying = true;
var sound = sounds[m.Filename];
music = soundEngine.Play2D(sound, false, true, float2.Zero, MusicVolume);
}
public static void PlayMusic()
@@ -226,7 +247,51 @@ namespace OpenRA
get { return (video != null) ? video.SeekPosition : 0; }
}
// Returns true if it played a phrase
// Returns true if played successfully
public static bool PlayPredefined(Player p, Actor voicedUnit, string type, string definition, string variant, bool attentuateVolume)
{
if (definition == null) return false;
if (Rules.Voices == null) return false;
if (Rules.Notifications == null) return false;
var rules = (voicedUnit != null) ? Rules.Voices[type] : Rules.Notifications[type];
if (rules == null) return false;
var ID = (voicedUnit != null) ? voicedUnit.ActorID : 0;
var clip = (voicedUnit != null) ? rules.VoicePools.Value[definition].GetNext() : rules.NotificationsPools.Value[definition].GetNext();
if (clip == null) return false;
var suffix = rules.DefaultVariant;
var prefix = rules.DefaultPrefix;
if (voicedUnit != null)
{
if (!rules.VoicePools.Value.ContainsKey("Attack"))
rules.VoicePools.Value.Add("Attack", rules.VoicePools.Value["Move"]);
if (!rules.VoicePools.Value.ContainsKey("AttackMove"))
rules.VoicePools.Value.Add("AttackMove", rules.VoicePools.Value["Move"]);
}
if (variant != null)
{
if (rules.Variants.ContainsKey(variant) && !rules.DisableVariants.Contains(definition))
suffix = rules.Variants[variant][ID % rules.Variants[variant].Length];
if (rules.Prefixes.ContainsKey(variant) && !rules.DisablePrefixes.Contains(definition))
prefix = rules.Prefixes[variant][ID % rules.Prefixes[variant].Length];
}
var name = prefix + clip + suffix;
if (!String.IsNullOrEmpty(name) && (p == null || p == p.World.LocalPlayer))
soundEngine.Play2D(sounds[name],
false, true, float2.Zero,
InternalSoundVolume, attentuateVolume);
return true;
}
public static bool PlayVoice(string phrase, Actor voicedUnit, string variant)
{
if (voicedUnit == null) return false;
@@ -236,26 +301,24 @@ namespace OpenRA
if (mi == null) return false;
if (mi.Voice == null) return false;
var vi = Rules.Voices[mi.Voice.ToLowerInvariant()];
var type = mi.Voice.ToLowerInvariant();
if (!vi.Pools.Value.ContainsKey(phrase))
return false;
return PlayPredefined(null, voicedUnit, type, phrase, variant, true);
}
var clip = vi.Pools.Value[phrase].GetNext();
if (clip == null)
return false;
public static bool PlayNotification(Player player, string type, string notification, string variant)
{
if (type == null) return false;
if (notification == null) return false;
var variantExt = (vi.Variants.ContainsKey(variant) && !vi.DisableVariants.Contains(phrase)) ?
vi.Variants[variant][voicedUnit.ActorID % vi.Variants[variant].Length] : vi.DefaultVariant;
Play(clip + variantExt);
return true;
return PlayPredefined(player, null, type.ToLowerInvariant(), notification, variant, false);
}
}
interface ISoundEngine
{
ISoundSource AddSoundSourceFromMemory(byte[] data, int channels, int sampleBits, int sampleRate);
ISound Play2D(ISoundSource sound, bool loop, bool relative, float2 pos, float volume);
ISound Play2D(ISoundSource sound, bool loop, bool relative, float2 pos, float volume, bool attenuateVolume);
float Volume { get; set; }
void PauseSound(ISound sound, bool paused);
void StopSound(ISound sound);
@@ -276,8 +339,17 @@ namespace OpenRA
class OpenAlSoundEngine : ISoundEngine
{
class PoolSlot
{
public bool isActive;
public int frameStarted;
public float2 pos;
public bool isRelative;
public ISoundSource sound;
}
float volume = 1f;
Dictionary<int, bool> sourcePool = new Dictionary<int, bool>();
Dictionary<int, PoolSlot> sourcePool = new Dictionary<int, PoolSlot>();
const int POOL_SIZE = 32;
public OpenAlSoundEngine()
@@ -301,7 +373,7 @@ namespace OpenRA
return;
}
sourcePool.Add(source, false);
sourcePool.Add(source, new PoolSlot() { isActive = false });
}
}
@@ -309,9 +381,9 @@ namespace OpenRA
{
foreach (var kvp in sourcePool)
{
if (!kvp.Value)
if (!kvp.Value.isActive)
{
sourcePool[kvp.Key] = true;
sourcePool[kvp.Key].isActive = true;
return kvp.Key;
}
}
@@ -329,9 +401,9 @@ namespace OpenRA
return -1;
foreach (int i in freeSources)
sourcePool[i] = false;
sourcePool[i].isActive = false;
sourcePool[freeSources[0]] = true;
sourcePool[freeSources[0]].isActive = true;
return freeSources[0];
}
@@ -341,10 +413,62 @@ namespace OpenRA
return new OpenAlSoundSource(data, channels, sampleBits, sampleRate);
}
public ISound Play2D(ISoundSource sound, bool loop, bool relative, float2 pos, float volume)
const int maxInstancesPerFrame = 3;
const int groupDistance = 64;
const int groupDistanceSqr = groupDistance * groupDistance;
public ISound Play2D(ISoundSource sound, bool loop, bool relative, float2 pos, float volume, bool attenuateVolume)
{
if (sound == null)
{
Log.Write("debug", "Attempt to Play2D a null `ISoundSource`");
return null;
}
var world = Game.orderManager.world;
int currFrame = world != null ? world.FrameNumber : 0;
float atten = 1f;
// Check if max # of instances-per-location reached:
if (attenuateVolume)
{
int instances = 0, activeCount = 0;
foreach (var s in sourcePool.Values)
{
if (!s.isActive)
continue;
if (s.isRelative != relative)
continue;
++activeCount;
if (s.sound != sound)
continue;
if (currFrame - s.frameStarted >= 5)
continue;
// Too far away to count?
var lensqr = (s.pos - pos).LengthSquared;
if (lensqr >= groupDistanceSqr)
continue;
// If we are starting too many instances of the same sound within a short time then stop this one:
if (++instances == maxInstancesPerFrame)
return null;
}
// Attenuate a little bit based on number of active sounds:
atten = 0.66f * ((POOL_SIZE - activeCount * 0.5f) / POOL_SIZE);
}
int source = GetSourceFromPool();
return new OpenAlSound(source, (sound as OpenAlSoundSource).buffer, loop, relative, pos, volume);
if (source == -1) return null;
var slot = sourcePool[source];
slot.pos = pos;
slot.frameStarted = currFrame;
slot.sound = sound;
slot.isRelative = relative;
return new OpenAlSound(source, (sound as OpenAlSoundSource).buffer, loop, relative, pos, volume * atten);
}
public float Volume
@@ -355,6 +479,8 @@ namespace OpenRA
public void PauseSound(ISound sound, bool paused)
{
if (sound == null) return;
int key = ((OpenAlSound)sound).source;
int state;
Al.alGetSourcei(key, Al.AL_SOURCE_STATE, out state);
@@ -396,6 +522,8 @@ namespace OpenRA
public void StopSound(ISound sound)
{
if (sound == null) return;
int key = ((OpenAlSound)sound).source;
int state;
Al.alGetSourcei(key, Al.AL_SOURCE_STATE, out state);
@@ -453,15 +581,14 @@ namespace OpenRA
if (source == -1) return;
this.source = source;
Al.alSourcef(source, Al.AL_PITCH, 1f);
Al.alSourcef(source, Al.AL_GAIN, 1f);
Volume = volume;
Al.alSource3f(source, Al.AL_POSITION, pos.X, pos.Y, 0f);
Al.alSource3f(source, Al.AL_VELOCITY, 0f, 0f, 0f);
Al.alSourcei(source, Al.AL_BUFFER, buffer);
Al.alSourcei(source, Al.AL_LOOPING, looping ? Al.AL_TRUE : Al.AL_FALSE);
Al.alSourcei(source, Al.AL_SOURCE_RELATIVE, relative ? 1 : 0);
Al.alSourcef(source, Al.AL_REFERENCE_DISTANCE, 200);
Al.alSourcef(source, Al.AL_MAX_DISTANCE, 1500);
Volume = volume;
Al.alSourcef(source, Al.AL_REFERENCE_DISTANCE, 160);
Al.alSourcef(source, Al.AL_MAX_DISTANCE, 3200 / Game.viewport.Zoom);
Al.alSourcePlay(source);
}
@@ -495,4 +622,35 @@ namespace OpenRA
}
}
}
class NullSoundEngine : ISoundEngine
{
public ISoundSource AddSoundSourceFromMemory(byte[] data, int channels, int sampleBits, int sampleRate)
{
return new NullSoundSource();
}
public ISound Play2D(ISoundSource sound, bool loop, bool relative, float2 pos, float volume, bool attenuateVolume)
{
return new NullSound();
}
public void PauseSound(ISound sound, bool paused) {}
public void StopSound(ISound sound) {}
public void SetAllSoundsPaused(bool paused) {}
public void StopAllSounds() {}
public void SetListenerPosition(float2 position) {}
public void SetSoundVolume(float volume, ISound music, ISound video) {}
public float Volume { get; set; }
}
class NullSoundSource : ISoundSource {}
class NullSound : ISound
{
public float Volume { get; set; }
public float SeekPosition { get { return 0; } }
public bool Playing { get { return false; } }
}
}

View File

@@ -13,13 +13,14 @@ using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Windows.Forms;
using System.Text;
namespace OpenRA
{
static class Program
{
[STAThread]
static void Main( string[] args )
static void Main(string[] args)
{
// brutal hack
Application.CurrentCulture = CultureInfo.InvariantCulture;
@@ -32,19 +33,60 @@ namespace OpenRA
try
{
Run( args );
Run(args);
}
catch( Exception e )
catch (Exception e)
{
Log.AddChannel("exception", "exception.log");
Log.Write("exception", "{0}", e.ToString());
throw;
var rpt = BuildExceptionReport(e).ToString();
Log.Write("exception", "{0}", rpt);
Console.Error.WriteLine(rpt);
}
}
static void Run( string[] args )
static StringBuilder BuildExceptionReport(Exception e)
{
Game.Initialize( new Arguments(args) );
return BuildExceptionReport(e, new StringBuilder(), 0);
}
static void Indent(StringBuilder sb, int d)
{
sb.Append(new string(' ', d * 2));
}
static StringBuilder BuildExceptionReport(Exception e, StringBuilder sb, int d)
{
if (e == null) return sb;
sb.AppendFormat("Exception of type `{0}`: {1}", e.GetType().FullName, e.Message);
if (e is TypeLoadException)
{
var tle = (TypeLoadException)e;
sb.AppendLine();
Indent(sb, d);
sb.AppendFormat("TypeName=`{0}`", tle.TypeName);
}
else // TODO: more exception types
{
}
if (e.InnerException != null)
{
sb.AppendLine();
Indent(sb, d); sb.Append("Inner ");
BuildExceptionReport(e.InnerException, sb, d + 1);
}
sb.AppendLine();
Indent(sb, d); sb.Append(e.StackTrace);
return sb;
}
static void Run(string[] args)
{
Game.Initialize(new Arguments(args));
GC.Collect();
Game.Run();
}

View File

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

View File

@@ -54,31 +54,33 @@ namespace OpenRA
InnerGet( t ).Add( actor, val );
}
void CheckDestroyed(Actor actor)
{
if (actor.Destroyed)
throw new InvalidOperationException("Attempted to get trait from destroyed object ({0})".F(actor));
}
public bool Contains<T>( Actor actor )
{
if( actor.Destroyed )
throw new InvalidOperationException("Attempted to get trait from destroyed object ({0})".F(actor));
CheckDestroyed(actor);
return ( (TraitContainer<T>)InnerGet( typeof( T ) ) ).GetMultiple( actor.ActorID ).Count() != 0;
}
public T Get<T>( Actor actor )
{
if( actor.Destroyed )
throw new InvalidOperationException("Attempted to get trait from destroyed object ({0})".F(actor));
CheckDestroyed(actor);
return ( (TraitContainer<T>)InnerGet( typeof( T ) ) ).Get( actor.ActorID );
}
public T GetOrDefault<T>( Actor actor )
{
if( actor.Destroyed )
throw new InvalidOperationException("Attempted to get trait from destroyed object ({0})".F(actor));
CheckDestroyed(actor);
return ( (TraitContainer<T>)InnerGet( typeof( T ) ) ).GetOrDefault( actor.ActorID );
}
public IEnumerable<T> WithInterface<T>( Actor actor )
{
if( actor.Destroyed )
throw new InvalidOperationException("Attempted to get trait from destroyed object ({0})".F(actor));
CheckDestroyed(actor);
return ( (TraitContainer<T>)InnerGet( typeof( T ) ) ).GetMultiple( actor.ActorID );
}
@@ -118,14 +120,10 @@ namespace OpenRA
public T Get( uint actor )
{
++queries;
var index = actors.BinarySearchMany( actor );
if( index >= actors.Count || actors[ index ].ActorID != actor )
throw new InvalidOperationException("TraitDictionary does not contain instance of type `{0}`".F(typeof(T)));
else if( index + 1 < actors.Count && actors[ index + 1 ].ActorID == actor )
throw new InvalidOperationException("TraitDictionary contains multiple instance of type `{0}`".F(typeof(T)));
else
return traits[ index ];
var result = GetOrDefault(actor);
if ((object)result == null)
throw new InvalidOperationException("Actor does not have trait of type `{0}`".F(typeof(T)));
return result;
}
public T GetOrDefault( uint actor )
@@ -135,7 +133,7 @@ namespace OpenRA
if( index >= actors.Count || actors[ index ].ActorID != actor )
return default( T );
else if( index + 1 < actors.Count && actors[ index + 1 ].ActorID == actor )
throw new InvalidOperationException("TraitDictionary contains multiple instance of type `{0}`".F(typeof(T)));
throw new InvalidOperationException("Actor has multiple traits of type `{0}`".F(typeof(T)));
else return traits[ index ];
}

View File

@@ -0,0 +1,64 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System.Linq;
namespace OpenRA.Traits
{
public class CreatesShroudInfo : ITraitInfo
{
public readonly int Range = 0;
public object Create(ActorInitializer init) { return new CreatesShroud(this); }
}
public class CreatesShroud : ITick, ISync
{
CreatesShroudInfo Info;
[Sync] CPos previousLocation;
Shroud.ActorVisibility v;
public CreatesShroud(CreatesShroudInfo info)
{
Info = info;
}
public void Tick(Actor self)
{
// TODO: don't tick all the time.
if(self.Owner == null) return;
if (previousLocation != self.Location && v != null) {
previousLocation = self.Location;
var shrouds = self.World.ActorsWithTrait<Shroud>().Select(s => s.Actor.Owner.Shroud);
foreach (var shroud in shrouds) {
shroud.UnhideActor(self, v, Info.Range);
}
}
if (!self.TraitsImplementing<IDisable>().Any(d => d.Disabled)) {
var shrouds = self.World.ActorsWithTrait<Shroud>().Select(s => s.Actor.Owner.Shroud);
foreach (var shroud in shrouds) {
shroud.HideActor(self, Info.Range);
}
}
else {
var shrouds = self.World.ActorsWithTrait<Shroud>().Select(s => s.Actor.Owner.Shroud);
foreach (var shroud in shrouds) {
shroud.UnhideActor(self, v, Info.Range);
}
}
v = new Shroud.ActorVisibility {
vis = Shroud.GetVisOrigins(self).ToArray()
};
}
}
}

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