code:
/*
Author: NullQuery
Created on: 2014-09-24

	** CAUTION - A WORD OF WARNING **

If there is no getter or setter available and you aren't extending my code with a sub-type, DO NOT ACCESS VARIABLES DIRECTLY!

Add a getter/setter instead, even if it does nothing but return or set the variable. Thank you for your patience with me. -NQ

	** Public API **

	var/datum/html_interface/hi = new/datum/html_interface(ref, title, width = 700, height = 480, head = "")

Creates a new HTML interface object with [ref] as the object and [title] as the initial title of the page. [width] and [height] is the initial width and height
of the window. The text in [head] is added just before the end  tag.

	hi.setTitle(title)

Changes the title of the page.

	hi.getTitle()

Returns the current title of the page.

	hi.updateLayout(layout)

Updates the overall layout of the page (the HTML code between the body tags).

This should be used sparingly.

	hi.updateContent(id, content, ignore_cache = FALSE)

Updates a portion of the page, i.e., the DOM element with the appropriate ID. The contents of the element are replaced with the provided HTML.

The content is cached on the server-side to minimize network traffic when the client "should have" the same HTML. The client may not have
the same HTML if scripts cause the content to change. In this case set the ignore_cache parameter.

	hi.executeJavaScript(jscript, client = null)

Executes Javascript on the browser.

The client is optional and may be a /mob, /client or /html_interface_client object. If not specified the code is executed on all clients.

	hi.show(client)

Shows the HTML interface to the provided client. This will create a window, apply the current layout and contents. It will then wait for events.

	hi.hide(client)

Hides the HTML interface from the provided client. This will close the browser window.

	hi.isUsed()

Returns TRUE if the interface is being used (has an active client) or FALSE if not.

	hi.closeAll()

Closes the interface on all clients.

	** Additional notes **

When working with byond:// links make sure to reference the HTML interface object and NOT the original object. Topic() will still be called on
your object, but it will pass through the HTML interface first allowing interception at a higher level.

If you want to use custom resources(images/css/js) with an existing interface:
You have to use modules/client/asset_cache to ensure they get sent BEFORE the interface opens

	** Sample code **

mob/var/datum/html_interface/hi

mob/verb/test()
	if (!hi) hi = new/datum/html_interface(src, "[src.key]")

	hi.updateLayout("

")
	hi.updateContent("content", "
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
")

	hi.show(src)

*/

/var/list/html_interfaces = new/list()

/datum/html_interface
	// The atom we should report to.
	var/atom/ref

	// The current title of the browser window.
	var/title

	// A list of content elements that have been changed. This is necessary when showing the browser control to new clients.
	var/list/content_elements = new/list()

	// The HTML layout, typically what's in-between the  tag. May be overridden by extensions.
	var/layout

	// An associative list of clients currently viewing this screen. The key is the /client object, the value is the /datum/html_interface_client object.
	var/list/clients

	// This goes just before the closing HEAD tag. I haven't exposed any getters/setters for it because it's only being used by extensions.
	var/head = ""

	// The initial width of the browser control, used when the window is first shown to a client.
	var/width

	// The initial height of the browser control, used when the window is first shown to a client.
	var/height

	// A type associated list of assets the interface needs.
	//Sent to the client when the interface opens on the client for the first time.
	var/static/list/asset_list

/datum/html_interface/New(atom/ref, title, width = 700, height = 480, head = "")
	html_interfaces.Add(src)

	. = ..()

	src.ref            = ref
	src.title          = title
	src.width          = width
	src.height         = height
	src.head           = head

/datum/html_interface/Destroy()
	src.closeAll()

	html_interfaces.Remove(src)

	return ..()

/*                 * Hooks */
/datum/html_interface/proc/specificRenderTitle(datum/html_interface_client/hclient, ignore_cache = FALSE)

//if you need to override this, either call ..() or add your resources to asset_list
/datum/html_interface/proc/registerResources(var/list/resources = list())
	resources["jquery.min.js"] = 'js/jquery.min.js'
	resources["bootstrap.min.js"] = 'js/bootstrap.min.js'
	resources["bootstrap.min.css"] = 'css/bootstrap.min.css'
	resources["html_interface.css"] = 'css/html_interface.css'
	resources["html_interface.js"] = 'js/html_interface.js'
	var/assetlist = list()
	for (var/R in resources)
		register_asset(R,resources[R])
		assetlist += R
	if (!asset_list)
		asset_list = list()
	asset_list[type] = assetlist

/datum/html_interface/proc/createWindow(datum/html_interface_client/hclient)
	winclone(hclient.client, "window", "browser_\ref[src]")

	var/list/params = list(
		"size"        = "[width]x[height]",
		"statusbar"   = "false",
		"on-close"    = "byond://?src=\ref[src]&html_interface_action=onclose"
	)

	if (hclient.client.hi_last_pos) params["pos"] = "[hclient.client.hi_last_pos]"

	winset(hclient.client, "browser_\ref[src]", list2params(params))

	winset(hclient.client, "browser_\ref[src].browser", list2params(list("parent" = "browser_\ref[src]", "type" = "browser", "pos" = "0,0", "size" = "[width]x[height]", "anchor1" = "0,0", "anchor2" = "100,100", "use-title" = "true", "auto-format" = "false")))

/*                 * Public API */
/datum/html_interface/proc/getTitle() return src.title

/datum/html_interface/proc/setTitle(title, ignore_cache = FALSE)
	src.title = title

	var/datum/html_interface_client/hclient

	for (var/client in src.clients)
		hclient = src._getClient(src.clients[client])

		if (hclient && hclient.active) src._renderTitle(src.clients[client], ignore_cache)

/datum/html_interface/proc/executeJavaScript(jscript, datum/html_interface_client/hclient = null)
	if (hclient)
		hclient = getClient(hclient)

		if (istype(hclient))
			if (hclient.is_loaded) hclient.client << output(list2params(list(jscript)), "browser_\ref[src].browser:eval")
	else
		for (var/client in src.clients) if(src.clients[client]) src.executeJavaScript(jscript, src.clients[client])

/datum/html_interface/proc/callJavaScript(func, list/arguments, datum/html_interface_client/hclient = null)
	if (!arguments) arguments = new/list()

	if (hclient)
		hclient = getClient(hclient)

		if (istype(hclient))
			if (hclient.is_loaded)
				hclient.client << output(list2params(arguments), "browser_\ref[src].browser:[func]")
	else
		for (var/client in src.clients) if (src.clients[client]) src.callJavaScript(func, arguments, src.clients[client])

/datum/html_interface/proc/updateLayout(layout)
	src.layout = layout

	var/datum/html_interface_client/hclient

	for (var/client in src.clients)
		hclient = src._getClient(src.clients[client])

		if (hclient && hclient.active) src._renderLayout(hclient)

/datum/html_interface/proc/updateContent(id, content, ignore_cache = FALSE)
	src.content_elements[id] = content

	var/datum/html_interface_client/hclient

	for (var/client in src.clients)
		hclient = src._getClient(src.clients[client])

		if (hclient && hclient.active)
			spawn (-1) src._renderContent(id, hclient, ignore_cache)

/datum/html_interface/proc/show(datum/html_interface_client/hclient)
	hclient = getClient(hclient, TRUE)

	if (istype(hclient))
		if ((type in asset_list) && islist(asset_list[type]))
			send_asset_list(hclient.client, asset_list[type], TRUE)

		if (!winexists(hclient.client, "browser_\ref[src]"))
			src.createWindow(hclient)
			//src._renderTitle(hclient, TRUE)
			//src._renderLayout(hclient)

		hclient.is_loaded = FALSE
		hclient.client << output(replacetextEx(replacetextEx(file2text('html_interface.html'), "\[hsrc\]", "\ref[src]"), "", "[head]"), "browser_\ref[src].browser")

		winshow(hclient.client, "browser_\ref[src]", TRUE)

		while (hclient.client && hclient.active && !hclient.is_loaded) sleep(2)

/datum/html_interface/proc/hide(datum/html_interface_client/hclient)
	hclient = getClient(hclient)

	if (istype(hclient))
		if (src.clients)
			src.clients.Remove(hclient.client)

			if (!src.clients.len) src.clients = null

		hclient.client.hi_last_pos = winget(hclient.client, "browser_\ref[src]" ,"pos")

		winshow(hclient.client, "browser_\ref[src]", FALSE)
		winset(hclient.client, "browser_\ref[src]", "parent=none")

		if (hascall(src.ref, "hiOnHide")) call(src.ref, "hiOnHide")(hclient)

// Convert a /mob to /client, and /client to /datum/html_interface_client
/datum/html_interface/proc/getClient(client, create_if_not_exist = FALSE)
	if (istype(client, /datum/html_interface_client)) return src._getClient(client)
	else if (ismob(client))
		var/mob/mob = client
		client      = mob.client

	if (istype(client, /client))
		if (create_if_not_exist && (!src.clients || !(client in src.clients)))
			if (!src.clients)             src.clients = new/list()
			if (!(client in src.clients)) src.clients[client] = new/datum/html_interface_client(client)

		if (src.clients && (client in src.clients)) return src._getClient(src.clients[client])
		else                                        return null
	else                                            return null

/datum/html_interface/proc/enableFor(datum/html_interface_client/hclient)
	hclient.active = TRUE

	src.show(hclient)

/datum/html_interface/proc/disableFor(datum/html_interface_client/hclient)
	hclient.active = FALSE

/datum/html_interface/proc/isUsed()
	if (src.clients && src.clients.len > 0)
		var/datum/html_interface_client/hclient

		for (var/key in clients)
			hclient = _getClient(clients[key])

			if (hclient)
				if (hclient.active) return TRUE
			else
				clients.Remove(key)

	return FALSE

/datum/html_interface/proc/closeAll()
	if (src.clients)
		for (var/client in src.clients)
			src.hide(src.clients[client])

/*                 * Danger Zone */

/datum/html_interface/proc/_getClient(datum/html_interface_client/hclient)
	if (hclient)
		if (hclient.client)
			// res = if the client has been active in the past 10 minutes and the client is allowed to view the object (context-sensitive).
			var/res = hclient.client.inactivity <= 6000 && (hascall(src.ref, "hiIsValidClient") ? call(src.ref, "hiIsValidClient")(hclient, src) : TRUE)

			if (res)
				if (!hclient.active) src.enableFor(hclient)
			else
				if (hclient.active)  src.disableFor(hclient)

			return hclient
		else
			return null
	else
		return null

/datum/html_interface/proc/_renderTitle(datum/html_interface_client/hclient, ignore_cache = FALSE, ignore_loaded = FALSE)
	if (hclient && (ignore_loaded || hclient.is_loaded))
		// Only render if we have new content.

		if (ignore_cache || src.title != hclient.title)
			hclient.title = title

			src.specificRenderTitle(hclient)

			hclient.client << output(list2params(list(title)), "browser_\ref[src].browser:setTitle")

/datum/html_interface/proc/_renderLayout(datum/html_interface_client/hclient, ignore_loaded = FALSE)
	if (hclient && (ignore_loaded || hclient.is_loaded))
		var/html   = src.layout

		// Only render if we have new content.
		if (html != hclient.layout)
			hclient.layout = html

			hclient.client << output(list2params(list(html)), "browser_\ref[src].browser:updateLayout")

			for (var/id in src.content_elements) src._renderContent(id, hclient, ignore_loaded = ignore_loaded)

/datum/html_interface/proc/_renderContent(id, datum/html_interface_client/hclient, ignore_cache = FALSE, ignore_loaded = FALSE)
	if (hclient && (ignore_loaded || hclient.is_loaded))
		var/html   = src.content_elements[id]

		// Only render if we have new content.
		if (ignore_cache || !(id in hclient.content_elements) || html != hclient.content_elements[id])
			hclient.content_elements[id] = html

			hclient.client << output(list2params(list(id, html)), "browser_\ref[src].browser:updateContent")

/datum/html_interface/Topic(href, href_list[])
	var/datum/html_interface_client/hclient = getClient(usr.client)

	if (istype(hclient))
		if ("html_interface_action" in href_list)
			switch (href_list["html_interface_action"])

				if ("onload")
					hclient.layout = null
					hclient.content_elements.len = 0

					src._renderTitle(hclient, TRUE, TRUE)
					src._renderLayout(hclient, TRUE)

					hclient.is_loaded = TRUE

				if ("onclose")
					src.hide(hclient)
		else if (src.ref && hclient.active) src.ref.Topic(href, href_list, hclient)


code:
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta charset="UTF-8" />
		<title></title>
		<link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
		<link rel="stylesheet" type="text/css" href="html_interface.css" />
		<script type="text/javascript">var hSrc = "[hsrc]";</script>
		<script type="text/javascript" src="jquery.min.js"></script>
		<script type="text/javascript" src="jquery.mousewheel.min.js"></script>
		<script type="text/javascript" src="bootstrap.min.js"></script>
		<script type="text/javascript" src="html_interface.js"></script>
	</head>
	<body>
	</body>
</html>

license: mit


code:
/datum/html_interface_client
	// The /client object represented by this model.
	var/client/client

	// The layout currently visible to the client.
	var/layout

	// The content elements (mirrored from /datum/html_interface) currently visible to the client.
	var/list/content_elements = new/list()

	// The current title for this client
	var/title

	// TRUE if the browser control has loaded and will accept input, FALSE if not.
	var/is_loaded = FALSE

	// TRUE if this client should receive updates, FALSE if not.
	var/active = TRUE

	// A list of extra variables, for use by extensions.
	var/list/extra_vars

/datum/html_interface_client/New(client/client)
	. = ..()

	src.client = client

/datum/html_interface_client/proc/putExtraVar(key, value)
	if (!src.extra_vars) src.extra_vars = new/list()
	src.extra_vars[key] = value

/datum/html_interface_client/proc/removeExtraVar(key)
	if (src.extra_vars)
		. = src.extra_vars[key]

		src.extra_vars.Remove(key)

		if (!src.extra_vars.len) src.extra_vars = null

	return .

/datum/html_interface_client/proc/getExtraVar(key)
	if (src.extra_vars) return src.extra_vars[key]


code:
var is_loading								= false;
var load_count								= 0;

function onload()
{
	if (!is_loading)
	{
		var count							= ++load_count;
		is_loading							= true;
		$("body").html("");

		window.location.href				= "byond://?src=" + hSrc + "&html_interface_action=onload";

		// The request may fail which would prevent the player from refreshing the screen again. Try to detect this retry.
		setTimeout(function()
		{
			if (count == load_count && is_loading && $("body").html() == "")
			{
				is_loading					= false;
				onload();
			}
		}, 500);
	}
}

$(document).ready(function()
{
	$(document).on("keydown", function(e)
	{
		if (!e.ctrlKey && e.which == 116)
		{
			e.preventDefault();

			onload();
		}
	});

	onload();
});

function fixText(text)						{ return text.replace(/ÿ/g, ""); }

function setTitle(new_title)				{ $("title").html(fixText(new_title)); $(window).trigger("onUpdateTitle"); }
function updateLayout(new_html)				{ $("body").html(fixText(new_html)); $(window).trigger("onUpdateLayout"); setTimeout(function(){ is_loading = false; }, 200); }
function updateContent(id, new_html)		{ $("#" + id).html(fixText(new_html)); $(window).trigger("onUpdateContent"); }


code:
body
{
	background-color: #272727;
	background-image: url(uiBg.png);
	background-repeat: repeat-x;
	background-position: center top;

	font-family: verdana,Geneva,sans-serif;
	font-size: 12px;
	color: #FFFFFF;
	line-height: 170%; /* NullQuery: 170% of what? */
}

/* Fix for IE8 */
body
{
	background-color: #1F1F1F\9 !important;
}

#ntbgcenter
{
	position: absolute;
	top: 0px;
	left: 0px;
	right: 0px;
	height: 246px;

	background-image: url(uiBgcenter.png);
	background-position: center;
	background-repeat: no-repeat;

	z-index: -1;
}

#content
{
	padding: 8px;
	font-family: Verdana, Geneva, sans-serif;
}

hr
{
	background-color: #40628a;
	height: 1px;
}

a, a:link, a:visited, a:active, .linkOn, .linkOff
{
	color: #ffffff;
	text-decoration: none;
	background: #40628a;
	border: 1px solid #161616;
	padding: 1px 4px 1px 4px;
	margin: 0 2px 0 0;
	cursor:default;
}

a.nobg, a.nobg:link, a.nobg:visited, a.nobg:active
{
	color: #ffffff;
	text-decoration: none;
	background: transparent;
	border: none;
	padding: 0px;
	margin: 0px;
	cursor:default;
	font-weight:bold;
}
a.nobg:hover
{
	color:#40628a;
}

a:hover
{
	color: #40628a;
	background: #ffffff;
}

a.white, a.white:link, a.white:visited, a.white:active
{
	color: #40628a;
	text-decoration: none;
	background: #ffffff;
	border: 1px solid #161616;
	padding: 1px 4px 1px 4px;
	margin: 0 2px 0 0;
	cursor:default;
}

a.white:hover
{
	color: #ffffff;
	background: #40628a;
}

.linkOn, a.linkOn:link, a.linkOn:visited, a.linkOn:active, a.linkOn:hover
{
	color: #ffffff;
	background: #2f943c;
	border-color: #24722e;
}

.linkOff, a.linkOff:link, a.linkOff:visited, a.linkOff:active, a.linkOff:hover
{
	color: #ffffff;
	background: #999999;
	border-color: #666666;
}

a.icon, .linkOn.icon, .linkOff.icon
{
	position: relative;
	padding: 1px 4px 2px 20px;
}

a.icon img, .linkOn.icon img
{
	position: absolute;
	top: 0;
	left: 0;
	width: 18px;
	height: 18px;
}

ul
{
	padding: 4px 0 0 10px;
	margin: 0;
	list-style-type: none;
}

li
{
	padding: 0 0 2px 0;
}

img, a img
{
	border-style:none;
}

h1, h2, h3, h4, h5, h6
{
	margin: 0;
	padding: 16px 0 8px 0;
	color: #517087;
}

h1
{
	font-size: 15px;
}

h2
{
	font-size: 14px;
}

h3
{
	font-size: 13px;
}

h4
{
	font-size: 12px;
}

.good
{
	color: #00ff00;
}

.average
{
	color: #d09000;
}

.bad
{
	color: #ff0000;
}

.highlight
{
	color: #8BA5C4;
}

.dark
{
	color: #272727;
}

.notice
{
	position: relative;
	background: #E9C183;
	color: #15345A;
	font-size: 10px;
	font-style: italic;
	padding: 2px 4px 0 4px;
	margin: 4px;
}

.notice.icon
{
	padding: 2px 4px 0 20px;
}

.notice img
{
	position: absolute;
	top: 0;
	left: 0;
	width: 16px;
	height: 16px;
}

div.notice
{
	clear: both;
}

.statusDisplay
{
	background: #000000;
	color: #ffffff;
	border: 1px solid #40628a;
	padding: 4px;
	margin: 3px 0;
}

.statusLabel
{
	width: 138px;
	float: left;
	overflow: hidden;
	color: #98B0C3;
}

.statusValue
{
	float: left;
}

.block
{
	padding: 8px;
	margin: 10px 4px 4px 4px;
	border: 1px solid #40628a;
	background-color: #202020;
}

.block h3
{
	padding: 0;
}

.progressBar
{
	width: 240px;
	height: 14px;
	border: 1px solid #666666;
	float: left;
	margin: 0 5px;
	overflow: hidden;
}

.progressFill
{
	width: 100%;
	height: 100%;
	background: #40628a;
	overflow: hidden;
}

.progressFill.good
{
	color: #ffffff;
	background: #00ff00;
}

.progressFill.average
{
	color: #ffffff;
	background: #d09000;
}

.progressFill.bad
{
	color: #ffffff;
	background: #ff0000;
}

.progressFill.highlight
{
	color: #ffffff;
	background: #8BA5C4;
}

.clearBoth
{
	clear: both;
}

.clearLeft
{
	clear: left;
}

.clearRight
{
	clear: right;
}

.line
{
	width: 100%;
	clear: both;
}


code:
/*
Author: NullQuery
Created on: 2014-09-25

Extension to implement Nanotrasen styled windows.

Additional procs:

	hi.setEyeColor(color, client)

Use this to set the color of the 'eye' in the top-left corner of the window.

The client is optional and may be a /mob, /client or /html_interface_client object. It must be specified, since the eye icon is specific to a client.

*/

/datum/html_interface/nanotrasen/New()
	. = ..()

	// Add appropriate CSS and set the default layout.
	src.head = src.head + "<link rel=\"stylesheet\" type=\"text/css\" href=\"hi-nanotrasen.css\" />"
	src.updateLayout("")

/datum/html_interface/nanotrasen/updateLayout(layout)
	// Wrap the layout in our custom HTML
	return ..("

[layout]
")

/datum/html_interface/specificRenderTitle(datum/html_interface_client/hclient, ignore_cache = FALSE)
	// Update the title in our custom header (in addition to default functionality)
	winset(hclient.client, "browser_\ref[src].uiTitle", list2params(list("text" = "[src.title]")))

/datum/html_interface/nanotrasen/registerResources(var/list/resources = list())
	resources["uiBg.png"] = 'uiBg.png'
	resources["uiBgcenter.png"] = 'uiBgcenter.png'
	resources["hi-nanotrasen.css"] = 'hi-nanotrasen.css'
	..(resources)

/datum/html_interface/nanotrasen/createWindow(datum/html_interface_client/hclient)
	. = ..() // we want the default window

	// Remove the titlebar
	winset(hclient.client, "browser_\ref[src]", list2params(list(
		"titlebar"    = "false"
	)))

	// Reposition the browser
	winset(hclient.client, "browser_\ref[src].browser", list2params(list(
		"pos"         = "0,35",
		"size"        = "[width]x[height - 35]"
	)))

	// Add top background image
	winset(hclient.client, "browser_\ref[src].topbg", list2params(list(
		"parent"      = "browser_\ref[src]",
		"type"        = "label",
		"pos"         = "0,0",
		"size"        = "[width]x35",
		"anchor1"     = "0,0",
		"anchor2"     = "100,0",
		"image"       = "['uiBgtop.png']",
		"image-mode"  = "tile",
		"is-disabled" = "true"
	)))

	// Add Nanotrasen logo
	winset(hclient.client, "browser_\ref[src].uiTitleFluff", list2params(list(
		"parent"      = "browser_\ref[src]",
		"type"        = "label",
		"pos"         = "[width - 42 - 4 - 24 - 4 - 24 - 4],5",
		"size"        = "42x24",
		"anchor1"     = "100,0",
		"anchor2"     = "100,0",
		"image"       = "['uiTitleFluff.png']",
		"image-mode"  = "tile",
		"is-disabled" = "true"
	)))

	// Add Eye picture
	winset(hclient.client, "browser_\ref[src].uiTitleEye", list2params(list(
		"parent"      = "browser_\ref[src]",
		"type"        = "label",
		"pos"         = "8,5",
		"size"        = "42x24",
		"anchor1"     = "0,0",
		"anchor2"     = "0,0",
		"image"       = "['uiEyeGreen.png']",
		"image-mode"  = "tile",
		"is-disabled" = "true"
	)))

	// Add title text
	winset(hclient.client, "browser_\ref[src].uiTitle", list2params(list(
		"parent"         = "browser_\ref[src]",
		"type"           = "label",
		"is-transparent" = "true",
		"pos"            = "64,0",
		"size"           = "580x35",
		"anchor1"        = "0,0",
		"anchor2"        = "100,0",
		"is-disabled"    = "true",
		"text"           = "[src.title]",
		"align"          = "left",
		"font-family"    = "verdana,Geneva,sans-serif",
		"font-size"      = "12", // ~ 16px
		"text-color"     = "#E9C183"
	)))

	// Add minimize button
	// TODO: Style the button (add image)
	winset(hclient.client, "browser_\ref[src].uiTitleMinimize", list2params(list(
		"parent"         = "browser_\ref[src]",
		"type"           = "button",
		"is-flat"        = "true",
		"background-color"="#383838", // should be unnecessary if image is used
		"text-color"     = "#FFFFFF", // should be unnecessary if image is used
		"is-transparent" = "true",
		"pos"            = "[width - 24 - 4 - 24 - 4],5",
		"size"           = "24x24",
		"anchor1"        = "100,0",
		"anchor2"        = "100,0",
		"text"           = "-",
		"font-family"    = "verdana,Geneva,sans-serif", // should be unnecessary if image is used
		"font-size"      = "12", // ~ 16px - should be unnecessary if image is used

		// Disable resizing (disables maximizing), minimize window, bind window.on-size to catch 'restore window' button to enable resizing if restored.
		"command"        = ".winset \"browser_\ref[src].can-resize=false;browser_\ref[src].is-minimized=true;browser_\ref[src].on-size=\".swinset \\\"browser_\ref[src].can-resize=true;browser_\ref[src].on-size=\\\"\"\""
	)))

	// Add close button
	// TODO: Style the button (add image)
	winset(hclient.client, "browser_\ref[src].uiTitleClose", list2params(list(
		"parent"         = "browser_\ref[src]",
		"type"           = "button",
		"is-flat"        = "true",
		"background-color"="#383838", // should be unnecessary if image is used
		"text-color"     = "#FFFFFF", // should be unnecessary if image is used
		"command"        = "byond://?src=\ref[src];html_interface_action=onclose",
		"is-transparent" = "true",
		"pos"            = "[width - 24 - 4],5",
		"size"           = "24x24",
		"anchor1"        = "100,0",
		"anchor2"        = "100,0",
		"text"           = "X",
		"font-family"    = "verdana,Geneva,sans-serif", // should be unnecessary if image is used
		"font-size"      = "12" // ~ 16px - should be unnecessary if image is used
	)))

/datum/html_interface/nanotrasen/enableFor(datum/html_interface_client/hclient)
	. = ..()

	src.setEyeColor("green", hclient)

/datum/html_interface/nanotrasen/disableFor(datum/html_interface_client/hclient)
	hclient.active = FALSE

	src.setEyeColor("red", hclient)

/datum/html_interface/nanotrasen/proc/setEyeColor(color, datum/html_interface_client/hclient)
	hclient = getClient(hclient)

	if (istype(hclient))
		var/resource
		switch (color)
			if ("green")  resource = 'uiEyeGreen.png'
			if ("orange") resource = 'uiEyeOrange.png'
			if ("red")    resource = 'uiEyeRed.png'
			else          CRASH("Invalid color: [color]")

		if (hclient.getExtraVar("eye_color") != color)
			hclient.putExtraVar("eye_color", color)

			winset(hclient.client, "browser_\ref[src].uiTitleEye", list2params(list("image" = "[resource]")))
	else
		WARNING("Invalid object passed to /datum/html_interface/nanotrasen/proc/setEyeColor")


code:
#define BEEBOX_MAX_FRAMES				3		//Max frames per box
#define BEES_RATIO						0.5 	//Multiplied by the max number of honeycombs to find the max number of bees
#define BEE_PROB_NEW_BEE				20		//The chance for spare bee_resources to be turned into new bees
#define BEE_RESOURCE_HONEYCOMB_COST		100		//The amount of bee_resources for a new honeycomb to be produced, percentage cost 1-100
#define BEE_RESOURCE_NEW_BEE_COST		50		//The amount of bee_resources for a new bee to be produced, percentage cost 1-100

/mob/proc/bee_friendly()
	return 0

/mob/living/simple_animal/hostile/poison/bees/bee_friendly()
	return 1

/mob/living/carbon/human/bee_friendly()
	if(dna && dna.species && dna.species.id == "pod") //bees pollinate plants, duh.
		return 1
	if((wear_suit && (wear_suit.flags & THICKMATERIAL)) && (head && (head.flags & THICKMATERIAL)))
		return 1
	return 0

/obj/structure/beebox
	name = "apiary"
	desc = "Dr Miles Manners is just your average Wasp themed super hero by day, but by night he becomes DR BEES!"
	icon = 'icons/obj/hydroponics/equipment.dmi'
	icon_state = "beebox"
	anchored = 1
	density = 1
	var/mob/living/simple_animal/hostile/poison/bees/queen/queen_bee = null
	var/list/bees = list() //bees owned by the box, not those inside it
	var/list/honeycombs = list()
	var/list/honey_frames = list()
	var/bee_resources = 0

/obj/structure/beebox/New()
	..()
	SSobj.processing += src

/obj/structure/beebox/Destroy()
	SSobj.processing -= src
	bees.Cut()
	bees = null
	honeycombs.Cut()
	honeycombs = null
	queen_bee = null
	return ..()

//Premade apiaries can spawn with a random reagent
/obj/structure/beebox/premade
	var/random_reagent = FALSE

/obj/structure/beebox/premade/New()
	..()

	var/datum/reagent/R = null
	if(random_reagent)
		R = pick(subtypesof(/datum/reagent))
		R = chemical_reagents_list[initial(R.id)]

	queen_bee = new(src)
	queen_bee.beehome = src
	bees += queen_bee
	queen_bee.assign_reagent(R)

	for(var/i in 1 to BEEBOX_MAX_FRAMES)
		var/obj/item/honey_frame/HF = new(src)
		honey_frames += HF

	for(var/i in 1 to get_max_bees())
		var/mob/living/simple_animal/hostile/poison/bees/B = new(src)
		bees += B
		B.beehome = src
		B.assign_reagent(R)

/obj/structure/beebox/premade/random
	random_reagent = TRUE

/obj/structure/beebox/process()
	if(queen_bee)
		if(bee_resources >= BEE_RESOURCE_HONEYCOMB_COST)
			if(honeycombs.len < get_max_honeycomb())
				bee_resources = max(bee_resources-BEE_RESOURCE_HONEYCOMB_COST, 0)
				var/obj/item/weapon/reagent_containers/honeycomb/HC = new(src)
				if(queen_bee.beegent)
					HC.set_reagent(queen_bee.beegent.id)
				honeycombs += HC

		if(bees.len < get_max_bees())
			var/freebee = FALSE //a freebee, geddit?, hahaha HAHAHAHA
			if(bees.len <= 1) //there's always one set of worker bees, this isn't colony collapse disorder its 2d spessmen
				freebee = TRUE
			if((bee_resources >= BEE_RESOURCE_NEW_BEE_COST && prob(BEE_PROB_NEW_BEE)) || freebee)
				if(!freebee)
					bee_resources = max(bee_resources - BEE_RESOURCE_NEW_BEE_COST, 0)
				var/mob/living/simple_animal/hostile/poison/bees/B = new(src)
				B.beehome = src
				B.assign_reagent(queen_bee.beegent)
				bees += B

/obj/structure/beebox/proc/get_max_honeycomb()
	. = 0
	for(var/hf in honey_frames)
		var/obj/item/honey_frame/HF = hf
		. += HF.honeycomb_capacity

/obj/structure/beebox/proc/get_max_bees()
	. = get_max_honeycomb() * BEES_RATIO

/obj/structure/beebox/examine(mob/user)
	..()

	if(!queen_bee)
		user << "There is no queen bee! There won't bee any honeycomb without a queen!"

	var/half_bee = get_max_bees()*0.5
	if(half_bee && (bees.len >= half_bee))
		user << "This place is a BUZZ with activity... there are lots of bees!"

	user << "[bee_resources]/100 resource supply."
	user << "[bee_resources]% towards a new honeycomb."
	user << "[bee_resources*2]% towards a new bee."

	if(honeycombs.len)
		var/plural = honeycombs.len > 1
		user << "There [plural? "are" : "is"] [honeycombs.len] uncollected honeycomb[plural ? "s":""] in the apiary."

	if(honeycombs.len >= get_max_honeycomb())
		user << "there's no room for more honeycomb!"

/obj/structure/beebox/attackby(obj/item/I, mob/user, params)
	if(istype(I, /obj/item/honey_frame))
		var/obj/item/honey_frame/HF = I
		if(honey_frames.len < BEEBOX_MAX_FRAMES)
			visible_message("[user] adds a frame to the apiary.")
			user.unEquip(HF)
			HF.loc = src
			honey_frames += HF
		else
			user << "There's no room for anymore frames in the apiary!"

	if(istype(I, /obj/item/weapon/wrench))
		if(default_unfasten_wrench(user, I, time = 20))
			return

	if(istype(I, /obj/item/queen_bee))
		if(queen_bee)
			user << "This hive already has a queen!"
			return

		var/obj/item/queen_bee/qb = I
		user.unEquip(qb)

		qb.queen.loc = src
		bees += qb.queen
		queen_bee = qb.queen
		qb.queen = null

		if(queen_bee)
			visible_message("[user] sets [qb] down inside the apiary, making it their new home.")
			var/relocated = 0
			for(var/b in bees)
				var/mob/living/simple_animal/hostile/poison/bees/B = b
				if(B.reagent_incompatible(queen_bee))
					bees -= B
					B.beehome = null
					if(B.loc == src)
						B.loc = get_turf(src)
					relocated++
			if(relocated)
				user << "This queen has a different reagent to some of the bees who live here, those bees will not return to this apiary!"

		else
			user << "The queen bee disappeared! bees disappearing has been in the news lately..."

		qdel(qb)

/obj/structure/beebox/attack_hand(mob/user)
	if(ishuman(user))
		if(!user.bee_friendly())
			//Time to get stung!
			var/bees = FALSE
			for(var/b in bees) //everyone who's ever lived here now instantly hates you, suck it assistant!
				var/mob/living/simple_animal/hostile/poison/bees/B = b
				if(B.isqueen)
					continue
				if(B.loc == src)
					B.loc = get_turf(src)
				B.target = user
				bees = TRUE
			if(bees)
				visible_message("[user] disturbs the bees!")
		else
			var/option = alert(user, "What Action do you wish to perform?","Apiary","Remove a Honey Frame","Remove the Queen Bee")
			if(!Adjacent(user))
				return
			switch(option)
				if("Remove a Honey Frame")
					if(!honey_frames.len)
						user << "There are no honey frames to remove!"
						return

					var/obj/item/honey_frame/HF = pick_n_take(honey_frames)
					if(HF)
						if(!user.put_in_active_hand(HF))
							HF.loc = get_turf(src)
						visible_message("[user] removes a frame from the apiary.")

						var/amtH = HF.honeycomb_capacity
						var/fallen = 0
						while(honeycombs.len && amtH) //let's pretend you always grab the frame with the most honeycomb on it
							var/obj/item/weapon/reagent_containers/honeycomb/HC = pick_n_take(honeycombs)
							if(HC)
								HC.loc = get_turf(user)
								amtH--
								fallen++
						if(fallen)
							var/multiple = fallen > 1
							visible_message("[user] scrapes [multiple ? "[fallen]" : "a"] honeycomb[multiple ? "s" : ""] off of the frame.")

				if("Remove the Queen Bee")
					if(!queen_bee || queen_bee.loc != src)
						user << "There is no queen bee to remove!"
						return
					var/obj/item/queen_bee/QB = new()
					queen_bee.loc = QB
					bees -= queen_bee
					QB.queen = queen_bee
					QB.name = queen_bee.name
					if(!user.put_in_active_hand(QB))
						QB.loc = get_turf(src)
					visible_message("[user] removes the queen from the apiary.")
					queen_bee = null


code:
/obj/item/clothing/head/beekeeper_head
	name = "beekeeper hat"
	desc = "keeps the lil buzzing buggers out of your eyes"
	icon_state = "beekeeper"
	item_state = "beekeeper"
	flags = THICKMATERIAL

/obj/item/clothing/suit/beekeeper_suit
	name = "beekeeper suit"
	desc = "keeps the lil buzzing buggers away from your squishy bits"
	icon_state = "beekeeper"
	item_state = "beekeeper"
	flags = THICKMATERIAL


code:
/obj/item/honey_frame
	name = "honey frame"
	desc = "a scaffold for bees to build honeycomb on"
	icon = 'icons/obj/hydroponics/equipment.dmi'
	icon_state = "honey_frame"
	var/honeycomb_capacity = 10 //10 Honeycomb per frame by default, researchable frames perhaps?

/obj/item/honey_frame/New()
	pixel_x = rand(8,-8)
	pixel_y = rand(8,-8)


code:
/obj/item/weapon/reagent_containers/honeycomb
	name = "honeycomb"
	desc = "a hexagonal mesh of honeycomb"
	icon = 'icons/obj/hydroponics/harvest.dmi'
	icon_state = "honeycomb"
	possible_transfer_amounts = list()
	spillable = 0
	disease_amount = 0
	volume = 10
	amount_per_transfer_from_this = 0
	list_reagents = list("honey" = 5)
	var/honey_color = ""

/obj/item/weapon/reagent_containers/honeycomb/New()
	..()
	pixel_x = rand(8,-8)
	pixel_y = rand(8,-8)
	update_icon()

/obj/item/weapon/reagent_containers/honeycomb/update_icon()
	overlays.Cut()
	var/image/honey
	if(honey_color)
		honey = image(icon = 'icons/obj/hydroponics/harvest.dmi', icon_state = "greyscale_honey")
		honey.color = honey_color
	else
		honey = image(icon = 'icons/obj/hydroponics/harvest.dmi', icon_state = "honey")
	overlays += honey

/obj/item/weapon/reagent_containers/honeycomb/proc/set_reagent(reagent)
	var/datum/reagent/R = chemical_reagents_list[reagent]
	if(istype(R))
		name = "honeycomb ([R.name])"
		honey_color = R.color
		reagents.add_reagent(R.id,5)
	else
		honey_color = ""
	update_icon()


code:
/obj/machinery/biogenerator
	name = "Biogenerator"
	desc = "Converts plants into biomass, which can be used to construct useful items."
	icon = 'icons/obj/biogenerator.dmi'
	icon_state = "biogen-empty"
	density = 1
	anchored = 1
	use_power = 1
	idle_power_usage = 40
	var/processing = 0
	var/obj/item/weapon/reagent_containers/glass/beaker = null
	var/points = 0
	var/menustat = "menu"
	var/efficiency = 0
	var/productivity = 0
	var/max_items = 40

/obj/machinery/biogenerator/New()
		..()
		create_reagents(1000)
		component_parts = list()
		component_parts += new /obj/item/weapon/circuitboard/biogenerator(null)
		component_parts += new /obj/item/weapon/stock_parts/matter_bin(null)
		component_parts += new /obj/item/weapon/stock_parts/manipulator(null)
		component_parts += new /obj/item/weapon/stock_parts/console_screen(null)
		component_parts += new /obj/item/stack/cable_coil(null, 1)
		RefreshParts()

/obj/machinery/biogenerator/RefreshParts()
	var/E = 0
	var/P = 0
	var/max_storage = 40
	for(var/obj/item/weapon/stock_parts/matter_bin/B in component_parts)
		P += B.rating
		max_storage = 40 * B.rating
	for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
		E += M.rating
	efficiency = E
	productivity = P
	max_items = max_storage

/obj/machinery/biogenerator/on_reagent_change()			//When the reagents change, change the icon as well.
	update_icon()

/obj/machinery/biogenerator/update_icon()
	if(panel_open)
		icon_state = "biogen-empty-o"
	else if(!src.beaker)
		icon_state = "biogen-empty"
	else if(!src.processing)
		icon_state = "biogen-stand"
	else
		icon_state = "biogen-work"
	return

/obj/machinery/biogenerator/attackby(obj/item/O, mob/user, params)
	if(istype(O, /obj/item/weapon/reagent_containers/glass) && !panel_open)
		if(beaker)
			user << "A container is already loaded into the machine."
		else
			user.unEquip(O)
			O.loc = src
			beaker = O
			user << "You add the container to the machine."
			updateUsrDialog()
	else if(processing)
		user << "The biogenerator is currently processing."
	else if(istype(O, /obj/item/weapon/storage/bag/plants))
		var/i = 0
		for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in contents)
			i++
		if(i >= max_items)
			user << "The biogenerator is already full! Activate it."
		else
			for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in O.contents)
				if(i >= max_items)
					break
				G.loc = src
				i++
			if(i<max_items)
				user << "You empty the plant bag into the biogenerator."
			else if(O.contents.len == 0)
				user << "You empty the plant bag into the biogenerator, filling it to its capacity."
			else
				user << "You fill the biogenerator to its capacity."

	else if(!istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown))
		user << "You cannot put this in [src.name]!"
	else
		var/i = 0
		for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in contents)
			i++
		if(i >= max_items)
			user << "The biogenerator is full! Activate it."
		else
			user.unEquip(O)
			O.loc = src
			user << "You put [O.name] in [src.name]"

	if(!processing)
		if(default_deconstruction_screwdriver(user, "biogen-empty-o", "biogen-empty", O))
			if(beaker)
				var/obj/item/weapon/reagent_containers/glass/B = beaker
				B.loc = loc
				beaker = null

	if(exchange_parts(user, O))
		return

	default_deconstruction_crowbar(O)

	update_icon()
	return

/obj/machinery/biogenerator/interact(mob/user)
	if(stat & BROKEN || panel_open)
		return
	user.set_machine(src)
	var/dat
	if(processing)
		dat += "
Biogenerator is processing! Please wait...

"
	else
		switch(menustat)
			if("nopoints")
				dat += "
You do not have biomass to create products.
Please, put growns into reactor and activate it.
"
				menustat = "menu"
			if("complete")
				dat += "
Operation complete.
"
				menustat = "menu"
			if("void")
				dat += "
Error: No growns inside.
Please, put growns into reactor.
"
				menustat = "menu"
			if("nobeakerspace")
				dat += "
Not enough space left in container. Unable to create product.
"
				menustat = "menu"
		if(beaker)
			dat += "
Biomass: [points] units.

"
			dat += "ActivateDetach Container"
			dat += "
Food:
"
			dat += "
"
			dat += "10 milk: Makex5 ([20/efficiency])
"
			dat += "10 cream: Makex5 ([30/efficiency])
"
			dat += "Milk carton: Makex5 ([100/efficiency])
"
			dat += "Cream carton: Makex5 ([300/efficiency])
"
			dat += "10u black pepper: Makex5 ([25/efficiency])
"
			dat += "Pepper mill: Makex5 ([50/efficiency])
"
			dat += "Monkey cube: Makex5 ([250/efficiency])"
			dat += "
"
			dat += "
Botany Chemicals:
"
			dat += "
"
			dat += "E-Z-Nutrient: Makex5 ([10/efficiency])
"
			dat += "Left 4 Zed: Makex5 ([20/efficiency])
"
			dat += "Robust Harvest: Makex5 ([25/efficiency])
"
			dat += "Weed Killer: Makex5 ([50/efficiency])
"
			dat += "Pest Killer: Makex5 ([50/efficiency])
"
			dat += "Empty bottle: Makex5 ([5/efficiency])
"
			dat += "
"
			dat += "
Leather and Cloth:
"
			dat += "
"
			dat += "Wallet: Make ([100/efficiency])
"
			dat += "Book bag: Make ([200/efficiency])
"
			dat += "Empty sandbag: Make ([200/efficiency])
"
			dat += "Plant bag: Make ([200/efficiency])
"
			dat += "Rag: Make ([200/efficiency])
"
			dat += "Mining satchel: Make ([200/efficiency])
"
			dat += "Chemistry bag: Make ([200/efficiency])
"
			dat += "Botanical gloves: Make ([250/efficiency])
"
			dat += "Utility belt: Make ([300/efficiency])
"
			dat += "Security belt: Make ([300/efficiency])
"
			dat += "Medical belt: Make ([300/efficiency])
"
			dat += "Janitorial belt: Make ([300/efficiency])
"
			dat += "Bandolier belt: Make ([300/efficiency])
"
			dat += "Shoulder holster: Make ([400/efficiency])
"
			dat += "Leather satchel: Make ([400/efficiency])
"
			dat += "Leather jacket: Make ([500/efficiency])
"
			dat += "Leather overcoat: Make ([1000/efficiency])
"
			dat += "Rice hat: Make ([300/efficiency])
"
			dat += "
"
		else
			dat += "
No container inside, please insert container.
"

	var/datum/browser/popup = new(user, "biogen", name, 350, 520)
	popup.set_content(dat)
	popup.open()
	return

/obj/machinery/biogenerator/attack_hand(mob/user)
	interact(user)

/obj/machinery/biogenerator/proc/activate()
	if (usr.stat != 0)
		return
	if (src.stat != 0) //NOPOWER etc
		return
	if(src.processing)
		usr << "The biogenerator is in the process of working."
		return
	var/S = 0
	for(var/obj/item/weapon/reagent_containers/food/snacks/grown/I in contents)
		S += 5
		if(I.reagents.get_reagent_amount("nutriment") < 0.1)
			points += 1*productivity
		else points += I.reagents.get_reagent_amount("nutriment")*10*productivity
		qdel(I)
	if(S)
		processing = 1
		update_icon()
		updateUsrDialog()
		playsound(src.loc, 'sound/machines/blender.ogg', 50, 1)
		use_power(S*30)
		sleep(S+15/productivity)
		processing = 0
		update_icon()
	else
		menustat = "void"
	return

/obj/machinery/biogenerator/proc/check_cost(cost)
	if (cost > points)
		menustat = "nopoints"
		return 1
	else
		points -= cost
		processing = 1
		update_icon()
		updateUsrDialog()
		return 0

/obj/machinery/biogenerator/proc/check_container_volume(reagent_amount)
	if(beaker.reagents.total_volume + reagent_amount > beaker.reagents.maximum_volume)
		menustat = "nobeakerspace"
		return 1

/obj/machinery/biogenerator/proc/create_product(create)
	switch(create)
		if("milk")
			if(check_container_volume(10))
				return 0
			else if (check_cost(20/efficiency))
				return 0
			else beaker.reagents.add_reagent("milk",10)
		if("bpepper")
			if(check_container_volume(10))
				return 0
			else if (check_cost(25/efficiency))
				return 0
			else beaker.reagents.add_reagent("blackpepper",10)
		if("cream")
			if(check_container_volume(10))
				return 0
			else if (check_cost(30/efficiency))
				return 0
			else beaker.reagents.add_reagent("cream",10)
		if("cmilk")
			if (check_cost(100/efficiency))
				return 0
			else new/obj/item/weapon/reagent_containers/food/condiment/milk(src.loc)
		if("mpepper")
			if (check_cost(50/efficiency))
				return 0
			else new/obj/item/weapon/reagent_containers/food/condiment/peppermill(src.loc)
		if("ccream")
			if (check_cost(300/efficiency))
				return 0
			else new/obj/item/weapon/reagent_containers/food/drinks/bottle/cream(src.loc)
		if("meat")
			if (check_cost(250/efficiency))
				return 0
			else new/obj/item/weapon/reagent_containers/food/snacks/monkeycube(src.loc)
		if("ez")
			if (check_cost(10/efficiency))
				return 0
			else new/obj/item/weapon/reagent_containers/glass/bottle/nutrient/ez(src.loc)
		if("l4z")
			if (check_cost(20/efficiency))
				return 0
			else new/obj/item/weapon/reagent_containers/glass/bottle/nutrient/l4z(src.loc)
		if("rh")
			if (check_cost(25/efficiency))
				return 0
			else new/obj/item/weapon/reagent_containers/glass/bottle/nutrient/rh(src.loc)
		if("wk")
			if (check_cost(50/efficiency))
				return 0
			else new/obj/item/weapon/reagent_containers/glass/bottle/killer/weedkiller(src.loc)
		if("pk")
			if (check_cost(50/efficiency))
				return 0
			else new/obj/item/weapon/reagent_containers/glass/bottle/killer/pestkiller(src.loc)
		if("empty")
			if (check_cost(5/efficiency))
				return 0
			else new/obj/item/weapon/reagent_containers/glass/bottle/nutrient/empty(src.loc)
		if("wallet")
			if (check_cost(100/efficiency))
				return 0
			else new/obj/item/weapon/storage/wallet(src.loc)
		if("bkbag")
			if (check_cost(200/efficiency))
				return 0
			else new/obj/item/weapon/storage/bag/books(src.loc)
		if("sdbag")
			if (check_cost(200/efficiency)) return 0
			else new/obj/item/weapon/emptysandbag(src.loc)
		if("ptbag")
			if (check_cost(200/efficiency))
				return 0
			else new/obj/item/weapon/storage/bag/plants(src.loc)
		if("mnbag")
			if (check_cost(200/efficiency))
				return 0
			else new/obj/item/weapon/storage/bag/ore(src.loc)
		if("chbag")
			if (check_cost(200/efficiency))
				return 0
			else new/obj/item/weapon/storage/bag/chemistry(src.loc)
		if("rag")
			if (check_cost(200/efficiency))
				return 0
			else new/obj/item/weapon/reagent_containers/glass/rag(src.loc)
		if("gloves")
			if (check_cost(250/efficiency))
				return 0
			else new/obj/item/clothing/gloves/botanic_leather(src.loc)
		if("tbelt")
			if (check_cost(300/efficiency))
				return 0
			else new/obj/item/weapon/storage/belt/utility(src.loc)
		if("sbelt")
			if (check_cost(300/efficiency))
				return 0
			else new/obj/item/weapon/storage/belt/security(src.loc)
		if("mbelt")
			if (check_cost(300/efficiency))
				return 0
			else new/obj/item/weapon/storage/belt/medical(src.loc)
		if("jbelt")
			if (check_cost(300/efficiency))
				return 0
			else new/obj/item/weapon/storage/belt/janitor(src.loc)
		if("bbelt")
			if (check_cost(300/efficiency))
				return 0
			else new/obj/item/weapon/storage/belt/bandolier(src.loc)
		if("sholster")
			if (check_cost(400/efficiency))
				return 0
			else new/obj/item/weapon/storage/belt/holster(src.loc)
		if("satchel")
			if (check_cost(400/efficiency))
				return 0
			else new/obj/item/weapon/storage/backpack/satchel(src.loc)
		if("jacket")
			if (check_cost(500/efficiency))
				return 0
			else new/obj/item/clothing/suit/jacket/leather(src.loc)
		if("overcoat")
			if (check_cost(1000/efficiency))
				return 0
			else new/obj/item/clothing/suit/jacket/leather/overcoat(src.loc)
		if("rice_hat")
			if (check_cost(300/efficiency))
				return 0
			else new/obj/item/clothing/head/rice_hat(src.loc)
	processing = 0
	menustat = "complete"
	update_icon()
	return 1

/obj/machinery/biogenerator/proc/detach()
	if(beaker)
		beaker.loc = src.loc
		beaker = null
		update_icon()

/obj/machinery/biogenerator/Topic(href, href_list)
	if(..() || panel_open)
		return

	usr.set_machine(src)

	if(href_list["activate"])
		activate()
		updateUsrDialog()

	else if(href_list["detach"])
		detach()
		updateUsrDialog()

	else if(href_list["create"])
		var/amount = (text2num(href_list["amount"]))
		var/i = amount
		var/C = href_list["create"]
		if(i <= 0)
			return
		while(i >= 1)
			create_product(C)
			i--
		updateUsrDialog()

	else if(href_list["menu"])
		menustat = "menu"
		updateUsrDialog()


code:
/obj/machinery/plantgenes
	name = "plant DNA manipulator"
	desc = "An advanced device designed to manipulate plant genetic makeup."
	icon = 'icons/obj/hydroponics/equipment.dmi'
	icon_state = "dnamod"
	density = 1
	anchored = 1

	var/obj/item/seeds/seed
	var/obj/item/weapon/disk/plantgene/disk

	var/list/core_genes = list()
	var/list/reagent_genes = list()
	var/list/trait_genes = list()

	var/datum/plant_gene/target
	var/operation = ""
	var/rating = 0 // TODO: add failures, make it useful

/obj/machinery/plantgenes/New()
	..()
	component_parts = list()
	component_parts += new /obj/item/weapon/circuitboard/plantgenes(src)
	component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
	component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
	component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
	component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
	component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
	RefreshParts()

/obj/machinery/plantgenes/RefreshParts()
	rating = 0
	for(var/obj/item/weapon/stock_parts/S in component_parts)
		rating += S.rating-1

/obj/machinery/plantgenes/update_icon()
	..()
	overlays.Cut()
	if((stat & (BROKEN|NOPOWER)))
		icon_state = "dnamod-off"
	else
		icon_state = "dnamod"
	if(seed)
		overlays += "dnamod-dna"
	if(panel_open)
		overlays += "dnamod-open"

/obj/machinery/plantgenes/attackby(obj/item/I, mob/user, params)
	if(default_deconstruction_screwdriver(user, "dnamod", "dnamod", I))
		update_icon()
		return
	if(exchange_parts(user, I))
		return
	if(default_deconstruction_crowbar(I))
		return
	if(isrobot(user))
		return

	if(istype(I, /obj/item/seeds))
		if(seed)
			user << "A sample is already loaded into the machine!"
		else
			if(!user.drop_item())
				return
			insert_seed(I)
			user << "You add [I] to the machine."
			interact(user)
		return
	else if(istype(I, /obj/item/weapon/disk/plantgene))
		if(disk)
			user << "A data disk is already loaded into the machine!"
		else
			if(!user.drop_item())
				return
			disk = I
			disk.loc = src
			user << "You add [I] to the machine."
			interact(user)
	else
		..()

/obj/machinery/plantgenes/attack_hand(mob/user)
	if(..())
		return
	interact(user)

/obj/machinery/plantgenes/interact(mob/user)
	user.set_machine(src)
	if(!user)
		return

	var/datum/browser/popup = new(user, "plantdna", "Plant DNA Manipulator", 450, 600) // Set up the popup browser window
	if(!( in_range(src, user) || istype(user, /mob/living/silicon) ))
		popup.close()
		return

	var/dat = ""

	if(operation)
		if(!seed || (!target && operation != "insert"))
			operation = ""
			target = null
			interact(user)
			return
		if((operation == "replace" || operation == "insert") && (!disk || !disk.gene))
			operation = ""
			target = null
			interact(user)
			return

		dat += "

Confirm Operation

"
		dat += "
Are you sure you want to [operation] "
		switch(operation)
			if("remove")
				dat += "[target.get_name()] gene from \the [seed]?
"
//				dat += "Failure may damage or destroy the sample!" // No failures yet. TODO: add failures
			if("extract")
				dat += "[target.get_name()] gene from \the [seed]?
"
				dat += "The sample will be destroyed in process!"
			if("replace")
				dat += "[target.get_name()] gene with [disk.gene.get_name()]?
"
//				dat += "Failure may damage or destroy the sample!" // No failures yet. TODO: add failures
			if("insert")
				dat += "[disk.gene.get_name()] gene into \the [seed]?
"
//				dat += "Failure may damage or destroy the sample!" // No failures yet. TODO: add failures
		dat += "

Confirm "
		dat += "Abort
"
		popup.set_content(dat)
		popup.open()
		return

	dat+= "
"

	dat += "

Plant Sample:

"
	dat += seed ? seed.name : "None"
	dat += "

"

	dat += "

Data Disk:

"
	if(!disk)
		dat += "None"
	else if(!disk.gene)
		dat += "Empty Disk"
	else
		dat += disk.gene.get_name()
	if(disk && disk.read_only)
		dat += " (RO)"
	dat += "

"

	dat += "

"

	if(seed)
		var/can_insert = disk && disk.gene && disk.gene.can_add(seed)
		var/can_extract = disk && !disk.read_only

		dat += "

Core Genes

"
		for(var/a in core_genes)
			var/datum/plant_gene/G = a
			if(!G)
				continue
			dat += "
[G.get_name()]	"
			if(can_extract)
				dat += "Extract"
			if(can_insert && istype(disk.gene, G.type))
				dat += "Replace"
			dat += "
"
		dat += "

"

		if(seed.yield != -1)
			dat += "

Content Genes

"
			if(reagent_genes.len)
				dat += "
"
				for(var/a in reagent_genes)
					var/datum/plant_gene/G = a
					dat += "
[G.get_name()]	"
					if(can_extract)
						dat += "Extract"
					dat += "Remove"
					dat += "
"
				dat += "
"
			else
				dat += "No content-related genes detected in sample.
"
			dat += "
"
			if(can_insert && istype(disk.gene, /datum/plant_gene/reagent))
				dat += "Insert: [disk.gene.get_name()]"

			dat += "

Trait Genes

"
			if(trait_genes.len)
				dat += "
"
				for(var/a in trait_genes)
					var/datum/plant_gene/G = a
					dat += "
[G.get_name()]	"
					if(can_extract)
						dat += "Extract"
					dat += "Remove"
					dat += "
"
				dat += "
"
			else
				dat += "No trait-related genes detected in sample.
"
			if(can_insert && istype(disk.gene, /datum/plant_gene/trait))
				dat += "Insert: [disk.gene.get_name()]"
			dat += "
"
	else
		dat += "
No sample found.
Please, insert a plant sample to use this device."
	popup.set_content(dat)
	popup.open()

/obj/machinery/plantgenes/Topic(var/href, var/list/href_list)
	if(..())
		return
	usr.set_machine(src)

	if(href_list["eject_seed"] && !operation)
		if (seed)
			seed.loc = src.loc
			seed.verb_pickup()
			seed = null
			update_genes()
			update_icon()
		else
			var/obj/item/I = usr.get_active_hand()
			if (istype(I, /obj/item/seeds))
				if(!usr.drop_item())
					return
				insert_seed(I)
				usr << "You add [I] to the machine."
		update_icon()
	else if(href_list["eject_disk"] && !operation)
		if (disk)
			disk.loc = src.loc
			disk.verb_pickup()
			disk = null
			update_genes()
		else
			var/obj/item/I = usr.get_active_hand()
			if(istype(I, /obj/item/weapon/disk/plantgene))
				if(!usr.drop_item())
					return
				disk = I
				disk.loc = src
				usr << "You add [I] to the machine."
	else if(href_list["op"] == "insert" && disk && disk.gene && seed)
		if(!operation) // Wait for confirmation
			operation = "insert"
		else
			if(!istype(disk.gene, /datum/plant_gene/core) && disk.gene.can_add(seed))
				seed.genes += disk.gene.Copy()
				if(istype(disk.gene, /datum/plant_gene/reagent))
					seed.reagents_from_genes()
			update_genes()
			repaint_seed()
			operation = ""
			target = null

	else if(href_list["gene"] && seed)
		var/datum/plant_gene/G = seed.get_gene(href_list["gene"])
		if(!G || !href_list["op"] || !(href_list["op"] in list("remove", "extract", "replace")))
			interact(usr)
			return

		if(!operation || target != G) // Wait for confirmation
			target = G
			operation = href_list["op"]

		else if(operation == href_list["op"] && target == G)
			switch(href_list["op"])
				if("remove")
					if(!istype(G, /datum/plant_gene/core))
						seed.genes -= G
						if(istype(G, /datum/plant_gene/reagent))
							seed.reagents_from_genes()
					repaint_seed()
				if("extract")
					if(disk && !disk.read_only)
						disk.gene = G
						disk.update_name()
						qdel(seed)
						seed = null
						update_icon()
				if("replace")
					if(disk && disk.gene && istype(disk.gene, G.type) && istype(G, /datum/plant_gene/core))
						seed.genes -= G
						var/datum/plant_gene/core/C = disk.gene.Copy()
						seed.genes += C
						C.apply_stat(seed)
						repaint_seed()
				if("insert")
					if(disk && disk.gene && !istype(disk.gene, /datum/plant_gene/core) && disk.gene.can_add(seed))
						seed.genes += disk.gene.Copy()
						if(istype(disk.gene, /datum/plant_gene/reagent))
							seed.reagents_from_genes()
						repaint_seed()

			update_genes()
			operation = ""
			target = null
	else if(href_list["abort"])
		operation = ""
		target = null

	interact(usr)

/obj/machinery/plantgenes/proc/insert_seed(obj/item/seeds/S)
	if(!istype(S) || seed)
		return
	S.loc = src
	seed = S
	update_genes()
	update_icon()

/obj/machinery/plantgenes/proc/update_genes()
	core_genes = list()
	reagent_genes = list()
	trait_genes = list()

	if(seed)
		var/gene_paths = list(
			/datum/plant_gene/core/potency,
			/datum/plant_gene/core/yield,
			/datum/plant_gene/core/production,
			/datum/plant_gene/core/endurance,
			/datum/plant_gene/core/lifespan
			)
		for(var/a in gene_paths)
			core_genes += seed.get_gene(a)

		for(var/datum/plant_gene/reagent/G in seed.genes)
			reagent_genes += G
		for(var/datum/plant_gene/trait/G in seed.genes)
			trait_genes += G

/obj/machinery/plantgenes/proc/repaint_seed()
	if(!seed)
		return
	if(copytext(seed.name, 1, 13) == "experimental")
		return // Already modded name and icon
	seed.name = "experimental " + seed.name
	seed.icon_state = "seed-x"

/*
 *  Plant DNA disk
 */

/obj/item/weapon/disk/plantgene
	name = "plant data disk"
	desc = "A disk for storing plant genetic data."
	icon_state = "datadisk2"
	materials = list(MAT_METAL=30, MAT_GLASS=10)
	var/datum/plant_gene/gene
	var/read_only = 0 //Well, it's still a floppy disk

/obj/item/weapon/disk/plantgene/New()
	..()
	overlays += "datadisk_gene"
	src.pixel_x = rand(-5, 5)
	src.pixel_y = rand(-5, 5)

/obj/item/weapon/disk/plantgene/attackby(obj/item/weapon/W, mob/user, params)
	..()
	if(istype(W, /obj/item/weapon/pen))
		var/t = stripped_input(user, "What would you like the label to be?", name, null)
		if(user.get_active_hand() != W)
			return
		if(!in_range(src, user) && loc != user)
			return
		if(t)
			name = "plant data disk - '[t]'"
		else
			name = "plant data disk"

/obj/item/weapon/disk/plantgene/proc/update_name()
	if(gene)
		name = "plant data disk - '[gene.get_name()]'"
	else
		name = "plant data disk"

/obj/item/weapon/disk/plantgene/attack_self(mob/user)
	read_only = !read_only
	user << "You flip the write-protect tab to [src.read_only ? "protected" : "unprotected"]."

/obj/item/weapon/disk/plantgene/examine(mob/user)
	..()
	user << "The write-protect tab is set to [src.read_only ? "protected" : "unprotected"]."

/*
 *  Plant DNA Disks Box
 */
/obj/item/weapon/storage/box/disks_plantgene
	name = "plant data disks box"
	icon_state = "disk_kit"

/obj/item/weapon/storage/box/disks_plantgene/New()
	..()
	for(var/i in 1 to 7)
		new /obj/item/weapon/disk/plantgene(src)


code:
// ***********************************************************
// Foods that are produced from hydroponics ~~~~~~~~~~
// Data from the seeds carry over to these grown foods
// ***********************************************************

// Base type. Subtypes are found in /grown dir.
/obj/item/weapon/reagent_containers/food/snacks/grown
	icon = 'icons/obj/hydroponics/harvest.dmi'
	var/obj/item/seeds/seed = null // type path, gets converted to item on New(). It's safe to assume it's always a seed item.
	var/plantname = ""
	var/bitesize_mod = 0
	var/splat_type = /obj/effect/decal/cleanable/plant_smudge
	// If set, bitesize = 1 + round(reagents.total_volume / bitesize_mod)
	dried_type = -1
	// Saves us from having to define each stupid grown's dried_type as itself.
	// If you don't want a plant to be driable (watermelons) set this to null in the time definition.
	burn_state = FLAMMABLE

/obj/item/weapon/reagent_containers/food/snacks/grown/New(newloc, var/obj/item/seeds/new_seed = null)
	..()
	if(new_seed)
		seed = new_seed.Copy()
	else if(ispath(seed))
		// This is for adminspawn or map-placed growns. They get the default stats of their seed type.
		seed = new seed()
		seed.adjust_potency(50-seed.potency)
	else // Something is terribly wrong
		qdel(src)
		return

	pixel_x = rand(-5, 5)
	pixel_y = rand(-5, 5)

	if(dried_type == -1)
		dried_type = src.type

	for(var/datum/plant_gene/trait/T in seed.genes)
		T.on_new(src, newloc)

	seed.prepare_result(src)
	add_juice()
	transform *= TransformUsingVariable(seed.potency, 100, 0.5) //Makes the resulting produce's sprite larger or smaller based on potency!

/obj/item/weapon/reagent_containers/food/snacks/grown/proc/add_juice()
	if(reagents)
		if(bitesize_mod)
			bitesize = 1 + round(reagents.total_volume / bitesize_mod)
		return 1
	return 0

/obj/item/weapon/reagent_containers/food/snacks/grown/examine(user)
	..()
	for(var/datum/plant_gene/trait/T in seed.genes)
		if(T.examine_line)
			user << T.examine_line

/obj/item/weapon/reagent_containers/food/snacks/grown/attackby(obj/item/O, mob/user, params)
	..()
	if (istype(O, /obj/item/device/analyzer/plant_analyzer))
		var/msg = "*---------*\n This is \a [src].\n"
		msg += seed.get_analyzer_text()
		msg += "\n- Nutritional value: [reagents.get_reagent_amount("nutriment")]\n"
		msg += "- Other substances: [reagents.total_volume-reagents.get_reagent_amount("nutriment")]\n"
		msg += "*---------*"

		var/list/scannable_reagents = list("charcoal" = "Anti-Toxin", "morphine" = "Morphine", "amatoxin" = "Amatoxins",
			"toxin" = "Toxins", "mushroomhallucinogen" = "Mushroom Hallucinogen", "condensedcapsaicin" = "Condensed Capsaicin",
			"capsaicin" = "Capsaicin", "frostoil" = "Frost Oil", "gold" = "Mineral Content", "glycerol" = "Glycerol",
			"radium" = "Highly Radioactive Material", "uranium" = "Radioactive Material")
		var/reag_txt = ""
		for(var/reagent_id in scannable_reagents)
			if(reagent_id in seed.reagents_add)
				var/amt = reagents.get_reagent_amount(reagent_id)
				reag_txt += "\n- [scannable_reagents[reagent_id]]: [amt*100/reagents.maximum_volume]%"

		if(reag_txt)
			msg += reag_txt
			msg += "
*---------*"
		user << msg
		return
	return

// Various gene procs
/obj/item/weapon/reagent_containers/food/snacks/grown/attack_self(mob/user)
	if(seed.get_gene(/datum/plant_gene/trait/squash))
		squash(user)
	..()

/obj/item/weapon/reagent_containers/food/snacks/grown/throw_impact(atom/hit_atom)
	if(!..() && seed.get_gene(/datum/plant_gene/trait/squash)) //was it caught by a mob?
		squash(hit_atom)

/obj/item/weapon/reagent_containers/food/snacks/grown/proc/squash(atom/target)
	var/turf/T = get_turf(target)
	if(ispath(splat_type, /obj/effect/decal/cleanable/plant_smudge))
		if(filling_color)
			var/obj/O = new splat_type(T)
			O.color = filling_color
			O.name = "[name] smudge"
	else if(splat_type)
		new splat_type(T)

	if(trash)
		if(ispath(trash, /obj/item/weapon/grown) || ispath(trash, /obj/item/weapon/reagent_containers/food/snacks/grown))
			new trash(T, seed)
		else
			new trash(T)

	visible_message("[src] has been squashed.","You hear a smack.")
	for(var/datum/plant_gene/trait/trait in seed.genes)
		trait.on_squash(src, target)

	for(var/A in T)
		reagents.reaction(A)

	qdel(src)

/obj/item/weapon/reagent_containers/food/snacks/grown/On_Consume()
	if(iscarbon(usr))
		for(var/datum/plant_gene/trait/T in seed.genes)
			T.on_consume(src, usr)
	..()

/obj/item/weapon/reagent_containers/food/snacks/grown/Crossed(atom/movable/AM)
	var/datum/plant_gene/trait/slip/S = seed.get_gene(/datum/plant_gene/trait/slip)
	if(S && !ispath(trash, /obj/item/weapon/grown) && iscarbon(AM))
		var/mob/living/carbon/M = AM
		var/stun = max(seed.potency * S.rate * 2, 1)
		var/weaken = max(seed.potency * S.rate, 0.5)
		if(M.slip(stun, weaken, src))
			for(var/datum/plant_gene/trait/T in seed.genes)
				T.on_slip(src, M)
		return 1
	..()

// Glow gene procs
/obj/item/weapon/reagent_containers/food/snacks/grown/Destroy()
	var/datum/plant_gene/trait/glow/G = seed.get_gene(/datum/plant_gene/trait/glow)
	if(G && ismob(loc))
		loc.AddLuminosity(-G.get_lum(seed))
	return ..()

/obj/item/weapon/reagent_containers/food/snacks/grown/pickup(mob/user)
	..()
	var/datum/plant_gene/trait/glow/G = seed.get_gene(/datum/plant_gene/trait/glow)
	if(G)
		SetLuminosity(0)
		user.AddLuminosity(G.get_lum(seed))

/obj/item/weapon/reagent_containers/food/snacks/grown/dropped(mob/user)
	..()
	var/datum/plant_gene/trait/glow/G = seed.get_gene(/datum/plant_gene/trait/glow)
	if(G)
		user.AddLuminosity(-G.get_lum(seed))
		SetLuminosity(G.get_lum(seed))

// For item-containing growns such as eggy or gatfruit
/obj/item/weapon/reagent_containers/food/snacks/grown/shell/attack_self(mob/user as mob)
	user.unEquip(src)
	if(trash)
		var/obj/item/weapon/T
		if(ispath(trash, /obj/item/weapon/grown) || ispath(trash, /obj/item/weapon/reagent_containers/food/snacks/grown))
			T = new trash(user.loc, seed)
		else
			T = new trash(user.loc)
		user.put_in_hands(T)
		user << "You open [src]\'s shell, revealing \a [T]."
	qdel(src)


code:
// Ambrosia - base type
/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia
	seed = /obj/item/seeds/ambrosia
	name = "ambrosia branch"
	desc = "This is a plant."
	icon_state = "ambrosiavulgaris"
	slot_flags = SLOT_HEAD
	filling_color = "#008000"
	bitesize_mod = 2

// Ambrosia Vulgaris
/obj/item/seeds/ambrosia
	name = "pack of ambrosia vulgaris seeds"
	desc = "These seeds grow into common ambrosia, a plant grown by and from medicine."
	icon_state = "seed-ambrosiavulgaris"
	species = "ambrosiavulgaris"
	plantname = "Ambrosia Vulgaris"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris
	lifespan = 60
	endurance = 25
	yield = 6
	potency = 5
	icon_dead = "ambrosia-dead"
	mutatelist = list(/obj/item/seeds/ambrosia/deus)
	reagents_add = list("space_drugs" = 0.15, "bicaridine" = 0.1, "kelotane" = 0.1, "vitamin" = 0.04, "nutriment" = 0.05, "toxin" = 0.1)

/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris
	seed = /obj/item/seeds/ambrosia
	name = "ambrosia vulgaris branch"
	desc = "This is a plant containing various healing chemicals."

// Ambrosia Deus
/obj/item/seeds/ambrosia/deus
	name = "pack of ambrosia deus seeds"
	desc = "These seeds grow into ambrosia deus. Could it be the food of the gods..?"
	icon_state = "seed-ambrosiadeus"
	species = "ambrosiadeus"
	plantname = "Ambrosia Deus"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/deus
	mutatelist = list()
	reagents_add = list("omnizine" = 0.15, "synaptizine" = 0.15, "space_drugs" = 0.1, "vitamin" = 0.04, "nutriment" = 0.05)
	rarity = 40

/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/deus
	seed = /obj/item/seeds/ambrosia/deus
	name = "ambrosia deus branch"
	desc = "Eating this makes you feel immortal!"
	icon_state = "ambrosiadeus"
	filling_color = "#008B8B"


code:
// Apple
/obj/item/seeds/apple
	name = "pack of apple seeds"
	desc = "These seeds grow into apple trees."
	icon_state = "seed-apple"
	species = "apple"
	plantname = "Apple Tree"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/apple
	lifespan = 55
	endurance = 35
	yield = 5
	icon_grow = "apple-grow"
	icon_dead = "apple-dead"
	mutatelist = list(/obj/item/seeds/apple/gold)
	reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1)

/obj/item/weapon/reagent_containers/food/snacks/grown/apple
	seed = /obj/item/seeds/apple
	name = "apple"
	desc = "It's a little piece of Eden."
	icon_state = "apple"
	filling_color = "#FF4500"
	bitesize = 100 // Always eat the apple in one bite

// Posioned Apple
/obj/item/seeds/apple/poisoned
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/apple/poisoned
	mutatelist = list()
	reagents_add = list("zombiepowder" = 0.5, "vitamin" = 0.04, "nutriment" = 0.1)
	rarity = 50 // Source of cyanide, and hard (almost impossible) to obtain normally.

/obj/item/weapon/reagent_containers/food/snacks/grown/apple/poisoned
	seed = /obj/item/seeds/apple/poisoned

// Gold Apple
/obj/item/seeds/apple/gold
	name = "pack of golden apple seeds"
	desc = "These seeds grow into golden apple trees. Good thing there are no firebirds in space."
	icon_state = "seed-goldapple"
	species = "goldapple"
	plantname = "Golden Apple Tree"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/apple/gold
	maturation = 10
	production = 10
	mutatelist = list()
	reagents_add = list("gold" = 0.2, "vitamin" = 0.04, "nutriment" = 0.1)
	rarity = 40 // Alchemy!

/obj/item/weapon/reagent_containers/food/snacks/grown/apple/gold
	seed = /obj/item/seeds/apple/gold
	name = "golden apple"
	desc = "Emblazoned upon the apple is the word 'Kallisti'."
	icon_state = "goldapple"
	filling_color = "#FFD700"


code:
// Banana
/obj/item/seeds/banana
	name = "pack of banana seeds"
	desc = "They're seeds that grow into banana trees. When grown, keep away from clown."
	icon_state = "seed-banana"
	species = "banana"
	plantname = "Banana Tree"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/banana
	lifespan = 50
	endurance = 30
	icon_dead = "banana-dead"
	genes = list(/datum/plant_gene/trait/slip)
	mutatelist = list(/obj/item/seeds/banana/mime, /obj/item/seeds/banana/bluespace)
	reagents_add = list("banana" = 0.1, "potassium" = 0.1, "vitamin" = 0.04, "nutriment" = 0.02)

/obj/item/weapon/reagent_containers/food/snacks/grown/banana
	seed = /obj/item/seeds/banana
	name = "banana"
	desc = "It's an excellent prop for a clown."
	icon_state = "banana"
	item_state = "banana"
	trash = /obj/item/weapon/grown/bananapeel
	filling_color = "#FFFF00"
	bitesize = 5

/obj/item/weapon/reagent_containers/food/snacks/grown/banana/suicide_act(mob/user)
	user.visible_message("[user] is aiming the [src.name] at themself! It looks like \he's trying to commit suicide.")
	playsound(loc, 'sound/items/bikehorn.ogg', 50, 1, -1)
	sleep(25)
	if(!user)
		return (OXYLOSS)
	user.say("BANG!")
	sleep(25)
	if(!user)
		return (OXYLOSS)
	user.visible_message("[user] laughs so hard they begin to suffocate!")
	return (OXYLOSS)

/obj/item/weapon/grown/bananapeel
	seed = /obj/item/seeds/banana
	name = "banana peel"
	desc = "A peel from a banana."
	icon_state = "banana_peel"
	item_state = "banana_peel"
	w_class = 1
	throwforce = 0
	throw_speed = 3
	throw_range = 7

/obj/item/weapon/grown/bananapeel/suicide_act(mob/user)
	user.visible_message("[user] is deliberately slipping on the [src.name]! It looks like \he's trying to commit suicide.")
	playsound(loc, 'sound/misc/slip.ogg', 50, 1, -1)
	return (BRUTELOSS)

// Mimana - invisible sprites are totally a feature!
/obj/item/seeds/banana/mime
	name = "pack of mimana seeds"
	desc = "They're seeds that grow into mimana trees. When grown, keep away from mime."
	icon_state = "seed-mimana"
	species = "mimana"
	plantname = "Mimana Tree"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/banana/mime
	growthstages = 4
	mutatelist = list()
	reagents_add = list("nothing" = 0.1, "mutetoxin" = 0.1, "nutriment" = 0.02)
	rarity = 15

/obj/item/weapon/reagent_containers/food/snacks/grown/banana/mime
	seed = /obj/item/seeds/banana/mime
	name = "mimana"
	desc = "It's an excellent prop for a mime."
	icon_state = "mimana"
	trash = /obj/item/weapon/grown/bananapeel/mimanapeel
	filling_color = "#FFFFEE"

/obj/item/weapon/grown/bananapeel/mimanapeel
	seed = /obj/item/seeds/banana/mime
	name = "mimana peel"
	desc = "A mimana peel."
	icon_state = "mimana_peel"

// Bluespace Banana
/obj/item/seeds/banana/bluespace
	name = "pack of bluespace banana seeds"
	desc = "They're seeds that grow into bluespace banana trees. When grown, keep away from bluespace clown."
	icon_state = "seed-banana-blue"
	species = "bluespacebanana"
	icon_grow = "banana-grow"
	plantname = "Bluespace Banana Tree"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/banana/bluespace
	mutatelist = list()
	genes = list(/datum/plant_gene/trait/slip, /datum/plant_gene/trait/teleport)
	reagents_add = list("singulo" = 0.2, "banana" = 0.1, "vitamin" = 0.04, "nutriment" = 0.02)
	rarity = 30

/obj/item/weapon/reagent_containers/food/snacks/grown/banana/bluespace
	seed = /obj/item/seeds/banana/bluespace
	name = "bluespace banana"
	icon_state = "banana_blue"
	trash = /obj/item/weapon/grown/bananapeel/bluespace
	filling_color = "#0000FF"

/obj/item/weapon/grown/bananapeel/bluespace
	seed = /obj/item/seeds/banana/bluespace
	name = "bluespace banana peel"
	desc = "A peel from a bluespace banana."
	icon_state = "banana_peel_blue"

// Other
/obj/item/weapon/grown/bananapeel/specialpeel     //used by /obj/item/clothing/shoes/clown_shoes/banana_shoes
	name = "synthesized banana peel"
	desc = "A synthetic banana peel."

/obj/item/weapon/grown/bananapeel/specialpeel/Crossed(AM)
	if(..())
		qdel(src)


code:
// Soybeans
/obj/item/seeds/soya
	name = "pack of soybean seeds"
	desc = "These seeds grow into soybean plants."
	icon_state = "seed-soybean"
	species = "soybean"
	plantname = "Soybean Plants"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/soybeans
	maturation = 4
	production = 4
	potency = 15
	growthstages = 4
	icon_grow = "soybean-grow"
	icon_dead = "soybean-dead"
	mutatelist = list(/obj/item/seeds/soya/koi)
	reagents_add = list("vitamin" = 0.04, "nutriment" = 0.05)

/obj/item/weapon/reagent_containers/food/snacks/grown/soybeans
	seed = /obj/item/seeds/soya
	name = "soybeans"
	desc = "It's pretty bland, but oh the possibilities..."
	gender = PLURAL
	icon_state = "soybeans"
	filling_color = "#F0E68C"
	bitesize_mod = 2

// Koibean
/obj/item/seeds/soya/koi
	name = "pack of koibean seeds"
	desc = "These seeds grow into koibean plants."
	icon_state = "seed-koibean"
	species = "koibean"
	plantname = "Koibean Plants"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/koibeans
	potency = 10
	mutatelist = list()
	reagents_add = list("carpotoxin" = 0.1, "vitamin" = 0.04, "nutriment" = 0.05)
	rarity = 20

/obj/item/weapon/reagent_containers/food/snacks/grown/koibeans
	seed = /obj/item/seeds/soya/koi
	name = "koibean"
	desc = "Something about these seems fishy."
	icon_state = "koibeans"
	filling_color = "#F0E68C"
	bitesize_mod = 2


code:
// Berries
/obj/item/seeds/berry
	name = "pack of berry seeds"
	desc = "These seeds grow into berry bushes."
	icon_state = "seed-berry"
	species = "berry"
	plantname = "Berry Bush"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/berries
	lifespan = 20
	maturation = 5
	production = 5
	yield = 2
	icon_grow = "berry-grow" // Uses one growth icons set for all the subtypes
	icon_dead = "berry-dead" // Same for the dead icon
	mutatelist = list(/obj/item/seeds/berry/glow, /obj/item/seeds/berry/poison)
	reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1)

/obj/item/weapon/reagent_containers/food/snacks/grown/berries
	seed = /obj/item/seeds/berry
	name = "bunch of berries"
	desc = "Nutritious!"
	icon_state = "berrypile"
	gender = PLURAL
	filling_color = "#FF00FF"
	bitesize_mod = 2

// Poison Berries
/obj/item/seeds/berry/poison
	name = "pack of poison-berry seeds"
	desc = "These seeds grow into poison-berry bushes."
	icon_state = "seed-poisonberry"
	species = "poisonberry"
	plantname = "Poison-Berry Bush"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/berries/poison
	mutatelist = list(/obj/item/seeds/berry/death)
	reagents_add = list("cyanide" = 0.15, "tirizene" = 0.2, "vitamin" = 0.04, "nutriment" = 0.1)
	rarity = 10 // Mildly poisonous berries are common in reality

/obj/item/weapon/reagent_containers/food/snacks/grown/berries/poison
	seed = /obj/item/seeds/berry/poison
	name = "bunch of poison-berries"
	desc = "Taste so good, you could die!"
	icon_state = "poisonberrypile"
	filling_color = "#C71585"

// Death Berries
/obj/item/seeds/berry/death
	name = "pack of death-berry seeds"
	desc = "These seeds grow into death berries."
	icon_state = "seed-deathberry"
	species = "deathberry"
	plantname = "Death Berry Bush"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/berries/death
	lifespan = 30
	potency = 50
	mutatelist = list()
	reagents_add = list("coniine" = 0.08, "tirizene" = 0.1, "vitamin" = 0.04, "nutriment" = 0.1)
	rarity = 30

/obj/item/weapon/reagent_containers/food/snacks/grown/berries/death
	seed = /obj/item/seeds/berry/death
	name = "bunch of death-berries"
	desc = "Taste so good, you could die!"
	icon_state = "deathberrypile"
	filling_color = "#708090"

// Glow Berries
/obj/item/seeds/berry/glow
	name = "pack of glow-berry seeds"
	desc = "These seeds grow into glow-berry bushes."
	icon_state = "seed-glowberry"
	species = "glowberry"
	plantname = "Glow-Berry Bush"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/berries/glow
	lifespan = 30
	endurance = 25
	mutatelist = list()
	genes = list(/datum/plant_gene/trait/glow/berry)
	reagents_add = list("uranium" = 0.25, "iodine" = 0.2, "vitamin" = 0.04, "nutriment" = 0.1)
	rarity = 20

/obj/item/weapon/reagent_containers/food/snacks/grown/berries/glow
	seed = /obj/item/seeds/berry/glow
	name = "bunch of glow-berries"
	desc = "Nutritious!"
	icon_state = "glowberrypile"
	filling_color = "#7CFC00"

// Cherries
/obj/item/seeds/cherry
	name = "pack of cherry pits"
	desc = "Careful not to crack a tooth on one... That'd be the pits."
	icon_state = "seed-cherry"
	species = "cherry"
	plantname = "Cherry Tree"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/cherries
	lifespan = 35
	endurance = 35
	maturation = 5
	production = 5
	growthstages = 5
	icon_grow = "cherry-grow"
	icon_dead = "cherry-dead"
	mutatelist = list(/obj/item/seeds/cherry/blue)
	reagents_add = list("nutriment" = 0.07, "sugar" = 0.07)

/obj/item/weapon/reagent_containers/food/snacks/grown/cherries
	seed = /obj/item/seeds/cherry
	name = "cherries"
	desc = "Great for toppings!"
	icon_state = "cherry"
	gender = PLURAL
	filling_color = "#FF0000"
	bitesize_mod = 2

// Blue Cherries
/obj/item/seeds/cherry/blue
	name = "pack of blue cherry pits"
	desc = "The blue kind of cherries"
	icon_state = "seed-bluecherry"
	species = "bluecherry"
	plantname = "Blue Cherry Tree"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries
	mutatelist = list()
	reagents_add = list("nutriment" = 0.07, "sugar" = 0.07)
	rarity = 10

/obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries
	seed = /obj/item/seeds/cherry/blue
	name = "blue cherries"
	desc = "They're cherries that are blue."
	icon_state = "bluecherry"
	filling_color = "#6495ED"
	bitesize_mod = 2

// Grapes
/obj/item/seeds/grape
	name = "pack of grape seeds"
	desc = "These seeds grow into grape vines."
	icon_state = "seed-grapes"
	species = "grape"
	plantname = "Grape Vine"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/grapes
	lifespan = 50
	endurance = 25
	maturation = 3
	production = 5
	yield = 4
	growthstages = 2
	icon_grow = "grape-grow"
	icon_dead = "grape-dead"
	mutatelist = list(/obj/item/seeds/grape/green)
	reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1, "sugar" = 0.1)

/obj/item/weapon/reagent_containers/food/snacks/grown/grapes
	seed = /obj/item/seeds/grape
	name = "bunch of grapes"
	desc = "Nutritious!"
	icon_state = "grapes"
	dried_type = /obj/item/weapon/reagent_containers/food/snacks/no_raisin
	filling_color = "#FF1493"
	bitesize_mod = 2

// Green Grapes
/obj/item/seeds/grape/green
	name = "pack of green grape seeds"
	desc = "These seeds grow into green-grape vines."
	icon_state = "seed-greengrapes"
	species = "greengrape"
	plantname = "Green-Grape Vine"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/grapes/green
	reagents_add = list("kelotane" = 0.2, "vitamin" = 0.04, "nutriment" = 0.1, "sugar" = 0.1)
	// No rarity: technically it's a beneficial mutant, but it's not exactly "new"...
	mutatelist = list()

/obj/item/weapon/reagent_containers/food/snacks/grown/grapes/green
	seed = /obj/item/seeds/grape/green
	name = "bunch of green grapes"
	icon_state = "greengrapes"
	filling_color = "#7FFF00"


code:
// Wheat
/obj/item/seeds/wheat
	name = "pack of wheat seeds"
	desc = "These may, or may not, grow into wheat."
	icon_state = "seed-wheat"
	species = "wheat"
	plantname = "Wheat Stalks"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/wheat
	production = 1
	yield = 4
	potency = 15
	oneharvest = 1
	icon_dead = "wheat-dead"
	mutatelist = list(/obj/item/seeds/wheat/oat)
	reagents_add = list("nutriment" = 0.04)

/obj/item/weapon/reagent_containers/food/snacks/grown/wheat
	seed = /obj/item/seeds/wheat
	name = "wheat"
	desc = "Sigh... wheat... a-grain?"
	gender = PLURAL
	icon_state = "wheat"
	filling_color = "#F0E68C"
	bitesize_mod = 2

// Oat
/obj/item/seeds/wheat/oat
	name = "pack of oat seeds"
	desc = "These may, or may not, grow into oat."
	icon_state = "seed-oat"
	species = "oat"
	plantname = "Oat Stalks"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/oat
	mutatelist = list()

/obj/item/weapon/reagent_containers/food/snacks/grown/oat
	seed = /obj/item/seeds/wheat/oat
	name = "oat"
	desc = "Eat oats, do squats."
	gender = PLURAL
	icon_state = "oat"
	filling_color = "#556B2F"
	bitesize_mod = 2

// Rice
/obj/item/seeds/wheat/rice
	name = "pack of rice seeds"
	desc = "These may, or may not, grow into rice."
	icon_state = "seed-rice"
	species = "rice"
	plantname = "Rice Stalks"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/rice
	mutatelist = list()
	growthstages = 3

/obj/item/weapon/reagent_containers/food/snacks/grown/rice
	seed = /obj/item/seeds/wheat/rice
	name = "rice"
	desc = "Rice to meet you."
	gender = PLURAL
	icon_state = "rice"
	filling_color = "#FAFAD2"
	bitesize_mod = 2


code:
// Chili
/obj/item/seeds/chili
	name = "pack of chili seeds"
	desc = "These seeds grow into chili plants. HOT! HOT! HOT!"
	icon_state = "seed-chili"
	species = "chili"
	plantname = "Chili Plants"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/chili
	lifespan = 20
	maturation = 5
	production = 5
	yield = 4
	potency = 20
	icon_grow = "chili-grow" // Uses one growth icons set for all the subtypes
	icon_dead = "chili-dead" // Same for the dead icon
	mutatelist = list(/obj/item/seeds/chili/ice, /obj/item/seeds/chili/ghost)
	reagents_add = list("capsaicin" = 0.25, "vitamin" = 0.04, "nutriment" = 0.04)

/obj/item/weapon/reagent_containers/food/snacks/grown/chili
	seed = /obj/item/seeds/chili
	name = "chili"
	desc = "It's spicy! Wait... IT'S BURNING ME!!"
	icon_state = "chilipepper"
	filling_color = "#FF0000"
	bitesize_mod = 2

// Ice Chili
/obj/item/seeds/chili/ice
	name = "pack of ice pepper seeds"
	desc = "These seeds grow into ice pepper plants."
	icon_state = "seed-icepepper"
	species = "chiliice"
	plantname = "Ice Pepper Plants"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/icepepper
	lifespan = 25
	maturation = 4
	production = 4
	rarity = 20
	mutatelist = list()
	reagents_add = list("frostoil" = 0.25, "vitamin" = 0.02, "nutriment" = 0.02)

/obj/item/weapon/reagent_containers/food/snacks/grown/icepepper
	seed = /obj/item/seeds/chili/ice
	name = "ice pepper"
	desc = "It's a mutant strain of chili"
	icon_state = "icepepper"
	filling_color = "#0000CD"
	bitesize_mod = 2

// Ghost Chili
/obj/item/seeds/chili/ghost
	name = "pack of ghost chili seeds"
	desc = "These seeds grow into a chili said to be the hottest in the galaxy."
	icon_state = "seed-chilighost"
	species = "chilighost"
	plantname = "chilighost"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/ghost_chili
	endurance = 10
	maturation = 10
	production = 10
	yield = 3
	rarity = 20
	mutatelist = list()
	reagents_add = list("condensedcapsaicin" = 0.3, "capsaicin" = 0.55, "nutriment" = 0.04)

/obj/item/weapon/reagent_containers/food/snacks/grown/ghost_chili
	seed = /obj/item/seeds/chili/ghost
	name = "ghost chili"
	desc = "It seems to be vibrating gently."
	icon_state = "ghostchilipepper"
	var/mob/held_mob
	filling_color = "#F8F8FF"
	bitesize_mod = 4

/obj/item/weapon/reagent_containers/food/snacks/grown/ghost_chili/attack_hand(mob/user)
	..()
	if( istype(src.loc, /mob) )
		held_mob = src.loc
		SSobj.processing |= src

/obj/item/weapon/reagent_containers/food/snacks/grown/ghost_chili/process()
	if(held_mob && src.loc == held_mob)
		if( (held_mob.l_hand == src) || (held_mob.r_hand == src))
			if(hasvar(held_mob,"gloves") && held_mob:gloves)
				return
			held_mob.bodytemperature += 15 * TEMPERATURE_DAMAGE_COEFFICIENT
			if(prob(10))
				held_mob << "Your hand holding [src] burns!"
	else
		held_mob = null
		..()


code:
// Citrus - base type
/obj/item/weapon/reagent_containers/food/snacks/grown/citrus
	seed = /obj/item/seeds/lime
	name = "citrus"
	desc = "It's so sour, your face will twist."
	icon_state = "lime"
	bitesize_mod = 2

// Lime
/obj/item/seeds/lime
	name = "pack of lime seeds"
	desc = "These are very sour seeds."
	icon_state = "seed-lime"
	species = "lime"
	plantname = "Lime Tree"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lime
	lifespan = 55
	endurance = 50
	yield = 4
	potency = 15
	mutatelist = list(/obj/item/seeds/orange)
	reagents_add = list("vitamin" = 0.04, "nutriment" = 0.05)

/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lime
	seed = /obj/item/seeds/lime
	name = "lime"
	desc = "It's so sour, your face will twist."
	icon_state = "lime"
	filling_color = "#00FF00"

// Orange
/obj/item/seeds/orange
	name = "pack of orange seeds"
	desc = "Sour seeds."
	icon_state = "seed-orange"
	species = "orange"
	plantname = "Orange Tree"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/orange
	lifespan = 60
	endurance = 50
	yield = 5
	potency = 20
	icon_grow = "lime-grow"
	icon_dead = "lime-dead"
	mutatelist = list(/obj/item/seeds/lime)
	reagents_add = list("vitamin" = 0.04, "nutriment" = 0.05)

/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/orange
	seed = /obj/item/seeds/orange
	name = "orange"
	desc = "It's an tangy fruit."
	icon_state = "orange"
	filling_color = "#FFA500"

// Lemon
/obj/item/seeds/lemon
	name = "pack of lemon seeds"
	desc = "These are sour seeds."
	icon_state = "seed-lemon"
	species = "lemon"
	plantname = "Lemon Tree"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lemon
	lifespan = 55
	endurance = 45
	yield = 4
	icon_grow = "lime-grow"
	icon_dead = "lime-dead"
	mutatelist = list(/obj/item/seeds/cash)
	reagents_add = list("vitamin" = 0.04, "nutriment" = 0.05)

/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lemon
	seed = /obj/item/seeds/lemon
	name = "lemon"
	desc = "When life gives you lemons, be grateful they aren't limes."
	icon_state = "lemon"
	filling_color = "#FFD700"

// Money Lemon
/obj/item/seeds/cash
	name = "pack of money seeds"
	desc = "When life gives you lemons, mutate them into cash."
	icon_state = "seed-cash"
	species = "cashtree"
	plantname = "Money Tree"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/shell/moneyfruit
	icon_grow = "lime-grow"
	icon_dead = "lime-dead"
	lifespan = 55
	endurance = 45
	yield = 4
	reagents_add = list("nutriment" = 0.05)
	rarity = 50  // Nanotrasen approves...

/obj/item/weapon/reagent_containers/food/snacks/grown/shell/moneyfruit
	seed = /obj/item/seeds/cash
	name = "Money Fruit"
	desc = "Looks like a lemon with someone buldging from the inside."
	icon_state = "moneyfruit"
	bitesize_mod = 2

/obj/item/weapon/reagent_containers/food/snacks/grown/shell/moneyfruit/add_juice()
	..()
	switch(seed.potency)
		if(0 to 10)
			trash = /obj/item/stack/spacecash
		if(11 to 20)
			trash = /obj/item/stack/spacecash/c10
		if(21 to 30)
			trash = /obj/item/stack/spacecash/c20
		if(31 to 40)
			trash = /obj/item/stack/spacecash/c50
		if(41 to 50)
			trash = /obj/item/stack/spacecash/c100
		if(51 to 60)
			trash = /obj/item/stack/spacecash/c200
		if(61 to 80)
			trash = /obj/item/stack/spacecash/c500
		else
			trash = /obj/item/stack/spacecash/c1000


code:
// Cocoa Pod
/obj/item/seeds/cocoapod
	name = "pack of cocoa pod seeds"
	desc = "These seeds grow into cacao trees. They look fattening." //SIC: cocoa is the seeds. The trees are spelled cacao.
	icon_state = "seed-cocoapod"
	species = "cocoapod"
	plantname = "Cocao Tree"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/cocoapod
	lifespan = 20
	maturation = 5
	production = 5
	yield = 2
	growthstages = 5
	icon_grow = "cocoapod-grow"
	icon_dead = "cocoapod-dead"
	mutatelist = list(/obj/item/seeds/cocoapod/vanillapod)
	reagents_add = list("cocoa" = 0.25, "nutriment" = 0.1)

/obj/item/weapon/reagent_containers/food/snacks/grown/cocoapod
	seed = /obj/item/seeds/cocoapod
	name = "cocoa pod"
	desc = "Fattening... Mmmmm... chucklate."
	icon_state = "cocoapod"
	filling_color = "#FFD700"
	bitesize_mod = 2

// Vanilla Pod
/obj/item/seeds/cocoapod/vanillapod
	name = "pack of vanilla pod seeds"
	desc = "These seeds grow into vanilla trees. They look fattening."
	icon_state = "seed-vanillapod"
	species = "vanillapod"
	plantname = "Vanilla Tree"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/vanillapod
	mutatelist = list()
	reagents_add = list("vanilla" = 0.25, "nutriment" = 0.1)

/obj/item/weapon/reagent_containers/food/snacks/grown/vanillapod
	seed = /obj/item/seeds/cocoapod/vanillapod
	name = "vanilla pod"
	desc = "Fattening... Mmmmm... vanilla."
	icon_state = "vanillapod"
	filling_color = "#FFD700"


code:
// Corn
/obj/item/seeds/corn
	name = "pack of corn seeds"
	desc = "I don't mean to sound corny..."
	icon_state = "seed-corn"
	species = "corn"
	plantname = "Corn Stalks"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/corn
	maturation = 8
	oneharvest = 1
	potency = 20
	growthstages = 3
	icon_grow = "corn-grow" // Uses one growth icons set for all the subtypes
	icon_dead = "corn-dead" // Same for the dead icon
	mutatelist = list(/obj/item/seeds/corn/snapcorn)
	reagents_add = list("cornoil" = 0.2, "vitamin" = 0.04, "nutriment" = 0.1)

/obj/item/weapon/reagent_containers/food/snacks/grown/corn
	seed = /obj/item/seeds/corn
	name = "ear of corn"
	desc = "Needs some butter!"
	icon_state = "corn"
	cooked_type = /obj/item/weapon/reagent_containers/food/snacks/popcorn
	filling_color = "#FFFF00"
	trash = /obj/item/weapon/grown/corncob
	bitesize_mod = 2

/obj/item/weapon/grown/corncob
	name = "corn cob"
	desc = "A reminder of meals gone by."
	icon_state = "corncob"
	item_state = "corncob"
	w_class = 1
	throwforce = 0
	throw_speed = 3
	throw_range = 7

/obj/item/weapon/grown/corncob/attackby(obj/item/weapon/grown/W, mob/user, params)
	..()
	if(W.is_sharp())
		user << "You use [W] to fashion a pipe out of the corn cob!"
		new /obj/item/clothing/mask/cigarette/pipe/cobpipe (user.loc)
		user.unEquip(src)
		qdel(src)
		return

// Snapcorn
/obj/item/seeds/corn/snapcorn
	name = "pack of snapcorn seeds"
	desc = "Oh snap!"
	icon_state = "seed-snapcorn"
	species = "snapcorn"
	plantname = "Snapcorn Stalks"
	product = /obj/item/weapon/grown/snapcorn
	mutatelist = list()
	rarity = 10

/obj/item/weapon/grown/snapcorn
	seed = /obj/item/seeds/corn/snapcorn
	name = "snap corn"
	desc = "A cob with snap pops"
	icon_state = "snapcorn"
	item_state = "corncob"
	w_class = 1
	throwforce = 0
	throw_speed = 3
	throw_range = 7
	var/snap_pops = 1

/obj/item/weapon/grown/snapcorn/add_juice()
	..()
	snap_pops = max(round(seed.potency/8), 1)

/obj/item/weapon/grown/snapcorn/attack_self(mob/user)
	..()
	user << "You pick up a snap pops from the cob."
	var/obj/item/toy/snappop/S = new /obj/item/toy/snappop(user.loc)
	if(ishuman(user))
		user.put_in_hands(S)
	snap_pops -= 1
	if(!snap_pops)
		new /obj/item/weapon/grown/corncob(user.loc)
		qdel(src)


code:
// Eggplant
/obj/item/seeds/eggplant
	name = "pack of eggplant seeds"
	desc = "These seeds grow to produce berries that look nothing like eggs."
	icon_state = "seed-eggplant"
	species = "eggplant"
	plantname = "Eggplants"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/eggplant
	yield = 2
	potency = 20
	icon_grow = "eggplant-grow"
	icon_dead = "eggplant-dead"
	mutatelist = list(/obj/item/seeds/eggplant/eggy)
	reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1)

/obj/item/weapon/reagent_containers/food/snacks/grown/eggplant
	seed = /obj/item/seeds/eggplant
	name = "eggplant"
	desc = "Maybe there's a chicken inside?"
	icon_state = "eggplant"
	filling_color = "#800080"
	bitesize_mod = 2

// Egg-Plant
/obj/item/seeds/eggplant/eggy
	desc = "These seeds grow to produce berries that look a lot like eggs."
	icon_state = "seed-eggy"
	species = "eggy"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/shell/eggy
	lifespan = 75
	production = 12
	mutatelist = list()
	reagents_add = list("nutriment" = 0.1)

/obj/item/weapon/reagent_containers/food/snacks/grown/shell/eggy
	seed = /obj/item/seeds/eggplant/eggy
	name = "Egg-plant"
	desc = "There MUST be a chicken inside."
	icon_state = "eggyplant"
	trash = /obj/item/weapon/reagent_containers/food/snacks/egg
	filling_color = "#F8F8FF"
	bitesize_mod = 2


code:
// Poppy
/obj/item/seeds/poppy
	name = "pack of poppy seeds"
	desc = "These seeds grow into poppies."
	icon_state = "seed-poppy"
	species = "poppy"
	plantname = "Poppy Plants"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/poppy
	endurance = 10
	maturation = 8
	yield = 6
	potency = 20
	oneharvest = 1
	growthstages = 3
	icon_grow = "poppy-grow"
	icon_dead = "poppy-dead"
	mutatelist = list(/obj/item/seeds/poppy/geranium, /obj/item/seeds/poppy/lily)
	reagents_add = list("bicaridine" = 0.2, "nutriment" = 0.05)

/obj/item/weapon/reagent_containers/food/snacks/grown/poppy
	seed = /obj/item/seeds/poppy
	name = "poppy"
	desc = "Long-used as a symbol of rest, peace, and death."
	icon_state = "poppy"
	slot_flags = SLOT_HEAD
	filling_color = "#FF6347"
	bitesize_mod = 3

// Lily
/obj/item/seeds/poppy/lily
	name = "pack of lily seeds"
	desc = "These seeds grow into lilies."
	icon_state = "seed-lily"
	species = "lily"
	plantname = "Lily Plants"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/poppy/lily
	mutatelist = list()

/obj/item/weapon/reagent_containers/food/snacks/grown/poppy/lily
	seed = /obj/item/seeds/poppy/lily
	name = "lily"
	desc = "A beautiful orange flower"
	icon_state = "lily"
	filling_color = "#FFA500"

// Geranium
/obj/item/seeds/poppy/geranium
	name = "pack of geranium seeds"
	desc = "These seeds grow into geranium."
	icon_state = "seed-geranium"
	species = "geranium"
	plantname = "Geranium Plants"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/poppy/geranium
	mutatelist = list()

/obj/item/weapon/reagent_containers/food/snacks/grown/poppy/geranium
	seed = /obj/item/seeds/poppy/geranium
	name = "geranium"
	desc = "A beautiful blue flower"
	icon_state = "geranium"
	filling_color = "#008B8B"

// Harebell
/obj/item/seeds/harebell
	name = "pack of harebell seeds"
	desc = "These seeds grow into pretty little flowers."
	icon_state = "seed-harebell"
	species = "harebell"
	plantname = "Harebells"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/harebell
	lifespan = 100
	endurance = 20
	maturation = 7
	production = 1
	yield = 2
	potency = 30
	oneharvest = 1
	growthstages = 4
	plant_type = PLANT_WEED
	reagents_add = list("nutriment" = 0.04)

/obj/item/weapon/reagent_containers/food/snacks/grown/harebell
	seed = /obj/item/seeds/harebell
	name = "harebell"
	desc = "\"I'll sweeten thy sad grave: thou shalt not lack the flower that's like thy face, pale primrose, nor the azured hare-bell, like thy veins; no, nor the leaf of eglantine, whom not to slander, out-sweeten'd not thy breath.\""
	icon_state = "harebell"
	slot_flags = SLOT_HEAD
	filling_color = "#E6E6FA"
	bitesize_mod = 3

// Sunflower
/obj/item/seeds/sunflower
	name = "pack of sunflower seeds"
	desc = "These seeds grow into sunflowers."
	icon_state = "seed-sunflower"
	species = "sunflower"
	plantname = "Sunflowers"
	product = /obj/item/weapon/grown/sunflower
	endurance = 20
	production = 2
	yield = 2
	oneharvest = 1
	growthstages = 3
	icon_grow = "sunflower-grow"
	icon_dead = "sunflower-dead"
	mutatelist = list(/obj/item/seeds/sunflower/moonflower, /obj/item/seeds/sunflower/novaflower)
	reagents_add = list("cornoil" = 0.08, "nutriment" = 0.04)

/obj/item/weapon/grown/sunflower // FLOWER POWER!
	seed = /obj/item/seeds/sunflower
	name = "sunflower"
	desc = "It's beautiful! A certain person might beat you to death if you trample these."
	icon_state = "sunflower"
	damtype = "fire"
	force = 0
	slot_flags = SLOT_HEAD
	throwforce = 0
	w_class = 1
	throw_speed = 1
	throw_range = 3

/obj/item/weapon/grown/sunflower/attack(mob/M, mob/user)
	M << " [user] smacks you with a sunflower!FLOWER POWER"
	user << "Your sunflower's FLOWER POWERstrikes [M]"

// Moonflower
/obj/item/seeds/sunflower/moonflower
	name = "pack of moonflower seeds"
	desc = "These seeds grow into moonflowers."
	icon_state = "seed-moonflower"
	species = "moonflower"
	plantname = "Moonflowers"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/moonflower
	mutatelist = list()
	reagents_add = list("moonshine" = 0.2, "vitamin" = 0.02, "nutriment" = 0.02)
	rarity = 15

/obj/item/weapon/reagent_containers/food/snacks/grown/moonflower
	seed = /obj/item/seeds/sunflower/moonflower
	name = "moonflower"
	desc = "Store in a location at least 50 yards away from werewolves."
	icon_state = "moonflower"
	slot_flags = SLOT_HEAD
	filling_color = "#E6E6FA"
	bitesize_mod = 2

// Novaflower
/obj/item/seeds/sunflower/novaflower
	name = "pack of novaflower seeds"
	desc = "These seeds grow into novaflowers."
	icon_state = "seed-novaflower"
	species = "novaflower"
	plantname = "Novaflowers"
	product = /obj/item/weapon/grown/novaflower
	mutatelist = list()
	reagents_add = list("condensedcapsaicin" = 0.25, "capsaicin" = 0.3, "nutriment" = 0)
	rarity = 20

/obj/item/weapon/grown/novaflower
	seed = /obj/item/seeds/sunflower/novaflower
	name = "novaflower"
	desc = "These beautiful flowers have a crisp smokey scent, like a summer bonfire."
	icon_state = "novaflower"
	damtype = "fire"
	force = 0
	slot_flags = SLOT_HEAD
	throwforce = 0
	w_class = 1
	throw_speed = 1
	throw_range = 3
	attack_verb = list("roasted", "scorched", "burned")

/obj/item/weapon/grown/novaflower/add_juice()
	..()
	force = round((5 + seed.potency / 5), 1)

/obj/item/weapon/grown/novaflower/attack(mob/living/carbon/M, mob/user)
	if(!..()) return
	if(istype(M, /mob/living))
		M << "You are lit on fire from the intense heat of the [name]!"
		M.adjust_fire_stacks(seed.potency / 20)
		M.IgniteMob()

/obj/item/weapon/grown/novaflower/afterattack(atom/A as mob|obj, mob/user,proximity)
	if(!proximity) return
	if(force > 0)
		force -= rand(1, (force / 3) + 1)
	else
		usr << "All the petals have fallen off the [name] from violent whacking!"
		usr.unEquip(src)
		qdel(src)

/obj/item/weapon/grown/novaflower/pickup(mob/living/carbon/human/user)
	..()
	if(!user.gloves)
		user << "The [name] burns your bare hand!"
		user.adjustFireLoss(rand(1, 5))


code:
// Grass
/obj/item/seeds/grass
	name = "pack of grass seeds"
	desc = "These seeds grow into grass. Yummy!"
	icon_state = "seed-grass"
	species = "grass"
	plantname = "Grass"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/grass
	lifespan = 40
	endurance = 40
	maturation = 2
	production = 5
	yield = 5
	growthstages = 2
	icon_grow = "grass-grow"
	icon_dead = "grass-dead"
	mutatelist = list(/obj/item/seeds/grass/carpet)
	reagents_add = list("nutriment" = 0.02, "hydrogen" = 0.05)

/obj/item/weapon/reagent_containers/food/snacks/grown/grass
	seed = /obj/item/seeds/grass
	name = "grass"
	desc = "Green and lush."
	icon_state = "grassclump"
	filling_color = "#32CD32"
	bitesize_mod = 2

/obj/item/weapon/reagent_containers/food/snacks/grown/grass/attack_self(mob/user)
	user << "You prepare the astroturf."
	var/grassAmt = 1 + round(seed.potency / 50) // The grass we're holding
	for(var/obj/item/weapon/reagent_containers/food/snacks/grown/grass/G in user.loc) // The grass on the floor
		grassAmt += 1 + round(G.seed.potency)
		qdel(G)
	while(grassAmt > 0)
		var/obj/item/stack/tile/GT = new /obj/item/stack/tile/grass(user.loc)
		if(grassAmt >= GT.max_amount)
			GT.amount = GT.max_amount
		else
			GT.amount = grassAmt
			for(var/obj/item/stack/tile/grass/GR in user.loc)
				if(GR != GT && GR.amount < GR.max_amount)
					GR.attackby(GT, user) //we try to transfer all old unfinished stacks to the new stack we created.
		grassAmt -= GT.max_amount
	qdel(src)
	return

// Carpet
/obj/item/seeds/grass/carpet
	name = "pack of carpet seeds"
	desc = "These seeds grow into stylish carpet samples."
	icon_state = "seed-carpet"
	species = "carpet"
	plantname = "Carpet"
	product = /obj/item/weapon/reagent_containers/food/snacks/grown/carpet
	mutatelist = list(/obj/item/seeds/grass/carpet)
	rarity = 10

/obj/item/weapon/reagent_containers/food/snacks/grown/carpet
	seed = /obj/item/seeds/grass/carpet
	name = "carpet"
	desc = "The textile industry's dark secret."
	icon_state = "carpetclump"

/obj/item/weapon/reagent_containers/food/snacks/grown/carpet/attack_self(mob/user)
	user << "You roll out the red carpet."
	var/carpetAmt = 1 + round(seed.potency / 50) // The carpet we're holding
	for(var/obj/item/weapon/reagent_containers/food/snacks/grown/carpet/C in user.loc) // The carpet on the floor
		carpetAmt += 1 + round(C.seed.potency / 50)
		qdel(C)
	while(carpetAmt > 0)
		var/obj/item/stack/tile/CT = new /obj/item/stack/tile/carpet(user.loc)
		if(carpetAmt >= CT.max_amount)
			CT.amount = CT.max_amount
		else
			CT.amount = carpetAmt
			for(var/obj/item/stack/tile/carpet/CA in user.loc)
				if(CA != CT && CA.amount < CA.max_amount)
					CA.attackby(CT, user) //we try to transfer all old unfinished stacks to the new stack we created.
		carpetAmt -= CT.max_amount
	qdel(src)
	return