Skip to content

Using multitool menus.

PJB3005 edited this page Jul 24, 2015 · 5 revisions

What is a multitool menu?

Multitool menus are menus on machinery for configuring certain settings, such as frequencies, IDs, and other stuff, as the name would suggest you need a multitool to open one.

One of the best examples of a multitool menu is telecomms machinery: An example of multitool menus used in telecomms.

Other examples include :

  • Atmospherics machinery
  • Cycling airlocks

How do I use them?

Procs with a '*' in front of them should be overriden.

NOTE: Don't ask me why but N3X15 placed half the code under /obj and the other half under /obj/machinery, objs only have the code for the basic UI, I don't even know why either.

To have multitool menus enabled on your machine, simply add the MULTITOOL_MENU bitflag to machine_flags on your machine.

basic procs

These are the basic procs and code you're gonna need to setup the multitool menu: Now, using this code as is will just open a blank multitool menu, let's see how to add some stuff to it:

* multitool_menu(var/mob/user, var/obj/item/device/multitool/P)

Params:

  • var/mob/user: The mob that's using this multitool menu.
  • var/obj/item/device/multitool/P: The multitool this multitool menu was opened with.

Should return: Valid HTML markup, this should only be the content, other stuff is handled for you.

Example:

/obj/machinery/atmospherics/unary/vent_pump/multitool_menu(var/mob/user,var/obj/item/device/multitool/P)
	return {"
	<ul>
		<li><b>Frequency:</b> <a href="?src=\ref[src];set_freq=-1">[format_frequency(frequency)] GHz</a> (<a href="?src=\ref[src];set_freq=[1439]">Reset</a>)</li>
		<li>[format_tag("ID Tag","id_tag","set_id")]</li>
	</ul>
	"}

That's the basics of multitool menus down.

format_tag(var/label, var/varname, var/act="set_tag")

This proc will easily format href in relation to vars on the src object, currently it's only used with the 'set_tag' act, as such I will only refer to that.

'set_tag' is an easy way to set a var on the object to input from a user.

'set_id' is used instead by vents, but this is only because they have shit code and are snowflaky, don't use 'set_id'.

Due to HREF exploit reason, you need to make sure the var you're allowing the user to edit is in a special list, this list is at the beginning of machinery.dm

Params:

  • var/label: What should be in front of the field containing the variable's data, for clarification for the user.
  • var/varname: The name of the variable on the src that the user's input should be outputted to.
  • var/act="set_tag": Only set_tag is used, this would determine the action that would happen with the var.

Returns: A preformatted HREF for use in, for example, multitool menus.

Example:

/obj/machinery/atmospherics/unary/vent_scrubber/multitool_menu(var/mob/user,var/obj/item/device/multitool/P)
	return {"
	<ul>
		<li><b>Frequency:</b> <a href="?src=\ref[src];set_freq=-1">[format_frequency(frequency)] GHz</a> (<a href="?src=\ref[src];set_freq=[1439]">Reset</a>)</li>
		<li>[format_tag("ID Tag","id_tag")]</li>
	</ul>
	"}

Will turn out this:

An image of a multitool menu with format_tag() in action.

Other HREFs

set_frequency

Due to the way radio connections are coded, a certain proc needs to be called for a change in the frequency var of an object to take effect (you can't specify the var name, it is always assumed to be frequency.), radio related machinery has this code in initialize().

Using set_frequency will automatically re-initialize() the object.

The number associated with set_frequency will determine what the frequency should be set to, if it is -1, the user can manually enter it.

So yes, you people out there that understand Jscript can set the frequency through a fancier HTML box.

Example:

	<ul>
		<li><b>Frequency:</b> <a href="?src=\ref[src];set_freq=-1">[format_frequency(frequency)] GHz</a> (<a href="?src=\ref[src];set_freq=[1439]">Reset</a>)</li>
		<li>[format_tag("ID Tag","id_tag")]</li>
	</ul>

More advanced stuff

* multitool_topic(var/mob/user, var/list/href_list, var/obj/O)

If simple var setting isn't good enough for you, you'll want to add extra hrefs to Topic(), however, you should use multitool_topic() for any HREFs in a multitool menu, why?

  • You can re-initialize the object via return values.
  • You can update the multitool menu via return values.
  • It will check if the user actually has a multitool and he isn't a HREF exploiting prick.

Params:

  • var/mob/user: User, duh.
  • var/list/href_list: list of HREFs passed down from Topic().
  • var/obj/O: The object in the multitool's buffer, don't use this for linkin though, we'll get to that!

Should return:

  • MT_UPDATE: Will make the multitool menu update, if possible.
  • MT_REINIT: Will make the object re-initialize().
  • MT_UPDATE|MT_REINIT: Both of the above.
  • MT_ERROR: Well something went wrong now didn't it? Causes re initialization and menu updating from internal HREFs to cancel, practical use is... None?

Example:

/obj/machinery/air_sensor/multitool_topic(var/mob/user, var/list/href_list, var/obj/O)
	. = ..()
	if(.)
		return .

	if("toggle_out_flag" in href_list)
		var/bitflag_value = text2num(href_list["toggle_out_flag"])//this is a string normally
		if(!test_bitflag(bitflag_value) && bitflag_value <= 32) //Here to prevent breaking the sensors with HREF exploits
			return 0
		if(output&bitflag_value)//the bitflag is on ATM
			output &= ~bitflag_value
		else//can't not be off
			output |= bitflag_value
		return MT_UPDATE

Linking

Multitool menus support hooks for linking machinery together a la telecomms, to set this up for your obj, you will need to override the following procs:

  • linkMenu
  • canLink
  • isLinkedWith
  • linkWith
  • unlinkFrom

* linkMenu(var/obj/O)

Params:

  • var/obj/O: The object in the multitool's buffer.

Should return: Valid HTML markup for the linking menu, note that flush buffer/add to buffer will always be shown.

Example:

/obj/machinery/computer/general_air_control/linkMenu(var/obj/O)
		var/dat=""
		if((istype(O,/obj/machinery/air_sensor) || istype(O, /obj/machinery/meter)) && !isLinkedWith(O))
			dat += " <a href='?src=\ref[src];link=1'>\[New Sensor\]</a> "
		return dat

NOTE: You can add additional context to the HREFs, this additional context will be available in other link-related procs.

* canLink(var/obj/O, var/list/context)

Params:

  • var/obj/O: The object in the multitool's buffer.
  • var/link/context: Any additional passed on from linkMenu's HREFs.

Returns: 1 if linking should be possible with the provided params, do any sanity here.

* isLinkedWith(var/obj/O)

Params:

  • var/obj/O: The object in the multitool's buffer.

Returns: 1 if the object O is already linked with the src.

* linkWith(var/obj/O, var/link/context)

Params:

  • var/obj/O: The object in the multitool's buffer.
  • var/link/context: Any additional passed on from linkMenu's HREFs.

This is where the action happens, use this proc to actually link the obj to the src, what linking implies is up to you.

Returns: 1 if the linking was successfull, else 0.

* getLink(var/idx)

Params:

  • var/idx: The index of the atom to get a reference to.

Used to get a reference to objects linked to this one, uses a numerical index, which is placed in the HTML interface.

Returns: A reference to the object, based on the index.

* unlinkFrom(var/mob/user, var/obj/buffer)

Params:

  • var/mob/user: If you can't figure this one out, then you probably didn't understand most of the rest of this page.
  • var/obj/buffer: The object unlink from.

This is where objects are unlinked.

Returns: 1 if the unlinking was successfull, else 0.