Compare commits
549 Commits
playtest-2
...
playtest-2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f3def3f86 | ||
|
|
5426e2c831 | ||
|
|
38b2b6cb4e | ||
|
|
94415d9cfb | ||
|
|
2fb822e1c1 | ||
|
|
0978d21439 | ||
|
|
775b0409c4 | ||
|
|
1083f8cf55 | ||
|
|
4cf8f9a434 | ||
|
|
6152fa2890 | ||
|
|
c0a702a386 | ||
|
|
336076c248 | ||
|
|
c21b60f555 | ||
|
|
efd0d81dca | ||
|
|
63467cd000 | ||
|
|
46f4685eec | ||
|
|
af3a5cf939 | ||
|
|
fb0ce8c06a | ||
|
|
8358597fd2 | ||
|
|
b31f830cb1 | ||
|
|
561d47a6a1 | ||
|
|
b8b0111aa2 | ||
|
|
f204f25474 | ||
|
|
47075e1cd0 | ||
|
|
793dfa5748 | ||
|
|
0b493bcb09 | ||
|
|
dd476bbf5c | ||
|
|
fc5350c9f8 | ||
|
|
b2c867bf2b | ||
|
|
3d8d116106 | ||
|
|
4b2f08f21f | ||
|
|
233088077b | ||
|
|
a59621910e | ||
|
|
05b6b59dad | ||
|
|
2bc7570674 | ||
|
|
0085ac130b | ||
|
|
7e1ee0e2e5 | ||
|
|
6bd3de8ec8 | ||
|
|
fab7f2c4b6 | ||
|
|
ea799e5735 | ||
|
|
3ab4112631 | ||
|
|
817e6f1ec1 | ||
|
|
81c8f0360f | ||
|
|
bec29d81c5 | ||
|
|
3a11aeb434 | ||
|
|
dddec1ec61 | ||
|
|
82426e0e45 | ||
|
|
3033eb8be0 | ||
|
|
e9665cf9f3 | ||
|
|
9bc743068a | ||
|
|
72a9954491 | ||
|
|
f2fe30a7bb | ||
|
|
ce39c79477 | ||
|
|
6fc4807a10 | ||
|
|
f890ea010e | ||
|
|
5b360a7fe2 | ||
|
|
55efd53ef7 | ||
|
|
fa5cf96f40 | ||
|
|
e33c783fc1 | ||
|
|
1438030e82 | ||
|
|
09e4d64f99 | ||
|
|
b5bd6191c2 | ||
|
|
e57de0ebce | ||
|
|
3bc9e7d2e4 | ||
|
|
6b636b166c | ||
|
|
026a86ba75 | ||
|
|
5a4bd14835 | ||
|
|
43159a0e05 | ||
|
|
3380817865 | ||
|
|
d6fcaafd78 | ||
|
|
0703f3f164 | ||
|
|
a083554218 | ||
|
|
c34c62ad42 | ||
|
|
fc3c091a48 | ||
|
|
000a5eaa56 | ||
|
|
48d713aafd | ||
|
|
885eec7444 | ||
|
|
95871e6cc1 | ||
|
|
f0ba0ce2e8 | ||
|
|
a166815348 | ||
|
|
35a149ea87 | ||
|
|
0287993c31 | ||
|
|
2d10f6b739 | ||
|
|
db7887687b | ||
|
|
f593807617 | ||
|
|
6da02b7b92 | ||
|
|
86c99c47c9 | ||
|
|
3b3e39b375 | ||
|
|
4b3feed324 | ||
|
|
57dd8bb91e | ||
|
|
34b1f90200 | ||
|
|
128e2c9e1f | ||
|
|
d0669823a2 | ||
|
|
1f99b1ec8e | ||
|
|
2c5eeb551e | ||
|
|
54906702bd | ||
|
|
ec56311a3d | ||
|
|
cdd09ea24f | ||
|
|
1ecdbc1d90 | ||
|
|
b1a5195c51 | ||
|
|
03f03ff501 | ||
|
|
3c5967a623 | ||
|
|
9013e8376c | ||
|
|
9b5b054297 | ||
|
|
4e161f0c91 | ||
|
|
6bbd54ab93 | ||
|
|
87190762d1 | ||
|
|
f4da36065f | ||
|
|
e71135b511 | ||
|
|
dfc880807e | ||
|
|
d12853ddf7 | ||
|
|
f1019ab332 | ||
|
|
96d1f8d83b | ||
|
|
c4fc0e57b3 | ||
|
|
6403c5e6af | ||
|
|
b3fbafad59 | ||
|
|
7594c4eab2 | ||
|
|
4163f1d6b0 | ||
|
|
ea716200a7 | ||
|
|
2bd9b7a640 | ||
|
|
4f670d516d | ||
|
|
f5835244c7 | ||
|
|
b00b1c36bc | ||
|
|
b2ddc6cfd8 | ||
|
|
0d6dbdc58b | ||
|
|
78baf76ae1 | ||
|
|
43c43e25c4 | ||
|
|
32daf025ab | ||
|
|
750bdb7bba | ||
|
|
8a796416a4 | ||
|
|
691e6cf9e8 | ||
|
|
de208e7a2f | ||
|
|
63a72c5d28 | ||
|
|
b6b4b89008 | ||
|
|
0b65735d86 | ||
|
|
44215ae6f1 | ||
|
|
fba5b80980 | ||
|
|
3f6af59612 | ||
|
|
693a622322 | ||
|
|
60e9d3f660 | ||
|
|
1d40858f70 | ||
|
|
5188529ff6 | ||
|
|
2079db79f7 | ||
|
|
d73eec068f | ||
|
|
8a32e5761c | ||
|
|
12e1a531fe | ||
|
|
32830da3c2 | ||
|
|
9f47e75492 | ||
|
|
e975681c16 | ||
|
|
a968d296bb | ||
|
|
031240ffc1 | ||
|
|
dfc4b07b1a | ||
|
|
63241dbf69 | ||
|
|
5b7523b9e0 | ||
|
|
4b228a71ef | ||
|
|
1635ace182 | ||
|
|
b4e3ce5de6 | ||
|
|
50ceb7c4dd | ||
|
|
4395a04d57 | ||
|
|
c5313375f0 | ||
|
|
2503ddfde4 | ||
|
|
b356cca528 | ||
|
|
d52394bb47 | ||
|
|
1da2d89ced | ||
|
|
a88a7d9834 | ||
|
|
9507fde91d | ||
|
|
742a27158a | ||
|
|
5ed383e3e2 | ||
|
|
1679837e46 | ||
|
|
eb3685fe67 | ||
|
|
50f8465d1e | ||
|
|
5502864a1f | ||
|
|
d572e59d2e | ||
|
|
e313bbfb31 | ||
|
|
a51c5fd9ca | ||
|
|
0c104cfc3a | ||
|
|
3a77082c66 | ||
|
|
975e4db452 | ||
|
|
d92f184bc9 | ||
|
|
2eea5cc3b2 | ||
|
|
0e8cb14099 | ||
|
|
1ec3b2ffe2 | ||
|
|
c836d69385 | ||
|
|
11c45e4388 | ||
|
|
3b9fac9c84 | ||
|
|
185558985e | ||
|
|
e3d25f6fed | ||
|
|
200071e713 | ||
|
|
bdb7bb97cd | ||
|
|
82809f27f7 | ||
|
|
c8e84b3a11 | ||
|
|
9581f07242 | ||
|
|
411aedafa0 | ||
|
|
f7f307c3bf | ||
|
|
c10df031bd | ||
|
|
a56228aba1 | ||
|
|
1b09544314 | ||
|
|
2dc18594a2 | ||
|
|
baa7a58a10 | ||
|
|
bb5212d2bb | ||
|
|
38db7d1e50 | ||
|
|
3371085da0 | ||
|
|
5c688370ed | ||
|
|
ab01722d96 | ||
|
|
ae5cb9864a | ||
|
|
43e5838555 | ||
|
|
cf8b02de26 | ||
|
|
d3ede583c2 | ||
|
|
cda871d2eb | ||
|
|
2ea3b77b7a | ||
|
|
3ab04e4c30 | ||
|
|
3b2190d720 | ||
|
|
b3691dcce9 | ||
|
|
722bc00c9b | ||
|
|
fe07da8634 | ||
|
|
54feab66e0 | ||
|
|
fda897c69e | ||
|
|
31d3616b8d | ||
|
|
eb6bab36a0 | ||
|
|
81f9798307 | ||
|
|
d1dafd5782 | ||
|
|
799a2ea541 | ||
|
|
4b2e45bbae | ||
|
|
32721ac8cb | ||
|
|
6871d2ed37 | ||
|
|
bdfa6f6ecc | ||
|
|
c59fbd5f9d | ||
|
|
54916cc548 | ||
|
|
3ff3ed39fb | ||
|
|
a8dbedd486 | ||
|
|
988a68dae5 | ||
|
|
9a9c5911a6 | ||
|
|
bfb07e9948 | ||
|
|
dda4e2c33a | ||
|
|
05e143662d | ||
|
|
9e2f15bde4 | ||
|
|
8f90423793 | ||
|
|
eecc002236 | ||
|
|
4167d3291a | ||
|
|
3be6229cf2 | ||
|
|
5f693945f0 | ||
|
|
82f478716c | ||
|
|
6544069aa2 | ||
|
|
8486a4fbae | ||
|
|
edd1138556 | ||
|
|
14ed3ae816 | ||
|
|
d5db9e88d4 | ||
|
|
f0a4fa7712 | ||
|
|
1f92768193 | ||
|
|
ccfcf0a1ee | ||
|
|
51626bf0db | ||
|
|
be6da2452a | ||
|
|
ec423db4e5 | ||
|
|
4c7f215559 | ||
|
|
0f9da06309 | ||
|
|
4ce6cabc46 | ||
|
|
b2b13b98b7 | ||
|
|
4c729ca5ed | ||
|
|
a78f8865b8 | ||
|
|
d5b37d4343 | ||
|
|
e424883857 | ||
|
|
b6e8c9c9ea | ||
|
|
ed9bb72dbe | ||
|
|
9753808936 | ||
|
|
82fdbc4bc6 | ||
|
|
d7f3b81e4c | ||
|
|
36f349ecba | ||
|
|
30a374b9e9 | ||
|
|
2a0b9a8596 | ||
|
|
9a9324946f | ||
|
|
babf1556e3 | ||
|
|
bb1c87b084 | ||
|
|
1c584fb158 | ||
|
|
83e1855919 | ||
|
|
4bc04769ec | ||
|
|
178358c29a | ||
|
|
42b16f74a1 | ||
|
|
9b493ad9e7 | ||
|
|
d7d5baae0e | ||
|
|
a8e434b74d | ||
|
|
07d5ba8405 | ||
|
|
a5141f9908 | ||
|
|
d15fb82b08 | ||
|
|
947b27a227 | ||
|
|
b49110bf5c | ||
|
|
8578958e40 | ||
|
|
65e78ca8b0 | ||
|
|
608bf9ada1 | ||
|
|
4373831317 | ||
|
|
aa78d63d72 | ||
|
|
400d94caba | ||
|
|
1660c4fe7c | ||
|
|
e643f12371 | ||
|
|
339c0bc520 | ||
|
|
e15c240a8f | ||
|
|
7bd66c2560 | ||
|
|
1f8fd404e5 | ||
|
|
93e951eb75 | ||
|
|
c52cd77c4c | ||
|
|
0da911c9f8 | ||
|
|
395aa0fc10 | ||
|
|
e10920d4ea | ||
|
|
914afa2dee | ||
|
|
ca1e0b4c48 | ||
|
|
70cf48dcaf | ||
|
|
68130c85f3 | ||
|
|
d0aea18b3e | ||
|
|
ac301b22e2 | ||
|
|
b56125fa39 | ||
|
|
b362ddac15 | ||
|
|
5f2aa810b1 | ||
|
|
189a6c337e | ||
|
|
9c552839ea | ||
|
|
79aa7901cf | ||
|
|
ad2dbffe75 | ||
|
|
88959b2e6c | ||
|
|
f256742a0d | ||
|
|
22e2d3d0f4 | ||
|
|
3eed137117 | ||
|
|
e28be10dd4 | ||
|
|
90361cb631 | ||
|
|
c3b959846c | ||
|
|
39884e16fa | ||
|
|
f107f8a87b | ||
|
|
8246b2f35f | ||
|
|
f13d12acec | ||
|
|
4090be72d4 | ||
|
|
90d30005f6 | ||
|
|
7c968a8f88 | ||
|
|
e4ab86e6f9 | ||
|
|
f41fb32d60 | ||
|
|
5249a17d48 | ||
|
|
99256bcad0 | ||
|
|
f402c37b14 | ||
|
|
494ab2db4d | ||
|
|
5d4160bc82 | ||
|
|
b9194e4305 | ||
|
|
8ab1fbe83a | ||
|
|
96a088f998 | ||
|
|
7d4399d7cc | ||
|
|
107c37f33d | ||
|
|
88949024e6 | ||
|
|
aad0b3d2d8 | ||
|
|
4e0e53c714 | ||
|
|
87a2817234 | ||
|
|
f3e796e972 | ||
|
|
7d5a843684 | ||
|
|
f914929eb7 | ||
|
|
8f7b776556 | ||
|
|
aeaa58a01b | ||
|
|
4dacd3be26 | ||
|
|
05929bdfe9 | ||
|
|
0690041347 | ||
|
|
842fd8b4e5 | ||
|
|
7a89e3d67a | ||
|
|
5ecc6224b0 | ||
|
|
f5c592291c | ||
|
|
7f229a3fde | ||
|
|
c859fb1186 | ||
|
|
6dceb30632 | ||
|
|
f3dc31be40 | ||
|
|
a2f5ffd59e | ||
|
|
a2c66a32b0 | ||
|
|
72139675ac | ||
|
|
2b57f04dc0 | ||
|
|
15e09fa83b | ||
|
|
55ee1d41f3 | ||
|
|
2e7908366a | ||
|
|
6ab4fda9a6 | ||
|
|
a5ba41cae8 | ||
|
|
5e9cdad044 | ||
|
|
c14de26c07 | ||
|
|
e5f506c81d | ||
|
|
4160f08c6c | ||
|
|
4ad0d1682e | ||
|
|
8fb4fc9a14 | ||
|
|
5a0187e1db | ||
|
|
7f5141c338 | ||
|
|
354cabf8d1 | ||
|
|
fd734c8553 | ||
|
|
9238de6a47 | ||
|
|
b2c5f488a7 | ||
|
|
c634867cdd | ||
|
|
d7f2273788 | ||
|
|
5c1a982fdd | ||
|
|
0300a67da8 | ||
|
|
862dfb3275 | ||
|
|
03121ed826 | ||
|
|
0cdff00cb6 | ||
|
|
787facec65 | ||
|
|
44d63b9103 | ||
|
|
49571fc78a | ||
|
|
60569bc97c | ||
|
|
b37510c30e | ||
|
|
343b7bf3e1 | ||
|
|
7a2423a742 | ||
|
|
57dfc739c6 | ||
|
|
f3d4b6541c | ||
|
|
d1c20d6c72 | ||
|
|
e4beb8236e | ||
|
|
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 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -13,9 +13,6 @@ mods/*/*.dll
|
||||
# ReSharper crap
|
||||
_ReSharper.*/
|
||||
|
||||
# Red Alert binary files
|
||||
mods/*/packages/*.[mM][iI][xX]
|
||||
|
||||
#binary stuff
|
||||
/*.dll
|
||||
*.pdb
|
||||
|
||||
5
AUTHORS
5
AUTHORS
@@ -15,12 +15,16 @@ Also thanks to:
|
||||
* Barnaby Smith (mvi)
|
||||
* Bellator
|
||||
* Christer Ulfsparre (Holloweye)
|
||||
* Cody Brittain (Generalcamo)
|
||||
* Daniel Derejvanik (Harisson)
|
||||
* Erasmus Schroder (rasco)
|
||||
* Igor Popov (ihptru)
|
||||
* James Dunne (jsd)
|
||||
* Jeff Harris (jeff_1amstudios)
|
||||
* Jes (-Jes-)
|
||||
* Joakim Lindberg (booom3)
|
||||
* Kenny Hoxworth (hoxworth)
|
||||
* Kyrre Soerensen (zypres)
|
||||
* Lawrence Wang
|
||||
* Mark Olson (markolson)
|
||||
* Matthew Gatland (mgatland)
|
||||
@@ -33,6 +37,7 @@ Also thanks to:
|
||||
* Raymond Martineau (mart0258)
|
||||
* Riderr3
|
||||
* Tim Mylemans (gecko)
|
||||
* Tirili
|
||||
|
||||
Past developers included:
|
||||
* Paul Chote (pchote)
|
||||
|
||||
19
CONTRIBUTING.md
Normal file
19
CONTRIBUTING.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# OpenRA Contributing Guidelines
|
||||
|
||||
## Bug reports
|
||||
|
||||
* Have you read the [FAQ](https://github.com/OpenRA/OpenRA/wiki/FAQ)?
|
||||
* Add the appropriate log files on crashes.
|
||||
* Please be specific on how to reproduce the problem.
|
||||
|
||||
## Patches
|
||||
|
||||
* [Coding standard](https://github.com/OpenRA/OpenRA/wiki/Coding-Standard)
|
||||
* [Branches and Releases](https://github.com/OpenRA/OpenRA/wiki/Branches-and-Releases)
|
||||
* [Licensing](http://www.gnu.org/licenses/quick-guide-gplv3.html)
|
||||
|
||||
Please `git rebase` to the latest revision of the bleed branch.
|
||||
|
||||
Don't forget to add youself to [AUTHORS](https://github.com/OpenRA/OpenRA/blob/bleed/AUTHORS).
|
||||
|
||||
While your pull-request is in review it will be helpful if you join [IRC](irc://chat.freenode.net/openra) to discuss the changes.
|
||||
2
Makefile
2
Makefile
@@ -1,5 +1,5 @@
|
||||
CSC = gmcs
|
||||
CSFLAGS = -nologo -warn:4 -debug:+ -debug:full -optimize- -codepage:utf8 -unsafe
|
||||
CSFLAGS = -nologo -warn:4 -debug:full -optimize- -codepage:utf8 -unsafe
|
||||
DEFINE = DEBUG;TRACE
|
||||
COMMON_LIBS = System.dll System.Core.dll System.Drawing.dll System.Xml.dll thirdparty/ICSharpCode.SharpZipLib.dll
|
||||
PHONY = core tools package all mods clean distclean
|
||||
|
||||
@@ -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
|
||||
@@ -42,7 +42,7 @@ namespace OpenRA.Editor
|
||||
tilePalette.ResumeLayout();
|
||||
actorPalette.ResumeLayout();
|
||||
resourcePalette.ResumeLayout();
|
||||
surface1.Bind(null, null, null);
|
||||
surface1.Bind(null, null, null, null);
|
||||
pmMiniMap.Image = null;
|
||||
currentMod = toolStripComboBox1.SelectedItem as string;
|
||||
|
||||
@@ -141,12 +141,17 @@ namespace OpenRA.Editor
|
||||
int[] ShadowIndex = { 3, 4 };
|
||||
var palette = new Palette(FileSystem.Open(tileset.Palette), ShadowIndex);
|
||||
|
||||
surface1.Bind(map, tileset, palette);
|
||||
// required for desert terrain in RA
|
||||
var playerPalette = tileset.PlayerPalette ?? tileset.Palette;
|
||||
var PlayerPalette = new Palette(FileSystem.Open(playerPalette), ShadowIndex);
|
||||
|
||||
surface1.Bind(map, tileset, palette, PlayerPalette);
|
||||
// construct the palette of tiles
|
||||
var palettes = new[] { tilePalette, actorPalette, resourcePalette };
|
||||
foreach (var p in palettes) { p.Visible = false; p.SuspendLayout(); }
|
||||
|
||||
foreach (var tc in tileset.Templates.GroupBy(t => t.Value.Category))
|
||||
string[] templateOrder = tileset.EditorTemplateOrder ?? new string[]{};
|
||||
foreach (var tc in tileset.Templates.GroupBy(t => t.Value.Category).OrderBy(t => templateOrder.ToList().IndexOf(t.Key)))
|
||||
{
|
||||
var category = tc.Key ?? "(Uncategorized)";
|
||||
var categoryHeader = new Label
|
||||
@@ -211,7 +216,13 @@ namespace OpenRA.Editor
|
||||
if (etf != null && etf.RequireTilesets != null
|
||||
&& !etf.RequireTilesets.Contains(tileset.Id)) continue;
|
||||
|
||||
var template = RenderUtils.RenderActor(info, tileset, palette);
|
||||
var TemplatePalette = PlayerPalette;
|
||||
var rsi = info.Traits.GetOrDefault<RenderSimpleInfo>();
|
||||
// exception for desert buildings
|
||||
if (rsi != null && rsi.Palette != null && rsi.Palette.Contains("terrain"))
|
||||
TemplatePalette = palette;
|
||||
|
||||
var template = RenderUtils.RenderActor(info, tileset, TemplatePalette);
|
||||
var ibox = new PictureBox
|
||||
{
|
||||
Image = template.Bitmap,
|
||||
@@ -242,7 +253,7 @@ namespace OpenRA.Editor
|
||||
{
|
||||
try
|
||||
{
|
||||
var template = RenderUtils.RenderResourceType(a, tileset.Extensions, palette);
|
||||
var template = RenderUtils.RenderResourceType(a, tileset.Extensions, PlayerPalette);
|
||||
var ibox = new PictureBox
|
||||
{
|
||||
Image = template.Bitmap,
|
||||
@@ -317,7 +328,7 @@ namespace OpenRA.Editor
|
||||
if ((int)rd.width.Value != surface1.Map.MapSize.X || (int)rd.height.Value != surface1.Map.MapSize.Y)
|
||||
{
|
||||
surface1.Map.Resize((int)rd.width.Value, (int)rd.height.Value);
|
||||
surface1.Bind(surface1.Map, surface1.TileSet, surface1.Palette); // rebind it to invalidate all caches
|
||||
surface1.Bind(surface1.Map, surface1.TileSet, surface1.Palette, surface1.PlayerPalette); // rebind it to invalidate all caches
|
||||
}
|
||||
|
||||
surface1.Invalidate();
|
||||
@@ -386,6 +397,7 @@ namespace OpenRA.Editor
|
||||
map.ResizeCordon((int)nmd.cordonLeft.Value, (int)nmd.cordonTop.Value,
|
||||
(int)nmd.cordonRight.Value, (int)nmd.cordonBottom.Value);
|
||||
|
||||
map.Players.Clear();
|
||||
map.MakeDefaultPlayers();
|
||||
|
||||
NewMap(map);
|
||||
@@ -515,6 +527,7 @@ namespace OpenRA.Editor
|
||||
void SetupDefaultPlayers(object sender, EventArgs e)
|
||||
{
|
||||
dirty = true;
|
||||
surface1.Map.Players.Clear();
|
||||
surface1.Map.MakeDefaultPlayers();
|
||||
|
||||
surface1.Chunks.Clear();
|
||||
|
||||
@@ -174,10 +174,10 @@ namespace OpenRA.Editor
|
||||
// Add waypoint actors
|
||||
foreach( var kv in wps )
|
||||
{
|
||||
var a = new ActorReference("mpspawn");
|
||||
var a = new ActorReference("waypoint");
|
||||
a.Add(new LocationInit((CPos)kv.Second));
|
||||
a.Add(new OwnerInit("Neutral"));
|
||||
Map.Actors.Value.Add("spawn" + kv.First, a);
|
||||
Map.Actors.Value.Add("waypoint" + kv.First, a);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -414,8 +414,51 @@ namespace OpenRA.Editor
|
||||
|
||||
void LoadPlayer(IniFile file, string section, bool isRA)
|
||||
{
|
||||
var c = section == "BadGuy" ? "red" :
|
||||
isRA ? "blue" : "gold";
|
||||
string c;
|
||||
string race;
|
||||
switch (section)
|
||||
{
|
||||
case "Spain":
|
||||
c = "gold";
|
||||
race = "allies";
|
||||
break;
|
||||
case "England":
|
||||
c = "green";
|
||||
race = "allies";
|
||||
break;
|
||||
case "Ukraine":
|
||||
c = "orange";
|
||||
race = "soviet";
|
||||
break;
|
||||
case "Germany":
|
||||
c = "black";
|
||||
race = "allies";
|
||||
break;
|
||||
case "France":
|
||||
c = "teal";
|
||||
race = "allies";
|
||||
break;
|
||||
case "Turkey":
|
||||
c = "salmon";
|
||||
race = "allies";
|
||||
break;
|
||||
case "Greece":
|
||||
case "GoodGuy":
|
||||
c = isRA? "blue" : "gold";
|
||||
race = isRA ? "allies" : "gdi";
|
||||
break;
|
||||
case "USSR":
|
||||
case "BadGuy":
|
||||
c = "red";
|
||||
race = isRA ? "soviet" : "nod";
|
||||
break;
|
||||
case "Special":
|
||||
case "Neutral":
|
||||
default:
|
||||
c = "neutral";
|
||||
race = isRA ? "allies" : "gdi";
|
||||
break;
|
||||
}
|
||||
|
||||
var color = namedColorMapping[c];
|
||||
|
||||
@@ -424,7 +467,7 @@ namespace OpenRA.Editor
|
||||
Name = section,
|
||||
OwnsWorld = section == "Neutral",
|
||||
NonCombatant = section == "Neutral",
|
||||
Race = isRA ? (section == "BadGuy" ? "soviet" : "allies") : (section == "BadGuy" ? "nod" : "gdi"),
|
||||
Race = race,
|
||||
ColorRamp = new ColorRamp(
|
||||
(byte)((color.First.GetHue() / 360.0f) * 255),
|
||||
(byte)(color.First.GetSaturation() * 255),
|
||||
|
||||
@@ -20,11 +20,19 @@ namespace OpenRA.Editor
|
||||
{
|
||||
public string MapFolderPath;
|
||||
|
||||
public bool DirectoryIsEmpty(string path)
|
||||
{
|
||||
return !Directory.GetFileSystemEntries(path).Any();
|
||||
}
|
||||
|
||||
public MapSelect(string currentMod)
|
||||
{
|
||||
MapFolderPath = new string[] { Environment.CurrentDirectory, "mods", currentMod, "maps" }
|
||||
MapFolderPath = new string[] { Platform.SupportDir, "maps", currentMod }
|
||||
.Aggregate(Path.Combine);
|
||||
|
||||
if (!Directory.Exists(MapFolderPath))
|
||||
Directory.CreateDirectory(MapFolderPath);
|
||||
|
||||
InitializeComponent();
|
||||
MapIconsList.Images.Add(pictureBox1.Image);
|
||||
}
|
||||
@@ -34,6 +42,9 @@ namespace OpenRA.Editor
|
||||
MapList.Items.Clear();
|
||||
txtPathOut.Text = MapFolderPath;
|
||||
|
||||
if (DirectoryIsEmpty(MapFolderPath))
|
||||
return;
|
||||
|
||||
foreach (var map in ModData.FindMapsIn(MapFolderPath))
|
||||
{
|
||||
ListViewItem map1 = new ListViewItem();
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace OpenRA.Editor
|
||||
public Map Map { get; private set; }
|
||||
public TileSet TileSet { get; private set; }
|
||||
public Palette Palette { get; private set; }
|
||||
public Palette PlayerPalette { get; private set; }
|
||||
public int2 Offset;
|
||||
|
||||
public int2 GetOffset() { return Offset; }
|
||||
@@ -55,11 +56,12 @@ namespace OpenRA.Editor
|
||||
|
||||
public Keys GetModifiers() { return ModifierKeys; }
|
||||
|
||||
public void Bind(Map m, TileSet ts, Palette p)
|
||||
public void Bind(Map m, TileSet ts, Palette p, Palette pp)
|
||||
{
|
||||
Map = m;
|
||||
TileSet = ts;
|
||||
Palette = p;
|
||||
PlayerPalette = pp;
|
||||
PlayerPalettes = null;
|
||||
Chunks.Clear();
|
||||
Tool = null;
|
||||
@@ -306,7 +308,10 @@ namespace OpenRA.Editor
|
||||
public void DrawActor(SGraphics g, CPos p, ActorTemplate t, ColorPalette cp)
|
||||
{
|
||||
var centered = t.Appearance == null || !t.Appearance.RelativeToTopLeft;
|
||||
DrawImage(g, t.Bitmap, p, centered, cp);
|
||||
var actorPalette = cp;
|
||||
if (t.Appearance != null && t.Appearance.UseTerrainPalette)
|
||||
actorPalette = Palette.AsSystemPalette();
|
||||
DrawImage(g, t.Bitmap, p, centered, actorPalette);
|
||||
}
|
||||
|
||||
float2 GetDrawPosition(CPos location, Bitmap bmp, bool centered)
|
||||
@@ -348,7 +353,7 @@ namespace OpenRA.Editor
|
||||
var pr = Map.Players[name];
|
||||
var pcpi = Rules.Info["player"].Traits.Get<PlayerColorPaletteInfo>();
|
||||
var remap = new PlayerColorRemap(pcpi.RemapIndex, pr.ColorRamp);
|
||||
return new Palette(Palette, remap).AsSystemPalette();
|
||||
return new Palette(PlayerPalette, remap).AsSystemPalette();
|
||||
}
|
||||
|
||||
Cache<string, ColorPalette> PlayerPalettes;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -78,10 +78,13 @@ namespace OpenRA.FileFormats
|
||||
public string Name;
|
||||
public string Id;
|
||||
public string Palette;
|
||||
public string PlayerPalette;
|
||||
public int TileSize = 24;
|
||||
public string[] Extensions;
|
||||
public int WaterPaletteRotationBase = 0x60;
|
||||
public Dictionary<string, TerrainTypeInfo> Terrain = new Dictionary<string, TerrainTypeInfo>();
|
||||
public Dictionary<ushort, TileTemplate> Templates = new Dictionary<ushort, TileTemplate>();
|
||||
public string[] EditorTemplateOrder;
|
||||
|
||||
static readonly string[] fields = {"Name", "TileSize", "Id", "Palette", "Extensions"};
|
||||
|
||||
|
||||
@@ -200,8 +200,8 @@ namespace OpenRA.FileFormats
|
||||
|
||||
var ret = new List<MiniYamlNode>();
|
||||
|
||||
var aDict = a.ToDictionary( x => x.Key );
|
||||
var bDict = b.ToDictionary( x => x.Key );
|
||||
var aDict = a.ToDictionaryWithConflictLog(x => x.Key, "MiniYaml.Merge", null, x => "{0} (at {1})".F(x.Key, x.Location));
|
||||
var bDict = b.ToDictionaryWithConflictLog(x => x.Key, "MiniYaml.Merge", null, x => "{0} (at {1})".F(x.Key, x.Location));
|
||||
var keys = aDict.Keys.Union( bDict.Keys ).ToList();
|
||||
|
||||
var noInherit = keys.Where(x => x.Length > 0 && x[0] == '-')
|
||||
|
||||
@@ -39,6 +39,12 @@ namespace OpenRA.FileFormats
|
||||
get { return colors; }
|
||||
}
|
||||
|
||||
public void ApplyRemap(IPaletteRemap r)
|
||||
{
|
||||
for(int i = 0; i < 256; i++)
|
||||
colors[i] = (uint)r.GetRemappedColor(Color.FromArgb((int)colors[i]),i).ToArgb();
|
||||
}
|
||||
|
||||
public Palette(Stream s, int[] remapShadow)
|
||||
{
|
||||
colors = new uint[256];
|
||||
@@ -61,9 +67,8 @@ namespace OpenRA.FileFormats
|
||||
|
||||
public Palette(Palette p, IPaletteRemap r)
|
||||
{
|
||||
colors = new uint[256];
|
||||
for(int i = 0; i < 256; i++)
|
||||
colors[i] = (uint)r.GetRemappedColor(Color.FromArgb((int)p.colors[i]),i).ToArgb();
|
||||
colors = (uint[])p.colors.Clone();
|
||||
ApplyRemap(r);
|
||||
}
|
||||
|
||||
public Palette(Palette p)
|
||||
@@ -71,6 +76,13 @@ namespace OpenRA.FileFormats
|
||||
colors = (uint[])p.colors.Clone();
|
||||
}
|
||||
|
||||
public Palette(uint[] data)
|
||||
{
|
||||
if (data.Length != 256)
|
||||
throw new InvalidDataException("Attempting to create palette with incorrect array size");
|
||||
colors = (uint[])data.Clone();
|
||||
}
|
||||
|
||||
public ColorPalette AsSystemPalette()
|
||||
{
|
||||
ColorPalette pal;
|
||||
@@ -88,6 +100,21 @@ namespace OpenRA.FileFormats
|
||||
return pal;
|
||||
}
|
||||
|
||||
public Bitmap AsBitmap()
|
||||
{
|
||||
var b = new Bitmap(256, 1, PixelFormat.Format32bppArgb);
|
||||
var data = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),
|
||||
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
unsafe
|
||||
{
|
||||
uint* c = (uint*)data.Scan0;
|
||||
for (var x = 0; x < 256; x++)
|
||||
*(c + x) = colors[x];
|
||||
}
|
||||
b.UnlockBits(data);
|
||||
return b;
|
||||
}
|
||||
|
||||
public static Palette Load(string filename, int[] remap)
|
||||
{
|
||||
using(var s = File.OpenRead(filename))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4
OpenRA.FileFormats/Thirdparty/Random.cs
vendored
4
OpenRA.FileFormats/Thirdparty/Random.cs
vendored
@@ -20,6 +20,7 @@ namespace OpenRA.Thirdparty
|
||||
int index = 0;
|
||||
|
||||
public int Last;
|
||||
public int TotalCount = 0;
|
||||
|
||||
public Random() : this(Environment.TickCount) { }
|
||||
|
||||
@@ -41,13 +42,14 @@ namespace OpenRA.Thirdparty
|
||||
y ^= y >> 18;
|
||||
|
||||
index = (index + 1) % 624;
|
||||
TotalCount++;
|
||||
Last = (int)(y % int.MaxValue);
|
||||
return Last;
|
||||
}
|
||||
|
||||
public int Next(int low, int high) { return low + Next() % (high - low); }
|
||||
public int Next(int high) { return Next() % high; }
|
||||
public double NextDouble() { return Math.Abs(Next() / (double)0x7fffffff); }
|
||||
public float NextFloat() { return Math.Abs(Next() / (float)0x7fffffff); }
|
||||
|
||||
void Generate()
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@ using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA
|
||||
@@ -43,6 +44,8 @@ namespace OpenRA
|
||||
return HasLocation.PxPosition;
|
||||
}
|
||||
}
|
||||
|
||||
public Shroud.ActorVisibility Sight;
|
||||
|
||||
[Sync]
|
||||
public Player Owner;
|
||||
@@ -71,7 +74,7 @@ namespace OpenRA
|
||||
AddTrait(trait.Create(init));
|
||||
}
|
||||
|
||||
Move = Lazy.New( () => TraitOrDefault<IMove>() );
|
||||
Move = Lazy.New(() => TraitOrDefault<IMove>());
|
||||
|
||||
Size = Lazy.New(() =>
|
||||
{
|
||||
@@ -79,17 +82,23 @@ namespace OpenRA
|
||||
if (si != null && si.Bounds != null)
|
||||
return new int2(si.Bounds[0], si.Bounds[1]);
|
||||
|
||||
// auto size from render
|
||||
var firstSprite = TraitsImplementing<IRender>().SelectMany(ApplyIRender).FirstOrDefault();
|
||||
if (firstSprite.Sprite == null) return int2.Zero;
|
||||
return (firstSprite.Sprite.size * firstSprite.Scale).ToInt2();
|
||||
return TraitsImplementing<IAutoSelectionSize>().Select(x => x.SelectionSize(this)).FirstOrDefault();
|
||||
});
|
||||
|
||||
ApplyIRender = x => x.Render(this);
|
||||
ApplyRenderModifier = (m, p) => p.ModifyRender(this, m);
|
||||
if (this.HasTrait<RevealsShroud>())
|
||||
{
|
||||
Sight = new Shroud.ActorVisibility
|
||||
{
|
||||
range = this.Trait<RevealsShroud>().RevealRange,
|
||||
vis = Shroud.GetVisOrigins(this).ToArray()
|
||||
};
|
||||
}
|
||||
|
||||
Bounds = Cached.New( () => CalculateBounds(false) );
|
||||
ExtendedBounds = Cached.New( () => CalculateBounds(true) );
|
||||
ApplyIRender = (x, wr) => x.Render(this, wr);
|
||||
ApplyRenderModifier = (m, p, wr) => p.ModifyRender(this, wr, m);
|
||||
|
||||
Bounds = Cached.New(() => CalculateBounds(false));
|
||||
ExtendedBounds = Cached.New(() => CalculateBounds(true));
|
||||
}
|
||||
|
||||
public void Tick()
|
||||
@@ -97,7 +106,12 @@ namespace OpenRA
|
||||
Bounds.Invalidate();
|
||||
ExtendedBounds.Invalidate();
|
||||
|
||||
currentActivity = Util.RunActivity( this, currentActivity );
|
||||
currentActivity = Traits.Util.RunActivity( this, currentActivity );
|
||||
}
|
||||
|
||||
public void UpdateSight()
|
||||
{
|
||||
Sight.vis = Shroud.GetVisOrigins(this).ToArray();
|
||||
}
|
||||
|
||||
public bool IsIdle
|
||||
@@ -108,13 +122,13 @@ namespace OpenRA
|
||||
OpenRA.FileFormats.Lazy<int2> Size;
|
||||
|
||||
// note: these delegates are cached to avoid massive allocation.
|
||||
Func<IRender, IEnumerable<Renderable>> ApplyIRender;
|
||||
Func<IEnumerable<Renderable>, IRenderModifier, IEnumerable<Renderable>> ApplyRenderModifier;
|
||||
public IEnumerable<Renderable> Render()
|
||||
Func<IRender, WorldRenderer, IEnumerable<Renderable>> ApplyIRender;
|
||||
Func<IEnumerable<Renderable>, IRenderModifier, WorldRenderer, IEnumerable<Renderable>> ApplyRenderModifier;
|
||||
public IEnumerable<Renderable> Render(WorldRenderer wr)
|
||||
{
|
||||
var mods = TraitsImplementing<IRenderModifier>();
|
||||
var sprites = TraitsImplementing<IRender>().SelectMany(ApplyIRender);
|
||||
return mods.Aggregate(sprites, ApplyRenderModifier);
|
||||
var sprites = TraitsImplementing<IRender>().SelectMany(x => ApplyIRender(x, wr));
|
||||
return mods.Aggregate(sprites, (m,p) => ApplyRenderModifier(m,p,wr));
|
||||
}
|
||||
|
||||
// When useAltitude = true, the bounding box is extended
|
||||
@@ -129,22 +143,14 @@ namespace OpenRA
|
||||
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 PVecInt(size.X, size.Y + move.Altitude);
|
||||
}
|
||||
@@ -240,10 +246,15 @@ namespace OpenRA
|
||||
{
|
||||
World.AddFrameEndTask(w =>
|
||||
{
|
||||
var oldOwner = Owner;
|
||||
|
||||
// momentarily remove from world so the ownership queries don't get confused
|
||||
w.Remove(this);
|
||||
Owner = newOwner;
|
||||
w.Add(this);
|
||||
|
||||
foreach (var t in this.TraitsImplementing<INotifyOwnerChanged>())
|
||||
t.OnOwnerChanged(this, oldOwner, newOwner);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Effects
|
||||
@@ -25,12 +26,12 @@ namespace OpenRA.Effects
|
||||
this.delay = delay;
|
||||
}
|
||||
|
||||
public void Tick( World world )
|
||||
public void Tick(World world)
|
||||
{
|
||||
if (--delay <= 0)
|
||||
world.AddFrameEndTask(w => { w.Remove(this); a(); });
|
||||
}
|
||||
|
||||
public IEnumerable<Renderable> Render() { yield break; }
|
||||
public IEnumerable<Renderable> Render(WorldRenderer wr) { yield break; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Effects
|
||||
@@ -32,14 +33,14 @@ namespace OpenRA.Effects
|
||||
world.AddFrameEndTask(w => w.Remove(this));
|
||||
}
|
||||
|
||||
public IEnumerable<Renderable> Render()
|
||||
public IEnumerable<Renderable> Render(WorldRenderer wr)
|
||||
{
|
||||
if (!target.IsInWorld)
|
||||
yield break;
|
||||
|
||||
if (remainingTicks % 2 == 0)
|
||||
foreach (var r in target.Render())
|
||||
yield return r.WithPalette("highlight");
|
||||
foreach (var r in target.Render(wr))
|
||||
yield return r.WithPalette(wr.Palette("highlight"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,13 +9,14 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Effects
|
||||
{
|
||||
public interface IEffect
|
||||
{
|
||||
void Tick( World world );
|
||||
IEnumerable<Renderable> Render();
|
||||
void Tick(World world);
|
||||
IEnumerable<Renderable> Render(WorldRenderer r);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ namespace OpenRA
|
||||
{
|
||||
public static int CellSize { get { return modData.Manifest.TileSize; } }
|
||||
|
||||
public static MouseButtonPreference mouseButtonPreference = new MouseButtonPreference();
|
||||
|
||||
public static ModData modData;
|
||||
static WorldRenderer worldRenderer;
|
||||
|
||||
@@ -56,7 +58,7 @@ namespace OpenRA
|
||||
|
||||
static string ChooseReplayFilename()
|
||||
{
|
||||
return DateTime.UtcNow.ToString("OpenRA-yyyy-MM-ddTHHmmssZ.rep");
|
||||
return DateTime.UtcNow.ToString("OpenRA-yyyy-MM-ddTHHmmssZ");
|
||||
}
|
||||
|
||||
static void JoinInner(OrderManager om)
|
||||
@@ -302,8 +304,40 @@ namespace OpenRA
|
||||
JoinLocal();
|
||||
viewport = new Viewport(new int2(Renderer.Resolution), Rectangle.Empty, Renderer);
|
||||
|
||||
modData.LoadScreen.StartGame();
|
||||
Settings.Save();
|
||||
if (Game.Settings.Server.Dedicated)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Game.Settings.Server.Map = WidgetUtils.ChooseInitialMap(Game.Settings.Server.Map);
|
||||
Game.Settings.Save();
|
||||
Game.CreateServer(new ServerSettings(Game.Settings.Server));
|
||||
while(true)
|
||||
{
|
||||
System.Threading.Thread.Sleep(100);
|
||||
|
||||
if((server.State == Server.ServerState.GameStarted)
|
||||
&& (server.conns.Count<=1))
|
||||
{
|
||||
Console.WriteLine("No one is playing, shutting down...");
|
||||
server.Shutdown();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Game.Settings.Server.DedicatedLoop)
|
||||
{
|
||||
Console.WriteLine("Starting a new server instance...");
|
||||
continue;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
System.Environment.Exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
modData.LoadScreen.StartGame();
|
||||
Settings.Save();
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoadShellMap()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -34,6 +34,8 @@ namespace OpenRA.GameRules
|
||||
public string Map = null;
|
||||
public string[] Ban = null;
|
||||
public int TimeOut = 0;
|
||||
public bool Dedicated = false;
|
||||
public bool DedicatedLoop = true;
|
||||
|
||||
public ServerSettings() { }
|
||||
|
||||
@@ -49,6 +51,8 @@ namespace OpenRA.GameRules
|
||||
Map = other.Map;
|
||||
Ban = other.Ban;
|
||||
TimeOut = other.TimeOut;
|
||||
Dedicated = other.Dedicated;
|
||||
DedicatedLoop = other.DedicatedLoop;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,12 +112,35 @@ namespace OpenRA.GameRules
|
||||
public MouseScrollType MouseScroll = MouseScrollType.Standard;
|
||||
public float ViewportEdgeScrollStep = 10f;
|
||||
|
||||
public bool UseClassicMouseStyle = false;
|
||||
|
||||
// Internal game settings
|
||||
public int Timestep = 40;
|
||||
|
||||
public string ConnectTo = "";
|
||||
}
|
||||
|
||||
public class KeySettings
|
||||
{
|
||||
public string PauseKey = "f3";
|
||||
|
||||
public string CycleBaseKey = "backspace";
|
||||
public string ToLastEventKey = "space";
|
||||
public string ToSelectionKey = "home";
|
||||
public string SellKey = "v";
|
||||
public string PowerDownKey = "b";
|
||||
public string RepairKey = "n";
|
||||
|
||||
public string AttackMoveKey = "a";
|
||||
public string StopKey = "s";
|
||||
public string ScatterKey = "x";
|
||||
public string StanceCycleKey = "z";
|
||||
public string DeployKey = "f";
|
||||
|
||||
public string CycleTabsKey = "tab";
|
||||
}
|
||||
|
||||
|
||||
public class Settings
|
||||
{
|
||||
string SettingsFile;
|
||||
@@ -124,6 +151,7 @@ namespace OpenRA.GameRules
|
||||
public GraphicSettings Graphics = new GraphicSettings();
|
||||
public ServerSettings Server = new ServerSettings();
|
||||
public DebugSettings Debug = new DebugSettings();
|
||||
public KeySettings Keys = new KeySettings();
|
||||
|
||||
public Dictionary<string, object> Sections;
|
||||
|
||||
@@ -138,6 +166,7 @@ namespace OpenRA.GameRules
|
||||
{"Graphics", Graphics},
|
||||
{"Server", Server},
|
||||
{"Debug", Debug},
|
||||
{"Keys", Keys},
|
||||
};
|
||||
|
||||
// Override fieldloader to ignore invalid entries
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace OpenRA.GameRules
|
||||
public class WeaponInfo
|
||||
{
|
||||
public readonly float Range = 0;
|
||||
public readonly string Report = null;
|
||||
public readonly string[] Report = null;
|
||||
public readonly int ROF = 1;
|
||||
public readonly int Burst = 1;
|
||||
public readonly bool Charges = false;
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace OpenRA.Graphics
|
||||
this.DisableFunc = d;
|
||||
}
|
||||
|
||||
public Renderable Image(Actor self, string pal)
|
||||
public Renderable Image(Actor self, PaletteReference pal)
|
||||
{
|
||||
var p = self.CenterLocation;
|
||||
var loc = p.ToFloat2() - 0.5f * Animation.Image.size
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
public static class CursorProvider
|
||||
{
|
||||
public static Dictionary<string, Palette> Palettes { get; private set; }
|
||||
static Dictionary<string, CursorSequence> cursors;
|
||||
|
||||
public static void Initialize(string[] sequenceFiles)
|
||||
@@ -28,13 +29,14 @@ namespace OpenRA.Graphics
|
||||
int[] ShadowIndex = { };
|
||||
|
||||
if (sequences.NodesDict.ContainsKey("ShadowIndex"))
|
||||
{
|
||||
Array.Resize(ref ShadowIndex, ShadowIndex.Length + 1);
|
||||
ShadowIndex[ShadowIndex.Length - 1] = Convert.ToInt32(sequences.NodesDict["ShadowIndex"].Value);
|
||||
}
|
||||
{
|
||||
Array.Resize(ref ShadowIndex, ShadowIndex.Length + 1);
|
||||
ShadowIndex[ShadowIndex.Length - 1] = Convert.ToInt32(sequences.NodesDict["ShadowIndex"].Value);
|
||||
}
|
||||
|
||||
Palettes = new Dictionary<string, Palette>();
|
||||
foreach (var s in sequences.NodesDict["Palettes"].Nodes)
|
||||
Game.modData.Palette.AddPalette(s.Key, new Palette(FileSystem.Open(s.Value.Value), ShadowIndex));
|
||||
Palettes.Add(s.Key, new Palette(FileSystem.Open(s.Value.Value), ShadowIndex));
|
||||
|
||||
foreach (var s in sequences.NodesDict["Cursors"].Nodes)
|
||||
LoadSequencesForCursor(s.Key, s.Value);
|
||||
|
||||
@@ -25,11 +25,13 @@ namespace OpenRA.Graphics
|
||||
ITexture texture;
|
||||
Dictionary<string, Palette> palettes;
|
||||
Dictionary<string, int> indices;
|
||||
Dictionary<string, bool> allowsMods;
|
||||
|
||||
public HardwarePalette()
|
||||
{
|
||||
palettes = new Dictionary<string, Palette>();
|
||||
indices = new Dictionary<string, int>();
|
||||
allowsMods = new Dictionary<string, bool>();
|
||||
texture = Game.Renderer.Device.CreateTexture();
|
||||
}
|
||||
|
||||
@@ -49,22 +51,24 @@ namespace OpenRA.Graphics
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void AddPalette(string name, Palette p)
|
||||
public void AddPalette(string name, Palette p, bool allowModifiers)
|
||||
{
|
||||
if (palettes.ContainsKey(name))
|
||||
throw new InvalidOperationException("Palette {0} has already been defined".F(name));
|
||||
|
||||
palettes.Add(name, p);
|
||||
indices.Add(name, allocated++);
|
||||
allowsMods.Add(name, allowModifiers);
|
||||
}
|
||||
|
||||
uint[,] data = new uint[MaxPalettes, 256];
|
||||
public void Update(IEnumerable<IPaletteModifier> paletteMods)
|
||||
{
|
||||
var copy = palettes.ToDictionary(p => p.Key, p => new Palette(p.Value));
|
||||
var modifiable = copy.Where(p => allowsMods[p.Key]).ToDictionary(p => p.Key, p => p.Value);
|
||||
|
||||
foreach (var mod in paletteMods)
|
||||
mod.AdjustPalette(copy);
|
||||
mod.AdjustPalette(modifiable);
|
||||
|
||||
foreach (var pal in copy)
|
||||
{
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace OpenRA.Graphics
|
||||
|
||||
foreach (var t in world.ActorsWithTrait<IRadarSignature>())
|
||||
{
|
||||
if (!world.LocalShroud.IsVisible(t.Actor))
|
||||
if (!world.RenderedShroud.IsVisible(t.Actor))
|
||||
continue;
|
||||
|
||||
var color = t.Trait.RadarSignatureColor(t.Actor);
|
||||
@@ -158,7 +158,7 @@ namespace OpenRA.Graphics
|
||||
var map = world.Map;
|
||||
var size = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height));
|
||||
var bitmap = new Bitmap(size, size);
|
||||
if (world.LocalShroud.Disabled)
|
||||
if (world.RenderedShroud.Disabled)
|
||||
return bitmap;
|
||||
|
||||
var bitmapData = bitmap.LockBits(bitmap.Bounds(),
|
||||
@@ -176,9 +176,9 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
var mapX = x + map.Bounds.Left;
|
||||
var mapY = y + map.Bounds.Top;
|
||||
if (!world.LocalShroud.IsExplored(mapX, mapY))
|
||||
if (!world.RenderedShroud.IsExplored(mapX, mapY))
|
||||
*(c + (y * bitmapData.Stride >> 2) + x) = shroud;
|
||||
else if (!world.LocalShroud.IsVisible(mapX,mapY))
|
||||
else if (!world.RenderedShroud.IsVisible(mapX,mapY))
|
||||
*(c + (y * bitmapData.Stride >> 2) + x) = fog;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,20 +50,20 @@ namespace OpenRA.Graphics
|
||||
TempBufferCount = Game.Settings.Graphics.NumTempBuffers;
|
||||
SheetSize = Game.Settings.Graphics.SheetSize;
|
||||
|
||||
WorldSpriteShader = device.CreateShader("world-shp");
|
||||
WorldLineShader = device.CreateShader("world-line");
|
||||
LineShader = device.CreateShader("chrome-line");
|
||||
RgbaSpriteShader = device.CreateShader("chrome-rgba");
|
||||
SpriteShader = device.CreateShader("chrome-shp");
|
||||
WorldSpriteShader = device.CreateShader("shp");
|
||||
WorldLineShader = device.CreateShader("line");
|
||||
LineShader = device.CreateShader("line");
|
||||
RgbaSpriteShader = device.CreateShader("rgba");
|
||||
SpriteShader = device.CreateShader("shp");
|
||||
|
||||
WorldSpriteRenderer = new SpriteRenderer( this, WorldSpriteShader );
|
||||
WorldSpriteRenderer = new SpriteRenderer(this, WorldSpriteShader);
|
||||
WorldLineRenderer = new LineRenderer(this, WorldLineShader);
|
||||
LineRenderer = new LineRenderer(this, LineShader);
|
||||
RgbaSpriteRenderer = new SpriteRenderer( this, RgbaSpriteShader );
|
||||
SpriteRenderer = new SpriteRenderer( this, SpriteShader );
|
||||
RgbaSpriteRenderer = new SpriteRenderer(this, RgbaSpriteShader);
|
||||
SpriteRenderer = new SpriteRenderer(this, SpriteShader);
|
||||
|
||||
for( int i = 0 ; i < TempBufferCount ; i++ )
|
||||
tempBuffers.Enqueue( device.CreateVertexBuffer( TempBufferSize ) );
|
||||
for (int i = 0; i < TempBufferCount; i++)
|
||||
tempBuffers.Enqueue(device.CreateVertexBuffer(TempBufferSize));
|
||||
}
|
||||
|
||||
public void InitializeFonts(Manifest m)
|
||||
@@ -80,22 +80,22 @@ namespace OpenRA.Graphics
|
||||
float2 r2 = new float2(-1, 1);
|
||||
var zr1 = zoom*r1;
|
||||
|
||||
SetShaderParams( WorldSpriteShader, zr1, r2, scroll );
|
||||
SetShaderParams( WorldLineShader, zr1, r2, scroll );
|
||||
SetShaderParams( LineShader, r1, r2, scroll );
|
||||
SetShaderParams( RgbaSpriteShader, r1, r2, scroll );
|
||||
SetShaderParams( SpriteShader, r1, r2, scroll );
|
||||
SetShaderParams(WorldSpriteShader, zr1, r2, scroll);
|
||||
SetShaderParams(WorldLineShader, zr1, r2, scroll);
|
||||
SetShaderParams(LineShader, r1, r2, float2.Zero);
|
||||
SetShaderParams(RgbaSpriteShader, r1, r2, float2.Zero);
|
||||
SetShaderParams(SpriteShader, r1, r2, float2.Zero);
|
||||
}
|
||||
|
||||
void SetShaderParams( IShader s, float2 r1, float2 r2, float2 scroll )
|
||||
void SetShaderParams(IShader s, float2 r1, float2 r2, float2 scroll)
|
||||
{
|
||||
s.SetValue( "Palette", PaletteTexture );
|
||||
s.SetValue( "Scroll", (int) scroll.X, (int) scroll.Y );
|
||||
s.SetValue( "r1", r1.X, r1.Y );
|
||||
s.SetValue( "r2", r2.X, r2.Y );
|
||||
s.SetValue("Palette", PaletteTexture);
|
||||
s.SetValue("Scroll", (int)scroll.X, (int)scroll.Y);
|
||||
s.SetValue("r1", r1.X, r1.Y);
|
||||
s.SetValue("r2", r2.X, r2.Y);
|
||||
}
|
||||
|
||||
public void EndFrame( IInputHandler inputHandler )
|
||||
public void EndFrame(IInputHandler inputHandler)
|
||||
{
|
||||
Flush();
|
||||
device.PumpInput(inputHandler);
|
||||
@@ -129,14 +129,17 @@ namespace OpenRA.Graphics
|
||||
// which makes the window non-interactive in Windowed/Pseudofullscreen mode.
|
||||
static Screen FixOSX() { return Screen.PrimaryScreen; }
|
||||
|
||||
internal static void Initialize( WindowMode windowMode )
|
||||
internal static void Initialize(WindowMode windowMode)
|
||||
{
|
||||
if (Platform.CurrentPlatform == PlatformType.OSX)
|
||||
FixOSX();
|
||||
|
||||
var resolution = GetResolution( windowMode );
|
||||
var rendererPath = Path.GetFullPath( "OpenRA.Renderer.{0}.dll".F(Game.Settings.Graphics.Renderer) );
|
||||
device = CreateDevice( Assembly.LoadFile( rendererPath ), resolution.Width, resolution.Height, windowMode );
|
||||
var resolution = GetResolution(windowMode);
|
||||
|
||||
string renderer = Game.Settings.Server.Dedicated ? "Null" : Game.Settings.Graphics.Renderer;
|
||||
var rendererPath = Path.GetFullPath("OpenRA.Renderer.{0}.dll".F(renderer));
|
||||
|
||||
device = CreateDevice(Assembly.LoadFile(rendererPath), resolution.Width, resolution.Height, windowMode);
|
||||
}
|
||||
|
||||
static Size GetResolution(WindowMode windowmode)
|
||||
@@ -147,12 +150,12 @@ namespace OpenRA.Graphics
|
||||
return new Size(size.X, size.Y);
|
||||
}
|
||||
|
||||
static IGraphicsDevice CreateDevice( Assembly rendererDll, int width, int height, WindowMode window )
|
||||
static IGraphicsDevice CreateDevice(Assembly rendererDll, int width, int height, WindowMode window)
|
||||
{
|
||||
foreach( RendererAttribute r in rendererDll.GetCustomAttributes( typeof( RendererAttribute ), false ) )
|
||||
foreach (RendererAttribute r in rendererDll.GetCustomAttributes(typeof(RendererAttribute), false))
|
||||
{
|
||||
var factory = (IDeviceFactory) r.Type.GetConstructor( Type.EmptyTypes ).Invoke( null );
|
||||
return factory.Create( new Size( width, height ), window );
|
||||
var factory = (IDeviceFactory)r.Type.GetConstructor(Type.EmptyTypes).Invoke(null);
|
||||
return factory.Create(new Size(width, height), window);
|
||||
}
|
||||
|
||||
throw new InvalidOperationException("Renderer DLL is missing RendererAttribute to tell us what type to use!");
|
||||
@@ -161,7 +164,7 @@ namespace OpenRA.Graphics
|
||||
internal IVertexBuffer<Vertex> GetTempVertexBuffer()
|
||||
{
|
||||
var ret = tempBuffers.Dequeue();
|
||||
tempBuffers.Enqueue( ret );
|
||||
tempBuffers.Enqueue(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -173,8 +176,8 @@ namespace OpenRA.Graphics
|
||||
get { return currentBatchRenderer; }
|
||||
set
|
||||
{
|
||||
if( currentBatchRenderer == value ) return;
|
||||
if( currentBatchRenderer != null )
|
||||
if (currentBatchRenderer == value) return;
|
||||
if (currentBatchRenderer != null)
|
||||
currentBatchRenderer.Flush();
|
||||
currentBatchRenderer = value;
|
||||
}
|
||||
@@ -183,7 +186,7 @@ namespace OpenRA.Graphics
|
||||
public void EnableScissor(int left, int top, int width, int height)
|
||||
{
|
||||
Flush();
|
||||
Device.EnableScissor( left, top, width, height );
|
||||
Device.EnableScissor(left, top, width, height);
|
||||
}
|
||||
|
||||
public void DisableScissor()
|
||||
|
||||
@@ -18,12 +18,13 @@ namespace OpenRA.Graphics
|
||||
public class Sequence
|
||||
{
|
||||
readonly Sprite[] sprites;
|
||||
readonly int start, length, facings, tick;
|
||||
readonly int start, length, stride, facings, tick;
|
||||
|
||||
public readonly string Name;
|
||||
public int Start { get { return start; } }
|
||||
public int End { get { return start + length; } }
|
||||
public int Length { get { return length; } }
|
||||
public int Stride { get { return stride; } }
|
||||
public int Facings { get { return facings; } }
|
||||
public int Tick { get { return tick; } }
|
||||
|
||||
@@ -43,6 +44,10 @@ namespace OpenRA.Graphics
|
||||
else
|
||||
length = int.Parse(d["Length"].Value);
|
||||
|
||||
if (d.ContainsKey("Stride"))
|
||||
stride = int.Parse(d["Stride"].Value);
|
||||
else
|
||||
stride = length;
|
||||
|
||||
if(d.ContainsKey("Facings"))
|
||||
facings = int.Parse(d["Facings"].Value);
|
||||
@@ -54,10 +59,15 @@ namespace OpenRA.Graphics
|
||||
else
|
||||
tick = 40;
|
||||
|
||||
if (start < 0 || start + facings * length > sprites.Length)
|
||||
if (length > stride)
|
||||
throw new InvalidOperationException(
|
||||
"{0}: Sequence {1}.{2}: Length must be <= stride"
|
||||
.F(info.Nodes[0].Location, unit, name));
|
||||
|
||||
if (start < 0 || start + facings * stride > sprites.Length)
|
||||
throw new InvalidOperationException(
|
||||
"{6}: Sequence {0}.{1} uses frames [{2}..{3}] of SHP `{4}`, but only 0..{5} actually exist"
|
||||
.F(unit, name, start, start + facings * length - 1, srcOverride ?? unit, sprites.Length - 1,
|
||||
.F(unit, name, start, start + facings * stride - 1, srcOverride ?? unit, sprites.Length - 1,
|
||||
info.Nodes[0].Location));
|
||||
}
|
||||
|
||||
@@ -69,7 +79,7 @@ namespace OpenRA.Graphics
|
||||
public Sprite GetSprite(int frame, int facing)
|
||||
{
|
||||
var f = Traits.Util.QuantizeFacing( facing, facings );
|
||||
return sprites[ (f * length) + ( frame % length ) + start ];
|
||||
return sprites[ (f * stride) + ( frame % length ) + start ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,21 +15,25 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
public class ShroudRenderer
|
||||
{
|
||||
Traits.Shroud shroud;
|
||||
World world;
|
||||
Traits.Shroud shroud {
|
||||
get {
|
||||
return world.RenderedShroud;
|
||||
}
|
||||
}
|
||||
|
||||
Sprite[] shadowBits = Game.modData.SpriteLoader.LoadAllSprites("shadow");
|
||||
Sprite[,] sprites, fogSprites;
|
||||
|
||||
bool dirty = true;
|
||||
Map map;
|
||||
|
||||
public ShroudRenderer(World world)
|
||||
{
|
||||
this.shroud = world.LocalShroud;
|
||||
this.world = world;
|
||||
this.map = world.Map;
|
||||
|
||||
sprites = new Sprite[map.MapSize.X, map.MapSize.Y];
|
||||
fogSprites = new Sprite[map.MapSize.X, map.MapSize.Y];
|
||||
shroud.Dirty += () => dirty = true;
|
||||
}
|
||||
|
||||
static readonly byte[][] SpecialShroudTiles =
|
||||
@@ -101,11 +105,20 @@ namespace OpenRA.Graphics
|
||||
return shadowBits[SpecialShroudTiles[u ^ uSides][v]];
|
||||
}
|
||||
|
||||
internal void Draw( WorldRenderer wr )
|
||||
bool initializePalettes = true;
|
||||
PaletteReference fogPalette, shroudPalette;
|
||||
internal void Draw(WorldRenderer wr)
|
||||
{
|
||||
if (dirty)
|
||||
if (initializePalettes)
|
||||
{
|
||||
dirty = false;
|
||||
fogPalette = wr.Palette("fog");
|
||||
shroudPalette = wr.Palette("shroud");
|
||||
initializePalettes = false;
|
||||
}
|
||||
|
||||
if (shroud != null && shroud.dirty)
|
||||
{
|
||||
shroud.dirty = false;
|
||||
for (int i = map.Bounds.Left; i < map.Bounds.Right; i++)
|
||||
for (int j = map.Bounds.Top; j < map.Bounds.Bottom; j++)
|
||||
sprites[i, j] = ChooseShroud(i, j);
|
||||
@@ -116,14 +129,12 @@ namespace OpenRA.Graphics
|
||||
}
|
||||
|
||||
var clipRect = Game.viewport.WorldBounds(wr.world);
|
||||
DrawShroud( wr, clipRect, fogSprites, "fog" );
|
||||
DrawShroud( wr, clipRect, sprites, "shroud" );
|
||||
DrawShroud(wr, clipRect, fogSprites, fogPalette);
|
||||
DrawShroud(wr, clipRect, sprites, shroudPalette);
|
||||
}
|
||||
|
||||
void DrawShroud( WorldRenderer wr, Rectangle clip, Sprite[,] s, string pal )
|
||||
void DrawShroud(WorldRenderer wr, Rectangle clip, Sprite[,] s, PaletteReference pal)
|
||||
{
|
||||
var shroudPalette = wr.GetPaletteIndex(pal);
|
||||
|
||||
for (var j = clip.Top; j < clip.Bottom; j++)
|
||||
{
|
||||
var starti = clip.Left;
|
||||
@@ -138,14 +149,14 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
s[starti, j].DrawAt(
|
||||
Game.CellSize * new float2(starti, j),
|
||||
shroudPalette,
|
||||
pal.Index,
|
||||
new float2(Game.CellSize * (i - starti), Game.CellSize));
|
||||
starti = i + 1;
|
||||
}
|
||||
|
||||
s[i, j].DrawAt(
|
||||
Game.CellSize * new float2(i, j),
|
||||
shroudPalette);
|
||||
pal.Index);
|
||||
starti = i + 1;
|
||||
last = s[i, j];
|
||||
}
|
||||
@@ -153,7 +164,7 @@ namespace OpenRA.Graphics
|
||||
if (starti < clip.Right)
|
||||
s[starti, j].DrawAt(
|
||||
Game.CellSize * new float2(starti, j),
|
||||
shroudPalette,
|
||||
pal.Index,
|
||||
new float2(Game.CellSize * (clip.Right - starti), Game.CellSize));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,12 +49,12 @@ namespace OpenRA.Graphics
|
||||
|
||||
public void DrawSprite(Sprite s, float2 location, WorldRenderer wr, string palette)
|
||||
{
|
||||
DrawSprite(s, location, wr.GetPaletteIndex(palette), s.size);
|
||||
DrawSprite(s, location, wr.Palette(palette).Index, s.size);
|
||||
}
|
||||
|
||||
public void DrawSprite(Sprite s, float2 location, WorldRenderer wr, string palette, float2 size)
|
||||
{
|
||||
DrawSprite(s, location, wr.GetPaletteIndex(palette), size);
|
||||
DrawSprite(s, location, wr.Palette(palette).Index, size);
|
||||
}
|
||||
|
||||
public void DrawSprite(Sprite s, float2 location, int paletteIndex, float2 size)
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenRA.Graphics
|
||||
|
||||
int nv = 0;
|
||||
|
||||
var terrainPalette = Game.modData.Palette.GetPaletteIndex("terrain");
|
||||
var terrainPalette = wr.Palette("terrain").Index;
|
||||
|
||||
for( int j = map.Bounds.Top; j < map.Bounds.Bottom; j++ )
|
||||
for( int i = map.Bounds.Left; i < map.Bounds.Right; i++ )
|
||||
@@ -72,9 +72,9 @@ namespace OpenRA.Graphics
|
||||
if (firstRow < 0) firstRow = 0;
|
||||
if (lastRow > map.Bounds.Height) lastRow = map.Bounds.Height;
|
||||
|
||||
if (world.LocalPlayer != null && !world.LocalShroud.Disabled && world.LocalShroud.Bounds.HasValue)
|
||||
if (world.RenderedPlayer != null && !world.RenderedShroud.Disabled && world.RenderedShroud.Bounds.HasValue)
|
||||
{
|
||||
var r = world.LocalShroud.Bounds.Value;
|
||||
var r = world.RenderedShroud.Bounds.Value;
|
||||
if (firstRow < r.Top - map.Bounds.Top)
|
||||
firstRow = r.Top - map.Bounds.Top;
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ namespace OpenRA.Graphics
|
||||
|
||||
renderer.SpriteRenderer.DrawSprite(cursorSprite,
|
||||
Viewport.LastMousePos - cursorSequence.Hotspot,
|
||||
Game.modData.Palette.GetPaletteIndex(cursorSequence.Palette),
|
||||
wr.Palette(cursorSequence.Palette).Index,
|
||||
cursorSprite.size);
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ namespace OpenRA.Graphics
|
||||
cachedScroll = scrollPosition;
|
||||
}
|
||||
|
||||
var b = world.LocalShroud.Bounds;
|
||||
var b = world.RenderedShroud.Bounds;
|
||||
return (b.HasValue) ? Rectangle.Intersect(cachedRect, b.Value) : cachedRect;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,27 +17,56 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Graphics
|
||||
{
|
||||
public class PaletteReference
|
||||
{
|
||||
public readonly string Name;
|
||||
public readonly int Index;
|
||||
public readonly Palette Palette;
|
||||
public PaletteReference(string name, int index, Palette palette)
|
||||
{
|
||||
Name = name;
|
||||
Index = index;
|
||||
Palette = palette;
|
||||
}
|
||||
}
|
||||
|
||||
public class WorldRenderer
|
||||
{
|
||||
public readonly World world;
|
||||
internal readonly TerrainRenderer terrainRenderer;
|
||||
internal readonly ShroudRenderer shroudRenderer;
|
||||
internal readonly HardwarePalette palette;
|
||||
internal Cache<string, PaletteReference> palettes;
|
||||
|
||||
internal WorldRenderer(World world)
|
||||
{
|
||||
this.world = world;
|
||||
this.palette = Game.modData.Palette;
|
||||
foreach( var pal in world.traitDict.ActorsWithTraitMultiple<IPalette>( world ) )
|
||||
palette = new HardwarePalette();
|
||||
foreach (var p in CursorProvider.Palettes)
|
||||
palette.AddPalette(p.Key, p.Value, false);
|
||||
|
||||
palettes = new Cache<string, PaletteReference>(CreatePaletteReference);
|
||||
foreach (var pal in world.traitDict.ActorsWithTraitMultiple<IPalette>(world))
|
||||
pal.Trait.InitPalette( this );
|
||||
|
||||
// Generate initial palette texture
|
||||
palette.Update(new IPaletteModifier[] {});
|
||||
|
||||
terrainRenderer = new TerrainRenderer(world, this);
|
||||
shroudRenderer = new ShroudRenderer(world);
|
||||
}
|
||||
|
||||
public int GetPaletteIndex(string name) { return palette.GetPaletteIndex(name); }
|
||||
public Palette GetPalette(string name) { return palette.GetPalette(name); }
|
||||
public void AddPalette(string name, Palette pal) { palette.AddPalette(name, pal); }
|
||||
PaletteReference CreatePaletteReference(string name)
|
||||
{
|
||||
var pal = palette.GetPalette(name);
|
||||
if (pal == null)
|
||||
throw new InvalidOperationException("Palette `{0}` does not exist".F(name));
|
||||
|
||||
return new PaletteReference(name, palette.GetPaletteIndex(name), pal);
|
||||
}
|
||||
|
||||
public PaletteReference Palette(string name) { return palettes[name]; }
|
||||
public void AddPalette(string name, Palette pal, bool allowModifiers) { palette.AddPalette(name, pal, allowModifiers); }
|
||||
|
||||
class SpriteComparer : IComparer<Renderable>
|
||||
{
|
||||
@@ -57,10 +86,10 @@ namespace OpenRA.Graphics
|
||||
bounds.BottomRightAsCPos().ToPPos()
|
||||
);
|
||||
|
||||
var renderables = actors.SelectMany(a => a.Render())
|
||||
var renderables = actors.SelectMany(a => a.Render(this))
|
||||
.OrderBy(r => r, comparer);
|
||||
|
||||
var effects = world.Effects.SelectMany(e => e.Render());
|
||||
var effects = world.Effects.SelectMany(e => e.Render(this));
|
||||
|
||||
return renderables.Concat(effects);
|
||||
}
|
||||
@@ -77,8 +106,8 @@ namespace OpenRA.Graphics
|
||||
|
||||
terrainRenderer.Draw(this, Game.viewport);
|
||||
foreach (var a in world.traitDict.ActorsWithTraitMultiple<IRenderAsTerrain>(world))
|
||||
foreach (var r in a.Trait.RenderAsTerrain(a.Actor))
|
||||
r.Sprite.DrawAt(r.Pos, this.GetPaletteIndex(r.Palette), r.Scale);
|
||||
foreach (var r in a.Trait.RenderAsTerrain(this, a.Actor))
|
||||
r.Sprite.DrawAt(r.Pos, r.Palette.Index, r.Scale);
|
||||
|
||||
foreach (var a in world.Selection.Actors)
|
||||
if (!a.Destroyed)
|
||||
@@ -91,7 +120,7 @@ namespace OpenRA.Graphics
|
||||
world.OrderGenerator.RenderBeforeWorld(this, world);
|
||||
|
||||
foreach (var image in SpritesToRender())
|
||||
image.Sprite.DrawAt(image.Pos, this.GetPaletteIndex(image.Palette), image.Scale);
|
||||
image.Sprite.DrawAt(image.Pos, image.Palette.Index, image.Scale);
|
||||
|
||||
// added for contrails
|
||||
foreach (var a in world.ActorsWithTrait<IPostRender>())
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -15,32 +15,53 @@ namespace OpenRA
|
||||
public class NullInputHandler : IInputHandler
|
||||
{
|
||||
// ignore all input
|
||||
public void ModifierKeys( Modifiers mods ) { }
|
||||
public void OnKeyInput( KeyInput input ) { }
|
||||
public void OnMouseInput( MouseInput input ) { }
|
||||
public void ModifierKeys(Modifiers mods) { }
|
||||
public void OnKeyInput(KeyInput input) { }
|
||||
public void OnMouseInput(MouseInput input) { }
|
||||
}
|
||||
|
||||
public class DefaultInputHandler : IInputHandler
|
||||
{
|
||||
readonly World world;
|
||||
public DefaultInputHandler( World world )
|
||||
public DefaultInputHandler(World world)
|
||||
{
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public void ModifierKeys( Modifiers mods )
|
||||
public void ModifierKeys(Modifiers mods)
|
||||
{
|
||||
Game.HandleModifierKeys( mods );
|
||||
Game.HandleModifierKeys(mods);
|
||||
}
|
||||
|
||||
public void OnKeyInput( KeyInput input )
|
||||
public void OnKeyInput(KeyInput input)
|
||||
{
|
||||
Sync.CheckSyncUnchanged(world, () => Ui.HandleKeyPress(input));
|
||||
}
|
||||
|
||||
public void OnMouseInput( MouseInput input )
|
||||
public void OnMouseInput(MouseInput input)
|
||||
{
|
||||
Sync.CheckSyncUnchanged(world, () => Ui.HandleInput(input));
|
||||
}
|
||||
}
|
||||
|
||||
public class MouseButtonPreference
|
||||
{
|
||||
|
||||
public MouseButton Action
|
||||
{
|
||||
get
|
||||
{
|
||||
return Game.Settings.Game.UseClassicMouseStyle ? MouseButton.Left : MouseButton.Right;
|
||||
}
|
||||
}
|
||||
|
||||
public MouseButton Cancel
|
||||
{
|
||||
get
|
||||
{
|
||||
return Game.Settings.Game.UseClassicMouseStyle ? MouseButton.Right : MouseButton.Left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace OpenRA
|
||||
public string Description;
|
||||
public string Author;
|
||||
public string Tileset;
|
||||
public string[] Difficulties;
|
||||
|
||||
[FieldLoader.Ignore] public Lazy<Dictionary<string, ActorReference>> Actors;
|
||||
|
||||
@@ -178,6 +179,7 @@ namespace OpenRA
|
||||
"Description",
|
||||
"Author",
|
||||
"Tileset",
|
||||
"Difficulties",
|
||||
"MapSize",
|
||||
"Bounds",
|
||||
"UseAsShellmap",
|
||||
@@ -383,22 +385,24 @@ namespace OpenRA
|
||||
|
||||
public void MakeDefaultPlayers()
|
||||
{
|
||||
Players.Clear();
|
||||
|
||||
var firstRace = OpenRA.Rules.Info["world"].Traits
|
||||
.WithInterface<CountryInfo>().First(c => c.Selectable).Race;
|
||||
|
||||
Players.Add("Neutral", new PlayerReference
|
||||
{
|
||||
Name = "Neutral",
|
||||
Race = firstRace,
|
||||
OwnsWorld = true,
|
||||
NonCombatant = true
|
||||
});
|
||||
if (!Players.ContainsKey("Neutral"))
|
||||
Players.Add("Neutral", new PlayerReference
|
||||
{
|
||||
Name = "Neutral",
|
||||
Race = firstRace,
|
||||
OwnsWorld = true,
|
||||
NonCombatant = true
|
||||
});
|
||||
|
||||
var numSpawns = GetSpawnPoints().Length;
|
||||
for (var index = 0; index < numSpawns; index++)
|
||||
{
|
||||
if (Players.ContainsKey("Multi{0}".F(index)))
|
||||
continue;
|
||||
|
||||
var p = new PlayerReference
|
||||
{
|
||||
Name = "Multi{0}".F(index),
|
||||
|
||||
@@ -28,7 +28,6 @@ namespace OpenRA
|
||||
public ILoadScreen LoadScreen = null;
|
||||
public SheetBuilder SheetBuilder;
|
||||
public SpriteLoader SpriteLoader;
|
||||
public HardwarePalette Palette { get; private set; }
|
||||
|
||||
public ModData( params string[] mods )
|
||||
{
|
||||
@@ -51,13 +50,11 @@ namespace OpenRA
|
||||
|
||||
AvailableMaps = FindMaps(Manifest.Mods);
|
||||
|
||||
Palette = new HardwarePalette();
|
||||
ChromeMetrics.Initialize(Manifest.ChromeMetrics);
|
||||
ChromeProvider.Initialize(Manifest.Chrome);
|
||||
SheetBuilder = new SheetBuilder(TextureChannel.Red);
|
||||
SpriteLoader = new SpriteLoader(new string[] { ".shp" }, SheetBuilder);
|
||||
CursorProvider.Initialize(Manifest.Cursors);
|
||||
Palette.Update(new IPaletteModifier[] { });
|
||||
}
|
||||
|
||||
public Map PrepareMap(string uid)
|
||||
|
||||
@@ -34,12 +34,23 @@ namespace OpenRA.Network
|
||||
void StartSavingReplay(byte[] initialContent)
|
||||
{
|
||||
var filename = chooseFilename();
|
||||
var replayPath = Path.Combine(Platform.SupportDir, "Replays");
|
||||
var replaysDirectory = Path.Combine(Platform.SupportDir, "Replays");
|
||||
|
||||
if (!Directory.Exists(replayPath))
|
||||
Directory.CreateDirectory(replayPath);
|
||||
if (!Directory.Exists(replaysDirectory))
|
||||
Directory.CreateDirectory(replaysDirectory);
|
||||
|
||||
var file = File.Create(Path.Combine(replayPath, filename));
|
||||
string fullFilename;
|
||||
var id = -1;
|
||||
do
|
||||
{
|
||||
fullFilename = Path.Combine(replaysDirectory, id < 0
|
||||
? "{0}.rep".F(filename)
|
||||
: "{0}-{1}.rep".F(filename, id));
|
||||
id++;
|
||||
}
|
||||
while (File.Exists(fullFilename));
|
||||
|
||||
var file = File.Create(fullFilename);
|
||||
file.Write(initialContent);
|
||||
this.writer = new BinaryWriter(file);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,9 @@ namespace OpenRA.Network
|
||||
public class Client
|
||||
{
|
||||
public int Index;
|
||||
public ColorRamp ColorRamp;
|
||||
public ColorRamp PreferredColorRamp; // Color that the client normally uses from settings.yaml.
|
||||
public ColorRamp ColorRamp; // Actual color that the client is using.
|
||||
// Usually the same as PreferredColorRamp but can be different on maps with locked colors.
|
||||
public string Country;
|
||||
public int SpawnPoint;
|
||||
public string Name;
|
||||
@@ -64,6 +66,7 @@ namespace OpenRA.Network
|
||||
public bool LockColor;
|
||||
public bool LockTeam;
|
||||
public bool LockSpawn;
|
||||
public bool Required;
|
||||
}
|
||||
|
||||
public class Global
|
||||
@@ -76,6 +79,9 @@ namespace OpenRA.Network
|
||||
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 Difficulty;
|
||||
public bool Crates = true;
|
||||
}
|
||||
|
||||
public Session(string[] mods)
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace OpenRA.Network
|
||||
{
|
||||
report.Frame = orderManager.NetFrameNumber;
|
||||
report.SyncedRandom = orderManager.world.SharedRandom.Last;
|
||||
report.TotalCount = orderManager.world.SharedRandom.TotalCount;
|
||||
report.Traits.Clear();
|
||||
foreach (var a in orderManager.world.ActorsWithTrait<ISync>())
|
||||
{
|
||||
@@ -58,7 +59,7 @@ namespace OpenRA.Network
|
||||
if (r.Frame == frame)
|
||||
{
|
||||
Log.Write("sync", "Sync for net frame {0} -------------", r.Frame);
|
||||
Log.Write("sync", "SharedRandom: "+r.SyncedRandom);
|
||||
Log.Write("sync", "SharedRandom: {0} (#{1})", r.SyncedRandom, r.TotalCount);
|
||||
Log.Write("sync", "Synced Traits:");
|
||||
foreach (var a in r.Traits)
|
||||
Log.Write("sync", "\t {0} {1} {2} {3} ({4})".F(
|
||||
@@ -77,6 +78,7 @@ namespace OpenRA.Network
|
||||
{
|
||||
public int Frame;
|
||||
public int SyncedRandom;
|
||||
public int TotalCount;
|
||||
public List<TraitReport> Traits = new List<TraitReport>();
|
||||
}
|
||||
|
||||
|
||||
@@ -111,7 +111,11 @@ namespace OpenRA.Network
|
||||
case "HandshakeRequest":
|
||||
{
|
||||
var request = HandshakeRequest.Deserialize(order.TargetString);
|
||||
var localMods = orderManager.LobbyInfo.GlobalSettings.Mods.Select(m => "{0}@{1}".F(m,Mod.AllMods[m].Version)).ToArray();
|
||||
|
||||
// Check if mods match
|
||||
if (localMods.FirstOrDefault().ToString().Split('@')[0] != request.Mods.FirstOrDefault().ToString().Split('@')[0])
|
||||
throw new InvalidOperationException("Server's mod ({0}) and yours ({1}) don't match".F(localMods.FirstOrDefault().ToString().Split('@')[0], request.Mods.FirstOrDefault().ToString().Split('@')[0]));
|
||||
// Check that the map exists on the client
|
||||
if (!Game.modData.AvailableMaps.ContainsKey(request.Map))
|
||||
throw new InvalidOperationException("Missing map {0}".F(request.Map));
|
||||
@@ -119,6 +123,7 @@ namespace OpenRA.Network
|
||||
var info = new Session.Client()
|
||||
{
|
||||
Name = Game.Settings.Player.Name,
|
||||
PreferredColorRamp = Game.Settings.Player.ColorRamp,
|
||||
ColorRamp = Game.Settings.Player.ColorRamp,
|
||||
Country = "random",
|
||||
SpawnPoint = 0,
|
||||
@@ -126,7 +131,6 @@ namespace OpenRA.Network
|
||||
State = Session.ClientState.NotReady
|
||||
};
|
||||
|
||||
var localMods = orderManager.LobbyInfo.GlobalSettings.Mods.Select(m => "{0}@{1}".F(m,Mod.AllMods[m].Version)).ToArray();
|
||||
var response = new HandshakeResponse()
|
||||
{
|
||||
Client = info,
|
||||
@@ -198,8 +202,7 @@ namespace OpenRA.Network
|
||||
{
|
||||
var oldStance = p.Stances[target];
|
||||
p.Stances[target] = s;
|
||||
if (target == w.LocalPlayer)
|
||||
w.WorldActor.Trait<Shroud>().UpdatePlayerStance(w, p, oldStance, s);
|
||||
target.Shroud.UpdatePlayerStance(w, p, oldStance, s);
|
||||
|
||||
foreach (var nsc in w.ActorsWithTrait<INotifyStanceChanged>())
|
||||
nsc.Trait.StanceChanged(nsc.Actor, p, target, oldStance, s);
|
||||
|
||||
@@ -194,7 +194,8 @@
|
||||
<Compile Include="Widgets\DropDownButtonWidget.cs" />
|
||||
<Compile Include="Widgets\GridLayout.cs" />
|
||||
<Compile Include="Widgets\ImageWidget.cs" />
|
||||
<Compile Include="Widgets\LabelWidget.cs" />
|
||||
<Compile Include="Widgets\LabelWidget.cs" />
|
||||
<Compile Include="Widgets\LineGraphWidget.cs" />
|
||||
<Compile Include="Widgets\ListLayout.cs" />
|
||||
<Compile Include="Widgets\MapPreviewWidget.cs" />
|
||||
<Compile Include="Widgets\PasswordFieldWidget.cs" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -17,7 +17,7 @@ namespace OpenRA.Orders
|
||||
{
|
||||
class UnitOrderGenerator : IOrderGenerator
|
||||
{
|
||||
public IEnumerable<Order> Order( World world, CPos xy, MouseInput mi )
|
||||
public IEnumerable<Order> Order(World world, CPos xy, MouseInput mi)
|
||||
{
|
||||
var underCursor = world.FindUnitsAtMouse(mi.Location)
|
||||
.Where(a => a.HasTrait<ITargetable>())
|
||||
@@ -41,9 +41,9 @@ namespace OpenRA.Orders
|
||||
yield return CheckSameOrder(o.iot, o.trait.IssueOrder(o.self, o.iot, o.target, mi.Modifiers.HasModifier(Modifiers.Shift)));
|
||||
}
|
||||
|
||||
public void Tick( World world ) { }
|
||||
public void RenderBeforeWorld( WorldRenderer wr, World world ) { }
|
||||
public void RenderAfterWorld( WorldRenderer wr, World world ) { }
|
||||
public void Tick(World world) { }
|
||||
public void RenderBeforeWorld(WorldRenderer wr, World world) { }
|
||||
public void RenderAfterWorld(WorldRenderer wr, World world) { }
|
||||
|
||||
public string GetCursor(World world, CPos xy, MouseInput mi)
|
||||
{
|
||||
@@ -75,35 +75,35 @@ namespace OpenRA.Orders
|
||||
if (self.Destroyed)
|
||||
return null;
|
||||
|
||||
if( mi.Button == MouseButton.Right )
|
||||
if (mi.Button == Game.mouseButtonPreference.Action)
|
||||
{
|
||||
foreach( var o in self.TraitsImplementing<IIssueOrder>()
|
||||
.SelectMany( trait => trait.Orders
|
||||
.Select( x => new { Trait = trait, Order = x } ) )
|
||||
.OrderByDescending( x => x.Order.OrderPriority ) )
|
||||
.SelectMany(trait => trait.Orders
|
||||
.Select(x => new { Trait = trait, Order = x } ))
|
||||
.OrderByDescending(x => x.Order.OrderPriority))
|
||||
{
|
||||
var actorsAt = self.World.ActorMap.GetUnitsAt( xy ).ToList();
|
||||
var actorsAt = self.World.ActorMap.GetUnitsAt(xy).ToList();
|
||||
|
||||
var forceAttack = mi.Modifiers.HasModifier(Modifiers.Ctrl);
|
||||
var forceQueue = mi.Modifiers.HasModifier(Modifiers.Shift);
|
||||
string cursor = null;
|
||||
if( underCursor != null )
|
||||
if (underCursor != null)
|
||||
if (o.Order.CanTargetActor(self, underCursor, forceAttack, forceQueue, ref cursor))
|
||||
return new UnitOrderResult( self, o.Order, o.Trait, cursor, Target.FromActor( underCursor ) );
|
||||
return new UnitOrderResult(self, o.Order, o.Trait, cursor, Target.FromActor(underCursor));
|
||||
if (o.Order.CanTargetLocation(self, xy, actorsAt, forceAttack, forceQueue, ref cursor))
|
||||
return new UnitOrderResult( self, o.Order, o.Trait, cursor, Target.FromCell( xy ) );
|
||||
return new UnitOrderResult(self, o.Order, o.Trait, cursor, Target.FromCell(xy));
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static Order CheckSameOrder( IOrderTargeter iot, Order order )
|
||||
static Order CheckSameOrder(IOrderTargeter iot, Order order)
|
||||
{
|
||||
if( order == null && iot.OrderID != null )
|
||||
Game.Debug( "BUG: in order targeter - decided on {0} but then didn't order", iot.OrderID );
|
||||
else if( iot.OrderID != order.OrderString )
|
||||
Game.Debug( "BUG: in order targeter - decided on {0} but ordered {1}", iot.OrderID, order.OrderString );
|
||||
if (order == null && iot.OrderID != null)
|
||||
Game.Debug("BUG: in order targeter - decided on {0} but then didn't order", iot.OrderID);
|
||||
else if (iot.OrderID != order.OrderString)
|
||||
Game.Debug("BUG: in order targeter - decided on {0} but ordered {1}", iot.OrderID, order.OrderString);
|
||||
return order;
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace OpenRA.Orders
|
||||
public readonly string cursor;
|
||||
public readonly Target target;
|
||||
|
||||
public UnitOrderResult( Actor self, IOrderTargeter iot, IIssueOrder trait, string cursor, Target target )
|
||||
public UnitOrderResult(Actor self, IOrderTargeter iot, IIssueOrder trait, string cursor, Target target)
|
||||
{
|
||||
this.self = self;
|
||||
this.iot = iot;
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace OpenRA
|
||||
public readonly PlayerReference PlayerReference;
|
||||
public bool IsBot;
|
||||
|
||||
public Shroud Shroud { get { return World.LocalShroud; } }
|
||||
public Shroud Shroud;
|
||||
public World World { get; private set; }
|
||||
|
||||
static CountryInfo ChooseCountry(World world, string name)
|
||||
@@ -76,7 +76,8 @@ namespace OpenRA
|
||||
Country = ChooseCountry(world, pr.Race);
|
||||
}
|
||||
PlayerActor = world.CreateActor("Player", new TypeDictionary { new OwnerInit(this) });
|
||||
|
||||
Shroud = PlayerActor.Trait<Shroud>();
|
||||
Shroud.Owner = this;
|
||||
// Enable the bot logic on the host
|
||||
IsBot = botType != null;
|
||||
if (IsBot && Game.IsHost)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -64,7 +64,7 @@ namespace OpenRA
|
||||
|
||||
Cache<int, List<Actor>> controlGroups = new Cache<int, List<Actor>>(_ => new List<Actor>());
|
||||
|
||||
public void DoControlGroup(World world, int group, Modifiers mods)
|
||||
public void DoControlGroup(World world, int group, Modifiers mods, int MultiTapCount)
|
||||
{
|
||||
var addModifier = Platform.CurrentPlatform == PlatformType.OSX ? Modifiers.Meta : Modifiers.Ctrl;
|
||||
if (mods.HasModifier(addModifier))
|
||||
@@ -82,7 +82,7 @@ namespace OpenRA
|
||||
return;
|
||||
}
|
||||
|
||||
if (mods.HasModifier(Modifiers.Alt))
|
||||
if (mods.HasModifier(Modifiers.Alt) || MultiTapCount >= 2)
|
||||
{
|
||||
Game.viewport.Center(controlGroups[group]);
|
||||
return;
|
||||
|
||||
@@ -26,6 +26,13 @@ using XTimer = System.Timers.Timer;
|
||||
|
||||
namespace OpenRA.Server
|
||||
{
|
||||
public enum ServerState : int
|
||||
{
|
||||
WaitingPlayers = 1,
|
||||
GameStarted = 2,
|
||||
ShuttingDown = 3
|
||||
}
|
||||
|
||||
public class Server
|
||||
{
|
||||
// Valid player connections
|
||||
@@ -40,7 +47,7 @@ namespace OpenRA.Server
|
||||
|
||||
TypeDictionary ServerTraits = new TypeDictionary();
|
||||
public Session lobbyInfo;
|
||||
public bool GameStarted = false;
|
||||
|
||||
public readonly IPAddress Ip;
|
||||
public readonly int Port;
|
||||
int randomSeed;
|
||||
@@ -51,16 +58,31 @@ namespace OpenRA.Server
|
||||
public Map Map;
|
||||
XTimer gameTimeout;
|
||||
|
||||
volatile bool shutdown = false;
|
||||
protected volatile ServerState pState = new ServerState();
|
||||
public ServerState State
|
||||
{
|
||||
get { return pState; }
|
||||
protected set { pState = value; }
|
||||
}
|
||||
|
||||
public void Shutdown()
|
||||
{
|
||||
shutdown = true;
|
||||
State = ServerState.ShuttingDown;
|
||||
}
|
||||
|
||||
public void EndGame()
|
||||
{
|
||||
foreach (var t in ServerTraits.WithInterface<IEndGame>())
|
||||
t.GameEnded(this);
|
||||
if (Settings.AllowUPnP)
|
||||
RemovePortforward();
|
||||
}
|
||||
|
||||
public Server(IPEndPoint endpoint, string[] mods, ServerSettings settings, ModData modData)
|
||||
{
|
||||
Log.AddChannel("server", "server.log");
|
||||
|
||||
pState = ServerState.WaitingPlayers;
|
||||
listener = new TcpListener(endpoint);
|
||||
listener.Start();
|
||||
var localEndpoint = (IPEndPoint)listener.LocalEndpoint;
|
||||
@@ -118,6 +140,7 @@ namespace OpenRA.Server
|
||||
lobbyInfo.GlobalSettings.Map = settings.Map;
|
||||
lobbyInfo.GlobalSettings.ServerName = settings.Name;
|
||||
lobbyInfo.GlobalSettings.Ban = settings.Ban;
|
||||
lobbyInfo.GlobalSettings.Dedicated = settings.Dedicated;
|
||||
|
||||
foreach (var t in ServerTraits.WithInterface<INotifyServerStart>())
|
||||
t.ServerStarted(this);
|
||||
@@ -139,10 +162,9 @@ namespace OpenRA.Server
|
||||
foreach( var c in preConns ) checkRead.Add( c.socket );
|
||||
|
||||
Socket.Select( checkRead, null, null, timeout );
|
||||
if (shutdown)
|
||||
if (State == ServerState.ShuttingDown)
|
||||
{
|
||||
if (Settings.AllowUPnP)
|
||||
RemovePortforward();
|
||||
EndGame();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -158,15 +180,13 @@ namespace OpenRA.Server
|
||||
foreach (var t in ServerTraits.WithInterface<ITick>())
|
||||
t.Tick(this);
|
||||
|
||||
if (shutdown)
|
||||
if (State == ServerState.ShuttingDown)
|
||||
{
|
||||
if (Settings.AllowUPnP)
|
||||
RemovePortforward();
|
||||
EndGame();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GameStarted = false;
|
||||
foreach (var t in ServerTraits.WithInterface<INotifyServerShutdown>())
|
||||
t.ServerShutdown(this);
|
||||
|
||||
@@ -244,7 +264,7 @@ namespace OpenRA.Server
|
||||
{
|
||||
try
|
||||
{
|
||||
if (GameStarted)
|
||||
if (State == ServerState.GameStarted)
|
||||
{
|
||||
Log.Write("server", "Rejected connection from {0}; game is already started.",
|
||||
newConn.socket.RemoteEndPoint);
|
||||
@@ -263,7 +283,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.",
|
||||
@@ -273,6 +293,17 @@ 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)
|
||||
@@ -302,9 +333,11 @@ namespace OpenRA.Server
|
||||
|
||||
lobbyInfo.Clients.Add(client);
|
||||
//Assume that first validated client is server admin
|
||||
if(lobbyInfo.Clients.Count==1)
|
||||
if(lobbyInfo.Clients.Where(c1 => c1.Bot == null).Count()==1)
|
||||
client.IsAdmin=true;
|
||||
|
||||
OpenRA.Network.Session.Client clientAdmin = lobbyInfo.Clients.Where(c1 => c1.IsAdmin).Single();
|
||||
|
||||
Log.Write("server", "Client {0}: Accepted connection from {1}",
|
||||
newConn.PlayerIndex, newConn.socket.RemoteEndPoint);
|
||||
|
||||
@@ -314,6 +347,20 @@ namespace OpenRA.Server
|
||||
SyncLobbyInfo();
|
||||
SendChat(newConn, "has joined the game.");
|
||||
|
||||
if ( File.Exists("{0}motd_{1}.txt".F(Platform.SupportDir, lobbyInfo.GlobalSettings.Mods[0])) )
|
||||
{
|
||||
var motd = System.IO.File.ReadAllText("{0}motd_{1}.txt".F(Platform.SupportDir, lobbyInfo.GlobalSettings.Mods[0]));
|
||||
SendChatTo(newConn, motd);
|
||||
}
|
||||
|
||||
if ( lobbyInfo.GlobalSettings.Dedicated )
|
||||
{
|
||||
if (client.IsAdmin)
|
||||
SendChatTo(newConn, " You are admin now!");
|
||||
else
|
||||
SendChatTo(newConn, " Current admin is {0}".F(clientAdmin.Name));
|
||||
}
|
||||
|
||||
if (mods.Any(m => m.Contains("{DEV_VERSION}")))
|
||||
SendChat(newConn, "is running a development version, "+
|
||||
"and may cause desync if they have any incompatible changes.");
|
||||
@@ -327,6 +374,8 @@ namespace OpenRA.Server
|
||||
return;
|
||||
if (pr.LockColor)
|
||||
c.ColorRamp = pr.ColorRamp;
|
||||
else
|
||||
c.ColorRamp = c.PreferredColorRamp;
|
||||
if (pr.LockRace)
|
||||
c.Country = pr.Race;
|
||||
if (pr.LockSpawn)
|
||||
@@ -467,15 +516,29 @@ namespace OpenRA.Server
|
||||
{
|
||||
conns.Remove(toDrop);
|
||||
SendChat(toDrop, "Connection Dropped");
|
||||
|
||||
if (GameStarted)
|
||||
|
||||
OpenRA.Network.Session.Client dropClient = lobbyInfo.Clients.Where(c1 => c1.Index == toDrop.PlayerIndex).Single();
|
||||
|
||||
if (State == ServerState.GameStarted)
|
||||
SendDisconnected(toDrop); /* Report disconnection */
|
||||
|
||||
lobbyInfo.Clients.RemoveAll(c => c.Index == toDrop.PlayerIndex);
|
||||
|
||||
// reassign admin if necessary
|
||||
if ( lobbyInfo.GlobalSettings.Dedicated && dropClient.IsAdmin && State == ServerState.WaitingPlayers)
|
||||
{
|
||||
if (lobbyInfo.Clients.Where(c1 => c1.Bot == null).Count() > 0)
|
||||
{
|
||||
// client was not alone on the server but he was admin: set admin to the last connected client
|
||||
OpenRA.Network.Session.Client lastClient = lobbyInfo.Clients.Where(c1 => c1.Bot == null).Last();
|
||||
lastClient.IsAdmin = true;
|
||||
SendChat(toDrop, "Admin left! {0} is a new admin now!".F(lastClient.Name));
|
||||
}
|
||||
}
|
||||
|
||||
DispatchOrders( toDrop, toDrop.MostRecentFrame, new byte[] { 0xbf } );
|
||||
|
||||
if (conns.Count != 0)
|
||||
if (conns.Count != 0 || lobbyInfo.GlobalSettings.Dedicated)
|
||||
SyncLobbyInfo();
|
||||
}
|
||||
|
||||
@@ -488,7 +551,7 @@ namespace OpenRA.Server
|
||||
|
||||
public void SyncLobbyInfo()
|
||||
{
|
||||
if (!GameStarted) /* don't do this while the game is running, it breaks things. */
|
||||
if (State != ServerState.GameStarted) /* don't do this while the game is running, it breaks things. */
|
||||
DispatchOrders(null, 0,
|
||||
new ServerOrder("SyncInfo", lobbyInfo.Serialize()).Serialize());
|
||||
|
||||
@@ -498,8 +561,9 @@ namespace OpenRA.Server
|
||||
|
||||
public void StartGame()
|
||||
{
|
||||
GameStarted = true;
|
||||
State = ServerState.GameStarted;
|
||||
listener.Stop();
|
||||
|
||||
Console.WriteLine("Game started");
|
||||
|
||||
foreach( var c in conns )
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace OpenRA.Server
|
||||
public interface INotifyServerShutdown { void ServerShutdown(Server server); }
|
||||
public interface IStartGame { void GameStarted(Server server); }
|
||||
public interface IClientJoined { void ClientJoined(Server server, Connection conn); }
|
||||
public interface IEndGame { void GameEnded(Server server); }
|
||||
public interface ITick
|
||||
{
|
||||
void Tick(Server server);
|
||||
@@ -28,7 +29,7 @@ namespace OpenRA.Server
|
||||
|
||||
public abstract class ServerTrait {}
|
||||
|
||||
public class DebugServerTrait : ServerTrait, IInterpretCommand, IStartGame, INotifySyncLobbyInfo, INotifyServerStart, INotifyServerShutdown
|
||||
public class DebugServerTrait : ServerTrait, IInterpretCommand, IStartGame, INotifySyncLobbyInfo, INotifyServerStart, INotifyServerShutdown, IEndGame
|
||||
{
|
||||
public bool InterpretCommand(Server server, Connection conn, Session.Client client, string cmd)
|
||||
{
|
||||
@@ -55,5 +56,10 @@ namespace OpenRA.Server
|
||||
{
|
||||
Console.WriteLine("ServerShutdown()");
|
||||
}
|
||||
|
||||
public void GameEnded(Server server)
|
||||
{
|
||||
Console.WriteLine("GameEnded()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,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();
|
||||
@@ -247,7 +248,7 @@ namespace OpenRA
|
||||
}
|
||||
|
||||
// Returns true if played successfully
|
||||
public static bool PlayPredefined(Player p, Actor voicedUnit, string type, string definition, string variant)
|
||||
public static bool PlayPredefined(Player p, Actor voicedUnit, string type, string definition, string variant, bool attentuateVolume)
|
||||
{
|
||||
if (definition == null) return false;
|
||||
|
||||
@@ -281,10 +282,13 @@ namespace OpenRA
|
||||
prefix = rules.Prefixes[variant][ID % rules.Prefixes[variant].Length];
|
||||
}
|
||||
|
||||
if (p == null)
|
||||
Play(prefix + clip + suffix);
|
||||
else
|
||||
PlayToPlayer(p, prefix + clip + suffix);
|
||||
var name = prefix + clip + suffix;
|
||||
|
||||
if (!String.IsNullOrEmpty(name) && (p == null || p == p.World.LocalPlayer))
|
||||
soundEngine.Play2D(sounds[name],
|
||||
false, true, float2.Zero,
|
||||
InternalSoundVolume, attentuateVolume);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -297,9 +301,9 @@ namespace OpenRA
|
||||
if (mi == null) return false;
|
||||
if (mi.Voice == null) return false;
|
||||
|
||||
var type = mi.Voice.ToLowerInvariant();
|
||||
var type = mi.Voice.ToLowerInvariant();
|
||||
|
||||
return PlayPredefined(null, voicedUnit, type, phrase, variant);
|
||||
return PlayPredefined(null, voicedUnit, type, phrase, variant, true);
|
||||
}
|
||||
|
||||
public static bool PlayNotification(Player player, string type, string notification, string variant)
|
||||
@@ -307,7 +311,7 @@ namespace OpenRA
|
||||
if (type == null) return false;
|
||||
if (notification == null) return false;
|
||||
|
||||
return PlayPredefined(player, null, type.ToLowerInvariant(), notification, variant);
|
||||
return PlayPredefined(player, null, type.ToLowerInvariant(), notification, variant, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@ namespace OpenRA.Traits
|
||||
public class CreatesShroud : ITick
|
||||
{
|
||||
CreatesShroudInfo Info;
|
||||
CPos previousLocation;
|
||||
Shroud.ActorVisibility v;
|
||||
|
||||
public CreatesShroud(CreatesShroudInfo info)
|
||||
{
|
||||
@@ -29,8 +31,34 @@ namespace OpenRA.Traits
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
if (!self.IsDisabled())
|
||||
self.World.WorldActor.Trait<Shroud>().HideActor(self, Info.Range);
|
||||
// todo: don't tick all the time.
|
||||
if(self.Owner == null) return;
|
||||
|
||||
if (previousLocation != self.Location && v != null) {
|
||||
previousLocation = self.Location;
|
||||
|
||||
var shrouds = self.World.ActorsWithTrait<Traits.Shroud>().Select(s => s.Actor.Owner.Shroud);
|
||||
foreach (var shroud in shrouds) {
|
||||
shroud.UnhideActor(self, v, Info.Range);
|
||||
}
|
||||
}
|
||||
|
||||
if (!self.TraitsImplementing<IDisable>().Any(d => d.Disabled)) {
|
||||
var shrouds = self.World.ActorsWithTrait<Traits.Shroud>().Select(s => s.Actor.Owner.Shroud);
|
||||
foreach (var shroud in shrouds) {
|
||||
shroud.HideActor(self, Info.Range);
|
||||
}
|
||||
}
|
||||
else {
|
||||
var shrouds = self.World.ActorsWithTrait<Traits.Shroud>().Select(s => s.Actor.Owner.Shroud);
|
||||
foreach (var shroud in shrouds) {
|
||||
shroud.UnhideActor(self, v, Info.Range);
|
||||
}
|
||||
}
|
||||
|
||||
v = new Shroud.ActorVisibility {
|
||||
vis = Shroud.GetVisOrigins(self).ToArray()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ namespace OpenRA.Traits
|
||||
public class EditorAppearanceInfo : TraitInfo<EditorAppearance>
|
||||
{
|
||||
public readonly bool RelativeToTopLeft = false;
|
||||
public readonly bool UseTerrainPalette = false;
|
||||
}
|
||||
|
||||
public class EditorAppearance { }
|
||||
|
||||
@@ -76,8 +76,7 @@ namespace OpenRA.Traits
|
||||
case "DevShroud":
|
||||
{
|
||||
DisableShroud ^= true;
|
||||
if (self.World.LocalPlayer == self.Owner)
|
||||
self.World.LocalShroud.Disabled = DisableShroud;
|
||||
self.Owner.Shroud.Disabled = DisableShroud;
|
||||
break;
|
||||
}
|
||||
case "DevPathDebug":
|
||||
@@ -87,8 +86,7 @@ namespace OpenRA.Traits
|
||||
}
|
||||
case "DevGiveExploration":
|
||||
{
|
||||
if (self.World.LocalPlayer == self.Owner)
|
||||
self.World.WorldActor.Trait<Shroud>().ExploreAll(self.World);
|
||||
self.Owner.Shroud.ExploreAll(self.World);
|
||||
break;
|
||||
}
|
||||
case "DevUnlimitedPower":
|
||||
|
||||
@@ -86,6 +86,9 @@ namespace OpenRA.Traits
|
||||
public int DisplayCash;
|
||||
public int DisplayOre;
|
||||
|
||||
public int Earned;
|
||||
public int Spent;
|
||||
|
||||
public bool CanGiveOre(int amount)
|
||||
{
|
||||
return Ore + amount <= OreCapacity;
|
||||
@@ -94,10 +97,13 @@ namespace OpenRA.Traits
|
||||
public void GiveOre(int num)
|
||||
{
|
||||
Ore += num;
|
||||
Earned += num;
|
||||
|
||||
if (Ore > OreCapacity)
|
||||
{
|
||||
nextSiloAdviceTime = 0;
|
||||
|
||||
Earned -= Ore - OreCapacity;
|
||||
Ore = OreCapacity;
|
||||
}
|
||||
}
|
||||
@@ -106,6 +112,7 @@ namespace OpenRA.Traits
|
||||
{
|
||||
if (Ore < num) return false;
|
||||
Ore -= num;
|
||||
Spent += num;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -113,6 +120,7 @@ namespace OpenRA.Traits
|
||||
public void GiveCash(int num)
|
||||
{
|
||||
Cash += num;
|
||||
Earned += num;
|
||||
}
|
||||
|
||||
public bool TakeCash(int num)
|
||||
@@ -121,6 +129,7 @@ namespace OpenRA.Traits
|
||||
|
||||
// Spend ore before cash
|
||||
Ore -= num;
|
||||
Spent += num;
|
||||
if (Ore < 0)
|
||||
{
|
||||
Cash += Ore;
|
||||
@@ -184,7 +193,7 @@ namespace OpenRA.Traits
|
||||
{
|
||||
DisplayOre -= move;
|
||||
playCashTickDown(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
@@ -23,16 +24,16 @@ namespace OpenRA.Traits
|
||||
|
||||
public virtual object Create(ActorInitializer init) { return new RenderSimple(init.self); }
|
||||
|
||||
public virtual IEnumerable<Renderable> RenderPreview(ActorInfo building, Player owner)
|
||||
public virtual IEnumerable<Renderable> RenderPreview(ActorInfo building, PaletteReference pr)
|
||||
{
|
||||
var anim = new Animation(RenderSimple.GetImage(building), () => 0);
|
||||
anim.PlayRepeating("idle");
|
||||
yield return new Renderable(anim.Image, 0.5f * anim.Image.size * (1 - Scale),
|
||||
Palette ?? (owner != null ? PlayerPalette + owner.InternalName : null), 0, Scale);
|
||||
|
||||
yield return new Renderable(anim.Image, 0.5f * anim.Image.size * (1 - Scale), pr, 0, Scale);
|
||||
}
|
||||
}
|
||||
|
||||
public class RenderSimple : IRender, ITick
|
||||
public class RenderSimple : IRender, IAutoSelectionSize, ITick, INotifyOwnerChanged
|
||||
{
|
||||
public Dictionary<string, AnimationWithOffset> anims = new Dictionary<string, AnimationWithOffset>();
|
||||
|
||||
@@ -55,7 +56,6 @@ namespace OpenRA.Traits
|
||||
return Info.Image ?? actor.Name;
|
||||
}
|
||||
|
||||
string cachedImage = null;
|
||||
public string GetImage(Actor self)
|
||||
{
|
||||
if (cachedImage != null)
|
||||
@@ -65,6 +65,9 @@ namespace OpenRA.Traits
|
||||
}
|
||||
|
||||
RenderSimpleInfo Info;
|
||||
string cachedImage = null;
|
||||
bool initializePalette = true;
|
||||
protected PaletteReference palette;
|
||||
|
||||
public RenderSimple(Actor self, Func<int> baseFacing)
|
||||
{
|
||||
@@ -77,20 +80,40 @@ namespace OpenRA.Traits
|
||||
anim.PlayRepeating("idle");
|
||||
}
|
||||
|
||||
public string Palette(Player p) { return Info.Palette ?? Info.PlayerPalette + p.InternalName; }
|
||||
|
||||
public virtual IEnumerable<Renderable> Render(Actor self)
|
||||
protected virtual string PaletteName(Actor self)
|
||||
{
|
||||
return Info.Palette ?? Info.PlayerPalette + self.Owner.InternalName;
|
||||
}
|
||||
|
||||
protected void UpdatePalette() { initializePalette = true; }
|
||||
public void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner) { UpdatePalette(); }
|
||||
|
||||
public virtual IEnumerable<Renderable> Render(Actor self, WorldRenderer wr)
|
||||
{
|
||||
if (initializePalette)
|
||||
{
|
||||
palette = wr.Palette(PaletteName(self));
|
||||
initializePalette = false;
|
||||
}
|
||||
|
||||
foreach (var a in anims.Values)
|
||||
if (a.DisableFunc == null || !a.DisableFunc())
|
||||
{
|
||||
Renderable ret = a.Image(self, Palette(self.Owner));
|
||||
Renderable ret = a.Image(self, palette);
|
||||
if (Info.Scale != 1f)
|
||||
ret = ret.WithScale(Info.Scale).WithPos(ret.Pos + 0.5f * ret.Sprite.size * (1 - Info.Scale));
|
||||
yield return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public int2 SelectionSize(Actor self)
|
||||
{
|
||||
return anims.Values.Where(b => (b.DisableFunc == null || !b.DisableFunc())
|
||||
&& b.Animation.CurrentSequence != null)
|
||||
.Select(a => (a.Animation.Image.size*Info.Scale).ToInt2())
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
public virtual void Tick(Actor self)
|
||||
{
|
||||
foreach (var a in anims.Values)
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
class RevealsShroudInfo : ITraitInfo
|
||||
public class RevealsShroudInfo : ITraitInfo
|
||||
{
|
||||
public readonly int Range = 0;
|
||||
public object Create(ActorInitializer init) { return new RevealsShroud(this); }
|
||||
}
|
||||
|
||||
class RevealsShroud : ITick
|
||||
public class RevealsShroud : ITick
|
||||
{
|
||||
RevealsShroudInfo Info;
|
||||
CPos previousLocation;
|
||||
@@ -29,11 +29,22 @@ namespace OpenRA.Traits
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
// todo: don't tick all the time.
|
||||
|
||||
World w = self.World;
|
||||
if(self.Owner == null) return;
|
||||
|
||||
if (previousLocation != self.Location)
|
||||
{
|
||||
previousLocation = self.Location;
|
||||
self.World.WorldActor.Trait<Shroud>().UpdateActor(self);
|
||||
var actors = w.ActorsWithTrait<Shroud>();
|
||||
|
||||
foreach( var s in actors )
|
||||
s.Actor.Owner.Shroud.RemoveActor(self);
|
||||
|
||||
self.UpdateSight();
|
||||
|
||||
foreach( var s in actors )
|
||||
s.Actor.Owner.Shroud.AddActor(self);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace OpenRA.Traits
|
||||
|
||||
void DrawPips(WorldRenderer wr, Actor self, float2 basePosition)
|
||||
{
|
||||
if (self.Owner != self.World.LocalPlayer) return;
|
||||
if (self.Owner != self.World.RenderedPlayer) return;
|
||||
|
||||
var pipSources = self.TraitsImplementing<IPips>();
|
||||
if (pipSources.Count() == 0)
|
||||
@@ -95,7 +95,7 @@ namespace OpenRA.Traits
|
||||
|
||||
void DrawTags(WorldRenderer wr, Actor self, float2 basePosition)
|
||||
{
|
||||
if (self.Owner != self.World.LocalPlayer) return;
|
||||
if (self.Owner != self.World.RenderedPlayer) return;
|
||||
|
||||
// If a mod wants to implement a unit with multiple tags, then they are placed on multiple rows
|
||||
var tagxyBase = basePosition + new float2(-16, 2); // Correct for the offset in the shp file
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenRA.Traits
|
||||
|
||||
public static readonly Target None = new Target();
|
||||
|
||||
public bool IsValid { get { return valid && (actor == null || (actor.IsInWorld && actor.Owner == owner)); } }
|
||||
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; } }
|
||||
|
||||
|
||||
@@ -34,7 +34,8 @@ namespace OpenRA.Traits
|
||||
}
|
||||
|
||||
public interface ITick { void Tick(Actor self); }
|
||||
public interface IRender { IEnumerable<Renderable> Render(Actor self); }
|
||||
public interface IRender { IEnumerable<Renderable> Render(Actor self, WorldRenderer wr); }
|
||||
public interface IAutoSelectionSize { int2 SelectionSize(Actor self); }
|
||||
|
||||
public interface IIssueOrder
|
||||
{
|
||||
@@ -62,6 +63,7 @@ namespace OpenRA.Traits
|
||||
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, CPos exit); }
|
||||
public interface INotifyOwnerChanged { void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner); }
|
||||
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); }
|
||||
@@ -83,7 +85,7 @@ namespace OpenRA.Traits
|
||||
Color RadarSignatureColor(Actor self);
|
||||
}
|
||||
|
||||
public interface IVisibilityModifier { bool IsVisible(Actor self); }
|
||||
public interface IVisibilityModifier { bool IsVisible(Shroud s, Actor self); }
|
||||
public interface IRadarColorModifier { Color RadarColorOverride(Actor self); }
|
||||
public interface IHasLocation { PPos PxPosition { get; } }
|
||||
|
||||
@@ -113,7 +115,7 @@ namespace OpenRA.Traits
|
||||
}
|
||||
|
||||
public interface INotifyAttack { void Attacking(Actor self, Target target); }
|
||||
public interface IRenderModifier { IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r); }
|
||||
public interface IRenderModifier { IEnumerable<Renderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<Renderable> r); }
|
||||
public interface IDamageModifier { float GetDamageModifier(Actor attacker, WarheadInfo warhead); }
|
||||
public interface ISpeedModifier { decimal GetSpeedModifier(); }
|
||||
public interface IFirepowerModifier { float GetFirepowerModifier(); }
|
||||
@@ -154,12 +156,12 @@ namespace OpenRA.Traits
|
||||
{
|
||||
public readonly Sprite Sprite;
|
||||
public readonly float2 Pos;
|
||||
public readonly string Palette;
|
||||
public readonly PaletteReference Palette;
|
||||
public readonly int Z;
|
||||
public readonly int ZOffset;
|
||||
public float Scale;
|
||||
|
||||
public Renderable(Sprite sprite, float2 pos, string palette, int z, int zOffset, float scale)
|
||||
public Renderable(Sprite sprite, float2 pos, PaletteReference palette, int z, int zOffset, float scale)
|
||||
{
|
||||
Sprite = sprite;
|
||||
Pos = pos;
|
||||
@@ -169,14 +171,14 @@ namespace OpenRA.Traits
|
||||
Scale = scale; /* default */
|
||||
}
|
||||
|
||||
public Renderable(Sprite sprite, float2 pos, string palette, int z)
|
||||
public Renderable(Sprite sprite, float2 pos, PaletteReference palette, int z)
|
||||
: this(sprite, pos, palette, z, 0, 1f) { }
|
||||
|
||||
public Renderable(Sprite sprite, float2 pos, string palette, int z, float scale)
|
||||
public Renderable(Sprite sprite, float2 pos, PaletteReference palette, int z, float scale)
|
||||
: this(sprite, pos, palette, z, 0, scale) { }
|
||||
|
||||
public Renderable WithScale(float newScale) { return new Renderable(Sprite, Pos, Palette, Z, ZOffset, newScale); }
|
||||
public Renderable WithPalette(string newPalette) { return new Renderable(Sprite, Pos, newPalette, Z, ZOffset, Scale); }
|
||||
public Renderable WithPalette(PaletteReference newPalette) { return new Renderable(Sprite, Pos, newPalette, Z, ZOffset, Scale); }
|
||||
public Renderable WithZOffset(int newOffset) { return new Renderable(Sprite, Pos, Palette, Z, newOffset, Scale); }
|
||||
public Renderable WithPos(float2 newPos) { return new Renderable(Sprite, newPos, Palette, Z, ZOffset, Scale); }
|
||||
}
|
||||
@@ -208,7 +210,7 @@ namespace OpenRA.Traits
|
||||
|
||||
public interface IPostRenderSelection { void RenderAfterWorld(WorldRenderer wr); }
|
||||
public interface IPreRenderSelection { void RenderBeforeWorld(WorldRenderer wr, Actor self); }
|
||||
public interface IRenderAsTerrain { IEnumerable<Renderable> RenderAsTerrain(Actor self); }
|
||||
public interface IRenderAsTerrain { IEnumerable<Renderable> RenderAsTerrain(WorldRenderer wr, Actor self); }
|
||||
|
||||
public interface ITargetable
|
||||
{
|
||||
@@ -226,7 +228,7 @@ namespace OpenRA.Traits
|
||||
public interface ILintPass { void Run(Action<string> emitError, Action<string> emitWarning); }
|
||||
|
||||
public interface IObjectivesPanel { string ObjectivesPanel { get; } }
|
||||
|
||||
|
||||
public static class DisableExts
|
||||
{
|
||||
public static bool IsDisabled(this Actor a)
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace OpenRA.Traits
|
||||
public readonly string BasePalette = null;
|
||||
public readonly string BaseName = "player";
|
||||
public readonly int[] RemapIndex = {};
|
||||
public readonly bool AllowModifiers = true;
|
||||
|
||||
public object Create( ActorInitializer init ) { return new PlayerColorPalette( init.self.Owner, this ); }
|
||||
}
|
||||
@@ -36,9 +37,9 @@ namespace OpenRA.Traits
|
||||
public void InitPalette( WorldRenderer wr )
|
||||
{
|
||||
var paletteName = "{0}{1}".F( info.BaseName, owner.InternalName );
|
||||
var newpal = new Palette(wr.GetPalette(info.BasePalette),
|
||||
var newpal = new Palette(wr.Palette(info.BasePalette).Palette,
|
||||
new PlayerColorRemap(info.RemapIndex, owner.ColorRamp));
|
||||
wr.AddPalette(paletteName, newpal);
|
||||
wr.AddPalette(paletteName, newpal, info.AllowModifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,21 +33,21 @@ namespace OpenRA.Traits
|
||||
{
|
||||
hasSetupPalettes = true;
|
||||
foreach (var rt in world.WorldActor.TraitsImplementing<ResourceType>())
|
||||
rt.info.PaletteIndex = wr.GetPaletteIndex(rt.info.Palette);
|
||||
rt.info.PaletteRef = wr.Palette(rt.info.Palette);
|
||||
}
|
||||
|
||||
var clip = Game.viewport.WorldBounds(world);
|
||||
for (int x = clip.Left; x < clip.Right; x++)
|
||||
for (int y = clip.Top; y < clip.Bottom; y++)
|
||||
{
|
||||
if (!world.LocalShroud.IsExplored(new CPos(x, y)))
|
||||
if (!world.RenderedShroud.IsExplored(new CPos(x, y)))
|
||||
continue;
|
||||
|
||||
var c = content[x, y];
|
||||
if (c.image != null)
|
||||
c.image[c.density].DrawAt(
|
||||
new CPos(x, y).ToPPos().ToFloat2(),
|
||||
c.type.info.PaletteIndex);
|
||||
c.type.info.PaletteRef.Index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace OpenRA.Traits
|
||||
public readonly bool AllowUnderActors = false;
|
||||
|
||||
public Sprite[][] Sprites;
|
||||
public int PaletteIndex;
|
||||
public PaletteReference PaletteRef;
|
||||
|
||||
public PipType PipColor = PipType.Yellow;
|
||||
|
||||
|
||||
@@ -25,16 +25,24 @@ namespace OpenRA.Traits
|
||||
Map map;
|
||||
World world;
|
||||
|
||||
public Player Owner;
|
||||
public int[,] visibleCells;
|
||||
public bool[,] exploredCells;
|
||||
Rectangle? exploredBounds;
|
||||
public bool[,] foggedCells;
|
||||
public Rectangle? exploredBounds;
|
||||
bool disabled = false;
|
||||
public bool dirty = true;
|
||||
public bool Disabled
|
||||
{
|
||||
get { return disabled || world.LocalPlayer == null; }
|
||||
get { return disabled; }
|
||||
set { disabled = value; Dirty(); }
|
||||
}
|
||||
|
||||
public bool Observing
|
||||
{
|
||||
get { return world.IsShellmap || (world.LocalPlayer == null && Owner == null);; }
|
||||
}
|
||||
|
||||
public Rectangle? Bounds
|
||||
{
|
||||
get { return Disabled ? null : exploredBounds; }
|
||||
@@ -42,20 +50,28 @@ namespace OpenRA.Traits
|
||||
|
||||
public event Action Dirty = () => { };
|
||||
|
||||
public void Jank()
|
||||
{
|
||||
Dirty();
|
||||
}
|
||||
|
||||
|
||||
public Shroud(World world)
|
||||
{
|
||||
this.world = world;
|
||||
map = world.Map;
|
||||
visibleCells = new int[map.MapSize.X, map.MapSize.Y];
|
||||
exploredCells = new bool[map.MapSize.X, map.MapSize.Y];
|
||||
foggedCells = new bool[map.MapSize.X, map.MapSize.Y];
|
||||
world.ActorAdded += AddActor;
|
||||
world.ActorRemoved += RemoveActor;
|
||||
Dirty += () => dirty = true;
|
||||
}
|
||||
|
||||
// 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 CPos[] vis; }
|
||||
Dictionary<Actor, ActorVisibility> vis = new Dictionary<Actor, ActorVisibility>();
|
||||
public class ActorVisibility { public int range; public CPos[] vis; }
|
||||
public Dictionary<Actor, ActorVisibility> vis = new Dictionary<Actor, ActorVisibility>();
|
||||
|
||||
static IEnumerable<CPos> FindVisibleTiles(World world, CPos a, int r)
|
||||
{
|
||||
@@ -72,25 +88,13 @@ namespace OpenRA.Traits
|
||||
yield return new CPos(i, j);
|
||||
}
|
||||
|
||||
void AddActor(Actor a)
|
||||
public void AddActor(Actor a)
|
||||
{
|
||||
if (!a.HasTrait<RevealsShroud>())
|
||||
return;
|
||||
if (!a.HasTrait<RevealsShroud>()) return;
|
||||
if (a.Owner == null || Owner == null) return;
|
||||
if(a.Owner.Stances[Owner] != Stance.Ally) return;
|
||||
|
||||
if (a.Owner.World.LocalPlayer == null
|
||||
|| a.Owner.Stances[a.Owner.World.LocalPlayer] != Stance.Ally) return;
|
||||
|
||||
if (vis.ContainsKey(a))
|
||||
{
|
||||
Game.Debug("Warning: Actor {0}:{1} at {2} bad vis".F(a.Info.Name, a.ActorID, a.Location));
|
||||
RemoveActor(a);
|
||||
}
|
||||
|
||||
var v = new ActorVisibility
|
||||
{
|
||||
range = a.Trait<RevealsShroud>().RevealRange,
|
||||
vis = GetVisOrigins(a).ToArray()
|
||||
};
|
||||
ActorVisibility v = a.Sight;
|
||||
|
||||
if (v.range == 0) return; // don't bother for things that can't see
|
||||
|
||||
@@ -100,14 +104,13 @@ namespace OpenRA.Traits
|
||||
{
|
||||
++visibleCells[q.X, q.Y];
|
||||
exploredCells[q.X, q.Y] = true;
|
||||
foggedCells[q.X, q.Y] = true;
|
||||
}
|
||||
|
||||
var box = new Rectangle(p.X - v.range, p.Y - v.range, 2 * v.range + 1, 2 * v.range + 1);
|
||||
exploredBounds = (exploredBounds.HasValue) ? Rectangle.Union(exploredBounds.Value, box) : box;
|
||||
}
|
||||
|
||||
vis[a] = v;
|
||||
|
||||
if (!Disabled)
|
||||
Dirty();
|
||||
}
|
||||
@@ -124,12 +127,39 @@ namespace OpenRA.Traits
|
||||
|
||||
foreach (var p in v.vis)
|
||||
foreach (var q in FindVisibleTiles(a.World, p, range))
|
||||
exploredCells[q.X, q.Y] = visibleCells[q.X, q.Y] > 0;
|
||||
foggedCells[q.X, q.Y] = visibleCells[q.X, q.Y] > 0;
|
||||
|
||||
if (!Disabled)
|
||||
Dirty();
|
||||
}
|
||||
|
||||
public void UnhideActor(Actor a, ActorVisibility v, int range) {
|
||||
if (a.Owner.World.LocalPlayer == null
|
||||
|| a.Owner.Stances[a.Owner.World.LocalPlayer] == Stance.Ally) return;
|
||||
|
||||
if (v == null)
|
||||
return;
|
||||
|
||||
foreach (var p in v.vis)
|
||||
foreach (var q in FindVisibleTiles(a.World, p, range))
|
||||
foggedCells[q.X, q.Y] = exploredCells[q.X, q.Y];
|
||||
|
||||
if (!Disabled)
|
||||
Dirty();
|
||||
}
|
||||
|
||||
public void MergeShroud(Shroud s) {
|
||||
for (int i = map.Bounds.Left; i < map.Bounds.Right; i++) {
|
||||
for (int j = map.Bounds.Top; j < map.Bounds.Bottom; j++) {
|
||||
if (s.exploredCells[i,j] == true)
|
||||
exploredCells[i, j] = true;
|
||||
if (s.foggedCells[i,j] == true)
|
||||
foggedCells[i, j] = true;
|
||||
}
|
||||
exploredBounds = Rectangle.Union(exploredBounds.Value, s.exploredBounds.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdatePlayerStance(World w, Player player, Stance oldStance, Stance newStance)
|
||||
{
|
||||
if (oldStance == newStance)
|
||||
@@ -138,7 +168,7 @@ namespace OpenRA.Traits
|
||||
// No longer our ally; remove unit vis
|
||||
if (oldStance == Stance.Ally)
|
||||
{
|
||||
var toRemove = vis.Select(a => a.Key).Where(a => a.Owner == player).ToList();
|
||||
var toRemove = w.Actors.Where(a => a.Owner == player).ToList();
|
||||
foreach (var a in toRemove)
|
||||
RemoveActor(a);
|
||||
}
|
||||
@@ -148,6 +178,16 @@ namespace OpenRA.Traits
|
||||
AddActor(a);
|
||||
}
|
||||
|
||||
public int Explored()
|
||||
{
|
||||
int seen = 0;
|
||||
for (int i = map.Bounds.Left; i < map.Bounds.Right; i++)
|
||||
for (int j = map.Bounds.Top; j < map.Bounds.Bottom; j++)
|
||||
if(foggedCells[i, j]) seen++;
|
||||
|
||||
return seen;
|
||||
}
|
||||
|
||||
public static IEnumerable<CPos> GetVisOrigins(Actor a)
|
||||
{
|
||||
var ios = a.OccupiesSpace;
|
||||
@@ -160,17 +200,26 @@ namespace OpenRA.Traits
|
||||
return new[] { a.CenterLocation.ToCPos() };
|
||||
}
|
||||
|
||||
void RemoveActor(Actor a)
|
||||
public void RemoveActor(Actor a)
|
||||
{
|
||||
ActorVisibility v;
|
||||
if (!vis.TryGetValue(a, out v)) return;
|
||||
if (!a.HasTrait<RevealsShroud>())return;
|
||||
if (a.Owner == null || Owner == null) return;
|
||||
|
||||
ActorVisibility v = a.Sight;
|
||||
|
||||
if(a.Owner.Stances[Owner] != Stance.Ally) {
|
||||
if (a.HasTrait<CreatesShroud>()) {
|
||||
foreach (var p in v.vis)
|
||||
foreach (var q in FindVisibleTiles(a.World, p, v.range))
|
||||
foggedCells[q.X, q.Y] = exploredCells[q.X, q.Y];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var p in v.vis)
|
||||
foreach (var q in FindVisibleTiles(a.World, p, v.range))
|
||||
--visibleCells[q.X, q.Y];
|
||||
|
||||
vis.Remove(a);
|
||||
|
||||
if (!Disabled)
|
||||
Dirty();
|
||||
}
|
||||
@@ -185,8 +234,10 @@ namespace OpenRA.Traits
|
||||
|
||||
public void Explore(World world, CPos center, int range)
|
||||
{
|
||||
foreach (var q in FindVisibleTiles(world, center, range))
|
||||
foreach (var q in FindVisibleTiles(world, center, range)) {
|
||||
exploredCells[q.X, q.Y] = true;
|
||||
foggedCells[q.X, q.Y] = true;
|
||||
}
|
||||
|
||||
var box = new Rectangle(center.X - range, center.Y - range, 2 * range + 1, 2 * range + 1);
|
||||
exploredBounds = (exploredBounds.HasValue) ? Rectangle.Union(exploredBounds.Value, box) : box;
|
||||
@@ -197,9 +248,12 @@ namespace OpenRA.Traits
|
||||
|
||||
public void ExploreAll(World world)
|
||||
{
|
||||
for (int i = map.Bounds.Left; i < map.Bounds.Right; i++)
|
||||
for (int j = map.Bounds.Top; j < map.Bounds.Bottom; j++)
|
||||
for (int i = map.Bounds.Left; i < map.Bounds.Right; i++) {
|
||||
for (int j = map.Bounds.Top; j < map.Bounds.Bottom; j++) {
|
||||
exploredCells[i, j] = true;
|
||||
foggedCells[i, j] = true;
|
||||
}
|
||||
}
|
||||
exploredBounds = world.Map.Bounds;
|
||||
|
||||
if (!Disabled)
|
||||
@@ -212,6 +266,10 @@ namespace OpenRA.Traits
|
||||
for (var i = 0; i <= exploredCells.GetUpperBound(0); i++)
|
||||
exploredCells[i, j] = visibleCells[i, j] > 0;
|
||||
|
||||
for (var j = 0; j <= foggedCells.GetUpperBound(1); j++)
|
||||
for (var i = 0; i <= foggedCells.GetUpperBound(0); i++)
|
||||
foggedCells[i, j] = visibleCells[i, j] > 0;
|
||||
|
||||
if (!Disabled)
|
||||
Dirty();
|
||||
}
|
||||
@@ -222,16 +280,16 @@ namespace OpenRA.Traits
|
||||
if (!map.IsInMap(x, y))
|
||||
return false;
|
||||
|
||||
if (Disabled)
|
||||
if (Disabled || Observing)
|
||||
return true;
|
||||
|
||||
return exploredCells[x,y];
|
||||
return foggedCells[x,y];
|
||||
}
|
||||
|
||||
public bool IsVisible(CPos xy) { return IsVisible(xy.X, xy.Y); }
|
||||
public bool IsVisible(int x, int y)
|
||||
{
|
||||
if (Disabled)
|
||||
if (Disabled || Observing)
|
||||
return true;
|
||||
|
||||
// Visibility is allowed to extend beyond the map cordon so that
|
||||
@@ -245,10 +303,20 @@ namespace OpenRA.Traits
|
||||
// Actors are hidden under shroud, but not under fog by default
|
||||
public bool IsVisible(Actor a)
|
||||
{
|
||||
if (a.TraitsImplementing<IVisibilityModifier>().Any(t => !t.IsVisible(a)))
|
||||
// I need to pass in the current shroud, otherwise we're just checking that true==true
|
||||
if (a.TraitsImplementing<IVisibilityModifier>().Any(t => !t.IsVisible(this, a)))
|
||||
return false;
|
||||
|
||||
return Disabled || a.Owner == a.World.LocalPlayer || GetVisOrigins(a).Any(o => IsExplored(o));
|
||||
if(Owner == null) return true;
|
||||
|
||||
return Disabled || Observing || a.Owner.Stances[Owner] == Stance.Ally || GetVisOrigins(a).Any(o => IsExplored(o));
|
||||
}
|
||||
|
||||
public bool IsTargetable(Actor a) {
|
||||
if (a.TraitsImplementing<IVisibilityModifier>().Any(t => !t.IsVisible(this, a)))
|
||||
return false;
|
||||
|
||||
return GetVisOrigins(a).Any(o => IsVisible(o));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,10 @@ namespace OpenRA.Widgets
|
||||
public int VisualHeight = ChromeMetrics.Get<int>("ButtonDepth");
|
||||
public string Font = ChromeMetrics.Get<string>("ButtonFont");
|
||||
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 = _ => {};
|
||||
|
||||
@@ -39,6 +41,7 @@ namespace OpenRA.Widgets
|
||||
OnMouseUp = _ => OnClick();
|
||||
OnKeyPress = _ => OnClick();
|
||||
IsDisabled = () => Disabled;
|
||||
IsHighlighted = () => Highlighted;
|
||||
}
|
||||
|
||||
protected ButtonWidget(ButtonWidget widget)
|
||||
@@ -52,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();
|
||||
@@ -124,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);
|
||||
}
|
||||
@@ -138,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);
|
||||
}
|
||||
|
||||
@@ -46,19 +46,26 @@ namespace OpenRA.Widgets
|
||||
|
||||
foreach (var line in recentLines.AsEnumerable().Reverse())
|
||||
{
|
||||
chatpos.Y -= 20;
|
||||
var inset = 0;
|
||||
string owner = null;
|
||||
|
||||
if (!string.IsNullOrEmpty(line.Owner))
|
||||
{
|
||||
var owner = line.Owner + ":";
|
||||
owner = line.Owner + ":";
|
||||
inset = font.Measure(owner).X + 10;
|
||||
}
|
||||
|
||||
var text = WidgetUtils.WrapText(line.Text, chatLogArea.Width - inset, font);
|
||||
var textLines = text.Split(new[] { '\n' }).Count();
|
||||
chatpos.Y -= 20 * textLines;
|
||||
|
||||
if (owner != null)
|
||||
{
|
||||
font.DrawTextWithContrast(owner, chatpos,
|
||||
line.Color, Color.Black, UseContrast ? 1 : 0);
|
||||
}
|
||||
|
||||
font.DrawTextWithContrast(line.Text, chatpos + new int2(inset, 0),
|
||||
font.DrawTextWithContrast(text, chatpos + new int2(inset, 0),
|
||||
Color.White, Color.Black, UseContrast ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,11 +45,6 @@ namespace OpenRA.Widgets
|
||||
|
||||
public override Rectangle EventBounds { get { return Rectangle.Empty; } }
|
||||
|
||||
public override bool LoseFocus(MouseInput mi)
|
||||
{
|
||||
return composing ? false : base.LoseFocus(mi);
|
||||
}
|
||||
|
||||
public override bool HandleKeyPress(KeyInput e)
|
||||
{
|
||||
if (e.Event == KeyInputEvent.Up) return false;
|
||||
|
||||
187
OpenRA.Game/Widgets/LineGraphWidget.cs
Normal file
187
OpenRA.Game/Widgets/LineGraphWidget.cs
Normal file
@@ -0,0 +1,187 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
|
||||
namespace OpenRA.Widgets
|
||||
{
|
||||
public class LineGraphWidget : Widget
|
||||
{
|
||||
public Func<IEnumerable<LineGraphSeries>> GetSeries;
|
||||
public Func<string> GetValueFormat;
|
||||
public Func<string> GetXAxisValueFormat;
|
||||
public Func<string> GetYAxisValueFormat;
|
||||
public Func<int> GetXAxisSize;
|
||||
public Func<int> GetYAxisSize;
|
||||
public Func<string> GetXAxisLabel;
|
||||
public Func<string> GetYAxisLabel;
|
||||
public Func<bool> GetDisplayFirstYAxisValue;
|
||||
public Func<string> GetLabelFont;
|
||||
public Func<string> GetAxisFont;
|
||||
public string ValueFormat = "{0}";
|
||||
public string XAxisValueFormat = "{0}";
|
||||
public string YAxisValueFormat = "{0}";
|
||||
public int XAxisSize = 10;
|
||||
public int YAxisSize = 10;
|
||||
public string XAxisLabel = "";
|
||||
public string YAxisLabel = "";
|
||||
public bool DisplayFirstYAxisValue = false;
|
||||
public string LabelFont;
|
||||
public string AxisFont;
|
||||
|
||||
public LineGraphWidget()
|
||||
: base()
|
||||
{
|
||||
GetValueFormat = () => ValueFormat;
|
||||
GetXAxisValueFormat = () => XAxisValueFormat;
|
||||
GetYAxisValueFormat = () => YAxisValueFormat;
|
||||
GetXAxisSize = () => XAxisSize;
|
||||
GetYAxisSize = () => YAxisSize;
|
||||
GetXAxisLabel = () => XAxisLabel;
|
||||
GetYAxisLabel = () => YAxisLabel;
|
||||
GetDisplayFirstYAxisValue = () => DisplayFirstYAxisValue;
|
||||
GetLabelFont = () => LabelFont;
|
||||
GetAxisFont = () => AxisFont;
|
||||
}
|
||||
|
||||
protected LineGraphWidget(LineGraphWidget other)
|
||||
: base(other)
|
||||
{
|
||||
GetSeries = other.GetSeries;
|
||||
GetValueFormat = other.GetValueFormat;
|
||||
GetXAxisValueFormat = other.GetXAxisValueFormat;
|
||||
GetYAxisValueFormat = other.GetYAxisValueFormat;
|
||||
GetXAxisSize = other.GetXAxisSize;
|
||||
GetYAxisSize = other.GetYAxisSize;
|
||||
GetXAxisLabel = other.GetXAxisLabel;
|
||||
GetYAxisLabel = other.GetYAxisLabel;
|
||||
GetDisplayFirstYAxisValue = other.GetDisplayFirstYAxisValue;
|
||||
GetLabelFont = other.GetLabelFont;
|
||||
GetAxisFont = other.GetAxisFont;
|
||||
ValueFormat = other.ValueFormat;
|
||||
XAxisValueFormat = other.XAxisValueFormat;
|
||||
YAxisValueFormat = other.YAxisValueFormat;
|
||||
XAxisSize = other.XAxisSize;
|
||||
YAxisSize = other.YAxisSize;
|
||||
XAxisLabel = other.XAxisLabel;
|
||||
YAxisLabel = other.YAxisLabel;
|
||||
DisplayFirstYAxisValue = other.DisplayFirstYAxisValue;
|
||||
LabelFont = other.LabelFont;
|
||||
AxisFont = other.AxisFont;
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
if (GetSeries == null || !GetSeries().Any()
|
||||
|| GetLabelFont == null || GetLabelFont() == null
|
||||
|| GetAxisFont == null || GetAxisFont() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var rect = RenderBounds;
|
||||
var origin = new float2(rect.Left, rect.Bottom);
|
||||
|
||||
var width = rect.Width;
|
||||
var height = rect.Height;
|
||||
|
||||
var tiny = Game.Renderer.Fonts[GetLabelFont()];
|
||||
var bold = Game.Renderer.Fonts[GetAxisFont()];
|
||||
|
||||
var xAxisSize = GetXAxisSize();
|
||||
var yAxisSize = GetYAxisSize();
|
||||
|
||||
var maxValue = GetSeries().Select(p => p.Points).SelectMany(d => d).Concat(new[] { 0f }).Max();
|
||||
var scale = 200 / Math.Max(5000, (float)Math.Ceiling(maxValue / 1000) * 1000);
|
||||
|
||||
var xStep = width / xAxisSize;
|
||||
var yStep = height / yAxisSize;
|
||||
|
||||
var pointCount = GetSeries().First().Points.Count();
|
||||
var pointStart = Math.Max(0, pointCount - xAxisSize);
|
||||
var pointEnd = Math.Max(pointCount, xAxisSize);
|
||||
|
||||
var keyOffset = 0;
|
||||
foreach (var series in GetSeries())
|
||||
{
|
||||
var key = series.Key;
|
||||
var color = series.Color;
|
||||
var points = series.Points;
|
||||
if (points.Any())
|
||||
{
|
||||
points = points.Reverse().Take(xAxisSize).Reverse();
|
||||
var scaledData = points.Select(d => d * scale);
|
||||
var x = 0;
|
||||
scaledData.Aggregate((a, b) =>
|
||||
{
|
||||
Game.Renderer.LineRenderer.DrawLine(
|
||||
origin + new float2(x, -a),
|
||||
origin + new float2(x + xStep, -b),
|
||||
color, color);
|
||||
x += xStep;
|
||||
return b;
|
||||
});
|
||||
|
||||
var value = points.Last();
|
||||
if (value != 0)
|
||||
{
|
||||
tiny.DrawText(GetValueFormat().F(value), origin + new float2(x, -value * scale - 2), color);
|
||||
}
|
||||
}
|
||||
|
||||
tiny.DrawText(key, new float2(rect.Left, rect.Top) + new float2(5, 10 * keyOffset + 3), color);
|
||||
keyOffset++;
|
||||
}
|
||||
|
||||
//todo: make this stuff not draw outside of the RenderBounds
|
||||
for (int n = pointStart, x = 0; n <= pointEnd; n++, x += xStep)
|
||||
{
|
||||
Game.Renderer.LineRenderer.DrawLine(origin + new float2(x, 0), origin + new float2(x, -5), Color.White, Color.White);
|
||||
tiny.DrawText(GetXAxisValueFormat().F(n), origin + new float2(x, 2), Color.White);
|
||||
}
|
||||
bold.DrawText(GetXAxisLabel(), origin + new float2(width / 2, 20), Color.White);
|
||||
|
||||
for (var y = (GetDisplayFirstYAxisValue() ? 0 : yStep); y <= height; y += yStep)
|
||||
{
|
||||
var yValue = y / scale;
|
||||
Game.Renderer.LineRenderer.DrawLine(origin + new float2(width - 5, -y), origin + new float2(width, -y), Color.White, Color.White);
|
||||
tiny.DrawText(GetYAxisValueFormat().F(yValue), origin + new float2(width + 2, -y), Color.White);
|
||||
}
|
||||
bold.DrawText(GetYAxisLabel(), origin + new float2(width + 40, -(height / 2)), Color.White);
|
||||
|
||||
Game.Renderer.LineRenderer.DrawLine(origin, origin + new float2(width, 0), Color.White, Color.White);
|
||||
Game.Renderer.LineRenderer.DrawLine(origin, origin + new float2(0, -height), Color.White, Color.White);
|
||||
Game.Renderer.LineRenderer.DrawLine(origin + new float2(width, 0), origin + new float2(width, -height), Color.White, Color.White);
|
||||
Game.Renderer.LineRenderer.DrawLine(origin + new float2(0, -height), origin + new float2(width, -height), Color.White, Color.White);
|
||||
}
|
||||
|
||||
public override Widget Clone()
|
||||
{
|
||||
return new LineGraphWidget(this);
|
||||
}
|
||||
}
|
||||
|
||||
public class LineGraphSeries
|
||||
{
|
||||
public string Key;
|
||||
public Color Color;
|
||||
public IEnumerable<float> Points;
|
||||
|
||||
public LineGraphSeries(string key, Color color, IEnumerable<float> points)
|
||||
{
|
||||
Key = key;
|
||||
Color = color;
|
||||
Points = points;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
@@ -21,10 +22,11 @@ namespace OpenRA.Widgets
|
||||
public Func<Map> Map = () => null;
|
||||
public Func<Dictionary<int2, Color>> SpawnColors = () => new Dictionary<int2, Color>();
|
||||
public Action<MouseInput> OnMouseDown = _ => {};
|
||||
public Action<int, int2> OnTooltip = (_, __) => { };
|
||||
public bool IgnoreMouseInput = false;
|
||||
public bool ShowSpawnPoints = true;
|
||||
|
||||
static Cache<Map,Bitmap> PreviewCache = new Cache<Map, Bitmap>(stub => Minimap.RenderMapPreview( new Map( stub.Path )));
|
||||
static readonly Cache<Map,Bitmap> PreviewCache = new Cache<Map, Bitmap>(stub => Minimap.RenderMapPreview( new Map( stub.Path )));
|
||||
|
||||
public MapPreviewWidget() : base() { }
|
||||
|
||||
@@ -96,7 +98,8 @@ namespace OpenRA.Widgets
|
||||
{
|
||||
var colors = SpawnColors();
|
||||
|
||||
foreach (var p in map.GetSpawnPoints())
|
||||
var spawnPoints = map.GetSpawnPoints().ToList();
|
||||
foreach (var p in spawnPoints)
|
||||
{
|
||||
var owned = colors.ContainsKey(p);
|
||||
var pos = ConvertToPreview(p);
|
||||
@@ -107,8 +110,24 @@ namespace OpenRA.Widgets
|
||||
WidgetUtils.FillRectWithColor(new Rectangle(pos.X + offset.X + 2, pos.Y + offset.Y + 2, 12, 12), colors[p]);
|
||||
|
||||
Game.Renderer.RgbaSpriteRenderer.DrawSprite(sprite, pos + offset);
|
||||
|
||||
if ((pos - Viewport.LastMousePos).LengthSquared < 64)
|
||||
{
|
||||
OnTooltip(spawnPoints.IndexOf(p) + 1, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forces loading the preview into the map cache.
|
||||
/// </summary>
|
||||
public Bitmap LoadMapPreview()
|
||||
{
|
||||
var map = Map();
|
||||
if( map == null ) return null;
|
||||
|
||||
return PreviewCache[map];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,11 @@ namespace OpenRA.Widgets
|
||||
Game.Renderer.SpriteRenderer.DrawSprite(s,pos, wr, "chrome");
|
||||
}
|
||||
|
||||
public static void DrawSHP(Sprite s, float2 pos, WorldRenderer wr, float2 size)
|
||||
{
|
||||
Game.Renderer.SpriteRenderer.DrawSprite(s, pos, wr, "chrome", size);
|
||||
}
|
||||
|
||||
public static void DrawPanel(string collection, Rectangle Bounds)
|
||||
{
|
||||
DrawPanelPartial(collection, Bounds, PanelSides.All);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -52,33 +52,53 @@ namespace OpenRA.Widgets
|
||||
public override bool HandleMouseInput(MouseInput mi)
|
||||
{
|
||||
var xy = Game.viewport.ViewToWorldPx(mi);
|
||||
|
||||
var UseClassicMouseStyle = Game.Settings.Game.UseClassicMouseStyle;
|
||||
|
||||
var HasBox = (SelectionBox != null) ? true : false;
|
||||
var MultiClick = (mi.MultiTapCount >= 2) ? true : false;
|
||||
|
||||
if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down)
|
||||
{
|
||||
if (!TakeFocus(mi))
|
||||
return false;
|
||||
|
||||
|
||||
dragStart = dragEnd = xy;
|
||||
ApplyOrders(world, xy, mi);
|
||||
}
|
||||
|
||||
//place buildings
|
||||
if (!UseClassicMouseStyle || (UseClassicMouseStyle && !world.Selection.Actors.Any()) )
|
||||
ApplyOrders(world, xy, mi);
|
||||
}
|
||||
|
||||
if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Move)
|
||||
dragEnd = xy;
|
||||
|
||||
if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up)
|
||||
{
|
||||
if (UseClassicMouseStyle && Focused)
|
||||
{
|
||||
//order units around
|
||||
if (!HasBox && world.Selection.Actors.Any() && !MultiClick)
|
||||
{
|
||||
ApplyOrders(world, xy, mi);
|
||||
LoseFocus(mi);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (world.OrderGenerator is UnitOrderGenerator)
|
||||
{
|
||||
if (mi.MultiTapCount == 2)
|
||||
if (MultiClick)
|
||||
{
|
||||
var unit = SelectActorsInBox(world, xy, xy, _ => true).FirstOrDefault();
|
||||
|
||||
var visibleWorld = Game.viewport.ViewBounds(world);
|
||||
var topLeft = Game.viewport.ViewToWorldPx(new int2(visibleWorld.Left, visibleWorld.Top));
|
||||
var bottomRight = Game.viewport.ViewToWorldPx(new int2(visibleWorld.Right, visibleWorld.Bottom));
|
||||
var newSelection = SelectActorsInBox(world, topLeft, bottomRight,
|
||||
a => unit != null && a.Info.Name == unit.Info.Name && a.Owner == unit.Owner);
|
||||
|
||||
world.Selection.Combine(world, newSelection, true, false);
|
||||
var newSelection2= SelectActorsInBox(world, topLeft, bottomRight,
|
||||
a => unit != null && a.Info.Name == unit.Info.Name && a.Owner == unit.Owner);
|
||||
|
||||
world.Selection.Combine(world, newSelection2, true, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -86,21 +106,27 @@ namespace OpenRA.Widgets
|
||||
world.Selection.Combine(world, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dragStart = dragEnd = xy;
|
||||
LoseFocus(mi);
|
||||
}
|
||||
|
||||
|
||||
if (mi.Button == MouseButton.None && mi.Event == MouseInputEvent.Move)
|
||||
dragStart = dragEnd = xy;
|
||||
|
||||
|
||||
if (mi.Button == MouseButton.Right && mi.Event == MouseInputEvent.Down)
|
||||
if (SelectionBox == null) /* don't issue orders while selecting */
|
||||
ApplyOrders(world, xy, mi);
|
||||
{
|
||||
if (UseClassicMouseStyle)
|
||||
world.Selection.Clear();
|
||||
|
||||
if (!HasBox) // don't issue orders while selecting
|
||||
ApplyOrders(world, xy, mi);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public Pair<PPos, PPos>? SelectionBox
|
||||
{
|
||||
get
|
||||
@@ -115,14 +141,14 @@ namespace OpenRA.Widgets
|
||||
if (world.OrderGenerator == null) return;
|
||||
|
||||
var orders = world.OrderGenerator.Order(world, xy.ToCPos(), mi).ToArray();
|
||||
orders.Do( o => world.IssueOrder( o ) );
|
||||
orders.Do(o => world.IssueOrder(o));
|
||||
|
||||
world.PlayVoiceForOrders(orders);
|
||||
}
|
||||
|
||||
public override string GetCursor(int2 pos)
|
||||
{
|
||||
return Sync.CheckSyncUnchanged( world, () =>
|
||||
return Sync.CheckSyncUnchanged(world, () =>
|
||||
{
|
||||
if (SelectionBox != null)
|
||||
return null; /* always show an arrow while selecting */
|
||||
@@ -130,12 +156,12 @@ namespace OpenRA.Widgets
|
||||
var mi = new MouseInput
|
||||
{
|
||||
Location = pos,
|
||||
Button = MouseButton.Right,
|
||||
Button = Game.mouseButtonPreference.Action,
|
||||
Modifiers = Game.GetModifierKeys()
|
||||
};
|
||||
|
||||
// TODO: fix this up.
|
||||
return world.OrderGenerator.GetCursor( world, Game.viewport.ViewToWorld(mi), mi );
|
||||
return world.OrderGenerator.GetCursor(world, Game.viewport.ViewToWorld(mi), mi);
|
||||
} );
|
||||
}
|
||||
|
||||
@@ -145,10 +171,10 @@ namespace OpenRA.Widgets
|
||||
{
|
||||
if (e.KeyName.Length == 1 && char.IsDigit(e.KeyName[0]))
|
||||
{
|
||||
world.Selection.DoControlGroup(world, e.KeyName[0] - '0', e.Modifiers);
|
||||
world.Selection.DoControlGroup(world, e.KeyName[0] - '0', e.Modifiers, e.MultiTapCount);
|
||||
return true;
|
||||
}
|
||||
else if(e.KeyName == "pause" || e.KeyName == "f3")
|
||||
else if (e.KeyName == Game.Settings.Keys.PauseKey)
|
||||
{
|
||||
world.IssueOrder(Order.PauseRequest());
|
||||
}
|
||||
@@ -164,11 +190,11 @@ namespace OpenRA.Widgets
|
||||
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) )
|
||||
.Where(x => x.HasTrait<Selectable>() && world.RenderedShroud.IsVisible(x) && cond(x))
|
||||
.GroupBy(x => x.GetSelectionPriority())
|
||||
.OrderByDescending(g => g.Key)
|
||||
.Select( g => g.AsEnumerable() )
|
||||
.DefaultIfEmpty( NoActors )
|
||||
.Select(g => g.AsEnumerable())
|
||||
.DefaultIfEmpty(NoActors)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,10 +41,29 @@ namespace OpenRA
|
||||
public Player LocalPlayer { get; private set; }
|
||||
public readonly Shroud LocalShroud;
|
||||
|
||||
public Player RenderedPlayer;
|
||||
public Shroud RenderedShroud {
|
||||
get {
|
||||
if(RenderedPlayer == null)
|
||||
{
|
||||
return LocalShroud;
|
||||
}else{
|
||||
return RenderedPlayer.Shroud;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void SetLocalPlayer(string pr)
|
||||
{
|
||||
if (!(orderManager.Connection is ReplayConnection))
|
||||
LocalPlayer = Players.FirstOrDefault(p => p.InternalName == pr);
|
||||
{
|
||||
LocalPlayer = Players.FirstOrDefault(p => p.InternalName == pr);
|
||||
RenderedPlayer = LocalPlayer;
|
||||
}else{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public readonly Actor WorldActor;
|
||||
@@ -138,6 +157,7 @@ namespace OpenRA
|
||||
a.IsInWorld = false;
|
||||
actors.Remove(a);
|
||||
ActorRemoved(a);
|
||||
|
||||
}
|
||||
|
||||
public void Add(IEffect b) { effects.Add(b); }
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace OpenRA
|
||||
public static IEnumerable<Actor> FindUnitsAtMouse(this World world, int2 mouseLocation)
|
||||
{
|
||||
var loc = Game.viewport.ViewToWorldPx(mouseLocation);
|
||||
return FindUnits(world, loc, loc).Where(a => world.LocalShroud.IsVisible(a));
|
||||
return FindUnits(world, loc, loc).Where(a => world.RenderedShroud.IsVisible(a));
|
||||
}
|
||||
|
||||
public static IEnumerable<Actor> FindUnits(this World world, PPos a, PPos b)
|
||||
@@ -58,14 +58,37 @@ namespace OpenRA
|
||||
|
||||
public static IEnumerable<CPos> FindTilesInCircle(this World world, CPos a, int r)
|
||||
{
|
||||
var min = world.ClampToWorld(a - new CVec(r, r));
|
||||
var max = world.ClampToWorld(a + new CVec(r, r));
|
||||
for (var j = min.Y; j <= max.Y; j++)
|
||||
for (var i = min.X; i <= max.X; i++)
|
||||
if (r * r >= (new CPos(i, j) - a).LengthSquared)
|
||||
yield return new CPos(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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];
|
||||
@@ -104,7 +127,7 @@ namespace OpenRA
|
||||
|
||||
public static float Gauss1D(this Thirdparty.Random r, int samples)
|
||||
{
|
||||
return Exts.MakeArray(samples, _ => (float)r.NextDouble() * 2 - 1f)
|
||||
return Exts.MakeArray(samples, _ => r.NextFloat() * 2 - 1f)
|
||||
.Sum() / samples;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,8 +61,6 @@ namespace OpenRA.Mods.Cnc
|
||||
}
|
||||
}
|
||||
|
||||
static Set<string> excludePalettes = new Set<string>("cursor", "chrome", "colorpicker", "shroud", "fog");
|
||||
|
||||
public void AdjustPalette(Dictionary<string,Palette> palettes)
|
||||
{
|
||||
if (to == EffectType.None && remainingFrames == 0)
|
||||
@@ -70,9 +68,6 @@ namespace OpenRA.Mods.Cnc
|
||||
|
||||
foreach (var pal in palettes)
|
||||
{
|
||||
if (excludePalettes.Contains(pal.Key))
|
||||
continue;
|
||||
|
||||
for (var x = 0; x < 256; x++)
|
||||
{
|
||||
var orig = pal.Value.GetColor(x);
|
||||
|
||||
@@ -32,11 +32,11 @@ namespace OpenRA.Mods.Cnc.Effects
|
||||
|
||||
public void Tick(World world) { anim.Tick(); }
|
||||
|
||||
public IEnumerable<Renderable> Render()
|
||||
public IEnumerable<Renderable> Render(WorldRenderer wr)
|
||||
{
|
||||
yield return new Renderable(anim.Image,
|
||||
target.CenterLocation.ToFloat2() - new float2(.5f * anim.Image.size.X, anim.Image.size.Y - Game.CellSize),
|
||||
"effect", (int)target.CenterLocation.Y);
|
||||
wr.Palette("effect"), (int)target.CenterLocation.Y);
|
||||
}
|
||||
|
||||
void Finish( World world )
|
||||
|
||||
@@ -107,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">
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.RA;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Cnc
|
||||
@@ -39,7 +40,7 @@ namespace OpenRA.Mods.Cnc
|
||||
Info = info;
|
||||
}
|
||||
|
||||
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
|
||||
public IEnumerable<Renderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<Renderable> r)
|
||||
{
|
||||
foreach (var c in cargo.Passengers)
|
||||
{
|
||||
@@ -55,7 +56,7 @@ namespace OpenRA.Mods.Cnc
|
||||
Info.PassengerTypes.Contains(p.Trait<Passenger>().info.CargoType))
|
||||
: cargo.Passengers;
|
||||
|
||||
return r.Concat(visiblePassengers.SelectMany(a => a.Render())
|
||||
return r.Concat(visiblePassengers.SelectMany(a => a.Render(wr))
|
||||
.Select(a => a.WithPos(a.Pos - new float2(0, Info.RelativeAltitude))
|
||||
.WithZOffset(a.ZOffset + Info.RelativeAltitude)));
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
@@ -20,7 +21,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
Widget menu;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public CncIngameMenuLogic(Widget widget, World world, Action onExit)
|
||||
public CncIngameMenuLogic(Widget widget, World world, Action onExit, WorldRenderer worldRenderer)
|
||||
{
|
||||
var resumeDisabled = false;
|
||||
menu = widget.Get("INGAME_MENU");
|
||||
@@ -72,6 +73,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs()
|
||||
{
|
||||
{ "world", world },
|
||||
{ "worldRenderer", worldRenderer },
|
||||
{ "onExit", () => hideButtons = false },
|
||||
});
|
||||
};
|
||||
|
||||
@@ -85,9 +85,8 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
settingsMenu.Get<ButtonWidget>("SETTINGS_BUTTON").OnClick = () =>
|
||||
{
|
||||
Menu = MenuType.None;
|
||||
Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs()
|
||||
Game.OpenWindow("SETTINGS_PANEL", new WidgetArgs()
|
||||
{
|
||||
{ "world", world },
|
||||
{ "onExit", () => Menu = MenuType.Settings },
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
@@ -17,6 +18,7 @@ using OpenRA.GameRules;
|
||||
using OpenRA.Mods.RA;
|
||||
using OpenRA.Mods.RA.Widgets.Logic;
|
||||
using OpenRA.Widgets;
|
||||
using OpenRA.Mods.RA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
{
|
||||
@@ -25,7 +27,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
enum PanelType { General, Input }
|
||||
|
||||
PanelType Settings = PanelType.General;
|
||||
ColorPickerPaletteModifier playerPalettePreview;
|
||||
ColorPreviewManagerWidget colorPreview;
|
||||
World world;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
@@ -52,8 +54,8 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
var nameTextfield = generalPane.Get<TextFieldWidget>("NAME_TEXTFIELD");
|
||||
nameTextfield.Text = playerSettings.Name;
|
||||
|
||||
playerPalettePreview = world.WorldActor.Trait<ColorPickerPaletteModifier>();
|
||||
playerPalettePreview.Ramp = playerSettings.ColorRamp;
|
||||
colorPreview = panel.Get<ColorPreviewManagerWidget>("COLOR_MANAGER");
|
||||
colorPreview.Ramp = playerSettings.ColorRamp;
|
||||
|
||||
var colorDropdown = generalPane.Get<DropDownButtonWidget>("COLOR");
|
||||
colorDropdown.OnMouseDown = _ => ShowColorPicker(colorDropdown, playerSettings);
|
||||
@@ -118,7 +120,9 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
inputButton.OnClick = () => Settings = PanelType.Input;
|
||||
inputButton.IsDisabled = () => Settings == PanelType.Input;
|
||||
|
||||
inputPane.Get<CheckboxWidget>("CLASSICORDERS_CHECKBOX").IsDisabled = () => true;
|
||||
var classicMouseCheckbox = inputPane.Get<CheckboxWidget>("CLASSICORDERS_CHECKBOX");
|
||||
classicMouseCheckbox.IsChecked = () => gameSettings.UseClassicMouseStyle;
|
||||
classicMouseCheckbox.OnClick = () => gameSettings.UseClassicMouseStyle ^= true;
|
||||
|
||||
var scrollSlider = inputPane.Get<SliderWidget>("SCROLLSPEED_SLIDER");
|
||||
scrollSlider.Value = gameSettings.ViewportEdgeScrollStep;
|
||||
@@ -151,8 +155,8 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
|
||||
bool ShowColorPicker(DropDownButtonWidget color, PlayerSettings s)
|
||||
{
|
||||
Action<ColorRamp> onSelect = c => { s.ColorRamp = c; color.RemovePanel(); };
|
||||
Action<ColorRamp> onChange = c => { playerPalettePreview.Ramp = c; };
|
||||
Action<ColorRamp> onSelect = c => {s.ColorRamp = c; color.RemovePanel();};
|
||||
Action<ColorRamp> onChange = c => {colorPreview.Ramp = c;};
|
||||
|
||||
var colorChooser = Game.LoadWidget(world, "COLOR_CHOOSER", null, new WidgetArgs()
|
||||
{
|
||||
|
||||
@@ -90,16 +90,6 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
|
||||
static string ActorName( string a )
|
||||
{
|
||||
// hack hack hack - going to die soon anyway
|
||||
if (a == "barracks")
|
||||
return "Infantry Production";
|
||||
if (a == "vehicleproduction")
|
||||
return "Vehicle Production";
|
||||
if (a == "techcenter")
|
||||
return "Tech Center";
|
||||
if (a == "anypower")
|
||||
return "Power Plant";
|
||||
|
||||
ActorInfo ai;
|
||||
Rules.Info.TryGetValue(a.ToLowerInvariant(), out ai);
|
||||
if (ai != null && ai.Traits.Contains<TooltipInfo>())
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,9 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
public readonly string TooltipContainer;
|
||||
public readonly string TooltipTemplate = "PRODUCTION_TOOLTIP";
|
||||
|
||||
public readonly string ReadyText = "";
|
||||
public readonly string HoldText = "";
|
||||
|
||||
public string TooltipActor { get; private set; }
|
||||
public readonly World world;
|
||||
|
||||
@@ -54,8 +57,8 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
Animation cantBuild, clock;
|
||||
Rectangle eventBounds = Rectangle.Empty;
|
||||
readonly WorldRenderer worldRenderer;
|
||||
readonly SpriteFont overlayFont;
|
||||
readonly float2 holdOffset, readyOffset, timeOffset, queuedOffset;
|
||||
SpriteFont overlayFont;
|
||||
float2 holdOffset, readyOffset, timeOffset, queuedOffset;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public ProductionPaletteWidget(World world, WorldRenderer worldRenderer)
|
||||
@@ -75,12 +78,6 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
u => u.Name,
|
||||
u => Game.modData.SpriteLoader.LoadAllSprites(
|
||||
u.Traits.Get<TooltipInfo>().Icon ?? (u.Name + "icon"))[0]);
|
||||
|
||||
overlayFont = Game.Renderer.Fonts["TinyBold"];
|
||||
holdOffset = new float2(32,24) - overlayFont.Measure("On Hold") / 2;
|
||||
readyOffset = new float2(32,24) - overlayFont.Measure("Ready") / 2;
|
||||
timeOffset = new float2(32,24) - overlayFont.Measure(WidgetUtils.FormatTime(0)) / 2;
|
||||
queuedOffset = new float2(4,2);
|
||||
}
|
||||
|
||||
public override void Tick()
|
||||
@@ -210,10 +207,15 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
overlayFont = Game.Renderer.Fonts["TinyBold"];
|
||||
timeOffset = new float2(32,24) - overlayFont.Measure(WidgetUtils.FormatTime(0)) / 2;
|
||||
queuedOffset = new float2(4,2);
|
||||
holdOffset = new float2(32,24) - overlayFont.Measure(HoldText) / 2;
|
||||
readyOffset = new float2(32,24) - overlayFont.Measure(ReadyText) / 2;
|
||||
|
||||
if (CurrentQueue == null)
|
||||
return;
|
||||
|
||||
var isBuildingSomething = CurrentQueue.CurrentItem() != null;
|
||||
var buildableItems = CurrentQueue.BuildableItems().OrderBy(a => a.Traits.Get<BuildableInfo>().BuildPaletteOrder);
|
||||
|
||||
// Background
|
||||
@@ -235,7 +237,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);
|
||||
}
|
||||
|
||||
@@ -248,11 +250,11 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
var first = icon.Queued[0];
|
||||
var waiting = first != CurrentQueue.CurrentItem() && !first.Done;
|
||||
if (first.Done)
|
||||
overlayFont.DrawTextWithContrast("Ready",
|
||||
overlayFont.DrawTextWithContrast(ReadyText,
|
||||
icon.Pos + readyOffset,
|
||||
Color.White, Color.Black, 1);
|
||||
else if (first.Paused)
|
||||
overlayFont.DrawTextWithContrast("On Hold",
|
||||
overlayFont.DrawTextWithContrast(HoldText,
|
||||
icon.Pos + holdOffset,
|
||||
Color.White, Color.Black, 1);
|
||||
else if (!waiting)
|
||||
|
||||
@@ -138,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));
|
||||
@@ -157,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);
|
||||
@@ -266,7 +266,7 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
public override bool HandleKeyPress(KeyInput e)
|
||||
{
|
||||
if (e.Event != KeyInputEvent.Down) return false;
|
||||
if (e.KeyName == "tab")
|
||||
if (e.KeyName == Game.Settings.Keys.CycleTabsKey)
|
||||
{
|
||||
Sound.PlayNotification(null, "Sounds", "ClickSound", null);
|
||||
SelectNextTab(e.Modifiers.HasModifier(Modifiers.Shift));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,9 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
{
|
||||
public int Spacing = 10;
|
||||
|
||||
public readonly string ReadyText = "";
|
||||
public readonly string HoldText = "";
|
||||
|
||||
Dictionary<string, Sprite> iconSprites;
|
||||
Animation clock;
|
||||
Dictionary<Rectangle, SupportPowerIcon> Icons = new Dictionary<Rectangle, SupportPowerIcon>();
|
||||
@@ -36,8 +39,8 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
public override Rectangle EventBounds { get { return eventBounds; } }
|
||||
readonly WorldRenderer worldRenderer;
|
||||
readonly SupportPowerManager spm;
|
||||
readonly SpriteFont overlayFont;
|
||||
readonly float2 holdOffset, readyOffset, timeOffset;
|
||||
SpriteFont overlayFont;
|
||||
float2 holdOffset, readyOffset, timeOffset;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public SupportPowersWidget(World world, WorldRenderer worldRenderer)
|
||||
@@ -54,11 +57,6 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
u => Game.modData.SpriteLoader.LoadAllSprites(u)[0]);
|
||||
|
||||
clock = new Animation("clock");
|
||||
|
||||
overlayFont = Game.Renderer.Fonts["TinyBold"];
|
||||
holdOffset = new float2(32,24) - overlayFont.Measure("On Hold") / 2;
|
||||
readyOffset = new float2(32,24) - overlayFont.Measure("Ready") / 2;
|
||||
timeOffset = new float2(32,24) - overlayFont.Measure(WidgetUtils.FormatTime(0)) / 2;
|
||||
}
|
||||
|
||||
public class SupportPowerIcon
|
||||
@@ -94,6 +92,11 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
overlayFont = Game.Renderer.Fonts["TinyBold"];
|
||||
holdOffset = new float2(32,24) - overlayFont.Measure(HoldText) / 2;
|
||||
readyOffset = new float2(32,24) - overlayFont.Measure(ReadyText) / 2;
|
||||
timeOffset = new float2(32,24) - overlayFont.Measure(WidgetUtils.FormatTime(0)) / 2;
|
||||
|
||||
// Background
|
||||
foreach (var rect in Icons.Keys)
|
||||
WidgetUtils.DrawPanel("panel-black", rect.InflateBy(1,1,1,1));
|
||||
@@ -115,11 +118,11 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
foreach (var p in Icons.Values)
|
||||
{
|
||||
if (p.Power.Ready)
|
||||
overlayFont.DrawTextWithContrast("Ready",
|
||||
overlayFont.DrawTextWithContrast(ReadyText,
|
||||
p.Pos + readyOffset,
|
||||
Color.White, Color.Black, 1);
|
||||
else if (!p.Power.Active)
|
||||
overlayFont.DrawTextWithContrast("On Hold",
|
||||
overlayFont.DrawTextWithContrast(HoldText,
|
||||
p.Pos + holdOffset,
|
||||
Color.White, Color.Black, 1);
|
||||
else
|
||||
|
||||
@@ -53,10 +53,10 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
tooltipContainer.Value.RemoveTooltip();
|
||||
}
|
||||
|
||||
public override void DrawBackground(Rectangle rect, bool disabled, bool pressed, bool hover)
|
||||
public override void DrawBackground(Rectangle rect, bool disabled, bool pressed, bool hover, bool highlighted)
|
||||
{
|
||||
var baseName = IsToggled() ? "button-toggled" : "button";
|
||||
ButtonWidget.DrawBackground(baseName, rect, disabled, pressed, hover);
|
||||
ButtonWidget.DrawBackground(baseName, rect, disabled, pressed, hover, highlighted);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,13 +165,12 @@ namespace OpenRA.Mods.RA.AI
|
||||
{
|
||||
var bi = Rules.Info[actorType].Traits.Get<BuildingInfo>();
|
||||
|
||||
for (var k = 0; k < MaxBaseDistance; k++)
|
||||
foreach (var t in world.FindTilesInCircle(baseCenter, k))
|
||||
if (world.CanPlaceBuilding(actorType, bi, t, null))
|
||||
if (bi.IsCloseEnoughToBase(world, p, actorType, t))
|
||||
if (NoBuildingsUnder(Util.ExpandFootprint(
|
||||
FootprintUtils.Tiles(actorType, bi, t), false)))
|
||||
return t;
|
||||
foreach (var t in world.FindTilesInCircle(baseCenter, MaxBaseDistance))
|
||||
if (world.CanPlaceBuilding(actorType, bi, t, null))
|
||||
if (bi.IsCloseEnoughToBase(world, p, actorType, t))
|
||||
if (NoBuildingsUnder(Util.ExpandFootprint(
|
||||
FootprintUtils.Tiles(actorType, bi, t), false)))
|
||||
return t;
|
||||
|
||||
return null; // i don't know where to put it.
|
||||
}
|
||||
@@ -224,7 +223,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
|
||||
/* pick something worth attacking owned by that player */
|
||||
var targets = world.Actors
|
||||
.Where(a => a.Owner == enemy && a.HasTrait<IOccupySpace>());
|
||||
.Where(a => a.Owner == enemy && a.HasTrait<IOccupySpace>() && !a.HasTrait<Husk>());
|
||||
Actor target = null;
|
||||
|
||||
if (targets.Any())
|
||||
@@ -270,8 +269,8 @@ namespace OpenRA.Mods.RA.AI
|
||||
{
|
||||
Activity act = a.GetCurrentActivity();
|
||||
// A Wait activity is technically idle:
|
||||
if ((act.GetType() != typeof(OpenRA.Mods.RA.Activities.Wait)) &&
|
||||
(act.NextActivity == null || act.NextActivity.GetType() != typeof(OpenRA.Mods.RA.Activities.FindResources)))
|
||||
if (!(act is Activities.Wait) &&
|
||||
(act.NextActivity == null || !(act.NextActivity is Activities.FindResources)))
|
||||
continue;
|
||||
}
|
||||
if (!harv.IsEmpty) continue;
|
||||
@@ -282,7 +281,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
|
||||
var newUnits = self.World.ActorsWithTrait<IMove>()
|
||||
.Where(a => a.Actor.Owner == p && !a.Actor.HasTrait<BaseBuilding>()
|
||||
&& !activeUnits.Contains(a.Actor))
|
||||
&& !activeUnits.Contains(a.Actor) && a.Actor.IsInWorld)
|
||||
.Select(a => a.Actor).ToArray();
|
||||
|
||||
foreach (var a in newUnits)
|
||||
@@ -326,7 +325,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
foreach (var a1 in attackForce)
|
||||
{
|
||||
var enemyUnits = world.FindUnitsInCircle(a1.CenterLocation, Game.CellSize * 10)
|
||||
.Where(unit => p.Stances[unit.Owner] == Stance.Enemy).ToList();
|
||||
.Where(unit => p.Stances[unit.Owner] == Stance.Enemy && !unit.HasTrait<Husk>()).ToList();
|
||||
|
||||
if (enemyUnits.Count > 0)
|
||||
{
|
||||
@@ -490,4 +489,4 @@ namespace OpenRA.Mods.RA.AI
|
||||
aggro[e.Attacker.Owner].Aggro += e.Damage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,9 @@ namespace OpenRA.Mods.RA.Activities
|
||||
|
||||
if (!Target.IsValid)
|
||||
return NextActivity;
|
||||
|
||||
if (!self.Owner.HasFogVisibility() && Target.Actor != null && Target.Actor.HasTrait<Mobile>() && !self.Owner.Shroud.IsTargetable(Target.Actor))
|
||||
return NextActivity;
|
||||
|
||||
if (targetable != null && !targetable.TargetableBy(Target.Actor, self))
|
||||
return NextActivity;
|
||||
|
||||
@@ -32,16 +32,9 @@ namespace OpenRA.Mods.RA.Activities
|
||||
if ((nearest - mobile.toCell).LengthSquared > 2)
|
||||
return Util.SequenceActivities(new MoveAdjacentTo(Target.FromActor(target)), this);
|
||||
|
||||
var capturable = target.TraitOrDefault<Capturable>();
|
||||
if (capturable != null && capturable.CaptureInProgress && capturable.Captor.Owner.Stances[self.Owner] == Stance.Ally)
|
||||
if (!target.Trait<Capturable>().BeginCapture(target, self))
|
||||
return NextActivity;
|
||||
|
||||
var sellable = target.TraitOrDefault<Sellable>();
|
||||
if (sellable != null && sellable.Selling)
|
||||
return NextActivity;
|
||||
|
||||
target.Trait<Capturable>().BeginCapture(target, self);
|
||||
|
||||
var capturesInfo = self.Info.Traits.Get<CapturesInfo>();
|
||||
if (capturesInfo != null && capturesInfo.WastedAfterwards)
|
||||
self.World.AddFrameEndTask(w => self.Destroy());
|
||||
|
||||
@@ -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
|
||||
@@ -9,6 +9,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
@@ -30,9 +31,17 @@ namespace OpenRA.Mods.RA.Activities
|
||||
foreach (var t in target.TraitsImplementing<IAcceptSpy>())
|
||||
t.OnInfiltrate(target, self);
|
||||
|
||||
self.Destroy();
|
||||
if (self.HasTrait<DontDestroyWhenInfiltrating>())
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
if (self.Destroyed) return;
|
||||
w.Remove(self);
|
||||
});
|
||||
else
|
||||
self.Destroy();
|
||||
|
||||
Sound.PlayToPlayer(self.Owner, "bldginf1.aud");
|
||||
if (target.HasTrait<Building>())
|
||||
Sound.PlayToPlayer(self.Owner, "bldginf1.aud");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
var repairsUnits = host.Info.Traits.Get<RepairsUnitsInfo>();
|
||||
var unitCost = self.Info.Traits.Get<ValuedInfo>().Cost;
|
||||
var hpToRepair = repairsUnits.HpPerStep;
|
||||
var cost = (hpToRepair * unitCost * repairsUnits.ValuePercentage) / (health.MaxHP * 100);
|
||||
var cost = Math.Max(1, (hpToRepair * unitCost * repairsUnits.ValuePercentage) / (health.MaxHP * 100));
|
||||
|
||||
if (!self.Owner.PlayerActor.Trait<PlayerResources>().TakeCash(cost))
|
||||
{
|
||||
|
||||
@@ -19,9 +19,6 @@ namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
public override Activity Tick(Actor self)
|
||||
{
|
||||
var capturing = self.TraitOrDefault<Capturable>();
|
||||
if (capturing != null && capturing.CaptureInProgress) return NextActivity;
|
||||
|
||||
var h = self.TraitOrDefault<Health>();
|
||||
var si = self.Info.Traits.Get<SellableInfo>();
|
||||
var pr = self.Owner.PlayerActor.Trait<PlayerResources>();
|
||||
|
||||
@@ -34,6 +34,9 @@ namespace OpenRA.Mods.RA.Activities
|
||||
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
foreach (var nt in self.TraitsImplementing<INotifyTransform>())
|
||||
nt.OnTransform(self);
|
||||
|
||||
var selected = w.Selection.Contains(self);
|
||||
|
||||
self.Destroy();
|
||||
@@ -65,6 +68,9 @@ namespace OpenRA.Mods.RA.Activities
|
||||
|
||||
var a = w.CreateActor( ToActor, init );
|
||||
|
||||
foreach (var nt in self.TraitsImplementing<INotifyTransformed>())
|
||||
nt.OnTransformed(a);
|
||||
|
||||
if (selected)
|
||||
w.Selection.Add(w, a);
|
||||
});
|
||||
|
||||
@@ -35,10 +35,8 @@ namespace OpenRA.Mods.RA
|
||||
if (IsSuitableCell(pilot, self.Location) && r > 100 - info.SuccessRate && aircraft.Altitude > 10
|
||||
&& self.Owner.WinState != WinState.Lost)
|
||||
{
|
||||
self.World.AddFrameEndTask(w => w.Add(
|
||||
new Parachute(pilot.Owner,
|
||||
Util.CenterOfCell(self.CenterLocation.ToCPos()),
|
||||
aircraft.Altitude, pilot)));
|
||||
self.World.AddFrameEndTask(w => w.Add(new Parachute(pilot,
|
||||
Util.CenterOfCell(self.CenterLocation.ToCPos()), aircraft.Altitude)));
|
||||
|
||||
Sound.Play(info.ChuteSound, self.CenterLocation);
|
||||
}
|
||||
|
||||
@@ -38,13 +38,12 @@ namespace OpenRA.Mods.RA.Air
|
||||
}
|
||||
|
||||
var attack = self.Trait<AttackHeli>();
|
||||
var range = attack.GetMaximumRange() * 0.625f;
|
||||
var dist = target.CenterLocation - self.CenterLocation;
|
||||
|
||||
var desiredFacing = Util.GetFacing(dist, aircraft.Facing);
|
||||
aircraft.Facing = Util.TickFacing(aircraft.Facing, desiredFacing, aircraft.ROT);
|
||||
|
||||
if( !float2.WithinEpsilon( float2.Zero, dist.ToFloat2(), range * Game.CellSize ) )
|
||||
if (!Combat.IsInRange(self.CenterLocation, attack.GetMaximumRange(), target))
|
||||
aircraft.TickMove(PSubPos.PerPx * aircraft.MovementSpeed, desiredFacing);
|
||||
|
||||
attack.DoAttack( self, target );
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
}
|
||||
|
||||
var dist = Dest - aircraft.PxPosition;
|
||||
if (float2.WithinEpsilon(float2.Zero, dist.ToFloat2(), 2))
|
||||
if (Math.Abs(dist.X) < 2 && Math.Abs(dist.Y) < 2)
|
||||
{
|
||||
aircraft.SubPxPosition = Dest.ToPSubPos();
|
||||
return NextActivity;
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
}
|
||||
else if (order.OrderString == "ReturnToBase")
|
||||
{
|
||||
var airfield = ReturnToBase.ChooseAirfield(self);
|
||||
var airfield = ReturnToBase.ChooseAirfield(self, true);
|
||||
if (airfield == null) return;
|
||||
|
||||
UnReserve();
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
var altitude = self.Trait<Aircraft>().Altitude;
|
||||
if (altitude == 0) return; // we're on the ground, let's stay there.
|
||||
|
||||
var airfield = ReturnToBase.ChooseAirfield(self);
|
||||
var airfield = ReturnToBase.ChooseAirfield(self, true);
|
||||
if (airfield != null)
|
||||
{
|
||||
self.QueueActivity(new ReturnToBase(self, airfield));
|
||||
|
||||
@@ -22,20 +22,20 @@ namespace OpenRA.Mods.RA.Air
|
||||
|
||||
PPos w1, w2, w3; /* tangent points to turn circles */
|
||||
|
||||
public static Actor ChooseAirfield(Actor self)
|
||||
public static Actor ChooseAirfield(Actor self, bool unreservedOnly)
|
||||
{
|
||||
var rearmBuildings = self.Info.Traits.Get<PlaneInfo>().RearmBuildings;
|
||||
return self.World.ActorsWithTrait<Reservable>()
|
||||
.Where(a => a.Actor.Owner == self.Owner)
|
||||
.Where(a => rearmBuildings.Contains(a.Actor.Info.Name)
|
||||
&& !Reservable.IsReserved(a.Actor))
|
||||
&& (!unreservedOnly || !Reservable.IsReserved(a.Actor)))
|
||||
.Select(a => a.Actor)
|
||||
.ClosestTo( self.CenterLocation );
|
||||
}
|
||||
|
||||
void Calculate(Actor self)
|
||||
{
|
||||
if (dest == null || Reservable.IsReserved(dest)) dest = ChooseAirfield(self);
|
||||
if (dest == null || Reservable.IsReserved(dest)) dest = ChooseAirfield(self, true);
|
||||
|
||||
if (dest == null) return;
|
||||
|
||||
@@ -52,17 +52,21 @@ namespace OpenRA.Mods.RA.Air
|
||||
|
||||
var speed = .2f * aircraft.MovementSpeed;
|
||||
|
||||
var approachStart = landPos.ToFloat2() - new float2(aircraft.Altitude * speed, 0);
|
||||
/* if the aircraft is on the ground, it will take off to the cruise altitude first before approaching */
|
||||
var altitude = aircraft.Altitude;
|
||||
if (altitude == 0) altitude = self.Info.Traits.Get<PlaneInfo>().CruiseAltitude;
|
||||
|
||||
var approachStart = landPos.ToInt2() - new float2(altitude * speed, 0);
|
||||
var turnRadius = (128f / self.Info.Traits.Get<AircraftInfo>().ROT) * speed / (float)Math.PI;
|
||||
|
||||
/* work out the center points */
|
||||
var fwd = -float2.FromAngle(aircraft.Facing / 128f * (float)Math.PI);
|
||||
var side = new float2(-fwd.Y, fwd.X); /* rotate */
|
||||
var sideTowardBase = new[] { side, -side }
|
||||
.OrderBy(a => float2.Dot(a, self.CenterLocation.ToFloat2() - approachStart))
|
||||
.OrderBy(a => float2.Dot(a, self.CenterLocation.ToInt2() - approachStart))
|
||||
.First();
|
||||
|
||||
var c1 = self.CenterLocation.ToFloat2() + turnRadius * sideTowardBase;
|
||||
var c1 = self.CenterLocation.ToInt2() + turnRadius * sideTowardBase;
|
||||
var c2 = approachStart + new float2(0, turnRadius * Math.Sign(self.CenterLocation.Y - approachStart.Y)); // above or below start point
|
||||
|
||||
/* work out tangent points */
|
||||
@@ -94,14 +98,13 @@ namespace OpenRA.Mods.RA.Air
|
||||
Calculate(self);
|
||||
if (dest == null)
|
||||
{
|
||||
var rearmBuildings = self.Info.Traits.Get<PlaneInfo>().RearmBuildings;
|
||||
var nearestAfld = self.World.ActorsWithTrait<Reservable>()
|
||||
.Where(a => a.Actor.Owner == self.Owner && rearmBuildings.Contains(a.Actor.Info.Name))
|
||||
.Select(a => a.Actor)
|
||||
.ClosestTo(self.CenterLocation);
|
||||
var nearestAfld = ChooseAirfield(self, false);
|
||||
|
||||
self.CancelActivity();
|
||||
return Util.SequenceActivities(Fly.ToCell(nearestAfld.Location), new FlyCircle());
|
||||
if (nearestAfld != null)
|
||||
return Util.SequenceActivities(Fly.ToCell(nearestAfld.Location), new FlyCircle());
|
||||
else
|
||||
return new FlyCircle();
|
||||
}
|
||||
|
||||
return Util.SequenceActivities(
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user