I added a new column to the [font='courier new']item_templates[/font] table: [font='courier new']isApplied[/font]. If an item template has this set to true it means that you apply it to a jar instead of placing it into the jar as a moveable item (like a potato, for example). Once you place substrate in you cannot drag it around, you can only remove it.
The substrate item has a terrain item type in the [font='courier new']item_types[/font] table. There are different actions available from the user's closet based on item type and sometimes template:
protected function getAvailableActionsAttribute() { $possibleActions = []; switch ($this->template->type->name) { case 'consumable': array_push($possibleActions, array('text' => 'Put in Jar', 'onclick' => "return showPutInJarForm($this->itemID)")); break; case 'decorative': array_push($possibleActions, array('text' => 'Put in Jar', 'onclick' => "return showPutInJarForm($this->itemID)")); break; case 'substrate': array_push($possibleActions, array('text' => 'Put in Jar', 'onclick' => "return showPutInJarForm($this->itemID)")); break; case 'jar': array_push($possibleActions, array('text' => 'Install Jar', 'onclick' => "return showInstallJarForm($this->itemID)")); break; case 'breeding': if(strpos($this->template->name,'Fertility Spray') !== false) { array_push($possibleActions, array('text' => 'Spray', 'onclick' => "return showPutInJarForm($this->itemID)")); }; break; case 'training': array_push($possibleActions, array('text' => 'Put in Jar', 'onclick' => "return showPutInJarForm($this->itemID)")); break; case 'terrain': array_push($possibleActions, array('text' => 'Apply to Jar', 'onclick' => "return showPutInJarForm($this->itemID)")); break; } return $possibleActions; }
So if the item type is 'terrain' the action text that appears is "Apply to Jar" vs "Put in Jar". It could call a different function when clicked as well, but in this case we handle the application step in the same function as the putting-in step so we show the same form.
So a user goes to their closet, scrolls to the Garden Dirt item, clicks "Apply to Jar", and selects which jar to apply the item to.
Then we update the item as we usually would by placing it inside the jar, except we only assign the item a position if [font='courier new']!$item->isApplied[/font]. At the end we run any special actions the item may have (which in this case it does) via [font='courier new']$item->runSpecialActions()[/font]:
case 'terrain': $jarController = new JarController(); $jar = $jarController->findJar($this->jarID); $jar->terrainItemID = $this->itemID; $propertiesToUpdate = [ 'terrainItemID' => $this->itemID ]; $jar->updateJar($propertiesToUpdate); break;
So the terrain gets applied. The item is not deleted until the substrate is thrown away. And if a jar has a terrain applied we draw the terrain tiles in the background:
Of course the next step is to have the substrate actually have some sort of effect. Snails housed in a jar without substrate should be affected by the lack of proper environment. Unfortunately right now I do not yet have snail health implemented. That is, snails can die of lack of energy via starvation, but they also need to be able to get ill from environmental and genetic factors and then die that way, too. The terrain will be just one of many things that should affect a snail's overall health and performance.