OPFOR Panel Fixes (#3761)

## About The Pull Request

- Change some text areas to have `fluid` so they're not small
- Move information that was on a hover button into the placeholder text
for the text area for two inputs
- Bump window height slightly so it doesn't get scrollbary
- Change some `onChange` to `onBlur` so it doesn't hammer the server
with `ui_act` calls literally every single time someone types a
character
- Fix the intensity slider just saying NaN
- Change the intensity slider so the slider itself colors to what
"interval" of intensity you're in, uses the color of the button below it
- Remove a line in the backstory placeholder text that says to check a
discord channel we don't have
- Moved some stuff in `ui_data` to `ui_static_data` that absolutely did
not need to get sent every update
- Fixed an incorrect variable in `export_json` that made it fail to
export equipment properly

## Why It's Good For The Game

Fixes #3758 

## Proof Of Testing
<details>
<summary>Screenshots/Videos</summary>


![image](https://github.com/user-attachments/assets/2cd9ea6c-f5ca-4c82-9fe7-d118bd8bdda6)

</details>

## Changelog
🆑
fix: OPFOR should no longer eat all inputs
fix: OPFOR panel should now correctly export to JSON
/🆑
This commit is contained in:
Roxy
2025-05-08 17:50:35 -04:00
committed by GitHub
parent 6490bee9ef
commit f73da55b45
5 changed files with 44 additions and 71 deletions

View File

@@ -184,22 +184,6 @@
data["equipment_issued"] = equipment_issued
data["equipment_list"] = list()
for(var/equipment_category in SSopposing_force.equipment_list)
var/category_items = list()
for(var/datum/opposing_force_equipment/opfor_equipment as anything in SSopposing_force.equipment_list[equipment_category])
category_items += list(list(
"ref" = REF(opfor_equipment),
"name" = opfor_equipment.name,
"description" = opfor_equipment.description,
"equipment_category" = opfor_equipment.category,
"admin_note" = opfor_equipment.admin_note,
))
data["equipment_list"] += list(list(
"category" = equipment_category,
"items" = category_items,
))
data["selected_equipment"] = list()
for(var/datum/opposing_force_selected_equipment/equipment as anything in selected_equipment)
var/list/equipment_data = list(
@@ -218,6 +202,25 @@
return data
/datum/opposing_force/ui_static_data(mob/user)
. = ..()
.["equipment_list"] = list()
for(var/equipment_category in SSopposing_force.equipment_list)
var/category_items = list()
for(var/datum/opposing_force_equipment/opfor_equipment as anything in SSopposing_force.equipment_list[equipment_category])
category_items += list(list(
"ref" = REF(opfor_equipment),
"name" = opfor_equipment.name,
"description" = opfor_equipment.description,
"equipment_category" = opfor_equipment.category,
"admin_note" = opfor_equipment.admin_note,
))
.["equipment_list"] += list(list(
"category" = equipment_category,
"items" = category_items,
))
/datum/opposing_force/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
@@ -964,7 +967,7 @@
)
for(var/datum/opposing_force_selected_equipment/iterating_equipment as anything in selected_equipment)
exported_data["selected_equipment"]["[objectives.Find(iterating_equipment)]"] = list(
exported_data["selected_equipment"]["[selected_equipment.Find(iterating_equipment)]"] = list(
"equipment_name" = iterating_equipment.opposing_force_equipment.name,
"equipment_parent_category" = iterating_equipment.opposing_force_equipment.category,
"equipment_parent_type" = iterating_equipment.opposing_force_equipment.type,
@@ -986,22 +989,6 @@
fdel(to_write_file)
/datum/action/opfor
name = "Open Opposing Force Panel"
button_icon_state = "round_end"
/datum/action/opfor/Trigger(trigger_flags)
. = ..()
if(!.)
return
owner.opposing_force()
/datum/action/opfor/IsAvailable(feedback = FALSE)
if(!target)
return FALSE
return ..()
/obj/effect/statclick/opfor_specific
var/datum/opposing_force/opfor

View File

@@ -195,9 +195,3 @@ SUBSYSTEM_DEF(opposing_force)
returned_html += " - [opposing_force.build_html_panel_entry()]"
return returned_html.Join("<br>")
/// Gives a mind the opfor action button, which calls the opfor verb when pressed
/datum/controller/subsystem/opposing_force/proc/give_opfor_button(mob/living/carbon/human/player)
var/datum/action/opfor/info_button
info_button = new(src)
info_button.Grant(player)

View File

@@ -1,3 +0,0 @@
// Removes the opfor button from appearing on screen. There's a verb in the OOC tab
/datum/controller/subsystem/opposing_force/give_opfor_button(mob/living/carbon/human/player)
return

View File

@@ -9722,7 +9722,6 @@
#include "modular_zubbers\master_files\skyrat\modules\blueshield\code\blueshield.dm"
#include "modular_zubbers\master_files\skyrat\modules\company_imports\code\armament_datums\deforest_medical.dm"
#include "modular_zubbers\master_files\skyrat\modules\deforest_medical_items\code\cargo_packs.dm"
#include "modular_zubbers\master_files\skyrat\modules\opposing_force\code\opposing_force_subsystem.dm"
#include "modular_zubbers\master_files\skyrat\modules\verbs\code\subtle.dm"
#include "modular_zubbers\modules\lewd_clothing\latex_halfcatsuit.dm"
#include "modular_zubbers\modules\plexagon_selfserve\code\off_duty_component.dm"

View File

@@ -27,7 +27,7 @@ export const OpposingForcePanel = (props) => {
<Window
title={'Opposing Force: ' + creator_ckey}
width={585}
height={840}
height={860}
theme={owner_antag ? 'syndicate' : 'admin'}
>
<Window.Content scrollable>
@@ -203,11 +203,12 @@ export const OpposingForceTab = (props) => {
<Stack.Item>
<Section title="Backstory">
<TextArea
fluid
disabled={!can_edit}
height="100px"
value={backstory}
placeholder="Provide a description of why you want to do bad things. Include specifics such as what lead upto the events that made you want to do bad things, think of it as though you were your character, react appropriately. If you don't have any ideas, check the #player-shared-opfors channel for some. (2000 char limit)"
onChange={(_e, value) =>
placeholder="Provide a description of why you want to do bad things. Include specifics such as what lead upto the events that made you want to do bad things, think of it as though you were your character, react appropriately. (2000 char limit)"
onBlur={(value) =>
act('set_backstory', {
backstory: value,
})
@@ -309,7 +310,7 @@ export const OpposingForceObjectives = (props) => {
width="100%"
placeholder="blank objective"
value={selectedObjective.title}
onChange={(e, value) =>
onBlur={(value) =>
act('set_objective_title', {
objective_ref: selectedObjective.ref,
title: value,
@@ -327,13 +328,19 @@ export const OpposingForceObjectives = (props) => {
<Stack.Item>
<Slider
disabled={!can_edit}
step={0.1}
stepPixelSize={0.1}
step={1}
value={selectedObjective.intensity}
format={(value) => round(value)}
format={(value) => round(value, 1)}
minValue={0}
maxValue={500}
onDrag={(e, value) =>
ranges={{
good: [0, 149],
teal: [150, 249],
olive: [250, 349],
orange: [350, 449],
red: [450, 500],
}}
onDrag={(_e, value) =>
act('set_objective_intensity', {
objective_ref: selectedObjective.ref,
new_intensity_level: value,
@@ -411,21 +418,15 @@ export const OpposingForceObjectives = (props) => {
</Stack.Item>
<Stack.Item>
<Stack vertical mt={2}>
<Stack.Item>
Description
<Button
icon="info"
tooltip="Input objective description here, be descriptive about what you want to do, such as 'Destroy the Death Star' or 'Destroy the Death Star and the Death Star Base' (1000 char limit)."
color="light-gray"
/>
</Stack.Item>
<Stack.Item>Description</Stack.Item>
<Stack.Item>
<TextArea
fluid
disabled={!can_edit}
height="85px"
value={selectedObjective.description}
onChange={(e, value) =>
placeholder="Input objective description here, be descriptive about what you want to do, such as 'Destroy the Death Star' or 'Destroy the Death Star and the Death Star Base' (1000 char limit)."
onBlur={(value) =>
act('set_objective_description', {
objective_ref: selectedObjective.ref,
new_desciprtion: value,
@@ -437,20 +438,15 @@ export const OpposingForceObjectives = (props) => {
</Stack.Item>
<Stack.Item>
<Stack vertical mt={2}>
<Stack.Item>
Justification
<Button
icon="info"
tooltip="Input justification for the objective here, make sure you have a good reason for the objective (1000 char limit)."
color="light-gray"
/>
</Stack.Item>
<Stack.Item>Justification</Stack.Item>
<Stack.Item>
<TextArea
fluid
disabled={!can_edit}
height="85px"
value={selectedObjective.justification}
onChange={(e, value) =>
placeholder="Input justification for the objective here, make sure you have a good reason for the objective (1000 char limit)."
onBlur={(value) =>
act('set_objective_justification', {
objective_ref: selectedObjective.ref,
new_justification: value,
@@ -539,7 +535,7 @@ export const EquipmentTab = (props) => {
width="100%"
placeholder="Reason for item"
value={equipment.reason}
onChange={(e, value) =>
onBlur={(value) =>
act('set_equipment_reason', {
selected_equipment_ref: equipment.ref,
new_equipment_reason: value,
@@ -614,7 +610,7 @@ export const AdminChatTab = (props) => {
selfClear
placeholder="Send a message or command using '/'"
mt={1}
onEnter={(e, value) =>
onEnter={(value) =>
act('send_message', {
message: value,
})