From 9280fc7de4d6838cdb60b52abb596229d44e0f3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sat, 11 Apr 2015 20:20:09 +0200 Subject: [PATCH 01/37] Added a basic tutorial to the manual. --- .../opencomputers/doc/en_US/general/openOS.md | 9 ++-- .../doc/en_US/general/quickstart.md | 48 ++++++++++++++++++ .../assets/opencomputers/doc/en_US/index.md | 23 +++++---- .../doc/img/configuration_case1.png | Bin 0 -> 23743 bytes .../doc/img/configuration_case2.png | Bin 0 -> 20350 bytes .../doc/img/configuration_done.png | Bin 0 -> 241985 bytes .../scala/li/cil/oc/integration/Mods.scala | 2 +- 7 files changed, 69 insertions(+), 13 deletions(-) create mode 100644 src/main/resources/assets/opencomputers/doc/en_US/general/quickstart.md create mode 100644 src/main/resources/assets/opencomputers/doc/img/configuration_case1.png create mode 100644 src/main/resources/assets/opencomputers/doc/img/configuration_case2.png create mode 100644 src/main/resources/assets/opencomputers/doc/img/configuration_done.png diff --git a/src/main/resources/assets/opencomputers/doc/en_US/general/openOS.md b/src/main/resources/assets/opencomputers/doc/en_US/general/openOS.md index 17c5bdaa6..e4041930c 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/general/openOS.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/general/openOS.md @@ -1,7 +1,10 @@ # OpenOS -OpenOS is a basic operating system available in OpenComputers. It is required to boot up a [computer](computer.md) for the first time, and can be crafted by placing an empty [floppy disk](../item/floppy.md) and an OpenComputers manual inside a Crafting table. +OpenOS is a basic operating system available in OpenComputers. It is required to boot up a [computer](computer.md) for the first time, and can be crafted by placing an empty [floppy disk](../item/floppy.md) and an OpenComputers [manual](../item/manual.md) inside a crafting table. -Once crafted, the [floppy disk](../item/floppy.md) can be placed inside a [disk drive](../block/diskDrive.md) connected to a [computer](computer.md) system, which will allow the [computer](computer.md) to boot up OpenOS. Once booted, it is advisable to install OpenOS to an empty [hard drive](../item/hdd1.md), foregoing the need for a [floppy disk](../item/floppy.md) and to gain access to a read-write file system ([floppy disk](../item/floppy.md) are read-only). A tier 3 [computer case](../block/case3.md) does not require a [disk drive](../block/diskDrive.md), as it has a slot built in for the [floppy disk](../item/floppy.md). OpenOS can be installed by simply running `install`, and following the on-screen prompts to complete the installation. The [floppy disk](../item/floppy.md) may be removed once the system has been rebooted. OpenOS can be installed on all devices except [drones](../item/drone.md) and [microcontrollers](../block/microcontroller.md) (both of which require manually programming an [EEPROM](../item/eeprom.md) to provide functionality). +Once crafted, the [floppy disk](../item/floppy.md) can be placed inside a [disk drive](../block/diskDrive.md) connected to a [correctly configured](quickstart.md) [computer](computer.md) system, which will allow the [computer](computer.md) to boot up OpenOS. +Once booted, it is advisable to install OpenOS to an empty [hard drive](../item/hdd1.md), foregoing the need for a [floppy disk](../item/floppy.md) and to gain access to a read-write file system (the OpenOS [floppy disk](../item/floppy.md) and other "loot" disks are read-only). A tier 3 [computer case](../block/case3.md) does not require a [disk drive](../block/diskDrive.md), as it has a slot built in for the [floppy disk](../item/floppy.md). +OpenOS can be installed by simply running `install`, and following the on-screen prompts to complete the installation. The [floppy disk](../item/floppy.md) may be removed once the system has been rebooted. OpenOS can be installed on all devices except [drones](../item/drone.md) and [microcontrollers](../block/microcontroller.md) (both of which require manually programming an [EEPROM](../item/eeprom.md) to provide functionality, because they have no built in file system). -OpenOS has many built in functions, the most useful of them is the `lua` command, which opens up a Lua interpreter. This is a good testing space for trying out various commands, and experimenting with component API, before writing the commands into a .lua script. For more information on programming, refer to the [Lua Programming](lua.md) page. To run Lua scripts, simply type in the name of the file and hit enter (for example, script.lua can be run by typing the `script` command in the terminal). \ No newline at end of file +OpenOS has many built in functions, the most useful of them is the `lua` command, which opens up a Lua interpreter. This is a good testing space for trying out various commands, and experimenting with component API, before writing the commands into a .lua script. Take note of the information displayed when starting the interpreter, it will tell you how to show results of the commands you enter, and how to exit it. +For more information on programming, refer to the [Lua Programming](lua.md) page. To run Lua scripts, simply type in the name of the file and hit enter (for example, `script.lua` can be run by typing the `script` command in the terminal). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/general/quickstart.md b/src/main/resources/assets/opencomputers/doc/en_US/general/quickstart.md new file mode 100644 index 000000000..a78aee1b3 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/en_US/general/quickstart.md @@ -0,0 +1,48 @@ +# Getting Started + +Also know as "how to build your first computer". To get your first [computer](computer.md) to run, you will need to first set it up correctly. There are many different types of computers in OpenComputers, but let's start with the basic one: the standard computer. + +**Disclaimer**: this will be step-by-step, and also provide some information on how to look for issues yourself later on, so this is quite long. If you never built a computer in real life, and/or are completely new to the mod, it is highly recommended you read through it all. + +First off, you will need a [computer case](../block/case1.md). This is the block into which you will build most of the components, defining the behavior of the computer you're building. +![A tier two computer case.](oredict:oc:case2) +For example, you will need to choose what tier of [graphics card](../item/graphicsCard1.md) you wish to use, if you need a [network card](../item/lanCard.md), a [redstone card](../item/redstoneCard1.md) or, if you're just playing around in creative mode, maybe even a [debug card](../item/debugCard.md). + +When you open the computer case's GUI you will see a few slots to the right. The number of slots, and what tier of component can be placed into them (indicated by the small roman numeral in the slot) depends on the tier of the case itself. +![GUI of a tier two computer case.](opencomputers:doc/img/configuration_case1.png) +In their empty state, computer cases are pretty useless. You can try to power up your computer now, but it'll immediately print an error message to your chat log, and make its dissatisfaction heard by beeping at you. Good thing the error message is telling you what you can do to fix this situation: it's missing energy. Connect your computer to some power, either directly or via a [power converter](../block/powerConverter.md). + +When you try to start it now, it'll tell you that you need a [CPU](../item/cpu1.md). These come in different tiers - a trend you'll notice is present all throughout OpenComputers. For CPUs, higher tiers mean more components at a time, as well as faster execution. So pick a tier, and put it in your computer. + +Next up you'll be asked to insert some [memory](../item/ram1.md). Notice that the beep code is different now: long-short. Higher tiers of RAM mean more memory available to the programs running on your computer. To run [OpenOS](openOS.md), which is the goal of this introduction, you'll want to use at least two tier one memory sticks. + +We're making good progress here. By now your computer case will look somewhat like this: +![Partially configured computer.](opencomputers:doc/img/configuration_case2.png) + +And behold, turning it on now does not print any more error messages! But alas, it still doesn't do much. At least it beeps twice now. That means the actual execution of the computer failed. In other words: it technically runs! This is where a very useful tool comes into play: the [analyzer](../item/analyzer.md). This tool allows inspecting many of OpenComputers' blocks, as well as some blocks from other mods. To use it on the computer, use the analyzer on the case while sneaking. + +You should now see the error that caused the computer to crash: +`no bios found; install configured EEPROM` + +The emphasis here is on *configured*. Crafting an [EEPROM](../item/eeprom.md) is pretty simple. To configure it, you will usually use a computer - but that's a little difficult right now, so we're going to use a recipe to craft a configured "Lua BIOS" EEPROM. The standard recipe is an EEPROM plus a [manual](../item/manual.md). Put the configured EEPROM into your computer, aaaand. + +Nope. Still nothing. But we know what to do: player uses analyzer, it's super effective! Now we have a different error message: +`no bootable medium found; file not found` + +Well then. That means the BIOS is working. It's just not finding a file system to boot from, such as a [floppy](../item/floppy.md) and [hard drive](../item/hdd1.md). The Lua BIOS in particular expects such a file system to furthermore contain a file named `init.lua` at root level. As with the EEPROM, you usually write to file systems using a computer. You probably guessed it: we now need to craft our operating system floppy. Take a blank floppy disk and a manual, craft them together, and you'll get an OpenOS disk. + +Now, if you used a tier two case as in the screenshots above, you'll have nowhere to place that floppy. If you have a tier three or creative case, you can place the floppy right into the case. Otherwise you'll need to place a [disk drive](../block/diskDrive.md) next to your case (or connect it via [cables](../block/cable.md)). Once your disk is in place, you know what to do. Press the power button. + +It lives! Or should, anyway. If it doesn't something went wrong, and you'll want to investigate using the analyzer. But assuming it's running now, you're pretty much done. The hardest part is over. All that's left is to make it take input and show some output. + +To allow the computer to show some output, you'll want to grab a [screen](../block/screen1.md) and a [graphics card](../item/graphicsCard1.md). +![No, it's not a flatscreen.](oredict:oc:screen2) +Place the screen adjacent to your computer case, or, again, connect it using some cable. Then place a graphics card of your choice into the computer case. You should now see a blinking cursor on the screen. Finally, place a [keyboard](../block/keyboard.md) either on the screen itself, or in a way so that it faces the screen, to enable keyboard input. + +And with that, you're done. The computer is up and running and ready for action. Try using it now! Type `lua` in the shell and press enter, and you'll be greeted with a bit of information on how to use the Lua interpreter. Here you can test basic Lua commands. For more information this topic see [the Lua page](lua.md). + +![It lives!](opencomputers:doc/img/configuration_done.png) + +Have fun building more complex computers, messing with [servers](../item/server1.md) and assembling [robots](../block/robot.md), [drones](../item/drone.md), [microcontrollers](../block/microcontroller.md) and [tablets](../item/tablet.md) in the [assembler](../block/assembler.md). + +Happy coding! diff --git a/src/main/resources/assets/opencomputers/doc/en_US/index.md b/src/main/resources/assets/opencomputers/doc/en_US/index.md index 56de596b8..28c3a8ca2 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/index.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/index.md @@ -4,7 +4,9 @@ OpenComputers is a mod that adds persistent, modular, and highly configurable [c To learn about how to use the manual, check out [the page about the manual](item/manual.md) (that green text is a link, you can click it). You can find a table of contents at the bottom of this page. -Persistence ensures that a running [computer](general/computer.md) retains its state when the chunk it is in is unloaded. This means that if the player moves away from the [computer](general/computer.md), or logs off, the [computer](general/computer.md) will remember its last known state and continue from that point on when the player goes near the [computer](general/computer.md). Persistence works for all devices except for [tablets](item/tablet.md). +## Prologue + +As mentioned above, computers in OpenComputers feature persistence, which means that a running [computer](general/computer.md) retains its state when the chunk it is in is unloaded. This means that if the player moves away from the [computer](general/computer.md), or logs off, the [computer](general/computer.md) will remember its last known state and continue from that point on when the player goes near the [computer](general/computer.md). Persistence works for all devices except for [tablets](item/tablet.md). All devices are modular and can be assembled with a wide range of components, just like [computers](general/computer.md) in real life. Players who enjoy tinkering will be able to optimize devices to their heart's content. If desired, devices can be [dismantled](block/disassembler.md) and rebuilt if the initial configuration wasn't satisfactory. For [computers](general/computer.md) and [servers](item/server1.md), components can be swapped out on-the-fly simply by opening the corresponding GUI. @@ -19,16 +21,19 @@ This manual contains detailed information regarding all blocks and items, how to ## Table of Contents ### Devices -- [Computers](general/computer.md) -- [Servers](item/server1.md) -- [Microcontrollers](block/microcontroller.md) -- [Robots](block/robot.md) -- [Drones](item/drone.md) +- [Computers](general/computer.md) +- [Servers](item/server1.md) +- [Microcontrollers](block/microcontroller.md) +- [Robots](block/robot.md) +- [Drones](item/drone.md) ### Software and Programming -- [OpenOS](general/openOS.md) +- [OpenOS](general/openOS.md) - [Lua](general/lua.md) ### Blocks and Items -- [Items](item/index.md) -- [Blocks](block/index.md) +- [Items](item/index.md) +- [Blocks](block/index.md) + +### Guides +- [Getting Started](general/quickstart.md) diff --git a/src/main/resources/assets/opencomputers/doc/img/configuration_case1.png b/src/main/resources/assets/opencomputers/doc/img/configuration_case1.png new file mode 100644 index 0000000000000000000000000000000000000000..ae1503e768a3c03c1c05eaef8e34a498af8a4667 GIT binary patch literal 23743 zcmYhicRX8f_&0tMds9_vchT0YRiVVHR%vLpYSgGbYi}VaIuxyznxUw@YSmt?U3*3e zwPNoC3HhCVzQ6DDJbxw5$;&x8cdqyK9@qUw4{?u)o|_&304A;b8jk@0+5!NOI9h7( zNQTyU1o(2%>#m`fzN@X5?+XtbK-JpS(ne6r<%ONiW1AP&{_fp2cL3n|3oQ-RCw`cX zM$<0adr1TnZ({cQEKL)3-fJ_(#oMn`U&S%UM_-hs=?|4;g{Dc$@O*&XXAYyuyb@+| zCr+@`BA(*nPu|xw5~@1tw7=)N87q0DlIEr_J>(J^nsltOm%62l>*#+*sPLIq?4Ev# z#1@tmDvuWw91?GzTQ^!aD_lD%F@9!h^Zr&i1h!+RfC(c|04f7==Tc~aFN_HQ7r-kA z05Y~AD**=Yw<##WFUc#!%#K1Fa5Vz|{dEESrjlB~9mb!X;Jf6MXo!9DRm{(ZERl4h zLLPdEq$UN1f>Ex4YKI2(%{%i65Upk@2~pt$0GveLM{*HB!FT~h1^{O^!}A|0ETCqL z{~jTrqU}f8?M%Z9!;ia%h|l7jr`Uz=|2t7cB@%YJXCnw`zL;ZZpaK9lnBmp6cnQwt zV0Iu&vXQc^oieDL>V&D~qtIU*g$k!Chr6){a~az6!y^mYs}Mj|LE4!ez+G7ooraT> zT7B>Av`}QR1Rc#srQr)CRX={+r?#_cSF;Q5b8CHU{eF%!5CD8~gUHUSzC{*>CXDJZ z_n-36uzP-#u8{BJWqk&j424wJw^gu`F~Gu~u6pNtGVT19u`1IiRt$}W^rn-;K0oyO zU0>%{d#hQoLhOx0p48fZ#7RVpd>qcnyg8wn<=S z^RWEj0PN5xO)fm8qIUUWnZad{`m4?V=Nflh*DIF>vJys%#P&tqw{B&qfK78yxZ~BM zwj>A&9@Y==bI_rj+^psGQKD62z6|f{xY^~nj8rbD5WZJp=DLmUm7Ji zuk3{ufAP_2Z(GHD<)5POu%-+9FrtGj=`SggL_MUlwIhcm)}ko-AN-fYOw|U;0zD_ z4gd+(ArBBZnj@5Rn}{A!!^i36C7s`NzrW}kd(Lvg94zRhLQ@HU`-C~f!ap;-LULK(dVr}{T))+5P6O2#-awy*C3%^0VfxcdN^sw$N z36&}}}dy7M3mh>QVByX0O0!V{Bj09-&hE4P@XACkHUHX+T>aqlxmGJcA58vXD|(180Onw z;!Ad$Kht_|vC514LqgYu04UoqKj?kIq^nb})-BYExY>&yOYhc33yS=!#TF@{r$-jh zIqO!n*DW7aw)iW}p~$W`RDh@uz<(1-6Uml5rf?h%-yCYPL)Kihc_(2Bpt>b}nahd~ z_%gA537z_nV)At<>gSCOj2+g2#BZ+Zux9x{y$9)WV!-l#qu{y1NG^or5Hpio4DzB0 z0MGm#w2iVGEUG!mqCYFLkOzR7aCF9$#79c${SjwYGb<_m4?6lZAZ$^0btXa-LL+w3 zS{&vYDH{9UDB+@Z?$5sQnehHVELZ6d368})+uzUDvirp~%gmc5Vcsk8D^8rxQfWAs7H9MyFY#Vx!Pv`wF(8WAzmpAQ0q`%;1p#ATCb#<9Q(5F zs8q~)1)%UY6c*9cVKJhBHJwskcWrrh(SYEGhqgL>6;@6!p+s0(m_jMS?D=(JnZL(b z%@TQk%3+OKhd%nNS)U^YiKO+UliRZJtm8+aS!wkHVmvQRc!~+zv(5H2zH4pGn!=C2 zzSk%IKFb+we*4h2YD7_yTy1(b6S&=oAcoTL+Xn=ReN)-VPq}E`J@(3A$x9`&%qo&Y z(wYJobO9J?jol?3tS;YQOQfdM1yL4YRPZ>F_pzUXGUaJPjsJp(`pyR$17&Rgp?v4; zXd(ZtZDaF%^gYQJX$xk2uf*K8AKQne%8W}igNRB&YTrH^bin!((oChRt9a)qXqZQ@ znz!TMxR_izwHuk3^+2iPTLvIatH~*;_||ZmG`v{NAE|XeHCQ(boK!ZF?m;zK!e-2S z>wcPEgf-#{T07|=OwQht^IK_#__3OV%7h@5r9X2f=e<{Klo@YTlM_zHK2b3{-*Vz!qgi zW&*JktZGamEtK@9eI!v5Ra)DHQ7Z%Qwd(ll!TJp~?-%wex)6vYZV;mDkRAE<1Pa7! zY*?4J8axbqK#ilOMYRs|y(!L<(C#SHTZr|f(EbpcjQ=zlG2)^!KFu{Uu8~&B&K`lH z6YYM}nIOGpstXqRX2+Rx+8@V)<_Tw0>EM~?@mB?CSopn;j&lTpZsa%LcA1e0Zr7^u z-&nkrd-^Qo@Y&X(m4B(L|0UJ3<~KX*T^Dj)QL{Oli2G&?!vsro(|-821y-W9AOayL z#ZH|uCdjgwB|%bY2F%Up)G5BJ&}&?b{7M3AI$)0}xyj^c`ZuL`r|rParF7s&v|hR6 zVCf@n?kz|%f7`aHEHMnW%XGDawRBrhap^2&(=N6Q3x#B)(QSi0BMxZ~(4yF8 zJM5)fq!)uiRk=t>v1U4hi5H91!>OjPLM_h!(8Nqan=gI&kxK2;E^9xQUc%&bB&Q;w zrzI()68~$>uvq3|H9Z5A+F`0=NUr3Ewv<_R;X$X#(InUGemWs<3m$UTFrw_cl{%vA zy*7&5HV--V9wXv6r&qcr213p}KL-ULWC`#!u1-ZYmFx*b#oSptyHsAXEkHiHmwUQa zSlYj4H+zP!QQRynseAjzp(D7MUUP%XoL33}P^-6O&df+O*JC)^XaHc0`aDp1Ugeyk zX#29)3zlw3fBXH^D*)wrz`W&)%8eB1CqJ>`8}kOj^y!b;JxVSQEZz^lM$OeldL?hu z;i!tJTx%*ulfjRiF z(7YD%Gl56#2-amBv^7Xb!*5ZDpYkgNnLL6FE|a!q>L(nwF;z~Vnt~DA`npQ8H{oU> zUHb#k{01l!rO!;Qn-V{)QuljFV0{@qrD(+LCmUS+AV9i5WLLz^brlfn!aQdDVroHl zUXp3)5Bqr1ZpoB4gb;>XjkO56bD@CB)IR3Htm7uOjD!5?cC}8XwVW5v?o1o!4bDlP z+@`Ot@SW=Sy7c*_?7CYGeks|h*lM1S#LMe=`cPwax$^5)x5C#ZZ7(tQqG!V%=T1tUU#T4#+d?fv9WYL7G z-4OufT?RV1#1!w_XwoNKe%2Mh=M~A4@hRkr@P*gq5w|XXx$evxCvk)l^@74XZ+~L{ z!-F?Jx*e%Ev&35I?RCogSU^!x5n+;I6|nIBb`0K?>(9~lYA!maoDTn+ygdP#ZJy2{ z;PKTX%E2VRN9H&3_SYN!-ToSK!aSsLq$wNWcHzkTGtwD7Y4%B3LYB%hW80KwD-~Cn z&e9IGftXTf1d~xn;2kY0s^@&EO;%{QDWc3KQ`^^vK3LKpg&(wi>)TSn2ytV+YquxE>4Nol|7Any+~4}K=u9ol6mj;&iZINY++evYieQHka~^U zZY9<{YNGS^ZS0)@)0FU{Msp{-YC`>ilG_A?Q0HFin${Os*_xbcp1Zk1Iy)mY`(h-T zN#BJ90#mEeS^tVdd~Bf4vhcw-6^o$WAq$-0jmU`T&l&lRpJ}YwP{*5$0k6^d3V^0c z@9wj0{Il);2WRFGw3C(a^LE+q_Zu-CM~~HSX{dd8Ono zq5kV5j!>4onA{3nKmE0zL(eAd)?_3mSpSx-uX4WQ?ve$n))3#3#$sRQlrGfeBBVhL zb*)FZRY3;m{WxV!tQ-?8_qe!}Q>ykTi;EkumJ=yy*n2P`=nwnqq zETYd2atk(U%{hO_Aky!w#wk8oxqUl5_{8CM#^eKr8zkPfz%AHT7YSdjja}%B<>WKJ zzA_Q@y?=Wr@=o)$`qD-`W;kfL$jVf;=oi%ZaW2gE`KW`Y>q^SmtiWgm$&au0EVo_ zr4-SvP(bwe*%K>5Wa}HH&8Z5zd)q8yONZ-uC*F@w>#Dc?Iu&^XQsE&@B9N3!@eO-s zM~9OW?*w0g$<2e!DZA#agU!JY_hwMb*2ec2R!GW+qxuM9B+pB()5hxlQuAlW2dg7l zrw|2yrWa#$5FC$+*+q60ewEqoF+H{rqa7&B#_~EFpj#|it-p*?=2Mh)`yh~d&i*bx z?8Z4Sr`!jWE!P=a$|q#CC@CY0sVs36dxi^?UU_*Ef@~&Gp()1b>Lf~P8fbv`oh~^X z|8~Gcz2@P31gDwX*@d1^ddQU#f&Y zAK6W(q_we4{U6Z0bf=wP&}5J`J=BQ8VlY{MQe3hv+J8Oj#Y;5V+l%a z{2&EFJ&FPu|A=7NQ{fFZJgo(bVs(_s4j-VxTHcp2|MLwyg7~dC#mj7@n8MjW#P{JZ ziB3|mq+d;zj z$Ab98z{SSDZ$&h>n|C{S-t~0GhLEgsPl;IatOF4?2`5esfEW-@8j20}IzYk$a101y zdSHy==H{kLE|PS#t97_^Md0}Lze{ZYYeZ2VLCBMDm#;QYs&i@^LqM(Y&s_ij666d( zy(~{QG+KG`++?-FF-QOa4tS4@N4D5{jwk?bI+WO3h6`KHkV+bFAcPW-JHA|fj@nXK zFrm22T#5dgjL5e0yl!A6&4VM@N9BKA5#|D4Ioz14$O@QS;U)jZlHQNtJ#U_-c4gg* zjWKg&a$TH!S;>|-n%4Mwe`O$6d0?eeSb3K&>P#6)-r7FvcL;>FwA(4~U;NA;{I9K6 zqdk#xB@~Fj=^wCG6XBY-Jr(HiCRc3JqvK%WG*%Fye`)3>MiI0bXP@f zo69YLl77d|NZO~&Fx@hD4c{rY=d99y&q4ADqHqd2$4$u?POD-xquxoIFi1BjLN0e* zkijXN+RI*XhX6Q!KnzFODlNz6MZE@4WO#;g4JjW(U4>C-{o1OfIzhPISSkC4IiWm+ zd{z=B3>PLyWgdEbJ*}$`?%xhMoe0UFB~O5_S)?6LOHV7}Pdx5WpYzO=-i2?Sm9!h- zkq6%iWs%?HH1lf(SF|;gcRqi$R>tidFHj^n%G&bnd5!dL!c$ef$6KoPL7_FE^JBrK z;<4kvvw0in8rVBJcar?1kmY%*s}P`x`o^E@@`;6_ff~p_qv((VlWT)qhLrZZ3zh75 z*v%wNCQ^Qq&$h@unA@{RtKogKfYobbr@;uD>$$hRW;$I%h|^j&8}+`(2?y-y+>Dk4 z>8KOFRY~55lRXd4a?!!YITXSD-u9_xrske&pHe*Q?FQ1n?w$M-BdgdnU#!vF8YhRj zi9-*TNNK!$cBA(o11 z(3}3};C#Ka-Gf_RMSWb{EwA2LKy)N3L~$x3zi3)~zWFk7(BTGIW8LNe)}qiQN|pc7 z0AIp8KTX!Xa^o7Trut=Yy^_23I|n}h+RCf5wk*NNp21G-Ls|DK%;0`I8EdEcux4eF zLeqq)Z`ug+66Hz z%aHGf zi+;bUgYb-|yXc6G8H>wG{6pi?Z{={u>!^BY9Ze=RN1KH#eSW4{%HU~V@nVgzsa&R* z(8OtTLj%iNQnyy1)k%ybjsJLN%hvQIeh!ef7J5`9CmKs#4aFE*Gx~2^OVyl*OCM-l zfm#fvjM#afGp<$%hhPM)-tYeNmXc6nhUQL;s3=*rH*uF2t0+knGA}G&$3RGGoIbC{ zCa8!x-0MJ%*%`%XuB4pWasvO43{Sqn#gCIuZRI#X9;`yP7>M73Pm`;ex?V%G>D$mD>b$(LvNE7*t=sA3w5d2|kK>*#9D^9w? ze+)Ogr7c)SWAT?xpf27{Cx}B`ct>E8-JUhyY7tn_0Hof9MkILlNTu|t6yxI`+VZV) zK_nx#+zq=#nG1E3%eom+GQ@77ikR{U@#jJf)oP(%5uTUqJxKxK=ED2CodOakO|k># zPtum7VO1a9F{Q!VgOFqRG2AOIe|6a0k`F(IY z%+jRs$(PO$^0HmB;__ocwu9F8-D(KXI7P8BC>1mU`VRm#Pk3$78*0Hh3mpq)tjv?2 z=Gs8ChqO?}(lzg72u@d%=79Np0@`szs2dVv_2X{sEko&^0p14D;S~wx(_bY?r<=M# zfd>Iwb-l}qFZa(vJl3;8;D3qODXy7atBmDSjEuAeTcL0&{-Mcj8|2wLiKe`|5Ieh0 z2Q)k+_(^H$kH7T)i93Z&r_x5bb-y70gVoy}uwDog9u zZjypE%b<4z+MP~BffHFS^=ktvP3uXhODq<2KA-PiQ~{#fpo>LsGx(0v;T9VFDh~d< zgX(%0neMT)saUA8Lm67a4&R~JDkW>H*;mzF7Ph9)Ebm9$Hi^|2EDb$xWQ+Nc&)H8l ze(>L{nn=Zqls0@kXz*O=&)*8c5@#o>KPi1VBG!Kzs4v_h+9eR~A>e;2(MbF{f(VkQ zJ5epwaS8J)M<+)+QSgmQU9>VN8;@F96gIJ-a76@Sn~(@1>3Bb9@$joMsWarydiQ!( z)?V7pW=tx!F_56JXN-22cP}7kgn$xy1)YvP~?2-Z(!d8qXRiLvjBIDhLVgFGW`z za)#`37OWh@nu8HZ=!KPu;?x#HOL?BQ%|KUQ%x!GY{~_WqGn%9SlwwJ-_B0QEV@heA z2nQELaq}M!Mi3L5NlUoxkh6WX;wJc)L1(CBRztj ziTM8B1*xPP29$_bHJ#MJ6`XNqQz7OI*`n+KLF^zuW)#O_K&$C)c)rE~qn_e`eK8dA zYdRd#7!Dug57DbL7ont>zd8pn?FyJwB~h!dEKuyw1k!#F<()hGEIVd6A1xk=_H-)N z=7-bt4Y1*NL5+lUAQM8!H6u+YYlUfeJbn@8?!8McNkWq?W+#;JlU8^A568BVW2f!a zPV6xP@REQ~^a4*0otXkNul(HEy!Gq~F%X*WzkD%wb7GZgY?En>k7cUj&lknqfQM<= zPpQ}pcoV2=(tPp|ZUuMJ<=riZPPCXMrM&?_4qT=!HX!`b4qdi+Q;P{`?)3c;Tka%I2d3PJQ&sx_xgIypQxp#O;X>!u%rdo?aeuOs`^OzvFpBgturBmD9z|zEAbg zejeW9EB^J#dYmFq&0yh(OVYlTP<<_vx{I6n1D%o&=-A>7$p(B}5ur_)UMQ8E557}x z52NUmPN?ImesygaP(?rZ4KJsKf1wZN>w}Z#SrF3$Y&?q$fAwl#GnY5pUm$+T& zonJ+8$}HOF>3hSxMDlq#pgs9CWv_(0K*i8D1L#v^r+%vQ+@+&wGGaIwrzZ}ylw9ze zI1ky;yA&G0c!3s`@cT-tH12mbBO9`OkO^=`h(X-m$JBOOgaWku^Ih)rO5MdS&!aZf zygpD}lZ@KBx^M3!)Oy*F;$hFQ`Pq`W!ltxczdXpI2M0144was8P7e5Q+yT~x46>uU z9ns}T%jx(DuvLLZWxUJ}unLDa%c`>W)>rhJh%?*#jaw`C&sKFql0W%_e!I|WxOvo{ z&ex4~w9VpfFNt##Im+&TU#*>KuNm59dj8X@pwg2V$nh-VXFKoTOzp1 z4xV0*W{?3~x^R!1UW<H3`9+=yI z+``|^f}lH+s~d|K=3wD#`b~T{-Ly40;aI8vE2#5ri?E|@+lS2FyT#_5j(w(q8LIex}ombw>tPIOR0r6nv?o#H@4s^rDIT;_u$Q!x#}Tgf0)>!Mp( z%@-32h1Dq<{=PHJnY<|&C(Fa4ja5N3tSD`}V?vJF1yZZcZy!lf{lRd5ri0sUb)Q;-XjwyRDnpE?Gq=7MwOY z)?=!_yWW2S+XzOig0lB)2<%=>!80$K#Wz7-|CFTcw_~AC!gmJFcu&AK^>Yzm2hE)z zq}cVRx}V{Hvg^t>kf#QMmr1ze74)-10u&kF5vavX6s-k3tZ72TVb{%SyRc8(w(A=K5~pfJ97tJ>$1M|YT-qD<&B z!Kt&NbFX5*^IJR!%|S>bfT)>{MMy0r@Wj>W*#ZeTBCJE1lzJa7Y?u;XhqP?y-@fMk6x)^W?O8(JjwhQviA)dNs(lo=s~NbU zhzvZ)*G2X?!2fl;)q3J5lU&SzQR7x?DQt5f7+--Pk{fqQv+oe`ejq=|+S}ZQ?6MW? z6O#slI{xX=eArlGm))9B1-HwKGTqu|s3ar2Qs7sFv_%y~5)k13^(zC8<9E+4y_(EA zYK7JDh(U64|KT~4b(XzXx9t}N+5@=Y({=OpqE^WgLgARBe$&%!SU#D2#IKQ5_&4fYFe1l%1v8LO zSf`Bg*g9Q_@YwKNs8cuRX$&42e|Xp1XCPe(K}@nscc1kQ=LW6D)$}CVd`4eEi!r6(6O1kU6w&9Bl6n`Z-?-PV@h(ubYK`f*xsk z3oo{ym0ogC{+&0uxtgx``9Q%g68Kb2GhP|^O6r6bfJg#2?Lrp-?KBbuWRR1f@_R*v zIqy$%C)~D*Iy*H>TT|N5s~M{daLri<&qy>9#J9Uj`4l6ZHVoLZ&vka{%WfuIc=*6pV&W3zhHpUbGlN!V<)x_J1LgMnH5Z zpzW@yeapfp^t3`=B&=8MyPRkoi*}mcITml=A(*lovbtMR+Fm|_g%W0b&2^FnPf0c=NU9dnK}qfIy$IA>cl8b;w&zNZf&yr zN&i?%FiFKP#KM^$(f54Tb!~oMl*l&%X3ArS+o?w}(`T)|njz$@sHV9}7CwKkgR^PE z>{jKeLP^bR065NcC09U;JLG1i_mflJBPQ6c{?Xf;){4Gqw&rFMm3F3jemf~Ou+91= zlD$ES8yKkfSjKTLe0^_0^<$d@u>FceWZ)=J14s0JlmTy4ZCCYKAUi79dIN4{@6wg_ zG8H40#Cd7dJ)B4om>BU(0`Z5)eEQzpm%Qc-n&bWQ;G+_hEb=UclEen0aJO8Z4*CPd z5JS6B(Yh<#@iQ6{@Oy)$#EVJlKX&~=_{44_w*#{XXa(6>G>G@|o9$67iko_fGIT`| zU+m?TXIGnRJuO6rVQeIYMr`e_qUq}K>xRD1QN3Zq*9>o*r-)(%<$Y$Pnc#Z?^(d)V zAsXf>?ew<4#mgGGV_HQCUv#3KPa*K{w8q1|neDgAB>|=a7SyFDM#+G* zBFy%blNwe^t!DIHR;~H6m?Z%ujhoWN`p_oXyNRvw>P@tv#xCehjTOWDfQd7n zcQu3Qxfo4arQ^0E-6j$RyfMKs3!61{|Aa+k6?DMSr?q3O;%?*Dy}~>vvE4_qzixi@{SN(OE2!ZHI5Pf#{eYqryem5~ z?G_3@4d(Ncn?;r^XudGs%(`@k0>=sT(#p_yL62|n0n-uv%_4eELv#hnlpgS}TU#&!<~xm^7hdUx*jOdY7I=XtzQ@47S1X^uXOyhPZ9 zDikn#tYm-tyC6XRG4hX%uT_Q|_nOC?oq+*H?MM@th^666OzTtey%NpOWsxBVgPfYB z=8tm~9?a5X;m>j8ye(dZz3XS!AdA2RPs8XO(E6Q15GbpUrW<|H?(~3+Yini&*c-s! zV-bHbFYv3{37E7>zc_-rLIBES_9?3kk-d=|ELN>Wh5Aw@-Neex=DRVXhHsghB7WAP zRgYkAg8AnDm4Hh#bHN4hJ!oruzurOg4nhB4@vG#!^#^xz0d#2$yzT_|Z>=yR;p_XS zE2kryWSN`jOa3BAGI-4OlXAXyw8VYA-d)2z=}M87KFUx7TG%&^%I{wX*W^DeDcdA| z&&rVF_W3340yy(r+d)-OW;hv{JYc>xsb<3&I3T(YNRH_NZ<;c^Fd1-?dJssrqx^9~M@^m{iW3eXf6>zXQ4 zv8>AfD|Qt&|G7BnD=Un;rZn;#cKy*SUx<7A0%Z46u>E5|+{KoM931=pDPK4ZZZ3c; zlg>7jb9z@<#(tY|KQ=(=KNEM9BT?D|m6>q4tcN`g3^YfvNUHds=RDW=%-t?<117Hk zfblx}vo%j>oCVQYQ}I4RwCfze!a)xaK19v>y@G(VS;)4xe3bE4g||AL6>mcU{w3x= zA0&?S7%_EiV2!AggHlG6y)=UOrp&@u(gXV)n)lPTy)fH>SYj$3^v-aVrM1i4xu>N4 z0maSRYk;mMafW7Zyjavsbrwpti z_)J9wOJw?U{J0{WWl>n_#%3s7=gxA@`^`AJ3S1j~rgc7!KYNYz%&mMw!#NLNFeP2Jt>xdV)T#a0C}O( zwfWE|_f(T_y5_(tFl1JtTGc=K7{uzjrZpl#VtR7C8mdzU6*I|DEfrx6H`*$n$B6;G z>3(6#$5NH&fJC7|)L_Q_&r~;LcYBhT_<5KC(3m~>+l%9@!cfdzk`5JB3%@)hp?AEP z9i^od?}lmwo)RaD6BJnhfDePVj6eAU%O6laIQ&{k{FAwT`J_uEDsM{Ujs@T z;a{2E-YC(ZNefTY45`uoRKWs;Ks22oCm^}HRT5H>GxLkGrTu5*;N_x>OHl}>=ZiFU z?|A`hrljKMoCZmhZ1a>{Q^!JYERqlb_M^LuT@c{uYOL5nNrCqZ5q4?ky91C6O`6xv z;WsFXzt-nsHLTM{YSPzN?9XtS67t|pw$!tH`b~G(={eT|Aw*gEYH2Ivy1rO*fa$_dx_uBix+SXyuyAq1+~zNVx5jai2j?Vnz}UIkFD{lJiGf< z!`x}~h1_5m%*(F)&SgMI1rl)57K`VTh`E@Ss~b%x`sJR<4nI()k`-em9;ffy6TRYg z0xSPF3sfnfu(9lx&_DI?*Z*r(Zj9$E`Ro}QC?9$ImDX=5Bnp@ziqRwM1kl5m2K^zB zZRVabBH^>sbyZu4Ur2>iF*y0irI0lJzk1`QHsZ$p& zs1(T=9HHOQ`=2B<1Dhc?aTUTncFQQmQs)BvRjT-nqu(3=%V)_xgA-9+HUKbr92+h? z1`eMp=teOwx$WIrDuISVA+|UGLje^B)`rtS8gT7}(<{9kMfQDWM=D))JIS=RHi59* zUl=NQ6dsIi>n9p{?={Edqer;v&bn6beIITK!Ghi;?r_*|t9AuUdarEMAX626`yE2o z^wA!eSS9=y5WoUr`IQs`lx|;M!x)GSu)rH0uNFUUDheU<`340HX}ZZ~d6q*p7Y=C8 z&*@GH(hB+xW;Ay{EM4Hf@Uneynhp#>&ogOK=ot_OZ!KECX{Ee(t42M(l_&96WT-Ky z6<7cRsEUBcx%iKfTNb)=9QGcUwfQW7=Miml_-;eLFdCyTGaXv?DN#a7aZB*Z-6 zkL>%@35n?gCPDVkF>e5_3=4}b)VqPw49+S3o8RAbNp#&{pBdv90)&3_Dj}w?3sCzp z0ry8av<2yD)29a)im4S}vY~#(jv#h){2HB2U5D~?5vA+Q$cNtKPzsuVE{(6_D-Wrv zI*;YP+5G7@U|xh zJrbZbv;1zrABT2j7=#Pz`UYdNI=6~Q*Tn{=g{9!+ejA#-LIcI7IgZHW^y!;Q2|D^- zd;t*2&pJknJkdwJMyI#}^{{G^`1GWw_DHd9R+K8Ww$JknGwwF&!MDwoo;^hHd_wTV z^NyTvzd6K)m;h*=jqX8Y(yGh+Mc}Yo(Hk{=OT5^%q~&@zZ)o4SrM&4|*bwq5V!Cvn zyMRKZ;q1bxc=wIXkF%M)Gob63S3+JChPz`xFU}h?04h4%ehk0TS|tnr9r=J}^upRi zX5-f2n+uD_Vv1F&{OS|$ADfkze#o<-^2=Mi2=2*H1&ou=hgEN!w-HceK;7_S0hrkV zubjpV8$&^X>w$FNsapE{fS#ES`TUV+9g4w^0@)kaZt1ecQ80QaI<3h_BY4LTDxVhy z5+z9W=j&OlO9GP(6A!-g-m9r!j#2b!Al5u>*6qtIGV3S-)8?-O*cw-C_SxT7*IBuI z0s1kBve)9!Re${Y1px)A0OSuhH}dDg3;-ZAg-z6^ zMgnjNrX^jFl1_^<%ZS!w{SwjdOlU`OPTib&t6AJwKDVvuRE2c5id7{%z&EG254siXtuEeU5a&t&bPM z`S_FmFJ%woGV0{5-35Uy^B0e}z_B=Bkxg)5lQ7eURff(%Y`yq?uw0)vR%T@QMCDc6 zq&(q<3cE(DDIj&2R4R$=y~oDw(t7Y0Y3>*-fi|F1GjVgSZoM^?gHv~cMQ5G`uhN)v zyAZuoL>3&1oB9%lJKYdlx$%pKo>5J)=4iHT6+ua0v`($;Kr?4)I4sut}NNX`fMdHudOKTX{P6HfBkmRXW6?OXTu&Su~VpQ z-yKewihI=%Jl7n{nxDk?#yK!TGho!zjdaX#{crLmLnuWTh}OTRr=qOA4=SGbR;>uY zI_#F1+qnuVv2l7I32z0u^O#R)m>*pTPs_haYH?5O#l&_x57PIZ59Y#$qY)vpR%@wP zs-u{%co}evnIX`~y?^`a*%yvEk1(afn>>cg8ZW@o=(^3$4H(zt>SG)>miqS8!OKGB zUvrCOiLz0!GYEO1`~aPBGpGgQ(?FS5cEIUJ*w1UQ2jFqKYfawg`qC*#pG$-8dXsNA z?Y@5;`5?t7byiHU?z{s zJSXfZ^52w@4(@}h+9@L!J zLH1Z$_N~omp?3?Ez5;AIW&Q>R;yeMBrxvQ=z>oYSdghY%MmH+8LZa?+j^bNh{-7=f z;>GM)Txd~r26_sE5OUIJ^oWJCcNB-ev(U+ect{zNeZ;oVyTE>(mPotAmAib^DWsHl zz-``NZr5K<7%9XbB1Kl)E_|pgS*Oz8OT+Ki@}KYNx!0U%+=^o)<-?BdDMx@4(06G7 zl<@|K$S}~y&Mt}|fYZ-m*LJC9p)J|`|3!CKD98TKb|z3+p*lz_2Cb?C=k8Z0gu}d< z9ky0P*5s#K_BYQj#Qwnc-w?vUcgh(Q8palA~a}^l4@n@~tY%zr3t4q{t%- z%*!AwF;CBtm~kusvX@lw;@%5kzvaiNIi|^T6xPMJlJ0VT`>g)%3<&FeX&pRB-6Bbw z`>LF#5jQaSqYp#1_ff(FKw08Foi5u{*DB6Bp%RQIxT4il+O_*#Z?p5J3<uYTX;G6?xFJcMYbIkVbEz7xPYP#MX)> z=99>|#z7_&Kci1+#!C++FP=DLM`gXq^>A+OMGjst*c4`KvpF}Jd1yx>aA?Gy;%Ey%f1n8R{v5t-_;nAFtHLZY!! z^NG`EVF5S4;SQq&f+rnHg#;-p%zWE!-8PjxkL+^zpPgZLd$&Yi3uuoiHKopv7_T@y zt@es&`&uTSVuYAei=^#$T)l$+Fr)-Hj-^@R-|$-K1rFAMsN6~?BbcFnAp>Gq(08Fi z*JLNhG1SQM7SUExm06xW6ZI47{l1{UGPK7r9nG(oRZ_;tbJtL%0i8Vq57+g z?kJ(6t53dJ?a&9Jl)jh=L{aC@Zd;{?rgC&NP;e{)^sREQaN1Hwv7Oph%p#e@^hztuO!d$rn8U z1*iN)F_)jlieO>=)5B=H9XX27z~)Q|2tCQ*02!2|6L6<0-o}SAfpW1?`~*WaVjV+A zQ#U^TD#i~Gy$P886-_V_1_0JF$xMo$>I`j*-Y5|1W--xSMVbq9t>FkFZYb+I?%Ex# z?19n4tHPz`Z%8TvI0|G2%Ynl!{=HRc?-@_I)=+Qh=1fbfwDteyGX!g#WdDQOvg@os zxOXd0D6imssM5}8vQMmD2Q!5pYX~BA@~hPSOtR_^tI% zr5S-Rj+1Tav^^5qT=-UMTnldC=tk(uY|ogDTd#i$DixE-PyKA*O5FnUpKm)oDy?HVDz5fOBf>Xq zbYn=TvvSR!mwxy1TvKe_tq|7EjIMZhyTzmw-mbD2J~sF4uNzg>gaSxf65=LK5yH*X zb{5^;A-PA4gYd`=N-qvh6muO9@IYm-=QVg*w{Wt**eW1v~~T5w3@jq`(}zs-Sm*#qbN1+ps0JY!)!ueY>p z9ymI6Y}CDqy2K-g&#`fiHpnoys;lc>;fB0_sB)$jaPg${6Cs$~;pZB$FpNumV&49A7I{fjn*7id5$3uN?(O^ z#0lDEzIlF~RYyyho~m5&3M6q<`2nu@;=Sm`w^dd7atc=!lh0h~S$(C}8<{5OypdDg z79!bJdqk=8T)tY0U-pW;<-DSA!xo~r>J>C_DFzAIyQ)Pci#oUHyK8J;tV-1tYlp^_ z3_9A<4rwojjoo?^o>;`?cp~t5OK>BwD=+fon$d1tiE>28ZCXl%RMvP=!u@9gY9b=# zXmj-i$sS*Avd~ifr)QaG+*E05s^2(vo_3aMbrOQUZgUtbLO^5Fc={`g|z+BoacW`^NaMkF0CrNWge ztzn5IW1bst9$h^c#Mn43UZm;hYDN_yXLD|_!l2_%>?vl?saAE{$2o;v{Zb`;n5D^$ zZ+m7x#%XydFDsz@4Nc7leNPO9**LxNNK#bh`SlI(8@c(YL|51@cgjx>AUB3$ zlYN;Ii!Kja-hK7wwD8nlf2iVB`hjDGW%@)|$**s(KV_^x3BF{9mANC%A@S)gGN8g& zY{<_FNKFn={Oq36c9e6FnV_PKpTS@su5QS}LWiHLuTr7#^d-a|Dg!T>Q=uY|0I2fBbFr;bX|R)mX1~t)AsC4=X>CkQ?c#3(SZ9BV1J} zM45%LJ+q2qt?yHaiXjo7@D)R>rOmU;H2KFnFu9-hrN5lFq#kf<$*E_*jFDxN6Y{Yd zenR@#B;p%0s~30soebU`GsSmWwW#tCBPN_BCkQ|Xu`!p8}VX^b> z2%_UTXVbS2B^t>$Cs+PeyyoS#F9E?qf6w$>>f%%$IQ`aAz8HJ4kM-fzxAm*F9bFFq zhYt1v3DIJ0UXO9xc0V1Vso}nZtA&NhCukvyPgXvHP7nOF;8T&0T`j$2G~oH^j?8aA z4C?p#Y8Cfh+9`_b=U%E%J9K^D(&QkVmOPMiZrYL(@7K5da}v%z*d4byF)3oT_}TNS z!iBwuw-&ghCRH7Zr&&W}ThCZu#9ymM81u~1df&X7sL6)5C&hj1FV_fB_o@lIBNzOpo!5RF=-)E+x4~+2(w_*p%I2ZqLzv{n>_E^F+}DE#174 zarRFo;}0Cil3N({D~2zfRu*P{mbt512fcjCd%;+&=fjUu)12|)2VX-j9rLGnI~j;o z`LteN6svrEix$h~>1f$!_j0q_+^SlCPc~Y@L#h#RdRe%9{ZdNO$=!a+gYoOusveEY z5+38P)=wUI$4Pj6msf2k7&moIdEa2|=!(@Dy_tcRpH3ZW`g!c|KHD}&+tV=g>OG@+ zW8Regn{;t%Z!Ib5uirvxcBOoJe$(o&!MrT8FJQLevRmwDCNW*BS*uUT#O17n=byVi zue<2XrmC>tpb=6PmZ4$MLVxJ#<@H|5J#oAad)=x@lGD(3SksB&U5qQrZV>kVEOoa! zyK-3cWT`7Wfx7V{31^s+&W&0zrZeNIY`zHW=NG-yX%(=}U=H|%8GYjM5q3{Ot0=rc z3*mT&F=LFv!h?n>E-_P z%^cuTfme*d(l99H(1{$*Ew?j>DgK`_#!}ZyI8*H*C@~6?QZ!tedn@f@DEBdkKGht^ z8|CCfGR~B-n*?15?c5$BWlbX^lAOuVJ95~RT+Vfhz${n5olECZpELDgRyp{q@wZkW z&r;hf)u|yP4`T9KV@}Eo<>60Z>vP${B>DVv0Q`ESlSwsnB~OPcaes-RKvPO5W`kiV zTIaZ@hLikKR#2uY7dVA;%e`Wh+JA`y3#}Mv^;5c;PTRj6_EEaIE_S0)u2Nbv>asqKR>2+SNI!tW9y;rPlGZ!27w5GtL#vOs&5;KH;ZKhNnthnJWFP zmHyTsi>86`OqtRXySkZU{Hb5iw3RfbkiizdNYAE^p&a13YRBfN^pNviIXAk*o?upL zY@y$3s#>I;pfwkta-F0$C11>hdaKd5k{jAIrx@ninXi%4LD@IW35vP(skDCNJk`xi zJg!po%vJRz)X&t-vQzEMm)x7Hy2BhcQR-J?cs!Tyn~I((?-9$jWkHZ37!zhmV{OK%&g zgCUzMm2pk|QtlPExnt3jKs6ZAvql9h1GW z`!(^DiJ+&{Hkg1;3;|m%)vX~#A0;UeG0I>g1jZQo=jsrVB%e{n4CL7Fw4Y>RJ|jr! zW`qHxG{HUeyi~qON+J2z9@DDbd?kg3_S(QqBCk@v zDc!6l>67N5D`V0(28I@-j8Olzyp$}0h3KT&0}<;tQ*x4HH@n3wK4=#()Me0?hTd|( z007tz004Tvc=!ilNKPCJ&7LJkCx<>mgl2n^qmolnDWu0wYF3eqaGX=6QiNuq+F7A7 z)1*=uCGSG_8>1_`7m}Z`cWRE~l&(ISh#7FnREi-|ca2bvG^-BMRia#}6fsBXO6-$1 zElcw?BxVIECPl|6R-#hss7p>THHuX!=~o7gJvITG8+&wiY&uLzilgRBjn@B;*$vGn zc@r3mCRIav!l5S5e^BbS5y+4+`cz6y3YVrzgT&@&PNEwk`FGiUm*xQXIOEA#IK9Ln zAUWtdRi%WX&{$&Yw@z82sHc^MoHWYGSbc0Zg9SqS%vN6pV-6kMuJy+?b#n6{7joeAbE%j|0 z`>EN$tf80G9!OUgC2}QQWgH@SCtYpUtR9o@@}ae)99Nqx(${RTcNS{+8WR{ z*HOr|&(4=V^J`@`I#vDCQY)gp(|qo_tUax;%tgD>@163*z?A-!@)add%IeiV)llcW zR^9B?PDm#C#W9uwkuvkr94)9R^(9$NGe*DjRWf^sT}9IDn2kB=*$AE+n)PdsPYoGn zP4xmJ7_W4dDc5dm$*NaqrA)fpH$*e-3YfNRku;wa{62OQoHp9l&iG39MKi;S9c%0g zWN7vtQ}bA}!e#ni-Wg*+q^0uA2p=Tx7z+qB2V-b9 z2TNBLHNmH*Y>+e%j*)5U#96b+NHa;5EC?8*`_d*UQD#isrmvWdKw8^vOx#zCn9W<# zjcH>mk;dpYpr@2oj9uW-mRXggBBm@hg;sSXzD*Mo852&I7~_p*!+UCKmezhdeG9Ds z&vl-Aj`PEf(72TBo5mq(&j*(V$2oY^%6aa&KNU)YPfgHMqW`U*=N?nNAO{U36LhJ3 znn=5#ad0W0H)D3Y#{?y@6FKd|L=HP;GTX&mpLV7FE%jMHxBZM=IFQmbXIzphL(=rG z+%layUd@;16d#gX<}@ip8|wh4eCmqX45wKMPWk*?qMlriPi8Uw*M4%#x%oi*$-P7! z%+UB^KI7)7ieMBxDp`9p6}dlm&+)tzTcg$Sm_sgdd?wHR``8Ud+Re|gc3>(Q(LO6h zzH;kq>ig%e!XPaJI7WYC((Pu`P8O^NLM$E zl6TToZ|M$ZNp%CG_^lD>M$So+^dvW{uv3FTMl`8R(t6y|3M!iCNo#3p)3+q{Jf`A~ zbj-01+$PY)7%Bz$ZL~_?7Q?6y0qeihE^eZNUs?IjkFs)H7AW4fy`JF zU)4$?H`4cOd}U}H5`UvTxy}f9W`ysN_|nTTmI4v`nJe|!TkW+N;hySKRf$i{nw`8u zfqqCn=S%a1tm3~KImnf!GR5bb)V~>%mNt`nJlb)`e!`ao88I?cVyv-alTKE(Ioujq z%TakG#U^Wa%g0tOC{Z0H#cxXJC7JBn47Mh=a#8LhiBtTf_CC#FHl=N()(>dqOXE)l zq5NqURa1E$6X#sK=h762*x7gN()8GBX~}oT>}JpLzLd{YQ=}A_0`$+lJ36=QO?hyE z_T;u0dP+arYO7yJd2JHM82kK^$8v`zwz0GtCX~0*N5aRfm>OmOOoYtFY``u-=h(EW zlxh%D+0z(Vj;*wmGv&jW>C!liLN{XinVPy0>%%2~%b5n1i^gyL|8*o3|)uW+-G4frV8pkZ*TS`z7>T4*iMfzLmyJKsUN>@{)iZ4lB zFaa5s9)BBh@G-I+QwbxqBU@^mHGG%u{0}`t8eAEp%ZJt0N;W2L!lV`z@}lT;Vb1TxaHM8?REk&UTfAfdPRI7-Rq z;nbBH?RcfDM=`r}V=D=04mAkPu#M4uX0(ELN(_B!H3Cgpxs=opt<8#E^^;cZkggVK zYja9=&&N!%Y=jI-X|DOoD6K-GEvT2A!Il|e8*jZPSao@i=9hWZm) zA=BuiWVK1NStsU@8B;)(HAl8f_$Xb4lJ;A3*oL;Yt)@P7$VN+PtXa7=M!u?Qg!Wys z$<_!~22*{x^c|8fNk%9)vFQ^zsykSPebUI5S_ zV9ZeixQ3Oh95NR>_7Y#8rdkQF`RnRbzt?=#nCojoiSrL)=*xU?ha=S6| zJXGmwqo$;kbe0~wvLRWai&;I>)I!vhiqe!6k*<KG_JvnR0@l=8KIs$60zxlXP`SyK)nAQf0{I zg>p-^Ut=_@e`CLiS-qF6#D#JhV^(jqE0ZC=9(tZ+(xlDvH%6A9YDVG)ZDl1%{Ghh~#~%xSKg{V@_bU#lNuC&7VwS8V`t1f8H0XkYev-q!)@;Y+EK ziB03u6=2OVi^k~lyreTI$w3XNwc?~_dxwNjyE><>LLgCqnA)<^;?vrd3JH&ma5c-A zxSUl955`s=B(#;xz$L2(n!3%JYtow0MnLbe)i6zo9!W)kkc=3k+p#ZQNgLy7?5Ahx z7a5K7iuvRz)g?`NJc;f}tENcgDdnhD6IeNttc+?7X_EZiD9094O+<5Kz2=Llw9<># zrfMn{8KDi2Nk!C@YBUPH(^OV4LfP5mtBujs^p*MyW8_t%H1suzG8Hpva8e*bC0}BW z(Tq9CP2y}fInkKYi;RgsNkt+MQezuaZ&#`qlIKf;17qShX@!EJ*b`w)gxthzuF%Mi zlpZnsHv&D?ZYt0O1TnnMNk?mRj#eX!#-ye0geH&DzZ-!Z8>PM&q1;P1@M(3`7~SR@ z?MA@Twdq3(G?I;^+Ol-1M_9)kA*?;EQ#09(+2|{^?-DteY-EkufT^93Nc(J*a%&^U zFy`Nll2;}{b|f*L)E0?jAwLBoxADkbxH+bf|6F~KIS?cF+3qC@{-;ceO7Wm{f$-Gx z)HN$>Ib|-jfO_n>Qw|(4g?L#yuunN)X0F2XsmEmJmglJo{pXTPTS#B$qSKsqwA93< zgk6Z$k-7LZm0aaKY)7kiQ3vv@s{)ZT-z3Lwz}&}B=GX}@UG7gAqe*J#u%j!keJFR z$4nG8x|*%8DJQ|1H8ZhV66j05v-HNkl60(blL>(5rn9lvM)TS>WL%()}B%#Ex8g30*%q1?iKpI39Qzn1iRYv(aoB1tedq;-dAeZxOVrb=5!p%dn9rZ zv->>e9_@MR8X1W_$313(7CJd8wZA!JOnW+-QOJ`q@nsKVPBe;!w-k+e3aCdW!s)LL_-v3Ao> z%7F?-G1ib=jr~o-!&1j`YmTy%ykjgFmCCWE2CfmxsCH5#IiA)iW!MBJ9!B`A&?I!s zc1iA?^H^?4KaGjo6dY5We-P-ym|hG5+0yJSk>-uY@=4+s#>SANFJrXKdALzX&Nb;0 z+O#rlZRe85f*XNt%5f~X)JI6)6MBa9sQ8e6S%HlV$zhD0lGu)of%Cc*;2iZxTLzyP z+U-+JUt1VQO?{lIJ~cF7cK-nY{n?Hw(n`g6a|KvCYmPb6E@m@P%&L&)ccD{9HqG|6 zJ5k4;6PkURz|2&0Or!QwdT7QdJ;6piBNNJ+F|rB|V=Eq7x|#?XidpT|^wSvq>P1K{ zG^`7O~rK{K4RekA7Wk@bVepYJhG!-=lrEQkR899#g)z~K^u)RiU(=_~)9%HXP23)#0 zWR*0QoWN^@HdIn2#0YKrW%sX3fhajsh&@U(<=D^MD}p69tw{sG5Iv>An1%+LoYPWy ze>s1b<9du?NjXwn@+mMjk1J>XSBPFQd4y9Ob328MYEmOiCSFL7#h&8SxfmUh*pnPb zy&8qB3oSmx<~GLkLF*%P`0G-3H5A0e*smDhlp~Kh7oBqDd24BAjC@az#*Z1rM5?5{ zA5DSCh1`Y2=fYIwL0Uzw(lM=$t4E%Kev#|266gm?)2UQlegI9(n*s27qc1|PEh?SU zFiZQWxi4ohw`u$(j+l;}aO4oU)mE;+{Aq@X{RMIc5tv zDh1>SfJ+^QF@=DYE}lN6T%;JfQY-aSI=h^Qpv-0bYyG+-b+WZO)7tD&$rJlZ%6_aq z&voprG4ZElX&05OnSO$vdWcTxiLWihzquC}rkK!`o_Hre|IGk+DLcDCIbKf5|2gv( z(T!ooBM>(Ie=JsTAv2}?Niz(V3Tfl$px6(R_ z+UH6L7gI-6x)~wnpbY6|xOKEjp@$h6W2#ZKf#*sOJCN{Fx@&f<9doe781FQ-tBp`! zVt5{^44|!iAgwN-*??pfx}ZIPC$xc7I>xCtAm!M!DA9ZE<}_{HUG1i})XhB_|E1Yn zY)rW7O|FVJl1eaA8!9=}O5#^ERRoN1tj5S|hZ~{qmKeIiw@y^OTl< zn$MM*GC8>p<*4uYUEy1_Apl8Y=X|jl&Oogjj_5MWAjZ$`I9cD#HJsm_*i4|=QQWoUn1pi zjQz@?t2V+$#LDSdEG9XiX7s(6ra-)joj~Nivq4!j?2ODBVoRaKtT2QWWiax( zbeFc*y>Ameq%*4>!MLQg_jZIU-s@<*69_;hvwX=6Zb!Kiw4<0I?-*H~LCtFAu!c{e zdyR6&Yd!tZ){B&`(yr^@j$+kf6K!`QSLfErwsd?u8`?WU9SKdG2Q!`?Aeo>^CL6}c zPfpx1apl5{U==v$@zf#PB3%(5tTq>A1!|Z;~s?ik#h`n<*>I+LCONiMggk zr_^^0CccE9)PG4p{Qt2tLMeL{B`LFTU0cYm$ex)Q$+*|%N|DTr%$r%r-dPuwt!wYNvM%@H z+83AWcl-Rl-+#V;c|6W}_~U)S9Bg!8is71|a(JW-Pm8uO1x zqe~vok{?WhT5(;idGe@=>c`WFylch_OLy!D?ru71he~t-bb8!fp{Z??Vi(^{Aa}iK46_KSLuYh!>Wf`!uHP} z7C`x0dt_yVU?7x?+?KyX?Ncw1!EXV$(2(2SmIXSx0iIWSjn(se4(x}4!W4_!`Ryuy z`DK<})Y+<=yd8d+k~L5ZuMYVCVt~!;QgI8DzG=#@kpj)QqbQ}bzYELG@9*7#xotF$ zu(=g81CMqBHfI4CJNe=s`S(ono_GY=DP6c?Lf3=Bnz4#S#Lr7);uOY>%a1__kb$M{ zH{B2Gl*$3py!!-d`#E_&d*#M&ChMvqFptNx{2Hly_s9I+ezyi24oUX`B<6K<%<-wxe%KRtEfm zx>e1-zn;El7JA{i6@sLLGoMNKGra5JziV2h3#s6)qyd1#L9;{`OMhBM%T!10h{=r4 zB0X3#aS(+reP}z(>jpq=;@FuR&R-o*7^PZ}Q2{ST@ZXiXMpMwg!WqjUIRGun&EFM% zcpgI~Tek*=P~d0cULz~&0d{9lx%;#6>w?o*vBS|DB4^Ahw7|8Mh=WV$aYZt5uRZbkUt^AcWB~V;wk}H(HQCz~1VvaSH4z~w zL^md9{5wRyVqdtsQ_(r-(Y`K(b>0dx;0)H1$+K#JK)>OIC-a>a!Z5ZD0jW+IGHFPuT-j1_}Z~?NPGe!pcGC} zrUnAm-FNBrNp;O5(84?X!FsnigY=m4NCH>t7JOx_ZvHAz;Ba3~v75{ab`UsxBiRXE zSplma{Xi$7XXwgU<+H7Y;Wpul%C;%MRr|aVK!sIF?F@#8>S)*}*!)0=}P=>3Cop?zsal!PN%uOIVT#C7^!A=*}Q? zv-&r1R^XDJv4F8Tjck3e6nDbprg6Sa`O4-}3wFfn_c3|s-OEx?=G$iF>$-&N%LxBc z*6wi+g^%+SqRwjo>s=5s&q^aC{6~gedKXxv`&*p4VGNRI{7O_FM!|aT|@)QMpHFXU-w%^rZjK-AuyT7o8h*`tGhT@S2$vSpmqZaa!yn2sB*% z(e)6*PS~;d^2T2iy8T<6T$Bd$j7w2r=Rdzu{$dm#zk2C!;l2+7^sm`EeU~4f(o_XJ z`OKraJ3`q39O|DMQhUpd`P4t~Vg{IZ4C;^Vuh0r_$$s!)0Vu|?_b#mfmyU}}A1nr8 zEOnpPS7pf4Od~g9;mddBFEX<;W_>=Wt@7;#V%Ltlw{7x3BlatTr0Ev@!qU*jt?mm57%ifRV9_6y?GO*ge^viNq_)e$Bz z^{svlp<^z0yK;sD>UPNV$Hsfjvcdqqf+eY zu!l2Pj7bU3<;6P?A>e{%`HiSl`!%qlbxn@5WU;XK;HD3&S?#z0 zI&HR0{A+FYvnlhDeHZ*o^s$H8^s|HWsI_A1e%U7C)&gSAMeP24j;*e)E(EHDzTK@4 z#b*w3sAE~#iT9`tQT%3MYC3FxTJ!!i^A}$oD|jV|JWo?rDEXF%4nOc)#To3*purv{ zt$Ii85(iZW2<&p3>CLS>KSP^;K%{&2mo9dy0m=?qxC4^2q@C48W>JYg3j!DI>0zlVu))?LRCy+|>&(P#@?* z-f;Ke#A4cF?Xj0CSuHA5C*EMDR5rn; zC&-cJZuOxY`C`0EJk&s*s6q`xs`A?BvRIXl2k1My3sJtO>?qSUUA+;}{U$}fK1=NV z{Eut)xl*+kmKAe1WZ07f^3Ff4m^CCNYkADnNsgq(KTkb$C(}Nt&uKbA9T7wOPDEml z2GG_IW}R*1Ue+m{_Mo;EP%%QrkMO(BHpB!CLPd)Ms0DT0EfaW-l%hF`K{onrJl*Fb z$DSf~e$Z{N03<2;r1FK|^SGpY~9Qqetv)s^`bM3wANTP3{R6A>*I~RD(y%2;y*( z?|nrhHsPYBcu4Gg37x-hQ|-|*61w|K8@GFLg1C55hay&#YY+}9^{G#i47SfJMiy#p z`*9shdRnQ=qyybNpGM55puVJ8yVjwO8X7q~z(x3tqMYs2rv{APB0i6wq2%b-DOm)W z*AFY9GwSML&nRCfI<+>_K^Q{p{xXG=y}n!ULpIN;Ct8Z?_Ik79T%Opy?L-v|vZ`0Z zvO1EVDn=x=yi)px&no`FHp^V%_Ps>U0L(njY+p}Z{=ex z8eeTG%=9G-l{UO{J6d4z&BLOn@I>Nl%z4;F%*Eky8P!HQOKV=J0(5a-gYZ$)sk>U{ zPnE+N;`?`(I#O$79}rc2LY<|2hIX5=6;cj+E6E0u&Iz(;oo3A}?HS~V- z+=pciW6#3+G}QD30c9p=Jno79Ymd$EJ2t3bStGxI_qAeu-o+-LL(A}Z6YJ1Emy4gM zZMNULGG~87x|KeI&qWH(F(T-=BV6c8!kcYW1x2fUj4*EEdF}SzM*+>Gc)!hT)QyU^ zBlCigr|`wZ>81PUt;H34&0ceuJy%07gV?*wl-?Z}&P0Ve?Knta#uRopI%VDW60Aj+ zIz}r&Id8Hre%J09b@9`p6K3X9Lv8o5ay9_VKwWANlc4L4>bjCk|D@Hxp7#wm8rg{a zn@o`{iDru+d+Zi8&7MpDc^cwskS*?WyU}CrMV%U!TIalTAnoka2`()?tZHYYeOuvg zyZlA#h+;thS;*nIQ$gF|sB=<(5F|<%^=^(emSFLG4YzOarR2f?`y^x`36&w`eD8eP zsm>;7>tR92_MfJtwWRDy^jiZ)aeWpTj0)I0ps6o!68$1`4ScwDxSt(7*34KA(_)BV5)-U(vt5Si`z2uy9mcc*S zFQ_s37#-23LY%(`+IF^Q4wPzQ9pE@lsKt)YPJ@0tQzW&%^lba?=diJ$vkf-lj7z)6 zfahVn=AHK7BeQ}wh=qB`Y+FdKWo}Z$S3r z6+4>m#Kj0&9&?K`vcmB%j9hO99eUHBGXqlZ$ND4Xey<1U#VB>tJX^mimN9|059o^p z*nhhH5#FE-QxmT?rVfliC0-A`G%UexgNW6PNTjfIu1ZaoST;R%RBongNYlA^LkK%r zP0Q*p|2=kj<@lRO#rJ%?A6Rpb)UW;89Z;*q@iWrSuha-CM&ed4a5Nf(nnoK(YD!PS z<%07+rF`oOsA@hUz8G(heuDDqxl+*9?Anj-{V1Td3QpN~6Cj-kyMMBe-pvr?&x+MZ$j+rg|g6uNmqy3 z*2Vo-bp?220=;jQasO@qeP^!jb_XPQVK;sOl@mg$5)ZU4shB#T^ApuG4Zr)%6l~YZ z76P$MN!AxOpTiJ%zZS+F&sLw75#DbEf(Z6(ZtdlkC;n(&gAmE}DfVb-DSt#Uc=Pq} z;byi~mQYUcs0*n>>f6GUjL=ialhh-cAN*A0+Lx7msliO}<@QxMjm>F58M#=1;YsW3 z`9vzD+dJ_=R#u7DFMZ)bos)E{Eos zT?#FmU+X7u{M~GjZo1AnRo@@Pp!cm44JvmA(oQI)`P52hle>7Qt z_vmc3akLH#z4z*|J+>AeK}6u&hN}21+QnKnYZmsy4hs0TCQzSI5RFst#Gm>FNYv?z zGh-}cmHwR_^N7ldk3qL~`ZUqzjV+@%7CtiA)-{Vr-^hGD>0v7;I?IqBUPJ2A?-k z-f!&*ZS;HYf9I%?_{Z1Z(;D;qVR4ZBR35sKxX2bJ_3863e+xdP*v}1!b%Rkq@Vu0ubLlLQIiXABNrV#?(gfQ4#Kzie z7jowiVO}XPq@j#x7@uGV40hkBMvW{90>ggfzdj!1iP)AE3owD^k}4#C&p&S1jjtNy zZ>my+3(`}Q#4r^rqGqs_H!QE7mZArqQ#;P_kAqUpDZ3y&UvbO(i(_y>N1Ioylpdg` z);4v7;*OHT_MJ5dexAq4U$cKsgG!)Q)?jD6vl78<9IHS)UT$l@IPOu>|JEM8Vxh|u z@=Y12($4YjdEy*ck(S<(PF6@-fSw-rXmyr(bKovx|A}8`wSr!b-o!Rzp#g z9h71KaEmgxTFB^IB=DdNw*p+0+IN8_K%%kt9}N8X@n-#4q1|Ima3KH<2k9kt&Fqra zP27<)J{YQdVmu_b_wejoZqHE>)@VzUo*IAwq*w4I-t+!Ow7?UTCDM{fi`@1Nb#WKR zU%@%^_g}1)8#GQ~dypW#Mh1oDjlMs-$9p?NlBKlsk{_Ul4H@is4B0;QcI=?hRbr%G^Ji zdhGG?WuL6Am)D3aaj`R^dzWoiFCnc?9~;e5+SWd|_XzPdSZuu%GdAVM+uY-V3c|JZ zn((8R*@zKgj%!!gA(V!cxv>U&U03P`jKIyuf|n-rg4wR|0Ly}8UoTr%NwC@gw=lPx z=}TB2jj)**g#-NlWViVM*fc^2>vye~g5e9hVNyrUp=b3RL^6R_A=B4#5)@_#0cj$& z#%<1#Ccnd~pBW`^gWiN(+FTB53}d=TeuCg5RhoKO0iFR9lZ& z=&O;$&Z!Fwwi{=2vSgC-AszP;TX4TUZ&~dS|BlUCd=;|&r|^USjAI(d*6%EtMyDXH z=z5AWF7^~-D62M32F!dRyojdK30|0E%Uq~I0cLMT- z=vt%RW)VaSMT;weE|9V9*~ksp<`Pdt0KE*T6H>JBE@fq8oq=F9O6l@vj0D)?D3G5O zxO~G&$X4C=%#*n0`RV>h6!`_Q;UOA3)iU>{qLOAvMk30Xkz>pG^NeR5UX-WiHl_AY z5))!Lc~m{r+T1ehk|Q5L!X01BvPX3Wvqw`?uajU6yVBVrIyO|{(8xUGd?ew>?DW(H zx0`n=^7~{S5z;b(I2hH5JDOWKk|yl|ecYIV5>LGne}trq?Aj;7F9kb#kXVJcB46Q@ zUO%%cz3y7pC71}Wbl z9XXvgjJyJNUQnLO&ajs)m}g;BUvu!K)o><_SdfKh7-3Ew?|?ot2RWYBPgzTaHe!v* zLpNVQJy9NYp5N{IT*O30Ik$fHoMMY#%{SMR&@%dgPZ;xg>s*6J#<f;k}*^!vXD&T`a(&X1XRj z&8adFyX=Ad>vwQ@*u*wg6W8JtTpBI#qIEOcbDsfr#d02*HzD(8#_YwCn$Rqrpw0z% zi-uBWon3#`?HBQjncfvE0W>eBHtKzR4RRDc>bAJGz)_TfUDxP5{!*gM3-O=BfenKMKd7c5l7L8xL= zt3J^@nNQ2L><_hctK95_0aF%B29X)be({$4yb5H62H1OMi z;luxkE;=g<-BK)yX`Vjy;PaeI3u%QL2CSxV9 z?vJ4q4#$I%k5CmlZLO{Mabt@ z0UDn#H;6qF8u#NiZS6Z{s}1?R5R~ctYZIVQzFy6K6JQ1RrtQKq$rrPe>d9cr1-?1a zN|XTkB6;?%QQxfYRpmv>hoaP`_muCp2nn%%u#0_L_zW(Q{3t|U@iZN=563;2Ez*Ze z&O+xGA5zQWNS>neCJ9gL1mrXidsPjcRBp`;Z^X>}6DC79J4hN=c_WekWfW>R-tT}& z+^iis!nDW1Dddeb!O}7)cWc~mKce2l3NV%M2zlxM2yugzkU!yQOKtDk?(uR$Og!Hx zibUG6Hm_U*pQWdS_q%E;*zDphDOl`sQWCi> zckhD_s&FSjnk-Q&_7<15q}q^Xv~VvOHRb`0Eqe2x90p}v7O89gtKB&oLlh&0d?6WO?z&6P@Z>Cp<1Dmb;N!E|w zv`@vkn(DoW!TL4gHAyCzuy2AFMdu6QseFB@MH{lk`)jG3!iOyMx{woNQ{@6d`-%t_hxznq&0A_A^l^GQ{QoQ3)W$ps&9@ zO)qKKSoeW{;3>hCZ#VB2e&uPZTau{;`LbHvDL@q*dQ5(2_6^6sEpT{7-XRLJeQ4?2 zqT!+9EUQs4;QOh1sR2RXB}z|nlUZR@##}K?q6Jv!{az32YRSKpi7Gjr{_r3Ys=GyL zBiG%g|HEVb-mhg6E6PWaTFvm_{4+cQ5+q}F-M9!ZVsrLk1hFgS1YbT6YgTf-P{06O z#QSxORaQk)6$2vWSY8Y`^lX_gA+H_uDV)0ty_QHma!ankVOm{VgvDyZ^yS31^UoV$ ze5xF}={JwzbwIlNI~=I$v5y+?2jxt`^l>ptpPJ$tKWj&c^+%6CoNa&?WM%e( z+TFVCF>)PQGM>o(v`~y;j<#zI>8vjU7c%3j^804~GN08*da95NqTK_bsOm>i)e)mT zb)`?30_Z+wv>{(Jz&d3?ceB|}$6j~;1dY%zhPHT3szg3;i%9zG?K zRu09<@H|6L~lP&@S*mDz8C6|9puSu#% z=BXC9*(E%Y_jv@ArF7cWjFGitqq{$GZ+rw*xlAgwEyoMA^;A~$V-85x3gpcMqgj{| zN%2%4Ak2jkJVtiW`Z-dwB)q**-`F*j0h+YAD6Qmb4_l3~5jGFCU~O;+X&Z->X=V%5 z9L$lhiAd0;%Zew1_oV58t!{er>&LXKW(5&lA^N4k^Ow*LW#LqGK!+@%NLJ|qloS$r zV5<8ba%dnmNx24eEb%0^(c7Z|EOm-DoA1K2)sY%q+QAz%^P$U}jUgvbm-)81d*)kW zn5Gze>1Hc}*h6QUOIpPm=>>SDOiJ^ zQFa98yXiT8zZIHe!8UFJkc(X6V0*)XcNOiW`+$#@VhA3^V&0@YX>?%!!@}4^oUBAjgx86hD1=o7pIeiz90zhko?~dhXUI|uP_Ac42L+)+klH+7c;)T1Lav%6LHda z#K?WC_IajO?Gwtx`^U3xC?{;h1?9i2@U^updtAi8W(JH12X#a=aNI@pFb0!MjFQlb z5-|MuIFE?43aoQN!CRTe$s!L^M4b|~A5ycL9?oP=XDe1w|Y4*w(kUy4P)G8w&q-gsARMCxtDw|CJa?ayJNmVKa^> zFE4Es{wC)C4|5Vjy>Wg8{R4_9HfUI$iBi)%hg(kv9RP=HKSnlxTp=wZZ-RXqTmBy6&24*Nep5FMxUw zr^^=fpUeH5sM+|MgktYd9R#9%ACFAqiG6IyEjugrp0Ou3-YwQ-K+p0^N~{Y;}* zd_8F3{Pcum5lGEK^;<&D;|TRmW!`28v_qw)nA^GfG? z(ijCWhe6YR^2JLj`~Xr#Rz8pl_{Y#_|FE)v+W504RGmMabX04*_h><>@I1gJS=T+a z!TQ6&&Q|_bQbCEDY#hp6*wiGCliucP6++&TdWa${AbDh=MUc?8yBKhp6z$OSE{_XxxQLM6}J9dEpv$B=|ZDO1BwQ{#2RLd4qNdLHx+F3=S@MeR!2rzny1SSK zaT^iR)~@3dY?9^(QQyiQ&1+Yx@;AhxD*v)($QR z%Wv-VTt5j4#VT~;{sXM%?aT2OFYEkpvm~iPuAvmXG+E6vUgVFCc}6|@sfXDu9yQXS zCPeeS!j>MWYD;2cztK(sF#ls-Doj-!wq)cbAvBAHsb83Sl@z#&II&U%d~bJOj}r zAGMQ-SUVCAX9+$#-d#AV^hrVOL1J21FSk2S)yKid;9Mk3MvVb99a))!*W~_Qy)@o5 zi&iX}IC=HfM{*Lj`B9;!56$^JfdkZ$*g{rUlRI+xh%{EG)C)x85n(yFeGrCRB*K^Mlo2WBF7#WJp#%S<3g zg8#K5bd!7WKK)A{)h&XVsi`=V>?f$aF-eX&Qip^j|3MiVbZxc6_rWU^o6QY0#J#VU zYn71Ihrgcaw|RJm5z!WK{*V5nR6Eu?%;L5S_{?E;$;AE?^QKhGcWH}cm1Y+61r_u=WkO_quy1ya;WirRaR z$+ck5Od}%HYOYOZd9vOrd3nq4EV996u7~q{&JmMS$GG!brroKoa;D`^N^&9Hql}QL z-a9ctqa3~O78@BAwlpT`G2bZ=xx8>3CwJ7M++HmMO%3HO_rsB!3C$UGI1%=#z;G28&lZN1^qkocD zdlo2uo+SRoB4$8wP`DuhuO{N<^Joh@1M!<0x6&))B7ymE3O|mmv7#_i1ZqE{eSPcV ztI2O}RMF=^Pvibf3oDB}#mbEffrP;y+hH9I9)zZowS>YwXZ7&{F$j%p>T6f4aKF2% z2nOayw`;yIW*8L|8BLPeGWPcwx6G0+8ZnwU&sMVIzepKBDIQuocm(aCOo3*%yxIP! zt_U;~xG};4vN*IQw#~EYn&)42RB%m=aeJg=E;lBMXotSt3B4(K(f`# z#t44+Es|q5^}C+qo7>&5x2&iiNMSn+L&nd`)-L0ogWm~t^Tx*YAd7}R{g+)klG>AxYZCg7V=tRqSpg-~R8J`7b>@$jk4OaUSB`7ur zeuJv>5TdQ8O$l2@%@t67K{n=M_LP?mXa-;#<$~Y08N_>S* ziD%}I@1MyqYxEm?ZU<`q=as}B#pOu&An+F(#A3;6AImMdx~WYoWMG--daWIp1&cKz z=CV7ztANg|MzH#lD^v#Ea|;&W%5`*|RTmrKd+z`eIr!=|Oc{8e6qK_bQVpk*ymtn` zyM~+}IPcw(EfyXw(3c|Rn_!XF4Q$LiNgQ(Y%X6cVJ;>)>Cp;a$qF({rYNm;nob!5EXVy(f_BtGv%c|-SEKI^6vlzU(P^Fo8gnUtm66ruYpx^k3peZH9!z@+_u5RRnzmhRJzCU5u2F^fkkn zuWEhJ>~R^SB+GwqW((i({YdCxJnoUDiII8i(WB*&#ck^XAqO06^4$}aR*WJOx-8&| zrO|hdeL6euG+TD`-b2yCcI|$MJeAh#Q}SZ8_vI5GMr~K%<{d3@s&ld(6>|(@lG(|G zkNhF$D+{kM znd1>VN~!kv?E=6Kq`xHtT=$2LJ^kr1fSPD2l-m$aqA1imzgP?&rQ#wQ6j-d}1xZ}x>Z#-vl z@+2>JK^iUbMHgX}2Yo+J(cvILL-rcn$yil&=N527T-6#FtWPvLlDbxrNf>_@uhwHq z0qbv!mu&bj=xXsA+Kb4R>nPuRy-rOi;=pcl3xGdl)cBy0L<-*Z3(!7y`@=xzDJ_N2 zzwNY}$P>?Q zmXfN&kc!`my4&!D_{jBHPx1!?w;VM|_As%DAHXR;)x_H$jJ!k7~ zI9nta&wTr>q>E$zze_*r2~T_2mDiRfubn}sS($-GJxx9!M>#o|E9^}Qaa9YtP&--$AE_KyE_+rg?M zJwC)>ojE*|S?LVR$GJuFx+T6s@CkAl@uNTHmkX6Uu8C|UI8nr2M(?Y}&4 zNodhI>}-CJLB7+7}coH-4v?VU;~ zz+aJIAI0pN4$cY|bB?^4?~+Qrud55w2Z-DjZ(DopY7_^b{KBL*O|a3Wr@tOwr({lC znfaIWl``n|pYgfcH0Wmd>n*5R%iG~5njH%vS{J1lxbUD$e98>*Of?q6WzIdn$C3ZC z06O83Ux(b~9ByMLbzn}n*uE*RfR(Loqwj>6klXgg&v3jNu<@fh;^5Qcr=#p(U#HZF zuYFt#Tjy-^RF3>|GFkB>NVVuA>1$EYCmNw31@tk(djoO~muP(>yp)SRsyGt;kR5C4 zF7wvwnwdXIQW$+QA-Swu06ISp+i#PQ*!t6CXmRm%C)E$x0JGPR65A`gsyAi)qo<%z^J4-q8 z7fC6w#j^sY+efXt8Ko~BNa_#h*PT5Q-k=`9{vSV zXHE6^@-dSqEh|I^OJy-U?z@p4|pzK!#nOS#(Qw#6g?rgckqwD6$gT5_PtUj-HG(6{&) zQrMV3eC&(96d83cjgf?Em^bZlkGU_@kg?fow*reBAl-A5xDKV+$SX@Rc#0Pjp}(B-)M@6W>*7G)eJ zB7aXR_N>!+KsR^!S7U&5+jomxbbMjlZtV;YYREUg`JYJg?y&kiTI6Y6|9F{AQjk9? zZ8u6~Q?4@}5*l^J^6(K^Za^`)$__c;aUyiaHcg+;J(Rk9NK%c|yFro-0C4>nTHb&D zRx$=ud=t?4SVU{va-~~cXk7+~(Syl`W}L8PMsP1SWLs*{GjV%|bi&sZ9p!N8`vd+j zbi_Zq2Um2aJIa2N8q)vrePn#9mlOatAFemfR>DW?@e`UI3q-hUE4r$)9Y=+K3%-#6 zlAR*uV(#0rOw*4m67^<(ls%#7^v__=Wgu+OO_|Miu#+kB&O4mZ!sxFsN6-Cb2(PLX;Z;aO5BKnihI{1PkEi8kthRzgGx4V&96OVOm>y?3=eI zT(Xe=`Ei(QnO4)b0;pe;ly6YzI*~k7Iz~5dmI`uxz))Q66?&IYGX%=yt6P=wp5K2p z2^$$jZwM`05*9G=WCpIYAL)VdWr{m$T)T)O23QMSYLi)O!8|T=YHHd z|ExD%GU=E1dbAf9Hro!jytB^BHu$_( za@c}}-*2Sfli048IDZ;_P;|7YEtJA^8WHT8mcUB_3@2IZ``_;8kd)PCYrkSK{qtZ2 zAXNQ}UfDLau}pPxB{*-%-B+*Wf@?m(AjjwOuq9#jTVhi69rfF4r%QYIZ<Yr9_9Z`9*JU+}pK-Fj5ns0oc{y?4jI3Wmf=2*pa+#7YqFCfzd{ z3Xs|BRJ36oXN;liYZ`|wyj}k=6g(U-7-5KC2!L?Z2nxBtvVi~zisifF)HOVS)gHD%*8{IONPky>7Qko8C zl{ol9Km5^D4y5&xXUIw-XZNuFvW?lV=`J2OXQ8!q`bb>{FJT zvPW%Q3&IH-n%z|jIfOV56ZlWneyk#ad{LNh{}<=?8v+{^6BveAtG(|-&v(^&MBWu> z9j^D_&F!f?)sVw7w;b=b{XTEbgYumEi7t=hJr%hC385)wr3_3uyY$U-y+d7uBE871 zOM&(?<{v;v$Dbk&Quj5o|1SF&QcvBW|6YCey4O_8H{<}catIt}bB4+~)#uufY z^{M7;AL_kPOE|J*6AX#DwkjLn-#HoSu6}s-d)SkN>R$4mKN&{vj~Dw44^*Iuw-g72 z+H{u&PJPt^);)77pECwxU$BTm*OpMJ-a1;(7(+*dOjA#pS6|}gY(u>=3~tGdgVw)! z?|}OyOg~MBL)isP2x-4~zxDJm#J%&bk}wIwWKyF!X-dMs|59&HDNy3k4oSHe2+w)o zSx4~)Bs*jZzEWZ%ZTK0#Bu9pU1^L2vqMpfGI!@9eZ=Pi`;+POia?+OHMy_%HLv{dp5A;~$uPw!t|vts2DrB_I!`i|3&#yS+I zTqNJhnU_jStFt6Gk2d&7*>}U>y5*rw(3!=$=x1ND3LcLsb)iV#*@>{nJ@Z|Px1`bD z71zMSqq~XQgQveZ`qgL(vjXQ~mEJRE*87Aka7RUH*ak9T;8iXw=cl0)D--uop2T6= zSG^L#QO`dPd@!%!<*>cr{v8P$~RhkgBnw)Iim_W(F z-{$?ryA}_{k!p&+4vBKBBpGHvKd!Vr>FcBKy#t5B9~_)5UihgQxC+L2rokQhZjM3x zM7sxaD(L;#GPKTe4_<~3h!$S`T)Tf97R@(Iej!np#}e4y|Fg15K7(^lKvWn6_YRx+ z4cX7-+9|l2<+aNsYH;83e6Sh67YGDTda+I5ujD#B#57|LLpJ&#;`W8Riz;L1H{6^w-q#tjHcSzt; zi^Y0#ki3Hryhm^`ISbS5l8C9+348+`cbnRUjC3WUEbo4K{Opz>J@=MZScQENxi83< zn4+kXc&u^V*5E3Suio`!=o67+-ozBh+CKXB3znxV)Hh~;3|7(lSqC0QR z^Fv_QYLahW*07=oeA%(+(^{(X_?pdW`j112s$Ur=hzv3K`!6a{g7~qX=*K=&YCRM9 zkxwh^X_nSGX_l%Bf1p+!kD(H3zS^hxS*2yENd|+XmWbiq-H@jyNlCXyd`xUs4AFDW zX?nCFkpnDbeT*lGN_1KQqpCK4Ywmc%f7W$)wrul?TtCu(uOq+IJjaJ!bwPo&Fa=*? zlz3iDd2R!Q@wEMbSP_Y%8>C%pD@^#HiorBlTO_gLG7oUg zZqkMJq9J|(*S7b)qrBG}2asjY_So)O`UOEc{O=kNe12zbQ3hf%7nWY&5mV3m74)=( zXJXVV0%9w`#|X*ShvA}P8JDT9i=Hm;;rd66ExV`GH3dtqSDX|lwR_b+)pC80JwtOk zv}|&>+`DJ>%*+=ie=Af}@ZsZtQ-{9eJ4_*I$NDeH$fk&S2c*XR5CKF{lUe_yZXc_K?4 zv0QFW*Zk~eVQdxXucd5|FPkd&PfiaC5|~#akogoI=_=daZZdfBr1SnKqH`+D6KO%j z`QdHXT!-~zAkLQ}V2&<0_SM33;3UkRv>~csC>T*3y4n+{lchi$?wk~)!au+j^{og4 zPg?x-Jlu5(X?2OTxR4>7s)4FMGp2_8y)plJ4SWGBd2RWeZcJh8E|{_v?Bz__o+3^p z0}Zs+=k~*`O090o`vQ9RHs6fN0cSW8nm`Qdy$CKY;ZL|nCM(v&Up z{h5eHzG_q-6nLD1(xh;M_y-=sl>P!uv&0`YdXu_r;X1rztnxrzD!$gb#kk5_e>L~A z$=&VVan}dtdjp5g!n^BS(gqmtp--mhHuS9pnkj!n@e^^>e$0zF_he&DjoF0)H;g|^ zv5RtkLZ1fW%+%Yk2+^yt~iT#z0z5K^dAGk7kaN$ z!{j@~YlmSoyYNV4B+@(r{2tF*hZ37k_u4Z4JcuSzH!=8_;@#aYrHg=M)DeGLY^~tD z)|YePqwtK`=b}$$`38aOlEeA78F=GpSc<2o7b36oQ>_ihKtqxmQj!J_Fi=-zj;*s- zGDpIKABGR1v$~azg%x$}$quOq?H8d|Yk6KoiEuOox zlgIwPxEja>D;y(SLo(6#)L;M}@e?y1juiCu$QLKSaQo)nt$->%uz9ucL$47k0)W~| zHTHC>RxMD&yt|=BMhI=IfRGU#&$FOacI3}wkG|0WN8c8dpgL}+LDg?yRb8mlcv)EP zk9Y61($VETlymBLrRL!Yc0bOY&ETu-=e_Myw8V_3C$$ zN`)Y#*CXBER&zNVNJ;WsF4QR;>C%p$Z$s>_N+e$o8>Od{NA}D8q>7C*Ls_~MY=!;+ zzD9B7%)tDkplnOeoUFCuN$7gfKhu35j(HoA9q(hAl`#+@-HO>B61qkDTO=H3@Kn)f z9Y8t1}bjG>5pr#l7iz zAy>i9Tz>f8PJd`pgL!p=W|4uj03hf*DM^#R?t}H6=|LWSc(aItZEO)XJR4|`YnL-IBx{8(|NWBm9I>np%8K%Ft_Xp8=K=jgL<*s zOQT+xp-hrxvU}%3p+_LTlv-3CO0H0x*&?31sq(Y>Wh<*B_Tg-w9q&4fM5)gVjj`$J zk3e~ML?l^Zr%eH0FCtc|fcz@(`aFWksGd4%0M83;jNaEK9^JEa01GI#F453Ex-8bx zw9(sZ?IYSw?`^;JQo4N^cMnhUx_eqy`%{1h zb$TjR6(2kazFjxUa)0F?umJn13JQOblc>B|LX0E;`?g#H7U#ZzSp?Z zLB=%YRbvl6S+TuiIvR=y?k^*p+8s+5otY{yr@nGeiN$r`oK#*B%s6b*tSW@SgZWAG z!=i^Zr~NZStaKZ@`~k@xuYJvz#OpD?cF}BE=;XH>yG#uu&QSZ+$f2z72jzOG;TOZ9 zbU8kadkuGs+hBPsqbU0Ej=PyBty4HF$K${HQARFs3|%{4zp1CbDPOL<$njyDXkOfj zoZGzX+mOshAPB7VJ^>F4`H_Tt>|3dHQI;8N`3`mUQd(O#TMl$-^1AP+fja(P2dNQ63AeR(Cr;|p^ia^jzG z%R^}i`psiR)?>sh7r}t)ZgtaBYKW;VUDNPH?pcf#&ITXEhjOY!_e8^ed3D9;`q^Xw zpdTtYowx?`+@2Ad-QwMK;s8ph4C~NT#kGh+u1;OTBaJbZWuxSL(kaBW8EQYX^rsb@)~((%=03 z+*_7>yniCf!ki6hpI5vLzhx?0t77KJ!hF^e?B-PH<1--jhdYu|?d*`P?2l-17s;uK8G_Im{xL zL9j;4z~K)JIOC482Ltu$!?(0-IwHH#YH3gxC@VnMQSq}wM6FIpTH_!7 zfprQLrhS8-xw3oxb2r&wYom(}x|n=xrsq^I!G@mYiV-(La$t}!TFN1eSE@avlUscn zlbwMA{7D-8Xi`MPF0pj1BV;XgQtpiP;$bOg=%dn6=?|PFgx%XbN ztBTh^)q)$*=(l4ynm|~8Y(V#fn^gfjb}K_|vdrxm0SoFjbU);FuHYb_(0T_4C^Zb` zhzEP@$ckG?>D3Y29?s=_ewrDWwk&SWe`*Tsi)o8${oQGr#6BV~3&lKI%1Ui^U{(RQ zNNWLsWt3X0WA`!yYwOqouWCbp5@&cQWO0Y#ohyxi!{2}1AGM_s8P(~zJqJ}>BoW_=cx`6zM5sA%nZQRTay7f{p(J$u5gZ@l!J%NZ1 zfzq2?CPKY~x;LieD;H9H3?p)pKNQz!M87%tqTy5UQG)x{a(_C|;=bRUMiG!O7{Pm1 zmN5bG!>6(Q;C$zJXaBRbQbXE-MfT)WK|W%=;<2Ih3aJ zo4O4Ex?nQp&;g!S)utW&jb>k}i_E{HwjCw4S$(&E{8^Wv;X?%ay=1<+?S9jl+Tpus z*+#~wng2cr;V+aY18ni~Zyazq4Jj*=Nu)eQ34_s>SiMQ30hWmo9}`41E_Uc^WLa4w zkbx{bFIBHyNZn^_!SkeB%gvC=Zyy?>i24dhx~33Z&ANZk&|HpMo@F@;dfjg(LYX)YBM(+ku4{2>5k^!jcb3DI(;fRtpXcs zHDB6!_h>GicK;in&K0uXVKBbu$Rh+Sp$Vh3vxjb;x_2dWGLi z?w&$t`QFfP%|^rln0H)DLh!i)n)`D#XTHNrzlAHG7%R#yKYcC5oewC6MRy#gmIfte z3ADo5pqs;&pIAQXTx8IHnQILDzWis2AlXC|ufTy@lWG9Vq${taF>(i?8VeGJ&JJC| zEjgK0n8-^LY*3>;!iQ@Z>Wc1~=G!~l>wDpat}n`Vg+_iE^TaoL(4tDB+QPM|3(&RM zSdi|OqsAL*s(l8MHI{OYI_Z#UAmN_yOE{Tbj#n5*1g%KsTH&GZba*znYgrLXhkDb1 zoc*Q{m8+o4bZQh^Hhknp`pHp+i1d8cf%Z6+t8-HI;cc7UbQVXPAoGSHlw32|yFR_x ze4jGT5?h}9u=NMxO!~e$j7m{S0T8j$SnBg zbyIP1i`y`<)>xo??{Ter!LlXg^%ugD{;VNxI-x~C3+i{-AsZ>{jB;BUpMOtUQvYtE p`~RB%dY1Zsn*Swphno!ENyQOC1-}2l@Be!nxUKVf8r0{}e*i5`#3=v( literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/opencomputers/doc/img/configuration_done.png b/src/main/resources/assets/opencomputers/doc/img/configuration_done.png new file mode 100644 index 0000000000000000000000000000000000000000..d0330e946b3f08cb4e6bf169cbad6e886eb01de0 GIT binary patch literal 241985 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

`fZNN~!* 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�!1mpni*CsLP&D3s9|0B+J!PSvCB!p-?H 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%0A|l(jkr+_KJD=*-KVDKBJvQC!-{ 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 z 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

0SkC>F&=aGnhC|I!_+>&%u0N~` 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 tY3CZAoJSYft5n9QTokRNXu Date: Sun, 12 Apr 2015 14:11:31 +0200 Subject: [PATCH 02/37] Improved culling for document rendering a bit, cleaned up code some. --- .../doc/en_US/general/quickstart.md | 4 +- .../assets/opencomputers/doc/en_US/index.md | 30 +++--- .../doc/img/configuration_case1.png | Bin 23743 -> 5682 bytes .../doc/img/configuration_case2.png | Bin 20350 -> 5666 bytes .../assets/opencomputers/lang/de_DE.lang | 1 + .../assets/opencomputers/lang/en_US.lang | 1 + .../scala/li/cil/oc/client/gui/Manual.scala | 2 +- .../client/renderer/markdown/Document.scala | 88 +++++++++++------- .../markdown/segment/CodeSegment.scala | 36 +++---- .../markdown/segment/InteractiveSegment.scala | 28 +++++- .../markdown/segment/NewLineSegment.scala | 15 --- .../markdown/segment/RenderSegment.scala | 12 +-- .../renderer/markdown/segment/Segment.scala | 49 ++++++---- .../markdown/segment/TextSegment.scala | 38 ++++---- .../segment/render/TextureImageProvider.scala | 11 ++- 15 files changed, 189 insertions(+), 126 deletions(-) delete mode 100644 src/main/scala/li/cil/oc/client/renderer/markdown/segment/NewLineSegment.scala diff --git a/src/main/resources/assets/opencomputers/doc/en_US/general/quickstart.md b/src/main/resources/assets/opencomputers/doc/en_US/general/quickstart.md index a78aee1b3..1abb20603 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/general/quickstart.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/general/quickstart.md @@ -5,7 +5,9 @@ Also know as "how to build your first computer". To get your first [computer](co **Disclaimer**: this will be step-by-step, and also provide some information on how to look for issues yourself later on, so this is quite long. If you never built a computer in real life, and/or are completely new to the mod, it is highly recommended you read through it all. First off, you will need a [computer case](../block/case1.md). This is the block into which you will build most of the components, defining the behavior of the computer you're building. + ![A tier two computer case.](oredict:oc:case2) + For example, you will need to choose what tier of [graphics card](../item/graphicsCard1.md) you wish to use, if you need a [network card](../item/lanCard.md), a [redstone card](../item/redstoneCard1.md) or, if you're just playing around in creative mode, maybe even a [debug card](../item/debugCard.md). When you open the computer case's GUI you will see a few slots to the right. The number of slots, and what tier of component can be placed into them (indicated by the small roman numeral in the slot) depends on the tier of the case itself. @@ -18,7 +20,6 @@ Next up you'll be asked to insert some [memory](../item/ram1.md). Notice that th We're making good progress here. By now your computer case will look somewhat like this: ![Partially configured computer.](opencomputers:doc/img/configuration_case2.png) - And behold, turning it on now does not print any more error messages! But alas, it still doesn't do much. At least it beeps twice now. That means the actual execution of the computer failed. In other words: it technically runs! This is where a very useful tool comes into play: the [analyzer](../item/analyzer.md). This tool allows inspecting many of OpenComputers' blocks, as well as some blocks from other mods. To use it on the computer, use the analyzer on the case while sneaking. You should now see the error that caused the computer to crash: @@ -37,6 +38,7 @@ It lives! Or should, anyway. If it doesn't something went wrong, and you'll want To allow the computer to show some output, you'll want to grab a [screen](../block/screen1.md) and a [graphics card](../item/graphicsCard1.md). ![No, it's not a flatscreen.](oredict:oc:screen2) + Place the screen adjacent to your computer case, or, again, connect it using some cable. Then place a graphics card of your choice into the computer case. You should now see a blinking cursor on the screen. Finally, place a [keyboard](../block/keyboard.md) either on the screen itself, or in a way so that it faces the screen, to enable keyboard input. And with that, you're done. The computer is up and running and ready for action. Try using it now! Type `lua` in the shell and press enter, and you'll be greeted with a bit of information on how to use the Lua interpreter. Here you can test basic Lua commands. For more information this topic see [the Lua page](lua.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/index.md b/src/main/resources/assets/opencomputers/doc/en_US/index.md index 28c3a8ca2..5bb024943 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/index.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/index.md @@ -2,21 +2,7 @@ OpenComputers is a mod that adds persistent, modular, and highly configurable [computers](general/computer.md), [servers](item/server1.md), [robots](block/robot.md), and [drones](item/drone.md) to the game. All devices can be programmed using Lua 5.2, allowing for systems with varying complexity depending on the usage. -To learn about how to use the manual, check out [the page about the manual](item/manual.md) (that green text is a link, you can click it). You can find a table of contents at the bottom of this page. - -## Prologue - -As mentioned above, computers in OpenComputers feature persistence, which means that a running [computer](general/computer.md) retains its state when the chunk it is in is unloaded. This means that if the player moves away from the [computer](general/computer.md), or logs off, the [computer](general/computer.md) will remember its last known state and continue from that point on when the player goes near the [computer](general/computer.md). Persistence works for all devices except for [tablets](item/tablet.md). - -All devices are modular and can be assembled with a wide range of components, just like [computers](general/computer.md) in real life. Players who enjoy tinkering will be able to optimize devices to their heart's content. If desired, devices can be [dismantled](block/disassembler.md) and rebuilt if the initial configuration wasn't satisfactory. For [computers](general/computer.md) and [servers](item/server1.md), components can be swapped out on-the-fly simply by opening the corresponding GUI. - -OpenComputers devices are compatible with many different mods for manipulation of blocks and entities (through the [adapter](block/adapter.md), or specific upgrades in a [robot](block/robot.md) or [drone](item/drone.md)). Power can be supplied using a large range of other mods, including, but not limited to, Redstone Flux, IndustrialCraft2 EU, Mekanism Joules, Applied Energistics 2 energy as well as Factorization Charge. - -Most devices are able to run a basic operating system called [OpenOS](general/openOS.md) (with the exception of drones and microcontrollers). OpenComputers allows for creation of custom OSes and Architectures, should the player desire it. - -Devices have access to various resources such as [disk space](item/hdd1.md) and [memory (RAM)](item/ram1.md). [Microcontrollers](block/microcontroller.md) are cheap [computers](general/computer.md) with less functionality and components, and do not have an operating system, requiring creative use of programming. [Robots](block/robot.md) are mobile [computers](general/computer.md) and are able to interact with blocks and entities (but are unable to interact with external OpenComputers components). [Drones](item/drone.md) are fast, entity-based [robots](block/robot.md) with limited functionality, able to move differently and are able to interact differently with the world. [Servers](item/server1.md) are higher tier [computers](general/computer.md) and are able to hold more components, increasing the amount of resources available to control larger networks and run larger programs. - -This manual contains detailed information regarding all blocks and items, how to set up different types of systems and devices, as well as an introduction to Lua programming. +To learn about how to use the manual, check out [the page about the manual](item/manual.md) (that green text is a link, you can click it). ## Table of Contents @@ -37,3 +23,17 @@ This manual contains detailed information regarding all blocks and items, how to ### Guides - [Getting Started](general/quickstart.md) + +## Overview + +As mentioned above, computers in OpenComputers feature persistence, which means that a running [computer](general/computer.md) retains its state when the chunk it is in is unloaded. This means that if the player moves away from the [computer](general/computer.md), or logs off, the [computer](general/computer.md) will remember its last known state and continue from that point on when the player goes near the [computer](general/computer.md). Persistence works for all devices except for [tablets](item/tablet.md). + +All devices are modular and can be assembled with a wide range of components, just like [computers](general/computer.md) in real life. Players who enjoy tinkering will be able to optimize devices to their heart's content. If desired, devices can be [dismantled](block/disassembler.md) and rebuilt if the initial configuration wasn't satisfactory. For [computers](general/computer.md) and [servers](item/server1.md), components can be swapped out on-the-fly simply by opening the corresponding GUI. + +OpenComputers devices are compatible with many different mods for manipulation of blocks and entities (through the [adapter](block/adapter.md), or specific upgrades in a [robot](block/robot.md) or [drone](item/drone.md)). Power can be supplied using a large range of other mods, including, but not limited to, Redstone Flux, IndustrialCraft2 EU, Mekanism Joules, Applied Energistics 2 energy as well as Factorization Charge. + +Most devices are able to run a basic operating system called [OpenOS](general/openOS.md) (with the exception of drones and microcontrollers). OpenComputers allows for creation of custom OSes and Architectures, should the player desire it. + +Devices have access to various resources such as [disk space](item/hdd1.md) and [memory (RAM)](item/ram1.md). [Microcontrollers](block/microcontroller.md) are cheap [computers](general/computer.md) with less functionality and components, and do not have an operating system, requiring creative use of programming. [Robots](block/robot.md) are mobile [computers](general/computer.md) and are able to interact with blocks and entities (but are unable to interact with external OpenComputers components). [Drones](item/drone.md) are fast, entity-based [robots](block/robot.md) with limited functionality, able to move differently and are able to interact differently with the world. [Servers](item/server1.md) are higher tier [computers](general/computer.md) and are able to hold more components, increasing the amount of resources available to control larger networks and run larger programs. + +This manual contains detailed information regarding all blocks and items, how to set up different types of systems and devices, as well as an introduction to Lua programming. diff --git a/src/main/resources/assets/opencomputers/doc/img/configuration_case1.png b/src/main/resources/assets/opencomputers/doc/img/configuration_case1.png index ae1503e768a3c03c1c05eaef8e34a498af8a4667..fe1c0458d5e5ded7cdc29959a135267a863d783b 100644 GIT binary patch literal 5682 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 literal 23743 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 literal 20350 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 diff --git a/src/main/resources/assets/opencomputers/lang/de_DE.lang b/src/main/resources/assets/opencomputers/lang/de_DE.lang index 4ce4bef37..4d2d245c0 100644 --- a/src/main/resources/assets/opencomputers/lang/de_DE.lang +++ b/src/main/resources/assets/opencomputers/lang/de_DE.lang @@ -186,6 +186,7 @@ oc:gui.Error.OutOfMemory=Nicht genug Arbeitsspeicher. oc:gui.Manual.Blocks=OpenComputers Blöcke oc:gui.Manual.Items=OpenComputers Gegenstände oc:gui.Manual.Warning.BlockMissing=Block nicht verfügbar. +oc:gui.Manual.Warning.ImageMissing=Bild nicht gefunden. oc:gui.Manual.Warning.ItemMissing=Gegenstand nicht verfügbar. oc:gui.Manual.Warning.OreDictMissing=Ore-Dictionary-Eintrag nicht verfügbar. oc:gui.Raid.Warning=§4Eine Platte einzufügen löscht sie.[nl] Eine Platte zu entfernen löscht das Raid. diff --git a/src/main/resources/assets/opencomputers/lang/en_US.lang b/src/main/resources/assets/opencomputers/lang/en_US.lang index 4d1799cb0..ee936e3da 100644 --- a/src/main/resources/assets/opencomputers/lang/en_US.lang +++ b/src/main/resources/assets/opencomputers/lang/en_US.lang @@ -186,6 +186,7 @@ oc:gui.Error.OutOfMemory=Out of memory. oc:gui.Manual.Blocks=OpenComputers Blocks oc:gui.Manual.Items=OpenComputers Items oc:gui.Manual.Warning.BlockMissing=Block unavailable. +oc:gui.Manual.Warning.ImageMissing=Image not found. oc:gui.Manual.Warning.ItemMissing=Item unavailable. oc:gui.Manual.Warning.OreDictMissing=Ore dictionary entry unavailable. oc:gui.Raid.Warning=§4Adding a disk wipes it.[nl] Removing a disk wipes the raid. diff --git a/src/main/scala/li/cil/oc/client/gui/Manual.scala b/src/main/scala/li/cil/oc/client/gui/Manual.scala index 74df4d1eb..04e2149c7 100644 --- a/src/main/scala/li/cil/oc/client/gui/Manual.scala +++ b/src/main/scala/li/cil/oc/client/gui/Manual.scala @@ -39,7 +39,7 @@ class Manual extends GuiScreen { var xSize = 0 var ySize = 0 var isDragging = false - var document = Iterable.empty[Segment] + var document: Segment = null var documentHeight = 0 var currentSegment = None: Option[InteractiveSegment] protected var scrollButton: ImageButton = _ diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/Document.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/Document.scala index cf30af9b1..9ad838045 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/Document.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/Document.scala @@ -7,32 +7,65 @@ import net.minecraft.client.Minecraft import net.minecraft.client.gui.FontRenderer import org.lwjgl.opengl.GL11 +import scala.collection.Iterable import scala.util.matching.Regex /** * Primitive Markdown parser, only supports a very small subset. Used for * parsing documentation into segments, to be displayed in a GUI somewhere. + * + * General usage is: parse a string using parse(), render it using render(). + * + * The parser generates a list of segments, each segment representing a part + * of the document, with a specific formatting / render type. For example, + * links are their own segments, a bold section in a link would be its own + * section and so on. + * The data structure is essentially a very flat multi-tree, where the segments + * returned are the leaves, and the roots are the individual lines, represented + * as text segments. + * Formatting is done by accumulating formatting information over the parent + * nodes, up to the root. */ object Document { /** * Parses a plain text document into a list of segments. */ - def parse(document: Iterable[String]): Iterable[Segment] = { - var segments = document.flatMap(line => Iterable(new segment.TextSegment(null, Option(line).fold("")(_.reverse.dropWhile(_.isWhitespace).reverse)), new segment.NewLineSegment())).toArray + def parse(document: Iterable[String]): Segment = { + var segments: Iterable[Segment] = document.map(line => new segment.TextSegment(null, Option(line).fold("")(_.reverse.dropWhile(_.isWhitespace).reverse))) for ((pattern, factory) <- segmentTypes) { segments = segments.flatMap(_.refine(pattern, factory)) } - for (Array(s1, s2) <- segments.sliding(2)) { - s2.previous = s1 + for (window <- segments.sliding(2)) { + window.head.next = window.last } - segments + segments.head } /** - * Renders a list of segments and tooltips if a segment with a tooltip is hovered. - * Returns a link address if a link is hovered. + * Compute the overall height of a document, e.g. for computation of scroll offsets. */ - def render(document: Iterable[Segment], x: Int, y: Int, maxWidth: Int, maxHeight: Int, yOffset: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { + def height(document: Segment, maxWidth: Int, renderer: FontRenderer): Int = { + var currentX = 0 + var currentY = 0 + var segment = document + while (segment != null) { + currentY += segment.nextY(currentX, maxWidth, renderer) + currentX = segment.nextX(currentX, maxWidth, renderer) + segment = segment.next + } + currentY + } + + /** + * Line height for a normal line of text. + */ + def lineHeight(renderer: FontRenderer): Int = renderer.FONT_HEIGHT + 1 + + /** + * Renders a list of segments and tooltips if a segment with a tooltip is hovered. + * Returns the hovered interactive segment, if any. + */ + def render(document: Segment, x: Int, y: Int, maxWidth: Int, maxHeight: Int, yOffset: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { val mc = Minecraft.getMinecraft GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS) @@ -68,13 +101,20 @@ object Document { // Actual rendering. var hovered: Option[InteractiveSegment] = None - var currentX = 0 - var currentY = 0 - for (segment <- document) { - val result = segment.render(x, y + currentY - yOffset, currentX, maxWidth, y, maxHeight - (currentY - yOffset), renderer, mouseX, mouseY) - hovered = hovered.orElse(result) - currentY += segment.height(currentX, maxWidth, renderer) - currentX = segment.width(currentX, maxWidth, renderer) + var indent = 0 + var currentY = y - yOffset + val minY = y - lineHeight(renderer) + val maxY = y + maxHeight + lineHeight(renderer) + var segment = document + while (segment != null) { + val segmentHeight = segment.nextY(indent, maxWidth, renderer) + if (currentY + segmentHeight >= minY && currentY <= maxY) { + val result = segment.render(x, currentY, indent, maxWidth, renderer, mouseX, mouseY) + hovered = hovered.orElse(result) + } + currentY += segmentHeight + indent = segment.nextX(indent, maxWidth, renderer) + segment = segment.next } if (mouseX < x || mouseX > x + maxWidth || mouseY < y || mouseY > y + maxHeight) hovered = None hovered.foreach(_.notifyHover()) @@ -84,24 +124,6 @@ object Document { hovered } - /** - * Compute the overall height of a document, for computation of scroll offsets. - */ - def height(document: Iterable[Segment], maxWidth: Int, renderer: FontRenderer): Int = { - var currentX = 0 - var currentY = 0 - for (segment <- document) { - currentY += segment.height(currentX, maxWidth, renderer) - currentX = segment.width(currentX, maxWidth, renderer) - } - currentY - } - - /** - * Line height for a normal line of text. - */ - def lineHeight(renderer: FontRenderer): Int = renderer.FONT_HEIGHT + 1 - // ----------------------------------------------------------------------- // private def HeaderSegment(s: Segment, m: Regex.Match) = new segment.HeaderSegment(s, m.group(2), m.group(1).length) diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/CodeSegment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/CodeSegment.scala index eace30584..1149769ae 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/CodeSegment.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/CodeSegment.scala @@ -5,25 +5,13 @@ import li.cil.oc.client.renderer.markdown.Document import net.minecraft.client.gui.FontRenderer import org.lwjgl.opengl.GL11 -private[markdown] class CodeSegment(protected val parent: Segment, val text: String) extends Segment { +private[markdown] class CodeSegment(val parent: Segment, val text: String) extends Segment { private final val breaks = Set(' ', '.', ',', ':', ';', '!', '?', '_', '=', '-', '+', '*', '/', '\\') private final val lists = Set("- ", "* ") private lazy val rootPrefix = root.asInstanceOf[TextSegment].text.take(2) - override def height(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = { - var lines = 0 - var chars = text - val wrapIndent = computeWrapIndent(renderer) - var numChars = maxChars(chars, maxWidth - indent, maxWidth - wrapIndent) - while (chars.length > numChars) { - lines += 1 - chars = chars.drop(numChars).dropWhile(_.isWhitespace) - numChars = maxChars(chars, maxWidth - wrapIndent, maxWidth - wrapIndent) - } - lines * Document.lineHeight(renderer) - } - - override def width(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = { + override def nextX(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = { + if (isLast) return 0 var currentX = indent var chars = text val wrapIndent = computeWrapIndent(renderer) @@ -36,7 +24,21 @@ private[markdown] class CodeSegment(protected val parent: Segment, val text: Str currentX + stringWidth(chars) } - override def render(x: Int, y: Int, indent: Int, maxWidth: Int, minY: Int, maxY: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { + override def nextY(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = { + var lines = 0 + var chars = text + val wrapIndent = computeWrapIndent(renderer) + var numChars = maxChars(chars, maxWidth - indent, maxWidth - wrapIndent) + while (chars.length > numChars) { + lines += 1 + chars = chars.drop(numChars).dropWhile(_.isWhitespace) + numChars = maxChars(chars, maxWidth - wrapIndent, maxWidth - wrapIndent) + } + if (isLast) lines += 1 + lines * Document.lineHeight(renderer) + } + + override def render(x: Int, y: Int, indent: Int, maxWidth: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { TextBufferRenderCache.renderer.generateChars(text.toCharArray) var currentX = x + indent @@ -44,7 +46,7 @@ private[markdown] class CodeSegment(protected val parent: Segment, val text: Str var chars = text val wrapIndent = computeWrapIndent(renderer) var numChars = maxChars(chars, maxWidth - indent, maxWidth - wrapIndent) - while (chars.length > 0 && (currentY - y) < maxY) { + while (chars.length > 0) { val part = chars.take(numChars) GL11.glColor4f(0.75f, 0.8f, 1, 1) TextBufferRenderCache.renderer.drawString(part, currentX, currentY) diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/InteractiveSegment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/InteractiveSegment.scala index 5419f701c..2ed60efde 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/InteractiveSegment.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/InteractiveSegment.scala @@ -1,13 +1,39 @@ package li.cil.oc.client.renderer.markdown.segment +/** + * Segments that can react to mouse presence and input. + * + * The currently hovered interactive segment is picked in the render process + * and returned there. Calling code can then decide whether to render the + * segment's tooltip, for example. It should also notice the currently hovered + * segment when a left-click occurs. + */ trait InteractiveSegment extends Segment { + /** + * The tooltip that should be displayed when this segment is being hovered. + */ def tooltip: Option[String] = None def link: Option[String] = None + /** + * Should be called by whatever is rendering the document when a left mouse + * click occurs. + * + * The mouse coordinates are expected to be in the same frame of reference as + * the document. + * + * @param mouseX the X coordinate of the mouse cursor. + * @param mouseY the Y coordinate of the mouse cursor. + * @return whether the click was processed (true) or ignored (false). + */ def onMouseClick(mouseX: Int, mouseY: Int): Boolean = false + // Called during the render call on the currently hovered interactive segment. + // Useful to track hover state, e.g. for link highlighting. private[markdown] def notifyHover(): Unit = {} - private[markdown] def checkHovered(mouseX: Int, mouseY: Int, x: Int, y: Int, w: Int, h: Int): Option[InteractiveSegment] = if (mouseX >= x && mouseY >= y && mouseX <= x + w && mouseY <= y + h) Some(this) else None + // Collision check, test if coordinate is inside this interactive segment. + private[markdown] def checkHovered(mouseX: Int, mouseY: Int, x: Int, y: Int, w: Int, h: Int): Option[InteractiveSegment] = + if (mouseX >= x && mouseY >= y && mouseX <= x + w && mouseY <= y + h) Some(this) else None } diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/NewLineSegment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/NewLineSegment.scala deleted file mode 100644 index d6eee6f03..000000000 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/NewLineSegment.scala +++ /dev/null @@ -1,15 +0,0 @@ -package li.cil.oc.client.renderer.markdown.segment - -import li.cil.oc.client.renderer.markdown.Document -import net.minecraft.client.gui.FontRenderer - -private[markdown] class NewLineSegment extends Segment { - override protected def parent: Segment = null - - override def height(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = previous match { - case segment: TextSegment => (Document.lineHeight(renderer) * segment.resolvedScale).toInt - case _ => Document.lineHeight(renderer) - } - - override def toString: String = s"{NewLineSegment}" -} diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/RenderSegment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/RenderSegment.scala index c29996015..d1183338c 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/RenderSegment.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/RenderSegment.scala @@ -24,19 +24,17 @@ private[markdown] class RenderSegment(val parent: Segment, val title: String, va def imageWidth(maxWidth: Int) = math.min(maxWidth, imageRenderer.getWidth) - def imageHeight(maxWidth: Int) = (imageRenderer.getHeight * scale(maxWidth)).toInt + def imageHeight(maxWidth: Int) = math.ceil(imageRenderer.getHeight * scale(maxWidth)).toInt + 4 - override def width(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = imageWidth(maxWidth) + override def nextY(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = imageHeight(maxWidth) + (if (indent > 0) Document.lineHeight(renderer) else 0) - override def height(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = { - math.max(0, imageHeight(maxWidth)) + (if (indent > 0) Document.lineHeight(renderer) else 0) - } + override def nextX(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = 0 - override def render(x: Int, y: Int, indent: Int, maxWidth: Int, minY: Int, maxY: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { + override def render(x: Int, y: Int, indent: Int, maxWidth: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { val width = imageWidth(maxWidth) val height = imageHeight(maxWidth) val xOffset = (maxWidth - width) / 2 - val yOffset = 4 + (if (indent > 0) Document.lineHeight(renderer) else 0) + val yOffset = 2 + (if (indent > 0) Document.lineHeight(renderer) else 0) val s = scale(maxWidth) lastX = x + xOffset diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/Segment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/Segment.scala index be1ec951e..dd35430f1 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/Segment.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/Segment.scala @@ -7,31 +7,48 @@ import scala.util.matching.Regex trait Segment { /** - * Computes the height of this segment, in pixels, given it starts at the - * specified indent into the current line, with the specified maximum - * allowed width. + * Parent segment, i.e. the segment this segment was refined from. + * Each line starts as a TextSegment that is refined based into segments + * based on the handled formatting rules / patterns. */ - def height(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = 0 + def parent: Segment /** - * Computes the width of the last line of this segment, given it starts - * at the specified indent into the current line, with the specified - * maximum allowed width. - * If the segment remains on the same line, returns the new end of the - * line (i.e. indent plus width of the segment). + * The root segment, i.e. the original parent of this segment. */ - def width(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = 0 + @tailrec final def root: Segment = if (parent == null) this else parent.root - def render(x: Int, y: Int, indent: Int, maxWidth: Int, minY: Int, maxY: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = None + /** + * Get the X coordinate at which to render the next segment. + * + * For flowing/inline segments this will be to the right of the last line + * this segment renders, for block segments it will be at the start of + * the next line below this segment. + * + * The coordinates in this context are relative to (0,0). + */ + def nextX(indent: Int, maxWidth: Int, renderer: FontRenderer): Int - // Used when rendering, to compute the style of a nested segment. - protected def parent: Segment + /** + * Get the Y coordinate at which to render the next segment. + * + * For flowing/inline segments this will be the same level as the last line + * this segment renders, unless it's the last segment on its line. For block + * segments and last-on-line segments this will be the next line after. + * + * The coordinates in this context are relative to (0,0). + */ + def nextY(indent: Int, maxWidth: Int, renderer: FontRenderer): Int - @tailrec protected final def root: Segment = if (parent == null) this else parent.root + def render(x: Int, y: Int, indent: Int, maxWidth: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = None // Used during construction, checks a segment for inner segments. private[markdown] def refine(pattern: Regex, factory: (Segment, Regex.Match) => Segment): Iterable[Segment] = Iterable(this) - // Set after construction of document, used for formatting (e.g. newline height). - private[markdown] var previous: Segment = null + // Set after construction of document, used for formatting, specifically + // to compute the height for last segment on a line (to force a new line). + private[markdown] var next: Segment = null + + // Utility method to check if the segment is the last on a line. + private[markdown] def isLast = next == null || root != next.root } diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/TextSegment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/TextSegment.scala index 8ecab9ac7..dd2b2c917 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/TextSegment.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/TextSegment.scala @@ -8,7 +8,7 @@ import scala.annotation.tailrec import scala.collection.mutable import scala.util.matching.Regex -private[markdown] class TextSegment(protected val parent: Segment, val text: String) extends Segment { +private[markdown] class TextSegment(val parent: Segment, val text: String) extends Segment { private final val breaks = Set(' ', '.', ',', ':', ';', '!', '?', '_', '=', '-', '+', '*', '/', '\\') private final val lists = Set("- ", "* ") private lazy val rootPrefix = root.asInstanceOf[TextSegment].text.take(2) @@ -39,21 +39,8 @@ private[markdown] class TextSegment(protected val parent: Segment, val text: Str result } - override def height(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = { - var lines = 0 - var chars = text - if (indent == 0) chars = chars.dropWhile(_.isWhitespace) - val wrapIndent = computeWrapIndent(renderer) - var numChars = maxChars(chars, maxWidth - indent, maxWidth - wrapIndent, renderer) - while (chars.length > numChars) { - lines += 1 - chars = chars.drop(numChars).dropWhile(_.isWhitespace) - numChars = maxChars(chars, maxWidth - wrapIndent, maxWidth - wrapIndent, renderer) - } - (lines * Document.lineHeight(renderer) * resolvedScale).toInt - } - - override def width(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = { + override def nextX(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = { + if (isLast) return 0 var currentX = indent var chars = text if (indent == 0) chars = chars.dropWhile(_.isWhitespace) @@ -67,7 +54,22 @@ private[markdown] class TextSegment(protected val parent: Segment, val text: Str currentX + (stringWidth(chars, renderer) * resolvedScale).toInt } - override def render(x: Int, y: Int, indent: Int, maxWidth: Int, minY: Int, maxY: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { + override def nextY(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = { + var lines = 0 + var chars = text + if (indent == 0) chars = chars.dropWhile(_.isWhitespace) + val wrapIndent = computeWrapIndent(renderer) + var numChars = maxChars(chars, maxWidth - indent, maxWidth - wrapIndent, renderer) + while (chars.length > numChars) { + lines += 1 + chars = chars.drop(numChars).dropWhile(_.isWhitespace) + numChars = maxChars(chars, maxWidth - wrapIndent, maxWidth - wrapIndent, renderer) + } + if (isLast) lines += 1 + (lines * Document.lineHeight(renderer) * resolvedScale).toInt + } + + override def render(x: Int, y: Int, indent: Int, maxWidth: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { val fontScale = resolvedScale var currentX = x + indent var currentY = y @@ -77,7 +79,7 @@ private[markdown] class TextSegment(protected val parent: Segment, val text: Str var numChars = maxChars(chars, maxWidth - indent, maxWidth - wrapIndent, renderer) val interactive = findInteractive() var hovered: Option[InteractiveSegment] = None - while (chars.length > 0 && (currentY - y) < maxY) { + while (chars.length > 0) { val part = chars.take(numChars) hovered = hovered.orElse(interactive.fold(None: Option[InteractiveSegment])(_.checkHovered(mouseX, mouseY, currentX, currentY, (stringWidth(part, renderer) * fontScale).toInt, (Document.lineHeight(renderer) * fontScale).toInt))) GL11.glPushMatrix() diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/TextureImageProvider.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/TextureImageProvider.scala index e3ea2d3fe..487d778fa 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/TextureImageProvider.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/TextureImageProvider.scala @@ -2,11 +2,18 @@ package li.cil.oc.client.renderer.markdown.segment.render import li.cil.oc.api.manual.ImageProvider import li.cil.oc.api.manual.ImageRenderer +import li.cil.oc.api.manual.InteractiveImageRenderer +import li.cil.oc.client.Textures import net.minecraft.util.ResourceLocation object TextureImageProvider extends ImageProvider { override def getImage(data: String): ImageRenderer = { - val location = new ResourceLocation(data) - new TextureImageRenderer(location) + try new TextureImageRenderer(new ResourceLocation(data)) catch { + case t: Throwable => new TextureImageRenderer(Textures.guiManualMissingItem) with InteractiveImageRenderer { + override def getTooltip(tooltip: String): String = "oc:gui.Manual.Warning.ImageMissing" + + override def onMouseClick(mouseX: Int, mouseY: Int): Boolean = false + } + } } } From c6bfcb464e054b0541434ec548520d903d56b77b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sun, 12 Apr 2015 14:17:55 +0200 Subject: [PATCH 03/37] Moved link handling into link segment, using mouse click handler. --- .../scala/li/cil/oc/client/gui/Manual.scala | 28 ++----------------- .../markdown/segment/InteractiveSegment.scala | 2 -- .../markdown/segment/LinkSegment.scala | 22 ++++++++++++++- 3 files changed, 23 insertions(+), 29 deletions(-) diff --git a/src/main/scala/li/cil/oc/client/gui/Manual.scala b/src/main/scala/li/cil/oc/client/gui/Manual.scala index 04e2149c7..52e513a02 100644 --- a/src/main/scala/li/cil/oc/client/gui/Manual.scala +++ b/src/main/scala/li/cil/oc/client/gui/Manual.scala @@ -1,6 +1,5 @@ package li.cil.oc.client.gui -import java.net.URI import java.util import li.cil.oc.Localization @@ -182,19 +181,8 @@ class Manual extends GuiScreen { isDragging = true scrollMouse(mouseY) } - else if (button == 0) { - // Left click, did we hit a link? - currentSegment.foreach(segment => if (!segment.onMouseClick(mouseX, mouseY)) segment.link match { - case Some(link) => - if (link.startsWith("http://") || link.startsWith("https://")) handleUrl(link) - else pushPage(ManualAPI.makeRelative(link, ManualAPI.history.top.path)) - case _ => - }) - } - else if (button == 1) { - // Right mouseclick = back. - popPage() - } + else if (button == 0) currentSegment.foreach(_.onMouseClick(mouseX, mouseY)) + else if (button == 1) popPage() } override protected def mouseClickMove(mouseX: Int, mouseY: Int, lastButtonClicked: Int, timeSinceMouseClick: Long) { @@ -211,18 +199,6 @@ class Manual extends GuiScreen { } } - private def handleUrl(url: String): Unit = { - // Pretty much copy-paste from GuiChat. - try { - val desktop = Class.forName("java.awt.Desktop") - val instance = desktop.getMethod("getDesktop").invoke(null) - desktop.getMethod("browse", classOf[URI]).invoke(instance, new URI(url)) - } - catch { - case t: Throwable => Minecraft.getMinecraft.thePlayer.addChatMessage(Localization.Chat.WarningLink(t.toString)) - } - } - private def scrollMouse(mouseY: Int) { scrollTo(math.round((mouseY - guiTop - scrollPosY - 6.5) * maxOffset / (scrollHeight - 13.0)).toInt) } diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/InteractiveSegment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/InteractiveSegment.scala index 2ed60efde..347e993a7 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/InteractiveSegment.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/InteractiveSegment.scala @@ -14,8 +14,6 @@ trait InteractiveSegment extends Segment { */ def tooltip: Option[String] = None - def link: Option[String] = None - /** * Should be called by whatever is rendering the document when a left mouse * click occurs. diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/LinkSegment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/LinkSegment.scala index 9ea335986..15fc30289 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/LinkSegment.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/LinkSegment.scala @@ -1,7 +1,11 @@ package li.cil.oc.client.renderer.markdown.segment +import java.net.URI + +import li.cil.oc.Localization import li.cil.oc.api import li.cil.oc.client.Manual +import net.minecraft.client.Minecraft private[markdown] class LinkSegment(parent: Segment, text: String, val url: String) extends TextSegment(parent, text) with InteractiveSegment { private final val normalColor = 0x66FF66 @@ -23,7 +27,11 @@ private[markdown] class LinkSegment(parent: Segment, text: String, val url: Stri override def tooltip: Option[String] = Option(url) - override def link: Option[String] = Option(url) + override def onMouseClick(mouseX: Int, mouseY: Int): Boolean = { + if (url.startsWith("http://") || url.startsWith("https://")) handleUrl(url) + else Manual.navigate(Manual.makeRelative(url, Manual.history.top.path)) + true + } override private[markdown] def notifyHover(): Unit = lastHovered = System.currentTimeMillis() @@ -34,5 +42,17 @@ private[markdown] class LinkSegment(parent: Segment, text: String, val url: Stri (r << 16) | (g << 8) | b } + private def handleUrl(url: String): Unit = { + // Pretty much copy-paste from GuiChat. + try { + val desktop = Class.forName("java.awt.Desktop") + val instance = desktop.getMethod("getDesktop").invoke(null) + desktop.getMethod("browse", classOf[URI]).invoke(instance, new URI(url)) + } + catch { + case t: Throwable => Minecraft.getMinecraft.thePlayer.addChatMessage(Localization.Chat.WarningLink(t.toString)) + } + } + override def toString: String = s"{LinkSegment: text = $text, url = $url}" } From fe66cec9d6d719c32b83045bce66af23f17df03f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sun, 12 Apr 2015 14:49:33 +0200 Subject: [PATCH 04/37] More cleanup, pulled common functionality from text and code segments into trait. --- .../markdown/segment/BasicTextSegment.scala | 68 ++++++++++ .../markdown/segment/CodeSegment.scala | 60 +------- .../renderer/markdown/segment/Segment.scala | 6 + .../markdown/segment/TextSegment.scala | 128 ++++++------------ 4 files changed, 120 insertions(+), 142 deletions(-) create mode 100644 src/main/scala/li/cil/oc/client/renderer/markdown/segment/BasicTextSegment.scala diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/BasicTextSegment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/BasicTextSegment.scala new file mode 100644 index 000000000..7fd3e328f --- /dev/null +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/BasicTextSegment.scala @@ -0,0 +1,68 @@ +package li.cil.oc.client.renderer.markdown.segment + +import li.cil.oc.client.renderer.markdown.Document +import net.minecraft.client.gui.FontRenderer + +trait BasicTextSegment extends Segment { + protected final val breaks = Set(' ', '.', ',', ':', ';', '!', '?', '_', '=', '-', '+', '*', '/', '\\') + protected final val lists = Set("- ", "* ") + protected lazy val rootPrefix = root.asInstanceOf[TextSegment].text.take(2) + + override def nextX(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = { + if (isLast) return 0 + var currentX = indent + var chars = text + if (ignoreLeadingWhitespace && indent == 0) chars = chars.dropWhile(_.isWhitespace) + val wrapIndent = computeWrapIndent(renderer) + var numChars = maxChars(chars, maxWidth - indent, maxWidth - wrapIndent, renderer) + while (chars.length > numChars) { + chars = chars.drop(numChars).dropWhile(_.isWhitespace) + numChars = maxChars(chars, maxWidth - wrapIndent, maxWidth - wrapIndent, renderer) + currentX = wrapIndent + } + currentX + stringWidth(chars, renderer) + } + + override def nextY(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = { + var lines = 0 + var chars = text + if (ignoreLeadingWhitespace && indent == 0) chars = chars.dropWhile(_.isWhitespace) + val wrapIndent = computeWrapIndent(renderer) + var numChars = maxChars(chars, maxWidth - indent, maxWidth - wrapIndent, renderer) + while (chars.length > numChars) { + lines += 1 + chars = chars.drop(numChars).dropWhile(_.isWhitespace) + numChars = maxChars(chars, maxWidth - wrapIndent, maxWidth - wrapIndent, renderer) + } + if (isLast) lines += 1 + lines * lineHeight(renderer) + } + + // ----------------------------------------------------------------------- // + + protected def text: String + + protected def ignoreLeadingWhitespace: Boolean = true + + protected def lineHeight(renderer: FontRenderer): Int = Document.lineHeight(renderer) + + protected def stringWidth(s: String, renderer: FontRenderer): Int + + protected def maxChars(s: String, maxWidth: Int, maxLineWidth: Int, renderer: FontRenderer): Int = { + var pos = -1 + var lastBreak = -1 + val fullWidth = stringWidth(s, renderer) + while (pos < s.length) { + pos += 1 + val width = stringWidth(s.take(pos), renderer) + if (width >= maxWidth) { + if (lastBreak > 0 || fullWidth <= maxLineWidth || s.exists(breaks.contains)) return lastBreak + 1 + else return pos - 1 + } + if (pos < s.length && breaks.contains(s.charAt(pos))) lastBreak = pos + } + pos + } + + protected def computeWrapIndent(renderer: FontRenderer) = if (lists.contains(rootPrefix)) renderer.getStringWidth(rootPrefix) else 0 +} diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/CodeSegment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/CodeSegment.scala index 1149769ae..46f36f4aa 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/CodeSegment.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/CodeSegment.scala @@ -1,43 +1,10 @@ package li.cil.oc.client.renderer.markdown.segment import li.cil.oc.client.renderer.TextBufferRenderCache -import li.cil.oc.client.renderer.markdown.Document import net.minecraft.client.gui.FontRenderer import org.lwjgl.opengl.GL11 -private[markdown] class CodeSegment(val parent: Segment, val text: String) extends Segment { - private final val breaks = Set(' ', '.', ',', ':', ';', '!', '?', '_', '=', '-', '+', '*', '/', '\\') - private final val lists = Set("- ", "* ") - private lazy val rootPrefix = root.asInstanceOf[TextSegment].text.take(2) - - override def nextX(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = { - if (isLast) return 0 - var currentX = indent - var chars = text - val wrapIndent = computeWrapIndent(renderer) - var numChars = maxChars(chars, maxWidth - indent, maxWidth - wrapIndent) - while (chars.length > numChars) { - chars = chars.drop(numChars).dropWhile(_.isWhitespace) - numChars = maxChars(chars, maxWidth - wrapIndent, maxWidth - wrapIndent) - currentX = wrapIndent + 1 - } - currentX + stringWidth(chars) - } - - override def nextY(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = { - var lines = 0 - var chars = text - val wrapIndent = computeWrapIndent(renderer) - var numChars = maxChars(chars, maxWidth - indent, maxWidth - wrapIndent) - while (chars.length > numChars) { - lines += 1 - chars = chars.drop(numChars).dropWhile(_.isWhitespace) - numChars = maxChars(chars, maxWidth - wrapIndent, maxWidth - wrapIndent) - } - if (isLast) lines += 1 - lines * Document.lineHeight(renderer) - } - +private[markdown] class CodeSegment(val parent: Segment, val text: String) extends BasicTextSegment { override def render(x: Int, y: Int, indent: Int, maxWidth: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { TextBufferRenderCache.renderer.generateChars(text.toCharArray) @@ -45,38 +12,23 @@ private[markdown] class CodeSegment(val parent: Segment, val text: String) exten var currentY = y var chars = text val wrapIndent = computeWrapIndent(renderer) - var numChars = maxChars(chars, maxWidth - indent, maxWidth - wrapIndent) + var numChars = maxChars(chars, maxWidth - indent, maxWidth - wrapIndent, renderer) while (chars.length > 0) { val part = chars.take(numChars) GL11.glColor4f(0.75f, 0.8f, 1, 1) TextBufferRenderCache.renderer.drawString(part, currentX, currentY) currentX = x + wrapIndent - currentY += Document.lineHeight(renderer) + currentY += lineHeight(renderer) chars = chars.drop(numChars).dropWhile(_.isWhitespace) - numChars = maxChars(chars, maxWidth - wrapIndent, maxWidth - wrapIndent) + numChars = maxChars(chars, maxWidth - wrapIndent, maxWidth - wrapIndent, renderer) } None } - private def stringWidth(s: String): Int = s.length * TextBufferRenderCache.renderer.charRenderWidth + override protected def ignoreLeadingWhitespace: Boolean = false - private def maxChars(s: String, maxWidth: Int, maxLineWidth: Int): Int = { - var pos = 0 - var lastBreak = -1 - while (pos < s.length) { - pos += 1 - val width = stringWidth(s.take(pos)) - if (width >= maxWidth) { - if (lastBreak > 0 || stringWidth(s) <= maxLineWidth || s.exists(breaks.contains)) return lastBreak + 1 - else return pos - 1 - } - if (pos < s.length && breaks.contains(s.charAt(pos))) lastBreak = pos - } - pos - } - - private def computeWrapIndent(renderer: FontRenderer) = if (lists.contains(rootPrefix)) renderer.getStringWidth(rootPrefix) else 0 + override protected def stringWidth(s: String, renderer: FontRenderer): Int = s.length * TextBufferRenderCache.renderer.charRenderWidth override def toString: String = s"{CodeSegment: text = $text}" } diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/Segment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/Segment.scala index dd35430f1..7e6ca0527 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/Segment.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/Segment.scala @@ -40,8 +40,14 @@ trait Segment { */ def nextY(indent: Int, maxWidth: Int, renderer: FontRenderer): Int + /** + * Render the segment at the specified coordinates with the specified + * properties. + */ def render(x: Int, y: Int, indent: Int, maxWidth: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = None + // ----------------------------------------------------------------------- // + // Used during construction, checks a segment for inner segments. private[markdown] def refine(pattern: Regex, factory: (Segment, Regex.Match) => Segment): Iterable[Segment] = Iterable(this) diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/TextSegment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/TextSegment.scala index dd2b2c917..e146dccd1 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/TextSegment.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/TextSegment.scala @@ -8,10 +8,32 @@ import scala.annotation.tailrec import scala.collection.mutable import scala.util.matching.Regex -private[markdown] class TextSegment(val parent: Segment, val text: String) extends Segment { - private final val breaks = Set(' ', '.', ',', ':', ';', '!', '?', '_', '=', '-', '+', '*', '/', '\\') - private final val lists = Set("- ", "* ") - private lazy val rootPrefix = root.asInstanceOf[TextSegment].text.take(2) +private[markdown] class TextSegment(val parent: Segment, val text: String) extends BasicTextSegment { + override def render(x: Int, y: Int, indent: Int, maxWidth: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { + var currentX = x + indent + var currentY = y + var chars = text + if (indent == 0) chars = chars.dropWhile(_.isWhitespace) + val wrapIndent = computeWrapIndent(renderer) + var numChars = maxChars(chars, maxWidth - indent, maxWidth - wrapIndent, renderer) + var hovered: Option[InteractiveSegment] = None + while (chars.length > 0) { + val part = chars.take(numChars) + hovered = hovered.orElse(resolvedInteractive.fold(None: Option[InteractiveSegment])(_.checkHovered(mouseX, mouseY, currentX, currentY, stringWidth(part, renderer), (Document.lineHeight(renderer) * resolvedScale).toInt))) + GL11.glPushMatrix() + GL11.glTranslatef(currentX, currentY, 0) + GL11.glScalef(resolvedScale, resolvedScale, resolvedScale) + GL11.glTranslatef(-currentX, -currentY, 0) + renderer.drawString(resolvedFormat + part, currentX, currentY, resolvedColor) + GL11.glPopMatrix() + currentX = x + wrapIndent + currentY += lineHeight(renderer) + chars = chars.drop(numChars).dropWhile(_.isWhitespace) + numChars = maxChars(chars, maxWidth - wrapIndent, maxWidth - wrapIndent, renderer) + } + + hovered + } override def refine(pattern: Regex, factory: (Segment, Regex.Match) => Segment): Iterable[Segment] = { val result = mutable.Buffer.empty[Segment] @@ -39,63 +61,13 @@ private[markdown] class TextSegment(val parent: Segment, val text: String) exten result } - override def nextX(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = { - if (isLast) return 0 - var currentX = indent - var chars = text - if (indent == 0) chars = chars.dropWhile(_.isWhitespace) - val wrapIndent = computeWrapIndent(renderer) - var numChars = maxChars(chars, maxWidth - indent, maxWidth - wrapIndent, renderer) - while (chars.length > numChars) { - chars = chars.drop(numChars).dropWhile(_.isWhitespace) - numChars = maxChars(chars, maxWidth - wrapIndent, maxWidth - wrapIndent, renderer) - currentX = wrapIndent - } - currentX + (stringWidth(chars, renderer) * resolvedScale).toInt - } + // ----------------------------------------------------------------------- // - override def nextY(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = { - var lines = 0 - var chars = text - if (indent == 0) chars = chars.dropWhile(_.isWhitespace) - val wrapIndent = computeWrapIndent(renderer) - var numChars = maxChars(chars, maxWidth - indent, maxWidth - wrapIndent, renderer) - while (chars.length > numChars) { - lines += 1 - chars = chars.drop(numChars).dropWhile(_.isWhitespace) - numChars = maxChars(chars, maxWidth - wrapIndent, maxWidth - wrapIndent, renderer) - } - if (isLast) lines += 1 - (lines * Document.lineHeight(renderer) * resolvedScale).toInt - } + override protected def lineHeight(renderer: FontRenderer): Int = (super.lineHeight(renderer) * resolvedScale).toInt - override def render(x: Int, y: Int, indent: Int, maxWidth: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { - val fontScale = resolvedScale - var currentX = x + indent - var currentY = y - var chars = text - if (indent == 0) chars = chars.dropWhile(_.isWhitespace) - val wrapIndent = computeWrapIndent(renderer) - var numChars = maxChars(chars, maxWidth - indent, maxWidth - wrapIndent, renderer) - val interactive = findInteractive() - var hovered: Option[InteractiveSegment] = None - while (chars.length > 0) { - val part = chars.take(numChars) - hovered = hovered.orElse(interactive.fold(None: Option[InteractiveSegment])(_.checkHovered(mouseX, mouseY, currentX, currentY, (stringWidth(part, renderer) * fontScale).toInt, (Document.lineHeight(renderer) * fontScale).toInt))) - GL11.glPushMatrix() - GL11.glTranslatef(currentX, currentY, 0) - GL11.glScalef(fontScale, fontScale, fontScale) - GL11.glTranslatef(-currentX, -currentY, 0) - renderer.drawString(resolvedFormat + part, currentX, currentY, resolvedColor) - GL11.glPopMatrix() - currentX = x + wrapIndent - currentY += (Document.lineHeight(renderer) * fontScale).toInt - chars = chars.drop(numChars).dropWhile(_.isWhitespace) - numChars = maxChars(chars, maxWidth - wrapIndent, maxWidth - wrapIndent, renderer) - } + override protected def stringWidth(s: String, renderer: FontRenderer): Int = (renderer.getStringWidth(resolvedFormat + s) * resolvedScale).toInt - hovered - } + // ----------------------------------------------------------------------- // protected def color = None: Option[Int] @@ -103,48 +75,28 @@ private[markdown] class TextSegment(val parent: Segment, val text: String) exten protected def format = "" - protected def stringWidth(s: String, renderer: FontRenderer): Int = renderer.getStringWidth(resolvedFormat + s) + private def resolvedColor: Int = color.getOrElse(parent match { + case segment: TextSegment => segment.resolvedColor + case _ => 0xDDDDDD + }) - def resolvedColor: Int = parent match { - case segment: TextSegment => color.getOrElse(segment.resolvedColor) - case _ => color.getOrElse(0xDDDDDD) + private def resolvedScale: Float = parent match { + case segment: TextSegment => scale.getOrElse(1f) * segment.resolvedScale + case _ => 1f } - def resolvedScale: Float = parent match { - case segment: TextSegment => scale.getOrElse(segment.resolvedScale) - case _ => scale.getOrElse(1f) - } - - def resolvedFormat: String = parent match { + private def resolvedFormat: String = parent match { case segment: TextSegment => segment.resolvedFormat + format case _ => format } - @tailrec private def findInteractive(): Option[InteractiveSegment] = this match { + private lazy val resolvedInteractive: Option[InteractiveSegment] = this match { case segment: InteractiveSegment => Some(segment) case _ => parent match { - case segment: TextSegment => segment.findInteractive() + case segment: TextSegment => segment.resolvedInteractive case _ => None } } - private def maxChars(s: String, maxWidth: Int, maxLineWidth: Int, renderer: FontRenderer): Int = { - val fontScale = resolvedScale - var pos = -1 - var lastBreak = -1 - while (pos < s.length) { - pos += 1 - val width = (stringWidth(s.take(pos), renderer) * fontScale).toInt - if (width >= maxWidth) { - if (lastBreak > 0 || stringWidth(s, renderer) <= maxLineWidth || s.exists(breaks.contains)) return lastBreak + 1 - else return pos - 1 - } - if (pos < s.length && breaks.contains(s.charAt(pos))) lastBreak = pos - } - pos - } - - private def computeWrapIndent(renderer: FontRenderer) = if (lists.contains(rootPrefix)) renderer.getStringWidth(rootPrefix) else 0 - override def toString: String = s"{TextSegment: text = $text}" } From 9fb1406f1c9fcd2a81e3b287ede98b3d80016608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sun, 12 Apr 2015 15:02:58 +0200 Subject: [PATCH 05/37] Also registering manual as `craftingBook` in oredict. --- .../markdown/segment/TextSegment.scala | 1 - .../scala/li/cil/oc/common/init/Items.scala | 3 ++- .../li/cil/oc/common/recipe/Recipes.scala | 20 +++++++++---------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/TextSegment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/TextSegment.scala index e146dccd1..9c0bc8383 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/TextSegment.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/TextSegment.scala @@ -4,7 +4,6 @@ import li.cil.oc.client.renderer.markdown.Document import net.minecraft.client.gui.FontRenderer import org.lwjgl.opengl.GL11 -import scala.annotation.tailrec import scala.collection.mutable import scala.util.matching.Regex diff --git a/src/main/scala/li/cil/oc/common/init/Items.scala b/src/main/scala/li/cil/oc/common/init/Items.scala index f8c758e2a..24154dd7d 100644 --- a/src/main/scala/li/cil/oc/common/init/Items.scala +++ b/src/main/scala/li/cil/oc/common/init/Items.scala @@ -29,6 +29,7 @@ import net.minecraft.item.ItemBlock import net.minecraft.item.ItemStack import net.minecraft.nbt.NBTTagCompound import net.minecraft.world.World +import net.minecraftforge.oredict.OreDictionary import scala.collection.mutable @@ -460,6 +461,6 @@ object Items extends ItemAPI { Recipes.addSubItem(new item.TexturePicker(multi), Constants.ItemName.TexturePicker, "oc:texturePicker") // 1.5.7 - Recipes.addSubItem(new item.Manual(multi), Constants.ItemName.Manual, "oc:manual") + Recipes.addSubItem(new item.Manual(multi), Constants.ItemName.Manual, "oc:manual", "craftingBook") } } diff --git a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala b/src/main/scala/li/cil/oc/common/recipe/Recipes.scala index 06dde6562..f4954bef7 100644 --- a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala +++ b/src/main/scala/li/cil/oc/common/recipe/Recipes.scala @@ -35,30 +35,30 @@ object Recipes { val oreDictEntries = mutable.LinkedHashMap.empty[String, ItemStack] var hadErrors = false - def addBlock(instance: Block, name: String, oreDict: String = null) = { + def addBlock(instance: Block, name: String, oreDict: String*) = { Items.registerBlock(instance, name) addRecipe(new ItemStack(instance), name) - register(oreDict, instance match { + register(instance match { case simple: SimpleBlock => simple.createItemStack() case _ => new ItemStack(instance) - }) + }, oreDict: _*) instance } - def addSubItem[T <: common.item.Delegate](delegate: T, name: String, oreDict: String = null) = { + def addSubItem[T <: common.item.Delegate](delegate: T, name: String, oreDict: String*) = { Items.registerItem(delegate, name) addRecipe(delegate.createItemStack(), name) - register(oreDict, delegate.createItemStack()) + register(delegate.createItemStack(), oreDict: _*) delegate } - def addItem(instance: Item, name: String, oreDict: String = null) = { + def addItem(instance: Item, name: String, oreDict: String*) = { Items.registerItem(instance, name) addRecipe(new ItemStack(instance), name) - register(oreDict, instance match { + register(instance match { case simple: SimpleItem => simple.createItemStack() case _ => new ItemStack(instance) - }) + }, oreDict: _*) instance } @@ -66,8 +66,8 @@ object Recipes { list += stack -> name } - private def register(name: String, item: ItemStack) { - if (name != null) { + private def register(item: ItemStack, names: String*) { + for (name <- names if name != null) { oreDictEntries += name -> item } } From 10a640d8ee1ea5a9d03b1bfab7fc21346477dcff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sun, 12 Apr 2015 16:46:03 +0200 Subject: [PATCH 06/37] Give a free manual to players once. --- src/main/resources/application.conf | 5 +++++ src/main/scala/li/cil/oc/Settings.scala | 1 + .../scala/li/cil/oc/common/EventHandler.scala | 20 +++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index a6ae0505f..441d15e02 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -1069,6 +1069,11 @@ opencomputers { # avoid issues with computers timing out, but can also lead to higher # server load. AGAIN, USE WITH CARE! threadPriority: -1 + + # Whether to give a new player a free copy of the manual. This will only + # happen one time per game, not per world, not per death. Once. If this + # is still too much for your taste, disable it here ;-) + giveManualToNewPlayers: true } # Settings for mod integration (the mod previously known as OpenComponents). diff --git a/src/main/scala/li/cil/oc/Settings.scala b/src/main/scala/li/cil/oc/Settings.scala index 339478458..72a2a4f2e 100644 --- a/src/main/scala/li/cil/oc/Settings.scala +++ b/src/main/scala/li/cil/oc/Settings.scala @@ -293,6 +293,7 @@ class Settings(val config: Config) { val presentChance = config.getDouble("misc.presentChance") max 0 min 1 val assemblerBlacklist = config.getStringList("misc.assemblerBlacklist") val threadPriority = config.getInt("misc.threadPriority") + val giveManualToNewPlayers = config.getBoolean("misc.giveManualToNewPlayers") // ----------------------------------------------------------------------- // // printer diff --git a/src/main/scala/li/cil/oc/common/EventHandler.scala b/src/main/scala/li/cil/oc/common/EventHandler.scala index eaf3223a8..7dbd5c594 100644 --- a/src/main/scala/li/cil/oc/common/EventHandler.scala +++ b/src/main/scala/li/cil/oc/common/EventHandler.scala @@ -28,13 +28,16 @@ import li.cil.oc.server.machine.Machine import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.util._ import net.minecraft.client.Minecraft +import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayerMP import net.minecraft.item.ItemStack +import net.minecraft.nbt.NBTTagCompound import net.minecraft.server.MinecraftServer import net.minecraft.tileentity.TileEntity import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.util.FakePlayer import net.minecraftforge.common.util.ForgeDirection +import net.minecraftforge.event.entity.EntityJoinWorldEvent import net.minecraftforge.event.world.BlockEvent import net.minecraftforge.event.world.WorldEvent @@ -227,6 +230,23 @@ object EventHandler { keyboards.foreach(_.releasePressedKeys(e.player)) } + @SubscribeEvent + def onEntityJoinWorld(e: EntityJoinWorldEvent): Unit = { + if (Settings.get.giveManualToNewPlayers && !e.world.isRemote) e.entity match { + case player: EntityPlayer if !player.isInstanceOf[FakePlayer] => + val nbt = player.getEntityData + if (!nbt.hasKey(EntityPlayer.PERSISTED_NBT_TAG)) { + nbt.setTag(EntityPlayer.PERSISTED_NBT_TAG, new NBTTagCompound()) + } + val ocData = nbt.getCompoundTag(EntityPlayer.PERSISTED_NBT_TAG) + if (!ocData.getBoolean(Settings.namespace + "receivedManual")) { + ocData.setBoolean(Settings.namespace + "receivedManual", true) + player.inventory.addItemStackToInventory(api.Items.get(Constants.ItemName.Manual).createItemStack(1)) + } + case _ => + } + } + lazy val drone = api.Items.get(Constants.ItemName.Drone) lazy val eeprom = api.Items.get(Constants.ItemName.EEPROM) lazy val mcu = api.Items.get(Constants.BlockName.Microcontroller) From c0ff965fa7ab0cc2a1f8e475f30cd62b9fe85ae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Mon, 13 Apr 2015 02:24:34 +0200 Subject: [PATCH 07/37] Fixed regression in redstone handling of print with only one state. Only rendering robot labels once per frame (not in both render passes, herp). --- .../resources/assets/opencomputers/doc/en_US/item/manual.md | 4 +++- .../li/cil/oc/client/renderer/tileentity/RobotRenderer.scala | 4 ++-- src/main/scala/li/cil/oc/common/item/data/PrintData.scala | 2 ++ src/main/scala/li/cil/oc/common/tileentity/Print.scala | 2 +- src/main/scala/li/cil/oc/integration/fmp/PrintPart.scala | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/manual.md b/src/main/resources/assets/opencomputers/doc/en_US/item/manual.md index def7a4779..9a01e1dcb 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/manual.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/manual.md @@ -10,4 +10,6 @@ Navigating the manual is similar to browsing a wiki: click on links (1) to follo When opening the manual again at a later point, you will return to the page you were on when you closed it. You can start over on the main index page by using it while sneaking. It is also possible to directly jump to a page concerning a block in the world by using the block while sneaking with the manual in hand. -If your questions are not answered by the manual, other places with information are the [wiki](http://ocdoc.cil.li), OpenComputers' [IRC channel](http://webchat.esper.net/?channels=#oc) and the [forums](http://oc.cil.li/). +If your questions are not answered by the manual, other places with information are [the wiki](http://ocdoc.cil.li), OpenComputers' [IRC channel](http://webchat.esper.net/?channels=#oc) and [the forums](http://oc.cil.li/). + +If you spot any mistakes in the manual, factual, grammatical or otherwise, or bugs in the mod, for that matter, please let us know [via the issue tracker](https://github.com/MightyPirates/OpenComputers/issues). If you'd like to contribute to the manual by adding content, get in touch via IRC or by creating a ticket on the issue tracker. diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/RobotRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/RobotRenderer.scala index a223b60e5..922495a4f 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/RobotRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/RobotRenderer.scala @@ -428,7 +428,7 @@ object RobotRenderer extends TileEntitySpecialRenderer { GL11.glPopMatrix() val name = robot.name - if (Settings.get.robotLabels && !Strings.isNullOrEmpty(name) && x * x + y * y + z * z < RendererLivingEntity.NAME_TAG_RANGE) { + if (Settings.get.robotLabels && MinecraftForgeClient.getRenderPass == 1 && !Strings.isNullOrEmpty(name) && x * x + y * y + z * z < RendererLivingEntity.NAME_TAG_RANGE) { GL11.glPushMatrix() // This is pretty much copy-pasta from the entity's label renderer. @@ -452,7 +452,7 @@ object RobotRenderer extends TileEntitySpecialRenderer { GL11.glDisable(GL11.GL_TEXTURE_2D) t.startDrawingQuads() - t.setColorRGBA_F(0, 0, 0, 0.25f) + t.setColorRGBA_F(0, 0, 0, 0.5f) t.addVertex(-halfWidth - 1, -1, 0) t.addVertex(-halfWidth - 1, 8, 0) t.addVertex(halfWidth + 1, 8, 0) diff --git a/src/main/scala/li/cil/oc/common/item/data/PrintData.scala b/src/main/scala/li/cil/oc/common/item/data/PrintData.scala index 78a3038e3..de696fa2c 100644 --- a/src/main/scala/li/cil/oc/common/item/data/PrintData.scala +++ b/src/main/scala/li/cil/oc/common/item/data/PrintData.scala @@ -31,6 +31,8 @@ class PrintData extends ItemData { def emitRedstone = redstoneLevel > 0 && stateOn.size > 0 + def hasActiveState = stateOn.size > 0 + def opacity = { if (opacityDirty) { opacityDirty = false diff --git a/src/main/scala/li/cil/oc/common/tileentity/Print.scala b/src/main/scala/li/cil/oc/common/tileentity/Print.scala index 8e344c2a3..17da93df2 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Print.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Print.scala @@ -44,7 +44,7 @@ class Print extends traits.TileEntity with traits.RedstoneAware with traits.Rota override protected def onRedstoneInputChanged(side: ForgeDirection, oldMaxValue: Int, newMaxValue: Int): Unit = { super.onRedstoneInputChanged(side, oldMaxValue, newMaxValue) - if (!data.emitRedstone) { + if (!data.emitRedstone && data.hasActiveState) { state = newMaxValue > 0 world.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, "random.click", 0.3F, if (state) 0.6F else 0.5F) world.markBlockForUpdate(x, y, z) diff --git a/src/main/scala/li/cil/oc/integration/fmp/PrintPart.scala b/src/main/scala/li/cil/oc/integration/fmp/PrintPart.scala index 18ec70ef4..14f2d296a 100644 --- a/src/main/scala/li/cil/oc/integration/fmp/PrintPart.scala +++ b/src/main/scala/li/cil/oc/integration/fmp/PrintPart.scala @@ -263,7 +263,7 @@ class PrintPart(val original: Option[tileentity.Print] = None) extends SimpleBlo protected def checkRedstone(): Unit = { val newMaxValue = computeInput() val newState = newMaxValue > 1 // Fixes oddities in cycling updates. - if (!data.emitRedstone && state != newState) { + if (!data.emitRedstone && data.hasActiveState && state != newState) { toggleState() } } From 3fe3f81d7dbcd7fb9162a41db3a7cd0a25e9ba14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Mon, 13 Apr 2015 03:38:21 +0200 Subject: [PATCH 08/37] Make prints set to emit redstone but not having a second state emit redstone always. --- .../client/renderer/item/ItemRenderer.scala | 2 +- .../scala/li/cil/oc/common/block/Print.scala | 2 +- .../cil/oc/common/item/data/PrintData.scala | 12 ++++++-- .../li/cil/oc/common/tileentity/Print.scala | 8 +++-- .../li/cil/oc/common/tileentity/Printer.scala | 30 +++++++++---------- .../li/cil/oc/integration/fmp/PrintPart.scala | 12 ++++---- 6 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/main/scala/li/cil/oc/client/renderer/item/ItemRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/item/ItemRenderer.scala index 017cd24e8..d20c17123 100644 --- a/src/main/scala/li/cil/oc/client/renderer/item/ItemRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/item/ItemRenderer.scala @@ -168,7 +168,7 @@ object ItemRenderer extends IItemRenderer { val data = new PrintData(stack) Minecraft.getMinecraft.renderEngine.bindTexture(TextureMap.locationBlocksTexture) val state = - if (data.stateOn.size > 0 && KeyBindings.showExtendedTooltips) + if (data.hasActiveState && KeyBindings.showExtendedTooltips) data.stateOn else data.stateOff diff --git a/src/main/scala/li/cil/oc/common/block/Print.scala b/src/main/scala/li/cil/oc/common/block/Print.scala index e7a807e78..febfaa1e0 100644 --- a/src/main/scala/li/cil/oc/common/block/Print.scala +++ b/src/main/scala/li/cil/oc/common/block/Print.scala @@ -62,7 +62,7 @@ class Print(protected implicit val tileTag: ClassTag[tileentity.Print]) extends if (data.emitRedstone) { tooltip.add(Localization.Tooltip.PrintRedstoneLevel(data.redstoneLevel)) } - if (data.lightLevel > 0) { + if (data.emitLight) { tooltip.add(Localization.Tooltip.PrintLightValue(data.lightLevel)) } } diff --git a/src/main/scala/li/cil/oc/common/item/data/PrintData.scala b/src/main/scala/li/cil/oc/common/item/data/PrintData.scala index de696fa2c..341a6962f 100644 --- a/src/main/scala/li/cil/oc/common/item/data/PrintData.scala +++ b/src/main/scala/li/cil/oc/common/item/data/PrintData.scala @@ -29,10 +29,18 @@ class PrintData extends ItemData { var isBeaconBase = false var lightLevel = 0 - def emitRedstone = redstoneLevel > 0 && stateOn.size > 0 - def hasActiveState = stateOn.size > 0 + def emitLight = lightLevel > 0 + + def emitRedstone = redstoneLevel > 0 + + def emitRedstone(state: Boolean): Boolean = if (state) emitRedstoneWhenOn else emitRedstoneWhenOff + + def emitRedstoneWhenOff = emitRedstone && !hasActiveState + + def emitRedstoneWhenOn = emitRedstone && hasActiveState + def opacity = { if (opacityDirty) { opacityDirty = false diff --git a/src/main/scala/li/cil/oc/common/tileentity/Print.scala b/src/main/scala/li/cil/oc/common/tileentity/Print.scala index 17da93df2..58c94f823 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Print.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Print.scala @@ -19,7 +19,7 @@ class Print extends traits.TileEntity with traits.RedstoneAware with traits.Rota _isOutputEnabled = true def activate(): Boolean = { - if (data.stateOn.size > 0) { + if (data.hasActiveState) { if (!state || !data.isButtonMode) { toggleState() return true @@ -32,7 +32,7 @@ class Print extends traits.TileEntity with traits.RedstoneAware with traits.Rota state = !state world.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, "random.click", 0.3F, if (state) 0.6F else 0.5F) world.markBlockForUpdate(x, y, z) - if (data.emitRedstone) { + if (data.emitRedstoneWhenOn) { ForgeDirection.VALID_DIRECTIONS.foreach(output(_, if (state) data.redstoneLevel else 0)) } if (state && data.isButtonMode) { @@ -89,6 +89,10 @@ class Print extends traits.TileEntity with traits.RedstoneAware with traits.Rota boundsOn = data.stateOn.drop(1).foldLeft(data.stateOn.headOption.fold(ExtendedAABB.unitBounds)(_.bounds))((a, b) => a.func_111270_a(b.bounds)) if (boundsOn.volume == 0) boundsOn = ExtendedAABB.unitBounds else boundsOn = boundsOn.rotateTowards(facing) + + if (data.emitRedstoneWhenOff) { + ForgeDirection.VALID_DIRECTIONS.foreach(output(_, data.redstoneLevel)) + } } override protected def onRotationChanged(): Unit = { diff --git a/src/main/scala/li/cil/oc/common/tileentity/Printer.scala b/src/main/scala/li/cil/oc/common/tileentity/Printer.scala index edab5033d..503883846 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Printer.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Printer.scala @@ -57,7 +57,7 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat // ----------------------------------------------------------------------- // - def canPrint = data.stateOff.size > 0 && data.stateOff.size + data.stateOn.size <= Settings.get.maxPrintComplexity + def canPrint = data.stateOff.size > 0 && data.stateOff.size < Settings.get.maxPrintComplexity && data.stateOn.size < Settings.get.maxPrintComplexity def isPrinting = output.isDefined @@ -100,6 +100,18 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat result(data.tooltip.orNull) } + @Callback(doc = """function(value:number) -- Set what light level the printed block should have.""") + def setLightLevel(context: Context, args: Arguments): Array[Object] = { + data.lightLevel = args.checkInteger(0) max 0 min Settings.get.maxPrintLightLevel + isActive = false // Needs committing. + null + } + + @Callback(doc = """function():number -- Get which light level the printed block should have.""") + def getLightLevel(context: Context, args: Arguments): Array[Object] = { + result(data.lightLevel) + } + @Callback(doc = """function(value:boolean or number) -- Set whether the printed block should emit redstone when in its active state.""") def setRedstoneEmitter(context: Context, args: Arguments): Array[Object] = { if (args.isBoolean(0)) data.redstoneLevel = if (args.checkBoolean(0)) 15 else 0 @@ -113,18 +125,6 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat result(data.emitRedstone, data.redstoneLevel) } - @Callback(doc = """function(value:number) -- Set what light level the printed block should have.""") - def setLightLevel(context: Context, args: Arguments): Array[Object] = { - data.lightLevel = args.checkInteger(0) max 0 min Settings.get.maxPrintLightLevel - isActive = false // Needs committing. - null - } - - @Callback(doc = """function():number -- Get which light level the printed block should have.""") - def getLightLevel(context: Context, args: Arguments): Array[Object] = { - result(data.lightLevel) - } - @Callback(doc = """function(value:boolean) -- Set whether the printed block should automatically return to its off state.""") def setButtonMode(context: Context, args: Arguments): Array[Object] = { data.isButtonMode = args.checkBoolean(0) @@ -139,7 +139,7 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat @Callback(doc = """function(minX:number, minY:number, minZ:number, maxX:number, maxY:number, maxZ:number, texture:string[, state:boolean=false][,tint:number]) -- Adds a shape to the printers configuration, optionally specifying whether it is for the off or on state.""") def addShape(context: Context, args: Arguments): Array[Object] = { - if (data.stateOff.size + data.stateOn.size >= Settings.get.maxPrintComplexity) { + if (data.stateOff.size >= Settings.get.maxPrintComplexity || data.stateOn.size >= Settings.get.maxPrintComplexity) { return result(null, "model too complex") } val minX = (args.checkInteger(0) max 0 min 16) / 16f @@ -173,7 +173,7 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat } @Callback(doc = """function():number -- Get the number of shapes in the current configuration.""") - def getShapeCount(context: Context, args: Arguments): Array[Object] = result(data.stateOff.size + data.stateOn.size) + def getShapeCount(context: Context, args: Arguments): Array[Object] = result(data.stateOff.size, data.stateOn.size) @Callback(doc = """function():number -- Get the maximum allowed number of shapes.""") def getMaxShapeCount(context: Context, args: Arguments): Array[Object] = result(Settings.get.maxPrintComplexity) diff --git a/src/main/scala/li/cil/oc/integration/fmp/PrintPart.scala b/src/main/scala/li/cil/oc/integration/fmp/PrintPart.scala index 14f2d296a..d4f8c9e35 100644 --- a/src/main/scala/li/cil/oc/integration/fmp/PrintPart.scala +++ b/src/main/scala/li/cil/oc/integration/fmp/PrintPart.scala @@ -138,20 +138,20 @@ class PrintPart(val original: Option[tileentity.Print] = None) extends SimpleBlo // ----------------------------------------------------------------------- // - override def conductsRedstone: Boolean = data.emitRedstone && state + override def conductsRedstone: Boolean = if (state) data.emitRedstoneWhenOn else data.emitRedstoneWhenOff - override def redstoneConductionMap: Int = if (data.emitRedstone && state) 0xFF else 0 + override def redstoneConductionMap: Int = if (conductsRedstone) 0xFF else 0 override def canConnectRedstone(side: Int): Boolean = true override def strongPowerLevel(side: Int): Int = weakPowerLevel(side) - override def weakPowerLevel(side: Int): Int = if (data.emitRedstone && state) data.redstoneLevel else 0 + override def weakPowerLevel(side: Int): Int = if (data.emitRedstone(state)) data.redstoneLevel else 0 // ----------------------------------------------------------------------- // override def activate(player: EntityPlayer, hit: MovingObjectPosition, item: ItemStack): Boolean = { - if (data.stateOn.size > 0) { + if (data.hasActiveState) { if (!state || !data.isButtonMode) { toggleState() return true @@ -262,7 +262,7 @@ class PrintPart(val original: Option[tileentity.Print] = None) extends SimpleBlo protected def checkRedstone(): Unit = { val newMaxValue = computeInput() - val newState = newMaxValue > 1 // Fixes oddities in cycling updates. + val newState = newMaxValue > 1 // >1 Fixes oddities in cycling updates. if (!data.emitRedstone && data.hasActiveState && state != newState) { toggleState() } @@ -270,7 +270,7 @@ class PrintPart(val original: Option[tileentity.Print] = None) extends SimpleBlo protected def computeInput(): Int = { val inner = tile.partList.foldLeft(0)((power, part) => part match { - case print: PrintPart if print.state && print.data.emitRedstone => math.max(power, print.data.redstoneLevel) + case print: PrintPart if print.data.emitRedstone(print.state) => math.max(power, print.data.redstoneLevel) case _ => power }) math.max(inner, ForgeDirection.VALID_DIRECTIONS.map(computeInput).max) From 0e883fb08ba4b579fe8613dc86bfaff82f0ffe24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Mon, 13 Apr 2015 19:06:54 +0200 Subject: [PATCH 09/37] Added functionality to allow defining recipes for (built-in) loot disks. OpenOS recipe is defined differently now! OPPM now has a recipe. --- .../opencomputers/recipes/default.recipes | 25 +++-- src/main/scala/li/cil/oc/common/Loot.scala | 5 +- .../scala/li/cil/oc/common/init/Items.scala | 16 +-- .../li/cil/oc/common/recipe/Recipes.scala | 99 +++++++++++-------- 4 files changed, 80 insertions(+), 65 deletions(-) diff --git a/src/main/resources/assets/opencomputers/recipes/default.recipes b/src/main/resources/assets/opencomputers/recipes/default.recipes index 2c53ee43f..9625c1efa 100644 --- a/src/main/resources/assets/opencomputers/recipes/default.recipes +++ b/src/main/resources/assets/opencomputers/recipes/default.recipes @@ -15,6 +15,23 @@ manual { type: shapeless input: [book, "oc:circuitChip1"] } +lootDisks: [ + { + name: OpenOS + type: shapeless + input: ["oc:floppy", "oc:manual"] + }, + { + name: OPPM + type: shapeless + input: ["oc:floppy", "oc:internetCard"] + } +] +luaBios { + type: shapeless + input: ["oc:eeprom", "oc:manual"] +} + droneCase1 { input: [[{block="minecraft:end_stone"}, compass, {block="minecraft:end_stone"}] ["oc:circuitChip1", "oc:microcontrollerCase1", "oc:circuitChip1"] @@ -117,14 +134,6 @@ hdd3 { ["oc:materialCircuitBoardPrinted", "oc:materialDisk", craftingPiston] ["oc:circuitChip3", "oc:materialDisk", diamond]] } -openOS { - type: shapeless - input: ["oc:floppy", "oc:manual"] -} -luaBios { - type: shapeless - input: ["oc:eeprom", "oc:manual"] -} graphicsCard1 { input: [["oc:circuitChip1", "oc:materialALU", "oc:ram1"] ["", "oc:materialCard", ""]] diff --git a/src/main/scala/li/cil/oc/common/Loot.scala b/src/main/scala/li/cil/oc/common/Loot.scala index e9125da0e..96f48fec1 100644 --- a/src/main/scala/li/cil/oc/common/Loot.scala +++ b/src/main/scala/li/cil/oc/common/Loot.scala @@ -10,6 +10,7 @@ import li.cil.oc.Settings import li.cil.oc.common.init.Items import li.cil.oc.util.Color import net.minecraft.inventory.IInventory +import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraft.nbt.NBTTagCompound import net.minecraft.util.WeightedRandomChestContent @@ -20,7 +21,7 @@ import net.minecraftforge.event.world.WorldEvent import scala.collection.convert.WrapAsScala._ import scala.collection.mutable -object Loot extends WeightedRandomChestContent(Items.createOpenOS(), 1, 1, Settings.get.lootProbability) { +object Loot extends WeightedRandomChestContent(new ItemStack(null: Item), 1, 1, Settings.get.lootProbability) { val containers = Array( ChestGenHooks.DUNGEON_CHEST, ChestGenHooks.PYRAMID_DESERT_CHEST, @@ -76,7 +77,7 @@ object Loot extends WeightedRandomChestContent(Items.createOpenOS(), 1, 1, Setti } private def parseLootDisks(list: java.util.Properties, acc: mutable.Map[String, (ItemStack, Int)]) { - for (key <- list.stringPropertyNames if key != "OpenOS") { + for (key <- list.stringPropertyNames) { val value = list.getProperty(key) try value.split(":") match { case Array(name, count, color) => diff --git a/src/main/scala/li/cil/oc/common/init/Items.scala b/src/main/scala/li/cil/oc/common/init/Items.scala index 24154dd7d..c3fa12269 100644 --- a/src/main/scala/li/cil/oc/common/init/Items.scala +++ b/src/main/scala/li/cil/oc/common/init/Items.scala @@ -20,7 +20,6 @@ import li.cil.oc.common.item.data.RobotData import li.cil.oc.common.item.data.TabletData import li.cil.oc.common.recipe.Recipes import li.cil.oc.integration.Mods -import li.cil.oc.util.Color import net.minecraft.block.Block import net.minecraft.creativetab.CreativeTabs import net.minecraft.entity.player.EntityPlayer @@ -29,7 +28,6 @@ import net.minecraft.item.ItemBlock import net.minecraft.item.ItemStack import net.minecraft.nbt.NBTTagCompound import net.minecraft.world.World -import net.minecraftforge.oredict.OreDictionary import scala.collection.mutable @@ -115,18 +113,7 @@ object Items extends ItemAPI { // ----------------------------------------------------------------------- // def createOpenOS(amount: Int = 1) = { - val data = new NBTTagCompound() - data.setString(Settings.namespace + "fs.label", "openos") - - val nbt = new NBTTagCompound() - nbt.setTag(Settings.namespace + "data", data) - nbt.setString(Settings.namespace + "lootPath", "OpenOS") - nbt.setInteger(Settings.namespace + "color", Color.dyes.indexOf("dyeGreen")) - - val stack = get(Constants.ItemName.LootDisk).createItemStack(amount) - stack.setTagCompound(nbt) - - stack + Loot.builtInDisks.get("OpenOS").map(_._1.copy()).orNull } def createLuaBios(amount: Int = 1) = { @@ -390,7 +377,6 @@ object Items extends ItemAPI { else super.onItemRightClick(stack, world, player) } } - Recipes.addRecipe(createOpenOS(), "openOS") Recipes.addSubItem(new item.UpgradeInventoryController(multi), Constants.ItemName.InventoryControllerUpgrade, "oc:inventoryControllerUpgrade") Recipes.addSubItem(new item.UpgradeChunkloader(multi), Constants.ItemName.ChunkloaderUpgrade, "oc:chunkloaderUpgrade") diff --git a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala b/src/main/scala/li/cil/oc/common/recipe/Recipes.scala index f4954bef7..537ebb433 100644 --- a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala +++ b/src/main/scala/li/cil/oc/common/recipe/Recipes.scala @@ -7,6 +7,7 @@ import com.typesafe.config._ import cpw.mods.fml.common.Loader import cpw.mods.fml.common.registry.GameRegistry import li.cil.oc._ +import li.cil.oc.common.Loot import li.cil.oc.common.block.SimpleBlock import li.cil.oc.common.init.Items import li.cil.oc.common.item.Delegator @@ -119,7 +120,44 @@ object Recipes { // Register all known recipes. for ((stack, name) <- list) { - addRecipe(stack, recipes, name) + if (recipes.hasPath(name)) { + val value = recipes.getValue(name) + value.valueType match { + case ConfigValueType.OBJECT => + addRecipe(stack, recipes.getConfig(name), "'" + name + "'") + case ConfigValueType.BOOLEAN => + // Explicitly disabled, keep in NEI if true. + if (!value.unwrapped.asInstanceOf[Boolean]) { + hide(stack) + } + case _ => + OpenComputers.log.error(s"Failed adding recipe for '$name', you will not be able to craft this item. The error was: Invalid value for recipe.") + hadErrors = true + } + } + else { + OpenComputers.log.warn(s"No recipe for '$name', you will not be able to craft this item. To suppress this warning, disable the recipe (assign `false` to it).") + hadErrors = true + } + } + + // Register all unknown recipes. Well. Loot disk recipes. + if (recipes.hasPath("lootDisks")) try { + val lootRecipes = recipes.getConfigList("lootDisks") + for (recipe <- lootRecipes) { + val name = recipe.getString("name") + Loot.builtInDisks.get(name) match { + case Some((stack, _)) => addRecipe(stack, recipe, "loot disk '" + name + "'") + case _ => + OpenComputers.log.warn(s"Failed adding recipe for loot disk '$name': No such global loot disk.") + hadErrors = true + } + } + } + catch { + case t: Throwable => + OpenComputers.log.warn("Failed parsing loot disk recipes.", t) + hadErrors = true } // Recrafting operations. @@ -246,54 +284,35 @@ object Recipes { list.clear() } - private def addRecipe(output: ItemStack, list: Config, name: String) = try { - if (list.hasPath(name)) { - val value = list.getValue(name) - value.valueType match { - case ConfigValueType.OBJECT => - val recipe = list.getConfig(name) - val recipeType = tryGetType(recipe) - try { - recipeType match { - case "shaped" => addShapedRecipe(output, recipe) - case "shapeless" => addShapelessRecipe(output, recipe) - case "furnace" => addFurnaceRecipe(output, recipe) - case "gt_assembler" => - if (Mods.GregTech.isAvailable) { - addGTAssemblingMachineRecipe(output, recipe) - } - else { - OpenComputers.log.error(s"Skipping GregTech assembler recipe for '$name' because GregTech is not present, you will not be able to craft this item.") - hadErrors = true - } - case other => - OpenComputers.log.error(s"Failed adding recipe for '$name', you will not be able to craft this item. The error was: Invalid recipe type '$other'.") - hadErrors = true - } + private def addRecipe(output: ItemStack, recipe: Config, name: String) = try { + val recipeType = tryGetType(recipe) + try { + recipeType match { + case "shaped" => addShapedRecipe(output, recipe) + case "shapeless" => addShapelessRecipe(output, recipe) + case "furnace" => addFurnaceRecipe(output, recipe) + case "gt_assembler" => + if (Mods.GregTech.isAvailable) { + addGTAssemblingMachineRecipe(output, recipe) } - catch { - case e: RecipeException => - OpenComputers.log.error(s"Failed adding $recipeType recipe for '$name', you will not be able to craft this item! The error was: ${e.getMessage}") - hadErrors = true + else { + OpenComputers.log.error(s"Skipping GregTech assembler recipe for $name because GregTech is not present, you will not be able to craft this item.") + hadErrors = true } - case ConfigValueType.BOOLEAN => - // Explicitly disabled, keep in NEI if true. - if (!value.unwrapped.asInstanceOf[Boolean]) { - hide(output) - } - case _ => - OpenComputers.log.error(s"Failed adding recipe for '$name', you will not be able to craft this item. The error was: Invalid value for recipe.") + case other => + OpenComputers.log.error(s"Failed adding recipe for $name, you will not be able to craft this item. The error was: Invalid recipe type '$other'.") hadErrors = true } } - else { - OpenComputers.log.warn(s"No recipe for '$name', you will not be able to craft this item. To suppress this warning, disable the recipe (assign `false` to it).") - hadErrors = true + catch { + case e: RecipeException => + OpenComputers.log.error(s"Failed adding $recipeType recipe for $name, you will not be able to craft this item! The error was: ${e.getMessage}") + hadErrors = true } } catch { case e: Throwable => - OpenComputers.log.error(s"Failed adding recipe for '$name', you will not be able to craft this item.", e) + OpenComputers.log.error(s"Failed adding recipe for $name, you will not be able to craft this item.", e) hadErrors = true } From 85a45e863306ce041a143678d592baa2d56c7449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Mon, 13 Apr 2015 21:35:13 +0200 Subject: [PATCH 10/37] Disabled printed block opacity by default, added setting to enable. Rendering too derpy with MC's lighting engine for this for my taste. Added wrench tool, mostly for MC 1.8. --- assets/items.psd | Bin 587368 -> 590598 bytes src/main/java/li/cil/oc/api/API.java | 2 +- .../java/li/cil/oc/api/internal/Wrench.java | 30 ++++++ src/main/resources/application.conf | 10 ++ .../assets/opencomputers/lang/en_US.lang | 2 + .../opencomputers/recipes/default.recipes | 5 + .../opencomputers/textures/items/Wrench.png | Bin 0 -> 528 bytes src/main/scala/li/cil/oc/Constants.scala | 1 + src/main/scala/li/cil/oc/Settings.scala | 1 + .../cil/oc/common/asm/ClassTransformer.scala | 1 + .../scala/li/cil/oc/common/block/Print.scala | 2 +- .../scala/li/cil/oc/common/init/Items.scala | 1 + .../scala/li/cil/oc/common/item/Wrench.scala | 94 ++++++++++++++++++ .../scala/li/cil/oc/integration/Mods.scala | 2 + .../opencomputers/ModOpenComputers.scala | 10 ++ 15 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 src/main/java/li/cil/oc/api/internal/Wrench.java create mode 100644 src/main/resources/assets/opencomputers/textures/items/Wrench.png create mode 100644 src/main/scala/li/cil/oc/common/item/Wrench.scala diff --git a/assets/items.psd b/assets/items.psd index 42bc35c6c6c5a3443db838948e3e7330e18e2fb7..2bf82fc04a028786564edc81ba08ea73bc40a426 100644 GIT binary patch delta 4179 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 diff --git a/src/main/java/li/cil/oc/api/API.java b/src/main/java/li/cil/oc/api/API.java index d37844ed4..adbec7d9c 100644 --- a/src/main/java/li/cil/oc/api/API.java +++ b/src/main/java/li/cil/oc/api/API.java @@ -16,7 +16,7 @@ import li.cil.oc.api.detail.NetworkAPI; */ public class API { public static final String ID_OWNER = "OpenComputers|Core"; - public static final String VERSION = "5.1.0"; + public static final String VERSION = "5.1.1"; public static DriverAPI driver = null; public static FileSystemAPI fileSystem = null; diff --git a/src/main/java/li/cil/oc/api/internal/Wrench.java b/src/main/java/li/cil/oc/api/internal/Wrench.java new file mode 100644 index 000000000..06c6716cb --- /dev/null +++ b/src/main/java/li/cil/oc/api/internal/Wrench.java @@ -0,0 +1,30 @@ +package li.cil.oc.api.internal; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; + +/** + * Implemented on items that are wrench-like tools. + */ +public interface Wrench { + /** + * Called when the wrench is used. + *

+ * This is called in two scenarios, once when testing whether the wrench + * can be used on a certain block, in which case the simulate + * argument will be true, and once when actually used on a block, + * in which case the simulate argument will be false, + * allowing the tool to damage itself, for example. + *

+ * This is usually called from blocks' activation logic. + * + * @param player the player using the tool + * @param world the world containing the block the wrench is used on. + * @param x the X coordinate of the block. + * @param y the Y coordinate of the block. + * @param z the Z coordinate of the block. + * @param simulate whether to simulate the usage. + * @return whether the wrench can be used on the block. + */ + boolean useWrenchOnBlock(EntityPlayer player, World world, int x, int y, int z, boolean simulate); +} diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index 441d15e02..4ada8d8e9 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -946,6 +946,16 @@ opencomputers { # cartridge. Tweak this if you think printing is too cheap or expensive. # Note: the amount a single dye adds is this divided by 10. inkValue: 50000 + + # Whether to enable print opacity, i.e. make prints have shadows. If + # enabled, prints will have an opacity that is estimated from their + # sampled fill rate. This is disabled by default, because MC's lighting + # computation is apparently not very happy with multiple blocks with + # dynamic opacity sitting next to each other, and since all prints share + # the same block type, this can lead to weird shadows on prints. If you + # don't care about that and prefer them to be not totally shadowless, + # enable this. + printsHaveOpacity: false } # Other settings that you might find useful to tweak. diff --git a/src/main/resources/assets/opencomputers/lang/en_US.lang b/src/main/resources/assets/opencomputers/lang/en_US.lang index ee936e3da..388ec1164 100644 --- a/src/main/resources/assets/opencomputers/lang/en_US.lang +++ b/src/main/resources/assets/opencomputers/lang/en_US.lang @@ -135,6 +135,7 @@ item.oc.UpgradeTankController.name=Tank Controller Upgrade item.oc.UpgradeTractorBeam.name=Tractor Beam Upgrade item.oc.WirelessNetworkCard.name=Wireless Network Card item.oc.WorldSensorCard.name=World Sensor Card +item.oc.wrench.name=Scrench # Entities entity.oc.Drone.name=Drone @@ -338,6 +339,7 @@ oc:tooltip.UpgradeTankController=This upgrade allows robots and drones more cont oc:tooltip.UpgradeTractorBeam=Equips a device with extremely advanced technology, nicknamed the "Item Magnet". Allows the device to pick up items anywhere within 3 blocks of its location. oc:tooltip.WirelessNetworkCard=Allows wireless sending of network messages in addition to normal ones. You can adjust the §fsignal strength§7 to control how far messages are sent. Higher signal strength results in higher energy consumption. oc:tooltip.WorldSensorCard=Allows reading out information about the world, such as its gravity and whether it has a breathable atmosphere. Use results at own risk. The manufacturer takes no responsibility for bodily or material harm caused by decisions made upon the cards' outputs. We have lawyers. And money. Don't even try. +oc:tooltip.Wrench=A hybrid of Screwdriver and Wrench, this tool is easy to learn, but hard to master. #Achievements achievement.oc.adapter=Plug In Baby diff --git a/src/main/resources/assets/opencomputers/recipes/default.recipes b/src/main/resources/assets/opencomputers/recipes/default.recipes index 9625c1efa..755a133f1 100644 --- a/src/main/resources/assets/opencomputers/recipes/default.recipes +++ b/src/main/resources/assets/opencomputers/recipes/default.recipes @@ -15,6 +15,11 @@ manual { type: shapeless input: [book, "oc:circuitChip1"] } +wrench { + input: [[ingotIron, "", ingotIron] + ["", "oc:circuitChip2", ""], + ["", ingotIron, ""]] +} lootDisks: [ { name: OpenOS diff --git a/src/main/resources/assets/opencomputers/textures/items/Wrench.png b/src/main/resources/assets/opencomputers/textures/items/Wrench.png new file mode 100644 index 0000000000000000000000000000000000000000..0c2e620af0865646c2430933eaa6f39f4204cdd0 GIT binary patch literal 528 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8^8r2~t`nE7H{<2i(6L&$VSm%~g&`s$jvjI9+U7n&LUYz` zwc+D)^h{{5Hr-KKzGeUE2u&4B#{dsSx%L^07VKKsI%`ROUH<+P7dIZ>JbCeI2M?zs z=dRXGn%ib;F?ZL3nw~yG9v)kFdv|}&*e_76mFL^s{tNX5xe_#Asoe=eM#i}&zQ log.warn(s"Skipping interface $interfaceName from unknown mod $modid.") + ClassTransformer.hadErrors = true } case _ => } diff --git a/src/main/scala/li/cil/oc/common/block/Print.scala b/src/main/scala/li/cil/oc/common/block/Print.scala index febfaa1e0..061df66c6 100644 --- a/src/main/scala/li/cil/oc/common/block/Print.scala +++ b/src/main/scala/li/cil/oc/common/block/Print.scala @@ -75,7 +75,7 @@ class Print(protected implicit val tileTag: ClassTag[tileentity.Print]) extends override def getLightOpacity(world: IBlockAccess, x: Int, y: Int, z: Int): Int = world.getTileEntity(x, y, z) match { - case print: tileentity.Print => (print.data.opacity * 4).toInt + case print: tileentity.Print if Settings.get.printsHaveOpacity => (print.data.opacity * 4).toInt case _ => super.getLightOpacity(world, x, y, z) } diff --git a/src/main/scala/li/cil/oc/common/init/Items.scala b/src/main/scala/li/cil/oc/common/init/Items.scala index c3fa12269..d3ee1f3a0 100644 --- a/src/main/scala/li/cil/oc/common/init/Items.scala +++ b/src/main/scala/li/cil/oc/common/init/Items.scala @@ -448,5 +448,6 @@ object Items extends ItemAPI { // 1.5.7 Recipes.addSubItem(new item.Manual(multi), Constants.ItemName.Manual, "oc:manual", "craftingBook") + Recipes.addItem(new item.Wrench(), Constants.ItemName.Wrench, "oc:wrench") } } diff --git a/src/main/scala/li/cil/oc/common/item/Wrench.scala b/src/main/scala/li/cil/oc/common/item/Wrench.scala new file mode 100644 index 000000000..2fff19aa7 --- /dev/null +++ b/src/main/scala/li/cil/oc/common/item/Wrench.scala @@ -0,0 +1,94 @@ +package li.cil.oc.common.item + +import li.cil.oc.api +import li.cil.oc.common.asm.Injectable +import li.cil.oc.integration.Mods +import net.minecraft.block.Block +import net.minecraft.entity.EntityLivingBase +import net.minecraft.entity.item.EntityMinecart +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.init.Blocks +import net.minecraft.item.ItemStack +import net.minecraft.world.World +import net.minecraftforge.common.util.ForgeDirection + +@Injectable.InterfaceList(Array( + new Injectable.Interface(value = "appeng.api.implementations.items.IAEWrench", modid = Mods.IDs.AppliedEnergistics2), + new Injectable.Interface(value = "buildcraft.api.tools.IToolWrench", modid = Mods.IDs.BuildCraftTools), + new Injectable.Interface(value = "cofh.api.item.IToolHammer", modid = Mods.IDs.CoFHItem), + new Injectable.Interface(value = "crazypants.enderio.tool.ITool", modid = Mods.IDs.EnderIO), + new Injectable.Interface(value = "mekanism.api.IMekWrench", modid = Mods.IDs.Mekanism), + new Injectable.Interface(value = "powercrystals.minefactoryreloaded.api.IMFRHammer", modid = Mods.IDs.MineFactoryReloaded), + new Injectable.Interface(value = "mrtjp.projectred.api.IScrewdriver", modid = Mods.IDs.ProjectRedCore), + new Injectable.Interface(value = "mods.railcraft.api.core.items.IToolCrowbar", modid = Mods.IDs.Railcraft), + new Injectable.Interface(value = "ic2.api.item.IBoxable", modid = Mods.IDs.IndustrialCraft2) +)) +class Wrench extends SimpleItem with api.internal.Wrench { + setHarvestLevel("wrench", 1) + + override def doesSneakBypassUse(world: World, x: Int, y: Int, z: Int, player: EntityPlayer): Boolean = true + + override def onItemUseFirst(stack: ItemStack, player: EntityPlayer, world: World, x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = { + world.blockExists(x, y, z) && world.canMineBlock(player, x, y, z) && (world.getBlock(x, y, z) match { + case block: Block if block.rotateBlock(world, x, y, z, ForgeDirection.getOrientation(side)) => + block.onNeighborBlockChange(world, x, y, z, Blocks.air) + player.swingItem() + !world.isRemote + case _ => + super.onItemUseFirst(stack, player, world, x, y, z, side, hitX, hitY, hitZ) + }) + } + + def useWrenchOnBlock(player: EntityPlayer, world: World, x: Int, y: Int, z: Int, simulate: Boolean): Boolean = { + if (!simulate) player.swingItem() + true + } + + // Applied Energistics 2 + + def canWrench(stack: ItemStack, player: EntityPlayer, x: Int, y: Int, z: Int): Boolean = true + + // BuildCraft + + def canWrench(player: EntityPlayer, x: Int, y: Int, z: Int): Boolean = true + + def wrenchUsed(player: EntityPlayer, x: Int, y: Int, z: Int): Unit = player.swingItem() + + // CoFH + + def isUsable(stack: ItemStack, player: EntityLivingBase, x: Int, y: Int, z: Int): Boolean = true + + def toolUsed(stack: ItemStack, player: EntityLivingBase, x: Int, y: Int, z: Int): Unit = player.swingItem() + + // EnderIO + + def canUse(stack: ItemStack, player: EntityPlayer, x: Int, y: Int, z: Int): Boolean = true + + def used(stack: ItemStack, player: EntityPlayer, x: Int, y: Int, z: Int): Unit = {} + + // Mekanism + + def canUseWrench(player: EntityPlayer, x: Int, y: Int, z: Int): Boolean = true + + // Project Red + + def damageScrewdriver(world: World, player: EntityPlayer): Unit = {} + + // Railcraft + + def canWhack(player: EntityPlayer, stack: ItemStack, x: Int, y: Int, z: Int): Boolean = true + + def onWhack(player: EntityPlayer, stack: ItemStack, x: Int, y: Int, z: Int): Unit = {} + + def canLink(player: EntityPlayer, stack: ItemStack, cart: EntityMinecart): Boolean = false + + def onLink(player: EntityPlayer, stack: ItemStack, cart: EntityMinecart): Unit = {} + + def canBoost(player: EntityPlayer, stack: ItemStack, cart: EntityMinecart): Boolean = false + + def onBoost(player: EntityPlayer, stack: ItemStack, cart: EntityMinecart): Unit = {} + + // IndustrialCraft 2 + + def canBeStoredInToolbox(stack: ItemStack): Boolean = true +} diff --git a/src/main/scala/li/cil/oc/integration/Mods.scala b/src/main/scala/li/cil/oc/integration/Mods.scala index bca2f34d6..4c645a182 100644 --- a/src/main/scala/li/cil/oc/integration/Mods.scala +++ b/src/main/scala/li/cil/oc/integration/Mods.scala @@ -50,6 +50,7 @@ object Mods { val NotEnoughItems = new SimpleMod(IDs.NotEnoughItems) val OpenComputers = new SimpleMod(IDs.OpenComputers) val PortalGun = new SimpleMod(IDs.PortalGun) + val ProjectRedCore = new SimpleMod(IDs.ProjectRedCore) val ProjectRedTransmission = new SimpleMod(IDs.ProjectRedTransmission) val Railcraft = new SimpleMod(IDs.Railcraft) val RedLogic = new SimpleMod(IDs.RedLogic) @@ -167,6 +168,7 @@ object Mods { final val NotEnoughItems = "NotEnoughItems" final val OpenComputers = "OpenComputers" final val PortalGun = "PortalGun" + final val ProjectRedCore = "ProjRed|Core" final val ProjectRedTransmission = "ProjRed|Transmission" final val Railcraft = "Railcraft" final val RedLogic = "RedLogic" diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala b/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala index a05991463..cf61fbabe 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala @@ -8,6 +8,7 @@ import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.api.detail.ItemInfo import li.cil.oc.api.internal +import li.cil.oc.api.internal.Wrench import li.cil.oc.api.manual.PathProvider import li.cil.oc.api.prefab.ItemStackTabIconRenderer import li.cil.oc.api.prefab.ResourceContentProvider @@ -32,6 +33,7 @@ import li.cil.oc.integration.util.BundledRedstone import li.cil.oc.integration.util.WirelessRedstone import li.cil.oc.server.network.WirelessNetwork import li.cil.oc.util.ExtendedNBT._ +import net.minecraft.entity.player.EntityPlayer import net.minecraft.item.ItemStack import net.minecraft.nbt.NBTTagCompound import net.minecraft.world.World @@ -49,6 +51,7 @@ object ModOpenComputers extends ModProxy { ServerTemplate.register() TabletTemplate.register() TemplateBlacklist.register() + FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerWrenchTool", "li.cil.oc.integration.opencomputers.ModOpenComputers.useWrench") ForgeChunkManager.setForcedChunkLoadingCallback(OpenComputers, ChunkloaderUpgradeHandler) @@ -212,6 +215,13 @@ object ModOpenComputers extends ModProxy { api.Manual.addTab(new ItemStackTabIconRenderer(api.Items.get("cpu1").createItemStack(1)), "oc:gui.Manual.Items", "%LANGUAGE%/item/index.md") } + def useWrench(player: EntityPlayer, x: Int, y: Int, z: Int, changeDurability: Boolean): Boolean = { + player.getCurrentEquippedItem.getItem match { + case wrench: Wrench => wrench.useWrenchOnBlock(player, player.getEntityWorld, x, y, z, !changeDurability) + case _ => false + } + } + private def blacklistHost(host: Class[_], itemNames: String*) { for (itemName <- itemNames) { val nbt = new NBTTagCompound() From 58b50ad39e067ad7f21609c487d36bf111c94716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Mon, 13 Apr 2015 23:33:28 +0200 Subject: [PATCH 11/37] Polished up documentation some more. Added "home" tab to manual. In case people are people. --- .../assets/opencomputers/doc/de_DE/index.md | 9 +++++++-- .../doc/en_US/block/accessPoint.md | 6 +++--- .../opencomputers/doc/en_US/block/adapter.md | 2 +- .../opencomputers/doc/en_US/block/assembler.md | 6 ++++-- .../opencomputers/doc/en_US/block/cable.md | 4 ++-- .../opencomputers/doc/en_US/block/capacitor.md | 2 +- .../opencomputers/doc/en_US/block/case1.md | 4 +++- .../doc/en_US/block/chameliumBlock.md | 4 ++-- .../opencomputers/doc/en_US/block/charger.md | 4 ++-- .../doc/en_US/block/disassembler.md | 2 +- .../opencomputers/doc/en_US/block/diskDrive.md | 4 +++- .../opencomputers/doc/en_US/block/geolyzer.md | 4 ++-- .../opencomputers/doc/en_US/block/hologram1.md | 4 ++-- .../opencomputers/doc/en_US/block/keyboard.md | 2 +- .../doc/en_US/block/microcontroller.md | 4 ++-- .../doc/en_US/block/motionSensor.md | 2 +- .../doc/en_US/block/powerConverter.md | 2 +- .../doc/en_US/block/powerDistributor.md | 2 +- .../opencomputers/doc/en_US/block/print.md | 4 ++++ .../opencomputers/doc/en_US/block/printer.md | 2 +- .../opencomputers/doc/en_US/block/raid.md | 4 +++- .../opencomputers/doc/en_US/block/redstone.md | 6 ++++-- .../opencomputers/doc/en_US/block/robot.md | 4 ++-- .../opencomputers/doc/en_US/block/screen1.md | 11 ++++++----- .../opencomputers/doc/en_US/block/serverRack.md | 2 +- .../opencomputers/doc/en_US/block/switch.md | 8 ++++---- .../opencomputers/doc/en_US/general/computer.md | 2 +- .../opencomputers/doc/en_US/general/lua.md | 16 ++++++++++------ .../assets/opencomputers/doc/en_US/item/acid.md | 2 +- .../opencomputers/doc/en_US/item/analyzer.md | 2 +- .../opencomputers/doc/en_US/item/index.md | 1 + .../opencomputers/doc/en_US/item/tablet.md | 6 +++++- .../doc/en_US/item/upgradeContainer1.md | 2 +- .../opencomputers/doc/en_US/item/wrench.md | 5 +++++ .../assets/opencomputers/lang/de_DE.lang | 12 ++++++++++++ .../assets/opencomputers/lang/en_US.lang | 2 ++ .../opencomputers/textures/gui/manual_home.png | Bin 0 -> 442 bytes src/main/scala/li/cil/oc/client/Textures.scala | 3 ++- .../oc/client/renderer/markdown/Document.scala | 2 +- .../oc/integration/nei/ManualUsageHandler.scala | 3 ++- .../opencomputers/ModOpenComputers.scala | 4 ++++ 41 files changed, 112 insertions(+), 58 deletions(-) create mode 100644 src/main/resources/assets/opencomputers/doc/en_US/item/wrench.md create mode 100644 src/main/resources/assets/opencomputers/textures/gui/manual_home.png diff --git a/src/main/resources/assets/opencomputers/doc/de_DE/index.md b/src/main/resources/assets/opencomputers/doc/de_DE/index.md index 6534b57ab..5b19c4d6f 100644 --- a/src/main/resources/assets/opencomputers/doc/de_DE/index.md +++ b/src/main/resources/assets/opencomputers/doc/de_DE/index.md @@ -1,5 +1,10 @@ # Handbuch -Test für Lokalisierung. +Leider ist das Handbuch bisher nur [auf Englisch](/en_US/index.md) vorhanden. -Ergo, [Link zur Beispielseite](general/example.md) die nur auf Englisch existiert. \ No newline at end of file +Wenn du des Englischen mächtig bist und dazu beitragen willst, das Handbuch zu übersetzen, super! Wenn du noch dazu sauberes Deutsch schreiben kannst, nicht alle drei Wörter einen Rechtschreibfehler einbaust, und es dich nervt wenn Leute Standart statt Standard schreiben, lies weiter. Sonst... schau mer mal ;-) Etwas Grundkenntnis von Git ist nötig, um deine Übersetzung dann als Pull-Request in OpenComputers einzubringen. + +Um beim Übersetzen zu helfen bedarf es keiner Programmierkenntnisse. Die gesamte Dokumentation ist in Form von Markdown-Dokumenten vorhanden, und findet sich [hier](http://git.io/ve1Fj). Im `en_US` Ordner findet sich die Englische Dokumentation, mit der gleichen Datei- und Ordnerstruktur müsste die Übersetzung ins Deutsche in den `de_DE` Ordner. +Dass die Ordner und Dateien gleich heißen ist wichtig, damit die richtige Seite automatisch angezeigt werden kann, wenn man das Handbuch z.B. auf einen Block anwendet. Zudem wird für fehlende Seiten automatisch auf die Englischen zurückgegriffen, sofern vorhanden. Das heißt auch, dass es schon hilft wenn einzelne Seiten übersetzt werden. Diese würden dann in Deutsch angezeigt, während alle anderen Seiten nach wie vor auf Englisch angezeigt würden. + +Wenn sich freiwillige finden würden, wäre das super. Andernfalls müsst ihr euch bis auf Weiteres mit der [Englischen Variante](/en_US/index.md) begnügen. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/accessPoint.md b/src/main/resources/assets/opencomputers/doc/en_US/block/accessPoint.md index f154d2a7b..4b49e55fd 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/accessPoint.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/accessPoint.md @@ -2,10 +2,10 @@ ![AAA](oredict:oc:accessPoint) -The Access Point is the wireless version of the [switch](switch.md). It can be used to separate subnetworks so that machines in them will not see components in other networks, while still allowing to send network messages to the machines in other networks. +The access point is the wireless version of the [switch](switch.md). It can be used to separate subnetworks so that machines in them will not see [components](../general/computer.md) in other networks, while still allowing to send network messages to the machines in other networks. In addition to that, this block will resend any wired messages it receives as wireless ones, wireless messages it receives as wired messages, and repeat wireless messages as wireless ones. -Switches and access point do *not* keep track of which packets they relayed recently, so avoid cycles in your network, or you may receive the same packet multiple times. +[Switches](switch.md) and access point do *not* keep track of which packets they relayed recently, so avoid cycles in your network, or you may receive the same packet multiple times. Due to the limited buffer size of switches, you also should be careful of sending too many messages in a short time, or you will experience package loss. You can upgrade your switches and access points to increase the speed with which they relay messages, as well as their internal message queue size. -Packets are only re-sent a certain number of times, so chaining an arbitrary number of switches or access points is not possible. +Packets are only re-sent a certain number of times, so chaining an arbitrary number of switches or access points is not possible. By default, a packet will hop up to five times. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/adapter.md b/src/main/resources/assets/opencomputers/doc/en_US/block/adapter.md index 379041bd6..856492d32 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/adapter.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/adapter.md @@ -2,6 +2,6 @@ ![Now with 100% more everything.](oredict:oc:adapter) -The Adapter allows computers to interact with a number of blocks that are not part of OpenComputers, such as blocks from Minecraft itself (like the Furnace) and from a number of other mods. Supported blocks adjacent to the adapter will show up as components in [computers](../general/computer.md) connected to the adapter. +The adapter allows [computers](../general/computer.md) to interact with a number of blocks that are not part of OpenComputers, such as blocks from Minecraft itself (like the furnace) and from a number of other mods. Supported blocks adjacent to the adapter will show up as components in [computers](../general/computer.md) connected to the adapter. In addition to this, the adapter provides a slot for a few select upgrades. For example, the [inventory controller upgrade](../item/inventoryControllerUpgrade.md) allows computers to query more information from an inventory adjacent to the adapter, similar to when the upgrade is installed in a device (such as a [robot](robot.md) or [drone](../item/drone.md)), and a [tank controller upgrade](../item/tankControllerUpgrade.md) provides similar functionality for fluid tanks next to the adapter. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/assembler.md b/src/main/resources/assets/opencomputers/doc/en_US/block/assembler.md index 3866ff288..100c2dd1b 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/assembler.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/assembler.md @@ -2,10 +2,12 @@ ![Harder, better, faster, stronger.](oredict:oc:assembler) -The Assembler is an advanced workstation that can be used to build more complex electronic devices, such as [robots](robot.md), [drones](../item/drone.md) and [tablets](../item/tablet.md). They usually require a relatively large amount of energy to assemble these devices, so it is recommended to power them sufficiently. +The assembler is an advanced workstation that can be used to build more complex electronic devices, such as [robots](robot.md), [drones](../item/drone.md) and [tablets](../item/tablet.md). They usually require a relatively large amount of energy to assemble these devices, so it is recommended to power them sufficiently, for example by building a few [capacitors](capacitor.md). -To build a device using an assembler, first insert the base part for that device. For [robots](robot.md) that is a [computer case](case1.md) of any tier, for tablets that is a [tablet case](../item/tabletCase1.md), for example. Continue to insert any parts you would like the device to contain. Take particular care to provide an operating system, or a possibility to install one later on (for robots you can install a [disk drive](diskDrive.md) to insert and remove [floppies](../item/floppy.md) later on, for example). +To build a device using an assembler, first insert the base part for that device. For [robots](robot.md) that is a [computer case](case1.md) of any tier, for tablets that is a [tablet case](../item/tabletCase1.md), for example. As in all OpenComputers inventories, the parts that can be inserted into selective slots are highlighted in your inventory when hovering the slots. If you have NEI open, and compatible pages are on the currently visible page, they will also be highlighted. Continue to insert any parts you would like the device to contain. Take particular care to provide an operating system, or a possibility to install one later on (for robots you can install a [disk drive](diskDrive.md) to insert and remove [floppies](../item/floppy.md) later on, for example). For most devices, their [EEPROM](../item/eeprom.md) can be changed later on, by crafting them together with the EEPROM to insert in them. If there already was an EEPROM present, the old one will be returned to your inventory. Also note that for [robots](robot.md) to have a [screen](screen1.md) you need to install a tier one screen in them, and to allow typing on the screen you also need to install a [keyboard](keyboard.md). For [tablets](../item/tablet.md) the screen is pre-installed in the tablet case, but you still need to install a keyboard if you wish to type on your [tablet](../item/tablet.md). Once everything is in place, press the start button and wait for the device to be assembled and charged. It is important to remember that you *cannot* change the device after it has been assembled. If you forgot something or made a mistake, you will have to disassemble the device completely using the [disassembler](disassembler.md), which has a slight chance of breaking parts in the process. + +A final note on complexity: the tier of an item determines how much complexity it requires, with tier 1 items requiring 1 complexity, tier 2 requiring 2 and tier 3 requiring 3. A special case are container upgrades, such as [upgrade containers](../item/upgradeContainer1.md) and [card containers](../item/cardContainer1.md), which use twice the complexity of their own tier. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/cable.md b/src/main/resources/assets/opencomputers/doc/en_US/block/cable.md index e323f4251..b56733907 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/cable.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/cable.md @@ -2,8 +2,8 @@ ![Salad.](oredict:oc:cable) -The Cable simply serves as a way of connecting computers and machines that are far apart. If you have a compact build where all components touch each other (directly or indirectly, most blocks also behave the same way as cables) you will usually not need cables. +The cable simply serves as a way of connecting [computers](../general/computer.md) and machines that are far apart. If you have a compact build where all components touch each other (directly or indirectly, most blocks also behave the same way as cables) you will usually not need cables. Cables can be colored using any kind of dye. Colored cables will only connect to cables of the same color and to light gray colored cables - the default color. This can be useful for running cables for multiple subnetworks in parallel, without using covers. -If necessary, Cables can be covered using Forge MultiPart covers, or Immibis Microblocks covers. \ No newline at end of file +If necessary, cables can be covered using Forge MultiPart covers, or Immibis Microblocks covers. Keep in mind that [3D prints](print.md) also are Forge MultiPart compatible, so it is possible to print custom covers, if so desired. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/capacitor.md b/src/main/resources/assets/opencomputers/doc/en_US/block/capacitor.md index 8c5498cd2..3e4fc2682 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/capacitor.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/capacitor.md @@ -2,7 +2,7 @@ ![It's over 9000.](oredict:oc:capacitor) -The capacitor stores energy to be used by the network, acting as an energy buffer when needed. Unlike conversion from other mod's energy to OpenComputers' internal energy type (using a [power converter](powerConverter.md), transferring energy inside a single subnetwork is instantaneous, so it can be advantageous to store some energy internally for tasks that consume a lot of energy, such as assembling devices in the [assembler](assembler.md) or charging [robots](robot.md). +The capacitor stores energy to be used by the network, acting as an energy buffer when needed. Unlike conversion from other mod's energy to OpenComputers' internal energy type (using a [power converter](powerConverter.md) for example), transferring energy inside a single subnetwork is instantaneous, so it can be advantageous to store some energy internally for tasks that consume a lot of energy, such as assembling devices in the [assembler](assembler.md) or charging [robots](robot.md) or other devices using a [charger](charger.md). The storage efficiency of capacitors increases with the number of capacitors in direct contact or in the vicinity. For example, two capacitors directly next to each other will have a higher storage capacity than the sum of two separated capacitors. This adjacency bonus applies for capacitors up to two blocks away, and is reduced as the distance between capacitors increases. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/case1.md b/src/main/resources/assets/opencomputers/doc/en_US/block/case1.md index efd5ded50..bb561ec48 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/case1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/case1.md @@ -4,6 +4,8 @@ Computer cases come in three different tiers, which limits the components that can be inserted into them. An additional tier also exists for use in creative mode only. Computer cases can also be placed inside an [assembler](assembler.md) to build [robots](robot.md). +The tier of component that can be inserted into any slot of a computer case can be seen as a small roman numeral in the corner of a tier-limited slot. This indicates the maximum tier that can be inserted, so it is also possible, for example, to insert a tier 1 card into a tier 2 slot. + The tier 1 case can house up to and including the following components: - 2x tier 1 expansion cards (such as [graphics cards](../item/graphicsCard1.md), [network cards](../item/lanCard.md), etc) - 1x tier 1 [CPU](../item/cpu1.md) @@ -32,4 +34,4 @@ The tier 4 (Creative) case can house the following components: - 1x tier 3 [CPU](../item/cpu3.md) - 2x tier 3 [RAM](../item/ram5.md) - 2x tier 3 [HDD](../item/hdd3.md) -- 1x [floppy disk](../item/floppy.md) \ No newline at end of file +- 1x [floppy disk](../item/floppy.md) diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/chameliumBlock.md b/src/main/resources/assets/opencomputers/doc/en_US/block/chameliumBlock.md index 4e08bc3d8..3ca9cba2d 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/chameliumBlock.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/chameliumBlock.md @@ -1,7 +1,7 @@ -# Chamelium Block +# Block of Chamelium ![So... blank.](oredict:oc:chameliumBlock) -A bunch of [Chamelium](../item/chamelium.md) slapped together, this can be nice to decorate parts of your base, if you want a clean, monochrome block. Can be dyed to take any one of the 16 common Minecraft colors. +A bunch of [chamelium](../item/chamelium.md) slapped together, this can be nice to decorate parts of your base, if you want a clean, monochrome block. Can be dyed to take any one of the 16 common Minecraft colors. Another use is to pick its texture and use that in your [3D prints](print.md), if you want something clean white to apply a tint to. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/charger.md b/src/main/resources/assets/opencomputers/doc/en_US/block/charger.md index 65b3e757e..c0e96b390 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/charger.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/charger.md @@ -2,8 +2,8 @@ ![All right, let's do this.](oredict:oc:charger) -The Charger is used to charge devices such as [robots](robot.md), [drones](../item/drone.md) and [tablets](../item/tablet.md). A charger has to be activated by applying a redstone signal to it. The relative charge speed is based on the applied redstone signal's strength, with a strength of 15 meaning a charge speed of 100%. +The charger is used to charge devices such as [robots](robot.md), [drones](../item/drone.md) and [tablets](../item/tablet.md). A charger has to be activated by applying a redstone signal to it. The relative charge speed is based on the applied redstone signal's strength, with a strength of 15 meaning a charge speed of 100%. -Note that this logic can be inversed by hitting the charger with a BuildCraft compatible wrench. In inversed mode the charger defaults to 100% charge speed, and a higher redstone signal will result in a slower charge speed. +Note that this logic can be inversed by hitting the charger with a [wrench](../item/wrench.md). In inversed mode the charger defaults to 100% charge speed, and a higher redstone signal will result in a slower charge speed. When a [tablet](../item/tablet.md) is placed in the charger, its first [hard drive](../item/hdd1.md) is also exposed to [computers](../general/computer.md) connected to the charger, similar to how [floppies](../item/floppy.md) in [disk drives](diskDrive.md) are. This allows transferring of data between the [computer](../general/computer.md) and [tablet](../item/tablet.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/disassembler.md b/src/main/resources/assets/opencomputers/doc/en_US/block/disassembler.md index 830b15c94..659c4c69f 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/disassembler.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/disassembler.md @@ -2,6 +2,6 @@ ![Build it, tear it down.](oredict:oc:disassembler) -The Disassembler can be used to deconstruct most items in OpenComputers into their original parts. This is mostly useful to reclaim materials from old parts that are no longer useful, or to deconstruct devices that are either no longer needed or were incorrectly built (e.g. [robots](robot.md) without an operating system). +The disassembler can be used to deconstruct most items in OpenComputers into their original parts. This is mostly useful to reclaim materials from old parts that are no longer useful, or to deconstruct devices that are either no longer needed or were incorrectly built (e.g. [robots](robot.md) without an [operating system](../general/openOS.md)). Disassembling items takes a relatively long time, and some energy. There is also a slight chance of loosing a component, which is applied on a component by component basis - be careful about throwing a device into the disassembler. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/diskDrive.md b/src/main/resources/assets/opencomputers/doc/en_US/block/diskDrive.md index c1ad8b493..0b82cc36d 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/diskDrive.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/diskDrive.md @@ -2,6 +2,8 @@ ![Going round and round and...](oredict:oc:diskDrive) -The Disk Drive can be used to read [floppy disks](../item/floppy.md) using a computer connected to the disk drive. This is useful to get started, since the lower tier [computer cases](case1.md) do not have a built-in floppy slot, and you'll need an operating system to get started. An OpenOS disk can be crafted using an empty [floppy disk](../item/floppy.md) and a Book. +The disk drive can be used to read [floppy disks](../item/floppy.md) using a [computer](../general/computer.md) connected to the disk drive. This is useful to get started, since the lower tier [computer cases](case1.md) do not have a built-in floppy slot, and you'll need an operating system to get started. An [OpenOS](../general/openOS.lua) disk can be crafted using an empty [floppy disk](../item/floppy.md) and a [manual](../item/manual.lua). It can also be installed in [robots](robot.md) to allow inserting an removing [floppy disks](../item/floppy.md) into and from the robot at any time. This can be very useful since the only other way to transfer data to and from a robot is using networking - for example using [network cards](../item/lanCard.md). + +Disks can be inserted and removed without opening the disk drive's GUI by using them while sneaking. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/geolyzer.md b/src/main/resources/assets/opencomputers/doc/en_US/block/geolyzer.md index 7f0b2e5a3..2586f9eac 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/geolyzer.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/geolyzer.md @@ -2,6 +2,6 @@ ![It rocks.](oredict:oc:geolyzer) -The Geolyzer can be used by computers to scan the terrain surrounding the geolyzer for the blocks' approximate hardness. This can be useful to generate maps of the area to display on [hologram projectors](hologram1.md) as well as to detect potentially valuable blocks (ores are usually harder than dirt and stone). Geolyzer scan results have a certain amount of noise added; in theory, multiple scans can be performed to determine a more accurate reading of a block's hardness level. +The geolyzer can be used by [computers](../general/computer.md) to scan the terrain surrounding the geolyzer for the blocks' approximate hardness. This can be useful to generate maps of the area to display on [hologram projectors](hologram1.md) as well as to detect potentially valuable blocks (ores are usually harder than dirt and stone). Geolyzer scan results have a certain amount of noise added; in theory, multiple scans can be performed to determine a more accurate reading of a block's hardness level. -The geolyzer can also be installed in [robots](robot.md) as an upgrade to allow them to scan their surroundings. Performing a scan will consume some energy, though, so using it excessively may quickly drain a [robot](robot.md)'s batteries. +The geolyzer can also be installed in [robots](robot.md) and [tablets](../item/tablet.md) as an upgrade to allow them to scan their surroundings. Performing a scan will consume some energy, though, so using it excessively may quickly drain the device's batteries. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/hologram1.md b/src/main/resources/assets/opencomputers/doc/en_US/block/hologram1.md index 81d1e074a..6020158d2 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/hologram1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/hologram1.md @@ -2,6 +2,6 @@ ![Is this the real life? Is this just fantasy?](oredict:oc:hologram1) -The Hologram Projector is a volumetric display, i.e. it provides a three dimensional array of voxels that can be individually enabled or disabled by a connected computer. The second tier projector, while having the same resolution as the tier one projector, supports displaying the individual voxels in three different user-definable colors. +The hologram projector is a volumetric display, i.e. it provides a three dimensional array of voxels that can be individually enabled or disabled by a connected [computer](../general/computer.md). The second tier projector, while having the same resolution as the tier one projector, supports displaying the individual voxels in three different user-definable colors. -Holograms can be rotated along their vertical axis by hitting them with a BuildCraft compatible wrench on their top or bottom. This can save some effort, so that the output doesn't have to be transformed on the software side. Holograms can also be scaled up or down as desired. +Holograms can be rotated along their vertical axis by hitting them with a [wrench](../item/wrench.md) on their top or bottom. This can save some effort, so that the output doesn't have to be transformed on the software side. Holograms can also be scaled up or down as desired. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/keyboard.md b/src/main/resources/assets/opencomputers/doc/en_US/block/keyboard.md index f0fa45c7a..83e8438ab 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/keyboard.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/keyboard.md @@ -2,6 +2,6 @@ ![QWERTY](oredict:oc:keyboard) -A Keyboard is needed to type text on [screens](screen1.md), be they in the world or built into devices such as [robots](robot.md) or [tablets](../item/tablet.md). +A keyboard is needed to type text on [screens](screen1.md), be they in the world or built into devices such as [robots](robot.md) or [tablets](../item/tablet.md). For a keyboard to work with a [screen](screen1.md) in the world, it has to be placed next to the [screen](screen1.md), facing that [screen](screen1.md), or placed directly on the [screen](screen1.md) (on top or on one of its sides). You can tell that a keyboard is "connected" to a [screen](screen1.md) if by using the keyboard the [screen's](screen1.md) GUI opens up. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/microcontroller.md b/src/main/resources/assets/opencomputers/doc/en_US/block/microcontroller.md index 6fd08a7bb..b4422a8bc 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/microcontroller.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/microcontroller.md @@ -2,6 +2,6 @@ ![Don't belittle it.](block:OpenComputers:microcontroller) -Microcontrollers are built using a [microcontroller case](../item/microcontrollerCase1.md) in the [assembler](assembler.md). They have less functionality compared to computers. +Microcontrollers are built using a [microcontroller case](../item/microcontrollerCase1.md) in the [assembler](assembler.md). They have less functionality compared to computers, but are cheaper to build. -Microcontrollers can take various components, such as [CPUs](../item/cpu1.md), [memory (RAM)](../item/ram1.md), and Expansion cards. Microcontrollers are unable to contain a [hard disk drive](../item/hdd1.md), but do contain a slot for an [EEPROM](../item/eeprom.md), which can be programmed for very specific tasks. \ No newline at end of file +Microcontrollers can take various components, such as [CPUs](../item/cpu1.md), [memory (RAM)](../item/ram1.md), and Expansion cards. Microcontrollers are unable to contain a [hard disk drive](../item/hdd1.md), but do contain a slot for an [EEPROM](../item/eeprom.md), which can be programmed for very specific tasks. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/motionSensor.md b/src/main/resources/assets/opencomputers/doc/en_US/block/motionSensor.md index 2d9f19e61..86634dca4 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/motionSensor.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/motionSensor.md @@ -2,6 +2,6 @@ ![Don't. Blink.](oredict:oc:motionSensor) -The Motion Sensor allows [computers](../general/computer.md) to detect movement of living entities. If an entity moves faster than a set threshold, a signal will be injected into [computers](../general/computer.md) connected to the motion sensor. The threshold can be configured via the component the motion sensor exposes to connected computers. +The motion sensor allows [computers](../general/computer.md) to detect movement of living entities. If an entity moves faster than a set threshold, a signal will be injected into [computers](../general/computer.md) connected to the motion sensor. The threshold can be configured via the component the motion sensor exposes to connected computers. Movement is only detected if it happens within a radius of eight blocks around the motion sensor, and if there is a direct line of sight from the block to the entity that moved. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/powerConverter.md b/src/main/resources/assets/opencomputers/doc/en_US/block/powerConverter.md index 0c2ae0515..fdd9fb6f3 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/powerConverter.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/powerConverter.md @@ -2,4 +2,4 @@ ![One of us? One of us!](oredict:oc:powerConverter) -The Power Converter serves as the fastest way to convert energy from other mods' power systems to OpenComputers' internal energy. If you only run a simple computer, you probably won't need a converter. If you have a large capacitor bank that you only drain every now and then, you probably won't need one, either. However, if you wish to directly power an [assembler](assembler.md) or [charger](charger.md), it is usually a good idea to use a converter, instead of directly connecting them to external power. +The power converter serves as the fastest way to convert energy from other mods' power systems to OpenComputers' internal energy. If you only run a simple computer, you probably won't need a converter. If you have a large capacitor bank that you only drain every now and then, you probably won't need one, either. However, if you wish to directly power an [assembler](assembler.md) or [charger](charger.md), it is usually a good idea to use a converter, instead of directly connecting them to external power. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/powerDistributor.md b/src/main/resources/assets/opencomputers/doc/en_US/block/powerDistributor.md index de88f4f09..d9796e7a7 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/powerDistributor.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/powerDistributor.md @@ -2,4 +2,4 @@ ![Power to the masses.](oredict:oc:powerDistributor) -The Power Distributor distributes a shared power storage (such as a [capacitor](capacitor.md)), allowing several subnetworks to share their energy, without components being exposed to computers in other networks. It operates by regularly "balancing" the energy in all subnetworks it is connected to, so that the *relative* amount of energy is the same in them. +The power distributor distributes a shared power storage (such as a [capacitor](capacitor.md)), allowing several subnetworks to share their energy, without components being exposed to computers in other networks. It operates by regularly "balancing" the energy in all subnetworks it is connected to, so that the *relative* amount of energy is the same in them. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/print.md b/src/main/resources/assets/opencomputers/doc/en_US/block/print.md index a56b2838c..c78ebb887 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/print.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/print.md @@ -5,3 +5,7 @@ 3D prints are created using a [3D printer](printer.md). They are primarily intended for decorative purposes, but can also be created in such a way that they react to or emit redstone signals, allowing for a little bit of functional behavior on the side. 3D prints can be recycled by putting them as input into a 3D printer. This will re-use some of the [chamelium](../item/chamelium.md) that was used to print them. Color that was used to print the model will not be recycled. + +Holding the key for OpenComputers' extended tooltips (default is [Shift]), a print's active state will be shown, if any. + +Printed blocks are also Forge MultiPart compatible. If present, multiple prints can be placed into a single block-space, unless they do not collide, and the total number of shapes in the block-space does not exceed the limit for a single model. Due to the nature of Forge MultiPart, prints can therefore also be placed into the same block-space as any other Forge MultiPart compatible block, such as torches, levers, cables or red alloy wires from Project Red, for example. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/printer.md b/src/main/resources/assets/opencomputers/doc/en_US/block/printer.md index 09d44ca57..6023364db 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/printer.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/printer.md @@ -4,7 +4,7 @@ 3D printers allow you to print any block of any shape, with any type of texture. To get started with 3D printers, you will need to place down a 3D printer block next to a computer. This will give access to the `printer3d` component API, allowing you to set up and print [models](print.md) using the provided functions. -A more convenient way to setup 3D printers is to use Open Programs Package Manager (OPPM). Once installed, make sure you have an [internet card](../item/internetCard.md) in your computer and run the following command: +A more convenient way to setup 3D printers is to use Open Programs Package Manager (OPPM). Once installed (`oppm install oppm`), make sure you have an [internet card](../item/internetCard.md) in your computer and run the following command: `oppm install print3d-examples` The examples can then be found in `/usr/share/models/` as .3dm files. Take a look through the example files for available options, in particular the `example.3dm` file. Alternatively, you can download the `print3d` and `print3d-examples` programs from OpenPrograms using `wget` and an internet card. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/raid.md b/src/main/resources/assets/opencomputers/doc/en_US/block/raid.md index 6f82a9250..f434b8b59 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/raid.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/raid.md @@ -2,8 +2,10 @@ ![40 man instance.](oredict:oc:raid) -The Raid block houses three [hard drives](../item/hdd1.md) which will be combined into a single file system. This combined file system has the size of the sum of the capacities of the individual [hard drives](../item/hdd1.md) and is available to all [computers](../general/computer.md) connected to the raid. +The raid block houses three [hard drives](../item/hdd1.md) which will be combined into a single file system. This combined file system has the size of the sum of the capacities of the individual [hard drives](../item/hdd1.md) and is available to all [computers](../general/computer.md) connected to the raid. The raid only works (and shows up as a file system) when three [hard drives](../item/hdd1.md) are present. The [hard drives](../item/hdd1.md) may differ in size. Beware that adding a [hard drive](../item/hdd1.md) to the raid block will wipe it of its contents. Removing a single [hard drives](../item/hdd1.md) from a complete raid will also wipe the raid. Adding the disk back in will *not* restore it, the raid's new file system will not contain any files. + +Breaking a raid block will retain its contents, so it can be safely relocated without losing its data. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/redstone.md b/src/main/resources/assets/opencomputers/doc/en_US/block/redstone.md index b5362ad8e..bfb855c30 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/redstone.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/redstone.md @@ -2,8 +2,10 @@ ![Hi Red.](oredict:oc:redstone) -The Redstone I/O block can be used to remotely read and emit redstone signals. It behaves like a hybrid of a tier 1 and 2 [redstone card](../item/redstoneCard1.md): it can read and emit simple analog as well as bundled signals, but cannot read or emit wireless redstone signals. +The redstone I/O block can be used to remotely read and emit redstone signals. It behaves like a hybrid of a tier 1 and 2 [redstone card](../item/redstoneCard1.md): it can read and emit simple analog as well as bundled signals, but cannot read or emit wireless redstone signals. -When providing a side to the methods of the component exposed by this block, the directions are the global principal directions, i.e. it is recommended to use sides.north, sides.east and so on. +When providing a side to the methods of the component exposed by this block, the directions are the global principal directions, i.e. it is recommended to use `sides.north`, `sides.east` and so on. Like the redstone card, this block injects a signal into connected computers when the state of a redstone signal changes - both for analog as well as for bundled signals. + +Also like redstone cards, this block can be configured to wake up connected computers when a certain input strength is exceeded, allowing automated booting of computers. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/robot.md b/src/main/resources/assets/opencomputers/doc/en_US/block/robot.md index 1a4aeb597..b80c332c5 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/robot.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/robot.md @@ -2,8 +2,8 @@ ![His name was Tobor.](block:OpenComputers:robot) -Unlike computers, robots can move around and interact with the world much like a player can. They can *not* interact with external components, however! If you need to communicate with a computer or other robots, use a [wireless network card](../item/wlanCard.md), or create some low-level protocol using redstone signals via a [redstone card](../item/redstoneCard1.md), for example. +Unlike computers, robots can move around and interact with the world much like a player can. They can *not* interact with external components, however! If you need to communicate with a [computer](../general/computer.md) or other robots, use a [wireless network card](../item/wlanCard.md), or create some low-level protocol using redstone signals via a [redstone card](../item/redstoneCard1.md), for example. -Robots are built by placing a [computer case](case1.md) of any tier in an [assembler](assembler.md). Higher tier computer cases can build more complex robots, due to being able to hold a higher tier [CPU](../item/cpu1.md). Complexity of the robot (as shown in the [assembler](assembler.md)) is determined by the tier of the components and upgrades placed in the robot slots; higher tier components will increase the complexity more than a lower tier component. If the complexity of the robot is too high, the [assembler](assembler.md) will not build the robot. +Robots are built by placing a [computer case](case1.md) of any tier in an [assembler](assembler.md). Higher tier computer cases can build more complex robots, due to being able to hold a higher tier [CPU](../item/cpu1.md). Complexity of the robot (as shown in the [assembler](assembler.md)) is determined by the tier of the components and upgrades placed in the robot slots; higher tier components will increase the complexity more than a lower tier component. If the complexity of the robot is too high, the [assembler](assembler.md) will not build the robot. Various upgrades can be placed into robots to increase the functionality. These include [inventory](../item/inventoryUpgrade.md) and [inventory controller](../item/inventoryControllerUpgrade.md) upgrades, [tank upgrades](../item/tankUpgrade.md), [navigation upgrade](../item/navigationUpgrade.md), among others. [Upgrade](../item/upgradeContainer1.md) and [card](../item/cardContainer1.md) containers can be placed in the robot for on-the-fly insertion and removal of upgrades and components. A [disk drive](diskDrive.md) can also be placed inside a robot to allow [floppy disks](../item/floppy.md) to be inserted, which will let you install openOS to the robot (an alternative is to install openOS to a blank [hard drive](../item/hdd1.md) using a computer, and using the pre-installed [hard drive](../item/hdd1.md) as a component in the robot assembly). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/screen1.md b/src/main/resources/assets/opencomputers/doc/en_US/block/screen1.md index 7ef51edf8..60e18e716 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/screen1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/screen1.md @@ -2,15 +2,16 @@ ![See this?](oredict:oc:screen1) -A Screen is used in combination with a [graphics card](../item/graphicsCard1.md), to allow computers to display text. Different screen tiers have different capabilities, such as supporting different resolutions and color depths. Screens range from low-resolution, monochrome displays to high-resolution displays with up to 256 colors. +A screen is used in combination with a [graphics card](../item/graphicsCard1.md), to allow computers to display text. Different screen tiers have different capabilities, such as supporting different resolutions and color depths. Screens range from low-resolution, monochrome displays to high-resolution displays with up to 256 colors. -The available resolution and color depth depends on the lowest tier component. When using a [graphics card (tier 1)](../item/graphicsCard1.md) with a [screen (tier 3)](screen3.md), only the tier 1 resolution and color depth is usable. +The available resolution and color depth depends on the lowest tier component. When using a [graphics card (tier 1)](../item/graphicsCard1.md) with a [screen (tier 3)](screen3.md), only the tier 1 resolution and color depth is usable. However, when using a tier 3 graphics card with a tier 1 screen, while resolution and color depth will still be limit to tier 1, the different operations on the graphics card will be faster than when using a tier 1 graphics card. -Screens can be placed next to each other to form multi-block screens. This has no impact on the available resolution. To control how adjacent screens connect, screens can also be dyed using any dye. Screens with different colors will not connect. Screens with different tiers will never connect, even if they have the same color. +Screens can be placed next to each other to form multi-block screens, as long as they are facing the same way. When placed facing up or down they must also be rotated the same way. Their orientation is indicated by an arrow overlay shown while holding a screen in hand, in that case. +The size of a screen has no impact on the available resolution, only its tier has. To control how adjacent screens connect, screens can also be dyed using any dye. Simply use the screen with a dye in hand. The dye will not be consumed by this, but screens will also not retain this color once broken. Screens with different colors will not connect. Screens with different tiers will never connect, even if they have the same color. -Tier 2 and tier 3 screens also support mouse input. Clicks can either be performed in a screen's GUI (which can only be opened if a keyboard is connected to the screen), or by sneak-activating a screen empty-handed. Note that whether the GUI opens when sneak- or normally activating a screen can be controlled via the component it exposes to connected computers. +Tier 2 and tier 3 screens also support mouse input. Clicks can either be performed in a screen's GUI (which can only be opened if a [keyboard](keyboard.md) is connected to the screen), or by using a screen while sneaking (empty-handed when in doubt). The sneaking part is optional if the screen has no keyboard. Note that whether the GUI opens when sneak- or normally activating a screen can be controlled via the component it exposes to connected computers. Tier 3 screens allow more accurate hit position detection, if so enabled in their component. This allows detecting whether the upper or lower half of a single character space was clicked, for example, which can be useful when using special Unicode characters to simulate higher resolutions. The resolutions and color depths for the screens are as follows: - Tier 1: 50x16, 1-bit color. - Tier 2: 80x25, 4-bit color. -- Tier 3: 160x50, 8-bit color. \ No newline at end of file +- Tier 3: 160x50, 8-bit color. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/serverRack.md b/src/main/resources/assets/opencomputers/doc/en_US/block/serverRack.md index e82738713..08558ca4d 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/serverRack.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/serverRack.md @@ -2,7 +2,7 @@ ![Free housing.](oredict:oc:serverRack) -A Server Rack houses up to four [servers](../item/server1.md). A server is a higher tier computer, which can only run when inside a server rack. [Servers](../item/server1.md) can be remote controlled using a [remote terminal](../item/terminal.md). The number of terminals that can be connected to a single server at a time depends on the tier of the server. The distance up to which the remote terminals work can be configured in the rack's GUI. Higher values have a higher constant energy draw. +A server rack houses up to four [servers](../item/server1.md). A server is a higher tier [computer](../general/computer.md), which can only run when inside a server rack. [Servers](../item/server1.md) can be remote controlled using a [remote terminal](../item/terminal.md). The number of terminals that can be connected to a single server at a time depends on the tier of the server. The distance up to which the remote terminals work can be configured in the rack's GUI. Higher values have a higher constant energy draw. Each [server](../item/server1.md) in a server rack can only communicate with one "face" of the server rack at a time - or none at all. Which side each [server](../item/server1.md) is connected to can be configured in the server rack's GUI. Beware that the sides are from the point of view of the server rack, i.e. if you are looking at the front of the server rack, right will be to your left and vice versa. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/switch.md b/src/main/resources/assets/opencomputers/doc/en_US/block/switch.md index cf447676f..ec5f120d1 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/switch.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/switch.md @@ -2,10 +2,10 @@ ![Building bridges.](oredict:oc:switch) -The switch can be used to allow different subnetworks to send network messages to each other, without exposing components to computers in other networks. Keeping components local is usually a good idea, to avoid computers using the wrong screen or to avoid component overflows to happen (in which computers will crash / not start anymore). +The switch can be used to allow different subnetworks to send network messages to each other, without exposing components to [computers](../general/computer.md) in other networks. Keeping components local is usually a good idea, to avoid computers using the wrong [screen](screen1.md) or to avoid component overflows to happen (in which computers will crash / not start anymore). -There is also a wireless variation of this block, called the [access point](accessPoint.md), which will also relay messages wirelessly. +There is also a wireless variation of this block, called the [access point](accessPoint.md), which will also relay messages wirelessly. Wireless messages can be received and relayed by other access points, or by computers with a [wireless network card](../item/wlanCard.md). -Switches and [access points](accessPoint.md) do *not* keep track of which packets they relayed recently, so avoid cycles in your network or you may receive the same packet multiple times. +Switches and [access points](accessPoint.md) do *not* keep track of which packets they relayed recently, so avoid cycles in your network or you may receive the same packet multiple times. Due to the limited buffer size of switches, you also should be careful of sending too many messages in a short time, or you will experience package loss. You can upgrade your switches and access points to increase the speed with which they relay messages, as well as their internal message queue size. -Packets are only re-sent a certain number of times, so chaining an arbitrary number of switches or access points is not possible. +Packets are only re-sent a certain number of times, so chaining an arbitrary number of switches or access points is not possible. By default, a packet will hop up to five times. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/general/computer.md b/src/main/resources/assets/opencomputers/doc/en_US/general/computer.md index b5da1e742..9860d41ca 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/general/computer.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/general/computer.md @@ -7,4 +7,4 @@ Once the basic structure is built, components can be placed inside the [case](.. Lower tier computers also require a [disk drive](../block/diskDrive.md), which takes a [floppy](../item/floppy.md) disk. An OpenOS [floppy](../item/floppy.md) disk is needed for booting up the computer for the first time, and is used to install the operating system to the [HDD](../item/hdd1.md). Once installed to the [HDD](../item/hdd1.md), the [floppy](../item/floppy.md) disk is no longer necessary. Additional software is also available as [floppy](../item/floppy.md) disks (such as Open Programs Package Manager, or OPPM) and are obtained from dungeon loot. The final step necessary is to provide the computer with a power source. OpenComputers is compatible with most major power-providing mods, and many blocks can be powered directly. You can see which blocks can be connected to external power by checking if their tooltip contains an entry about the block's power conversion speed. -For a larger network with multiple computers, a [power converter](../block/powerConverter.md) (converts different mod's power to OC's internal Energy type), [power distributor](../block/powerDistributor.md) (distributes power to different computers), and [capacitor](../block/capacitor.md) (power storage for the network) can be used to connect different computers on the network using Cables. +For a larger network with multiple computers, a [power converter](../block/powerConverter.md) (converts different mod's power to OC's internal Energy type), [power distributor](../block/powerDistributor.md) (distributes power to different computers), and [capacitor](../block/capacitor.md) (power storage for the network) can be used to connect different computers on the network using [cables](../block/cable.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/general/lua.md b/src/main/resources/assets/opencomputers/doc/en_US/general/lua.md index 16de00ff9..e9fbb87c6 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/general/lua.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/general/lua.md @@ -1,12 +1,16 @@ # Lua -The Lua [reference manual](http://www.lua.org/manual/5.2/manual.html) is a good place to get started with the basics of Lua and becoming familiar with the basic syntax and standard libraries. OpenComputers has very similar standard libraries, and omits certain libraries almost entirely (such as about 99% of the debug library). +The Lua [reference manual](http://www.lua.org/manual/5.2/manual.html) and the [Programming in Lua](http://www.lua.org/pil/) books (first edition is available for free online) are a good place to get started with the basics of Lua and becoming familiar with the basic syntax and standard libraries. [OpenOS](openOS.md) strives to emulate the standard libraries very closely, with a few deviations, such as the mostly missing debug library (for sandboxing reasons). These differences are [documented on the wiki](http://ocdoc.cil.li/api:non-standard-lua-libs). -Non-standard libraries will need to be *required* in order to use them in a script. For example: +Non-standard libraries will need to be `require`d in order to use them in a script. For example: -`local component = require("component")` -`local rs = component.redstone` +`local component = require("component")` +`local rs = component.redstone` -This will allow you to call all of the functions provided by the [redstone](../item/redstoneCard1.md) component. +This will allow you to call all of the functions provided by the [redstone](../item/redstoneCard1.md) component. For example: -OpenComputers provides many custom libraries which can be used for many applications, from controlling and manipulating components attached to the [computer](computer.md), to reference APIs for colors and keyboard keycodes. Custom libraries can be used within a Lua script by using the `require()` function, as above. Some custom libraries require specific components to work, such as the Internet library requiring an [internet card](../item/internetCard.md). \ No newline at end of file +`rs.setOutput(require("sides").front, 15)` + +**Important**: when working in the Lua interpreter, *do not* use `local`, as that will make the variables local to a single line of input. Meaning if you were to enter the lines above one after another in the interpreter, the third one would error, telling you that `rs` is a `nil` value. Why only on the third line, you ask? Because, for ease of testing, the interpreter tries to load unknown variables as libraries. So even though the assignment to `component` from the first line would nothing, the use of `component` on the second line would cause that library to be loaded and used. Libraries are not automatically used when using Lua scripts to keep memory usage low, because that's a limited resource. + +OpenOS provides many custom libraries which can be used for many applications, from controlling and manipulating components attached to the [computer](computer.md), to reference APIs for colors used in bundled redstone control and [keyboard](../block/keyboard.md) keycodes. Custom libraries can be used within a Lua script by using the `require()` function, as above. Some custom libraries require specific components to work, such as the `internet` library requiring an [internet card](../item/internetCard.md). In that particular case it is even being provided by it, i.e. the library will show up once you install an internet card - technically speaking, it is contained on a small, read-only file system on the internet card. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/acid.md b/src/main/resources/assets/opencomputers/doc/en_US/item/acid.md index a0fb272d7..eaa7c6fec 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/acid.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/acid.md @@ -2,4 +2,4 @@ ![Reflux?](oredict:oc:materialAcid) -You'll probably only see this item when playing with the hardmode recipe set, in which case you'll need it to etch [circuit boards](circuitBoard.md) to craft [printed circuit boards](printedCircuitBoard.md). +You'll probably only see this item when playing with the hard mode recipe set, in which case you'll need it to etch [circuit boards](circuitBoard.md) to craft [printed circuit boards](printedCircuitBoard.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/analyzer.md b/src/main/resources/assets/opencomputers/doc/en_US/item/analyzer.md index 0cc021cfb..3592ccdda 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/analyzer.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/analyzer.md @@ -4,4 +4,4 @@ The analyzer is a handy tool for getting some information about OpenComputers-related blocks in the world. Simply (sneak-)activate a block to get some information printed to the chat. This ranges from basic things like the address of components, to power levels in the subnetwork the block is in, and information on the error lead to a computer to crash, for example. -Another useful functionality is that when using the using the analyzer on a block while holding down **Ctrl** the address of the block component will be copied to the clipboard. This information can then be pasted into a [computer](../general/computer.md) terminal if necessary. \ No newline at end of file +Another useful functionality is that when using the using the analyzer on a block while holding down [Ctrl] the address of the block component will be copied to the clipboard. This information can then be pasted into a [computer](../general/computer.md) terminal if necessary. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/index.md b/src/main/resources/assets/opencomputers/doc/en_US/item/index.md index 514f30a89..c39217dc9 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/index.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/index.md @@ -9,6 +9,7 @@ Keep in mind that some of these may not be available, depending on the recipe se * [Manual](manual.md) * [Remote Terminal](terminal.md) * [Texture Picker](texturePicker.md) +* [Scrench](wrench.md) ## Devices * [Drone](drone.md) diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/tablet.md b/src/main/resources/assets/opencomputers/doc/en_US/item/tablet.md index 30e6d8c02..7515e9e2c 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/tablet.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/tablet.md @@ -4,6 +4,10 @@ Tablets are built by placing a [tablet case](tabletCase1.md) into an [assembler](../block/assembler.md), configuring as desired and assembling it. Tablets act as portable computers that cannot directly interact with the world - for example, basic [redstone cards](redstoneCard1.md) do not work in them. A number of upgrades do, such as the [sign i/o](signUpgrade.md) upgrade or the [piston](pistonUpgrade.md) upgrade. -To force rebooting a tablet, sneak-activate it while holding it in your hand. Unlike computers, tablets do not persist across the player holding it leaving and re-entering the game. They also do not persist across the player holding the tablet changing dimensions (e.g. going to the Nether or back). +The tier 2 tablet also allows installing a single container upgrade. The slot provided by the container can be accessed by opening the tablet's alternative GUI, by using it while sneaking. This will also forcibly shut-down the tablet. + +Unlike computers, tablets do not persist across the player holding it leaving and re-entering the game. They also do not persist across the player holding the tablet changing dimensions (e.g. going to the Nether or back). Tablets can be put into a [charger](../block/charger.md) to refill their energy, and to access the first [hard drive](hdd1.md) built into the tablet from a [computer](../general/computer.md) connected to the charger - in this setup, the charger will act similar to a [disk drive](../block/diskDrive.md), with the tablet being the [floppy disk](floppy.md). This can be very useful in case you forgot to install an OS on the hard drive built into the tablet, or after bricking a tablet's OS. + +Another advanced feature of the tablet is its ability to generate signals with information about certain blocks in the world, by using it on a block in the world for about one second (e.g. keep the right mouse button pressed). A short beep tone will notify you that the signal was generated. This only works if upgrades are installed in the tablet that populate the signal with information. For example, the [geolyzer](../block/geolyzer.md) will add information about the block itself, such as its hardness, the [navigation upgrade](navigationUpgrade.md) will add the coordinates of the block relative to the player holding the tablet. You will see which block will be analyzed by the green overlay that will be displayed while targeting it when holding the tablet. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/upgradeContainer1.md b/src/main/resources/assets/opencomputers/doc/en_US/item/upgradeContainer1.md index 767571737..b585e93e6 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/upgradeContainer1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/upgradeContainer1.md @@ -2,4 +2,4 @@ ![Can haz upgrade.](oredict:oc:upgradeContainer1) -The upgrade container is a container type upgrade for [robots](../block/robot.md), that provides a slot in the finished [robots](../block/robot.md) into which normal upgrades can be placed. The tier of upgrade that slot can hold is equal to the tier of the container. Unlike normal upgrades, the complexity of containers is twice their tier. Refer to [robot](../block/robot.md) documentation on complexity. +The upgrade container is a container type upgrade for [robots](../block/robot.md), that provides a slot in the finished [robots](../block/robot.md) into which normal upgrades can be placed. The tier of upgrade that slot can hold is equal to the tier of the container. Unlike normal upgrades, the complexity of containers is twice their tier. Refer to [robot](../block/robot.md) and [assembler](../block/assembler.md) documentation on complexity. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/wrench.md b/src/main/resources/assets/opencomputers/doc/en_US/item/wrench.md new file mode 100644 index 000000000..56dc2676e --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/wrench.md @@ -0,0 +1,5 @@ +# Scrench + +![Made in Swiss.](oredict:oc:wrench) + +Like pretty much any other technology-focused mod, OpenComputers has it's own version of a wrench tool. In this case it's a hybrid of a screwdriver and a wrench, that looks like it's incredibly awkward to use. It can be used to rotate most blocks, and is also compatible with most other mods' blocks that can be interacted with by using wrench-like tools. diff --git a/src/main/resources/assets/opencomputers/lang/de_DE.lang b/src/main/resources/assets/opencomputers/lang/de_DE.lang index 4d2d245c0..ea46fa9ca 100644 --- a/src/main/resources/assets/opencomputers/lang/de_DE.lang +++ b/src/main/resources/assets/opencomputers/lang/de_DE.lang @@ -184,6 +184,7 @@ oc:gui.Error.NoEnergy=Nicht genug Energie. oc:gui.Error.NoRAM=Im Computer ist kein RAM installiert. oc:gui.Error.OutOfMemory=Nicht genug Arbeitsspeicher. oc:gui.Manual.Blocks=OpenComputers Blöcke +oc:gui.Manual.Home=Startseite oc:gui.Manual.Items=OpenComputers Gegenstände oc:gui.Manual.Warning.BlockMissing=Block nicht verfügbar. oc:gui.Manual.Warning.ImageMissing=Bild nicht gefunden. @@ -338,3 +339,14 @@ oc:tooltip.UpgradeTankController=Dieses Upgrade erlaubt es dem Roboter, präzise oc:tooltip.UpgradeTractorBeam=Stattet den Roboter mit unglaublich fortschrittlicher Technologie - Kosename: "Gegenstandsmagnet" - aus. Erlaubt es dem Roboter, Gegenstände, innerhalb von 3 Blöcken um sich herum, einzusammeln. oc:tooltip.WirelessNetworkCard=Erlaubt das drahtlose Senden von Netzwerknachrichten, zusätzlich zu normalen. Drahtlose Nachrichten werden nur gesendet, wenn eine §fSignalstärke§7 festgelegt wurde! oc:tooltip.WorldSensorCard=Erlaubt es, Informationen über die Welt auszulesen, wie etwa Gravitation und ob die Atmosphäre atembar ist. Verwendung von Messergebnissen auf eigene Gefahr. Der Hersteller übernimmt keinerlei Garantie. + +# NEI Integration +nei.options.inventory.oredict=Zeige OreDictionary Namen +nei.options.inventory.oredict.true=True +nei.options.inventory.oredict.false=False +nei.usage.oc.Manual=Handbuch öffnen + +# Waila Integration +option.oc.address=Adresse +option.oc.componentName=Komponentenname +option.oc.energy=Energie \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/lang/en_US.lang b/src/main/resources/assets/opencomputers/lang/en_US.lang index 388ec1164..0927a2243 100644 --- a/src/main/resources/assets/opencomputers/lang/en_US.lang +++ b/src/main/resources/assets/opencomputers/lang/en_US.lang @@ -185,6 +185,7 @@ oc:gui.Error.NoEnergy=Not enough energy. oc:gui.Error.NoRAM=No RAM is installed in the computer. oc:gui.Error.OutOfMemory=Out of memory. oc:gui.Manual.Blocks=OpenComputers Blocks +oc:gui.Manual.Home=Home oc:gui.Manual.Items=OpenComputers Items oc:gui.Manual.Warning.BlockMissing=Block unavailable. oc:gui.Manual.Warning.ImageMissing=Image not found. @@ -419,6 +420,7 @@ achievement.oc.wirelessNetworkCard.desc=Time to go where no packet has gone befo nei.options.inventory.oredict=Show OreDictionary names nei.options.inventory.oredict.true=True nei.options.inventory.oredict.false=False +nei.usage.oc.Manual=Open Manual # Waila Integration option.oc.address=Address diff --git a/src/main/resources/assets/opencomputers/textures/gui/manual_home.png b/src/main/resources/assets/opencomputers/textures/gui/manual_home.png new file mode 100644 index 0000000000000000000000000000000000000000..a149b7dd89b9fec1bf6478da0fef82b0bfe6bea0 GIT binary patch literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8mH?j+*V28V#XCaFj)Vp`IGSb2=Wh<_zfqv)D{Yb_*Kj@| zeyY1}fK2n1#Jri&M)7j9@7J|lPfVHbSusCt!tH{Tg+BF*^5;FO(~pr&=?T#bmCab@ zs~ap6KhvY~RG5CGT<( Date: Tue, 14 Apr 2015 00:33:39 +0200 Subject: [PATCH 12/37] Fix potential crash when trying to render a char that could not be generated. --- .../cil/oc/client/renderer/font/DynamicFontRenderer.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/scala/li/cil/oc/client/renderer/font/DynamicFontRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/font/DynamicFontRenderer.scala index 7f9d65583..543db431a 100644 --- a/src/main/scala/li/cil/oc/client/renderer/font/DynamicFontRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/font/DynamicFontRenderer.scala @@ -42,7 +42,7 @@ class DynamicFontRenderer extends TextureFontRenderer with IResourceManagerReloa textures.clear() charMap.clear() textures += new DynamicFontRenderer.CharTexture(this) - activeTexture = textures(0) + activeTexture = textures.head generateChars(basicChars.toCharArray) } @@ -68,9 +68,9 @@ class DynamicFontRenderer extends TextureFontRenderer with IResourceManagerReloa } override protected def drawChar(tx: Float, ty: Float, char: Char) { - val icon = charMap(char) - if (icon != null && icon.texture == activeTexture) { - icon.draw(tx, ty) + charMap.get(char) match { + case Some(icon) if icon.texture == activeTexture => icon.draw(tx, ty) + case _ => } } From e54536dd9c57fb43435255e0f1fd116199c84042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Tue, 14 Apr 2015 01:44:35 +0200 Subject: [PATCH 13/37] Not ignoring index in Lua interpreter tab completion anymore. --- src/main/resources/assets/opencomputers/loot/OpenOS/bin/lua.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/assets/opencomputers/loot/OpenOS/bin/lua.lua b/src/main/resources/assets/opencomputers/loot/OpenOS/bin/lua.lua index d1176b111..f89de1059 100644 --- a/src/main/resources/assets/opencomputers/loot/OpenOS/bin/lua.lua +++ b/src/main/resources/assets/opencomputers/loot/OpenOS/bin/lua.lua @@ -86,6 +86,7 @@ if #args == 0 or options.i then end end local function hint(line, index) + line = (line or ""):sub(1, index - 1) local path = string.match(line, "[a-zA-Z_][a-zA-Z0-9_.]*$") if not path then return nil end local suffix = string.match(path, "[^.]+$") or "" From 518e0004e9b6320b59597debca53ef4280ebfc0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Tue, 14 Apr 2015 02:33:36 +0200 Subject: [PATCH 14/37] Remove duplicate entries in Lua interpreter tab completion. --- .../assets/opencomputers/loot/OpenOS/bin/lua.lua | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/resources/assets/opencomputers/loot/OpenOS/bin/lua.lua b/src/main/resources/assets/opencomputers/loot/OpenOS/bin/lua.lua index f89de1059..a60b03edc 100644 --- a/src/main/resources/assets/opencomputers/loot/OpenOS/bin/lua.lua +++ b/src/main/resources/assets/opencomputers/loot/OpenOS/bin/lua.lua @@ -76,7 +76,7 @@ if #args == 0 or options.i then elseif type(v) == "table" and getmetatable(v) and getmetatable(v).__call then postfix = "()" elseif type(v) == "table" then postfix = "." end - table.insert(r, prefix..k..postfix) + r[prefix..k..postfix] = true end end local mt = getmetatable(t) @@ -93,10 +93,13 @@ if #args == 0 or options.i then local prefix = string.sub(path, 1, #path - #suffix) local t = findTable(env, prefix) if not t then return nil end - local r = {} - findKeys(t, r, string.sub(line, 1, #line - #suffix), suffix) - table.sort(r) - return r + local r1, r2 = {}, {} + findKeys(t, r1, string.sub(line, 1, #line - #suffix), suffix) + for k in pairs(r1) do + table.insert(r2, k) + end + table.sort(r2) + return r2 end component.gpu.setForeground(0xFFFFFF) From b725cb9a5159280fe65413cb54e418558ce2100d Mon Sep 17 00:00:00 2001 From: Rashdan Date: Mon, 13 Apr 2015 22:52:24 -0700 Subject: [PATCH 15/37] Major/minor changes, made sure everything was linked, reworded some stuffs. --- .../doc/en_US/block/accessPoint.md | 6 ++-- .../opencomputers/doc/en_US/block/adapter.md | 2 +- .../doc/en_US/block/assembler.md | 10 +++--- .../opencomputers/doc/en_US/block/cable.md | 4 +-- .../doc/en_US/block/capacitor.md | 2 +- .../opencomputers/doc/en_US/block/case1.md | 2 +- .../doc/en_US/block/chameliumBlock.md | 4 +-- .../opencomputers/doc/en_US/block/charger.md | 6 ++-- .../doc/en_US/block/disassembler.md | 2 +- .../doc/en_US/block/diskDrive.md | 6 ++-- .../opencomputers/doc/en_US/block/geolyzer.md | 2 +- .../doc/en_US/block/hologram1.md | 2 +- .../opencomputers/doc/en_US/block/keyboard.md | 2 +- .../doc/en_US/block/microcontroller.md | 2 +- .../doc/en_US/block/motionSensor.md | 2 +- .../doc/en_US/block/powerConverter.md | 2 +- .../doc/en_US/block/powerDistributor.md | 2 +- .../opencomputers/doc/en_US/block/print.md | 4 +-- .../opencomputers/doc/en_US/block/printer.md | 6 ++-- .../opencomputers/doc/en_US/block/raid.md | 4 +-- .../opencomputers/doc/en_US/block/redstone.md | 4 +-- .../opencomputers/doc/en_US/block/robot.md | 6 ++-- .../opencomputers/doc/en_US/block/screen1.md | 11 +++--- .../doc/en_US/block/serverRack.md | 6 ++-- .../opencomputers/doc/en_US/block/switch.md | 8 ++--- .../doc/en_US/general/computer.md | 8 ++--- .../opencomputers/doc/en_US/general/openOS.md | 2 ++ .../doc/en_US/general/quickstart.md | 36 +++++++++---------- .../assets/opencomputers/doc/en_US/index.md | 2 +- .../doc/en_US/item/abstractBusCard.md | 2 +- .../opencomputers/doc/en_US/item/acid.md | 2 +- .../opencomputers/doc/en_US/item/alu.md | 2 +- .../opencomputers/doc/en_US/item/analyzer.md | 4 +-- .../doc/en_US/item/angelUpgrade.md | 2 +- .../opencomputers/doc/en_US/item/arrowKeys.md | 2 +- .../doc/en_US/item/batteryUpgrade1.md | 2 +- .../doc/en_US/item/buttonGroup.md | 2 +- .../opencomputers/doc/en_US/item/card.md | 2 +- .../doc/en_US/item/cardContainer1.md | 2 +- .../opencomputers/doc/en_US/item/chamelium.md | 6 ++-- .../opencomputers/doc/en_US/item/chip1.md | 2 +- .../doc/en_US/item/chunkloaderUpgrade.md | 2 +- .../doc/en_US/item/circuitBoard.md | 2 +- .../doc/en_US/item/componentBus1.md | 2 +- .../doc/en_US/item/controlUnit.md | 2 +- .../opencomputers/doc/en_US/item/cpu1.md | 6 ++-- .../doc/en_US/item/craftingUpgrade.md | 2 +- .../doc/en_US/item/cuttingWire.md | 2 +- .../doc/en_US/item/databaseUpgrade1.md | 4 +-- .../opencomputers/doc/en_US/item/debugCard.md | 2 +- .../opencomputers/doc/en_US/item/drone.md | 2 +- .../doc/en_US/item/droneCase1.md | 6 ++-- .../opencomputers/doc/en_US/item/floppy.md | 2 +- .../doc/en_US/item/generatorUpgrade.md | 4 +-- .../doc/en_US/item/graphicsCard1.md | 2 +- .../opencomputers/doc/en_US/item/hdd1.md | 2 +- .../opencomputers/doc/en_US/item/index.md | 8 ++--- .../doc/en_US/item/inkCartridge.md | 2 +- .../doc/en_US/item/internetCard.md | 2 +- .../en_US/item/inventoryControllerUpgrade.md | 4 +-- .../doc/en_US/item/inventoryUpgrade.md | 2 +- .../opencomputers/doc/en_US/item/lanCard.md | 2 +- .../doc/en_US/item/linkedCard.md | 2 +- .../opencomputers/doc/en_US/item/manual.md | 4 +-- .../doc/en_US/item/microcontrollerCase1.md | 4 +-- .../doc/en_US/item/navigationUpgrade.md | 2 +- .../opencomputers/doc/en_US/item/numPad.md | 2 +- .../doc/en_US/item/pistonUpgrade.md | 2 +- .../opencomputers/doc/en_US/item/ram1.md | 4 +-- .../doc/en_US/item/rawCircuitBoard.md | 2 +- .../doc/en_US/item/redstoneCard1.md | 4 +-- .../opencomputers/doc/en_US/item/server1.md | 2 +- .../doc/en_US/item/signUpgrade.md | 2 +- .../doc/en_US/item/solarGeneratorUpgrade.md | 4 +-- .../opencomputers/doc/en_US/item/tablet.md | 8 ++--- .../doc/en_US/item/tabletCase1.md | 6 ++-- .../opencomputers/doc/en_US/item/terminal.md | 2 +- .../doc/en_US/item/texturePicker.md | 2 +- .../doc/en_US/item/upgradeContainer1.md | 2 +- .../opencomputers/doc/en_US/item/wlanCard.md | 4 +-- .../opencomputers/doc/en_US/item/wrench.md | 2 +- 81 files changed, 154 insertions(+), 153 deletions(-) diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/accessPoint.md b/src/main/resources/assets/opencomputers/doc/en_US/block/accessPoint.md index 4b49e55fd..5dde0da28 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/accessPoint.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/accessPoint.md @@ -4,8 +4,8 @@ The access point is the wireless version of the [switch](switch.md). It can be used to separate subnetworks so that machines in them will not see [components](../general/computer.md) in other networks, while still allowing to send network messages to the machines in other networks. -In addition to that, this block will resend any wired messages it receives as wireless ones, wireless messages it receives as wired messages, and repeat wireless messages as wireless ones. +In addition to that, this block can act as a repeater: it can re-send wired messages as wired messages to other devices; or wireless messages as wired or wireless messages. -[Switches](switch.md) and access point do *not* keep track of which packets they relayed recently, so avoid cycles in your network, or you may receive the same packet multiple times. Due to the limited buffer size of switches, you also should be careful of sending too many messages in a short time, or you will experience package loss. You can upgrade your switches and access points to increase the speed with which they relay messages, as well as their internal message queue size. +[Switches](switch.md) and access point do *not* keep track of which packets they relayed recently, so avoid cycles in your network or you may receive the same packet multiple times. Due to the limited buffer size of switches, packet loss can occur when trying to send network messages too frequently. You can upgrade your switches and access points to increase the speed at which they relay messages, as well as their internal message queue size. -Packets are only re-sent a certain number of times, so chaining an arbitrary number of switches or access points is not possible. By default, a packet will hop up to five times. +Packets are only re-sent a certain number of times, so chaining an arbitrary number of [switches](switch.md) or access points is not possible. By default, a packet will be re-sent up to five times. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/adapter.md b/src/main/resources/assets/opencomputers/doc/en_US/block/adapter.md index 856492d32..8df3e7188 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/adapter.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/adapter.md @@ -2,6 +2,6 @@ ![Now with 100% more everything.](oredict:oc:adapter) -The adapter allows [computers](../general/computer.md) to interact with a number of blocks that are not part of OpenComputers, such as blocks from Minecraft itself (like the furnace) and from a number of other mods. Supported blocks adjacent to the adapter will show up as components in [computers](../general/computer.md) connected to the adapter. +The adapter allows [computers](../general/computer.md) to interact with blocks from vanilla Minecraft or other mods. Supported blocks adjacent to the adapter will show up as components in [computers](../general/computer.md) connected to the adapter. In addition to this, the adapter provides a slot for a few select upgrades. For example, the [inventory controller upgrade](../item/inventoryControllerUpgrade.md) allows computers to query more information from an inventory adjacent to the adapter, similar to when the upgrade is installed in a device (such as a [robot](robot.md) or [drone](../item/drone.md)), and a [tank controller upgrade](../item/tankControllerUpgrade.md) provides similar functionality for fluid tanks next to the adapter. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/assembler.md b/src/main/resources/assets/opencomputers/doc/en_US/block/assembler.md index 100c2dd1b..cb25ceb76 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/assembler.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/assembler.md @@ -2,12 +2,12 @@ ![Harder, better, faster, stronger.](oredict:oc:assembler) -The assembler is an advanced workstation that can be used to build more complex electronic devices, such as [robots](robot.md), [drones](../item/drone.md) and [tablets](../item/tablet.md). They usually require a relatively large amount of energy to assemble these devices, so it is recommended to power them sufficiently, for example by building a few [capacitors](capacitor.md). +The assembler is an advanced workstation that can be used to build more complex electronic devices, such as [robots](robot.md), [drones](../item/drone.md) and [tablets](../item/tablet.md). They require a large amount of energy to assemble devices, so it is recommended to power them sufficiently with a [capacitor bank](capacitor.md). -To build a device using an assembler, first insert the base part for that device. For [robots](robot.md) that is a [computer case](case1.md) of any tier, for tablets that is a [tablet case](../item/tabletCase1.md), for example. As in all OpenComputers inventories, the parts that can be inserted into selective slots are highlighted in your inventory when hovering the slots. If you have NEI open, and compatible pages are on the currently visible page, they will also be highlighted. Continue to insert any parts you would like the device to contain. Take particular care to provide an operating system, or a possibility to install one later on (for robots you can install a [disk drive](diskDrive.md) to insert and remove [floppies](../item/floppy.md) later on, for example). For most devices, their [EEPROM](../item/eeprom.md) can be changed later on, by crafting them together with the EEPROM to insert in them. If there already was an EEPROM present, the old one will be returned to your inventory. +To build a device using an assembler, insert the base part for that device. For [robots](robot.md), that is a [computer case](case1.md) of any tier; and for [tablets](../item/tablet.md), a [tablet case](../item/tabletCase1.md). As with all OpenComputers inventories, the parts that can be inserted into specific slots; hovering over a slot highlights the parts in your inventory that can go into the slot. If you have NEI open, filtered to show OpenComputers items, compatible items will be highlighted in NEI as well. Continue to insert any parts you would like the device to contain. Take particular care to provide an operating system, or a way to install one later on (for robots you can install a [disk drive](diskDrive.md) to insert and remove [floppies](../item/floppy.md) later on, for example). For most devices, their [EEPROM](../item/eeprom.md) can be changed later on, by crafting the device together with a different [EEPROM](../item/eeprom.md) to insert in them. Existing [EEPROM](../item/eeprom.md) on the device will be returned to your inventory. -Also note that for [robots](robot.md) to have a [screen](screen1.md) you need to install a tier one screen in them, and to allow typing on the screen you also need to install a [keyboard](keyboard.md). For [tablets](../item/tablet.md) the screen is pre-installed in the tablet case, but you still need to install a keyboard if you wish to type on your [tablet](../item/tablet.md). +Also note that for [robots](robot.md) to have a [screen](screen1.md), you will need to install a [screen (tier 1)](screen1.md) in them, and to allow typing on the [screen](screen1.md), you will need to install a [keyboard](keyboard.md). For [tablets](../item/tablet.md), the [screen](screen1.md) is pre-installed in the [tablet case](../item/tabletCase1.md), but you will need to install a [keyboard](keyboard.md) if you wish to type on the [tablet](../item/tablet.md). -Once everything is in place, press the start button and wait for the device to be assembled and charged. It is important to remember that you *cannot* change the device after it has been assembled. If you forgot something or made a mistake, you will have to disassemble the device completely using the [disassembler](disassembler.md), which has a slight chance of breaking parts in the process. +Once everything is in place, press the start button and wait for the device to be assembled and charged. It is important to remember that you *cannot* change the device after it has been assembled. If you forgot something or made a mistake, you will have to disassemble the device using the [disassembler](disassembler.md), which has a slight chance of breaking parts in the process. -A final note on complexity: the tier of an item determines how much complexity it requires, with tier 1 items requiring 1 complexity, tier 2 requiring 2 and tier 3 requiring 3. A special case are container upgrades, such as [upgrade containers](../item/upgradeContainer1.md) and [card containers](../item/cardContainer1.md), which use twice the complexity of their own tier. +A final note on complexity: the tier of an item determines how much complexity it requires, with tier 1 items requiring 1 complexity, tier 2 requiring 2 and tier 3 requiring 3. Container upgrades are the exception, where the complexity is twice the tier of the container (eg: a tier 2 [upgrade containers](../item/upgradeContainer1.md) requires 4 complexity, and likewise for [card containers](../item/cardContainer1.md)). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/cable.md b/src/main/resources/assets/opencomputers/doc/en_US/block/cable.md index b56733907..8b4c7028e 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/cable.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/cable.md @@ -2,8 +2,8 @@ ![Salad.](oredict:oc:cable) -The cable simply serves as a way of connecting [computers](../general/computer.md) and machines that are far apart. If you have a compact build where all components touch each other (directly or indirectly, most blocks also behave the same way as cables) you will usually not need cables. +The cable serves as a way of connecting [computers](../general/computer.md) and machines that are far apart. If you have a compact build where all components touch each other (directly or indirectly, most blocks also behave the same way as cables) you will usually not need cables. Cables can be colored using any kind of dye. Colored cables will only connect to cables of the same color and to light gray colored cables - the default color. This can be useful for running cables for multiple subnetworks in parallel, without using covers. -If necessary, cables can be covered using Forge MultiPart covers, or Immibis Microblocks covers. Keep in mind that [3D prints](print.md) also are Forge MultiPart compatible, so it is possible to print custom covers, if so desired. +If necessary, cables can be covered using Forge MultiPart covers, or Immibis Microblocks covers. Keep in mind that [3D prints](print.md) are Forge MultiPart compatible, so it is possible to print custom covers, if desired. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/capacitor.md b/src/main/resources/assets/opencomputers/doc/en_US/block/capacitor.md index 3e4fc2682..1d8faf904 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/capacitor.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/capacitor.md @@ -2,7 +2,7 @@ ![It's over 9000.](oredict:oc:capacitor) -The capacitor stores energy to be used by the network, acting as an energy buffer when needed. Unlike conversion from other mod's energy to OpenComputers' internal energy type (using a [power converter](powerConverter.md) for example), transferring energy inside a single subnetwork is instantaneous, so it can be advantageous to store some energy internally for tasks that consume a lot of energy, such as assembling devices in the [assembler](assembler.md) or charging [robots](robot.md) or other devices using a [charger](charger.md). +The capacitor stores energy to be used by the network, acting as an energy buffer when needed. Unlike conversion from other mod's energy to OpenComputers' internal energy type (using a [power converter](powerConverter.md) for example), transferring energy inside a single subnetwork is instantaneous. Having an internal energy bugger will be useful for tasks that require a lot of energy, such as [assembling](assembler.md) and/or [charging](charger.md) devices such as [robots](robot.md) or [drones](../item/drone.md). The storage efficiency of capacitors increases with the number of capacitors in direct contact or in the vicinity. For example, two capacitors directly next to each other will have a higher storage capacity than the sum of two separated capacitors. This adjacency bonus applies for capacitors up to two blocks away, and is reduced as the distance between capacitors increases. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/case1.md b/src/main/resources/assets/opencomputers/doc/en_US/block/case1.md index bb561ec48..aa9c46572 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/case1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/case1.md @@ -4,7 +4,7 @@ Computer cases come in three different tiers, which limits the components that can be inserted into them. An additional tier also exists for use in creative mode only. Computer cases can also be placed inside an [assembler](assembler.md) to build [robots](robot.md). -The tier of component that can be inserted into any slot of a computer case can be seen as a small roman numeral in the corner of a tier-limited slot. This indicates the maximum tier that can be inserted, so it is also possible, for example, to insert a tier 1 card into a tier 2 slot. +The maximum tier of the component that can be inserted into any slot of a computer case can be seen as a small roman numeral in the corner of a tier-limited slot. A tier 2 slot can take a tier 1 component, for instance. The tier 1 case can house up to and including the following components: - 2x tier 1 expansion cards (such as [graphics cards](../item/graphicsCard1.md), [network cards](../item/lanCard.md), etc) diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/chameliumBlock.md b/src/main/resources/assets/opencomputers/doc/en_US/block/chameliumBlock.md index 3ca9cba2d..99012ba02 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/chameliumBlock.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/chameliumBlock.md @@ -2,6 +2,6 @@ ![So... blank.](oredict:oc:chameliumBlock) -A bunch of [chamelium](../item/chamelium.md) slapped together, this can be nice to decorate parts of your base, if you want a clean, monochrome block. Can be dyed to take any one of the 16 common Minecraft colors. +A few pieces of [chamelium](../item/chamelium.md) can be combined to provide a monochrome block for decorative purposes. Chamelium blocks can also be dyed with any of the 16 Minecraft colors. -Another use is to pick its texture and use that in your [3D prints](print.md), if you want something clean white to apply a tint to. +Using the Chamelium block as a texture for [3D prints](print.md) provides a clean white surface for applying tints. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/charger.md b/src/main/resources/assets/opencomputers/doc/en_US/block/charger.md index c0e96b390..e8d3db1b4 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/charger.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/charger.md @@ -2,8 +2,8 @@ ![All right, let's do this.](oredict:oc:charger) -The charger is used to charge devices such as [robots](robot.md), [drones](../item/drone.md) and [tablets](../item/tablet.md). A charger has to be activated by applying a redstone signal to it. The relative charge speed is based on the applied redstone signal's strength, with a strength of 15 meaning a charge speed of 100%. +The charger is used to charge devices such as [robots](robot.md), [drones](../item/drone.md) and [tablets](../item/tablet.md). A charger has to be activated by applying a redstone signal to it. The charge speed is based on the applied redstone signal's strength, with a strength of 15 meaning a charge speed of 100%. -Note that this logic can be inversed by hitting the charger with a [wrench](../item/wrench.md). In inversed mode the charger defaults to 100% charge speed, and a higher redstone signal will result in a slower charge speed. +Note that this logic can be inversed by hitting the charger with a [wrench](../item/wrench.md). In inversed mode, the charger defaults to 100% charge speed, decreasing in charge speed as the strength of the redstone signal increases. -When a [tablet](../item/tablet.md) is placed in the charger, its first [hard drive](../item/hdd1.md) is also exposed to [computers](../general/computer.md) connected to the charger, similar to how [floppies](../item/floppy.md) in [disk drives](diskDrive.md) are. This allows transferring of data between the [computer](../general/computer.md) and [tablet](../item/tablet.md). +When a [tablet](../item/tablet.md) is placed in the charger, the first [hard drive](../item/hdd1.md) is also exposed to [computers](../general/computer.md) connected to the charger, similar to how [floppies](../item/floppy.md) in [disk drives](diskDrive.md) are. This allows transferring of data between the [computer](../general/computer.md) and [tablet](../item/tablet.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/disassembler.md b/src/main/resources/assets/opencomputers/doc/en_US/block/disassembler.md index 659c4c69f..770376b9d 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/disassembler.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/disassembler.md @@ -4,4 +4,4 @@ The disassembler can be used to deconstruct most items in OpenComputers into their original parts. This is mostly useful to reclaim materials from old parts that are no longer useful, or to deconstruct devices that are either no longer needed or were incorrectly built (e.g. [robots](robot.md) without an [operating system](../general/openOS.md)). -Disassembling items takes a relatively long time, and some energy. There is also a slight chance of loosing a component, which is applied on a component by component basis - be careful about throwing a device into the disassembler. +Disassembling items takes a long time, and some energy. There is also a slight chance of losing a component (which is applied on a component by component basis). \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/diskDrive.md b/src/main/resources/assets/opencomputers/doc/en_US/block/diskDrive.md index 0b82cc36d..ce8ded7a3 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/diskDrive.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/diskDrive.md @@ -2,8 +2,8 @@ ![Going round and round and...](oredict:oc:diskDrive) -The disk drive can be used to read [floppy disks](../item/floppy.md) using a [computer](../general/computer.md) connected to the disk drive. This is useful to get started, since the lower tier [computer cases](case1.md) do not have a built-in floppy slot, and you'll need an operating system to get started. An [OpenOS](../general/openOS.lua) disk can be crafted using an empty [floppy disk](../item/floppy.md) and a [manual](../item/manual.lua). +The disk drive can be used to read [floppy disks](../item/floppy.md) using a [computer](../general/computer.md) connected to the disk drive. This is useful to get started, since the lower tier [computer cases](case1.md) do not have a built-in floppy slot, and you'll need an operating system to boot up the [computer](../general/computer.md). An [OpenOS](../general/openOS.lua) disk can be crafted using an empty [floppy disk](../item/floppy.md) and a [manual](../item/manual.lua). -It can also be installed in [robots](robot.md) to allow inserting an removing [floppy disks](../item/floppy.md) into and from the robot at any time. This can be very useful since the only other way to transfer data to and from a robot is using networking - for example using [network cards](../item/lanCard.md). +It can also be installed in [robots](robot.md) to allow inserting [floppy disks](../item/floppy.md) into the [robot](robot.md). This can be very useful since the only other way to transfer data to and from a robot is using networking - for example using [network cards](../item/lanCard.md). -Disks can be inserted and removed without opening the disk drive's GUI by using them while sneaking. +[Disks](../item/floppy.md) can be inserted and removed without opening the disk drive's GUI by sneak-activating the disk drive (shift-right click) with the [floppy disk](../item/floppy.md) in hand. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/geolyzer.md b/src/main/resources/assets/opencomputers/doc/en_US/block/geolyzer.md index 2586f9eac..e7c190a69 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/geolyzer.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/geolyzer.md @@ -4,4 +4,4 @@ The geolyzer can be used by [computers](../general/computer.md) to scan the terrain surrounding the geolyzer for the blocks' approximate hardness. This can be useful to generate maps of the area to display on [hologram projectors](hologram1.md) as well as to detect potentially valuable blocks (ores are usually harder than dirt and stone). Geolyzer scan results have a certain amount of noise added; in theory, multiple scans can be performed to determine a more accurate reading of a block's hardness level. -The geolyzer can also be installed in [robots](robot.md) and [tablets](../item/tablet.md) as an upgrade to allow them to scan their surroundings. Performing a scan will consume some energy, though, so using it excessively may quickly drain the device's batteries. +The geolyzer can also be installed in [robots](robot.md) and [tablets](../item/tablet.md) as an upgrade to allow them to scan their surroundings. Performing a scan will consume some energy, though, so using it excessively will drain the device's batteries. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/hologram1.md b/src/main/resources/assets/opencomputers/doc/en_US/block/hologram1.md index 6020158d2..0e6d89769 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/hologram1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/hologram1.md @@ -2,6 +2,6 @@ ![Is this the real life? Is this just fantasy?](oredict:oc:hologram1) -The hologram projector is a volumetric display, i.e. it provides a three dimensional array of voxels that can be individually enabled or disabled by a connected [computer](../general/computer.md). The second tier projector, while having the same resolution as the tier one projector, supports displaying the individual voxels in three different user-definable colors. +The hologram projector is a volumetric display, i.e. it provides a three dimensional array of voxels that can be individually enabled or disabled by a connected [computer](../general/computer.md). The second tier projector, while having the same resolution as the tier 1 projector, supports displaying the individual voxels in three different user-definable colors. Holograms can be rotated along their vertical axis by hitting them with a [wrench](../item/wrench.md) on their top or bottom. This can save some effort, so that the output doesn't have to be transformed on the software side. Holograms can also be scaled up or down as desired. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/keyboard.md b/src/main/resources/assets/opencomputers/doc/en_US/block/keyboard.md index 83e8438ab..6ce96a892 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/keyboard.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/keyboard.md @@ -4,4 +4,4 @@ A keyboard is needed to type text on [screens](screen1.md), be they in the world or built into devices such as [robots](robot.md) or [tablets](../item/tablet.md). -For a keyboard to work with a [screen](screen1.md) in the world, it has to be placed next to the [screen](screen1.md), facing that [screen](screen1.md), or placed directly on the [screen](screen1.md) (on top or on one of its sides). You can tell that a keyboard is "connected" to a [screen](screen1.md) if by using the keyboard the [screen's](screen1.md) GUI opens up. +For a keyboard to work with a [screen](screen1.md) in the world, it has to be placed next to the [screen](screen1.md), facing that [screen](screen1.md), or placed directly on the [screen](screen1.md) (on top or on one of its sides). You can tell that a keyboard is "connected" to a [screen](screen1.md) if the [screen's](screen.md) GUI opens up when using the keyboard. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/microcontroller.md b/src/main/resources/assets/opencomputers/doc/en_US/block/microcontroller.md index b4422a8bc..910316304 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/microcontroller.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/microcontroller.md @@ -2,6 +2,6 @@ ![Don't belittle it.](block:OpenComputers:microcontroller) -Microcontrollers are built using a [microcontroller case](../item/microcontrollerCase1.md) in the [assembler](assembler.md). They have less functionality compared to computers, but are cheaper to build. +Microcontrollers are built using a [microcontroller case](../item/microcontrollerCase1.md) in the [assembler](assembler.md). They have less functionality compared to [computers](../general/computer.md), but are cheaper to build. Microcontrollers can take various components, such as [CPUs](../item/cpu1.md), [memory (RAM)](../item/ram1.md), and Expansion cards. Microcontrollers are unable to contain a [hard disk drive](../item/hdd1.md), but do contain a slot for an [EEPROM](../item/eeprom.md), which can be programmed for very specific tasks. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/motionSensor.md b/src/main/resources/assets/opencomputers/doc/en_US/block/motionSensor.md index 86634dca4..37225ec63 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/motionSensor.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/motionSensor.md @@ -2,6 +2,6 @@ ![Don't. Blink.](oredict:oc:motionSensor) -The motion sensor allows [computers](../general/computer.md) to detect movement of living entities. If an entity moves faster than a set threshold, a signal will be injected into [computers](../general/computer.md) connected to the motion sensor. The threshold can be configured via the component the motion sensor exposes to connected computers. +The motion sensor allows [computers](../general/computer.md) to detect movement of living entities. If an entity moves faster than a set threshold, a signal will be injected into [computers](../general/computer.md) connected to the motion sensor. The threshold can be configured using the component API that the motion sensor exposes to connected computers. Movement is only detected if it happens within a radius of eight blocks around the motion sensor, and if there is a direct line of sight from the block to the entity that moved. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/powerConverter.md b/src/main/resources/assets/opencomputers/doc/en_US/block/powerConverter.md index fdd9fb6f3..07728c892 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/powerConverter.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/powerConverter.md @@ -2,4 +2,4 @@ ![One of us? One of us!](oredict:oc:powerConverter) -The power converter serves as the fastest way to convert energy from other mods' power systems to OpenComputers' internal energy. If you only run a simple computer, you probably won't need a converter. If you have a large capacitor bank that you only drain every now and then, you probably won't need one, either. However, if you wish to directly power an [assembler](assembler.md) or [charger](charger.md), it is usually a good idea to use a converter, instead of directly connecting them to external power. +The power converter serves as the fastest way to convert energy from other mods' power systems to OpenComputers' internal energy. If you only run a simple computer, you probably won't need a converter. If you have a large capacitor bank that you only drain every now and then, you probably won't need one, either. However, if you wish to directly power an [assembler](assembler.md) or [charger](charger.md), it is usually a good idea to use a converter instead of directly connecting them to external power. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/powerDistributor.md b/src/main/resources/assets/opencomputers/doc/en_US/block/powerDistributor.md index d9796e7a7..70ec54adf 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/powerDistributor.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/powerDistributor.md @@ -2,4 +2,4 @@ ![Power to the masses.](oredict:oc:powerDistributor) -The power distributor distributes a shared power storage (such as a [capacitor](capacitor.md)), allowing several subnetworks to share their energy, without components being exposed to computers in other networks. It operates by regularly "balancing" the energy in all subnetworks it is connected to, so that the *relative* amount of energy is the same in them. +The power distributor distributes a shared power storage (such as a [capacitor](capacitor.md)), allowing several subnetworks to share their energy without components being exposed to computers in other networks. It operates by regularly "balancing" the energy in all subnetworks it is connected to, so that the *relative* amount of energy is the same in them. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/print.md b/src/main/resources/assets/opencomputers/doc/en_US/block/print.md index c78ebb887..8fea03113 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/print.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/print.md @@ -2,9 +2,9 @@ ![Any way you want me.](block:OpenComputers:print) -3D prints are created using a [3D printer](printer.md). They are primarily intended for decorative purposes, but can also be created in such a way that they react to or emit redstone signals, allowing for a little bit of functional behavior on the side. +3D prints are created using a [3D printer](printer.md). They are primarily intended for decorative purposes, but can also be created in such a way that they react to or emit redstone signals, allowing for a little bit extra functionality. -3D prints can be recycled by putting them as input into a 3D printer. This will re-use some of the [chamelium](../item/chamelium.md) that was used to print them. Color that was used to print the model will not be recycled. +3D prints can be recycled by putting them as input into a [3D printer](printer.md). This will re-use some of the [chamelium](../item/chamelium.md) that was used to print them. Color that was used to print the model will not be recycled. Holding the key for OpenComputers' extended tooltips (default is [Shift]), a print's active state will be shown, if any. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/printer.md b/src/main/resources/assets/opencomputers/doc/en_US/block/printer.md index 6023364db..3fdb09cae 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/printer.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/printer.md @@ -4,12 +4,12 @@ 3D printers allow you to print any block of any shape, with any type of texture. To get started with 3D printers, you will need to place down a 3D printer block next to a computer. This will give access to the `printer3d` component API, allowing you to set up and print [models](print.md) using the provided functions. -A more convenient way to setup 3D printers is to use Open Programs Package Manager (OPPM). Once installed (`oppm install oppm`), make sure you have an [internet card](../item/internetCard.md) in your computer and run the following command: +A more convenient way to setup 3D printers is to use Open Programs Package Manager (OPPM). Once installed (`oppm install oppm`), make sure you have an [internet card](../item/internetCard.md) in your [computer](../general/computer.md) and run the following command: `oppm install print3d-examples` -The examples can then be found in `/usr/share/models/` as .3dm files. Take a look through the example files for available options, in particular the `example.3dm` file. Alternatively, you can download the `print3d` and `print3d-examples` programs from OpenPrograms using `wget` and an internet card. +The examples can then be found in `/usr/share/models/` as .3dm files. Take a look through the example files for available options, in particular the `example.3dm` file. Alternatively, you can download the `print3d` and `print3d-examples` programs from OpenPrograms using `wget` and an [internet card](../item/internetCard.md). -In order to be able to print the models, a 3D printer needs to be configured via a computer. If set to print non-stop, the computer will be no longer required thereafter. You will also need to provide an [ink cartridge](../item/inkCartridge.md) and some [chamelium](../item/chamelium.md) as input materials. The amount of chamelium used depends on the volume of the 3D print, while the amount of ink used depends on the surface area of the printed item. +In order to be able to print the models, a 3D printer needs to be configured via a [computer](../general/computer.md). If set to print non-stop, the computer will no longer be required thereafter. You will also need to provide an [ink cartridge](../item/inkCartridge.md) and some [chamelium](../item/chamelium.md) as input materials. The amount of chamelium used depends on the volume of the 3D print, while the amount of ink used depends on the surface area of the printed item. To print an item, use the following command: `print3d /path/to/file.3dm` diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/raid.md b/src/main/resources/assets/opencomputers/doc/en_US/block/raid.md index f434b8b59..87eda2777 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/raid.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/raid.md @@ -6,6 +6,6 @@ The raid block houses three [hard drives](../item/hdd1.md) which will be combine The raid only works (and shows up as a file system) when three [hard drives](../item/hdd1.md) are present. The [hard drives](../item/hdd1.md) may differ in size. -Beware that adding a [hard drive](../item/hdd1.md) to the raid block will wipe it of its contents. Removing a single [hard drives](../item/hdd1.md) from a complete raid will also wipe the raid. Adding the disk back in will *not* restore it, the raid's new file system will not contain any files. +Beware that adding a [hard drive](../item/hdd1.md) to the raid block will wipe it of its contents. Removing a single [hard drives](../item/hdd1.md) from a complete raid will wipe the entire raid. Adding the disk back in will *not* restore the old files; the raid will be re-initialized as an empty file system. -Breaking a raid block will retain its contents, so it can be safely relocated without losing its data. +Breaking a raid block will retain its contents, so it can be safely relocated without losing any data. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/redstone.md b/src/main/resources/assets/opencomputers/doc/en_US/block/redstone.md index bfb855c30..8978fc884 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/redstone.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/redstone.md @@ -6,6 +6,4 @@ The redstone I/O block can be used to remotely read and emit redstone signals. I When providing a side to the methods of the component exposed by this block, the directions are the global principal directions, i.e. it is recommended to use `sides.north`, `sides.east` and so on. -Like the redstone card, this block injects a signal into connected computers when the state of a redstone signal changes - both for analog as well as for bundled signals. - -Also like redstone cards, this block can be configured to wake up connected computers when a certain input strength is exceeded, allowing automated booting of computers. +Like the [redstone cards](../item/redstoneCard1.md), this block injects a signal into connected [computers](../general/computer.md) when the state of a redstone signal changes - both for analog as well as for bundled signals. This block can also be configured to wake up connected [computers](../general/computer.md) when a certain input strength is exceeded, allowing automated booting of [computers](../general/computer.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/robot.md b/src/main/resources/assets/opencomputers/doc/en_US/block/robot.md index b80c332c5..7b32bc5c0 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/robot.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/robot.md @@ -2,8 +2,8 @@ ![His name was Tobor.](block:OpenComputers:robot) -Unlike computers, robots can move around and interact with the world much like a player can. They can *not* interact with external components, however! If you need to communicate with a [computer](../general/computer.md) or other robots, use a [wireless network card](../item/wlanCard.md), or create some low-level protocol using redstone signals via a [redstone card](../item/redstoneCard1.md), for example. +Unlike [computers](../general/computer.md), robots can move around and interact with the world much like a player can. They can *not* interact with external components, however! If you need to communicate with a [computer](../general/computer.md) or other robots, use a [wireless network card](../item/wlanCard.md), or create some low-level protocol using redstone signals via a [redstone card](../item/redstoneCard1.md), for example. -Robots are built by placing a [computer case](case1.md) of any tier in an [assembler](assembler.md). Higher tier computer cases can build more complex robots, due to being able to hold a higher tier [CPU](../item/cpu1.md). Complexity of the robot (as shown in the [assembler](assembler.md)) is determined by the tier of the components and upgrades placed in the robot slots; higher tier components will increase the complexity more than a lower tier component. If the complexity of the robot is too high, the [assembler](assembler.md) will not build the robot. +Robots are built by placing a [computer case](case1.md) of any tier in an [assembler](assembler.md). Higher tier [computer cases](case1.md) can build more complex robots, due to being able to hold a higher tier [CPU](../item/cpu1.md). Complexity of the robot (as shown in the [assembler](assembler.md)) is determined by the tier of the components and upgrades placed in the robot slots; higher tier components will increase the complexity more than a lower tier component. If the complexity of the robot is too high, the [assembler](assembler.md) will not build the robot. -Various upgrades can be placed into robots to increase the functionality. These include [inventory](../item/inventoryUpgrade.md) and [inventory controller](../item/inventoryControllerUpgrade.md) upgrades, [tank upgrades](../item/tankUpgrade.md), [navigation upgrade](../item/navigationUpgrade.md), among others. [Upgrade](../item/upgradeContainer1.md) and [card](../item/cardContainer1.md) containers can be placed in the robot for on-the-fly insertion and removal of upgrades and components. A [disk drive](diskDrive.md) can also be placed inside a robot to allow [floppy disks](../item/floppy.md) to be inserted, which will let you install openOS to the robot (an alternative is to install openOS to a blank [hard drive](../item/hdd1.md) using a computer, and using the pre-installed [hard drive](../item/hdd1.md) as a component in the robot assembly). +Various upgrades can be placed into robots to increase the functionality. These include [inventory](../item/inventoryUpgrade.md) and [inventory controller](../item/inventoryControllerUpgrade.md) upgrades, [tank upgrades](../item/tankUpgrade.md), [navigation upgrade](../item/navigationUpgrade.md), among others. [Upgrade](../item/upgradeContainer1.md) and [card](../item/cardContainer1.md) containers can be placed in the robot for on-the-fly insertion and removal of upgrades and components. A [disk drive](diskDrive.md) can also be placed inside a robot to allow [floppy disks](../item/floppy.md) to be inserted, which will let you install [openOS](../general/openOS.md) to the robot (an alternative is to install [openOS](../general/openOS.md) to a blank [hard drive](../item/hdd1.md) using a [computer](../general/computer.md), and using the pre-installed [hard drive](../item/hdd1.md) as a component in the robot assembly). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/screen1.md b/src/main/resources/assets/opencomputers/doc/en_US/block/screen1.md index 60e18e716..75710fb6b 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/screen1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/screen1.md @@ -2,14 +2,15 @@ ![See this?](oredict:oc:screen1) -A screen is used in combination with a [graphics card](../item/graphicsCard1.md), to allow computers to display text. Different screen tiers have different capabilities, such as supporting different resolutions and color depths. Screens range from low-resolution, monochrome displays to high-resolution displays with up to 256 colors. +A screen is used in combination with a [graphics card](../item/graphicsCard1.md), to allow [computers](../general/computer.md) to display text. Different screen tiers have different capabilities, such as supporting different resolutions and color depths. Screens range from low-resolution, monochrome displays to high-resolution displays with up to 256 colors. -The available resolution and color depth depends on the lowest tier component. When using a [graphics card (tier 1)](../item/graphicsCard1.md) with a [screen (tier 3)](screen3.md), only the tier 1 resolution and color depth is usable. However, when using a tier 3 graphics card with a tier 1 screen, while resolution and color depth will still be limit to tier 1, the different operations on the graphics card will be faster than when using a tier 1 graphics card. +The available resolution and color depth depends on the lowest tier component. When using a [graphics card (tier 1)](../item/graphicsCard1.md) with a [screen (tier 3)](screen3.md), only the tier 1 resolution and color depth is usable. However, when using a tier 3 [graphics card](../item/graphicsCard1.md) with a tier 1 screen, while resolution and color depth will still be limit to tier 1, the different operations on the [graphics card](../item/graphicsCard1.md) will be faster than when using a tier 1 [graphics card](../item/graphicsCard1.md). -Screens can be placed next to each other to form multi-block screens, as long as they are facing the same way. When placed facing up or down they must also be rotated the same way. Their orientation is indicated by an arrow overlay shown while holding a screen in hand, in that case. -The size of a screen has no impact on the available resolution, only its tier has. To control how adjacent screens connect, screens can also be dyed using any dye. Simply use the screen with a dye in hand. The dye will not be consumed by this, but screens will also not retain this color once broken. Screens with different colors will not connect. Screens with different tiers will never connect, even if they have the same color. +Screens can be placed next to each other to form multi-block screens, as long as they are facing the same way. When placed facing up or down they must also be rotated the same way. Their orientation is indicated by an arrow overlay shown while holding a screen in hand. -Tier 2 and tier 3 screens also support mouse input. Clicks can either be performed in a screen's GUI (which can only be opened if a [keyboard](keyboard.md) is connected to the screen), or by using a screen while sneaking (empty-handed when in doubt). The sneaking part is optional if the screen has no keyboard. Note that whether the GUI opens when sneak- or normally activating a screen can be controlled via the component it exposes to connected computers. Tier 3 screens allow more accurate hit position detection, if so enabled in their component. This allows detecting whether the upper or lower half of a single character space was clicked, for example, which can be useful when using special Unicode characters to simulate higher resolutions. +The size of a screen has no impact on the available resolution, only its tier has. To control how adjacent screens connect, screens can also be dyed using any dye. Simply right-click the screen with a dye in hand. The dye will not be consumed, but screens will not retain this color when broken. Screens with different colors will not connect. Screens with different tiers will never connect, even if they have the same color. + +Tier 2 and tier 3 screens also support mouse input. Clicks can either be performed in a screen's GUI (which can only be opened if a [keyboard](keyboard.md) is connected to the screen), or by using a screen while sneaking (empty-handed when in doubt). The sneaking part is optional if the screen has no [keyboard](keyboard.md). Note that whether the GUI opens when sneak- or normally activating a screen can be controlled using the component API that it exposes to connected [computers](../general/computer.md). Tier 3 screens allow more accurate hit position detection, if enabled in their component. This allows detecting whether the upper or lower half of a single character space was clicked, for example, which can be useful when using special Unicode characters to simulate higher resolutions. The resolutions and color depths for the screens are as follows: - Tier 1: 50x16, 1-bit color. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/serverRack.md b/src/main/resources/assets/opencomputers/doc/en_US/block/serverRack.md index 08558ca4d..c737a4711 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/serverRack.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/serverRack.md @@ -2,8 +2,8 @@ ![Free housing.](oredict:oc:serverRack) -A server rack houses up to four [servers](../item/server1.md). A server is a higher tier [computer](../general/computer.md), which can only run when inside a server rack. [Servers](../item/server1.md) can be remote controlled using a [remote terminal](../item/terminal.md). The number of terminals that can be connected to a single server at a time depends on the tier of the server. The distance up to which the remote terminals work can be configured in the rack's GUI. Higher values have a higher constant energy draw. +A server rack houses up to four [servers](../item/server1.md). A [server](../item/server1.md) is a higher tier [computer](../general/computer.md), which can only run when inside a server rack. [Servers](../item/server1.md) can be remote controlled using a [remote terminal](../item/terminal.md). The number of [remote terminals](../item/terminal.md) that can be connected to a single [server](../item/server1.md) at a time depends on the tier of the [server](../item/server1.md). The distance up to which the [remote terminal](../item/terminal.md) work can be configured in the rack's GUI. Higher values have require more energy. -Each [server](../item/server1.md) in a server rack can only communicate with one "face" of the server rack at a time - or none at all. Which side each [server](../item/server1.md) is connected to can be configured in the server rack's GUI. Beware that the sides are from the point of view of the server rack, i.e. if you are looking at the front of the server rack, right will be to your left and vice versa. +Each [server](../item/server1.md) in a server rack can only communicate with one "face" of the server rack at a time - or none at all. Which side each [server](../item/server1.md) is connected to can be configured in the server rack's GUI. Beware that the sides are from the point of view of the server rack, i.e. if you are looking at the front of the server rack, `sides.right` will be to your left and vice versa. -Server racks act as [switch](switch.md) and [power distributor](powerDistributor.md) in one. The switch mode of the server rack can be configured in its GUI, with the two options being internal and external. In external mode the server rack will behave like a normal switch. In internal mode, messages are only passed to the [servers](../item/server.md) in the rack, they will not be automatically relayed to the other faces of the rack. [Servers](../item/server1.md) will still be able to send messages to each other. This allows using server racks as advanced switches that can perform filter and mapping operations, for example. +Server racks act as [switch](switch.md) and [power distributor](powerDistributor.md) in one. The switch mode of the server rack can be configured in its GUI, with the two options being internal and external. In external mode the server rack will behave like a normal [switch](switch.md). In internal mode, messages are only passed to the [servers](../item/server.md) in the rack, and will not be automatically relayed to the other faces of the rack. [Servers](../item/server1.md) will still be able to send messages to each other. This allows using server racks as advanced [switches](switch.md) that can perform filter and mapping operations, for example. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/switch.md b/src/main/resources/assets/opencomputers/doc/en_US/block/switch.md index ec5f120d1..a607e0cfd 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/switch.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/switch.md @@ -2,10 +2,10 @@ ![Building bridges.](oredict:oc:switch) -The switch can be used to allow different subnetworks to send network messages to each other, without exposing components to [computers](../general/computer.md) in other networks. Keeping components local is usually a good idea, to avoid computers using the wrong [screen](screen1.md) or to avoid component overflows to happen (in which computers will crash / not start anymore). +The switch can be used to allow different subnetworks to send network messages to each other, without exposing components to [computers](../general/computer.md) in other networks. Keeping components local is usually a good idea, to avoid [computers](../general/computer.md) using the wrong [screen](screen1.md) or to avoid component overflows to happen (causing [computers](../general/computer.md) to crash and refuse to boot up). -There is also a wireless variation of this block, called the [access point](accessPoint.md), which will also relay messages wirelessly. Wireless messages can be received and relayed by other access points, or by computers with a [wireless network card](../item/wlanCard.md). +There is also a wireless variation of this block, called the [access point](accessPoint.md), which will also relay messages wirelessly. Wireless messages can be received and relayed by other [access points](accessPoint.md), or by [computers](../general/computer.md) with a [wireless network card](../item/wlanCard.md). -Switches and [access points](accessPoint.md) do *not* keep track of which packets they relayed recently, so avoid cycles in your network or you may receive the same packet multiple times. Due to the limited buffer size of switches, you also should be careful of sending too many messages in a short time, or you will experience package loss. You can upgrade your switches and access points to increase the speed with which they relay messages, as well as their internal message queue size. +Switches and [access points](accessPoint.md) do *not* keep track of which packets they relayed recently, so avoid cycles in your network or you may receive the same packet multiple times. Due to the limited buffer size of switches, sending messages too frequently will result in packet loss. You can upgrade your switches and [access points](accessPoint.md) to increase the speed with which they relay messages, as well as their internal message queue size. -Packets are only re-sent a certain number of times, so chaining an arbitrary number of switches or access points is not possible. By default, a packet will hop up to five times. +Packets are only re-sent a certain number of times, so chaining an arbitrary number of switches or access points is not possible. By default, a packet will be re-sent up to five times. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/general/computer.md b/src/main/resources/assets/opencomputers/doc/en_US/general/computer.md index 9860d41ca..5ca59e680 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/general/computer.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/general/computer.md @@ -1,10 +1,10 @@ # Computers -Computers are built using a variety of different [blocks](../block/index.md) and components. The bare minimum needed to build a computer is a [case](../block/case1.md), [screen](../block/screen1.md), and [keyboard](../block/keyboard.md). The case and screen are available in different tiers providing different functionality and allowing for more complex computer systems. In order for the screen to be accessible, the keyboard must be placed adjacent to the screen (either on the sides or directly in front of the screen). +Computers are built using a variety of different [blocks](../block/index.md) and components. The bare minimum needed to build a computer is a [case](../block/case1.md), [screen](../block/screen1.md), and [keyboard](../block/keyboard.md). The [case](../block/case1.md) and [screen](../block/screen1.md) are available in different tiers providing different functionality and allowing for more complex computer systems. In order for the [screen](../block/screen1.md) to be accessible, the [keyboard](../block/keyboard.md) must be placed adjacent to the [screen](../block/screen1.md) (either on the sides or directly in front of the [screen](../block/screen1.md)). -Once the basic structure is built, components can be placed inside the [case](../block/case1.md). These components include [CPUs](../item/cpu1.md), [memory (RAM)](../item/ram1.md), [hard disk drives (HDD)](../item/hdd1.md), [graphics cards](../item/graphicsCard1.md) (to be able to use the [screen](../block/screen1.md)), [network cards](../item/lanCard.md) (for communication between computer networks), etc. There are many components available allowing for highly flexible systems designed for specific purposes. +Once the basic structure is built, components can be placed inside the [case](../block/case1.md). These components include [CPUs](../item/cpu1.md), [memory (RAM)](../item/ram1.md), [hard drives (HDD)](../item/hdd1.md), [graphics cards](../item/graphicsCard1.md) (to be able to use the [screen](../block/screen1.md)), [network cards](../item/lanCard.md) (for communication between computer networks), etc. There are many components available allowing for highly flexible systems designed for specific purposes. -Lower tier computers also require a [disk drive](../block/diskDrive.md), which takes a [floppy](../item/floppy.md) disk. An OpenOS [floppy](../item/floppy.md) disk is needed for booting up the computer for the first time, and is used to install the operating system to the [HDD](../item/hdd1.md). Once installed to the [HDD](../item/hdd1.md), the [floppy](../item/floppy.md) disk is no longer necessary. Additional software is also available as [floppy](../item/floppy.md) disks (such as Open Programs Package Manager, or OPPM) and are obtained from dungeon loot. +Lower tier computers also require a [disk drive](../block/diskDrive.md), which takes a [floppy](../item/floppy.md) disk. An [OpenOS](openOS.md) [floppy](../item/floppy.md) disk is needed for booting up the computer for the first time, and is used to install the operating system to the [HDD](../item/hdd1.md). Once installed to the [HDD](../item/hdd1.md), the [floppy](../item/floppy.md) disk is no longer necessary. Additional software is also available as [floppy](../item/floppy.md) disks (such as Open Programs Package Manager, or OPPM) and are obtained from dungeon loot. The final step necessary is to provide the computer with a power source. OpenComputers is compatible with most major power-providing mods, and many blocks can be powered directly. You can see which blocks can be connected to external power by checking if their tooltip contains an entry about the block's power conversion speed. -For a larger network with multiple computers, a [power converter](../block/powerConverter.md) (converts different mod's power to OC's internal Energy type), [power distributor](../block/powerDistributor.md) (distributes power to different computers), and [capacitor](../block/capacitor.md) (power storage for the network) can be used to connect different computers on the network using [cables](../block/cable.md). +For a larger network with multiple computers, a [power converter](../block/powerConverter.md) (converts different mod's power to OC's internal Energy type), [power distributor](../block/powerDistributor.md) (distributes power to different computers on the network), and [capacitor](../block/capacitor.md) (power storage for the network) can be used to connect different computers on the network using [cables](../block/cable.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/general/openOS.md b/src/main/resources/assets/opencomputers/doc/en_US/general/openOS.md index e4041930c..0f1b23793 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/general/openOS.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/general/openOS.md @@ -4,7 +4,9 @@ OpenOS is a basic operating system available in OpenComputers. It is required to Once crafted, the [floppy disk](../item/floppy.md) can be placed inside a [disk drive](../block/diskDrive.md) connected to a [correctly configured](quickstart.md) [computer](computer.md) system, which will allow the [computer](computer.md) to boot up OpenOS. Once booted, it is advisable to install OpenOS to an empty [hard drive](../item/hdd1.md), foregoing the need for a [floppy disk](../item/floppy.md) and to gain access to a read-write file system (the OpenOS [floppy disk](../item/floppy.md) and other "loot" disks are read-only). A tier 3 [computer case](../block/case3.md) does not require a [disk drive](../block/diskDrive.md), as it has a slot built in for the [floppy disk](../item/floppy.md). + OpenOS can be installed by simply running `install`, and following the on-screen prompts to complete the installation. The [floppy disk](../item/floppy.md) may be removed once the system has been rebooted. OpenOS can be installed on all devices except [drones](../item/drone.md) and [microcontrollers](../block/microcontroller.md) (both of which require manually programming an [EEPROM](../item/eeprom.md) to provide functionality, because they have no built in file system). OpenOS has many built in functions, the most useful of them is the `lua` command, which opens up a Lua interpreter. This is a good testing space for trying out various commands, and experimenting with component API, before writing the commands into a .lua script. Take note of the information displayed when starting the interpreter, it will tell you how to show results of the commands you enter, and how to exit it. + For more information on programming, refer to the [Lua Programming](lua.md) page. To run Lua scripts, simply type in the name of the file and hit enter (for example, `script.lua` can be run by typing the `script` command in the terminal). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/general/quickstart.md b/src/main/resources/assets/opencomputers/doc/en_US/general/quickstart.md index 1abb20603..b880cbdc6 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/general/quickstart.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/general/quickstart.md @@ -2,49 +2,49 @@ Also know as "how to build your first computer". To get your first [computer](computer.md) to run, you will need to first set it up correctly. There are many different types of computers in OpenComputers, but let's start with the basic one: the standard computer. -**Disclaimer**: this will be step-by-step, and also provide some information on how to look for issues yourself later on, so this is quite long. If you never built a computer in real life, and/or are completely new to the mod, it is highly recommended you read through it all. +**Disclaimer**: this will be step-by-step, and also provide some information on how to look for issues yourself later on, so this is quite long. If you have never built a computer in real life, and/or are completely new to the mod, it is highly recommended you read through it all. -First off, you will need a [computer case](../block/case1.md). This is the block into which you will build most of the components, defining the behavior of the computer you're building. +First off, you will need a [computer case](../block/case1.md). This is the block which will contain of the components, defining the behavior of the computer you are building. ![A tier two computer case.](oredict:oc:case2) For example, you will need to choose what tier of [graphics card](../item/graphicsCard1.md) you wish to use, if you need a [network card](../item/lanCard.md), a [redstone card](../item/redstoneCard1.md) or, if you're just playing around in creative mode, maybe even a [debug card](../item/debugCard.md). -When you open the computer case's GUI you will see a few slots to the right. The number of slots, and what tier of component can be placed into them (indicated by the small roman numeral in the slot) depends on the tier of the case itself. +When you open the [computer case](../block/case1.md)'s GUI you will see a few slots to the right. The number of slots, and what tier of component can be placed into them (indicated by the small roman numeral in the slot) depends on the tier of the case itself. ![GUI of a tier two computer case.](opencomputers:doc/img/configuration_case1.png) -In their empty state, computer cases are pretty useless. You can try to power up your computer now, but it'll immediately print an error message to your chat log, and make its dissatisfaction heard by beeping at you. Good thing the error message is telling you what you can do to fix this situation: it's missing energy. Connect your computer to some power, either directly or via a [power converter](../block/powerConverter.md). +In their empty state, [computer cases](../block/case1.md) are pretty useless. You can try to power up your [computer](computer.md) now, but it'll immediately print an error message to your chat log, and make its dissatisfaction heard by beeping at you. Good thing the error message is telling you what you can do to fix this situation: it requires energy. Connect your [computer](computer.md) to some power, either directly or via a [power converter](../block/powerConverter.md). -When you try to start it now, it'll tell you that you need a [CPU](../item/cpu1.md). These come in different tiers - a trend you'll notice is present all throughout OpenComputers. For CPUs, higher tiers mean more components at a time, as well as faster execution. So pick a tier, and put it in your computer. +When you try to start it now, it will tell you that you need a [CPU](../item/cpu1.md). These come in different tiers - a trend you will notice is present throughout OpenComputers. For [CPUs](../item/cpu1.md), higher tiers mean more components at a time, as well as faster execution. So pick a tier, and put it in your [computer case](../block/case1.md). -Next up you'll be asked to insert some [memory](../item/ram1.md). Notice that the beep code is different now: long-short. Higher tiers of RAM mean more memory available to the programs running on your computer. To run [OpenOS](openOS.md), which is the goal of this introduction, you'll want to use at least two tier one memory sticks. +Next up you will be asked to insert some [memory (RAM)](../item/ram1.md). Notice that the beep code is different now: long-short. Higher tiers of [memory (RAM)](../item/ram1.md) mean more memory available to the programs running on your [computer](computer.md). To run [OpenOS](openOS.md), which is the goal of this introduction, you will want to use at least two tier 1 [memory (RAM)](../item/ram1.md) sticks. -We're making good progress here. By now your computer case will look somewhat like this: +We're making good progress here. By now your [computer case](../block/case1.md) will look somewhat like this: ![Partially configured computer.](opencomputers:doc/img/configuration_case2.png) -And behold, turning it on now does not print any more error messages! But alas, it still doesn't do much. At least it beeps twice now. That means the actual execution of the computer failed. In other words: it technically runs! This is where a very useful tool comes into play: the [analyzer](../item/analyzer.md). This tool allows inspecting many of OpenComputers' blocks, as well as some blocks from other mods. To use it on the computer, use the analyzer on the case while sneaking. +And behold, turning it on now does not print any more error messages! But alas, it still doesn't do much. At least it beeps twice now. That means the actual execution of the [computer](computer.md) failed. In other words: it technically runs! This is where a very useful tool comes into play: the [analyzer](../item/analyzer.md). This tool allows inspecting many of OpenComputers' blocks, as well as some blocks from other mods. To use it on the [computer](computer.md), use the [analyzer](../item/analyzer.md) on the case while sneaking. -You should now see the error that caused the computer to crash: +You should now see the error that caused the [computer](computer.md) to crash: `no bios found; install configured EEPROM` -The emphasis here is on *configured*. Crafting an [EEPROM](../item/eeprom.md) is pretty simple. To configure it, you will usually use a computer - but that's a little difficult right now, so we're going to use a recipe to craft a configured "Lua BIOS" EEPROM. The standard recipe is an EEPROM plus a [manual](../item/manual.md). Put the configured EEPROM into your computer, aaaand. +The emphasis here is on *configured*. Crafting an [EEPROM](../item/eeprom.md) is pretty simple. To configure it, you will usually use a [computer](computer.md) - but that's a little difficult right now, so we're going to use a recipe to craft a configured "Lua BIOS" [EEPROM](../item/eeprom.md). The standard recipe is an [EEPROM](../item/eeprom.md) plus a [manual](../item/manual.md). Put the configured [EEPROM](../item/eeprom.md) into your [computer](computer.md), aaaand. -Nope. Still nothing. But we know what to do: player uses analyzer, it's super effective! Now we have a different error message: +Nope. Still nothing. But we know what to do: player uses [analyzer](../item/analyzer.md), it's super effective! Now we have a different error message: `no bootable medium found; file not found` -Well then. That means the BIOS is working. It's just not finding a file system to boot from, such as a [floppy](../item/floppy.md) and [hard drive](../item/hdd1.md). The Lua BIOS in particular expects such a file system to furthermore contain a file named `init.lua` at root level. As with the EEPROM, you usually write to file systems using a computer. You probably guessed it: we now need to craft our operating system floppy. Take a blank floppy disk and a manual, craft them together, and you'll get an OpenOS disk. +Well then. That means the BIOS is working. It's just not finding a file system to boot from, such as a [floppy](../item/floppy.md) or [hard drive](../item/hdd1.md). The Lua BIOS in particular expects such a file system to furthermore contain a file named `init.lua` at root level. As with the [EEPROM](../item/eeprom.md), you usually write to file systems using a [computer](computer.md). You probably guessed it: we now need to craft our operating system disk. Take a blank [floppy disk](../item/floppy.md) and a [manual](../item/manual.md), craft them together, and you'll get an [OpenOS](openOS.md) disk. -Now, if you used a tier two case as in the screenshots above, you'll have nowhere to place that floppy. If you have a tier three or creative case, you can place the floppy right into the case. Otherwise you'll need to place a [disk drive](../block/diskDrive.md) next to your case (or connect it via [cables](../block/cable.md)). Once your disk is in place, you know what to do. Press the power button. +Now, if you used a tier 2 [computer case](../block/case2.md) as in the screenshots above, you'll have nowhere to place that floppy. If you have a tier 3 or creative [computer case](../block/case3.md), you can place the floppy right into the [case](../block/case1.md). Otherwise you'll need to place a [disk drive](../block/diskDrive.md) next to your case (or connect it via [cables](../block/cable.md)). Once your disk is in place, you know what to do. Press the power button. -It lives! Or should, anyway. If it doesn't something went wrong, and you'll want to investigate using the analyzer. But assuming it's running now, you're pretty much done. The hardest part is over. All that's left is to make it take input and show some output. +It lives! Or should, anyway. If it doesn't something went wrong, and you'll want to investigate using the [analyzer](../item/analyzer.md). But assuming it's running now, you're pretty much done. The hardest part is over. All that's left is to make it take input and show some output. -To allow the computer to show some output, you'll want to grab a [screen](../block/screen1.md) and a [graphics card](../item/graphicsCard1.md). +To allow the [computer](computer.md) to show some output, you'll want to grab a [screen](../block/screen1.md) and a [graphics card](../item/graphicsCard1.md). ![No, it's not a flatscreen.](oredict:oc:screen2) -Place the screen adjacent to your computer case, or, again, connect it using some cable. Then place a graphics card of your choice into the computer case. You should now see a blinking cursor on the screen. Finally, place a [keyboard](../block/keyboard.md) either on the screen itself, or in a way so that it faces the screen, to enable keyboard input. +Place the [screen](../block/screen1.md) adjacent to your [computer case](../block/case1.md), or, again, connect it using some [cable](../block/cable.md). Then place a [graphics card](../item/graphicsCard1.md) of your choice into the [computer case](../block/case1.md). You should now see a blinking cursor on the [screen](../block/screen1.md). Finally, place a [keyboard](../block/keyboard.md) either on the [screen](../block/screen1.md) itself, or in a way so that it faces the [screen](../block/screen1.md), to enable [keyboard](../block/keyboard.md) input. -And with that, you're done. The computer is up and running and ready for action. Try using it now! Type `lua` in the shell and press enter, and you'll be greeted with a bit of information on how to use the Lua interpreter. Here you can test basic Lua commands. For more information this topic see [the Lua page](lua.md). +And with that, you're done. The [computer](computer.md) is up and running and ready for action. Try using it now! Type `lua` in the shell and press enter, and you'll be greeted with a bit of information on how to use the Lua interpreter. Here you can test basic Lua commands. For more information this topic see [the Lua page](lua.md). ![It lives!](opencomputers:doc/img/configuration_done.png) -Have fun building more complex computers, messing with [servers](../item/server1.md) and assembling [robots](../block/robot.md), [drones](../item/drone.md), [microcontrollers](../block/microcontroller.md) and [tablets](../item/tablet.md) in the [assembler](../block/assembler.md). +Have fun building more complex [computers](computer.md), messing with [servers](../item/server1.md) and assembling [robots](../block/robot.md), [drones](../item/drone.md), [microcontrollers](../block/microcontroller.md) and [tablets](../item/tablet.md) in the [assembler](../block/assembler.md). Happy coding! diff --git a/src/main/resources/assets/opencomputers/doc/en_US/index.md b/src/main/resources/assets/opencomputers/doc/en_US/index.md index 5bb024943..4afde6dc7 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/index.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/index.md @@ -32,7 +32,7 @@ All devices are modular and can be assembled with a wide range of components, ju OpenComputers devices are compatible with many different mods for manipulation of blocks and entities (through the [adapter](block/adapter.md), or specific upgrades in a [robot](block/robot.md) or [drone](item/drone.md)). Power can be supplied using a large range of other mods, including, but not limited to, Redstone Flux, IndustrialCraft2 EU, Mekanism Joules, Applied Energistics 2 energy as well as Factorization Charge. -Most devices are able to run a basic operating system called [OpenOS](general/openOS.md) (with the exception of drones and microcontrollers). OpenComputers allows for creation of custom OSes and Architectures, should the player desire it. +Most devices are able to run a basic operating system called [OpenOS](general/openOS.md) (with the exception of [drones](item/drone.md) and [microcontrollers](block/microcontroller.md). OpenComputers allows for creation of custom OSes and Architectures, should the player desire it. Devices have access to various resources such as [disk space](item/hdd1.md) and [memory (RAM)](item/ram1.md). [Microcontrollers](block/microcontroller.md) are cheap [computers](general/computer.md) with less functionality and components, and do not have an operating system, requiring creative use of programming. [Robots](block/robot.md) are mobile [computers](general/computer.md) and are able to interact with blocks and entities (but are unable to interact with external OpenComputers components). [Drones](item/drone.md) are fast, entity-based [robots](block/robot.md) with limited functionality, able to move differently and are able to interact differently with the world. [Servers](item/server1.md) are higher tier [computers](general/computer.md) and are able to hold more components, increasing the amount of resources available to control larger networks and run larger programs. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/abstractBusCard.md b/src/main/resources/assets/opencomputers/doc/en_US/item/abstractBusCard.md index b38b46829..4263adfe2 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/abstractBusCard.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/abstractBusCard.md @@ -2,4 +2,4 @@ ![More networking!](oredict:oc:abstractBusCard) -This card allows [computers](../general/computer.md), [servers](server1.md) and robots to interact with StargateTech2's abstract bus. When the card is installed, these blocks will connect to the abstract bus and a component becomes available to the machine that can be used to send messages across the abstract bus. Incoming abstract bus messages are converted to signals that are injected into the machine. +This card allows [computers](../general/computer.md), [servers](server1.md) and [robots](../block/robot.md) to interact with StargateTech2's abstract bus. When the card is installed, these blocks will connect to the abstract bus and a component becomes available to the machine that can be used to send messages across the abstract bus. Incoming abstract bus messages are converted to signals that are injected into the machine. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/acid.md b/src/main/resources/assets/opencomputers/doc/en_US/item/acid.md index eaa7c6fec..333f93900 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/acid.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/acid.md @@ -2,4 +2,4 @@ ![Reflux?](oredict:oc:materialAcid) -You'll probably only see this item when playing with the hard mode recipe set, in which case you'll need it to etch [circuit boards](circuitBoard.md) to craft [printed circuit boards](printedCircuitBoard.md). +Encountered only when using hard-mode recipes, it is used to etch [circuit boards](circuitBoard.md) before crafting [printed circuit boards](printedCircuitBoard.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/alu.md b/src/main/resources/assets/opencomputers/doc/en_US/item/alu.md index eeadb009d..d429cb404 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/alu.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/alu.md @@ -2,4 +2,4 @@ ![I can into logic!](oredict:oc:materialALU) -Used for crafting most things pushing numbers, such as [CPUs](cpu1.md) and [graphics cards](graphicsCard1.md). +Used for crafting components that perform calculations, such as [CPUs](cpu1.md) and [graphics cards](graphicsCard1.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/analyzer.md b/src/main/resources/assets/opencomputers/doc/en_US/item/analyzer.md index 3592ccdda..b185704af 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/analyzer.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/analyzer.md @@ -2,6 +2,6 @@ ![Must. Resist. Bad. Joke.](oredict:oc:analyzer) -The analyzer is a handy tool for getting some information about OpenComputers-related blocks in the world. Simply (sneak-)activate a block to get some information printed to the chat. This ranges from basic things like the address of components, to power levels in the subnetwork the block is in, and information on the error lead to a computer to crash, for example. +The analyzer is a handy tool for reading information about OpenComputers-related blocks in the world. Simply (sneak-)activate a block to get some information printed to the chat box. This ranges from basic things like the address of components, to power levels in the subnetwork the block is in, and information on the error lead to a [computer](../general/computer.md) to crash, for example. -Another useful functionality is that when using the using the analyzer on a block while holding down [Ctrl] the address of the block component will be copied to the clipboard. This information can then be pasted into a [computer](../general/computer.md) terminal if necessary. \ No newline at end of file +Another useful functionality is that when Ctrl-rightclicking a block or component, the address of that component is copied to the clipboard. This information can then be pasted into a [computer](../general/computer.md) terminal if needed. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/angelUpgrade.md b/src/main/resources/assets/opencomputers/doc/en_US/item/angelUpgrade.md index cf836fd07..611146a39 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/angelUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/angelUpgrade.md @@ -2,4 +2,4 @@ ![Hallelujah.](oredict:oc:angelUpgrade) -This upgrade allows robots to place blocks in thin air, without a reference block, similar to a certain block by a certain mod this upgrade may or may not have been inspired by. +This upgrade allows [robots](../block/robot.md) to place blocks in thin air, without a reference block. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/arrowKeys.md b/src/main/resources/assets/opencomputers/doc/en_US/item/arrowKeys.md index 2da1b1575..8357b596c 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/arrowKeys.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/arrowKeys.md @@ -2,4 +2,4 @@ ![Just be grateful it's not made from arrows.](oredict:oc:materialArrowKey) -At the risk of repeating myself: it's a button sink. Because the button economy has seen some serious inflation in recent years. +At the risk of repeating myself: it's a button sink. Because the button economy has seen some serious inflation in recent years. It is used as a component for building [keyboards](../block/keyboard.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/batteryUpgrade1.md b/src/main/resources/assets/opencomputers/doc/en_US/item/batteryUpgrade1.md index fc1b754d4..d1c06b34c 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/batteryUpgrade1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/batteryUpgrade1.md @@ -2,4 +2,4 @@ ![Made of Metal.](oredict:oc:batteryUpgrade1) -This upgrade increases the internal energy buffer of devices, such as [robots](../block/robot.md) and [tablets](tablet.md), allowing them to operate longer without having to return to a charger. +This upgrade increases the internal energy buffer of devices, such as [robots](../block/robot.md) and [tablets](tablet.md), allowing them to operate longer without having to return to a [charger](../block/charger.md). Higher tier battery upgrades can store more energy. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/buttonGroup.md b/src/main/resources/assets/opencomputers/doc/en_US/item/buttonGroup.md index 5d1976afc..373d7cdc3 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/buttonGroup.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/buttonGroup.md @@ -2,4 +2,4 @@ ![Needs more buttons.](oredict:oc:materialButtonGroup) -Because you *always* have too many buttons lying around somewhere. Don't lie. We all shift-click that button recipe time and again. +Because you *always* have too many buttons lying around somewhere. Don't lie. We all shift-click that button recipe time and again. Button groups are used to build [keyboards](../block/keyboard.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/card.md b/src/main/resources/assets/opencomputers/doc/en_US/item/card.md index 2dc2388e4..55c5021b7 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/card.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/card.md @@ -2,4 +2,4 @@ ![Can't be read.](oredict:oc:materialCard) -Common crafting material for most, if not all card components in OpenComputers. +Common crafting material for card components in OpenComputers (such as [graphics cards](graphicsCard1.md), [network cards](lanCard.md), etc). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/cardContainer1.md b/src/main/resources/assets/opencomputers/doc/en_US/item/cardContainer1.md index 39a9985b7..64698c7df 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/cardContainer1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/cardContainer1.md @@ -2,4 +2,4 @@ ![Can haz cards!](oredict:oc:cardContainer1) -The card container is a container type upgrade for [robots](../block/robot.md) that provides a slot in the finished robots into which cards can be placed. The tier of card that the slot can hold is equal to the tier of the container. Unlike normal upgrades, the complexity of containers is twice their tier. See [here](../block/robot.md) for details on robot complexity. +The card container is a container upgrade for [robots](../block/robot.md) allowing cards to be inserted/removed to/from [robots](../block/robot.md) on-the-fly. The maximum tier of card that the slot can hold is equal to the tier of the container. Unlike normal upgrades, the complexity of containers is twice their tier. See [here](../block/robot.md) for details on robot complexity. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/chamelium.md b/src/main/resources/assets/opencomputers/doc/en_US/item/chamelium.md index 1395ccea1..18fabca86 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/chamelium.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/chamelium.md @@ -2,8 +2,8 @@ ![From Chameleon, in case you were wondering.](oredict:oc:chamelium) -Chamelium is a shape-shifting material that is used when creating [3D prints](../block/print.md) in a [3D printer](../block/printer.md). On its own it is featureless and therefore very useful for creating simple, plain and monochrome areas. +Chamelium is a shape-shifting material that is used when creating [3D prints](../block/print.md) in a [3D printer](../block/printer.md). On its own, it is featureless and therefore very useful for creating simple, plain and monochrome areas. -You can also slap some of it together to create a [block of Chamelium](../block/chameliumBlock.md). +You can also combine them to create a [block of Chamelium](../block/chameliumBlock.md). -As the tooltip says, eating it can have severe side-effects, so consume with care. Or better yet, don't. +As the tooltip says, eating it can cause adverse side-effects, so consume with care. Or better yet, don't. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/chip1.md b/src/main/resources/assets/opencomputers/doc/en_US/item/chip1.md index 4f35fc69a..945b9a8d8 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/chip1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/chip1.md @@ -2,4 +2,4 @@ ![Not the edible ones.](oredict:oc:circuitChip1) -Microchips are the bread and butter of electronic component crafting. They come in different tiers, for the different tier of devices they're used to craft with. +Microchips are the bread and butter of electronic component crafting. They come in different tiers, for crafting different tiers of components. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/chunkloaderUpgrade.md b/src/main/resources/assets/opencomputers/doc/en_US/item/chunkloaderUpgrade.md index 10423ca54..7f7e8210b 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/chunkloaderUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/chunkloaderUpgrade.md @@ -2,6 +2,6 @@ ![Not going anywhere.](oredict:oc:chunkloaderUpgrade) -The chunk loader upgrade can be installed in devices to allow them to keep the chunk they are in - as well as the surrounding chunks - loaded. This consumes quite a bit of energy, however. The chunk loader can be turned on and off using the component exposed to the device. +The chunk loader upgrade can be installed in devices (such as [robots](../block/robot.md) and [microcontrollers](../block/microcontroller.md)) to allow them to keep the chunk they are in - as well as the surrounding chunks - loaded. This consumes energy, however. The chunk loader can be turned on and off using the component API exposed to the device. The upgrade is automatically enabled when the device powers up, and automatically disabled when the device powers down. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/circuitBoard.md b/src/main/resources/assets/opencomputers/doc/en_US/item/circuitBoard.md index 296274c2a..28ad8ecf7 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/circuitBoard.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/circuitBoard.md @@ -2,4 +2,4 @@ ![Needs more gold.](oredict:oc:materialCircuitBoard) -Intermediary crafting item made from [raw circuit boards](rawCircuitBoard.md) and used to make [printed circuit boards](printedCircuitBoard.md). +Intermediate crafting item made from [raw circuit boards](rawCircuitBoard.md) and used to make [printed circuit boards](printedCircuitBoard.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/componentBus1.md b/src/main/resources/assets/opencomputers/doc/en_US/item/componentBus1.md index 116c97a7c..b6d2990e3 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/componentBus1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/componentBus1.md @@ -2,7 +2,7 @@ ![I need mooooore.](oredict:oc:componentBus1) -A component bus is a [server](server1.md)-specific upgrade that allows the server to communicate with more components at the same time, without shutting down. Like with [CPUs](cpu1.md), higher tier buses provide higher component limits. Higher tier [servers](server1.md) are also capable of taking more component buses, allowing for communication with many more components. +A component bus is a [server](server1.md)-specific upgrade that allows the [server](server1.md) to communicate with more components at the same time, without shutting down. Like with [CPUs](cpu1.md), higher tier buses provide higher component limits. Higher tier [servers](server1.md) are also capable of taking more component buses, allowing for communication with many more components. The number of components each component bus allows access to is as follows: - Tier 1: 8 components. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/controlUnit.md b/src/main/resources/assets/opencomputers/doc/en_US/item/controlUnit.md index 63994adfb..8935aeb96 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/controlUnit.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/controlUnit.md @@ -2,4 +2,4 @@ ![With built-in cruise control.](oredict:oc:materialCU) -Higher tier crafting material used in more advanced circuitry, such as [CPUs](cpu1.md). +Higher tier crafting item used in more advanced circuitry, such as [CPUs](cpu1.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/cpu1.md b/src/main/resources/assets/opencomputers/doc/en_US/item/cpu1.md index fcea3b83b..7ff267394 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/cpu1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/cpu1.md @@ -2,13 +2,13 @@ ![Braaainz.](oredict:oc:cpu1) -The central processing unit is a core part for each [computer](../general/computer.md) or [server](server1.md). It defines the architecture of the computer, and the number of components that can be connected to the computer before it stops working. Higher tier CPUs also provide a higher per-tick direct call limit to the computer - in simpler terms: better CPUs run faster. +The central processing unit is a core part for each [computer](../general/computer.md) or [server](server1.md). It defines the architecture of the [computer](../general/computer.md), and the number of components that can be connected to the [computer](../general/computer.md) before it stops working. Higher tier CPUs also provide a higher per-tick direct call limit to the [computer](../general/computer.md) - in simpler terms: better CPUs run faster. The number of components that the CPU allows access to is as follows: - Tier 1: 8 components. - Tier 2: 12 components. - Tier 3: 16 components. -In servers, the number of supported components can be further increased by installing [component buses](componentBus1.md). +In [servers](server1.md), the number of supported components can be further increased by installing [component buses](componentBus1.md). -If more than the supported number of components are connected to a computer, it will no longer be able to start, and if it was running, it will crash. +If more than the supported number of components are connected to a [computer](../general/computer.md), it will no longer be able to start, and if it was running, it will crash. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/craftingUpgrade.md b/src/main/resources/assets/opencomputers/doc/en_US/item/craftingUpgrade.md index 5ff8f5a7c..43320ee5e 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/craftingUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/craftingUpgrade.md @@ -2,4 +2,4 @@ ![Crafty.](oredict:oc:craftingUpgrade) -The crafting upgrade allows [robots](../block/robot.md) to craft shaped and shapeless recipes using items in their [inventory](../item/inventoryUpgrade.md). When crafting, the top-left three by three grid in the [robot](../block/robot.md)'s [inventory](../item/inventoryUpgrade.md) is used as the crafting grid. Items have to be located as they would be in a normal crafting table. Results will be placed back into the [robot](../block/robot.md)'s [inventory](../item/inventoryUpgrade.md). As with picking up items, the result will be placed into the selected slot; failing to do so will place the item in the next available empty slot. If no inventory space remains, the result will be dropped into the world. +The crafting upgrade allows [robots](../block/robot.md) to craft shaped and shapeless recipes using items in their [inventory](../item/inventoryUpgrade.md). When crafting, the top-left 3x3 grid in the [robot](../block/robot.md)'s [inventory](../item/inventoryUpgrade.md) is used as the crafting grid. Items have to be arranged according to the recipe. Results will be placed back into the [robot](../block/robot.md)'s [inventory](../item/inventoryUpgrade.md). As with picking up items, the result will be placed into the selected slot; failing to do so will place the item in the next available empty slot. If no inventory space remains, the result will be dropped into the world. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/cuttingWire.md b/src/main/resources/assets/opencomputers/doc/en_US/item/cuttingWire.md index 045ec42f4..8f532bc68 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/cuttingWire.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/cuttingWire.md @@ -2,4 +2,4 @@ ![Not a garrote. Honest.](oredict:oc:materialCuttingWire) -You'll usually only encounter this when playing with the hard mode recipe set. In that case, this is used for crafting [raw circuit boards](rawCircuitBoard.md). Very inefficiently. +An item encountered when using hard-mode recipes, it is used for crafting [raw circuit boards](rawCircuitBoard.md). Very inefficiently. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/databaseUpgrade1.md b/src/main/resources/assets/opencomputers/doc/en_US/item/databaseUpgrade1.md index 3f212e4f9..ff4b4cfd5 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/databaseUpgrade1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/databaseUpgrade1.md @@ -4,6 +4,6 @@ The database upgrade can be configured to store a list of item stack representations, which can then be used by other components. This is particularly useful for items that are differentiated purely based on their NBT data, which is not part of the item stack descriptor returned by callbacks. -To configure a database, open it by right-clicking it while holding it in your hand, then placing the stacks you wish to configure it with into the top inventory. This will store a "ghost stack", i.e. no "real" items are stored in the database. +To configure a database, open it by right-clicking with the database in hand. Place the stacks you wish to configure it with into the top inventory. This will store a "ghost stack", i.e. no "real" items are stored in the database. -Alternatively the database can be configured automatically using [inventory controllers](inventoryControllerUpgrade.md) and [geolyzers](../block/geolyzer.md). +Alternatively the database can be configured automatically using the component API provided by [inventory controllers](inventoryControllerUpgrade.md) and [geolyzers](../block/geolyzer.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/debugCard.md b/src/main/resources/assets/opencomputers/doc/en_US/item/debugCard.md index 2c968c953..624803cac 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/debugCard.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/debugCard.md @@ -4,4 +4,4 @@ The debug card is a creative-only item that was originally only intended to make debugging things easier, by automating some processes. It has since gotten a bunch more functionality, making it quite useful for custom map-making. -Note that you can use sneak-activate while holding the card to bind it to you / unbind it, meaning `runCommand` will be performed using your permission levels instead of the default OpenComputers ones. +Note that you can use sneak-activate while holding the card to bind it to you or unbind it, meaning `runCommand` will be performed using your permission levels instead of the default OpenComputers ones. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/drone.md b/src/main/resources/assets/opencomputers/doc/en_US/item/drone.md index c85ede5b4..e639c1982 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/drone.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/drone.md @@ -2,4 +2,4 @@ ![Big brother is trying to watch you.](item:OpenComputers:item@84) -Drones are built using a [drone case](droneCase1.md) in the [assembler](../block/assembler.md). They are entity-based [robots](../block/robot.md), a little cheaper with limited functionality. They are also capable of moving differently and much quicker than robots, and are usually controlled using a client program on a computer. The drone will need a configured [EEPROM](eeprom.md) to listen for commands to be executed or act on its own. +Drones are built using a [drone case](droneCase1.md) in the [assembler](../block/assembler.md). They are entity-based [robots](../block/robot.md), a little cheaper with limited functionality. They are also capable of moving differently and much quicker than [robots](../block/robot.md), and are usually controlled using a client program on a [computer](../general/computer.md). The drone will need a configured [EEPROM](eeprom.md) to listen for commands to be executed or act on its own. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/droneCase1.md b/src/main/resources/assets/opencomputers/doc/en_US/item/droneCase1.md index 53245de54..3cb50e9f7 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/droneCase1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/droneCase1.md @@ -2,11 +2,11 @@ ![Droning on.](oredict:oc:droneCase1) -The drone case is used to build [drones](drone.md) in the [assembler](../block/assembler.md). Drones are light-weight, fast and very mobile machines with limited functionality (fewer upgrade and component slots available). Unlike [robots](../block/robot.md) they cannot use tools, and can interact with the world only in a relatively limited manner. +The drone case is used to build [drones](drone.md) in the [assembler](../block/assembler.md). [Drones](drone.md) are light-weight, fast and very mobile machines with limited functionality (fewer upgrade and component slots available). Unlike [robots](../block/robot.md) they cannot use tools, and can interact with the world only in a relatively limited manner. -They make up for their limitations with speed and lower running energy costs. They are well suited for transport of small amounts of items, and ideal for reconnaissance. Pairing a drone with a robot can be quite powerful, with the robot doing the "hard work", and the drone providing information about the environment and transporting items to and from a central hub, for example. +They make up for their limitations with speed and lower running energy costs. They are well suited for transport of small amounts of items, and ideal for reconnaissance. Pairing a [drone](drone.md) with a [robot](../block/robot.md) can be quite powerful, with the [robot](../block/robot.md) doing the "hard work", and the [drone](drone.md) providing information about the environment and transporting items to and from a central hub, for example. -Like [microcontrollers](../block/microcontroller.md), Drones can only be programmed using their [EEPROM](eeprom.md). Accordingly, the [EEPROM](eeprom.md) can be changed by crafting the drone with another [EEPROM](eeprom.md). +Like [microcontrollers](../block/microcontroller.md), [drones](drone.md) can only be programmed using their [EEPROM](eeprom.md). Accordingly, the [EEPROM](eeprom.md) can be changed by crafting the [drone](drone.md) with another [EEPROM](eeprom.md); the existing [EEPROM](eeprom.md) is return to the player's inventory. The tier 1 drone case is capable of taking the following components: - 1x tier 1 [CPU](cpu1.md) diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/floppy.md b/src/main/resources/assets/opencomputers/doc/en_US/item/floppy.md index 3ef79a3b0..ae6071955 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/floppy.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/floppy.md @@ -2,4 +2,4 @@ ![Many inches.](oredict:oc:floppy) -The floppy disk is the cheapest and smallest type of storage medium in OpenComputers. It is a handy early game way of storing data and transferring it between [computers](../general/computer.md) and [robots](../block/robot.md). You may also find floppy disks with useful programs on them in dungeon chests (OpenPrograms Package Manager is a good example, allowing easy install of programs from a central GitHub repository). +The floppy disk is the cheapest and smallest type of storage medium in OpenComputers. It is a handy early-game way of storing data and transferring it between [computers](../general/computer.md) and [robots](../block/robot.md). You may also find floppy disks with useful programs on them in dungeon chests (OpenPrograms Package Manager is a good example, allowing easy install of programs from a central GitHub repository). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/generatorUpgrade.md b/src/main/resources/assets/opencomputers/doc/en_US/item/generatorUpgrade.md index 2e7a2a756..27c5dca64 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/generatorUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/generatorUpgrade.md @@ -2,6 +2,6 @@ ![Generator X.](oredict:oc:generatorUpgrade) -The generator upgrade allows devices to refuel on the go. Currently it only supports solid fuels, such as coal. It has an internal inventory that can store one item stack of fuel. Surplus fuel can be removed from the generator using the according API method. When removing a generator upgrade from a robot, its contents will be dropped into the world. +The generator upgrade allows devices to re-fuel on the go. Currently it only supports solid fuels, such as coal. It has an internal inventory that can store one item stack of fuel. Surplus fuel can be removed from the generator using the appropriate component API method. When removing a generator upgrade from a [robot](../block/robot.md), its contents will be dropped into the world. -The efficiency of generators is lower than that of usual generators of other mods, meaning it is usually more fuel efficient to power devices using a [charger](../block/charger.md). +The efficiency of generators is lower than that of usual generators from other mods, meaning it is usually more fuel efficient to power devices using a [charger](../block/charger.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/graphicsCard1.md b/src/main/resources/assets/opencomputers/doc/en_US/item/graphicsCard1.md index 6f33dd64d..e72fc5c6c 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/graphicsCard1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/graphicsCard1.md @@ -4,4 +4,4 @@ The graphics card is an essential part for most [computers](../general/computer.md) and allows the [computer](../general/computer.md) to display text on a connected [screen](../block/screen1.md). Graphics cards come in several tiers, and like [screens](../block/screen1.md), support different resolutions and color depths. -Another noteworthy difference for the different graphics card tiers is the number of operations a graphics card can perform per tick. The values listed in the graphics cards' tooltip is representative for a [computer](../general/computer.md) with a tier two [CPU](cpu1.md). Tier one CPUs perform slightly slower, tier three CPUs slightly faster. The numbers listed are for the different operations provided by a GPU: `copy`, `fill`, `set`, `setBackground` and `setForeground`, respectively. +Another noteworthy difference for the different graphics card tiers is the number of operations a graphics card can perform per tick. The values listed in the graphics cards' tooltips are representative for a [computer](../general/computer.md) with a tier two [CPU](cpu1.md). Tier one CPUs perform slightly slower, tier three CPUs slightly faster. The numbers listed are for the different operations provided by a GPU: `copy`, `fill`, `set`, `setBackground` and `setForeground`, respectively. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/hdd1.md b/src/main/resources/assets/opencomputers/doc/en_US/item/hdd1.md index c00bce3e7..c873304a4 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/hdd1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/hdd1.md @@ -2,4 +2,4 @@ ![Spaaaace.](oredict:oc:hdd1) -The hard disk drives are the higher tier storage medium in OpenComputers. There are no speed differences in the storage media provided by OpenComputers, they only differ in the amount of disk space they provide. There are also some devices that can only use disk drives, no [floppies](floppy.md) (although servers could use an external [disk drive](../block/diskDrive.md), for example). Hard drives can be placed inside a [raid](../block/raid.md), allowing multiple drives to share the same file system. +The hard disk drives are a higher tier storage medium in OpenComputers. All storage media perform at the same speed; higher tier storage provides more space. There are also some devices that can only use disk drives (although servers could use an external [disk drive](../block/diskDrive.md), for example). Hard drives can be placed inside a [raid](../block/raid.md), allowing multiple drives to share the same file system. Note that placing a hard drive in a [raid](../block/raid.md) wipes the drive of its contents. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/index.md b/src/main/resources/assets/opencomputers/doc/en_US/item/index.md index c39217dc9..e8d54dc51 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/index.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/index.md @@ -19,7 +19,7 @@ Keep in mind that some of these may not be available, depending on the recipe se ## Components ### Cards -* [AbstractBusCard](abstractBusCard.md) +* [AbstractBus Card](abstractBusCard.md) * [Debug Card](debugCard.md) (aka AMI) * [Graphics Card](graphicsCard1.md) * [Internet Card](internetCard.md) @@ -61,8 +61,8 @@ Keep in mind that some of these may not be available, depending on the recipe se ## Crafting * [Acid](acid.md) * [ALU](alu.md) -* [ArrowKeys](arrowKeys.md) -* [ButtonGroup](buttonGroup.md) +* [Arrow Keys](arrowKeys.md) +* [Button Group](buttonGroup.md) * [Card](card.md) * [Circuit Board](circuitBoard.md) * [Control Unit](controlUnit.md) @@ -77,7 +77,7 @@ Keep in mind that some of these may not be available, depending on the recipe se # Assembling / Printing * [Chamelium](chamelium.md) -* [Drone Case](droneCase1.md) * [Ink Cartridge](inkCartridge.md) +* [Drone Case](droneCase1.md) * [Microcontroller Case](microcontrollerCase1.md) * [Tablet Case](tabletCase1.md) diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/inkCartridge.md b/src/main/resources/assets/opencomputers/doc/en_US/item/inkCartridge.md index 7f7c5013b..14ae30e03 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/inkCartridge.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/inkCartridge.md @@ -2,4 +2,4 @@ ![The colors of the rainbow.](oredict:oc:inkCartridge) -Ink cartridges come in handy when refilling the color buffer of [3D printers](../block/printer.md). While it is also possible to refill them using dyes directly, this is messy and very inefficient, so it is strongly recommended to invest into a real OC Ink Cartridge (TM), today! +Ink cartridges come in handy when refilling the color buffer of [3D printers](../block/printer.md). While it is also possible to refill them using dyes directly, this is messy and very inefficient. It is strongly recommended to invest into a real OC Ink Cartridge (TM), today! (Disclaimer: they may or may cost more than the printer itself). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/internetCard.md b/src/main/resources/assets/opencomputers/doc/en_US/item/internetCard.md index 02cffa752..fa80e6d7f 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/internetCard.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/internetCard.md @@ -4,4 +4,4 @@ The internet card grants [computers](../general/computer.md) access to the internet. It provides ways to perform simple HTTP requests, as well as to open plain TCP client sockets that can be read and written to. -Installing an internet card in a [computers](../general/computer.md) will also attach a custom file system that contains a few internet related applications, such as one for downloading and uploading snippets from and to pastebin as well as a wannabe `wget` clone that allows downloading data from arbitrary HTTP URLs. +Installing an internet card in a [computers](../general/computer.md) will also attach a custom file system that contains a few internet related applications, such as one for downloading and uploading snippets from/to pastebin as well as a `wget` clone that allows downloading data from arbitrary HTTP URLs. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/inventoryControllerUpgrade.md b/src/main/resources/assets/opencomputers/doc/en_US/item/inventoryControllerUpgrade.md index a85f41e5d..c5f8edbae 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/inventoryControllerUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/inventoryControllerUpgrade.md @@ -2,6 +2,6 @@ ![I'm in control.](oredict:oc:inventoryControllerUpgrade) -The inventory controller upgrade provides extended inventory interaction to [robots](../block/robot.md) and [drones](drone.md). It allows the device to explicitly target slots in external inventories when dropping or sucking items. It also allows devices to read detailed information about item stacks. Lastly it provides robots with a means to change their equipped tool without external help. +The inventory controller upgrade provides extended inventory interaction to [robots](../block/robot.md) and [drones](drone.md). It allows the device to explicitly target slots in external inventories when dropping or sucking items. It also allows devices to read detailed information about item stacks. Lastly it provides [robots](../block/robot.md) with a means to change their equipped tool without external help. -This upgrade can also be placed in [adapters](../block/adapter.md), where it provides similar inspection methods for inventories adjacent to the adapter as it does to the robot. It does not allow the adapter to move items into or out of inventories, however. This feature is only available in [robots](../block/robot.md) and [drones](drone.md). +This upgrade can also be placed in [adapters](../block/adapter.md), where it provides similar inspection methods for inventories adjacent to the [adapter](../block/adapter.md) as it does to the [robot](../block/robot.md). It does not allow the [adapter](../block/adapter.md) to move items into or out of inventories, however. This feature is only available to [robots](../block/robot.md) and [drones](drone.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/inventoryUpgrade.md b/src/main/resources/assets/opencomputers/doc/en_US/item/inventoryUpgrade.md index 45a886e67..a451f184c 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/inventoryUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/inventoryUpgrade.md @@ -2,6 +2,6 @@ ![Where does it keep all this stuff...](oredict:oc:inventoryUpgrade) -The inventory upgrade provides inventory slots to [robots](../block/robot.md) and [drones](drone.md). For each inventory upgrade a robot will gain an addition 16 inventory slots, up to a maximum of 64 slots in total; a drone will gain 4 slots per upgrade, up to a maximum of 8 slots in total. +The inventory upgrade provides inventory slots to [robots](../block/robot.md) and [drones](drone.md). For each inventory upgrade a [robot](../block/robot.md) will gain an addition 16 inventory slots, up to a maximum of 64 slots in total; a [drone](drone.md) will gain 4 slots per upgrade, up to a total of 8 slots. If no inventory upgrade is installed in a device it will not be able to store or pick up items. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/lanCard.md b/src/main/resources/assets/opencomputers/doc/en_US/item/lanCard.md index ba368cdf7..3fbd8a6c4 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/lanCard.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/lanCard.md @@ -2,4 +2,4 @@ ![Enter the network.](oredict:oc:lanCard) -The network card allows computers to send and receive network messages. Such messages (or packets) can be either sent as a broadcast, in which case they will be sent to all nodes in the same subnetwork, or sent to specific target, in which case they will only be received by the node with the specified target address. [Switches](../block/switch.md) and [access points](../block/accessPoint.md) can be used to bridge multiple subnetworks by relaying messages between the subnetworks they are connected to. It is also possible to send a targeted message if the receiver is in another subnetwork, if the networks are connected via one or more [switches](../block/switch.md). +The network card allows [computers](../general/computer.md) to send and receive network messages. Messages (or packets) can be broadcasted to all receiving nodes in a subnetwork, or sent to a specific node with a specified address. [Switches](../block/switch.md) and [access points](../block/accessPoint.md) can be used to bridge multiple subnetworks by relaying messages between the subnetworks they are connected to. It is also possible to send a targeted message if the receiver is in another subnetwork, if the networks are connected via one or more [switches](../block/switch.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/linkedCard.md b/src/main/resources/assets/opencomputers/doc/en_US/item/linkedCard.md index 7244a3d20..ec3dc820c 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/linkedCard.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/linkedCard.md @@ -2,4 +2,4 @@ ![I feel we some kind of connection.](oredict:oc:linkedCard) -The linked card is a specialized but advanced version of a [network card](lanCard.md). It can only operate in pairs, providing a point-to-point communication between the paired cards. In return, the distance the cards can communicate over is unlimited. They can even communicate across dimensions. +The linked card is a specialized but advanced version of a [network card](lanCard.md). It can only operate in pairs, providing a point-to-point communication between the paired cards. Linked cards can communicate over large (unlimited) distances and across dimensions. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/manual.md b/src/main/resources/assets/opencomputers/doc/en_US/item/manual.md index 9a01e1dcb..f7df60427 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/manual.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/manual.md @@ -8,8 +8,8 @@ The thing you're reading right now! The manual contains a wealth of information Navigating the manual is similar to browsing a wiki: click on links (1) to follow them to the page they reference. Right-click or press the jump key to go back one page. Press escape or the inventory key to close the manual. To the left you will find a few tabs (2) that provide a way to quickly jump to select pages, such as the block and item index. To the right you will find the scroll bar (3). You can either drag it manually, or use the mouse wheel to scroll in a page. -When opening the manual again at a later point, you will return to the page you were on when you closed it. You can start over on the main index page by using it while sneaking. It is also possible to directly jump to a page concerning a block in the world by using the block while sneaking with the manual in hand. +The manual will remember the page where you last left off, when re-opening it. You can start over on the main index page by using it while sneaking. It is also possible to directly jump to a page concerning a block in the world by shift-right clicking the block with the manual in hand. If your questions are not answered by the manual, other places with information are [the wiki](http://ocdoc.cil.li), OpenComputers' [IRC channel](http://webchat.esper.net/?channels=#oc) and [the forums](http://oc.cil.li/). -If you spot any mistakes in the manual, factual, grammatical or otherwise, or bugs in the mod, for that matter, please let us know [via the issue tracker](https://github.com/MightyPirates/OpenComputers/issues). If you'd like to contribute to the manual by adding content, get in touch via IRC or by creating a ticket on the issue tracker. +If you spot any mistakes in the manual, factual, grammatical or otherwise; or bugs in the mod, for that matter, please let us know [via the issue tracker](https://github.com/MightyPirates/OpenComputers/issues). If you'd like to contribute to the manual by adding content, get in touch via IRC or by creating a ticket on the issue tracker. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/microcontrollerCase1.md b/src/main/resources/assets/opencomputers/doc/en_US/item/microcontrollerCase1.md index cc1359d8d..92045902b 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/microcontrollerCase1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/microcontrollerCase1.md @@ -2,9 +2,9 @@ ![It's so cute.](oredict:oc:microcontrollerCase1) -The microcontroller Case is the base part when building [microcontrollers](../block/microcontroller.md) in the [assembler](../block/assembler.md). Microcontrollers are very primitive computers. They may only contain a very limited number of components, and are intended to be used in very specific use-cases, such as transforming or reacting to redstone signals, or processing network messages. +The Microcontroller case is the base part when building [microcontrollers](../block/microcontroller.md) in the [assembler](../block/assembler.md). [Microcontrollers](../block/microcontroller.md) are very primitive [computers](../general/computer.md). They may only contain a very limited number of components, and are intended to be used in very specific use-cases, such as transforming or reacting to redstone signals, or processing network messages. -They do not have an actual file system. All programming must be done using the [EEPROM](eeprom.md) chip built into them. This chip can be swapped for another one by crafting a microcontroller with the chip to insert. The old [EEPROM](eeprom.md) will be returned to your inventory. +They do not have an actual file system. All programming must be done using the [EEPROM](eeprom.md) chip built into them. This chip can be swapped for another one by crafting a [microcontrollers](../block/microcontroller.md) with the chip to insert. The old [EEPROM](eeprom.md) will be returned to your inventory. While they also require power to run, they consume very little energy. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/navigationUpgrade.md b/src/main/resources/assets/opencomputers/doc/en_US/item/navigationUpgrade.md index 26e11f42b..ff513fdb6 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/navigationUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/navigationUpgrade.md @@ -4,4 +4,4 @@ The navigation upgrade provides location and orientation information to devices it is installed in. The coordinates the upgrade provides are relative to the center of the map that was used to craft the upgrade, and the functional range is based on the size of that map. -Navigation upgrades can be re-crafted with a map to replace the map in the upgrade with another one. The old map will be returned. +The map inside a Navigation upgrade can be changed by re-crafting the upgrade with a new map. The old map will be returned to the player. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/numPad.md b/src/main/resources/assets/opencomputers/doc/en_US/item/numPad.md index 5b3b75877..05ff6ade7 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/numPad.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/numPad.md @@ -2,4 +2,4 @@ ![Check for fingerprints.](oredict:oc:materialNumPad) -The numeric keypad is part of every [keyboard](../block/keyboard.md). I allows you to enter numbers. I'm seriously running out of ideas of what to write here... +The Numeric keypad is part of every [keyboard](../block/keyboard.md). It allows you to enter numbers. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/pistonUpgrade.md b/src/main/resources/assets/opencomputers/doc/en_US/item/pistonUpgrade.md index 28e91eb2b..269f4825a 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/pistonUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/pistonUpgrade.md @@ -2,6 +2,6 @@ ![Push it.](oredict:oc:pistonUpgrade) -The piston upgrade allows some devices to act very much like a vanilla piston. When installed, a component with a single method, `push()`, becomes available. When called the device will then try to push the block in its forward facing direction. For example, for [robots](../block/robot.md) this is their facing, for [tablets](tablet.md) it's the player's facing, for [microcontrollers](../block/microcontroller.md) it is their facing. +The piston upgrade allows some devices to act very much like a vanilla piston. When installed, a component with a single method, `push()`, becomes available. When called the device will then try to push the block in its forward facing direction. For [robots](../block/robot.md) and [microcontrollers](../block/microcontroller.md), this is the front face; for [tablets](tablet.md), it will use the player's facing direction. The logic for pushing follows the same rules as vanilla pistons. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/ram1.md b/src/main/resources/assets/opencomputers/doc/en_US/item/ram1.md index 80aa836d8..cd54adc4e 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/ram1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/ram1.md @@ -2,7 +2,7 @@ ![Do you remember, dancing in September~](oredict:oc:ram1) -Memory is, like the [CPU](cpu1.md), an essential part in all [computers](../general/computer.md). Depending on the CPU's architecture, the memory has a very essential effect on what a computer can and cannot do. For the standard Lua architecture, for example, it controls the actual amount of memory Lua scripts can use. This means that to run larger and more memory-intensive programs, you will need more RAM. +Memory is, like the [CPU](cpu1.md), an essential part in all [computers](../general/computer.md). Depending on the [CPU](cpu1.md)'s architecture, the memory has a very essential effect on what a [computer](../general/computer.md) can and cannot do. For the standard Lua architecture, for example, it controls the actual amount of memory Lua scripts can use. This means that to run larger and more memory-intensive programs, you will need more memory. RAM is available in multiple tiers with the following capacities, by default: - Tier 1: 192KB @@ -12,6 +12,6 @@ RAM is available in multiple tiers with the following capacities, by default: - Tier 3: 768KB - Tier 3.5: 1024KB -Note that these values only apply to the Lua architecture. Other architectures may provide different amounts of memory for the different tiers. +Note that these values only apply to the Lua architecture. Other architectures may provide different amounts of memory for the different tiers. Also note that tier 1 and 1.5 memory are both considered tier 1 memory, and similarly for tier 2 and 3 memory. The values can be changed in the configuration, if so desired. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/rawCircuitBoard.md b/src/main/resources/assets/opencomputers/doc/en_US/item/rawCircuitBoard.md index e6fcc56ea..ac00250ea 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/rawCircuitBoard.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/rawCircuitBoard.md @@ -2,4 +2,4 @@ ![Not sushi.](oredict:oc:materialCircuitBoardRaw) -Intermediary crafting material, used for crafting [circuit boards](circuitBoard.md) (or [printed circuit boards](printedCircuitBoard.md), depending on the recipe set you use). +Intermediary crafting material, used for crafting [circuit boards](circuitBoard.md) (or [printed circuit boards](printedCircuitBoard.md), depending on the recipe set being used). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/redstoneCard1.md b/src/main/resources/assets/opencomputers/doc/en_US/item/redstoneCard1.md index 622ef3828..58abd2b89 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/redstoneCard1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/redstoneCard1.md @@ -2,8 +2,8 @@ ![Seeing red.](oredict:oc:redstoneCard1) -The redstone card allows computers to read and emit analog redstone signal in adjacent blocks. When an incoming signal strength changes, a signal is injected into the computer. +The redstone card allows [computers](../general/computer.md) to read and emit analog redstone signal in adjacent blocks. When an incoming signal strength changes, a signal is injected into the [computer](../general/computer.md). -If there are any supported mods present that provide bundled redstone facilities, such as RedLogic, Project Red or MineFactory Reloaded, or mods that provide wireless redstone facilities such as WR-CBE and Slimevoid's Wireless mod, a second tier card is available that allows interacting with these systems. +If there are any supported mods present that provide bundled redstone facilities, such as RedLogic, Project Red or MineFactory Reloaded; or mods that provide wireless redstone facilities such as WR-CBE and Slimevoid's Wireless mod, a second tier card is available that allows interacting with these systems. The side provided to the several methods are relative to the orientation of the [computer case](../block/case1.md) / [robot](../block/robot.md) / [server rack](../block/serverRack.md). That means when looking at the front of the computer, `sides.right` is at your left and vice versa. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/server1.md b/src/main/resources/assets/opencomputers/doc/en_US/item/server1.md index acc755737..ca70f62fb 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/server1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/server1.md @@ -2,7 +2,7 @@ ![Serves u right.](oredict:oc:server1) -Servers are a form of higher tier [computer](../general/computer.md). They can be configured by holding them in the hand and using them - like opening a backpack or ender pouch, for example. After inserting a [CPU](cpu1.md), [memory](ram1.md) and Expansion cards, the server has to be placed inside a [server rack](../block/serverRack.md). For more information see the server rack entry. +Servers are a form of higher tier [computer](../general/computer.md). They can be configured by holding them in the hand and using them - like opening a backpack or Ender pouch, for example. After inserting a [CPU](cpu1.md), [memory](ram1.md) and Expansion cards, the server has to be placed inside a [server rack](../block/serverRack.md). For more information see the [server rack](../block/serverRack.md) entry. The tier 1 server is capable of taking the following components: - 1x tier 2 [CPU](cpu2.md) diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/signUpgrade.md b/src/main/resources/assets/opencomputers/doc/en_US/item/signUpgrade.md index 5d0b9a4f2..944bd24b6 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/signUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/signUpgrade.md @@ -2,4 +2,4 @@ ![I see the signs on the wall.](oredict:oc:signUpgrade) -This upgrade allows devices to interact with signs in the world. It allows reading the message currently being displayed on a sign, as well as setting that message to something else (unless some permission system blocks it). +This upgrade allows devices to interact with signs in the world. It allows reading the current message on the sign as well as changing the message on the sign (if permitted. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/solarGeneratorUpgrade.md b/src/main/resources/assets/opencomputers/doc/en_US/item/solarGeneratorUpgrade.md index 0f8e4e7ba..6740d5e69 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/solarGeneratorUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/solarGeneratorUpgrade.md @@ -2,6 +2,6 @@ ![Walking on the sun.](oredict:oc:solarGeneratorUpgrade) -The solar generator upgrade can be installed in devices such as [robots](../block/robot.md), [drones](drone.md) and [tablets](tablet.md) to passively generate energy. It will only work while the device is standing in the sun, i.e. it is day and there is no block between the device and the sky above it. +The solar generator upgrade can be installed in devices such as [robots](../block/robot.md), [drones](drone.md) and [tablets](tablet.md) to passively generate energy. It will only work while the device is exposed to direct sunlight; a device in an enclosed area or an area affected by weather will not generate energy. -The amount of energy generated is relatively small, but it should be enough to prolong the time needed between recharges, if not avoid them altogether. +The amount of energy generated is relatively small, but it should be enough to prolong the time needed between [recharges](../block/charger.md), if not avoid them altogether. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/tablet.md b/src/main/resources/assets/opencomputers/doc/en_US/item/tablet.md index 7515e9e2c..eab94a816 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/tablet.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/tablet.md @@ -4,10 +4,10 @@ Tablets are built by placing a [tablet case](tabletCase1.md) into an [assembler](../block/assembler.md), configuring as desired and assembling it. Tablets act as portable computers that cannot directly interact with the world - for example, basic [redstone cards](redstoneCard1.md) do not work in them. A number of upgrades do, such as the [sign i/o](signUpgrade.md) upgrade or the [piston](pistonUpgrade.md) upgrade. -The tier 2 tablet also allows installing a single container upgrade. The slot provided by the container can be accessed by opening the tablet's alternative GUI, by using it while sneaking. This will also forcibly shut-down the tablet. +The tier 2 tablet also allows installing a single container upgrade. The slot provided by the container can be accessed by opening the tablet's alternative GUI, by shift-right clicking with the tablet in hand. This will also forcibly shut down the tablet. -Unlike computers, tablets do not persist across the player holding it leaving and re-entering the game. They also do not persist across the player holding the tablet changing dimensions (e.g. going to the Nether or back). +Unlike computers, tablets do not persist across the player holding it leaving and re-entering the game. They also do not persist across dimensions (such as a player going to the Nether and back). -Tablets can be put into a [charger](../block/charger.md) to refill their energy, and to access the first [hard drive](hdd1.md) built into the tablet from a [computer](../general/computer.md) connected to the charger - in this setup, the charger will act similar to a [disk drive](../block/diskDrive.md), with the tablet being the [floppy disk](floppy.md). This can be very useful in case you forgot to install an OS on the hard drive built into the tablet, or after bricking a tablet's OS. +Tablets can be put into a [charger](../block/charger.md) to refill their energy, and to access the first [hard drive](hdd1.md) in the tablet from a [computer](../general/computer.md) connected to the charger - in this setup, the charger will behave similar to a [disk drive](../block/diskDrive.md), with the tablet being the [floppy disk](floppy.md). This can be very useful in case you forgot to install an OS on the hard drive built into the tablet, or after bricking a tablet's OS. -Another advanced feature of the tablet is its ability to generate signals with information about certain blocks in the world, by using it on a block in the world for about one second (e.g. keep the right mouse button pressed). A short beep tone will notify you that the signal was generated. This only works if upgrades are installed in the tablet that populate the signal with information. For example, the [geolyzer](../block/geolyzer.md) will add information about the block itself, such as its hardness, the [navigation upgrade](navigationUpgrade.md) will add the coordinates of the block relative to the player holding the tablet. You will see which block will be analyzed by the green overlay that will be displayed while targeting it when holding the tablet. +Another advanced feature of the tablet is its ability to generate signals with information about certain blocks in the world, by using it on a block in the world for about one second (e.g. keep the right mouse button pressed). A short beep tone will notify you that the signal was generated. This only works if upgrades are installed in the tablet that populate the signal with information. For example, the [geolyzer](../block/geolyzer.md) will add information about the block itself, such as its hardness, the [navigation upgrade](navigationUpgrade.md) will add the coordinates of the block relative to the player holding the tablet. The block to be analyzed will be highlighted with a green overlay while holding the tablet. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/tabletCase1.md b/src/main/resources/assets/opencomputers/doc/en_US/item/tabletCase1.md index 6ef3fcd81..923c02aac 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/tabletCase1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/tabletCase1.md @@ -2,11 +2,11 @@ ![Doesn't bend.](oredict:oc:tabletCase1) -The tablet case is the base part when building [tablets](tablet.md) in the [assembler](../block/assembler.md). Tablets are very compact and portable computers. They can host a small number of select upgrades, but obviously cannot interact with the world like [computer cases](../block/case1.md) can (using simple [network cards](lanCard.md) or [redstone cards](redstoneCard1.md) for example). +The tablet case is the base part when building [tablets](tablet.md) in the [assembler](../block/assembler.md). [Tablets](tablet.md) are very compact and portable [computers](../general/computer.md). They can host a small number of select upgrades, but cannot interact with the world like [computer cases](../block/case1.md) can (using simple [network cards](lanCard.md) or [redstone cards](redstoneCard1.md) for example). -Upgrades and cards that cannot be used in tablets can generally not be placed into the assembler, so if you can install an upgrade, you can usually assume that you will also be able to use it. +Upgrades and cards that cannot be used in [tablets](tablet.md) cannot be placed in the [assembler](../block/assembler.md). If an upgrade can be placed in the [assembler](../block/assembler.md), it will be available for use through the component API. -They must also remain in a player's inventory to continue running. When dropped or placed into some other inventory, they will turn off after a short amount of time. +They must also remain in a player's inventory to continue running. When dropped or placed into another inventory, they will turn off after a short amount of time. The tier 1 tablet case can hold the following components: - 1x [CPU (tier 2)](cpu2.md) diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/terminal.md b/src/main/resources/assets/opencomputers/doc/en_US/item/terminal.md index 95bd4a22f..b511360f3 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/terminal.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/terminal.md @@ -2,7 +2,7 @@ ![Remote access.](oredict:oc:terminal) -The remote terminal can be used to remote control [servers](server1.md). To use it, sneak-activate a server that is installed in a [server rack](../block/serverRack.md) (click on the [server rack](../block/serverRack.md) block in the world, targeting the [server](server1.md) to bind the terminal to). +The remote terminal can be used to remotely control [servers](server1.md). To use it, sneak-activate a server that is installed in a [server rack](../block/serverRack.md) (click on the [server rack](../block/serverRack.md) block in the world, targeting the [server](server1.md) to bind the terminal to). When a terminal is bound to a [server](server1.md), a virtual [screen](../block/screen1.md) and [keyboard](../block/keyboard.md) get connected to the server. This can lead to unexpected behavior if another real screen and/or keyboard is connected to the server, so this should be avoided. When using the terminal in hand after binding it, a GUI will open in the same manner as a [keyboard](../block/keyboard.md) attached to a [screen](../block/screen1.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/texturePicker.md b/src/main/resources/assets/opencomputers/doc/en_US/item/texturePicker.md index 31c944d66..9a3e183fb 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/texturePicker.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/texturePicker.md @@ -2,6 +2,6 @@ ![What do you mean, it's just a re-skin?](oredict:oc:texturePicker) -The texture picker is very useful when you're making models for your [3D printer](../block/printer.md). It allows getting the texture name of textures used by blocks in the world, simply by (sneak-)activate them with the tool. Disclaimer: for blocks that use special rendering, such as chests, this may not work. +The texture picker is very useful when making models for your [3D printer](../block/printer.md). It allows getting the texture name of textures used by blocks in the world, simply by (sneak-)activating them with the tool. Disclaimer: for blocks that use special rendering, such as chests, this may not work. While this is handy for quickly looking up texture names, it is good to know that you are not limited to the textures that can be picked with the analyzer. As long as you know the name of a texture (and it is a *block* texture), you can use it in your [3D prints](../block/print.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/upgradeContainer1.md b/src/main/resources/assets/opencomputers/doc/en_US/item/upgradeContainer1.md index b585e93e6..2a704973a 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/upgradeContainer1.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/upgradeContainer1.md @@ -2,4 +2,4 @@ ![Can haz upgrade.](oredict:oc:upgradeContainer1) -The upgrade container is a container type upgrade for [robots](../block/robot.md), that provides a slot in the finished [robots](../block/robot.md) into which normal upgrades can be placed. The tier of upgrade that slot can hold is equal to the tier of the container. Unlike normal upgrades, the complexity of containers is twice their tier. Refer to [robot](../block/robot.md) and [assembler](../block/assembler.md) documentation on complexity. +The upgrade container is a container type upgrade for [robots](../block/robot.md), that provides a slot in the finished [robots](../block/robot.md) into which normal upgrades can be placed. The maximum tier of upgrade that slot can hold is equal to the tier of the container. Unlike normal upgrades, the complexity of containers is twice their tier. Refer to [robot](../block/robot.md) and [assembler](../block/assembler.md) documentation on complexity. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/wlanCard.md b/src/main/resources/assets/opencomputers/doc/en_US/item/wlanCard.md index d4543b513..9404851cb 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/wlanCard.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/wlanCard.md @@ -2,6 +2,6 @@ ![May cause cancer. May not.](oredict:oc:wlanCard) -The wireless network card is an upgraded [network card](lanCard.md) that, in addition to wired network messages, can also send and receive wireless network messages. The signal strength directly controls the distance up to which a sent message can be received, where the strength is equal to that distance in blocks. +The wireless network card is an upgraded [network card](lanCard.md) that, in addition to wired network messages, can also send and receive wireless network messages. The signal strength directly controls the distance up to which a sent message can be received, where the strength is equal to the distance in blocks. -The higher the signal strength, the more energy it will take to send a single message. The terrain between the sender and receiver also determines whether a message will be successfully transmitted or not. To penetrate a block, the blocks hardness is subtracted from the signal strength - with the minimum being one for air blocks. If no strength remains to reach the receiver, the message will not be received. This is not an exact science however - sometimes messages may still reach the target. In general you will want to make sure the line of sight between the sender and receiver are clear. +The higher the signal strength, the more energy it will take to send a single message. The terrain between the sender and receiver also determines whether a message will be successfully transmitted or not. To penetrate a block, the blocks hardness is subtracted from the signal strength - with the minimum being one for air blocks. If no strength remains to reach the receiver, the message will not be received. This is not an exact science however - sometimes messages may still reach the target. In general you will want to make sure the line of sight between the sender and receiver is clear. diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/wrench.md b/src/main/resources/assets/opencomputers/doc/en_US/item/wrench.md index 56dc2676e..b26d7922e 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/wrench.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/wrench.md @@ -2,4 +2,4 @@ ![Made in Swiss.](oredict:oc:wrench) -Like pretty much any other technology-focused mod, OpenComputers has it's own version of a wrench tool. In this case it's a hybrid of a screwdriver and a wrench, that looks like it's incredibly awkward to use. It can be used to rotate most blocks, and is also compatible with most other mods' blocks that can be interacted with by using wrench-like tools. +Like pretty much any other technology-focused mod, OpenComputers has it's own version of a wrench tool. In this case, it is a hybrid of a screwdriver and a wrench, that looks like it's incredibly awkward to use. It can be used to rotate most blocks, and is also compatible with most other mods' blocks that can be interacted with by using wrench-like tools. From cefe7f4f00ee26a8087f90400105a5d6eadf4a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Tue, 14 Apr 2015 10:54:40 +0200 Subject: [PATCH 16/37] Made speed of gpu.setPaletteColor depend on GPU tier and made it a lot faster. Better recipe for OPPM disk. --- .../assets/opencomputers/recipes/default.recipes | 2 +- .../li/cil/oc/server/component/GraphicsCard.scala | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/resources/assets/opencomputers/recipes/default.recipes b/src/main/resources/assets/opencomputers/recipes/default.recipes index 755a133f1..562a20e63 100644 --- a/src/main/resources/assets/opencomputers/recipes/default.recipes +++ b/src/main/resources/assets/opencomputers/recipes/default.recipes @@ -29,7 +29,7 @@ lootDisks: [ { name: OPPM type: shapeless - input: ["oc:floppy", "oc:internetCard"] + input: ["oc:floppy", "oc:materialInterweb"] } ] luaBios { diff --git a/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala b/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala index dc82aea6a..4ad804a3b 100644 --- a/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala +++ b/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala @@ -128,7 +128,6 @@ abstract class GraphicsCard extends prefab.ManagedEnvironment { }) } - @Callback(doc = """function(index:number, color:number):number -- Set the palette color at the specified palette index. Returns the previous value.""") def setPaletteColor(context: Context, args: Arguments): Array[AnyRef] = { val index = args.checkInteger(0) val color = args.checkInteger(1) @@ -380,6 +379,9 @@ object GraphicsCard { @Callback(direct = true, limit = 32, doc = """function(value:number[, palette:boolean]):number, number or nil -- Sets the foreground color to the specified value. Optionally takes an explicit palette index. Returns the old value and if it was from the palette its palette index.""") override def setForeground(context: Context, args: Arguments) = super.setForeground(context, args) + + @Callback(direct = true, limit = 2, doc = """function(index:number, color:number):number -- Set the palette color at the specified palette index. Returns the previous value.""") + override def setPaletteColor(context: Context, args: Arguments): Array[AnyRef] = super.setPaletteColor(context, args) } class Tier2 extends GraphicsCard { @@ -400,6 +402,9 @@ object GraphicsCard { @Callback(direct = true, limit = 64, doc = """function(value:number[, palette:boolean]):number, number or nil -- Sets the foreground color to the specified value. Optionally takes an explicit palette index. Returns the old value and if it was from the palette its palette index.""") override def setForeground(context: Context, args: Arguments) = super.setForeground(context, args) + + @Callback(direct = true, limit = 8, doc = """function(index:number, color:number):number -- Set the palette color at the specified palette index. Returns the previous value.""") + override def setPaletteColor(context: Context, args: Arguments): Array[AnyRef] = super.setPaletteColor(context, args) } class Tier3 extends GraphicsCard { @@ -420,6 +425,9 @@ object GraphicsCard { @Callback(direct = true, limit = 128, doc = """function(value:number[, palette:boolean]):number, number or nil -- Sets the foreground color to the specified value. Optionally takes an explicit palette index. Returns the old value and if it was from the palette its palette index.""") override def setForeground(context: Context, args: Arguments) = super.setForeground(context, args) + + @Callback(direct = true, limit = 16, doc = """function(index:number, color:number):number -- Set the palette color at the specified palette index. Returns the previous value.""") + override def setPaletteColor(context: Context, args: Arguments): Array[AnyRef] = super.setPaletteColor(context, args) } -} \ No newline at end of file +} From 531e5847d0593ec2c8c77b260c0078a313450367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Tue, 14 Apr 2015 12:50:37 +0200 Subject: [PATCH 17/37] Fixed chamelium blocks being registered breaking mipmaps. Closes #1061. --- .../li/cil/oc/api/manual/ImageRenderer.java | 4 ++-- .../opencomputers/textures/blocks/White.png | Bin 109 -> 132 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/li/cil/oc/api/manual/ImageRenderer.java b/src/main/java/li/cil/oc/api/manual/ImageRenderer.java index 19aa4fb15..2dcad21f7 100644 --- a/src/main/java/li/cil/oc/api/manual/ImageRenderer.java +++ b/src/main/java/li/cil/oc/api/manual/ImageRenderer.java @@ -15,7 +15,7 @@ public interface ImageRenderer { * The width of the area this renderer uses. *

* This is used to offset the OpenGL state properly before calling - * {@link #render()}, to correctly align the image horizontally. + * {@link #render(int, int)}, to correctly align the image horizontally. * * @return the width of the rendered image. */ @@ -25,7 +25,7 @@ public interface ImageRenderer { * The height of the area this renderer uses. *

* This is used to offset the OpenGL state properly before calling - * {@link #render()}, as well as to know where to resume rendering + * {@link #render(int, int)}, as well as to know where to resume rendering * other content below the image. * * @return the height of the rendered image. diff --git a/src/main/resources/assets/opencomputers/textures/blocks/White.png b/src/main/resources/assets/opencomputers/textures/blocks/White.png index b9d310c9103991a26764dacab462ca493ced76e7..a48258bff29fa740c61a91eadfb0cb48ab2da4b5 100644 GIT binary patch delta 100 zcmd08VN~o4@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRCFVdQ&MBb@0J(1)NB{r; delta 77 zcmZo+%vJ0R@N?(olHy`uVBq!ia0vp^j3CUx1SBVv2j82hsG-8|>EaktaVzP^|Nr(5 b4U7z||Cs*ip6h%ERKnot>gTe~DWM4ftYQ^) From 85a07e4a3c5cc0bb8a9071d67c243d7566c77d92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Tue, 14 Apr 2015 14:21:41 +0200 Subject: [PATCH 18/37] Header levels. --- .../resources/assets/opencomputers/doc/en_US/block/index.md | 2 +- src/main/resources/assets/opencomputers/doc/en_US/item/index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/index.md b/src/main/resources/assets/opencomputers/doc/en_US/block/index.md index fe19c3fdf..19b3d670b 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/index.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/index.md @@ -28,7 +28,7 @@ Keep in mind that some of these may not be available, depending on the recipe se * [Motion Sensor](motionSensor.md) * [Redstone I/O](redstone.md) -### Assembly / Printing +## Assembly / Printing * [3D Print](print.md) * [3D Printer](printer.md) * [Assembler](assembler.md) diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/index.md b/src/main/resources/assets/opencomputers/doc/en_US/item/index.md index e8d54dc51..2c99c303e 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/item/index.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/item/index.md @@ -75,7 +75,7 @@ Keep in mind that some of these may not be available, depending on the recipe se * [Raw Circuit Board](rawCircuitBoard.md) * [Transistor](transistor.md) -# Assembling / Printing +## Assembling / Printing * [Chamelium](chamelium.md) * [Ink Cartridge](inkCartridge.md) * [Drone Case](droneCase1.md) From 1a66fbf7a982956e708a9500b177eef42b616f61 Mon Sep 17 00:00:00 2001 From: Vexatos Date: Tue, 14 Apr 2015 15:59:04 +0200 Subject: [PATCH 19/37] OPPM is apparently craftable now. --- src/main/resources/assets/opencomputers/loot/loot.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/assets/opencomputers/loot/loot.properties b/src/main/resources/assets/opencomputers/loot/loot.properties index b7b1b1b53..4e9e7d187 100644 --- a/src/main/resources/assets/opencomputers/loot/loot.properties +++ b/src/main/resources/assets/opencomputers/loot/loot.properties @@ -12,7 +12,7 @@ Network=network:1:dyeLime OpenIRC=irc:1:dyeLightBlue OpenLoader=openloader:1:dyeMagenta OpenOS=openos:0:dyeGreen -OPPM=oppm:1:dyeCyan +OPPM=oppm:0:dyeCyan # Higher chance to find the dig program, because it has the most immediate # use - OpenOS is craftable and IRC can be downloaded once an internet card # is available - which one needs anyway, to use the program... From 8b81e44481a9390c739cdde0a0dd87f895365eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Wed, 15 Apr 2015 19:29:31 +0200 Subject: [PATCH 20/37] Should fix potential NPE in worker thread when arch is re-evaluated, closes #1070. May also fix other related problems of the architecture previously potentially changing mid-execution. --- .../scala/li/cil/oc/server/machine/Machine.scala | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/scala/li/cil/oc/server/machine/Machine.scala b/src/main/scala/li/cil/oc/server/machine/Machine.scala index b25c18bb4..f41ca7613 100644 --- a/src/main/scala/li/cil/oc/server/machine/Machine.scala +++ b/src/main/scala/li/cil/oc/server/machine/Machine.scala @@ -117,19 +117,17 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach } case _ => 0 })) - val oldArchitecture = architecture - architecture = null + var newArchitecture: Architecture = null components.find { case stack: ItemStack => Option(Driver.driverFor(stack, host.getClass)) match { case Some(driver: Processor) if driver.slot(stack) == Slot.CPU => Option(driver.architecture(stack)) match { case Some(clazz) => - if (oldArchitecture == null || oldArchitecture.getClass != clazz) { - architecture = clazz.getConstructor(classOf[machine.Machine]).newInstance(this) - if (node.network != null) architecture.onConnect() + if (architecture == null || architecture.getClass != clazz) { + newArchitecture = clazz.getConstructor(classOf[machine.Machine]).newInstance(this) } else { - architecture = oldArchitecture + newArchitecture = architecture } true case _ => false @@ -138,6 +136,12 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach } case _ => false } + // This needs to operate synchronized against the worker thread, to avoid the + // architecture changing while it is currently being executed. + if (newArchitecture != architecture) this.synchronized { + architecture = newArchitecture + if (architecture != null && node.network != null) architecture.onConnect() + } hasMemory = Option(architecture).fold(false)(_.recomputeMemory(components)) } From 8eaeb46a0fe93d4653f581fdfed65c6dcbfda97f Mon Sep 17 00:00:00 2001 From: Vexatos Date: Wed, 15 Apr 2015 21:23:49 +0200 Subject: [PATCH 21/37] Update oppm.lua --- src/main/resources/assets/opencomputers/loot/OPPM/oppm.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/resources/assets/opencomputers/loot/OPPM/oppm.lua b/src/main/resources/assets/opencomputers/loot/OPPM/oppm.lua index c7811b00a..ecf2ff22f 100644 --- a/src/main/resources/assets/opencomputers/loot/OPPM/oppm.lua +++ b/src/main/resources/assets/opencomputers/loot/OPPM/oppm.lua @@ -575,7 +575,7 @@ if options.iKnowWhatIAmDoing then printUsage() return end - return + return true end --Very much not stolen from Sangar's install.lua @@ -631,6 +631,10 @@ if not result then error(reason, 0) end +if not reason then + return +end + print("All done! Please remove the Floppy Disk used for installation! Reboot now? [Y/n]") local result = io.read() if not result or result == "" or result:sub(1, 1):lower() == "y" then From e294ec4050b4da06a864493f4c1b252c19d789c3 Mon Sep 17 00:00:00 2001 From: Vexatos Date: Wed, 15 Apr 2015 21:27:26 +0200 Subject: [PATCH 22/37] Actually tried fixing OPPM auto-installer --- src/main/resources/assets/opencomputers/loot/OPPM/oppm.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/resources/assets/opencomputers/loot/OPPM/oppm.lua b/src/main/resources/assets/opencomputers/loot/OPPM/oppm.lua index ecf2ff22f..64df24d0c 100644 --- a/src/main/resources/assets/opencomputers/loot/OPPM/oppm.lua +++ b/src/main/resources/assets/opencomputers/loot/OPPM/oppm.lua @@ -505,6 +505,7 @@ local function installPackage(pack,path,update) term.write("Done.\n") saveToFile(tPacks) print("Successfully installed package "..pack) + return true end local function uninstallPackage(pack) @@ -565,7 +566,7 @@ if options.iKnowWhatIAmDoing then provideInfo(args[2]) elseif args[1] == "install" then if not getInternet() then return end - installPackage(args[2],args[3],false) + return installPackage(args[2],args[3],false) elseif args[1] == "update" then if not getInternet() then return end updatePackage(args[2]) @@ -575,7 +576,7 @@ if options.iKnowWhatIAmDoing then printUsage() return end - return true + return end --Very much not stolen from Sangar's install.lua From 55b5ea86623445d97d88f5fa7f363a97d12fc3af Mon Sep 17 00:00:00 2001 From: Kamran Mackey Date: Wed, 15 Apr 2015 13:53:19 -0600 Subject: [PATCH 23/37] Added Baymax as a robot name. Last time i'm doing this... --- src/main/resources/assets/opencomputers/robot.names | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/assets/opencomputers/robot.names b/src/main/resources/assets/opencomputers/robot.names index a14f0a57c..0153d1d3a 100644 --- a/src/main/resources/assets/opencomputers/robot.names +++ b/src/main/resources/assets/opencomputers/robot.names @@ -13,6 +13,7 @@ Anson Argyris # Perry Rhodan ASIMO # Honda Atlas # Portal Augustus # Perry Rhodan +Baymax # Big Hero 6 Bender # Futurama BMO # Adventure Time BraitenBurg # Simple intelligent agents. From f79faa924a4247a8626ad31fcfc2695051c42155 Mon Sep 17 00:00:00 2001 From: shadowkat10 Date: Thu, 16 Apr 2015 14:42:16 +1000 Subject: [PATCH 24/37] Update robot.names Added names from games by Christine Love, fun stuff. - Emilia - Hyun-ae - Mute --- src/main/resources/assets/opencomputers/robot.names | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/resources/assets/opencomputers/robot.names b/src/main/resources/assets/opencomputers/robot.names index a14f0a57c..5c4da97f2 100644 --- a/src/main/resources/assets/opencomputers/robot.names +++ b/src/main/resources/assets/opencomputers/robot.names @@ -32,6 +32,7 @@ Dog # Half-Life Donald Duck # Perry Rhodan Elmer # One of the first two robots developed by William Gray Walter. Elsie # One of the first two robots developed by William Gray Walter. +Emilia # Digital: A Love Story Eve # Wall-E Fact Core # Portal Flexo # Futurama @@ -41,6 +42,7 @@ HAL 9000 # Space Odyssey Harkness # Fallout 3 Heron # Vexatos Homunk # Perry Rhodan +Hyun-ae # Analogue: A Hate Story / Hate Plus Icarus # Deus Ex J.A.R.V.I.S # Iron Man JoshTheEnder # Contributor @@ -55,6 +57,7 @@ Loader 1340 # Borderlands 2 LordFokas # Contributor Marvin # Hitchhiker's Guide to the Galaxy Michiyo # Contributor +Mute # Analogue: A Hate Story / Hate Plus P-Body # Portal PixelToast # Contributor QT-1 # I, Robot From 32e3b7a06dc3c9743a526bbf552ba5846f3ecddc Mon Sep 17 00:00:00 2001 From: cyber01 Date: Thu, 16 Apr 2015 12:48:22 +0300 Subject: [PATCH 25/37] Create branch From 15f5609a0e158b4949dc754e27b34484450f36c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Fri, 17 Apr 2015 13:08:33 +0200 Subject: [PATCH 26/37] Should fix potential leakage of drones. Cleaned up robot name list a bit. --- .../assets/opencomputers/robot.names | 16 +++++++----- .../scala/li/cil/oc/common/EventHandler.scala | 26 ++++++++++++++++--- .../component/WirelessNetworkCard.scala | 2 +- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/main/resources/assets/opencomputers/robot.names b/src/main/resources/assets/opencomputers/robot.names index a972da5a5..9d76928a5 100644 --- a/src/main/resources/assets/opencomputers/robot.names +++ b/src/main/resources/assets/opencomputers/robot.names @@ -5,8 +5,10 @@ # Names of more or less famous robots and AIs, are welcome. Feel free to add # more via pull requests. Let's hope this won't get us sued... -# When adding names, please keep the list sorted alphabetially, make sure it's +# When adding names, please keep the list sorted alphabetically, make sure it's # not already in the list, and, where appropriate, provide a concise source. +# And since we now also have that special case, ignore special characters when +# sorting. Adventure Core # Portal Anson Argyris # Perry Rhodan @@ -27,13 +29,13 @@ Claptrap # Borderlands Crypto # Kodos Daedalus # Deus Ex Dalek Sec # Doctor Who -Deputy ANDY # Eureka Death Trap # Borderlands 2's Mechromancer +Deputy ANDY # Eureka Dog # Half-Life Donald Duck # Perry Rhodan Elmer # One of the first two robots developed by William Gray Walter. Elsie # One of the first two robots developed by William Gray Walter. -Emilia # Digital: A Love Story +*Emilia # Digital: A Love Story Eve # Wall-E Fact Core # Portal Flexo # Futurama @@ -43,11 +45,11 @@ HAL 9000 # Space Odyssey Harkness # Fallout 3 Heron # Vexatos Homunk # Perry Rhodan -Hyun-ae # Analogue: A Hate Story / Hate Plus +*Hyun-ae # Analogue: A Hate Story / Hate Plus Icarus # Deus Ex J.A.R.V.I.S # Iron Man -JoshTheEnder # Contributor Johnny 5 # Short Circuit +JoshTheEnder # Contributor K-9 # Doctor Who KARR # Knight Rider Kilobyte # Contributor @@ -58,13 +60,13 @@ Loader 1340 # Borderlands 2 LordFokas # Contributor Marvin # Hitchhiker's Guide to the Galaxy Michiyo # Contributor -Mute # Analogue: A Hate Story / Hate Plus +*Mute # Analogue: A Hate Story / Hate Plus P-Body # Portal PixelToast # Contributor QT-1 # I, Robot -R2-D2 # Star Wars R. Daneel Olivaw # Isaac Asimov's R. Giskard Reventlov # Isaac Asimov's +R2-D2 # Star Wars Replicator # Stargate Robby # Forbidden Planet Roomba # Under your couch... wait. diff --git a/src/main/scala/li/cil/oc/common/EventHandler.scala b/src/main/scala/li/cil/oc/common/EventHandler.scala index 7dbd5c594..db4c99a92 100644 --- a/src/main/scala/li/cil/oc/common/EventHandler.scala +++ b/src/main/scala/li/cil/oc/common/EventHandler.scala @@ -12,6 +12,7 @@ import cpw.mods.fml.common.network.FMLNetworkEvent.ClientConnectedToServerEvent import li.cil.oc._ import li.cil.oc.api.Network import li.cil.oc.api.detail.ItemInfo +import li.cil.oc.api.machine.MachineHost import li.cil.oc.client.renderer.PetRenderer import li.cil.oc.client.{PacketSender => ClientPacketSender} import li.cil.oc.common.asm.ClassTransformer @@ -39,6 +40,7 @@ import net.minecraftforge.common.util.FakePlayer import net.minecraftforge.common.util.ForgeDirection import net.minecraftforge.event.entity.EntityJoinWorldEvent import net.minecraftforge.event.world.BlockEvent +import net.minecraftforge.event.world.ChunkEvent import net.minecraftforge.event.world.WorldEvent import scala.collection.convert.WrapAsScala._ @@ -140,9 +142,14 @@ object EventHandler { else if (robot.world != null) robot.machine.update() }) runningRobots --= invalid - + } + else if (e.phase == TickEvent.Phase.END) { + // Clean up machines *after* a tick, to allow stuff to be saved, first. val closed = mutable.ArrayBuffer.empty[Machine] - machines.foreach(machine => if (machine.tryClose()) closed += machine) + machines.foreach(machine => if (machine.tryClose()) { + closed += machine + if (machine.node != null) machine.node.remove() + }) machines --= closed } @@ -341,10 +348,23 @@ object EventHandler { @SubscribeEvent def onWorldUnload(e: WorldEvent.Unload) { if (!e.world.isRemote) { - import scala.collection.convert.WrapAsScala._ e.world.loadedTileEntityList.collect { case te: tileentity.traits.TileEntity => te.dispose() } + e.world.loadedEntityList.collect { + case host: MachineHost => host.machine.stop() + } + } + } + + @SubscribeEvent + def onChunkUnload(e: ChunkEvent.Unload): Unit = { + if (!e.world.isRemote) { + e.getChunk.entityLists.foreach(_.collect { + case host: MachineHost => host.machine match { + case machine: Machine => scheduleClose(machine) + } + }) } } } diff --git a/src/main/scala/li/cil/oc/server/component/WirelessNetworkCard.scala b/src/main/scala/li/cil/oc/server/component/WirelessNetworkCard.scala index 16de4f242..e87d8f527 100644 --- a/src/main/scala/li/cil/oc/server/component/WirelessNetworkCard.scala +++ b/src/main/scala/li/cil/oc/server/component/WirelessNetworkCard.scala @@ -91,7 +91,7 @@ class WirelessNetworkCard(host: EnvironmentHost) extends NetworkCard(host) with override def onDisconnect(node: Node) { super.onDisconnect(node) - if (node == this.node) { + if (node == this.node || !world.blockExists(x, y, z)) { api.Network.leaveWirelessNetwork(this) } } From c42334ba16c23488854e9bfbbfb8b239833022ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Fri, 17 Apr 2015 13:36:14 +0200 Subject: [PATCH 27/37] Fixed previous commit breaking computers after stopping once. --- src/main/scala/li/cil/oc/common/EventHandler.scala | 5 ++++- src/main/scala/li/cil/oc/server/machine/Machine.scala | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/scala/li/cil/oc/common/EventHandler.scala b/src/main/scala/li/cil/oc/common/EventHandler.scala index db4c99a92..7d69d7126 100644 --- a/src/main/scala/li/cil/oc/common/EventHandler.scala +++ b/src/main/scala/li/cil/oc/common/EventHandler.scala @@ -27,6 +27,7 @@ import li.cil.oc.integration.util import li.cil.oc.server.component.Keyboard import li.cil.oc.server.machine.Machine import li.cil.oc.server.{PacketSender => ServerPacketSender} +import li.cil.oc.util.ExtendedWorld._ import li.cil.oc.util._ import net.minecraft.client.Minecraft import net.minecraft.entity.player.EntityPlayer @@ -148,7 +149,9 @@ object EventHandler { val closed = mutable.ArrayBuffer.empty[Machine] machines.foreach(machine => if (machine.tryClose()) { closed += machine - if (machine.node != null) machine.node.remove() + if (machine.host.world == null || !machine.host.world.blockExists(BlockPosition(machine.host))) { + if (machine.node != null) machine.node.remove() + } }) machines --= closed } diff --git a/src/main/scala/li/cil/oc/server/machine/Machine.scala b/src/main/scala/li/cil/oc/server/machine/Machine.scala index f41ca7613..5bfb7b9e7 100644 --- a/src/main/scala/li/cil/oc/server/machine/Machine.scala +++ b/src/main/scala/li/cil/oc/server/machine/Machine.scala @@ -185,7 +185,7 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach override def isPaused = state.synchronized(state.top == Machine.State.Paused && remainingPause > 0) - override def start(): Boolean = state.synchronized(state.top match { + override def start(): Boolean = node.network != null && state.synchronized(state.top match { case Machine.State.Stopped => onHostChanged() processAddedComponents() From a619c0dd11426d34791cfc9e6135f45a956b5187 Mon Sep 17 00:00:00 2001 From: cyber01 Date: Fri, 17 Apr 2015 18:51:07 +0300 Subject: [PATCH 28/37] Added russian translation for manual --- .../doc/ru_RU/block/accessPoint.md | 11 +++ .../opencomputers/doc/ru_RU/block/adapter.md | 7 ++ .../doc/ru_RU/block/assembler.md | 13 +++ .../opencomputers/doc/ru_RU/block/cable.md | 9 ++ .../doc/ru_RU/block/capacitor.md | 9 ++ .../opencomputers/doc/ru_RU/block/case1.md | 37 +++++++++ .../opencomputers/doc/ru_RU/block/case2.md | 1 + .../opencomputers/doc/ru_RU/block/case3.md | 1 + .../doc/ru_RU/block/caseCreative.md | 1 + .../doc/ru_RU/block/chameliumBlock.md | 7 ++ .../opencomputers/doc/ru_RU/block/charger.md | 9 ++ .../doc/ru_RU/block/disassembler.md | 7 ++ .../doc/ru_RU/block/diskDrive.md | 9 ++ .../opencomputers/doc/ru_RU/block/geolyzer.md | 7 ++ .../doc/ru_RU/block/hologram1.md | 7 ++ .../doc/ru_RU/block/hologram2.md | 1 + .../opencomputers/doc/ru_RU/block/index.md | 46 ++++++++++ .../opencomputers/doc/ru_RU/block/keyboard.md | 7 ++ .../doc/ru_RU/block/microcontroller.md | 7 ++ .../doc/ru_RU/block/motionSensor.md | 7 ++ .../doc/ru_RU/block/powerConverter.md | 5 ++ .../doc/ru_RU/block/powerDistributor.md | 5 ++ .../opencomputers/doc/ru_RU/block/print.md | 11 +++ .../opencomputers/doc/ru_RU/block/printer.md | 18 ++++ .../opencomputers/doc/ru_RU/block/raid.md | 11 +++ .../opencomputers/doc/ru_RU/block/redstone.md | 9 ++ .../opencomputers/doc/ru_RU/block/robot.md | 9 ++ .../opencomputers/doc/ru_RU/block/screen1.md | 18 ++++ .../opencomputers/doc/ru_RU/block/screen2.md | 1 + .../opencomputers/doc/ru_RU/block/screen3.md | 1 + .../doc/ru_RU/block/serverRack.md | 9 ++ .../opencomputers/doc/ru_RU/block/switch.md | 11 +++ .../doc/ru_RU/general/computer.md | 10 +++ .../opencomputers/doc/ru_RU/general/lua.md | 16 ++++ .../opencomputers/doc/ru_RU/general/openOS.md | 12 +++ .../doc/ru_RU/general/quickstart.md | 50 +++++++++++ .../assets/opencomputers/doc/ru_RU/index.md | 39 +++++++++ .../doc/ru_RU/item/abstractBusCard.md | 5 ++ .../opencomputers/doc/ru_RU/item/acid.md | 5 ++ .../opencomputers/doc/ru_RU/item/alu.md | 5 ++ .../opencomputers/doc/ru_RU/item/analyzer.md | 7 ++ .../doc/ru_RU/item/angelUpgrade.md | 5 ++ .../opencomputers/doc/ru_RU/item/arrowKeys.md | 5 ++ .../doc/ru_RU/item/batteryUpgrade1.md | 5 ++ .../doc/ru_RU/item/batteryUpgrade2.md | 1 + .../doc/ru_RU/item/batteryUpgrade3.md | 1 + .../doc/ru_RU/item/buttonGroup.md | 5 ++ .../opencomputers/doc/ru_RU/item/card.md | 5 ++ .../doc/ru_RU/item/cardContainer1.md | 5 ++ .../doc/ru_RU/item/cardContainer2.md | 1 + .../doc/ru_RU/item/cardContainer3.md | 1 + .../opencomputers/doc/ru_RU/item/chamelium.md | 9 ++ .../opencomputers/doc/ru_RU/item/chip1.md | 5 ++ .../opencomputers/doc/ru_RU/item/chip2.md | 1 + .../opencomputers/doc/ru_RU/item/chip3.md | 1 + .../doc/ru_RU/item/chunkloaderUpgrade.md | 7 ++ .../doc/ru_RU/item/circuitBoard.md | 4 + .../doc/ru_RU/item/componentBus1.md | 10 +++ .../doc/ru_RU/item/componentBus2.md | 1 + .../doc/ru_RU/item/componentBus3.md | 1 + .../doc/ru_RU/item/controlUnit.md | 5 ++ .../opencomputers/doc/ru_RU/item/cpu1.md | 14 ++++ .../opencomputers/doc/ru_RU/item/cpu2.md | 1 + .../opencomputers/doc/ru_RU/item/cpu3.md | 1 + .../doc/ru_RU/item/craftingUpgrade.md | 5 ++ .../doc/ru_RU/item/cuttingWire.md | 5 ++ .../doc/ru_RU/item/databaseUpgrade1.md | 9 ++ .../doc/ru_RU/item/databaseUpgrade2.md | 1 + .../doc/ru_RU/item/databaseUpgrade3.md | 1 + .../opencomputers/doc/ru_RU/item/debugCard.md | 7 ++ .../opencomputers/doc/ru_RU/item/disk.md | 5 ++ .../opencomputers/doc/ru_RU/item/drone.md | 5 ++ .../doc/ru_RU/item/droneCase1.md | 34 ++++++++ .../doc/ru_RU/item/droneCase2.md | 1 + .../doc/ru_RU/item/droneCaseCreative.md | 1 + .../opencomputers/doc/ru_RU/item/eeprom.md | 7 ++ .../doc/ru_RU/item/experienceUpgrade.md | 9 ++ .../opencomputers/doc/ru_RU/item/floppy.md | 5 ++ .../doc/ru_RU/item/generatorUpgrade.md | 7 ++ .../doc/ru_RU/item/graphicsCard1.md | 7 ++ .../doc/ru_RU/item/graphicsCard2.md | 1 + .../doc/ru_RU/item/graphicsCard3.md | 1 + .../opencomputers/doc/ru_RU/item/hdd1.md | 5 ++ .../opencomputers/doc/ru_RU/item/hdd2.md | 1 + .../opencomputers/doc/ru_RU/item/hdd3.md | 1 + .../opencomputers/doc/ru_RU/item/index.md | 83 +++++++++++++++++++ .../doc/ru_RU/item/inkCartridge.md | 5 ++ .../doc/ru_RU/item/inkCartridgeEmpty.md | 1 + .../doc/ru_RU/item/internetCard.md | 7 ++ .../opencomputers/doc/ru_RU/item/interweb.md | 5 ++ .../ru_RU/item/inventoryControllerUpgrade.md | 7 ++ .../doc/ru_RU/item/inventoryUpgrade.md | 7 ++ .../opencomputers/doc/ru_RU/item/lanCard.md | 5 ++ .../doc/ru_RU/item/leashUpgrade.md | 5 ++ .../doc/ru_RU/item/linkedCard.md | 5 ++ .../opencomputers/doc/ru_RU/item/manual.md | 15 ++++ .../doc/ru_RU/item/microcontrollerCase1.md | 31 +++++++ .../doc/ru_RU/item/microcontrollerCase2.md | 1 + .../ru_RU/item/microcontrollerCaseCreative.md | 1 + .../doc/ru_RU/item/navigationUpgrade.md | 7 ++ .../opencomputers/doc/ru_RU/item/numPad.md | 5 ++ .../doc/ru_RU/item/pistonUpgrade.md | 7 ++ .../doc/ru_RU/item/printedCircuitBoard.md | 5 ++ .../opencomputers/doc/ru_RU/item/ram1.md | 17 ++++ .../opencomputers/doc/ru_RU/item/ram2.md | 1 + .../opencomputers/doc/ru_RU/item/ram3.md | 1 + .../opencomputers/doc/ru_RU/item/ram4.md | 1 + .../opencomputers/doc/ru_RU/item/ram5.md | 1 + .../opencomputers/doc/ru_RU/item/ram6.md | 1 + .../doc/ru_RU/item/rawCircuitBoard.md | 5 ++ .../doc/ru_RU/item/redstoneCard1.md | 9 ++ .../doc/ru_RU/item/redstoneCard2.md | 1 + .../opencomputers/doc/ru_RU/item/server1.md | 39 +++++++++ .../opencomputers/doc/ru_RU/item/server2.md | 1 + .../opencomputers/doc/ru_RU/item/server3.md | 1 + .../doc/ru_RU/item/serverCreative.md | 1 + .../doc/ru_RU/item/signUpgrade.md | 5 ++ .../doc/ru_RU/item/solarGeneratorUpgrade.md | 7 ++ .../opencomputers/doc/ru_RU/item/tablet.md | 13 +++ .../doc/ru_RU/item/tabletCase1.md | 39 +++++++++ .../doc/ru_RU/item/tabletCase2.md | 1 + .../doc/ru_RU/item/tabletCaseCreative.md | 1 + .../doc/ru_RU/item/tankControllerUpgrade.md | 7 ++ .../doc/ru_RU/item/tankUpgrade.md | 5 ++ .../opencomputers/doc/ru_RU/item/terminal.md | 9 ++ .../doc/ru_RU/item/texturePicker.md | 7 ++ .../doc/ru_RU/item/tractorBeamUpgrade.md | 5 ++ .../doc/ru_RU/item/transistor.md | 5 ++ .../doc/ru_RU/item/upgradeContainer1.md | 5 ++ .../doc/ru_RU/item/upgradeContainer2.md | 1 + .../doc/ru_RU/item/upgradeContainer3.md | 1 + .../opencomputers/doc/ru_RU/item/wlanCard.md | 7 ++ .../doc/ru_RU/item/worldSensorCard.md | 4 + .../opencomputers/doc/ru_RU/item/wrench.md | 5 ++ 134 files changed, 1080 insertions(+) create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/accessPoint.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/adapter.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/assembler.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/cable.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/capacitor.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/case1.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/case2.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/case3.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/caseCreative.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/chameliumBlock.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/charger.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/disassembler.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/diskDrive.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/geolyzer.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/hologram1.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/hologram2.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/index.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/keyboard.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/microcontroller.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/motionSensor.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/powerConverter.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/powerDistributor.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/print.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/printer.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/raid.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/redstone.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/robot.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/screen1.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/screen2.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/screen3.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/serverRack.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/switch.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/general/computer.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/general/lua.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/general/openOS.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/general/quickstart.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/index.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/abstractBusCard.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/acid.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/alu.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/analyzer.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/angelUpgrade.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/arrowKeys.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/batteryUpgrade1.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/batteryUpgrade2.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/batteryUpgrade3.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/buttonGroup.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/card.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/cardContainer1.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/cardContainer2.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/cardContainer3.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/chamelium.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/chip1.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/chip2.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/chip3.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/chunkloaderUpgrade.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/circuitBoard.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/componentBus1.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/componentBus2.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/componentBus3.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/controlUnit.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/cpu1.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/cpu2.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/cpu3.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/craftingUpgrade.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/cuttingWire.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/databaseUpgrade1.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/databaseUpgrade2.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/databaseUpgrade3.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/debugCard.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/disk.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/drone.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/droneCase1.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/droneCase2.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/droneCaseCreative.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/eeprom.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/experienceUpgrade.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/floppy.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/generatorUpgrade.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/graphicsCard1.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/graphicsCard2.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/graphicsCard3.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/hdd1.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/hdd2.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/hdd3.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/index.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/inkCartridge.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/inkCartridgeEmpty.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/internetCard.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/interweb.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/inventoryControllerUpgrade.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/inventoryUpgrade.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/lanCard.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/leashUpgrade.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/linkedCard.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/manual.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/microcontrollerCase1.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/microcontrollerCase2.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/microcontrollerCaseCreative.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/navigationUpgrade.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/numPad.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/pistonUpgrade.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/printedCircuitBoard.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/ram1.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/ram2.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/ram3.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/ram4.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/ram5.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/ram6.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/rawCircuitBoard.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/redstoneCard1.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/redstoneCard2.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/server1.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/server2.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/server3.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/serverCreative.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/signUpgrade.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/solarGeneratorUpgrade.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/tablet.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/tabletCase1.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/tabletCase2.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/tabletCaseCreative.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/tankControllerUpgrade.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/tankUpgrade.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/terminal.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/texturePicker.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/tractorBeamUpgrade.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/transistor.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/upgradeContainer1.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/upgradeContainer2.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/upgradeContainer3.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/wlanCard.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/worldSensorCard.md create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/item/wrench.md diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/accessPoint.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/accessPoint.md new file mode 100644 index 000000000..58779b515 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/accessPoint.md @@ -0,0 +1,11 @@ +# Точка доступа + +![AAA](oredict:oc:accessPoint) + +Точки доступа, это беспроводные версии [коммутаторов](switch.md). Они могут быть использованы, когда требуется разделить подсети, чтобы устройства не видели [компоненты](../general/computer.md) в других сетях, однако сохраняя при этом возможность передачи сообщений между подсетями. + +В дополнение к этому, точки доступа могут использоваться как повторители: они могут перенаправлять сообщения из проводной линии другим устройствам; или беспроводные сообщения как проводные, так и беспроводные. + +Коммутаторы и [коммутаторы](switch.md) *не* отслеживают, какие пакеты и куда они передали, поэтому в сети могут образовываться петли или вы можете получать одно сообщение несколько раз. Из-за ограниченного буфера сообщений коммутатора, частое отправление сообщений приводит к их потере. Вы можете улучшить [коммутатор](switch.md) или точку доступа для увеличения скорости обработки сообщений, а также увеличения размера сообщений. + +Сообщения, могут перенаправлены всего несколько раз, поэтому цепочки с произвольным количеством коммутаторов или точек доступа невозможны. По умолчанию, сообщение может быть перенаправлено пять раз. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/adapter.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/adapter.md new file mode 100644 index 000000000..b072ea457 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/adapter.md @@ -0,0 +1,7 @@ +# Адаптер + +![Теперь на 100% больше чего-то.](oredict:oc:adapter) + +Адаптеры позволяют [компьютерам](../general/computer.md) взаимодействовать с блоками Minecraft и блоками из других модов. Поддерживаемые блоки, прилегающие к адаптеру, будут отображаться как компоненты [компьютера](../general/computer.md), подключенного к адаптеру. + +В дополнение к этому, адаптеры добавляют слот для нескольких улучшений. Например, [контроллер инвентаря](../item/inventoryControllerUpgrade.md) позволяет компьютеру получать подробную информацию о предметах в инвентаре, для блока подключенного через адаптер, также это улучшение может быть установлено и в другие устройства (например [роботов](robot.md) или [дронов](../item/drone.md)), также [контроллер бака](../item/tankControllerUpgrade.md) предоставляет аналогичный функционал, только для жидкостей. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/assembler.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/assembler.md new file mode 100644 index 000000000..dcd49e20d --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/assembler.md @@ -0,0 +1,13 @@ +# Сборщик роботов + +![Harder, better, faster, stronger.](oredict:oc:assembler) + +Сборщик роботов, это продвинутая система, позволяющая собирать такие сложные устройства, как [роботы](robot.md), [дроны](../item/drone.md) и [планшеты](../item/tablet.md). Они требуют для сборки большое количество энергии, поэтому рекомендуется использовать их совместно с [конденсатором энергии](capacitor.md). + +Для создания устройства с помощью сборщика, необходимо вставить корпус устройства. Для [роботов](robot.md) это [системный блок](case1.md) любого уровня; а для [планшетов](../item/tablet.md) это [корпус планшета](../item/tabletCase1.md). Также как в других устройствах OpenComputers, компоненты должны быть помещены в указанные слоты; при наведении курсора на компонент, подсвечивается слот, куда его можно вставить. Если у вас открыт NEI, со списком компонентов OpenComputers, совместимые компоненты также будут подсвечены в NEI. Вставьте все необходимые компоненты. Не забудьте про операционную систему или установите ее позже (для роботов вы можете вставить [дисковод](diskDrive.md) для чтения [дискет](../item/floppy.md)). Для большинства устройств их [EEPROM](../item/eeprom.md) может быть изменен после сборки, достаточно поместить устройство с новым [EEPROM](../item/eeprom.md) в верстаке. Старый [EEPROM](../item/eeprom.md) при этом будет возвращен вам в инвентарь. + +Также [роботы](robot.md) могут иметь [монитор](screen1.md), для этого нужно установить в них [монитор первого уровня](screen1.md), а для возможности печатать на [мониторе](screen1.md), требуется установить [клавиатуру](keyboard.md). Для [планшетов](../item/tablet.md), [монитор](screen1.md) уже установлен в [корпус планшета](../item/tabletCase1.md), но вы должны установить [клавиатуру](keyboard.md) для возможности печатать на [планшете](../item/tablet.md). + +После того, как вы поместили все нужные компоненты, нажмите кнопку старта и ожидайте, пока устройство будет собрано и заряжено. Также стоит заметить, что вы *не* сможете изменить устройство после разборки. Если вы что-то забыли или допустили ошибку, вам придется разобрать устройство в [разборщике](disassembler.md), при этом некоторые предметы имеют шанс поломаться. + +О сложности: уровень предмета означает, пунктов сложности они будут занимать, компоненты уровня 1 занимают 1 пункт сложности, уровня 2, требуют 2 пункта, а уровня 3, 3 пункта. Улучшения - контейнеры, имеют двойную сложность (например: [контейнеры](../item/upgradeContainer1.md) уровня 2 требуют 4 пункта сложности, аналогично для [контейнера карт](../item/cardContainer1.md)). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/cable.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/cable.md new file mode 100644 index 000000000..808d0905c --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/cable.md @@ -0,0 +1,9 @@ +# Кабель + +![Зелень.](oredict:oc:cable) + +Кабель необходим для соединения [компьютеров](../general/computer.md) и машин, которые далеки друг от друга. Если вы используете компактную сборку, где все компоненты касаются друг друга (напрямую или нет, большинство блоков ведут себя как кабели), тогда вам не нужны кабели. + +Кабели могут быть окрашены с помощью красок. Цветные кабели могут соединяться только с кабелями этого же цвета и светло-серого цвета - цветом по умолчанию. Это можно использовать для запуска кабелей в нескольких подсетей параллельно, без оболочки. + +Если необходимо, кабели могут быть накрыты оболочкой из Forge MultiPart или Immibis Microblocks. Имейте ввиду, что [3D печать](print.md) совместима с Forge MultiPart, что делает возможным печать дополнительных оболочек. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/capacitor.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/capacitor.md new file mode 100644 index 000000000..2b43ce72f --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/capacitor.md @@ -0,0 +1,9 @@ +# Конденсатор энергии + +![Овер 9000.](oredict:oc:capacitor) + +Конденсатор энергии хранит энергию, используемую в сети, действуя в качестве буфера энергии, когда это необходимо. В отличие от конвертации энергии других модов во внутреннюю энергию OpenComputers (с помощью [конвертера энергии](powerConverter.md) например), передает энергию внутри одной подсети мгновенно. Наличие энергетического буфера можно использовать, когда необходимо большое количество энергии, например, в [сборщике роботов](assembler.md) и/или [зарядном устройстве](charger.md) для [роботов](robot.md) или [дронов](../item/drone.md). + +Эффективность хранения возрастает с увеличением количества конденсаторов, находящихся рядом друг с другом или в непосредственной близости. Например, два конденсатора в непосредственной близости друг от друга, будут иметь большую емкость, чем 2 отдельно стоящих. Данный бонус распространяется на конденсаторы энергии, находящиеся в радиусе двух блоков относительно друг друга и уменьшается, с увеличением расстояния между ними. + +Конденсатор может быть подключен к [распределителю энергии](powerDistributor.md) для передачи энергии другим [компьютерам](../general/computer.md) или машинам в сети. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/case1.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/case1.md new file mode 100644 index 000000000..6a91b02bc --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/case1.md @@ -0,0 +1,37 @@ +# Системный блок + +![Просто коробка.](oredict:oc:case1) + +Системные блоки имеют 3 различных уровня, различающихся количеством компонентов, которые могут быть в них вставлены. Также есть креативный системный блок. Системные блоки могут быть помещены в [сборщик роботов](assembler.md) для создания [робота](robot.md). + +Максимальный уровень компонента, который может быть помещен в слот, указан в самом слоте с помощью цифры. Слот 2 уровня также может содержать компоненты 1 уровня. + +Системный блок 1 уровня может содержать следующие компоненты: +- 2x платы расширения уровня 1 (например [видеокарты](../item/graphicsCard1.md), [сетевые карты](../item/lanCard.md) и т.д.) +- 1x [процессор](../item/cpu1.md) уровня 1 +- 2x [планки памяти](../item/ram1.md) уровня 1 +- 1x [жесткий диск](../item/hdd1.md) уровня 1 + +Системный блок 2 уровня может содержать следующие компоненты +- 1x плату расширения уровня 1 (например [видеокарты](../item/graphicsCard1.md), [сетевые карты](../item/lanCard.md) и т.д. +- 1x плату расширения уровня 2 +- 1x [процессор](../item/cpu2.md) уровня 2 +- 2x [планки памяти](../item/ram3.md) уровня 2 +- 1x [жесткий диск](../item/hdd1.md) уровня 1 +- 1x [жесткий диск](../item/hdd2.md) уровня 2 + +Системный блок 3 уровня может содержать следующие компоненты +- 1x плату расширения уровня уровня 3 (например [видеокарты](../item/graphicsCard1.md), [сетевые карты](../item/lanCard.md) и т.д.) +- 2x платы расширения уровня уровня 2 +- 1x [процессор](../item/cpu3.md) уровня 3 +- 2x [планки памяти](../item/ram5.md) уровня 3 +- 1x [жесткий диск](../item/hdd2.md) уровня 2 +- 1x [жесткий диск](../item/hdd3.md) уровня 3 +- 1x [дискету](../item/floppy.md) + +Системный блок 4 уровня (креатив) может содержать следующие компоненты +- 3x платы расширения уровня уровня 3 (например [видеокарты](../item/graphicsCard1.md), [сетевые карты](../item/lanCard.md) и т.д.) +- 1x [процессор](../item/cpu3.md) уровня 3 +- 2x [планки памяти](../item/ram5.md) уровня 3 +- 2x [жестких диска](../item/hdd3.md) уровня 3 +- 1x [дискету](../item/floppy.md) diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/case2.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/case2.md new file mode 100644 index 000000000..ee87d2036 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/case2.md @@ -0,0 +1 @@ +#REDIRECT case1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/case3.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/case3.md new file mode 100644 index 000000000..ee87d2036 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/case3.md @@ -0,0 +1 @@ +#REDIRECT case1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/caseCreative.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/caseCreative.md new file mode 100644 index 000000000..ee87d2036 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/caseCreative.md @@ -0,0 +1 @@ +#REDIRECT case1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/chameliumBlock.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/chameliumBlock.md new file mode 100644 index 000000000..674f4c9c7 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/chameliumBlock.md @@ -0,0 +1,7 @@ +# Блок хамелиума + +![Эмм... да.](oredict:oc:chameliumBlock) + +Несколько кусочком [хамелиума](../item/chamelium.md) могут быть объединены в единый блок. Блоки хамелиума могут быть окрашены в 16 стандартных цветов Minecraft. + +Используя блок хамелиума в качестве текстуры для [3D печати](print.md) вы получаете абсолютно белую поверхность. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/charger.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/charger.md new file mode 100644 index 000000000..e68aa31ca --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/charger.md @@ -0,0 +1,9 @@ +# Зарядное устройство + +![Все хорошо, просто сделай это.](oredict:oc:charger) + +Зарядное устройство предназначено для зарядки устройств, таких как [роботы](robot.md), [дроны](../item/drone.md) и [планшеты](../item/tablet.md). Зарядное устройство активируется сигналом редстоуна. Скорость заряда зависит от силы редстоун сигнала, так, при силе 15, скорость заряда будет 100%. + +Логика работы зарядного устройства может быть инвертирована с помощью [ключа](../item/wrench.md). В инвертированном режиме, зарядное устройство заряжает со 100% скоростью, уменьшая скорость заряда в соответствии с силой редстоун сигнала. + +Когда [планшет](../item/tablet.md) помещен в зарядное устройство, первый [жесткий диск](../item/hdd1.md) подключается к [компьютеру](../general/computer.md), подключенному к зарядному устройству, также, как [дискеты](../item/floppy.md) в [дисководе](diskDrive.md). Это позволяет передавать информацию между [компьютером](../general/computer.md) и [планшетом](../item/tablet.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/disassembler.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/disassembler.md new file mode 100644 index 000000000..d5ced40d6 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/disassembler.md @@ -0,0 +1,7 @@ +# Разборщик + +![Построй это, снеси это.](oredict:oc:disassembler) + +Разборщик используется для разбора большинства блоков OpenComputers на исходные компоненты. Это удобно для сборки новых деталей из частей старых и ненужных или разборки устройств, которые вам больше не нужны, или были собраны неправильно (например [роботы](robot.md) без [операционной системы](../general/openOS.md)). + +Разборка занимает много времени и немного энергии. Также есть шанс, что компонент может сломаться. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/diskDrive.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/diskDrive.md new file mode 100644 index 000000000..d9c1f9090 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/diskDrive.md @@ -0,0 +1,9 @@ +# Дисковод + +![Ходим вокруг да около...](oredict:oc:diskDrive) + +Дисковод может быть использован для чтения [дискет](../item/floppy.md) при работе с [компьютером](../general/computer.md) подключенным к дисководу. Это удобно на начальных этапах, когда низкоуровневый [системный блок](case1.md) не имеет встроенного дисковода, а вам нужна операционная система, для запуска [компьютера](../general/computer.md). Дискета с [OpenOS](../general/openOS.lua) может быть создана из пустой [дискеты](../item/floppy.md) и [данного руководства](../item/manual.lua). + +Он может быть также установлен в [роботов](robot.md), чтобы они получили возможеость использовать [дискеты](../item/floppy.md). Это можно использовать для передачи данных в и из робота используя сеть - например, используя [сетевые карты](../item/lanCard.md). + +[Дискеты](../item/floppy.md) могут быть вставлены/убраны без необходимости открывать интерфейс дисковода достаточно кликнуть правой кнопкой мыши, с зажатой клавишей Shift и [дискетой](../item/floppy.md) в руках. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/geolyzer.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/geolyzer.md new file mode 100644 index 000000000..755c8bfa4 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/geolyzer.md @@ -0,0 +1,7 @@ +# Геоанализатор + +![Это камень.](oredict:oc:geolyzer) + +Геоанализатор используется [компьютерами](../general/computer.md) для сканирования местности вокруг него. Это можно использовать для генерации карт местности и показа их на [голограммном проекторе](hologram1.md), также его можно использовать для нахождения полезных блоков (руды обычно тверже земли и камня). В результаты работы анализатора добавляется некоторое количество шума/ошибок; в теории, чем больше сканирований произвести, тем точнее результаты. + +Геоанализатор также может быть установлен в [роботов](robot.md) и [планшеты](../item/tablet.md) в качестве улучшения, которое позволяет сканировать территорию вокруг них. Сканирование требует некоторого количества энергии, хотя, частое его использование быстро разрядит батарее устройства. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/hologram1.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/hologram1.md new file mode 100644 index 000000000..dbbc3e241 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/hologram1.md @@ -0,0 +1,7 @@ +# Голограммный проектор + +![Это реально? Или это только ваше воображение?](oredict:oc:hologram1) + +Голограммный проектор предоставляет массив вокселей, расположенных в трех плоскостях, каждый из которых может быть включен или выключен с помощью подключенного [компьютера](../general/computer.md). Проектор уровня 2 имеет такое же разрешение, что и проектор уровня 1, но поддерживает 3 цветные воксели, цвета которых указываются пользователем. + +Голограммы можно вращать в вертикальной плоскости, для этого их нужно ударить [ключом](../item/wrench.md) сверху или снизу. Это может сэкономить ресурсы, ведь не нужно переворачивать их программными средствами. Голограммы также могут быть отмасштабированы. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/hologram2.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/hologram2.md new file mode 100644 index 000000000..e1acf9676 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/hologram2.md @@ -0,0 +1 @@ +#REDIRECT hologram1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/index.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/index.md new file mode 100644 index 000000000..5bb260211 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/index.md @@ -0,0 +1,46 @@ +# Блоки + +Здесь представлен список блоков в OpenComputers. Если вы ищете предметы, проверьте [список предметов](../item/index.md). + +Некоторые блоки могут быть недоступны, в зависимости от рецептов. + +## Компьютеры +* [Системный блок](case1.md) +* [Микроконтроллер](microcontroller.md) +* [Робот](robot.md) +* [Серверная стойка](serverRack.md) + +## Компоненты + +### Ввод / Вывод +* [Холограммный проектор](hologram1.md) +* [Клавиатура](keyboard.md) +* [Монитор](screen1.md) + +### Хранение данных +* [Дисковод](diskDrive.md) +* [RAID](raid.md) + +### Расширения +* [Адаптер](adapter.md) +* [Кабель](cable.md) +* [Геоанализатор](geolyzer.md) +* [Датчик движения](motionSensor.md) +* [Редстоун I/O](redstone.md) + +## Сборка / Печать +* [3D печать](print.md) +* [3D принтер](printer.md) +* [Сборщик роботов](assembler.md) +* [Блок хамелиума](chameliumBlock.md) +* [Разборщик](disassembler.md) + +## Сеть +* [Точка доступа](accessPoint.md) +* [Коммутатор](switch.md) + +## Управление питанием +* [Конденсатор энергии](capacitor.md) +* [Зарядное устройство](charger.md) +* [Конвертер энергии](powerConverter.md) +* [Распределитель энергии](powerDistributor.md) diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/keyboard.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/keyboard.md new file mode 100644 index 000000000..053ff3627 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/keyboard.md @@ -0,0 +1,7 @@ +# Клавиатура + +![QWERTY](oredict:oc:keyboard) + +Клавиатура необходима для набора текст на [мониторе](screen1.md), они могут стоять отдельным блоком в мире или быть встроены в такие устройства как [роботы](robot.md) или [планшеты](../item/tablet.md). + +Для того, чтобы клавиатура работала с [монитором](screen1.md), она должна быть расположена рядом с [монитором](screen1.md), повернута к [монитору](screen1.md), или расположена на самом [мониторе](screen1.md) (сверху или с одного из боков). Вы можете узнать, что клавиатура "соединилась" с [монитором](screen1.md) если интерфейс [монитора](screen.md) открывается, при использовании клавиатуры. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/microcontroller.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/microcontroller.md new file mode 100644 index 000000000..ffb28ad92 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/microcontroller.md @@ -0,0 +1,7 @@ +# Микроконтроллер + +![Don't belittle it.](block:OpenComputers:microcontroller) + +Микроконтроллеры можно получить, поместив [корпус микроконтроллера](../item/microcontrollerCase1.md) в [сборщик роботов](assembler.md). Они обладают меньшей функциональностью, по сравнению с [компьютерами](../general/computer.md), но они дешевле в создании. + +Микроконтроллеры могут иметь несколько компонентов, таких как [процессоры](../item/cpu1.md), [планки памяти](../item/ram1.md) и платы расширения. Микроконтроллеры не могут иметь [жесткий диск](../item/hdd1.md), но имеют слот под [EEPROM](../item/eeprom.md), что позволяет запрограммировать их специфические задачи. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/motionSensor.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/motionSensor.md new file mode 100644 index 000000000..632448a9c --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/motionSensor.md @@ -0,0 +1,7 @@ +# Датчик движения + +![Не двигайся.](oredict:oc:motionSensor) + +Датчик движения позволяет [компьютерам](../general/computer.md) замечать движение живых существ. Если существо двигается быстрее, чем задано, то будет подан сигнал в [компьютер](../general/computer.md) соединенный с датчиком движения. Вы можете задать порог срабатывания датчика через API, которое доступно с компьютеров, подключенных к датчику. + +Датчик движения обнаружит движение только в прямой видимости между ним объектом, а также только в радиусе 8 блоков. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/powerConverter.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/powerConverter.md new file mode 100644 index 000000000..77f779dff --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/powerConverter.md @@ -0,0 +1,5 @@ +# Конвертер энергии + +![Один из нас? Один из нас!](oredict:oc:powerConverter) + +Конвертер энергии это самый быстрый способ получения энергии OpenComputers из энергии других модов. Если вы запустите простой компьютер, вероятно, вам не понадобится конвертер. Если у вас есть много конденсаторов, вам может понадобиться конвертер. Однако, если вы хотите подвести энергию к [сборщику роботов](assembler.md) или [зарядному устройству](charger.md), хорошей идеей будет подключить их через конвертер, чем напрямую. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/powerDistributor.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/powerDistributor.md new file mode 100644 index 000000000..d3b25b159 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/powerDistributor.md @@ -0,0 +1,5 @@ +# Распределитель энергии + +![Энергию в массы.](oredict:oc:powerDistributor) + +Распределитель энергии распределяет ее между несколькими хранилищами (такими как [конденсатор](capacitor.md)), что позволяет нескольким подсетям обмениваться энергией, без дополнительных компонентов. Это достигается "балансированием" энергии во всех подключенных подсетях, поддерживая *относительно* одинаковое количество энергии в них. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/print.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/print.md new file mode 100644 index 000000000..9e18a278c --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/print.md @@ -0,0 +1,11 @@ +# 3D печать + +![В любом случае я нужен вам.](block:OpenComputers:print) + +3D печать осуществляется с помощью [3D принтеру](printer.md). Они предназначены в первую очередь для декоративных целей, но также могут реагировать и излучать редстоун сигнал, что расширяет их функционал. + +3D модели могут быть переработаны, для этого их нужно поместить в [3D принтер](printer.md). Что позволяет повторно использовать немного [хамелиума](../item/chamelium.md) затраченного на их печать. Цвет, который использовался для печати модели, не может быть переработан. + +Зажав кнопку показа подсказок OpenComputers (по умолчанию [Shift]), принтер покажет свое состояние. + +Распечатанные блоки совместимы с Forge MultiPart. Если требуется, множество 3D моделей могут быть размещены в пределах одного блока, пока их количество не превысит размеров одной модели. Благодаря природе Forge Multipart, модели могут быть также расположены в пределах одного блока, как факелы, рычаги и кабели (из мода Project Red например). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/printer.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/printer.md new file mode 100644 index 000000000..9e32aaca9 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/printer.md @@ -0,0 +1,18 @@ +# 3D принтер + +![2D печать это прошлый век.](oredict:oc:printer) + +3D принтеры позвляют вам распечатать любой блок любой формы и текстуры. Для начала работы с 3D принтерами, вы должны поместить блок 3D принтера рядом с компьютером. Это даст доступ к API `printer3d`, позволяющем вам создавать и печатать [3D модели](print.md) используя предоставленные функции. + +Наиболее удобный способ настройки принтеров это Пакетный менеджер OpenPrograms (OPPM). После установки (`oppm install oppm`), убедитесь, что у вас есть [интернет карта](../item/internetCard.md) в [компьютере](../general/computer.md), а после чего выполните следующие команды: +`oppm install print3d-examples` + +После чего примеры моделей будут доступны в директории `/usr/share/models/` как .3dm файлы. Изучите файлы-примеры на предмет доступных опций, в этом вам очень поможет файл `example.3dm`. Также, вы можете установить `print3d` и `print3d-examples` программы из OpenPrograms используя `wget` и [интернет карту](../item/internetCard.md). + +Для возможности печати, 3D принтер должен быть настроен с помощью [компьютера](../general/computer.md). Если он настроен для печати нон-стоп, компьютер больше не потребуется. Вы также должны вставить [картридж с чернилами](../item/inkCartridge.md) и немного [хамелиума](../item/chamelium.md) в качестве исходных материалов. Количество хамелиума зависит от сложности 3D модели, в то время, как количество чернил зависит от площади печатаемой модели. + +Для печати модели, используйте следующую команду: +`print3d /путь/к/файлу.3dm` +заменив путь, на пть к .3dm файлу. + +Документация о создании новых моделей может быть найдена в файле `/usr/share/models/example.3dm`. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/raid.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/raid.md new file mode 100644 index 000000000..b181c3872 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/raid.md @@ -0,0 +1,11 @@ +# RAID + +![40 человек в 1.](oredict:oc:raid) + +Блок RAID может содержать 3 [жестких диска](../item/hdd1.md), объединенных в единую файловую систему. Благодаря объединению, объем памяти [жестких дисков](../item/hdd1.md) суммируется и становится доступен для всех [компьютеров](../general/computer.md), подключенных к RAID. + +RAID работает только, когда все 3 [жестких диска](../item/hdd1.md) вставлены и доступны. [Жесткие диски](../item/hdd1.md) могут иметь различный объем. + +При добавлении нового [жестого диска](../item/hdd1.md) RAID стирает его содержимое. Удаление одного [жесткого диска](../item/hdd1.md) сотрет информацию и на остальных. Обратоне возвращение диска *не* восстановит данные; RAID просто будет создан заного, с пустыми дисками. + +Если сломать RAID блок, он сохранит все содержимое и данные, поэтому можно смело переезжать в другое место. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/redstone.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/redstone.md new file mode 100644 index 000000000..abf9fbc19 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/redstone.md @@ -0,0 +1,9 @@ +# Редстоун I/O + +![Привет Ред.](oredict:oc:redstone) + +Блок редстоун I/O для удаленного чтения и излучения редстоун сигнала. Он ведет себя как что-то среднее между [редстоун картой](../item/redstoneCard1.md) 1 и 2 уровня: может читать и излучать сигнал как в один провод и в многожильный кабель, но не может читать и излучать беспроводные сигналы. + +При предоставлении сторон методам компонента, направления принципиально важны, например, рекомендуется использовать `sides.north`, `sides.east` и т.п. + +Также как [редстоун карты](../item/redstoneCard1.md), этот блок подает сигнал в [компьютер](../general/computer.md) при изменении редстоун сигнала - как для одиночных, так и для многожильных сигналов. Данный компьютер может быть настроен так, чтобы будить [компьютер](../general/computer.md), когда уровень сигнала превысил порог. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/robot.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/robot.md new file mode 100644 index 000000000..86795b083 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/robot.md @@ -0,0 +1,9 @@ +# Робот + +![Его имя Тобор.](block:OpenComputers:robot) + +В отличие от [компьютеров](../general/computer.md), роботы могут двигаться и взаимодействовать с игровым миром также, как игроки. Они *не* могут взаимодействовать с внешними компонентами! Если вам нужно связать робота с [компьютером](../general/computer.md) или другими роботами, используйте [беспроводные сетевые карты](../item/wlanCard.md), или создайте низкоуровневый протокол, на основе сигнала редстоуна и [редстоун карт](../item/redstoneCard1.md), к примеру. + +Роботы получается путем помещения [системного блока](case1.md) любого уровня в [сборщик роботов](assembler.md). Чем выше уровень [системного блока](case1.md), тем более сложных роботов можно построить, благодаря возможности использовать [процессоры](../item/cpu1.md) высокого уровня. Сложность робота (показывается в [сборщике роботов](assembler.md)) определяется уровнем компонентов и улучшений, помещенных в робота; компонент высокого уровня сильнее увеличивает сложность, чем компонент низкого. Если сложность робота превысила предел, тогда [сборщик роботов](assembler.md) не сможет создать робота. + +Для повышения функциональности в роботов можно поместить множество компонентов. Это могут быть [инвентари](../item/inventoryUpgrade.md) и [контроллеры инвентарей](../item/inventoryControllerUpgrade.md), [баки для жидкостей](../item/tankUpgrade.md), [навигация](../item/navigationUpgrade.md) и многие другие. [Контейнер улучшений](../item/upgradeContainer1.md) и [карт](../item/cardContainer1.md) позволяют вставлять и вынимать компоненты без пересборки робота. [Дисковод](diskDrive.md) также может быть помещен в робота, для возможности работы с [дискетами](../item/floppy.md), например, для установки [openOS](../general/openOS.md) на робота (также вы можете установить [openOS](../general/openOS.md) на пустой [жесткий диск](../item/hdd1.md) с помощью [компьютера](../general/computer.md) и использовать этот [жесткий диск](../item/hdd1.md) как компонент, при сборке робота). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/screen1.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/screen1.md new file mode 100644 index 000000000..6c91aabba --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/screen1.md @@ -0,0 +1,18 @@ +# Монитор + +![Вы тоже видите это?](oredict:oc:screen1) + +Монитор используется совместно с [видеокартой](../item/graphicsCard1.md), для отображения текста [компьютера](../general/computer.md). Разные уровни мониторов имеют разные возможности, такие как разное разрешение и глубина цвета. Они делятся на мониторы низкого разрешения и мониторы высокого разрешения, поддерживающих 2 и 256 цвета соответственно. + +Доступное разрешение и глубина цвета зависят от наименьшего уровня компонента. При использовании [видеокарты уровня 1](../item/graphicsCard1.md) и [монитора уровня 3](screen3.md), будет доступен только разрешение и глубина цвета первого уровня. Однако, при использовании [видеокарты](../item/graphicsCard1.md) уровня 3 с монитором уровня 1, разрешение и глубина цвета также будут уровня 1, но все остальные операции, выполняемые [видеокартой](../item/graphicsCard1.md) будут быстрее, чем при использовании [видеокарты](../item/graphicsCard1.md) уровня 1. + +Экраны могут быть размещены рядом друг с другом, образуя мультиблочные структуры. При размещении вверх или вниз, они будут развернуты также, как и все остальные. Их ориентация показана стрелкой, когда вы держите монитор в руках. + +Доступное разрешение не зависит от размера монитора, а только от его уровня. Прилегающие мониторы могут быть окрашены. Достаточно кликнуть правой кнопкой мыши по монитору с красителем в руке. Краситель не будет тратиться, но и монитор не сохранит этот цвет при разбивании. Мониторы разного цвета не соединяются. Мониторы разного уровня никогда не соединятся, даже если они одного цвета. + +Мониторы уровня 2 и 3 могут использовать мышь. Клики мышью могут быть выполнены как в интерфейсе монитора (когда подключена и используется [клавиатура](keyboard.md)) или находясь рядом с монитором. Открытие интерфейса монитора как обычно или с помощью Shift может контролироваться с помощью API на подключенном к монитору [компьютере](../general/computer.md). Мониторы уровня 3 наиболее точно определяют место клика, если включен их компонент. + +Разрешение и глубина цвета мониторов в зависимости от разрешения: +- Уровень 1: разрешение 50x16, 1-bit цвет. +- Уровень 2: разрешение 80x25, 4-bit цвет. +- Уровень 3: разрешение 160x50, 8-bit цвет. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/screen2.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/screen2.md new file mode 100644 index 000000000..9a0e09ec3 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/screen2.md @@ -0,0 +1 @@ +#REDIRECT screen1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/screen3.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/screen3.md new file mode 100644 index 000000000..9a0e09ec3 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/screen3.md @@ -0,0 +1 @@ +#REDIRECT screen1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/serverRack.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/serverRack.md new file mode 100644 index 000000000..54beab330 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/serverRack.md @@ -0,0 +1,9 @@ +# Серверная стойка + +![Бесплатное жилье.](oredict:oc:serverRack) + +Серверная стойка может содержать до 4 [серверов](../item/server1.md). [Сервер](../item/server1.md) это высокоуровневый [компьютер](../general/computer.md), который может работать только внутри серверной стойки. [Серверы](../item/server1.md) могут удаленно контролироваться, с помощью [терминала](../item/terminal.md). Количество [удаленных терминалов](../item/terminal.md), которое может быть подключено к одному [серверу](../item/server1.md) одновременно, зависит от уровня [сервера](../item/server1.md). Дистанция, на которой можно будет использовать [терминал](../item/terminal.md) настраивается в интерфейсе стойки. Большие значения требуют больше энергии. + +Каждый [сервер](../item/server1.md) в серверной стойке может взаимодействовать только с одной "стороной" стойки или ни с какой. К какой стороне, какой [сервер](../item/server1.md) подключен, настраивается в интерфейсе стойки. Будьте внимательны, стороны считаются относительно самой стойки, например, если вы смотрите на стойку спереди, то `правая сторона` стойки для вас будет слева. + +Серверные стойки взаимодействуют с [коммутаторами](switch.md) и [распределителями энергии](powerDistributor.md). Переключатель режимов работы стойки, может быть настроен в интерфейсе самой стойки, он имеет 2 режима: внешний и внутренний. Во внешнем режиме сервер будет работать как обычный [коммутатор](switch.md). Во внутреннем режиме, сообщения будут передаваться только к [серверам](../item/server.md) в стойке и не будут автоматически связаны со сторонами стойки. [Серверы](../item/server1.md) все также будут иметь возможность передачи сообщений друг другу. Это позволяет использовать серверные стойки как продвинутые [коммутаторы](switch.md) для операций фильтрации и направления данных, например. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/switch.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/switch.md new file mode 100644 index 000000000..56445e17f --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/switch.md @@ -0,0 +1,11 @@ +# Коммутатор + +![Строит мосты.](oredict:oc:switch) + +Коммутатор используется для передачи сообщений между несколькими подсетями, не используя компоненты [компьютеров](../general/computer.md) в других сетях. Сохранение компонентов, как правило, хорошая идея, что не позволяет [компьютерам](../general/computer.md) использовать неверный [монитор](screen1.md) или не позволяет перенагружать их (в результате чего [компьютеры](../general/computer.md) выключатся и отказываются загружаться). + +Также есть беспроводная версия коммутатора, называемая [точка доступа](accessPoint.md), с ее помощью сообщения передаются по беспроводной линии. Сообщения, переданные по беспроводной линии могут быть получены или перенаправлены другими [точками доступа](accessPoint.md) или [компьютерами](../general/computer.md) с [беспроводной сетевой картой](../item/wlanCard.md). + +Коммутаторы и [точки доступа](accessPoint.md) *не* отслеживают, какие пакеты и куда они передали, поэтому для в сети могут образовываться петли или вы можете получать одно сообщение несколько раз. Из-за ограниченного буфера сообщений коммутатора, частое отправление сообщений приводит к их потере. Вы можете улучшить коммутатор или [точку доступа](accessPoint.md) для увеличения скорости обработки сообщений, а также увеличения размера сообщений. + +Сообщения, могут перенаправлены всего несколько раз, поэтому цепочки с произвольным количеством коммутаторов или точек доступа невозможны. По умолчанию, сообщение может быть перенаправлено пять раз. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/general/computer.md b/src/main/resources/assets/opencomputers/doc/ru_RU/general/computer.md new file mode 100644 index 000000000..eac0380d6 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/general/computer.md @@ -0,0 +1,10 @@ +# Компьютеры + +Компьютеры могут быть собраны из большого количества [блоков](../block/index.md) и компонентов. Минимальный набор блоков, для создания компьютера, это [системный блок](../block/case1.md), [монитор](../block/screen1.md) и [клавиатура](../block/keyboard.md). [Системный блок](../block/case1.md) и [монитор](../block/screen1.md) имеют несколько уровней, различающихся функционалом и возможностями, что позволяет создавать сложные компьютерные системы. Для получения возможности печатать на [мониторе](../block/screen1.md), потребуется [клавиатура](../block/keyboard.md) расположенная рядом с [монитором](../block/screen1.md) (она может быть как спереди, так и по бокам [монитора](../block/screen1.md)). + +После того, как базовые блоки собраны, требуется вставить компоненты в [системный блок](../block/case1.md). Эти компоненты включают [процессор](../item/cpu1.md), [планки памяти](../item/ram1.md), [жесткие диски](../item/hdd1.md), [видеокарты](../item/graphicsCard1.md) (для вывода изображения на [монитор](../block/screen1.md)), [сетевые карты](../item/lanCard.md) (для связи компьютеров) и т.д.. Выбирая только нужные компоненты, вы можете собрать оптимальный компьютер для требуемой задачи. + +Системные блоки низкого уровня также требуется [дисковод](../block/diskDrive.md) для работы с [дискетами](../item/floppy.md). [Дискета](../item/floppy.md) с [OpenOS](openOS.md) требуется для запуска компьютера первый раз и с ее помощью можно установить операционную систему на [жесткий диск](../item/hdd1.md). После установки системы на [жесткий диск](../item/hdd1.md), [дискеты](../item/floppy.md) больше не требуются для запуска. Дополнительные программы также доступны в виде [дискет](../item/floppy.md) (например Пакетный менеджер OpenPrograms (OPPM)) могут быть найдены в сокровищницах. + +В качестве финального шага требуется подать энергию на компьютер. OpenComputers совместим с самыми популярными техническими модами и их энергетической системой, что позволяет подключать блоки напрямую. Вы можете узнать, подключен блок к внешнему источнику питания или нет, по подсказке, в которой указана скорость конвертации энергии. +Для больших сетей с множеством компьютеров, [конвертер энергии](../block/powerConverter.md) (конвертирует энергию других модов в энергию ОС), [распределитель энергии](../block/powerDistributor.md) (распределяет энергию между компьютерами в сети) и [конденсатор энергии](../block/capacitor.md) (энергохранилище) могут быть подключены к компьютерам в сети с помощью [кабеля](../block/cable.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/general/lua.md b/src/main/resources/assets/opencomputers/doc/ru_RU/general/lua.md new file mode 100644 index 000000000..b8a196591 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/general/lua.md @@ -0,0 +1,16 @@ +# Lua + +Книги [Lua руководство](http://www.lua.org/manual/5.2/manual.html) и [Программирование на Lua](http://www.lua.org/pil/) (первое издание доступно бесплатно) хорошее начало, для получения базовых навыков программирования на Lua, ознакомления с синтаксисом и стандартными библиотеками. [OpenOS](openOS.md) стремится соответствовать стандартным библиотекам, с несколькими различиями, например отладочная библиотека. Эти различия [документированы в wiki](http://ocdoc.cil.li/api:non-standard-lua-libs). + +Нестандартные библиотеки должны быть `подключены`, для использования их в скриптах. Например: + +`local component = require("component")` +`local rs = component.redstone` + +Это позвонил вызывать и использовать функции [редстоун карты](../item/redstoneCard1.md). Например: + +`rs.setOutput(require("sides").front, 15)` + +**Важно**: при работе с интерпретатором Lua, *не* используйте несколько `local` в одной строке. Если вы вставите третью строку выше подключения библиотеки, вы получите ошибку, так как вызов `rs` будет иметь значение `nil`. Почему только на третьей строке, спросите вы? Потому, что для простоты тестирования, интерпретатор пытается загрузить неизвестные переменные, как библиотеки. Хотя на после первой строки ничего не произойдет, то на второй строке вызов `component` вызовет эту библиотеку и запустит ее. Библиотеки не подгружаются автоматически, их нужно вызвать, это сделано для экономии ресурсов. + +OpenOS предоставляет множество дополнительных библиотек и программ, начиная от контроля и управления компонентами [компьютера](computer.md) и заканчивая API для многожильного редстоун кабеля, а также кодов клавиш [клавиатуры](../block/keyboard.md). Дополнительные библиотеки могут быть подключены к Lua скрипту через функцию `require()`, как показано выше. Некоторые библиотеки требуют определенные компоненты для работы, например `интернет` библиотека требует [интернет карту](../item/internetCard.md). В данном случае, библиотека станет доступна, только после установки интернет карты. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/general/openOS.md b/src/main/resources/assets/opencomputers/doc/ru_RU/general/openOS.md new file mode 100644 index 000000000..417fc3431 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/general/openOS.md @@ -0,0 +1,12 @@ +# OpenOS + +OpenOS это простая операционная система, доступная в OpenComputers. Она требуется для первого запуска [компьютера](computer.md) и может быть получена с помощью пустой [дискеты](../item/floppy.md) и [руководства](../item/manual.md) OpenComputers в окне верстака. + +После крафта, [дискета](../item/floppy.md) может быть помещена в [дисковод](../block/diskDrive.md), подключенный к [правильно настроенному](quickstart.md) [компьютеру](computer.md), что позволит [компьютеру](computer.md) запустить OpenOS. +После запуска, вы можете установить OpenOS на чистый [жесткий диск](../item/hdd1.md), что освобождает от необходимости использовать [дискету](../item/floppy.md) при каждом запуске, а также получить доступ к файловой системе в режиме записи ([Дискеты](../item/floppy.md) с OpenOS и другие "трофейные" дискеты имеют режим `только чтение`). [Системный блок](../block/case3.md) уровня 3 не требует внешнего [дисковода](../block/diskDrive.md), он уже встроен и может работать с [дискетами](../item/floppy.md). + +OpenOS может быть установлена командой `install`, после чего потребуется подтверждение установки. [дискету](../item/floppy.md) можно вытащить, после установки системы и перезапуска компьютера. OpenOS может быть установлена на все устройства, за исключением [дронов](../item/drone.md) и [микроконтроллеров](../block/microcontroller.md) (оба вида могут быть запрограммированы только с помощью [EEPROM](../item/eeprom.md) потому, что они не имеют собственной файловой системы). + +OpenOS имеет множество встроенных функций, вы также можете использовать команду `lua`, чтобы открыть интерпретатор Lua. Это наилучший способ проверки работы команд и экспериментов с API, перед написанием .lua скрипта. Также прочитайте информацию, отображаемую при запуске интерпретатора, она покажет вам, как вывести результаты выполнения команды и как выйти из интерпретатора. + +Для более подробной информации, прочитайте страницу [Программирование на Lua](lua.md). Для запуска Lua скриптов, просто напечатайте имя скрипта и нажмите Enter (например, `script.lua` может быть запущен командой `script` в терминале). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/general/quickstart.md b/src/main/resources/assets/opencomputers/doc/ru_RU/general/quickstart.md new file mode 100644 index 000000000..6b72085ff --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/general/quickstart.md @@ -0,0 +1,50 @@ +# Быстрый старт + +Также это руководство можно назвать "как сделать компьютер". Для запуска вашего первого [компьютера](computer.md) вам нужно его корректно собрать. В OpenComputers доступно большое количество компьютеров, но мы начнем с самого простого: обычного компьютера. + +**Примечание**: это пошаговая инструкция, которая позволит вам понять базовые принципы мода. Если вы никогда не собирали компьютер в реальной жизни или вы совсем не знаете этот мод, мы рекомендуем вам прочитать эту страницу. + +Сперва, вам понадобится [системный блок](../block/case1.md). Этот блок будет содержать все компоненты вашего компьютера и именно с него начинается создание компьютера. + +![Системный блок уровня 2.](oredict:oc:case2) + +Например, вам потребуется выбрать, [видеокарту](../item/graphicsCard1.md) какого уровня вы будете использовать, а может вам требуется [сетевая](../item/lanCard.md) или [редстоун](../item/redstoneCard1.md) карта или вы играете в креативе, тогда вам может понадобиться [отладочная карта](../item/debugCard.md). + +Когда вы откроете интерфейс [системного блока](../block/case1.md) вы увидите несколько слотов. Количество слотов и уровень компонентов, которые могут быть установлены (показано римскими цифрами в слоте) зависит от уровня системного блока. +![Интерфейс системного блока уровня 2.](opencomputers:doc/img/configuration_case1.png) +Пустые [системные блоки](../block/case1.md) бесполезны. Вы можете попытаться включить [компьютер](computer.md), но вы получите только сообщение о ошибке в чат, а также звуковой сигнал. Сообщение о ошибке указывает, что компьютерам нужна энергия для работы. Подключите ваш [компьютер](computer.md) к источнику энергии, напрямую или через [конвертер энергии](../block/powerConverter.md). + +При повторной попытке запуска, вы получите сообщение, о необходимости установки [процессора](../item/cpu1.md). Они бывают разных уровней, эта тенденция используется во всем OpenComputers. Чем выше уровень [процессора](../item/cpu1.md), тем больше компонентов он сможет использовать, а также, тем быстрее он работает. Выберите уровень и поместите процессор в [системный блок](../block/case1.md). + +После чего вы должны вставить [планки памяти](../item/ram1.md). Звуковой сигнал будет другим: 1 длинный и 1 короткий. Чем выше уровень [планок памяти](../item/ram1.md), тем больше памяти доступно программам на вашем [компьютере](computer.md). Для запуска [OpenOS](openOS.md), требуется как минимум две [планки памяти](../item/ram1.md) уровня 1. + +Так уже гораздо лучше. Теперь ваш [системный блок](../block/case1.md) выглядит примерно так: +![Частично собранный компьютер.](opencomputers:doc/img/configuration_case2.png) +И вот, попытка включения не выдает никаких сообщений! Но увы, он не запускается. При этом компьютер выдаст двойной звуковой сигнал. Это означает, что попытка запуска [компьютера](computer.md) не удалась. Другими словами: технически он работает! И тут нам на помощь приходит замечательный инструмент: [анализатор](../item/analyzer.md). Данный инструмент позволяет получать информацию о блоках OpenComputers, а также о некоторых блоках из другим модов. Для использования [анализатора](../item/analyzer.md) на [компьютере](computer.md) кликните по нему (с зажатой клавишей Shift). + +Вы получите сообщение, почему [компьютер](computer.md) не запускается: +`no bios found; install configured EEPROM` + +Самое главное здесь, это *настроенный*. Создать [EEPROM](../item/eeprom.md) очень просто. Для настройки, вы можете использовать [компьютер](computer.md), что немного сложно в данный момент, поэтому используйте его для крафта "Lua BIOS" [EEPROM](../item/eeprom.md). Обычно это [EEPROM](../item/eeprom.md) и [manual](../item/manual.md) расположенные рядом в верстаке. Поместите настроенный [EEPROM](../item/eeprom.md) в ваш [компьютер](computer.md) и..... + +Ничего. Совсем ничего. Но мы умеем использовать [анализатор](../item/analyzer.md), это очень удобно! В результате получаем другое сообщение: +`no bootable medium found; file not found` + +Ну что ж. BIOS работает и это хорошо. Но компьютер не может запустить операционную систему, тут нам потребуется [дискеты](../item/floppy.md) или [жесткий диск](../item/hdd1.md). Lua BIOS ожидает наличия в файловой системе файла `init.lua`, с которого начинается загрузка операционной системы. Вы, наверное догадались, что нам нужна дискета с операционной системой. Соедините пустую [дискету](../item/floppy.md) и [руководство](../item/manual.md) для создания дискеты с [OpenOS](openOS.md). + +Даже, если использовать [системный блок](../block/case2.md) уровня 2 (как на скриншотах выше), вы не сможете вставить дискету. Если вы будете использовать [системный блок](../block/case3.md) уровня 3 или креативный, вы сможете легко вставить дискету в [системный блок](../block/case1.md). Значит, нам потребуется [дисковод](../block/diskDrive.md) рядом с системным блоком (или подключенный с помощью [кабеля](../block/cable.md)). Как только вставите дискету, вы знаете, что делать. Включите компьютер. + +Он ожил! Ну или должен был. Если этого не произошло, значит что-то пошло не так и нам снова поможет [анализатор](../item/analyzer.md). Если предположить, что компьютер заработал, то вы проделали огромную работу. Самая сложная часть позади. Теперь осталось напечатать что-либо и вывести результат. + +Чтобы [компьютер](computer.md) мог выводить информацию, вы должны установить [монитор](../block/screen1.md) и [видеокарту](../item/graphicsCard1.md). +![Нет, это не плоский экран.](oredict:oc:screen2) + +Установите [монитор](../block/screen1.md) рядом с [системным блоком](../block/case1.md) или подключите его с помощью [кабеля](../block/cable.md). После чего установите [видеокарту](../item/graphicsCard1.md), которую вы выбрали в [системный блок](../block/case1.md). Вы должны увидеть мигающий курсор на [мониторе](../block/screen1.md). Теперь, установите [клавиатуру](../block/keyboard.md) перед [монитором](../block/screen1.md) или на одну из его сторон, чтобы получить возможность вводить текст с [клавиатуры](../block/keyboard.md). + +На этом все. Теперь ваш [компьютер](computer.md) запущен, работает и ожидает команд. Попробуйте что-нибудь напечатать! Введите `lua` и нажмите Enter, после чего вы получите приветственное сообщение интерпретатора Lua. Здесь вы можете выполнять простые команды Lua. Для более подробной информации, прочтите страницу о [Lua](lua.md). + +![Оно живое!](opencomputers:doc/img/configuration_done.png) + +Получите удовольствие, от создания сложных [компьютеров](computer.md), совместно [серверами](../item/server1.md) и сборкой [роботов](../block/robot.md), [дронов](../item/drone.md), [микроконтроллеров](../block/microcontroller.md) и [планшетов](../item/tablet.md) в [сборщике роботов](../block/assembler.md). + +Хорошего кода вам! diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/index.md b/src/main/resources/assets/opencomputers/doc/ru_RU/index.md new file mode 100644 index 000000000..47b8aee3b --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/index.md @@ -0,0 +1,39 @@ +# Руководство OpenComputers + +OpenComputers это мод, который добавляет модульные и настраиваемые [компьютеры](general/computer.md), [серверы](item/server1.md), [роботов](block/robot.md) и [дронов](item/drone.md) в игру, которые сохраняют свое состояние. Все устройства могут быть запрограммированы на языке Lua 5.2, что позволяет работать на системах любой сложности. + +Чтобы понять, как использовать руководство, прочитайте [эту страницу](item/manual.md) (этот зеленый текст - ссылка, кликните на него). + +## Содержание + +### Устройства +- [Компьютеры](general/computer.md) +- [Серверы](item/server1.md) +- [Микроконтроллеры](block/microcontroller.md) +- [Роботы](block/robot.md) +- [Дроны](item/drone.md) + +### Программы и программирование +- [OpenOS](general/openOS.md) +- [Lua](general/lua.md) + +### Блоки и предметы +- [Предметы](item/index.md) +- [Блоки](block/index.md) + +### Обучение +- [С чего начать?](general/quickstart.md) + +## Обзор + +Как упоминалось выше, компьютеры в OpenComputers сохраняют свое состояние, это означает, что [компьютер](general/computer.md) сохраняет свое состояние, даже если чанк был отгружен. Это означает, что если игрок отошел от [компьютера](general/computer.md) или вышел, то [компьютер](general/computer.md) запомнит свое последнее состояние и продолжит работу, тогда, когда игрок снова окажется около [компьютера](general/computer.md). Так работают все блоки, за исключением [планшетов](item/tablet.md). + +Все устройства модульные и могут быть собраны с большим количеством различных компонентов, также как [компьютеры](general/computer.md) в реальной жизни. Игроки, которые любят что-либо мастерить, могут собрать себе робота таким, каким хотят. Если потребуется, устройства могут быть [разобраны](block/disassembler.md). Для [компьютеров](general/computer.md) и [серверов](item/server1.md), компоненты могут быть заменены простым вынимаем из системного блока. + +Устройства OpenComputers совместимы с множеством других модов, что позволяет производить манипуляции над блоками и сущностями (через [адаптер](block/adapter.md) или добавляет специфические улучшения для [роботов](block/robot.md) и [дронов](item/drone.md)). Энергия может быть также получена из других модов, например, Redstone Flux, IndustrialCraft2 EU, Mekanism Joules, Applied Energistics 2 и Factorization Charge. + +Большинство устройств работают под простой операционной системой [OpenOS](general/openOS.md) (за исключением [дронов](item/drone.md) и [микроконтроллеров](block/microcontroller.md). OpenComputers позволяет создавать операционные системы и архитектуры, такими, какими захочет пользователь. + +Устройства имеют доступ к таким ресурсам, как [жесткий диск](item/hdd1.md) и [память (RAM)](item/ram1.md). [Микроконтроллеры](block/microcontroller.md) это дешевые [компьютеры](general/computer.md) с меньшим функционалом и компонентами, они не имеют файловой системы, требуют креатива для программирования. [Роботы](block/robot.md) это мобильные [компьютеры](general/computer.md) они могут взаимодействовать с блоками и существами (но не могут взаимодействовать с внешними компонентами OpenComputers). [Дроны](item/drone.md) это быстрые, entity-based [роботы](block/robot.md) с ограниченным функционалом, возможностью двигаться и взаимодействовать с миром отлично от роботов. [Серверы](item/server1.md) продвинутые [компьютеры](general/computer.md) могут содержать много компонентов, позволяют запускать огромные программы и управлять большими сетями. + +Данное руководство содержит детальную информацию обо всех блоках и предметах, о установке систем и устройств, а также введение в программирование на Lua. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/abstractBusCard.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/abstractBusCard.md new file mode 100644 index 000000000..fbee0fa7a --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/abstractBusCard.md @@ -0,0 +1,5 @@ +# Карта абстрактной шины + +![Нужно больше сетей!](oredict:oc:abstractBusCard) + +Карта позволяет [компьютерам](../general/computer.md), [серверам](server1.md) и [роботам](../block/robot.md) взаимодействовать с абстрактной шиной мода StargateTech2. Если карта установлена, блоки подключаются к абстрактной шине и позволяет передавать сообщения с ее помощью. Входящие абстрактные сообщения будут конвертированы в сигналы и направлены в машину. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/acid.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/acid.md new file mode 100644 index 000000000..2468909e7 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/acid.md @@ -0,0 +1,5 @@ +# Кислота + +![Отлив?](oredict:oc:materialAcid) + +При использовании сложных рецептов, нужно использовать кислоту на [печатной плате](circuitBoard.md) перед созданием [отпечатанной печатной платы](printedCircuitBoard.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/alu.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/alu.md new file mode 100644 index 000000000..441965834 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/alu.md @@ -0,0 +1,5 @@ +# Арифметико-логическая единица + +![Я могу считать!](oredict:oc:materialALU) + +Используется для крафта компонентов, в которых происходят вычисления, таких как [процессоры](cpu1.md) и [видеокарты](graphicsCard1.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/analyzer.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/analyzer.md new file mode 100644 index 000000000..d17b07e27 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/analyzer.md @@ -0,0 +1,7 @@ +# Анализатор + +![Что же это такое.](oredict:oc:analyzer) + +Анализатор это ручной инструмент, предназначенный для получения информации о блоках OpenComputers. Просто активируйте блок, для получения информации в чат. В зависимости от блока вы можете получить как адрес компонента и информацию о уровне энергии, так и информацию о ошибке, из-за которой [компьютер](../general/computer.md) не работает. + +Вы можете зажать кнопку Ctrl и кликнуть правой кнопкой мыши по блоку или компоненту, в результате адрес этого блока или компонента будет скопирован у буфер обмена. Данная информация может быть вставлена позже в окно [компьютера](../general/computer.md). \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/angelUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/angelUpgrade.md new file mode 100644 index 000000000..99b8d4274 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/angelUpgrade.md @@ -0,0 +1,5 @@ +# Улучшение - Ангельский блок + +![Аллилуйя](oredict:oc:angelUpgrade) + +Данное улучшение позволяет [роботам](../block/robot.md) ставить блоки прямо в воздухе, без соседнего блока. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/arrowKeys.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/arrowKeys.md new file mode 100644 index 000000000..af6eb5fe1 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/arrowKeys.md @@ -0,0 +1,5 @@ +# Клавиши со стрелками + +![Просто нажми нужную кнопку.](oredict:oc:materialArrowKey) + +Это необходимый элемент для крафта [клавиатуры](../block/keyboard.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/batteryUpgrade1.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/batteryUpgrade1.md new file mode 100644 index 000000000..571974c2c --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/batteryUpgrade1.md @@ -0,0 +1,5 @@ +# Улучшение - Аккумулятор + +![Сделано из металла.](oredict:oc:batteryUpgrade1) + +Данное улучшение увеличивает объем внутреннего энергохранилища, что позволяет [роботам](../block/robot.md) и [планшетам](tablet.md) работать гораздо дольше без [зарядки](../block/charger.md). Чем выше уровень батареи, тем больше энергии она может хранить. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/batteryUpgrade2.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/batteryUpgrade2.md new file mode 100644 index 000000000..0281a4533 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/batteryUpgrade2.md @@ -0,0 +1 @@ +#REDIRECT batteryUpgrade1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/batteryUpgrade3.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/batteryUpgrade3.md new file mode 100644 index 000000000..0281a4533 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/batteryUpgrade3.md @@ -0,0 +1 @@ +#REDIRECT batteryUpgrade1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/buttonGroup.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/buttonGroup.md new file mode 100644 index 000000000..86da13c70 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/buttonGroup.md @@ -0,0 +1,5 @@ +# Группа кнопок + +![Нужно больше кнопок.](oredict:oc:materialButtonGroup) + +Необходимый компонент для крафта [клавиатуры](../block/keyboard.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/card.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/card.md new file mode 100644 index 000000000..bd38aa171 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/card.md @@ -0,0 +1,5 @@ +# Карта + +![Не может быть прочитано.](oredict:oc:materialCard) + +Обычный компонент для крафта карт в OpenComputers (например [видеокарт](graphicsCard1.md), [сетевых карт](lanCard.md) и т.д.). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/cardContainer1.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/cardContainer1.md new file mode 100644 index 000000000..b8aa1f351 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/cardContainer1.md @@ -0,0 +1,5 @@ +# Контейнер для карт + +![Может хранить карты!](oredict:oc:cardContainer1) + +Контейнер для карт, как дополнение к улучшению для [роботов](../block/robot.md) позволяет добавлять/извлекать карты в/из [роботов](../block/robot.md). Максимальный уровень карты зависит от уровня контейнера. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/cardContainer2.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/cardContainer2.md new file mode 100644 index 000000000..16d29de27 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/cardContainer2.md @@ -0,0 +1 @@ +#REDIRECT cardContainer1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/cardContainer3.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/cardContainer3.md new file mode 100644 index 000000000..16d29de27 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/cardContainer3.md @@ -0,0 +1 @@ +#REDIRECT cardContainer1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/chamelium.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/chamelium.md new file mode 100644 index 000000000..71146b61b --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/chamelium.md @@ -0,0 +1,9 @@ +# Хамелиум + +![Такая интересная штука.](oredict:oc:chamelium) + +Это основной материал, используемый в [3D печати](../block/print.md) на [3D принтерах](../block/printer.md). Сам по себе он не представляет ценности. + +Вы можете объединять его, для получения [блоков хамелиума](../block/chameliumBlock.md). + +Несъедобно. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/chip1.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/chip1.md new file mode 100644 index 000000000..d747ebfea --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/chip1.md @@ -0,0 +1,5 @@ +# Микрочипы + +![Не съедобные.](oredict:oc:circuitChip1) + +Микрочипы - основа крафта электронных компонентов в OpenComputers. Они имеют различные уровни, для крафта компонентов разных уровней. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/chip2.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/chip2.md new file mode 100644 index 000000000..5679bbdeb --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/chip2.md @@ -0,0 +1 @@ +#REDIRECT chip1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/chip3.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/chip3.md new file mode 100644 index 000000000..5679bbdeb --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/chip3.md @@ -0,0 +1 @@ +#REDIRECT chip1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/chunkloaderUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/chunkloaderUpgrade.md new file mode 100644 index 000000000..607aacbdc --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/chunkloaderUpgrade.md @@ -0,0 +1,7 @@ +# Улучшение - Чанклоадер + +![Работает всегда.](oredict:oc:chunkloaderUpgrade) + +Данное улучшение может быть установлено (например, в [роботов](../block/robot.md) и [микроконтроллеры](../block/microcontroller.md)), чтобы устройства могли загружать чанки, в которых они находятся, а также соседние чанки. Однако на это требуется энергия. Чанклоадер может быть включен или выключен через API. + +Улучшение автоматически включается при включении устройства и выключается вместе с ним. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/circuitBoard.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/circuitBoard.md new file mode 100644 index 000000000..430d1468b --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/circuitBoard.md @@ -0,0 +1,4 @@ +# Печатная плата +![Нужно больше золота.](oredict:oc:materialCircuitBoard) + +Результат крафта из [заготовки печатной платы](rawCircuitBoard.md), используется для создания [отпечатанной печатной платы](printedCircuitBoard.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/componentBus1.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/componentBus1.md new file mode 100644 index 000000000..2f73d6a1d --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/componentBus1.md @@ -0,0 +1,10 @@ +# Компонентая шина + +![Нужно больше.....](oredict:oc:componentBus1) + +Компонентная шина это [серверное](server1.md) улучшение, которое позволяет [серверам](server1.md) взаимодействовать с большим количеством компонентов. Например [процессорами](cpu1.md), чем выше уровень шины, тем выше уровень компонента, который можно вставить. Чем выше уровень [сервера](server1.md), тем больше компонентных шин вы сможете вставить. + +Количество компонентов, к которому имеет компонентная шина: +- Уровень 1: 8 компонентов. +- Уровень 2: 12 компонентов. +- Уровень 3: 16 компонентов. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/componentBus2.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/componentBus2.md new file mode 100644 index 000000000..a49cd378a --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/componentBus2.md @@ -0,0 +1 @@ +#REDIRECT componentBus1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/componentBus3.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/componentBus3.md new file mode 100644 index 000000000..a49cd378a --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/componentBus3.md @@ -0,0 +1 @@ +#REDIRECT componentBus1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/controlUnit.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/controlUnit.md new file mode 100644 index 000000000..cb353ccda --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/controlUnit.md @@ -0,0 +1,5 @@ +# Блок управления + +![Теперь с круиз-контролем.](oredict:oc:materialCU) + +Чем выше уровень и сложность предмета, тем совершеннее компоненты ему нужны, например [процессоры](cpu1.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/cpu1.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/cpu1.md new file mode 100644 index 000000000..2d04578b8 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/cpu1.md @@ -0,0 +1,14 @@ +# Процессор + +![Мозги...](oredict:oc:cpu1) + +Основа всех [компьютеров](../general/computer.md) и [серверов](server1.md). Устанавливает архитектуру [компьютера](../general/computer.md) и количество компонентов, которые могут быть подключены к [компьютеру](../general/computer.md), прежде чем он перестанет работать. Чем выше уровень процессора, тем быстрее работает ваш [компьютер](../general/computer.md) - все просто. + +Количество компонентов, к которым имеет доступ процессор: +- Уровень 1: 8 компонентов. +- Уровень 2: 12 компонентов. +- Уровень 3: 16 компонентов. + +В [серверах](server1.md), количество компонентов расширяется с помощью [компонентных шин](componentBus1.md). + +Если к [компьютеру](../general/computer.md) подключено больше компонентов, чем может использовать процессор, он не включится. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/cpu2.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/cpu2.md new file mode 100644 index 000000000..b62149ec4 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/cpu2.md @@ -0,0 +1 @@ +#REDIRECT cpu1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/cpu3.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/cpu3.md new file mode 100644 index 000000000..b62149ec4 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/cpu3.md @@ -0,0 +1 @@ +#REDIRECT cpu1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/craftingUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/craftingUpgrade.md new file mode 100644 index 000000000..b481b303c --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/craftingUpgrade.md @@ -0,0 +1,5 @@ +# Улучшение - Верстак + +![Скрафти это.](oredict:oc:craftingUpgrade) + +Это улучшение позволяет [роботам](../block/robot.md) крафтить простые предметы, используя свой [инвентарь](../item/inventoryUpgrade.md). Для крафта используется сетка 3 на 3 слота (левый верхний угол) в [инвентаре](../item/inventoryUpgrade.md) [робота](../block/robot.md). Предметы должны быть расположены в соответствии с рецептом. Результаты крафта будут помещены в [инвентарь](../item/inventoryUpgrade.md) [робота](../block/robot.md). Также результат может быть помещен в выбранный слот, если он заполнен, тогда используется следующий слот. Когда место в инвентаре заканчивается, результаты крафта будут выброшены в мир. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/cuttingWire.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/cuttingWire.md new file mode 100644 index 000000000..9da22c97d --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/cuttingWire.md @@ -0,0 +1,5 @@ +# Проволока + +![Не гаррота. Лучше.](oredict:oc:materialCuttingWire) + +Предмет используется в сложных рецептах, нужен для создания [заготовки печатной платы](rawCircuitBoard.md). Очень неэффективно. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/databaseUpgrade1.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/databaseUpgrade1.md new file mode 100644 index 000000000..35af7a69e --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/databaseUpgrade1.md @@ -0,0 +1,9 @@ +# Улучшение - База данных + +![Она существует.](oredict:oc:databaseUpgrade1) + +Улучшение может быть настроено на хранение списка стаков предметов, которые могут быть использованы другими компонентами. Это особенно полезно для элементов, которые отличаются на основе NBT данных. + +Для конфигурации базы данных, откройте ее, кликнув правой кнопкой мыши с базой данных в руке. Поместите стаки предметов, которые на которые вы хотите сконфигурировать в верхнюю часть инвентаря. Это будут "призрачные стаки", т.е. не "реальные" предметы, хранящиеся в базе данных. + +Также база данных может быть сконфигурирована автоматически, через API предоставленным [контроллером инвентаря](inventoryControllerUpgrade.md) и [анализатором](../block/geolyzer.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/databaseUpgrade2.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/databaseUpgrade2.md new file mode 100644 index 000000000..196a017a3 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/databaseUpgrade2.md @@ -0,0 +1 @@ +#REDIRECT databaseUpgrade1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/databaseUpgrade3.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/databaseUpgrade3.md new file mode 100644 index 000000000..196a017a3 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/databaseUpgrade3.md @@ -0,0 +1 @@ +#REDIRECT databaseUpgrade1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/debugCard.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/debugCard.md new file mode 100644 index 000000000..270d4a1a1 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/debugCard.md @@ -0,0 +1,7 @@ +# Отладочная карта + +![Подождите.](item:OpenComputers:item@73) + +Отладочная карта, это креативный предмет, предназначенный изначально для отладки некоторых вещей, за счет автоматизации процесса. С тех пор она обрела большую функциональность, что делает ее идеальным инструментом для создания карт. + +Обратите внимание, что вы можете привязать/отвязать карту, нажав кнопку `Красться`, держа в руках карту, это означает, что `команды` будут выполнены на основе вашего уровня доступа, а не умолчаний OpenComputers. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/disk.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/disk.md new file mode 100644 index 000000000..186fee69a --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/disk.md @@ -0,0 +1,5 @@ +# Диск + +![Памяти Terry Pratchett.](oredict:oc:materialDisk) + +Базовый компонент для создания устройств хранения информации, таких как [дискеты](floppy.md) и [жесткие диски](hdd1.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/drone.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/drone.md new file mode 100644 index 000000000..96ee74f9a --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/drone.md @@ -0,0 +1,5 @@ +# Дрон + +![Большой брат следит за тобой.](item:OpenComputers:item@84) + +Дроны собираются из [корпуса дрона](droneCase1.md) в [сборщике роботов](../block/assembler.md). Они entity-based [роботы](../block/robot.md), но с меньшим функционалом. Они также могут перемещаться по диагонали и быстрее чем [роботы](../block/robot.md), также они обычно контролируются с помощью программы на [компьютере](../general/computer.md). Дроны могут быть сконфигурированы с помощью [EEPROM](eeprom.md) для выполнения различных комманд. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/droneCase1.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/droneCase1.md new file mode 100644 index 000000000..b1f8d815b --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/droneCase1.md @@ -0,0 +1,34 @@ +# Корпус дрона + +![Полетели.](oredict:oc:droneCase1) + +Корпус дрона используется для создания [дронов](drone.md) в [сборщике роботов](../block/assembler.md). [Дроны](drone.md) легковесны, быстры и очень мобильны, но с ограниченной функциональностью. В отличие от [роботов](../block/robot.md) они не могут использовать инструменты и могут ограниченно взаимодействовать с игровым миром. + +Их ограничения обусловлены скорость передвижения и низкими энергозатратами. Они созданы для переноса небольших количеств предметов и идеально подходят для разведки. Использование [дрона](drone.md) вместе с [роботом](../block/robot.md) дает большие возможности, с [роботом](../block/robot.md) выполняем тяжелую работу, а с помощью [дрона](drone.md) предоставляем информацию о окружении и переносим предметы. + +Также как и [микроконтроллеры](../block/microcontroller.md), [дроны](drone.md) могут быть запрограммированы только с помощью [EEPROM](eeprom.md). Также, [EEPROM](eeprom.md) может быть изменен, для этого нужно скрафтить этого [дрона](drone.md) с другим [EEPROM](eeprom.md); старый [EEPROM](eeprom.md) при этом будет возвращен игроку. + +Корпус дрона 1 уровня позволяет использовать следующие компоненты: +- 1x [процессор](cpu1.md) уровня 1 +- 1x [планка памяти](ram1.md) уровня 1 +- 1x [EEPROM](eeprom.md) +- 1x карта расширения уровня 2 +- 1x карта расширения уровня 1 +- 1x улучшение уровня 1 +- 1x улучшение уровня 2 + +Корпус дрона 2 уровня позволяет использовать следующие компоненты: +- 1x [процессор](cpu1.md) уровня 1 +- 2x [планки памяти](ram1.md) уровня 1 +- 1x [EEPROM](eeprom.md) +- 2x карты расширения уровня 2 +- 1x улучшение уровня 1 +- 1x улучшение уровня 2 +- 1x улучшение уровня 3 + +Корпус дрона 4 уровня (креатив) позволяет использовать следующие компоненты: +- 1x [процессор](cpu3.md) уровня 3 +- 2x [планка памяти](ram5.md) уровня 3 +- 1x [EEPROM](eeprom.md) +- 3x карты расширения уровня 3 +- 9x улучшений уровня 3 \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/droneCase2.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/droneCase2.md new file mode 100644 index 000000000..702933ee7 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/droneCase2.md @@ -0,0 +1 @@ +#REDIRECT droneCase1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/droneCaseCreative.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/droneCaseCreative.md new file mode 100644 index 000000000..702933ee7 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/droneCaseCreative.md @@ -0,0 +1 @@ +#REDIRECT droneCase1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/eeprom.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/eeprom.md new file mode 100644 index 000000000..11b46adb5 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/eeprom.md @@ -0,0 +1,7 @@ +# EEPROM + +![Начнем вечеринку.](oredict:oc:eeprom) + +EEPROM содержит код, который позволяет загрузить компьютер. Эти данные хранятся в виде простого массива байт, и могут различаться на [процессорах](cpu1.md) другой архитектуры. Например, для Lua обычно используют маленький скрипт, который ищет сценарий инициализации в файловой системе, для других архитектур это может быть другой машинный код. + +С помощью EEPROM могут быть запрограммированы [дроны](drone.md) и [микроконтроллеры](microcontroller.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/experienceUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/experienceUpgrade.md new file mode 100644 index 000000000..de53370f9 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/experienceUpgrade.md @@ -0,0 +1,9 @@ +# Улучшение - Опыт + +![Почувствуй силу.](oredict:oc:experienceUpgrade) + +Данное улучшение имеет особый характер, оно позволяет [роботам](../block/robot.md) и [дронам](drone.md) получать опыт, за выполнение различных действий, таких как добыча руд и убийство животных. Одно улучшение может хранить до 30 уровней опыта, добавляя различные бонусы с каждым уровнем, включая увеличение скорости передвижения или увеличения энергохранилища. + +[Роботы](../block/robot.md) роботы уровня 10 и выше получают золотистый оттенок, [роботы](../block/robot.md) уровня 20 и выше получают алмазный оттенок. + +Опыт хранится в самом улучшении, таким образом, переставив улучшение в другого робота, вы переместите опыт на него. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/floppy.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/floppy.md new file mode 100644 index 000000000..28fa1e4b8 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/floppy.md @@ -0,0 +1,5 @@ +# Дискета + +![Уберите от телефона.](oredict:oc:floppy) + +Дискета это самое простое и дешевое средство хранения информации в OpenComputers. На начальных этапах это единственный способ переноса программ между [компьютерами](../general/computer.md) и [роботами](../block/robot.md). Вы также можете найти дискеты в сокровищницах. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/generatorUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/generatorUpgrade.md new file mode 100644 index 000000000..b80948652 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/generatorUpgrade.md @@ -0,0 +1,7 @@ +# Улучшение - Генератор + +![Генератор X.](oredict:oc:generatorUpgrade) + +Улучшение позволяет устройствам заряжать себя. В данный момент поддерживается только твердое топливо, например уголь. Внутренний инвентарь генератора может хранить только один стак топлива. Топливо может быть убрано из генератора с помощью API. При вынимании генератора из [робота](../block/robot.md), его содержимое выпадает в игровой мир. + +Эффективность генераторов ниже, чем у генераторов в других модах, но этого должно хватить до [перезарядки](../block/charger.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/graphicsCard1.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/graphicsCard1.md new file mode 100644 index 000000000..441ae7fc5 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/graphicsCard1.md @@ -0,0 +1,7 @@ +# Видеокарта + +![Красивые картинки.](oredict:oc:graphicsCard1) + +Видеокарта является неотъемлемой частью большинства [компьютеров](../general/computer.md) и позволяет [компьютеру](../general/computer.md) выводить изображение на подключенный [монитор](../block/screen1.md). Видеокарты имеют несколько уровней, также как и [мониторы](../block/screen1.md), они поддерживают различные разрешения и глубину цвета. + +Другое отличие видеокарт разного уровня состоит в различном количестве операций, которые видеокарта может выполнить за тик. Приведенные в подсказках значения актуальны для [компьютеров](../general/computer.md) с [процессором](cpu1.md) второго уровня. Процессоры первого уровня немного медленнее, а третьего немного быстрее. Числа представлены для различных операций, выполняемых видеокартой: `copy` (копирование), `fill` (заполнение), `set` (установка), `setBackground` (установка заднего фона) и `setForeground` (установка основного фона), соответственно. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/graphicsCard2.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/graphicsCard2.md new file mode 100644 index 000000000..2503631a4 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/graphicsCard2.md @@ -0,0 +1 @@ +#REDIRECT graphicsCard1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/graphicsCard3.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/graphicsCard3.md new file mode 100644 index 000000000..2503631a4 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/graphicsCard3.md @@ -0,0 +1 @@ +#REDIRECT graphicsCard1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/hdd1.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/hdd1.md new file mode 100644 index 000000000..b746fe12a --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/hdd1.md @@ -0,0 +1,5 @@ +# Жесткий диск + +![Место....](oredict:oc:hdd1) + +Жесткие диски это самое продвинутое хранилище информации в OpenComputers. Все виды жестких дисков имеют одинаковую скорость работы, но разный объем памяти. Некоторые устройства могут использовать только жесткие диски (хотя серверы могут использовать внешний [дисковод](../block/diskDrive.md), например). Жесткие диски могут быть объединены в [RAID](../block/raid.md), благодаря чему несколько жестких дисков будут работать как один большой. При объединении жестких дисков в [RAID](../block/raid.md) вся информация на них будет стерта. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/hdd2.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/hdd2.md new file mode 100644 index 000000000..31a59d438 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/hdd2.md @@ -0,0 +1 @@ +#REDIRECT hdd1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/hdd3.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/hdd3.md new file mode 100644 index 000000000..31a59d438 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/hdd3.md @@ -0,0 +1 @@ +#REDIRECT hdd1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/index.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/index.md new file mode 100644 index 000000000..0e668022e --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/index.md @@ -0,0 +1,83 @@ +# Предметы + +Здесь представлен список предметов, доступных в OpenComputers. Если вы ищете блоки, проверьте [список блоков](../block/index.md). + +Некоторые блоки могут быть недоступны, в зависимости от рецепта. + +## Инструменты +* [Анализатор](analyzer.md) +* [Руководство](manual.md) +* [Терминал](terminal.md) +* [Выбор текстур](texturePicker.md) +* [Ключ](wrench.md) + +## Устройства +* [Дрон](drone.md) +* [Сервер](server1.md) +* [Планшет](tablet.md) + +## Компоненты + +### Карты +* [Карта абстрактной шины](abstractBusCard.md) +* [Отладочная карта](debugCard.md) +* [Видеокарта](graphicsCard1.md) +* [Интернет карта](internetCard.md) +* [Связанная карта](linkedCard.md) +* [Сетевая карта](lanCard.md) +* [Редстоун карта](redstoneCard1.md) +* [Беспроводная сетевая карта](wlanCard.md) +* [Мировой сенсор](worldSensorCard.md) + +### Улучшения +* [Ангельское](angelUpgrade.md) +* [Аккумулятор](batteryUpgrade1.md) +* [Хранилище карт](cardContainer1.md) +* [Чанклоадер](chunkloaderUpgrade.md) +* [Верстак](craftingUpgrade.md) +* [База данных](databaseUpgrade1.md) +* [Опыт](experienceUpgrade.md) +* [Генератор](generatorUpgrade.md) +* [Контроллер инвентаря](inventoryControllerUpgrade.md) +* [Инвентарь](inventoryUpgrade.md) +* [Поводок](leashUpgrade.md) +* [Навигация](navigationUpgrade.md) +* [Поршень](pistonUpgrade.md) +* [Табличка](signUpgrade.md) +* [Солнечная панель](solarGeneratorUpgrade.md) +* [Контроллер жидкости](tankControllerUpgrade.md) +* [Жидкость](tankUpgrade.md) +* [Притягивающий луч](tractorBeamUpgrade.md) +* [Улучшение](upgradeContainer1.md) + +### Другое +* [Компонентная шина](componentBus1.md) +* [Процессор](cpu1.md) +* [EEPROM](eeprom.md) +* [Дискета](floppy.md) +* [Жесткий диск](hdd1.md) +* [Оперативная память (RAM)](ram1.md) + +## Крафт +* [Кислота](acid.md) +* [АЛУ](alu.md) +* [Стрелочки](arrowKeys.md) +* [Группа кнопок](buttonGroup.md) +* [Карта](card.md) +* [Печатная плата](circuitBoard.md) +* [Блок управления](controlUnit.md) +* [Проволока](cuttingWire.md) +* [Диск](disk.md) +* [Интерсеть](interweb.md) +* [Микрочип](chip1.md) +* [Цифровая клавиатура](numPad.md) +* [Отпечатанная печатная плата](printedCircuitBoard.md) +* [Заготовка печатной платы](rawCircuitBoard.md) +* [Транзистор](transistor.md) + +## Сборка / Печать +* [Хамелиум](chamelium.md) +* [Картиридж с чернилами](inkCartridge.md) +* [Корпус дрона](droneCase1.md) +* [Корпус микроконтроллера](microcontrollerCase1.md) +* [Корпус планшета](tabletCase1.md) diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/inkCartridge.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/inkCartridge.md new file mode 100644 index 000000000..93e92d2c8 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/inkCartridge.md @@ -0,0 +1,5 @@ +# Картридж с чернилами + +![Цвета радуги.](oredict:oc:inkCartridge) + +Картридж с чернилами используется для цветной печати в [3D принтерах](../block/printer.md). Также можно перезаправить их используя краски, но это не очень эффективно. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/inkCartridgeEmpty.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/inkCartridgeEmpty.md new file mode 100644 index 000000000..2895df3c8 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/inkCartridgeEmpty.md @@ -0,0 +1 @@ +#REDIRECT inkCartridge.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/internetCard.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/internetCard.md new file mode 100644 index 000000000..4920fd05d --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/internetCard.md @@ -0,0 +1,7 @@ +# Интернет карта + +![Видео с котиками через 3, 2, ...](oredict:oc:internetCard) + +Интернет карта позволяет [компьютерам](../general/computer.md) выходить в интернет. Она позволяет выполнять простые HTTP запросы, а также открывать, читать и писать в TCP сокеты. + +Установка интернет карты в [компьютер](../general/computer.md) добавляет несколько интернет приложений, например приложение для загрузки/выгрузки программ в pastebin также как это делает `wget` в Linux. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/interweb.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/interweb.md new file mode 100644 index 000000000..28f1beea1 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/interweb.md @@ -0,0 +1,5 @@ +# Интерсеть + +![Вебсайт это место для видео о котиках.](oredict:oc:materialInterweb) + +Основной компонент для приборов дальней связи. Данный компонент использует странную механику, основанную на квантовой передаче сообщений через верхний мир. В основном используется для [интернет карт](internetCard.md) и [соединенных карт](linkedCard.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/inventoryControllerUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/inventoryControllerUpgrade.md new file mode 100644 index 000000000..be1396e4a --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/inventoryControllerUpgrade.md @@ -0,0 +1,7 @@ +# Улучшение - Контроллер инвентаря + +![Я контролирую все.](oredict:oc:inventoryControllerUpgrade) + +Контроллер инвентаря добавляет еще больше действий с инвентарем для [роботов](../block/robot.md) и [дронов](drone.md). Это позволяет устройству явно указывать слоты для внешних инвентарей. Также позволяет получать подробную информацию о стаках предметов. Напоследок позволяет [роботам](../block/robot.md) менять инструменты в зависимости от блока, без посторонней помощи. + +Данное улучшение может быть вставлено в [адаптеры](../block/adapter.md), что добавит дополнительные методы работы с инвентарем для [адаптера](../block/adapter.md) также как для [робота](../block/robot.md). Это не позволяет [адаптеру](../block/adapter.md) перемещать предметы в/из инвентари. Данная функция доступна только для [роботов](../block/robot.md) и [дронов](drone.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/inventoryUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/inventoryUpgrade.md new file mode 100644 index 000000000..88c3a4851 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/inventoryUpgrade.md @@ -0,0 +1,7 @@ +# Улучшение - Инвентарь + +![Ты сможешь взять это...](oredict:oc:inventoryUpgrade) + +Улучшение позволяет добавить слоты инвентаря для [роботов](../block/robot.md) и [дронов](drone.md). Каждое улучшение дает [роботу](../block/robot.md) 16 дополнительных слотов, максимум можно получить 64 слота; а для [дронов](drone.md) можно добавить 4 слота с каждым апгрейдом, максимум 8 слотов. + +Если данное улучшение не установлено в устройство, то оно не сможешь хранить в себе предметы. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/lanCard.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/lanCard.md new file mode 100644 index 000000000..7094ef65b --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/lanCard.md @@ -0,0 +1,5 @@ +# Сетевая карта + +![Войди в сеть.](oredict:oc:lanCard) + +Сетевая карта позволяет [компьютерам](../general/computer.md) отправлять и получать сетевые сообщения. Сообщения (или пакеты) будут отправлены всем принимающим устройствам в подсети или конкретной сетевой карте (после указания ее адреса). [Коммутаторы](../block/switch.md) и [точки доступа](../block/accessPoint.md) могут быть использованы для связи нескольких подсетей друг с другом, для передачи сообщений в них. Также возможно отправить письмо получателю, даже если он находится в другой подсети, если сеть подключена к одному или нескольким [коммутаторам](../block/switch.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/leashUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/leashUpgrade.md new file mode 100644 index 000000000..aa050db4d --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/leashUpgrade.md @@ -0,0 +1,5 @@ +# Улучшение - Поводок + +![-redacted- ~ Vexatos 2015](oredict:oc:leashUpgrade) + +Позволяет использовать поводок для животных, что позволяет привязывать их к различным устройствам, например [дронам](drone.md). При использовании этого улучшения, множество животных может быть привязано одновременно. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/linkedCard.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/linkedCard.md new file mode 100644 index 000000000..9cdfcb56f --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/linkedCard.md @@ -0,0 +1,5 @@ +# Соединенные карты + +![Я чувствую, что мы связаны.](oredict:oc:linkedCard) + +Соединенные карта это специальная продвинутая версия [сетевой карты](lanCard.md). Они могут работать только в паре, образуя соединение точка-точка между картами. Соединенные карты могут передавать данные через больше (бесконечно) расстояние, а также между измерениями. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/manual.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/manual.md new file mode 100644 index 000000000..965a0b802 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/manual.md @@ -0,0 +1,15 @@ +# Руководство + +![Я прочитаю ее.](oredict:oc:manual) + +Что вы сейчас читаете? Данное руководство содержит большой объем информации о моде OpenComputers. Если вам нужна информация о блоке или предмете, смотрите дальше! Пролистайте ниже, для просмотра информации (с помощью колесика мыши. + +![Ваш новый лучший друг.](opencomputers:doc/img/manual.png) + +Навигация по данному руководству подобна просмотру Wiki: кликните на ссылку (1) для перехода к упоминаемой странице. Правой клик или кнопка прыжка вернут вас на обратную страницу. Кнопка Esc или кнопка закрытия инвентаря закроют руководство. Слева вы найдете несколько вкладок (2), благодаря которым вы можете быстро перейти на нужную страницу, например список предметов или блоков. Справа видна полоса прокрутки (3). Вы можете двигать ее вручную или использовать колесико мышки. + +Руководство запомнит страницу, на которой вы остановились, даже если вы его закрыли. Вы можете начать сначала, открыв его с зажатой клавишей Shift. Вы также можете перейти на страницу о нужном блоке, кликнув правой кнопкой мыши на блоке с данным руководством в руке. + +Если у вас остались вопросы, вы можете ознакомиться с [Wiki](http://ocdoc.cil.li), [IRC каналом](http://webchat.esper.net/?channels=#oc) и [форумом](http://oc.cil.li/). + +Если вы нашли ошибки в данном руководстве или ошибки в моде, дайте нам знать [через Issues](https://github.com/MightyPirates/OpenComputers/issues) на GitHub. Если вы хотите внести свой вклад в данное руководство или изменить содержание, напишите нам в IRC или создайте ticket в Issues на GitHub. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/microcontrollerCase1.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/microcontrollerCase1.md new file mode 100644 index 000000000..a0b1704c9 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/microcontrollerCase1.md @@ -0,0 +1,31 @@ +# Корпус микроконтроллера + +![Он такой милый.](oredict:oc:microcontrollerCase1) + +Корпус микроконтроллера используется для создания [микроконтроллеров](../block/microcontroller.md) в [сборщике роботов](../block/assembler.md). [Микроконтроллеры](../block/microcontroller.md) это очень примитивные [компьютеры](../general/computer.md). Они содержат только очень ограниченный набор компонентов и используются в специфических задачах, например реакция на редстоун сигнал или обработка сетевых сообщений. + +Они не имеют файловой системы. Могут быть запрограммированы только с помощью [EEPROM](eeprom.md). Он может быть заменен на другой, при крафте [микроконтроллера](../block/microcontroller.md) с другим чипом. При этом, старый [EEPROM](eeprom.md) вернется в ваш инвентарь. + +Они также требуют энергии, для работы, но потребляют очень малое ее количество. + +Микроконтроллер 1 уровня может использовать следующие компоненты: +- 1x [процессор](cpu1.md) уровня 1 +- 1x [планка памяти](ram1.md) уровня 1 +- 1x [EEPROM](eeprom.md) +- 2x карты расширения уровня 1 +- 1x улучшение уровня 2 + +Микроконтроллер 2 уровня может использовать следующие компоненты: +- 1x [процессор](cpu1.md) уровня 1 +- 2x [планки памяти](ram1.md) уровня 1 +- 1x [EEPROM](eeprom.md) +- 1x карту расширения уровня 2 +- 1x карту расширения уровня 1 +- 1x улучшение уровня 3 + +Микроконтроллер 3 уровня может использовать следующие компоненты: +- 1x [процессор](cpu3.md) уровня 3 +- 2x [планки памяти](ram5.md) уровня 3 +- 1x [EEPROM](eeprom.md) +- 3x карты расширения уровня 3 +- 9x улучшений уровня 3 \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/microcontrollerCase2.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/microcontrollerCase2.md new file mode 100644 index 000000000..d3a9af68d --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/microcontrollerCase2.md @@ -0,0 +1 @@ +#REDIRECT microcontrollerCase1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/microcontrollerCaseCreative.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/microcontrollerCaseCreative.md new file mode 100644 index 000000000..d3a9af68d --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/microcontrollerCaseCreative.md @@ -0,0 +1 @@ +#REDIRECT microcontrollerCase1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/navigationUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/navigationUpgrade.md new file mode 100644 index 000000000..3d8036c4c --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/navigationUpgrade.md @@ -0,0 +1,7 @@ +# Улучшение - Навигация + +![Я потерялся. Снова.](oredict:oc:navigationUpgrade) + +Данное улучшение добавляет навигацию и ориентацию для устройств. Получаемые координаты начинаются от центра карты, где было собрано улучшение, радиус функционирования зависит от размера карты. + +Карта внутри улучшения может быть обновлена, повторным крафтом улучшения с новой картой. Старая карта при этом будет возвращена игроку. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/numPad.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/numPad.md new file mode 100644 index 000000000..84c65dd8a --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/numPad.md @@ -0,0 +1,5 @@ +# Цифровая клавиатура (NumPad) + +![Проверка на отпечатки.](oredict:oc:materialNumPad) + +Цифровая клавиатура часть [клавиатуры](../block/keyboard.md). Позволяет вводить цифры. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/pistonUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/pistonUpgrade.md new file mode 100644 index 000000000..3cc740f67 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/pistonUpgrade.md @@ -0,0 +1,7 @@ +# Улучшение - Поршень + +![Толкни это](oredict:oc:pistonUpgrade) + +Улучшение - поршень позволяет некоторым устройствам работать так же, как и обычный поршень. После установки, вам будет доступен компонент с одним методом `push()`. При вызове данного метода, устройство попытается сдвинуть блок, находящийся перед ним. Для [роботов](../block/robot.md) и [микроконтроллеров](../block/microcontroller.md) это передняя сторона; для [планшетов](tablet.md) будет использовано направление, куда смотрит игрок. + +Логика работы улучшения аналогична обычным поршням. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/printedCircuitBoard.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/printedCircuitBoard.md new file mode 100644 index 000000000..fd4828b20 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/printedCircuitBoard.md @@ -0,0 +1,5 @@ +# Отпечатанная печатная плата + +![AKA PCB](oredict:oc:materialCircuitBoardPrinted) + +Второй по популярности компонент крафта, после [транзистора](transistor.md) в OpenComputers. Используется как основа для множества компонентов, например [карт](card.md) и большого количества [блоков](../block/index.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/ram1.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/ram1.md new file mode 100644 index 000000000..2c70caaf3 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/ram1.md @@ -0,0 +1,17 @@ +# Оперативная память + +![Без нее никуда](oredict:oc:ram1) + +Память, также как [Процессор](cpu1.md) это неотъемлемая часть [компьютеров](../general/computer.md). В зависимости от архитектуры [процессора](cpu1.md), именно память отвечает за то, что [компьютеры](../general/computer.md) могут сделать, а что нет. Для стандартной архитектуры Lua, например, это позволяет контролировать количество память, которое будет использовано Lua скриптами. Это значит, что для запуска больших и требовательных программ вам потребуется больше памяти. + +Оперативная память имеет несколько уровней, в зависимости от ее объема, по умолчанию: +- Уровень 1: 192КБ +- Уровень 1.5: 256КБ +- Уровень 2: 384КБ +- Уровень 2.5: 512КБ +- Уровень 3: 768КБ +- Уровень 3.5: 1024КБ + +Следует заметить, что данные значения применимы только к архитектуре Lua. Другие архитектуры могут использовать другие объемы памяти на других уровнях. Также следует заметить, что память первого уровня и память уровня 1.5 относятся к первому уровню, аналогично для уровней 2 и 3. + +Эта параметры могут быть изменены в файле конфигурации, если потребуется. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/ram2.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/ram2.md new file mode 100644 index 000000000..94679a04e --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/ram2.md @@ -0,0 +1 @@ +#REDIRECT ram1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/ram3.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/ram3.md new file mode 100644 index 000000000..94679a04e --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/ram3.md @@ -0,0 +1 @@ +#REDIRECT ram1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/ram4.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/ram4.md new file mode 100644 index 000000000..94679a04e --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/ram4.md @@ -0,0 +1 @@ +#REDIRECT ram1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/ram5.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/ram5.md new file mode 100644 index 000000000..94679a04e --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/ram5.md @@ -0,0 +1 @@ +#REDIRECT ram1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/ram6.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/ram6.md new file mode 100644 index 000000000..94679a04e --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/ram6.md @@ -0,0 +1 @@ +#REDIRECT ram1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/rawCircuitBoard.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/rawCircuitBoard.md new file mode 100644 index 000000000..f71aae80b --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/rawCircuitBoard.md @@ -0,0 +1,5 @@ +# Заготовка печатной платы + +![Не суши.](oredict:oc:materialCircuitBoardRaw) + +Компонент крафта, используется для создания [печатной платы](circuitBoard.md) (или [отпечатанной печатной платы](printedCircuitBoard.md), в зависимости от рецепта). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/redstoneCard1.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/redstoneCard1.md new file mode 100644 index 000000000..312986e02 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/redstoneCard1.md @@ -0,0 +1,9 @@ +# Редстоун карта + +![Вижу красный.](oredict:oc:redstoneCard1) + +Редстоун карта позволяет [компьютерам](../general/computer.md) принимать и излучать вокруг себя редстоун сигнал. Когда сила входящего сигнала изменяется, он попадает в [компьютер](../general/computer.md). + +Если у вас установлен любой из модов, которые добавляют многожильные провода, такие как RedLogic, Project Red или MineFactory Reloaded и иные, вы в полной мере можете взаимодействовать и с ними. + +Сторона сигнала аналогична стороне [системного блока](../block/case1.md) / [робота](../block/robot.md) / [серверной стойки](../block/serverRack.md). Это означает, что если вы смотрите на компьютер спереди, `sides.right` будет слева от вас. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/redstoneCard2.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/redstoneCard2.md new file mode 100644 index 000000000..7480d5267 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/redstoneCard2.md @@ -0,0 +1 @@ +#REDIRECT redstoneCard1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/server1.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/server1.md new file mode 100644 index 000000000..768206505 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/server1.md @@ -0,0 +1,39 @@ +# Сервер + +![Так тебе и надо.](oredict:oc:server1) + +Серверы это форма самых продвинутых [компьютеров](../general/computer.md). Они могут быть сконфигурированы где угодно. После вставки [процессора](cpu1.md), [памяти](ram1.md) и платы расширения, сервер должен быть помещен в [серверную стойку](../block/serverRack.md). Подробнее читайте в статье про [серверную стойку](../block/serverRack.md). + +Сервер уровня 1 может содержать следующие компоненты: +- 1x [процессор](cpu2.md) уровня 2 +- 2x [планки памяти](ram3.md) уровня 2 +- 2x [жестких диска](hdd2.md) уровня 2 +- 1x [компонентную шину](componentBus2.md) уровня 2 +- 2x платы расширения уровня 2 +- 1x [EEPROM](eeprom.md) + +Сервер уровня 2 может содержать следующие компоненты: +- 1x [процессор](cpu2.md) уровня 3 +- 3x [планки памяти](ram5.md) уровня 3 +- 3x [жестких диска](hdd3.md) уровня 3 +- 2x [компонентных шины](componentBus3.md) уровня 3 +- 2x платы расширения уровня 2 +- 1x плату расширения уровня 3 +- 1x [EEPROM](eeprom.md) + +Сервер уровня 3 может содержать следующие компоненты: +- 1x [процессор](cpu2.md) уровня 3 +- 4x [планки памяти](ram5.md) уровня 3 +- 4x [жестких диска](hdd3.md) уровня 3 +- 3x [компонентных шины](componentBus3.md) уровня 3 +- 2x платы расширения уровня 2 +- 2x платы расширения уровня 3 +- 1x [EEPROM](eeprom.md) + +Сервер уровня 4 (креатив) может содержать следующие компоненты: +- 1x [процессор](cpu2.md) уровня 3 +- 4x [планки памяти](ram5.md) уровня 3 +- 4x [жестких диска](hdd3.md) уровня 3 +- 3x [компонентных шины](componentBus3.md) уровня 3 +- 4x платы расширения уровня 3 +- 1x [EEPROM](eeprom.md) diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/server2.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/server2.md new file mode 100644 index 000000000..d02b2f850 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/server2.md @@ -0,0 +1 @@ +#REDIRECT server1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/server3.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/server3.md new file mode 100644 index 000000000..d02b2f850 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/server3.md @@ -0,0 +1 @@ +#REDIRECT server1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/serverCreative.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/serverCreative.md new file mode 100644 index 000000000..d02b2f850 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/serverCreative.md @@ -0,0 +1 @@ +#REDIRECT server1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/signUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/signUpgrade.md new file mode 100644 index 000000000..3aec655a6 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/signUpgrade.md @@ -0,0 +1,5 @@ +# Улучшение - Таблички + +![Я вижу надписи на стенах.](oredict:oc:signUpgrade) + +Данное улучшение позволяет устройствам взаимодействовать с табличками. Позволяет читать сообщение, указанное на табличке, а также менять его (если разрешено). \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/solarGeneratorUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/solarGeneratorUpgrade.md new file mode 100644 index 000000000..69f232c1a --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/solarGeneratorUpgrade.md @@ -0,0 +1,7 @@ +# Улучшение - Солнечная панель + +![Я на солнышке лежу.](oredict:oc:solarGeneratorUpgrade) + +Данное улучшение может быть установлено в такие устройства как, [роботы](../block/robot.md), [дроны](drone.md) и [планшеты](tablet.md) для пассивной генерации энергии. Генерация энергии происходит только под прямыми солнечными лучами и не происходит в дождь или в помещении. + +Энергии генерируется сравнительно небольшое количество, но этого обычно хватает, до [перезарядки](../block/charger.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/tablet.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/tablet.md new file mode 100644 index 000000000..5f60f02e0 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/tablet.md @@ -0,0 +1,13 @@ +# Планшет + +![Дотронься, если сможешь.](item:OpenComputers:item@68) + +Планшеты можно скрафтить поместив [корпус планшета](tabletCase1.md) в [сборщик роботов](../block/assembler.md), настроив их и в итоге собрав готовый. Планшеты как переносные компьютеры, не могут напрямую взаимодействовать с игровым миром - например, простые [редстоун карты](redstoneCard1.md) не работают с ними. Количество улучшений также ограничено, это может быть улучшение для работы с [табличками](signUpgrade.md) или [поршнями](pistonUpgrade.md). + +Планшеты второго уровня позволяют установить одно улучшение - контейнер. Слот, добавленный контейнером, может быть открыт дополнительным интерфейсом планшета, при клике правой кнопкой мыши с зажатой клавишей Shift с планшетом в руке. Это также принудительно выключит планшет. + +В отличие от компьютеров, планшеты не сохраняют состояние, когда игрок входит/выходит в игру. Также они не сохраняют свое состояние при перемещении между мирами (например, в ад и обратно). + +Планшеты можно поместить в [зарядное устройство](../block/charger.md), чтобы зарядить их и получить доступ к первому [жесткому диску](hdd1.md) в планшете из [компьютера](../general/computer.md) соединенного с зарядным устройством - в данной установке, зарядки будет вести себя аналогично [дисководу](../block/diskDrive.md), с планшетом вместо [дискеты](floppy.md). Это полезно, если вы забыли установить операционную систему на жесткий диск перед сборкой планшета или случайно повредили ее. + +Другой особенностью планшетов является возможность генерации сигналов с информацией об определенных блоках в игровом мире. Короткий звук означает, что сигнал сгенерирован. Это работает, если установлено улучшение, позволяющее генерировать эту информацию. Например, [анализатор](../block/geolyzer.md) добавляет информацию о блоке, его прочности, [навигационное улучшение](navigationUpgrade.md) добавляет координаты блока. Проанализированный будет подсвечен зеленым. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/tabletCase1.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/tabletCase1.md new file mode 100644 index 000000000..b2ff26c6b --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/tabletCase1.md @@ -0,0 +1,39 @@ +# Корпус планшета + +![Не сгибать.](oredict:oc:tabletCase1) + +Корпус планшета используется для создания [планшетов](tablet.md) в [сборщике](../block/assembler.md). [Планшеты](tablet.md) миниатюрные и переносимые [компьютеры](../general/computer.md). Они могут содержать несколько улучшений, но не могут взаимодействовать с игровым миром, как [системный блок](../block/case1.md) могут (использовать простые [сетевые карты](lanCard.md) или [редстоун карту](redstoneCard1.md)). + +Улучшения и карты, которые не могут быть использованы в [планшетах](tablet.md) не могут быть помещены в [сборщик роботов](../block/assembler.md). Если улучшение было установлено в [сборщике роботов](../block/assembler.md), значит оно доступно через API. + +При нахождении в инвентаре игрока, они продолжают работать. Если их поместить в другой инвентарь и выкинуть, они выключатся через некоторое время. + +Корпус планшета 1 уровня может содержать следующие компоненты: +- 1x [процессор уровня 2](cpu2.md) +- 2x [планки памяти уровня 2](ram3.md) +- 1x [жесткий диск уровня 2](hdd2.md) +- 2x карты расширения уровня 2 +- 1x [EEPROM](eeprom.md) +- 1x улучшение уровня 1 +- 1x улучшение уровня 2 +- 1x улучшение уровня 3 + +Корпус планшета 2 уровня может содержать следующие компоненты: +- 1x [процессор уровня 3](cpu3.md) +- 2x [планки памяти уровня 2](ram3.md) +- 1x [жесткий диск уровня 2](hdd2.md) +- 1x карту расширения уровня 2 +- 1x карту расширения уровня 3 +- 1x [EEPROM](eeprom.md) +- 2x улучшения уровня 2 +- 1x улучшение уровня 3 +- 1x [Улучшение](upgradeContainer2.md) или [Контейнер карт](cardContainer2.md) уровня 2 + +Корпус планшета 4 уровня (креатив) может содержать следующие компоненты: +- 1x [процессор уровня 3](cpu3.md) +- 2x [планки памяти уровня 3](ram5.md) +- 1x [жесткий диск уровня 3](hdd3.md) +- 3x карты расширения уровня 3 +- 1x [EEPROM](eeprom.md) +- 9x улучшений уровня 3 +- 1x [Улучшение](upgradeContainer3.md) или [Контейнер карт](cardContainer3.md) уровня 3 \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/tabletCase2.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/tabletCase2.md new file mode 100644 index 000000000..325fd0f57 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/tabletCase2.md @@ -0,0 +1 @@ +#REDIRECT tabletCase1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/tabletCaseCreative.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/tabletCaseCreative.md new file mode 100644 index 000000000..325fd0f57 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/tabletCaseCreative.md @@ -0,0 +1 @@ +#REDIRECT tabletCase1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/tankControllerUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/tankControllerUpgrade.md new file mode 100644 index 000000000..883499f50 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/tankControllerUpgrade.md @@ -0,0 +1,7 @@ +# Улучшение - Контроллер бака + +![Туда сюда.](oredict:oc:tankControllerUpgrade) + +Контроллер бака, аналогичен [контроллеру инвентаря](inventoryControllerUpgrade.md), только для жидкостей. Позволяет устройствам получать подробную информацию о баках и их содержимом. + +Это улучшение может быть установлено в [адаптеры](../block/adapter.md), позволяя [компьютерам](../general/computer.md), подключенным к [адаптеру](../block/adapter.md) запрашивать информацию о баках, прилегающих к [адаптеру](../block/adapter.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/tankUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/tankUpgrade.md new file mode 100644 index 000000000..f50a7e4cb --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/tankUpgrade.md @@ -0,0 +1,5 @@ +# Улучшение - бак для жидкости + +![Высоси это.](oredict:oc:tankUpgrade) + +Позволяет устройства хранить жидкости. Каждый бак может хранить только жидкость одного типа и объемом не более 16 ведер (16000mB). [Роботы](../block/robot.md) и [дроны](drone.md) могут выкачивать жидкости из игрового мира, а также из других баков. Также они могут снова заполнять баки жидкостями и обратно выливать их (в зависимости от жидкости). Вы можете установить любое количество улучшение этого вида в устройство. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/terminal.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/terminal.md new file mode 100644 index 000000000..9c9da5d63 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/terminal.md @@ -0,0 +1,9 @@ +# Удаленный терминал + +![Удаленный доступ.](oredict:oc:terminal) + +Терминал может быть использован для контроля [серверов](server1.md). Для использования терминала, кликните им по серверу в [серверной стойке](../block/serverRack.md) (кликните по блоку [серверной стойки](../block/serverRack.md), в нужный [сервер](server1.md) для привязки терминала к нему). + +Когда терминал привязан к [серверу](server1.md),к серверу будут подключены виртуальный [монитор](../block/screen1.md) и [клавиатура](../block/keyboard.md). Это может привести к неожиданному поведению реального монитора и клавиатуры, подключенных к серверу. При использовании терминала вы сможете печатать, как будто к серверу подключена обычная [клавиатура](../block/keyboard.md) и [монитор](../block/screen1.md). + +К одному [серверу](server1.md) могут быть подключены несколько терминалов, однако все они будут показывать одинаковую информацию. Максимальное количество терминалов, которое может быть подключено к [серверу](server1.md) зависит от уровня [сервера](server1.md). Дальность действия терминалов, относительно [серверной стойки](../block/serverRack.md) настраивается в файле конфигурации. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/texturePicker.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/texturePicker.md new file mode 100644 index 000000000..d7d3114b2 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/texturePicker.md @@ -0,0 +1,7 @@ +# Выбор текстур + +![Что это за цвет?](oredict:oc:texturePicker) + +Данный предмет будет в первую очередь удобен для [3D принтеров](../block/printer.md). Позволяет узнать название текстуры блока, установленного в мире, достаточно просто кликнуть на блок. Обратите внимание: для блоков с особым рендером, таких как сундуки, это может не сработать. + +Вы можете выбрать любую текстуру и узнать ее название, а узнав текстуры, использовать его [3D печати](../block/print.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/tractorBeamUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/tractorBeamUpgrade.md new file mode 100644 index 000000000..a9111aaf7 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/tractorBeamUpgrade.md @@ -0,0 +1,5 @@ +# Улучшение - Притягивающий луч + +![Пошли со мной.](oredict:oc:tractorBeamUpgrade) + +Данное улучшение позволяет устройства подбирать предметы в радиусе 3 блоков вокруг себя. Это очень удобно использовать в [роботах](../block/robot.md) на любой из ферм или если вы можете ломать несколько блоков вокруг себя (как инструменты из Tinker's Construct). Каждая операция пытается подобрать один стак предметов вокруг себя, а также затрачивает некоторое количество энергии. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/transistor.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/transistor.md new file mode 100644 index 000000000..9bc64bcf7 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/transistor.md @@ -0,0 +1,5 @@ +# Транзистор + +![Транзистор.](oredict:oc:materialTransistor) + +Самый простой элемент крафта в OpenComputers. Он используется для крафта [микрочипов](chip1.md) и иных электронных компонентов. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/upgradeContainer1.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/upgradeContainer1.md new file mode 100644 index 000000000..ab64b3b95 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/upgradeContainer1.md @@ -0,0 +1,5 @@ +# Улучшение - Контейнер + +![Можно обновляться.](oredict:oc:upgradeContainer1) + +Данное улучшение применимо к [роботам](../block/robot.md), оно добавляет готовым [роботам](../block/robot.md) место под установку еще одного улучшения. Максимальный уровень улучшения, которое может быть установлено, равен уровню контейнера. Прочтите документацию о [роботах](../block/robot.md) и [сборщике роботов](../block/assembler.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/upgradeContainer2.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/upgradeContainer2.md new file mode 100644 index 000000000..408c907f9 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/upgradeContainer2.md @@ -0,0 +1 @@ +#REDIRECT upgradeContainer1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/upgradeContainer3.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/upgradeContainer3.md new file mode 100644 index 000000000..408c907f9 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/upgradeContainer3.md @@ -0,0 +1 @@ +#REDIRECT upgradeContainer1.md \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/wlanCard.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/wlanCard.md new file mode 100644 index 000000000..097480f13 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/wlanCard.md @@ -0,0 +1,7 @@ +# Беспроводная сетевая карта + +![Может вызвать рак, а может, и нет.](oredict:oc:wlanCard) + +Беспроводная сетевая карта, это улучшенная версия [сетевой карты](lanCard.md), в дополнение к сообщениям по проводной линии, также может принимать сообщения и по беспроводной. Сила сигнала позволяет контролировать, на каком расстоянии могут быть получены сообщения, где сила равна расстоянию в блоках. + +Чем выше сила сигнала, тем больше энергии затрачивается на передачу одного сообщения. Поверхность игрового мира также влияет на возможность получения сигнала. Если силы сигнала недостаточно, получатель не получит сообщение. Данная информация еще не подтверждена учеными, но сообщения все же иногда доходят. В общем случае, расстояние между отправителем и получателем не должно содержать гор и прочих образований. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/worldSensorCard.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/worldSensorCard.md new file mode 100644 index 000000000..6164134ed --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/worldSensorCard.md @@ -0,0 +1,4 @@ +# Карта Мировой сенсор +![Для смелых...](oredict:oc:worldSensorCard) + +Данная карта позволяет получать информацию об атмосфере и гравитации, на планетах добавляемых модом GalactiCraft. Может быть использовано как в [роботах](../block/robot.md) так и [дронах](drone.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/wrench.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/wrench.md new file mode 100644 index 000000000..bb57fd513 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/wrench.md @@ -0,0 +1,5 @@ +# Ключ + +![Сделано в Швейцарии.](oredict:oc:wrench) + +Как и другие технологические моды, OpenComputers имеет свой ключ. В данном случае, это гибрид ключа и отвертки, что позволяет невероятно удобно пользоваться им. Ключ может поворачивать большинство блоков, также он может быть использован в других модах. From e1bad9735f818975dbbacec2040c85d93d0e4ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Fri, 17 Apr 2015 18:31:15 +0200 Subject: [PATCH 29/37] Centralized logic that prints last computer crash reason when analyzed. This way it'll also work for third-party machines. --- .../scala/li/cil/oc/common/entity/Drone.scala | 14 +------------- src/main/scala/li/cil/oc/common/init/Items.scala | 2 +- .../scala/li/cil/oc/common/item/Analyzer.scala | 15 +++++++++++++++ .../li/cil/oc/common/tileentity/ServerRack.scala | 14 +------------- .../oc/common/tileentity/traits/Computer.scala | 15 +-------------- 5 files changed, 19 insertions(+), 41 deletions(-) diff --git a/src/main/scala/li/cil/oc/common/entity/Drone.scala b/src/main/scala/li/cil/oc/common/entity/Drone.scala index 697a8e301..48a69bd33 100644 --- a/src/main/scala/li/cil/oc/common/entity/Drone.scala +++ b/src/main/scala/li/cil/oc/common/entity/Drone.scala @@ -206,19 +206,7 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern // ----------------------------------------------------------------------- // - override def onAnalyze(player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = { - machine.lastError match { - case value if value != null => - player.addChatMessage(Localization.Analyzer.LastError(value)) - case _ => - } - player.addChatMessage(Localization.Analyzer.Components(machine.componentCount, machine.maxComponents)) - val list = machine.users - if (list.size > 0) { - player.addChatMessage(Localization.Analyzer.Users(list)) - } - Array(machine.node) - } + override def onAnalyze(player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = Array(machine.node) // ----------------------------------------------------------------------- // diff --git a/src/main/scala/li/cil/oc/common/init/Items.scala b/src/main/scala/li/cil/oc/common/init/Items.scala index d3ee1f3a0..cbe109097 100644 --- a/src/main/scala/li/cil/oc/common/init/Items.scala +++ b/src/main/scala/li/cil/oc/common/init/Items.scala @@ -415,7 +415,7 @@ object Items extends ItemAPI { // 1.4.2 val eeprom = new item.EEPROM() Recipes.addItem(eeprom, Constants.ItemName.EEPROM, "oc:eeprom") - Recipes.addRecipe(createLuaBios(), "luaBios") + Recipes.addRecipe(createLuaBios(), Constants.ItemName.LuaBios) Recipes.addSubItem(new item.MicrocontrollerCase(multi, Tier.One), Constants.ItemName.MicrocontrollerCaseTier1, "oc:microcontrollerCase1") // 1.4.3 diff --git a/src/main/scala/li/cil/oc/common/item/Analyzer.scala b/src/main/scala/li/cil/oc/common/item/Analyzer.scala index 0fd0be0be..cf5f859fe 100644 --- a/src/main/scala/li/cil/oc/common/item/Analyzer.scala +++ b/src/main/scala/li/cil/oc/common/item/Analyzer.scala @@ -5,6 +5,7 @@ import li.cil.oc.Constants import li.cil.oc.Localization import li.cil.oc.Settings import li.cil.oc.api +import li.cil.oc.api.machine.Machine import li.cil.oc.api.network.Analyzable import li.cil.oc.api.network._ import li.cil.oc.common.tileentity @@ -59,6 +60,20 @@ object Analyzer { private def analyzeNodes(nodes: Array[Node], player: EntityPlayer) = if (nodes != null) for (node <- nodes if node != null) { player match { case playerMP: EntityPlayerMP => + if (node != null) node.host match { + case machine: Machine => + if (machine != null) { + if (machine.lastError != null) { + playerMP.addChatMessage(Localization.Analyzer.LastError(machine.lastError)) + } + playerMP.addChatMessage(Localization.Analyzer.Components(machine.componentCount, machine.maxComponents)) + val list = machine.users + if (list.length > 0) { + playerMP.addChatMessage(Localization.Analyzer.Users(list)) + } + } + case _ => + } node match { case connector: Connector => if (connector.localBufferSize > 0) { diff --git a/src/main/scala/li/cil/oc/common/tileentity/ServerRack.scala b/src/main/scala/li/cil/oc/common/tileentity/ServerRack.scala index feb1897a4..6995f4218 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/ServerRack.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/ServerRack.scala @@ -214,19 +214,7 @@ class ServerRack extends traits.PowerAcceptor with traits.Hub with traits.PowerB override def onAnalyze(player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = { slotAt(ForgeDirection.getOrientation(side), hitX, hitY, hitZ) match { case Some(slot) => servers(slot) match { - case Some(server) => - val computer = server.machine - computer.lastError match { - case value if value != null => - player.addChatMessage(Localization.Analyzer.LastError(value)) - case _ => - } - player.addChatMessage(Localization.Analyzer.Components(computer.componentCount, computer.maxComponents)) - val list = computer.users - if (list.size > 0) { - player.addChatMessage(Localization.Analyzer.Users(list)) - } - Array(computer.node) + case Some(server) => Array(server.machine.node) case _ => null } case _ => Array(sidedNode(ForgeDirection.getOrientation(side))) diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala index 205e97f6e..8e8d301bc 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala @@ -5,7 +5,6 @@ import java.util import cpw.mods.fml.relauncher.Side import cpw.mods.fml.relauncher.SideOnly -import li.cil.oc.Localization import li.cil.oc.Settings import li.cil.oc.api.Machine import li.cil.oc.api.machine.MachineHost @@ -209,17 +208,5 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B // ----------------------------------------------------------------------- // - override def onAnalyze(player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = { - machine.lastError match { - case value if value != null => - player.addChatMessage(Localization.Analyzer.LastError(value)) - case _ => - } - player.addChatMessage(Localization.Analyzer.Components(machine.componentCount, machine.maxComponents)) - val list = machine.users - if (list.size > 0) { - player.addChatMessage(Localization.Analyzer.Users(list)) - } - Array(machine.node) - } + override def onAnalyze(player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = Array(machine.node) } From d03e78b0cbe1edfd852c55ffca776641aa9a0de6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Fri, 17 Apr 2015 20:14:51 +0200 Subject: [PATCH 30/37] Made time limit enforcement in __gc wrapper more memory friendly, closes #1079. --- .../assets/opencomputers/lua/machine.lua | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/main/resources/assets/opencomputers/lua/machine.lua b/src/main/resources/assets/opencomputers/lua/machine.lua index 3402c90ec..e72d36f1f 100644 --- a/src/main/resources/assets/opencomputers/lua/machine.lua +++ b/src/main/resources/assets/opencomputers/lua/machine.lua @@ -634,6 +634,14 @@ local function spcall(...) end end +local sgcco + +local function sgcf(self, gc) + while true do + self, gc = coroutine.yield(pcall(gc, self)) + end +end + local function sgc(self) local oldDeadline, oldHitDeadline = deadline, hitDeadline local mt = debug.getmetatable(self) @@ -642,11 +650,16 @@ local function sgc(self) if type(gc) ~= "function" then return end - local co = coroutine.create(gc) - debug.sethook(co, checkDeadline, "", hookInterval) + if not sgcco then + sgcco = coroutine.create(sgcf) + end + debug.sethook(sgcco, checkDeadline, "", hookInterval) deadline, hitDeadline = math.min(oldDeadline, computer.realTime() + 0.5), true - local result, reason = coroutine.resume(co, self) - debug.sethook(co) + local _, result, reason = coroutine.resume(sgcco, self, gc) + debug.sethook(sgcco) + if coroutine.status(sgcco) == "dead" then + sgcco = nil + end deadline, hitDeadline = oldDeadline, oldHitDeadline if not result then error(reason, 0) From e4dc95580d617400e46cba179024bfdb091120af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sat, 18 Apr 2015 12:54:33 +0200 Subject: [PATCH 31/37] Emitting particle effects from robots when they try to move but fail, as a visual indicator. Added forced pause even if move fails, to avoid particle spam. Makes detect() a bit more useful (since that'll now be faster than just trying to move). --- .../li/cil/oc/client/PacketHandler.scala | 36 +++++++++++++++++++ .../scala/li/cil/oc/common/PacketType.scala | 1 + .../scala/li/cil/oc/server/PacketSender.scala | 14 ++++++++ .../li/cil/oc/server/component/Robot.scala | 6 ++++ 4 files changed, 57 insertions(+) diff --git a/src/main/scala/li/cil/oc/client/PacketHandler.scala b/src/main/scala/li/cil/oc/client/PacketHandler.scala index 5ab795ed3..ee5640be9 100644 --- a/src/main/scala/li/cil/oc/client/PacketHandler.scala +++ b/src/main/scala/li/cil/oc/client/PacketHandler.scala @@ -52,6 +52,7 @@ object PacketHandler extends CommonPacketHandler { case PacketType.HologramScale => onHologramScale(p) case PacketType.HologramSet => onHologramSet(p) case PacketType.HologramTranslation => onHologramPositionOffsetY(p) + case PacketType.ParticleEffect => onParticleEffect(p) case PacketType.PetVisibility => onPetVisibility(p) case PacketType.PowerState => onPowerState(p) case PacketType.PrinterState => onPrinterState(p) @@ -234,6 +235,41 @@ object PacketHandler extends CommonPacketHandler { case _ => // Invalid packet. } + def onParticleEffect(p: PacketParser) = { + val dimension = p.readInt() + world(p.player, dimension) match { + case Some(world) => + val x = p.readInt() + val y = p.readInt() + val z = p.readInt() + val velocity = p.readDouble() + val direction = p.readDirection() + val name = p.readUTF() + val count = p.readUnsignedByte() + + for (i <- 0 until count) { + def rv(f: ForgeDirection => Int) = direction match { + case Some(d) => world.rand.nextFloat - 0.5 + f(d) * 0.5 + case _ => world.rand.nextFloat * 2 - 1 + } + val vx = rv(_.offsetX) + val vy = rv(_.offsetY) + val vz = rv(_.offsetZ) + if (vx * vx + vy * vy + vz * vz < 1) { + def rp(x: Int, v: Double, f: ForgeDirection => Int) = direction match { + case Some(d) => x + 0.5 + v * velocity * 0.5 + f(d) * velocity + case _ => x + 0.5 + v * velocity + } + val px = rp(x, vx, _.offsetX) + val py = rp(y, vy, _.offsetY) + val pz = rp(z, vz, _.offsetZ) + world.spawnParticle(name, px, py, pz, vx, vy + velocity * 0.25, vz) + } + } + case _ => // Invalid packet. + } + } + def onPetVisibility(p: PacketParser) { val count = p.readInt() for (i <- 0 until count) { diff --git a/src/main/scala/li/cil/oc/common/PacketType.scala b/src/main/scala/li/cil/oc/common/PacketType.scala index d34b1d04f..76ce62fa1 100644 --- a/src/main/scala/li/cil/oc/common/PacketType.scala +++ b/src/main/scala/li/cil/oc/common/PacketType.scala @@ -19,6 +19,7 @@ object PacketType extends Enumeration { HologramScale, HologramSet, HologramTranslation, + ParticleEffect, PetVisibility, // Goes both ways. PowerState, PrinterState, diff --git a/src/main/scala/li/cil/oc/server/PacketSender.scala b/src/main/scala/li/cil/oc/server/PacketSender.scala index e9f652b86..c1634cab0 100644 --- a/src/main/scala/li/cil/oc/server/PacketSender.scala +++ b/src/main/scala/li/cil/oc/server/PacketSender.scala @@ -205,6 +205,20 @@ object PacketSender { pb.sendToPlayersNearTileEntity(t) } + def sendParticleEffect(position: BlockPosition, name: String, count: Int, velocity: Double, direction: Option[ForgeDirection] = None): Unit = if (count > 0) { + val pb = new SimplePacketBuilder(PacketType.ParticleEffect) + + pb.writeInt(position.world.get.provider.dimensionId) + pb.writeInt(position.x) + pb.writeInt(position.y) + pb.writeInt(position.z) + pb.writeDouble(velocity) + pb.writeDirection(direction) + pb.writeUTF(name) + pb.writeByte(count.toByte) + + pb.sendToNearbyPlayers(position.world.get, position.x, position.y, position.z, Some(32.0)) + } def sendPetVisibility(name: Option[String] = None, player: Option[EntityPlayerMP] = None) { val pb = new SimplePacketBuilder(PacketType.PetVisibility) diff --git a/src/main/scala/li/cil/oc/server/component/Robot.scala b/src/main/scala/li/cil/oc/server/component/Robot.scala index bc67759bf..0dbc66064 100644 --- a/src/main/scala/li/cil/oc/server/component/Robot.scala +++ b/src/main/scala/li/cil/oc/server/component/Robot.scala @@ -10,6 +10,8 @@ import li.cil.oc.api.network._ import li.cil.oc.api.prefab import li.cil.oc.common.ToolDurabilityProviders import li.cil.oc.common.tileentity +import li.cil.oc.server.PacketSender +import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.ExtendedNBT._ import net.minecraft.nbt.NBTTagCompound @@ -72,6 +74,8 @@ class Robot(val agent: tileentity.Robot) extends prefab.ManagedEnvironment with else { val (something, what) = blockContent(direction) if (something) { + context.pause(0.4) + PacketSender.sendParticleEffect(BlockPosition(agent), "crit", 8, 0.25, Some(direction)) result(Unit, what) } else { @@ -84,6 +88,8 @@ class Robot(val agent: tileentity.Robot) extends prefab.ManagedEnvironment with } else { node.changeBuffer(Settings.get.robotMoveCost) + context.pause(0.4) + PacketSender.sendParticleEffect(BlockPosition(agent), "crit", 8, 0.25, Some(direction)) result(Unit, "impossible move") } } From 060f3bb5d8f0cf9dd0a9d6924d7ff85b1a6dc466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sat, 18 Apr 2015 13:04:09 +0200 Subject: [PATCH 32/37] Fixed OpenOS being listed twice in creative tab/NEI. --- src/main/scala/li/cil/oc/common/init/Items.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/scala/li/cil/oc/common/init/Items.scala b/src/main/scala/li/cil/oc/common/init/Items.scala index cbe109097..6e86c49f2 100644 --- a/src/main/scala/li/cil/oc/common/init/Items.scala +++ b/src/main/scala/li/cil/oc/common/init/Items.scala @@ -256,7 +256,6 @@ object Items extends ItemAPI { def init() { val multi = new item.Delegator() { def configuredItems = Array( - createOpenOS(), createLuaBios(), createConfiguredDrone(), createConfiguredMicrocontroller(), From 87d25abcb2668e6fb0036d7b557c8a7924acaeca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sat, 18 Apr 2015 16:35:13 +0200 Subject: [PATCH 33/37] Fixed absolute paths in manual. --- src/main/java/li/cil/oc/api/prefab/ResourceContentProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/li/cil/oc/api/prefab/ResourceContentProvider.java b/src/main/java/li/cil/oc/api/prefab/ResourceContentProvider.java index 586845b6b..44d5efe68 100644 --- a/src/main/java/li/cil/oc/api/prefab/ResourceContentProvider.java +++ b/src/main/java/li/cil/oc/api/prefab/ResourceContentProvider.java @@ -40,7 +40,7 @@ public class ResourceContentProvider implements ContentProvider { @Override public Iterable getContent(String path) { - final ResourceLocation location = new ResourceLocation(resourceDomain, basePath + path); + final ResourceLocation location = new ResourceLocation(resourceDomain, basePath + (path.startsWith("/") ? path.substring(1) : path)); InputStream is = null; try { is = Minecraft.getMinecraft().getResourceManager().getResource(location).getInputStream(); From 0a14e0532eff0380c566ab079f51701de7861ef0 Mon Sep 17 00:00:00 2001 From: dgelessus Date: Sat, 18 Apr 2015 17:16:10 +0200 Subject: [PATCH 34/37] Add peaceful-friendly recipe file + small tweak to default recipes --- .../opencomputers/recipes/default.recipes | 4 +- .../opencomputers/recipes/peaceful.recipes | 75 +++++++++++++++++++ .../assets/opencomputers/recipes/user.recipes | 1 + 3 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 src/main/resources/assets/opencomputers/recipes/peaceful.recipes diff --git a/src/main/resources/assets/opencomputers/recipes/default.recipes b/src/main/resources/assets/opencomputers/recipes/default.recipes index 562a20e63..f2acb4422 100644 --- a/src/main/resources/assets/opencomputers/recipes/default.recipes +++ b/src/main/resources/assets/opencomputers/recipes/default.recipes @@ -244,12 +244,12 @@ generatorUpgrade { } inventoryUpgrade { input: [[plankWood, hopper, plankWood] - [dispenser, chest, craftingPiston] + [dropper, chest, craftingPiston] [plankWood, "oc:circuitChip1", plankWood]] } inventoryControllerUpgrade { input: [[ingotGold, "oc:analyzer", ingotGold] - [dispenser, "oc:circuitChip2", craftingPiston] + [dropper, "oc:circuitChip2", craftingPiston] [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] } leashUpgrade { diff --git a/src/main/resources/assets/opencomputers/recipes/peaceful.recipes b/src/main/resources/assets/opencomputers/recipes/peaceful.recipes new file mode 100644 index 000000000..5401e0fb3 --- /dev/null +++ b/src/main/resources/assets/opencomputers/recipes/peaceful.recipes @@ -0,0 +1,75 @@ +include file("default.recipes") + +redstoneCard2 { + input: [[blockRedstone, "oc:circuitChip2", diamond] + ["", "oc:materialCard", ""]] +} +wlanCard { + input: [[diamond, "oc:circuitChip2", ""] + ["", "oc:materialCard", ""]] +} +linkedCard { + input: [[diamond, "", diamond] + ["oc:lanCard", "oc:materialInterweb", "oc:lanCard"] + ["oc:circuitChip3", "", "oc:circuitChip3"]] + output: 2 # Note: all resulting cards are linked to each other. +} + +angelUpgrade { + input: [[ingotIron, diamond, ingotIron] + ["oc:circuitChip1", pistonStickyBase, "oc:circuitChip1"] + [ingotIron, diamond, ingotIron]] +} +chunkloaderUpgrade { + input: [[ingotGold, glass, ingotGold] + ["oc:circuitChip3", diamond, "oc:circuitChip3"] + [obsidian, "oc:materialCircuitBoardPrinted", obsidian]] +} +inventoryUpgrade { + input: [[plankWood, hopper, plankWood] + [dropper, chest, craftingPiston] + [plankWood, "oc:circuitChip1", plankWood]] +} +inventoryControllerUpgrade { + input: [[ingotGold, "oc:analyzer", ingotGold] + [dropper, "oc:circuitChip2", craftingPiston] + [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] +} +signUpgrade { + input: [[ingotIron, dyeBlack, ingotIron] + ["oc:circuitChip1", stickWood, "oc:circuitChip1"] + [ingotIron, craftingPiston, ingotIron]] +} +tankUpgrade { + input: [[plankWood, fenceIron, plankWood] + [dropper, cauldron, craftingPiston] + [plankWood, "oc:circuitChip1", plankWood]] +} +tankControllerUpgrade { + input: [[ingotGold, glassBottle, ingotGold] + [dropper, "oc:circuitChip2", craftingPiston] + [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] +} + +inkCartridgeEmpty { + input: [[nuggetIron, dropper, nuggetIron], + ["oc:materialTransistor", bucket, "oc:materialTransistor"], + [nuggetIron, "oc:materialCircuitBoardPrinted", nuggetIron]] +} + +interweb { + input: [[redstone, {block="minecraft:wool", subID=9}, redstone] + [{block="minecraft:wool", subID=9}, diamond, {block="minecraft:wool", subID=9}] + [redstone, {block="minecraft:wool", subID=9}, redstone]] +} + +geolyzer { + input: [[ingotGold, compass, ingotGold] + [diamond, "oc:circuitChip2", diamond] + [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] +} +hologram2 { + input: [["oc:circuitChip3", glass, "oc:circuitChip3"] + ["oc:materialCircuitBoardPrinted", blockDiamond, "oc:materialCircuitBoardPrinted"] + [obsidian, yellowDust, obsidian]] +} diff --git a/src/main/resources/assets/opencomputers/recipes/user.recipes b/src/main/resources/assets/opencomputers/recipes/user.recipes index 4a612f4b6..69c4632ba 100644 --- a/src/main/resources/assets/opencomputers/recipes/user.recipes +++ b/src/main/resources/assets/opencomputers/recipes/user.recipes @@ -11,6 +11,7 @@ include file("default.recipes") #include file("hardmode.recipes") #include file("gregtech.recipes") +#include file("peaceful.recipes") #include file("your_custom.recipes") # You can also specify custom recipes in this file directly. Have a look at the From 02dd439e6a5044a25a6f94b5cc58e07190835aef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sat, 18 Apr 2015 20:22:19 +0200 Subject: [PATCH 35/37] Allow redrawing holograms a tad faster, closes #1064. Also added a new method, `setRaw`, takes a string (byte array) with each byte being the color for a voxel. Allows setting the whole hologram data at once, allowing for even faster redrawing / swapping of states. --- .../cil/oc/common/tileentity/Hologram.scala | 59 ++++++++++++------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/src/main/scala/li/cil/oc/common/tileentity/Hologram.scala b/src/main/scala/li/cil/oc/common/tileentity/Hologram.scala index 3bd875839..2de8d85a2 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Hologram.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Hologram.scala @@ -56,9 +56,6 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w var dirtyFromZ = Int.MaxValue var dirtyUntilZ = -1 - // Time to wait before sending another update packet. - var cooldown = 5 - var hasPower = true final val colorsByTier = Array(Array(0x00FF00), Array(0x0000FF, 0x00FF00, 0xFF0000)) // 0xBBGGRR for rendering convenience @@ -97,7 +94,6 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w dirtyUntilX = -1 dirtyFromZ = Int.MaxValue dirtyUntilZ = -1 - cooldown = 5 } // ----------------------------------------------------------------------- // @@ -113,7 +109,7 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w // ----------------------------------------------------------------------- // @Callback(doc = """function() -- Clears the hologram.""") - def clear(computer: Context, args: Arguments): Array[AnyRef] = this.synchronized { + def clear(context: Context, args: Arguments): Array[AnyRef] = this.synchronized { for (i <- 0 until volume.length) volume(i) = 0 ServerPacketSender.sendHologramClear(this) resetDirtyFlag() @@ -122,13 +118,13 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w } @Callback(direct = true, doc = """function(x:number, y:number, z:number):number -- Returns the value for the specified voxel.""") - def get(computer: Context, args: Arguments): Array[AnyRef] = this.synchronized { + def get(context: Context, args: Arguments): Array[AnyRef] = this.synchronized { val (x, y, z) = checkCoordinates(args) result(getColor(x, y, z)) } @Callback(direct = true, limit = 256, doc = """function(x:number, y:number, z:number, value:number or boolean) -- Set the value for the specified voxel.""") - def set(computer: Context, args: Arguments): Array[AnyRef] = this.synchronized { + def set(context: Context, args: Arguments): Array[AnyRef] = this.synchronized { val (x, y, z) = checkCoordinates(args) val value = checkColor(args, 3) setColor(x, y, z, value) @@ -136,7 +132,7 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w } @Callback(direct = true, limit = 128, doc = """function(x:number, z:number[, minY:number], maxY:number, value:number or boolean) -- Fills an interval of a column with the specified value.""") - def fill(computer: Context, args: Arguments): Array[AnyRef] = this.synchronized { + def fill(context: Context, args: Arguments): Array[AnyRef] = this.synchronized { val (x, _, z) = checkCoordinates(args, 0, -1, 1) val (minY, maxY, value) = if (args.count > 4) @@ -157,8 +153,30 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w null } + @Callback(doc = """function(data:string) -- Set the raw buffer to the specified byte array, where each byte represents a voxel color. Nesting is x,z,y.""") + def setRaw(context: Context, args: Arguments): Array[AnyRef] = this.synchronized { + val data = args.checkByteArray(0) + for (x <- 0 until width; z <- 0 until width) { + val offset = z * height + x * height * width + if (data.length >= offset + height) { + var lbit = 0 + var hbit = 0 + for (y <- (height - 1) to 0 by -1) { + val color = data(offset + y) + lbit |= (color & 1) << y + hbit |= ((color & 3) >>> 1) << y + } + volume(x + z * width) = lbit + volume(x + z * width + width * width) = hbit + } + } + setDirty(0, 0) + setDirty(width - 1, width - 1) + null + } + @Callback(doc = """function(x:number, z:number, sx:number, sz:number, tx:number, tz:number) -- Copies an area of columns by the specified translation.""") - def copy(computer: Context, args: Arguments): Array[AnyRef] = this.synchronized { + def copy(context: Context, args: Arguments): Array[AnyRef] = this.synchronized { val (x, _, z) = checkCoordinates(args, 0, -1, 1) val w = args.checkInteger(2) val h = args.checkInteger(3) @@ -205,30 +223,30 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w // 'free' if it's less than 0.25 seconds, i.e. for small copies. val area = (math.max(dx0, dx1) - math.min(dx0, dx1)) * (math.max(dz0, dz1) - math.min(dz0, dz1)) val relativeArea = math.max(0, area / (width * width).toFloat - 0.25) - computer.pause(relativeArea) + context.pause(relativeArea) null } @Callback(direct = true, doc = """function():number -- Returns the render scale of the hologram.""") - def getScale(computer: Context, args: Arguments): Array[AnyRef] = { + def getScale(context: Context, args: Arguments): Array[AnyRef] = { result(scale) } @Callback(doc = """function(value:number) -- Set the render scale. A larger scale consumes more energy.""") - def setScale(computer: Context, args: Arguments): Array[AnyRef] = { + def setScale(context: Context, args: Arguments): Array[AnyRef] = { scale = math.max(0.333333, math.min(Settings.get.hologramMaxScaleByTier(tier), args.checkDouble(0))) ServerPacketSender.sendHologramScale(this) null } @Callback(direct = true, doc = """function():number, number, number -- Returns the relative render projection offsets of the hologram.""") - def getTranslation(computer: Context, args: Arguments): Array[AnyRef] = { + def getTranslation(context: Context, args: Arguments): Array[AnyRef] = { result(translation.xCoord, translation.yCoord, translation.zCoord) } @Callback(doc = """function(tx:number, ty:number, tz:number) -- Sets the relative render projection offsets of the hologram.""") - def setTranslation(computer: Context, args: Arguments): Array[AnyRef] = { + def setTranslation(context: Context, args: Arguments): Array[AnyRef] = { // Validate all axes before setting the values. val maxTranslation = Settings.get.hologramMaxTranslationByTier(tier) val tx = math.max(-maxTranslation, math.min(maxTranslation, args.checkDouble(0))) @@ -249,7 +267,7 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w } @Callback(doc = """function(index:number):number -- Get the color defined for the specified value.""") - def getPaletteColor(computer: Context, args: Arguments): Array[AnyRef] = { + def getPaletteColor(context: Context, args: Arguments): Array[AnyRef] = { val index = args.checkInteger(0) if (index < 1 || index > colors.length) throw new ArrayIndexOutOfBoundsException() // Colors are stored as 0xAABBGGRR for rendering convenience, so convert them. @@ -257,7 +275,7 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w } @Callback(doc = """function(index:number, value:number):number -- Set the color defined for the specified value.""") - def setPaletteColor(computer: Context, args: Arguments): Array[AnyRef] = { + def setPaletteColor(context: Context, args: Arguments): Array[AnyRef] = { val index = args.checkInteger(0) if (index < 1 || index > colors.length) throw new ArrayIndexOutOfBoundsException() val value = args.checkInteger(1) @@ -300,12 +318,9 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w override def updateEntity() { super.updateEntity() if (isServer) { - if (dirty) { - cooldown -= 1 - if (cooldown <= 0) this.synchronized { - ServerPacketSender.sendHologramSet(this) - resetDirtyFlag() - } + if (dirty) this.synchronized { + ServerPacketSender.sendHologramSet(this) + resetDirtyFlag() } if (world.getTotalWorldTime % Settings.get.tickFrequency == 0) { if (litRatio < 0) this.synchronized { From cbd54883ac5d31c6c9df458641ec4f5ef1257157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sat, 18 Apr 2015 20:22:35 +0200 Subject: [PATCH 36/37] Bump version number. --- build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.properties b/build.properties index 0af0c72e3..ab649e181 100644 --- a/build.properties +++ b/build.properties @@ -1,7 +1,7 @@ minecraft.version=1.7.10 forge.version=10.13.2.1291 -oc.version=1.5.7 +oc.version=1.5.8 oc.subversion=dev ae2.version=rv2-beta-26 From be071be9a24672133bb0280da7a6b3fc2c49f4ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sat, 18 Apr 2015 20:42:35 +0200 Subject: [PATCH 37/37] Made recipe set extraction a bit more generic, added the peaceful set. --- .../scala/li/cil/oc/common/recipe/Recipes.scala | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala b/src/main/scala/li/cil/oc/common/recipe/Recipes.scala index 537ebb433..ac57f0a85 100644 --- a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala +++ b/src/main/scala/li/cil/oc/common/recipe/Recipes.scala @@ -85,18 +85,16 @@ object Recipes { oreDictEntries.clear() try { - val defaultRecipes = new File(Loader.instance.getConfigDir + File.separator + "opencomputers" + File.separator + "default.recipes") - val hardmodeRecipes = new File(Loader.instance.getConfigDir + File.separator + "opencomputers" + File.separator + "hardmode.recipes") - val gregTechRecipes = new File(Loader.instance.getConfigDir + File.separator + "opencomputers" + File.separator + "gregtech.recipes") - val userRecipes = new File(Loader.instance.getConfigDir + File.separator + "opencomputers" + File.separator + "user.recipes") - - defaultRecipes.getParentFile.mkdirs() - FileUtils.copyURLToFile(getClass.getResource("/assets/opencomputers/recipes/default.recipes"), defaultRecipes) - FileUtils.copyURLToFile(getClass.getResource("/assets/opencomputers/recipes/hardmode.recipes"), hardmodeRecipes) - FileUtils.copyURLToFile(getClass.getResource("/assets/opencomputers/recipes/gregtech.recipes"), gregTechRecipes) + val recipeSets = Array("default", "hardmode", "gregtech", "peaceful") + val recipeDirectory = new File(Loader.instance.getConfigDir + File.separator + "opencomputers") + val userRecipes = new File(recipeDirectory, "user.recipes") + userRecipes.getParentFile.mkdirs() if (!userRecipes.exists()) { FileUtils.copyURLToFile(getClass.getResource("/assets/opencomputers/recipes/user.recipes"), userRecipes) } + for (recipeSet <- recipeSets) { + FileUtils.copyURLToFile(getClass.getResource(s"/assets/opencomputers/recipes/$recipeSet.recipes"), new File(recipeDirectory, s"$recipeSet.recipes")) + } lazy val config: ConfigParseOptions = ConfigParseOptions.defaults. setSyntax(ConfigSyntax.CONF). setIncluder(new ConfigIncluder with ConfigIncluderFile {