Compare commits
577 Commits
playtest-2
...
release-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7574124ff0 | ||
|
|
e1cb4d60c4 | ||
|
|
1d62329969 | ||
|
|
36813ff52f | ||
|
|
267141749d | ||
|
|
edd41c5be1 | ||
|
|
5dc0439173 | ||
|
|
4dbee1c0e3 | ||
|
|
76baba89c1 | ||
|
|
5da96941e1 | ||
|
|
c2ec8cd372 | ||
|
|
b73a0a9720 | ||
|
|
6f3b21616f | ||
|
|
1792f16929 | ||
|
|
8dfd02e69e | ||
|
|
c8b1c1b999 | ||
|
|
da9422824a | ||
|
|
403b51ca4b | ||
|
|
3fad0983b9 | ||
|
|
bbab5237d1 | ||
|
|
699838332d | ||
|
|
6e237b53e1 | ||
|
|
36990601db | ||
|
|
82f9549f01 | ||
|
|
656503c0c5 | ||
|
|
83fc70f415 | ||
|
|
bd8ba636c9 | ||
|
|
6eb2f2bffe | ||
|
|
d9a6cc6b1c | ||
|
|
8c3aabb215 | ||
|
|
d44d9f67f2 | ||
|
|
8f8800803b | ||
|
|
52007b6277 | ||
|
|
795008011e | ||
|
|
ec6b8646e9 | ||
|
|
40206f8280 | ||
|
|
887a9e7c9c | ||
|
|
e4218ede41 | ||
|
|
f4d0f80cd3 | ||
|
|
8661fb6b8d | ||
|
|
c212095a40 | ||
|
|
f337c7fb40 | ||
|
|
073a8ee079 | ||
|
|
a4b01cf114 | ||
|
|
cba069a039 | ||
|
|
bf4829205c | ||
|
|
328dce26ba | ||
|
|
0524708e05 | ||
|
|
7e376330d0 | ||
|
|
762db8b304 | ||
|
|
37479b3cfd | ||
|
|
07c2330245 | ||
|
|
0c6daf191c | ||
|
|
b897579a20 | ||
|
|
fcc0bcf438 | ||
|
|
0cd258f24f | ||
|
|
43e99bf9f5 | ||
|
|
83d10ba838 | ||
|
|
48997725c3 | ||
|
|
631f899f18 | ||
|
|
2a4a9d778f | ||
|
|
2e2b4d04db | ||
|
|
deede92fbc | ||
|
|
e3b2e84792 | ||
|
|
e07d55f5f4 | ||
|
|
1803b412c3 | ||
|
|
8dd7bfdb67 | ||
|
|
d1400ab4fa | ||
|
|
67c40f3119 | ||
|
|
68d0201538 | ||
|
|
d30d3ed05a | ||
|
|
43f2895eb8 | ||
|
|
185e3cffb4 | ||
|
|
d68196a3b0 | ||
|
|
4551302c09 | ||
|
|
56f36e45db | ||
|
|
8fabf1504a | ||
|
|
fd96d08ce8 | ||
|
|
0e801f9d3a | ||
|
|
e5ab56e843 | ||
|
|
ff0ad9cb41 | ||
|
|
3e81a4bd70 | ||
|
|
84f7aa56e1 | ||
|
|
c42f270ce0 | ||
|
|
af31ae4931 | ||
|
|
8b6308d3a2 | ||
|
|
6ecc4c18dc | ||
|
|
56557b8766 | ||
|
|
83ba80f4c9 | ||
|
|
65227c3c09 | ||
|
|
1b5474f377 | ||
|
|
38b5e2f7ca | ||
|
|
0ff3c56d4f | ||
|
|
4888732fb7 | ||
|
|
3079e2b488 | ||
|
|
34d96878b8 | ||
|
|
61e548151b | ||
|
|
7cc7dcc559 | ||
|
|
757c9ca63c | ||
|
|
5cb86f8937 | ||
|
|
cd1a29f1ea | ||
|
|
79b4765d9f | ||
|
|
05e9dcd5ce | ||
|
|
4c915ce8fe | ||
|
|
5d5fe3f5a1 | ||
|
|
5bacf69445 | ||
|
|
0a858ac353 | ||
|
|
b7258e61f3 | ||
|
|
bd45ffa022 | ||
|
|
b45f9568d0 | ||
|
|
f8290b8a7e | ||
|
|
21b002ce22 | ||
|
|
1fbd8f6cc6 | ||
|
|
2798f0d841 | ||
|
|
bf73cdbd01 | ||
|
|
03229eca0c | ||
|
|
489fdc1893 | ||
|
|
e2b2082660 | ||
|
|
5ab2e2b225 | ||
|
|
caa58e46c3 | ||
|
|
e9f4338852 | ||
|
|
f146cedad5 | ||
|
|
cc449f81f8 | ||
|
|
085e29d22b | ||
|
|
f8427fa242 | ||
|
|
eb9b6a3842 | ||
|
|
43fc1219f0 | ||
|
|
1469620831 | ||
|
|
036997a7a0 | ||
|
|
b4d9c40dc8 | ||
|
|
62257459fd | ||
|
|
ea641f081f | ||
|
|
a641c7a87d | ||
|
|
605a1eacf6 | ||
|
|
da3adf4f8e | ||
|
|
8680405b68 | ||
|
|
5ad2d1892f | ||
|
|
b723e350c8 | ||
|
|
0b665bc35b | ||
|
|
c012ea90dd | ||
|
|
b0b0fac847 | ||
|
|
c253e59c57 | ||
|
|
952e277d35 | ||
|
|
f984934270 | ||
|
|
fb58840cea | ||
|
|
3d8dc80f03 | ||
|
|
d970195394 | ||
|
|
c33c9e9f69 | ||
|
|
6d3a932453 | ||
|
|
622650785c | ||
|
|
362dc8128e | ||
|
|
f8e73afbee | ||
|
|
dbbe026b88 | ||
|
|
4b36a9bf7f | ||
|
|
70a5333b40 | ||
|
|
e8359b08c6 | ||
|
|
cebc0b66a5 | ||
|
|
6ac86cbc1a | ||
|
|
60ceb800e1 | ||
|
|
5f47b7b7fc | ||
|
|
7e2866714c | ||
|
|
7e8313b808 | ||
|
|
bfd28abb70 | ||
|
|
1afc0cbfce | ||
|
|
82bcd19d2e | ||
|
|
49049a715b | ||
|
|
3114a5b85e | ||
|
|
222f17a586 | ||
|
|
91027e9961 | ||
|
|
a06a7a8ccb | ||
|
|
a8bae22dd3 | ||
|
|
daa89f52b6 | ||
|
|
22c1059904 | ||
|
|
c0138966e7 | ||
|
|
0f14263b82 | ||
|
|
dfc6304efa | ||
|
|
632d717af8 | ||
|
|
a74a3aa3b5 | ||
|
|
c90c351692 | ||
|
|
5612a57842 | ||
|
|
6e3c8c9745 | ||
|
|
0920c67017 | ||
|
|
1ed0d80348 | ||
|
|
c41fcb15b0 | ||
|
|
6c79b454bf | ||
|
|
610e40b8d6 | ||
|
|
5038018aa5 | ||
|
|
cce12e781f | ||
|
|
245de3abcb | ||
|
|
11f9fa1942 | ||
|
|
85fa7eb8c4 | ||
|
|
62d7168d41 | ||
|
|
2a053daa2e | ||
|
|
21a903fe2d | ||
|
|
83fc546fbe | ||
|
|
f648223c39 | ||
|
|
583c3f9a64 | ||
|
|
0d9c78670e | ||
|
|
32a37d8c0f | ||
|
|
168ff6dc82 | ||
|
|
03f904155e | ||
|
|
f479f9a32d | ||
|
|
bdbb9d2a9f | ||
|
|
e3ae0ceae3 | ||
|
|
34ea82e267 | ||
|
|
fe7e016e33 | ||
|
|
f901355bef | ||
|
|
60fb45c909 | ||
|
|
9ccfb2c322 | ||
|
|
0c9f39df78 | ||
|
|
7fffb71ac4 | ||
|
|
bf0cee9057 | ||
|
|
55b17f70a8 | ||
|
|
c9318cd2dd | ||
|
|
ffd2588f50 | ||
|
|
c3b9b37122 | ||
|
|
a30d82b333 | ||
|
|
81e2c1d2d7 | ||
|
|
5f2ffc0508 | ||
|
|
00297b607b | ||
|
|
1c702048a1 | ||
|
|
fdd356c2e7 | ||
|
|
1e64a63fa4 | ||
|
|
05f079758a | ||
|
|
b220bbeda2 | ||
|
|
0a358a8846 | ||
|
|
ed43c1b482 | ||
|
|
c505954b07 | ||
|
|
d5279d123f | ||
|
|
9be501fc3d | ||
|
|
1721d7e025 | ||
|
|
881484d06a | ||
|
|
537cfb8fd3 | ||
|
|
41f1ea36fe | ||
|
|
486d340028 | ||
|
|
e2bbd22144 | ||
|
|
43d0363a55 | ||
|
|
b253de508b | ||
|
|
1da82aeba9 | ||
|
|
db4d6aaf22 | ||
|
|
5ea86873c6 | ||
|
|
0f126fd630 | ||
|
|
ecc2a7241f | ||
|
|
fbf68db0c0 | ||
|
|
9ce8c90d25 | ||
|
|
affa9ca336 | ||
|
|
3a1c4d1e6f | ||
|
|
45fbecbcd0 | ||
|
|
02f28f54c7 | ||
|
|
81f035904e | ||
|
|
8e2d712688 | ||
|
|
29b63bc3c0 | ||
|
|
d98cdd5331 | ||
|
|
94905afa3c | ||
|
|
a659892227 | ||
|
|
82eddfdf98 | ||
|
|
063191b09e | ||
|
|
3fc6f62aea | ||
|
|
48f934f188 | ||
|
|
192af5d60f | ||
|
|
53a7b0987b | ||
|
|
a3897dbc15 | ||
|
|
55651738a7 | ||
|
|
22bddf9645 | ||
|
|
2a37e6233e | ||
|
|
c1722e1270 | ||
|
|
95c27ef943 | ||
|
|
3aafde7e18 | ||
|
|
85678de9f0 | ||
|
|
bda4bfa4f3 | ||
|
|
481624e3f0 | ||
|
|
d1f12ff801 | ||
|
|
eae482d413 | ||
|
|
abd774d017 | ||
|
|
f2c630731e | ||
|
|
3e3977776d | ||
|
|
36fbddbb5c | ||
|
|
e33d988301 | ||
|
|
a55167c9ac | ||
|
|
d0a4555a1f | ||
|
|
4724ac6b00 | ||
|
|
d998367d35 | ||
|
|
0e9e7d0a9d | ||
|
|
5e1e5903d6 | ||
|
|
25fae5d109 | ||
|
|
44b8630c71 | ||
|
|
6204bfcabf | ||
|
|
1355a9f837 | ||
|
|
db8f22cdbf | ||
|
|
860ec9d85f | ||
|
|
5f2f25b758 | ||
|
|
3728685c67 | ||
|
|
5e6b8deec1 | ||
|
|
21f2b0df43 | ||
|
|
2100484598 | ||
|
|
ba1a36f26e | ||
|
|
9c9a16d80e | ||
|
|
3d8e215598 | ||
|
|
ce806fdbe6 | ||
|
|
208a3a47fe | ||
|
|
f0708ecfb2 | ||
|
|
653d72086c | ||
|
|
9258ba3ec7 | ||
|
|
d851c5646e | ||
|
|
ac0d3779f1 | ||
|
|
9a0d62dc85 | ||
|
|
59e1703b41 | ||
|
|
e49a439c79 | ||
|
|
b2e9085371 | ||
|
|
8cea309ec6 | ||
|
|
a59dfa555c | ||
|
|
e22126ca02 | ||
|
|
867f112dfe | ||
|
|
24e6e23000 | ||
|
|
498adc86a9 | ||
|
|
a20d1c95c8 | ||
|
|
4a101cf1b1 | ||
|
|
583b11a2b2 | ||
|
|
b3c5137add | ||
|
|
3dc39b2c9d | ||
|
|
5897a44fc5 | ||
|
|
8b0f15f80b | ||
|
|
1262cf0f29 | ||
|
|
b74e63f42d | ||
|
|
e89ee2c131 | ||
|
|
c2321e3eea | ||
|
|
22a49ba7c6 | ||
|
|
4d614e9122 | ||
|
|
e0069fd62a | ||
|
|
c75c72b525 | ||
|
|
007b2c5434 | ||
|
|
b8a932a084 | ||
|
|
61c3932340 | ||
|
|
c2029e9d5c | ||
|
|
d0548d6766 | ||
|
|
5a40c5df03 | ||
|
|
f5ba36a735 | ||
|
|
efe2f2e043 | ||
|
|
6681382819 | ||
|
|
7a578a0679 | ||
|
|
5fee165692 | ||
|
|
0a4669b925 | ||
|
|
109546d20f | ||
|
|
f5c606266d | ||
|
|
facf958bae | ||
|
|
480db8be42 | ||
|
|
7c4e32bd94 | ||
|
|
854a9c4eb7 | ||
|
|
cbb0b17c31 | ||
|
|
f2ab8a8541 | ||
|
|
63d21eac8c | ||
|
|
579ff04f68 | ||
|
|
18d75feb15 | ||
|
|
11da96fe22 | ||
|
|
9201b1cced | ||
|
|
e02397da3e | ||
|
|
6014f648f4 | ||
|
|
2c55a008f1 | ||
|
|
b9be918b6c | ||
|
|
781cbc00d3 | ||
|
|
b9365a149f | ||
|
|
1d4f1c657f | ||
|
|
9a66d7b530 | ||
|
|
3a87b934a6 | ||
|
|
9845d0e035 | ||
|
|
3754e791e5 | ||
|
|
643154de15 | ||
|
|
af8b29aee5 | ||
|
|
36c0ec753d | ||
|
|
9115fc4397 | ||
|
|
0d59a4dcd7 | ||
|
|
e0c3c53c00 | ||
|
|
11654cc893 | ||
|
|
bb85ea75e4 | ||
|
|
2450576dbe | ||
|
|
dd81b6d872 | ||
|
|
3160034d66 | ||
|
|
d0d3813173 | ||
|
|
2ff4a76955 | ||
|
|
9626ed356c | ||
|
|
5ecf8d3b7f | ||
|
|
8041b17032 | ||
|
|
b9cda8fcca | ||
|
|
ed6a625c69 | ||
|
|
d498ff1085 | ||
|
|
f8a0dd59b7 | ||
|
|
8e602104af | ||
|
|
aac78773f4 | ||
|
|
d3915ad291 | ||
|
|
b61e4a6083 | ||
|
|
5318380bfa | ||
|
|
a64629f1c5 | ||
|
|
5231da1ea3 | ||
|
|
aa06751de5 | ||
|
|
f10eb9e082 | ||
|
|
9966b4efd1 | ||
|
|
0ec3e8b227 | ||
|
|
984a498ed2 | ||
|
|
c122e6f54d | ||
|
|
1924cc71f1 | ||
|
|
220473bf74 | ||
|
|
4373f577d8 | ||
|
|
2f773e49ef | ||
|
|
03ec1f08cf | ||
|
|
a0f9f98b1c | ||
|
|
b59a0e8c0d | ||
|
|
1fa70d259f | ||
|
|
1f0da42a15 | ||
|
|
845379e577 | ||
|
|
80123b6aa4 | ||
|
|
1aafc9f726 | ||
|
|
8607575e2b | ||
|
|
162c386bdd | ||
|
|
445e5ec84b | ||
|
|
54c35e3721 | ||
|
|
a2b92d0fe4 | ||
|
|
2ed12f1d95 | ||
|
|
fe5bcdeab9 | ||
|
|
9c6bc45f8f | ||
|
|
2cc749118f | ||
|
|
331388bfe8 | ||
|
|
079a52ee65 | ||
|
|
5b470650b7 | ||
|
|
380875ad3e | ||
|
|
79976a4bfe | ||
|
|
769b5d7dc6 | ||
|
|
2a95c5f668 | ||
|
|
1bf649d27d | ||
|
|
bda92f3898 | ||
|
|
7220025a62 | ||
|
|
0b6eda0815 | ||
|
|
e70e778775 | ||
|
|
7fb659bd3a | ||
|
|
b109436cc3 | ||
|
|
6ba0c448c8 | ||
|
|
ed5ff9cd31 | ||
|
|
1146790dc1 | ||
|
|
cf1d4d0efb | ||
|
|
b127ae8027 | ||
|
|
9c49143534 | ||
|
|
6bc3249685 | ||
|
|
3ab197f400 | ||
|
|
9ff69b7946 | ||
|
|
0b98a8ce5e | ||
|
|
2e26047b23 | ||
|
|
2cdd1f7376 | ||
|
|
033dd10192 | ||
|
|
9f5a8512d2 | ||
|
|
5c4e49cc3f | ||
|
|
8eb4782a49 | ||
|
|
99eb3b046d | ||
|
|
ac0389d04f | ||
|
|
6929ed024a | ||
|
|
f4cb798c8b | ||
|
|
8f6b8b75bc | ||
|
|
cb3daab5fa | ||
|
|
4d16ca238c | ||
|
|
84d623397b | ||
|
|
26b75f406f | ||
|
|
b30e4ab432 | ||
|
|
b0e10c9ada | ||
|
|
c6a1031ab7 | ||
|
|
7cbed30dc6 | ||
|
|
ce0099f5d2 | ||
|
|
45a5e317c0 | ||
|
|
11ddd88d60 | ||
|
|
ce05b8dfec | ||
|
|
f5d397030c | ||
|
|
874799c2c3 | ||
|
|
20af089fcd | ||
|
|
21ab0b461c | ||
|
|
7af0e64708 | ||
|
|
527c6dc36b | ||
|
|
8831a93375 | ||
|
|
677efcbced | ||
|
|
4f1a7ff5fb | ||
|
|
c9edf7d0dc | ||
|
|
d64ecac74e | ||
|
|
c804be6f01 | ||
|
|
959875c709 | ||
|
|
4d94cb5593 | ||
|
|
c1fb5dd5f5 | ||
|
|
db0e1eabc7 | ||
|
|
801ff5cc17 | ||
|
|
94f7f1c473 | ||
|
|
9862b8ccee | ||
|
|
722c7a5f7d | ||
|
|
72d038e04e | ||
|
|
b83188d435 | ||
|
|
f9cbd1bbbf | ||
|
|
4e88166673 | ||
|
|
f3d68f4944 | ||
|
|
3827a5436a | ||
|
|
4a7417347a | ||
|
|
dc6b286d25 | ||
|
|
aa36a56b27 | ||
|
|
a831e72fa2 | ||
|
|
b96158adcb | ||
|
|
5414875d00 | ||
|
|
fd4b10c6bd | ||
|
|
d110b45679 | ||
|
|
22e0828566 | ||
|
|
c3052d863a | ||
|
|
0b4455515d | ||
|
|
4ed74c6cc0 | ||
|
|
ebf64f67cf | ||
|
|
b16849768d | ||
|
|
f140c6ec9c | ||
|
|
8f1d06ff31 | ||
|
|
3f0fafb380 | ||
|
|
84124de79d | ||
|
|
8ad4e08651 | ||
|
|
8f981977e0 | ||
|
|
676210422f | ||
|
|
749301899e | ||
|
|
1bb1e00a0d | ||
|
|
83ee6b758e | ||
|
|
accaf027fe | ||
|
|
9b1e798b35 | ||
|
|
cffaabb3bf | ||
|
|
5ab5bc9f7c | ||
|
|
d9c4aada8a | ||
|
|
27fa99852b | ||
|
|
ec7795fa99 | ||
|
|
8e74df6155 | ||
|
|
4984d07960 | ||
|
|
2a312911cb | ||
|
|
a20e30312e | ||
|
|
e0e1011d30 | ||
|
|
1fcf044980 | ||
|
|
2287f1f662 | ||
|
|
ffbc76919e | ||
|
|
083952a531 | ||
|
|
bd29d382c7 | ||
|
|
8df09da816 | ||
|
|
4778ef803e | ||
|
|
37f91542a9 | ||
|
|
e1907364e6 | ||
|
|
7f48a242db | ||
|
|
4362a215d9 | ||
|
|
72b2e03dd0 | ||
|
|
f7c1eb2933 | ||
|
|
5dd46b1b16 | ||
|
|
68a731ed5e | ||
|
|
4c667be946 | ||
|
|
66f82c6c2a | ||
|
|
ff32864b47 | ||
|
|
e9656795a2 | ||
|
|
3fbb81b4fc | ||
|
|
442138e1f8 | ||
|
|
2d39b1dfac | ||
|
|
3b704e25fa | ||
|
|
c068be453a | ||
|
|
6f8f940f31 | ||
|
|
c000640928 | ||
|
|
059347af40 | ||
|
|
f0001856bc | ||
|
|
8c218b67ab | ||
|
|
5426a5fd3c | ||
|
|
d1241c438a | ||
|
|
bc7aa9a491 | ||
|
|
ae94d7ecc7 | ||
|
|
7e1986ecbc | ||
|
|
a07697be03 | ||
|
|
b99e664726 | ||
|
|
881b4ba277 | ||
|
|
3058bfbc17 | ||
|
|
8a08365666 | ||
|
|
6c96a106e7 | ||
|
|
6291c8396b | ||
|
|
79afa07118 | ||
|
|
0e43043a33 | ||
|
|
c06fc02915 | ||
|
|
8badbb3d60 | ||
|
|
57283b4a80 | ||
|
|
d9992eea6a | ||
|
|
c8c4507acf |
16
.gitignore
vendored
16
.gitignore
vendored
@@ -10,6 +10,9 @@ obj
|
||||
*.manifest
|
||||
mods/*/*.dll
|
||||
|
||||
# ReSharper crap
|
||||
_ReSharper.*/
|
||||
|
||||
# Red Alert binary files
|
||||
mods/*/packages/*.[mM][iI][xX]
|
||||
|
||||
@@ -22,6 +25,8 @@ mods/*/packages/*.[mM][iI][xX]
|
||||
# backup files by various editors
|
||||
*~
|
||||
*.orig
|
||||
\#*
|
||||
.*.sw?
|
||||
# dependency DLLs (different for every platform!)
|
||||
cg.dll
|
||||
cgGL.dll
|
||||
@@ -32,8 +37,6 @@ cgGL.dll
|
||||
*.pidb
|
||||
*.userprefs
|
||||
|
||||
packaging/windows/*.exe
|
||||
|
||||
# osx crap
|
||||
.DS_Store
|
||||
|
||||
@@ -52,9 +55,6 @@ OpenRA.Launcher.Mac/OpenRA.xcodeproj/*.mode1v3
|
||||
*.config
|
||||
*.resources
|
||||
|
||||
# other crap
|
||||
Logs/
|
||||
Replays/
|
||||
settings.yaml
|
||||
\#*
|
||||
.*.sw?
|
||||
# KDE crap
|
||||
*.kate-swp
|
||||
*.directory
|
||||
4
AUTHORS
4
AUTHORS
@@ -12,16 +12,20 @@ The OpenRA developers are:
|
||||
Also thanks to:
|
||||
* Akseli Virtanen (RAGEQUIT)
|
||||
* Andrew Riedi
|
||||
* Barnaby Smith (mvi)
|
||||
* Bellator
|
||||
* Christer Ulfsparre (Holloweye)
|
||||
* Erasmus Schroder (rasco)
|
||||
* Igor Popov (ihptru)
|
||||
* James Dunne (jsd)
|
||||
* Jeff Harris (jeff_1amstudios)
|
||||
* Joakim Lindberg (booom3)
|
||||
* Kenny Hoxworth (hoxworth)
|
||||
* Kyrre Soerensen (zypres)
|
||||
* Lawrence Wang
|
||||
* Mark Olson (markolson)
|
||||
* Matthew Gatland (mgatland)
|
||||
* Matthias Mailänder (Mailaender)
|
||||
* Max Ugrumov (katzsmile)
|
||||
* Max621
|
||||
* Nukem
|
||||
|
||||
45
Makefile
45
Makefile
@@ -5,10 +5,10 @@ COMMON_LIBS = System.dll System.Core.dll System.Drawing.dll System.Xml.dll third
|
||||
PHONY = core tools package all mods clean distclean
|
||||
|
||||
.SUFFIXES:
|
||||
core: game renderers mod_ra mod_cnc utility
|
||||
core: game renderers mods utility tsbuild
|
||||
tools: editor ralint tsbuild
|
||||
package: core editor
|
||||
mods: mod_ra mod_cnc
|
||||
mods: mod_ra mod_cnc mod_d2k
|
||||
all: core tools
|
||||
clean:
|
||||
@-rm -f *.exe *.dll *.mdb mods/**/*.dll mods/**/*.mdb *.resources
|
||||
@@ -97,6 +97,16 @@ mod_cnc_EXTRA_CMDS = mono --debug RALint.exe cnc
|
||||
PROGRAMS += mod_cnc
|
||||
mod_cnc: $(mod_cnc_TARGET)
|
||||
|
||||
# Dune 2000
|
||||
mod_d2k_SRCS := $(shell find OpenRA.Mods.D2k/ -iname '*.cs')
|
||||
mod_d2k_TARGET = mods/d2k/OpenRA.Mods.D2k.dll
|
||||
mod_d2k_KIND = library
|
||||
mod_d2k_DEPS = $(STD_MOD_DEPS) $(mod_ra_TARGET) $(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
|
||||
#
|
||||
@@ -127,15 +137,19 @@ ralint: $(ralint_TARGET)
|
||||
|
||||
# Builds and exports tilesets from a bitmap
|
||||
tsbuild_SRCS := $(shell find OpenRA.TilesetBuilder/ -iname '*.cs')
|
||||
tsbuild_TARGET = TilesetBuilder.exe
|
||||
tsbuild_TARGET = OpenRA.TilesetBuilder.exe
|
||||
tsbuild_KIND = winexe
|
||||
tsbuild_DEPS = $(fileformats_TARGET) $(game_TARGET)
|
||||
tsbuild_LIBS = $(COMMON_LIBS) $(tsbuild_DEPS) System.Windows.Forms.dll
|
||||
tsbuild_EXTRA = -resource:OpenRA.TilesetBuilder.Form1.resources
|
||||
tsbuild_EXTRA = -resource:OpenRA.TilesetBuilder.frmBuilder.resources -resource:OpenRA.TilesetBuilder.frmNew.resources -resource:OpenRA.TilesetBuilder.Surface.resources
|
||||
PROGRAMS += tsbuild
|
||||
OpenRA.TilesetBuilder.Form1.resources:
|
||||
resgen2 OpenRA.TilesetBuilder/Form1.resx OpenRA.TilesetBuilder.Form1.resources 1> /dev/null
|
||||
tsbuild: OpenRA.TilesetBuilder.Form1.resources $(tsbuild_TARGET)
|
||||
OpenRA.TilesetBuilder.frmBuilder.resources:
|
||||
resgen2 OpenRA.TilesetBuilder/frmBuilder.resx OpenRA.TilesetBuilder.frmBuilder.resources 1> /dev/null
|
||||
OpenRA.TilesetBuilder.frmNew.resources:
|
||||
resgen2 OpenRA.TilesetBuilder/frmNew.resx OpenRA.TilesetBuilder.frmNew.resources 1> /dev/null
|
||||
OpenRA.TilesetBuilder.Surface.resources:
|
||||
resgen2 OpenRA.TilesetBuilder/Surface.resx OpenRA.TilesetBuilder.Surface.resources 1> /dev/null
|
||||
tsbuild: OpenRA.TilesetBuilder.frmBuilder.resources OpenRA.TilesetBuilder.frmNew.resources OpenRA.TilesetBuilder.Surface.resources $(tsbuild_TARGET)
|
||||
|
||||
#
|
||||
# Launchers / Utilities
|
||||
@@ -188,7 +202,7 @@ BIN_INSTALL_DIR = $(DESTDIR)$(bindir)
|
||||
INSTALL_DIR = $(DESTDIR)$(datadir)/openra
|
||||
INSTALL = install
|
||||
INSTALL_PROGRAM = $(INSTALL)
|
||||
CORE = fileformats rcg rgl rsdl rnull game editor utility
|
||||
CORE = fileformats rcg rgl rsdl rnull game editor utility tsbuild
|
||||
|
||||
install: all
|
||||
@-echo "Installing OpenRA to $(INSTALL_DIR)"
|
||||
@@ -196,6 +210,10 @@ install: all
|
||||
@$(INSTALL_PROGRAM) $(foreach prog,$(CORE),$($(prog)_TARGET)) $(INSTALL_DIR)
|
||||
@$(INSTALL_PROGRAM) -d $(INSTALL_DIR)/mods/cnc
|
||||
@$(INSTALL_PROGRAM) $(mod_cnc_TARGET) $(INSTALL_DIR)/mods/cnc
|
||||
@$(INSTALL_PROGRAM) -d $(INSTALL_DIR)/mods/ra
|
||||
@$(INSTALL_PROGRAM) $(mod_ra_TARGET) $(INSTALL_DIR)/mods/ra
|
||||
@$(INSTALL_PROGRAM) -d $(INSTALL_DIR)/mods/d2k
|
||||
@$(INSTALL_PROGRAM) $(mod_d2k_TARGET) $(INSTALL_DIR)/mods/d2k
|
||||
|
||||
@-cp $(foreach f,$(shell ls mods/cnc --hide=*.dll),mods/cnc/$(f)) $(INSTALL_DIR)/mods/cnc
|
||||
@cp -r mods/cnc/maps $(INSTALL_DIR)/mods/cnc
|
||||
@@ -205,8 +223,6 @@ install: all
|
||||
@cp -r mods/cnc/sequences $(INSTALL_DIR)/mods/cnc
|
||||
@cp -r mods/cnc/tilesets $(INSTALL_DIR)/mods/cnc
|
||||
@cp -r mods/cnc/uibits $(INSTALL_DIR)/mods/cnc
|
||||
@$(INSTALL_PROGRAM) -d $(INSTALL_DIR)/mods/ra
|
||||
@$(INSTALL_PROGRAM) $(mod_ra_TARGET) $(INSTALL_DIR)/mods/ra
|
||||
|
||||
@-cp $(foreach f,$(shell ls mods/ra --hide=*.dll),mods/ra/$(f)) $(INSTALL_DIR)/mods/ra
|
||||
@cp -r mods/ra/maps $(INSTALL_DIR)/mods/ra
|
||||
@@ -215,6 +231,14 @@ install: all
|
||||
@cp -r mods/ra/rules $(INSTALL_DIR)/mods/ra
|
||||
@cp -r mods/ra/tilesets $(INSTALL_DIR)/mods/ra
|
||||
@cp -r mods/ra/uibits $(INSTALL_DIR)/mods/ra
|
||||
|
||||
@-cp $(foreach f,$(shell ls mods/d2k --hide=*.dll),mods/d2k/$(f)) $(INSTALL_DIR)/mods/d2k
|
||||
@cp -r mods/d2k/maps $(INSTALL_DIR)/mods/d2k
|
||||
@cp -r mods/d2k/bits $(INSTALL_DIR)/mods/d2k
|
||||
@cp -r mods/d2k/chrome $(INSTALL_DIR)/mods/d2k
|
||||
@cp -r mods/d2k/rules $(INSTALL_DIR)/mods/d2k
|
||||
@cp -r mods/d2k/tilesets $(INSTALL_DIR)/mods/d2k
|
||||
@cp -r mods/d2k/uibits $(INSTALL_DIR)/mods/d2k
|
||||
|
||||
@cp -r glsl $(INSTALL_DIR)
|
||||
@cp -r cg $(INSTALL_DIR)
|
||||
@@ -237,3 +261,4 @@ install: all
|
||||
uninstall:
|
||||
@-rm -r $(INSTALL_DIR)
|
||||
@-rm $(DESTDIR)$(bindir)/openra
|
||||
@-rm $(DESTDIR)$(bindir)/openra-editor
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenRA.Editor
|
||||
for (var u = 0; u < template.Size.X; u++)
|
||||
for (var v = 0; v < template.Size.Y; v++)
|
||||
{
|
||||
if (surface.Map.IsInMap(new int2(u, v) + pos))
|
||||
if (surface.Map.IsInMap(new CVec(u, v) + pos))
|
||||
{
|
||||
var z = u + v * template.Size.X;
|
||||
if (tile.TileBitmapBytes[z] != null)
|
||||
@@ -69,17 +69,17 @@ namespace OpenRA.Editor
|
||||
Brush.Bitmap.Height * surface.Zoom);
|
||||
}
|
||||
|
||||
void FloodFillWithBrush(Surface s, int2 pos)
|
||||
void FloodFillWithBrush(Surface s, CPos pos)
|
||||
{
|
||||
var queue = new Queue<int2>();
|
||||
var queue = new Queue<CPos>();
|
||||
var replace = s.Map.MapTiles.Value[pos.X, pos.Y];
|
||||
var touched = new bool[s.Map.MapSize.X, s.Map.MapSize.Y];
|
||||
|
||||
Action<int, int> MaybeEnqueue = (x, y) =>
|
||||
Action<int, int> maybeEnqueue = (x, y) =>
|
||||
{
|
||||
if (s.Map.IsInMap(x, y) && !touched[x, y])
|
||||
{
|
||||
queue.Enqueue(new int2(x, y));
|
||||
queue.Enqueue(new CPos(x, y));
|
||||
touched[x, y] = true;
|
||||
}
|
||||
};
|
||||
@@ -91,16 +91,16 @@ namespace OpenRA.Editor
|
||||
if (!s.Map.MapTiles.Value[p.X, p.Y].Equals(replace))
|
||||
continue;
|
||||
|
||||
var a = FindEdge(s, p, new int2(-1, 0), replace);
|
||||
var b = FindEdge(s, p, new int2(1, 0), replace);
|
||||
var a = FindEdge(s, p, new CVec(-1, 0), replace);
|
||||
var b = FindEdge(s, p, new CVec(1, 0), replace);
|
||||
|
||||
for (var x = a.X; x <= b.X; x++)
|
||||
{
|
||||
s.Map.MapTiles.Value[x, p.Y] = new TileReference<ushort, byte> { type = Brush.N, index = (byte)0 };
|
||||
if (s.Map.MapTiles.Value[x, p.Y - 1].Equals(replace))
|
||||
MaybeEnqueue(x, p.Y - 1);
|
||||
maybeEnqueue(x, p.Y - 1);
|
||||
if (s.Map.MapTiles.Value[x, p.Y + 1].Equals(replace))
|
||||
MaybeEnqueue(x, p.Y + 1);
|
||||
maybeEnqueue(x, p.Y + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace OpenRA.Editor
|
||||
s.Chunks.Clear();
|
||||
}
|
||||
|
||||
int2 FindEdge(Surface s, int2 p, int2 d, TileReference<ushort, byte> replace)
|
||||
CPos FindEdge(Surface s, CPos p, CVec d, TileReference<ushort, byte> replace)
|
||||
{
|
||||
for (; ; )
|
||||
{
|
||||
|
||||
30
OpenRA.Editor/Form1.Designer.cs
generated
30
OpenRA.Editor/Form1.Designer.cs
generated
@@ -82,6 +82,9 @@ namespace OpenRA.Editor
|
||||
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
|
||||
this.toolStripStatusLabelFiller = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.toolStripStatusLabelMousePosition = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.copySelectionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.splitContainer1.Panel1.SuspendLayout();
|
||||
this.splitContainer1.Panel2.SuspendLayout();
|
||||
this.splitContainer1.SuspendLayout();
|
||||
@@ -417,8 +420,11 @@ namespace OpenRA.Editor
|
||||
this.resizeToolStripMenuItem,
|
||||
this.showActorNamesToolStripMenuItem,
|
||||
this.showGridToolStripMenuItem,
|
||||
this.toolStripSeparator5,
|
||||
this.fixOpenAreasToolStripMenuItem,
|
||||
this.setupDefaultPlayersMenuItem});
|
||||
this.setupDefaultPlayersMenuItem,
|
||||
this.toolStripSeparator4,
|
||||
this.copySelectionToolStripMenuItem});
|
||||
this.mapToolStripMenuItem.Name = "mapToolStripMenuItem";
|
||||
this.mapToolStripMenuItem.Size = new System.Drawing.Size(43, 23);
|
||||
this.mapToolStripMenuItem.Text = "&Map";
|
||||
@@ -507,6 +513,23 @@ namespace OpenRA.Editor
|
||||
this.toolStripStatusLabelMousePosition.Size = new System.Drawing.Size(22, 17);
|
||||
this.toolStripStatusLabelMousePosition.Text = "0,0";
|
||||
//
|
||||
// copySelectionToolStripMenuItem
|
||||
//
|
||||
this.copySelectionToolStripMenuItem.Name = "copySelectionToolStripMenuItem";
|
||||
this.copySelectionToolStripMenuItem.Size = new System.Drawing.Size(185, 22);
|
||||
this.copySelectionToolStripMenuItem.Text = "Copy Selection";
|
||||
this.copySelectionToolStripMenuItem.Click += new System.EventHandler(this.copySelectionToolStripMenuItem_Click);
|
||||
//
|
||||
// toolStripSeparator4
|
||||
//
|
||||
this.toolStripSeparator4.Name = "toolStripSeparator4";
|
||||
this.toolStripSeparator4.Size = new System.Drawing.Size(182, 6);
|
||||
//
|
||||
// toolStripSeparator5
|
||||
//
|
||||
this.toolStripSeparator5.Name = "toolStripSeparator5";
|
||||
this.toolStripSeparator5.Size = new System.Drawing.Size(182, 6);
|
||||
//
|
||||
// Form1
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
@@ -520,9 +543,9 @@ namespace OpenRA.Editor
|
||||
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);
|
||||
@@ -592,6 +615,9 @@ 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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,38 +138,62 @@ 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);
|
||||
// construct the palette of tiles
|
||||
var palettes = new[] { tilePalette, actorPalette, resourcePalette };
|
||||
foreach (var p in palettes) { p.Visible = false; p.SuspendLayout(); }
|
||||
foreach (var t in tileset.Templates)
|
||||
|
||||
foreach (var tc in tileset.Templates.GroupBy(t => t.Value.Category))
|
||||
{
|
||||
try
|
||||
var category = tc.Key ?? "(Uncategorized)";
|
||||
var categoryHeader = new Label
|
||||
{
|
||||
var bitmap = tileset.RenderTemplate((ushort)t.Key, palette);
|
||||
var ibox = new PictureBox
|
||||
BackColor = SystemColors.Highlight,
|
||||
ForeColor = SystemColors.HighlightText,
|
||||
Text = category,
|
||||
AutoSize = false,
|
||||
Height = 24,
|
||||
TextAlign = ContentAlignment.MiddleLeft,
|
||||
Width = tilePalette.ClientSize.Width,
|
||||
};
|
||||
// hook this manually, anchoring inside FlowLayoutPanel is flaky.
|
||||
tilePalette.Resize += (_,e) => categoryHeader.Width = tilePalette.ClientSize.Width;
|
||||
|
||||
if (tilePalette.Controls.Count > 0)
|
||||
tilePalette.SetFlowBreak(
|
||||
tilePalette.Controls[tilePalette.Controls.Count - 1], true);
|
||||
tilePalette.Controls.Add(categoryHeader);
|
||||
|
||||
foreach( var t in tc )
|
||||
{
|
||||
try
|
||||
{
|
||||
Image = bitmap,
|
||||
Width = bitmap.Width / 2,
|
||||
Height = bitmap.Height / 2,
|
||||
SizeMode = PictureBoxSizeMode.StretchImage
|
||||
};
|
||||
|
||||
var brushTemplate = new BrushTemplate { Bitmap = bitmap, N = t.Key };
|
||||
ibox.Click += (_, e) => surface1.SetTool(new BrushTool(brushTemplate));
|
||||
|
||||
var template = t.Value;
|
||||
tilePalette.Controls.Add(ibox);
|
||||
tt.SetToolTip(ibox,
|
||||
"{1}:{0} ({2}x{3})".F(
|
||||
template.Image,
|
||||
template.Id,
|
||||
template.Size.X,
|
||||
template.Size.Y));
|
||||
var bitmap = tileset.RenderTemplate((ushort)t.Key, palette);
|
||||
var ibox = new PictureBox
|
||||
{
|
||||
Image = bitmap,
|
||||
Width = bitmap.Width / 2,
|
||||
Height = bitmap.Height / 2,
|
||||
SizeMode = PictureBoxSizeMode.StretchImage
|
||||
};
|
||||
|
||||
var brushTemplate = new BrushTemplate { Bitmap = bitmap, N = t.Key };
|
||||
ibox.Click += (_, e) => surface1.SetTool(new BrushTool(brushTemplate));
|
||||
|
||||
var template = t.Value;
|
||||
tilePalette.Controls.Add(ibox);
|
||||
tt.SetToolTip(ibox,
|
||||
"{1}:{0} ({2}x{3})".F(
|
||||
template.Image,
|
||||
template.Id,
|
||||
template.Size.X,
|
||||
template.Size.Y));
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
var actorTemplates = new List<ActorTemplate>();
|
||||
@@ -522,5 +546,10 @@ namespace OpenRA.Editor
|
||||
var player = actorOwnerChooser.SelectedItem as PlayerReference;
|
||||
surface1.NewActorOwner = player.Name;
|
||||
}
|
||||
|
||||
private void copySelectionToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
surface1.CopySelection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,13 +120,45 @@
|
||||
<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>
|
||||
<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="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
|
||||
</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==
|
||||
</value>
|
||||
</data>
|
||||
<data name="newToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
@@ -260,41 +292,6 @@
|
||||
z2ki+Wo1CWklROkMCiT8wEm0kXEsCTmrAiTbDtcEpTVdZOS1oDfWk5xZ6RPeQZeUR8zxK0Qe1BO65xjr
|
||||
t0YotXhjAEAeQ7It8ZSESUjkznIq2bYsTGYW29JZxIs2nFEdLOSdfwFwpvLxRKIY2AAAAABJRU5ErkJg
|
||||
gg==
|
||||
</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
|
||||
</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==
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
|
||||
@@ -175,7 +175,7 @@ namespace OpenRA.Editor
|
||||
foreach( var kv in wps )
|
||||
{
|
||||
var a = new ActorReference("mpspawn");
|
||||
a.Add(new LocationInit(kv.Second));
|
||||
a.Add(new LocationInit((CPos)kv.Second));
|
||||
a.Add(new OwnerInit("Neutral"));
|
||||
Map.Actors.Value.Add("spawn" + kv.First, a);
|
||||
}
|
||||
@@ -276,7 +276,7 @@ namespace OpenRA.Editor
|
||||
Map.Actors.Value.Add("Actor" + ActorCount++,
|
||||
new ActorReference(overlayActorMapping[raOverlayNames[o]])
|
||||
{
|
||||
new LocationInit( new int2(i, j) ),
|
||||
new LocationInit( new CPos(i, j) ),
|
||||
new OwnerInit( "Neutral" )
|
||||
});
|
||||
}
|
||||
@@ -294,7 +294,7 @@ namespace OpenRA.Editor
|
||||
Map.Actors.Value.Add("Actor" + ActorCount++,
|
||||
new ActorReference(kv.Value.ToLowerInvariant())
|
||||
{
|
||||
new LocationInit(new int2(loc % MapSize, loc / MapSize)),
|
||||
new LocationInit(new CPos(loc % MapSize, loc / MapSize)),
|
||||
new OwnerInit("Neutral")
|
||||
});
|
||||
}
|
||||
@@ -323,7 +323,7 @@ namespace OpenRA.Editor
|
||||
foreach (KeyValuePair<string, string> kv in overlay)
|
||||
{
|
||||
var loc = int.Parse(kv.Key);
|
||||
var cell = new int2(loc % MapSize, loc / MapSize);
|
||||
var cell = new CPos(loc % MapSize, loc / MapSize);
|
||||
|
||||
var res = Pair.New((byte)0, (byte)0);
|
||||
if (overlayResourceMapping.ContainsKey(kv.Value.ToLower()))
|
||||
@@ -353,7 +353,7 @@ namespace OpenRA.Editor
|
||||
Map.Actors.Value.Add("Actor" + ActorCount++,
|
||||
new ActorReference(kv.Value.Split(',')[0].ToLowerInvariant())
|
||||
{
|
||||
new LocationInit(new int2(loc % MapSize, loc / MapSize)),
|
||||
new LocationInit(new CPos(loc % MapSize, loc / MapSize)),
|
||||
new OwnerInit("Neutral")
|
||||
});
|
||||
}
|
||||
@@ -380,7 +380,7 @@ namespace OpenRA.Editor
|
||||
|
||||
var actor = new ActorReference(parts[1].ToLowerInvariant())
|
||||
{
|
||||
new LocationInit(new int2(loc % MapSize, loc / MapSize)),
|
||||
new LocationInit(new CPos(loc % MapSize, loc / MapSize)),
|
||||
new OwnerInit(parts[0]),
|
||||
new HealthInit(float.Parse(parts[2], NumberFormatInfo.InvariantInfo)/256),
|
||||
new FacingInit((section == "INFANTRY") ? int.Parse(parts[6]) : int.Parse(parts[4])),
|
||||
@@ -432,7 +432,7 @@ namespace OpenRA.Editor
|
||||
(byte)(color.Second.GetBrightness() * 255))
|
||||
};
|
||||
|
||||
var Neutral = new [] {"Neutral"};
|
||||
var neutral = new [] {"Neutral"};
|
||||
foreach (var s in file.GetSection(section, true))
|
||||
{
|
||||
Console.WriteLine(s.Key);
|
||||
@@ -442,8 +442,8 @@ namespace OpenRA.Editor
|
||||
pr.InitialCash = int.Parse(s.Value);
|
||||
break;
|
||||
case "Allies":
|
||||
pr.Allies = s.Value.Split(',').Intersect(Players).Except(Neutral).ToArray();
|
||||
pr.Enemies = s.Value.Split(',').SymmetricDifference(Players).Except(Neutral).ToArray();
|
||||
pr.Allies = s.Value.Split(',').Intersect(Players).Except(neutral).ToArray();
|
||||
pr.Enemies = s.Value.Split(',').SymmetricDifference(Players).Except(neutral).ToArray();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
@@ -13,6 +13,25 @@
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ApplicationIcon>OpenRA.Editor.Icon.ico</ApplicationIcon>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<UpgradeBackupLocation />
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -25,6 +44,7 @@
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@@ -35,6 +55,7 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
@@ -122,6 +143,7 @@
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
@@ -157,6 +179,23 @@
|
||||
<ItemGroup>
|
||||
<Content Include="OpenRA.Editor.Icon.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Windows Installer 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
114
OpenRA.Editor/Properties/Resources.Designer.cs
generated
114
OpenRA.Editor/Properties/Resources.Designer.cs
generated
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
36
OpenRA.Editor/Properties/Settings.Designer.cs
generated
36
OpenRA.Editor/Properties/Settings.Designer.cs
generated
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,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 = () => { };
|
||||
@@ -59,7 +65,7 @@ namespace OpenRA.Editor
|
||||
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 +89,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 +165,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 +190,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 +215,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();
|
||||
@@ -267,31 +288,39 @@ 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);
|
||||
}
|
||||
|
||||
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 +333,7 @@ namespace OpenRA.Editor
|
||||
if (cp != null) bmp.Palette = restorePalette;
|
||||
}
|
||||
|
||||
void DrawActorBorder(SGraphics g, int2 p, ActorTemplate t)
|
||||
void DrawActorBorder(SGraphics g, CPos p, ActorTemplate t)
|
||||
{
|
||||
var centered = t.Appearance == null || !t.Appearance.RelativeToTopLeft;
|
||||
var drawPos = GetDrawPosition(p, t.Bitmap, centered);
|
||||
@@ -318,7 +347,7 @@ namespace OpenRA.Editor
|
||||
{
|
||||
var pr = Map.Players[name];
|
||||
var pcpi = Rules.Info["player"].Traits.Get<PlayerColorPaletteInfo>();
|
||||
var remap = new PlayerColorRemap(pcpi.PaletteFormat, pr.ColorRamp);
|
||||
var remap = new PlayerColorRemap(pcpi.RemapIndex, pr.ColorRamp);
|
||||
return new Palette(Palette, remap).AsSystemPalette();
|
||||
}
|
||||
|
||||
@@ -367,6 +396,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 +443,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)
|
||||
|
||||
@@ -184,6 +184,58 @@ 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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -105,11 +105,14 @@ namespace OpenRA.FileFormats
|
||||
levels.Add(new List<MiniYamlNode>());
|
||||
|
||||
var lineNo = 0;
|
||||
foreach (var line in lines)
|
||||
foreach (var ll in lines)
|
||||
{
|
||||
var line = ll;
|
||||
++lineNo;
|
||||
if (line.Contains('#'))
|
||||
line = line.Substring(0, line.IndexOf('#')).TrimEnd(' ', '\t');
|
||||
var t = line.TrimStart(' ', '\t');
|
||||
if (t.Length == 0 || t[0] == '#')
|
||||
if (t.Length == 0)
|
||||
continue;
|
||||
var level = line.Length - t.Length;
|
||||
var location = new MiniYamlNode.SourceLocation { Filename = filename, Line = lineNo };
|
||||
|
||||
@@ -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>
|
||||
@@ -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,7 @@ namespace OpenRA.FileFormats
|
||||
get { return colors; }
|
||||
}
|
||||
|
||||
public Palette(Stream s, bool remapTransparent)
|
||||
public Palette(Stream s, int[] remapShadow)
|
||||
{
|
||||
colors = new uint[256];
|
||||
|
||||
@@ -54,13 +54,9 @@ 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)
|
||||
@@ -92,12 +88,12 @@ namespace OpenRA.FileFormats
|
||||
return pal;
|
||||
}
|
||||
|
||||
public static Palette Load( string filename, bool remap )
|
||||
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); }
|
||||
}
|
||||
|
||||
@@ -14,40 +14,32 @@ using System.Linq;
|
||||
|
||||
namespace OpenRA.FileFormats
|
||||
{
|
||||
// TODO: ship this out of here.
|
||||
public enum PaletteFormat { ra, cnc, d2k }
|
||||
|
||||
public class PlayerColorRemap : IPaletteRemap
|
||||
{
|
||||
Dictionary<int, Color> remapColors;
|
||||
|
||||
static readonly int[] CncRemapRamp = new[] { 0, 2, 4, 6, 8, 10, 13, 15, 1, 3, 5, 7, 9, 11, 12, 14 };
|
||||
static readonly int[] NormalRemapRamp = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
|
||||
static int GetRemapBase(PaletteFormat fmt)
|
||||
public static int GetRemapIndex(int[] Ramp, int i)
|
||||
{
|
||||
return (fmt == PaletteFormat.cnc) ? 0xb0 : (fmt == PaletteFormat.d2k) ? 240 : 80;
|
||||
return Ramp[i];
|
||||
}
|
||||
|
||||
static int[] GetRemapRamp(PaletteFormat fmt)
|
||||
{
|
||||
return (fmt == PaletteFormat.cnc) ? CncRemapRamp : NormalRemapRamp;
|
||||
}
|
||||
|
||||
public static int GetRemapIndex(PaletteFormat fmt, int i)
|
||||
{
|
||||
return GetRemapBase(fmt) + GetRemapRamp(fmt)[i];
|
||||
}
|
||||
|
||||
public PlayerColorRemap(PaletteFormat fmt, ColorRamp c)
|
||||
public PlayerColorRemap(int[] Ramp, ColorRamp c)
|
||||
{
|
||||
var c1 = c.GetColor(0);
|
||||
var c2 = c.GetColor(1); /* temptemp: this can be expressed better */
|
||||
var c2 = c.GetColor(1); // temptemp: this can be expressed better
|
||||
|
||||
var baseIndex = GetRemapBase(fmt);
|
||||
var ramp = GetRemapRamp(fmt);
|
||||
var baseIndex = Ramp[0];
|
||||
var RemapRamp = Ramp.Select(r => r - Ramp[0]).ToArray();
|
||||
|
||||
remapColors = ramp.Select((x, i) => Pair.New(baseIndex + i, Exts.ColorLerp(x / 16f, c1, c2)))
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,9 +32,9 @@ namespace OpenRA
|
||||
|
||||
public IOccupySpace OccupiesSpace { get { return occupySpace.Value; } }
|
||||
|
||||
public int2 Location { get { return occupySpace.Value.TopLeft; } }
|
||||
public CPos Location { get { return occupySpace.Value.TopLeft; } }
|
||||
|
||||
public int2 CenterLocation
|
||||
public PPos CenterLocation
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -123,22 +123,30 @@ namespace OpenRA
|
||||
// at its current altitude
|
||||
Rectangle CalculateBounds(bool useAltitude)
|
||||
{
|
||||
var size = Size.Value;
|
||||
var size = (PVecInt)(Size.Value);
|
||||
var loc = CenterLocation - size / 2;
|
||||
|
||||
var si = Info.Traits.GetOrDefault<SelectableInfo>();
|
||||
if (si != null && si.Bounds != null && si.Bounds.Length > 2)
|
||||
{
|
||||
#if true
|
||||
loc += new PVecInt(si.Bounds[2], si.Bounds[3]);
|
||||
#else
|
||||
loc.X += si.Bounds[2];
|
||||
loc.Y += si.Bounds[3];
|
||||
#endif
|
||||
}
|
||||
|
||||
var move = Move.Value;
|
||||
if (move != null)
|
||||
{
|
||||
#if true
|
||||
loc -= new PVecInt(0, move.Altitude);
|
||||
#else
|
||||
loc.Y -= move.Altitude;
|
||||
#endif
|
||||
if (useAltitude)
|
||||
size = new int2(size.X, size.Y + move.Altitude);
|
||||
size = new PVecInt(size.X, size.Y + move.Altitude);
|
||||
}
|
||||
|
||||
return new Rectangle(loc.X, loc.Y, size.X, size.Y);
|
||||
|
||||
@@ -62,12 +62,12 @@ namespace OpenRA
|
||||
public int Value( World world ) { return value; }
|
||||
}
|
||||
|
||||
public class LocationInit : IActorInit<int2>
|
||||
public class LocationInit : IActorInit<CPos>
|
||||
{
|
||||
[FieldFromYamlKey] public readonly int2 value = int2.Zero;
|
||||
public LocationInit() { }
|
||||
public LocationInit( int2 init ) { value = init; }
|
||||
public int2 Value( World world ) { return value; }
|
||||
public LocationInit( CPos init ) { value = init.ToInt2(); }
|
||||
public CPos Value(World world) { return (CPos)value; }
|
||||
}
|
||||
|
||||
public class SubCellInit : IActorInit<SubCell>
|
||||
@@ -78,12 +78,12 @@ namespace OpenRA
|
||||
public SubCell Value(World world) { return (SubCell)value; }
|
||||
}
|
||||
|
||||
public class CenterLocationInit : IActorInit<int2>
|
||||
public class CenterLocationInit : IActorInit<PPos>
|
||||
{
|
||||
[FieldFromYamlKey] public readonly int2 value = int2.Zero;
|
||||
public CenterLocationInit() { }
|
||||
public CenterLocationInit( int2 init ) { value = init; }
|
||||
public int2 Value( World world ) { return value; }
|
||||
public CenterLocationInit(PPos init) { value = init.ToInt2(); }
|
||||
public PPos Value(World world) { return (PPos)value; }
|
||||
}
|
||||
|
||||
public class OwnerInit : IActorInit<Player>
|
||||
|
||||
@@ -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
71
OpenRA.Game/CPos.cs
Normal 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
76
OpenRA.Game/CVec.cs
Normal 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); }
|
||||
}
|
||||
}
|
||||
@@ -166,7 +166,7 @@ namespace OpenRA
|
||||
{
|
||||
var isNetTick = LocalTick % NetTickScale == 0;
|
||||
|
||||
if (!isNetTick || orderManager.IsReadyForNextFrame)
|
||||
if ((!isNetTick || orderManager.IsReadyForNextFrame) && !orderManager.GamePaused )
|
||||
{
|
||||
++orderManager.LocalFrameNumber;
|
||||
|
||||
@@ -188,6 +188,8 @@ namespace OpenRA
|
||||
else
|
||||
if (orderManager.NetFrameNumber == 0)
|
||||
orderManager.LastTickTime = Environment.TickCount;
|
||||
|
||||
viewport.Tick();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,7 +246,6 @@ namespace OpenRA
|
||||
AppDomain.CurrentDomain.AssemblyResolve += FileSystem.ResolveAssembly;
|
||||
|
||||
Settings = new Settings(Platform.SupportDir + "settings.yaml", args);
|
||||
Settings.Save();
|
||||
|
||||
Log.LogPath = Platform.SupportDir + "Logs" + Path.DirectorySeparatorChar;
|
||||
Log.AddChannel("perf", "perf.log");
|
||||
@@ -278,11 +279,11 @@ namespace OpenRA
|
||||
if (orderManager != null)
|
||||
orderManager.Dispose();
|
||||
|
||||
// Discard any invalid mods
|
||||
// Discard any invalid mods, set RA as default
|
||||
var mm = mods.Where( m => Mod.AllMods.ContainsKey( m ) ).ToArray();
|
||||
if (mm.Length == 0) mm = new[] { "ra" };
|
||||
Console.WriteLine("Loading mods: {0}", mm.JoinWith(","));
|
||||
Settings.Game.Mods = mm;
|
||||
Settings.Save();
|
||||
|
||||
Sound.StopMusic();
|
||||
Sound.StopVideo();
|
||||
@@ -301,7 +302,39 @@ 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.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 +423,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);
|
||||
|
||||
@@ -70,6 +70,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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 string DedicatedMOTD = null;
|
||||
|
||||
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;
|
||||
DedicatedMOTD = other.DedicatedMOTD;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +92,8 @@ namespace OpenRA.GameRules
|
||||
public bool Repeat = false;
|
||||
public bool ShellmapMusic = true;
|
||||
public string Engine = "AL";
|
||||
|
||||
public SoundCashTicks SoundCashTickType = SoundCashTicks.Extreme;
|
||||
}
|
||||
|
||||
public class PlayerSettings
|
||||
@@ -86,8 +103,6 @@ namespace OpenRA.GameRules
|
||||
public string LastServer = "localhost:1234";
|
||||
}
|
||||
|
||||
public enum MouseScrollType { Disabled, Standard, Inverted }
|
||||
|
||||
public class GameSettings
|
||||
{
|
||||
public string[] Mods = { "ra" };
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -24,9 +24,9 @@ namespace OpenRA.GameRules
|
||||
public readonly bool Ore = false; // can this damage ore?
|
||||
public readonly string Explosion = null; // explosion effect to use
|
||||
public readonly string WaterExplosion = null; // explosion effect on hitting water (usually a splash)
|
||||
public readonly string SmudgeType = null; // type of smudge to apply
|
||||
public readonly string[] SmudgeType = { }; // type of smudge to apply
|
||||
public readonly int[] Size = { 0, 0 }; // size of the explosion. provide 2 values for a ring effect (outer/inner)
|
||||
public readonly int InfDeath = 0; // infantry death animation to use
|
||||
public readonly int InfDeath = 1; // 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
|
||||
@@ -72,11 +72,11 @@ namespace OpenRA.GameRules
|
||||
{
|
||||
public WeaponInfo weapon;
|
||||
public Actor firedBy;
|
||||
public int2 src;
|
||||
public PPos src;
|
||||
public int srcAltitude;
|
||||
public int facing;
|
||||
public Target target;
|
||||
public int2 dest;
|
||||
public PPos dest;
|
||||
public int destAltitude;
|
||||
public float firepowerModifier = 1.0f;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace OpenRA.Graphics
|
||||
public Renderable Image(Actor self, string pal)
|
||||
{
|
||||
var p = self.CenterLocation;
|
||||
var loc = p - 0.5f * Animation.Image.size
|
||||
var loc = p.ToFloat2() - 0.5f * Animation.Image.size
|
||||
+ (OffsetFunc != null ? OffsetFunc() : float2.Zero);
|
||||
var r = new Renderable(Animation.Image, loc, pal, p.Y);
|
||||
|
||||
|
||||
@@ -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,
|
||||
@@ -25,9 +25,16 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
foreach (var s in sequences.NodesDict["Palettes"].Nodes)
|
||||
Game.modData.Palette.AddPalette(s.Key, new Palette(FileSystem.Open(s.Value.Value), false));
|
||||
Game.modData.Palette.AddPalette(s.Key, new Palette(FileSystem.Open(s.Value.Value), ShadowIndex));
|
||||
|
||||
foreach (var s in sequences.NodesDict["Cursors"].Nodes)
|
||||
LoadSequencesForCursor(s.Key, s.Value);
|
||||
|
||||
@@ -135,7 +135,10 @@ namespace OpenRA.Graphics
|
||||
FixOSX();
|
||||
|
||||
var resolution = GetResolution( windowMode );
|
||||
var rendererPath = Path.GetFullPath( "OpenRA.Renderer.{0}.dll".F(Game.Settings.Graphics.Renderer) );
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -27,10 +27,9 @@ namespace OpenRA.Graphics
|
||||
public int Facings { get { return facings; } }
|
||||
public int Tick { get { return tick; } }
|
||||
|
||||
string srcOverride;
|
||||
public Sequence(string unit, string name, MiniYaml info)
|
||||
{
|
||||
srcOverride = info.Value;
|
||||
var srcOverride = info.Value;
|
||||
Name = name;
|
||||
var d = info.NodesDict;
|
||||
|
||||
@@ -62,26 +61,6 @@ namespace OpenRA.Graphics
|
||||
info.Nodes[0].Location));
|
||||
}
|
||||
|
||||
public MiniYaml Save()
|
||||
{
|
||||
var root = new List<MiniYamlNode>();
|
||||
|
||||
root.Add(new MiniYamlNode("Start", start.ToString()));
|
||||
|
||||
if (length > 1 && (start != 0 || length != sprites.Length - start))
|
||||
root.Add(new MiniYamlNode("Length", length.ToString()));
|
||||
else if (length > 1 && length == sprites.Length - start)
|
||||
root.Add(new MiniYamlNode("Length", "*"));
|
||||
|
||||
if (facings > 1)
|
||||
root.Add(new MiniYamlNode("Facings", facings.ToString()));
|
||||
|
||||
if (tick != 40)
|
||||
root.Add(new MiniYamlNode("Tick", tick.ToString()));
|
||||
|
||||
return new MiniYaml(srcOverride, root);
|
||||
}
|
||||
|
||||
public Sprite GetSprite( int frame )
|
||||
{
|
||||
return GetSprite( frame, 0 );
|
||||
|
||||
@@ -149,18 +149,18 @@ namespace OpenRA.Graphics
|
||||
}
|
||||
|
||||
// Convert from viewport coords to cell coords (not px)
|
||||
public float2 ViewToWorld(MouseInput mi) { return ViewToWorld(mi.Location); }
|
||||
public float2 ViewToWorld(int2 loc)
|
||||
public CPos ViewToWorld(MouseInput mi) { return ViewToWorld(mi.Location); }
|
||||
public CPos ViewToWorld(int2 loc)
|
||||
{
|
||||
return (1f / Game.CellSize) * (1f/Zoom*loc.ToFloat2() + Location);
|
||||
return (CPos)( (1f / Game.CellSize) * (1f/Zoom*loc.ToFloat2() + Location) ).ToInt2();
|
||||
}
|
||||
|
||||
public int2 ViewToWorldPx(int2 loc) { return (1f/Zoom*loc.ToFloat2() + Location).ToInt2(); }
|
||||
public int2 ViewToWorldPx(MouseInput mi) { return ViewToWorldPx(mi.Location); }
|
||||
public PPos ViewToWorldPx(int2 loc) { return (PPos)(1f/Zoom*loc.ToFloat2() + Location).ToInt2(); }
|
||||
public PPos ViewToWorldPx(MouseInput mi) { return ViewToWorldPx(mi.Location); }
|
||||
|
||||
public void Center(float2 loc)
|
||||
{
|
||||
scrollPosition = NormalizeScrollPosition((Game.CellSize*loc - 1f/(2*Zoom)*screenSize.ToFloat2()).ToInt2());
|
||||
scrollPosition = NormalizeScrollPosition((Game.CellSize * loc - 1f/(2*Zoom)*screenSize.ToFloat2()).ToInt2());
|
||||
}
|
||||
|
||||
public void Center(IEnumerable<Actor> actors)
|
||||
@@ -168,9 +168,9 @@ namespace OpenRA.Graphics
|
||||
if (!actors.Any()) return;
|
||||
|
||||
var avgPos = actors
|
||||
.Select(a => a.CenterLocation)
|
||||
.Select(a => (PVecInt)a.CenterLocation)
|
||||
.Aggregate((a, b) => a + b) / actors.Count();
|
||||
scrollPosition = NormalizeScrollPosition((avgPos - 1f/(2*Zoom)*screenSize.ToFloat2()).ToInt2());
|
||||
scrollPosition = NormalizeScrollPosition(((PVecFloat)avgPos - (PVecFloat)(1f / (2 * Zoom) * screenSize.ToFloat2())).ToInt2());
|
||||
}
|
||||
|
||||
// Rectangle (in viewport coords) that contains things to be drawn
|
||||
|
||||
@@ -53,8 +53,9 @@ namespace OpenRA.Graphics
|
||||
var comparer = new SpriteComparer();
|
||||
|
||||
var actors = world.FindUnits(
|
||||
new int2(Game.CellSize*bounds.Left, Game.CellSize*bounds.Top),
|
||||
new int2(Game.CellSize*bounds.Right, Game.CellSize*bounds.Bottom));
|
||||
bounds.TopLeftAsCPos().ToPPos(),
|
||||
bounds.BottomRightAsCPos().ToPPos()
|
||||
);
|
||||
|
||||
var renderables = actors.SelectMany(a => a.Render())
|
||||
.OrderBy(r => r, comparer);
|
||||
@@ -140,25 +141,21 @@ namespace OpenRA.Graphics
|
||||
selectable.DrawRollover(this, unit);
|
||||
}
|
||||
|
||||
public void DrawLocus(Color c, int2[] cells)
|
||||
public void DrawLocus(Color c, CPos[] cells)
|
||||
{
|
||||
var dict = cells.ToDictionary(a => a, a => 0);
|
||||
var wlr = Game.Renderer.WorldLineRenderer;
|
||||
|
||||
foreach (var t in dict.Keys)
|
||||
{
|
||||
if (!dict.ContainsKey(t + new int2(-1, 0)))
|
||||
wlr.DrawLine(Game.CellSize * t, Game.CellSize * (t + new int2(0, 1)),
|
||||
c, c);
|
||||
if (!dict.ContainsKey(t + new int2(1, 0)))
|
||||
wlr.DrawLine(Game.CellSize * (t + new int2(1, 0)), Game.CellSize * (t + new int2(1, 1)),
|
||||
c, c);
|
||||
if (!dict.ContainsKey(t + new int2(0, -1)))
|
||||
wlr.DrawLine(Game.CellSize * t, Game.CellSize * (t + new int2(1, 0)),
|
||||
c, c);
|
||||
if (!dict.ContainsKey(t + new int2(0, 1)))
|
||||
wlr.DrawLine(Game.CellSize * (t + new int2(0, 1)), Game.CellSize * (t + new int2(1, 1)),
|
||||
c, c);
|
||||
if (!dict.ContainsKey(t + new CVec(-1, 0)))
|
||||
wlr.DrawLine(t.ToPPos().ToFloat2(), (t + new CVec(0, 1)).ToPPos().ToFloat2(), c, c);
|
||||
if (!dict.ContainsKey(t + new CVec(1, 0)))
|
||||
wlr.DrawLine((t + new CVec(1, 0)).ToPPos().ToFloat2(), (t + new CVec(1, 1)).ToPPos().ToFloat2(), c, c);
|
||||
if (!dict.ContainsKey(t + new CVec(0, -1)))
|
||||
wlr.DrawLine(t.ToPPos().ToFloat2(), (t + new CVec(1, 0)).ToPPos().ToFloat2(), c, c);
|
||||
if (!dict.ContainsKey(t + new CVec(0, 1)))
|
||||
wlr.DrawLine((t + new CVec(0, 1)).ToPPos().ToFloat2(), (t + new CVec(1, 1)).ToPPos().ToFloat2(), c, c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ namespace OpenRA
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> Sequences = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> Weapons = new List<MiniYamlNode>();
|
||||
[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;
|
||||
@@ -150,6 +151,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];
|
||||
|
||||
@@ -204,6 +206,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());
|
||||
@@ -338,7 +341,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)
|
||||
|
||||
@@ -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 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -64,17 +64,21 @@ 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 AllowCheats = false;
|
||||
public bool Dedicated;
|
||||
public string DedicatedMOTD;
|
||||
}
|
||||
|
||||
public Session(string[] mods)
|
||||
|
||||
@@ -94,6 +94,19 @@ namespace OpenRA.Network
|
||||
Game.StartGame(orderManager.LobbyInfo.GlobalSettings.Map, false);
|
||||
break;
|
||||
}
|
||||
|
||||
case "PauseGame":
|
||||
{
|
||||
var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
|
||||
|
||||
if(client != null)
|
||||
{
|
||||
orderManager.GamePaused = !orderManager.GamePaused;
|
||||
var pausetext = "The game is {0} by {1}".F( orderManager.GamePaused ? "paused" : "un-paused", client.Name );
|
||||
Game.AddChatLine(Color.White, "", pausetext);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "HandshakeRequest":
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
@@ -12,9 +12,12 @@
|
||||
<AssemblyName>OpenRA.Game</AssemblyName>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>2.0</OldToolsVersion>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<ApplicationIcon>OpenRA.ico</ApplicationIcon>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
@@ -27,11 +30,8 @@
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<ApplicationIcon>OpenRA.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -44,6 +44,7 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Optimize>false</Optimize>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
@@ -55,6 +56,7 @@
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
@@ -78,6 +80,11 @@
|
||||
<Compile Include="ActorInitializer.cs" />
|
||||
<Compile Include="ActorMap.cs" />
|
||||
<Compile Include="ActorReference.cs" />
|
||||
<Compile Include="PSubVec.cs" />
|
||||
<Compile Include="PSubPos.cs" />
|
||||
<Compile Include="PVecInt.cs" />
|
||||
<Compile Include="PVecFloat.cs" />
|
||||
<Compile Include="PPos.cs" />
|
||||
<Compile Include="Download.cs" />
|
||||
<Compile Include="Effects\DelayedAction.cs" />
|
||||
<Compile Include="Effects\FlashTarget.cs" />
|
||||
@@ -87,7 +94,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" />
|
||||
@@ -114,6 +121,8 @@
|
||||
<Compile Include="Graphics\WorldRenderer.cs" />
|
||||
<Compile Include="Group.cs" />
|
||||
<Compile Include="InputHandler.cs" />
|
||||
<Compile Include="CVec.cs" />
|
||||
<Compile Include="CPos.cs" />
|
||||
<Compile Include="Map.cs" />
|
||||
<Compile Include="ModData.cs" />
|
||||
<Compile Include="Network\Connection.cs" />
|
||||
@@ -142,6 +151,7 @@
|
||||
<Compile Include="Server\Server.cs" />
|
||||
<Compile Include="Server\ServerOrder.cs" />
|
||||
<Compile Include="Server\TraitInterfaces.cs" />
|
||||
<Compile Include="Server\UPnP.cs" />
|
||||
<Compile Include="Sound.cs" />
|
||||
<Compile Include="Support\Arguments.cs" />
|
||||
<Compile Include="Support\PerfHistory.cs" />
|
||||
@@ -157,7 +167,6 @@
|
||||
<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" />
|
||||
@@ -214,6 +223,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 +243,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" />
|
||||
@@ -241,4 +260,4 @@
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -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"; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace OpenRA.Orders
|
||||
{
|
||||
class UnitOrderGenerator : IOrderGenerator
|
||||
{
|
||||
public IEnumerable<Order> Order( World world, int2 xy, MouseInput mi )
|
||||
public IEnumerable<Order> Order( World world, CPos xy, MouseInput mi )
|
||||
{
|
||||
var underCursor = world.FindUnitsAtMouse(mi.Location)
|
||||
.Where(a => a.HasTrait<ITargetable>())
|
||||
@@ -45,7 +45,7 @@ namespace OpenRA.Orders
|
||||
public void RenderBeforeWorld( WorldRenderer wr, World world ) { }
|
||||
public void RenderAfterWorld( WorldRenderer wr, World world ) { }
|
||||
|
||||
public string GetCursor( World world, int2 xy, MouseInput mi )
|
||||
public string GetCursor(World world, CPos xy, MouseInput mi)
|
||||
{
|
||||
bool useSelect = false;
|
||||
|
||||
@@ -63,12 +63,11 @@ namespace OpenRA.Orders
|
||||
.Where(o => o != null)
|
||||
.ToArray();
|
||||
|
||||
if( orders.Length == 0 ) return (useSelect) ? "select" : "default";
|
||||
|
||||
return orders[0].cursor ?? ((useSelect) ? "select" : "default");
|
||||
var cursorName = orders.Select(o => o.cursor).FirstOrDefault();
|
||||
return cursorName ?? (useSelect ? "select" : "default");
|
||||
}
|
||||
|
||||
static UnitOrderResult OrderForUnit( Actor self, int2 xy, MouseInput mi, Actor underCursor )
|
||||
static UnitOrderResult OrderForUnit(Actor self, CPos xy, MouseInput mi, Actor underCursor)
|
||||
{
|
||||
if (self.Owner != self.World.LocalPlayer)
|
||||
return null;
|
||||
|
||||
71
OpenRA.Game/PPos.cs
Normal file
71
OpenRA.Game/PPos.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
/// <summary>
|
||||
/// Pixel coordinate position in the world (fine).
|
||||
/// </summary>
|
||||
public struct PPos
|
||||
{
|
||||
public readonly int X, Y;
|
||||
|
||||
public PPos(int x, int y) { X = x; Y = y; }
|
||||
|
||||
public static readonly PPos Zero = new PPos(0, 0);
|
||||
|
||||
public static explicit operator PPos(int2 a) { return new PPos(a.X, a.Y); }
|
||||
|
||||
public static explicit operator PVecInt(PPos a) { return new PVecInt(a.X, a.Y); }
|
||||
public static explicit operator PVecFloat(PPos a) { return new PVecFloat(a.X, a.Y); }
|
||||
|
||||
public static PPos operator +(PPos a, PVecInt b) { return new PPos(a.X + b.X, a.Y + b.Y); }
|
||||
public static PVecInt operator -(PPos a, PPos b) { return new PVecInt(a.X - b.X, a.Y - b.Y); }
|
||||
public static PPos operator -(PPos a, PVecInt b) { return new PPos(a.X - b.X, a.Y - b.Y); }
|
||||
|
||||
public static bool operator ==(PPos me, PPos other) { return (me.X == other.X && me.Y == other.Y); }
|
||||
public static bool operator !=(PPos me, PPos other) { return !(me == other); }
|
||||
|
||||
public static PPos Max(PPos a, PPos b) { return new PPos(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
|
||||
public static PPos Min(PPos a, PPos b) { return new PPos(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
|
||||
|
||||
public static PPos Lerp(PPos a, PPos b, int mul, int div)
|
||||
{
|
||||
return a + ((PVecInt)(b - a) * mul / div);
|
||||
}
|
||||
|
||||
public float2 ToFloat2() { return new float2(X, Y); }
|
||||
public int2 ToInt2() { return new int2(X, Y); }
|
||||
public CPos ToCPos() { return new CPos((int)(1f / Game.CellSize * X), (int)(1f / Game.CellSize * Y)); }
|
||||
public PSubPos ToPSubPos() { return new PSubPos(X * PSubPos.PerPx, Y * PSubPos.PerPx); }
|
||||
|
||||
public PPos Clamp(Rectangle r)
|
||||
{
|
||||
return new PPos(Math.Min(r.Right, Math.Max(X, r.Left)),
|
||||
Math.Min(r.Bottom, Math.Max(Y, r.Top)));
|
||||
}
|
||||
|
||||
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return false;
|
||||
|
||||
PPos o = (PPos)obj;
|
||||
return o == this;
|
||||
}
|
||||
|
||||
public override string ToString() { return "{0},{1}".F(X, Y); }
|
||||
}
|
||||
}
|
||||
73
OpenRA.Game/PSubPos.cs
Normal file
73
OpenRA.Game/PSubPos.cs
Normal 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
103
OpenRA.Game/PSubVec.cs
Normal 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
97
OpenRA.Game/PVecFloat.cs
Normal 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
80
OpenRA.Game/PVecInt.cs
Normal 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); }
|
||||
}
|
||||
}
|
||||
@@ -90,11 +90,6 @@ namespace OpenRA
|
||||
}
|
||||
}
|
||||
|
||||
public void GiveAdvice(string advice)
|
||||
{
|
||||
Sound.PlayToPlayer(this, advice);
|
||||
}
|
||||
|
||||
public Dictionary<Player, Stance> Stances = new Dictionary<Player, Stance>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2012 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -15,11 +15,15 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Net.NetworkInformation;
|
||||
using UPnP;
|
||||
using System.Threading;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Network;
|
||||
|
||||
using XTimer = System.Timers.Timer;
|
||||
|
||||
namespace OpenRA.Server
|
||||
{
|
||||
public class Server
|
||||
@@ -45,9 +49,13 @@ namespace OpenRA.Server
|
||||
public ServerSettings Settings;
|
||||
public ModData ModData;
|
||||
public Map Map;
|
||||
XTimer gameTimeout;
|
||||
|
||||
volatile bool shutdown = false;
|
||||
public void Shutdown() { shutdown = true; }
|
||||
public void Shutdown()
|
||||
{
|
||||
shutdown = true;
|
||||
}
|
||||
|
||||
public Server(IPEndPoint endpoint, string[] mods, ServerSettings settings, ModData modData)
|
||||
{
|
||||
@@ -64,6 +72,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) );
|
||||
|
||||
@@ -71,6 +117,9 @@ 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;
|
||||
lobbyInfo.GlobalSettings.DedicatedMOTD = settings.DedicatedMOTD;
|
||||
|
||||
foreach (var t in ServerTraits.WithInterface<INotifyServerStart>())
|
||||
t.ServerStarted(this);
|
||||
@@ -93,7 +142,11 @@ namespace OpenRA.Server
|
||||
|
||||
Socket.Select( checkRead, null, null, timeout );
|
||||
if (shutdown)
|
||||
{
|
||||
if (Settings.AllowUPnP)
|
||||
RemovePortforward();
|
||||
break;
|
||||
}
|
||||
|
||||
foreach( Socket s in checkRead )
|
||||
if( s == listener.Server ) AcceptConnection();
|
||||
@@ -108,7 +161,11 @@ namespace OpenRA.Server
|
||||
t.Tick(this);
|
||||
|
||||
if (shutdown)
|
||||
{
|
||||
if (Settings.AllowUPnP)
|
||||
RemovePortforward();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GameStarted = false;
|
||||
@@ -120,6 +177,20 @@ namespace OpenRA.Server
|
||||
try { listener.Stop(); }
|
||||
catch { }
|
||||
} ) { IsBackground = true }.Start();
|
||||
|
||||
}
|
||||
|
||||
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:
|
||||
@@ -194,7 +265,7 @@ namespace OpenRA.Server
|
||||
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.",
|
||||
@@ -204,6 +275,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);
|
||||
@@ -221,6 +318,8 @@ namespace OpenRA.Server
|
||||
if(lobbyInfo.Clients.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 +328,16 @@ namespace OpenRA.Server
|
||||
|
||||
SyncLobbyInfo();
|
||||
SendChat(newConn, "has joined the game.");
|
||||
|
||||
if ( lobbyInfo.GlobalSettings.Dedicated )
|
||||
{
|
||||
if (lobbyInfo.GlobalSettings.DedicatedMOTD != null)
|
||||
SendChatTo(newConn, lobbyInfo.GlobalSettings.DedicatedMOTD);
|
||||
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, "+
|
||||
@@ -332,6 +441,9 @@ namespace OpenRA.Server
|
||||
|
||||
void InterpretServerOrder(Connection conn, ServerOrder so)
|
||||
{
|
||||
var fromClient = GetClient(conn);
|
||||
var fromIndex = fromClient != null ? fromClient.Index : 0;
|
||||
|
||||
switch (so.Name)
|
||||
{
|
||||
case "Command":
|
||||
@@ -347,17 +459,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,15 +492,29 @@ namespace OpenRA.Server
|
||||
{
|
||||
conns.Remove(toDrop);
|
||||
SendChat(toDrop, "Connection Dropped");
|
||||
|
||||
|
||||
OpenRA.Network.Session.Client dropClient = lobbyInfo.Clients.Where(c1 => c1.Index == toDrop.PlayerIndex).Single();
|
||||
|
||||
if (GameStarted)
|
||||
SendDisconnected(toDrop); /* Report disconnection */
|
||||
|
||||
lobbyInfo.Clients.RemoveAll(c => c.Index == toDrop.PlayerIndex);
|
||||
|
||||
// reassign admin if necessary
|
||||
if ( lobbyInfo.GlobalSettings.Dedicated && dropClient.IsAdmin && !GameStarted)
|
||||
{
|
||||
if (lobbyInfo.Clients.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.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();
|
||||
}
|
||||
|
||||
@@ -406,6 +538,10 @@ namespace OpenRA.Server
|
||||
public void StartGame()
|
||||
{
|
||||
GameStarted = true;
|
||||
listener.Stop();
|
||||
|
||||
Console.WriteLine("Game started");
|
||||
|
||||
foreach( var c in conns )
|
||||
foreach( var d in conns )
|
||||
DispatchOrdersToClient( c, d.PlayerIndex, 0x7FFFFFFF, new byte[] { 0xBF } );
|
||||
@@ -419,6 +555,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
163
OpenRA.Game/Server/UPnP.cs
Normal file
163
OpenRA.Game/Server/UPnP.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
@@ -39,6 +45,7 @@ namespace OpenRA
|
||||
|
||||
static ISoundEngine CreateEngine(string engine)
|
||||
{
|
||||
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();
|
||||
@@ -64,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()
|
||||
@@ -140,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()
|
||||
@@ -238,7 +247,48 @@ 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)
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
if (p == null)
|
||||
Play(prefix + clip + suffix);
|
||||
else
|
||||
PlayToPlayer(p, prefix + clip + suffix);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool PlayVoice(string phrase, Actor voicedUnit, string variant)
|
||||
{
|
||||
if (voicedUnit == null) return false;
|
||||
@@ -248,26 +298,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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -288,8 +336,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()
|
||||
@@ -313,7 +370,7 @@ namespace OpenRA
|
||||
return;
|
||||
}
|
||||
|
||||
sourcePool.Add(source, false);
|
||||
sourcePool.Add(source, new PoolSlot() { isActive = false });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,9 +378,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;
|
||||
}
|
||||
}
|
||||
@@ -341,9 +398,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];
|
||||
}
|
||||
@@ -353,10 +410,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
|
||||
@@ -367,6 +476,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);
|
||||
@@ -408,6 +519,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);
|
||||
@@ -465,15 +578,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);
|
||||
}
|
||||
|
||||
@@ -515,7 +627,7 @@ namespace OpenRA
|
||||
return new NullSoundSource();
|
||||
}
|
||||
|
||||
public ISound Play2D(ISoundSource sound, bool loop, bool relative, float2 pos, float volume)
|
||||
public ISound Play2D(ISoundSource sound, bool loop, bool relative, float2 pos, float volume, bool attenuateVolume)
|
||||
{
|
||||
return new NullSound();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
using System.Drawing;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Effects;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
@@ -25,7 +26,7 @@ namespace OpenRA.Traits
|
||||
{
|
||||
Actor self;
|
||||
DrawLineToTargetInfo Info;
|
||||
Target target;
|
||||
List<Target> targets;
|
||||
Color c;
|
||||
int lifetime;
|
||||
|
||||
@@ -33,7 +34,16 @@ namespace OpenRA.Traits
|
||||
|
||||
public void SetTarget(Actor self, Target target, Color c, bool display)
|
||||
{
|
||||
this.target = target;
|
||||
this.targets = new List<Target> { target };
|
||||
this.c = c;
|
||||
|
||||
if (display)
|
||||
lifetime = Info.Ticks;
|
||||
}
|
||||
|
||||
public void SetTargets(Actor self, List<Target> targets, Color c, bool display)
|
||||
{
|
||||
this.targets = targets;
|
||||
this.c = c;
|
||||
|
||||
if (display)
|
||||
@@ -42,23 +52,29 @@ namespace OpenRA.Traits
|
||||
|
||||
public void RenderAfterWorld(WorldRenderer wr)
|
||||
{
|
||||
if (self.IsIdle) return;
|
||||
//if (self.IsIdle) return;
|
||||
|
||||
var force = Game.GetModifierKeys().HasModifier(Modifiers.Alt);
|
||||
if ((lifetime <= 0 || --lifetime <= 0) && !force)
|
||||
return;
|
||||
|
||||
if (!target.IsValid)
|
||||
if (targets == null || targets.Count == 0)
|
||||
return;
|
||||
|
||||
var move = self.TraitOrDefault<IMove>();
|
||||
var origin = move != null ? self.CenterLocation - new int2(0, move.Altitude) : self.CenterLocation;
|
||||
var origin = (move != null ? self.CenterLocation - new PVecInt(0, move.Altitude) : self.CenterLocation).ToFloat2();
|
||||
|
||||
var wlr = Game.Renderer.WorldLineRenderer;
|
||||
|
||||
wlr.DrawLine(origin, target.CenterLocation, c, c);
|
||||
DrawTargetMarker(wlr, target.CenterLocation);
|
||||
DrawTargetMarker(wlr, origin);
|
||||
foreach (var target in targets)
|
||||
{
|
||||
if (!target.IsValid)
|
||||
continue;
|
||||
|
||||
wlr.DrawLine(origin, target.CenterLocation.ToFloat2(), c, c);
|
||||
DrawTargetMarker(wlr, target.CenterLocation.ToFloat2());
|
||||
DrawTargetMarker(wlr, origin);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawTargetMarker(LineRenderer wlr, float2 p)
|
||||
@@ -72,6 +88,18 @@ namespace OpenRA.Traits
|
||||
|
||||
public static class LineTargetExts
|
||||
{
|
||||
public static void SetTargetLines(this Actor self, List<Target> targets, Color color)
|
||||
{
|
||||
var line = self.TraitOrDefault<DrawLineToTarget>();
|
||||
if (line != null)
|
||||
{
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
line.SetTargets(self, targets, color, false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetTargetLine(this Actor self, Target target, Color color)
|
||||
{
|
||||
self.SetTargetLine(target, color, true);
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace OpenRA.Traits
|
||||
}
|
||||
|
||||
public int HP { get { return hp; } }
|
||||
public readonly int MaxHP;
|
||||
public int MaxHP;
|
||||
|
||||
public bool IsDead { get { return hp <= 0; } }
|
||||
public bool RemoveOnDeath = true;
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
#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
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
public class EvaAlertsInfo : TraitInfo<EvaAlerts>
|
||||
{
|
||||
// Sound effects
|
||||
public readonly string RadarUp = "radaron2.aud";
|
||||
public readonly string RadarDown = "radardn1.aud";
|
||||
|
||||
public readonly string CashTickUp = "cashup1.aud";
|
||||
public readonly string CashTickDown = "cashdn1.aud";
|
||||
|
||||
// Build Palette
|
||||
public readonly string BuildingCannotPlaceAudio = "nodeply1.aud";
|
||||
public readonly string NewOptions = "newopt1.aud";
|
||||
|
||||
// For manual powerup/down in ra-ng
|
||||
public readonly string DisablePower = "bleep11.aud";
|
||||
public readonly string EnablePower = "bleep12.aud";
|
||||
|
||||
// Eva speech
|
||||
public readonly string Repairing = "repair1.aud";
|
||||
public readonly string LowPower = "lopower1.aud";
|
||||
public readonly string SilosNeeded = "silond1.aud";
|
||||
public readonly string PrimaryBuildingSelected = "pribldg1.aud";
|
||||
|
||||
// Special powers
|
||||
public readonly string AbilityInsufficientPower = "nopowr1.aud";
|
||||
|
||||
public readonly string LevelUp = "hydrod1.aud";
|
||||
}
|
||||
|
||||
public class EvaAlerts {}
|
||||
}
|
||||
@@ -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,
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.GameRules;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
@@ -62,6 +63,8 @@ namespace OpenRA.Traits
|
||||
{
|
||||
readonly Player Owner;
|
||||
int AdviceInterval;
|
||||
|
||||
int cashtickallowed = 0;
|
||||
|
||||
public PlayerResources(Actor self, PlayerResourcesInfo info)
|
||||
{
|
||||
@@ -133,8 +136,10 @@ namespace OpenRA.Traits
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
var eva = self.World.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
|
||||
|
||||
if(cashtickallowed > 0) {
|
||||
cashtickallowed = cashtickallowed - 1;
|
||||
}
|
||||
|
||||
OreCapacity = self.World.ActorsWithTrait<IStoreOre>()
|
||||
.Where(a => a.Actor.Owner == Owner)
|
||||
.Sum(a => a.Trait.Capacity);
|
||||
@@ -145,7 +150,7 @@ namespace OpenRA.Traits
|
||||
if (--nextSiloAdviceTime <= 0)
|
||||
{
|
||||
if (Ore > 0.8*OreCapacity)
|
||||
Owner.GiveAdvice(eva.SilosNeeded);
|
||||
Sound.PlayNotification(Owner, "Speech", "SilosNeeded", Owner.Country.Race);
|
||||
|
||||
nextSiloAdviceTime = AdviceInterval;
|
||||
}
|
||||
@@ -158,12 +163,12 @@ namespace OpenRA.Traits
|
||||
if (DisplayCash < Cash)
|
||||
{
|
||||
DisplayCash += move;
|
||||
Sound.PlayToPlayer(self.Owner, eva.CashTickUp);
|
||||
playCashTickUp(self);
|
||||
}
|
||||
else if (DisplayCash > Cash)
|
||||
{
|
||||
DisplayCash -= move;
|
||||
Sound.PlayToPlayer(self.Owner, eva.CashTickDown);
|
||||
playCashTickDown(self);
|
||||
}
|
||||
|
||||
diff = Math.Abs(Ore - DisplayOre);
|
||||
@@ -173,13 +178,34 @@ namespace OpenRA.Traits
|
||||
if (DisplayOre < Ore)
|
||||
{
|
||||
DisplayOre += move;
|
||||
Sound.PlayToPlayer(self.Owner, eva.CashTickUp);
|
||||
playCashTickUp(self);
|
||||
}
|
||||
else if (DisplayOre > Ore)
|
||||
{
|
||||
DisplayOre -= move;
|
||||
Sound.PlayToPlayer(self.Owner, eva.CashTickDown);
|
||||
playCashTickDown(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void playCashTickUp(Actor self)
|
||||
{
|
||||
if (Game.Settings.Sound.SoundCashTickType != SoundCashTicks.Disabled)
|
||||
{
|
||||
Sound.PlayNotification(self.Owner, "Sounds", "CashTickUp", self.Owner.Country.Race);
|
||||
}
|
||||
}
|
||||
|
||||
public void playCashTickDown(Actor self)
|
||||
{
|
||||
if (
|
||||
Game.Settings.Sound.SoundCashTickType == SoundCashTicks.Extreme ||
|
||||
(Game.Settings.Sound.SoundCashTickType == SoundCashTicks.Normal && cashtickallowed == 0)
|
||||
) {
|
||||
Sound.PlayNotification(self.Owner, "Sounds", "CashTickDown", self.Owner.Country.Race);
|
||||
cashtickallowed = 3;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace OpenRA.Traits
|
||||
class RevealsShroud : ITick
|
||||
{
|
||||
RevealsShroudInfo Info;
|
||||
int2 previousLocation;
|
||||
CPos previousLocation;
|
||||
|
||||
public RevealsShroud(RevealsShroudInfo info)
|
||||
{
|
||||
|
||||
@@ -146,12 +146,12 @@ namespace OpenRA.Traits
|
||||
{
|
||||
var alt = new float2(0, -mobile.Altitude);
|
||||
var targets = activity.GetTargets(self);
|
||||
var start = self.CenterLocation + alt;
|
||||
var start = self.CenterLocation.ToFloat2() + alt;
|
||||
|
||||
var c = Color.Green;
|
||||
|
||||
var wlr = Game.Renderer.WorldLineRenderer;
|
||||
foreach (var step in targets.Select(p => p.CenterLocation))
|
||||
foreach (var step in targets.Select(p => p.CenterLocation.ToFloat2()))
|
||||
{
|
||||
var stp = step + alt;
|
||||
wlr.DrawLine(stp + new float2(-1, -1), stp + new float2(-1, 1), c, c);
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace OpenRA.Traits
|
||||
|
||||
Actor actor;
|
||||
Player owner;
|
||||
int2 pos;
|
||||
PPos pos;
|
||||
bool valid;
|
||||
|
||||
public static Target FromActor(Actor a)
|
||||
@@ -28,8 +28,8 @@ namespace OpenRA.Traits
|
||||
owner = (a != null) ? a.Owner : null
|
||||
};
|
||||
}
|
||||
public static Target FromPos(int2 p) { return new Target { pos = p, valid = true }; }
|
||||
public static Target FromCell(int2 c) { return new Target { pos = Util.CenterOfCell(c), valid = true }; }
|
||||
public static Target FromPos(PPos p) { return new Target { pos = p, valid = true }; }
|
||||
public static Target FromCell(CPos c) { return new Target { pos = Util.CenterOfCell(c), valid = true }; }
|
||||
public static Target FromOrder(Order o)
|
||||
{
|
||||
return o.TargetActor != null
|
||||
@@ -39,9 +39,9 @@ namespace OpenRA.Traits
|
||||
|
||||
public static readonly Target None = new Target();
|
||||
|
||||
public bool IsValid { get { return valid && (actor == null || (actor.IsInWorld && actor.Owner == owner)); } }
|
||||
public int2 PxPosition { get { return IsActor ? actor.Trait<IHasLocation>().PxPosition : pos; } }
|
||||
public int2 CenterLocation { get { return PxPosition; } }
|
||||
public bool IsValid { get { return valid && (actor == null || (actor.IsInWorld && !actor.IsDead() && actor.Owner == owner)); } }
|
||||
public PPos PxPosition { get { return IsActor ? actor.Trait<IHasLocation>().PxPosition : pos; } }
|
||||
public PPos CenterLocation { get { return PxPosition; } }
|
||||
|
||||
public Actor Actor { get { return IsActor ? actor : null; } }
|
||||
public bool IsActor { get { return actor != null && !actor.Destroyed; } }
|
||||
|
||||
@@ -47,20 +47,21 @@ namespace OpenRA.Traits
|
||||
string OrderID { get; }
|
||||
int OrderPriority { get; }
|
||||
bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueue, ref string cursor);
|
||||
bool CanTargetLocation(Actor self, int2 location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueue, ref string cursor);
|
||||
bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueue, ref string cursor);
|
||||
bool IsQueued { get; }
|
||||
}
|
||||
|
||||
public interface IResolveOrder { void ResolveOrder(Actor self, Order order); }
|
||||
public interface IValidateOrder { bool OrderValidation(OrderManager orderManager, World world, int clientId, Order order); }
|
||||
public interface IOrderVoice { string VoicePhraseForOrder(Actor self, Order order); }
|
||||
public interface INotify { void Play(Player p, string notification); }
|
||||
public interface INotifySold { void Selling(Actor self); void Sold(Actor self); }
|
||||
public interface INotifyDamage { void Damaged(Actor self, AttackInfo e); }
|
||||
public interface INotifyDamageStateChanged { void DamageStateChanged(Actor self, AttackInfo e); }
|
||||
public interface INotifyKilled { void Killed(Actor self, AttackInfo e); }
|
||||
public interface INotifyAppliedDamage { void AppliedDamage(Actor self, Actor damaged, AttackInfo e); }
|
||||
public interface INotifyBuildComplete { void BuildingComplete(Actor self); }
|
||||
public interface INotifyProduction { void UnitProduced(Actor self, Actor other, int2 exit); }
|
||||
public interface INotifyProduction { void UnitProduced(Actor self, Actor other, CPos exit); }
|
||||
public interface INotifyCapture { void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner); }
|
||||
public interface INotifyOtherCaptured { void OnActorCaptured(Actor self, Actor captured, Actor captor, Player oldOwner, Player newOwner); }
|
||||
public interface IAcceptSpy { void OnInfiltrate(Actor self, Actor spy); }
|
||||
@@ -75,27 +76,26 @@ namespace OpenRA.Traits
|
||||
public interface IDisable { bool Disabled { get; } }
|
||||
public interface IExplodeModifier { bool ShouldExplode(Actor self); }
|
||||
public interface IHuskModifier { string HuskActor(Actor self); }
|
||||
public interface INudge { void OnNudge(Actor self, Actor nudger, bool force); }
|
||||
|
||||
public interface IRadarSignature
|
||||
{
|
||||
IEnumerable<int2> RadarSignatureCells(Actor self);
|
||||
IEnumerable<CPos> RadarSignatureCells(Actor self);
|
||||
Color RadarSignatureColor(Actor self);
|
||||
}
|
||||
|
||||
public interface IVisibilityModifier { bool IsVisible(Actor self); }
|
||||
public interface IRadarColorModifier { Color RadarColorOverride(Actor self); }
|
||||
public interface IHasLocation { int2 PxPosition { get; } }
|
||||
public interface IHasLocation { PPos PxPosition { get; } }
|
||||
|
||||
public interface IOccupySpace : IHasLocation
|
||||
{
|
||||
int2 TopLeft { get; }
|
||||
IEnumerable<Pair<int2, SubCell>> OccupiedCells();
|
||||
CPos TopLeft { get; }
|
||||
IEnumerable<Pair<CPos, SubCell>> OccupiedCells();
|
||||
}
|
||||
|
||||
public static class IOccupySpaceExts
|
||||
{
|
||||
public static int2 NearestCellTo(this IOccupySpace ios, int2 other)
|
||||
public static CPos NearestCellTo(this IOccupySpace ios, CPos other)
|
||||
{
|
||||
var nearest = ios.TopLeft;
|
||||
var nearestDistance = int.MaxValue;
|
||||
@@ -125,13 +125,14 @@ namespace OpenRA.Traits
|
||||
|
||||
public interface ITeleportable : IHasLocation /* crap name! */
|
||||
{
|
||||
bool CanEnterCell(int2 location);
|
||||
void SetPosition(Actor self, int2 cell);
|
||||
void SetPxPosition(Actor self, int2 px);
|
||||
void AdjustPxPosition(Actor self, int2 px); /* works like SetPxPosition, but visual only */
|
||||
bool CanEnterCell(CPos location);
|
||||
void SetPosition(Actor self, CPos cell);
|
||||
void SetPxPosition(Actor self, PPos px);
|
||||
void AdjustPxPosition(Actor self, PPos px); /* works like SetPxPosition, but visual only */
|
||||
}
|
||||
|
||||
public interface IMove : ITeleportable { int Altitude { get; set; } }
|
||||
public interface INotifyBlockingMove { void OnNotifyBlockingMove(Actor self, Actor blocking); }
|
||||
|
||||
public interface IFacing
|
||||
{
|
||||
@@ -212,7 +213,7 @@ namespace OpenRA.Traits
|
||||
public interface ITargetable
|
||||
{
|
||||
string[] TargetTypes { get; }
|
||||
IEnumerable<int2> TargetableCells(Actor self);
|
||||
IEnumerable<CPos> TargetableCells(Actor self);
|
||||
bool TargetableBy(Actor self, Actor byActor);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,16 @@ namespace OpenRA.Traits
|
||||
return ( facing - rot ) & 0xFF;
|
||||
}
|
||||
|
||||
public static int GetFacing(PVecInt d, int currentFacing)
|
||||
{
|
||||
return GetFacing(d.ToInt2(), currentFacing);
|
||||
}
|
||||
|
||||
public static int GetFacing(CVec d, int currentFacing)
|
||||
{
|
||||
return GetFacing(d.ToInt2(), currentFacing);
|
||||
}
|
||||
|
||||
public static int GetFacing( int2 d, int currentFacing )
|
||||
{
|
||||
if (d == int2.Zero)
|
||||
@@ -80,14 +90,14 @@ namespace OpenRA.Traits
|
||||
ecc * (cosAngle * v.Y - sinAngle * v.X));
|
||||
}
|
||||
|
||||
public static int2 CenterOfCell(int2 loc)
|
||||
public static PPos CenterOfCell(CPos loc)
|
||||
{
|
||||
return new int2( Game.CellSize / 2, Game.CellSize / 2 ) + Game.CellSize * loc;
|
||||
return loc.ToPPos() + new PVecInt(Game.CellSize / 2, Game.CellSize / 2);
|
||||
}
|
||||
|
||||
public static int2 BetweenCells(int2 from, int2 to)
|
||||
public static PPos BetweenCells(CPos from, CPos to)
|
||||
{
|
||||
return int2.Lerp( CenterOfCell( from ), CenterOfCell( to ), 1, 2 );
|
||||
return PPos.Lerp(CenterOfCell(from), CenterOfCell(to), 1, 2);
|
||||
}
|
||||
|
||||
public static int2 AsInt2(this int[] xs) { return new int2(xs[0], xs[1]); }
|
||||
@@ -120,6 +130,7 @@ namespace OpenRA.Traits
|
||||
|
||||
public static Color ArrayToColor(int[] x) { return Color.FromArgb(x[0], x[1], x[2]); }
|
||||
|
||||
[Obsolete("Use ToCPos() method", true)]
|
||||
public static int2 CellContaining(float2 pos) { return (1f / Game.CellSize * pos).ToInt2(); }
|
||||
|
||||
/* pretty crap */
|
||||
@@ -134,39 +145,39 @@ namespace OpenRA.Traits
|
||||
}
|
||||
}
|
||||
|
||||
static IEnumerable<int2> Neighbours(int2 c, bool allowDiagonal)
|
||||
static IEnumerable<CPos> Neighbours(CPos c, bool allowDiagonal)
|
||||
{
|
||||
yield return c;
|
||||
yield return new int2(c.X - 1, c.Y);
|
||||
yield return new int2(c.X + 1, c.Y);
|
||||
yield return new int2(c.X, c.Y - 1);
|
||||
yield return new int2(c.X, c.Y + 1);
|
||||
yield return new CPos(c.X - 1, c.Y);
|
||||
yield return new CPos(c.X + 1, c.Y);
|
||||
yield return new CPos(c.X, c.Y - 1);
|
||||
yield return new CPos(c.X, c.Y + 1);
|
||||
|
||||
if (allowDiagonal)
|
||||
{
|
||||
yield return new int2(c.X - 1, c.Y - 1);
|
||||
yield return new int2(c.X + 1, c.Y - 1);
|
||||
yield return new int2(c.X - 1, c.Y + 1);
|
||||
yield return new int2(c.X + 1, c.Y + 1);
|
||||
yield return new CPos(c.X - 1, c.Y - 1);
|
||||
yield return new CPos(c.X + 1, c.Y - 1);
|
||||
yield return new CPos(c.X - 1, c.Y + 1);
|
||||
yield return new CPos(c.X + 1, c.Y + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<int2> ExpandFootprint(IEnumerable<int2> cells, bool allowDiagonal)
|
||||
public static IEnumerable<CPos> ExpandFootprint(IEnumerable<CPos> cells, bool allowDiagonal)
|
||||
{
|
||||
var result = new Dictionary<int2, bool>();
|
||||
var result = new Dictionary<CPos, bool>();
|
||||
foreach (var c in cells.SelectMany(c => Neighbours(c, allowDiagonal)))
|
||||
result[c] = true;
|
||||
return result.Keys;
|
||||
}
|
||||
|
||||
public static IEnumerable<int2> AdjacentCells( Target target )
|
||||
public static IEnumerable<CPos> AdjacentCells(Target target)
|
||||
{
|
||||
var cells = target.IsActor
|
||||
? target.Actor.OccupiesSpace.OccupiedCells().Select(c => c.First).ToArray()
|
||||
: new int2[] {};
|
||||
: new CPos[] {};
|
||||
|
||||
if (cells.Length == 0)
|
||||
cells = new [] { Util.CellContaining(target.CenterLocation) };
|
||||
cells = new CPos[] { target.CenterLocation.ToCPos() };
|
||||
|
||||
return Util.ExpandFootprint(cells, true);
|
||||
}
|
||||
@@ -208,264 +219,264 @@ namespace OpenRA.Traits
|
||||
};
|
||||
|
||||
|
||||
public static readonly int2[] SubPxVector =
|
||||
public static readonly PSubVec[] SubPxVector =
|
||||
{
|
||||
new int2( 0, 1024 ),
|
||||
new int2( 25, 1023 ),
|
||||
new int2( 50, 1022 ),
|
||||
new int2( 75, 1021 ),
|
||||
new int2( 100, 1019 ),
|
||||
new int2( 125, 1016 ),
|
||||
new int2( 150, 1012 ),
|
||||
new int2( 175, 1008 ),
|
||||
new int2( 199, 1004 ),
|
||||
new int2( 224, 999 ),
|
||||
new int2( 248, 993 ),
|
||||
new int2( 273, 986 ),
|
||||
new int2( 297, 979 ),
|
||||
new int2( 321, 972 ),
|
||||
new int2( 344, 964 ),
|
||||
new int2( 368, 955 ),
|
||||
new int2( 391, 946 ),
|
||||
new int2( 414, 936 ),
|
||||
new int2( 437, 925 ),
|
||||
new int2( 460, 914 ),
|
||||
new int2( 482, 903 ),
|
||||
new int2( 504, 890 ),
|
||||
new int2( 526, 878 ),
|
||||
new int2( 547, 865 ),
|
||||
new int2( 568, 851 ),
|
||||
new int2( 589, 837 ),
|
||||
new int2( 609, 822 ),
|
||||
new int2( 629, 807 ),
|
||||
new int2( 649, 791 ),
|
||||
new int2( 668, 775 ),
|
||||
new int2( 687, 758 ),
|
||||
new int2( 706, 741 ),
|
||||
new int2( 724, 724 ),
|
||||
new int2( 741, 706 ),
|
||||
new int2( 758, 687 ),
|
||||
new int2( 775, 668 ),
|
||||
new int2( 791, 649 ),
|
||||
new int2( 807, 629 ),
|
||||
new int2( 822, 609 ),
|
||||
new int2( 837, 589 ),
|
||||
new int2( 851, 568 ),
|
||||
new int2( 865, 547 ),
|
||||
new int2( 878, 526 ),
|
||||
new int2( 890, 504 ),
|
||||
new int2( 903, 482 ),
|
||||
new int2( 914, 460 ),
|
||||
new int2( 925, 437 ),
|
||||
new int2( 936, 414 ),
|
||||
new int2( 946, 391 ),
|
||||
new int2( 955, 368 ),
|
||||
new int2( 964, 344 ),
|
||||
new int2( 972, 321 ),
|
||||
new int2( 979, 297 ),
|
||||
new int2( 986, 273 ),
|
||||
new int2( 993, 248 ),
|
||||
new int2( 999, 224 ),
|
||||
new int2( 1004, 199 ),
|
||||
new int2( 1008, 175 ),
|
||||
new int2( 1012, 150 ),
|
||||
new int2( 1016, 125 ),
|
||||
new int2( 1019, 100 ),
|
||||
new int2( 1021, 75 ),
|
||||
new int2( 1022, 50 ),
|
||||
new int2( 1023, 25 ),
|
||||
new int2( 1024, 0 ),
|
||||
new int2( 1023, -25 ),
|
||||
new int2( 1022, -50 ),
|
||||
new int2( 1021, -75 ),
|
||||
new int2( 1019, -100 ),
|
||||
new int2( 1016, -125 ),
|
||||
new int2( 1012, -150 ),
|
||||
new int2( 1008, -175 ),
|
||||
new int2( 1004, -199 ),
|
||||
new int2( 999, -224 ),
|
||||
new int2( 993, -248 ),
|
||||
new int2( 986, -273 ),
|
||||
new int2( 979, -297 ),
|
||||
new int2( 972, -321 ),
|
||||
new int2( 964, -344 ),
|
||||
new int2( 955, -368 ),
|
||||
new int2( 946, -391 ),
|
||||
new int2( 936, -414 ),
|
||||
new int2( 925, -437 ),
|
||||
new int2( 914, -460 ),
|
||||
new int2( 903, -482 ),
|
||||
new int2( 890, -504 ),
|
||||
new int2( 878, -526 ),
|
||||
new int2( 865, -547 ),
|
||||
new int2( 851, -568 ),
|
||||
new int2( 837, -589 ),
|
||||
new int2( 822, -609 ),
|
||||
new int2( 807, -629 ),
|
||||
new int2( 791, -649 ),
|
||||
new int2( 775, -668 ),
|
||||
new int2( 758, -687 ),
|
||||
new int2( 741, -706 ),
|
||||
new int2( 724, -724 ),
|
||||
new int2( 706, -741 ),
|
||||
new int2( 687, -758 ),
|
||||
new int2( 668, -775 ),
|
||||
new int2( 649, -791 ),
|
||||
new int2( 629, -807 ),
|
||||
new int2( 609, -822 ),
|
||||
new int2( 589, -837 ),
|
||||
new int2( 568, -851 ),
|
||||
new int2( 547, -865 ),
|
||||
new int2( 526, -878 ),
|
||||
new int2( 504, -890 ),
|
||||
new int2( 482, -903 ),
|
||||
new int2( 460, -914 ),
|
||||
new int2( 437, -925 ),
|
||||
new int2( 414, -936 ),
|
||||
new int2( 391, -946 ),
|
||||
new int2( 368, -955 ),
|
||||
new int2( 344, -964 ),
|
||||
new int2( 321, -972 ),
|
||||
new int2( 297, -979 ),
|
||||
new int2( 273, -986 ),
|
||||
new int2( 248, -993 ),
|
||||
new int2( 224, -999 ),
|
||||
new int2( 199, -1004 ),
|
||||
new int2( 175, -1008 ),
|
||||
new int2( 150, -1012 ),
|
||||
new int2( 125, -1016 ),
|
||||
new int2( 100, -1019 ),
|
||||
new int2( 75, -1021 ),
|
||||
new int2( 50, -1022 ),
|
||||
new int2( 25, -1023 ),
|
||||
new int2( 0, -1024 ),
|
||||
new int2( -25, -1023 ),
|
||||
new int2( -50, -1022 ),
|
||||
new int2( -75, -1021 ),
|
||||
new int2( -100, -1019 ),
|
||||
new int2( -125, -1016 ),
|
||||
new int2( -150, -1012 ),
|
||||
new int2( -175, -1008 ),
|
||||
new int2( -199, -1004 ),
|
||||
new int2( -224, -999 ),
|
||||
new int2( -248, -993 ),
|
||||
new int2( -273, -986 ),
|
||||
new int2( -297, -979 ),
|
||||
new int2( -321, -972 ),
|
||||
new int2( -344, -964 ),
|
||||
new int2( -368, -955 ),
|
||||
new int2( -391, -946 ),
|
||||
new int2( -414, -936 ),
|
||||
new int2( -437, -925 ),
|
||||
new int2( -460, -914 ),
|
||||
new int2( -482, -903 ),
|
||||
new int2( -504, -890 ),
|
||||
new int2( -526, -878 ),
|
||||
new int2( -547, -865 ),
|
||||
new int2( -568, -851 ),
|
||||
new int2( -589, -837 ),
|
||||
new int2( -609, -822 ),
|
||||
new int2( -629, -807 ),
|
||||
new int2( -649, -791 ),
|
||||
new int2( -668, -775 ),
|
||||
new int2( -687, -758 ),
|
||||
new int2( -706, -741 ),
|
||||
new int2( -724, -724 ),
|
||||
new int2( -741, -706 ),
|
||||
new int2( -758, -687 ),
|
||||
new int2( -775, -668 ),
|
||||
new int2( -791, -649 ),
|
||||
new int2( -807, -629 ),
|
||||
new int2( -822, -609 ),
|
||||
new int2( -837, -589 ),
|
||||
new int2( -851, -568 ),
|
||||
new int2( -865, -547 ),
|
||||
new int2( -878, -526 ),
|
||||
new int2( -890, -504 ),
|
||||
new int2( -903, -482 ),
|
||||
new int2( -914, -460 ),
|
||||
new int2( -925, -437 ),
|
||||
new int2( -936, -414 ),
|
||||
new int2( -946, -391 ),
|
||||
new int2( -955, -368 ),
|
||||
new int2( -964, -344 ),
|
||||
new int2( -972, -321 ),
|
||||
new int2( -979, -297 ),
|
||||
new int2( -986, -273 ),
|
||||
new int2( -993, -248 ),
|
||||
new int2( -999, -224 ),
|
||||
new int2( -1004, -199 ),
|
||||
new int2( -1008, -175 ),
|
||||
new int2( -1012, -150 ),
|
||||
new int2( -1016, -125 ),
|
||||
new int2( -1019, -100 ),
|
||||
new int2( -1021, -75 ),
|
||||
new int2( -1022, -50 ),
|
||||
new int2( -1023, -25 ),
|
||||
new int2( -1024, 0 ),
|
||||
new int2( -1023, 25 ),
|
||||
new int2( -1022, 50 ),
|
||||
new int2( -1021, 75 ),
|
||||
new int2( -1019, 100 ),
|
||||
new int2( -1016, 125 ),
|
||||
new int2( -1012, 150 ),
|
||||
new int2( -1008, 175 ),
|
||||
new int2( -1004, 199 ),
|
||||
new int2( -999, 224 ),
|
||||
new int2( -993, 248 ),
|
||||
new int2( -986, 273 ),
|
||||
new int2( -979, 297 ),
|
||||
new int2( -972, 321 ),
|
||||
new int2( -964, 344 ),
|
||||
new int2( -955, 368 ),
|
||||
new int2( -946, 391 ),
|
||||
new int2( -936, 414 ),
|
||||
new int2( -925, 437 ),
|
||||
new int2( -914, 460 ),
|
||||
new int2( -903, 482 ),
|
||||
new int2( -890, 504 ),
|
||||
new int2( -878, 526 ),
|
||||
new int2( -865, 547 ),
|
||||
new int2( -851, 568 ),
|
||||
new int2( -837, 589 ),
|
||||
new int2( -822, 609 ),
|
||||
new int2( -807, 629 ),
|
||||
new int2( -791, 649 ),
|
||||
new int2( -775, 668 ),
|
||||
new int2( -758, 687 ),
|
||||
new int2( -741, 706 ),
|
||||
new int2( -724, 724 ),
|
||||
new int2( -706, 741 ),
|
||||
new int2( -687, 758 ),
|
||||
new int2( -668, 775 ),
|
||||
new int2( -649, 791 ),
|
||||
new int2( -629, 807 ),
|
||||
new int2( -609, 822 ),
|
||||
new int2( -589, 837 ),
|
||||
new int2( -568, 851 ),
|
||||
new int2( -547, 865 ),
|
||||
new int2( -526, 878 ),
|
||||
new int2( -504, 890 ),
|
||||
new int2( -482, 903 ),
|
||||
new int2( -460, 914 ),
|
||||
new int2( -437, 925 ),
|
||||
new int2( -414, 936 ),
|
||||
new int2( -391, 946 ),
|
||||
new int2( -368, 955 ),
|
||||
new int2( -344, 964 ),
|
||||
new int2( -321, 972 ),
|
||||
new int2( -297, 979 ),
|
||||
new int2( -273, 986 ),
|
||||
new int2( -248, 993 ),
|
||||
new int2( -224, 999 ),
|
||||
new int2( -199, 1004 ),
|
||||
new int2( -175, 1008 ),
|
||||
new int2( -150, 1012 ),
|
||||
new int2( -125, 1016 ),
|
||||
new int2( -100, 1019 ),
|
||||
new int2( -75, 1021 ),
|
||||
new int2( -50, 1022 ),
|
||||
new int2( -25, 1023 )
|
||||
new PSubVec( 0, 1024 ),
|
||||
new PSubVec( 25, 1023 ),
|
||||
new PSubVec( 50, 1022 ),
|
||||
new PSubVec( 75, 1021 ),
|
||||
new PSubVec( 100, 1019 ),
|
||||
new PSubVec( 125, 1016 ),
|
||||
new PSubVec( 150, 1012 ),
|
||||
new PSubVec( 175, 1008 ),
|
||||
new PSubVec( 199, 1004 ),
|
||||
new PSubVec( 224, 999 ),
|
||||
new PSubVec( 248, 993 ),
|
||||
new PSubVec( 273, 986 ),
|
||||
new PSubVec( 297, 979 ),
|
||||
new PSubVec( 321, 972 ),
|
||||
new PSubVec( 344, 964 ),
|
||||
new PSubVec( 368, 955 ),
|
||||
new PSubVec( 391, 946 ),
|
||||
new PSubVec( 414, 936 ),
|
||||
new PSubVec( 437, 925 ),
|
||||
new PSubVec( 460, 914 ),
|
||||
new PSubVec( 482, 903 ),
|
||||
new PSubVec( 504, 890 ),
|
||||
new PSubVec( 526, 878 ),
|
||||
new PSubVec( 547, 865 ),
|
||||
new PSubVec( 568, 851 ),
|
||||
new PSubVec( 589, 837 ),
|
||||
new PSubVec( 609, 822 ),
|
||||
new PSubVec( 629, 807 ),
|
||||
new PSubVec( 649, 791 ),
|
||||
new PSubVec( 668, 775 ),
|
||||
new PSubVec( 687, 758 ),
|
||||
new PSubVec( 706, 741 ),
|
||||
new PSubVec( 724, 724 ),
|
||||
new PSubVec( 741, 706 ),
|
||||
new PSubVec( 758, 687 ),
|
||||
new PSubVec( 775, 668 ),
|
||||
new PSubVec( 791, 649 ),
|
||||
new PSubVec( 807, 629 ),
|
||||
new PSubVec( 822, 609 ),
|
||||
new PSubVec( 837, 589 ),
|
||||
new PSubVec( 851, 568 ),
|
||||
new PSubVec( 865, 547 ),
|
||||
new PSubVec( 878, 526 ),
|
||||
new PSubVec( 890, 504 ),
|
||||
new PSubVec( 903, 482 ),
|
||||
new PSubVec( 914, 460 ),
|
||||
new PSubVec( 925, 437 ),
|
||||
new PSubVec( 936, 414 ),
|
||||
new PSubVec( 946, 391 ),
|
||||
new PSubVec( 955, 368 ),
|
||||
new PSubVec( 964, 344 ),
|
||||
new PSubVec( 972, 321 ),
|
||||
new PSubVec( 979, 297 ),
|
||||
new PSubVec( 986, 273 ),
|
||||
new PSubVec( 993, 248 ),
|
||||
new PSubVec( 999, 224 ),
|
||||
new PSubVec( 1004, 199 ),
|
||||
new PSubVec( 1008, 175 ),
|
||||
new PSubVec( 1012, 150 ),
|
||||
new PSubVec( 1016, 125 ),
|
||||
new PSubVec( 1019, 100 ),
|
||||
new PSubVec( 1021, 75 ),
|
||||
new PSubVec( 1022, 50 ),
|
||||
new PSubVec( 1023, 25 ),
|
||||
new PSubVec( 1024, 0 ),
|
||||
new PSubVec( 1023, -25 ),
|
||||
new PSubVec( 1022, -50 ),
|
||||
new PSubVec( 1021, -75 ),
|
||||
new PSubVec( 1019, -100 ),
|
||||
new PSubVec( 1016, -125 ),
|
||||
new PSubVec( 1012, -150 ),
|
||||
new PSubVec( 1008, -175 ),
|
||||
new PSubVec( 1004, -199 ),
|
||||
new PSubVec( 999, -224 ),
|
||||
new PSubVec( 993, -248 ),
|
||||
new PSubVec( 986, -273 ),
|
||||
new PSubVec( 979, -297 ),
|
||||
new PSubVec( 972, -321 ),
|
||||
new PSubVec( 964, -344 ),
|
||||
new PSubVec( 955, -368 ),
|
||||
new PSubVec( 946, -391 ),
|
||||
new PSubVec( 936, -414 ),
|
||||
new PSubVec( 925, -437 ),
|
||||
new PSubVec( 914, -460 ),
|
||||
new PSubVec( 903, -482 ),
|
||||
new PSubVec( 890, -504 ),
|
||||
new PSubVec( 878, -526 ),
|
||||
new PSubVec( 865, -547 ),
|
||||
new PSubVec( 851, -568 ),
|
||||
new PSubVec( 837, -589 ),
|
||||
new PSubVec( 822, -609 ),
|
||||
new PSubVec( 807, -629 ),
|
||||
new PSubVec( 791, -649 ),
|
||||
new PSubVec( 775, -668 ),
|
||||
new PSubVec( 758, -687 ),
|
||||
new PSubVec( 741, -706 ),
|
||||
new PSubVec( 724, -724 ),
|
||||
new PSubVec( 706, -741 ),
|
||||
new PSubVec( 687, -758 ),
|
||||
new PSubVec( 668, -775 ),
|
||||
new PSubVec( 649, -791 ),
|
||||
new PSubVec( 629, -807 ),
|
||||
new PSubVec( 609, -822 ),
|
||||
new PSubVec( 589, -837 ),
|
||||
new PSubVec( 568, -851 ),
|
||||
new PSubVec( 547, -865 ),
|
||||
new PSubVec( 526, -878 ),
|
||||
new PSubVec( 504, -890 ),
|
||||
new PSubVec( 482, -903 ),
|
||||
new PSubVec( 460, -914 ),
|
||||
new PSubVec( 437, -925 ),
|
||||
new PSubVec( 414, -936 ),
|
||||
new PSubVec( 391, -946 ),
|
||||
new PSubVec( 368, -955 ),
|
||||
new PSubVec( 344, -964 ),
|
||||
new PSubVec( 321, -972 ),
|
||||
new PSubVec( 297, -979 ),
|
||||
new PSubVec( 273, -986 ),
|
||||
new PSubVec( 248, -993 ),
|
||||
new PSubVec( 224, -999 ),
|
||||
new PSubVec( 199, -1004 ),
|
||||
new PSubVec( 175, -1008 ),
|
||||
new PSubVec( 150, -1012 ),
|
||||
new PSubVec( 125, -1016 ),
|
||||
new PSubVec( 100, -1019 ),
|
||||
new PSubVec( 75, -1021 ),
|
||||
new PSubVec( 50, -1022 ),
|
||||
new PSubVec( 25, -1023 ),
|
||||
new PSubVec( 0, -1024 ),
|
||||
new PSubVec( -25, -1023 ),
|
||||
new PSubVec( -50, -1022 ),
|
||||
new PSubVec( -75, -1021 ),
|
||||
new PSubVec( -100, -1019 ),
|
||||
new PSubVec( -125, -1016 ),
|
||||
new PSubVec( -150, -1012 ),
|
||||
new PSubVec( -175, -1008 ),
|
||||
new PSubVec( -199, -1004 ),
|
||||
new PSubVec( -224, -999 ),
|
||||
new PSubVec( -248, -993 ),
|
||||
new PSubVec( -273, -986 ),
|
||||
new PSubVec( -297, -979 ),
|
||||
new PSubVec( -321, -972 ),
|
||||
new PSubVec( -344, -964 ),
|
||||
new PSubVec( -368, -955 ),
|
||||
new PSubVec( -391, -946 ),
|
||||
new PSubVec( -414, -936 ),
|
||||
new PSubVec( -437, -925 ),
|
||||
new PSubVec( -460, -914 ),
|
||||
new PSubVec( -482, -903 ),
|
||||
new PSubVec( -504, -890 ),
|
||||
new PSubVec( -526, -878 ),
|
||||
new PSubVec( -547, -865 ),
|
||||
new PSubVec( -568, -851 ),
|
||||
new PSubVec( -589, -837 ),
|
||||
new PSubVec( -609, -822 ),
|
||||
new PSubVec( -629, -807 ),
|
||||
new PSubVec( -649, -791 ),
|
||||
new PSubVec( -668, -775 ),
|
||||
new PSubVec( -687, -758 ),
|
||||
new PSubVec( -706, -741 ),
|
||||
new PSubVec( -724, -724 ),
|
||||
new PSubVec( -741, -706 ),
|
||||
new PSubVec( -758, -687 ),
|
||||
new PSubVec( -775, -668 ),
|
||||
new PSubVec( -791, -649 ),
|
||||
new PSubVec( -807, -629 ),
|
||||
new PSubVec( -822, -609 ),
|
||||
new PSubVec( -837, -589 ),
|
||||
new PSubVec( -851, -568 ),
|
||||
new PSubVec( -865, -547 ),
|
||||
new PSubVec( -878, -526 ),
|
||||
new PSubVec( -890, -504 ),
|
||||
new PSubVec( -903, -482 ),
|
||||
new PSubVec( -914, -460 ),
|
||||
new PSubVec( -925, -437 ),
|
||||
new PSubVec( -936, -414 ),
|
||||
new PSubVec( -946, -391 ),
|
||||
new PSubVec( -955, -368 ),
|
||||
new PSubVec( -964, -344 ),
|
||||
new PSubVec( -972, -321 ),
|
||||
new PSubVec( -979, -297 ),
|
||||
new PSubVec( -986, -273 ),
|
||||
new PSubVec( -993, -248 ),
|
||||
new PSubVec( -999, -224 ),
|
||||
new PSubVec( -1004, -199 ),
|
||||
new PSubVec( -1008, -175 ),
|
||||
new PSubVec( -1012, -150 ),
|
||||
new PSubVec( -1016, -125 ),
|
||||
new PSubVec( -1019, -100 ),
|
||||
new PSubVec( -1021, -75 ),
|
||||
new PSubVec( -1022, -50 ),
|
||||
new PSubVec( -1023, -25 ),
|
||||
new PSubVec( -1024, 0 ),
|
||||
new PSubVec( -1023, 25 ),
|
||||
new PSubVec( -1022, 50 ),
|
||||
new PSubVec( -1021, 75 ),
|
||||
new PSubVec( -1019, 100 ),
|
||||
new PSubVec( -1016, 125 ),
|
||||
new PSubVec( -1012, 150 ),
|
||||
new PSubVec( -1008, 175 ),
|
||||
new PSubVec( -1004, 199 ),
|
||||
new PSubVec( -999, 224 ),
|
||||
new PSubVec( -993, 248 ),
|
||||
new PSubVec( -986, 273 ),
|
||||
new PSubVec( -979, 297 ),
|
||||
new PSubVec( -972, 321 ),
|
||||
new PSubVec( -964, 344 ),
|
||||
new PSubVec( -955, 368 ),
|
||||
new PSubVec( -946, 391 ),
|
||||
new PSubVec( -936, 414 ),
|
||||
new PSubVec( -925, 437 ),
|
||||
new PSubVec( -914, 460 ),
|
||||
new PSubVec( -903, 482 ),
|
||||
new PSubVec( -890, 504 ),
|
||||
new PSubVec( -878, 526 ),
|
||||
new PSubVec( -865, 547 ),
|
||||
new PSubVec( -851, 568 ),
|
||||
new PSubVec( -837, 589 ),
|
||||
new PSubVec( -822, 609 ),
|
||||
new PSubVec( -807, 629 ),
|
||||
new PSubVec( -791, 649 ),
|
||||
new PSubVec( -775, 668 ),
|
||||
new PSubVec( -758, 687 ),
|
||||
new PSubVec( -741, 706 ),
|
||||
new PSubVec( -724, 724 ),
|
||||
new PSubVec( -706, 741 ),
|
||||
new PSubVec( -687, 758 ),
|
||||
new PSubVec( -668, 775 ),
|
||||
new PSubVec( -649, 791 ),
|
||||
new PSubVec( -629, 807 ),
|
||||
new PSubVec( -609, 822 ),
|
||||
new PSubVec( -589, 837 ),
|
||||
new PSubVec( -568, 851 ),
|
||||
new PSubVec( -547, 865 ),
|
||||
new PSubVec( -526, 878 ),
|
||||
new PSubVec( -504, 890 ),
|
||||
new PSubVec( -482, 903 ),
|
||||
new PSubVec( -460, 914 ),
|
||||
new PSubVec( -437, 925 ),
|
||||
new PSubVec( -414, 936 ),
|
||||
new PSubVec( -391, 946 ),
|
||||
new PSubVec( -368, 955 ),
|
||||
new PSubVec( -344, 964 ),
|
||||
new PSubVec( -321, 972 ),
|
||||
new PSubVec( -297, 979 ),
|
||||
new PSubVec( -273, 986 ),
|
||||
new PSubVec( -248, 993 ),
|
||||
new PSubVec( -224, 999 ),
|
||||
new PSubVec( -199, 1004 ),
|
||||
new PSubVec( -175, 1008 ),
|
||||
new PSubVec( -150, 1012 ),
|
||||
new PSubVec( -125, 1016 ),
|
||||
new PSubVec( -100, 1019 ),
|
||||
new PSubVec( -75, 1021 ),
|
||||
new PSubVec( -50, 1022 ),
|
||||
new PSubVec( -25, 1023 )
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,16 +20,16 @@ namespace OpenRA.Traits
|
||||
|
||||
class Waypoint : IOccupySpace, ISync
|
||||
{
|
||||
[Sync] int2 location;
|
||||
[Sync] CPos location;
|
||||
|
||||
public Waypoint(ActorInitializer init)
|
||||
{
|
||||
this.location = init.Get<LocationInit,int2>();
|
||||
this.location = init.Get<LocationInit, CPos>();
|
||||
}
|
||||
|
||||
public int2 TopLeft { get { return location; } }
|
||||
public CPos TopLeft { get { return location; } }
|
||||
|
||||
public IEnumerable<Pair<int2, SubCell>> OccupiedCells() { yield break; }
|
||||
public int2 PxPosition { get { return Util.CenterOfCell( location ); } }
|
||||
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { yield break; }
|
||||
public PPos PxPosition { get { return Util.CenterOfCell(location); } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace OpenRA.Traits
|
||||
{
|
||||
public readonly string BasePalette = null;
|
||||
public readonly string BaseName = "player";
|
||||
public readonly PaletteFormat PaletteFormat = PaletteFormat.ra;
|
||||
public readonly int[] RemapIndex = {};
|
||||
|
||||
public object Create( ActorInitializer init ) { return new PlayerColorPalette( init.self.Owner, this ); }
|
||||
}
|
||||
@@ -37,7 +37,7 @@ namespace OpenRA.Traits
|
||||
{
|
||||
var paletteName = "{0}{1}".F( info.BaseName, owner.InternalName );
|
||||
var newpal = new Palette(wr.GetPalette(info.BasePalette),
|
||||
new PlayerColorRemap(info.PaletteFormat, owner.ColorRamp));
|
||||
new PlayerColorRemap(info.RemapIndex, owner.ColorRamp));
|
||||
wr.AddPalette(paletteName, newpal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,12 +12,13 @@ using System;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
public class ResourceLayerInfo : TraitInfo<ResourceLayer> { }
|
||||
|
||||
public class ResourceLayer: IRenderOverlay, IWorldLoaded
|
||||
public class ResourceLayer : IRenderOverlay, IWorldLoaded
|
||||
{
|
||||
World world;
|
||||
|
||||
@@ -26,12 +27,12 @@ namespace OpenRA.Traits
|
||||
|
||||
bool hasSetupPalettes;
|
||||
|
||||
public void Render( WorldRenderer wr )
|
||||
public void Render(WorldRenderer wr)
|
||||
{
|
||||
if (!hasSetupPalettes)
|
||||
{
|
||||
hasSetupPalettes = true;
|
||||
foreach( var rt in world.WorldActor.TraitsImplementing<ResourceType>() )
|
||||
foreach (var rt in world.WorldActor.TraitsImplementing<ResourceType>())
|
||||
rt.info.PaletteIndex = wr.GetPaletteIndex(rt.info.Palette);
|
||||
}
|
||||
|
||||
@@ -39,13 +40,13 @@ namespace OpenRA.Traits
|
||||
for (int x = clip.Left; x < clip.Right; x++)
|
||||
for (int y = clip.Top; y < clip.Bottom; y++)
|
||||
{
|
||||
if (!world.LocalShroud.IsExplored(new int2(x, y)))
|
||||
if (!world.LocalShroud.IsExplored(new CPos(x, y)))
|
||||
continue;
|
||||
|
||||
var c = content[x, y];
|
||||
if (c.image != null)
|
||||
c.image[c.density].DrawAt(
|
||||
Game.CellSize * new int2(x, y),
|
||||
new CPos(x, y).ToPPos().ToFloat2(),
|
||||
c.type.info.PaletteIndex);
|
||||
}
|
||||
}
|
||||
@@ -70,7 +71,7 @@ namespace OpenRA.Traits
|
||||
if (type == null)
|
||||
continue;
|
||||
|
||||
if (!AllowResourceAt(type, new int2(x,y)))
|
||||
if (!AllowResourceAt(type, new CPos(x,y)))
|
||||
continue;
|
||||
|
||||
content[x, y].type = type;
|
||||
@@ -86,7 +87,7 @@ namespace OpenRA.Traits
|
||||
}
|
||||
}
|
||||
|
||||
public bool AllowResourceAt(ResourceType rt, int2 a)
|
||||
public bool AllowResourceAt(ResourceType rt, CPos a)
|
||||
{
|
||||
if (!world.Map.IsInMap(a.X, a.Y)) return false;
|
||||
if (!rt.info.AllowedTerrainTypes.Contains(world.GetTerrainInfo(a).Type)) return false;
|
||||
@@ -104,7 +105,7 @@ namespace OpenRA.Traits
|
||||
int sum = 0;
|
||||
for (var u = -1; u < 2; u++)
|
||||
for (var v = -1; v < 2; v++)
|
||||
if (content[i+u, j+v].type == t)
|
||||
if (content[i + u, j + v].type == t)
|
||||
++sum;
|
||||
return sum;
|
||||
}
|
||||
@@ -131,14 +132,14 @@ namespace OpenRA.Traits
|
||||
content[i, j].image.Length - 1,
|
||||
content[i, j].density + n);
|
||||
|
||||
world.Map.CustomTerrain[i,j] = t.info.TerrainType;
|
||||
world.Map.CustomTerrain[i, j] = t.info.TerrainType;
|
||||
}
|
||||
|
||||
public bool IsFull(int i, int j) { return content[i, j].density == content[i, j].image.Length - 1; }
|
||||
|
||||
public ResourceType Harvest(int2 p)
|
||||
public ResourceType Harvest(CPos p)
|
||||
{
|
||||
var type = content[p.X,p.Y].type;
|
||||
var type = content[p.X, p.Y].type;
|
||||
if (type == null) return null;
|
||||
|
||||
if (--content[p.X, p.Y].density < 0)
|
||||
@@ -150,7 +151,7 @@ namespace OpenRA.Traits
|
||||
return type;
|
||||
}
|
||||
|
||||
public void Destroy(int2 p)
|
||||
public void Destroy(CPos p)
|
||||
{
|
||||
// Don't break other users of CustomTerrain if there are no resources
|
||||
if (content[p.X, p.Y].type == null)
|
||||
@@ -162,7 +163,13 @@ namespace OpenRA.Traits
|
||||
world.Map.CustomTerrain[p.X, p.Y] = null;
|
||||
}
|
||||
|
||||
public ResourceType GetResource(int2 p) { return content[p.X, p.Y].type; }
|
||||
public ResourceType GetResource(CPos p) { return content[p.X, p.Y].type; }
|
||||
public int GetResourceDensity(CPos p) { return content[p.X, p.Y].density; }
|
||||
public int GetMaxResourceDensity(CPos p)
|
||||
{
|
||||
if (content[p.X, p.Y].image == null) return 0;
|
||||
return content[p.X, p.Y].image.Length - 1;
|
||||
}
|
||||
|
||||
public struct CellContents
|
||||
{
|
||||
|
||||
@@ -54,22 +54,22 @@ namespace OpenRA.Traits
|
||||
|
||||
// cache of positions that were added, so no matter what crazy trait code does, it
|
||||
// can't make us invalid.
|
||||
class ActorVisibility { public int range; public int2[] vis; }
|
||||
class ActorVisibility { public int range; public CPos[] vis; }
|
||||
Dictionary<Actor, ActorVisibility> vis = new Dictionary<Actor, ActorVisibility>();
|
||||
|
||||
static IEnumerable<int2> FindVisibleTiles(World world, int2 a, int r)
|
||||
static IEnumerable<CPos> FindVisibleTiles(World world, CPos a, int r)
|
||||
{
|
||||
var min = a - new int2(r, r);
|
||||
var max = a + new int2(r, r);
|
||||
if (min.X < world.Map.Bounds.Left - 1) min.X = world.Map.Bounds.Left - 1;
|
||||
if (min.Y < world.Map.Bounds.Top - 1) min.Y = world.Map.Bounds.Top - 1;
|
||||
if (max.X > world.Map.Bounds.Right) max.X = world.Map.Bounds.Right;
|
||||
if (max.Y > world.Map.Bounds.Bottom) max.Y = world.Map.Bounds.Bottom;
|
||||
var min = a - new CVec(r, r);
|
||||
var max = a + new CVec(r, r);
|
||||
if (min.X < world.Map.Bounds.Left - 1) min = new CPos(world.Map.Bounds.Left - 1, min.Y);
|
||||
if (min.Y < world.Map.Bounds.Top - 1) min = new CPos(min.X, world.Map.Bounds.Top - 1);
|
||||
if (max.X > world.Map.Bounds.Right) max = new CPos(world.Map.Bounds.Right, max.Y);
|
||||
if (max.Y > world.Map.Bounds.Bottom) max = new CPos(max.X, world.Map.Bounds.Bottom);
|
||||
|
||||
for (var j = min.Y; j <= max.Y; j++)
|
||||
for (var i = min.X; i <= max.X; i++)
|
||||
if (r * r >= (new int2(i, j) - a).LengthSquared)
|
||||
yield return new int2(i, j);
|
||||
if (r * r >= (new CPos(i, j) - a).LengthSquared)
|
||||
yield return new CPos(i, j);
|
||||
}
|
||||
|
||||
void AddActor(Actor a)
|
||||
@@ -148,7 +148,7 @@ namespace OpenRA.Traits
|
||||
AddActor(a);
|
||||
}
|
||||
|
||||
public static IEnumerable<int2> GetVisOrigins(Actor a)
|
||||
public static IEnumerable<CPos> GetVisOrigins(Actor a)
|
||||
{
|
||||
var ios = a.OccupiesSpace;
|
||||
if (ios != null)
|
||||
@@ -157,7 +157,7 @@ namespace OpenRA.Traits
|
||||
if (cells.Any()) return cells.Select(c => c.First);
|
||||
}
|
||||
|
||||
return new[] { a.CenterLocation / Game.CellSize };
|
||||
return new[] { a.CenterLocation.ToCPos() };
|
||||
}
|
||||
|
||||
void RemoveActor(Actor a)
|
||||
@@ -183,7 +183,7 @@ namespace OpenRA.Traits
|
||||
RemoveActor(a); AddActor(a);
|
||||
}
|
||||
|
||||
public void Explore(World world, int2 center, int range)
|
||||
public void Explore(World world, CPos center, int range)
|
||||
{
|
||||
foreach (var q in FindVisibleTiles(world, center, range))
|
||||
exploredCells[q.X, q.Y] = true;
|
||||
@@ -216,7 +216,7 @@ namespace OpenRA.Traits
|
||||
Dirty();
|
||||
}
|
||||
|
||||
public bool IsExplored(int2 xy) { return IsExplored(xy.X, xy.Y); }
|
||||
public bool IsExplored(CPos xy) { return IsExplored(xy.X, xy.Y); }
|
||||
public bool IsExplored(int x, int y)
|
||||
{
|
||||
if (!map.IsInMap(x, y))
|
||||
@@ -228,7 +228,7 @@ namespace OpenRA.Traits
|
||||
return exploredCells[x,y];
|
||||
}
|
||||
|
||||
public bool IsVisible(int2 xy) { return IsVisible(xy.X, xy.Y); }
|
||||
public bool IsVisible(CPos xy) { return IsVisible(xy.X, xy.Y); }
|
||||
public bool IsVisible(int x, int y)
|
||||
{
|
||||
if (Disabled)
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace OpenRA.Traits
|
||||
yield return a;
|
||||
}
|
||||
|
||||
public IEnumerable<Actor> ActorsInBox(int2 a, int2 b)
|
||||
public IEnumerable<Actor> ActorsInBox(PPos a, PPos b)
|
||||
{
|
||||
var r = Rectangle.FromLTRB(a.X, a.Y, b.X, b.Y);
|
||||
|
||||
|
||||
@@ -22,11 +22,11 @@ namespace OpenRA.Widgets
|
||||
public bool Depressed = false;
|
||||
public int VisualHeight = ChromeMetrics.Get<int>("ButtonDepth");
|
||||
public string Font = ChromeMetrics.Get<string>("ButtonFont");
|
||||
public string ClickSound = null;
|
||||
public string ClickDisabledSound = null;
|
||||
public bool Disabled = false;
|
||||
public bool Highlighted = false;
|
||||
public Func<string> GetText;
|
||||
public Func<bool> IsDisabled;
|
||||
public Func<bool> IsHighlighted;
|
||||
public Action<MouseInput> OnMouseDown = _ => {};
|
||||
public Action<MouseInput> OnMouseUp = _ => {};
|
||||
|
||||
@@ -41,6 +41,7 @@ namespace OpenRA.Widgets
|
||||
OnMouseUp = _ => OnClick();
|
||||
OnKeyPress = _ => OnClick();
|
||||
IsDisabled = () => Disabled;
|
||||
IsHighlighted = () => Highlighted;
|
||||
}
|
||||
|
||||
protected ButtonWidget(ButtonWidget widget)
|
||||
@@ -54,6 +55,8 @@ namespace OpenRA.Widgets
|
||||
OnMouseDown = widget.OnMouseDown;
|
||||
Disabled = widget.Disabled;
|
||||
IsDisabled = widget.IsDisabled;
|
||||
Highlighted = widget.Highlighted;
|
||||
IsHighlighted = widget.IsHighlighted;
|
||||
|
||||
OnMouseUp = mi => OnClick();
|
||||
OnKeyPress = _ => OnClick();
|
||||
@@ -73,10 +76,10 @@ namespace OpenRA.Widgets
|
||||
if (!IsDisabled())
|
||||
{
|
||||
OnKeyPress(e);
|
||||
Sound.Play(ClickSound);
|
||||
Sound.PlayNotification(null, "Sounds", "ClickSound", null);
|
||||
}
|
||||
else
|
||||
Sound.Play(ClickDisabledSound);
|
||||
Sound.PlayNotification(null, "Sounds", "ClickDisabledSound", null);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -105,12 +108,12 @@ namespace OpenRA.Widgets
|
||||
{
|
||||
OnMouseDown(mi);
|
||||
Depressed = true;
|
||||
Sound.Play(ClickSound);
|
||||
Sound.PlayNotification(null, "Sounds", "ClickSound", null);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoseFocus(mi);
|
||||
Sound.Play(ClickDisabledSound);
|
||||
Sound.PlayNotification(null, "Sounds", "ClickDisabledSound", null);
|
||||
}
|
||||
}
|
||||
else if (mi.Event == MouseInputEvent.Move && Focused)
|
||||
@@ -126,13 +129,14 @@ namespace OpenRA.Widgets
|
||||
{
|
||||
var rb = RenderBounds;
|
||||
var disabled = IsDisabled();
|
||||
var highlighted = IsHighlighted();
|
||||
|
||||
var font = Game.Renderer.Fonts[Font];
|
||||
var text = GetText();
|
||||
var s = font.Measure(text);
|
||||
var stateOffset = (Depressed) ? new int2(VisualHeight, VisualHeight) : new int2(0, 0);
|
||||
|
||||
DrawBackground(rb, disabled, Depressed, Ui.MouseOverWidget == this);
|
||||
DrawBackground(rb, disabled, Depressed, Ui.MouseOverWidget == this, highlighted);
|
||||
font.DrawText(text, new int2(rb.X + (UsableWidth - s.X)/ 2, rb.Y + (Bounds.Height - s.Y) / 2) + stateOffset,
|
||||
disabled ? Color.Gray : Color.White);
|
||||
}
|
||||
@@ -140,17 +144,19 @@ namespace OpenRA.Widgets
|
||||
public override Widget Clone() { return new ButtonWidget(this); }
|
||||
public virtual int UsableWidth { get { return Bounds.Width; } }
|
||||
|
||||
public virtual void DrawBackground(Rectangle rect, bool disabled, bool pressed, bool hover)
|
||||
public virtual void DrawBackground(Rectangle rect, bool disabled, bool pressed, bool hover, bool highlighted)
|
||||
{
|
||||
ButtonWidget.DrawBackground("button", rect, disabled, pressed, hover);
|
||||
ButtonWidget.DrawBackground("button", rect, disabled, pressed, hover, highlighted);
|
||||
}
|
||||
|
||||
public static void DrawBackground(string baseName, Rectangle rect, bool disabled, bool pressed, bool hover)
|
||||
public static void DrawBackground(string baseName, Rectangle rect, bool disabled, bool pressed, bool hover, bool highlighted)
|
||||
{
|
||||
var state = disabled ? "-disabled" :
|
||||
pressed ? "-pressed" :
|
||||
hover ? "-hover" :
|
||||
"";
|
||||
if (highlighted)
|
||||
state += "-highlighted";
|
||||
|
||||
WidgetUtils.DrawPanel(baseName + state, rect);
|
||||
}
|
||||
|
||||
@@ -79,11 +79,11 @@ namespace OpenRA.Widgets
|
||||
var thumbHover = Ui.MouseOverWidget == this && thumbRect.Contains(Viewport.LastMousePos);
|
||||
WidgetUtils.DrawPanel(Background, backgroundRect);
|
||||
WidgetUtils.DrawPanel("scrollpanel-bg", scrollbarRect);
|
||||
ButtonWidget.DrawBackground("button", upButtonRect, upDisabled, UpPressed, upHover);
|
||||
ButtonWidget.DrawBackground("button", downButtonRect, downDisabled, DownPressed, downHover);
|
||||
ButtonWidget.DrawBackground("button", upButtonRect, upDisabled, UpPressed, upHover, false);
|
||||
ButtonWidget.DrawBackground("button", downButtonRect, downDisabled, DownPressed, downHover, false);
|
||||
|
||||
if (thumbHeight > 0)
|
||||
ButtonWidget.DrawBackground("scrollthumb", thumbRect, false, Focused && thumbHover, thumbHover);
|
||||
ButtonWidget.DrawBackground("scrollthumb", thumbRect, false, Focused && thumbHover, thumbHover, false);
|
||||
|
||||
var upOffset = !UpPressed || upDisabled ? 4 : 4 + ButtonDepth;
|
||||
var downOffset = !DownPressed || downDisabled ? 4 : 4 + ButtonDepth;
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace OpenRA.Widgets
|
||||
|
||||
// Thumb
|
||||
var thumbHover = Ui.MouseOverWidget == this && tr.Contains(Viewport.LastMousePos);
|
||||
ButtonWidget.DrawBackground("scrollthumb", tr, IsDisabled(), isMoving, thumbHover);
|
||||
ButtonWidget.DrawBackground("scrollthumb", tr, IsDisabled(), isMoving, thumbHover, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,11 @@ namespace OpenRA.Widgets
|
||||
{
|
||||
public override void Draw()
|
||||
{
|
||||
var s = WidgetUtils.FormatTime(Game.LocalTick);
|
||||
var font = Game.Renderer.Fonts["Title"];
|
||||
var rb = RenderBounds;
|
||||
|
||||
var s = WidgetUtils.FormatTime(Game.LocalTick) + (Game.orderManager.GamePaused?" (paused)":"");
|
||||
var pos = new float2(rb.Left - font.Measure(s).X / 2, rb.Top);
|
||||
|
||||
font.DrawTextWithContrast(s, pos, Color.White, Color.Black, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,12 +42,12 @@ namespace OpenRA.Widgets
|
||||
return;
|
||||
}
|
||||
|
||||
Game.Renderer.WorldLineRenderer.DrawRect(selbox.Value.First, selbox.Value.Second, Color.White);
|
||||
Game.Renderer.WorldLineRenderer.DrawRect(selbox.Value.First.ToFloat2(), selbox.Value.Second.ToFloat2(), Color.White);
|
||||
foreach (var u in SelectActorsInBox(world, selbox.Value.First, selbox.Value.Second, _ => true))
|
||||
worldRenderer.DrawRollover(u);
|
||||
}
|
||||
|
||||
int2 dragStart, dragEnd;
|
||||
PPos dragStart, dragEnd;
|
||||
|
||||
public override bool HandleMouseInput(MouseInput mi)
|
||||
{
|
||||
@@ -101,7 +101,7 @@ namespace OpenRA.Widgets
|
||||
return true;
|
||||
}
|
||||
|
||||
public Pair<int2, int2>? SelectionBox
|
||||
public Pair<PPos, PPos>? SelectionBox
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -110,11 +110,11 @@ namespace OpenRA.Widgets
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyOrders(World world, int2 xy, MouseInput mi)
|
||||
public void ApplyOrders(World world, PPos xy, MouseInput mi)
|
||||
{
|
||||
if (world.OrderGenerator == null) return;
|
||||
|
||||
var orders = world.OrderGenerator.Order(world, Traits.Util.CellContaining(xy), mi).ToArray();
|
||||
var orders = world.OrderGenerator.Order(world, xy.ToCPos(), mi).ToArray();
|
||||
orders.Do( o => world.IssueOrder( o ) );
|
||||
|
||||
world.PlayVoiceForOrders(orders);
|
||||
@@ -135,7 +135,7 @@ namespace OpenRA.Widgets
|
||||
};
|
||||
|
||||
// TODO: fix this up.
|
||||
return world.OrderGenerator.GetCursor( world, Game.viewport.ViewToWorld(mi).ToInt2(), mi );
|
||||
return world.OrderGenerator.GetCursor( world, Game.viewport.ViewToWorld(mi), mi );
|
||||
} );
|
||||
}
|
||||
|
||||
@@ -148,6 +148,10 @@ namespace OpenRA.Widgets
|
||||
world.Selection.DoControlGroup(world, e.KeyName[0] - '0', e.Modifiers);
|
||||
return true;
|
||||
}
|
||||
else if(e.KeyName == "pause" || e.KeyName == "f3")
|
||||
{
|
||||
world.IssueOrder(Order.PauseRequest());
|
||||
}
|
||||
|
||||
bool handled = false;
|
||||
|
||||
@@ -157,7 +161,7 @@ namespace OpenRA.Widgets
|
||||
}
|
||||
|
||||
static readonly Actor[] NoActors = {};
|
||||
IEnumerable<Actor> SelectActorsInBox(World world, int2 a, int2 b, Func<Actor, bool> cond)
|
||||
IEnumerable<Actor> SelectActorsInBox(World world, PPos a, PPos b, Func<Actor, bool> cond)
|
||||
{
|
||||
return world.FindUnits(a, b)
|
||||
.Where( x => x.HasTrait<Selectable>() && world.LocalShroud.IsVisible(x) && cond(x) )
|
||||
|
||||
@@ -183,7 +183,7 @@ namespace OpenRA
|
||||
|
||||
while (frameEndActions.Count != 0)
|
||||
frameEndActions.Dequeue()(this);
|
||||
Game.viewport.Tick();
|
||||
|
||||
}
|
||||
|
||||
public IEnumerable<Actor> Actors { get { return actors; } }
|
||||
|
||||
@@ -27,24 +27,24 @@ namespace OpenRA
|
||||
return FindUnits(world, loc, loc).Where(a => world.LocalShroud.IsVisible(a));
|
||||
}
|
||||
|
||||
public static IEnumerable<Actor> FindUnits(this World world, int2 a, int2 b)
|
||||
public static IEnumerable<Actor> FindUnits(this World world, PPos a, PPos b)
|
||||
{
|
||||
var u = float2.Min(a, b).ToInt2();
|
||||
var v = float2.Max(a, b).ToInt2();
|
||||
var u = PPos.Min(a, b);
|
||||
var v = PPos.Max(a, b);
|
||||
return world.WorldActor.Trait<SpatialBins>().ActorsInBox(u,v);
|
||||
}
|
||||
|
||||
public static Actor ClosestTo( this IEnumerable<Actor> actors, int2 px )
|
||||
public static Actor ClosestTo(this IEnumerable<Actor> actors, PPos px)
|
||||
{
|
||||
return actors.OrderBy( a => (a.CenterLocation - px).LengthSquared ).FirstOrDefault();
|
||||
}
|
||||
|
||||
public static IEnumerable<Actor> FindUnitsInCircle(this World world, int2 a, int r)
|
||||
public static IEnumerable<Actor> FindUnitsInCircle(this World world, PPos a, int r)
|
||||
{
|
||||
using (new PerfSample("FindUnitsInCircle"))
|
||||
{
|
||||
var min = a - new int2(r, r);
|
||||
var max = a + new int2(r, r);
|
||||
var min = a - PVecInt.FromRadius(r);
|
||||
var max = a + PVecInt.FromRadius(r);
|
||||
|
||||
var actors = world.FindUnits(min, max);
|
||||
|
||||
@@ -56,48 +56,71 @@ namespace OpenRA
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<int2> FindTilesInCircle(this World world, int2 a, int r)
|
||||
public static IEnumerable<CPos> FindTilesInCircle(this World world, CPos a, int r)
|
||||
{
|
||||
var min = world.ClampToWorld(a - new int2(r, r));
|
||||
var max = world.ClampToWorld(a + new int2(r, r));
|
||||
for (var j = min.Y; j <= max.Y; j++)
|
||||
for (var i = min.X; i <= max.X; i++)
|
||||
if (r * r >= (new int2(i, j) - a).LengthSquared)
|
||||
yield return new int2(i, j);
|
||||
if (r >= TilesByDistance.Length)
|
||||
throw new InvalidOperationException("FindTilesInCircle supports queries for only <= {0}".F(MaxRange));
|
||||
|
||||
for(var i = 0; i <= r; i++)
|
||||
{
|
||||
foreach(var offset in TilesByDistance[i])
|
||||
{
|
||||
var t = offset + a;
|
||||
if (world.Map.Bounds.Contains(t.X, t.Y))
|
||||
yield return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetTerrainType(this World world, int2 cell)
|
||||
static List<CVec>[] InitTilesByDistance(int max)
|
||||
{
|
||||
var ts = new List<CVec>[max+1];
|
||||
for (var i = 0; i < max+1; i++)
|
||||
ts[i] = new List<CVec>();
|
||||
|
||||
for (var j = -max; j <= max; j++)
|
||||
for (var i = -max; i <= max; i++)
|
||||
if (max * max >= i * i + j * j)
|
||||
ts[(int)Math.Ceiling(Math.Sqrt(i*i + j*j))].Add(new CVec(i,j));
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
const int MaxRange = 50;
|
||||
static List<CVec>[] TilesByDistance = InitTilesByDistance(MaxRange);
|
||||
|
||||
public static string GetTerrainType(this World world, CPos cell)
|
||||
{
|
||||
var custom = world.Map.CustomTerrain[cell.X, cell.Y];
|
||||
return custom != null ? custom : world.TileSet.GetTerrainType(world.Map.MapTiles.Value[cell.X, cell.Y]);
|
||||
}
|
||||
|
||||
public static TerrainTypeInfo GetTerrainInfo(this World world, int2 cell)
|
||||
public static TerrainTypeInfo GetTerrainInfo(this World world, CPos cell)
|
||||
{
|
||||
return world.TileSet.Terrain[world.GetTerrainType(cell)];
|
||||
}
|
||||
|
||||
public static int2 ClampToWorld( this World world, int2 xy )
|
||||
public static CPos ClampToWorld(this World world, CPos xy)
|
||||
{
|
||||
var r = world.Map.Bounds;
|
||||
return xy.Clamp(new Rectangle(r.X,r.Y,r.Width-1, r.Height-1));
|
||||
}
|
||||
|
||||
public static int2 ChooseRandomEdgeCell(this World w)
|
||||
public static CPos ChooseRandomEdgeCell(this World w)
|
||||
{
|
||||
var isX = w.SharedRandom.Next(2) == 0;
|
||||
var edge = w.SharedRandom.Next(2) == 0;
|
||||
|
||||
return new int2(
|
||||
return new CPos(
|
||||
isX ? w.SharedRandom.Next(w.Map.Bounds.Left, w.Map.Bounds.Right)
|
||||
: (edge ? w.Map.Bounds.Left : w.Map.Bounds.Right),
|
||||
!isX ? w.SharedRandom.Next(w.Map.Bounds.Top, w.Map.Bounds.Bottom)
|
||||
: (edge ? w.Map.Bounds.Top : w.Map.Bounds.Bottom));
|
||||
}
|
||||
|
||||
public static int2 ChooseRandomCell(this World w, Thirdparty.Random r)
|
||||
public static CPos ChooseRandomCell(this World w, Thirdparty.Random r)
|
||||
{
|
||||
return new int2(
|
||||
return new CPos(
|
||||
r.Next(w.Map.Bounds.Left, w.Map.Bounds.Right),
|
||||
r.Next(w.Map.Bounds.Top, w.Map.Bounds.Bottom));
|
||||
}
|
||||
@@ -121,7 +144,7 @@ namespace OpenRA
|
||||
return selectable != null && selectable.Voice != null;
|
||||
}
|
||||
|
||||
public static VoiceInfo GetVoice(this Actor a)
|
||||
public static SoundInfo GetVoice(this Actor a)
|
||||
{
|
||||
var selectable = a.Info.Traits.GetOrDefault<SelectableInfo>();
|
||||
if (selectable == null) return null;
|
||||
|
||||
@@ -27,8 +27,8 @@ namespace OpenRA.Mods.Cnc
|
||||
readonly RenderUnit ru;
|
||||
State state;
|
||||
|
||||
int2 startDock;
|
||||
int2 endDock;
|
||||
PPos startDock;
|
||||
PPos endDock;
|
||||
public HarvesterDockSequence(Actor self, Actor proc)
|
||||
{
|
||||
this.proc = proc;
|
||||
@@ -36,7 +36,7 @@ namespace OpenRA.Mods.Cnc
|
||||
harv = self.Trait<Harvester>();
|
||||
ru = self.Trait<RenderUnit>();
|
||||
startDock = self.Trait<IHasLocation>().PxPosition;
|
||||
endDock = proc.Trait<IHasLocation>().PxPosition + new int2(-15,8);
|
||||
endDock = proc.Trait<IHasLocation>().PxPosition + new PVecInt(-15,8);
|
||||
}
|
||||
|
||||
public override Activity Tick(Actor self)
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace OpenRA.Mods.Cnc.Effects
|
||||
Animation anim;
|
||||
Actor firedBy;
|
||||
|
||||
public IonCannon(Actor firedBy, World world, int2 location)
|
||||
public IonCannon(Actor firedBy, World world, CPos location)
|
||||
{
|
||||
this.firedBy = firedBy;
|
||||
target = Target.FromCell(location);
|
||||
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.Cnc.Effects
|
||||
public IEnumerable<Renderable> Render()
|
||||
{
|
||||
yield return new Renderable(anim.Image,
|
||||
target.CenterLocation - new float2(.5f * anim.Image.size.X, anim.Image.size.Y - Game.CellSize),
|
||||
target.CenterLocation.ToFloat2() - new float2(.5f * anim.Image.size.X, anim.Image.size.Y - Game.CellSize),
|
||||
"effect", (int)target.CenterLocation.Y);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Cnc
|
||||
{
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
Sound.Play(Info.LaunchSound, Game.CellSize * order.TargetLocation.ToFloat2());
|
||||
Sound.Play(Info.LaunchSound, order.TargetLocation.ToPPos());
|
||||
w.Add(new IonCannon(self, w, order.TargetLocation));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,13 +22,13 @@ namespace OpenRA.Mods.RA
|
||||
class CncShellmapScript: IWorldLoaded, ITick
|
||||
{
|
||||
Dictionary<string, Actor> Actors;
|
||||
static int2 ViewportOrigin;
|
||||
static CPos ViewportOrigin;
|
||||
|
||||
public void WorldLoaded(World w)
|
||||
{
|
||||
var b = w.Map.Bounds;
|
||||
ViewportOrigin = new int2(b.Left + b.Width/2, b.Top + b.Height/2);
|
||||
Game.MoveViewport(ViewportOrigin);
|
||||
ViewportOrigin = new CPos(b.Left + b.Width/2, b.Top + b.Height/2);
|
||||
Game.MoveViewport(ViewportOrigin.ToFloat2());
|
||||
|
||||
Actors = w.WorldActor.Trait<SpawnMapActors>().Actors;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA
|
||||
void SetViewport()
|
||||
{
|
||||
var t = (ticks + 45) % (360f * speed) * (Math.PI / 180) * 1f / speed;
|
||||
var loc = ViewportOrigin + new float2(-15,4) * float2.FromAngle( (float)t );
|
||||
var loc = ViewportOrigin.ToFloat2() + (new float2(-15,4) * float2.FromAngle( (float)t ));
|
||||
Game.viewport.Center(loc);
|
||||
}
|
||||
|
||||
@@ -78,11 +78,11 @@ namespace OpenRA.Mods.RA
|
||||
}));
|
||||
}
|
||||
|
||||
void LoopTrack(Actor self, int2 left, int2 right)
|
||||
void LoopTrack(Actor self, CPos left, CPos right)
|
||||
{
|
||||
var mobile = self.Trait<Mobile>();
|
||||
self.QueueActivity(mobile.ScriptedMove(left));
|
||||
self.QueueActivity(new Teleport(right));
|
||||
self.QueueActivity(new SimpleTeleport(right));
|
||||
self.QueueActivity(new CallFunc(() => LoopTrack(self,left,right)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Cnc
|
||||
Players = w.Players.ToDictionary(p => p.InternalName);
|
||||
Actors = w.WorldActor.Trait<SpawnMapActors>().Actors;
|
||||
var b = w.Map.Bounds;
|
||||
Game.MoveViewport(new int2(b.Left + b.Width/2, b.Top + b.Height/2));
|
||||
Game.MoveViewport(new CPos(b.Left + b.Width/2, b.Top + b.Height/2).ToFloat2());
|
||||
|
||||
Scripting.Media.PlayFMVFullscreen(w, "gdi1.vqa",
|
||||
() => Scripting.Media.PlayFMVFullscreen(w, "landing.vqa", () =>
|
||||
@@ -130,7 +130,7 @@ namespace OpenRA.Mods.Cnc
|
||||
ReinforceFromSea(self.World,
|
||||
Actors["lstStart"].Location,
|
||||
Actors["lstEnd"].Location,
|
||||
new int2(53,53),
|
||||
new CPos(53, 53),
|
||||
new string[] {"e1","e1","e1"},
|
||||
Players["GoodGuy"]);
|
||||
}
|
||||
@@ -140,7 +140,7 @@ namespace OpenRA.Mods.Cnc
|
||||
ReinforceFromSea(self.World,
|
||||
Actors["lstStart"].Location,
|
||||
Actors["lstEnd"].Location,
|
||||
new int2(53,53),
|
||||
new CPos(53, 53),
|
||||
new string[] {"e1","e1","e1"},
|
||||
Players["GoodGuy"]);
|
||||
}
|
||||
@@ -150,7 +150,7 @@ namespace OpenRA.Mods.Cnc
|
||||
ReinforceFromSea(self.World,
|
||||
Actors["lstStart"].Location,
|
||||
Actors["lstEnd"].Location,
|
||||
new int2(53,53),
|
||||
new CPos(53, 53),
|
||||
new string[] {"jeep"},
|
||||
Players["GoodGuy"]);
|
||||
}
|
||||
@@ -160,7 +160,7 @@ namespace OpenRA.Mods.Cnc
|
||||
ReinforceFromSea(self.World,
|
||||
Actors["lstStart"].Location,
|
||||
Actors["lstEnd"].Location,
|
||||
new int2(53,53),
|
||||
new CPos(53, 53),
|
||||
new string[] {"jeep"},
|
||||
Players["GoodGuy"]);
|
||||
}
|
||||
@@ -177,7 +177,7 @@ namespace OpenRA.Mods.Cnc
|
||||
self.QueueActivity(new CallFunc(() => SetGunboatPath()));
|
||||
}
|
||||
|
||||
void ReinforceFromSea(World world, int2 startPos, int2 endPos, int2 unload, string[] items, Player player)
|
||||
void ReinforceFromSea(World world, CPos startPos, CPos endPos, CPos unload, string[] items, Player player)
|
||||
{
|
||||
world.AddFrameEndTask(w =>
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
@@ -12,6 +12,25 @@
|
||||
<AssemblyName>OpenRA.Mods.Cnc</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<UpgradeBackupLocation />
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -27,6 +46,7 @@
|
||||
<Command type="AfterBuild" command="mono RALint.exe cnc" workingdir="${ProjectDir}/../" />
|
||||
</CustomCommands>
|
||||
</CustomCommands>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@@ -35,6 +55,7 @@
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
@@ -86,15 +107,14 @@
|
||||
<Compile Include="Widgets\Logic\SimpleTooltipLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\SupportPowerTooltipLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\WorldTooltipLogic.cs" />
|
||||
<Compile Include="Widgets\PowerBarWidget.cs" />
|
||||
<Compile Include="Widgets\ProductionPaletteWidget.cs" />
|
||||
<Compile Include="Widgets\ProductionTabsWidget.cs" />
|
||||
<Compile Include="Widgets\SiloBarWidget.cs" />
|
||||
<Compile Include="Widgets\SupportPowersWidget.cs" />
|
||||
<Compile Include="Widgets\ToggleButtonWidget.cs" />
|
||||
<Compile Include="Widgets\TooltipContainerWidget.cs" />
|
||||
<Compile Include="WithFire.cs" />
|
||||
<Compile Include="WithRoof.cs" />
|
||||
<Compile Include="Widgets\ResourceBarWidget.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
|
||||
@@ -113,6 +133,23 @@
|
||||
<Private>False</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Windows Installer 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace OpenRA.Mods.Cnc
|
||||
{
|
||||
public class ProductionAirdropInfo : ProductionInfo
|
||||
{
|
||||
public readonly string ReadyAudio = "reinfor1.aud";
|
||||
public readonly string ReadyAudio = "Reinforce";
|
||||
[ActorReference] public readonly string ActorType = "c17";
|
||||
|
||||
public override object Create(ActorInitializer init) { return new ProductionAirdrop(this); }
|
||||
@@ -36,8 +36,8 @@ namespace OpenRA.Mods.Cnc
|
||||
|
||||
// Start a fixed distance away: the width of the map.
|
||||
// This makes the production timing independent of spawnpoint
|
||||
var startPos = self.Location + new int2(owner.World.Map.Bounds.Width, 0);
|
||||
var endPos = new int2(owner.World.Map.Bounds.Left - 5, self.Location.Y);
|
||||
var startPos = self.Location + new CVec(owner.World.Map.Bounds.Width, 0);
|
||||
var endPos = new CPos(owner.World.Map.Bounds.Left - 5, self.Location.Y);
|
||||
|
||||
// Assume a single exit point for simplicity
|
||||
var exit = self.Info.Traits.WithInterface<ExitInfo>().First();
|
||||
@@ -57,7 +57,7 @@ namespace OpenRA.Mods.Cnc
|
||||
new AltitudeInit( Rules.Info[actorType].Traits.Get<PlaneInfo>().CruiseAltitude ),
|
||||
});
|
||||
|
||||
a.QueueActivity(Fly.ToCell(self.Location + new int2(6,0)));
|
||||
a.QueueActivity(Fly.ToCell(self.Location + new CVec(6, 0)));
|
||||
a.QueueActivity(new Land(Target.FromActor(self)));
|
||||
a.QueueActivity(new CallFunc(() =>
|
||||
{
|
||||
@@ -66,7 +66,7 @@ namespace OpenRA.Mods.Cnc
|
||||
|
||||
rb.PlayCustomAnimRepeating(self, "idle");
|
||||
self.World.AddFrameEndTask(ww => DoProduction(self, producee, exit));
|
||||
Sound.PlayToPlayer(self.Owner, (Info as ProductionAirdropInfo).ReadyAudio);
|
||||
Sound.PlayNotification(self.Owner, "Speech", (Info as ProductionAirdropInfo).ReadyAudio, self.Owner.Country.Race);
|
||||
}));
|
||||
a.QueueActivity(Fly.ToCell(endPos));
|
||||
a.QueueActivity(new RemoveSelf());
|
||||
|
||||
@@ -15,31 +15,49 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Cnc
|
||||
{
|
||||
class RenderCargoInfo : ITraitInfo, Requires<CargoInfo>
|
||||
public class RenderCargoInfo : ITraitInfo, Requires<CargoInfo>
|
||||
{
|
||||
public object Create(ActorInitializer init) { return new RenderCargo(init.self); }
|
||||
/* altitude of the cargo, relative to us. -ve is underneath us */
|
||||
public readonly int RelativeAltitude = 0;
|
||||
public readonly string[] PassengerTypes;
|
||||
|
||||
public object Create(ActorInitializer init) { return new RenderCargo(init.self, this); }
|
||||
}
|
||||
|
||||
public class RenderCargo : IRenderModifier
|
||||
{
|
||||
Cargo cargo;
|
||||
IFacing facing;
|
||||
IMove move;
|
||||
RenderCargoInfo Info;
|
||||
|
||||
public RenderCargo(Actor self)
|
||||
public RenderCargo(Actor self, RenderCargoInfo info)
|
||||
{
|
||||
cargo = self.Trait<Cargo>();
|
||||
facing = self.TraitOrDefault<IFacing>();
|
||||
move = self.Trait<IMove>();
|
||||
Info = info;
|
||||
}
|
||||
|
||||
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
|
||||
{
|
||||
foreach (var c in cargo.Passengers)
|
||||
{
|
||||
c.Trait<ITeleportable>().SetPxPosition( c, self.Trait<IHasLocation>().PxPosition );
|
||||
if (facing != null && c.HasTrait<IFacing>())
|
||||
c.Trait<IFacing>().Facing = facing.Facing;
|
||||
c.Trait<ITeleportable>().SetPxPosition( c, move.PxPosition );
|
||||
|
||||
var cargoFacing = c.TraitOrDefault<IFacing>();
|
||||
if (facing != null && cargoFacing != null)
|
||||
cargoFacing.Facing = facing.Facing;
|
||||
}
|
||||
return r.Concat(cargo.Passengers.SelectMany(a => a.Render()));
|
||||
|
||||
var visiblePassengers = (Info.PassengerTypes != null && Info.PassengerTypes.Length > 0)
|
||||
? cargo.Passengers.Where(p =>
|
||||
Info.PassengerTypes.Contains(p.Trait<Passenger>().info.CargoType))
|
||||
: cargo.Passengers;
|
||||
|
||||
return r.Concat(visiblePassengers.SelectMany(a => a.Render())
|
||||
.Select(a => a.WithPos(a.Pos - new float2(0, Info.RelativeAltitude))
|
||||
.WithZOffset(a.ZOffset + Info.RelativeAltitude)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ namespace OpenRA.Mods.Cnc
|
||||
[ActorReference] public readonly string ViceroidActor = "vice";
|
||||
public readonly int Probability = 10;
|
||||
public readonly string Owner = "Creeps";
|
||||
public readonly int InfDeath = 5;
|
||||
public readonly int InfDeath = 6;
|
||||
|
||||
public object Create(ActorInitializer init) { return new SpawnViceroid(this); }
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
public void UpdateMouseover()
|
||||
{
|
||||
TooltipType = WorldTooltipType.None;
|
||||
var cell = Game.viewport.ViewToWorld(Viewport.LastMousePos).ToInt2();
|
||||
var cell = Game.viewport.ViewToWorld(Viewport.LastMousePos);
|
||||
if (!world.Map.IsInMap(cell))
|
||||
return;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using OpenRA.Mods.RA.Orders;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
@@ -114,6 +115,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
BindOrderButton<SellOrderGenerator>(world, sidebarRoot, "SELL_BUTTON", "sell");
|
||||
BindOrderButton<RepairOrderGenerator>(world, sidebarRoot, "REPAIR_BUTTON", "repair");
|
||||
|
||||
var powerManager = world.LocalPlayer.PlayerActor.Trait<PowerManager>();
|
||||
var playerResources = world.LocalPlayer.PlayerActor.Trait<PlayerResources>();
|
||||
sidebarRoot.Get<LabelWidget>("CASH").GetText = () =>
|
||||
"${0}".F(playerResources.DisplayCash + playerResources.DisplayOre);
|
||||
@@ -152,6 +154,30 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
InitObserverWidgets(world, playerRoot);
|
||||
});
|
||||
};
|
||||
|
||||
var siloBar = playerWidgets.Get<ResourceBarWidget>("SILOBAR");
|
||||
siloBar.GetProvided = () => playerResources.OreCapacity;
|
||||
siloBar.GetUsed = () => playerResources.Ore;
|
||||
siloBar.TooltipFormat = "Silo Usage: {0}/{1}";
|
||||
siloBar.RightIndicator = true;
|
||||
siloBar.GetBarColor = () =>
|
||||
{
|
||||
if (playerResources.Ore == playerResources.OreCapacity) return Color.Red;
|
||||
if (playerResources.Ore >= 0.8 * playerResources.OreCapacity) return Color.Orange;
|
||||
return Color.LimeGreen;
|
||||
};
|
||||
|
||||
var powerBar = playerWidgets.Get<ResourceBarWidget>("POWERBAR");
|
||||
powerBar.GetProvided = () => powerManager.PowerProvided;
|
||||
powerBar.GetUsed = () => powerManager.PowerDrained;
|
||||
powerBar.TooltipFormat = "Power Usage: {0}/{1}";
|
||||
powerBar.RightIndicator = false;
|
||||
powerBar.GetBarColor = () =>
|
||||
{
|
||||
if (powerManager.PowerState == PowerState.Critical) return Color.Red;
|
||||
if (powerManager.PowerState == PowerState.Low) return Color.Orange;
|
||||
return Color.LimeGreen;
|
||||
};
|
||||
}
|
||||
|
||||
static void BindOrderButton<T>(World world, Widget parent, string button, string icon)
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
// TODO: Create a mechanism to do things like this cleaner. Also needed for scripted missions
|
||||
Action onQuit = () =>
|
||||
{
|
||||
Sound.Play("batlcon1.aud");
|
||||
Sound.PlayNotification(null, "Speech", "Leave", null);
|
||||
resumeDisabled = true;
|
||||
Game.RunAfterDelay(1200, () => mpe.Fade(CncMenuPaletteEffect.EffectType.Black));
|
||||
Game.RunAfterDelay(1200 + 40 * mpe.Info.FadeLength, () =>
|
||||
|
||||
@@ -86,6 +86,10 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
Game.viewport.Zoom = graphicsSettings.PixelDouble ? 2 : 1;
|
||||
};
|
||||
|
||||
var showShellmapCheckbox = generalPane.Get<CheckboxWidget>("SHOW_SHELLMAP");
|
||||
showShellmapCheckbox.IsChecked = () => gameSettings.ShowShellmap;
|
||||
showShellmapCheckbox.OnClick = () => gameSettings.ShowShellmap ^= true;
|
||||
|
||||
generalPane.Get("WINDOW_RESOLUTION").IsVisible = () => graphicsSettings.Mode == WindowMode.Windowed;
|
||||
var windowWidth = generalPane.Get<TextFieldWidget>("WINDOW_WIDTH");
|
||||
windowWidth.Text = graphicsSettings.WindowedSize.X.ToString();
|
||||
|
||||
@@ -32,8 +32,10 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
var powerLabel = widget.Get<LabelWidget>("POWER");
|
||||
var timeLabel = widget.Get<LabelWidget>("TIME");
|
||||
var costLabel = widget.Get<LabelWidget>("COST");
|
||||
var descLabel = widget.Get<LabelWidget>("DESC");
|
||||
|
||||
var font = Game.Renderer.Fonts[nameLabel.Font];
|
||||
var descFont = Game.Renderer.Fonts[descLabel.Font];
|
||||
var requiresFont = Game.Renderer.Fonts[requiresLabel.Font];
|
||||
string lastActor = null;
|
||||
|
||||
@@ -70,12 +72,18 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
costLabel.GetColor = () => pr.DisplayCash + pr.DisplayOre >= cost
|
||||
? Color.White : Color.Red;
|
||||
|
||||
var leftWidth = Math.Max(font.Measure(tooltip.Name).X, requiresFont.Measure(requiresString).X);
|
||||
var descString = tooltip.Description.Replace("\\n", "\n");
|
||||
descLabel.GetText = () => descString;
|
||||
|
||||
var leftWidth = new [] {font.Measure(tooltip.Name).X, requiresFont.Measure(requiresString).X, descFont.Measure(descString).X}.Aggregate(Math.Max);
|
||||
var rightWidth = new [] {font.Measure(powerString).X, font.Measure(timeString).X, font.Measure(costString).X}.Aggregate(Math.Max);
|
||||
timeLabel.Bounds.X = powerLabel.Bounds.X = costLabel.Bounds.X = leftWidth + 2*nameLabel.Bounds.X;
|
||||
widget.Bounds.Width = leftWidth + rightWidth + 3*nameLabel.Bounds.X;
|
||||
|
||||
widget.Bounds.Height = power != 0 ? 65 : 45;
|
||||
var leftHeight = font.Measure(tooltip.Name).Y + requiresFont.Measure(requiresString).Y + descFont.Measure(descString).Y;
|
||||
var rightHeight = font.Measure(powerString).Y + font.Measure(timeString).Y + font.Measure(costString).Y;
|
||||
widget.Bounds.Height = Math.Max(leftHeight, rightHeight)*3/2 + 3*nameLabel.Bounds.Y;
|
||||
|
||||
lastActor = actor;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
#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;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.Cnc.Widgets
|
||||
{
|
||||
public class PowerBarWidget : Widget
|
||||
{
|
||||
public readonly string TooltipTemplate = "SIMPLE_TOOLTIP";
|
||||
public readonly string TooltipContainer;
|
||||
Lazy<TooltipContainerWidget> tooltipContainer;
|
||||
|
||||
float? lastProvidedFrac;
|
||||
float? lastDrainedFrac;
|
||||
readonly PowerManager pm;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public PowerBarWidget(World world)
|
||||
{
|
||||
pm = world.LocalPlayer.PlayerActor.Trait<PowerManager>();
|
||||
tooltipContainer = Lazy.New(() =>
|
||||
Ui.Root.Get<TooltipContainerWidget>(TooltipContainer));
|
||||
}
|
||||
|
||||
public override void MouseEntered()
|
||||
{
|
||||
if (TooltipContainer == null) return;
|
||||
Func<string> getText = () => "Power Usage: {0}/{1}".F(pm.PowerDrained, pm.PowerProvided);
|
||||
tooltipContainer.Value.SetTooltip(TooltipTemplate, new WidgetArgs() {{ "getText", getText }});
|
||||
}
|
||||
|
||||
public override void MouseExited()
|
||||
{
|
||||
if (TooltipContainer == null) return;
|
||||
tooltipContainer.Value.RemoveTooltip();
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
float powerScaleBy = 100;
|
||||
var maxPower = Math.Max(pm.PowerProvided, pm.PowerDrained);
|
||||
while (maxPower >= powerScaleBy) powerScaleBy *= 2;
|
||||
|
||||
// Current power supply
|
||||
var providedFrac = pm.PowerProvided / powerScaleBy;
|
||||
lastProvidedFrac = providedFrac = float2.Lerp(lastProvidedFrac.GetValueOrDefault(providedFrac), providedFrac, .3f);
|
||||
|
||||
var color = Color.LimeGreen;
|
||||
if (pm.PowerState == PowerState.Low)
|
||||
color = Color.Orange;
|
||||
if (pm.PowerState == PowerState.Critical)
|
||||
color = Color.Red;
|
||||
|
||||
var b = RenderBounds;
|
||||
var rect = new RectangleF(b.X,
|
||||
b.Y + (1-providedFrac)*b.Height,
|
||||
(float)b.Width,
|
||||
providedFrac*b.Height);
|
||||
Game.Renderer.LineRenderer.FillRect(rect, color);
|
||||
|
||||
var indicator = ChromeProvider.GetImage("sidebar-bits", "left-indicator");
|
||||
|
||||
var drainedFrac = pm.PowerDrained / powerScaleBy;
|
||||
lastDrainedFrac = drainedFrac = float2.Lerp(lastDrainedFrac.GetValueOrDefault(drainedFrac), drainedFrac, .3f);
|
||||
|
||||
float2 pos = new float2(b.X + b.Width - indicator.size.X,
|
||||
b.Y + (1-drainedFrac)*b.Height - indicator.size.Y / 2);
|
||||
|
||||
Game.Renderer.RgbaSpriteRenderer.DrawSprite(indicator, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,7 +146,7 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
else if (CurrentQueue.BuildableItems().Any(a => a.Name == clicked.Name))
|
||||
{
|
||||
Sound.Play(TabClick);
|
||||
Sound.Play(CurrentQueue.Info.QueuedAudio);
|
||||
Sound.PlayNotification(world.LocalPlayer, "Speech", CurrentQueue.Info.QueuedAudio, world.LocalPlayer.Country.Race);
|
||||
world.IssueOrder(Order.StartProduction(CurrentQueue.self, clicked.Name,
|
||||
Game.GetModifierKeys().HasModifier(Modifiers.Shift) ? 5 : 1));
|
||||
}
|
||||
@@ -164,13 +164,13 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
// instant cancel of things we havent started yet and things that are finished
|
||||
if (first.Paused || first.Done || first.TotalCost == first.RemainingCost)
|
||||
{
|
||||
Sound.Play(CurrentQueue.Info.CancelledAudio);
|
||||
Sound.PlayNotification(world.LocalPlayer, "Speech", CurrentQueue.Info.CancelledAudio, world.LocalPlayer.Country.Race);
|
||||
world.IssueOrder(Order.CancelProduction(CurrentQueue.self, clicked.Name,
|
||||
Game.GetModifierKeys().HasModifier(Modifiers.Shift) ? 5 : 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
Sound.Play(CurrentQueue.Info.OnHoldAudio);
|
||||
Sound.PlayNotification(world.LocalPlayer, "Speech", CurrentQueue.Info.OnHoldAudio, world.LocalPlayer.Country.Race);
|
||||
world.IssueOrder(Order.PauseProduction(CurrentQueue.self, clicked.Name, true));
|
||||
}
|
||||
}
|
||||
@@ -213,7 +213,6 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
if (CurrentQueue == null)
|
||||
return;
|
||||
|
||||
var isBuildingSomething = CurrentQueue.CurrentItem() != null;
|
||||
var buildableItems = CurrentQueue.BuildableItems().OrderBy(a => a.Traits.Get<BuildableInfo>().BuildPaletteOrder);
|
||||
|
||||
// Background
|
||||
@@ -235,7 +234,7 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
clock.Tick();
|
||||
WidgetUtils.DrawSHP(clock.Image, icon.Pos, worldRenderer);
|
||||
}
|
||||
else if (isBuildingSomething || !buildableItems.Any(a => a.Name == icon.Name))
|
||||
else if (!buildableItems.Any(a => a.Name == icon.Name))
|
||||
WidgetUtils.DrawSHP(cantBuild.Image, icon.Pos, worldRenderer);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,8 +61,6 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
class ProductionTabsWidget : Widget
|
||||
{
|
||||
public readonly string PaletteWidget = null;
|
||||
public readonly string ClickSound = null;
|
||||
public readonly string DisabledClickSound = null;
|
||||
public readonly float ScrollVelocity = 4f;
|
||||
public readonly int TabWidth = 30;
|
||||
public readonly int ArrowWidth = 20;
|
||||
@@ -140,8 +138,8 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
var rightHover = Ui.MouseOverWidget == this && rightButtonRect.Contains(Viewport.LastMousePos);
|
||||
|
||||
WidgetUtils.DrawPanel("panel-black", rb);
|
||||
ButtonWidget.DrawBackground("button", leftButtonRect, leftDisabled, leftPressed, leftHover);
|
||||
ButtonWidget.DrawBackground("button", rightButtonRect, rightDisabled, rightPressed, rightHover);
|
||||
ButtonWidget.DrawBackground("button", leftButtonRect, leftDisabled, leftPressed, leftHover, false);
|
||||
ButtonWidget.DrawBackground("button", rightButtonRect, rightDisabled, rightPressed, rightHover, false);
|
||||
|
||||
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("scrollbar", leftPressed || leftDisabled ? "left_pressed" : "left_arrow"),
|
||||
new float2(leftButtonRect.Left + 2, leftButtonRect.Top + 2));
|
||||
@@ -159,7 +157,7 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
var rect = new Rectangle(origin.X + ContentWidth, origin.Y, TabWidth, rb.Height);
|
||||
var hover = !leftHover && !rightHover && Ui.MouseOverWidget == this && rect.Contains(Viewport.LastMousePos);
|
||||
var baseName = tab.Queue == CurrentQueue ? "button-toggled" : "button";
|
||||
ButtonWidget.DrawBackground(baseName, rect, false, false, hover);
|
||||
ButtonWidget.DrawBackground(baseName, rect, false, false, hover, false);
|
||||
ContentWidth += TabWidth - 1;
|
||||
|
||||
int2 textSize = font.Measure(tab.Name);
|
||||
@@ -248,9 +246,9 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
if (leftPressed || rightPressed)
|
||||
{
|
||||
if ((leftPressed && !leftDisabled) || (rightPressed && !rightDisabled))
|
||||
Sound.Play(ClickSound);
|
||||
Sound.PlayNotification(null, "Sounds", "ClickSound", null);
|
||||
else
|
||||
Sound.Play(DisabledClickSound);
|
||||
Sound.PlayNotification(null, "Sounds", "ClickDisabledSound", null);
|
||||
}
|
||||
|
||||
// Check production tabs
|
||||
@@ -258,7 +256,7 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
if (offsetloc.X > 0 && offsetloc.X < ContentWidth)
|
||||
{
|
||||
CurrentQueue = Groups[queueGroup].Tabs[offsetloc.X/(TabWidth - 1)].Queue;
|
||||
Sound.Play(ClickSound);
|
||||
Sound.PlayNotification(null, "Sounds", "ClickSound", null);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -270,7 +268,7 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
if (e.Event != KeyInputEvent.Down) return false;
|
||||
if (e.KeyName == "tab")
|
||||
{
|
||||
Sound.Play(ClickSound);
|
||||
Sound.PlayNotification(null, "Sounds", "ClickSound", null);
|
||||
SelectNextTab(e.Modifiers.HasModifier(Modifiers.Shift));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -17,22 +17,25 @@ using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.Cnc.Widgets
|
||||
{
|
||||
public class SiloBarWidget : Widget
|
||||
public class ResourceBarWidget : Widget
|
||||
{
|
||||
public readonly string TooltipTemplate = "SIMPLE_TOOLTIP";
|
||||
public readonly string TooltipContainer;
|
||||
Lazy<TooltipContainerWidget> tooltipContainer;
|
||||
|
||||
public float LowStorageThreshold = 0.8f;
|
||||
float? lastCapacityFrac;
|
||||
float? lastStoredFrac;
|
||||
EWMA providedLerp = new EWMA(0.3f);
|
||||
EWMA usedLerp = new EWMA(0.3f);
|
||||
|
||||
readonly PlayerResources pr;
|
||||
public Func<float> GetProvided = () => 0;
|
||||
public Func<float> GetUsed = () => 0;
|
||||
public string TooltipFormat = "";
|
||||
public bool RightIndicator = false;
|
||||
public Func<Color> GetBarColor = () => Color.White;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public SiloBarWidget(World world)
|
||||
public ResourceBarWidget(World world)
|
||||
{
|
||||
pr = world.LocalPlayer.PlayerActor.Trait<PlayerResources>();
|
||||
tooltipContainer = Lazy.New(() =>
|
||||
Ui.Root.Get<TooltipContainerWidget>(TooltipContainer));
|
||||
}
|
||||
@@ -40,7 +43,7 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
public override void MouseEntered()
|
||||
{
|
||||
if (TooltipContainer == null) return;
|
||||
Func<string> getText = () => "Silo Usage: {0}/{1}".F(pr.Ore, pr.OreCapacity);
|
||||
Func<string> getText = () => TooltipFormat.F(GetUsed(), GetProvided());
|
||||
tooltipContainer.Value.SetTooltip(TooltipTemplate, new WidgetArgs() {{ "getText", getText }});
|
||||
}
|
||||
|
||||
@@ -52,36 +55,30 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
float scaleBy = 100;
|
||||
var max = Math.Max(pr.OreCapacity, pr.Ore);
|
||||
var scaleBy = 100.0f;
|
||||
var provided = GetProvided();
|
||||
var used = GetUsed();
|
||||
var max = Math.Max(provided, used);
|
||||
while (max >= scaleBy) scaleBy *= 2;
|
||||
|
||||
// Current capacity
|
||||
var capacityFrac = pr.OreCapacity / scaleBy;
|
||||
lastCapacityFrac = capacityFrac = float2.Lerp(lastCapacityFrac.GetValueOrDefault(capacityFrac), capacityFrac, .3f);
|
||||
var providedFrac = providedLerp.Update(provided/scaleBy);
|
||||
var usedFrac = usedLerp.Update(used/scaleBy);
|
||||
|
||||
var color = GetBarColor();
|
||||
|
||||
var b = RenderBounds;
|
||||
var rect = new RectangleF(b.X, float2.Lerp( b.Bottom, b.Top, capacityFrac ),
|
||||
(float)b.Width, capacityFrac*b.Height);
|
||||
var rect = new RectangleF(b.X, float2.Lerp( b.Bottom, b.Top, providedFrac ),
|
||||
b.Width, providedFrac*b.Height);
|
||||
Game.Renderer.LineRenderer.FillRect(rect, color);
|
||||
|
||||
var indicator = ChromeProvider.GetImage("sidebar-bits", "right-indicator");
|
||||
var indicator = ChromeProvider.GetImage("sidebar-bits",
|
||||
RightIndicator ? "right-indicator" : "left-indicator");
|
||||
|
||||
var storedFrac = pr.Ore / scaleBy;
|
||||
lastStoredFrac = storedFrac = float2.Lerp(lastStoredFrac.GetValueOrDefault(storedFrac), storedFrac, .3f);
|
||||
var indicatorX = RightIndicator ? (b.Right - indicator.size.X) : b.Left;
|
||||
|
||||
float2 pos = new float2(b.X, float2.Lerp( b.Bottom, b.Top, storedFrac ) - indicator.size.Y / 2);
|
||||
var pos = new float2(indicatorX, float2.Lerp( b.Bottom, b.Top, usedFrac ) - indicator.size.Y / 2);
|
||||
|
||||
Game.Renderer.RgbaSpriteRenderer.DrawSprite(indicator, pos);
|
||||
}
|
||||
|
||||
Color GetBarColor()
|
||||
{
|
||||
if (pr.Ore == pr.OreCapacity) return Color.Red;
|
||||
if (pr.Ore >= LowStorageThreshold * pr.OreCapacity) return Color.Orange;
|
||||
return Color.LimeGreen;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user