Resolves conflicts.

This commit is contained in:
Desolate
2018-10-11 05:36:22 -05:00
486 changed files with 16260 additions and 10647 deletions
+297
View File
@@ -0,0 +1,297 @@
# Buildmode
## Code layout
### Buildmode
Manager for buildmode modes. Contains logic to manage switching between each mode, and presenting a suitable user interface.
### Effects
Special graphics used by buildmode modes for user interface purposes.
### Buildmode Mode
Implementer of buildmode behaviors.
Existing varieties:
+ Basic
**Description**:
Allows creation of simple structures consisting of floors, walls, windows, and airlocks.
**Controls**:
+ *Left click a turf*:
"Upgrades" the turf based on the following rules below:
+ Space -> Tiled floor
+ Simulated floor -> Regular wall
+ Wall -> Reinforced wall
+ *Right click a turf*:
"Downgrades" the turf based on the following rules below:
+ Reinforced wall -> Regular wall
+ Wall -> Tiled floor
+ Simulated floor -> Space
+ *Right click an object*:
Deletes the clicked object.
+ *Alt+Left click a location*:
Places an airlock at the clicked location.
+ *Ctrl+Left click a location*:
Places a window at the clicked location.
+ Advanced
**Description**:
Creates an instance of a configurable atom path where you click.
**Controls**:
+ *Right click on the mode selector*:
Choose a path to spawn.
+ *Alt+Left click a turf, object, or mob*:
Select the type of the object clicked.
+ *Left click a location* (requires chosen path):
Place an instance of the chosen path at the location.
+ *Right click an object*:
Delete the object.
+ Fill
**Description**:
Creates an instance of an atom path on every tile in a chosen region.
With a special control input, instead deletes everything within the region.
**Controls**:
+ *Right click on the mode selector*:
Choose a path to spawn.
+ *Left click on a region* (requires chosen path):
Fill the region with the chosen path.
+ *Alt+Left click on a region*:
Deletes everything within the region.
+ *Right click during region selection*:
Cancel region selection.
+ Atmos
**Description**:
Fills a region with configurable atmos. By default, ignores unsimulated turfs, but is able to "overwrite" the atmos of unsimulated turfs with a special control input.
By default, fills a region with a breathable, standard atmosphere.
**Controls**:
+ *Right click on the mode selector icon*:
Set the following traits:
+ Total Pressure
+ Temperature
+ Partial Pressure Ratio (PPR) Oxygen
+ PPR Nitrogen
+ PPR Plasma
+ PPR CO2
+ PPR N2O
+ *Left click a region*:
Fill the region with the configured atmos.
+ *Control+Left click a region*:
As with the regular left click, but also "overwrites" the base atmos of any unsimulated turfs in the region - such as space turfs.
+ *Right click during region selection*:
Cancel region selection.
+ Copy
**Description**:
Take an existing object in the world, and place duplicates with identical attributes where you click.
May not always work nicely - "deep" variables such as lists or datums may malfunction.
**Controls**:
+ *Right click an existing object*:
Select the clicked object as a template.
+ *Left click a location* (Requires a selected object as template):
Place a duplicate of the template at the clicked location.
+ Link
**Description**:
Form links between door control buttons and either airlocks or pod bay doors.
The selected button will be highlighted, and visible lines will be drawn between the doors it is linked to and itself.
**Controls**:
+ *Left click a door control button*:
Makes the button active, and show what doors it is linked to.
+ *Right click an airlock* (requires active button):
Links the airlock to the active button. Will remove all links from the button first, if the button is linked to pod bay doors.
+ *Right click a pod bay door* (requires active button):
Links the pod bay door to the active button. Will remove all links from the button first, if the button is linked to regular airlocks.
+ Area Edit
**Description**:
Modifies and creates areas.
The active area will be highlighted in yellow.
**Controls**:
+ *Right click the mode selector*:
Create a new area, and make it active.
+ *Right click an existing area*:
Make the clicked area active.
+ *Left click a turf*:
When an area is active, adds the turf to the active area.
+ Var Edit
**Description**:
Allows for setting and resetting variables of objects with a click.
If the object does not have the var, will do nothing and print a warning message.
**Controls**:
+ *Right click the mode selector*:
Choose which variable to set, and what to set it to.
+ *Left click an atom*:
Change the clicked atom's variables as configured.
+ *Right click an atom*:
Reset the targeted variable to its original value in the code.
+ Map Generator
**Description**:
Fills rectangular regions with algorithmically generated content. Right click during region selection to cancel.
See the `procedural_mapping` module for the generators themselves.
**Controls**:
+ *Right-click on the mode selector*:
Select a map generator from all the generators present in the codebase.
+ *Left click two corners of an area*:
Use the generator to populate the region.
+ *Right click during region selection*:
Cancel region selection.
+ Save
**Description**:
Captures a rectangular region in a `.dmm` format, which can be loaded back later using the "Place Map Template" debug verb.
Keep in mind this feature is somewhat experimental, and may not always work.
**Controls**:
+ *Right click on the mode selector*:
Configure whether to save in either JSON mode or not.
+ *Left click two corners of an area*:
Save the region to a `.dmm` file. You will be prompted for where to save this - a copy will be saved in the `_maps/quicksave` folder.
+ *Right click during region selection*:
Cancel region selection.
+ Throwing
**Description**:
Select an object with left click, and right click to throw it towards where you clicked.
**Controls**:
+ *Left click on a movable atom*:
Select the atom for throwing.
+ *Right click on a location*:
Throw the selected atom towards that location.
+ Boom
**Description**:
Make explosions where you click.
**Controls**:
+ *Right click the mode selector*:
Configure the explosion size.
+ *Left click a location*:
Cause an explosion where you clicked.
+87
View File
@@ -0,0 +1,87 @@
/datum/buildmode_mode
var/key = "oops"
var/datum/click_intercept/buildmode/BM
var/use_corner_selection = FALSE
var/processing_selection = FALSE
var/list/preview
var/turf/cornerA
var/turf/cornerB
/datum/buildmode_mode/New(datum/click_intercept/buildmode/newBM)
BM = newBM
preview = list()
return ..()
/datum/buildmode_mode/Destroy()
Reset()
return ..()
/datum/buildmode_mode/proc/enter_mode(datum/click_intercept/buildmode/BM)
return
/datum/buildmode_mode/proc/exit_mode(datum/click_intercept/buildmode/BM)
return
/datum/buildmode_mode/proc/get_button_iconstate()
return "buildmode_[key]"
/datum/buildmode_mode/proc/show_help(mob/user)
CRASH("No help defined, yell at a coder")
to_chat(user, "<span class='warning'>There is no help defined for this mode, this is a bug.</span>")
/datum/buildmode_mode/proc/change_settings(mob/user)
to_chat(user, "<span class='warning'>There is no configuration available for this mode</span>")
/datum/buildmode_mode/proc/Reset()
deselect_region()
/datum/buildmode_mode/proc/select_tile(turf/T, corner_to_select)
var/overlaystate
BM.holder.images -= preview
switch(corner_to_select)
if(AREASELECT_CORNERA)
overlaystate = "greenOverlay"
if(AREASELECT_CORNERB)
overlaystate = "blueOverlay"
preview += image('icons/turf/overlays.dmi', T, overlaystate)
BM.holder.images += preview
return T
/datum/buildmode_mode/proc/highlight_region(region)
BM.holder.images -= preview
for(var/t in region)
preview += image('icons/turf/overlays.dmi', T, "redOverlay")
BM.holder.images += preview
/datum/buildmode_mode/proc/deselect_region()
BM.holder.images -= preview
QDEL_LIST(preview)
cornerA = null
cornerB = null
/datum/buildmode_mode/proc/handle_click(user, params, object)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
if(use_corner_selection)
if(left_click)
if(!cornerA)
cornerA = select_tile(get_turf(object), AREASELECT_CORNERA)
return
else if(!cornerB)
cornerB = select_tile(get_turf(object), AREASELECT_CORNERB)
to_chat(user, "<span class='boldwarning'>Region selected, if you're happy with your selection left click again, otherwise right click.</span>")
return
if(processing_selection)
return
processing_selection = TRUE
handle_selected_region(user, params)
processing_selection = FALSE
deselect_region()
else if(cornerA || cornerB)
to_chat(user, "<span class='notice'>Region selection canceled!</span>")
deselect_region()
/datum/buildmode_mode/proc/handle_selected_region(mob/user, params)
return
+127
View File
@@ -0,0 +1,127 @@
#define BM_SWITCHSTATE_NONE 0
#define BM_SWITCHSTATE_MODE 1
#define BM_SWITCHSTATE_DIR 2
/datum/click_intercept/buildmode
var/build_dir = SOUTH
var/datum/buildmode_mode/mode
// SECTION UI
// Switching management
var/switch_state = BM_SWITCHSTATE_NONE
var/switch_width = 5
// modeswitch UI
var/obj/screen/buildmode/mode/modebutton
var/list/modeswitch_buttons = list()
// dirswitch UI
var/obj/screen/buildmode/bdir/dirbutton
var/list/dirswitch_buttons = list()
/datum/click_intercept/buildmode/New()
mode = new /datum/buildmode_mode/basic(src)
. = ..()
mode.enter_mode(src)
/datum/click_intercept/buildmode/Destroy()
close_switchstates()
QDEL_NULL(mode)
QDEL_LIST(modeswitch_buttons)
QDEL_LIST(dirswitch_buttons)
return ..()
/datum/click_intercept/buildmode/create_buttons()
// keep a reference so we can update it upon mode switch
modebutton = new /obj/screen/buildmode/mode(src)
buttons += modebutton
buttons += new /obj/screen/buildmode/help(src)
// keep a reference so we can update it upon dir switch
dirbutton = new /obj/screen/buildmode/bdir(src)
buttons += dirbutton
buttons += new /obj/screen/buildmode/quit(src)
// build the list of modeswitching buttons
build_options_grid(subtypesof(/datum/buildmode_mode), modeswitch_buttons, /obj/screen/buildmode/modeswitch)
build_options_grid(list(SOUTH,EAST,WEST,NORTH,NORTHWEST), dirswitch_buttons, /obj/screen/buildmode/dirswitch)
/datum/click_intercept/buildmode/proc/build_options_grid(list/elements, list/buttonslist, buttontype)
var/pos_idx = 0
for(var/thing in elements)
var/x = pos_idx % switch_width
var/y = FLOOR(pos_idx / switch_width, 1)
var/obj/screen/buildmode/B = new buttontype(src, thing)
// extra .5 for a nice offset look
B.screen_loc = "NORTH-[(1 + 0.5 + y*1.5)],WEST+[0.5 + x*1.5]"
buttonslist += B
pos_idx++
/datum/click_intercept/buildmode/proc/close_switchstates()
switch(switch_state)
if(BM_SWITCHSTATE_MODE)
close_modeswitch()
if(BM_SWITCHSTATE_DIR)
close_dirswitch()
/datum/click_intercept/buildmode/proc/toggle_modeswitch()
if(switch_state == BM_SWITCHSTATE_MODE)
close_modeswitch()
else
close_switchstates()
open_modeswitch()
/datum/click_intercept/buildmode/proc/open_modeswitch()
switch_state = BM_SWITCHSTATE_MODE
holder.screen += modeswitch_buttons
/datum/click_intercept/buildmode/proc/close_modeswitch()
switch_state = BM_SWITCHSTATE_NONE
holder.screen -= modeswitch_buttons
/datum/click_intercept/buildmode/proc/toggle_dirswitch()
if(switch_state == BM_SWITCHSTATE_DIR)
close_dirswitch()
else
close_switchstates()
open_dirswitch()
/datum/click_intercept/buildmode/proc/open_dirswitch()
switch_state = BM_SWITCHSTATE_DIR
holder.screen += dirswitch_buttons
/datum/click_intercept/buildmode/proc/close_dirswitch()
switch_state = BM_SWITCHSTATE_NONE
holder.screen -= dirswitch_buttons
/datum/click_intercept/buildmode/proc/change_mode(newmode)
mode.exit_mode(src)
QDEL_NULL(mode)
close_switchstates()
mode = new newmode(src)
mode.enter_mode(src)
modebutton.update_icon()
/datum/click_intercept/buildmode/proc/change_dir(newdir)
build_dir = newdir
close_dirswitch()
dirbutton.update_icon()
return TRUE
/datum/click_intercept/buildmode/InterceptClickOn(user, params, atom/object)
mode.handle_click(user, params, object)
/proc/togglebuildmode(mob/M in GLOB.player_list)
set name = "Toggle Build Mode"
set category = "Event"
if(M.client)
if(istype(M.client.click_intercept, /datum/click_intercept/buildmode))
var/datum/click_intercept/buildmode/B = M.client.click_intercept
B.quit()
log_admin("[key_name(usr)] has left build mode.")
else
new/datum/click_intercept/buildmode(M.client)
message_admins("[key_name_admin(usr)] has entered build mode.")
log_admin("[key_name(usr)] has entered build mode.")
#undef BM_SWITCHSTATE_NONE
#undef BM_SWITCHSTATE_MODE
#undef BM_SWITCHSTATE_DIR
+88
View File
@@ -0,0 +1,88 @@
/obj/screen/buildmode
icon = 'icons/misc/buildmode.dmi'
var/datum/click_intercept/buildmode/bd
layer = HUD_LAYER_BUILDMODE
/obj/screen/buildmode/New(bld)
bd = bld
return ..()
/obj/screen/buildmode/Destroy()
bd = null
return ..()
/obj/screen/buildmode/mode
name = "Toggle Mode"
icon_state = "buildmode_basic"
screen_loc = "NORTH,WEST"
/obj/screen/buildmode/mode/Click(location, control, params)
var/list/pa = params2list(params)
if(pa.Find("left"))
bd.toggle_modeswitch()
else if(pa.Find("right"))
bd.mode.change_settings(usr)
update_icon()
return TRUE
/obj/screen/buildmode/mode/update_icon()
icon_state = bd.mode.get_button_iconstate()
/obj/screen/buildmode/help
icon_state = "buildhelp"
screen_loc = "NORTH,WEST+1"
name = "Buildmode Help"
/obj/screen/buildmode/help/Click()
bd.mode.show_help(usr)
return TRUE
/obj/screen/buildmode/bdir
icon_state = "build"
screen_loc = "NORTH,WEST+2"
name = "Change Dir"
/obj/screen/buildmode/bdir/update_icon()
dir = bd.build_dir
/obj/screen/buildmode/bdir/Click()
bd.toggle_dirswitch()
update_icon()
return TRUE
// used to switch between modes
/obj/screen/buildmode/modeswitch
var/datum/buildmode_mode/modetype
/obj/screen/buildmode/modeswitch/New(bld, mt)
modetype = mt
icon_state = "buildmode_[initial(modetype.key)]"
name = initial(modetype.key)
return ..(bld)
/obj/screen/buildmode/modeswitch/Click()
bd.change_mode(modetype)
return TRUE
// used to switch between dirs
/obj/screen/buildmode/dirswitch
icon_state = "build"
/obj/screen/buildmode/dirswitch/New(bld, newdir)
dir = newdir
name = dir2text(dir)
return ..(bld)
/obj/screen/buildmode/dirswitch/Click()
bd.change_dir(dir)
return TRUE
/obj/screen/buildmode/quit
icon_state = "buildquit"
screen_loc = "NORTH,WEST+3"
name = "Quit Buildmode"
/obj/screen/buildmode/quit/Click()
bd.quit()
return TRUE
+28
View File
@@ -0,0 +1,28 @@
/obj/effect/buildmode_line
var/image/I
var/client/cl
/obj/effect/buildmode_line/New(client/C, atom/atom_a, atom/atom_b, linename)
name = linename
loc = get_turf(atom_a)
I = image('icons/misc/mark.dmi', src, "line", 19.0)
var/x_offset = ((atom_b.x * 32) + atom_b.pixel_x) - ((atom_a.x * 32) + atom_a.pixel_x)
var/y_offset = ((atom_b.y * 32) + atom_b.pixel_y) - ((atom_a.y * 32) + atom_a.pixel_y)
var/matrix/mat = matrix()
mat.Translate(0, 16)
mat.Scale(1, sqrt((x_offset * x_offset) + (y_offset * y_offset)) / 32)
mat.Turn(90 - Atan2(x_offset, y_offset)) // So... You pass coords in order x,y to this version of atan2. It should be called acsc2.
mat.Translate(atom_a.pixel_x, atom_a.pixel_y)
transform = mat
cl = C
cl.images += I
/obj/effect/buildmode_line/Destroy()
if(I)
if(istype(cl))
cl.images -= I
cl = null
QDEL_NULL(I)
return ..()
@@ -0,0 +1,59 @@
/datum/buildmode_mode/advanced
key = "advanced"
var/objholder = null
// FIXME: add logic which adds a button displaying the icon
// of the currently selected path
/datum/buildmode_mode/advanced/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Set object type</span>")
to_chat(user, "<span class='notice'>Left Mouse Button + alt on turf/obj = Copy object type")
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj = Place objects</span>")
to_chat(user, "<span class='notice'>Right Mouse Button = Delete objects</span>")
to_chat(user, "")
to_chat(user, "<span class='notice'>Use the button in the upper left corner to</span>")
to_chat(user, "<span class='notice'>change the direction of built objects.</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/buildmode_mode/advanced/change_settings(mob/user)
var/target_path = input(user,"Enter typepath:" ,"Typepath","/obj/structure/closet")
objholder = text2path(target_path)
if(!ispath(objholder))
objholder = pick_closest_path(target_path)
if(!objholder)
alert("No path was selected")
return
else if(ispath(objholder, /area))
objholder = null
alert("That path is not allowed.")
return
/datum/buildmode_mode/advanced/handle_click(user, params, obj/object)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
var/right_click = pa.Find("right")
var/alt_click = pa.Find("alt")
if(left_click && alt_click)
if (isturf(object) || isobj(object) || ismob(object))
objholder = object.type
to_chat(user, "<span class='notice'>[initial(object.name)] ([object.type]) selected.</span>")
else
to_chat(user, "<span class='notice'>[initial(object.name)] is not a turf, object, or mob! Please select again.</span>")
else if(left_click)
if(ispath(objholder,/turf))
var/turf/T = get_turf(object)
log_admin("Build Mode: [key_name(user)] modified [T] ([T.x],[T.y],[T.z]) to [objholder]")
T.ChangeTurf(objholder)
else if(!isnull(objholder))
var/obj/A = new objholder (get_turf(object))
A.setDir(BM.build_dir)
log_admin("Build Mode: [key_name(user)] modified [A]'s ([A.x],[A.y],[A.z]) dir to [BM.build_dir]")
else
to_chat(user, "<span class='warning'>Select object type first.</span>")
else if(right_click)
if(isobj(object))
log_admin("Build Mode: [key_name(user)] deleted [object] at ([object.x],[object.y],[object.z])")
qdel(object)
@@ -0,0 +1,59 @@
/datum/buildmode_mode/area_edit
key = "areaedit"
var/area/storedarea
var/image/areaimage
/datum/buildmode_mode/area_edit/New()
areaimage = image('icons/turf/areas.dmi', null, "yellow")
..()
/datum/buildmode_mode/area_edit/enter_mode(datum/click_intercept/buildmode/BM)
BM.holder.images += areaimage
/datum/buildmode_mode/area_edit/exit_mode(datum/click_intercept/buildmode/BM)
areaimage.loc = null // de-color the area
BM.holder.images -= areaimage
return ..()
/datum/buildmode_mode/area_edit/Destroy()
QDEL_NULL(areaimage)
return ..()
/datum/buildmode_mode/area_edit/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on obj/turf/mob = Paint area</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on obj/turf/mob = Select area to paint</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Create new area</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/buildmode_mode/area_edit/change_settings(mob/user)
var/target_path = input(user,"Enter typepath:", "Typepath", "/area")
var/areatype = text2path(target_path)
if(ispath(areatype,/area))
var/areaname = input(user,"Enter area name:", "Area name", "Area")
if(!areaname || !length(areaname))
return
storedarea = new areatype
storedarea.power_equip = 0
storedarea.power_light = 0
storedarea.power_environ = 0
storedarea.always_unpowered = 0
storedarea.name = areaname
areaimage.loc = storedarea // color our area
/datum/buildmode_mode/area_edit/handle_click(user, params, object)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
var/right_click = pa.Find("right")
if(left_click)
if(!storedarea)
to_chat(user, "<span class='warning'>Configure or select the area you want to paint first!</span>")
return
var/turf/T = get_turf(object)
if(get_area(T) != storedarea)
storedarea.contents.Add(T)
else if(right_click)
var/turf/T = get_turf(object)
storedarea = get_area(T)
areaimage.loc = storedarea // color our area
+72
View File
@@ -0,0 +1,72 @@
/datum/buildmode_mode/atmos
key = "atmos"
use_corner_selection = TRUE
var/pressure = ONE_ATMOSPHERE
var/temperature = T20C
var/oxygen = O2STANDARD
var/nitrogen = N2STANDARD
var/plasma = 0
var/cdiox = 0
var/nitrox = 0
/datum/buildmode_mode/atmos/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on turf = Select corner</span>")
to_chat(user, "<span class='notice'>Left Mouse Button + Ctrl on turf = Set 'base atmos conditions' for unsimulated turfs in region</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Adjust target atmos</span>")
to_chat(user, "<span class='notice'><b>Notice:</b> Starts out with standard breathable/liveable defaults</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
// FIXME this is a little tedious, something where you don't have to fill in each field would be cooler
// maybe some kind of stat panel thing?
/datum/buildmode_mode/atmos/change_settings(mob/user)
pressure = input(user, "Atmospheric Pressure", "Input", ONE_ATMOSPHERE) as num|null
temperature = input(user, "Temperature", "Input", T20C) as num|null
oxygen = input(user, "Oxygen ratio", "Input", O2STANDARD) as num|null
nitrogen = input(user, "Nitrogen ratio", "Input", N2STANDARD) as num|null
plasma = input(user, "Plasma ratio", "Input", 0) as num|null
cdiox = input(user, "CO2 ratio", "Input", 0) as num|null
nitrox = input(user, "N2O ratio", "Input", 0) as num|null
/datum/buildmode_mode/atmos/proc/ppratio_to_moles(ppratio)
// ideal gas equation: Pressure * Volume = Moles * r * Temperature
// air datum fields are in moles, we have partial pressure ratios
// Moles = (Pressure * Volume) / (r * Temperature)
return ((ppratio * pressure) * CELL_VOLUME) / (temperature * R_IDEAL_GAS_EQUATION)
/datum/buildmode_mode/atmos/handle_selected_region(mob/user, params)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
var/ctrl_click = pa.Find("ctrl")
if(left_click) //rectangular
for(var/turf/T in block(cornerA,cornerB))
if(istype(T, /turf/simulated))
// fill the turf with the appropriate gasses
// this feels slightly icky
var/turf/simulated/S = T
if(S.air)
S.air.temperature = temperature
S.air.oxygen = ppratio_to_moles(oxygen)
S.air.nitrogen = ppratio_to_moles(nitrogen)
S.air.toxins = ppratio_to_moles(plasma)
S.air.carbon_dioxide = ppratio_to_moles(cdiox)
S.air.trace_gases.Cut()
if(nitrox)
var/datum/gas/TG = new /datum/gas/sleeping_agent
TG.moles = ppratio_to_moles(nitrox)
S.air.trace_gases += TG
S.update_visuals()
S.air_update_turf()
else if(ctrl_click) // overwrite "default" unsimulated air
T.temperature = temperature
T.oxygen = ppratio_to_moles(oxygen)
T.nitrogen = ppratio_to_moles(nitrogen)
T.toxins = ppratio_to_moles(plasma)
T.carbon_dioxide = ppratio_to_moles(cdiox)
// no interface for trace gases on unsim turfs
T.air_update_turf()
// admin log
log_admin("Build Mode: [key_name(user)] changed the atmos of region [COORD(cornerA)] to [COORD(cornerB)]. T: [temperature], P: [pressure], Ox: [oxygen]%, N2: [nitrogen]%, Plsma: [plasma]%, CO2: [cdiox]%, N2O: [nitrox]%. [ctrl_click ? "Overwrote base unsimulated turf gases." : ""]")
+50
View File
@@ -0,0 +1,50 @@
/datum/buildmode_mode/basic
key = "basic"
/datum/buildmode_mode/basic/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button = Construct / Upgrade</span>")
to_chat(user, "<span class='notice'>Right Mouse Button = Deconstruct / Delete / Downgrade</span>")
to_chat(user, "<span class='notice'>Left Mouse Button + ctrl = R-Window</span>")
to_chat(user, "<span class='notice'>Left Mouse Button + alt = Airlock</span>")
to_chat(user, "")
to_chat(user, "<span class='notice'>Use the button in the upper left corner to</span>")
to_chat(user, "<span class='notice'>change the direction of built objects.</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/buildmode_mode/basic/handle_click(user, params, obj/object)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
var/right_click = pa.Find("right")
var/ctrl_click = pa.Find("ctrl")
var/alt_click = pa.Find("alt")
if(istype(object,/turf) && left_click && !alt_click && !ctrl_click)
var/turf/T = object
if(istype(object,/turf/space))
T.ChangeTurf(/turf/simulated/floor/plasteel)
else if(istype(object,/turf/simulated/floor))
T.ChangeTurf(/turf/simulated/wall)
else if(istype(object,/turf/simulated/wall))
T.ChangeTurf(/turf/simulated/wall/r_wall)
log_admin("Build Mode: [key_name(user)] built [T] at ([T.x],[T.y],[T.z])")
else if(right_click)
log_admin("Build Mode: [key_name(user)] deleted [object] at ([object.x],[object.y],[object.z])")
if(istype(object,/turf/simulated/wall))
var/turf/T = object
T.ChangeTurf(/turf/simulated/floor/plasteel)
else if(istype(object,/turf/simulated/floor))
var/turf/T = object
T.ChangeTurf(/turf/space)
else if(istype(object,/turf/simulated/wall/r_wall))
var/turf/T = object
T.ChangeTurf(/turf/simulated/wall)
else if(istype(object,/obj))
qdel(object)
else if(istype(object,/turf) && alt_click && left_click)
log_admin("Build Mode: [key_name(user)] built an airlock at ([object.x],[object.y],[object.z])")
new/obj/machinery/door/airlock(get_turf(object))
else if(istype(object,/turf) && ctrl_click && left_click)
var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object))
WIN.setDir(BM.build_dir)
log_admin("Build Mode: [key_name(user)] built a window at ([object.x],[object.y],[object.z])")
+32
View File
@@ -0,0 +1,32 @@
/datum/buildmode_mode/boom
key = "boom"
var/devastation = -1
var/heavy = -1
var/light = -1
var/flash = -1
var/flames = -1
/datum/buildmode_mode/boom/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Mouse Button on obj = Kaboom</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/buildmode_mode/boom/change_settings(mob/user)
devastation = input("Range of total devastation. -1 to none", text("Input")) as num|null
if(devastation == null) devastation = -1
heavy = input("Range of heavy impact. -1 to none", text("Input")) as num|null
if(heavy == null) heavy = -1
light = input("Range of light impact. -1 to none", text("Input")) as num|null
if(light == null) light = -1
flash = input("Range of flash. -1 to none", text("Input")) as num|null
if(flash == null) flash = -1
flames = input("Range of flames. -1 to none", text("Input")) as num|null
if(flames == null) flames = -1
/datum/buildmode_mode/boom/handle_click(user, params, obj/object)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
if(left_click)
explosion(object, devastation, heavy, light, flash, null, TRUE, flames)
+27
View File
@@ -0,0 +1,27 @@
/datum/buildmode_mode/copy
key = "copy"
var/atom/movable/stored = null
/datum/buildmode_mode/copy/exit_mode()
stored = null
return ..()
/datum/buildmode_mode/copy/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on obj/turf/mob = Spawn a Copy of selected target</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on obj/mob = Select target to copy</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/buildmode_mode/copy/handle_click(user, params, obj/object)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
var/right_click = pa.Find("right")
if(left_click)
var/turf/T = get_turf(object)
if(stored)
DuplicateObject(stored, perfectcopy=1, sameloc=0,newloc=T)
else if(right_click)
if(ismovableatom(object)) // No copying turfs for now.
to_chat(user, "<span class='notice'>[object] set as template.</span>")
stored = object
+49
View File
@@ -0,0 +1,49 @@
/datum/buildmode_mode/fill
key = "fill"
use_corner_selection = TRUE
var/objholder = null
/datum/buildmode_mode/fill/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select corner</span>")
to_chat(user, "<span class='notice'>Left Mouse Button + Alt on turf/obj/mob = Delete region</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Select object type</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/buildmode_mode/fill/change_settings(mob/user)
var/target_path = input(user,"Enter typepath:" ,"Typepath","/obj/structure/closet")
objholder = text2path(target_path)
if(!ispath(objholder))
objholder = pick_closest_path(target_path)
if(!objholder)
alert("No path has been selected.")
return
else if(ispath(objholder, /area))
objholder = null
alert("Area paths are not supported for this mode, use the area edit mode instead.")
return
deselect_region()
/datum/buildmode_mode/fill/handle_click(mob/user, params, obj/object)
if(isnull(objholder))
to_chat(user, "<span class='warning'>Select an object type first.</span>")
deselect_region()
return
..()
/datum/buildmode_mode/fill/handle_selected_region(mob/user, params)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
var/alt_click = pa.Find("alt")
if(left_click) //rectangular
if(alt_click)
empty_region(block(cornerA,cornerB))
else
for(var/turf/T in block(cornerA,cornerB))
if(ispath(objholder,/turf))
T.ChangeTurf(objholder)
else
var/obj/A = new objholder(T)
A.setDir(BM.build_dir)
+94
View File
@@ -0,0 +1,94 @@
/datum/buildmode_mode/link
key = "link"
var/list/link_lines = list()
var/obj/link_obj
/datum/buildmode_mode/link/proc/clear_lines()
QDEL_LIST(link_lines)
/datum/buildmode_mode/link/proc/form_connection(atom/source, atom/dest, valid)
var/obj/effect/buildmode_line/L = new(BM.holder, source, dest, "[source.name] to [dest.name]")
L.color = valid ? "#339933" : "#993333"
link_lines += L
var/obj/effect/buildmode_line/L2 = new(BM.holder, dest, source, "[dest.name] to [source.name]") // Yes, reversed one so that you can see it source both sides.
L2.color = L.color
link_lines += L2
/datum/buildmode_mode/link/Destroy()
clear_lines()
link_obj = null
return ..()
/datum/buildmode_mode/link/Reset()
clear_lines()
link_obj = null
..()
/datum/buildmode_mode/link/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on obj = Select button to link</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on obj = Link/unlink to selected button")
to_chat(user, "<span class='notice'>***********************************************************</span>")
// FIXME: this probably would work better with something component-based
/datum/buildmode_mode/link/handle_click(mob/user, params, obj/object)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
var/right_click = pa.Find("right")
if(left_click && istype(object, /obj/machinery))
link_obj = object
if(right_click && istype(object, /obj/machinery))
if(istype(link_obj, /obj/machinery/door_control) && istype(object, /obj/machinery/door/airlock))
var/obj/machinery/door_control/M = link_obj
var/obj/machinery/door/airlock/P = object
if(!M.id || M.id == "")
M.id = input(user, "Please select an ID for the button", "Buildmode", "")
if(!M.id || M.id == "")
goto(line_jump)
if(P.id_tag == M.id && (P in range(M.range, M)) && P.id_tag && P.id_tag != "")
P.id_tag = null
to_chat(user, "[P] unlinked.")
goto(line_jump)
if(!M.normaldoorcontrol)
if(link_lines.len && alert(user, "Warning: This will disable links to connected pod doors. Continue?", "Buildmode", "Yes", "No") == "No")
goto(line_jump)
M.normaldoorcontrol = 1
if(P.id_tag && alert(user, "Warning: This will unlink something else from the door. Continue?", "Buildmode", "Yes", "No") == "No")
goto(line_jump)
P.id_tag = M.id
if(istype(link_obj, /obj/machinery/door_control) && istype(object, /obj/machinery/door/poddoor))
var/obj/machinery/door_control/M = link_obj
var/obj/machinery/door/poddoor/P = object
if(!M.id || M.id == "")
M.id = input(user, "Please select an ID for the button", "Buildmode", "")
if(!M.id || M.id == "")
goto(line_jump)
if(P.id_tag == M.id && P.id_tag && P.id_tag != "")
P.id_tag = null
to_chat(user, "[P] unlinked.")
goto(line_jump)
if(M.normaldoorcontrol)
if(link_lines.len && alert(user, "Warning: This will disable links to connected airlocks. Continue?", "Buildmode", "Yes", "No") == "No")
goto(line_jump)
M.normaldoorcontrol = 0
if(!M.id || M.id == "")
M.id = input(user, "Please select an ID for the button", "Buildmode", "")
if(!M.id || M.id == "")
goto(line_jump)
if(P.id_tag && P.id_tag != 1 && alert(user, "Warning: This will unlink something else from the door. Continue?", "Buildmode", "Yes", "No") == "No")
goto(line_jump)
P.id_tag = M.id
line_jump // For the goto
clear_lines()
if(istype(link_obj, /obj/machinery/door_control))
var/obj/machinery/door_control/M = link_obj
for(var/obj/machinery/door/airlock/P in range(M.range,M))
if(P.id_tag == M.id)
form_connection(M, P, M.normaldoorcontrol)
for(var/obj/machinery/door/poddoor/P in GLOB.airlocks)
if(P.id_tag == M.id)
form_connection(M, P, !M.normaldoorcontrol)
+40
View File
@@ -0,0 +1,40 @@
/datum/buildmode_mode/mapgen
key = "mapgen"
use_corner_selection = TRUE
var/generator_path
/datum/buildmode_mode/mapgen/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select corner</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Select generator</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/buildmode_mode/mapgen/change_settings(mob/user)
var/list/gen_paths = subtypesof(/datum/mapGenerator)
var/type = input(user,"Select Generator Type","Type") as null|anything in gen_paths
if(!type) return
generator_path = type
deselect_region()
/datum/buildmode_mode/mapgen/handle_click(mob/user, params, obj/object)
if(isnull(generator_path))
to_chat(user, "<span class='warning'>Select generator type first.</span>")
deselect_region()
return
..()
/datum/buildmode_mode/mapgen/handle_selected_region(mob/user, params)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
if(left_click) //rectangular
if(cornerA && cornerB)
var/datum/mapGenerator/G = new generator_path
G.defineRegion(cornerA, cornerB, 1)
highlight_region(G.map)
var/confirm = alert("Are you sure you want run the map generator?", "Run generator", "Yes", "No")
if(confirm == "Yes")
G.generate()
+28
View File
@@ -0,0 +1,28 @@
/datum/buildmode_mode/save
key = "save"
use_corner_selection = TRUE
var/use_json = TRUE
/datum/buildmode_mode/save/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select corner</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/buildmode_mode/save/change_settings(mob/user)
use_json = (alert("Would you like to use json (Default is \"Yes\")?",,"Yes","No") == "Yes")
/datum/buildmode_mode/save/handle_selected_region(mob/user, params)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
if(left_click)
var/map_name = input(user, "Please select a name for your map", "Buildmode", "")
if(map_name == "")
return
var/map_flags = 0
if(use_json)
map_flags = 32 // Magic number defined in `writer.dm` that I can't use directly
// because #defines are for some reason our coding standard
var/our_map = maploader.save_map(cornerA, cornerB, map_name, map_flags)
user << ftp(our_map) // send the map they've made! Or are stealing, whatever
to_chat(user, "Map saving complete! [our_map]")
+12
View File
@@ -0,0 +1,12 @@
// SKELETON CODE, not yet functional
/datum/buildmode_mode/sdql
key = "sdql"
var/sdql_command = "SELECT /turf IN"
/datum/buildmode_mode/sdql/show_help(mob/user)
/datum/buildmode_mode/sdql/change_settings(mob/user)
/datum/buildmode_mode/sdql/handle_click(mob/user, params, obj/object)
@@ -0,0 +1,25 @@
/datum/buildmode_mode/throwing
key = "throw"
var/atom/movable/throw_atom = null
/datum/buildmode_mode/throwing/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on turf/obj/mob = Throw</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/buildmode_mode/throwing/handle_click(user, params, obj/object)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
var/right_click = pa.Find("right")
if(left_click)
if(isturf(object))
return
throw_atom = object
to_chat(user, "Selected object '[throw_atom]'")
if(right_click)
if(throw_atom)
throw_atom.throw_at(object, 10, 1, user)
log_admin("Build Mode: [key_name(user)] threw [throw_atom] at [object] ([object.x],[object.y],[object.z])")
@@ -0,0 +1,55 @@
/datum/buildmode_mode/varedit
key = "edit"
// Varedit mode
var/varholder = "name"
var/valueholder = "value"
/datum/buildmode_mode/varedit/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Select var(type) & value</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj/mob = Set var(type) & value</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on turf/obj/mob = Reset var's value</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
// FIXME: This needs to use a standard var-editing interface instead of
// doing its own thing here
/datum/buildmode_mode/varedit/change_settings(mob/user)
var/temp_varname = input(user,"Enter variable name:", "Name", "name")
if(!vv_varname_lockcheck(temp_varname))
return
var/temp_value = user.client.vv_get_value()
if(isnull(temp_value["class"]))
Reset()
to_chat(user, "<span class='notice'>Variable unset.</span>")
return
// we assign this once all user input is done, since things could get wonky otherwise
varholder = temp_varname
valueholder = temp_value["value"]
/datum/buildmode_mode/varedit/handle_click(user, params, obj/object)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
var/right_click = pa.Find("right")
if(isnull(varholder))
to_chat(user, "<span class='warning'>Choose a variable to modify first.</span>")
return
if(left_click)
if(object.vars.Find(varholder))
if(!object.vv_edit_var(varholder, valueholder))
to_chat(user, "<span class='warning'>Your edit was rejected by [object].</span>")
return
log_admin("Build Mode: [key_name(user)] modified [object.name]'s [varholder] to [valueholder]")
else
to_chat(user, "<span class='warning'>[initial(object.name)] does not have a var called '[varholder]'</span>")
if(right_click)
if(object.vars.Find(varholder))
var/reset_value = initial(object.vars[varholder])
if(!object.vv_edit_var(varholder, reset_value))
to_chat(user, "<span class='warning'>Your edit was rejected by [object].</span>")
return
log_admin("Build Mode: [key_name(user)] modified [object.name]'s [varholder] to [reset_value]")
else
to_chat(user, "<span class='warning'>[initial(object.name)] does not have a var called '[varholder]'</span>")