Skip to content

Construction Datums: ??? and a How To

ComicIronic edited this page May 2, 2015 · 4 revisions

What is a construction datum?

A construction datum (/datum/construction) is a code object intended to act as a handler for moving through steps in a process which requires features such as state changes, icon updates, do_afters, busy checks, multiple useable items, storage of used items, stack and welder checks, and so on.

The construction datum has a holder atom to which the construction is being applied, a step list which it goes through to progress construction, and many many many many procs.

How do I use one?

Usage of construction datums depends on what you're trying to do with them. There are several kinds of uses for construction datums:

  • Checking and tracking items attached to a frame in any order - e.g. mech chassis construction
  • Creating a required list of actions to produce a resultant atom
  • Moving backwards and forwards through a several-stage set of actions - e.g. mech construction

Using the datums

When you create a construction datum, you want to hook it into your atom's code. This is typically done using attackby(), but you can use it pretty much anywhere. The important proc for the datum is action(). Its args are the atom you want to check, and the user.

The right kind of datum

Depending on action() and type, the datums work in different ways. If you want a take-any datum i.e. one that accepts any of the steps to be done in any order, use check_all_steps(used_atom, user) in action(). If you want to have a one-way progress, use a datum with check_step(used_atom, user). If you want to have a reversible step list, use a /datum/construction/reversible, and check_step(used_atom, user) in action().

Adding a step

A new plain construction datum has no steps. Depending on if the datum is reversible or not, the steps can look pretty different, but the basics are

list( Co_KEY = /path/to/item,
    Co_DESC = "Its GUI has been written in Visual Basic.",
    Co_AMOUNT = 1,
    Co_DELAY = 30,
    Co_START_MSG = "{USER} begin{s} to fandangle {HOLDER}",
    Co_VIS_MSG = "{USER} fandangle{s} {HOLDER}")

Let's break this down a little

  • Co_KEY
    • The type of item to use for the step. This can also be a list of valid types, but a plain type is accepted as well.
  • Co_DESC
    • What the holder atom's description is set to when this step is reached.
  • Co_AMOUNT
    • How much we take from the used atom. What this does is largely contextual, but it uses welding fuel from welders, takes from stacks, and takes the according number of items.
  • Co_DELAY
    • Pretty self-explanatory, the delay of the do_after that the user experiences trying to complete this step.
  • Co_START_MSG
    • The message put out when the user begins a step with a delay.
  • Co_VIS_MSG
    • The message put out when a step is completed.

Other tags that might be used include

  • Co_KEEP
    • Stores the used atom, even if permanence is set to 0. If permanence is set to 1, this is redundant.
  • Co_TAKE
    • Causes stacks and welders to be dropped like other atoms when used in steps with Co_AMOUNT, instead of having their custom behaviour.

A tag you will never use is Co_MAX_AMOUNT. It's set automatically by a proc, and is only used by reversible datums to reset Co_AMOUNT values.

Reversible steps

For reversibles, the steps look a little different. Co_DESC remains in the base list, but things like Co_KEY, Co_AMOUNT, and instructions that only matter in one direction are moved into two sub-lists:

list(Co_DESC = "It's got no fans.",
    Co_NEXTSTEP = list(......),
    Co_BACKSTEP = list(......))

These sublists are each their own kind of step, having amount requirements, valid atom types, and so on.

The message formatting

The reason the messages are formatted in such an odd way is that the datum auto-formats the messages for the observers and the user of the construction step. {USER} is replaced by the user's name for people watching, and by "You" for the user. {s} is replaced by "s" for watchers, and is deleted for the user. {HOLDER} is the holder atom's name, always.

Permanence and atom storage

Permanence is a construction datum var (not included in steps) that causes it to store all atoms used. Co_KEEP has a similar function, but only enables it for the steps specified.

If Co_AMOUNT is set for a step, permanence is enabled, or Co_KEEP is included in the step - and the step is not adding from a stack or using a welder - the used atom is kept to be referenced later, rather than just deleted. The user is made to drop the item into the holder atom, and it's added as an entry to used_atoms.

Indexes in used_atoms

When an atom is added, it gets an assoc text index in the used_atoms list so you know which step an item was used on, and which item a step was completed with. This is done in two ways:

  • For one-directional datums, the index is a text version of the step number.
  • For reversible datums, the index is a text version of the step number followed by either a "+" if the step is in the forward direction, or a "-" if it's in the reverse direction.

Custom actions

The custom_action proc is called when a step completes, and allows for specified behaviour to occur. The basic form of the proc plays the tool sounds when a specific tool is used, and generates the on-completion construction message. You might want to add additional behaviour to this proc, such as icon_state changes, custom sounds or effects, and so on.

Completion

There are two things important to how a construction datum completes: the result var, and the spawn_result() proc. The result var is a typepath. Its default use is in spawning the desired atom when all the datum steps are finished. The spawn_result proc is what does this spawning. It also deletes the holder atom. If you want to add behaviour for when a datum finishes, this is the place to do it.