---
# System prepended metadata

title: Contextual Screen Tip Implementation

---

# Contextual Screen Tip Implementation

## Interaction Types

There are two relationships for an interaction between two objects to happen.

### Self defining items (Type A)
These are items that are defined by their behavior. These should define their contextual text within themselves, and not in their targets.

- Stun batons (LMB to stun, RMB to harm)
- Syringes (LMB to inject, RMB to draw)
- Health analyzers (LMB to scan for health/wounds [another piece of context], RMB to scan for schemicals)

### Receving action defining objects (Type B)
These are objects (not necessarily items) that are defined by what happens *to* them. These should define their contextual text within themselves, and not in their operating tools.

- Tables (RMB with wrench to deconstruct)
- Construction objects (LMB with glass to put in screen for computers)
- Carbon copies (RMB to take a copy)

### Supporting one, but not the other

Both systems need to be supported. For example, if only Type A items were supported, then every piece of glass would have to know every type of machine that it needs to be added to. If only Type B items were supported, then the code that handles contextual text for humans would be very long.

This hurts modularization, as well as adding a barrier of entry to adding contextual text. It should be very easy to add contextual text as to incentivize people create it.

## API

Specifying contextual text will be done through signals. This is for both reusability (contextual text being added by components, for example) as well as to reduce the number of proc calls on MouseEnter to an absolute minimum.

Signals will receive a list of the following structure:

```dm
list(
    MAGIC_LEFT_CLICK: string[],
    MAGIC_RIGHT_CLICK: string[],
)
```

This is to allow for reusable composition of context.

### Type A interactions

These would be on a `COMSIG_ITEM_REQUESTING_CONTEXT_FOR_TARGET` (name pending) signal. It will provide the context list and an `atom/target` for what the user is hovering over. These would only be registerable on `/obj/item`.

Stun batons might look like:

```dm
/obj/item/melee/baton/Initialize()
    // -snip-
    RegisterSignal(src, COMSIG_ITEM_REQUESTING_CONTEXT_FOR_TARGET, .proc/add_context)

/obj/item/melee/baton/proc/add_context(
    datum/source,
    list/context,
    atom/target,
)
    SIGNAL_HANDLER
    
    if (!iscarbon(target))
        return
    
    context[MAGIC_LEFT_CLICK] += "Stun"
    context[MAGIC_RIGHT_CLICK] += "Harm"
```

### Type B interactions
These would be on a `COMSIG_REQUESTING_CONTEXT_FROM_ITEM` (name pending) signal. It will provide the context list, the `/obj/item` that is hovering over this (`null` if the user is not holding an item), and the `/mob/user` that is hovering over it.

Table deconstruction might look like:

```dm
/obj/structure/table/Initialize()
    // -snip-
    RegisterSignal(src, COMSIG_REQUESTING_CONTEXT_FROM_ITEM, .proc/add_context)

/obj/structure/table/proc/add_context(
    datum/source,
    list/context,
    obj/item/held_item,
    mob/user,
)
    SIGNAL_HANDLER
    
    if (TOOL_WRENCH in held_item?.tool_behaviors)
        context[MAGIC_RIGHT_CLICK] += "Deconstruct"
```

### Type B and tool behaviors

While optional, it's most likely that Type B interactions will comprise mostly of tool behaviors. Thus, I think for the sake of barrier of entry, this can be made first-class with something like:

```dm
/obj/structure/table
    // This would ideally be `/static`
    contextual_tool_usage = list(
        TOOL_WRENCH = list(
            MAGIC_RIGHT_CLICK = list("Deconstruct")
        )
    )
```
