mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-11-08 09:23:00 +00:00
Compare commits
708 Commits
1.80pr0
...
feature/on
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8819f2559d | ||
|
|
4b741739e8 | ||
|
|
f23acef2dd | ||
|
|
ac8444b364 | ||
|
|
3b4c1eac1c | ||
|
|
7cc77cb1ed | ||
|
|
0f70d68d0d | ||
|
|
c6bd88f3ad | ||
|
|
efa57521c7 | ||
|
|
4700f8831b | ||
|
|
9428bee316 | ||
|
|
89c7183a1d | ||
|
|
d2a9e7e458 | ||
|
|
1774f1a079 | ||
|
|
de1307913b | ||
|
|
093132533d | ||
|
|
0685be6bfa | ||
|
|
f40733e9a6 | ||
|
|
a3d1cff298 | ||
|
|
b8957cab5c | ||
|
|
3ac8dde779 | ||
|
|
17dace979a | ||
|
|
d405316a4b | ||
|
|
7e18f2cead | ||
|
|
000786a1a7 | ||
|
|
0bf13562b9 | ||
|
|
45a189e834 | ||
|
|
0ce6f34a09 | ||
|
|
4d984dc5ee | ||
|
|
984d358930 | ||
|
|
a95893b823 | ||
|
|
81aaead032 | ||
|
|
a2083bcff1 | ||
|
|
052f2a16dc | ||
|
|
fd10ed6f62 | ||
|
|
c0bdd4ff1d | ||
|
|
5f0addbc3e | ||
|
|
c9589ad0e7 | ||
|
|
b21c495815 | ||
|
|
18429c50f9 | ||
|
|
7ec8ddcf7d | ||
|
|
5bf9f9e3c5 | ||
|
|
e4164ee9a1 | ||
|
|
b522af3075 | ||
|
|
8775052dee | ||
|
|
c0c5d57e10 | ||
|
|
4c2e97b1af | ||
|
|
f17df15117 | ||
|
|
bfbb18bdfc | ||
|
|
cac65ef755 | ||
|
|
a42793024b | ||
|
|
7dbc4e6455 | ||
|
|
a0d71cb3ad | ||
|
|
83546d0acb | ||
|
|
e2f9ddd534 | ||
|
|
911e404bfa | ||
|
|
bfeafe163f | ||
|
|
6cf32f1f74 | ||
|
|
04f162ef25 | ||
|
|
b2aa390ae1 | ||
|
|
6ca61f000f | ||
|
|
20a47a7f88 | ||
|
|
e2e6946c92 | ||
|
|
abe917cd54 | ||
|
|
a1d77ab8e7 | ||
|
|
c8db671409 | ||
|
|
52641b7bea | ||
|
|
3e751ee94a | ||
|
|
2b28cc3558 | ||
|
|
f9761388b1 | ||
|
|
d28694eb57 | ||
|
|
d758895578 | ||
|
|
043d5f00ca | ||
|
|
36878e75b7 | ||
|
|
ebb50cba48 | ||
|
|
7c218361d9 | ||
|
|
bb2eab0bed | ||
|
|
e8c0cf3857 | ||
|
|
db825a7aab | ||
|
|
dbcae810f0 | ||
|
|
914df8b0c7 | ||
|
|
f753513289 | ||
|
|
7bb8efed1d | ||
|
|
0cec4aee8c | ||
|
|
e0c9dc24e7 | ||
|
|
244907a39a | ||
|
|
9be61abd6b | ||
|
|
922f424a78 | ||
|
|
5c7828dd79 | ||
|
|
74f5093d2a | ||
|
|
4651e362c9 | ||
|
|
a2e2a5cb37 | ||
|
|
15a3882016 | ||
|
|
d3ecd5214b | ||
|
|
0a8a8a742e | ||
|
|
ecff23d027 | ||
|
|
20dcb32bae | ||
|
|
678462d2db | ||
|
|
61fdfec09b | ||
|
|
5eadf5533d | ||
|
|
2d3cd5dc80 | ||
|
|
5208ad0b98 | ||
|
|
662fb96beb | ||
|
|
4c14431a3d | ||
|
|
5ae38a3f18 | ||
|
|
94e10d1f67 | ||
|
|
0a50676884 | ||
|
|
41cce78fcb | ||
|
|
4c0fa1fabe | ||
|
|
54e1dafa3f | ||
|
|
3ac76bc05b | ||
|
|
83030df3ee | ||
|
|
07d15caf6f | ||
|
|
3298efe652 | ||
|
|
01d9919a3e | ||
|
|
80b1170b63 | ||
|
|
2e7302e654 | ||
|
|
ca7fb8a0b4 | ||
|
|
c9b0894f26 | ||
|
|
c3454a195d | ||
|
|
3b3dd8071b | ||
|
|
0d28c67534 | ||
|
|
d0af85754a | ||
|
|
3e265c27ff | ||
|
|
8d356f50c4 | ||
|
|
f30c4f16c0 | ||
|
|
8bb8caa315 | ||
|
|
0f17a3d72e | ||
|
|
7647369e2d | ||
|
|
4b4208e724 | ||
|
|
2a16a1df85 | ||
|
|
25f7c58400 | ||
|
|
c3db91f11f | ||
|
|
8c66ce03d4 | ||
|
|
2be2a0625e | ||
|
|
c904d5041b | ||
|
|
632762768e | ||
|
|
c69ba205f8 | ||
|
|
019f4dbea9 | ||
|
|
259ea41ce3 | ||
|
|
11290f7204 | ||
|
|
abd06133fb | ||
|
|
29a3a0c48f | ||
|
|
2728c63512 | ||
|
|
f3b11bc1c2 | ||
|
|
04590befb3 | ||
|
|
4e9034f910 | ||
|
|
ba9cfa3764 | ||
|
|
341e3e2f89 | ||
|
|
3f70ca5192 | ||
|
|
f11bfc53ee | ||
|
|
61e3967b8e | ||
|
|
add86ea100 | ||
|
|
dd51c89278 | ||
|
|
788d783745 | ||
|
|
35da60543e | ||
|
|
ce7923d248 | ||
|
|
55847460c5 | ||
|
|
893524b0a8 | ||
|
|
8fb3ae405f | ||
|
|
aa447ec101 | ||
|
|
56b1cb4521 | ||
|
|
90cc24614c | ||
|
|
d7301ff15e | ||
|
|
1cf10c5c47 | ||
|
|
6691ec8e3a | ||
|
|
a9f77221ff | ||
|
|
dd3b69a633 | ||
|
|
d766f8b34e | ||
|
|
2ae6fb47e7 | ||
|
|
dd5698241b | ||
|
|
ed8e9d7817 | ||
|
|
6c29b44c3c | ||
|
|
0caa133089 | ||
|
|
a8b08bd971 | ||
|
|
c9181a121f | ||
|
|
30f4e0829f | ||
|
|
2155fce036 | ||
|
|
27602ec8fc | ||
|
|
66f683d9c9 | ||
|
|
ac08a52323 | ||
|
|
fe0f998c27 | ||
|
|
bcf79165f9 | ||
|
|
9b2a50cdfc | ||
|
|
c5d99db654 | ||
|
|
5253ab3e58 | ||
|
|
11d8253d9c | ||
|
|
bc2b481918 | ||
|
|
b26564ccb9 | ||
|
|
28e3ffe978 | ||
|
|
540e2e25aa | ||
|
|
845118e9e2 | ||
|
|
b2b8753ee7 | ||
|
|
060fb21bdb | ||
|
|
ef008709c7 | ||
|
|
09da119f27 | ||
|
|
f8487d1e1c | ||
|
|
b6f773ffce | ||
|
|
c8673473ef | ||
|
|
3829815756 | ||
|
|
7eac8faf0d | ||
|
|
0bd0f4d313 | ||
|
|
73873eb8cb | ||
|
|
0420b6c831 | ||
|
|
bb741975b7 | ||
|
|
8bffec6964 | ||
|
|
9e19dd7070 | ||
|
|
aba0e3d2d4 | ||
|
|
d9d025e33b | ||
|
|
1fe29ab098 | ||
|
|
53f16782ab | ||
|
|
bfb4f88304 | ||
|
|
fb6d65ec23 | ||
|
|
6b364052c7 | ||
|
|
7169abcd7b | ||
|
|
75ccfbdb3d | ||
|
|
728644c104 | ||
|
|
999351e667 | ||
|
|
11e879db41 | ||
|
|
a4a774fcdf | ||
|
|
4fb0240a36 | ||
|
|
80ec54eaf6 | ||
|
|
9e4ae3a494 | ||
|
|
19e4c03d3a | ||
|
|
c6b8cb1fab | ||
|
|
f20a7afa7f | ||
|
|
01f5d006fc | ||
|
|
cd6b076efe | ||
|
|
f8193a4d23 | ||
|
|
5be2202b2e | ||
|
|
fbbfe33e21 | ||
|
|
7a916ed8c2 | ||
|
|
60305cd106 | ||
|
|
b8630f739a | ||
|
|
1c8480a329 | ||
|
|
5219648128 | ||
|
|
1ef7c8e8db | ||
|
|
1415dd0dae | ||
|
|
282aa804f8 | ||
|
|
e959051239 | ||
|
|
373b7ba293 | ||
|
|
70c6f3498b | ||
|
|
afec3743f3 | ||
|
|
5989d021c7 | ||
|
|
baa8993999 | ||
|
|
92f5860de6 | ||
|
|
12abd4292e | ||
|
|
fa498e74fb | ||
|
|
bd90d7d3b0 | ||
|
|
4bd5b0d236 | ||
|
|
0115bc8dca | ||
|
|
1fdfcdb5f2 | ||
|
|
6c32d8a57e | ||
|
|
5f323a85a7 | ||
|
|
85c556d324 | ||
|
|
61ff91f237 | ||
|
|
3b2de38227 | ||
|
|
bde9ac9747 | ||
|
|
6aa4a385a3 | ||
|
|
a2da6d9601 | ||
|
|
88b1124204 | ||
|
|
51644e32ed | ||
|
|
cf5216aefb | ||
|
|
c7e5386e80 | ||
|
|
707f0899da | ||
|
|
3095a6bbad | ||
|
|
a5bbed528d | ||
|
|
0c1114edbc | ||
|
|
369be7c32c | ||
|
|
fd8837c631 | ||
|
|
2f829a1413 | ||
|
|
0de3a42808 | ||
|
|
2fb6a9dc62 | ||
|
|
87b771b7c8 | ||
|
|
79697e37b0 | ||
|
|
4f9de6b02c | ||
|
|
e9cea7d0f5 | ||
|
|
90626748e4 | ||
|
|
30b55d966b | ||
|
|
3371345fad | ||
|
|
2c264728d9 | ||
|
|
90c4ebd208 | ||
|
|
5df97e5133 | ||
|
|
8f6feff4fd | ||
|
|
26bca2e109 | ||
|
|
0d5397db34 | ||
|
|
acb5f65e16 | ||
|
|
c9e7b45509 | ||
|
|
226ae3648f | ||
|
|
83f34b430d | ||
|
|
0a5155c0ff | ||
|
|
579f7443a8 | ||
|
|
df1c8e22b8 | ||
|
|
96288164c5 | ||
|
|
263bade338 | ||
|
|
d29ffed383 | ||
|
|
08099f08f2 | ||
|
|
bee41e7f97 | ||
|
|
35425f0f61 | ||
|
|
f480965e67 | ||
|
|
6701403370 | ||
|
|
ff2c26c4a1 | ||
|
|
4c89364964 | ||
|
|
94613d28a6 | ||
|
|
f6ea561270 | ||
|
|
b4fb7bb20f | ||
|
|
35d29e1d88 | ||
|
|
f14a14f4c3 | ||
|
|
77cadf52fe | ||
|
|
e97a32cd69 | ||
|
|
44a5284dd6 | ||
|
|
43a5fc9fe7 | ||
|
|
505ccf97cf | ||
|
|
2c91c7962f | ||
|
|
f785b0a488 | ||
|
|
af847818d2 | ||
|
|
ee20d7bed2 | ||
|
|
11060596b1 | ||
|
|
71d024a76c | ||
|
|
260bb2e4e1 | ||
|
|
f28a1ba517 | ||
|
|
239a2f0d25 | ||
|
|
1850dcdf38 | ||
|
|
af0549946b | ||
|
|
7e5a9b3a5a | ||
|
|
c0294e1534 | ||
|
|
bb6d423710 | ||
|
|
0ab79fd466 | ||
|
|
756d297c85 | ||
|
|
1cf3d78eac | ||
|
|
f1bb56557d | ||
|
|
4b36ed6719 | ||
|
|
592c0c9341 | ||
|
|
e664eb26a9 | ||
|
|
1ab5094b7f | ||
|
|
94d701b1f7 | ||
|
|
db2364dae6 | ||
|
|
87406bc00d | ||
|
|
224e752a8f | ||
|
|
48754659f8 | ||
|
|
f0559867d0 | ||
|
|
02eb52da71 | ||
|
|
ef05eb7fe9 | ||
|
|
6fdf38f55f | ||
|
|
c46391555f | ||
|
|
1d63598d43 | ||
|
|
5e244273c2 | ||
|
|
b0a2dd5eb1 | ||
|
|
13f886be5a | ||
|
|
845e1b633d | ||
|
|
6a8c544914 | ||
|
|
6fca136327 | ||
|
|
123a0158af | ||
|
|
b37b33f4f4 | ||
|
|
00a1342883 | ||
|
|
14e4d037ad | ||
|
|
28a89a26ad | ||
|
|
c9a3bcb68b | ||
|
|
025af6a0a0 | ||
|
|
f247879d98 | ||
|
|
bf533dd00a | ||
|
|
0fb8177721 | ||
|
|
22066a96dd | ||
|
|
836de416bc | ||
|
|
6bbd1f3718 | ||
|
|
6255314ba8 | ||
|
|
fc93ee474f | ||
|
|
13ed933c6b | ||
|
|
fb5ba01e5a | ||
|
|
7090f6b6a7 | ||
|
|
01c024d8b0 | ||
|
|
52a2c6f7f9 | ||
|
|
d9190f95ec | ||
|
|
6df22235ae | ||
|
|
174b63d59a | ||
|
|
f0257028ba | ||
|
|
4a9f1e013c | ||
|
|
a7db108762 | ||
|
|
be861a1c0d | ||
|
|
1489da1f5f | ||
|
|
c70acbb05a | ||
|
|
7e08662b95 | ||
|
|
93d1facbab | ||
|
|
4580f10567 | ||
|
|
06b2f3511f | ||
|
|
084bbe8480 | ||
|
|
3acbdb2f90 | ||
|
|
01a0ce3dd0 | ||
|
|
bfb682bef9 | ||
|
|
9b5aa43d95 | ||
|
|
efb351e1b0 | ||
|
|
2445a5b5d5 | ||
|
|
c611b20db8 | ||
|
|
221143e767 | ||
|
|
34ac28066e | ||
|
|
9472d30dfc | ||
|
|
eb628e9b62 | ||
|
|
157bc01be5 | ||
|
|
8e958d7a13 | ||
|
|
76a3562d58 | ||
|
|
225ec594e7 | ||
|
|
585c769c2a | ||
|
|
fac625173a | ||
|
|
bffc3c18cc | ||
|
|
9e9df37c40 | ||
|
|
0f982e6199 | ||
|
|
4f3be7963e | ||
|
|
2cd4daa9ad | ||
|
|
60e9ce1b68 | ||
|
|
c9bf463419 | ||
|
|
a90e2a8bfd | ||
|
|
3828750ade | ||
|
|
5e3eb2c6a7 | ||
|
|
fd842be37f | ||
|
|
0cc65adff9 | ||
|
|
d6e4323f17 | ||
|
|
255dc925fb | ||
|
|
114c49e3f6 | ||
|
|
26077cbced | ||
|
|
44c67796b8 | ||
|
|
9770f103ed | ||
|
|
07ae332c24 | ||
|
|
99b5534099 | ||
|
|
54d202cf6b | ||
|
|
47f470910e | ||
|
|
235131c3fb | ||
|
|
9f35d2a2b7 | ||
|
|
934fd08506 | ||
|
|
7b182e32b8 | ||
|
|
3d9d54beef | ||
|
|
51b9f3ca3b | ||
|
|
3b6ed552e3 | ||
|
|
5ff3ae6434 | ||
|
|
e66f0d7033 | ||
|
|
b34adde6f3 | ||
|
|
5f2446009d | ||
|
|
19fc491532 | ||
|
|
853e626756 | ||
|
|
0a2cb7442d | ||
|
|
d86aa50bec | ||
|
|
df2fe7c445 | ||
|
|
6c85ca071f | ||
|
|
aaa82dceab | ||
|
|
b31518cfb5 | ||
|
|
e8ecf5dcd5 | ||
|
|
163c1db6be | ||
|
|
c8697d9158 | ||
|
|
c2af482615 | ||
|
|
a402fc9093 | ||
|
|
d822147704 | ||
|
|
387fc13322 | ||
|
|
b30191638f | ||
|
|
95991694e0 | ||
|
|
9b6d335c5d | ||
|
|
ffa075cd3d | ||
|
|
971c719a9f | ||
|
|
f3c291cb4d | ||
|
|
d76ce22db7 | ||
|
|
6d590cee3b | ||
|
|
af07a78f76 | ||
|
|
757b1efd7e | ||
|
|
d19bc53cb4 | ||
|
|
61b2ed36a9 | ||
|
|
4fb93853ce | ||
|
|
6e6b8e7eef | ||
|
|
50a4a961e5 | ||
|
|
f5edb32be9 | ||
|
|
b86708aaf8 | ||
|
|
5cf581e6c9 | ||
|
|
05e838ca5a | ||
|
|
25a18ee33a | ||
|
|
1d905963e9 | ||
|
|
ebf8492198 | ||
|
|
12e61efd76 | ||
|
|
0a350077e9 | ||
|
|
19c8613dea | ||
|
|
fb00698557 | ||
|
|
3d1eb830c7 | ||
|
|
2bc72a883f | ||
|
|
c15fcd00ec | ||
|
|
cd2a51f816 | ||
|
|
8b7c769ff9 | ||
|
|
4101cb2dfb | ||
|
|
03794970ba | ||
|
|
9d0afe9e18 | ||
|
|
f833450a68 | ||
|
|
d6bf2c5dbc | ||
|
|
b5e75a86c8 | ||
|
|
00943163c8 | ||
|
|
eb9b7f3b8c | ||
|
|
ba4b1e21fe | ||
|
|
cd85a03429 | ||
|
|
0113e7229f | ||
|
|
7e556acebc | ||
|
|
aa8455e0b1 | ||
|
|
2e22ca4ccf | ||
|
|
68f4611abc | ||
|
|
0e1135ed97 | ||
|
|
ebbdd29bd6 | ||
|
|
8c4331d15a | ||
|
|
4df4b91d09 | ||
|
|
b28c565665 | ||
|
|
efb0065ebd | ||
|
|
a0b6cbb671 | ||
|
|
44ba4069c1 | ||
|
|
bdc438fc62 | ||
|
|
b3c49db761 | ||
|
|
7ff4631a9f | ||
|
|
aad81bead7 | ||
|
|
88b55934c7 | ||
|
|
42962dcd48 | ||
|
|
093d2ea89f | ||
|
|
97a6679510 | ||
|
|
a3b0e4e993 | ||
|
|
3bf15a3798 | ||
|
|
dc96f2121a | ||
|
|
2899246dbc | ||
|
|
2444245b80 | ||
|
|
a748d0167b | ||
|
|
6cf1801f7e | ||
|
|
61c08afc7f | ||
|
|
61dc61d356 | ||
|
|
7f365c5102 | ||
|
|
42874073e9 | ||
|
|
63cdc7a72e | ||
|
|
cf7308dbc8 | ||
|
|
b37dbbd0af | ||
|
|
a6b870dfbb | ||
|
|
6426255bd4 | ||
|
|
8c36eccfef | ||
|
|
88de097c1c | ||
|
|
6ccffe9742 | ||
|
|
2fd01b2adf | ||
|
|
ea0d688345 | ||
|
|
891666c8bf | ||
|
|
a328308f67 | ||
|
|
e6ef1cfadd | ||
|
|
7f754f33bb | ||
|
|
516bd8cf03 | ||
|
|
add046cbda | ||
|
|
9908f8c289 | ||
|
|
259fe4b6b4 | ||
|
|
b07f28c30c | ||
|
|
8acf43256c | ||
|
|
962e419098 | ||
|
|
2e7c9b163d | ||
|
|
2c63a5f9a3 | ||
|
|
25128dfb66 | ||
|
|
c049de6939 | ||
|
|
82dbaece41 | ||
|
|
8e3badf4f7 | ||
|
|
93aea371a7 | ||
|
|
dd63fac8af | ||
|
|
8b411387f1 | ||
|
|
922818dfa5 | ||
|
|
0308ec555a | ||
|
|
008663c0e1 | ||
|
|
38e09920fa | ||
|
|
6fba381a4e | ||
|
|
e063f5a6b8 | ||
|
|
0b8b39ced0 | ||
|
|
5f22d8bac6 | ||
|
|
a5e1dad5fc | ||
|
|
ebb7d7a8d9 | ||
|
|
c6abf0b890 | ||
|
|
c10e1ba78c | ||
|
|
2e901a063d | ||
|
|
5a60818c99 | ||
|
|
a3400ecf26 | ||
|
|
a2fd0b1f7f | ||
|
|
db9cd15fb3 | ||
|
|
9af15d1e30 | ||
|
|
dc5517303f | ||
|
|
941d47908f | ||
|
|
0164032a4a | ||
|
|
70c2f50aa8 | ||
|
|
54273fc6e5 | ||
|
|
4e55e03c8b | ||
|
|
156e74b69c | ||
|
|
9d1872c948 | ||
|
|
8ba5edb6e4 | ||
|
|
5a4375f6ac | ||
|
|
6020cd55b1 | ||
|
|
7f8100ae0f | ||
|
|
22631cfc63 | ||
|
|
5faceac7ba | ||
|
|
ff16868dd8 | ||
|
|
287c6f172c | ||
|
|
cad10fa2c7 | ||
|
|
58713caa73 | ||
|
|
a6e3d4fd26 | ||
|
|
f34a319b79 | ||
|
|
1cc403191f | ||
|
|
2c7ee1d7e7 | ||
|
|
3e3c1239b0 | ||
|
|
4b4e041f6f | ||
|
|
423d5af87f | ||
|
|
5b6bbc3cbf | ||
|
|
f4dab801e4 | ||
|
|
a9e7acbec5 | ||
|
|
ac2382a861 | ||
|
|
2f93354981 | ||
|
|
c7f5d039b2 | ||
|
|
d652bdb0b0 | ||
|
|
f1c4634dfa | ||
|
|
f89bbeee54 | ||
|
|
e0e81a9b18 | ||
|
|
bfa5f6ec9c | ||
|
|
988e9f10db | ||
|
|
b0ac48b9a3 | ||
|
|
3de674dfb1 | ||
|
|
39a56c8e55 | ||
|
|
06b63980eb | ||
|
|
3eae944923 | ||
|
|
6997471280 | ||
|
|
4b95ed5d53 | ||
|
|
088dab799e | ||
|
|
0cdd0ea21a | ||
|
|
c413b9af04 | ||
|
|
76e926c090 | ||
|
|
d87b0e9435 | ||
|
|
b0f0d8fd71 | ||
|
|
7b07921a73 | ||
|
|
56c9dec687 | ||
|
|
936a531cd5 | ||
|
|
09215daa03 | ||
|
|
42f2235d45 | ||
|
|
2436d813e6 | ||
|
|
6271555c45 | ||
|
|
4b8493baab | ||
|
|
4e3def39e0 | ||
|
|
7e71045c7b | ||
|
|
2d5d5e3a9e | ||
|
|
c0b5b6af07 | ||
|
|
c104eabcdd | ||
|
|
933bdcc6b7 | ||
|
|
45803e4a49 | ||
|
|
8abff95441 | ||
|
|
f99caed4f2 | ||
|
|
4b0a976bd6 | ||
|
|
30d191df0b | ||
|
|
17a3e120e8 | ||
|
|
55b160e1bb | ||
|
|
a57eb14113 | ||
|
|
fa99305914 | ||
|
|
27ef182294 | ||
|
|
82e76d9872 | ||
|
|
2a0556fa4c | ||
|
|
22e36fc35d | ||
|
|
655a328b86 | ||
|
|
df1ef7133d | ||
|
|
bd14223ea8 | ||
|
|
72dfb0e7cc | ||
|
|
b2cc6ec82a | ||
|
|
c1d5ae2a09 | ||
|
|
627524dcb7 | ||
|
|
6b6829e22b | ||
|
|
67eecd4b1c | ||
|
|
a021a072b5 | ||
|
|
7e5970673f | ||
|
|
4eb4bb933f | ||
|
|
5284b145f8 | ||
|
|
bd8769f300 | ||
|
|
994dcd9f58 | ||
|
|
2bfb53227a | ||
|
|
ba761a15b6 | ||
|
|
58e6e9ea46 | ||
|
|
4825aefccf | ||
|
|
3a360a50b0 | ||
|
|
65ef8a0937 | ||
|
|
14d3a182d9 | ||
|
|
800e448264 | ||
|
|
2fef772f3d | ||
|
|
463d6fdcbe | ||
|
|
b2c786c06c | ||
|
|
c537c4fa78 | ||
|
|
2a01883177 | ||
|
|
c190ec5147 | ||
|
|
6ff9db89cc | ||
|
|
2a1e110a65 | ||
|
|
d08b47db93 | ||
|
|
2d0690e625 | ||
|
|
876df68294 | ||
|
|
b1efbdad95 | ||
|
|
230b578a98 | ||
|
|
02ce111d9e | ||
|
|
1b562ae837 | ||
|
|
ae04070915 | ||
|
|
f2596a8547 | ||
|
|
6cd734a305 | ||
|
|
d4cb5f6f3f | ||
|
|
5775c77aa3 | ||
|
|
29952d5b4f | ||
|
|
b2542289f0 | ||
|
|
910ac37716 | ||
|
|
ec7a251c09 | ||
|
|
92b319a05b | ||
|
|
b3760f58e6 | ||
|
|
a74388c954 | ||
|
|
5c6369b910 | ||
|
|
bbbbccf63d | ||
|
|
d050ca9849 | ||
|
|
77d225d1fe | ||
|
|
9b5f4a877c | ||
|
|
34cb75dfc3 | ||
|
|
43d68db349 | ||
|
|
b202b7b8a5 | ||
|
|
df01405583 |
17
.editorconfig
Normal file
17
.editorconfig
Normal file
@@ -0,0 +1,17 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
# Sadly too many files have whitespace errors, so we leave this as is for
|
||||
# now and just make sure we don't introduce any more.
|
||||
# trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.properties]
|
||||
insert_final_newline = false
|
||||
16
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
16
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Report some misbehaviour in the mod
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
## Before reporting
|
||||
- Search for the bug both here and [on the ComputerCraft issues page](https://github.com/dan200/ComputerCraft/issues?utf8=%E2%9C%93&q=is%3Aissue+)
|
||||
- If possible, try to reproduce on vanilla ComputerCraft. If it still occurs, [report on the ComputerCraft repo](https://github.com/dan200/ComputerCraft/issues/new) instead.
|
||||
-->
|
||||
|
||||
## Useful information to include:
|
||||
- Minecraft version
|
||||
- CC: Tweaked version
|
||||
- Detailed reproduction steps!** Sometimes I can spot a bug pretty easily, but often it's much more obscure. Anything you can give which will help reproduce it means it'll get fixed quicker.
|
||||
15
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
15
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea or improvement
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
## Before reporting
|
||||
- Search for the suggestion both here and [on the ComputerCraft issues page](https://github.com/dan200/ComputerCraft/issues?utf8=%E2%9C%93&q=is%3Aissue+). It's possible someone's suggested it before!
|
||||
- Unless something is specific to CC:Tweaked, try to [suggest them on the ComputerCraft repo](https://github.com/dan200/ComputerCraft/issues/new). There's a lot more people watching it, so it allows the wider community to contribute.
|
||||
-->
|
||||
|
||||
## Useful information to include:
|
||||
- Explanation of how the feature/change chould work.
|
||||
- Some rationale/use case for a feature. I'd like to keep CC:T as minimal
|
||||
9
.github/pull_request_template.md
vendored
Normal file
9
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<!--
|
||||
Unless this feature is specific to CC:Tweaked, try to [target the original ComputerCraft repo](https://github.com/dan200/ComputerCraft/) instead. There's a lot more people watching it, so it allows the wider community to contribute.
|
||||
-->
|
||||
|
||||
## Useful information to include:
|
||||
- Brief explanation of the changes you've made.
|
||||
- Rationale of why this change has been made/reasoning behind it.
|
||||
|
||||
The more information you can provide, the easier it is to review something now _and_ to see why a change was made, when the code needs updating in the future.
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -5,6 +5,8 @@ deploy
|
||||
*.ipr
|
||||
*.iws
|
||||
*.iml
|
||||
.idea
|
||||
.gradle
|
||||
luaj-2.0.3/lib
|
||||
luaj-2.0.3/*.jar
|
||||
*.DS_Store
|
||||
|
||||
14
.travis.yml
Normal file
14
.travis.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
language: java
|
||||
|
||||
script: ./gradlew build --no-daemon
|
||||
|
||||
before_cache:
|
||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.gradle/caches/
|
||||
- $HOME/.gradle/wrapper/s
|
||||
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
2
LICENSE
2
LICENSE
@@ -36,7 +36,7 @@ This mod is provided 'as is' with no warranties, implied or otherwise. The owner
|
||||
of this mod takes no responsibility for any damages incurred from the use of
|
||||
this mod. This mod alters fundamental parts of the Minecraft game, parts of
|
||||
Minecraft may not work with this mod installed. All damages caused from the use
|
||||
or misuse of this mad fall on the user.
|
||||
or misuse of this mod fall on the user.
|
||||
|
||||
3. Play rights
|
||||
--------------
|
||||
|
||||
56
README.md
56
README.md
@@ -1,25 +1,47 @@
|
||||
ComputerCraft
|
||||
=============
|
||||
# 
|
||||
[](https://travis-ci.org/SquidDev-CC/CC-Tweaked)
|
||||
|
||||
ComputerCraft is a Minecraft modification which adds programmable Robots and Computers to the world of Minecraft.
|
||||
If you're not familiar with ComputerCraft, visit the [Website](http://www.computercraft.info/download) or the [Wiki](http://www.computercraft.info/wiki) to find out more.
|
||||
CC: Tweaked is a fork of ComputerCraft which aims to provide earlier access to the more experimental and in-development
|
||||
features of the mod. For a more stable experience, I recommend checking out the
|
||||
[original mod](https://github.com/dan200/ComputerCraft).
|
||||
|
||||
About this Repository
|
||||
=====================
|
||||
## What?
|
||||
CC: Tweaked (or CC:T for short) does not aim to create a competing fork of ComputerCraft, nor am I planning to take it
|
||||
in in a vastly different direction to the original mod. In fact, CC:T aims to be a nurturing ground for various
|
||||
features, with a pull request against the original mod being the end goal.
|
||||
|
||||
ComputerCraft was originally released in late 2011 by [Daniel Ratcliffe](https://twitter.com/DanTwoHundred). In early 2017, after working on the mod solo for five years, it was decided to release the source code publicly to allow Dan to devote time to other projects. This repository marks the first public release of this source code.
|
||||
CC:T also includes many pull requests from the community which have not yet been merged, offering a large number
|
||||
of additional bug fixes and features over the original mod.
|
||||
|
||||
The code in this repository will always represent the "bleeding edge" of the ComputerCraft codebase, but stable builds back to 1.79 will be marked on the [Releases](https://github.com/dan200/ComputerCraft/releases) page.
|
||||
## Features
|
||||
CC: Tweaked contains the all features of the latest alpha, as well as numerous fixes, performance improvements and
|
||||
several additional features. I'd recommend checking out [the releases page](https://github.com/SquidDev-CC/CC-Tweaked/releases)
|
||||
to see the full changes, but here's a couple of the more interesting changes:
|
||||
|
||||
Contributing
|
||||
============
|
||||
- Replace LuaJ with Cobalt.
|
||||
- Allow running multiple computers at the same time.
|
||||
- Websocket support in the HTTP library.
|
||||
- Wired modems and cables act more like multiparts.
|
||||
- Add map-like rendering for pocket computers and printed pages/books.
|
||||
- Adds the `/computercraft` command, offering various diagnostic tools for server owners. This allows operators to
|
||||
track which computers are hogging resources, turn on and shutdown multiple computers at once and interact with
|
||||
computers remotely.
|
||||
- Add full-block wired modems, allowing one to wrap non-solid peripherals (such as turtles, or chests if Plethora is
|
||||
installed).
|
||||
|
||||
While ComputerCraft will no longer be actively developed by Daniel Ratcliffe, you may still contribute pull requests which will be reviewed and incorporated into releases periodically. A pull requests is more likely to be accepted if it meets the following criteria:
|
||||
## Relation to CCTweaks?
|
||||
This mod has nothing to do with CCTweaks, though there is no denying the name is a throwback to it. That being said,
|
||||
several features have been included, such as full block modems, the Cobalt runtime and map-like rendering for pocket
|
||||
computers.
|
||||
|
||||
* It does not add any new dependencies for compiling, running or using the mod.
|
||||
* It does not break compatibility with world saves or programs created with previous versions of the mod.
|
||||
* It does not add unneccessary complexity for users of the mod, and maintains the accessibility for which the mod is known.
|
||||
* It does not add unneccessary complexity or stylistic changes to the code, especially where functionality is not being changed.
|
||||
* It does not create bugs!
|
||||
## Contributing
|
||||
Any contribution is welcome, be that using the mod, reporting bugs or contributing code. If you do wish to contribute
|
||||
code, do consider submitting it to the ComputerCraft repository instead.
|
||||
|
||||
The pull requests most likely to be accepted are those which fix bugs, simplify code, or make the mod compatible with newer versions of Minecraft.
|
||||
That being said, in order to start helping develop CC:T, you'll need to follow these steps:
|
||||
|
||||
- **Clone the repository:** `git clone https://github.com/SquidDev-CC/CC-Tweaked.git && cd CC-Tweaked`
|
||||
- **Setup Forge:** `./gradlew setupDecompWorkspace`
|
||||
- **Test your changes:** `./gradlew runClient` (or run the `GradleStart` class from your IDE).
|
||||
|
||||
If you want to run CC:T in a normal Minecraft instance, run `./gradlew build` and copy the `.jar` from `build/libs`.
|
||||
|
||||
204
build.gradle
204
build.gradle
@@ -9,77 +9,197 @@ buildscript {
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath 'net.minecraftforge.gradle:ForgeGradle:2.2-SNAPSHOT'
|
||||
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
|
||||
classpath 'org.ajoberstar:gradle-git:1.6.0'
|
||||
}
|
||||
}
|
||||
apply plugin: 'net.minecraftforge.gradle.forge'
|
||||
|
||||
/*
|
||||
// for people who want stable - not yet functional for MC 1.8.8 - we require the forgegradle 2.1 snapshot
|
||||
plugins {
|
||||
id "net.minecraftforge.gradle.forge" version "2.0.2"
|
||||
id 'com.matthewprenger.cursegradle' version '1.0.10'
|
||||
}
|
||||
*/
|
||||
|
||||
version = "1.80pr0"
|
||||
group = "dan200.computercraft"
|
||||
archivesBaseName = "ComputerCraft"
|
||||
apply plugin: 'net.minecraftforge.gradle.forge'
|
||||
apply plugin: 'org.ajoberstar.grgit'
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: 'maven'
|
||||
|
||||
version = "1.80pr1.8"
|
||||
group = "org.squiddev"
|
||||
archivesBaseName = "cc-tweaked"
|
||||
|
||||
minecraft {
|
||||
version = "1.9.4-12.17.0.1959"
|
||||
version = "1.12.2-14.23.4.2749"
|
||||
runDir = "run"
|
||||
replace '${version}', project.version
|
||||
|
||||
|
||||
// the mappings can be changed at any time, and must be in the following format.
|
||||
// snapshot_YYYYMMDD snapshot are built nightly.
|
||||
// stable_# stables are built at the discretion of the MCP team.
|
||||
// Use non-default mappings at your own risk. they may not allways work.
|
||||
// simply re-run your setup task after changing the mappings to update your workspace.
|
||||
mappings = "snapshot_20160518"
|
||||
mappings = "snapshot_20180724"
|
||||
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// you may put jars on which you depend on in ./libs
|
||||
// or you may define them like so..
|
||||
//compile "some.group:artifact:version:classifier"
|
||||
//compile "some.group:artifact:version"
|
||||
|
||||
// real examples
|
||||
//compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env
|
||||
//compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env
|
||||
|
||||
// the 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime.
|
||||
//provided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
|
||||
|
||||
// the deobf configurations: 'deobfCompile' and 'deobfProvided' are the same as the normal compile and provided,
|
||||
// except that these dependencies get remapped to your current MCP mappings
|
||||
//deobfCompile 'com.mod-buildcraft:buildcraft:6.0.8:dev'
|
||||
//deobfProvided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
|
||||
|
||||
// for more info...
|
||||
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
|
||||
// http://www.gradle.org/docs/current/userguide/dependency_management.html
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven {
|
||||
name = "JEI"
|
||||
url = "http://dvs1.progwml6.com/files/maven"
|
||||
}
|
||||
maven {
|
||||
name = "squiddev"
|
||||
url = "https://dl.bintray.com/squiddev/maven"
|
||||
}
|
||||
|
||||
ivy { artifactPattern "https://asie.pl/files/mods/Charset/LibOnly/[module]-[revision](-[classifier]).[ext]" }
|
||||
}
|
||||
|
||||
processResources
|
||||
{
|
||||
// this will ensure that this task is redone when the versions change.
|
||||
configurations {
|
||||
shade
|
||||
compile.extendsFrom shade
|
||||
deployerJars
|
||||
}
|
||||
|
||||
dependencies {
|
||||
deobfProvided "mezz.jei:jei_1.12.2:4.8.5.159:api"
|
||||
deobfProvided "pl.asie:Charset-Lib:0.5.4.6"
|
||||
|
||||
runtime "mezz.jei:jei_1.12.2:4.8.5.159"
|
||||
|
||||
shade 'org.squiddev:Cobalt:0.3.2-nothread'
|
||||
|
||||
testCompile 'junit:junit:4.11'
|
||||
|
||||
deployerJars "org.apache.maven.wagon:wagon-ssh:3.0.0"
|
||||
}
|
||||
|
||||
javadoc {
|
||||
include "dan200/computercraft/api/**/*.java"
|
||||
}
|
||||
|
||||
jar {
|
||||
dependsOn javadoc
|
||||
|
||||
manifest {
|
||||
attributes('FMLAT': 'computercraft_at.cfg')
|
||||
}
|
||||
|
||||
into("docs", { from (javadoc.destinationDir) })
|
||||
|
||||
into("api", { from (sourceSets.main.allSource) {
|
||||
include "dan200/computercraft/api/**/*.java"
|
||||
}})
|
||||
|
||||
from configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }
|
||||
}
|
||||
|
||||
import org.ajoberstar.grgit.Grgit
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version
|
||||
inputs.property "mcversion", project.minecraft.version
|
||||
|
||||
// replace stuff in mcmod.info, nothing else
|
||||
def grgit = Grgit.open(dir: '.')
|
||||
inputs.property "commithash", grgit.head().id
|
||||
|
||||
def blacklist = ['GitHub', 'dan200', 'Daniel Ratcliffe']
|
||||
Set<String> contributors = []
|
||||
|
||||
grgit.log().each {
|
||||
if (!blacklist.contains(it.author.name)) contributors.add(it.author.name)
|
||||
if (!blacklist.contains(it.committer.name)) contributors.add(it.committer.name)
|
||||
}
|
||||
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
include 'mcmod.info'
|
||||
|
||||
// replace version and mcversion
|
||||
expand 'version':project.version, 'mcversion':project.minecraft.version
|
||||
include 'assets/computercraft/lua/rom/help/credits.txt'
|
||||
|
||||
expand 'version':project.version,
|
||||
'mcversion':project.minecraft.version,
|
||||
'gitcontributors':contributors.sort(false, String.CASE_INSENSITIVE_ORDER).join('\n')
|
||||
}
|
||||
|
||||
// copy everything else, thats not the mcmod.info
|
||||
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
exclude 'mcmod.info'
|
||||
exclude 'assets/computercraft/lua/rom/help/credits.txt'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
curseforge {
|
||||
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
|
||||
project {
|
||||
id = '282001'
|
||||
releaseType = 'beta'
|
||||
changelog = ''
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
from components.java
|
||||
artifact sourceJar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uploadArchives {
|
||||
repositories {
|
||||
if(project.hasProperty('mavenUploadUrl')) {
|
||||
mavenDeployer {
|
||||
configuration = configurations.deployerJars
|
||||
|
||||
repository(url: project.property('mavenUploadUrl')) {
|
||||
authentication(
|
||||
userName: project.property('mavenUploadUser'),
|
||||
privateKey: project.property('mavenUploadKey'))
|
||||
}
|
||||
|
||||
pom.project {
|
||||
name 'CC: Tweaked'
|
||||
packaging 'jar'
|
||||
description 'A fork of ComputerCraft which aims to provide earlier access to the more experimental and in-development features of the mod.'
|
||||
url 'https://github.com/SquidDev-CC/CC-Tweaked'
|
||||
|
||||
scm {
|
||||
url 'https://github.com/dan200/ComputerCraft.git'
|
||||
}
|
||||
|
||||
issueManagement {
|
||||
system 'github'
|
||||
url 'https://github.com/dan200/ComputerCraft/issues'
|
||||
}
|
||||
|
||||
licenses {
|
||||
license {
|
||||
name 'ComputerCraft Public License, Version 1.0'
|
||||
url 'https://github.com/dan200/ComputerCraft/blob/master/LICENSE'
|
||||
distribution 'repo'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pom.whenConfigured { pom ->
|
||||
pom.dependencies.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gradle.projectsEvaluated {
|
||||
tasks.withType(JavaCompile) {
|
||||
options.compilerArgs << "-Xlint"
|
||||
}
|
||||
}
|
||||
|
||||
runClient.outputs.upToDateWhen { false }
|
||||
runServer.outputs.upToDateWhen { false }
|
||||
|
||||
test {
|
||||
testLogging {
|
||||
events "failed", "standardOut", "standardError"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,4 +3,8 @@ echo "Java code:"
|
||||
cat `find src | grep \\.java$` | wc
|
||||
|
||||
echo "Lua code:"
|
||||
cat `find src/main/resources/assets/computercraft/lua` | wc
|
||||
cat `find src/main/resources/assets/computercraft/lua | grep \\.lua$` | wc
|
||||
|
||||
echo "JSON:"
|
||||
cat `find src/main/resources/assets/computercraft | grep \\.json$` | wc
|
||||
|
||||
|
||||
25
deploy.sh
Normal file → Executable file
25
deploy.sh
Normal file → Executable file
@@ -18,29 +18,4 @@ OUTPUTJAR=`ls -1 build/libs | grep -v sources | sed s/\-//g`
|
||||
FRIENDLYNAME=`ls -1 build/libs | grep -v sources | sed s/\-/\ /g | sed s/\.jar//g`
|
||||
cp build/libs/$INPUTJAR deploy/$OUTPUTJAR
|
||||
|
||||
echo "Creating API..."
|
||||
mkdir -p deploy/api/src/dan200/computercraft
|
||||
cp -r build/sources/main/java/dan200/computercraft/api deploy/api/src/dan200/computercraft/api
|
||||
|
||||
echo "Creating API Javadocs..."
|
||||
mkdir -p deploy/api/doc
|
||||
cd src/main/java/dan200/computercraft/api
|
||||
find . -type f -name "*.java" | xargs javadoc -d ../../../../../../deploy/api/doc -windowtitle "$FRIENDLYNAME"
|
||||
cd ../../../../../..
|
||||
|
||||
echo "Adding API and Javadocs to deployment..."
|
||||
cd deploy
|
||||
zip -r $OUTPUTJAR api/doc > /dev/null
|
||||
zip -r $OUTPUTJAR api/src/dan200/computercraft > /dev/null
|
||||
cd ..
|
||||
rm -rf deploy/api
|
||||
|
||||
echo "Adding LuaJ to deployment..."
|
||||
mkdir deploy/luaj
|
||||
cd deploy/luaj
|
||||
jar xf ../../libs/luaj-jse-2.0.3.jar
|
||||
zip -r ../$OUTPUTJAR org > /dev/null
|
||||
cd ../..
|
||||
rm -rf deploy/luaj
|
||||
|
||||
echo "Done."
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,5 @@
|
||||
#Mon Sep 14 12:28:28 PDT 2015
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.7-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.3-bin.zip
|
||||
|
||||
110
gradlew
vendored
Normal file → Executable file
110
gradlew
vendored
Normal file → Executable file
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
@@ -6,47 +6,6 @@
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS="-Xmx2048m"
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
@@ -61,9 +20,49 @@ while [ -h "$PRG" ] ; do
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
@@ -90,7 +89,7 @@ location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
@@ -114,6 +113,7 @@ fi
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
@@ -154,11 +154,19 @@ if $cygwin ; then
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
84
gradlew.bat
vendored
Normal file
84
gradlew.bat
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
Binary file not shown.
181
luaj-2.0.3/src/core/org/luaj/vm2/lib/Bit32Lib.java
Normal file
181
luaj-2.0.3/src/core/org/luaj/vm2/lib/Bit32Lib.java
Normal file
@@ -0,0 +1,181 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2012 Luaj.org. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2.lib;
|
||||
|
||||
import org.luaj.vm2.LuaInteger;
|
||||
import org.luaj.vm2.LuaTable;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.Varargs;
|
||||
|
||||
/**
|
||||
* Subclass of LibFunction that implements the Lua standard {@code bit32} library.
|
||||
*/
|
||||
public class Bit32Lib extends ZeroArgFunction
|
||||
{
|
||||
public LuaValue call( )
|
||||
{
|
||||
LuaTable t = new LuaTable();
|
||||
bind( t, Bit32LibV.class, new String[] {
|
||||
"band", "bnot", "bor", "btest", "bxor", "extract", "replace"
|
||||
} );
|
||||
bind( t, Bit32Lib2.class, new String[] {
|
||||
"arshift", "lrotate", "lshift", "rrotate", "rshift"
|
||||
} );
|
||||
env.set( "bit32", t );
|
||||
return t;
|
||||
}
|
||||
|
||||
public static final class Bit32LibV extends VarArgFunction
|
||||
{
|
||||
public Varargs invoke( Varargs args )
|
||||
{
|
||||
switch( opcode )
|
||||
{
|
||||
case 0: // band
|
||||
{
|
||||
int result = -1;
|
||||
for( int i = 1; i <= args.narg(); i++ )
|
||||
{
|
||||
result &= args.checkint( i );
|
||||
}
|
||||
return bitsToValue( result );
|
||||
}
|
||||
case 1: // bnot
|
||||
return bitsToValue( ~args.checkint( 1 ) );
|
||||
case 2: // bot
|
||||
{
|
||||
int result = 0;
|
||||
for( int i = 1; i <= args.narg(); i++ )
|
||||
{
|
||||
result |= args.checkint( i );
|
||||
}
|
||||
return bitsToValue( result );
|
||||
}
|
||||
case 3: // btest
|
||||
{
|
||||
int bits = -1;
|
||||
for( int i = 1; i <= args.narg(); i++ )
|
||||
{
|
||||
bits &= args.checkint( i );
|
||||
}
|
||||
return valueOf( bits != 0 );
|
||||
}
|
||||
case 4: // bxor
|
||||
{
|
||||
int result = 0;
|
||||
for( int i = 1; i <= args.narg(); i++ )
|
||||
{
|
||||
result ^= args.checkint( i );
|
||||
}
|
||||
return bitsToValue( result );
|
||||
}
|
||||
case 5: // extract
|
||||
{
|
||||
int field = args.checkint( 2 );
|
||||
int width = args.optint( 3, 1 );
|
||||
|
||||
if( field < 0 ) argerror( 2, "field cannot be negative" );
|
||||
if( width <= 0 ) argerror( 3, "width must be postive" );
|
||||
if( field + width > 32 ) error( "trying to access non-existent bits" );
|
||||
|
||||
return bitsToValue( (args.checkint( 1 ) >>> field) & (-1 >>> (32 - width)) );
|
||||
}
|
||||
case 6: // replace
|
||||
{
|
||||
int n = args.checkint( 1 );
|
||||
int v = args.checkint( 2 );
|
||||
int field = args.checkint( 3 );
|
||||
int width = args.optint( 4, 1 );
|
||||
|
||||
if( field < 0 ) argerror( 3, "field cannot be negative" );
|
||||
if( width <= 0 ) argerror( 4, "width must be postive" );
|
||||
if( field + width > 32 ) error( "trying to access non-existent bits" );
|
||||
|
||||
int mask = (-1 >>> (32 - width)) << field;
|
||||
n = (n & ~mask) | ((v << field) & mask);
|
||||
return bitsToValue( n );
|
||||
}
|
||||
}
|
||||
return NIL;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Bit32Lib2 extends TwoArgFunction
|
||||
{
|
||||
public LuaValue call( LuaValue arg1, LuaValue arg2 )
|
||||
{
|
||||
switch( opcode )
|
||||
{
|
||||
case 0: // arshift
|
||||
{
|
||||
int x = arg1.checkint();
|
||||
int disp = arg2.checkint();
|
||||
return disp >= 0 ? bitsToValue( x >> disp ) : bitsToValue( x << -disp );
|
||||
}
|
||||
case 1: // lrotate
|
||||
return rotate( arg1.checkint(), arg2.checkint() );
|
||||
case 2: // lshift
|
||||
return shift( arg1.checkint(), arg2.checkint() );
|
||||
case 3: // rrotate
|
||||
return rotate( arg1.checkint(), -arg2.checkint() );
|
||||
case 4: // rshift
|
||||
return shift( arg1.checkint(), -arg2.checkint() );
|
||||
}
|
||||
return NIL;
|
||||
}
|
||||
}
|
||||
|
||||
static LuaValue rotate( int x, int disp )
|
||||
{
|
||||
if( disp < 0 )
|
||||
{
|
||||
disp = -disp & 31;
|
||||
return bitsToValue( (x >>> disp) | (x << (32 - disp)) );
|
||||
}
|
||||
else
|
||||
{
|
||||
disp = disp & 31;
|
||||
return bitsToValue( (x << disp) | (x >>> (32 - disp)) );
|
||||
}
|
||||
}
|
||||
|
||||
static LuaValue shift( int x, int disp )
|
||||
{
|
||||
if( disp >= 32 || disp <= -32 )
|
||||
{
|
||||
return ZERO;
|
||||
}
|
||||
else if( disp >= 0 )
|
||||
{
|
||||
return bitsToValue( x << disp );
|
||||
}
|
||||
else
|
||||
{
|
||||
return bitsToValue( x >>> -disp );
|
||||
}
|
||||
}
|
||||
|
||||
private static LuaValue bitsToValue( int x )
|
||||
{
|
||||
return x < 0 ? LuaValue.valueOf( (long) x & 0xFFFFFFFFL ) : LuaInteger.valueOf( x );
|
||||
}
|
||||
}
|
||||
1
settings.gradle
Normal file
1
settings.gradle
Normal file
@@ -0,0 +1 @@
|
||||
rootProject.name = 'cc-tweaked'
|
||||
7
setup.bat
Normal file
7
setup.bat
Normal file
@@ -0,0 +1,7 @@
|
||||
echo "Setting up IntelliJ development environment with gradle..."
|
||||
rmdir /s /q .\build
|
||||
call gradlew.bat --stacktrace setupDecompWorkspace --refresh-dependencies
|
||||
call gradlew.bat --stacktrace cleanIdea idea
|
||||
|
||||
echo "Done."
|
||||
pause
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
@@ -8,15 +8,26 @@ package dan200.computercraft.api;
|
||||
|
||||
import dan200.computercraft.api.filesystem.IMount;
|
||||
import dan200.computercraft.api.filesystem.IWritableMount;
|
||||
import dan200.computercraft.api.lua.ILuaAPIFactory;
|
||||
import dan200.computercraft.api.media.IMedia;
|
||||
import dan200.computercraft.api.media.IMediaProvider;
|
||||
import dan200.computercraft.api.network.IPacketNetwork;
|
||||
import dan200.computercraft.api.network.wired.IWiredElement;
|
||||
import dan200.computercraft.api.network.wired.IWiredNode;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.api.peripheral.IPeripheralProvider;
|
||||
import dan200.computercraft.api.permissions.ITurtlePermissionProvider;
|
||||
import dan200.computercraft.api.pocket.IPocketUpgrade;
|
||||
import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
@@ -32,6 +43,7 @@ public final class ComputerCraftAPI
|
||||
return computerCraft != null;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static String getInstalledVersion()
|
||||
{
|
||||
findCC();
|
||||
@@ -46,116 +58,134 @@ public final class ComputerCraftAPI
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static String getAPIVersion()
|
||||
{
|
||||
return "${version}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a numbered directory in a subfolder of the save directory for a given world, and returns that number.<br>
|
||||
* Use in conjuction with createSaveDirMount() to create a unique place for your peripherals or media items to store files.<br>
|
||||
* @param world The world for which the save dir should be created. This should be the serverside world object.
|
||||
* @param parentSubPath The folder path within the save directory where the new directory should be created. eg: "computercraft/disk"
|
||||
* @return The numerical value of the name of the new folder, or -1 if the folder could not be created for some reason.<br>
|
||||
* eg: if createUniqueNumberedSaveDir( world, "computer/disk" ) was called returns 42, then "computer/disk/42" is now available for writing.
|
||||
* @see #createSaveDirMount(World, String, long)
|
||||
*/
|
||||
public static int createUniqueNumberedSaveDir( World world, String parentSubPath )
|
||||
{
|
||||
findCC();
|
||||
if( computerCraft_createUniqueNumberedSaveDir != null )
|
||||
{
|
||||
try {
|
||||
return (Integer)computerCraft_createUniqueNumberedSaveDir.invoke( null, world, parentSubPath );
|
||||
} catch (Exception e) {
|
||||
// It failed
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a file system mount that maps to a subfolder of the save directory for a given world, and returns it.<br>
|
||||
* Use in conjuction with IComputerAccess.mount() or IComputerAccess.mountWritable() to mount a folder from the
|
||||
* users save directory onto a computers file system.<br>
|
||||
* @param world The world for which the save dir can be found. This should be the serverside world object.
|
||||
* @param subPath The folder path within the save directory that the mount should map to. eg: "computer/disk/42".<br>
|
||||
* Use createUniqueNumberedSaveDir() to create a new numbered folder to use.
|
||||
* @param capacity The ammount of data that can be stored in the directory before it fills up, in bytes.
|
||||
* @return The mount, or null if it could be created for some reason. Use IComputerAccess.mount() or IComputerAccess.mountWritable()
|
||||
* to mount this on a Computers' file system.
|
||||
* @see #createUniqueNumberedSaveDir(World, String)
|
||||
* @see dan200.computercraft.api.peripheral.IComputerAccess#mount(String, dan200.computercraft.api.filesystem.IMount)
|
||||
* @see dan200.computercraft.api.peripheral.IComputerAccess#mountWritable(String, dan200.computercraft.api.filesystem.IWritableMount)
|
||||
* @see dan200.computercraft.api.filesystem.IMount
|
||||
* @see IWritableMount
|
||||
*/
|
||||
public static IWritableMount createSaveDirMount( World world, String subPath, long capacity )
|
||||
{
|
||||
findCC();
|
||||
if( computerCraft_createSaveDirMount != null )
|
||||
{
|
||||
try {
|
||||
return (IWritableMount)computerCraft_createSaveDirMount.invoke( null, world, subPath, capacity );
|
||||
} catch (Exception e){
|
||||
// It failed
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a file system mount to a resource folder, and returns it.<br>
|
||||
* Use in conjuction with IComputerAccess.mount() or IComputerAccess.mountWritable() to mount a resource folder onto a computers file system.<br>
|
||||
* The files in this mount will be a combination of files in the specified mod jar, and resource packs that contain resources with the same domain and path.<br>
|
||||
* @param modClass A class in whose jar to look first for the resources to mount. Using your main mod class is recommended. eg: MyMod.class
|
||||
* @param domain The domain under which to look for resources. eg: "mymod"
|
||||
* @param subPath The domain under which to look for resources. eg: "mymod/lua/myfiles"
|
||||
* @return The mount, or null if it could be created for some reason. Use IComputerAccess.mount() or IComputerAccess.mountWritable()
|
||||
* to mount this on a Computers' file system.
|
||||
* @see dan200.computercraft.api.peripheral.IComputerAccess#mount(String, dan200.computercraft.api.filesystem.IMount)
|
||||
* @see dan200.computercraft.api.peripheral.IComputerAccess#mountWritable(String, IWritableMount)
|
||||
* @see dan200.computercraft.api.filesystem.IMount
|
||||
*/
|
||||
public static IMount createResourceMount( Class modClass, String domain, String subPath )
|
||||
{
|
||||
findCC();
|
||||
if( computerCraft_createResourceMount != null )
|
||||
{
|
||||
try {
|
||||
return (IMount)computerCraft_createResourceMount.invoke( null, modClass, domain, subPath );
|
||||
} catch (Exception e){
|
||||
// It failed
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a peripheral handler to convert blocks into IPeripheral implementations.
|
||||
* @see dan200.computercraft.api.peripheral.IPeripheral
|
||||
* @see dan200.computercraft.api.peripheral.IPeripheralProvider
|
||||
*/
|
||||
public static void registerPeripheralProvider( IPeripheralProvider handler )
|
||||
{
|
||||
findCC();
|
||||
if ( computerCraft_registerPeripheralProvider != null)
|
||||
{
|
||||
try {
|
||||
computerCraft_registerPeripheralProvider.invoke( null, handler );
|
||||
} catch (Exception e){
|
||||
// It failed
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Creates a numbered directory in a subfolder of the save directory for a given world, and returns that number.
|
||||
*
|
||||
* Use in conjunction with createSaveDirMount() to create a unique place for your peripherals or media items to store files.
|
||||
*
|
||||
* @param world The world for which the save dir should be created. This should be the server side world object.
|
||||
* @param parentSubPath The folder path within the save directory where the new directory should be created. eg: "computercraft/disk"
|
||||
* @return The numerical value of the name of the new folder, or -1 if the folder could not be created for some reason.
|
||||
*
|
||||
* eg: if createUniqueNumberedSaveDir( world, "computer/disk" ) was called returns 42, then "computer/disk/42" is now
|
||||
* available for writing.
|
||||
* @see #createSaveDirMount(World, String, long)
|
||||
*/
|
||||
public static int createUniqueNumberedSaveDir( @Nonnull World world, @Nonnull String parentSubPath )
|
||||
{
|
||||
findCC();
|
||||
if( computerCraft_createUniqueNumberedSaveDir != null )
|
||||
{
|
||||
try {
|
||||
return (Integer)computerCraft_createUniqueNumberedSaveDir.invoke( null, world, parentSubPath );
|
||||
} catch (Exception e) {
|
||||
// It failed
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a file system mount that maps to a subfolder of the save directory for a given world, and returns it.
|
||||
*
|
||||
* Use in conjunction with IComputerAccess.mount() or IComputerAccess.mountWritable() to mount a folder from the
|
||||
* users save directory onto a computers file system.
|
||||
*
|
||||
* @param world The world for which the save dir can be found. This should be the server side world object.
|
||||
* @param subPath The folder path within the save directory that the mount should map to. eg: "computer/disk/42".
|
||||
* Use createUniqueNumberedSaveDir() to create a new numbered folder to use.
|
||||
* @param capacity The amount of data that can be stored in the directory before it fills up, in bytes.
|
||||
* @return The mount, or null if it could be created for some reason. Use IComputerAccess.mount() or IComputerAccess.mountWritable()
|
||||
* to mount this on a Computers' file system.
|
||||
* @see #createUniqueNumberedSaveDir(World, String)
|
||||
* @see IComputerAccess#mount(String, IMount)
|
||||
* @see IComputerAccess#mountWritable(String, IWritableMount)
|
||||
* @see IMount
|
||||
* @see IWritableMount
|
||||
*/
|
||||
@Nullable
|
||||
public static IWritableMount createSaveDirMount( @Nonnull World world, @Nonnull String subPath, long capacity )
|
||||
{
|
||||
findCC();
|
||||
if( computerCraft_createSaveDirMount != null )
|
||||
{
|
||||
try {
|
||||
return (IWritableMount)computerCraft_createSaveDirMount.invoke( null, world, subPath, capacity );
|
||||
} catch (Exception e){
|
||||
// It failed
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a file system mount to a resource folder, and returns it.
|
||||
*
|
||||
* Use in conjunction with IComputerAccess.mount() or IComputerAccess.mountWritable() to mount a resource folder
|
||||
* onto a computer's file system.
|
||||
*
|
||||
* The files in this mount will be a combination of files in the specified mod jar, and resource packs that contain
|
||||
* resources with the same domain and path.
|
||||
*
|
||||
* @param modClass A class in whose jar to look first for the resources to mount. Using your main mod class is recommended. eg: MyMod.class
|
||||
* @param domain The domain under which to look for resources. eg: "mymod".
|
||||
* @param subPath The domain under which to look for resources. eg: "mymod/lua/myfiles".
|
||||
* @return The mount, or {@code null} if it could be created for some reason. Use IComputerAccess.mount() or
|
||||
* IComputerAccess.mountWritable() to mount this on a Computers' file system.
|
||||
* @see IComputerAccess#mount(String, IMount)
|
||||
* @see IComputerAccess#mountWritable(String, IWritableMount)
|
||||
* @see IMount
|
||||
*/
|
||||
@Nullable
|
||||
public static IMount createResourceMount( @Nonnull Class<?> modClass, @Nonnull String domain, @Nonnull String subPath )
|
||||
{
|
||||
findCC();
|
||||
if( computerCraft_createResourceMount != null )
|
||||
{
|
||||
try {
|
||||
return (IMount)computerCraft_createResourceMount.invoke( null, modClass, domain, subPath );
|
||||
} catch (Exception e){
|
||||
// It failed
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a peripheral handler to convert blocks into {@link IPeripheral} implementations.
|
||||
*
|
||||
* @param handler The peripheral provider to register.
|
||||
* @see dan200.computercraft.api.peripheral.IPeripheral
|
||||
* @see dan200.computercraft.api.peripheral.IPeripheralProvider
|
||||
*/
|
||||
public static void registerPeripheralProvider( @Nonnull IPeripheralProvider handler )
|
||||
{
|
||||
findCC();
|
||||
if ( computerCraft_registerPeripheralProvider != null)
|
||||
{
|
||||
try {
|
||||
computerCraft_registerPeripheralProvider.invoke( null, handler );
|
||||
} catch (Exception e){
|
||||
// It failed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new turtle turtle for use in ComputerCraft. After calling this,
|
||||
* users should be able to craft Turtles with your new turtle. It is recommended to call
|
||||
* this during the load() method of your mod.
|
||||
*
|
||||
* @param upgrade The turtle upgrade to register.
|
||||
* @see dan200.computercraft.api.turtle.ITurtleUpgrade
|
||||
*/
|
||||
public static void registerTurtleUpgrade( ITurtleUpgrade upgrade )
|
||||
public static void registerTurtleUpgrade( @Nonnull ITurtleUpgrade upgrade )
|
||||
{
|
||||
if( upgrade != null )
|
||||
{
|
||||
@@ -172,10 +202,12 @@ public final class ComputerCraftAPI
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a bundled redstone handler to provide bundled redstone output for blocks
|
||||
* Registers a bundled redstone handler to provide bundled redstone output for blocks.
|
||||
*
|
||||
* @param handler The bundled redstone provider to register.
|
||||
* @see dan200.computercraft.api.redstone.IBundledRedstoneProvider
|
||||
*/
|
||||
public static void registerBundledRedstoneProvider( IBundledRedstoneProvider handler )
|
||||
public static void registerBundledRedstoneProvider( @Nonnull IBundledRedstoneProvider handler )
|
||||
{
|
||||
findCC();
|
||||
if( computerCraft_registerBundledRedstoneProvider != null )
|
||||
@@ -190,11 +222,15 @@ public final class ComputerCraftAPI
|
||||
|
||||
/**
|
||||
* If there is a Computer or Turtle at a certain position in the world, get it's bundled redstone output.
|
||||
* @see dan200.computercraft.api.redstone.IBundledRedstoneProvider
|
||||
*
|
||||
* @param world The world this block is in.
|
||||
* @param pos The position this block is at.
|
||||
* @param side The side to extract the bundled redstone output from.
|
||||
* @return If there is a block capable of emitting bundled redstone at the location, it's signal (0-65535) will be returned.
|
||||
* If there is no block capable of emitting bundled redstone at the location, -1 will be returned.
|
||||
* @see dan200.computercraft.api.redstone.IBundledRedstoneProvider
|
||||
*/
|
||||
public static int getBundledRedstoneOutput( World world, BlockPos pos, EnumFacing side )
|
||||
public static int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull EnumFacing side )
|
||||
{
|
||||
findCC();
|
||||
if( computerCraft_getDefaultBundledRedstoneOutput != null )
|
||||
@@ -209,10 +245,12 @@ public final class ComputerCraftAPI
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a media handler to provide IMedia implementations for Items
|
||||
* Registers a media handler to provide {@link IMedia} implementations for Items
|
||||
*
|
||||
* @param handler The media provider to register.
|
||||
* @see dan200.computercraft.api.media.IMediaProvider
|
||||
*/
|
||||
public static void registerMediaProvider( IMediaProvider handler )
|
||||
public static void registerMediaProvider( @Nonnull IMediaProvider handler )
|
||||
{
|
||||
findCC();
|
||||
if( computerCraft_registerMediaProvider != null )
|
||||
@@ -226,10 +264,12 @@ public final class ComputerCraftAPI
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a permission handler to restrict where turtles can move or build
|
||||
* Registers a permission handler to restrict where turtles can move or build.
|
||||
*
|
||||
* @param handler The turtle permission provider to register.
|
||||
* @see dan200.computercraft.api.permissions.ITurtlePermissionProvider
|
||||
*/
|
||||
public static void registerPermissionProvider( ITurtlePermissionProvider handler )
|
||||
public static void registerPermissionProvider( @Nonnull ITurtlePermissionProvider handler )
|
||||
{
|
||||
findCC();
|
||||
if( computerCraft_registerPermissionProvider != null )
|
||||
@@ -242,76 +282,199 @@ public final class ComputerCraftAPI
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerPocketUpgrade( @Nonnull IPocketUpgrade upgrade )
|
||||
{
|
||||
findCC();
|
||||
if(computerCraft_registerPocketUpgrade != null) {
|
||||
try {
|
||||
computerCraft_registerPocketUpgrade.invoke( null, upgrade );
|
||||
} catch (Exception e) {
|
||||
// It failed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to get the game-wide wireless network.
|
||||
*
|
||||
* @return The global wireless network, or {@code null} if it could not be fetched.
|
||||
*/
|
||||
public static IPacketNetwork getWirelessNetwork()
|
||||
{
|
||||
findCC();
|
||||
if( computerCraft_getWirelessNetwork != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
return (IPacketNetwork) computerCraft_getWirelessNetwork.invoke( null );
|
||||
} catch (Exception e) {
|
||||
// It failed;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void registerAPIFactory( @Nonnull ILuaAPIFactory upgrade )
|
||||
{
|
||||
findCC();
|
||||
if( computerCraft_registerAPIFactory != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
computerCraft_registerAPIFactory.invoke( null, upgrade );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
// It failed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new wired node for a given wired element
|
||||
*
|
||||
* @param element The element to construct it for
|
||||
* @return The element's node
|
||||
* @see IWiredElement#getNode()
|
||||
*/
|
||||
@Nonnull
|
||||
public static IWiredNode createWiredNodeForElement( @Nonnull IWiredElement element )
|
||||
{
|
||||
findCC();
|
||||
if( computerCraft_createWiredNodeForElement != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
return (IWiredNode) computerCraft_createWiredNodeForElement.invoke( null, element );
|
||||
}
|
||||
catch( ReflectiveOperationException e )
|
||||
{
|
||||
throw new IllegalStateException( "Error creating wired node", e );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalStateException( "ComputerCraft cannot be found" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the wired network element for a block in world
|
||||
*
|
||||
* @param world The world the block exists in
|
||||
* @param pos The position the block exists in
|
||||
* @param side The side to extract the network element from
|
||||
* @return The element's node
|
||||
* @see IWiredElement#getNode()
|
||||
*/
|
||||
@Nullable
|
||||
public static IWiredElement getWiredElementAt( @Nonnull IBlockAccess world, @Nonnull BlockPos pos, @Nonnull EnumFacing side )
|
||||
{
|
||||
findCC();
|
||||
if( computerCraft_getWiredElementAt != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
return (IWiredElement) computerCraft_getWiredElementAt.invoke( null, world, pos, side );
|
||||
}
|
||||
catch( ReflectiveOperationException ignored )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// The functions below here are private, and are used to interface with the non-API ComputerCraft classes.
|
||||
// Reflection is used here so you can develop your mod without decompiling ComputerCraft and including
|
||||
// it in your solution, and so your mod won't crash if ComputerCraft is installed.
|
||||
|
||||
private static void findCC()
|
||||
{
|
||||
if( !ccSearched ) {
|
||||
try {
|
||||
computerCraft = Class.forName( "dan200.computercraft.ComputerCraft" );
|
||||
computerCraft_getVersion = findCCMethod( "getVersion", new Class[]{
|
||||
// Reflection is used here so you can develop your mod without decompiling ComputerCraft and including
|
||||
// it in your solution, and so your mod won't crash if ComputerCraft is installed.
|
||||
|
||||
private static void findCC()
|
||||
{
|
||||
if( !ccSearched ) {
|
||||
try {
|
||||
computerCraft = Class.forName( "dan200.computercraft.ComputerCraft" );
|
||||
computerCraft_getVersion = findCCMethod( "getVersion", new Class<?>[]{
|
||||
} );
|
||||
computerCraft_createUniqueNumberedSaveDir = findCCMethod( "createUniqueNumberedSaveDir", new Class[]{
|
||||
computerCraft_createUniqueNumberedSaveDir = findCCMethod( "createUniqueNumberedSaveDir", new Class<?>[]{
|
||||
World.class, String.class
|
||||
} );
|
||||
computerCraft_createSaveDirMount = findCCMethod( "createSaveDirMount", new Class[] {
|
||||
World.class, String.class, Long.TYPE
|
||||
} );
|
||||
computerCraft_createResourceMount = findCCMethod( "createResourceMount", new Class[] {
|
||||
Class.class, String.class, String.class
|
||||
} );
|
||||
computerCraft_registerPeripheralProvider = findCCMethod( "registerPeripheralProvider", new Class[] {
|
||||
IPeripheralProvider.class
|
||||
} );
|
||||
computerCraft_registerTurtleUpgrade = findCCMethod( "registerTurtleUpgrade", new Class[] {
|
||||
computerCraft_createSaveDirMount = findCCMethod( "createSaveDirMount", new Class<?>[] {
|
||||
World.class, String.class, Long.TYPE
|
||||
} );
|
||||
computerCraft_createResourceMount = findCCMethod( "createResourceMount", new Class<?>[] {
|
||||
Class.class, String.class, String.class
|
||||
} );
|
||||
computerCraft_registerPeripheralProvider = findCCMethod( "registerPeripheralProvider", new Class<?>[] {
|
||||
IPeripheralProvider.class
|
||||
} );
|
||||
computerCraft_registerTurtleUpgrade = findCCMethod( "registerTurtleUpgrade", new Class<?>[] {
|
||||
ITurtleUpgrade.class
|
||||
} );
|
||||
computerCraft_registerBundledRedstoneProvider = findCCMethod( "registerBundledRedstoneProvider", new Class[] {
|
||||
computerCraft_registerBundledRedstoneProvider = findCCMethod( "registerBundledRedstoneProvider", new Class<?>[] {
|
||||
IBundledRedstoneProvider.class
|
||||
} );
|
||||
computerCraft_getDefaultBundledRedstoneOutput = findCCMethod( "getDefaultBundledRedstoneOutput", new Class[] {
|
||||
computerCraft_getDefaultBundledRedstoneOutput = findCCMethod( "getDefaultBundledRedstoneOutput", new Class<?>[] {
|
||||
World.class, BlockPos.class, EnumFacing.class
|
||||
} );
|
||||
computerCraft_registerMediaProvider = findCCMethod( "registerMediaProvider", new Class[] {
|
||||
computerCraft_registerMediaProvider = findCCMethod( "registerMediaProvider", new Class<?>[] {
|
||||
IMediaProvider.class
|
||||
} );
|
||||
computerCraft_registerPermissionProvider = findCCMethod( "registerPermissionProvider", new Class[] {
|
||||
computerCraft_registerPermissionProvider = findCCMethod( "registerPermissionProvider", new Class<?>[] {
|
||||
ITurtlePermissionProvider.class
|
||||
} );
|
||||
} catch( Exception e ) {
|
||||
System.out.println( "ComputerCraftAPI: ComputerCraft not found." );
|
||||
} finally {
|
||||
ccSearched = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
computerCraft_registerPocketUpgrade = findCCMethod( "registerPocketUpgrade", new Class<?>[] {
|
||||
IPocketUpgrade.class
|
||||
} );
|
||||
computerCraft_getWirelessNetwork = findCCMethod( "getWirelessNetwork", new Class<?>[] {
|
||||
} );
|
||||
computerCraft_registerAPIFactory = findCCMethod( "registerAPIFactory", new Class<?>[] {
|
||||
ILuaAPIFactory.class
|
||||
} );
|
||||
computerCraft_createWiredNodeForElement = findCCMethod( "createWiredNodeForElement", new Class<?>[] {
|
||||
IWiredElement.class
|
||||
} );
|
||||
computerCraft_getWiredElementAt = findCCMethod( "getWiredElementAt", new Class<?>[]{
|
||||
IBlockAccess.class, BlockPos.class, EnumFacing.class
|
||||
} );
|
||||
} catch( Exception e ) {
|
||||
System.out.println( "ComputerCraftAPI: ComputerCraft not found." );
|
||||
} finally {
|
||||
ccSearched = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Method findCCMethod( String name, Class[] args )
|
||||
{
|
||||
try {
|
||||
private static Method findCCMethod( String name, Class<?>[] args )
|
||||
{
|
||||
try {
|
||||
if( computerCraft != null )
|
||||
{
|
||||
return computerCraft.getMethod( name, args );
|
||||
return computerCraft.getMethod( name, args );
|
||||
}
|
||||
return null;
|
||||
} catch( NoSuchMethodException e ) {
|
||||
System.out.println( "ComputerCraftAPI: ComputerCraft method " + name + " not found." );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean ccSearched = false;
|
||||
private static Class computerCraft = null;
|
||||
} catch( NoSuchMethodException e ) {
|
||||
System.out.println( "ComputerCraftAPI: ComputerCraft method " + name + " not found." );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean ccSearched = false;
|
||||
private static Class<?> computerCraft = null;
|
||||
private static Method computerCraft_getVersion = null;
|
||||
private static Method computerCraft_createUniqueNumberedSaveDir = null;
|
||||
private static Method computerCraft_createSaveDirMount = null;
|
||||
private static Method computerCraft_createResourceMount = null;
|
||||
private static Method computerCraft_registerPeripheralProvider = null;
|
||||
private static Method computerCraft_createUniqueNumberedSaveDir = null;
|
||||
private static Method computerCraft_createSaveDirMount = null;
|
||||
private static Method computerCraft_createResourceMount = null;
|
||||
private static Method computerCraft_registerPeripheralProvider = null;
|
||||
private static Method computerCraft_registerTurtleUpgrade = null;
|
||||
private static Method computerCraft_registerBundledRedstoneProvider = null;
|
||||
private static Method computerCraft_getDefaultBundledRedstoneOutput = null;
|
||||
private static Method computerCraft_registerMediaProvider = null;
|
||||
private static Method computerCraft_registerPermissionProvider = null;
|
||||
private static Method computerCraft_registerPocketUpgrade = null;
|
||||
private static Method computerCraft_getWirelessNetwork = null;
|
||||
private static Method computerCraft_registerAPIFactory = null;
|
||||
private static Method computerCraft_createWiredNodeForElement = null;
|
||||
private static Method computerCraft_getWiredElementAt = null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package dan200.computercraft.api.filesystem;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Provides a mount of the entire computer's file system.
|
||||
*
|
||||
* This exists for use by various APIs - one should not attempt to mount it.
|
||||
*/
|
||||
public interface IFileSystem extends IWritableMount
|
||||
{
|
||||
/**
|
||||
* Combine two paths together, reducing them into a normalised form.
|
||||
*
|
||||
* @param path The main path.
|
||||
* @param child The path to append.
|
||||
* @return The combined, normalised path.
|
||||
*/
|
||||
String combine( String path, String child );
|
||||
|
||||
/**
|
||||
* Copy files from one location to another.
|
||||
*
|
||||
* @param from The location to copy from.
|
||||
* @param to The location to copy to. This should not exist.
|
||||
* @throws IOException If the copy failed.
|
||||
*/
|
||||
void copy( String from, String to ) throws IOException;
|
||||
|
||||
/**
|
||||
* Move files from one location to another.
|
||||
*
|
||||
* @param from The location to move from.
|
||||
* @param to The location to move to. This should not exist.
|
||||
* @throws IOException If the move failed.
|
||||
*/
|
||||
void move( String from, String to ) throws IOException;
|
||||
}
|
||||
@@ -1,57 +1,78 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.filesystem;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a read only part of a virtual filesystem that can be mounted onto a computercraft using IComputerAccess.mount().
|
||||
* Ready made implementations of this interface can be created using ComputerCraftAPI.createSaveDirMount() or ComputerCraftAPI.createResourceMount(), or you're free to implement it yourselves!
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#createSaveDirMount(World, String)
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#createResourceMount(Class, String, String)
|
||||
* @see dan200.computercraft.api.peripheral.IComputerAccess#mount(String, IMount)
|
||||
* Represents a read only part of a virtual filesystem that can be mounted onto a computer using
|
||||
* {@link IComputerAccess#mount(String, IMount)}
|
||||
*
|
||||
* Ready made implementations of this interface can be created using
|
||||
* {@link ComputerCraftAPI#createSaveDirMount(World, String, long)} or
|
||||
* {@link ComputerCraftAPI#createResourceMount(Class, String, String)}, or you're free to implement it yourselves!
|
||||
*
|
||||
* @see ComputerCraftAPI#createSaveDirMount(World, String, long)
|
||||
* @see ComputerCraftAPI#createResourceMount(Class, String, String)
|
||||
* @see IComputerAccess#mount(String, IMount)
|
||||
* @see IWritableMount
|
||||
*/
|
||||
public interface IMount
|
||||
{
|
||||
/**
|
||||
* Returns whether a file with a given path exists or not.
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram"
|
||||
* @return true if the file exists, false otherwise
|
||||
*/
|
||||
public boolean exists( String path ) throws IOException;
|
||||
/**
|
||||
* Returns whether a file with a given path exists or not.
|
||||
*
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram"
|
||||
* @return If the file exists.
|
||||
* @throws IOException If an error occurs when checking the existence of the file.
|
||||
*/
|
||||
boolean exists( @Nonnull String path ) throws IOException;
|
||||
|
||||
/**
|
||||
* Returns whether a file with a given path is a directory or not.
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprograms"
|
||||
* @return true if the file exists and is a directory, false otherwise
|
||||
*/
|
||||
public boolean isDirectory( String path ) throws IOException;
|
||||
/**
|
||||
* Returns whether a file with a given path is a directory or not.
|
||||
*
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprograms".
|
||||
* @return If the file exists and is a directory
|
||||
* @throws IOException If an error occurs when checking whether the file is a directory.
|
||||
*/
|
||||
boolean isDirectory( @Nonnull String path ) throws IOException;
|
||||
|
||||
/**
|
||||
* Returns the file names of all the files in a directory.
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprograms"
|
||||
* @param contents A list of strings. Add all the file names to this list
|
||||
*/
|
||||
public void list( String path, List<String> contents ) throws IOException;
|
||||
/**
|
||||
* Returns the file names of all the files in a directory.
|
||||
*
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprograms".
|
||||
* @param contents A list of strings. Add all the file names to this list.
|
||||
* @throws IOException If the file was not a directory, or could not be listed.
|
||||
*/
|
||||
void list( @Nonnull String path, @Nonnull List<String> contents ) throws IOException;
|
||||
|
||||
/**
|
||||
* Returns the size of a file with a given path, in bytes
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram"
|
||||
* @return the size of the file, in bytes
|
||||
*/
|
||||
public long getSize( String path ) throws IOException;
|
||||
|
||||
/**
|
||||
* Opens a file with a given path, and returns an inputstream representing it's contents.
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram"
|
||||
* @return a stream representing the contents of the file
|
||||
*/
|
||||
public InputStream openForRead( String path ) throws IOException;
|
||||
/**
|
||||
* Returns the size of a file with a given path, in bytes
|
||||
*
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram".
|
||||
* @return The size of the file, in bytes.
|
||||
* @throws IOException If the file does not exist, or its size could not be determined.
|
||||
*/
|
||||
long getSize( @Nonnull String path ) throws IOException;
|
||||
|
||||
/**
|
||||
* Opens a file with a given path, and returns an {@link InputStream} representing its contents.
|
||||
*
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram".
|
||||
* @return A stream representing the contents of the file.
|
||||
* @throws IOException If the file does not exist, or could not be opened.
|
||||
*/
|
||||
@Nonnull
|
||||
InputStream openForRead( @Nonnull String path ) throws IOException;
|
||||
}
|
||||
|
||||
@@ -1,52 +1,75 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.filesystem;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Represents a part of a virtual filesystem that can be mounted onto a computercraft using IComputerAccess.mount() or IComputerAccess.mountWritable(), that can also be written to.
|
||||
* Ready made implementations of this interface can be created using ComputerCraftAPI.createSaveDirMount(), or you're free to implement it yourselves!
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#createSaveDirMount(World, String)
|
||||
* @see dan200.computercraft.api.peripheral.IComputerAccess#mountWritable(String, dan200.computercraft.api.filesystem.IMount)
|
||||
* @see dan200.computercraft.api.filesystem.IMount
|
||||
* Represents a part of a virtual filesystem that can be mounted onto a computer using {@link IComputerAccess#mount(String, IMount)}
|
||||
* or {@link IComputerAccess#mountWritable(String, IWritableMount)}, that can also be written to.
|
||||
*
|
||||
* Ready made implementations of this interface can be created using
|
||||
* {@link ComputerCraftAPI#createSaveDirMount(World, String, long)}, or you're free to implement it yourselves!
|
||||
*
|
||||
* @see ComputerCraftAPI#createSaveDirMount(World, String, long)
|
||||
* @see IComputerAccess#mount(String, IMount)
|
||||
* @see IComputerAccess#mountWritable(String, IWritableMount)
|
||||
* @see IMount
|
||||
*/
|
||||
public interface IWritableMount extends IMount
|
||||
{
|
||||
/**
|
||||
* Creates a directory at a given path inside the virtual file system.
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/mynewprograms"
|
||||
*/
|
||||
public void makeDirectory( String path ) throws IOException;
|
||||
/**
|
||||
* Creates a directory at a given path inside the virtual file system.
|
||||
*
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/mynewprograms".
|
||||
* @throws IOException If the directory already exists or could not be created.
|
||||
*/
|
||||
void makeDirectory( @Nonnull String path ) throws IOException;
|
||||
|
||||
/**
|
||||
* Deletes a directory at a given path inside the virtual file system.
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myoldprograms"
|
||||
*/
|
||||
public void delete( String path ) throws IOException;
|
||||
/**
|
||||
* Deletes a directory at a given path inside the virtual file system.
|
||||
*
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myoldprograms".
|
||||
* @throws IOException If the file does not exist or could not be deleted.
|
||||
*/
|
||||
void delete( @Nonnull String path ) throws IOException;
|
||||
|
||||
/**
|
||||
* Opens a file with a given path, and returns an outputstream for writing to it.
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram"
|
||||
* @return a stream for writing to
|
||||
*/
|
||||
public OutputStream openForWrite( String path ) throws IOException;
|
||||
/**
|
||||
* Opens a file with a given path, and returns an {@link OutputStream} for writing to it.
|
||||
*
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram".
|
||||
* @return A stream for writing to
|
||||
* @throws IOException If the file could not be opened for writing.
|
||||
*/
|
||||
@Nonnull
|
||||
OutputStream openForWrite( @Nonnull String path ) throws IOException;
|
||||
|
||||
/**
|
||||
* Opens a file with a given path, and returns an outputstream for appending to it.
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram"
|
||||
* @return a stream for writing to
|
||||
*/
|
||||
public OutputStream openForAppend( String path ) throws IOException;
|
||||
/**
|
||||
* Opens a file with a given path, and returns an {@link OutputStream} for appending to it.
|
||||
*
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram".
|
||||
* @return A stream for writing to.
|
||||
* @throws IOException If the file could not be opened for writing.
|
||||
*/
|
||||
@Nonnull
|
||||
OutputStream openForAppend( @Nonnull String path ) throws IOException;
|
||||
|
||||
/**
|
||||
* Get the ammount of free space on the mount, in bytes. You should decrease this value as the user writes to the mount, and write operations should fail once it reaches zero.
|
||||
* @return The ammount of free space, in bytes.
|
||||
*/
|
||||
public long getRemainingSpace() throws IOException;
|
||||
/**
|
||||
* Get the amount of free space on the mount, in bytes. You should decrease this value as the user writes to the
|
||||
* mount, and write operations should fail once it reaches zero.
|
||||
*
|
||||
* @return The amount of free space, in bytes.
|
||||
* @throws IOException If the remaining space could not be computed.
|
||||
*/
|
||||
long getRemainingSpace() throws IOException;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
@API( owner="ComputerCraft", provides="ComputerCraft|API|FileSystem", apiVersion="${version}" )
|
||||
package dan200.computercraft.api.filesystem;
|
||||
|
||||
import net.minecraftforge.fml.common.API;
|
||||
import net.minecraftforge.fml.common.API;
|
||||
|
||||
31
src/main/java/dan200/computercraft/api/lua/ICallContext.java
Normal file
31
src/main/java/dan200/computercraft/api/lua/ICallContext.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2018. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.lua;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* An interface passed to peripherals and {@link ILuaObject}s by computers or turtles, providing methods that allow the
|
||||
* method to interact with the invoking computer.
|
||||
*/
|
||||
public interface ICallContext
|
||||
{
|
||||
/**
|
||||
* Queue a task to be executed on the main server thread at the beginning of next tick, but do not wait for it to
|
||||
* complete. This should be used when you need to interact with the world in a thread-safe manner but do not care
|
||||
* about the result or you wish to run asynchronously.
|
||||
*
|
||||
* When the task has finished, it will enqueue a {@code task_completed} event, which takes the task id, a success
|
||||
* value and the return values, or an error message if it failed. If you need to wait on this event, it may be
|
||||
* better to use {@link MethodResult#onMainThread(ILuaCallable)}.
|
||||
*
|
||||
* @param task The task to execute on the main thread.
|
||||
* @return The "id" of the task. This will be the first argument to the {@code task_completed} event.
|
||||
* @throws LuaException If the task could not be queued.
|
||||
*/
|
||||
long issueMainThreadTask( @Nonnull ILuaTask task ) throws LuaException;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package dan200.computercraft.api.lua;
|
||||
|
||||
import dan200.computercraft.api.filesystem.IFileSystem;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* An interface passed to {@link ILuaAPIFactory} in order to provide additional information
|
||||
* about a computer.
|
||||
*/
|
||||
public interface IComputerSystem extends IComputerAccess
|
||||
{
|
||||
/**
|
||||
* Get the file system for this computer.
|
||||
*
|
||||
* @return The computer's file system, or {@code null} if it is not initialised.
|
||||
*/
|
||||
@Nullable
|
||||
IFileSystem getFileSystem();
|
||||
|
||||
/**
|
||||
* Get the label for this computer
|
||||
*
|
||||
* @return This computer's label, or {@code null} if it is not set.
|
||||
*/
|
||||
@Nullable
|
||||
String getLabel();
|
||||
}
|
||||
47
src/main/java/dan200/computercraft/api/lua/ILuaAPI.java
Normal file
47
src/main/java/dan200/computercraft/api/lua/ILuaAPI.java
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.lua;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
|
||||
/**
|
||||
* Represents a {@link ILuaObject} which is stored as a global variable on computer startup.
|
||||
*
|
||||
* Before implementing this interface, consider alternative methods of providing methods. It is generally preferred
|
||||
* to use peripherals to provide functionality to users.
|
||||
*
|
||||
* @see ILuaAPIFactory
|
||||
* @see ComputerCraftAPI#registerAPIFactory(ILuaAPIFactory)
|
||||
*/
|
||||
public interface ILuaAPI extends ILuaObject
|
||||
{
|
||||
/**
|
||||
* Get the globals this API will be assigned to. This will override any other global, so you should
|
||||
*
|
||||
* @return A list of globals this API will be assigned to.
|
||||
*/
|
||||
String[] getNames();
|
||||
|
||||
/**
|
||||
* Called when the computer is turned on.
|
||||
*
|
||||
* One should only interact with the file system.
|
||||
*/
|
||||
default void startup() { }
|
||||
|
||||
/**
|
||||
* Called every time the computer is ticked. This can be used to process various.
|
||||
*/
|
||||
default void update() { }
|
||||
|
||||
/**
|
||||
* Called when the computer is turned off or unloaded.
|
||||
*
|
||||
* This should reset the state of the object, disposing any remaining file handles, or other resources.
|
||||
*/
|
||||
default void shutdown() { }
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package dan200.computercraft.api.lua;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Construct an {@link ILuaAPI} for a specific computer.
|
||||
*
|
||||
* @see ILuaAPI
|
||||
* @see ComputerCraftAPI#registerAPIFactory(ILuaAPIFactory)
|
||||
*/
|
||||
public interface ILuaAPIFactory
|
||||
{
|
||||
/**
|
||||
* Create a new API instance for a given computer.
|
||||
*
|
||||
* @param computer The computer this API is for.
|
||||
* @return The created API, or {@code null} if one should not be injected.
|
||||
*/
|
||||
@Nullable
|
||||
ILuaAPI create( @Nonnull IComputerSystem computer );
|
||||
}
|
||||
31
src/main/java/dan200/computercraft/api/lua/ILuaCallable.java
Normal file
31
src/main/java/dan200/computercraft/api/lua/ILuaCallable.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2018. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.lua;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* A function which calls performs an action in a specific context (such as on the server thread) and returns a result.
|
||||
*
|
||||
* @see MethodResult#onMainThread(ILuaCallable)
|
||||
* @see ILuaContext#executeMainThreadTask(ILuaTask)
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ILuaCallable
|
||||
{
|
||||
/**
|
||||
* Run the code within the specified context and return the result to continue with.
|
||||
*
|
||||
* @return The result of executing this function. Note that this may not be evaluated within the same context as
|
||||
* this call is.
|
||||
* @throws LuaException If you throw any exception from this function, a lua error will be raised with the
|
||||
* same message as your exception. Use this to throw appropriate errors if the wrong
|
||||
* arguments are supplied to your method.
|
||||
*/
|
||||
@Nonnull
|
||||
MethodResult execute() throws LuaException;
|
||||
}
|
||||
@@ -1,58 +1,93 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2018. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.lua;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* An interface passed to peripherals and ILuaObjects' by computers or turtles, providing methods
|
||||
* that allow the peripheral call to wait for events before returning, just like in lua.
|
||||
* This is very useful if you need to signal work to be performed on the main thread, and don't want to return
|
||||
* until the work has been completed.
|
||||
* An interface passed to peripherals and {@link ILuaObject}s by computers or turtles, providing methods
|
||||
* that allow the peripheral call to wait for events before returning, just like in lua. This is very useful if you need
|
||||
* to signal work to be performed on the main thread, and don't want to return until the work has been completed.
|
||||
*
|
||||
* This interface mostly exists for integrating with older code. One should use {@link MethodResult} instead, as this
|
||||
* encourages an asynchronous way of interacting with Lua coroutines.
|
||||
*/
|
||||
public interface ILuaContext
|
||||
public interface ILuaContext extends ICallContext
|
||||
{
|
||||
/**
|
||||
* Wait for an event to occur on the computercraft, suspending the thread until it arises. This method is exactly equivalent to os.pullEvent() in lua.
|
||||
* @param filter A specific event to wait for, or null to wait for any event
|
||||
* @return An object array containing the name of the event that occurred, and any event parameters
|
||||
* @throws Exception If the user presses CTRL+T to terminate the current program while pullEvent() is waiting for an event, a "Terminated" exception will be thrown here.
|
||||
* Do not attempt to common this exception, unless you wish to prevent termination, which is not recommended.
|
||||
* @throws InterruptedException If the user shuts down or reboots the computercraft while pullEvent() is waiting for an event, InterruptedException will be thrown. This exception must not be caught or intercepted, or the computercraft will leak memory and end up in a broken state.
|
||||
*/
|
||||
public Object[] pullEvent( String filter ) throws LuaException, InterruptedException;
|
||||
|
||||
/**
|
||||
* The same as pullEvent(), except "terminated" events are ignored. Only use this if you want to prevent program termination, which is not recommended. This method is exactly equivalent to os.pullEventRaw() in lua.
|
||||
* @param filter A specific event to wait for, or null to wait for any event
|
||||
* @return An object array containing the name of the event that occurred, and any event parameters
|
||||
* @throws InterruptedException If the user shuts down or reboots the computercraft while pullEventRaw() is waiting for an event, InterruptedException will be thrown. This exception must not be caught or intercepted, or the computercraft will leak memory and end up in a broken state.
|
||||
* @see #pullEvent(String)
|
||||
*/
|
||||
public Object[] pullEventRaw( String filter ) throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Yield the current coroutine with some arguments until it is resumed. This method is exactly equivalent to coroutine.yield() in lua. Use pullEvent() if you wish to wait for events.
|
||||
* @param arguments An object array containing the arguments to pass to coroutine.yield()
|
||||
* @return An object array containing the return values from coroutine.yield()
|
||||
* @throws InterruptedException If the user shuts down or reboots the computercraft the coroutine is suspended, InterruptedException will be thrown. This exception must not be caught or intercepted, or the computercraft will leak memory and end up in a broken state.
|
||||
* @see #pullEvent(String)
|
||||
*/
|
||||
public Object[] yield( Object[] arguments ) throws InterruptedException;
|
||||
/**
|
||||
* Wait for an event to occur on the computer, suspending the thread until it arises. This method is exactly
|
||||
* equivalent to {@code os.pullEvent()} in lua.
|
||||
*
|
||||
* @param filter A specific event to wait for, or null to wait for any event.
|
||||
* @return An object array containing the name of the event that occurred, and any event parameters.
|
||||
* @throws LuaException If the user presses CTRL+T to terminate the current program while pullEvent() is
|
||||
* waiting for an event, a "Terminated" exception will be thrown here.
|
||||
*
|
||||
* Do not attempt to catch this exception. You should use {@link #pullEventRaw(String)}
|
||||
* should you wish to disable termination.
|
||||
* @throws InterruptedException If the user shuts down or reboots the computer while pullEvent() is waiting for an
|
||||
* event, InterruptedException will be thrown. This exception must not be caught or
|
||||
* intercepted, or the computer will leak memory and end up in a broken state.
|
||||
* @deprecated Use {@link MethodResult#pullEvent(String, ILuaFunction)}
|
||||
*/
|
||||
@Nonnull
|
||||
@Deprecated
|
||||
Object[] pullEvent( @Nullable String filter ) throws LuaException, InterruptedException;
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* @param task
|
||||
* @return
|
||||
* The same as {@link #pullEvent(String)}, except "terminated" events are ignored. Only use this if you want to
|
||||
* prevent program termination, which is not recommended. This method is exactly equivalent to
|
||||
* {@code os.pullEventRaw()} in lua.
|
||||
*
|
||||
* @param filter A specific event to wait for, or null to wait for any event.
|
||||
* @return An object array containing the name of the event that occurred, and any event parameters.
|
||||
* @throws InterruptedException If the user shuts down or reboots the computer while pullEventRaw() is waiting for
|
||||
* an event, InterruptedException will be thrown. This exception must not be caught or
|
||||
* intercepted, or the computer will leak memory and end up in a broken state.
|
||||
* @see #pullEvent(String)
|
||||
* @deprecated Use {@link MethodResult#pullEventRaw(String, ILuaFunction)}
|
||||
*/
|
||||
public Object[] executeMainThreadTask( ILuaTask task ) throws LuaException, InterruptedException;
|
||||
@Nonnull
|
||||
@Deprecated
|
||||
Object[] pullEventRaw( @Nullable String filter ) throws InterruptedException;
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* @param task
|
||||
* @return
|
||||
* Yield the current coroutine with some arguments until it is resumed. This method is exactly equivalent to
|
||||
* {@code coroutine.yield()} in lua. Use {@code pullEvent()} if you wish to wait for events.
|
||||
*
|
||||
* @param arguments An object array containing the arguments to pass to coroutine.yield()
|
||||
* @return An object array containing the return values from coroutine.yield()
|
||||
* @throws InterruptedException If the user shuts down or reboots the computer the coroutine is suspended,
|
||||
* InterruptedException will be thrown. This exception must not be caught or
|
||||
* intercepted, or the computer will leak memory and end up in a broken state.
|
||||
* @see #pullEvent(String)
|
||||
* @deprecated Use {@link MethodResult#pullEventRaw(ILuaFunction)}
|
||||
*/
|
||||
public long issueMainThreadTask( ILuaTask task ) throws LuaException;
|
||||
@Nonnull
|
||||
@Deprecated
|
||||
Object[] yield( @Nullable Object[] arguments ) throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Queue a task to be executed on the main server thread at the beginning of next tick, waiting for it to complete.
|
||||
* This should be used when you need to interact with the world in a thread-safe manner.
|
||||
*
|
||||
* Note that the return values of your task are handled as events, meaning more complex objects such as maps or
|
||||
* {@link ILuaObject} will not preserve their identities.
|
||||
*
|
||||
* @param task The task to execute on the main thread.
|
||||
* @return The objects returned by {@code task}.
|
||||
* @throws LuaException If the task could not be queued, or if the task threw an exception.
|
||||
* @throws InterruptedException If the user shuts down or reboots the computer the coroutine is suspended,
|
||||
* InterruptedException will be thrown. This exception must not be caught or
|
||||
* intercepted, or the computer will leak memory and end up in a broken state.
|
||||
* @deprecated Use {@link MethodResult#onMainThread(ILuaCallable)}
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated
|
||||
Object[] executeMainThreadTask( @Nonnull ILuaTask task ) throws LuaException, InterruptedException;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2018. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.lua;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A function which executes using a {@link ILuaContext}.
|
||||
*
|
||||
* Like {@link ILuaContext}, this is not intended for use in the future - it purely exists as an argument for
|
||||
* {@link MethodResult#withLuaContext(ILuaContextTask)}.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ILuaContextTask
|
||||
{
|
||||
@Nullable
|
||||
@Deprecated
|
||||
Object[] execute( @Nonnull ILuaContext context ) throws LuaException, InterruptedException;
|
||||
}
|
||||
33
src/main/java/dan200/computercraft/api/lua/ILuaFunction.java
Normal file
33
src/main/java/dan200/computercraft/api/lua/ILuaFunction.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2018. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.lua;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A Lua function which consumes some values and returns a result.
|
||||
*
|
||||
* @see MethodResult#then(ILuaFunction)
|
||||
* @see MethodResult#pullEvent(ILuaFunction)
|
||||
* @see MethodResult#pullEventRaw(String)
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ILuaFunction
|
||||
{
|
||||
/**
|
||||
* Accept the values and return another method result.
|
||||
*
|
||||
* @param values The inputs for this function.
|
||||
* @return The result of executing this function.
|
||||
* @throws LuaException If you throw any exception from this function, a lua error will be raised with the
|
||||
* same message as your exception. Use this to throw appropriate errors if the wrong
|
||||
* arguments are supplied to your method.
|
||||
*/
|
||||
@Nonnull
|
||||
MethodResult call( @Nullable Object[] values ) throws LuaException;
|
||||
}
|
||||
@@ -1,26 +1,85 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2018. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.lua;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* An interface for representing custom objects returned by IPeripheral.callMethod() calls.
|
||||
* An interface for representing custom objects returned by {@link IPeripheral#callMethod(IComputerAccess, ILuaContext, int, Object[])}
|
||||
* calls.
|
||||
*
|
||||
* Return objects implementing this interface to expose objects with methods to lua.
|
||||
*/
|
||||
public interface ILuaObject
|
||||
{
|
||||
/**
|
||||
* Get the names of the methods that this object implements. This works the same as IPeripheral.getMethodNames(). See that method for detailed documentation.
|
||||
* @see dan200.computercraft.api.peripheral.IPeripheral#getMethodNames()
|
||||
*/
|
||||
public String[] getMethodNames();
|
||||
/**
|
||||
* Get the names of the methods that this object implements. This works the same as {@link IPeripheral#getMethodNames()}.
|
||||
* See that method for detailed documentation.
|
||||
*
|
||||
* @return The method names this object provides.
|
||||
* @see IPeripheral#getMethodNames()
|
||||
*/
|
||||
@Nonnull
|
||||
String[] getMethodNames();
|
||||
|
||||
/**
|
||||
* Called when a user calls one of the methods that this object implements. This works the same as IPeripheral.callMethod(). See that method for detailed documentation.
|
||||
* @see dan200.computercraft.api.peripheral.IPeripheral#callMethod(dan200.computercraft.api.peripheral.IComputerAccess, ILuaContext, int, Object[])
|
||||
*/
|
||||
public Object[] callMethod( ILuaContext context, int method, Object[] arguments ) throws LuaException, InterruptedException;
|
||||
/**
|
||||
* Called when a user calls one of the methods that this object implements. This works the same as
|
||||
* {@link IPeripheral#callMethod(IComputerAccess, ILuaContext, int, Object[])}}. See that method for detailed
|
||||
* documentation.
|
||||
*
|
||||
* @param context The context of the currently running lua thread. This can be used to wait for events
|
||||
* or otherwise yield.
|
||||
* @param method An integer identifying which of the methods from getMethodNames() the computercraft
|
||||
* wishes to call. The integer indicates the index into the getMethodNames() table
|
||||
* that corresponds to the string passed into peripheral.call()
|
||||
* @param arguments The arguments for this method. See {@link IPeripheral#callMethod(IComputerAccess, ILuaContext, int, Object[])}
|
||||
* for the possible values and conversion rules.
|
||||
* @return An array of objects, representing the values you wish to return to the Lua program. See
|
||||
* {@link MethodResult#of(Object...)} for the valid values and conversion rules.
|
||||
* @throws LuaException If you throw any exception from this function, a lua error will be raised with the
|
||||
* same message as your exception. Use this to throw appropriate errors if the wrong
|
||||
* arguments are supplied to your method.
|
||||
* @throws InterruptedException If the user shuts down or reboots the computer the coroutine is suspended,
|
||||
* InterruptedException will be thrown. This exception must not be caught or
|
||||
* intercepted, or the computer will leak memory and end up in a broken state.
|
||||
* @see IPeripheral#callMethod(IComputerAccess, ILuaContext, int, Object[])
|
||||
* @deprecated Use {@link #callMethod(ICallContext, int, Object[])} instead.
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated
|
||||
Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException;
|
||||
|
||||
/**
|
||||
* Called when a user calls one of the methods that this object implements. This works the same as
|
||||
* {@link IPeripheral#callMethod(IComputerAccess, ICallContext, int, Object[])}}. See that method for detailed
|
||||
* documentation.
|
||||
*
|
||||
* @param context The context of the current call.
|
||||
* @param method An integer identifying which of the methods from getMethodNames() the computercraft
|
||||
* wishes to call. The integer indicates the index into the getMethodNames() table
|
||||
* that corresponds to the string passed into peripheral.call()
|
||||
* @param arguments The arguments for this method. See {@link IPeripheral#callMethod(IComputerAccess, ICallContext, int, Object[])}
|
||||
* for the possible values and conversion rules.
|
||||
* @return The result of calling this method. Use {@link MethodResult#empty()} to return nothing or
|
||||
* {@link MethodResult#of(Object...)} to return several values.
|
||||
* @throws LuaException If you throw any exception from this function, a lua error will be raised with the
|
||||
* same message as your exception. Use this to throw appropriate errors if the wrong
|
||||
* arguments are supplied to your method.
|
||||
* @see IPeripheral#callMethod(IComputerAccess, ICallContext, int, Object[])
|
||||
* @see MethodResult
|
||||
*/
|
||||
@Nonnull
|
||||
@SuppressWarnings( { "deprecation" } )
|
||||
default MethodResult callMethod( @Nonnull ICallContext context, int method, @Nonnull Object[] arguments ) throws LuaException
|
||||
{
|
||||
return MethodResult.withLuaContext( lua -> callMethod( lua, method, arguments ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,33 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.lua;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A task which can be executed via {@link ILuaContext#executeMainThreadTask(ILuaTask)} or
|
||||
* {@link ILuaContext#issueMainThreadTask(ILuaTask)}. This will be run on the main thread, at the beginning of the
|
||||
* next tick.
|
||||
*
|
||||
* @see ILuaContext#executeMainThreadTask(ILuaTask)
|
||||
* @see ILuaContext#issueMainThreadTask(ILuaTask)
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ILuaTask
|
||||
{
|
||||
public Object[] execute() throws LuaException;
|
||||
/**
|
||||
* Execute this task.
|
||||
*
|
||||
* @return The arguments to add to the {@code task_completed} event. These will be returned by
|
||||
* {@link ILuaContext#executeMainThreadTask(ILuaTask)}.
|
||||
* @throws LuaException If you throw any exception from this function, a lua error will be raised with the
|
||||
* same message as your exception. Use this to throw appropriate errors if the wrong
|
||||
* arguments are supplied to your method.
|
||||
*/
|
||||
@Nullable
|
||||
Object[] execute() throws LuaException;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2018. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.lua;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
/**
|
||||
* Evaluates {@link MethodResult}s within a {@link ILuaContext}.
|
||||
*
|
||||
* @see MethodResult#evaluate(ILuaContext)
|
||||
* @see MethodResult#withLuaContext(ILuaContextTask)
|
||||
* @deprecated This should not be used except to interface between the two call call systems.
|
||||
*/
|
||||
@Deprecated
|
||||
class LuaContextResultEvaluator
|
||||
{
|
||||
@Deprecated
|
||||
public static Object[] evaluate( @Nonnull ILuaContext context, @Nonnull MethodResult future ) throws LuaException, InterruptedException
|
||||
{
|
||||
Deque<ILuaFunction> callbacks = null;
|
||||
while( true )
|
||||
{
|
||||
if( future instanceof MethodResult.AndThen )
|
||||
{
|
||||
MethodResult.AndThen then = ((MethodResult.AndThen) future);
|
||||
|
||||
// Thens are "unwrapped", being pushed onto a stack
|
||||
if( callbacks == null ) callbacks = new ArrayDeque<>();
|
||||
callbacks.addLast( then.getCallback() );
|
||||
|
||||
future = then.getPrevious();
|
||||
if( future == null ) throw new NullPointerException( "Null result from " + then.getCallback() );
|
||||
}
|
||||
else if( future instanceof MethodResult.Immediate )
|
||||
{
|
||||
Object[] values = ((MethodResult.Immediate) future).getResult();
|
||||
|
||||
// Immediate values values will attempt to call the previous "then", or return if nothing
|
||||
// else needs to be done.
|
||||
ILuaFunction callback = callbacks == null ? null : callbacks.pollLast();
|
||||
if( callback == null ) return values;
|
||||
|
||||
future = callback.call( values );
|
||||
if( future == null ) throw new NullPointerException( "Null result from " + callback );
|
||||
}
|
||||
else if( future instanceof MethodResult.OnEvent )
|
||||
{
|
||||
MethodResult.OnEvent onEvent = (MethodResult.OnEvent) future;
|
||||
|
||||
// Poll for an event, and then call the previous "then" or return if nothing else needs
|
||||
// to be done.
|
||||
Object[] values = onEvent.isRaw() ? context.pullEventRaw( onEvent.getFilter() ) : context.pullEvent( onEvent.getFilter() );
|
||||
|
||||
ILuaFunction callback = callbacks == null ? null : callbacks.pollLast();
|
||||
if( callback == null ) return values;
|
||||
|
||||
future = callback.call( values );
|
||||
if( future == null ) throw new NullPointerException( "Null result from " + callback );
|
||||
}
|
||||
else if( future instanceof MethodResult.OnMainThread )
|
||||
{
|
||||
MethodResult.OnMainThread onMainThread = (MethodResult.OnMainThread) future;
|
||||
|
||||
// Evaluate our task on the main thread and mark it as the next future to evaluate.
|
||||
Reference temporary = new Reference();
|
||||
context.executeMainThreadTask( () -> {
|
||||
temporary.value = onMainThread.getTask().execute();
|
||||
return null;
|
||||
} );
|
||||
|
||||
future = temporary.value;
|
||||
if( future == null ) throw new NullPointerException( "Null result from " + onMainThread.getTask() );
|
||||
}
|
||||
else if( future instanceof MethodResult.WithLuaContext )
|
||||
{
|
||||
MethodResult.WithLuaContext withContext = (MethodResult.WithLuaContext) future;
|
||||
|
||||
// Run the task, and then call the previous "then" or return if nothing else
|
||||
// needs to be done.
|
||||
Object[] values = withContext.getConsumer().execute( context );
|
||||
|
||||
ILuaFunction callback = callbacks == null ? null : callbacks.pollLast();
|
||||
if( callback == null ) return values;
|
||||
|
||||
future = callback.call( values );
|
||||
if( future == null ) throw new NullPointerException( "Null result from " + callback );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalStateException( "Unknown MethodResult " + future );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class Reference
|
||||
{
|
||||
MethodResult value;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,19 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.lua;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* An exception representing an error in Lua, like that raised by the error() function
|
||||
* An exception representing an error in Lua, like that raised by the {@code error()} function.
|
||||
*/
|
||||
public class LuaException extends Exception
|
||||
{
|
||||
private static final long serialVersionUID = -6136063076818512651L;
|
||||
private final int m_level;
|
||||
|
||||
public LuaException()
|
||||
@@ -18,17 +21,23 @@ public class LuaException extends Exception
|
||||
this( "error", 1 );
|
||||
}
|
||||
|
||||
public LuaException( String message )
|
||||
public LuaException( @Nullable String message )
|
||||
{
|
||||
this( message, 1 );
|
||||
}
|
||||
|
||||
public LuaException( String message, int level )
|
||||
public LuaException( @Nullable String message, int level )
|
||||
{
|
||||
super( message );
|
||||
m_level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* The level this error is raised at. Level 1 is the function's caller, level 2 is that function's caller, and so
|
||||
* on.
|
||||
*
|
||||
* @return The level to raise the error at.
|
||||
*/
|
||||
public int getLevel()
|
||||
{
|
||||
return m_level;
|
||||
|
||||
354
src/main/java/dan200/computercraft/api/lua/MethodResult.java
Normal file
354
src/main/java/dan200/computercraft/api/lua/MethodResult.java
Normal file
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2018. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.lua;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The result of calling a method, such as {@link ILuaObject#callMethod(ICallContext, int, Object[])} or
|
||||
* {@link IPeripheral#callMethod(IComputerAccess, ICallContext, int, Object[])}.
|
||||
*
|
||||
* This is non-dissimilar to a promise or {@link ListenableFuture}. One can either return an immediate value through
|
||||
* {@link #of(Object...)}, wait for an external action with {@link #onMainThread(ILuaCallable)} or {@link #pullEvent()}
|
||||
* and then act on the result of either of those by using {@link #then(ILuaFunction)}.
|
||||
*/
|
||||
public abstract class MethodResult
|
||||
{
|
||||
private static MethodResult empty;
|
||||
|
||||
MethodResult()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* A result which returns immediately with no value.
|
||||
*
|
||||
* Use {@link #of(Object...)} if you need to return one or more values.
|
||||
*
|
||||
* @return The empty method result.
|
||||
* @see #of(Object...)
|
||||
*/
|
||||
@Nonnull
|
||||
public static MethodResult empty()
|
||||
{
|
||||
if( empty == null ) empty = new Immediate( null );
|
||||
return empty;
|
||||
}
|
||||
|
||||
/**
|
||||
* A result which returns several values.
|
||||
*
|
||||
* @param result The values to return, this may be {@code null}. {@link Number}s, {@link String}s, {@link Boolean}s,
|
||||
* {@link Map}s, {@link ILuaObject}s, and {@code null} be converted to their corresponding lua type.
|
||||
* All other types will be converted to nil.
|
||||
* @return A result which will return these values when evaluated.
|
||||
* @see #empty()
|
||||
*/
|
||||
@Nonnull
|
||||
public static MethodResult of( Object... result )
|
||||
{
|
||||
return result == null ? empty() : new Immediate( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for an event to occur on the computer, suspending the coroutine until it arises. This method is equivalent
|
||||
* to {@code os.pullEvent()} in Lua.
|
||||
*
|
||||
* Normally you'll wish to consume the event using {@link #then(ILuaFunction)}. This can be done slightly more
|
||||
* easily with {@link #pullEvent(ILuaFunction)}.
|
||||
*
|
||||
* If you want to listen to a specific event, it's easier to use {@link #pullEvent(String)} rather than
|
||||
* running until the desired event is found.
|
||||
*
|
||||
* @return The constructed method result. This evaluates to the name of the event that occurred, and any event
|
||||
* parameters.
|
||||
* @see #pullEvent(ILuaFunction)
|
||||
* @see #pullEvent(String)
|
||||
*/
|
||||
@Nonnull
|
||||
public static MethodResult pullEvent()
|
||||
{
|
||||
return new OnEvent( false, null );
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for the specified event to occur on the computer, suspending the coroutine until it arises. This method is
|
||||
* equivalent to {@code os.pullEvent(event)} in Lua.
|
||||
*
|
||||
* Normally you'll wish to consume the event using {@link #then(ILuaFunction)}. This can be done slightly more
|
||||
* easily with {@link #pullEvent(String, ILuaFunction)}.
|
||||
*
|
||||
* @param filter The event name to filter on.
|
||||
* @return The constructed method result. This evaluates to the name of the event that occurred, and any event
|
||||
* parameters.
|
||||
* @see #pullEvent(String, ILuaFunction)
|
||||
* @see #pullEvent()
|
||||
*/
|
||||
@Nonnull
|
||||
public static MethodResult pullEvent( @Nonnull String filter )
|
||||
{
|
||||
Preconditions.checkNotNull( filter, "event cannot be null" );
|
||||
return new OnEvent( false, filter );
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for an event to occur on the computer, suspending the coroutine until it arises. This method to
|
||||
* {@link #pullEvent()} and {@link #then(ILuaFunction)}.
|
||||
*
|
||||
* If you want to listen to a specific event, it's easier to use {@link #pullEvent(String, ILuaFunction)} rather
|
||||
* than running until the desired event is found.
|
||||
*
|
||||
* @param callback The function to call when the event is received.
|
||||
* @return The constructed method result. This evaluates to the result of the {@code callback}.
|
||||
* @see #pullEvent()
|
||||
* @see #pullEvent(String, ILuaFunction)
|
||||
*/
|
||||
@Nonnull
|
||||
public static MethodResult pullEvent( @Nonnull ILuaFunction callback )
|
||||
{
|
||||
Preconditions.checkNotNull( callback, "callback cannot be null" );
|
||||
return new OnEvent( false, null ).then( callback );
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for the specified event to occur on the computer, suspending the coroutine until it arises. This method to
|
||||
* {@link #pullEvent(String)} and {@link #then(ILuaFunction)}.
|
||||
*
|
||||
* @param filter The event name to filter on.
|
||||
* @param callback The function to call when the event is received.
|
||||
* @return The constructed method result. This evaluates to the result of the {@code callback}.
|
||||
* @see #pullEvent(String)
|
||||
* @see #pullEvent(ILuaFunction)
|
||||
*/
|
||||
@Nonnull
|
||||
public static MethodResult pullEvent( @Nullable String filter, @Nonnull ILuaFunction callback )
|
||||
{
|
||||
Preconditions.checkNotNull( callback, "callback cannot be null" );
|
||||
return new OnEvent( false, filter ).then( callback );
|
||||
}
|
||||
|
||||
/**
|
||||
* The same as {@link #pullEvent()}, except {@code terminated} events are also passed to the callback, instead of
|
||||
* throwing an error. Only use this if you want to prevent program termination, which is not recommended.
|
||||
*
|
||||
* @return The constructed method result. This evaluates to the name of the event that occurred, and any event
|
||||
* parameters.
|
||||
*/
|
||||
@Nonnull
|
||||
public static MethodResult pullEventRaw()
|
||||
{
|
||||
return new OnEvent( true, null );
|
||||
}
|
||||
|
||||
/**
|
||||
* The same as {@link #pullEvent(String)}, except {@code terminated} events are also passed to the callback, instead
|
||||
* of throwing an error. Only use this if you want to prevent program termination, which is not recommended.
|
||||
*
|
||||
* @param filter The event name to filter on.
|
||||
* @return The constructed method result. This evaluates to the name of the event that occurred, and any event
|
||||
* parameters.
|
||||
*/
|
||||
@Nonnull
|
||||
public static MethodResult pullEventRaw( @Nonnull String filter )
|
||||
{
|
||||
return new OnEvent( true, filter );
|
||||
}
|
||||
|
||||
/**
|
||||
* The same as {@link #pullEvent(ILuaFunction)}, except {@code terminated} events are also passed to the callback,
|
||||
* instead of throwing an error. Only use this if you want to prevent program termination, which is not recommended.
|
||||
*
|
||||
* @param callback The function to call when the event is received.
|
||||
* @return The constructed method result. This evaluates to the result of the {@code callback}.
|
||||
*/
|
||||
@Nonnull
|
||||
public static MethodResult pullEventRaw( @Nonnull ILuaFunction callback )
|
||||
{
|
||||
Preconditions.checkNotNull( callback, "callback cannot be null" );
|
||||
return new OnEvent( true, null ).then( callback );
|
||||
}
|
||||
|
||||
/**
|
||||
* The same as {@link #pullEvent(String, ILuaFunction)}, except {@code terminated} events are also passed to the
|
||||
* callback, instead of throwing an error. Only use this if you want to prevent program termination, which is not
|
||||
* recommended.
|
||||
*
|
||||
* @param filter The event name to filter on.
|
||||
* @param callback The function to call when the event is received.
|
||||
* @return The constructed method result. This evaluates to the result of the {@code callback}.
|
||||
*/
|
||||
@Nonnull
|
||||
public static MethodResult pullEventRaw( @Nullable String filter, @Nonnull ILuaFunction callback )
|
||||
{
|
||||
Preconditions.checkNotNull( callback, "callback cannot be null" );
|
||||
return new OnEvent( true, filter ).then( callback );
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue a task to be executed on the main server thread at the beginning of next tick, waiting for it to complete.
|
||||
* This should be used when you need to interact with the world in a thread-safe manner.
|
||||
*
|
||||
* @param callback The task to execute on the server thread.
|
||||
* @return The constructed method result, which evaluates to the result of the {@code callback}.
|
||||
*/
|
||||
@Nonnull
|
||||
public static MethodResult onMainThread( @Nonnull ILuaCallable callback )
|
||||
{
|
||||
Preconditions.checkNotNull( callback, "callback cannot be null" );
|
||||
return new OnMainThread( callback );
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume the result of this {@link MethodResult} and return another result.
|
||||
*
|
||||
* Note this does NOT modify the current method result, rather returning a new (wrapped) one. You must return the
|
||||
* result of this call if you wish to use it.
|
||||
*
|
||||
* @param callback The function which consumes the provided values.
|
||||
* @return The constructed method result.
|
||||
*/
|
||||
@Nonnull
|
||||
public final MethodResult then( @Nonnull ILuaFunction callback )
|
||||
{
|
||||
Preconditions.checkNotNull( callback, "callback cannot be null" );
|
||||
return new AndThen( this, callback );
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a blocking task within a {@link ILuaContext} and return its result.
|
||||
*
|
||||
* @param consumer The task to execute with the provided Lua context.
|
||||
* @return The constructed method result.
|
||||
* @see #evaluate(ILuaContext)
|
||||
* @deprecated This should not be used except to interface between the two call systems.
|
||||
*/
|
||||
@Deprecated
|
||||
public static MethodResult withLuaContext( @Nonnull ILuaContextTask consumer )
|
||||
{
|
||||
Preconditions.checkNotNull( consumer, "consumer cannot be null" );
|
||||
return new WithLuaContext( consumer );
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate this result task using {@link ILuaContext} and return its result.
|
||||
*
|
||||
* @param context The context to execute with.
|
||||
* @return The resulting values.
|
||||
* @throws LuaException If an error was thrown while executing one of the methods within this future.
|
||||
* @throws InterruptedException If the user shuts down or reboots the computer while the coroutine is suspended.
|
||||
* @see #withLuaContext(ILuaContextTask)
|
||||
* @deprecated This should not be used except to interface between the two call systems.
|
||||
*/
|
||||
@Deprecated
|
||||
public final Object[] evaluate( @Nonnull ILuaContext context ) throws LuaException, InterruptedException
|
||||
{
|
||||
return LuaContextResultEvaluator.evaluate( context, this );
|
||||
}
|
||||
|
||||
public static class Immediate extends MethodResult
|
||||
{
|
||||
@Nullable
|
||||
private final Object[] values;
|
||||
|
||||
@Nullable
|
||||
private Immediate( Object[] values )
|
||||
{
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public Object[] getResult()
|
||||
{
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
public static class OnEvent extends MethodResult
|
||||
{
|
||||
private final boolean raw;
|
||||
private final String filter;
|
||||
|
||||
private OnEvent( boolean raw, String filter )
|
||||
{
|
||||
this.raw = raw;
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
public boolean isRaw()
|
||||
{
|
||||
return raw;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getFilter()
|
||||
{
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
|
||||
public static class OnMainThread extends MethodResult
|
||||
{
|
||||
private final ILuaCallable task;
|
||||
|
||||
public OnMainThread( ILuaCallable task )
|
||||
{
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public ILuaCallable getTask()
|
||||
{
|
||||
return task;
|
||||
}
|
||||
}
|
||||
|
||||
public static class AndThen extends MethodResult
|
||||
{
|
||||
private final MethodResult previous;
|
||||
private final ILuaFunction callback;
|
||||
|
||||
private AndThen( MethodResult previous, ILuaFunction callback )
|
||||
{
|
||||
this.previous = previous;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public MethodResult getPrevious()
|
||||
{
|
||||
return previous;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public ILuaFunction getCallback()
|
||||
{
|
||||
return callback;
|
||||
}
|
||||
}
|
||||
|
||||
public static class WithLuaContext extends MethodResult
|
||||
{
|
||||
private final ILuaContextTask consumer;
|
||||
|
||||
private WithLuaContext( ILuaContextTask consumer )
|
||||
{
|
||||
this.consumer = consumer;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public ILuaContextTask getConsumer()
|
||||
{
|
||||
return consumer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
@@ -11,50 +11,65 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Represents an item that can be placed in a disk drive and used by a Computer.
|
||||
* Implement this interface on your Item class to allow it to be used in the drive.
|
||||
*/
|
||||
public interface IMedia
|
||||
{
|
||||
/**
|
||||
* Get a string representing the label of this item. Will be called vi disk.getLabel() in lua.
|
||||
* @param stack The itemstack to inspect
|
||||
* @return The label. ie: "Dan's Programs"
|
||||
*/
|
||||
public String getLabel( ItemStack stack );
|
||||
/**
|
||||
* Get a string representing the label of this item. Will be called via {@code disk.getLabel()} in lua.
|
||||
*
|
||||
* @param stack The itemstack to inspect.
|
||||
* @return The label. ie: "Dan's Programs".
|
||||
*/
|
||||
@Nullable
|
||||
String getLabel( @Nonnull ItemStack stack );
|
||||
|
||||
/**
|
||||
* Set a string representing the label of this item. Will be called vi disk.setLabel() in lua.
|
||||
* @param stack The itemstack to modify.
|
||||
* @param label The string to set the label to.
|
||||
* @return true if the label was updated, false if the label may not be modified.
|
||||
*/
|
||||
public boolean setLabel( ItemStack stack, String label );
|
||||
|
||||
/**
|
||||
* If this disk represents an item with audio (like a record), get the readable name of the audio track. ie: "Jonathon Coulton - Still Alive"
|
||||
* @param stack The itemstack to inspect.
|
||||
* @return The name, or null if this item does not represent an item with audio.
|
||||
*/
|
||||
public String getAudioTitle( ItemStack stack );
|
||||
/**
|
||||
* Set a string representing the label of this item. Will be called vi {@code disk.setLabel()} in lua.
|
||||
*
|
||||
* @param stack The itemstack to modify.
|
||||
* @param label The string to set the label to.
|
||||
* @return true if the label was updated, false if the label may not be modified.
|
||||
*/
|
||||
boolean setLabel( @Nonnull ItemStack stack, @Nullable String label );
|
||||
|
||||
/**
|
||||
* If this disk represents an item with audio (like a record), get the resource name of the audio track to play.
|
||||
* @param stack The itemstack to inspect.
|
||||
* @return The name, or null if this item does not represent an item with audio.
|
||||
*/
|
||||
public SoundEvent getAudio( ItemStack stack );
|
||||
|
||||
/**
|
||||
* If this disk represents an item with data (like a floppy disk), get a mount representing it's contents. This will be mounted onto the filesystem of the computercraft while the media is in the disk drive.
|
||||
* @param stack The itemstack to inspect.
|
||||
* @param world The world in which the item and disk drive reside.
|
||||
* @return The mount, or null if this item does not represent an item with data. If the IMount returned also implements IWritableMount, it will mounted using mountWritable()
|
||||
* @see dan200.computercraft.api.filesystem.IMount
|
||||
* @see dan200.computercraft.api.filesystem.IWritableMount
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#createSaveDirMount(World, String, long)
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#createResourceMount(Class, String, String)
|
||||
*/
|
||||
public IMount createDataMount( ItemStack stack, World world );
|
||||
/**
|
||||
* If this disk represents an item with audio (like a record), get the readable name of the audio track. ie:
|
||||
* "Jonathon Coulton - Still Alive"
|
||||
*
|
||||
* @param stack The itemstack to inspect.
|
||||
* @return The name, or null if this item does not represent an item with audio.
|
||||
*/
|
||||
@Nullable
|
||||
String getAudioTitle( @Nonnull ItemStack stack );
|
||||
|
||||
/**
|
||||
* If this disk represents an item with audio (like a record), get the resource name of the audio track to play.
|
||||
*
|
||||
* @param stack The itemstack to inspect.
|
||||
* @return The name, or null if this item does not represent an item with audio.
|
||||
*/
|
||||
@Nullable
|
||||
SoundEvent getAudio( @Nonnull ItemStack stack );
|
||||
|
||||
/**
|
||||
* If this disk represents an item with data (like a floppy disk), get a mount representing it's contents. This will
|
||||
* be mounted onto the filesystem of the computer while the media is in the disk drive.
|
||||
*
|
||||
* @param stack The itemstack to inspect.
|
||||
* @param world The world in which the item and disk drive reside.
|
||||
* @return The mount, or null if this item does not represent an item with data. If the mount returned also
|
||||
* implements {@link dan200.computercraft.api.filesystem.IWritableMount}, it will mounted using mountWritable()
|
||||
* @see dan200.computercraft.api.filesystem.IMount
|
||||
* @see dan200.computercraft.api.filesystem.IWritableMount
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#createSaveDirMount(World, String, long)
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#createResourceMount(Class, String, String)
|
||||
*/
|
||||
@Nullable
|
||||
IMount createDataMount( @Nonnull ItemStack stack, @Nonnull World world );
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
@@ -8,16 +8,24 @@ package dan200.computercraft.api.media;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* This interface is used to provide IMedia implementations for ItemStack
|
||||
* This interface is used to provide {@link IMedia} implementations for {@link ItemStack}.
|
||||
*
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#registerMediaProvider(IMediaProvider)
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface IMediaProvider
|
||||
{
|
||||
/**
|
||||
* Produce an IMedia implementation from an ItemStack.
|
||||
*
|
||||
* @param stack The stack from which to extract the media information.
|
||||
* @return An IMedia implementation, or null if the item is not something you wish to handle
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#registerMediaProvider(IMediaProvider)
|
||||
* @return an IMedia implementation, or null if the item is not something you wish to handle
|
||||
*/
|
||||
public IMedia getMedia( ItemStack stack );
|
||||
@Nullable
|
||||
IMedia getMedia( @Nonnull ItemStack stack );
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.api.network;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* A packet network represents a collection of devices which can send and receive packets.
|
||||
*
|
||||
* @see Packet
|
||||
* @see IPacketReceiver
|
||||
*/
|
||||
public interface IPacketNetwork
|
||||
{
|
||||
/**
|
||||
* Add a receiver to the network.
|
||||
*
|
||||
* @param receiver The receiver to register to the network.
|
||||
*/
|
||||
void addReceiver( @Nonnull IPacketReceiver receiver );
|
||||
|
||||
/**
|
||||
* Remove a receiver from the network.
|
||||
*
|
||||
* @param receiver The device to remove from the network.
|
||||
*/
|
||||
void removeReceiver( @Nonnull IPacketReceiver receiver );
|
||||
|
||||
/**
|
||||
* Determine whether this network is wireless.
|
||||
*
|
||||
* @return Whether this network is wireless.
|
||||
*/
|
||||
boolean isWireless();
|
||||
|
||||
/**
|
||||
* Submit a packet for transmitting across the network. This will route the packet through the network, sending it
|
||||
* to all receivers within range (or any interdimensional ones).
|
||||
*
|
||||
* @param packet The packet to send.
|
||||
* @param range The maximum distance this packet will be sent.
|
||||
* @see #transmitInterdimensional(Packet)
|
||||
* @see IPacketReceiver#receiveSameDimension(Packet, double)
|
||||
*/
|
||||
void transmitSameDimension( @Nonnull Packet packet, double range );
|
||||
|
||||
/**
|
||||
* Submit a packet for transmitting across the network. This will route the packet through the network, sending it
|
||||
* to all receivers across all dimensions.
|
||||
*
|
||||
* @param packet The packet to send.
|
||||
* @see #transmitSameDimension(Packet, double)
|
||||
* @see IPacketReceiver#receiveDifferentDimension(Packet)
|
||||
*/
|
||||
void transmitInterdimensional( @Nonnull Packet packet );
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.api.network;
|
||||
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* An object on an {@link IPacketNetwork}, capable of receiving packets.
|
||||
*/
|
||||
public interface IPacketReceiver
|
||||
{
|
||||
/**
|
||||
* Get the world in which this packet receiver exists.
|
||||
*
|
||||
* @return The receivers's world.
|
||||
*/
|
||||
@Nonnull
|
||||
World getWorld();
|
||||
|
||||
/**
|
||||
* Get the position in the world at which this receiver exists.
|
||||
*
|
||||
* @return The receiver's position.
|
||||
*/
|
||||
@Nonnull
|
||||
Vec3d getPosition();
|
||||
|
||||
/**
|
||||
* Get the maximum distance this receiver can send and receive messages.
|
||||
*
|
||||
* When determining whether a receiver can receive a message, the largest distance of the packet and receiver is
|
||||
* used - ensuring it is within range. If the packet or receiver is inter-dimensional, then the packet will always
|
||||
* be received.
|
||||
*
|
||||
* @return The maximum distance this device can send and receive messages.
|
||||
* @see #isInterdimensional()
|
||||
* @see #receiveSameDimension(Packet packet, double)
|
||||
* @see IPacketNetwork#transmitInterdimensional(Packet)
|
||||
*/
|
||||
double getRange();
|
||||
|
||||
/**
|
||||
* Determine whether this receiver can receive packets from other dimensions.
|
||||
*
|
||||
* A device will receive an inter-dimensional packet if either it or the sending device is inter-dimensional.
|
||||
*
|
||||
* @return Whether this receiver receives packets from other dimensions.
|
||||
* @see #getRange()
|
||||
* @see #receiveDifferentDimension(Packet)
|
||||
* @see IPacketNetwork#transmitInterdimensional(Packet)
|
||||
*/
|
||||
boolean isInterdimensional();
|
||||
|
||||
/**
|
||||
* Receive a network packet from the same dimension.
|
||||
*
|
||||
* @param packet The packet to receive. Generally you should check that you are listening on the given channel and,
|
||||
* if so, queue the appropriate modem event.
|
||||
* @param distance The distance this packet has travelled from the source.
|
||||
* @see Packet
|
||||
* @see #getRange()
|
||||
* @see IPacketNetwork#transmitSameDimension(Packet, double)
|
||||
* @see IPacketNetwork#transmitInterdimensional(Packet)
|
||||
*/
|
||||
void receiveSameDimension( @Nonnull Packet packet, double distance );
|
||||
|
||||
/**
|
||||
* Receive a network packet from a different dimension.
|
||||
*
|
||||
* @param packet The packet to receive. Generally you should check that you are listening on the given channel and,
|
||||
* if so, queue the appropriate modem event.
|
||||
* @see Packet
|
||||
* @see IPacketNetwork#transmitInterdimensional(Packet)
|
||||
* @see IPacketNetwork#transmitSameDimension(Packet, double)
|
||||
* @see #isInterdimensional()
|
||||
*/
|
||||
void receiveDifferentDimension( @Nonnull Packet packet );
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.api.network;
|
||||
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* An object on a {@link IPacketNetwork}, capable of sending packets.
|
||||
*/
|
||||
public interface IPacketSender
|
||||
{
|
||||
/**
|
||||
* Get the world in which this packet sender exists.
|
||||
*
|
||||
* @return The sender's world.
|
||||
*/
|
||||
@Nonnull
|
||||
World getWorld();
|
||||
|
||||
/**
|
||||
* Get the position in the world at which this sender exists.
|
||||
*
|
||||
* @return The sender's position.
|
||||
*/
|
||||
@Nonnull
|
||||
Vec3d getPosition();
|
||||
|
||||
/**
|
||||
* Get some sort of identification string for this sender. This does not strictly need to be unique, but you
|
||||
* should be able to extract some identifiable information from it.
|
||||
*
|
||||
* @return This device's id.
|
||||
*/
|
||||
@Nonnull
|
||||
String getSenderID();
|
||||
}
|
||||
118
src/main/java/dan200/computercraft/api/network/Packet.java
Normal file
118
src/main/java/dan200/computercraft/api/network/Packet.java
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.api.network;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a packet which may be sent across a {@link IPacketNetwork}.
|
||||
*
|
||||
* @see IPacketSender
|
||||
* @see IPacketNetwork#transmitSameDimension(Packet, double)
|
||||
* @see IPacketNetwork#transmitInterdimensional(Packet)
|
||||
* @see IPacketReceiver#receiveDifferentDimension(Packet)
|
||||
* @see IPacketReceiver#receiveSameDimension(Packet, double)
|
||||
*/
|
||||
public class Packet
|
||||
{
|
||||
private final int m_channel;
|
||||
private final int m_replyChannel;
|
||||
private final Object m_payload;
|
||||
|
||||
private final IPacketSender m_sender;
|
||||
|
||||
/**
|
||||
* Create a new packet, ready for transmitting across the network.
|
||||
*
|
||||
* @param channel The channel to send the packet along. Receiving devices should only process packets from on
|
||||
* channels they are listening to.
|
||||
* @param replyChannel The channel to reply on.
|
||||
* @param payload The contents of this packet. This should be a "valid" Lua object, safe for queuing as an
|
||||
* event or returning from a peripheral call.
|
||||
* @param sender The object which sent this packet.
|
||||
*/
|
||||
public Packet( int channel, int replyChannel, @Nullable Object payload, @Nonnull IPacketSender sender )
|
||||
{
|
||||
Preconditions.checkNotNull( sender, "sender cannot be null" );
|
||||
|
||||
m_channel = channel;
|
||||
m_replyChannel = replyChannel;
|
||||
m_payload = payload;
|
||||
m_sender = sender;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channel this packet is sent along. Receivers should generally only process packets from on channels they
|
||||
* are listening to.
|
||||
*
|
||||
* @return This packet's channel.
|
||||
*/
|
||||
public int getChannel()
|
||||
{
|
||||
return m_channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* The channel to reply on. Objects which will reply should send it along this channel.
|
||||
*
|
||||
* @return This channel to reply on.
|
||||
*/
|
||||
public int getReplyChannel()
|
||||
{
|
||||
return m_replyChannel;
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual data of this packet. This should be a "valid" Lua object, safe for queuing as an
|
||||
* event or returning from a peripheral call.
|
||||
*
|
||||
* @return The packet's payload
|
||||
*/
|
||||
@Nullable
|
||||
public Object getPayload()
|
||||
{
|
||||
return m_payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* The object which sent this message.
|
||||
*
|
||||
* @return The sending object.
|
||||
*/
|
||||
@Nonnull
|
||||
public IPacketSender getSender()
|
||||
{
|
||||
return m_sender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( Object o )
|
||||
{
|
||||
if( this == o ) return true;
|
||||
if( o == null || getClass() != o.getClass() ) return false;
|
||||
|
||||
Packet packet = (Packet) o;
|
||||
|
||||
if( m_channel != packet.m_channel ) return false;
|
||||
if( m_replyChannel != packet.m_replyChannel ) return false;
|
||||
if( m_payload != null ? !m_payload.equals( packet.m_payload ) : packet.m_payload != null ) return false;
|
||||
return m_sender.equals( packet.m_sender );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
int result;
|
||||
result = m_channel;
|
||||
result = 31 * result + m_replyChannel;
|
||||
result = 31 * result + (m_payload != null ? m_payload.hashCode() : 0);
|
||||
result = 31 * result + m_sender.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
@API( owner="ComputerCraft", provides="ComputerCraft|API|Network", apiVersion="${version}" )
|
||||
package dan200.computercraft.api.network;
|
||||
|
||||
import net.minecraftforge.fml.common.API;
|
||||
@@ -0,0 +1,29 @@
|
||||
package dan200.computercraft.api.network.wired;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* An object which may be part of a wired network.
|
||||
*
|
||||
* Elements should construct a node using {@link ComputerCraftAPI#createWiredNodeForElement(IWiredElement)}. This acts
|
||||
* as a proxy for all network objects. Whilst the node may change networks, an element's node should remain constant
|
||||
* for its lifespan.
|
||||
*
|
||||
* Elements are generally tied to a block or tile entity in world. In such as case, one should provide the
|
||||
* {@link IWiredElement} capability for the appropriate sides.
|
||||
*/
|
||||
public interface IWiredElement extends IWiredSender
|
||||
{
|
||||
/**
|
||||
* Called when objects on the network change. This may occur when network nodes are added or removed, or when
|
||||
* peripherals change.
|
||||
*
|
||||
* @param change The change which occurred.
|
||||
* @see IWiredNetworkChange
|
||||
*/
|
||||
default void networkChanged( @Nonnull IWiredNetworkChange change )
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package dan200.computercraft.api.network.wired;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A wired network is composed of one of more {@link IWiredNode}s, a set of connections between them, and a series
|
||||
* of peripherals.
|
||||
*
|
||||
* Networks from a connected graph. This means there is some path between all nodes on the network. Further more, if
|
||||
* there is some path between two nodes then they must be on the same network. {@link IWiredNetwork} will automatically
|
||||
* handle the merging and splitting of networks (and thus changing of available nodes and peripherals) as connections
|
||||
* change.
|
||||
*
|
||||
* This does mean one can not rely on the network remaining consistent between subsequent operations. Consequently,
|
||||
* it is generally preferred to use the methods provided by {@link IWiredNode}.
|
||||
*
|
||||
* @see IWiredNode#getNetwork()
|
||||
*/
|
||||
public interface IWiredNetwork
|
||||
{
|
||||
/**
|
||||
* Create a connection between two nodes.
|
||||
*
|
||||
* This should only be used on the server thread.
|
||||
*
|
||||
* @param left The first node to connect
|
||||
* @param right The second node to connect
|
||||
* @return {@code true} if a connection was created or {@code false} if the connection already exists.
|
||||
* @throws IllegalStateException If neither node is on the network.
|
||||
* @throws IllegalArgumentException If {@code left} and {@code right} are equal.
|
||||
* @see IWiredNode#connectTo(IWiredNode)
|
||||
* @see IWiredNetwork#connect(IWiredNode, IWiredNode)
|
||||
*/
|
||||
boolean connect( @Nonnull IWiredNode left, @Nonnull IWiredNode right );
|
||||
|
||||
/**
|
||||
* Destroy a connection between this node and another.
|
||||
*
|
||||
* This should only be used on the server thread.
|
||||
*
|
||||
* @param left The first node in the connection.
|
||||
* @param right The second node in the connection.
|
||||
* @return {@code true} if a connection was destroyed or {@code false} if no connection exists.
|
||||
* @throws IllegalArgumentException If either node is not on the network.
|
||||
* @throws IllegalArgumentException If {@code left} and {@code right} are equal.
|
||||
* @see IWiredNode#disconnectFrom(IWiredNode)
|
||||
* @see IWiredNetwork#connect(IWiredNode, IWiredNode)
|
||||
*/
|
||||
boolean disconnect( @Nonnull IWiredNode left, @Nonnull IWiredNode right );
|
||||
|
||||
/**
|
||||
* Sever all connections this node has, removing it from this network.
|
||||
*
|
||||
* This should only be used on the server thread. You should only call this on nodes
|
||||
* that your network element owns.
|
||||
*
|
||||
* @param node The node to remove
|
||||
* @return Whether this node was removed from the network. One cannot remove a node from a network where it is the
|
||||
* only element.
|
||||
* @throws IllegalArgumentException If the node is not in the network.
|
||||
* @see IWiredNode#remove()
|
||||
*/
|
||||
boolean remove( @Nonnull IWiredNode node );
|
||||
|
||||
/**
|
||||
* Update the peripherals a node provides.
|
||||
*
|
||||
* This should only be used on the server thread. You should only call this on nodes
|
||||
* that your network element owns.
|
||||
*
|
||||
* @param node The node to attach peripherals for.
|
||||
* @param peripherals The new peripherals for this node.
|
||||
* @throws IllegalArgumentException If the node is not in the network.
|
||||
* @see IWiredNode#updatePeripherals(Map)
|
||||
*/
|
||||
void updatePeripherals( @Nonnull IWiredNode node, @Nonnull Map<String, IPeripheral> peripherals );
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package dan200.computercraft.api.network.wired;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents a change to the objects on a wired network.
|
||||
*
|
||||
* @see IWiredElement#networkChanged(IWiredNetworkChange)
|
||||
*/
|
||||
public interface IWiredNetworkChange
|
||||
{
|
||||
/**
|
||||
* A set of peripherals which have been removed. Note that there may be entries with the same name
|
||||
* in the added and removed set, but with a different peripheral.
|
||||
*
|
||||
* @return The set of removed peripherals.
|
||||
*/
|
||||
@Nonnull
|
||||
Map<String, IPeripheral> peripheralsRemoved();
|
||||
|
||||
/**
|
||||
* A set of peripherals which have been added. Note that there may be entries with the same name
|
||||
* in the added and removed set, but with a different peripheral.
|
||||
*
|
||||
* @return The set of added peripherals.
|
||||
*/
|
||||
@Nonnull
|
||||
Map<String, IPeripheral> peripheralsAdded();
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package dan200.computercraft.api.network.wired;
|
||||
|
||||
import dan200.computercraft.api.network.IPacketNetwork;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Wired nodes act as a layer between {@link IWiredElement}s and {@link IWiredNetwork}s.
|
||||
*
|
||||
* Firstly, a node acts as a packet network, capable of sending and receiving modem messages to connected nodes. These
|
||||
* methods may be safely used on any thread.
|
||||
*
|
||||
* When sending a packet, the system will attempt to find the shortest path between the two nodes based on their
|
||||
* element's position. Note that packet senders and receivers can have different locations from their associated
|
||||
* element: the distance between the two will be added to the total packet's distance.
|
||||
*
|
||||
* Wired nodes also provide several convenience methods for interacting with a wired network. These should only ever
|
||||
* be used on the main server thread.
|
||||
*/
|
||||
public interface IWiredNode extends IPacketNetwork
|
||||
{
|
||||
/**
|
||||
* The associated element for this network node.
|
||||
*
|
||||
* @return This node's element.
|
||||
*/
|
||||
@Nonnull
|
||||
IWiredElement getElement();
|
||||
|
||||
/**
|
||||
* The network this node is currently connected to. Note that this may change
|
||||
* after any network operation, so it should not be cached.
|
||||
*
|
||||
* This should only be used on the server thread.
|
||||
*
|
||||
* @return This node's network.
|
||||
*/
|
||||
@Nonnull
|
||||
IWiredNetwork getNetwork();
|
||||
|
||||
/**
|
||||
* Create a connection from this node to another.
|
||||
*
|
||||
* This should only be used on the server thread.
|
||||
*
|
||||
* @param node The other node to connect to.
|
||||
* @return {@code true} if a connection was created or {@code false} if the connection already exists.
|
||||
* @see IWiredNetwork#connect(IWiredNode, IWiredNode)
|
||||
* @see IWiredNode#disconnectFrom(IWiredNode)
|
||||
*/
|
||||
default boolean connectTo( @Nonnull IWiredNode node )
|
||||
{
|
||||
return getNetwork().connect( this, node );
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy a connection between this node and another.
|
||||
*
|
||||
* This should only be used on the server thread.
|
||||
*
|
||||
* @param node The other node to disconnect from.
|
||||
* @return {@code true} if a connection was destroyed or {@code false} if no connection exists.
|
||||
* @throws IllegalArgumentException If {@code node} is not on the same network.
|
||||
* @see IWiredNetwork#disconnect(IWiredNode, IWiredNode)
|
||||
* @see IWiredNode#connectTo(IWiredNode)
|
||||
*/
|
||||
default boolean disconnectFrom( @Nonnull IWiredNode node )
|
||||
{
|
||||
return getNetwork().disconnect( this, node );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sever all connections this node has, removing it from this network.
|
||||
*
|
||||
* This should only be used on the server thread. You should only call this on nodes
|
||||
* that your network element owns.
|
||||
*
|
||||
* @return Whether this node was removed from the network. One cannot remove a node from a network where it is the
|
||||
* only element.
|
||||
* @throws IllegalArgumentException If the node is not in the network.
|
||||
* @see IWiredNetwork#remove(IWiredNode)
|
||||
*/
|
||||
default boolean remove()
|
||||
{
|
||||
return getNetwork().remove( this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark this node's peripherals as having changed.
|
||||
*
|
||||
* This should only be used on the server thread. You should only call this on nodes
|
||||
* that your network element owns.
|
||||
*
|
||||
* @param peripherals The new peripherals for this node.
|
||||
* @see IWiredNetwork#updatePeripherals(IWiredNode, Map)
|
||||
*/
|
||||
default void updatePeripherals( @Nonnull Map<String, IPeripheral> peripherals )
|
||||
{
|
||||
getNetwork().updatePeripherals( this, peripherals );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package dan200.computercraft.api.network.wired;
|
||||
|
||||
import dan200.computercraft.api.network.IPacketSender;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* An object on a {@link IWiredNetwork} capable of sending packets.
|
||||
*
|
||||
* Unlike a regular {@link IPacketSender}, this must be associated with the node you are attempting to
|
||||
* to send the packet from.
|
||||
*/
|
||||
public interface IWiredSender extends IPacketSender
|
||||
{
|
||||
/**
|
||||
* The node in the network representing this object.
|
||||
*
|
||||
* This should be used as a proxy for the main network. One should send packets
|
||||
* and register receivers through this object.
|
||||
*
|
||||
* @return The node for this element.
|
||||
*/
|
||||
@Nonnull
|
||||
IWiredNode getNode();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
@API( owner="ComputerCraft", provides="ComputerCraft|API|Network|Wired", apiVersion="${version}" )
|
||||
package dan200.computercraft.api.network.wired;
|
||||
|
||||
import net.minecraftforge.fml.common.API;
|
||||
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
@API( owner="ComputerCraft", provides="ComputerCraft|API", apiVersion="${version}" )
|
||||
package dan200.computercraft.api;
|
||||
|
||||
import net.minecraftforge.fml.common.API;
|
||||
import net.minecraftforge.fml.common.API;
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.peripheral;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.filesystem.IMount;
|
||||
import dan200.computercraft.api.filesystem.IWritableMount;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The interface passed to peripherals by computers or turtles, providing methods
|
||||
@@ -16,87 +23,166 @@ import dan200.computercraft.api.filesystem.IWritableMount;
|
||||
*/
|
||||
public interface IComputerAccess
|
||||
{
|
||||
/**
|
||||
* Mount a mount onto the computers' file system in a read only mode.<br>
|
||||
* @param desiredLocation The location on the computercraft's file system where you would like the mount to be mounted.
|
||||
* @param mount The mount object to mount on the computercraft. These can be obtained by calling ComputerCraftAPI.createSaveDirMount(), ComputerCraftAPI.createResourceMount() or by creating your own objects that implement the IMount interface.
|
||||
* @return The location on the computercraft's file system where you the mount mounted, or null if there was already a file in the desired location. Store this value if you wish to unmount the mount later.
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#createSaveDirMount(World, String)
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#createResourceMount(Class, String, String)
|
||||
* @see #mountWritable(String, dan200.computercraft.api.filesystem.IWritableMount)
|
||||
* @see #unmount(String)
|
||||
* @see dan200.computercraft.api.filesystem.IMount
|
||||
*/
|
||||
public String mount( String desiredLocation, IMount mount );
|
||||
/**
|
||||
* Mount a mount onto the computer's file system in a read only mode.
|
||||
*
|
||||
* @param desiredLocation The location on the computer's file system where you would like the mount to be mounted.
|
||||
* @param mount The mount object to mount on the computer.
|
||||
* @return The location on the computer's file system where you the mount mounted, or {@code null} if there was already a
|
||||
* file in the desired location. Store this value if you wish to unmount the mount later.
|
||||
* @throws RuntimeException If the peripheral has been detached.
|
||||
* @see ComputerCraftAPI#createSaveDirMount(World, String, long)
|
||||
* @see ComputerCraftAPI#createResourceMount(Class, String, String)
|
||||
* @see #mount(String, IMount, String)
|
||||
* @see #mountWritable(String, IWritableMount)
|
||||
* @see #unmount(String)
|
||||
* @see IMount
|
||||
*/
|
||||
@Nullable
|
||||
String mount( @Nonnull String desiredLocation, @Nonnull IMount mount );
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* Mount a mount onto the computer's file system in a read only mode.
|
||||
*
|
||||
* @param desiredLocation The location on the computer's file system where you would like the mount to be mounted.
|
||||
* @param mount The mount object to mount on the computer.
|
||||
* @param driveName A custom name to give for this mount location, as returned by {@code fs.getDrive()}.
|
||||
* @return The location on the computer's file system where you the mount mounted, or {@code null} if there was already a
|
||||
* file in the desired location. Store this value if you wish to unmount the mount later.
|
||||
* @throws RuntimeException If the peripheral has been detached.
|
||||
* @see ComputerCraftAPI#createSaveDirMount(World, String, long)
|
||||
* @see ComputerCraftAPI#createResourceMount(Class, String, String)
|
||||
* @see #mount(String, IMount)
|
||||
* @see #mountWritable(String, IWritableMount)
|
||||
* @see #unmount(String)
|
||||
* @see IMount
|
||||
*/
|
||||
public String mount( String desiredLocation, IMount mount, String driveName );
|
||||
|
||||
/**
|
||||
* Mount a mount onto the computers' file system in a writable mode.<br>
|
||||
* @param desiredLocation The location on the computercraft's file system where you would like the mount to be mounted.
|
||||
* @param mount The mount object to mount on the computercraft. These can be obtained by calling ComputerCraftAPI.createSaveDirMount() or by creating your own objects that implement the IWritableMount interface.
|
||||
* @return The location on the computercraft's file system where you the mount mounted, or null if there was already a file in the desired location. Store this value if you wish to unmount the mount later.
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#createSaveDirMount(World, String)
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#createResourceMount(Class, String, String)
|
||||
* @see #mount(String, IMount)
|
||||
* @see #unmount(String)
|
||||
* @see IMount
|
||||
*/
|
||||
public String mountWritable( String desiredLocation, IWritableMount mount );
|
||||
@Nullable
|
||||
String mount( @Nonnull String desiredLocation, @Nonnull IMount mount, @Nonnull String driveName );
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* Mount a mount onto the computer's file system in a writable mode.
|
||||
*
|
||||
* @param desiredLocation The location on the computer's file system where you would like the mount to be mounted.
|
||||
* @param mount The mount object to mount on the computer.
|
||||
* @return The location on the computer's file system where you the mount mounted, or null if there was already a
|
||||
* file in the desired location. Store this value if you wish to unmount the mount later.
|
||||
* @throws RuntimeException If the peripheral has been detached.
|
||||
* @see ComputerCraftAPI#createSaveDirMount(World, String, long)
|
||||
* @see ComputerCraftAPI#createResourceMount(Class, String, String)
|
||||
* @see #mount(String, IMount)
|
||||
* @see #unmount(String)
|
||||
* @see IMount
|
||||
*/
|
||||
public String mountWritable( String desiredLocation, IWritableMount mount, String driveName );
|
||||
@Nullable
|
||||
String mountWritable( @Nonnull String desiredLocation, @Nonnull IWritableMount mount );
|
||||
|
||||
/**
|
||||
* Unmounts a directory previously mounted onto the computers file system by mount() or mountWritable().<br>
|
||||
* When a directory is unmounted, it will disappear from the computers file system, and the user will no longer be able to
|
||||
* access it. All directories mounted by a mount or mountWritable are automatically unmounted when the peripheral
|
||||
* is attached if they have not been explicitly unmounted.
|
||||
* @param location The desired location in the computers file system of the directory to unmount.
|
||||
* This must be the location of a directory previously mounted by mount() or mountWritable(), as
|
||||
* indicated by their return value.
|
||||
* @see #mount(String, IMount)
|
||||
* @see #mountWritable(String, IWritableMount)
|
||||
*/
|
||||
public void unmount( String location );
|
||||
|
||||
/**
|
||||
* Returns the numerical ID of this computercraft.<br>
|
||||
* This is the same number obtained by calling os.getComputerID() or running the "id" program from lua,
|
||||
* and is guarunteed unique. This number will be positive.
|
||||
* @return The identifier.
|
||||
*/
|
||||
public int getID();
|
||||
/**
|
||||
* Mount a mount onto the computer's file system in a writable mode.
|
||||
*
|
||||
* @param desiredLocation The location on the computer's file system where you would like the mount to be mounted.
|
||||
* @param mount The mount object to mount on the computer.
|
||||
* @param driveName A custom name to give for this mount location, as returned by {@code fs.getDrive()}.
|
||||
* @return The location on the computer's file system where you the mount mounted, or null if there was already a
|
||||
* file in the desired location. Store this value if you wish to unmount the mount later.
|
||||
* @throws RuntimeException If the peripheral has been detached.
|
||||
* @see ComputerCraftAPI#createSaveDirMount(World, String, long)
|
||||
* @see ComputerCraftAPI#createResourceMount(Class, String, String)
|
||||
* @see #mount(String, IMount)
|
||||
* @see #unmount(String)
|
||||
* @see IMount
|
||||
*/
|
||||
String mountWritable( @Nonnull String desiredLocation, @Nonnull IWritableMount mount, @Nonnull String driveName );
|
||||
|
||||
/**
|
||||
* Causes an event to be raised on this computercraft, which the computercraft can respond to by calling
|
||||
* os.pullEvent(). This can be used to notify the computercraft when things happen in the world or to
|
||||
* this peripheral.
|
||||
* @param event A string identifying the type of event that has occurred, this will be
|
||||
* returned as the first value from os.pullEvent(). It is recommended that you
|
||||
* you choose a name that is unique, and recognisable as originating from your
|
||||
* peripheral. eg: If your peripheral type is "button", a suitable event would be
|
||||
* "button_pressed".
|
||||
* @param arguments In addition to a name, you may pass an array of extra arguments to the event, that will
|
||||
* be supplied as extra return values to os.pullEvent(). Objects in the array will be converted
|
||||
* to lua data types in the same fashion as the return values of IPeripheral.callMethod().<br>
|
||||
* You may supply null to indicate that no arguments are to be supplied.
|
||||
* @see dan200.computercraft.api.peripheral.IPeripheral#callMethod
|
||||
*/
|
||||
public void queueEvent( String event, Object[] arguments );
|
||||
/**
|
||||
* Unmounts a directory previously mounted onto the computers file system by {@link #mount(String, IMount)}
|
||||
* or {@link #mountWritable(String, IWritableMount)}.
|
||||
*
|
||||
* When a directory is unmounted, it will disappear from the computers file system, and the user will no longer be
|
||||
* able to access it. All directories mounted by a mount or mountWritable are automatically unmounted when the
|
||||
* peripheral is attached if they have not been explicitly unmounted.
|
||||
*
|
||||
* Note that you cannot unmount another peripheral's mounts.
|
||||
*
|
||||
* @param location The desired location in the computers file system of the directory to unmount.
|
||||
* This must be the location of a directory previously mounted by {@link #mount(String, IMount)} or
|
||||
* {@link #mountWritable(String, IWritableMount)}, as indicated by their return value.
|
||||
* @throws RuntimeException If the peripheral has been detached.
|
||||
* @throws RuntimeException If the mount does not exist, or was mounted by another peripheral.
|
||||
* @see #mount(String, IMount)
|
||||
* @see #mountWritable(String, IWritableMount)
|
||||
*/
|
||||
void unmount( @Nullable String location );
|
||||
|
||||
/**
|
||||
* Get a string, unique to the computercraft, by which the computercraft refers to this peripheral.
|
||||
* For directly attached peripherals this will be "left","right","front","back",etc, but
|
||||
* for peripherals attached remotely it will be different. It is good practice to supply
|
||||
* this string when raising events to the computercraft, so that the computercraft knows from
|
||||
* which peripheral the event came.
|
||||
* @return A string unique to the computercraft, but not globally.
|
||||
*/
|
||||
public String getAttachmentName();
|
||||
/**
|
||||
* Returns the numerical ID of this computer.
|
||||
*
|
||||
* This is the same number obtained by calling {@code os.getComputerID()} or running the "id" program from lua,
|
||||
* and is guaranteed unique. This number will be positive.
|
||||
*
|
||||
* @return The identifier.
|
||||
*/
|
||||
int getID();
|
||||
|
||||
/**
|
||||
* Causes an event to be raised on this computer, which the computer can respond to by calling
|
||||
* {@code os.pullEvent()}. This can be used to notify the computer when things happen in the world or to
|
||||
* this peripheral.
|
||||
*
|
||||
* @param event A string identifying the type of event that has occurred, this will be
|
||||
* returned as the first value from {@code os.pullEvent()}. It is recommended that you
|
||||
* you choose a name that is unique, and recognisable as originating from your
|
||||
* peripheral. eg: If your peripheral type is "button", a suitable event would be
|
||||
* "button_pressed".
|
||||
* @param arguments In addition to a name, you may pass an array of extra arguments to the event, that will
|
||||
* be supplied as extra return values to os.pullEvent(). Objects in the array will be converted
|
||||
* to lua data types in the same fashion as the return values of IPeripheral.callMethod().
|
||||
*
|
||||
* You may supply {@code null} to indicate that no arguments are to be supplied.
|
||||
* @throws RuntimeException If the peripheral has been detached.
|
||||
* @see dan200.computercraft.api.peripheral.IPeripheral#callMethod
|
||||
*/
|
||||
void queueEvent( @Nonnull String event, @Nullable Object[] arguments );
|
||||
|
||||
/**
|
||||
* Get a string, unique to the computer, by which the computer refers to this peripheral.
|
||||
* For directly attached peripherals this will be "left","right","front","back",etc, but
|
||||
* for peripherals attached remotely it will be different. It is good practice to supply
|
||||
* this string when raising events to the computer, so that the computer knows from
|
||||
* which peripheral the event came.
|
||||
*
|
||||
* @return A string unique to the computer, but not globally.
|
||||
* @throws RuntimeException If the peripheral has been detached.
|
||||
*/
|
||||
@Nonnull
|
||||
String getAttachmentName();
|
||||
|
||||
/**
|
||||
* Get a set of peripherals that this computer access can "see", along with their attachment name.
|
||||
*
|
||||
* This may include other peripherals on the wired network or peripherals on other sides of the computer.
|
||||
*
|
||||
* @return All reachable peripherals
|
||||
* @see #getAttachmentName()
|
||||
* @see #getAvailablePeripheral(String)
|
||||
*/
|
||||
@Nonnull
|
||||
default Map<String, IPeripheral> getAvailablePeripherals()
|
||||
{
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reachable peripheral with the given attachement name. This is a equivalent to
|
||||
* {@link #getAvailablePeripherals()}{@code .get(name)}, though may be more performant.
|
||||
*
|
||||
* @param name The peripheral's attached name
|
||||
* @return The reachable peripheral, or {@code null} if none can be found.
|
||||
* @see #getAvailablePeripherals()
|
||||
*/
|
||||
@Nullable
|
||||
default IPeripheral getAvailablePeripheral( @Nonnull String name )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,98 +1,177 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2018. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.peripheral;
|
||||
|
||||
import dan200.computercraft.api.lua.ICallContext;
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.lua.MethodResult;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* The interface that defines a peripheral. See IPeripheralProvider for how to associate blocks with peripherals.
|
||||
* The interface that defines a peripheral. See {@link IPeripheralProvider} for how to associate blocks with peripherals.
|
||||
*/
|
||||
public interface IPeripheral
|
||||
{
|
||||
/**
|
||||
* Should return a string that uniquely identifies this type of peripheral.
|
||||
* This can be queried from lua by calling peripheral.getType()
|
||||
* @return A string identifying the type of peripheral.
|
||||
*/
|
||||
public String getType();
|
||||
|
||||
/**
|
||||
* Should return an array of strings that identify the methods that this
|
||||
* peripheral exposes to Lua. This will be called once before each attachment,
|
||||
* and should not change when called multiple times.
|
||||
* @return An array of strings representing method names.
|
||||
* @see #callMethod
|
||||
*/
|
||||
public String[] getMethodNames();
|
||||
|
||||
/**
|
||||
* This is called when a lua program on an attached computercraft calls peripheral.call() with
|
||||
* one of the methods exposed by getMethodNames().<br>
|
||||
* <br>
|
||||
* Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe
|
||||
* when interacting with minecraft objects.
|
||||
* @param computer The interface to the computercraft that is making the call. Remember that multiple
|
||||
* computers can be attached to a peripheral at once.
|
||||
* @param context The context of the currently running lua thread. This can be used to wait for events
|
||||
* or otherwise yield.
|
||||
* @param method An integer identifying which of the methods from getMethodNames() the computercraft
|
||||
* wishes to call. The integer indicates the index into the getMethodNames() table
|
||||
* that corresponds to the string passed into peripheral.call()
|
||||
* @param arguments An array of objects, representing the arguments passed into peripheral.call().<br>
|
||||
* Lua values of type "string" will be represented by Object type String.<br>
|
||||
* Lua values of type "number" will be represented by Object type Double.<br>
|
||||
* Lua values of type "boolean" will be represented by Object type Boolean.<br>
|
||||
* Lua values of any other type will be represented by a null object.<br>
|
||||
* This array will be empty if no arguments are passed.
|
||||
* @return An array of objects, representing values you wish to return to the lua program.<br>
|
||||
* Integers, Doubles, Floats, Strings, Booleans and null be converted to their corresponding lua type.<br>
|
||||
* All other types will be converted to nil.<br>
|
||||
* You may return null to indicate no values should be returned.
|
||||
* @throws Exception If you throw any exception from this function, a lua error will be raised with the
|
||||
* same message as your exception. Use this to throw appropriate errors if the wrong
|
||||
* arguments are supplied to your method.
|
||||
* @see #getMethodNames
|
||||
*/
|
||||
public Object[] callMethod( IComputerAccess computer, ILuaContext context, int method, Object[] arguments ) throws LuaException, InterruptedException;
|
||||
|
||||
/**
|
||||
* Is called when canAttachToSide has returned true, and a computercraft is attaching to the peripheral.
|
||||
* This will occur when a peripheral is placed next to an active computercraft, when a computercraft is turned on next to a peripheral,
|
||||
* or when a turtle travels into a square next to a peripheral.
|
||||
* Between calls to attach() and detach(), the attached computercraft can make method calls on the peripheral using peripheral.call().
|
||||
* This method can be used to keep track of which computers are attached to the peripheral, or to take action when attachment
|
||||
* occurs.<br>
|
||||
* <br>
|
||||
* Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe
|
||||
* when interacting with minecraft objects.
|
||||
* @param computer The interface to the computercraft that is being attached. Remember that multiple
|
||||
* computers can be attached to a peripheral at once.
|
||||
* @see #detach
|
||||
*/
|
||||
public void attach( IComputerAccess computer );
|
||||
|
||||
/**
|
||||
* Is called when a computercraft is detaching from the peripheral.
|
||||
* This will occur when a computercraft shuts down, when the peripheral is removed while attached to computers,
|
||||
* or when a turtle moves away from a square attached to a peripheral.
|
||||
* This method can be used to keep track of which computers are attached to the peripheral, or to take action when detachment
|
||||
* occurs.<br>
|
||||
* <br>
|
||||
* Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe
|
||||
* when interacting with minecraft objects.
|
||||
* @param computer The interface to the computercraft that is being detached. Remember that multiple
|
||||
* computers can be attached to a peripheral at once.
|
||||
* @see #detach
|
||||
*/
|
||||
public void detach( IComputerAccess computer );
|
||||
/**
|
||||
* Should return a string that uniquely identifies this type of peripheral.
|
||||
* This can be queried from lua by calling {@code peripheral.getType()}
|
||||
*
|
||||
* @return A string identifying the type of peripheral.
|
||||
*/
|
||||
@Nonnull
|
||||
String getType();
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* Should return an array of strings that identify the methods that this
|
||||
* peripheral exposes to Lua. This will be called once before each attachment,
|
||||
* and should not change when called multiple times.
|
||||
*
|
||||
* @return An array of strings representing method names.
|
||||
* @see #callMethod
|
||||
*/
|
||||
public boolean equals( IPeripheral other );
|
||||
@Nonnull
|
||||
String[] getMethodNames();
|
||||
|
||||
/**
|
||||
* This is called when a lua program on an attached computer calls {@code peripheral.call()} with
|
||||
* one of the methods exposed by {@link #getMethodNames()}.
|
||||
*
|
||||
* Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe
|
||||
* when interacting with Minecraft objects.
|
||||
*
|
||||
* @param computer The interface to the computer that is making the call. Remember that multiple
|
||||
* computers can be attached to a peripheral at once.
|
||||
* @param context The context of the currently running lua thread. This can be used to wait for events
|
||||
* or otherwise yield.
|
||||
* @param method An integer identifying which of the methods from getMethodNames() the computercraft
|
||||
* wishes to call. The integer indicates the index into the getMethodNames() table
|
||||
* that corresponds to the string passed into peripheral.call()
|
||||
* @param arguments An array of objects, representing the arguments passed into {@code peripheral.call()}.<br>
|
||||
* Lua values of type "string" will be represented by Object type String.<br>
|
||||
* Lua values of type "number" will be represented by Object type Double.<br>
|
||||
* Lua values of type "boolean" will be represented by Object type Boolean.<br>
|
||||
* Lua values of type "table" will be represented by Object type Map.<br>
|
||||
* Lua values of any other type will be represented by a null object.<br>
|
||||
* This array will be empty if no arguments are passed.
|
||||
* @return An array of objects, representing values you wish to return to the lua program. Integers, Doubles, Floats,
|
||||
* Strings, Booleans, Maps and ILuaObject and null be converted to their corresponding lua type. All other types
|
||||
* will be converted to nil.
|
||||
*
|
||||
* You may return null to indicate no values should be returned.
|
||||
* @throws LuaException If you throw any exception from this function, a lua error will be raised with the
|
||||
* same message as your exception. Use this to throw appropriate errors if the wrong
|
||||
* arguments are supplied to your method.
|
||||
* @throws InterruptedException If the user shuts down or reboots the computer the coroutine is suspended,
|
||||
* InterruptedException will be thrown. This exception must not be caught or
|
||||
* intercepted, or the computer will leak memory and end up in a broken state.
|
||||
* @see #getMethodNames
|
||||
* @deprecated Use {@link #callMethod(IComputerAccess, ICallContext, int, Object[])} instead.
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated
|
||||
Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException;
|
||||
|
||||
/**
|
||||
* This is called when a lua program on an attached computer calls {@code peripheral.call()} with
|
||||
* one of the methods exposed by {@link #getMethodNames()}.
|
||||
*
|
||||
* Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe
|
||||
* when interacting with Minecraft objects.
|
||||
*
|
||||
* @param computer The interface to the computer that is making the call. Remember that multiple
|
||||
* computers can be attached to a peripheral at once.
|
||||
* @param context The context of the current call.
|
||||
* @param method An integer identifying which of the methods from getMethodNames() the computercraft
|
||||
* wishes to call. The integer indicates the index into the getMethodNames() table
|
||||
* that corresponds to the string passed into peripheral.call()
|
||||
* @param arguments An array of objects, representing the arguments passed into {@code peripheral.call()}.<br>
|
||||
* Lua values of type "string" will be represented by Object type String.<br>
|
||||
* Lua values of type "number" will be represented by Object type Double.<br>
|
||||
* Lua values of type "boolean" will be represented by Object type Boolean.<br>
|
||||
* Lua values of type "table" will be represented by Object type Map.<br>
|
||||
* Lua values of any other type will be represented by a null object.<br>
|
||||
* This array will be empty if no arguments are passed.
|
||||
* @return The result of calling this method. Use {@link MethodResult#empty()} to return nothing or
|
||||
* {@link MethodResult#of(Object...)} to return several values.
|
||||
* @throws LuaException If you throw any exception from this function, a lua error will be raised with the
|
||||
* same message as your exception. Use this to throw appropriate errors if the wrong
|
||||
* arguments are supplied to your method.
|
||||
* @see #getMethodNames
|
||||
*/
|
||||
@Nonnull
|
||||
@SuppressWarnings({ "deprecation" })
|
||||
default MethodResult callMethod( @Nonnull IComputerAccess computer, @Nonnull ICallContext context, int method, @Nonnull Object[] arguments ) throws LuaException
|
||||
{
|
||||
return MethodResult.withLuaContext( lua -> callMethod( computer, lua, method, arguments ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is called when canAttachToSide has returned true, and a computer is attaching to the peripheral.
|
||||
*
|
||||
* This will occur when a peripheral is placed next to an active computer, when a computer is turned on next to a
|
||||
* peripheral, or when a turtle travels into a square next to a peripheral.
|
||||
*
|
||||
* Between calls to attach() and detach(), the attached computer can make method calls on the peripheral using
|
||||
* {@code peripheral.call()}. This method can be used to keep track of which computers are attached to the
|
||||
* peripheral, or to take action when attachment occurs.
|
||||
*
|
||||
* Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe
|
||||
* when interacting with Minecraft objects.
|
||||
*
|
||||
* @param computer The interface to the computer that is being attached. Remember that multiple
|
||||
* computers can be attached to a peripheral at once.
|
||||
* @see #detach
|
||||
*/
|
||||
default void attach( @Nonnull IComputerAccess computer )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Is called when a computer is detaching from the peripheral.
|
||||
*
|
||||
* This will occur when a computer shuts down, when the peripheral is removed while attached to computers,
|
||||
* or when a turtle moves away from a square attached to a peripheral. This method can be used to keep track of
|
||||
* which computers are attached to the peripheral, or to take action when detachment
|
||||
* occurs.
|
||||
*
|
||||
* Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe
|
||||
* when interacting with Minecraft objects.
|
||||
*
|
||||
* @param computer The interface to the computer that is being detached. Remember that multiple
|
||||
* computers can be attached to a peripheral at once.
|
||||
* @see #detach
|
||||
*/
|
||||
default void detach( @Nonnull IComputerAccess computer )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object that this peripheral provides methods for. This will generally be the tile entity
|
||||
* or block, but may be an inventory, entity, etc...
|
||||
*
|
||||
* @return The object this peripheral targets
|
||||
*/
|
||||
@Nonnull
|
||||
default Object getTarget()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether this peripheral is equivalent to another one.
|
||||
*
|
||||
* The minimal example should at least check whether they are the same object. However, you may wish to check if
|
||||
* they point to the same block or tile entity.
|
||||
*
|
||||
* @param other The peripheral to compare against. This may be {@code null}.
|
||||
* @return Whether these peripherals are equivalent.
|
||||
*/
|
||||
boolean equals( @Nullable IPeripheral other );
|
||||
}
|
||||
|
||||
@@ -1,25 +1,35 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.peripheral;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* This interface is used to create peripheral implementations for blocks
|
||||
* This interface is used to create peripheral implementations for blocks.
|
||||
*
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#registerPeripheralProvider(IPeripheralProvider)
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface IPeripheralProvider
|
||||
{
|
||||
/**
|
||||
* Produce an peripheral implementation from a block location.
|
||||
*
|
||||
* @param world The world the block is in.
|
||||
* @param pos The position the block is at.
|
||||
* @param side The side to get the peripheral from.
|
||||
* @return A peripheral, or {@code null} if there is not a peripheral here you'd like to handle.
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#registerPeripheralProvider(IPeripheralProvider)
|
||||
* @return a peripheral, or null if there is not a peripheral here you'd like to handle.
|
||||
*/
|
||||
public IPeripheral getPeripheral( World world, BlockPos pos, EnumFacing side );
|
||||
@Nullable
|
||||
IPeripheral getPeripheral( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull EnumFacing side );
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
@@ -9,12 +9,34 @@ package dan200.computercraft.api.permissions;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* This interface is used to restrict where turtles can move or build
|
||||
* This interface is used to restrict where turtles can move or build.
|
||||
*
|
||||
* Turtles will call these methods before attempting to perform an action, allowing them to be cancelled.
|
||||
*
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#registerPermissionProvider(ITurtlePermissionProvider)
|
||||
*/
|
||||
public interface ITurtlePermissionProvider
|
||||
{
|
||||
public boolean isBlockEnterable( World world, BlockPos pos );
|
||||
public boolean isBlockEditable( World world, BlockPos pos );
|
||||
/**
|
||||
* Determine whether a block can be entered by a turtle.
|
||||
*
|
||||
* @param world The world the block exists in
|
||||
* @param pos The location of the block.
|
||||
* @return Whether the turtle can move into this block.
|
||||
*/
|
||||
boolean isBlockEnterable( @Nonnull World world, @Nonnull BlockPos pos );
|
||||
|
||||
/**
|
||||
* Determine whether a block can be modified by a turtle.
|
||||
*
|
||||
* This includes breaking and placing blocks.
|
||||
*
|
||||
* @param world The world the block exists in
|
||||
* @param pos The location of the block.
|
||||
* @return Whether the turtle can modify this block.
|
||||
*/
|
||||
boolean isBlockEditable( @Nonnull World world, @Nonnull BlockPos pos );
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
@API( owner="ComputerCraft", provides="ComputerCraft|API|Permissions", apiVersion="${version}" )
|
||||
package dan200.computercraft.api.permissions;
|
||||
|
||||
import net.minecraftforge.fml.common.API;
|
||||
import net.minecraftforge.fml.common.API;
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
package dan200.computercraft.api.pocket;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Wrapper class for pocket computers
|
||||
*/
|
||||
public interface IPocketAccess
|
||||
{
|
||||
/**
|
||||
* Gets the entity holding this item.
|
||||
*
|
||||
* @return The holding entity. This may be {@code null}.
|
||||
*/
|
||||
@Nullable
|
||||
Entity getEntity();
|
||||
|
||||
/**
|
||||
* Get the colour of this pocket computer as a RGB number.
|
||||
*
|
||||
* @return The colour this pocket computer is. This will be a RGB colour between {@code 0x000000} and
|
||||
* {@code 0xFFFFFF} or -1 if it has no colour.
|
||||
* @see #setColour(int)
|
||||
*/
|
||||
int getColour();
|
||||
|
||||
/**
|
||||
* Set the colour of the pocket computer to a RGB number.
|
||||
*
|
||||
* @param colour The colour this pocket computer should be changed to. This should be a RGB colour between
|
||||
* {@code 0x000000} and {@code 0xFFFFFF} or -1 to reset to the default colour.
|
||||
* @see #getColour()
|
||||
*/
|
||||
void setColour( int colour );
|
||||
|
||||
/**
|
||||
* Get the colour of this pocket computer's light as a RGB number.
|
||||
*
|
||||
* @return The colour this light is. This will be a RGB colour between {@code 0x000000} and {@code 0xFFFFFF} or
|
||||
* -1 if it has no colour.
|
||||
* @see #setLight(int)
|
||||
*/
|
||||
int getLight();
|
||||
|
||||
/**
|
||||
* Set the colour of the pocket computer's light to a RGB number.
|
||||
*
|
||||
* @param colour The colour this modem's light will be changed to. This should be a RGB colour between
|
||||
* {@code 0x000000} and {@code 0xFFFFFF} or -1 to reset to the default colour.
|
||||
* @see #getLight()
|
||||
*/
|
||||
void setLight( int colour );
|
||||
|
||||
/**
|
||||
* Get the upgrade-specific NBT.
|
||||
*
|
||||
* This is persisted between computer reboots and chunk loads.
|
||||
*
|
||||
* @return The upgrade's NBT.
|
||||
* @see #updateUpgradeNBTData()
|
||||
*/
|
||||
@Nonnull
|
||||
NBTTagCompound getUpgradeNBTData();
|
||||
|
||||
/**
|
||||
* Mark the upgrade-specific NBT as dirty.
|
||||
*
|
||||
* @see #getUpgradeNBTData()
|
||||
*/
|
||||
void updateUpgradeNBTData();
|
||||
|
||||
/**
|
||||
* Remove the current peripheral and create a new one. You may wish to do this if the methods available change.
|
||||
*/
|
||||
void invalidatePeripheral();
|
||||
|
||||
/**
|
||||
* Get a list of all upgrades for the pocket computer.
|
||||
*
|
||||
* @return A collection of all upgrade names.
|
||||
*/
|
||||
@Nonnull
|
||||
Map<ResourceLocation, IPeripheral> getUpgrades();
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package dan200.computercraft.api.pocket;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Additional peripherals for pocket computers.
|
||||
*
|
||||
* This is similar to {@link dan200.computercraft.api.turtle.ITurtleUpgrade}.
|
||||
*/
|
||||
public interface IPocketUpgrade
|
||||
{
|
||||
|
||||
/**
|
||||
* Gets a unique identifier representing this type of turtle upgrade. eg: "computercraft:wireless_modem" or
|
||||
* "my_mod:my_upgrade".
|
||||
*
|
||||
* You should use a unique resource domain to ensure this upgrade is uniquely identified. The upgrade will fail
|
||||
* registration if an already used ID is specified.
|
||||
*
|
||||
* @return The upgrade's id.
|
||||
* @see IPocketUpgrade#getUpgradeID()
|
||||
* @see ComputerCraftAPI#registerPocketUpgrade(IPocketUpgrade)
|
||||
*/
|
||||
@Nonnull
|
||||
ResourceLocation getUpgradeID();
|
||||
|
||||
/**
|
||||
* Return an unlocalised string to describe the type of pocket computer this upgrade provides.
|
||||
*
|
||||
* An example of a built-in adjectives is "Wireless" - this is converted to "Wireless Pocket Computer".
|
||||
*
|
||||
* @return The unlocalised adjective.
|
||||
* @see ITurtleUpgrade#getUnlocalisedAdjective()
|
||||
*/
|
||||
@Nonnull
|
||||
String getUnlocalisedAdjective();
|
||||
|
||||
/**
|
||||
* Return an item stack representing the type of item that a pocket computer must be crafted with to create a
|
||||
* pocket computer which holds this upgrade. This item stack is also used to determine the upgrade given by
|
||||
* {@code pocket.equip()}/{@code pocket.unequip()}.
|
||||
*
|
||||
* @return The item stack used for crafting. This can be {@link ItemStack#EMPTY} if crafting is disabled.
|
||||
*/
|
||||
@Nonnull
|
||||
ItemStack getCraftingItem();
|
||||
|
||||
/**
|
||||
* Creates a peripheral for the pocket computer.
|
||||
*
|
||||
* The peripheral created will be stored for the lifetime of the upgrade, will be passed an argument to
|
||||
* {@link #update(IPocketAccess, IPeripheral)} and will be attached, detached and have methods called in the same
|
||||
* manner as an ordinary peripheral.
|
||||
*
|
||||
* @param access The access object for the pocket item stack.
|
||||
* @return The newly created peripheral.
|
||||
* @see #update(IPocketAccess, IPeripheral)
|
||||
*/
|
||||
@Nullable
|
||||
IPeripheral createPeripheral( @Nonnull IPocketAccess access );
|
||||
|
||||
/**
|
||||
* Called when the pocket computer item stack updates.
|
||||
*
|
||||
* @param access The access object for the pocket item stack.
|
||||
* @param peripheral The peripheral for this upgrade.
|
||||
* @see #createPeripheral(IPocketAccess)
|
||||
*/
|
||||
default void update( @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the pocket computer is right clicked.
|
||||
*
|
||||
* @param world The world the computer is in.
|
||||
* @param access The access object for the pocket item stack.
|
||||
* @param peripheral The peripheral for this upgrade.
|
||||
* @return {@code true} to stop the GUI from opening, otherwise false. You should always provide some code path
|
||||
* which returns {@code false}, such as requiring the player to be sneaking - otherwise they will be unable to
|
||||
* access the GUI.
|
||||
* @see #createPeripheral(IPocketAccess)
|
||||
*/
|
||||
default boolean onRightClick( @Nonnull World world, @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,34 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.redstone;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* This interface is used to provide bundled redstone output for blocks
|
||||
* This interface is used to provide bundled redstone output for blocks.
|
||||
*
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#registerBundledRedstoneProvider(IBundledRedstoneProvider)
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface IBundledRedstoneProvider
|
||||
{
|
||||
/**
|
||||
* Produce an bundled redstone output from a block location.
|
||||
*
|
||||
* @param world The world this block is in.
|
||||
* @param pos The position this block is at.
|
||||
* @param side The side to extract the bundled redstone output from.
|
||||
* @return A number in the range 0-65535 to indicate this block is providing output, or -1 if you do not wish to
|
||||
* handle this block.
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#registerBundledRedstoneProvider(IBundledRedstoneProvider)
|
||||
* @return a number in the range 0-65535 to indicate this block is providing output, or -1 if you do not wish to handle this block
|
||||
*/
|
||||
public int getBundledRedstoneOutput( World world, BlockPos pos, EnumFacing side );
|
||||
int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull EnumFacing side );
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,126 +1,224 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.turtle;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.lua.MethodResult;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* The interface passed to turtle by turtles, providing methods that they can call.
|
||||
* This should not be implemented by your classes. Do not interact with turtles except via this interface and ITurtleUpgrade.
|
||||
*
|
||||
* This should not be implemented by your classes. Do not interact with turtles except via this interface and
|
||||
* {@link ITurtleUpgrade}.
|
||||
*/
|
||||
public interface ITurtleAccess
|
||||
{
|
||||
/**
|
||||
* Returns the world in which the turtle resides.
|
||||
* @return the world in which the turtle resides.
|
||||
*/
|
||||
public World getWorld();
|
||||
|
||||
/**
|
||||
* Returns a vector containing the integer co-ordinates at which the turtle resides.
|
||||
* @return a vector containing the integer co-ordinates at which the turtle resides.
|
||||
*/
|
||||
public BlockPos getPosition();
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* Returns the world in which the turtle resides.
|
||||
*
|
||||
* @return the world in which the turtle resides.
|
||||
*/
|
||||
public boolean teleportTo( World world, BlockPos pos );
|
||||
|
||||
/**
|
||||
* Returns a vector containing the floating point co-ordinates at which the turtle is rendered.
|
||||
* This will shift when the turtle is moving.
|
||||
* @param f The subframe fraction
|
||||
* @return a vector containing the floating point co-ordinates at which the turtle resides.
|
||||
*/
|
||||
public Vec3d getVisualPosition( float f );
|
||||
@Nonnull
|
||||
World getWorld();
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* Returns a vector containing the integer co-ordinates at which the turtle resides.
|
||||
*
|
||||
* @return a vector containing the integer co-ordinates at which the turtle resides.
|
||||
*/
|
||||
public float getVisualYaw( float f );
|
||||
|
||||
/**
|
||||
* Returns the world direction the turtle is currently facing.
|
||||
* @return the world direction the turtle is currently facing.
|
||||
*/
|
||||
public EnumFacing getDirection();
|
||||
@Nonnull
|
||||
BlockPos getPosition();
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* Attempt to move this turtle to a new position.
|
||||
*
|
||||
* This will preserve the turtle's internal state, such as it's inventory, computer and upgrades. It should
|
||||
* be used before playing a movement animation using {@link #playAnimation(TurtleAnimation)}.
|
||||
*
|
||||
* @param world The new world to move it to
|
||||
* @param pos The new position to move it to.
|
||||
* @return Whether the movement was successful. It may fail if the block was not loaded or the block placement
|
||||
* was cancelled. Note this will not check
|
||||
* {@link dan200.computercraft.api.permissions.ITurtlePermissionProvider#isBlockEnterable(World, BlockPos)}.
|
||||
* @throws UnsupportedOperationException When attempting to teleport on the client side.
|
||||
*/
|
||||
public void setDirection( EnumFacing dir );
|
||||
boolean teleportTo( @Nonnull World world, @Nonnull BlockPos pos );
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* Returns a vector containing the floating point co-ordinates at which the turtle is rendered.
|
||||
* This will shift when the turtle is moving.
|
||||
*
|
||||
* @param f The subframe fraction.
|
||||
* @return A vector containing the floating point co-ordinates at which the turtle resides.
|
||||
* @see #getVisualYaw(float)
|
||||
*/
|
||||
public int getSelectedSlot();
|
||||
@Nonnull
|
||||
Vec3d getVisualPosition( float f );
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* Returns the yaw the turtle is facing when it is rendered.
|
||||
*
|
||||
* @param f The subframe fraction.
|
||||
* @return The yaw the turtle is facing.
|
||||
* @see #getVisualPosition(float)
|
||||
*/
|
||||
public void setSelectedSlot( int slot );
|
||||
float getVisualYaw( float f );
|
||||
|
||||
/**
|
||||
* Sets the colour of the turtle, as if the player had dyed it with a dye item.
|
||||
* @param dyeColour 0-15 to dye the turtle one of the 16 standard minecraft colours, or -1 to remove the dye from the turtle.
|
||||
* Returns the world direction the turtle is currently facing.
|
||||
*
|
||||
* @return The world direction the turtle is currently facing.
|
||||
* @see #setDirection(EnumFacing)
|
||||
*/
|
||||
public void setDyeColour( int dyeColour );
|
||||
@Nonnull
|
||||
EnumFacing getDirection();
|
||||
|
||||
/**
|
||||
* Gets the colour the turtle has been dyed.
|
||||
* @return 0-15 if the turtle has been dyed one of the 16 standard minecraft colours, -1 if the turtle is clean.
|
||||
* Set the direction the turtle is facing. Note that this will not play a rotation animation, you will also need to
|
||||
* call {@link #playAnimation(TurtleAnimation)} to do so.
|
||||
*
|
||||
* @param dir The new direction to set. This should be on either the x or z axis (so north, south, east or west).
|
||||
* @see #getDirection()
|
||||
*/
|
||||
public int getDyeColour();
|
||||
void setDirection( @Nonnull EnumFacing dir );
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* Get the currently selected slot in the turtle's inventory.
|
||||
*
|
||||
* @return An integer representing the current slot.
|
||||
* @see #getInventory()
|
||||
* @see #setSelectedSlot(int)
|
||||
*/
|
||||
public IInventory getInventory();
|
||||
int getSelectedSlot();
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* Set the currently selected slot in the turtle's inventory.
|
||||
*
|
||||
* @param slot The slot to set. This must be greater or equal to 0 and less than the inventory size. Otherwise no
|
||||
* action will be taken.
|
||||
* @throws UnsupportedOperationException When attempting to change the slot on the client side.
|
||||
* @see #getInventory()
|
||||
* @see #getSelectedSlot()
|
||||
*/
|
||||
public boolean isFuelNeeded();
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
*/
|
||||
public int getFuelLevel();
|
||||
void setSelectedSlot( int slot );
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* Set the colour of the turtle to a RGB number.
|
||||
*
|
||||
* @param colour The colour this turtle should be changed to. This should be a RGB colour between {@code 0x000000}
|
||||
* and {@code 0xFFFFFF} or -1 to reset to the default colour.
|
||||
* @see #getColour()
|
||||
*/
|
||||
public void setFuelLevel( int fuel );
|
||||
void setColour( int colour );
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* Get the colour of this turtle as a RGB number.
|
||||
*
|
||||
* @return The colour this turtle is. This will be a RGB colour between {@code 0x000000} and {@code 0xFFFFFF} or
|
||||
* -1 if it has no colour.
|
||||
* @see #setColour(int)
|
||||
*/
|
||||
public int getFuelLimit();
|
||||
int getColour();
|
||||
|
||||
/**
|
||||
* Removes some fuel from the turtles fuel supply. Negative numbers can be passed in to INCREASE the fuel level of the turtle.
|
||||
* @return Whether the turtle was able to consume the ammount of fuel specified. Will return false if you supply a number
|
||||
* greater than the current fuel level of the turtle.
|
||||
*/
|
||||
public boolean consumeFuel( int fuel );
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* Get the player who owns this turtle, namely whoever placed it.
|
||||
*
|
||||
* @return This turtle's owner.
|
||||
*/
|
||||
public void addFuel( int fuel );
|
||||
@Nonnull
|
||||
GameProfile getOwningPlayer();
|
||||
|
||||
/**
|
||||
* Get the inventory of this turtle
|
||||
*
|
||||
* @return This turtle's inventory
|
||||
* @see #getItemHandler()
|
||||
*/
|
||||
@Nonnull
|
||||
IInventory getInventory();
|
||||
|
||||
/**
|
||||
* Get the inventory of this turtle as an {@link IItemHandlerModifiable}.
|
||||
*
|
||||
* @return This turtle's inventory
|
||||
* @see #getInventory()
|
||||
* @see IItemHandlerModifiable
|
||||
* @see net.minecraftforge.items.CapabilityItemHandler#ITEM_HANDLER_CAPABILITY
|
||||
*/
|
||||
@Nonnull
|
||||
IItemHandlerModifiable getItemHandler();
|
||||
|
||||
/**
|
||||
* Determine whether this turtle will require fuel when performing actions.
|
||||
*
|
||||
* @return Whether this turtle needs fuel.
|
||||
* @see #getFuelLevel()
|
||||
* @see #setFuelLevel(int)
|
||||
*/
|
||||
boolean isFuelNeeded();
|
||||
|
||||
/**
|
||||
* Get the current fuel level of this turtle.
|
||||
*
|
||||
* @return The turtle's current fuel level.
|
||||
* @see #isFuelNeeded()
|
||||
* @see #setFuelLevel(int)
|
||||
*/
|
||||
int getFuelLevel();
|
||||
|
||||
/**
|
||||
* Set the fuel level to a new value. It is generally preferred to use {@link #consumeFuel(int)}} or {@link #addFuel(int)}
|
||||
* instead.
|
||||
*
|
||||
* @param fuel The new amount of fuel. This must be between 0 and the fuel limit.
|
||||
* @see #getFuelLevel()
|
||||
* @see #getFuelLimit()
|
||||
* @see #addFuel(int)
|
||||
* @see #consumeFuel(int)
|
||||
*/
|
||||
void setFuelLevel( int fuel );
|
||||
|
||||
/**
|
||||
* Get the maximum amount of fuel a turtle can hold.
|
||||
*
|
||||
* @return The turtle's fuel limit.
|
||||
*/
|
||||
int getFuelLimit();
|
||||
|
||||
/**
|
||||
* Removes some fuel from the turtles fuel supply. Negative numbers can be passed in to INCREASE the fuel level of the turtle.
|
||||
*
|
||||
* @param fuel The amount of fuel to consume.
|
||||
* @return Whether the turtle was able to consume the amount of fuel specified. Will return false if you supply a number
|
||||
* greater than the current fuel level of the turtle. No fuel will be consumed if {@code false} is returned.
|
||||
* @throws UnsupportedOperationException When attempting to consume fuel on the client side.
|
||||
*/
|
||||
boolean consumeFuel( int fuel );
|
||||
|
||||
/**
|
||||
* Increase the turtle's fuel level by the given amount.
|
||||
*
|
||||
* @param fuel The amount to refuel with.
|
||||
* @throws UnsupportedOperationException When attempting to refuel on the client side.
|
||||
*/
|
||||
void addFuel( int fuel );
|
||||
|
||||
/**
|
||||
* Adds a custom command to the turtles command queue. Unlike peripheral methods, these custom commands will be executed
|
||||
@@ -128,42 +226,100 @@ public interface ITurtleAccess
|
||||
* with the turtles standard movement and tool commands. An issued command will return an unique integer, which will
|
||||
* be supplied as a parameter to a "turtle_response" event issued to the turtle after the command has completed. Look at the
|
||||
* lua source code for "rom/apis/turtle" for how to build a lua wrapper around this functionality.
|
||||
* @param command an object which will execute the custom command when its point in the queue is reached
|
||||
* @return the objects the command returned when executed. you should probably return these to the player
|
||||
*
|
||||
* @param context The Lua context to pull events from.
|
||||
* @param command An object which will execute the custom command when its point in the queue is reached
|
||||
* @return The objects the command returned when executed. you should probably return these to the player
|
||||
* unchanged if called from a peripheral method.
|
||||
* @throws UnsupportedOperationException When attempting to execute a command on the client side.
|
||||
* @throws LuaException If the user presses CTRL+T to terminate the current program while {@code executeCommand()} is
|
||||
* waiting for an event, a "Terminated" exception will be thrown here.
|
||||
* @throws InterruptedException If the user shuts down or reboots the computer while pullEvent() is waiting for an
|
||||
* event, InterruptedException will be thrown. This exception must not be caught or
|
||||
* intercepted, or the computer will leak memory and end up in a broken state.
|
||||
* @see ITurtleCommand
|
||||
* @see ILuaContext#pullEvent(String)
|
||||
* @deprecated Use {@link #executeCommand(ITurtleCommand)} instead.
|
||||
*/
|
||||
public Object[] executeCommand( ILuaContext context, ITurtleCommand command ) throws LuaException, InterruptedException;
|
||||
@Nonnull
|
||||
@Deprecated
|
||||
Object[] executeCommand( @Nonnull ILuaContext context, @Nonnull ITurtleCommand command ) throws LuaException, InterruptedException;
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* Adds a custom command to the turtles command queue. Unlike peripheral methods, these custom commands will be
|
||||
* executed on the main thread, so are guaranteed to be able to access Minecraft objects safely, and will be queued
|
||||
* up with the turtles standard movement and tool commands.
|
||||
*
|
||||
* An issued command will return an unique integer, which will be supplied as a parameter to a "turtle_response"
|
||||
* event issued to the turtle after the command has completed. Look at the Lua source code for "rom/apis/turtle" for
|
||||
* how to build a Lua wrapper around this functionality.
|
||||
*
|
||||
* @param command An object which will execute the custom command when its point in the queue is reached
|
||||
* @return The constructed method result. This evaluates to the result of the provided {@code command}.
|
||||
* @throws UnsupportedOperationException When attempting to execute a command on the client side.
|
||||
* @see ITurtleCommand
|
||||
* @see MethodResult#pullEvent(String)
|
||||
*/
|
||||
public void playAnimation( TurtleAnimation animation );
|
||||
|
||||
/**
|
||||
* Returns the turtle on the specified side of the turtle, if there is one.
|
||||
* @return the turtle on the specified side of the turtle, if there is one.
|
||||
*/
|
||||
public ITurtleUpgrade getUpgrade( TurtleSide side );
|
||||
@Nonnull
|
||||
MethodResult executeCommand( @Nonnull ITurtleCommand command );
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* Start playing a specific animation. This will prevent other turtle commands from executing until
|
||||
* it is finished.
|
||||
*
|
||||
* @param animation The animation to play.
|
||||
* @throws UnsupportedOperationException When attempting to execute play an animation on the client side.
|
||||
* @see TurtleAnimation
|
||||
*/
|
||||
public void setUpgrade( TurtleSide side, ITurtleUpgrade upgrade );
|
||||
|
||||
/**
|
||||
* Returns the peripheral created by the upgrade on the specified side of the turtle, if there is one.
|
||||
* @return the peripheral created by the upgrade on the specified side of the turtle, if there is one.
|
||||
*/
|
||||
public IPeripheral getPeripheral( TurtleSide side );
|
||||
void playAnimation( @Nonnull TurtleAnimation animation );
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* Returns the turtle on the specified side of the turtle, if there is one.
|
||||
*
|
||||
* @param side The side to get the upgrade from.
|
||||
* @return The upgrade on the specified side of the turtle, if there is one.
|
||||
* @see #setUpgrade(TurtleSide, ITurtleUpgrade)
|
||||
*/
|
||||
public NBTTagCompound getUpgradeNBTData( TurtleSide side );
|
||||
@Nullable
|
||||
ITurtleUpgrade getUpgrade( @Nonnull TurtleSide side );
|
||||
|
||||
/**
|
||||
* TODO: Document me
|
||||
* Set the upgrade for a given side, resetting peripherals and clearing upgrade specific data.
|
||||
*
|
||||
* @param side The side to set the upgrade on.
|
||||
* @param upgrade The upgrade to set, may be {@code null} to clear.
|
||||
* @see #getUpgrade(TurtleSide)
|
||||
*/
|
||||
public void updateUpgradeNBTData( TurtleSide side );
|
||||
void setUpgrade( @Nonnull TurtleSide side, @Nullable ITurtleUpgrade upgrade );
|
||||
|
||||
/**
|
||||
* Returns the peripheral created by the upgrade on the specified side of the turtle, if there is one.
|
||||
*
|
||||
* @param side The side to get the peripheral from.
|
||||
* @return The peripheral created by the upgrade on the specified side of the turtle, {@code null} if none exists.
|
||||
*/
|
||||
@Nullable
|
||||
IPeripheral getPeripheral( @Nonnull TurtleSide side );
|
||||
|
||||
/**
|
||||
* Get an upgrade-specific NBT compound, which can be used to store arbitrary data.
|
||||
*
|
||||
* This will be persisted across turtle restarts and chunk loads, as well as being synced to the client. You must
|
||||
* call {@link #updateUpgradeNBTData(TurtleSide)} after modifying it.
|
||||
*
|
||||
* @param side The side to get the upgrade data for.
|
||||
* @return The upgrade-specific data.
|
||||
* @see #updateUpgradeNBTData(TurtleSide)
|
||||
*/
|
||||
@Nonnull
|
||||
NBTTagCompound getUpgradeNBTData( @Nullable TurtleSide side );
|
||||
|
||||
/**
|
||||
* Mark the upgrade-specific data as dirty on a specific side. This is required for the data to be synced to the
|
||||
* client and persisted.
|
||||
*
|
||||
* @param side The side to mark dirty.
|
||||
* @see #updateUpgradeNBTData(TurtleSide)
|
||||
*/
|
||||
void updateUpgradeNBTData( @Nonnull TurtleSide side );
|
||||
}
|
||||
|
||||
@@ -1,25 +1,36 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.turtle;
|
||||
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* An interface for objects executing custom turtle commands, used with ITurtleAccess.issueCommand
|
||||
* @see ITurtleAccess#executeCommand(dan200.computercraft.api.lua.ILuaContext,ITurtleCommand)
|
||||
* An interface for objects executing custom turtle commands, used with {@link ITurtleAccess#executeCommand(ILuaContext, ITurtleCommand)}.
|
||||
*
|
||||
* @see ITurtleAccess#executeCommand(ILuaContext, ITurtleCommand)
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ITurtleCommand
|
||||
{
|
||||
/**
|
||||
* Will be called by the turtle on the main thread when it is time to execute the custom command.
|
||||
* The handler should either perform the work of the command, and return success, or return
|
||||
* failure with an error message to indicate the command cannot be executed at this time.
|
||||
* @param turtle access to the turtle for whom the command was issued
|
||||
* @return TurtleCommandResult.success() or TurtleCommandResult.failure( errorMessage )
|
||||
* @see ITurtleAccess#executeCommand(dan200.computercraft.api.lua.ILuaContext,ITurtleCommand)
|
||||
* @see dan200.computercraft.api.turtle.TurtleCommandResult
|
||||
*/
|
||||
public TurtleCommandResult execute( ITurtleAccess turtle );
|
||||
/**
|
||||
* Will be called by the turtle on the main thread when it is time to execute the custom command.
|
||||
*
|
||||
* The handler should either perform the work of the command, and return success, or return
|
||||
* failure with an error message to indicate the command cannot be executed at this time.
|
||||
*
|
||||
* @param turtle Access to the turtle for whom the command was issued.
|
||||
* @return A result, indicating whether this action succeeded or not.
|
||||
* @see ITurtleAccess#executeCommand(ILuaContext, ITurtleCommand)
|
||||
* @see TurtleCommandResult#success()
|
||||
* @see TurtleCommandResult#failure(String)
|
||||
* @see TurtleCommandResult
|
||||
*/
|
||||
@Nonnull
|
||||
TurtleCommandResult execute( @Nonnull ITurtleAccess turtle );
|
||||
}
|
||||
|
||||
@@ -1,108 +1,149 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.turtle;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.api.turtle.event.TurtleAttackEvent;
|
||||
import dan200.computercraft.api.turtle.event.TurtleBlockEvent;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.event.entity.player.AttackEntityEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.vecmath.Matrix4f;
|
||||
|
||||
|
||||
/**
|
||||
* The primary interface for defining an update for Turtles. A turtle update
|
||||
* can either be a new tool, or a new peripheral.
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#registerTurtleUpgrade( dan200.computercraft.api.turtle.ITurtleUpgrade )
|
||||
*
|
||||
* @see ComputerCraftAPI#registerTurtleUpgrade(ITurtleUpgrade)
|
||||
*/
|
||||
public interface ITurtleUpgrade
|
||||
{
|
||||
/**
|
||||
* Gets a unique identifier representing this type of turtle upgrade. eg: "computercraft:wireless_modem" or "my_mod:my_upgrade".
|
||||
* You should use a unique resource domain to ensure this upgrade is uniquely identified.
|
||||
/**
|
||||
* Gets a unique identifier representing this type of turtle upgrade. eg: "computercraft:wireless_modem" or "my_mod:my_upgrade".
|
||||
* You should use a unique resource domain to ensure this upgrade is uniquely identified.
|
||||
* The turtle will fail registration if an already used ID is specified.
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#registerTurtleUpgrade( dan200.computercraft.api.turtle.ITurtleUpgrade )
|
||||
*/
|
||||
public ResourceLocation getUpgradeID();
|
||||
*
|
||||
* @return The unique ID for this upgrade.
|
||||
* @see ComputerCraftAPI#registerTurtleUpgrade(ITurtleUpgrade)
|
||||
*/
|
||||
@Nonnull
|
||||
ResourceLocation getUpgradeID();
|
||||
|
||||
/**
|
||||
* Gets a numerical identifier representing this type of turtle upgrade,
|
||||
* for backwards compatibility with pre-1.76 worlds. If your upgrade was
|
||||
* not released for older ComputerCraft versions, you can return -1 here.
|
||||
* The turtle will fail registration if an already used positive ID is specified.
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#registerTurtleUpgrade( dan200.computercraft.api.turtle.ITurtleUpgrade )
|
||||
*
|
||||
* @return The legacy ID, or -1 if is needed.
|
||||
* @see ComputerCraftAPI#registerTurtleUpgrade(ITurtleUpgrade)
|
||||
*/
|
||||
public int getLegacyUpgradeID();
|
||||
int getLegacyUpgradeID();
|
||||
|
||||
/**
|
||||
* Return a String to describe this type of turtle in turtle item names.
|
||||
* Examples of built-in adjectives are "Wireless", "Mining" and "Crafty".
|
||||
*/
|
||||
public String getUnlocalisedAdjective();
|
||||
|
||||
/**
|
||||
* Return whether this turtle adds a tool or a peripheral to the turtle.
|
||||
* @see TurtleUpgradeType for the differences between the two.
|
||||
*/
|
||||
public TurtleUpgradeType getType();
|
||||
|
||||
/**
|
||||
* Return an item stack representing the type of item that a turtle must be crafted
|
||||
* with to create a turtle which holds this upgrade. This item stack is also used
|
||||
* to determine the upgrade given by turtle.equip()
|
||||
*/
|
||||
public ItemStack getCraftingItem();
|
||||
* Return an unlocalised string to describe this type of turtle in turtle item names.
|
||||
*
|
||||
* Examples of built-in adjectives are "Wireless", "Mining" and "Crafty".
|
||||
*
|
||||
* @return The localisation key for this upgrade's adjective.
|
||||
*/
|
||||
@Nonnull
|
||||
String getUnlocalisedAdjective();
|
||||
|
||||
/**
|
||||
* Will only be called for peripheral upgrades. Creates a peripheral for a turtle
|
||||
* being placed using this upgrade. The peripheral created will be stored
|
||||
* for the lifetime of the upgrade, will have update() called once-per-tick, and will be
|
||||
* attached, detached and have methods called in the same manner as a Computer peripheral.
|
||||
*
|
||||
* Return whether this turtle adds a tool or a peripheral to the turtle.
|
||||
*
|
||||
* @return The type of upgrade this is.
|
||||
* @see TurtleUpgradeType for the differences between them.
|
||||
*/
|
||||
@Nonnull
|
||||
TurtleUpgradeType getType();
|
||||
|
||||
/**
|
||||
* Return an item stack representing the type of item that a turtle must be crafted
|
||||
* with to create a turtle which holds this upgrade. This item stack is also used
|
||||
* to determine the upgrade given by {@code turtle.equip()}
|
||||
*
|
||||
* @return The item stack to craft with, or {@link ItemStack#EMPTY} if it cannot be crafted.
|
||||
*/
|
||||
@Nonnull
|
||||
ItemStack getCraftingItem();
|
||||
|
||||
/**
|
||||
* Will only be called for peripheral upgrades. Creates a peripheral for a turtle being placed using this upgrade.
|
||||
*
|
||||
* The peripheral created will be stored for the lifetime of the upgrade and will be passed as an argument to
|
||||
* {@link #update(ITurtleAccess, TurtleSide)}. It will be attached, detached and have methods called in the same
|
||||
* manner as a Computer peripheral.
|
||||
*
|
||||
* @param turtle Access to the turtle that the peripheral is being created for.
|
||||
* @param side Which side of the turtle (left or right) that the upgrade resides on.
|
||||
* @return The newly created peripheral. You may return null if this upgrade is a Tool
|
||||
* and this method is not expected to be called.
|
||||
*/
|
||||
public IPeripheral createPeripheral( ITurtleAccess turtle, TurtleSide side );
|
||||
* @param side Which side of the turtle (left or right) that the upgrade resides on.
|
||||
* @return The newly created peripheral. You may return {@code null} if this upgrade is a Tool
|
||||
* and this method is not expected to be called.
|
||||
*/
|
||||
@Nullable
|
||||
IPeripheral createPeripheral( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side );
|
||||
|
||||
/**
|
||||
* Will only be called for Tool turtle. Called when turtle.dig() or turtle.attack() is called
|
||||
* by the turtle, and the tool is required to do some work.
|
||||
* @param turtle Access to the turtle that the tool resides on.
|
||||
* @param side Which side of the turtle (left or right) the tool resides on.
|
||||
* @param verb Which action (dig or attack) the turtle is being called on to perform.
|
||||
* @param direction Which world direction the action should be performed in, relative to the turtles
|
||||
* position. This will either be up, down, or the direction the turtle is facing, depending on
|
||||
* whether dig, digUp or digDown was called.
|
||||
* @return Whether the turtle was able to perform the action, and hence whether the turtle.dig()
|
||||
* or turtle.attack() lua method should return true. If true is returned, the tool will perform
|
||||
* a swinging animation. You may return null if this turtle is a Peripheral
|
||||
* and this method is not expected to be called.
|
||||
*/
|
||||
public TurtleCommandResult useTool( ITurtleAccess turtle, TurtleSide side, TurtleVerb verb, EnumFacing direction );
|
||||
/**
|
||||
* Will only be called for Tool turtle. Called when turtle.dig() or turtle.attack() is called
|
||||
* by the turtle, and the tool is required to do some work.
|
||||
*
|
||||
* Conforming implementations should fire {@link BlockEvent.BreakEvent} and {@link TurtleBlockEvent.Dig}for digging,
|
||||
* {@link AttackEntityEvent} and {@link TurtleAttackEvent} for attacking.
|
||||
*
|
||||
* @param turtle Access to the turtle that the tool resides on.
|
||||
* @param side Which side of the turtle (left or right) the tool resides on.
|
||||
* @param verb Which action (dig or attack) the turtle is being called on to perform.
|
||||
* @param direction Which world direction the action should be performed in, relative to the turtles
|
||||
* position. This will either be up, down, or the direction the turtle is facing, depending on
|
||||
* whether dig, digUp or digDown was called.
|
||||
* @return Whether the turtle was able to perform the action, and hence whether the {@code turtle.dig()}
|
||||
* or {@code turtle.attack()} lua method should return true. If true is returned, the tool will perform
|
||||
* a swinging animation. You may return {@code null} if this turtle is a Peripheral and this method is not expected
|
||||
* to be called.
|
||||
*/
|
||||
@Nonnull
|
||||
TurtleCommandResult useTool( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, @Nonnull TurtleVerb verb, @Nonnull EnumFacing direction );
|
||||
|
||||
/**
|
||||
* Called to obtain the model to be used when rendering a turtle peripheral.
|
||||
*
|
||||
* This can be obtained from {@link net.minecraft.client.renderer.ItemModelMesher#getItemModel(ItemStack)},
|
||||
* {@link net.minecraft.client.renderer.block.model.ModelManager#getModel(ModelResourceLocation)} or any other
|
||||
* source.
|
||||
*
|
||||
* @param turtle Access to the turtle that the upgrade resides on. This will be null when getting item models!
|
||||
* @param side Which side of the turtle (left or right) the upgrade resides on.
|
||||
* @return The model that you wish to be used to render your upgrade, and a transformation to apply to it. Returning a transformation of null has the same effect as the identify matrix.
|
||||
* @param side Which side of the turtle (left or right) the upgrade resides on.
|
||||
* @return The model that you wish to be used to render your upgrade, and a transformation to apply to it. Returning
|
||||
* a transformation of {@code null} has the same effect as the identify matrix.
|
||||
*/
|
||||
@SideOnly( Side.CLIENT )
|
||||
public Pair<IBakedModel, Matrix4f> getModel( ITurtleAccess turtle, TurtleSide side );
|
||||
@Nonnull
|
||||
Pair<IBakedModel, Matrix4f> getModel( @Nullable ITurtleAccess turtle, @Nonnull TurtleSide side );
|
||||
|
||||
/**
|
||||
* Called once per tick for each turtle which has the upgrade equipped.
|
||||
*
|
||||
* @param turtle Access to the turtle that the upgrade resides on.
|
||||
* @param side Which side of the turtle (left or right) the upgrade resides on.
|
||||
* @param side Which side of the turtle (left or right) the upgrade resides on.
|
||||
*/
|
||||
public void update( ITurtleAccess turtle, TurtleSide side );
|
||||
default void update( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,87 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.turtle;
|
||||
|
||||
/**
|
||||
* An animation a turtle will play between executing commands.
|
||||
*
|
||||
* Each animation takes 8 ticks to complete unless otherwise specified.
|
||||
*
|
||||
* @see ITurtleAccess#playAnimation(TurtleAnimation)
|
||||
*/
|
||||
public enum TurtleAnimation
|
||||
{
|
||||
/**
|
||||
* An animation which does nothing. This takes no time to complete.
|
||||
*
|
||||
* @see #Wait
|
||||
* @see #ShortWait
|
||||
*/
|
||||
None,
|
||||
|
||||
/**
|
||||
* Make the turtle move forward. Note that the animation starts from the block <em>behind</em> it, and
|
||||
* moves into this one.
|
||||
*/
|
||||
MoveForward,
|
||||
|
||||
/**
|
||||
* Make the turtle move backwards. Note that the animation starts from the block <em>in front</em> it, and
|
||||
* moves into this one.
|
||||
*/
|
||||
MoveBack,
|
||||
|
||||
/**
|
||||
* Make the turtle move backwards. Note that the animation starts from the block <em>above</em> it, and
|
||||
* moves into this one.
|
||||
*/
|
||||
MoveUp,
|
||||
|
||||
/**
|
||||
* Make the turtle move backwards. Note that the animation starts from the block <em>below</em> it, and
|
||||
* moves into this one.
|
||||
*/
|
||||
MoveDown,
|
||||
|
||||
/**
|
||||
* Turn the turtle to the left. Note that the animation starts with the turtle facing <em>right</em>, and
|
||||
* the turtle turns to face in the current direction.
|
||||
*/
|
||||
TurnLeft,
|
||||
|
||||
/**
|
||||
* Turn the turtle to the left. Note that the animation starts with the turtle facing <em>right</em>, and
|
||||
* the turtle turns to face in the current direction.
|
||||
*/
|
||||
TurnRight,
|
||||
|
||||
/**
|
||||
* Swing the tool on the left.
|
||||
*/
|
||||
SwingLeftTool,
|
||||
|
||||
/**
|
||||
* Swing the tool on the right.
|
||||
*/
|
||||
SwingRightTool,
|
||||
|
||||
/**
|
||||
* Wait until the animation has finished, performing no movement.
|
||||
*
|
||||
* @see #ShortWait
|
||||
* @see #None
|
||||
*/
|
||||
Wait,
|
||||
|
||||
/**
|
||||
* Wait until the animation has finished, performing no movement. This takes 4 ticks to complete.
|
||||
*
|
||||
* @see #Wait
|
||||
* @see #None
|
||||
*/
|
||||
ShortWait,
|
||||
}
|
||||
|
||||
@@ -1,22 +1,46 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.turtle;
|
||||
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Used to indicate the result of executing a turtle command.
|
||||
*
|
||||
* @see ITurtleCommand#execute(ITurtleAccess)
|
||||
* @see ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, EnumFacing)
|
||||
*/
|
||||
public final class TurtleCommandResult
|
||||
{
|
||||
private static final TurtleCommandResult s_success = new TurtleCommandResult( true, null, null );
|
||||
private static final TurtleCommandResult s_emptyFailure = new TurtleCommandResult( false, null, null );
|
||||
|
||||
/**
|
||||
* Create a successful command result with no result.
|
||||
*
|
||||
* @return A successful command result with no values.
|
||||
*/
|
||||
@Nonnull
|
||||
public static TurtleCommandResult success()
|
||||
{
|
||||
return success( null );
|
||||
}
|
||||
|
||||
public static TurtleCommandResult success( Object[] results )
|
||||
/**
|
||||
* Create a successful command result with the given result values.
|
||||
*
|
||||
* @param results The results of executing this command.
|
||||
* @return A successful command result with the given values.
|
||||
*/
|
||||
@Nonnull
|
||||
public static TurtleCommandResult success( @Nullable Object[] results )
|
||||
{
|
||||
if( results == null || results.length == 0 )
|
||||
{
|
||||
@@ -28,12 +52,25 @@ public final class TurtleCommandResult
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a failed command result with no error message.
|
||||
*
|
||||
* @return A failed command result with no message.
|
||||
*/
|
||||
@Nonnull
|
||||
public static TurtleCommandResult failure()
|
||||
{
|
||||
return failure( null );
|
||||
}
|
||||
|
||||
public static TurtleCommandResult failure( String errorMessage )
|
||||
/**
|
||||
* Create a failed command result with an error message.
|
||||
*
|
||||
* @param errorMessage The error message to provide.
|
||||
* @return A failed command result with a message.
|
||||
*/
|
||||
@Nonnull
|
||||
public static TurtleCommandResult failure( @Nullable String errorMessage )
|
||||
{
|
||||
if( errorMessage == null )
|
||||
{
|
||||
@@ -56,16 +93,33 @@ public final class TurtleCommandResult
|
||||
m_results = results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the command executed successfully.
|
||||
*
|
||||
* @return If the command was successful.
|
||||
*/
|
||||
public boolean isSuccess()
|
||||
{
|
||||
return m_success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the error message of this command result.
|
||||
*
|
||||
* @return The command's error message, or {@code null} if it was a success.
|
||||
*/
|
||||
@Nullable
|
||||
public String getErrorMessage()
|
||||
{
|
||||
return m_errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resulting values of this command result.
|
||||
*
|
||||
* @return The command's result, or {@code null} if it was a failure.
|
||||
*/
|
||||
@Nullable
|
||||
public Object[] getResults()
|
||||
{
|
||||
return m_results;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
@@ -11,13 +11,13 @@ package dan200.computercraft.api.turtle;
|
||||
*/
|
||||
public enum TurtleSide
|
||||
{
|
||||
/**
|
||||
* The turtles left side (where the pickaxe usually is on a Wireless Mining Turtle)
|
||||
*/
|
||||
Left,
|
||||
/**
|
||||
* The turtle's left side (where the pickaxe usually is on a Wireless Mining Turtle)
|
||||
*/
|
||||
Left,
|
||||
|
||||
/**
|
||||
* The turtles right side (where the modem usually is on a Wireless Mining Turtle)
|
||||
*/
|
||||
Right,
|
||||
/**
|
||||
* The turtle's right side (where the modem usually is on a Wireless Mining Turtle)
|
||||
*/
|
||||
Right,
|
||||
}
|
||||
|
||||
@@ -1,27 +1,44 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.turtle;
|
||||
|
||||
/**
|
||||
* An enum representing the two different types of turtle that an ITurtleUpgrade
|
||||
* implementation can add to a turtle.
|
||||
* @see ITurtleUpgrade
|
||||
* An enum representing the different types of turtle that an {@link ITurtleUpgrade} implementation can add to a turtle.
|
||||
*
|
||||
* @see ITurtleUpgrade#getType()
|
||||
*/
|
||||
public enum TurtleUpgradeType
|
||||
{
|
||||
/**
|
||||
* A tool is rendered as an item on the side of the turtle, and responds to the turtle.dig()
|
||||
* and turtle.attack() methods (Such as pickaxe or sword on Mining and Melee turtles).
|
||||
*/
|
||||
Tool,
|
||||
|
||||
/**
|
||||
* A peripheral adds a special peripheral which is attached to the side of the turtle,
|
||||
* and can be interacted with the peripheral API (Such as the modem on Wireless Turtles).
|
||||
*/
|
||||
Peripheral,
|
||||
/**
|
||||
* A tool is rendered as an item on the side of the turtle, and responds to the {@code turtle.dig()}
|
||||
* and {@code turtle.attack()} methods (Such as pickaxe or sword on Mining and Melee turtles).
|
||||
*/
|
||||
Tool,
|
||||
|
||||
/**
|
||||
* A peripheral adds a special peripheral which is attached to the side of the turtle,
|
||||
* and can be interacted with the {@code peripheral} API (Such as the modem on Wireless Turtles).
|
||||
*/
|
||||
Peripheral,
|
||||
|
||||
/**
|
||||
* An upgrade which provides both a tool and a peripheral. This can be used when you wish
|
||||
* your upgrade to also provide methods. For example, a pickaxe could provide methods
|
||||
* determining whether it can break the given block or not.
|
||||
*/
|
||||
Both,;
|
||||
|
||||
public boolean isTool()
|
||||
{
|
||||
return this == Tool || this == Both;
|
||||
}
|
||||
|
||||
public boolean isPeripheral()
|
||||
{
|
||||
return this == Peripheral || this == Both;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,29 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.turtle;
|
||||
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
/**
|
||||
* An enum representing the two different actions that an ITurtleUpgrade of type
|
||||
* Tool may be called on to perform by a turtle.
|
||||
* @see ITurtleUpgrade
|
||||
* @see ITurtleUpgrade#useTool
|
||||
* An enum representing the different actions that an {@link ITurtleUpgrade} of type Tool may be called on to perform by
|
||||
* a turtle.
|
||||
*
|
||||
* @see ITurtleUpgrade#getType()
|
||||
* @see ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, EnumFacing)
|
||||
*/
|
||||
public enum TurtleVerb
|
||||
{
|
||||
/**
|
||||
* The turtle called turtle.dig(), turtle.digUp() or turtle.digDown()
|
||||
*/
|
||||
Dig,
|
||||
|
||||
/**
|
||||
* The turtle called turtle.attack(), turtle.attackUp() or turtle.attackDown()
|
||||
*/
|
||||
Attack,
|
||||
/**
|
||||
* The turtle called {@code turtle.dig()}, {@code turtle.digUp()} or {@code turtle.digDown()}
|
||||
*/
|
||||
Dig,
|
||||
|
||||
/**
|
||||
* The turtle called {@code turtle.attack()}, {@code turtle.attackUp()} or {@code turtle.attackDown()}
|
||||
*/
|
||||
Attack,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.turtle.event;
|
||||
|
||||
/**
|
||||
* A basic action that a turtle may perform, as accessed by the {@code turtle} API.
|
||||
*
|
||||
* @see TurtleActionEvent
|
||||
*/
|
||||
public enum TurtleAction
|
||||
{
|
||||
/**
|
||||
* A turtle moves to a new position.
|
||||
*
|
||||
* @see TurtleBlockEvent.Move
|
||||
*/
|
||||
MOVE,
|
||||
|
||||
/**
|
||||
* A turtle turns in a specific direction.
|
||||
*/
|
||||
TURN,
|
||||
|
||||
/**
|
||||
* A turtle attempts to dig a block.
|
||||
*
|
||||
* @see TurtleBlockEvent.Dig
|
||||
*/
|
||||
DIG,
|
||||
|
||||
/**
|
||||
* A turtle attempts to place a block or item in the world.
|
||||
*
|
||||
* @see TurtleBlockEvent.Place
|
||||
*/
|
||||
PLACE,
|
||||
|
||||
/**
|
||||
* A turtle attempts to attack an entity.
|
||||
*
|
||||
* @see TurtleActionEvent
|
||||
*/
|
||||
ATTACK,
|
||||
|
||||
/**
|
||||
* Drop an item into an inventory/the world.
|
||||
*
|
||||
* @see TurtleInventoryEvent.Drop
|
||||
*/
|
||||
DROP,
|
||||
|
||||
/**
|
||||
* Suck an item from an inventory or the world.
|
||||
*
|
||||
* @see TurtleInventoryEvent.Suck
|
||||
*/
|
||||
SUCK,
|
||||
|
||||
/**
|
||||
* Refuel the turtle's fuel levels.
|
||||
*/
|
||||
REFUEL,
|
||||
|
||||
/**
|
||||
* Equip or unequip an item.
|
||||
*/
|
||||
EQUIP,
|
||||
|
||||
/**
|
||||
* Inspect a block in world
|
||||
*
|
||||
* @see TurtleBlockEvent.Inspect
|
||||
*/
|
||||
INSPECT,
|
||||
|
||||
/**
|
||||
* Gather metdata about an item in the turtle's inventory.
|
||||
*/
|
||||
INSPECT_ITEM,
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package dan200.computercraft.api.turtle.event;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.api.turtle.TurtleCommandResult;
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* An event fired when a turtle is performing a known action.
|
||||
*/
|
||||
@Cancelable
|
||||
public class TurtleActionEvent extends TurtleEvent
|
||||
{
|
||||
private final TurtleAction action;
|
||||
private String failureMessage;
|
||||
|
||||
public TurtleActionEvent( @Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action )
|
||||
{
|
||||
super( turtle );
|
||||
|
||||
Preconditions.checkNotNull( action, "action cannot be null" );
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public TurtleAction getAction()
|
||||
{
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cancellation state of this action.
|
||||
*
|
||||
* If {@code cancel} is {@code true}, this action will not be carried out.
|
||||
*
|
||||
* @param cancel The new canceled value.
|
||||
* @see TurtleCommandResult#failure()
|
||||
* @deprecated Use {@link #setCanceled(boolean, String)} instead.
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void setCanceled( boolean cancel )
|
||||
{
|
||||
setCanceled( cancel, null );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cancellation state of this action, setting a failure message if required.
|
||||
*
|
||||
* If {@code cancel} is {@code true}, this action will not be carried out.
|
||||
*
|
||||
* @param cancel The new canceled value.
|
||||
* @param failureMessage The message to return to the user explaining the failure.
|
||||
* @see TurtleCommandResult#failure(String)
|
||||
*/
|
||||
public void setCanceled( boolean cancel, @Nullable String failureMessage )
|
||||
{
|
||||
super.setCanceled( cancel );
|
||||
this.failureMessage = cancel ? failureMessage : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message with which this will fail.
|
||||
*
|
||||
* @return The failure message.
|
||||
* @see TurtleCommandResult#failure()
|
||||
* @see #setCanceled(boolean, String)
|
||||
*/
|
||||
@Nullable
|
||||
public String getFailureMessage()
|
||||
{
|
||||
return failureMessage;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.turtle.event;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.api.turtle.TurtleSide;
|
||||
import dan200.computercraft.api.turtle.TurtleVerb;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.event.entity.player.AttackEntityEvent;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Fired when a turtle attempts to attack an entity.
|
||||
*
|
||||
* This must be fired by {@link ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, EnumFacing)},
|
||||
* as the base {@code turtle.attack()} command does not fire it.
|
||||
*
|
||||
* Note that such commands should also fire {@link AttackEntityEvent}, so you do not need to listen to both.
|
||||
*
|
||||
* @see TurtleAction#ATTACK
|
||||
*/
|
||||
public class TurtleAttackEvent extends TurtlePlayerEvent
|
||||
{
|
||||
private final Entity target;
|
||||
private final ITurtleUpgrade upgrade;
|
||||
private final TurtleSide side;
|
||||
|
||||
public TurtleAttackEvent( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull Entity target, @Nonnull ITurtleUpgrade upgrade, @Nonnull TurtleSide side )
|
||||
{
|
||||
super( turtle, TurtleAction.ATTACK, player );
|
||||
Preconditions.checkNotNull( target, "target cannot be null" );
|
||||
Preconditions.checkNotNull( upgrade, "upgrade cannot be null" );
|
||||
Preconditions.checkNotNull( side, "side cannot be null" );
|
||||
this.target = target;
|
||||
this.upgrade = upgrade;
|
||||
this.side = side;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity being attacked by this turtle.
|
||||
*
|
||||
* @return The entity being attacked.
|
||||
*/
|
||||
@Nonnull
|
||||
public Entity getTarget()
|
||||
{
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the upgrade responsible for attacking.
|
||||
*
|
||||
* @return The upgrade responsible for attacking.
|
||||
*/
|
||||
@Nonnull
|
||||
public ITurtleUpgrade getUpgrade()
|
||||
{
|
||||
return upgrade;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the side the attacking upgrade is on.
|
||||
*
|
||||
* @return The upgrade's side.
|
||||
*/
|
||||
@Nonnull
|
||||
public TurtleSide getSide()
|
||||
{
|
||||
return side;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.turtle.event;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.api.turtle.TurtleSide;
|
||||
import dan200.computercraft.api.turtle.TurtleVerb;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A general event for when a turtle interacts with a block or region.
|
||||
*
|
||||
* You should generally listen to one of the sub-events instead, cancelling them where
|
||||
* appropriate.
|
||||
*
|
||||
* Note that you are not guaranteed to receive this event, if it has been cancelled by other
|
||||
* mechanisms, such as block protection systems.
|
||||
*
|
||||
* Be aware that some events (such as {@link TurtleInventoryEvent}) do not necessarily interact
|
||||
* with a block, simply objects within that block space.
|
||||
*/
|
||||
@Cancelable
|
||||
public abstract class TurtleBlockEvent extends TurtlePlayerEvent
|
||||
{
|
||||
private final World world;
|
||||
private final BlockPos pos;
|
||||
|
||||
protected TurtleBlockEvent( @Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos )
|
||||
{
|
||||
super( turtle, action, player );
|
||||
|
||||
Preconditions.checkNotNull( world, "world cannot be null" );
|
||||
Preconditions.checkNotNull( pos, "pos cannot be null" );
|
||||
this.world = world;
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the world the turtle is interacting in.
|
||||
*
|
||||
* @return The world the turtle is interacting in.
|
||||
*/
|
||||
public World getWorld()
|
||||
{
|
||||
return world;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the position the turtle is interacting with. Note that this is different
|
||||
* to {@link ITurtleAccess#getPosition()}.
|
||||
*
|
||||
* @return The position the turtle is interacting with.
|
||||
*/
|
||||
public BlockPos getPos()
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when a turtle attempts to dig a block.
|
||||
*
|
||||
* This must be fired by {@link ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, EnumFacing)},
|
||||
* as the base {@code turtle.dig()} command does not fire it.
|
||||
*
|
||||
* Note that such commands should also fire {@link BlockEvent.BreakEvent}, so you do not need to listen to both.
|
||||
*
|
||||
* @see TurtleAction#DIG
|
||||
*/
|
||||
@Cancelable
|
||||
public static class Dig extends TurtleBlockEvent
|
||||
{
|
||||
private final IBlockState block;
|
||||
private final ITurtleUpgrade upgrade;
|
||||
private final TurtleSide side;
|
||||
|
||||
public Dig( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull IBlockState block, @Nonnull ITurtleUpgrade upgrade, @Nonnull TurtleSide side )
|
||||
{
|
||||
super( turtle, TurtleAction.DIG, player, world, pos );
|
||||
|
||||
Preconditions.checkNotNull( block, "block cannot be null" );
|
||||
Preconditions.checkNotNull( upgrade, "upgrade cannot be null" );
|
||||
Preconditions.checkNotNull( side, "side cannot be null" );
|
||||
this.block = block;
|
||||
this.upgrade = upgrade;
|
||||
this.side = side;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the block which is about to be broken.
|
||||
*
|
||||
* @return The block which is going to be broken.
|
||||
*/
|
||||
@Nonnull
|
||||
public IBlockState getBlock()
|
||||
{
|
||||
return block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the upgrade doing the digging
|
||||
*
|
||||
* @return The upgrade doing the digging.
|
||||
*/
|
||||
@Nonnull
|
||||
public ITurtleUpgrade getUpgrade()
|
||||
{
|
||||
return upgrade;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the side the upgrade doing the digging is on.
|
||||
*
|
||||
* @return The upgrade's side.
|
||||
*/
|
||||
@Nonnull
|
||||
public TurtleSide getSide()
|
||||
{
|
||||
return side;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when a turtle attempts to move into a block.
|
||||
*
|
||||
* @see TurtleAction#MOVE
|
||||
*/
|
||||
@Cancelable
|
||||
public static class Move extends TurtleBlockEvent
|
||||
{
|
||||
public Move( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos )
|
||||
{
|
||||
super( turtle, TurtleAction.MOVE, player, world, pos );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when a turtle attempts to place a block in the world.
|
||||
*
|
||||
* @see TurtleAction#PLACE
|
||||
*/
|
||||
@Cancelable
|
||||
public static class Place extends TurtleBlockEvent
|
||||
{
|
||||
private final ItemStack stack;
|
||||
|
||||
public Place( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull ItemStack stack )
|
||||
{
|
||||
super( turtle, TurtleAction.PLACE, player, world, pos );
|
||||
|
||||
Preconditions.checkNotNull( stack, "stack cannot be null" );
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item stack that will be placed. This should not be modified.
|
||||
*
|
||||
* @return The item stack to be placed.
|
||||
*/
|
||||
@Nonnull
|
||||
public ItemStack getStack()
|
||||
{
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when a turtle gathers data on a block in world.
|
||||
*
|
||||
* You may prevent blocks being inspected, or add additional information to the result.
|
||||
*
|
||||
* @see TurtleAction#INSPECT
|
||||
*/
|
||||
@Cancelable
|
||||
public static class Inspect extends TurtleBlockEvent
|
||||
{
|
||||
private final IBlockState state;
|
||||
private final Map<String, Object> data;
|
||||
|
||||
public Inspect( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull IBlockState state, @Nonnull Map<String, Object> data )
|
||||
{
|
||||
super( turtle, TurtleAction.INSPECT, player, world, pos );
|
||||
|
||||
Preconditions.checkNotNull( state, "state cannot be null" );
|
||||
Preconditions.checkNotNull( data, "data cannot be null" );
|
||||
this.data = data;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the block state which is being inspected.
|
||||
*
|
||||
* @return The inspected block state.
|
||||
*/
|
||||
@Nonnull
|
||||
public IBlockState getState()
|
||||
{
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the "inspection data" from this block, which will be returned to the user.
|
||||
*
|
||||
* @return This block's inspection data.
|
||||
*/
|
||||
@Nonnull
|
||||
public Map<String, Object> getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new information to the inspection result. Note this will override fields with the same name.
|
||||
*
|
||||
* @param newData The data to add. Note all values should be convertable to Lua (see
|
||||
* {@link dan200.computercraft.api.peripheral.IPeripheral#callMethod(IComputerAccess, ILuaContext, int, Object[])}).
|
||||
*/
|
||||
public void addData( @Nonnull Map<String, ?> newData )
|
||||
{
|
||||
Preconditions.checkNotNull( newData, "newData cannot be null" );
|
||||
data.putAll( newData );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.turtle.event;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* A base class for all events concerning a turtle. This will only ever constructed and fired on the server side,
|
||||
* so sever specific methods on {@link ITurtleAccess} are safe to use.
|
||||
*
|
||||
* You should generally not need to subscribe to this event, preferring one of the more specific classes.
|
||||
*
|
||||
* @see TurtleActionEvent
|
||||
*/
|
||||
public abstract class TurtleEvent extends Event
|
||||
{
|
||||
private final ITurtleAccess turtle;
|
||||
|
||||
protected TurtleEvent( @Nonnull ITurtleAccess turtle )
|
||||
{
|
||||
Preconditions.checkNotNull( turtle, "turtle cannot be null" );
|
||||
this.turtle = turtle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the turtle which is performing this action.
|
||||
*
|
||||
* @return The access for this turtle.
|
||||
*/
|
||||
@Nonnull
|
||||
public ITurtleAccess getTurtle()
|
||||
{
|
||||
return turtle;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package dan200.computercraft.api.turtle.event;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Fired when a turtle attempts to interact with an inventory.
|
||||
*/
|
||||
@Cancelable
|
||||
public abstract class TurtleInventoryEvent extends TurtleBlockEvent
|
||||
{
|
||||
private final IItemHandler handler;
|
||||
|
||||
protected TurtleInventoryEvent( @Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nullable IItemHandler handler )
|
||||
{
|
||||
super( turtle, action, player, world, pos );
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the inventory being interacted with
|
||||
*
|
||||
* @return The inventory being interacted with, {@code null} if the item will be dropped to/sucked from the world.
|
||||
*/
|
||||
@Nullable
|
||||
public IItemHandler getItemHandler()
|
||||
{
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when a turtle attempts to suck from an inventory.
|
||||
*
|
||||
* @see TurtleAction#SUCK
|
||||
*/
|
||||
@Cancelable
|
||||
public static class Suck extends TurtleInventoryEvent
|
||||
{
|
||||
public Suck( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nullable IItemHandler handler )
|
||||
{
|
||||
super( turtle, TurtleAction.SUCK, player, world, pos, handler );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when a turtle attempts to drop an item into an inventory.
|
||||
*
|
||||
* @see TurtleAction#DROP
|
||||
*/
|
||||
@Cancelable
|
||||
public static class Drop extends TurtleInventoryEvent
|
||||
{
|
||||
private final ItemStack stack;
|
||||
|
||||
public Drop( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nullable IItemHandler handler, @Nonnull ItemStack stack )
|
||||
{
|
||||
super( turtle, TurtleAction.DROP, player, world, pos, handler );
|
||||
|
||||
Preconditions.checkNotNull( stack, "stack cannot be null" );
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* The item which will be inserted into the inventory/dropped on the ground.
|
||||
*
|
||||
* Note that this is a copy of the original stack, and so should not be modified, as that will have no effect.
|
||||
*
|
||||
* @return The item stack which will be dropped.
|
||||
*/
|
||||
public ItemStack getStack()
|
||||
{
|
||||
return stack.copy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
package dan200.computercraft.api.turtle.event;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* An action done by a turtle which is normally done by a player.
|
||||
*
|
||||
* {@link #getPlayer()} may be used to modify the player's attributes or perform permission checks.
|
||||
*/
|
||||
public abstract class TurtlePlayerEvent extends TurtleActionEvent
|
||||
{
|
||||
private final FakePlayer player;
|
||||
|
||||
protected TurtlePlayerEvent( @Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action, @Nonnull FakePlayer player )
|
||||
{
|
||||
super( turtle, action );
|
||||
|
||||
Preconditions.checkNotNull( player, "player cannot be null" );
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* A fake player, representing this turtle.
|
||||
*
|
||||
* This may be used for triggering permission checks.
|
||||
*
|
||||
* @return A {@link FakePlayer} representing this turtle.
|
||||
*/
|
||||
@Nonnull
|
||||
public FakePlayer getPlayer()
|
||||
{
|
||||
return player;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
@API(owner = "ComputerCraft", provides = "ComputerCraft|API|Turtle|Event", apiVersion = "${version}")
|
||||
package dan200.computercraft.api.turtle.event;
|
||||
|
||||
import net.minecraftforge.fml.common.API;
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of the public ComputerCraft API - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. This API may be redistributed unmodified and in full only.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. This API may be redistributed unmodified and in full only.
|
||||
* For help using the API, and posting your mods, visit the forums at computercraft.info.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,24 +1,27 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.gui;
|
||||
|
||||
import dan200.computercraft.core.terminal.TextBuffer;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import dan200.computercraft.shared.util.Palette;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.VertexBuffer;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class FixedWidthFontRenderer
|
||||
{
|
||||
public static ResourceLocation font = new ResourceLocation( "computercraft", "textures/gui/termFont.png" );
|
||||
public static ResourceLocation background = new ResourceLocation( "computercraft", "textures/gui/termBackground.png" );
|
||||
private static ResourceLocation font = new ResourceLocation( "computercraft", "textures/gui/term_font.png" );
|
||||
public static ResourceLocation background = new ResourceLocation( "computercraft", "textures/gui/term_background.png" );
|
||||
|
||||
public static int FONT_HEIGHT = 9;
|
||||
public static int FONT_WIDTH = 6;
|
||||
@@ -30,24 +33,53 @@ public class FixedWidthFontRenderer
|
||||
m_textureManager = textureManager;
|
||||
}
|
||||
|
||||
private void drawChar( VertexBuffer renderer, double x, double y, int index, int color )
|
||||
private static void greyscaleify( double[] rgb )
|
||||
{
|
||||
Arrays.fill( rgb, ( rgb[0] + rgb[1] + rgb[2] ) / 3.0f );
|
||||
}
|
||||
|
||||
private void drawChar( BufferBuilder renderer, double x, double y, int index, int color, Palette p, boolean greyscale )
|
||||
{
|
||||
int column = index % 16;
|
||||
int row = index / 16;
|
||||
Colour colour = Colour.values()[ 15 - color ];
|
||||
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).tex( (double) (column * FONT_WIDTH) / 256.0, (double) ((row + 1) * FONT_HEIGHT) / 256.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( x + FONT_WIDTH, y + FONT_HEIGHT, 0.0 ).tex( (double) ((column + 1) * FONT_WIDTH) / 256.0, (double) ((row + 1) * FONT_HEIGHT) / 256.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( x + FONT_WIDTH, y, 0.0 ).tex( (double) ((column + 1) * FONT_WIDTH) / 256.0, (double) (row * FONT_HEIGHT) / 256.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( x, y, 0.0 ).tex( (double) (column * FONT_WIDTH) / 256.0, (double) (row * FONT_HEIGHT ) / 256.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
|
||||
double[] colour = p.getColour( 15 - color );
|
||||
if(greyscale)
|
||||
{
|
||||
greyscaleify( colour );
|
||||
}
|
||||
float r = (float)colour[0];
|
||||
float g = (float)colour[1];
|
||||
float b = (float)colour[2];
|
||||
|
||||
int xStart = 1 + column * (FONT_WIDTH + 2);
|
||||
int yStart = 1 + row * (FONT_HEIGHT + 2);
|
||||
|
||||
renderer.pos( x, y, 0.0 ).tex( xStart / 256.0, yStart / 256.0 ).color( r, g, b, 1.0f ).endVertex();
|
||||
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).tex( xStart / 256.0, (yStart + FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).endVertex();
|
||||
renderer.pos( x + FONT_WIDTH, y, 0.0 ).tex( (xStart + FONT_WIDTH) / 256.0, yStart / 256.0 ).color( r, g, b, 1.0f ).endVertex();
|
||||
renderer.pos( x + FONT_WIDTH, y, 0.0 ).tex( (xStart + FONT_WIDTH) / 256.0, yStart / 256.0 ).color( r, g, b, 1.0f ).endVertex();
|
||||
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).tex( xStart / 256.0, (yStart + FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).endVertex();
|
||||
renderer.pos( x + FONT_WIDTH, y + FONT_HEIGHT, 0.0 ).tex( (xStart + FONT_WIDTH) / 256.0, (yStart + FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).endVertex();
|
||||
}
|
||||
|
||||
private void drawQuad( VertexBuffer renderer, double x, double y, int color, double width )
|
||||
private void drawQuad( BufferBuilder renderer, double x, double y, int color, double width, Palette p, boolean greyscale )
|
||||
{
|
||||
Colour colour = Colour.values()[ 15 - color ];
|
||||
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).tex( 0.0, 1.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( x + width, y + FONT_HEIGHT, 0.0 ).tex( 1.0, 1.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( x + width, y, 0.0 ).tex( 1.0, 0.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( x, y, 0.0 ).tex( 0.0, 0.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
double[] colour = p.getColour( 15 - color );
|
||||
if(greyscale)
|
||||
{
|
||||
greyscaleify( colour );
|
||||
}
|
||||
float r = (float)colour[0];
|
||||
float g = (float)colour[1];
|
||||
float b = (float)colour[2];
|
||||
|
||||
renderer.pos( x, y, 0.0 ).color( r, g, b, 1.0f ).endVertex();
|
||||
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).color( r, g, b, 1.0f ).endVertex();
|
||||
renderer.pos( x + width, y, 0.0 ).color( r, g, b, 1.0f ).endVertex();
|
||||
renderer.pos( x + width, y, 0.0 ).color( r, g, b, 1.0f ).endVertex();
|
||||
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).color( r, g, b, 1.0f ).endVertex();
|
||||
renderer.pos( x + width, y + FONT_HEIGHT, 0.0 ).color( r, g, b, 1.0f ).endVertex();
|
||||
}
|
||||
|
||||
private boolean isGreyScale( int colour )
|
||||
@@ -55,12 +87,12 @@ public class FixedWidthFontRenderer
|
||||
return (colour == 0 || colour == 15 || colour == 7 || colour == 8);
|
||||
}
|
||||
|
||||
public void drawStringBackgroundPart( int x, int y, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, boolean greyScale )
|
||||
public void drawStringBackgroundPart( int x, int y, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, boolean greyScale, Palette p )
|
||||
{
|
||||
// Draw the quads
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
VertexBuffer renderer = tessellator.getBuffer();
|
||||
renderer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR );
|
||||
BufferBuilder renderer = tessellator.getBuffer();
|
||||
renderer.begin( GL11.GL_TRIANGLES, DefaultVertexFormats.POSITION_COLOR );
|
||||
if( leftMarginSize > 0.0 )
|
||||
{
|
||||
int colour1 = "0123456789abcdef".indexOf( backgroundColour.charAt( 0 ) );
|
||||
@@ -68,7 +100,7 @@ public class FixedWidthFontRenderer
|
||||
{
|
||||
colour1 = 15;
|
||||
}
|
||||
drawQuad( renderer, x - leftMarginSize, y, colour1, leftMarginSize );
|
||||
drawQuad( renderer, x - leftMarginSize, y, colour1, leftMarginSize, p, greyScale );
|
||||
}
|
||||
if( rightMarginSize > 0.0 )
|
||||
{
|
||||
@@ -77,7 +109,7 @@ public class FixedWidthFontRenderer
|
||||
{
|
||||
colour2 = 15;
|
||||
}
|
||||
drawQuad( renderer, x + backgroundColour.length() * FONT_WIDTH, y, colour2, rightMarginSize );
|
||||
drawQuad( renderer, x + backgroundColour.length() * FONT_WIDTH, y, colour2, rightMarginSize, p, greyScale );
|
||||
}
|
||||
for( int i = 0; i < backgroundColour.length(); i++ )
|
||||
{
|
||||
@@ -86,17 +118,19 @@ public class FixedWidthFontRenderer
|
||||
{
|
||||
colour = 15;
|
||||
}
|
||||
drawQuad( renderer, x + i * FONT_WIDTH, y, colour, FONT_WIDTH );
|
||||
drawQuad( renderer, x + i * FONT_WIDTH, y, colour, FONT_WIDTH, p, greyScale );
|
||||
}
|
||||
GlStateManager.disableTexture2D();
|
||||
tessellator.draw();
|
||||
GlStateManager.enableTexture2D();
|
||||
}
|
||||
|
||||
public void drawStringTextPart( int x, int y, TextBuffer s, TextBuffer textColour, boolean greyScale )
|
||||
public void drawStringTextPart( int x, int y, TextBuffer s, TextBuffer textColour, boolean greyScale, Palette p )
|
||||
{
|
||||
// Draw the quads
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
VertexBuffer renderer = tessellator.getBuffer();
|
||||
renderer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR );
|
||||
BufferBuilder renderer = tessellator.getBuffer();
|
||||
renderer.begin( GL11.GL_TRIANGLES, DefaultVertexFormats.POSITION_TEX_COLOR );
|
||||
for( int i = 0; i < s.length(); i++ )
|
||||
{
|
||||
// Switch colour
|
||||
@@ -107,37 +141,37 @@ public class FixedWidthFontRenderer
|
||||
}
|
||||
|
||||
// Draw char
|
||||
int index = (int)s.charAt( i );
|
||||
int index = s.charAt( i );
|
||||
if( index < 0 || index > 255 )
|
||||
{
|
||||
index = (int)'?';
|
||||
index = '?';
|
||||
}
|
||||
drawChar( renderer, x + i * FONT_WIDTH, y, index, colour );
|
||||
drawChar( renderer, x + i * FONT_WIDTH, y, index, colour, p, greyScale );
|
||||
}
|
||||
tessellator.draw();
|
||||
}
|
||||
|
||||
public void drawString( TextBuffer s, int x, int y, TextBuffer textColour, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, boolean greyScale )
|
||||
public void drawString( TextBuffer s, int x, int y, TextBuffer textColour, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, boolean greyScale, Palette p )
|
||||
{
|
||||
// Draw background
|
||||
if( backgroundColour != null )
|
||||
{
|
||||
// Bind the background texture
|
||||
m_textureManager.bindTexture( background );
|
||||
// Bind the background texture
|
||||
m_textureManager.bindTexture( background );
|
||||
|
||||
// Draw the quads
|
||||
drawStringBackgroundPart( x, y, backgroundColour, leftMarginSize, rightMarginSize, greyScale );
|
||||
}
|
||||
|
||||
// Draw text
|
||||
drawStringBackgroundPart( x, y, backgroundColour, leftMarginSize, rightMarginSize, greyScale, p );
|
||||
}
|
||||
|
||||
// Draw text
|
||||
if( s != null && textColour != null )
|
||||
{
|
||||
// Bind the font texture
|
||||
m_textureManager.bindTexture( font );
|
||||
|
||||
{
|
||||
// Bind the font texture
|
||||
bindFont();
|
||||
|
||||
// Draw the quads
|
||||
drawStringTextPart( x, y, s, textColour, greyScale );
|
||||
}
|
||||
drawStringTextPart( x, y, s, textColour, greyScale, p );
|
||||
}
|
||||
}
|
||||
|
||||
public int getStringWidth(String s)
|
||||
@@ -148,4 +182,10 @@ public class FixedWidthFontRenderer
|
||||
}
|
||||
return s.length() * FONT_WIDTH;
|
||||
}
|
||||
|
||||
public void bindFont()
|
||||
{
|
||||
m_textureManager.bindTexture( font );
|
||||
GlStateManager.glTexParameteri( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
@@ -11,7 +11,6 @@ import dan200.computercraft.client.gui.widgets.WidgetTerminal;
|
||||
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.IComputer;
|
||||
import dan200.computercraft.shared.computer.core.IComputerContainer;
|
||||
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
@@ -25,16 +24,16 @@ import java.io.IOException;
|
||||
public class GuiComputer extends GuiContainer
|
||||
{
|
||||
private static final ResourceLocation background = new ResourceLocation( "computercraft", "textures/gui/corners.png" );
|
||||
private static final ResourceLocation backgroundAdvanced = new ResourceLocation( "computercraft", "textures/gui/corners2.png" );
|
||||
private static final ResourceLocation backgroundCommand = new ResourceLocation( "computercraft", "textures/gui/cornersCommand.png" );
|
||||
private static final ResourceLocation backgroundAdvanced = new ResourceLocation( "computercraft", "textures/gui/corners_advanced.png" );
|
||||
private static final ResourceLocation backgroundCommand = new ResourceLocation( "computercraft", "textures/gui/corners_command.png" );
|
||||
|
||||
private final ComputerFamily m_family;
|
||||
private final IComputer m_computer;
|
||||
private final int m_termWidth;
|
||||
private final int m_termHeight;
|
||||
private WidgetTerminal m_terminal;
|
||||
private WidgetTerminal m_terminal;
|
||||
|
||||
protected GuiComputer( Container container, ComputerFamily family, IComputer computer, int termWidth, int termHeight )
|
||||
public GuiComputer( Container container, ComputerFamily family, IComputer computer, int termWidth, int termHeight )
|
||||
{
|
||||
super( container );
|
||||
m_family = family;
|
||||
@@ -46,85 +45,78 @@ public class GuiComputer extends GuiContainer
|
||||
|
||||
public GuiComputer( TileComputer computer )
|
||||
{
|
||||
this(
|
||||
this(
|
||||
new ContainerComputer( computer ),
|
||||
computer.getFamily(),
|
||||
computer.createComputer(),
|
||||
ComputerCraft.terminalWidth_computer,
|
||||
ComputerCraft.terminalHeight_computer
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui()
|
||||
{
|
||||
super.initGui();
|
||||
Keyboard.enableRepeatEvents( true );
|
||||
super.initGui();
|
||||
Keyboard.enableRepeatEvents( true );
|
||||
|
||||
m_terminal = new WidgetTerminal( 0, 0, m_termWidth, m_termHeight, new IComputerContainer()
|
||||
{
|
||||
@Override
|
||||
public IComputer getComputer()
|
||||
{
|
||||
return m_computer;
|
||||
}
|
||||
}, 2, 2, 2, 2 );
|
||||
m_terminal = new WidgetTerminal( 0, 0, m_termWidth, m_termHeight, () -> m_computer, 2, 2, 2, 2 );
|
||||
m_terminal.setAllowFocusLoss( false );
|
||||
xSize = m_terminal.getWidth() + 24;
|
||||
ySize = m_terminal.getHeight() + 24;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuiClosed()
|
||||
{
|
||||
super.onGuiClosed();
|
||||
super.onGuiClosed();
|
||||
Keyboard.enableRepeatEvents( false );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesGuiPauseGame()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public boolean doesGuiPauseGame()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateScreen()
|
||||
{
|
||||
super.updateScreen();
|
||||
m_terminal.update();
|
||||
super.updateScreen();
|
||||
m_terminal.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
protected void keyTyped(char c, int k) throws IOException
|
||||
{
|
||||
if( k == 1 )
|
||||
{
|
||||
super.keyTyped( c, k );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_terminal.keyTyped( c, k );
|
||||
}
|
||||
if( k == 1 )
|
||||
{
|
||||
super.keyTyped( c, k );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_terminal.keyTyped( c, k );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
protected void mouseClicked( int x, int y, int button )
|
||||
{
|
||||
int startX = (width - m_terminal.getWidth()) / 2;
|
||||
int startY = (height - m_terminal.getHeight()) / 2;
|
||||
m_terminal.mouseClicked( x - startX, y - startY, button );
|
||||
m_terminal.mouseClicked( x - startX, y - startY, button );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public void handleMouseInput() throws IOException
|
||||
{
|
||||
super.handleMouseInput();
|
||||
super.handleMouseInput();
|
||||
|
||||
int x = Mouse.getEventX() * width / mc.displayWidth;
|
||||
int y = height - Mouse.getEventY() * height / mc.displayHeight - 1;
|
||||
int startX = (width - m_terminal.getWidth()) / 2;
|
||||
int startY = (height - m_terminal.getHeight()) / 2;
|
||||
m_terminal.handleMouseInput( x - startX, y - startY );
|
||||
m_terminal.handleMouseInput( x - startX, y - startY );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -134,17 +126,17 @@ public class GuiComputer extends GuiContainer
|
||||
m_terminal.handleKeyboardInput();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
protected void drawGuiContainerForegroundLayer(int par1, int par2)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
protected void drawGuiContainerBackgroundLayer( float var1, int var2, int var3 )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public void drawScreen( int mouseX, int mouseY, float f )
|
||||
{
|
||||
// Work out where to draw
|
||||
@@ -153,14 +145,14 @@ public class GuiComputer extends GuiContainer
|
||||
int endX = startX + m_terminal.getWidth();
|
||||
int endY = startY + m_terminal.getHeight();
|
||||
|
||||
// Draw background
|
||||
drawDefaultBackground();
|
||||
// Draw background
|
||||
drawDefaultBackground();
|
||||
|
||||
// Draw terminal
|
||||
// Draw terminal
|
||||
m_terminal.draw( this.mc, startX, startY, mouseX, mouseY );
|
||||
|
||||
// Draw a border around the terminal
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
|
||||
// Draw a border around the terminal
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
switch( m_family )
|
||||
{
|
||||
case Normal:
|
||||
@@ -181,15 +173,15 @@ public class GuiComputer extends GuiContainer
|
||||
}
|
||||
}
|
||||
|
||||
drawTexturedModalRect(startX - 12, startY - 12, 12, 28, 12, 12);
|
||||
drawTexturedModalRect(startX - 12, endY, 12, 40, 12, 16);
|
||||
drawTexturedModalRect(endX, startY - 12, 24, 28, 12, 12);
|
||||
drawTexturedModalRect(endX, endY, 24, 40, 12, 16);
|
||||
drawTexturedModalRect(startX - 12, startY - 12, 12, 28, 12, 12);
|
||||
drawTexturedModalRect(startX - 12, endY, 12, 40, 12, 16);
|
||||
drawTexturedModalRect(endX, startY - 12, 24, 28, 12, 12);
|
||||
drawTexturedModalRect(endX, endY, 24, 40, 12, 16);
|
||||
|
||||
drawTexturedModalRect(startX, startY-12, 0, 0, endX - startX, 12);
|
||||
drawTexturedModalRect(startX, endY, 0, 12, endX - startX, 16);
|
||||
drawTexturedModalRect(startX, startY-12, 0, 0, endX - startX, 12);
|
||||
drawTexturedModalRect(startX, endY, 0, 12, endX - startX, 16);
|
||||
|
||||
drawTexturedModalRect(startX-12, startY, 0, 28, 12, endY - startY);
|
||||
drawTexturedModalRect(endX, startY, 36, 28, 12, endY - startY);
|
||||
}
|
||||
drawTexturedModalRect(startX-12, startY, 0, 28, 12, endY - startY);
|
||||
drawTexturedModalRect(endX, startY, 36, 28, 12, endY - startY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package dan200.computercraft.client.gui;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraftforge.common.config.ConfigElement;
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
import net.minecraftforge.common.config.Property;
|
||||
import net.minecraftforge.fml.client.IModGuiFactory;
|
||||
import net.minecraftforge.fml.client.config.GuiConfig;
|
||||
import net.minecraftforge.fml.client.config.IConfigElement;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class GuiConfigCC extends GuiConfig
|
||||
{
|
||||
public GuiConfigCC( GuiScreen parentScreen )
|
||||
{
|
||||
super( parentScreen, getConfigElements(), ComputerCraft.MOD_ID, false, false, "CC: Tweaked" );
|
||||
}
|
||||
|
||||
private static List<IConfigElement> getConfigElements()
|
||||
{
|
||||
ArrayList<IConfigElement> elements = new ArrayList<>();
|
||||
for (Property property : ComputerCraft.Config.config.getCategory( Configuration.CATEGORY_GENERAL ).getOrderedValues())
|
||||
{
|
||||
elements.add( new ConfigElement( property ) );
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
public static class Factory
|
||||
implements IModGuiFactory
|
||||
{
|
||||
|
||||
@Override
|
||||
public void initialize( Minecraft minecraft )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasConfigGui()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuiScreen createConfigGui( GuiScreen parentScreen )
|
||||
{
|
||||
return new GuiConfigCC( parentScreen );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<RuntimeOptionCategoryElement> runtimeGuiCategories()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
@@ -30,8 +30,8 @@ public class GuiDiskDrive extends GuiContainer
|
||||
protected void drawGuiContainerForegroundLayer(int par1, int par2)
|
||||
{
|
||||
String title = m_diskDrive.getDisplayName().getUnformattedText();
|
||||
fontRendererObj.drawString( title, (xSize - fontRendererObj.getStringWidth(title)) / 2, 6, 0x404040 );
|
||||
fontRendererObj.drawString( I18n.format("container.inventory"), 8, (ySize - 96) + 2, 0x404040 );
|
||||
fontRenderer.drawString( title, (xSize - fontRenderer.getStringWidth(title)) / 2, 6, 0x404040 );
|
||||
fontRenderer.drawString( I18n.format("container.inventory"), 8, (ySize - 96) + 2, 0x404040 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -43,4 +43,12 @@ public class GuiDiskDrive extends GuiContainer
|
||||
int i1 = (height - ySize) / 2;
|
||||
drawTexturedModalRect(l, i1, 0, 0, xSize, ySize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawScreen( int mouseX, int mouseY, float partialTicks)
|
||||
{
|
||||
drawDefaultBackground();
|
||||
super.drawScreen(mouseX, mouseY, partialTicks);
|
||||
renderHoveredToolTip(mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
@@ -32,8 +32,8 @@ public class GuiPrinter extends GuiContainer
|
||||
protected void drawGuiContainerForegroundLayer(int par1, int par2)
|
||||
{
|
||||
String title = m_printer.getDisplayName().getUnformattedText();
|
||||
fontRendererObj.drawString( title, (xSize - fontRendererObj.getStringWidth(title)) / 2, 6, 0x404040 );
|
||||
fontRendererObj.drawString( I18n.format("container.inventory"), 8, (ySize - 96) + 2, 0x404040 );
|
||||
fontRenderer.drawString( title, (xSize - fontRenderer.getStringWidth(title)) / 2, 6, 0x404040 );
|
||||
fontRenderer.drawString( I18n.format("container.inventory"), 8, (ySize - 96) + 2, 0x404040 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,7 +48,15 @@ public class GuiPrinter extends GuiContainer
|
||||
boolean printing = m_container.isPrinting();
|
||||
if( printing )
|
||||
{
|
||||
drawTexturedModalRect(startX + 34, startY + 21, 176, 0, 25, 45);
|
||||
drawTexturedModalRect(startX + 34, startY + 21, 176, 0, 25, 45);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawScreen( int mouseX, int mouseY, float partialTicks)
|
||||
{
|
||||
drawDefaultBackground();
|
||||
super.drawScreen(mouseX, mouseY, partialTicks);
|
||||
renderHoveredToolTip(mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,127 +1,104 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.gui;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.core.terminal.TextBuffer;
|
||||
import dan200.computercraft.shared.media.inventory.ContainerHeldItem;
|
||||
import dan200.computercraft.shared.media.items.ItemPrintout;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import org.lwjgl.input.Mouse;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static dan200.computercraft.client.render.PrintoutRenderer.*;
|
||||
|
||||
public class GuiPrintout extends GuiContainer
|
||||
{
|
||||
private static final ResourceLocation background = new ResourceLocation( "computercraft", "textures/gui/printout.png" );
|
||||
|
||||
private static final int xSize = 172;
|
||||
private static final int ySize = 209;
|
||||
|
||||
private final boolean m_book;
|
||||
private final int m_pages;
|
||||
private final TextBuffer[] m_text;
|
||||
private final TextBuffer[] m_colours;
|
||||
private int m_page;
|
||||
private final boolean m_book;
|
||||
private final int m_pages;
|
||||
private final TextBuffer[] m_text;
|
||||
private final TextBuffer[] m_colours;
|
||||
private int m_page;
|
||||
|
||||
public GuiPrintout( ContainerHeldItem container )
|
||||
{
|
||||
super( container );
|
||||
m_book = (ItemPrintout.getType( container.getStack() ) == ItemPrintout.Type.Book);
|
||||
|
||||
String[] text = ItemPrintout.getText( container.getStack() );
|
||||
m_text = new TextBuffer[ text.length ];
|
||||
for( int i=0; i<m_text.length; ++i )
|
||||
{
|
||||
m_text[i] = new TextBuffer( text[i] );
|
||||
}
|
||||
String[] colours = ItemPrintout.getColours( container.getStack() );
|
||||
m_colours = new TextBuffer[ colours.length ];
|
||||
for( int i=0; i<m_colours.length; ++i )
|
||||
{
|
||||
m_colours[i] = new TextBuffer( colours[i] );
|
||||
}
|
||||
m_text = new TextBuffer[ text.length ];
|
||||
for( int i = 0; i < m_text.length; ++i ) m_text[ i ] = new TextBuffer( text[ i ] );
|
||||
|
||||
m_pages = Math.max( m_text.length / ItemPrintout.LINES_PER_PAGE, 1 );
|
||||
m_page = 0;
|
||||
}
|
||||
String[] colours = ItemPrintout.getColours( container.getStack() );
|
||||
m_colours = new TextBuffer[ colours.length ];
|
||||
for( int i = 0; i < m_colours.length; ++i ) m_colours[ i ] = new TextBuffer( colours[ i ] );
|
||||
|
||||
m_page = 0;
|
||||
m_pages = Math.max( m_text.length / ItemPrintout.LINES_PER_PAGE, 1 );
|
||||
m_book = ItemPrintout.getType( container.getStack() ) == ItemPrintout.Type.Book;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui()
|
||||
{
|
||||
super.initGui();
|
||||
}
|
||||
super.initGui();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuiClosed()
|
||||
{
|
||||
super.onGuiClosed();
|
||||
super.onGuiClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesGuiPauseGame()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public boolean doesGuiPauseGame()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateScreen()
|
||||
{
|
||||
super.updateScreen();
|
||||
super.updateScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void keyTyped(char c, int k) throws IOException
|
||||
protected void keyTyped( char c, int k ) throws IOException
|
||||
{
|
||||
super.keyTyped( c, k );
|
||||
super.keyTyped( c, k );
|
||||
|
||||
if( k == 205 )
|
||||
{
|
||||
// Right
|
||||
if( m_page < m_pages - 1 )
|
||||
{
|
||||
m_page = m_page + 1;
|
||||
}
|
||||
}
|
||||
else if( k == 203 )
|
||||
{
|
||||
// Left
|
||||
if( m_page > 0 )
|
||||
{
|
||||
m_page = m_page - 1;
|
||||
}
|
||||
}
|
||||
if( k == 205 )
|
||||
{
|
||||
// Right
|
||||
if( m_page < m_pages - 1 ) m_page++;
|
||||
}
|
||||
else if( k == 203 )
|
||||
{
|
||||
// Left
|
||||
if( m_page > 0 ) m_page--;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMouseInput() throws IOException
|
||||
{
|
||||
super.handleMouseInput();
|
||||
super.handleMouseInput();
|
||||
|
||||
int mouseWheelChange = Mouse.getEventDWheel();
|
||||
if (mouseWheelChange < 0)
|
||||
{
|
||||
// Up
|
||||
if( m_page < m_pages - 1 )
|
||||
{
|
||||
m_page = m_page + 1;
|
||||
}
|
||||
}
|
||||
else if (mouseWheelChange > 0)
|
||||
{
|
||||
// Down
|
||||
if( m_page > 0 )
|
||||
{
|
||||
m_page = m_page - 1;
|
||||
}
|
||||
}
|
||||
int mouseWheelChange = Mouse.getEventDWheel();
|
||||
if( mouseWheelChange < 0 )
|
||||
{
|
||||
// Up
|
||||
if( m_page < m_pages - 1 ) m_page++;
|
||||
}
|
||||
else if( mouseWheelChange > 0 )
|
||||
{
|
||||
// Down
|
||||
if( m_page > 0 ) m_page--;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -135,78 +112,20 @@ public class GuiPrintout extends GuiContainer
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawScreen(int mouseX, int mouseY, float f)
|
||||
public void drawScreen( int mouseX, int mouseY, float f )
|
||||
{
|
||||
// Draw background
|
||||
drawDefaultBackground();
|
||||
|
||||
// Draw the printout
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
this.mc.getTextureManager().bindTexture( background );
|
||||
|
||||
int startY = (height - ySize) / 2;
|
||||
//int startX = (width - xSize) / 2 - (m_page * 8);
|
||||
int startX = (width - (xSize + (m_pages - 1)*8)) / 2;
|
||||
|
||||
if( m_book )
|
||||
{
|
||||
// Border
|
||||
drawTexturedModalRect( startX - 8, startY - 8, xSize + 48, 0, 12, ySize + 24);
|
||||
drawTexturedModalRect( startX + xSize + (m_pages - 1)*8 - 4, startY - 8, xSize + 48 + 12, 0, 12, ySize + 24);
|
||||
|
||||
drawTexturedModalRect( startX, startY - 8, 0, ySize, xSize, 12);
|
||||
drawTexturedModalRect( startX, startY + ySize - 4, 0, ySize + 12, xSize, 12);
|
||||
for( int n=1; n<m_pages; ++n )
|
||||
{
|
||||
drawTexturedModalRect( startX + xSize + (n-1)*8, startY - 8, 0, ySize, 8, 12);
|
||||
drawTexturedModalRect( startX + xSize + (n-1)*8, startY + ySize - 4, 0, ySize + 12, 8, 12);
|
||||
}
|
||||
}
|
||||
|
||||
// Left half
|
||||
if( m_page == 0 )
|
||||
{
|
||||
drawTexturedModalRect( startX, startY, 24, 0, xSize / 2, ySize);
|
||||
drawTexturedModalRect( startX, startY, 0, 0, 12, ySize);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawTexturedModalRect( startX, startY, 0, 0, 12, ySize);
|
||||
for( int n=1; n<m_page; ++n )
|
||||
{
|
||||
drawTexturedModalRect( startX + n*8, startY, 12, 0, 12, ySize);
|
||||
}
|
||||
drawTexturedModalRect( startX + m_page*8, startY, 24, 0, xSize / 2, ySize);
|
||||
}
|
||||
|
||||
// Right half
|
||||
if( m_page == (m_pages - 1) )
|
||||
{
|
||||
drawTexturedModalRect( startX + m_page*8 + xSize/2, startY, 24 + xSize / 2, 0, xSize / 2, ySize);
|
||||
drawTexturedModalRect( startX + m_page*8 + (xSize - 12), startY, 24 + xSize + 12, 0, 12, ySize);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawTexturedModalRect( startX + (m_pages - 1)*8 + (xSize - 12), startY, 24 + xSize + 12, 0, 12, ySize);
|
||||
for( int n=m_pages-2; n>=m_page; --n )
|
||||
{
|
||||
drawTexturedModalRect( startX + n*8 + (xSize - 12), startY, 24 + xSize, 0, 12, ySize);
|
||||
}
|
||||
drawTexturedModalRect( startX + m_page*8 + xSize/2, startY, 24 + xSize / 2, 0, xSize / 2, ySize);
|
||||
}
|
||||
// Draw background
|
||||
zLevel = zLevel - 1;
|
||||
drawDefaultBackground();
|
||||
zLevel = zLevel + 1;
|
||||
|
||||
// Draw the text
|
||||
FixedWidthFontRenderer fontRenderer = (FixedWidthFontRenderer)ComputerCraft.getFixedWidthFontRenderer();
|
||||
int x = startX + m_page * 8 + 13;
|
||||
int y = startY + 11;
|
||||
for( int line=0; line<ItemPrintout.LINES_PER_PAGE; ++line )
|
||||
{
|
||||
int lineIdx = ItemPrintout.LINES_PER_PAGE * m_page + line;
|
||||
if( lineIdx >= 0 && lineIdx < m_text.length )
|
||||
{
|
||||
fontRenderer.drawString( m_text[lineIdx], x, y, m_colours[lineIdx], null, 0, 0, false );
|
||||
}
|
||||
y = y + FixedWidthFontRenderer.FONT_HEIGHT;
|
||||
}
|
||||
}
|
||||
// Draw the printout
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
|
||||
int startY = (height - Y_SIZE) / 2;
|
||||
int startX = (width - X_SIZE) / 2;
|
||||
|
||||
drawBorder( startX, startY, zLevel, m_page, m_pages, m_book );
|
||||
drawText( startX + X_TEXT_MARGIN, startY + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * m_page, m_text, m_colours );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
@@ -11,7 +11,6 @@ import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.IComputer;
|
||||
import dan200.computercraft.shared.computer.core.IComputerContainer;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
|
||||
import net.minecraft.client.Minecraft;
|
||||
@@ -28,10 +27,10 @@ import java.io.IOException;
|
||||
public class GuiTurtle extends GuiContainer
|
||||
{
|
||||
private static final ResourceLocation background = new ResourceLocation( "computercraft", "textures/gui/turtle.png" );
|
||||
private static final ResourceLocation backgroundAdvanced = new ResourceLocation( "computercraft", "textures/gui/turtle2.png" );
|
||||
private static final ResourceLocation backgroundAdvanced = new ResourceLocation( "computercraft", "textures/gui/turtle_advanced.png" );
|
||||
|
||||
protected World m_world;
|
||||
protected ContainerTurtle m_container;
|
||||
protected World m_world;
|
||||
protected ContainerTurtle m_container;
|
||||
|
||||
protected final ComputerFamily m_family;
|
||||
protected final ITurtleAccess m_turtle;
|
||||
@@ -40,15 +39,15 @@ public class GuiTurtle extends GuiContainer
|
||||
|
||||
public GuiTurtle( World world, InventoryPlayer inventoryplayer, TileTurtle turtle )
|
||||
{
|
||||
this( world, turtle, new ContainerTurtle( inventoryplayer, turtle.getAccess() ) );
|
||||
this( world, turtle, new ContainerTurtle( inventoryplayer, turtle.getAccess() ) );
|
||||
}
|
||||
|
||||
protected GuiTurtle( World world, TileTurtle turtle, ContainerTurtle container )
|
||||
{
|
||||
super( container );
|
||||
super( container );
|
||||
|
||||
m_world = world;
|
||||
m_container = container;
|
||||
m_world = world;
|
||||
m_container = container;
|
||||
m_family = turtle.getFamily();
|
||||
m_turtle = turtle.getAccess();
|
||||
m_computer = turtle.createComputer();
|
||||
@@ -60,67 +59,60 @@ public class GuiTurtle extends GuiContainer
|
||||
@Override
|
||||
public void initGui()
|
||||
{
|
||||
super.initGui();
|
||||
Keyboard.enableRepeatEvents(true);
|
||||
m_terminalGui = new WidgetTerminal(
|
||||
super.initGui();
|
||||
Keyboard.enableRepeatEvents(true);
|
||||
m_terminalGui = new WidgetTerminal(
|
||||
( width - xSize ) / 2 + 8,
|
||||
( height - ySize ) / 2 + 8,
|
||||
ComputerCraft.terminalWidth_turtle,
|
||||
ComputerCraft.terminalHeight_turtle,
|
||||
new IComputerContainer()
|
||||
{
|
||||
@Override
|
||||
public IComputer getComputer()
|
||||
{
|
||||
return m_computer;
|
||||
}
|
||||
},
|
||||
() -> m_computer,
|
||||
2, 2, 2, 2
|
||||
);
|
||||
m_terminalGui.setAllowFocusLoss( false );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuiClosed()
|
||||
{
|
||||
super.onGuiClosed();
|
||||
super.onGuiClosed();
|
||||
Keyboard.enableRepeatEvents(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateScreen()
|
||||
{
|
||||
super.updateScreen();
|
||||
m_terminalGui.update();
|
||||
super.updateScreen();
|
||||
m_terminalGui.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void keyTyped(char c, int k) throws IOException
|
||||
{
|
||||
if( k == 1 )
|
||||
{
|
||||
super.keyTyped( c, k );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_terminalGui.keyTyped( c, k );
|
||||
}
|
||||
if( k == 1 )
|
||||
{
|
||||
super.keyTyped( c, k );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_terminalGui.keyTyped( c, k );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
protected void mouseClicked(int x, int y, int button) throws IOException
|
||||
{
|
||||
super.mouseClicked( x, y, button );
|
||||
m_terminalGui.mouseClicked( x, y, button );
|
||||
super.mouseClicked( x, y, button );
|
||||
m_terminalGui.mouseClicked( x, y, button );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@Override
|
||||
public void handleMouseInput() throws IOException
|
||||
{
|
||||
super.handleMouseInput();
|
||||
super.handleMouseInput();
|
||||
int x = Mouse.getEventX() * this.width / mc.displayWidth;
|
||||
int y = this.height - Mouse.getEventY() * this.height / mc.displayHeight - 1;
|
||||
m_terminalGui.handleMouseInput( x, y );
|
||||
m_terminalGui.handleMouseInput( x, y );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -135,32 +127,40 @@ public class GuiTurtle extends GuiContainer
|
||||
int x = (width - xSize) / 2;
|
||||
int y = (height - ySize) / 2;
|
||||
|
||||
// Draw selection slot
|
||||
int slot = m_container.getSelectedSlot();
|
||||
if( slot >= 0 )
|
||||
{
|
||||
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
|
||||
int slotX = (slot%4);
|
||||
int slotY = (slot/4);
|
||||
this.mc.getTextureManager().bindTexture( advanced ? backgroundAdvanced : background );
|
||||
drawTexturedModalRect(x + m_container.m_turtleInvStartX - 2 + slotX * 18, y + m_container.m_playerInvStartY - 2 + slotY * 18, 0, 217, 24, 24);
|
||||
}
|
||||
// Draw selection slot
|
||||
int slot = m_container.getSelectedSlot();
|
||||
if( slot >= 0 )
|
||||
{
|
||||
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
|
||||
int slotX = (slot%4);
|
||||
int slotY = (slot/4);
|
||||
this.mc.getTextureManager().bindTexture( advanced ? backgroundAdvanced : background );
|
||||
drawTexturedModalRect(x + m_container.m_turtleInvStartX - 2 + slotX * 18, y + m_container.m_playerInvStartY - 2 + slotY * 18, 0, 217, 24, 24);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
protected void drawGuiContainerBackgroundLayer( float f, int mouseX, int mouseY )
|
||||
{
|
||||
// Draw term
|
||||
// Draw term
|
||||
boolean advanced = (m_family == ComputerFamily.Advanced);
|
||||
m_terminalGui.draw( Minecraft.getMinecraft(), 0, 0, mouseX, mouseY );
|
||||
|
||||
// Draw border/inventory
|
||||
m_terminalGui.draw( Minecraft.getMinecraft(), 0, 0, mouseX, mouseY );
|
||||
|
||||
// Draw border/inventory
|
||||
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
|
||||
this.mc.getTextureManager().bindTexture( advanced ? backgroundAdvanced : background );
|
||||
this.mc.getTextureManager().bindTexture( advanced ? backgroundAdvanced : background );
|
||||
int x = (width - xSize) / 2;
|
||||
int y = (height - ySize) / 2;
|
||||
drawTexturedModalRect(x, y, 0, 0, xSize, ySize);
|
||||
|
||||
drawSelectionSlot( advanced );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawScreen( int mouseX, int mouseY, float partialTicks)
|
||||
{
|
||||
drawDefaultBackground();
|
||||
super.drawScreen(mouseX, mouseY, partialTicks);
|
||||
renderHoveredToolTip(mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.gui.widgets;
|
||||
|
||||
public class MousePos
|
||||
{
|
||||
public int x;
|
||||
public int y;
|
||||
|
||||
public MousePos( int x, int y )
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,22 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.gui.widgets;
|
||||
|
||||
import dan200.computercraftedu.client.gui.widgets.MousePos;
|
||||
import dan200.computercraftedu.client.gui.widgets.WidgetContainer;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.audio.PositionedSoundRecord;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.renderer.*;
|
||||
import net.minecraft.client.renderer.RenderItem;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public abstract class Widget extends Gui
|
||||
{
|
||||
@@ -178,10 +175,10 @@ public abstract class Widget extends Gui
|
||||
{
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
tessellator.getBuffer().begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX );
|
||||
tessellator.getBuffer().pos( (double) ( x + 0 ), (double) ( y + h ), (double) this.zLevel ).tex( 0.0, 1.0 ).endVertex();
|
||||
tessellator.getBuffer().pos( (double) ( x + w ), (double) ( y + h ), (double) this.zLevel ).tex( 1.0, 1.0 ).endVertex();
|
||||
tessellator.getBuffer().pos( (double) ( x + w ), (double) ( y + 0 ), (double) this.zLevel ).tex( 1.0, 0.0 ).endVertex();
|
||||
tessellator.getBuffer().pos( (double) ( x + 0 ), (double) ( y + 0 ), (double) this.zLevel ).tex( 0.0, 0.0 ).endVertex();
|
||||
tessellator.getBuffer().pos( x + 0, y + h, this.zLevel ).tex( 0.0, 1.0 ).endVertex();
|
||||
tessellator.getBuffer().pos( x + w, y + h, this.zLevel ).tex( 1.0, 1.0 ).endVertex();
|
||||
tessellator.getBuffer().pos( x + w, y + 0, this.zLevel ).tex( 1.0, 0.0 ).endVertex();
|
||||
tessellator.getBuffer().pos( x + 0, y + 0, this.zLevel ).tex( 0.0, 0.0 ).endVertex();
|
||||
tessellator.draw();
|
||||
}
|
||||
|
||||
@@ -268,12 +265,11 @@ public abstract class Widget extends Gui
|
||||
protected void drawTooltip( String[] lines, int x, int y )
|
||||
{
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
FontRenderer fontRenderer = mc.fontRendererObj;
|
||||
FontRenderer fontRenderer = mc.fontRenderer;
|
||||
|
||||
int width = 0;
|
||||
for( int i=0; i<lines.length; ++i )
|
||||
for( String line : lines )
|
||||
{
|
||||
String line = lines[i];
|
||||
width = Math.max( fontRenderer.getStringWidth( line ), width );
|
||||
}
|
||||
int startX = x + 12;
|
||||
@@ -328,9 +324,9 @@ public abstract class Widget extends Gui
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawItemStack( int x, int y, ItemStack stack )
|
||||
protected void drawItemStack( int x, int y, @Nonnull ItemStack stack )
|
||||
{
|
||||
if( stack != null )
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
GlStateManager.enableLighting();
|
||||
@@ -344,7 +340,7 @@ public abstract class Widget extends Gui
|
||||
if( renderItem != null )
|
||||
{
|
||||
renderItem.renderItemAndEffectIntoGUI( stack, x, y );
|
||||
renderItem.renderItemOverlayIntoGUI( mc.fontRendererObj, stack, x, y, null );
|
||||
renderItem.renderItemOverlayIntoGUI( mc.fontRenderer, stack, x, y, null );
|
||||
}
|
||||
}
|
||||
finally
|
||||
@@ -364,7 +360,7 @@ public abstract class Widget extends Gui
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
try
|
||||
{
|
||||
mc.fontRendererObj.drawString( s, x, y, color );
|
||||
mc.fontRenderer.drawString( s, x, y, color );
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -375,7 +371,7 @@ public abstract class Widget extends Gui
|
||||
protected int getStringWidth( String s )
|
||||
{
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
return mc.fontRendererObj.getStringWidth( s );
|
||||
return mc.fontRenderer.getStringWidth( s );
|
||||
}
|
||||
|
||||
protected void playClickSound()
|
||||
|
||||
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
|
||||
package dan200.computercraft.client.gui.widgets;
|
||||
|
||||
import dan200.computercraft.client.gui.widgets.Widget;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class WidgetContainer extends Widget
|
||||
{
|
||||
private ArrayList<Widget> m_widgets;
|
||||
private Widget m_modalWidget;
|
||||
|
||||
public WidgetContainer( int x, int y, int w, int h )
|
||||
{
|
||||
super( x, y, w, h );
|
||||
m_widgets = new ArrayList<>();
|
||||
m_modalWidget = null;
|
||||
}
|
||||
|
||||
public void addWidget( Widget widget )
|
||||
{
|
||||
m_widgets.add( widget );
|
||||
widget.setParent( this );
|
||||
}
|
||||
|
||||
public void setModalWidget( Widget widget )
|
||||
{
|
||||
m_modalWidget = widget;
|
||||
if( widget != null )
|
||||
{
|
||||
widget.setParent( this );
|
||||
}
|
||||
}
|
||||
|
||||
public Widget getModalWidget()
|
||||
{
|
||||
return m_modalWidget;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
for( Widget m_widget : m_widgets )
|
||||
{
|
||||
m_widget.update();
|
||||
}
|
||||
if( m_modalWidget != null )
|
||||
{
|
||||
m_modalWidget.update();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw( Minecraft mc, int xOrigin, int yOrigin, int mouseX, int mouseY )
|
||||
{
|
||||
for( Widget widget : m_widgets )
|
||||
{
|
||||
if( widget.isVisible() )
|
||||
{
|
||||
widget.draw(
|
||||
mc,
|
||||
xOrigin + getXPosition(),
|
||||
yOrigin + getYPosition(),
|
||||
(m_modalWidget == null) ? (mouseX - getXPosition()) : -99,
|
||||
(m_modalWidget == null) ? (mouseY - getYPosition()) : -99
|
||||
);
|
||||
}
|
||||
}
|
||||
if( m_modalWidget != null )
|
||||
{
|
||||
if( m_modalWidget.isVisible() )
|
||||
{
|
||||
GlStateManager.pushMatrix();
|
||||
try
|
||||
{
|
||||
GlStateManager.translate( 0.0f, 0.0f, 200.0f );
|
||||
m_modalWidget.draw(
|
||||
mc,
|
||||
xOrigin + getXPosition(),
|
||||
yOrigin + getYPosition(),
|
||||
mouseX - getXPosition(),
|
||||
mouseY - getYPosition()
|
||||
);
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawForeground( Minecraft mc, int xOrigin, int yOrigin, int mouseX, int mouseY )
|
||||
{
|
||||
for( Widget widget : m_widgets )
|
||||
{
|
||||
if( widget.isVisible() )
|
||||
{
|
||||
widget.drawForeground(
|
||||
mc,
|
||||
xOrigin + getXPosition(),
|
||||
yOrigin + getYPosition(),
|
||||
(m_modalWidget == null) ? (mouseX - getXPosition()) : -99,
|
||||
(m_modalWidget == null) ? (mouseY - getYPosition()) : -99
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if( m_modalWidget != null )
|
||||
{
|
||||
if( m_modalWidget.isVisible() )
|
||||
{
|
||||
GlStateManager.pushMatrix();
|
||||
try
|
||||
{
|
||||
GlStateManager.translate( 0.0f, 0.0f, 200.0f );
|
||||
m_modalWidget.drawForeground(
|
||||
mc,
|
||||
xOrigin + getXPosition(),
|
||||
yOrigin + getYPosition(),
|
||||
mouseX - getXPosition(),
|
||||
mouseY - getYPosition()
|
||||
);
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifyMousePosition( MousePos pos )
|
||||
{
|
||||
pos.x -= getXPosition();
|
||||
pos.y -= getYPosition();
|
||||
if( m_modalWidget == null )
|
||||
{
|
||||
for( Widget widget : m_widgets )
|
||||
{
|
||||
if( widget.isVisible() )
|
||||
{
|
||||
widget.modifyMousePosition( pos );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_modalWidget.isVisible() )
|
||||
{
|
||||
m_modalWidget.modifyMousePosition( pos );
|
||||
}
|
||||
}
|
||||
pos.x += getXPosition();
|
||||
pos.y += getYPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean suppressItemTooltips( Minecraft mc, int xOrigin, int yOrigin, int mouseX, int mouseY )
|
||||
{
|
||||
if( m_modalWidget == null )
|
||||
{
|
||||
for( Widget widget : m_widgets )
|
||||
{
|
||||
if( widget.isVisible() )
|
||||
{
|
||||
if( widget.suppressItemTooltips(
|
||||
mc,
|
||||
xOrigin + getXPosition(),
|
||||
yOrigin + getYPosition(),
|
||||
mouseX - getXPosition(),
|
||||
mouseY - getYPosition()
|
||||
) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_modalWidget.isVisible() && m_modalWidget.suppressItemTooltips(
|
||||
mc,
|
||||
xOrigin + getXPosition(),
|
||||
yOrigin + getYPosition(),
|
||||
mouseX - getXPosition(),
|
||||
mouseY - getYPosition()
|
||||
) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean suppressKeyPress( char c, int k )
|
||||
{
|
||||
if( m_modalWidget == null )
|
||||
{
|
||||
for( Widget widget : m_widgets )
|
||||
{
|
||||
if( widget.isVisible() )
|
||||
{
|
||||
if( widget.suppressKeyPress( c, k ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_modalWidget.isVisible() )
|
||||
{
|
||||
if( m_modalWidget.suppressKeyPress( c, k ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMouseInput( int mouseX, int mouseY )
|
||||
{
|
||||
if( m_modalWidget == null )
|
||||
{
|
||||
for( Widget widget : m_widgets )
|
||||
{
|
||||
if( widget.isVisible() )
|
||||
{
|
||||
widget.handleMouseInput(
|
||||
mouseX - getXPosition(),
|
||||
mouseY - getYPosition()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_modalWidget.isVisible() )
|
||||
{
|
||||
m_modalWidget.handleMouseInput(
|
||||
mouseX - getXPosition(),
|
||||
mouseY - getYPosition()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleKeyboardInput()
|
||||
{
|
||||
if( m_modalWidget == null )
|
||||
{
|
||||
for( Widget widget : m_widgets )
|
||||
{
|
||||
if( widget.isVisible() )
|
||||
{
|
||||
widget.handleKeyboardInput();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_modalWidget.isVisible() )
|
||||
{
|
||||
m_modalWidget.handleKeyboardInput();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked( int mouseX, int mouseY, int mouseButton )
|
||||
{
|
||||
if( m_modalWidget == null )
|
||||
{
|
||||
for( Widget widget : m_widgets )
|
||||
{
|
||||
if( widget.isVisible() )
|
||||
{
|
||||
widget.mouseClicked(
|
||||
mouseX - getXPosition(),
|
||||
mouseY - getYPosition(),
|
||||
mouseButton
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_modalWidget.isVisible() )
|
||||
{
|
||||
m_modalWidget.mouseClicked(
|
||||
mouseX - getXPosition(),
|
||||
mouseY - getYPosition(),
|
||||
mouseButton
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped( char c, int k )
|
||||
{
|
||||
if( m_modalWidget == null )
|
||||
{
|
||||
for( Widget widget : m_widgets )
|
||||
{
|
||||
if( widget.isVisible() )
|
||||
{
|
||||
widget.keyTyped( c, k );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_modalWidget.isVisible() )
|
||||
{
|
||||
m_modalWidget.keyTyped( c, k );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
@@ -13,6 +13,7 @@ import dan200.computercraft.core.terminal.TextBuffer;
|
||||
import dan200.computercraft.shared.computer.core.IComputer;
|
||||
import dan200.computercraft.shared.computer.core.IComputerContainer;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import dan200.computercraft.shared.util.Palette;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
@@ -25,18 +26,18 @@ import java.util.ArrayList;
|
||||
|
||||
public class WidgetTerminal extends Widget
|
||||
{
|
||||
private static final ResourceLocation background = new ResourceLocation( "computercraft", "textures/gui/termBackground.png" );
|
||||
private static final ResourceLocation background = new ResourceLocation( "computercraft", "textures/gui/term_background.png" );
|
||||
private static float TERMINATE_TIME = 0.5f;
|
||||
|
||||
private IComputerContainer m_computer;
|
||||
private final IComputerContainer m_computer;
|
||||
|
||||
private float m_terminateTimer;
|
||||
private float m_rebootTimer;
|
||||
private float m_shutdownTimer;
|
||||
|
||||
private int m_lastClickButton;
|
||||
private int m_lastClickX;
|
||||
private int m_lastClickY;
|
||||
private int m_lastClickButton;
|
||||
private int m_lastClickX;
|
||||
private int m_lastClickY;
|
||||
|
||||
private boolean m_focus;
|
||||
private boolean m_allowFocusLoss;
|
||||
@@ -75,7 +76,7 @@ public class WidgetTerminal extends Widget
|
||||
m_topMargin = topMargin;
|
||||
m_bottomMargin = bottomMargin;
|
||||
|
||||
m_keysDown = new ArrayList<Integer>();
|
||||
m_keysDown = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void setAllowFocusLoss( boolean allowFocusLoss )
|
||||
@@ -167,9 +168,9 @@ public class WidgetTerminal extends Widget
|
||||
@Override
|
||||
public void mouseClicked( int mouseX, int mouseY, int button )
|
||||
{
|
||||
if( mouseX >= getXPosition() && mouseX < getXPosition() + getWidth() &&
|
||||
mouseY >= getYPosition() && mouseY < getYPosition() + getHeight() )
|
||||
{
|
||||
if( mouseX >= getXPosition() && mouseX < getXPosition() + getWidth() &&
|
||||
mouseY >= getYPosition() && mouseY < getYPosition() + getHeight() )
|
||||
{
|
||||
if( !m_focus && button == 0)
|
||||
{
|
||||
m_focus = true;
|
||||
@@ -198,7 +199,7 @@ public class WidgetTerminal extends Widget
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_focus && button == 0 && m_allowFocusLoss )
|
||||
@@ -229,8 +230,8 @@ public class WidgetTerminal extends Widget
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMouseInput( int mouseX, int mouseY )
|
||||
{
|
||||
public void handleMouseInput( int mouseX, int mouseY )
|
||||
{
|
||||
IComputer computer = m_computer.getComputer();
|
||||
if( mouseX >= getXPosition() && mouseX < getXPosition() + getWidth() &&
|
||||
mouseY >= getYPosition() && mouseY < getYPosition() + getHeight() &&
|
||||
@@ -287,159 +288,160 @@ public class WidgetTerminal extends Widget
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
{
|
||||
// Handle special keys
|
||||
if( m_focus && !m_locked && (Keyboard.isKeyDown( 29 ) || Keyboard.isKeyDown( 157 )) )
|
||||
{
|
||||
// Ctrl+T for terminate
|
||||
if( Keyboard.isKeyDown( 20 ) )
|
||||
{
|
||||
if( m_terminateTimer < TERMINATE_TIME )
|
||||
{
|
||||
m_terminateTimer = m_terminateTimer + 0.05f;
|
||||
if( m_terminateTimer >= TERMINATE_TIME )
|
||||
{
|
||||
if( m_focus && !m_locked && (Keyboard.isKeyDown( 29 ) || Keyboard.isKeyDown( 157 )) )
|
||||
{
|
||||
// Ctrl+T for terminate
|
||||
if( Keyboard.isKeyDown( 20 ) )
|
||||
{
|
||||
if( m_terminateTimer < TERMINATE_TIME )
|
||||
{
|
||||
m_terminateTimer = m_terminateTimer + 0.05f;
|
||||
if( m_terminateTimer >= TERMINATE_TIME )
|
||||
{
|
||||
queueEvent( "terminate" );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_terminateTimer = 0.0f;
|
||||
}
|
||||
|
||||
// Ctrl+R for reboot
|
||||
if( Keyboard.isKeyDown(19) )
|
||||
{
|
||||
if( m_rebootTimer < TERMINATE_TIME )
|
||||
{
|
||||
m_rebootTimer = m_rebootTimer + 0.05f;
|
||||
if( m_rebootTimer >= TERMINATE_TIME )
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_terminateTimer = 0.0f;
|
||||
}
|
||||
|
||||
// Ctrl+R for reboot
|
||||
if( Keyboard.isKeyDown(19) )
|
||||
{
|
||||
if( m_rebootTimer < TERMINATE_TIME )
|
||||
{
|
||||
m_rebootTimer = m_rebootTimer + 0.05f;
|
||||
if( m_rebootTimer >= TERMINATE_TIME )
|
||||
{
|
||||
IComputer computer = m_computer.getComputer();
|
||||
if( computer != null )
|
||||
{
|
||||
if( computer != null )
|
||||
{
|
||||
computer.reboot();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rebootTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rebootTimer = 0.0f;
|
||||
}
|
||||
|
||||
// Ctrl+S for shutdown
|
||||
if( Keyboard.isKeyDown(31) )
|
||||
{
|
||||
if( m_shutdownTimer < TERMINATE_TIME )
|
||||
{
|
||||
m_shutdownTimer = m_shutdownTimer + 0.05f;
|
||||
if( m_shutdownTimer >= TERMINATE_TIME )
|
||||
{
|
||||
// Ctrl+S for shutdown
|
||||
if( Keyboard.isKeyDown(31) )
|
||||
{
|
||||
if( m_shutdownTimer < TERMINATE_TIME )
|
||||
{
|
||||
m_shutdownTimer = m_shutdownTimer + 0.05f;
|
||||
if( m_shutdownTimer >= TERMINATE_TIME )
|
||||
{
|
||||
IComputer computer = m_computer.getComputer();
|
||||
if( computer != null )
|
||||
{
|
||||
computer.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_shutdownTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_terminateTimer = 0.0f;
|
||||
m_rebootTimer = 0.0f;
|
||||
m_shutdownTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_shutdownTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_terminateTimer = 0.0f;
|
||||
m_rebootTimer = 0.0f;
|
||||
m_shutdownTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw( Minecraft mc, int xOrigin, int yOrigin, int mouseX, int mouseY )
|
||||
{
|
||||
int startX = xOrigin + getXPosition();
|
||||
int startY = yOrigin + getYPosition();
|
||||
int startX = xOrigin + getXPosition();
|
||||
int startY = yOrigin + getYPosition();
|
||||
|
||||
// Draw the screen contents
|
||||
IComputer computer = m_computer.getComputer();
|
||||
Terminal terminal = (computer != null) ? computer.getTerminal() : null;
|
||||
if( terminal != null )
|
||||
{
|
||||
// Draw the terminal
|
||||
boolean greyscale = !computer.isColour();
|
||||
synchronized( terminal )
|
||||
{
|
||||
// Get the data from the terminal first
|
||||
// Unfortunately we have to keep the lock for the whole of drawing, so the text doesn't change under us.
|
||||
FixedWidthFontRenderer fontRenderer = (FixedWidthFontRenderer)ComputerCraft.getFixedWidthFontRenderer();
|
||||
boolean tblink = m_focus && terminal.getCursorBlink() && ComputerCraft.getGlobalCursorBlink();
|
||||
int tw = terminal.getWidth();
|
||||
int th = terminal.getHeight();
|
||||
int tx = terminal.getCursorX();
|
||||
int ty = terminal.getCursorY();
|
||||
|
||||
int x = startX + m_leftMargin;
|
||||
int y = startY + m_topMargin;
|
||||
synchronized( m_computer )
|
||||
{
|
||||
// Draw the screen contents
|
||||
IComputer computer = m_computer.getComputer();
|
||||
Terminal terminal = ( computer != null ) ? computer.getTerminal() : null;
|
||||
if( terminal != null )
|
||||
{
|
||||
// Draw the terminal
|
||||
boolean greyscale = !computer.isColour();
|
||||
|
||||
Palette palette = terminal.getPalette();
|
||||
|
||||
// Get the data from the terminal first
|
||||
// Unfortunately we have to keep the lock for the whole of drawing, so the text doesn't change under us.
|
||||
FixedWidthFontRenderer fontRenderer = (FixedWidthFontRenderer) ComputerCraft.getFixedWidthFontRenderer();
|
||||
boolean tblink = m_focus && terminal.getCursorBlink() && ComputerCraft.getGlobalCursorBlink();
|
||||
int tw = terminal.getWidth();
|
||||
int th = terminal.getHeight();
|
||||
int tx = terminal.getCursorX();
|
||||
int ty = terminal.getCursorY();
|
||||
|
||||
int x = startX + m_leftMargin;
|
||||
int y = startY + m_topMargin;
|
||||
|
||||
// Draw margins
|
||||
TextBuffer emptyLine = new TextBuffer( ' ', tw );
|
||||
TextBuffer emptyLine = new TextBuffer( ' ', tw );
|
||||
if( m_topMargin > 0 )
|
||||
{
|
||||
fontRenderer.drawString( emptyLine, x, startY, terminal.getTextColourLine( 0 ), terminal.getBackgroundColourLine( 0 ), m_leftMargin, m_rightMargin, greyscale );
|
||||
fontRenderer.drawString( emptyLine, x, startY, terminal.getTextColourLine( 0 ), terminal.getBackgroundColourLine( 0 ), m_leftMargin, m_rightMargin, greyscale, palette );
|
||||
}
|
||||
if( m_bottomMargin > 0 )
|
||||
{
|
||||
fontRenderer.drawString( emptyLine, x, startY + 2 * m_bottomMargin + ( th - 1 ) * FixedWidthFontRenderer.FONT_HEIGHT, terminal.getTextColourLine( th - 1 ), terminal.getBackgroundColourLine( th - 1 ), m_leftMargin, m_rightMargin, greyscale );
|
||||
fontRenderer.drawString( emptyLine, x, startY + 2 * m_bottomMargin + ( th - 1 ) * FixedWidthFontRenderer.FONT_HEIGHT, terminal.getTextColourLine( th - 1 ), terminal.getBackgroundColourLine( th - 1 ), m_leftMargin, m_rightMargin, greyscale, palette );
|
||||
}
|
||||
|
||||
// Draw lines
|
||||
for( int line=0; line<th; ++line )
|
||||
{
|
||||
TextBuffer text = terminal.getLine(line);
|
||||
for( int line = 0; line < th; ++line )
|
||||
{
|
||||
TextBuffer text = terminal.getLine( line );
|
||||
TextBuffer colour = terminal.getTextColourLine( line );
|
||||
TextBuffer backgroundColour = terminal.getBackgroundColourLine( line );
|
||||
fontRenderer.drawString( text, x, y, colour, backgroundColour, m_leftMargin, m_rightMargin, greyscale );
|
||||
if( tblink && ty == line )
|
||||
{
|
||||
if( tx >= 0 && tx < tw )
|
||||
{
|
||||
TextBuffer cursor = new TextBuffer( '_', 1 );
|
||||
TextBuffer cursorColour = new TextBuffer( "0123456789abcdef".charAt( terminal.getTextColour() ), 1 );
|
||||
fontRenderer.drawString(
|
||||
cursor,
|
||||
x + FixedWidthFontRenderer.FONT_WIDTH * tx,
|
||||
y,
|
||||
cursorColour, null,
|
||||
0, 0,
|
||||
greyscale
|
||||
);
|
||||
}
|
||||
}
|
||||
y = y + FixedWidthFontRenderer.FONT_HEIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw a black background
|
||||
mc.getTextureManager().bindTexture( background );
|
||||
Colour black = Colour.Black;
|
||||
GlStateManager.color( black.getR(), black.getG(), black.getB(), 1.0f );
|
||||
try
|
||||
fontRenderer.drawString( text, x, y, colour, backgroundColour, m_leftMargin, m_rightMargin, greyscale, palette );
|
||||
y += FixedWidthFontRenderer.FONT_HEIGHT;
|
||||
}
|
||||
|
||||
if( tblink && tx >= 0 && ty >= 0 && tx < tw && ty < th )
|
||||
{
|
||||
TextBuffer cursor = new TextBuffer( '_', 1 );
|
||||
TextBuffer cursorColour = new TextBuffer( "0123456789abcdef".charAt( terminal.getTextColour() ), 1 );
|
||||
|
||||
fontRenderer.drawString(
|
||||
cursor,
|
||||
x + FixedWidthFontRenderer.FONT_WIDTH * tx,
|
||||
startY + m_topMargin + FixedWidthFontRenderer.FONT_HEIGHT * ty,
|
||||
cursorColour, null,
|
||||
0, 0,
|
||||
greyscale,
|
||||
palette
|
||||
);
|
||||
}
|
||||
} else
|
||||
{
|
||||
drawTexturedModalRect( startX, startY, 0, 0, getWidth(), getHeight() );
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
// Draw a black background
|
||||
mc.getTextureManager().bindTexture( background );
|
||||
Colour black = Colour.Black;
|
||||
GlStateManager.color( black.getR(), black.getG(), black.getB(), 1.0f );
|
||||
try
|
||||
{
|
||||
drawTexturedModalRect( startX, startY, 0, 0, getWidth(), getHeight() );
|
||||
} finally
|
||||
{
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,86 +1,98 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.proxy;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.client.render.TileEntityTurtleRenderer;
|
||||
import dan200.computercraft.client.render.TurtleSmartItemModel;
|
||||
import dan200.computercraft.shared.proxy.CCTurtleProxyCommon;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||
import dan200.computercraft.shared.turtle.core.TurtleBrain;
|
||||
import dan200.computercraft.shared.turtle.items.ItemTurtleBase;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.ItemMeshDefinition;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.block.model.ModelBakery;
|
||||
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.color.IItemColor;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.client.resources.IResourceManager;
|
||||
import net.minecraft.client.resources.SimpleReloadableResourceManager;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.event.ModelBakeEvent;
|
||||
import net.minecraftforge.client.event.ModelRegistryEvent;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
import net.minecraftforge.client.model.IModel;
|
||||
import net.minecraftforge.client.model.ModelLoader;
|
||||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class CCTurtleProxyClient extends CCTurtleProxyCommon
|
||||
{
|
||||
public CCTurtleProxyClient()
|
||||
{
|
||||
}
|
||||
|
||||
// IComputerCraftProxy implementation
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
// IComputerCraftProxy implementation
|
||||
|
||||
@Override
|
||||
public void preInit()
|
||||
{
|
||||
super.preInit();
|
||||
|
||||
// Setup client forge handlers
|
||||
registerForgeHandlers();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void registerModels( ModelRegistryEvent event )
|
||||
{
|
||||
// Register item models
|
||||
ItemMeshDefinition turtleMeshDefinition = new ItemMeshDefinition()
|
||||
{
|
||||
private ModelResourceLocation turtle_dynamic = new ModelResourceLocation( "computercraft:turtle_dynamic", "inventory" );
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ModelResourceLocation getModelLocation( ItemStack stack )
|
||||
public ModelResourceLocation getModelLocation( @Nonnull ItemStack stack )
|
||||
{
|
||||
return turtle_dynamic;
|
||||
}
|
||||
};
|
||||
String[] turtleModelNames = new String[] {
|
||||
"turtle_dynamic",
|
||||
"CC-Turtle", "CC-TurtleAdvanced",
|
||||
"turtle_black", "turtle_red", "turtle_green", "turtle_brown",
|
||||
"turtle_blue", "turtle_purple", "turtle_cyan", "turtle_lightGrey",
|
||||
"turtle_grey", "turtle_pink", "turtle_lime", "turtle_yellow",
|
||||
"turtle_lightBlue", "turtle_magenta", "turtle_orange", "turtle_white",
|
||||
"turtle", "turtle_advanced",
|
||||
"turtle_white",
|
||||
"turtle_elf_overlay"
|
||||
};
|
||||
registerItemModel( ComputerCraft.Blocks.turtle, turtleMeshDefinition, turtleModelNames );
|
||||
registerItemModel( ComputerCraft.Blocks.turtleExpanded, turtleMeshDefinition, turtleModelNames );
|
||||
registerItemModel( ComputerCraft.Blocks.turtleAdvanced, turtleMeshDefinition, turtleModelNames );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
|
||||
// Setup turtle colours
|
||||
Minecraft.getMinecraft().getItemColors().registerItemColorHandler(
|
||||
new TurtleItemColour(),
|
||||
ComputerCraft.Blocks.turtle, ComputerCraft.Blocks.turtleExpanded, ComputerCraft.Blocks.turtleAdvanced
|
||||
);
|
||||
|
||||
// Setup renderers
|
||||
ClientRegistry.bindTileEntitySpecialRenderer( TileTurtle.class, new TileEntityTurtleRenderer() );
|
||||
|
||||
// Setup client forge handlers
|
||||
registerForgeHandlers();
|
||||
}
|
||||
}
|
||||
|
||||
private void registerItemModel( Block block, ItemMeshDefinition definition, String[] names )
|
||||
{
|
||||
@@ -95,17 +107,32 @@ public class CCTurtleProxyClient extends CCTurtleProxyCommon
|
||||
resources[i] = new ResourceLocation( "computercraft:" + names[i] );
|
||||
}
|
||||
ModelBakery.registerItemVariants( item, resources );
|
||||
Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register( item, definition );
|
||||
ModelLoader.setCustomMeshDefinition( item, definition );
|
||||
}
|
||||
|
||||
private void registerForgeHandlers()
|
||||
{
|
||||
private void registerForgeHandlers()
|
||||
{
|
||||
ForgeHandlers handlers = new ForgeHandlers();
|
||||
MinecraftForge.EVENT_BUS.register( handlers );
|
||||
}
|
||||
}
|
||||
|
||||
public class ForgeHandlers
|
||||
public static class ForgeHandlers
|
||||
{
|
||||
private static final String[] TURTLE_UPGRADES = {
|
||||
"turtle_modem_off_left",
|
||||
"turtle_modem_on_left",
|
||||
"turtle_modem_off_right",
|
||||
"turtle_modem_on_right",
|
||||
"turtle_crafting_table_left",
|
||||
"turtle_crafting_table_right",
|
||||
"advanced_turtle_modem_off_left",
|
||||
"advanced_turtle_modem_on_left",
|
||||
"advanced_turtle_modem_off_right",
|
||||
"advanced_turtle_modem_on_right",
|
||||
"turtle_speaker_upgrade_left",
|
||||
"turtle_speaker_upgrade_right",
|
||||
};
|
||||
|
||||
private TurtleSmartItemModel m_turtleSmartItemModel;
|
||||
|
||||
public ForgeHandlers()
|
||||
@@ -131,22 +158,27 @@ public class CCTurtleProxyClient extends CCTurtleProxyCommon
|
||||
@SubscribeEvent
|
||||
public void onTextureStitchEvent( TextureStitchEvent.Pre event )
|
||||
{
|
||||
event.getMap().registerSprite( new ResourceLocation( "computercraft", "blocks/craftyUpgrade" ) );
|
||||
// Load all textures for upgrades
|
||||
TextureMap map = event.getMap();
|
||||
for( String upgrade : TURTLE_UPGRADES )
|
||||
{
|
||||
IModel model = ModelLoaderRegistry.getModelOrMissing( new ResourceLocation( "computercraft", "block/" + upgrade ) );
|
||||
for( ResourceLocation texture : model.getTextures() )
|
||||
{
|
||||
map.registerSprite( texture );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onModelBakeEvent( ModelBakeEvent event )
|
||||
{
|
||||
loadModel( event, "turtle_modem_off_left" );
|
||||
loadModel( event, "turtle_modem_on_left" );
|
||||
loadModel( event, "turtle_modem_off_right" );
|
||||
loadModel( event, "turtle_modem_on_right" );
|
||||
loadModel( event, "turtle_crafting_table_left" );
|
||||
loadModel( event, "turtle_crafting_table_right" );
|
||||
loadModel( event, "advanced_turtle_modem_off_left" );
|
||||
loadModel( event, "advanced_turtle_modem_on_left" );
|
||||
loadModel( event, "advanced_turtle_modem_off_right" );
|
||||
loadModel( event, "advanced_turtle_modem_on_right" );
|
||||
// Load all upgrade models
|
||||
for( String upgrade : TURTLE_UPGRADES )
|
||||
{
|
||||
loadModel( event, upgrade );
|
||||
}
|
||||
|
||||
loadSmartModel( event, "turtle_dynamic", m_turtleSmartItemModel );
|
||||
}
|
||||
|
||||
@@ -158,14 +190,7 @@ public class CCTurtleProxyClient extends CCTurtleProxyCommon
|
||||
IBakedModel bakedModel = model.bake(
|
||||
model.getDefaultState(),
|
||||
DefaultVertexFormats.ITEM,
|
||||
new Function<ResourceLocation, TextureAtlasSprite>()
|
||||
{
|
||||
@Override
|
||||
public TextureAtlasSprite apply( ResourceLocation location )
|
||||
{
|
||||
return Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite( location.toString() );
|
||||
}
|
||||
}
|
||||
location -> Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite( location.toString() )
|
||||
);
|
||||
event.getModelRegistry().putObject(
|
||||
new ModelResourceLocation( "computercraft:" + name, "inventory" ),
|
||||
@@ -181,4 +206,20 @@ public class CCTurtleProxyClient extends CCTurtleProxyCommon
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static class TurtleItemColour implements IItemColor
|
||||
{
|
||||
@Override
|
||||
public int colorMultiplier( @Nonnull ItemStack stack, int tintIndex )
|
||||
{
|
||||
if( tintIndex == 0 )
|
||||
{
|
||||
ItemTurtleBase turtle = (ItemTurtleBase) stack.getItem();
|
||||
int colour = turtle.getColour( stack );
|
||||
if( colour != -1 ) return colour;
|
||||
}
|
||||
|
||||
return 0xFFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
@@ -8,176 +8,235 @@ package dan200.computercraft.client.proxy;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.client.gui.*;
|
||||
import dan200.computercraft.client.render.ItemPocketRenderer;
|
||||
import dan200.computercraft.client.render.ItemPrintoutRenderer;
|
||||
import dan200.computercraft.client.render.RenderOverlayCable;
|
||||
import dan200.computercraft.client.render.TileEntityCableRenderer;
|
||||
import dan200.computercraft.client.render.TileEntityMonitorRenderer;
|
||||
import dan200.computercraft.shared.command.ContainerViewComputer;
|
||||
import dan200.computercraft.shared.computer.blocks.ComputerState;
|
||||
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.IComputer;
|
||||
import dan200.computercraft.shared.computer.items.ItemComputer;
|
||||
import dan200.computercraft.shared.media.inventory.ContainerHeldItem;
|
||||
import dan200.computercraft.shared.media.items.ItemDiskLegacy;
|
||||
import dan200.computercraft.shared.media.items.ItemPrintout;
|
||||
import dan200.computercraft.shared.network.ComputerCraftPacket;
|
||||
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
|
||||
import dan200.computercraft.shared.peripheral.modem.TileCable;
|
||||
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
|
||||
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
|
||||
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
|
||||
import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer;
|
||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
||||
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||
import dan200.computercraft.shared.turtle.entity.TurtleVisionCamera;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import gnu.trove.map.hash.TIntIntHashMap;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiNewChat;
|
||||
import net.minecraft.client.renderer.ItemMeshDefinition;
|
||||
import net.minecraft.client.renderer.block.model.ModelBakery;
|
||||
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
||||
import net.minecraft.client.renderer.color.IItemColor;
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.IThreadListener;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.IThreadListener;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.event.ModelRegistryEvent;
|
||||
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
||||
import net.minecraftforge.client.event.RenderHandEvent;
|
||||
import net.minecraftforge.client.event.RenderPlayerEvent;
|
||||
import net.minecraftforge.client.model.ModelLoader;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.client.FMLClientHandler;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
|
||||
{
|
||||
private long m_tick;
|
||||
private long m_renderFrame;
|
||||
private FixedWidthFontRenderer m_fixedWidthFontRenderer;
|
||||
private static TIntIntHashMap lastCounts = new TIntIntHashMap();
|
||||
|
||||
public ComputerCraftProxyClient()
|
||||
{
|
||||
}
|
||||
|
||||
// IComputerCraftProxy implementation
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
m_tick = 0;
|
||||
private long m_tick;
|
||||
private long m_renderFrame;
|
||||
private FixedWidthFontRenderer m_fixedWidthFontRenderer;
|
||||
|
||||
// IComputerCraftProxy implementation
|
||||
|
||||
@Override
|
||||
public void preInit()
|
||||
{
|
||||
super.preInit();
|
||||
m_tick = 0;
|
||||
m_renderFrame = 0;
|
||||
|
||||
// Load textures
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
m_fixedWidthFontRenderer = new FixedWidthFontRenderer( mc.getTextureManager() );
|
||||
// Setup client forge handlers
|
||||
registerForgeHandlers();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void registerModels( ModelRegistryEvent event )
|
||||
{
|
||||
// Register item models
|
||||
registerItemModel( ComputerCraft.Blocks.computer, new ItemMeshDefinition()
|
||||
{
|
||||
private ModelResourceLocation computer = new ModelResourceLocation( "computercraft:CC-Computer", "inventory" );
|
||||
private ModelResourceLocation computer = new ModelResourceLocation( "computercraft:computer", "inventory" );
|
||||
private ModelResourceLocation advanced_computer = new ModelResourceLocation( "computercraft:advanced_computer", "inventory" );
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ModelResourceLocation getModelLocation( ItemStack stack )
|
||||
public ModelResourceLocation getModelLocation( @Nonnull ItemStack stack )
|
||||
{
|
||||
ItemComputer itemComputer = (ItemComputer) stack.getItem();
|
||||
ComputerFamily family = itemComputer.getFamily( stack.getItemDamage() );
|
||||
return ( family == ComputerFamily.Advanced ) ? advanced_computer : computer;
|
||||
}
|
||||
}, new String[]{ "CC-Computer", "advanced_computer" } );
|
||||
registerItemModel( ComputerCraft.Blocks.peripheral, 0, "CC-Peripheral" );
|
||||
}, new String[]{ "computer", "advanced_computer" } );
|
||||
registerItemModel( ComputerCraft.Blocks.peripheral, 0, "peripheral" );
|
||||
registerItemModel( ComputerCraft.Blocks.peripheral, 1, "wireless_modem" );
|
||||
registerItemModel( ComputerCraft.Blocks.peripheral, 2, "monitor" );
|
||||
registerItemModel( ComputerCraft.Blocks.peripheral, 3, "printer" );
|
||||
registerItemModel( ComputerCraft.Blocks.peripheral, 4, "advanced_monitor" );
|
||||
registerItemModel( ComputerCraft.Blocks.cable, 0, "CC-Cable" );
|
||||
registerItemModel( ComputerCraft.Blocks.cable, 0, "cable" );
|
||||
registerItemModel( ComputerCraft.Blocks.cable, 1, "wired_modem" );
|
||||
registerItemModel( ComputerCraft.Blocks.commandComputer, "command_computer" );
|
||||
registerItemModel( ComputerCraft.Blocks.advancedModem, "advanced_modem" );
|
||||
registerItemModel( ComputerCraft.Blocks.peripheral, 5, "speaker" );
|
||||
registerItemModel( ComputerCraft.Blocks.wiredModemFull, "wired_modem_full" );
|
||||
|
||||
registerItemModel( ComputerCraft.Items.disk, "disk" );
|
||||
registerItemModel( ComputerCraft.Items.diskExpanded, "diskExpanded" );
|
||||
registerItemModel( ComputerCraft.Items.treasureDisk, "treasureDisk" );
|
||||
registerItemModel( ComputerCraft.Items.diskExpanded, "disk_expanded" );
|
||||
registerItemModel( ComputerCraft.Items.treasureDisk, "treasure_disk" );
|
||||
registerItemModel( ComputerCraft.Items.printout, 0, "printout" );
|
||||
registerItemModel( ComputerCraft.Items.printout, 1, "pages" );
|
||||
registerItemModel( ComputerCraft.Items.printout, 2, "book" );
|
||||
registerItemModel( ComputerCraft.Items.pocketComputer, new ItemMeshDefinition()
|
||||
{
|
||||
private ModelResourceLocation pocket_computer_off = new ModelResourceLocation( "computercraft:pocketComputer", "inventory" );
|
||||
private ModelResourceLocation pocket_computer_off = new ModelResourceLocation( "computercraft:pocket_computer", "inventory" );
|
||||
private ModelResourceLocation pocket_computer_on = new ModelResourceLocation( "computercraft:pocket_computer_on", "inventory" );
|
||||
private ModelResourceLocation pocket_computer_blinking = new ModelResourceLocation( "computercraft:pocket_computer_blinking", "inventory" );
|
||||
private ModelResourceLocation pocket_computer_on_modem_on = new ModelResourceLocation( "computercraft:pocket_computer_on_modem_on", "inventory" );
|
||||
private ModelResourceLocation pocket_computer_blinking_modem_on = new ModelResourceLocation( "computercraft:pocket_computer_blinking_modem_on", "inventory" );
|
||||
private ModelResourceLocation advanced_pocket_computer_off = new ModelResourceLocation( "computercraft:advanced_pocket_computer_off", "inventory" );
|
||||
private ModelResourceLocation advanced_pocket_computer_off = new ModelResourceLocation( "computercraft:advanced_pocket_computer", "inventory" );
|
||||
private ModelResourceLocation advanced_pocket_computer_on = new ModelResourceLocation( "computercraft:advanced_pocket_computer_on", "inventory" );
|
||||
private ModelResourceLocation advanced_pocket_computer_blinking = new ModelResourceLocation( "computercraft:advanced_pocket_computer_blinking", "inventory" );
|
||||
private ModelResourceLocation advanced_pocket_computer_on_modem_on = new ModelResourceLocation( "computercraft:advanced_pocket_computer_on_modem_on", "inventory" );
|
||||
private ModelResourceLocation advanced_pocket_computer_blinking_modem_on = new ModelResourceLocation( "computercraft:advanced_pocket_computer_blinking_modem_on", "inventory" );
|
||||
private ModelResourceLocation colour_pocket_computer_off = new ModelResourceLocation( "computercraft:pocket_computer_colour", "inventory" );
|
||||
private ModelResourceLocation colour_pocket_computer_on = new ModelResourceLocation( "computercraft:pocket_computer_colour_on", "inventory" );
|
||||
private ModelResourceLocation colour_pocket_computer_blinking = new ModelResourceLocation( "computercraft:pocket_computer_colour_blinking", "inventory" );
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ModelResourceLocation getModelLocation( ItemStack stack )
|
||||
public ModelResourceLocation getModelLocation( @Nonnull ItemStack stack )
|
||||
{
|
||||
ItemPocketComputer itemPocketComputer = (ItemPocketComputer)stack.getItem();
|
||||
boolean modemOn = itemPocketComputer.getModemState( stack );
|
||||
switch( itemPocketComputer.getFamily( stack ) )
|
||||
ItemPocketComputer itemPocketComputer = (ItemPocketComputer) stack.getItem();
|
||||
ComputerState state = itemPocketComputer.getState( stack );
|
||||
if( itemPocketComputer.getColour( stack ) == -1 )
|
||||
{
|
||||
case Advanced:
|
||||
switch( itemPocketComputer.getFamily( stack ) )
|
||||
{
|
||||
switch( itemPocketComputer.getState( stack ) )
|
||||
{
|
||||
case Off:
|
||||
default:
|
||||
case Advanced:
|
||||
switch( state )
|
||||
{
|
||||
return advanced_pocket_computer_off;
|
||||
case Off:
|
||||
default:
|
||||
return advanced_pocket_computer_off;
|
||||
case On:
|
||||
return advanced_pocket_computer_on;
|
||||
case Blinking:
|
||||
return advanced_pocket_computer_blinking;
|
||||
}
|
||||
case On:
|
||||
case Normal:
|
||||
default:
|
||||
switch( state )
|
||||
{
|
||||
return modemOn ? advanced_pocket_computer_on_modem_on : advanced_pocket_computer_on;
|
||||
case Off:
|
||||
default:
|
||||
return pocket_computer_off;
|
||||
case On:
|
||||
return pocket_computer_on;
|
||||
case Blinking:
|
||||
return pocket_computer_blinking;
|
||||
}
|
||||
case Blinking:
|
||||
{
|
||||
return modemOn ? advanced_pocket_computer_blinking_modem_on : advanced_pocket_computer_blinking;
|
||||
}
|
||||
}
|
||||
}
|
||||
case Normal:
|
||||
default:
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( state )
|
||||
{
|
||||
switch( itemPocketComputer.getState( stack ) )
|
||||
{
|
||||
case Off:
|
||||
default:
|
||||
{
|
||||
return pocket_computer_off;
|
||||
}
|
||||
case On:
|
||||
{
|
||||
return modemOn ? pocket_computer_on_modem_on : pocket_computer_on;
|
||||
}
|
||||
case Blinking:
|
||||
{
|
||||
return modemOn ? pocket_computer_blinking_modem_on : pocket_computer_blinking;
|
||||
}
|
||||
}
|
||||
case Off:
|
||||
default:
|
||||
return colour_pocket_computer_off;
|
||||
case On:
|
||||
return colour_pocket_computer_on;
|
||||
case Blinking:
|
||||
return colour_pocket_computer_blinking;
|
||||
}
|
||||
}
|
||||
}
|
||||
}, new String[] {
|
||||
"pocketComputer", "pocket_computer_on", "pocket_computer_blinking", "pocket_computer_on_modem_on", "pocket_computer_blinking_modem_on",
|
||||
"advanced_pocket_computer_off", "advanced_pocket_computer_on", "advanced_pocket_computer_blinking", "advanced_pocket_computer_on_modem_on", "advanced_pocket_computer_blinking_modem_on",
|
||||
"pocket_computer", "pocket_computer_on", "pocket_computer_blinking",
|
||||
"advanced_pocket_computer", "advanced_pocket_computer_on", "advanced_pocket_computer_blinking",
|
||||
"pocket_computer_colour", "pocket_computer_colour_on", "pocket_computer_colour_blinking",
|
||||
} );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
|
||||
// Load textures
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
m_fixedWidthFontRenderer = new FixedWidthFontRenderer( mc.getTextureManager() );
|
||||
|
||||
// Setup
|
||||
mc.getItemColors().registerItemColorHandler( new DiskColorHandler( ComputerCraft.Items.disk ), ComputerCraft.Items.disk );
|
||||
mc.getItemColors().registerItemColorHandler( new DiskColorHandler( ComputerCraft.Items.diskExpanded ), ComputerCraft.Items.diskExpanded );
|
||||
|
||||
mc.getItemColors().registerItemColorHandler( ( stack, layer ) ->
|
||||
{
|
||||
switch( layer )
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
return 0xFFFFFF;
|
||||
case 1:
|
||||
{
|
||||
// Frame colour
|
||||
int colour = ComputerCraft.Items.pocketComputer.getColour( stack );
|
||||
return colour == -1 ? 0xFFFFFF : colour;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// Light colour
|
||||
int colour = ComputerCraft.Items.pocketComputer.getLightState( stack );
|
||||
return colour == -1 ? Colour.Black.getHex() : colour;
|
||||
}
|
||||
}
|
||||
}, ComputerCraft.Items.pocketComputer );
|
||||
|
||||
// Setup renderers
|
||||
ClientRegistry.bindTileEntitySpecialRenderer( TileMonitor.class, new TileEntityMonitorRenderer() );
|
||||
|
||||
// Setup client forge handlers
|
||||
registerForgeHandlers();
|
||||
}
|
||||
ClientRegistry.bindTileEntitySpecialRenderer( TileCable.class, new TileEntityCableRenderer() );
|
||||
}
|
||||
|
||||
private void registerItemModel( Block block, int damage, String name )
|
||||
{
|
||||
@@ -188,7 +247,7 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
|
||||
{
|
||||
ModelResourceLocation res = new ModelResourceLocation( "computercraft:" + name, "inventory" );
|
||||
ModelBakery.registerItemVariants( item, new ResourceLocation( "computercraft", name ) );
|
||||
Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register( item, damage, res );
|
||||
ModelLoader.setCustomModelResourceLocation( item, damage, res );
|
||||
}
|
||||
|
||||
private void registerItemModel( Block block, String name )
|
||||
@@ -200,10 +259,11 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
|
||||
{
|
||||
final ModelResourceLocation res = new ModelResourceLocation( "computercraft:" + name, "inventory" );
|
||||
ModelBakery.registerItemVariants( item, new ResourceLocation( "computercraft", name ) );
|
||||
Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register( item, new ItemMeshDefinition()
|
||||
ModelLoader.setCustomMeshDefinition( item, new ItemMeshDefinition()
|
||||
{
|
||||
@Nonnull
|
||||
@Override
|
||||
public ModelResourceLocation getModelLocation( ItemStack stack )
|
||||
public ModelResourceLocation getModelLocation( @Nonnull ItemStack stack )
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@@ -223,20 +283,20 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
|
||||
resources[i] = new ResourceLocation( "computercraft", names[i] );
|
||||
}
|
||||
ModelBakery.registerItemVariants( item, resources );
|
||||
Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register( item, definition );
|
||||
ModelLoader.setCustomMeshDefinition( item, definition );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClient()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getGlobalCursorBlink()
|
||||
{
|
||||
return ( m_tick / 8) % 2 == 0;
|
||||
}
|
||||
@Override
|
||||
public boolean isClient()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getGlobalCursorBlink()
|
||||
{
|
||||
return ( m_tick / 8) % 2 == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRenderFrame()
|
||||
@@ -245,57 +305,40 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDisplayLists( int list, int range )
|
||||
public Object getFixedWidthFontRenderer()
|
||||
{
|
||||
GL11.glDeleteLists( list, range );
|
||||
return m_fixedWidthFontRenderer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getFixedWidthFontRenderer()
|
||||
{
|
||||
return m_fixedWidthFontRenderer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRecordInfo( ItemStack recordStack )
|
||||
{
|
||||
List info = new ArrayList(1);
|
||||
recordStack.getItem().addInformation( recordStack, null, info, false );
|
||||
if( info.size() > 0 ) {
|
||||
return info.get(0).toString();
|
||||
} else {
|
||||
return super.getRecordInfo( recordStack );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playRecord( SoundEvent record, String recordInfo, World world, BlockPos pos )
|
||||
{
|
||||
Minecraft mc = FMLClientHandler.instance().getClient();
|
||||
world.playRecord( pos, record );
|
||||
if( record != null )
|
||||
{
|
||||
mc.ingameGUI.setRecordPlayingMessage( recordInfo );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDiskDriveGUI( InventoryPlayer inventory, TileDiskDrive drive )
|
||||
{
|
||||
return new GuiDiskDrive( inventory, drive );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getComputerGUI( TileComputer computer )
|
||||
{
|
||||
return new GuiComputer( computer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPrinterGUI( InventoryPlayer inventory, TilePrinter printer )
|
||||
{
|
||||
return new GuiPrinter( inventory, printer );
|
||||
}
|
||||
public String getRecordInfo( @Nonnull ItemStack recordStack )
|
||||
{
|
||||
List<String> info = new ArrayList<>( 1 );
|
||||
recordStack.getItem().addInformation( recordStack, null, info, ITooltipFlag.TooltipFlags.NORMAL );
|
||||
if( info.size() > 0 ) {
|
||||
return info.get( 0 );
|
||||
} else {
|
||||
return super.getRecordInfo( recordStack );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDiskDriveGUI( InventoryPlayer inventory, TileDiskDrive drive )
|
||||
{
|
||||
return new GuiDiskDrive( inventory, drive );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getComputerGUI( TileComputer computer )
|
||||
{
|
||||
return new GuiComputer( computer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPrinterGUI( InventoryPlayer inventory, TilePrinter printer )
|
||||
{
|
||||
return new GuiPrinter( inventory, printer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTurtleGUI( InventoryPlayer inventory, TileTurtle turtle )
|
||||
@@ -304,32 +347,39 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPrintoutGUI( InventoryPlayer inventory )
|
||||
{
|
||||
ContainerHeldItem container = new ContainerHeldItem( inventory );
|
||||
if( container.getStack() != null && container.getStack().getItem() instanceof ItemPrintout )
|
||||
public Object getPrintoutGUI( EntityPlayer player, EnumHand hand )
|
||||
{
|
||||
ContainerHeldItem container = new ContainerHeldItem( player, hand );
|
||||
if( container.getStack().getItem() instanceof ItemPrintout )
|
||||
{
|
||||
return new GuiPrintout( container );
|
||||
return new GuiPrintout( container );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPocketComputerGUI( InventoryPlayer inventory )
|
||||
public Object getPocketComputerGUI( EntityPlayer player, EnumHand hand )
|
||||
{
|
||||
ContainerHeldItem container = new ContainerHeldItem( inventory );
|
||||
if( container.getStack() != null && container.getStack().getItem() instanceof ItemPocketComputer )
|
||||
ContainerPocketComputer container = new ContainerPocketComputer( player, hand );
|
||||
if( container.getStack().getItem() instanceof ItemPocketComputer )
|
||||
{
|
||||
return new GuiPocketComputer( container );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getWorldDir( World world )
|
||||
{
|
||||
@Override
|
||||
public Object getComputerGUI( IComputer computer, int width, int height, ComputerFamily family )
|
||||
{
|
||||
ContainerViewComputer container = new ContainerViewComputer( computer );
|
||||
return new GuiComputer( container, family, computer, width, height );
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getWorldDir( World world )
|
||||
{
|
||||
return world.getSaveHandler().getWorldDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePacket( final ComputerCraftPacket packet, final EntityPlayer player )
|
||||
@@ -337,7 +387,10 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
|
||||
switch( packet.m_packetType )
|
||||
{
|
||||
case ComputerCraftPacket.ComputerChanged:
|
||||
case ComputerCraftPacket.ComputerTerminalChanged:
|
||||
case ComputerCraftPacket.ComputerDeleted:
|
||||
case ComputerCraftPacket.PlayRecord:
|
||||
case ComputerCraftPacket.PostChat:
|
||||
{
|
||||
// Packet from Server to Client
|
||||
IThreadListener listener = Minecraft.getMinecraft();
|
||||
@@ -349,14 +402,7 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
|
||||
}
|
||||
else
|
||||
{
|
||||
listener.addScheduledTask( new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
processPacket( packet, player );
|
||||
}
|
||||
} );
|
||||
listener.addScheduledTask( () -> processPacket( packet, player ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -378,13 +424,14 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
|
||||
// Packets from Server to Client //
|
||||
///////////////////////////////////
|
||||
case ComputerCraftPacket.ComputerChanged:
|
||||
case ComputerCraftPacket.ComputerTerminalChanged:
|
||||
{
|
||||
int instanceID = packet.m_dataInt[ 0 ];
|
||||
if( !ComputerCraft.clientComputerRegistry.contains( instanceID ) )
|
||||
{
|
||||
ComputerCraft.clientComputerRegistry.add( instanceID, new ClientComputer( instanceID ) );
|
||||
}
|
||||
ComputerCraft.clientComputerRegistry.get( instanceID ).handlePacket( packet, (EntityPlayer) player );
|
||||
ComputerCraft.clientComputerRegistry.get( instanceID ).handlePacket( packet, player );
|
||||
break;
|
||||
}
|
||||
case ComputerCraftPacket.ComputerDeleted:
|
||||
@@ -396,21 +443,69 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ComputerCraftPacket.PlayRecord:
|
||||
{
|
||||
BlockPos pos = new BlockPos( packet.m_dataInt[ 0 ], packet.m_dataInt[ 1 ], packet.m_dataInt[ 2 ] );
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
if( packet.m_dataInt.length > 3 )
|
||||
{
|
||||
SoundEvent sound = SoundEvent.REGISTRY.getObjectById( packet.m_dataInt[ 3 ] );
|
||||
mc.world.playRecord( pos, sound );
|
||||
mc.ingameGUI.setRecordPlayingMessage( packet.m_dataString[ 0 ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
mc.world.playRecord( pos, null );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ComputerCraftPacket.PostChat:
|
||||
{
|
||||
/*
|
||||
This allows us to send delete chat messages of the same "category" as the previous one.
|
||||
It's used by the various /computercraft commands to avoid filling the chat with repetitive
|
||||
messages.
|
||||
*/
|
||||
|
||||
int id = packet.m_dataInt[0];
|
||||
ITextComponent[] components = new ITextComponent[packet.m_dataString.length];
|
||||
for( int i = 0; i < packet.m_dataString.length; i++ )
|
||||
{
|
||||
components[i] = ITextComponent.Serializer.jsonToComponent( packet.m_dataString[i] );
|
||||
}
|
||||
|
||||
GuiNewChat chat = Minecraft.getMinecraft().ingameGUI.getChatGUI();
|
||||
|
||||
// Keep track of how many lines we wrote last time, deleting any extra ones.
|
||||
int lastCount = lastCounts.get( id );
|
||||
for( int i = components.length; i < lastCount; i++ ) chat.deleteChatLine( i + id );
|
||||
lastCounts.put( id, components.length );
|
||||
|
||||
// Add new lines
|
||||
for( int i = 0; i < components.length; i++ )
|
||||
{
|
||||
chat.printChatMessageWithOptionalDeletion( components[i], id + i );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void registerForgeHandlers()
|
||||
{
|
||||
ForgeHandlers handlers = new ForgeHandlers();
|
||||
FMLCommonHandler.instance().bus().register( handlers );
|
||||
private void registerForgeHandlers()
|
||||
{
|
||||
ForgeHandlers handlers = new ForgeHandlers();
|
||||
MinecraftForge.EVENT_BUS.register( handlers );
|
||||
}
|
||||
|
||||
public class ForgeHandlers
|
||||
{
|
||||
public ForgeHandlers()
|
||||
{
|
||||
}
|
||||
MinecraftForge.EVENT_BUS.register( new RenderOverlayCable() );
|
||||
MinecraftForge.EVENT_BUS.register( new ItemPocketRenderer() );
|
||||
MinecraftForge.EVENT_BUS.register( new ItemPrintoutRenderer() );
|
||||
}
|
||||
|
||||
public class ForgeHandlers
|
||||
{
|
||||
public ForgeHandlers()
|
||||
{
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onRenderHand( RenderHandEvent event )
|
||||
@@ -490,5 +585,31 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
|
||||
m_renderFrame++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onWorldUnload( WorldEvent.Unload event )
|
||||
{
|
||||
if( event.getWorld().isRemote )
|
||||
{
|
||||
ClientMonitor.destroyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
private static class DiskColorHandler implements IItemColor
|
||||
{
|
||||
private final ItemDiskLegacy disk;
|
||||
|
||||
private DiskColorHandler( ItemDiskLegacy disk )
|
||||
{
|
||||
this.disk = disk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int colorMultiplier( @Nonnull ItemStack stack, int layer )
|
||||
{
|
||||
return layer == 0 ? 0xFFFFFF : disk.getColour( stack );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,264 @@
|
||||
package dan200.computercraft.client.render;
|
||||
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
|
||||
import dan200.computercraft.core.terminal.Terminal;
|
||||
import dan200.computercraft.core.terminal.TextBuffer;
|
||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
||||
import dan200.computercraft.shared.util.Palette;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.ItemRenderer;
|
||||
import net.minecraft.client.renderer.RenderItem;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.EnumHandSide;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraftforge.client.ForgeHooksClient;
|
||||
import net.minecraftforge.client.event.RenderSpecificHandEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT;
|
||||
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH;
|
||||
|
||||
/**
|
||||
* Emulates map rendering for pocket computers
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class ItemPocketRenderer
|
||||
{
|
||||
@SubscribeEvent
|
||||
public void renderItem( RenderSpecificHandEvent event )
|
||||
{
|
||||
ItemStack stack = event.getItemStack();
|
||||
if( !(stack.getItem() instanceof ItemPocketComputer) ) return;
|
||||
|
||||
event.setCanceled( true );
|
||||
|
||||
EntityPlayer player = Minecraft.getMinecraft().player;
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
if( event.getHand() == EnumHand.MAIN_HAND && player.getHeldItemOffhand().isEmpty() )
|
||||
{
|
||||
renderItemFirstCentre(
|
||||
event.getInterpolatedPitch(),
|
||||
event.getEquipProgress(),
|
||||
event.getSwingProgress(),
|
||||
stack
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
renderItemFirstPersonSide(
|
||||
event.getHand() == EnumHand.MAIN_HAND ? player.getPrimaryHand() : player.getPrimaryHand().opposite(),
|
||||
event.getEquipProgress(),
|
||||
event.getSwingProgress(),
|
||||
stack
|
||||
);
|
||||
}
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
/**
|
||||
* The main rendering method for pocket computers and their associated terminal
|
||||
*
|
||||
* @param stack The stack to render
|
||||
* @see ItemRenderer#renderMapFirstPerson(ItemStack)
|
||||
*/
|
||||
private void renderPocketComputerItem( ItemStack stack )
|
||||
{
|
||||
// Setup various transformations. Note that these are partially adapated from the corresponding method
|
||||
// in ItemRenderer
|
||||
GlStateManager.disableLighting();
|
||||
|
||||
GlStateManager.rotate( 180f, 0f, 1f, 0f );
|
||||
GlStateManager.rotate( 180f, 0f, 0f, 1f );
|
||||
GlStateManager.scale( 0.5, 0.5, 0.5 );
|
||||
|
||||
ItemPocketComputer pocketComputer = ComputerCraft.Items.pocketComputer;
|
||||
ClientComputer computer = pocketComputer.createClientComputer( stack );
|
||||
|
||||
{
|
||||
// First render the background item. We use the item's model rather than a direct texture as this ensures
|
||||
// we display the pocket light and other such decorations.
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
GlStateManager.scale( 1.0f, -1.0f, 1.0f );
|
||||
|
||||
Minecraft minecraft = Minecraft.getMinecraft();
|
||||
TextureManager textureManager = minecraft.getTextureManager();
|
||||
RenderItem renderItem = minecraft.getRenderItem();
|
||||
|
||||
// Copy of RenderItem#renderItemModelIntoGUI but without the translation or scaling
|
||||
textureManager.bindTexture( TextureMap.LOCATION_BLOCKS_TEXTURE );
|
||||
textureManager.getTexture( TextureMap.LOCATION_BLOCKS_TEXTURE ).setBlurMipmap( false, false );
|
||||
|
||||
GlStateManager.enableRescaleNormal();
|
||||
GlStateManager.enableAlpha();
|
||||
GlStateManager.alphaFunc( GL11.GL_GREATER, 0.1F );
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc( GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA );
|
||||
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
|
||||
|
||||
IBakedModel bakedmodel = renderItem.getItemModelWithOverrides( stack, null, null );
|
||||
bakedmodel = ForgeHooksClient.handleCameraTransforms( bakedmodel, ItemCameraTransforms.TransformType.GUI, false );
|
||||
renderItem.renderItem( stack, bakedmodel );
|
||||
|
||||
GlStateManager.disableAlpha();
|
||||
GlStateManager.disableRescaleNormal();
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
// If we've a computer and terminal then attempt to render it.
|
||||
if( computer != null )
|
||||
{
|
||||
Terminal terminal = computer.getTerminal();
|
||||
if( terminal != null )
|
||||
{
|
||||
synchronized( terminal )
|
||||
{
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.disableDepth();
|
||||
|
||||
// Reset the position to be at the top left corner of the pocket computer
|
||||
// Note we translate towards the screen slightly too.
|
||||
GlStateManager.translate( -8 / 16.0, -8 / 16.0, 0.5 / 16.0 );
|
||||
// Translate to the top left of the screen.
|
||||
GlStateManager.translate( 4 / 16.0, 3 / 16.0, 0 );
|
||||
|
||||
// Work out the scaling required to resize the terminal in order to fit on the computer
|
||||
final int margin = 2;
|
||||
int tw = terminal.getWidth();
|
||||
int th = terminal.getHeight();
|
||||
int width = tw * FONT_WIDTH + margin * 2;
|
||||
int height = th * FONT_HEIGHT + margin * 2;
|
||||
int max = Math.max( height, width );
|
||||
|
||||
// The grid is 8 * 8 wide, so we start with a base of 1/2 (8 / 16).
|
||||
double scale = 1.0 / 2.0 / max;
|
||||
GlStateManager.scale( scale, scale, scale );
|
||||
|
||||
// The margin/start positions are determined in order for the terminal to be centred.
|
||||
int startX = (max - width) / 2 + margin;
|
||||
int startY = (max - height) / 2 + margin;
|
||||
|
||||
FixedWidthFontRenderer fontRenderer = (FixedWidthFontRenderer) ComputerCraft.getFixedWidthFontRenderer();
|
||||
boolean greyscale = !computer.isColour();
|
||||
Palette palette = terminal.getPalette();
|
||||
|
||||
// Render the actual text
|
||||
for( int line = 0; line < th; ++line )
|
||||
{
|
||||
TextBuffer text = terminal.getLine( line );
|
||||
TextBuffer colour = terminal.getTextColourLine( line );
|
||||
TextBuffer backgroundColour = terminal.getBackgroundColourLine( line );
|
||||
fontRenderer.drawString(
|
||||
text, startX, startY + line * FONT_HEIGHT,
|
||||
colour, backgroundColour, margin, margin, greyscale, palette
|
||||
);
|
||||
}
|
||||
|
||||
// And render the cursor;
|
||||
int tx = terminal.getCursorX(), ty = terminal.getCursorY();
|
||||
if( terminal.getCursorBlink() && ComputerCraft.getGlobalCursorBlink() &&
|
||||
tx >= 0 && ty >= 0 && tx < tw && ty < th )
|
||||
{
|
||||
TextBuffer cursorColour = new TextBuffer( "0123456789abcdef".charAt( terminal.getTextColour() ), 1 );
|
||||
fontRenderer.drawString(
|
||||
new TextBuffer( '_', 1 ), startX + FONT_WIDTH * tx, startY + FONT_HEIGHT * ty,
|
||||
cursorColour, null, 0, 0, greyscale, palette
|
||||
);
|
||||
}
|
||||
|
||||
GlStateManager.enableDepth();
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GlStateManager.enableLighting();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a pocket computer to one side of the player.
|
||||
*
|
||||
* @param side The side to render on
|
||||
* @param equipProgress The equip progress of this item
|
||||
* @param swingProgress The swing progress of this item
|
||||
* @param stack The stack to render
|
||||
* @see ItemRenderer#renderMapFirstPersonSide(float, EnumHandSide, float, ItemStack)
|
||||
*/
|
||||
private void renderItemFirstPersonSide( EnumHandSide side, float equipProgress, float swingProgress, ItemStack stack )
|
||||
{
|
||||
Minecraft minecraft = Minecraft.getMinecraft();
|
||||
float offset = side == EnumHandSide.RIGHT ? 1f : -1f;
|
||||
GlStateManager.translate( offset * 0.125f, -0.125f, 0f );
|
||||
|
||||
// If the player is not invisible then render a single arm
|
||||
if( !minecraft.player.isInvisible() )
|
||||
{
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.rotate( offset * 10f, 0f, 0f, 1f );
|
||||
minecraft.getItemRenderer().renderArmFirstPerson( equipProgress, swingProgress, side );
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
// Setup the appropriate transformations. This is just copied from the
|
||||
// corresponding method in ItemRenderer.
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate( offset * 0.51f, -0.08f + equipProgress * -1.2f, -0.75f );
|
||||
float f1 = MathHelper.sqrt( swingProgress );
|
||||
float f2 = MathHelper.sin( f1 * (float) Math.PI );
|
||||
float f3 = -0.5f * f2;
|
||||
float f4 = 0.4f * MathHelper.sin( f1 * ((float) Math.PI * 2f) );
|
||||
float f5 = -0.3f * MathHelper.sin( swingProgress * (float) Math.PI );
|
||||
GlStateManager.translate( offset * f3, f4 - 0.3f * f2, f5 );
|
||||
GlStateManager.rotate( f2 * -45f, 1f, 0f, 0f );
|
||||
GlStateManager.rotate( offset * f2 * -30f, 0f, 1f, 0f );
|
||||
|
||||
renderPocketComputerItem( stack );
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an item in the middle of the screen
|
||||
*
|
||||
* @param pitch The pitch of the player
|
||||
* @param equipProgress The equip progress of this item
|
||||
* @param swingProgress The swing progress of this item
|
||||
* @param stack The stack to render
|
||||
* @see ItemRenderer#renderMapFirstPerson(float, float, float)
|
||||
*/
|
||||
private void renderItemFirstCentre( float pitch, float equipProgress, float swingProgress, ItemStack stack )
|
||||
{
|
||||
ItemRenderer itemRenderer = Minecraft.getMinecraft().getItemRenderer();
|
||||
|
||||
// Setup the appropriate transformations. This is just copied from the
|
||||
// corresponding method in ItemRenderer.
|
||||
float swingRt = MathHelper.sqrt( swingProgress );
|
||||
float tX = -0.2f * MathHelper.sin( swingProgress * (float) Math.PI );
|
||||
float tZ = -0.4f * MathHelper.sin( swingRt * (float) Math.PI );
|
||||
GlStateManager.translate( 0f, -tX / 2f, tZ );
|
||||
float pitchAngle = itemRenderer.getMapAngleFromPitch( pitch );
|
||||
GlStateManager.translate( 0f, 0.04f + equipProgress * -1.2f + pitchAngle * -0.5f, -0.72f );
|
||||
GlStateManager.rotate( pitchAngle * -85f, 1f, 0f, 0f );
|
||||
itemRenderer.renderArms();
|
||||
float rX = MathHelper.sin( swingRt * (float) Math.PI );
|
||||
GlStateManager.rotate( rX * 20f, 1f, 0f, 0f );
|
||||
GlStateManager.scale( 2f, 2f, 2f );
|
||||
|
||||
renderPocketComputerItem( stack );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
package dan200.computercraft.client.render;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.media.items.ItemPrintout;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.ItemRenderer;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.EnumHandSide;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraftforge.client.event.RenderItemInFrameEvent;
|
||||
import net.minecraftforge.client.event.RenderSpecificHandEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
|
||||
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT;
|
||||
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH;
|
||||
import static dan200.computercraft.client.render.PrintoutRenderer.*;
|
||||
import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAGE;
|
||||
import static dan200.computercraft.shared.media.items.ItemPrintout.LINE_MAX_LENGTH;
|
||||
|
||||
public class ItemPrintoutRenderer
|
||||
{
|
||||
@SubscribeEvent
|
||||
public void onRenderInHand( RenderSpecificHandEvent event )
|
||||
{
|
||||
ItemStack stack = event.getItemStack();
|
||||
if( stack.getItem() != ComputerCraft.Items.printout ) return;
|
||||
|
||||
event.setCanceled( true );
|
||||
|
||||
EntityPlayer player = Minecraft.getMinecraft().player;
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
if( event.getHand() == EnumHand.MAIN_HAND && player.getHeldItemOffhand().isEmpty() )
|
||||
{
|
||||
renderPrintoutFirstPersonCentre(
|
||||
event.getInterpolatedPitch(),
|
||||
event.getEquipProgress(),
|
||||
event.getSwingProgress(),
|
||||
stack
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
renderPrintoutFirstPersonSide(
|
||||
event.getHand() == EnumHand.MAIN_HAND ? player.getPrimaryHand() : player.getPrimaryHand().opposite(),
|
||||
event.getEquipProgress(),
|
||||
event.getSwingProgress(),
|
||||
stack
|
||||
);
|
||||
}
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a pocket computer to one side of the player.
|
||||
*
|
||||
* @param side The side to render on
|
||||
* @param equipProgress The equip progress of this item
|
||||
* @param swingProgress The swing progress of this item
|
||||
* @param stack The stack to render
|
||||
* @see ItemRenderer#renderMapFirstPersonSide(float, EnumHandSide, float, ItemStack)
|
||||
*/
|
||||
private void renderPrintoutFirstPersonSide( EnumHandSide side, float equipProgress, float swingProgress, ItemStack stack )
|
||||
{
|
||||
Minecraft minecraft = Minecraft.getMinecraft();
|
||||
float offset = side == EnumHandSide.RIGHT ? 1f : -1f;
|
||||
GlStateManager.translate( offset * 0.125f, -0.125f, 0f );
|
||||
|
||||
// If the player is not invisible then render a single arm
|
||||
if( !minecraft.player.isInvisible() )
|
||||
{
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.rotate( offset * 10f, 0f, 0f, 1f );
|
||||
minecraft.getItemRenderer().renderArmFirstPerson( equipProgress, swingProgress, side );
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
// Setup the appropriate transformations. This is just copied from the
|
||||
// corresponding method in ItemRenderer.
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate( offset * 0.51f, -0.08f + equipProgress * -1.2f, -0.75f );
|
||||
float f1 = MathHelper.sqrt( swingProgress );
|
||||
float f2 = MathHelper.sin( f1 * (float) Math.PI );
|
||||
float f3 = -0.5f * f2;
|
||||
float f4 = 0.4f * MathHelper.sin( f1 * ((float) Math.PI * 2f) );
|
||||
float f5 = -0.3f * MathHelper.sin( swingProgress * (float) Math.PI );
|
||||
GlStateManager.translate( offset * f3, f4 - 0.3f * f2, f5 );
|
||||
GlStateManager.rotate( f2 * -45f, 1f, 0f, 0f );
|
||||
GlStateManager.rotate( offset * f2 * -30f, 0f, 1f, 0f );
|
||||
|
||||
renderPrintoutFirstPerson( stack );
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an item in the middle of the screen
|
||||
*
|
||||
* @param pitch The pitch of the player
|
||||
* @param equipProgress The equip progress of this item
|
||||
* @param swingProgress The swing progress of this item
|
||||
* @param stack The stack to render
|
||||
* @see ItemRenderer#renderMapFirstPerson(float, float, float)
|
||||
*/
|
||||
private void renderPrintoutFirstPersonCentre( float pitch, float equipProgress, float swingProgress, ItemStack stack )
|
||||
{
|
||||
ItemRenderer itemRenderer = Minecraft.getMinecraft().getItemRenderer();
|
||||
|
||||
// Setup the appropriate transformations. This is just copied from the
|
||||
// corresponding method in ItemRenderer.
|
||||
float swingRt = MathHelper.sqrt( swingProgress );
|
||||
float tX = -0.2f * MathHelper.sin( swingProgress * (float) Math.PI );
|
||||
float tZ = -0.4f * MathHelper.sin( swingRt * (float) Math.PI );
|
||||
GlStateManager.translate( 0f, -tX / 2f, tZ );
|
||||
float pitchAngle = itemRenderer.getMapAngleFromPitch( pitch );
|
||||
GlStateManager.translate( 0f, 0.04f + equipProgress * -1.2f + pitchAngle * -0.5f, -0.72f );
|
||||
GlStateManager.rotate( pitchAngle * -85f, 1f, 0f, 0f );
|
||||
itemRenderer.renderArms();
|
||||
float rX = MathHelper.sin( swingRt * (float) Math.PI );
|
||||
GlStateManager.rotate( rX * 20f, 1f, 0f, 0f );
|
||||
GlStateManager.scale( 2f, 2f, 2f );
|
||||
|
||||
renderPrintoutFirstPerson( stack );
|
||||
}
|
||||
|
||||
|
||||
private static void renderPrintoutFirstPerson( ItemStack stack )
|
||||
{
|
||||
// Setup various transformations. Note that these are partially adapated from the corresponding method
|
||||
// in ItemRenderer.renderMapFirstPerson
|
||||
GlStateManager.disableLighting();
|
||||
|
||||
GlStateManager.rotate( 180f, 0f, 1f, 0f );
|
||||
GlStateManager.rotate( 180f, 0f, 0f, 1f );
|
||||
GlStateManager.scale( 0.42f, 0.42f, -0.42f );
|
||||
GlStateManager.translate( -0.5f, -0.48f, 0.0f );
|
||||
|
||||
drawPrintout( stack );
|
||||
|
||||
GlStateManager.enableLighting();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onRenderInFrame( RenderItemInFrameEvent event )
|
||||
{
|
||||
ItemStack stack = event.getItem();
|
||||
if( stack.getItem() != ComputerCraft.Items.printout ) return;
|
||||
|
||||
event.setCanceled( true );
|
||||
|
||||
GlStateManager.disableLighting();
|
||||
|
||||
// Move a little bit forward to ensure we're not clipping with the frame
|
||||
GlStateManager.translate( 0.0f, 0.0f, -0.001f );
|
||||
GlStateManager.rotate( 180f, 0f, 0f, 1f );
|
||||
GlStateManager.scale( 0.95f, 0.95f, -0.95f );
|
||||
GlStateManager.translate( -0.5f, -0.5f, 0.0f );
|
||||
|
||||
drawPrintout( stack );
|
||||
|
||||
GlStateManager.enableLighting();
|
||||
}
|
||||
|
||||
private static void drawPrintout( ItemStack stack )
|
||||
{
|
||||
int pages = ItemPrintout.getPageCount( stack );
|
||||
boolean book = ItemPrintout.getType( stack ) == ItemPrintout.Type.Book;
|
||||
|
||||
double width = LINE_MAX_LENGTH * FONT_WIDTH + X_TEXT_MARGIN * 2;
|
||||
double height = LINES_PER_PAGE * FONT_HEIGHT + Y_TEXT_MARGIN * 2;
|
||||
|
||||
// Non-books will be left aligned
|
||||
if( !book ) width += offsetAt( pages );
|
||||
|
||||
double visualWidth = width, visualHeight = height;
|
||||
|
||||
// Meanwhile books will be centred
|
||||
if( book )
|
||||
{
|
||||
visualWidth += 2 * COVER_SIZE + 2 * offsetAt( pages );
|
||||
visualHeight += 2 * COVER_SIZE;
|
||||
}
|
||||
|
||||
double max = Math.max( visualHeight, visualWidth );
|
||||
|
||||
// Scale the printout to fit correctly.
|
||||
double scale = 1.0 / max;
|
||||
GlStateManager.scale( scale, scale, scale );
|
||||
GlStateManager.translate( (max - width) / 2.0f, (max - height) / 2.0f, 0.0f );
|
||||
|
||||
drawBorder( 0, 0, -0.01, 0, pages, book );
|
||||
drawText( X_TEXT_MARGIN, Y_TEXT_MARGIN, 0, ItemPrintout.getText( stack ), ItemPrintout.getColours( stack ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
package dan200.computercraft.client.render;
|
||||
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
|
||||
import net.minecraftforge.client.model.pipeline.LightUtil;
|
||||
import net.minecraftforge.client.model.pipeline.VertexTransformer;
|
||||
import net.minecraftforge.common.model.TRSRTransformation;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.vecmath.Matrix4f;
|
||||
import javax.vecmath.Point3f;
|
||||
import javax.vecmath.Vector3f;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Transforms vertices of a model, remaining aware of winding order, and rearranging
|
||||
* vertices if needed.
|
||||
*/
|
||||
public final class ModelTransformer
|
||||
{
|
||||
private static final Matrix4f identity;
|
||||
|
||||
static
|
||||
{
|
||||
identity = new Matrix4f();
|
||||
identity.setIdentity();
|
||||
}
|
||||
|
||||
private ModelTransformer()
|
||||
{
|
||||
}
|
||||
|
||||
public static void transformQuadsTo( List<BakedQuad> output, List<BakedQuad> input, Matrix4f transform )
|
||||
{
|
||||
if( transform == null || transform.equals( identity ) )
|
||||
{
|
||||
output.addAll( input );
|
||||
}
|
||||
else
|
||||
{
|
||||
Matrix4f normalMatrix = new Matrix4f( transform );
|
||||
normalMatrix.invert();
|
||||
normalMatrix.transpose();
|
||||
|
||||
for( BakedQuad quad : input ) output.add( doTransformQuad( quad, transform, normalMatrix ) );
|
||||
}
|
||||
}
|
||||
|
||||
public static BakedQuad transformQuad( BakedQuad input, Matrix4f transform )
|
||||
{
|
||||
if( transform == null || transform.equals( identity ) ) return input;
|
||||
|
||||
Matrix4f normalMatrix = new Matrix4f( transform );
|
||||
normalMatrix.invert();
|
||||
normalMatrix.transpose();
|
||||
return doTransformQuad( input, transform, normalMatrix );
|
||||
}
|
||||
|
||||
private static BakedQuad doTransformQuad( BakedQuad input, Matrix4f positionMatrix, Matrix4f normalMatrix )
|
||||
{
|
||||
|
||||
BakedQuadBuilder builder = new BakedQuadBuilder( input.getFormat() );
|
||||
NormalAwareTransformer transformer = new NormalAwareTransformer( builder, positionMatrix, normalMatrix );
|
||||
input.pipe( transformer );
|
||||
|
||||
if( transformer.areNormalsInverted() )
|
||||
{
|
||||
builder.swap( 1, 3 );
|
||||
transformer.areNormalsInverted();
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* A vertex transformer that tracks whether the normals have been inverted and so the vertices
|
||||
* should be reordered so backface culling works as expected.
|
||||
*/
|
||||
private static class NormalAwareTransformer extends VertexTransformer
|
||||
{
|
||||
private final Matrix4f positionMatrix;
|
||||
private final Matrix4f normalMatrix;
|
||||
|
||||
private int vertexIndex = 0, elementIndex = 0;
|
||||
private final Point3f[] before = new Point3f[ 4 ];
|
||||
private final Point3f[] after = new Point3f[ 4 ];
|
||||
|
||||
public NormalAwareTransformer( IVertexConsumer parent, Matrix4f positionMatrix, Matrix4f normalMatrix )
|
||||
{
|
||||
super( parent );
|
||||
this.positionMatrix = positionMatrix;
|
||||
this.normalMatrix = normalMatrix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setQuadOrientation( EnumFacing orientation )
|
||||
{
|
||||
super.setQuadOrientation( orientation == null ? orientation : TRSRTransformation.rotate( positionMatrix, orientation ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put( int element, @Nonnull float... data )
|
||||
{
|
||||
switch( getVertexFormat().getElement( element ).getUsage() )
|
||||
{
|
||||
case POSITION:
|
||||
{
|
||||
Point3f vec = new Point3f( data );
|
||||
Point3f newVec = new Point3f();
|
||||
positionMatrix.transform( vec, newVec );
|
||||
|
||||
float[] newData = new float[ 4 ];
|
||||
newVec.get( newData );
|
||||
super.put( element, newData );
|
||||
|
||||
|
||||
before[ vertexIndex ] = vec;
|
||||
after[ vertexIndex ] = newVec;
|
||||
break;
|
||||
}
|
||||
case NORMAL:
|
||||
{
|
||||
Vector3f vec = new Vector3f( data );
|
||||
normalMatrix.transform( vec );
|
||||
|
||||
float[] newData = new float[ 4 ];
|
||||
vec.get( newData );
|
||||
super.put( element, newData );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
super.put( element, data );
|
||||
break;
|
||||
}
|
||||
|
||||
elementIndex++;
|
||||
if( elementIndex == getVertexFormat().getElementCount() )
|
||||
{
|
||||
vertexIndex++;
|
||||
elementIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean areNormalsInverted()
|
||||
{
|
||||
Vector3f temp1 = new Vector3f(), temp2 = new Vector3f();
|
||||
Vector3f crossBefore = new Vector3f(), crossAfter = new Vector3f();
|
||||
|
||||
// Determine what cross product we expect to have
|
||||
temp1.sub( before[ 1 ], before[ 0 ] );
|
||||
temp2.sub( before[ 1 ], before[ 2 ] );
|
||||
crossBefore.cross( temp1, temp2 );
|
||||
normalMatrix.transform( crossBefore );
|
||||
|
||||
// And determine what cross product we actually have
|
||||
temp1.sub( after[ 1 ], after[ 0 ] );
|
||||
temp2.sub( after[ 1 ], after[ 2 ] );
|
||||
crossAfter.cross( temp1, temp2 );
|
||||
|
||||
// If the angle between expected and actual cross product is greater than
|
||||
// pi/2 radians then we will need to reorder our quads.
|
||||
return Math.abs( crossBefore.angle( crossAfter ) ) >= Math.PI / 2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A vertex consumer which is capable of building {@link BakedQuad}s.
|
||||
*
|
||||
* Equivalent to {@link net.minecraftforge.client.model.pipeline.UnpackedBakedQuad.Builder} but more memory
|
||||
* efficient.
|
||||
*
|
||||
* This also provides the ability to swap vertices through {@link #swap(int, int)} to allow reordering.
|
||||
*/
|
||||
private static class BakedQuadBuilder implements IVertexConsumer
|
||||
{
|
||||
private final VertexFormat format;
|
||||
|
||||
private final int[] vertexData;
|
||||
private int vertexIndex = 0, elementIndex = 0;
|
||||
|
||||
private EnumFacing orientation;
|
||||
private int quadTint;
|
||||
private boolean diffuse;
|
||||
private TextureAtlasSprite texture;
|
||||
|
||||
private BakedQuadBuilder( VertexFormat format )
|
||||
{
|
||||
this.format = format;
|
||||
this.vertexData = new int[ format.getSize() ];
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public VertexFormat getVertexFormat()
|
||||
{
|
||||
return format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setQuadTint( int tint )
|
||||
{
|
||||
this.quadTint = tint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setQuadOrientation( @Nonnull EnumFacing orientation )
|
||||
{
|
||||
this.orientation = orientation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplyDiffuseLighting( boolean diffuse )
|
||||
{
|
||||
this.diffuse = diffuse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTexture( @Nonnull TextureAtlasSprite texture )
|
||||
{
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put( int element, @Nonnull float... data )
|
||||
{
|
||||
LightUtil.pack( data, vertexData, format, vertexIndex, element );
|
||||
|
||||
elementIndex++;
|
||||
if( elementIndex == getVertexFormat().getElementCount() )
|
||||
{
|
||||
vertexIndex++;
|
||||
elementIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void swap( int a, int b )
|
||||
{
|
||||
int length = vertexData.length / 4;
|
||||
for( int i = 0; i < length; i++ )
|
||||
{
|
||||
int temp = vertexData[ a * length + i ];
|
||||
vertexData[ a * length + i ] = vertexData[ b * length + i ];
|
||||
vertexData[ b * length + i ] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
public BakedQuad build()
|
||||
{
|
||||
if( elementIndex != 0 || vertexIndex != 4 )
|
||||
{
|
||||
throw new IllegalStateException( "Got an unexpected number of elements/vertices" );
|
||||
}
|
||||
if( texture == null )
|
||||
{
|
||||
throw new IllegalStateException( "Texture has not been set" );
|
||||
}
|
||||
|
||||
return new BakedQuad( vertexData, quadTint, orientation, texture, diffuse, format );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
package dan200.computercraft.client.render;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
|
||||
import dan200.computercraft.core.terminal.TextBuffer;
|
||||
import dan200.computercraft.shared.util.Palette;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT;
|
||||
import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAGE;
|
||||
|
||||
public class PrintoutRenderer
|
||||
{
|
||||
private static final ResourceLocation BG = new ResourceLocation( "computercraft", "textures/gui/printout.png" );
|
||||
private static final double BG_SIZE = 256.0;
|
||||
|
||||
/**
|
||||
* Width of a page
|
||||
*/
|
||||
public static final int X_SIZE = 172;
|
||||
|
||||
/**
|
||||
* Height of a page
|
||||
*/
|
||||
public static final int Y_SIZE = 209;
|
||||
|
||||
/**
|
||||
* Padding between the left and right of a page and the text
|
||||
*/
|
||||
public static final int X_TEXT_MARGIN = 13;
|
||||
|
||||
/**
|
||||
* Padding between the top and bottom of a page and the text
|
||||
*/
|
||||
public static final int Y_TEXT_MARGIN = 11;
|
||||
|
||||
/**
|
||||
* Width of the extra page texture
|
||||
*/
|
||||
private static final int X_FOLD_SIZE = 12;
|
||||
|
||||
/**
|
||||
* Size of the leather cover
|
||||
*/
|
||||
public static final int COVER_SIZE = 12;
|
||||
|
||||
private static final int COVER_Y = Y_SIZE;
|
||||
private static final int COVER_X = X_SIZE + 4 * X_FOLD_SIZE;
|
||||
|
||||
public static void drawText( int x, int y, int start, TextBuffer[] text, TextBuffer[] colours )
|
||||
{
|
||||
FixedWidthFontRenderer fontRenderer = (FixedWidthFontRenderer) ComputerCraft.getFixedWidthFontRenderer();
|
||||
|
||||
for( int line = 0; line < LINES_PER_PAGE && line < text.length; ++line )
|
||||
{
|
||||
fontRenderer.drawString( text[ start + line ], x, y + line * FONT_HEIGHT, colours[ start + line ], null, 0, 0, false, Palette.DEFAULT );
|
||||
}
|
||||
}
|
||||
|
||||
public static void drawText( int x, int y, int start, String[] text, String[] colours )
|
||||
{
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.enableTexture2D();
|
||||
|
||||
FixedWidthFontRenderer fontRenderer = (FixedWidthFontRenderer) ComputerCraft.getFixedWidthFontRenderer();
|
||||
|
||||
for( int line = 0; line < LINES_PER_PAGE && line < text.length; ++line )
|
||||
{
|
||||
fontRenderer.drawString( new TextBuffer( text[ start + line ] ), x, y + line * FONT_HEIGHT, new TextBuffer( colours[ start + line ] ), null, 0, 0, false, Palette.DEFAULT );
|
||||
}
|
||||
}
|
||||
|
||||
public static void drawBorder( double x, double y, double z, int page, int pages, boolean isBook )
|
||||
{
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.enableTexture2D();
|
||||
|
||||
Minecraft.getMinecraft().getTextureManager().bindTexture( BG );
|
||||
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
BufferBuilder buffer = tessellator.getBuffer();
|
||||
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX );
|
||||
|
||||
int leftPages = page;
|
||||
int rightPages = pages - page - 1;
|
||||
|
||||
if( isBook )
|
||||
{
|
||||
// Border
|
||||
double offset = offsetAt( pages );
|
||||
final double left = x - 4 - offset;
|
||||
final double right = x + X_SIZE + offset - 4;
|
||||
|
||||
// Left and right border
|
||||
drawTexture( buffer, left - 4, y - 8, z - 0.02, COVER_X, 0, COVER_SIZE, Y_SIZE + COVER_SIZE * 2 );
|
||||
drawTexture( buffer, right, y - 8, z - 0.02, COVER_X + COVER_SIZE, 0, COVER_SIZE, Y_SIZE + COVER_SIZE * 2 );
|
||||
|
||||
// Draw centre panel (just stretched texture, sorry).
|
||||
drawTexture( buffer,
|
||||
x - offset, y, z - 0.02, X_SIZE + offset * 2, Y_SIZE,
|
||||
COVER_X + COVER_SIZE / 2, COVER_SIZE, COVER_SIZE, Y_SIZE
|
||||
);
|
||||
|
||||
double borderX = left;
|
||||
while( borderX < right )
|
||||
{
|
||||
double thisWidth = Math.min( right - borderX, X_SIZE );
|
||||
drawTexture( buffer, borderX, y - 8, z - 0.02, 0, COVER_Y, thisWidth, COVER_SIZE );
|
||||
drawTexture( buffer, borderX, y + Y_SIZE - 4, z - 0.02, 0, COVER_Y + COVER_SIZE, thisWidth, COVER_SIZE );
|
||||
borderX += thisWidth;
|
||||
}
|
||||
}
|
||||
|
||||
// Left half
|
||||
drawTexture( buffer, x, y, z, X_FOLD_SIZE * 2, 0, X_SIZE / 2, Y_SIZE );
|
||||
for( int n = 0; n <= leftPages; n++ )
|
||||
{
|
||||
drawTexture( buffer,
|
||||
x - offsetAt( n ), y, z - 1e-3 * n,
|
||||
// Use the left "bold" fold for the outermost page
|
||||
n == leftPages ? 0 : X_FOLD_SIZE, 0,
|
||||
X_FOLD_SIZE, Y_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
// Right half
|
||||
drawTexture( buffer, x + X_SIZE / 2, y, z, X_FOLD_SIZE * 2 + X_SIZE / 2, 0, X_SIZE / 2, Y_SIZE );
|
||||
for( int n = 0; n <= rightPages; n++ )
|
||||
{
|
||||
drawTexture( buffer,
|
||||
x + (X_SIZE - X_FOLD_SIZE) + offsetAt( n ), y, z - 1e-3 * n,
|
||||
// Two folds, then the main page. Use the right "bold" fold for the outermost page.
|
||||
X_FOLD_SIZE * 2 + X_SIZE + (n == rightPages ? X_FOLD_SIZE : 0), 0,
|
||||
X_FOLD_SIZE, Y_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
tessellator.draw();
|
||||
}
|
||||
|
||||
private static void drawTexture( BufferBuilder buffer, double x, double y, double z, double u, double v, double width, double height )
|
||||
{
|
||||
buffer.pos( x, y + height, z ).tex( u / BG_SIZE, (v + height) / BG_SIZE ).endVertex();
|
||||
buffer.pos( x + width, y + height, z ).tex( (u + width) / BG_SIZE, (v + height) / BG_SIZE ).endVertex();
|
||||
buffer.pos( x + width, y, z ).tex( (u + width) / BG_SIZE, v / BG_SIZE ).endVertex();
|
||||
buffer.pos( x, y, z ).tex( u / BG_SIZE, v / BG_SIZE ).endVertex();
|
||||
}
|
||||
|
||||
private static void drawTexture( BufferBuilder buffer, double x, double y, double z, double width, double height, double u, double v, double tWidth, double tHeight )
|
||||
{
|
||||
buffer.pos( x, y + height, z ).tex( u / BG_SIZE, (v + tHeight) / BG_SIZE ).endVertex();
|
||||
buffer.pos( x + width, y + height, z ).tex( (u + tWidth) / BG_SIZE, (v + tHeight) / BG_SIZE ).endVertex();
|
||||
buffer.pos( x + width, y, z ).tex( (u + tWidth) / BG_SIZE, v / BG_SIZE ).endVertex();
|
||||
buffer.pos( x, y, z ).tex( u / BG_SIZE, v / BG_SIZE ).endVertex();
|
||||
}
|
||||
|
||||
public static double offsetAt( int page )
|
||||
{
|
||||
return 32 * (1 - Math.pow( 1.2, -page ));
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user