mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-16 12:07:48 +00:00
* Removes ComponentInitialize() * Fixes a leftover merge conflict marker * Fixes the oversight that came from the upstream merge skew * Fixes all of the instances where we used ComponentInitialize() when we shouldn't've been * Fixes CI being broken because of the HEV suits Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> Co-authored-by: GoldenAlpharex <jerego1234@hotmail.com>
272 lines
11 KiB
Plaintext
272 lines
11 KiB
Plaintext
|
|
GLOBAL_LIST_EMPTY_TYPED(interaction_instances, /datum/interaction)
|
|
|
|
/datum/interaction
|
|
/// The name to be displayed in the interaction menu for this interaction
|
|
var/name = "broken interaction"
|
|
/// The description of the interacton.
|
|
var/description = "broken"
|
|
/// If it can be done at a distance.
|
|
var/distance_allowed = FALSE
|
|
/// A list of possible messages displayed loaded by the JSON.
|
|
var/list/message = list()
|
|
/// A list of possible messages displayed directly to the USER.
|
|
var/list/user_messages = list()
|
|
/// A list of possible messages displayed directly to the TARGET.
|
|
var/list/target_messages = list()
|
|
/// What category this interaction will fall under in the menu.
|
|
var/category = INTERACTION_CAT_HIDE
|
|
/// Defines how we interact with ourselves or others.
|
|
var/usage = INTERACTION_OTHER
|
|
/// Does this interaction play a sound?
|
|
var/sound_use = FALSE
|
|
/// If it plays a sound, how far does it travel?
|
|
var/sound_range = 1
|
|
/// Stores the sound for later.
|
|
var/sound_cache = null
|
|
/// Is this lewd?
|
|
var/lewd = FALSE
|
|
/// What parts do WE need(IMPORTANT TO GET IT TO THE CORRECT DEFINE, ORGAN SLOT)?
|
|
var/list/user_required_parts = list()
|
|
/// What parts do they need(IMPORTANT TO GET IT TO THE CORRECT DEFINE, ORGAN SLOT)?
|
|
var/list/target_required_parts = list()
|
|
/// The amount of pleasure the target recieves from this interaciton.
|
|
var/target_pleasure = 0
|
|
/// The amount of arousal the target recieves from this interaction.
|
|
var/target_arousal = 0
|
|
/// The amount of pain the target recieves.
|
|
var/target_pain = 0
|
|
/// The amount of pleasure the user recieves.
|
|
var/user_pleasure = 0
|
|
/// The amount of arousal the user recieves.
|
|
var/user_arousal = 0
|
|
/// The amount of pain the user recieves.
|
|
var/user_pain = 0
|
|
/// A list of possible sounds.
|
|
var/list/sound_possible = list()
|
|
/// What requirements does this interaction have? See defines.
|
|
var/list/interaction_requires = list()
|
|
/// What color should the interaction button be?
|
|
var/color = "blue"
|
|
/// What sexuality preference do we display for.
|
|
var/sexuality = ""
|
|
|
|
/datum/interaction/proc/allow_act(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
|
if(target == user && usage == INTERACTION_OTHER)
|
|
return FALSE
|
|
|
|
if(user_required_parts.len)
|
|
for(var/thing in user_required_parts)
|
|
var/obj/item/organ/external/genital/required_part = user.getorganslot(thing)
|
|
if(isnull(required_part))
|
|
return FALSE
|
|
if(!required_part.is_exposed())
|
|
return FALSE
|
|
|
|
if(target_required_parts.len)
|
|
for(var/thing in target_required_parts)
|
|
var/obj/item/organ/external/genital/required_part = target.getorganslot(thing)
|
|
if(isnull(required_part))
|
|
return FALSE
|
|
if(!required_part.is_exposed())
|
|
return FALSE
|
|
|
|
for(var/requirement in interaction_requires)
|
|
switch(requirement)
|
|
if(INTERACTION_REQUIRE_SELF_HAND)
|
|
if(!user.get_active_hand())
|
|
return FALSE
|
|
if(INTERACTION_REQUIRE_TARGET_HAND)
|
|
if(!target.get_active_hand())
|
|
return FALSE
|
|
else
|
|
CRASH("Unimplemented interaction requirement '[requirement]'")
|
|
return TRUE
|
|
|
|
/datum/interaction/proc/act(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
|
if(!allow_act(user, target))
|
|
return
|
|
if(!message)
|
|
message_admins("Interaction had a null message list. '[name]'")
|
|
return
|
|
if(!islist(message) && istext(message))
|
|
message_admins("Deprecated message handling for '[name]'. Correct format is a list with one entry. This message will only show once.")
|
|
message = list(message)
|
|
var/msg = pick(message)
|
|
// We replace %USER% with nothing because manual_emote already prepends it.
|
|
msg = trim(replacetext(replacetext(msg, "%TARGET%", "[target]"), "%USER%", ""), INTERACTION_MAX_CHAR)
|
|
if(lewd)
|
|
user.emote("subtler", null, msg, TRUE)
|
|
else
|
|
user.manual_emote(msg)
|
|
if(user_messages.len)
|
|
var/user_msg = pick(user_messages)
|
|
user_msg = replacetext(replacetext(user_msg, "%TARGET%", "[target]"), "%USER%", "[user]")
|
|
to_chat(user, user_msg)
|
|
if(target_messages.len)
|
|
var/target_msg = pick(target_messages)
|
|
target_msg = replacetext(replacetext(target_msg, "%TARGET%", "[target]"), "%USER%", "[user]")
|
|
to_chat(target, target_msg)
|
|
if(sound_use)
|
|
if(!sound_possible)
|
|
message_admins("Interaction has sound_use set to TRUE but does not set sound! '[name]'")
|
|
return
|
|
if(!islist(sound_possible) && istext(sound_possible))
|
|
message_admins("Deprecated sound handling for '[name]'. Correct format is a list with one entry. This message will only show once.")
|
|
sound_possible = list(sound_possible)
|
|
sound_cache = pick(sound_possible)
|
|
for(var/mob/mob in view(sound_range, user))
|
|
SEND_SOUND(sound_cache, mob)
|
|
|
|
if(lewd)
|
|
user.adjustPleasure(user_pleasure)
|
|
user.adjustArousal(user_arousal)
|
|
user.adjustPain(user_pain)
|
|
target.adjustPleasure(target_pleasure)
|
|
target.adjustArousal(target_arousal)
|
|
target.adjustPain(target_pain)
|
|
|
|
/datum/interaction/proc/load_from_json(path)
|
|
var/fpath = path
|
|
if(!fexists(fpath))
|
|
message_admins("Attempted to load an interaction from json and the file does not exist")
|
|
qdel(src)
|
|
return FALSE
|
|
var/file = file(fpath)
|
|
var/list/json = json_load(file)
|
|
name = sanitize_text(json["name"])
|
|
description = sanitize_text(json["description"])
|
|
distance_allowed = sanitize_integer(json["distance_allowed"], 0, 1, 0)
|
|
message = sanitize_islist(json["message"], list("json error"))
|
|
category = sanitize_text(json["category"])
|
|
usage = sanitize_text(json["usage"])
|
|
sound_use = sanitize_integer(json["sound_use"], 0, 1, 0)
|
|
sound_range = sanitize_integer(json["sound_range"], 1, 7, 1)
|
|
sound_possible = sanitize_islist(json["sound_possible"], list("json error"))
|
|
interaction_requires = sanitize_islist(json["interaction_requires"], list())
|
|
color = sanitize_text(json["color"])
|
|
|
|
user_messages = sanitize_islist(json["user_messages"], list())
|
|
user_required_parts = sanitize_islist(json["user_required_parts"], list())
|
|
user_arousal = sanitize_integer(json["user_arousal"], 0, 100, 0)
|
|
user_pleasure = sanitize_integer(json["user_pleasure"], 0, 100, 0)
|
|
user_pain = sanitize_integer(json["user_pain"], 0, 100, 0)
|
|
target_messages = sanitize_islist(json["target_messages"], list())
|
|
target_required_parts = sanitize_islist(json["target_required_parts"], list())
|
|
target_arousal = sanitize_integer(json["target_arousal"], 0, 100, 0)
|
|
target_pleasure = sanitize_integer(json["target_pleasure"], 0, 100, 0)
|
|
target_pain = sanitize_integer(json["target_pain"], 0, 100, 0)
|
|
lewd = sanitize_integer(json["lewd"], 0, 1, 0)
|
|
sexuality = sanitize_text(json["sexuality"])
|
|
return TRUE
|
|
|
|
/datum/interaction/proc/json_save(path)
|
|
var/fpath = path
|
|
if(fexists(fpath))
|
|
fdel(fpath)
|
|
var/list/json = list(
|
|
"name" = name,
|
|
"description" = description,
|
|
"distance_allowed" = distance_allowed,
|
|
"message" = message,
|
|
"category" = category,
|
|
"usage" = usage,
|
|
"sound_use" = sound_use,
|
|
"sound_range" = sound_range,
|
|
"sound_possible" = sound_possible,
|
|
"interaction_requires" = interaction_requires,
|
|
"color" = color,
|
|
"user_messages" = user_messages,
|
|
"user_required_parts" = user_required_parts,
|
|
"user_arousal" = user_arousal,
|
|
"user_pleasure" = user_pleasure,
|
|
"user_pain" = user_pain,
|
|
"target_messages" = target_messages,
|
|
"target_required_parts" = target_required_parts,
|
|
"target_arousal" = target_arousal,
|
|
"target_pleasure" = target_pleasure,
|
|
"target_pain" = target_pain,
|
|
"lewd" = lewd,
|
|
"sexuality" = sexuality,
|
|
)
|
|
var/file = file(fpath)
|
|
WRITE_FILE(file, json_encode(json))
|
|
return TRUE
|
|
|
|
/mob/living/carbon/human/Initialize(mapload)
|
|
. = ..()
|
|
AddComponent(/datum/component/interactable)
|
|
|
|
/// Global loading procs
|
|
/proc/populate_interaction_instances()
|
|
for(var/spath in subtypesof(/datum/interaction))
|
|
var/datum/interaction/interaction = new spath()
|
|
GLOB.interaction_instances[interaction.name] = interaction
|
|
populate_interaction_jsons(INTERACTION_JSON_FOLDER)
|
|
|
|
/proc/populate_interaction_jsons(directory)
|
|
for(var/file in flist(directory))
|
|
if(flist(directory + file) && !findlasttext(directory + file, ".json"))
|
|
populate_interaction_instances(directory + file)
|
|
continue
|
|
if(findlasttext(directory + file, ".master.json")) // This is a master json which has special handling
|
|
populate_interaction_jsons_master(directory + file)
|
|
continue
|
|
var/datum/interaction/interaction = new()
|
|
if(interaction.load_from_json(directory + file))
|
|
GLOB.interaction_instances[interaction.name] = interaction
|
|
else message_admins("Error loading interaction from file: '[directory + file]'. Inform coders.")
|
|
|
|
/proc/populate_interaction_jsons_master(path)
|
|
if(!fexists(path))
|
|
message_admins("We are attempting to load an interaction master without the file existing! '[path]'")
|
|
return
|
|
var/file = file(path)
|
|
var/list/json = json_load(file)
|
|
|
|
for(var/iname in json)
|
|
if(GLOB.interaction_instances[iname])
|
|
message_admins("Interaction Master '[path]' contained a duplicate interaction! '[iname]'")
|
|
continue
|
|
|
|
var/list/ijson = json[iname]
|
|
if(ijson["name"] != iname)
|
|
message_admins("Interaction Master '[path]' contained an invalid interaction! '[iname]'")
|
|
continue
|
|
|
|
var/datum/interaction/interaction = new()
|
|
|
|
interaction.distance_allowed = sanitize_integer(ijson["distance_allowed"], 0, 1, 0)
|
|
interaction.message = sanitize_islist(ijson["message"], list("json error"))
|
|
interaction.category = sanitize_text(ijson["category"])
|
|
interaction.usage = sanitize_text(ijson["usage"])
|
|
interaction.sound_use = sanitize_integer(ijson["sound_use"], 0, 1, 0)
|
|
interaction.sound_range = sanitize_integer(ijson["sound_range"], 1, 7, 1)
|
|
interaction.sound_possible = sanitize_islist(ijson["sound_possible"], list("json error"))
|
|
interaction.interaction_requires = sanitize_islist(ijson["interaction_requires"], list())
|
|
interaction.color = sanitize_text(ijson["color"])
|
|
|
|
interaction.user_messages = sanitize_islist(ijson["user_messages"], list())
|
|
interaction.user_required_parts = sanitize_islist(ijson["user_required_parts"], list())
|
|
interaction.user_arousal = sanitize_integer(ijson["user_arousal"], 0, 100, 0)
|
|
interaction.user_pleasure = sanitize_integer(ijson["user_pleasure"], 0, 100, 0)
|
|
interaction.user_pain = sanitize_integer(ijson["user_pain"], 0, 100, 0)
|
|
interaction.target_messages = sanitize_islist(ijson["target_messages"], list())
|
|
interaction.target_required_parts = sanitize_islist(ijson["target_required_parts"], list())
|
|
interaction.target_arousal = sanitize_integer(ijson["target_arousal"], 0, 100, 0)
|
|
interaction.target_pleasure = sanitize_integer(ijson["target_pleasure"], 0, 100, 0)
|
|
interaction.target_pain = sanitize_integer(ijson["target_pain"], 0, 100, 0)
|
|
interaction.lewd = sanitize_integer(ijson["lewd"], 0, 1, 0)
|
|
interaction.sexuality = sanitize_text(ijson["sexuality"])
|
|
|
|
GLOB.interaction_instances[iname] = interaction
|
|
|
|
/client/proc/reload_interactions()
|
|
set category = "Debug"
|
|
set name = "Reload Interactions"
|
|
set desc = "Force reload interactions"
|
|
if(!check_rights(R_DEBUG))
|
|
return
|
|
|
|
populate_interaction_instances()
|