mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-11 02:12:14 +00:00
push
This commit is contained in:
@@ -34,6 +34,17 @@ GLOBAL_LIST_INIT(lewd_kiss_sounds, list(
|
|||||||
'modular_sand/sound/interactions/kiss4.ogg',
|
'modular_sand/sound/interactions/kiss4.ogg',
|
||||||
'modular_sand/sound/interactions/kiss5.ogg'
|
'modular_sand/sound/interactions/kiss5.ogg'
|
||||||
))
|
))
|
||||||
|
GLOBAL_LIST_INIT(interaction_speeds, list(
|
||||||
|
4 SECONDS,
|
||||||
|
2 SECONDS,
|
||||||
|
1 SECONDS,
|
||||||
|
0.8 SECONDS,
|
||||||
|
0.5 SECONDS, // lowest value must always be over or equal to the subsystem wait/cooldown for interaction
|
||||||
|
))
|
||||||
|
|
||||||
|
#define INTERACTION_NORMAL 0
|
||||||
|
#define INTERACTION_LEWD 1
|
||||||
|
#define INTERACTION_EXTREME 2
|
||||||
|
|
||||||
#define CUM_TARGET_MOUTH "mouth"
|
#define CUM_TARGET_MOUTH "mouth"
|
||||||
#define CUM_TARGET_THROAT "throat"
|
#define CUM_TARGET_THROAT "throat"
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
SUBSYSTEM_DEF(interactions)
|
PROCESSING_SUBSYSTEM_DEF(interactions)
|
||||||
name = "Interactions"
|
name = "Interactions"
|
||||||
flags = SS_NO_FIRE
|
wait = 0.5 SECONDS
|
||||||
|
stat_tag = "ACT"
|
||||||
init_order = INIT_ORDER_INTERACTIONS
|
init_order = INIT_ORDER_INTERACTIONS
|
||||||
var/list/interactions
|
flags = SS_BACKGROUND|SS_POST_FIRE_TIMING
|
||||||
VAR_PROTECTED/list/blacklisted_mobs = list(
|
VAR_PROTECTED/list/blacklisted_mobs = list(
|
||||||
/mob/dead,
|
/mob/dead,
|
||||||
/mob/dview,
|
/mob/dview,
|
||||||
@@ -22,8 +23,9 @@ SUBSYSTEM_DEF(interactions)
|
|||||||
/mob/living/simple_animal/hostile/retaliate/goat
|
/mob/living/simple_animal/hostile/retaliate/goat
|
||||||
)
|
)
|
||||||
VAR_PROTECTED/initialized_blacklist
|
VAR_PROTECTED/initialized_blacklist
|
||||||
|
var/list/interactions = list()
|
||||||
|
|
||||||
/datum/controller/subsystem/interactions/Initialize(timeofday)
|
/datum/controller/subsystem/processing/interactions/Initialize(timeofday)
|
||||||
prepare_interactions()
|
prepare_interactions()
|
||||||
prepare_blacklisted_mobs()
|
prepare_blacklisted_mobs()
|
||||||
. = ..()
|
. = ..()
|
||||||
@@ -31,13 +33,13 @@ SUBSYSTEM_DEF(interactions)
|
|||||||
to_chat(world, span_boldannounce(extra_info))
|
to_chat(world, span_boldannounce(extra_info))
|
||||||
log_subsystem(src, extra_info)
|
log_subsystem(src, extra_info)
|
||||||
|
|
||||||
/datum/controller/subsystem/interactions/stat_entry(msg)
|
/datum/controller/subsystem/processing/interactions/stat_entry(msg)
|
||||||
msg += "|🖐:[LAZYLEN(interactions)]|"
|
msg += "|🖐:[LAZYLEN(interactions)]|"
|
||||||
msg += "🚫👨:[LAZYLEN(blacklisted_mobs)]"
|
msg += "🚫👨:[LAZYLEN(blacklisted_mobs)]"
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
/// Makes the interactions, they're also a global list because having it as a list and just hanging around there is stupid
|
/// Makes the interactions, they're also a global list because having it as a list and just hanging around there is stupid
|
||||||
/datum/controller/subsystem/interactions/proc/prepare_interactions()
|
/datum/controller/subsystem/processing/interactions/proc/prepare_interactions()
|
||||||
QDEL_NULL_LIST(interactions)
|
QDEL_NULL_LIST(interactions)
|
||||||
interactions = list()
|
interactions = list()
|
||||||
for(var/datum/interaction/interaction as anything in subtypesof(/datum/interaction))
|
for(var/datum/interaction/interaction as anything in subtypesof(/datum/interaction))
|
||||||
@@ -48,7 +50,7 @@ SUBSYSTEM_DEF(interactions)
|
|||||||
interactions["[interaction.type]"] = interaction
|
interactions["[interaction.type]"] = interaction
|
||||||
|
|
||||||
/// Blacklisting!
|
/// Blacklisting!
|
||||||
/datum/controller/subsystem/interactions/proc/prepare_blacklisted_mobs()
|
/datum/controller/subsystem/processing/interactions/proc/prepare_blacklisted_mobs()
|
||||||
blacklisted_mobs = typecacheof(blacklisted_mobs)
|
blacklisted_mobs = typecacheof(blacklisted_mobs)
|
||||||
initialized_blacklist = TRUE
|
initialized_blacklist = TRUE
|
||||||
|
|
||||||
@@ -56,7 +58,7 @@ SUBSYSTEM_DEF(interactions)
|
|||||||
* Lewd interactions have a blacklist for certain mobs. When we evalute the user and target, both of
|
* Lewd interactions have a blacklist for certain mobs. When we evalute the user and target, both of
|
||||||
* their requirements must be satisfied, and the mob must not be of a blacklisted type.
|
* their requirements must be satisfied, and the mob must not be of a blacklisted type.
|
||||||
*/
|
*/
|
||||||
/datum/controller/subsystem/interactions/proc/is_blacklisted(mob/living/creature)
|
/datum/controller/subsystem/processing/interactions/proc/is_blacklisted(mob/living/creature)
|
||||||
if(!creature || !initialized_blacklist)
|
if(!creature || !initialized_blacklist)
|
||||||
return TRUE
|
return TRUE
|
||||||
if(is_type_in_typecache(creature, blacklisted_mobs))
|
if(is_type_in_typecache(creature, blacklisted_mobs))
|
||||||
|
|||||||
@@ -15,13 +15,30 @@
|
|||||||
return
|
return
|
||||||
menu.open_menu(usr, src)
|
menu.open_menu(usr, src)
|
||||||
|
|
||||||
#define INTERACTION_NORMAL 0
|
|
||||||
#define INTERACTION_LEWD 1
|
|
||||||
#define INTERACTION_EXTREME 2
|
|
||||||
|
|
||||||
/// The menu itself, only var is target which is the mob you are interacting with
|
/// The menu itself, only var is target which is the mob you are interacting with
|
||||||
/datum/component/interaction_menu_granter
|
/datum/component/interaction_menu_granter
|
||||||
var/mob/living/target
|
var/mob/living/target
|
||||||
|
var/mob/living/auto_interaction_target
|
||||||
|
var/datum/interaction/currently_active_interaction
|
||||||
|
var/next_interaction_time
|
||||||
|
var/auto_interaction_pace = 1 SECONDS
|
||||||
|
|
||||||
|
/datum/component/interaction_menu_granter/process(delta_time)
|
||||||
|
if(!currently_active_interaction)
|
||||||
|
auto_interaction_target = null
|
||||||
|
currently_active_interaction = null
|
||||||
|
return PROCESS_KILL
|
||||||
|
if(QDELETED(auto_interaction_target))
|
||||||
|
auto_interaction_target = null
|
||||||
|
currently_active_interaction = null
|
||||||
|
return PROCESS_KILL
|
||||||
|
if(world.time <= next_interaction_time)
|
||||||
|
return
|
||||||
|
next_interaction_time = world.time + auto_interaction_pace
|
||||||
|
if(!currently_active_interaction.do_action(parent, auto_interaction_target, apply_cooldown = FALSE))
|
||||||
|
auto_interaction_target = null
|
||||||
|
currently_active_interaction = null
|
||||||
|
return PROCESS_KILL
|
||||||
|
|
||||||
/datum/component/interaction_menu_granter/Initialize(...)
|
/datum/component/interaction_menu_granter/Initialize(...)
|
||||||
if(!ismob(parent))
|
if(!ismob(parent))
|
||||||
@@ -29,21 +46,24 @@
|
|||||||
var/mob/parent_mob = parent
|
var/mob/parent_mob = parent
|
||||||
if(!parent_mob.client)
|
if(!parent_mob.client)
|
||||||
return COMPONENT_INCOMPATIBLE
|
return COMPONENT_INCOMPATIBLE
|
||||||
. = ..()
|
return ..()
|
||||||
|
|
||||||
/datum/component/interaction_menu_granter/RegisterWithParent()
|
/datum/component/interaction_menu_granter/RegisterWithParent()
|
||||||
. = ..()
|
. = ..()
|
||||||
RegisterSignal(parent, COMSIG_MOB_CTRLSHIFTCLICKON, PROC_REF(open_menu))
|
RegisterSignal(parent, COMSIG_MOB_CTRLSHIFTCLICKON, PROC_REF(open_menu))
|
||||||
|
|
||||||
/datum/component/interaction_menu_granter/Destroy(force, ...)
|
/datum/component/interaction_menu_granter/Destroy(force, ...)
|
||||||
target = null
|
STOP_PROCESSING(SSinteractions, src)
|
||||||
. = ..()
|
if(target)
|
||||||
|
UnregisterSignal(target, COMSIG_PARENT_QDELETING)
|
||||||
|
target = null
|
||||||
|
auto_interaction_target = null
|
||||||
|
currently_active_interaction = null
|
||||||
|
return ..()
|
||||||
|
|
||||||
/datum/component/interaction_menu_granter/UnregisterFromParent()
|
/datum/component/interaction_menu_granter/UnregisterFromParent()
|
||||||
UnregisterSignal(parent, COMSIG_MOB_CTRLSHIFTCLICKON)
|
UnregisterSignal(parent, COMSIG_MOB_CTRLSHIFTCLICKON)
|
||||||
if(target)
|
return ..()
|
||||||
UnregisterSignal(target, COMSIG_PARENT_QDELETING)
|
|
||||||
. = ..()
|
|
||||||
|
|
||||||
/// The one interacting is clicker, the interacted is clicked.
|
/// The one interacting is clicker, the interacted is clicked.
|
||||||
/datum/component/interaction_menu_granter/proc/open_menu(mob/clicker, mob/clicked)
|
/datum/component/interaction_menu_granter/proc/open_menu(mob/clicker, mob/clicked)
|
||||||
@@ -95,8 +115,9 @@
|
|||||||
//Getting player
|
//Getting player
|
||||||
var/mob/living/self = parent
|
var/mob/living/self = parent
|
||||||
//Getting info
|
//Getting info
|
||||||
.["isTargetSelf"] = target == self
|
.["isTargetSelf"] = target == self // Why all of these?
|
||||||
.["interactingWith"] = target != self ? "Interacting with \the [target]..." : "Interacting with yourself..."
|
.["user"] = self // Because people may have the same name
|
||||||
|
.["target"] = target // target == self can distinguish
|
||||||
.["selfAttributes"] = self.list_interaction_attributes(self)
|
.["selfAttributes"] = self.list_interaction_attributes(self)
|
||||||
.["lust"] = self.get_lust()
|
.["lust"] = self.get_lust()
|
||||||
.["maxLust"] = self.get_lust_tolerance() * 3
|
.["maxLust"] = self.get_lust_tolerance() * 3
|
||||||
@@ -340,6 +361,10 @@
|
|||||||
if(HAS_TRAIT(user, TRAIT_ESTROUS_DETECT))
|
if(HAS_TRAIT(user, TRAIT_ESTROUS_DETECT))
|
||||||
.["theirLust"] = target.get_lust()
|
.["theirLust"] = target.get_lust()
|
||||||
.["theirMaxLust"] = target.get_lust_tolerance() * 3
|
.["theirMaxLust"] = target.get_lust_tolerance() * 3
|
||||||
|
.["auto_interaction_pace"] = auto_interaction_pace
|
||||||
|
.["is_auto_target_self"] = auto_interaction_target == self
|
||||||
|
.["auto_interaction_target"] = auto_interaction_target
|
||||||
|
.["currently_active_interaction"] = currently_active_interaction?.type
|
||||||
|
|
||||||
//Get their genitals
|
//Get their genitals
|
||||||
var/list/genitals = list()
|
var/list/genitals = list()
|
||||||
@@ -463,6 +488,7 @@
|
|||||||
interaction["additionalDetails"] = I.additional_details
|
interaction["additionalDetails"] = I.additional_details
|
||||||
sent_interactions += list(interaction)
|
sent_interactions += list(interaction)
|
||||||
.["interactions"] = sent_interactions
|
.["interactions"] = sent_interactions
|
||||||
|
.["interaction_speeds"] = GLOB.interaction_speeds
|
||||||
|
|
||||||
/proc/num_to_pref(num)
|
/proc/num_to_pref(num)
|
||||||
switch(num)
|
switch(num)
|
||||||
@@ -480,21 +506,41 @@
|
|||||||
switch(action)
|
switch(action)
|
||||||
if("interact")
|
if("interact")
|
||||||
var/datum/interaction/o = SSinteractions.interactions[params["interaction"]]
|
var/datum/interaction/o = SSinteractions.interactions[params["interaction"]]
|
||||||
if(o)
|
if(!o)
|
||||||
o.do_action(parent_mob, target)
|
return FALSE
|
||||||
|
if(o == currently_active_interaction)
|
||||||
|
to_chat(parent_mob, span_notice("This interaction is being automated, sit back, relax or do a different one during it."))
|
||||||
return TRUE
|
return TRUE
|
||||||
return FALSE
|
o.do_action(parent_mob, target)
|
||||||
|
return TRUE
|
||||||
|
if("interaction_pace")
|
||||||
|
var/speed = params["speed"]
|
||||||
|
if(!(speed in GLOB.interaction_speeds))
|
||||||
|
return FALSE
|
||||||
|
src.auto_interaction_pace = speed
|
||||||
|
return TRUE
|
||||||
|
if("toggle_auto_interaction")
|
||||||
|
var/datum/interaction/o = SSinteractions.interactions[params["interaction"]]
|
||||||
|
if(!o || (currently_active_interaction == o) && (auto_interaction_target == target))
|
||||||
|
auto_interaction_target = null
|
||||||
|
currently_active_interaction = null
|
||||||
|
STOP_PROCESSING(SSinteractions, src)
|
||||||
|
else
|
||||||
|
auto_interaction_target = target
|
||||||
|
currently_active_interaction = o
|
||||||
|
START_PROCESSING(SSinteractions, src)
|
||||||
|
return TRUE
|
||||||
if("favorite")
|
if("favorite")
|
||||||
var/datum/interaction/interaction = SSinteractions.interactions[params["interaction"]]
|
var/datum/interaction/interaction = SSinteractions.interactions[params["interaction"]]
|
||||||
if(interaction)
|
if(!interaction)
|
||||||
var/datum/preferences/prefs = parent_mob.client.prefs
|
return FALSE
|
||||||
if(interaction.type in prefs.favorite_interactions)
|
var/datum/preferences/prefs = parent_mob.client.prefs
|
||||||
LAZYREMOVE(prefs.favorite_interactions, interaction.type)
|
if(interaction.type in prefs.favorite_interactions)
|
||||||
else
|
LAZYREMOVE(prefs.favorite_interactions, interaction.type)
|
||||||
LAZYADD(prefs.favorite_interactions, interaction.type)
|
else
|
||||||
prefs.save_preferences()
|
LAZYADD(prefs.favorite_interactions, interaction.type)
|
||||||
return TRUE
|
prefs.save_preferences()
|
||||||
return FALSE
|
return TRUE
|
||||||
if("genital")
|
if("genital")
|
||||||
var/mob/living/carbon/self = parent_mob
|
var/mob/living/carbon/self = parent_mob
|
||||||
if("visibility" in params)
|
if("visibility" in params)
|
||||||
@@ -627,7 +673,3 @@
|
|||||||
return FALSE
|
return FALSE
|
||||||
prefs.save_preferences()
|
prefs.save_preferences()
|
||||||
return TRUE
|
return TRUE
|
||||||
|
|
||||||
#undef INTERACTION_NORMAL
|
|
||||||
#undef INTERACTION_LEWD
|
|
||||||
#undef INTERACTION_EXTREME
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
var/list/additional_details
|
var/list/additional_details
|
||||||
|
|
||||||
/// Checks if user can do an interaction, action_check is for whether you're actually doing it or not (useful for the menu and not removing the buttons)
|
/// Checks if user can do an interaction, action_check is for whether you're actually doing it or not (useful for the menu and not removing the buttons)
|
||||||
/datum/interaction/proc/evaluate_user(mob/living/user, silent = TRUE, action_check = TRUE)
|
/datum/interaction/proc/evaluate_user(mob/living/user, silent = TRUE, apply_cooldown = TRUE)
|
||||||
if(SSinteractions.is_blacklisted(user))
|
if(SSinteractions.is_blacklisted(user))
|
||||||
return FALSE
|
return FALSE
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
if(COOLDOWN_FINISHED(user, last_interaction_time))
|
if(COOLDOWN_FINISHED(user, last_interaction_time))
|
||||||
return TRUE
|
return TRUE
|
||||||
|
|
||||||
if(action_check)
|
if(apply_cooldown)
|
||||||
return FALSE
|
return FALSE
|
||||||
else
|
else
|
||||||
return TRUE
|
return TRUE
|
||||||
@@ -106,21 +106,21 @@
|
|||||||
return TRUE
|
return TRUE
|
||||||
|
|
||||||
/// Actually doing the action, has a few checks to see if it's valid, usually overwritten to be make things actually happen and what-not
|
/// Actually doing the action, has a few checks to see if it's valid, usually overwritten to be make things actually happen and what-not
|
||||||
/datum/interaction/proc/do_action(mob/living/user, mob/living/target)
|
/datum/interaction/proc/do_action(mob/living/user, mob/living/target, apply_cooldown = TRUE)
|
||||||
if(!(interaction_flags & INTERACTION_FLAG_USER_IS_TARGET))
|
if(!(interaction_flags & INTERACTION_FLAG_USER_IS_TARGET))
|
||||||
if(user == target) //tactical href fix
|
if(user == target) //tactical href fix
|
||||||
to_chat(user, span_warning("You cannot target yourself."))
|
to_chat(user, span_warning("You cannot target yourself."))
|
||||||
return
|
return FALSE
|
||||||
if(get_dist(user, target) > max_distance)
|
if(get_dist(user, target) > max_distance)
|
||||||
to_chat(user, span_warning("They are too far away."))
|
to_chat(user, span_warning("They are too far away."))
|
||||||
return
|
return FALSE
|
||||||
if(interaction_flags & INTERACTION_FLAG_ADJACENT && !(user.Adjacent(target) && target.Adjacent(user)))
|
if(interaction_flags & INTERACTION_FLAG_ADJACENT && !(user.Adjacent(target) && target.Adjacent(user)))
|
||||||
to_chat(user, span_warning("You cannot get to them."))
|
to_chat(user, span_warning("You cannot get to them."))
|
||||||
return
|
return FALSE
|
||||||
if(!evaluate_user(user, silent = FALSE))
|
if(!evaluate_user(user, silent = FALSE, apply_cooldown = apply_cooldown))
|
||||||
return
|
return FALSE
|
||||||
if(!evaluate_target(user, target, silent = FALSE))
|
if(!evaluate_target(user, target, silent = FALSE))
|
||||||
return
|
return FALSE
|
||||||
|
|
||||||
if(write_log_user)
|
if(write_log_user)
|
||||||
user.log_message("[write_log_user] [target]", LOG_ATTACK)
|
user.log_message("[write_log_user] [target]", LOG_ATTACK)
|
||||||
@@ -128,7 +128,8 @@
|
|||||||
target.log_message("[write_log_target] [user]", LOG_VICTIM, log_globally = FALSE)
|
target.log_message("[write_log_target] [user]", LOG_VICTIM, log_globally = FALSE)
|
||||||
|
|
||||||
display_interaction(user, target)
|
display_interaction(user, target)
|
||||||
post_interaction(user, target)
|
post_interaction(user, target, apply_cooldown)
|
||||||
|
return TRUE
|
||||||
|
|
||||||
/// Display the message
|
/// Display the message
|
||||||
/datum/interaction/proc/display_interaction(mob/living/user, mob/living/target)
|
/datum/interaction/proc/display_interaction(mob/living/user, mob/living/target)
|
||||||
@@ -138,8 +139,9 @@
|
|||||||
user.visible_message("<span class='[simple_style]'>[capitalize(use_message)]</span>")
|
user.visible_message("<span class='[simple_style]'>[capitalize(use_message)]</span>")
|
||||||
|
|
||||||
/// After the interaction, the base only plays the sound and only if it has one
|
/// After the interaction, the base only plays the sound and only if it has one
|
||||||
/datum/interaction/proc/post_interaction(mob/living/user, mob/living/target)
|
/datum/interaction/proc/post_interaction(mob/living/user, mob/living/target, apply_cooldown = TRUE)
|
||||||
COOLDOWN_START(user, last_interaction_time, 0.6 SECONDS)
|
if(apply_cooldown)
|
||||||
|
COOLDOWN_START(user, last_interaction_time, 0.5 SECONDS)
|
||||||
if(interaction_sound)
|
if(interaction_sound)
|
||||||
var/soundfile_to_play
|
var/soundfile_to_play
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
var/user_refractory_cost
|
var/user_refractory_cost
|
||||||
var/target_refractory_cost
|
var/target_refractory_cost
|
||||||
|
|
||||||
/datum/interaction/lewd/evaluate_user(mob/living/user, silent = TRUE, action_check = TRUE)
|
/datum/interaction/lewd/evaluate_user(mob/living/user, silent = TRUE, apply_cooldown = TRUE)
|
||||||
. = ..()
|
. = ..()
|
||||||
if(!.)
|
if(!.)
|
||||||
return FALSE
|
return FALSE
|
||||||
@@ -45,11 +45,11 @@
|
|||||||
if(!(has_penis == TRUE))
|
if(!(has_penis == TRUE))
|
||||||
if((user_require_penis_exposed) && has_penis == HAS_UNEXPOSED_GENITAL)
|
if((user_require_penis_exposed) && has_penis == HAS_UNEXPOSED_GENITAL)
|
||||||
if(!silent)
|
if(!silent)
|
||||||
to_chat(user, span_warning("Your penis need to be exposed."))
|
to_chat(user, span_warning("Your penis needs to be exposed."))
|
||||||
return FALSE
|
return FALSE
|
||||||
if((user_require_penis_unexposed) && has_penis == HAS_EXPOSED_GENITAL)
|
if((user_require_penis_unexposed) && has_penis == HAS_EXPOSED_GENITAL)
|
||||||
if(!silent)
|
if(!silent)
|
||||||
to_chat(user, span_warning("Your penis need to be unexposed."))
|
to_chat(user, span_warning("Your penis needs to be unexposed."))
|
||||||
return FALSE
|
return FALSE
|
||||||
|
|
||||||
var/user_require_balls_exposed = !!(required_from_user_exposed & INTERACTION_REQUIRE_BALLS)
|
var/user_require_balls_exposed = !!(required_from_user_exposed & INTERACTION_REQUIRE_BALLS)
|
||||||
@@ -243,8 +243,6 @@
|
|||||||
if(interaction_flags & INTERACTION_FLAG_OOC_CONSENT)
|
if(interaction_flags & INTERACTION_FLAG_OOC_CONSENT)
|
||||||
if((!user.ckey) || (user.client && user.client.prefs.toggles & VERB_CONSENT))
|
if((!user.ckey) || (user.client && user.client.prefs.toggles & VERB_CONSENT))
|
||||||
return TRUE
|
return TRUE
|
||||||
if(action_check)
|
|
||||||
return FALSE
|
|
||||||
return FALSE
|
return FALSE
|
||||||
|
|
||||||
/datum/interaction/lewd/evaluate_target(mob/living/user, mob/living/target, silent = TRUE)
|
/datum/interaction/lewd/evaluate_target(mob/living/user, mob/living/target, silent = TRUE)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { BlockQuote, Button, Icon, ProgressBar, Section, Stack, Slider, Tooltip
|
|||||||
|
|
||||||
type HeaderInfo = {
|
type HeaderInfo = {
|
||||||
isTargetSelf: boolean;
|
isTargetSelf: boolean;
|
||||||
interactingWith: string;
|
target: string;
|
||||||
lust: number;
|
lust: number;
|
||||||
maxLust: number;
|
maxLust: number;
|
||||||
selfAttributes: string[];
|
selfAttributes: string[];
|
||||||
@@ -22,7 +22,7 @@ export const InfoSection = (props, context) => {
|
|||||||
const { act, data } = useBackend<HeaderInfo>(context);
|
const { act, data } = useBackend<HeaderInfo>(context);
|
||||||
const {
|
const {
|
||||||
isTargetSelf,
|
isTargetSelf,
|
||||||
interactingWith,
|
target,
|
||||||
lust,
|
lust,
|
||||||
maxLust,
|
maxLust,
|
||||||
selfAttributes,
|
selfAttributes,
|
||||||
@@ -37,7 +37,7 @@ export const InfoSection = (props, context) => {
|
|||||||
moaning_multiplier,
|
moaning_multiplier,
|
||||||
} = data;
|
} = data;
|
||||||
return (
|
return (
|
||||||
<Section title={interactingWith} fill>
|
<Section title={`Interacting with ${isTargetSelf ? "yourself" : target}...`} fill>
|
||||||
<Stack vertical fill>
|
<Stack vertical fill>
|
||||||
<Stack.Item grow basis={0}>
|
<Stack.Item grow basis={0}>
|
||||||
<Section fill overflow="auto">
|
<Section fill overflow="auto">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useLocalState } from '../../backend';
|
import { useBackend, useLocalState } from '../../backend';
|
||||||
import { Button, Icon, Input, Section, Tabs, Stack } from '../../components';
|
import { Button, Icon, Input, Section, Tabs, Stack, Slider } from '../../components';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
InteractionsTab,
|
InteractionsTab,
|
||||||
@@ -8,13 +8,27 @@ import {
|
|||||||
ContentPreferencesTab,
|
ContentPreferencesTab,
|
||||||
} from './tabs';
|
} from './tabs';
|
||||||
|
|
||||||
|
type MainTypes = {
|
||||||
|
interaction_speeds: number[];
|
||||||
|
currently_active_interaction: string;
|
||||||
|
auto_interaction_pace: number;
|
||||||
|
auto_interaction_target: string;
|
||||||
|
is_auto_target_self: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export const MainContent = (props, context) => {
|
export const MainContent = (props, context) => {
|
||||||
|
const { act, data } = useBackend<MainTypes>(context);
|
||||||
const [
|
const [
|
||||||
searchText,
|
searchText,
|
||||||
setSearchText,
|
setSearchText,
|
||||||
] = useLocalState(context, 'searchText', '');
|
] = useLocalState(context, 'searchText', '');
|
||||||
const [tabIndex, setTabIndex] = useLocalState(context, 'tabIndex', 0);
|
const [tabIndex, setTabIndex] = useLocalState(context, 'tabIndex', 0);
|
||||||
|
|
||||||
const [inFavorites, setInFavorites] = useLocalState(context, 'inFavorites', false);
|
const [inFavorites, setInFavorites] = useLocalState(context, 'inFavorites', false);
|
||||||
|
|
||||||
|
const interaction_speeds = (data.interaction_speeds || []) as number[];
|
||||||
|
const { auto_interaction_pace, auto_interaction_target, currently_active_interaction, is_auto_target_self } = data;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Section fill>
|
<Section fill>
|
||||||
<Stack vertical fill>
|
<Stack vertical fill>
|
||||||
@@ -59,7 +73,7 @@ export const MainContent = (props, context) => {
|
|||||||
</Stack.Item>
|
</Stack.Item>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack.Item>
|
</Stack.Item>
|
||||||
<Stack.Item grow basis={0} mb={-2.3}>
|
<Stack.Item grow basis={0} mb={tabIndex === 0 ? -1 : -2.3}>
|
||||||
<Section overflow="auto" fill>
|
<Section overflow="auto" fill>
|
||||||
{(() => {
|
{(() => {
|
||||||
switch (tabIndex) {
|
switch (tabIndex) {
|
||||||
@@ -75,6 +89,35 @@ export const MainContent = (props, context) => {
|
|||||||
})()}
|
})()}
|
||||||
</Section>
|
</Section>
|
||||||
</Stack.Item>
|
</Stack.Item>
|
||||||
|
{tabIndex === 0 && (
|
||||||
|
<Stack.Item>
|
||||||
|
<Stack fill>
|
||||||
|
{!!currently_active_interaction && (
|
||||||
|
<Stack.Item>
|
||||||
|
<Button
|
||||||
|
icon="stop"
|
||||||
|
selected
|
||||||
|
tooltip={`Stop interacting with ${is_auto_target_self ? "yourself" : auto_interaction_target}`}
|
||||||
|
onClick={() => act("toggle_auto_interaction")}
|
||||||
|
/>
|
||||||
|
</Stack.Item>
|
||||||
|
)}
|
||||||
|
<Stack.Item grow>
|
||||||
|
<Slider
|
||||||
|
fluid
|
||||||
|
minValue={1}
|
||||||
|
maxValue={interaction_speeds.length}
|
||||||
|
value={interaction_speeds.indexOf(auto_interaction_pace) + 1}
|
||||||
|
format={value => interaction_speeds[value - 1] / 10}
|
||||||
|
unit="seconds"
|
||||||
|
stepPixelSize={50}
|
||||||
|
onChange={(e, value) => act("interaction_pace",
|
||||||
|
{ speed: interaction_speeds[value - 1] })}
|
||||||
|
/>
|
||||||
|
</Stack.Item>
|
||||||
|
</Stack>
|
||||||
|
</Stack.Item>
|
||||||
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Section>
|
</Section>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -9,14 +9,24 @@ type ContentInfo = {
|
|||||||
interactions: InteractionData[];
|
interactions: InteractionData[];
|
||||||
favorite_interactions: string[];
|
favorite_interactions: string[];
|
||||||
user_is_blacklisted: boolean;
|
user_is_blacklisted: boolean;
|
||||||
|
target: string;
|
||||||
target_is_blacklisted: boolean;
|
target_is_blacklisted: boolean;
|
||||||
|
currently_active_interaction: string;
|
||||||
|
is_auto_target_self: boolean;
|
||||||
|
auto_interaction_target: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type InteractionData = {
|
type InteractionData = {
|
||||||
key: string;
|
key: string;
|
||||||
desc: string;
|
desc: string;
|
||||||
type: number;
|
type: number;
|
||||||
additionalDetails: string[];
|
additionalDetails: additionalDetailsContent[];
|
||||||
|
}
|
||||||
|
|
||||||
|
type additionalDetailsContent = {
|
||||||
|
info: string;
|
||||||
|
icon: string;
|
||||||
|
color: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const INTERACTION_NORMAL = 0;
|
const INTERACTION_NORMAL = 0;
|
||||||
@@ -49,7 +59,7 @@ export const InteractionsTab = (props, context) => {
|
|||||||
? valid_favorites
|
? valid_favorites
|
||||||
: interactions;
|
: interactions;
|
||||||
|
|
||||||
const { user_is_blacklisted, target_is_blacklisted } = data;
|
const { auto_interaction_target, currently_active_interaction, is_auto_target_self, user_is_blacklisted, target, target_is_blacklisted } = data;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack vertical>
|
<Stack vertical>
|
||||||
@@ -58,6 +68,21 @@ export const InteractionsTab = (props, context) => {
|
|||||||
interactions_to_display.map((interaction) => (
|
interactions_to_display.map((interaction) => (
|
||||||
<Stack.Item key={interaction.key}>
|
<Stack.Item key={interaction.key}>
|
||||||
<Stack fill>
|
<Stack fill>
|
||||||
|
{interaction.type !== INTERACTION_NORMAL && (
|
||||||
|
<Stack.Item>
|
||||||
|
<Button
|
||||||
|
key={interaction.key}
|
||||||
|
icon={(currently_active_interaction === interaction.key) && (auto_interaction_target === target)
|
||||||
|
? "stop" : "play"}
|
||||||
|
selected={(currently_active_interaction === interaction.key) && (auto_interaction_target === target)}
|
||||||
|
tooltip={(currently_active_interaction === interaction.key) && (auto_interaction_target === target)
|
||||||
|
? `Stop interacting with ${is_auto_target_self ? "yourself" : auto_interaction_target}` : "Automatically repeat this interaction"}
|
||||||
|
onClick={() => act('toggle_auto_interaction', {
|
||||||
|
interaction: interaction.key,
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</Stack.Item>
|
||||||
|
)}
|
||||||
<Stack.Item grow>
|
<Stack.Item grow>
|
||||||
<Button
|
<Button
|
||||||
key={interaction.key}
|
key={interaction.key}
|
||||||
|
|||||||
Reference in New Issue
Block a user