Lewis crafting table

From MineLabs
Revision as of 13:44, 11 July 2022 by JorenFabre (talk | contribs) (Uitleg Code (Screens))
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

De speler kan op de Lewis-craftingtable gebruiken om chemische bindingen te maken tussen atomen en daardoor een zuivere stof te craften die bestaat uit zulke bindingen.

De Lewis crafting table is geïnspireerd op een standaard Minecraft crafting table. De Lewis crafting table heeft een centraal 5x5 grid waar de speler atomen op kan plaatsen. Ieder atoom heeft een elektronegatieve (EN) waarde. Op basis van het verschil in EN, berekent een algoritme of de atomen een binding aangaan en wat voor een.

Wanneer een geldige binding (of molecule) is gemaakt op het grid, dan verschijnt onderaan een balk met slots. Het aantal slots komt overeen met het aantal geplaatste atomen. In zo’n slot moeten 10 stuks van dit atoom geplaatst worden. Voor de duidelijk wordt er boven de slots aangegeven wat de speler moet aanleveren en in het slot wordt het gevraagde atoom transparant getoond, totdat alle 10 atomen zijn gegeven.

Eens de speler alle slots heeft gevuld, dan vult de pijl zich als bij een furnace. Alle opgegeven atomen worden als het ware bijeengevoegd tot zulke moleculen die de stof vormen. In de outputslot krijgt de speler dan de blok van die stof.

Ionenbinding

Indien ΔEN > 1.7, dan wordt een ionaire binding gevormd tussen de atomen, die wordt getoond door een pijl (bv Na en Cl). Er kan een animatie bij komen die toont hoe de elektronen loskomen.

Figuur: een molecule met één ionenbinding is gevormd op de Lewis crafting table. Eens de correcte molecule was geplaatst op het grid, zijn de twee onderste slots verschenen. De speler moest hier 10 Na en 10 Cl aanleveren. Dit is nog niet volledig gebeurd. Eens deze voorwaarde voldaan is, zal de witte pijl gevuld worden. Dit geeft aan dat al de atomen zogezegd worden samengevoegd tot een NaCl rooster. Dat vormt dan het blok zout dat de speler kan nemen in de outputslot.

Covalente binding

Indien ΔEN < 1.7, dan wordt een covalente binding gevormd tussen de atomen, die wordt getoond door een streep (bv H, H en O). Er kan een animatie bij komen die toont hoe de elektronen loskomen.

Figuur: een molecule met twee covalente bindingen is gevormd op de Lewis crafting table. Eens de correcte molecule was geplaatst op het grid, zijn de drie onderste slots verschenen. De speler moest hier 10 H, 10 O en 10 H aanleveren. Dit is gebeurd dus nu wordt de witte pijl gevuld. Dit geeft aan dat al de atomen zogezegd worden samengevoegd tot H2O moleculen en al die moleculen samen vormen dan het blok water dat de speler kan nemen in de outputslot.

Uitleg Code (Screens)

Screen updates:

Voor het renderen van het scherm wordt er een inventory opgeslagen in de LewisBlockEntity. Dat is de inventory van de block die in de wereld is geplaatst. Elke keer als je het menu opendoet gaat worden er 2 LewisBlockScreenHandlers aangemaakt. één serverside en één clientside. De server ScreenHandler wordt er aangemaakt bij door de blockEntity en de client Screenhandler wordt aangemaakt door de OnInitialize in de client. Hierdoor worden er 2 verschillende inventories aangemaakt. Het probleem is hier dat deze inventories telkens bestaan uit slots en beide inventories hebben 36 slots: 25 slots voor het 5x5 inputveld 9 slots foor de item inputs 1 slot voor de output 1 slot voor de erlenmeyer

De slots van de client zijn niet automatisch gesynct met de slots op de server. Die van de client zullen dus eerst leeg zijn waarna de server een packet stuurt als je de block opent. Dit is voorzien door de ScreenHandler (base class) zelf en daar moet je niets mee doen. Checks in de inventory zullen wel altijd server + client side gebeuren. Aangezien dit niet handig is gebruiken we een propertyDelegate array in de BlockEntity. Hierin zitten momenteel 5 integers: DIT ZIJN DE ENIGE WAARDEN DIE GESYNCT ZIJN TUSSEN DE SERVER EN CLIENT (hierop komen we later terug)

Er is ook een LewisScreen class die gehandled wordt door de ScreenHandler van de client. Alles wat hier gebeurt verloopt op de client. Nu wordt het complex:

Als er een bepaalde inventory configuratie zal zijn op de server, dan zal de client die proberen te syncen maar dit zal maar deels lukken aangezien we met meerdere inventories werken (playerInventory en containerInventory). De inventories zullen syncen maar member variables niet waardoor we in de LewisScreen eigenlijk niets weten over de inventory zelf en het is ook onmogelijk om iets te weten te komen zonder custom packets te sturen van de server naar de client bij bepaalde events.

De oplossing is hier de propertyDelegate. Die waardes zijn member varaibles van de BlockEntity en dus niet van de screenHandler of Screen. De server screenhandler zal deze waarden juist zetten en opslaan in de BlockEntity. Het LewisScreen zal een reference hebben naar de client screenHandler (niet dus niet gesynct is met de server screenhandler) Het LewisScreen zal de getters van de waardes van de propertyDelegate kunnen gebruiken die de server heeft juistgezet door methods te gebruiken op de reference naar de client screenhandler. De reference naar de screenhandler van de client mag enkel gebruikt worden voor deze doeleinden want anders kunnen er items verdwijnen etc. (dit gebeurt niet automatisch en als je zelf zo'n waardes wil toevoegen, dan moet je alles manueel getten/setten. Deze waardes kunnen enkel integers zijn) Het LewisScreen zal de waardes inlezen op de juiste momenten en hierdoor de screens correct renderen:

De waardes: TextureID: (0 of 1): 0 betekent dat er geen geldig grid is en dat de input slots niet mogen worden getoond 1 betekend dat er wel een geldig grid is en hierdoor worden de input slots getoont en aangezet: dit is inline gedefinieerd bij de constructor voor CLIENT en SERVER. Dit moet inline gebeuren omdat isEnabled anders niet wordt aangeroepen (alternatief is packets sturen)

CraftingProgress: (0 tem 23) Deze waarde toont hoever de crafting al zit. Deze waarde wordt in de screenHandler in de functie craftingAnimation() op 1 gezet en daarna wordt de crafting automatisch afgehandeld in het LewisScreen door daar de waardes te updaten.

mappedOutput: om de output te kunnen voorstellen als integer is er een MAP in DelegateSettings.java die de output op een integer mapt waardoor je die kan doorgeven van de server naar de client

slotItems en slotReady: om de items die verwacht worden in de inputslots te tonen zullen deze 2 integers gebruikt worden. Stel dat de verwachte waarden H H O zijn (H2O), dan is er een mapping in DelegateSettings.java die de atomen mapt op priemnummers. Stel dat H wordt gemapt op 3 en O op 7, dan zal de integer slotItems 3*3*7 zijn (=42). Omdat elk nummer een unieke priemontbinding heeft is er ook een functie voorzien om die priemontbinding terug te verkrijgen door de functie LewisScreen#getSlotList(int) die een lijst teruggeeft met integers in ons voorbeeld is dit [3,3,7]. nu kunnen we de items terug mappen in de andere richting op atomen waardoor we [H,H,O] krijgen en deze kunnen we renderen als itemInGui slotReady doet iets analoog: Als er 10 atomen juist staan in een slot, dan mapt die dat slot op een priemnummer en neem je het product van alle valid slots (waar er 10 in zitten). deze wordt ook terug omgezet naar slotindexen later waardoor je exact weet op welk slot je een rode (geen 10 items) of groene (wel 10 items) achtergrond moet zetten.

Opmerkingen

De speler kan het Chemistry recipe book gebruiken om te onthouden welke molecule gevormd kunnen worden op het grid van de Lewis crafting table.

In het voorgaande is u misschien opgevallen dat we de moleculen niet toevoegen als afzonderlijk items. Dit zou een overdaad aan items geven. De speler komt de molecule enkel tegen wanneer deze gevormd worden op de crafting table of wanneer deze gezien worden door de spyglass.