Alien Ruin fix, various cherrypicked upstream fixes
Also adds new buildmode
This commit is contained in:
@@ -124,6 +124,11 @@
|
||||
#define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic" //from base of mob/anti_magic_check(): (magic, holy, protection_sources)
|
||||
#define COMPONENT_BLOCK_MAGIC 1
|
||||
#define COMSIG_MOB_HUD_CREATED "mob_hud_created" //from base of mob/create_mob_hud(): ()
|
||||
#define COMSIG_MOB_ATTACK_HAND "mob_attack_hand" //from base of
|
||||
#define COMSIG_MOB_ITEM_ATTACK "mob_item_attack" //from base of /obj/item/attack(): (mob/M, mob/user)
|
||||
#define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters)
|
||||
#define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" //from base of mob/RangedAttack(): (atom/A, params)
|
||||
#define COMSIG_MOB_THROW "mob_throw" //from base of /mob/throw_item(): (atom/target)
|
||||
|
||||
// /mob/living signals
|
||||
#define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living)
|
||||
|
||||
@@ -470,3 +470,6 @@ GLOBAL_LIST_INIT(pda_styles, list(MONO, VT, ORBITRON, SHARE))
|
||||
#define CAMERA_SEE_GHOSTS_ORBIT 2
|
||||
|
||||
#define CLIENT_FROM_VAR(I) (ismob(I) ? I:client : (istype(I, /client) ? I : (istype(I, /datum/mind) ? I:current?:client : null)))
|
||||
|
||||
#define AREASELECT_CORNERA "corner A"
|
||||
#define AREASELECT_CORNERB "corner B"
|
||||
@@ -10,9 +10,6 @@
|
||||
Note that AI have no need for the adjacency proc, and so this proc is a lot cleaner.
|
||||
*/
|
||||
/mob/living/silicon/ai/DblClickOn(var/atom/A, params)
|
||||
if(check_click_intercept(params,A))
|
||||
return
|
||||
|
||||
if(control_disabled || incapacitated())
|
||||
return
|
||||
|
||||
|
||||
@@ -272,6 +272,7 @@
|
||||
animals lunging, etc.
|
||||
*/
|
||||
/mob/proc/RangedAttack(atom/A, params)
|
||||
SEND_SIGNAL(src, COMSIG_MOB_ATTACK_RANGED, A, params)
|
||||
/*
|
||||
Restrained ClickOn
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
|
||||
/obj/item/proc/attack(mob/living/M, mob/living/user)
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, M, user)
|
||||
SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, M, user)
|
||||
if(item_flags & NOBLUDGEON)
|
||||
return
|
||||
|
||||
@@ -139,7 +140,7 @@
|
||||
// Click parameters is the params string from byond Click() code, see that documentation.
|
||||
/obj/item/proc/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_AFTERATTACK, target, user, proximity_flag, click_parameters)
|
||||
|
||||
SEND_SIGNAL(user, COMSIG_MOB_ITEM_AFTERATTACK, target, user, proximity_flag, click_parameters)
|
||||
|
||||
/obj/item/proc/get_clamped_volume()
|
||||
if(w_class)
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
/mob/dead/observer/DblClickOn(var/atom/A, var/params)
|
||||
if(check_click_intercept(params,A))
|
||||
return
|
||||
|
||||
if(can_reenter_corpse && mind && mind.current)
|
||||
if(A == mind.current || (mind.current in A)) // double click your corpse or whatever holds it
|
||||
reenter_corpse() // (cloning scanner, body bag, closet, mech, etc)
|
||||
|
||||
@@ -86,6 +86,7 @@
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/RangedAttack(atom/A, mouseparams)
|
||||
. = ..()
|
||||
if(gloves)
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
if(istype(G) && G.Touch(A,0)) // for magic gloves
|
||||
@@ -96,6 +97,7 @@
|
||||
|
||||
if(isturf(A) && get_dist(src,A) <= 1)
|
||||
src.Move_Pulled(A)
|
||||
return
|
||||
|
||||
/*
|
||||
Animals & All Unspecified
|
||||
|
||||
@@ -154,13 +154,14 @@
|
||||
suffix = "lavaland_surface_ufo_crash.dmm"
|
||||
cost = 5
|
||||
|
||||
/* Replaced with Alien Nest Ruins
|
||||
/datum/map_template/ruin/lavaland/xeno_nest
|
||||
name = "Xenomorph Nest"
|
||||
id = "xeno-nest"
|
||||
description = "These xenomorphs got bored of horrifically slaughtering people on space stations, and have settled down on a nice lava filled hellscape to focus on what's really important in life. \
|
||||
Quality memes."
|
||||
suffix = "lavaland_surface_xeno_nest.dmm"
|
||||
cost = 20
|
||||
cost = 20 */
|
||||
|
||||
/datum/map_template/ruin/lavaland/fountain
|
||||
name = "Fountain Hall"
|
||||
|
||||
@@ -62,72 +62,63 @@
|
||||
|
||||
// If the log is a speech file
|
||||
if(C.input_type == "Speech File")
|
||||
|
||||
dat += "<li><font color = #008F00>[C.name]</font color> <font color = #FF0000><a href='?src=[REF(src)];delete=[i]'>\[X\]</a></font color><br>"
|
||||
dat += "<li><font color = #008F00>[C.name]</font> <font color = #FF0000><a href='?src=[REF(src)];delete=[i]'>\[X\]</a></font><br>"
|
||||
|
||||
// -- Determine race of orator --
|
||||
|
||||
var/race // The actual race of the mob
|
||||
var/language = "Human" // MMIs, pAIs, Cyborgs and humans all speak Human
|
||||
var/mobtype = C.parameters["mobtype"]
|
||||
var/race // The actual race of the mob
|
||||
|
||||
var/list/humans = typesof(/mob/living/carbon/human, /mob/living/brain)
|
||||
var/list/monkeys = typesof(/mob/living/carbon/monkey)
|
||||
var/list/silicons = typesof(/mob/living/silicon)
|
||||
var/list/slimes = typesof(/mob/living/simple_animal/slime)
|
||||
var/list/animals = typesof(/mob/living/simple_animal)
|
||||
|
||||
if(mobtype in humans)
|
||||
if(ispath(mobtype, /mob/living/carbon/human) || ispath(mobtype, /mob/living/brain))
|
||||
race = "Humanoid"
|
||||
language = race
|
||||
|
||||
else if(mobtype in slimes) // NT knows a lot about slimes, but not aliens. Can identify slimes
|
||||
// NT knows a lot about slimes, but not aliens. Can identify slimes
|
||||
else if(ispath(mobtype, /mob/living/simple_animal/slime))
|
||||
race = "Slime"
|
||||
language = race
|
||||
|
||||
else if(mobtype in monkeys)
|
||||
else if(ispath(mobtype, /mob/living/carbon/monkey))
|
||||
race = "Monkey"
|
||||
language = race
|
||||
|
||||
else if(mobtype in silicons || C.parameters["job"] == "AI") // sometimes M gets deleted prematurely for AIs... just check the job
|
||||
// sometimes M gets deleted prematurely for AIs... just check the job
|
||||
else if(ispath(mobtype, /mob/living/silicon) || C.parameters["job"] == "AI")
|
||||
race = "Artificial Life"
|
||||
language = "Humanoid" //Ais and borgs speak human, and binary isnt picked up.
|
||||
|
||||
else if(isobj(mobtype))
|
||||
race = "Machinery"
|
||||
language = race
|
||||
|
||||
else if(mobtype in animals)
|
||||
else if(ispath(mobtype, ))
|
||||
race = "Domestic Animal"
|
||||
language = race
|
||||
|
||||
else
|
||||
race = "<i>Unidentifiable</i>"
|
||||
language = race
|
||||
|
||||
// -- If the orator is a human, or universal translate is active, OR mob has universal speech on --
|
||||
dat += "<u><font color = #18743E>Data type</font></u>: [C.input_type]<br>"
|
||||
dat += "<u><font color = #18743E>Source</font></u>: [C.parameters["name"]] (Job: [C.parameters["job"]])<br>"
|
||||
dat += "<u><font color = #18743E>Class</font></u>: [race]<br>"
|
||||
var/message = C.parameters["message"]
|
||||
var/language = C.parameters["language"]
|
||||
|
||||
if(language == "Humanoid" || universal_translate || C.parameters["uspeech"])
|
||||
dat += "<u><font color = #18743E>Data type</font color></u>: [C.input_type]<br>"
|
||||
dat += "<u><font color = #18743E>Source</font color></u>: [C.parameters["name"]] (Job: [C.parameters["job"]])<br>"
|
||||
dat += "<u><font color = #18743E>Class</font color></u>: [race]<br>"
|
||||
dat += "<u><font color = #18743E>Contents</font color></u>: \"[C.parameters["message"]]\"<br>"
|
||||
|
||||
|
||||
// -- Orator is not human and universal translate not active --
|
||||
|
||||
else
|
||||
dat += "<u><font color = #18743E>Data type</font color></u>: Audio File<br>"
|
||||
dat += "<u><font color = #18743E>Source</font color></u>: <i>Unidentifiable</i><br>"
|
||||
dat += "<u><font color = #18743E>Class</font color></u>: [race]<br>"
|
||||
dat += "<u><font color = #18743E>Contents</font color></u>: <i>Unintelligible</i><br>"
|
||||
// based on [/atom/movable/proc/lang_treat]
|
||||
if (universal_translate || user.has_language(language))
|
||||
message = "\"[message]\""
|
||||
else if (!user.has_language(language))
|
||||
var/datum/language/D = GLOB.language_datum_instances[language]
|
||||
message = "\"[D.scramble(message)]\""
|
||||
else if (language)
|
||||
message = "<i>(unintelligible)</i>"
|
||||
|
||||
dat += "<u><font color = #18743E>Contents</font></u>: [message]<br>"
|
||||
dat += "</li><br>"
|
||||
|
||||
else if(C.input_type == "Execution Error")
|
||||
dat += "<li><font color = #990000>[C.name]</font> <a href='?src=[REF(src)];delete=[i]'>\[X\]</a><br>"
|
||||
dat += "<u><font color = #787700>Error</font></u>: \"[C.parameters["message"]]\"<br>"
|
||||
dat += "</li><br>"
|
||||
|
||||
dat += "<li><font color = #990000>[C.name]</font color> <font color = #FF0000><a href='?src=[REF(src)];delete=[i]'>\[X\]</a></font color><br>"
|
||||
dat += "<u><font color = #787700>Output</font color></u>: \"[C.parameters["message"]]\"<br>"
|
||||
else
|
||||
dat += "<li><font color = #000099>[C.name]</font> <a href='?src=[REF(src)];delete=[i]'>\[X\]</a><br>"
|
||||
dat += "<u><font color = #18743E>Data type</font></u>: [C.input_type]<br>"
|
||||
dat += "<u><font color = #18743E>Contents</font></u>: <i>(unintelligible)</i><br>"
|
||||
dat += "</li><br>"
|
||||
|
||||
|
||||
@@ -221,4 +212,4 @@
|
||||
|
||||
/obj/machinery/computer/telecomms/server/attackby()
|
||||
. = ..()
|
||||
updateUsrDialog()
|
||||
updateUsrDialog()
|
||||
@@ -36,6 +36,7 @@
|
||||
log.parameters["name"] = signal.data["name"]
|
||||
log.parameters["job"] = signal.data["job"]
|
||||
log.parameters["message"] = signal.data["message"]
|
||||
log.parameters["language"] = signal.language
|
||||
|
||||
// If the signal is still compressed, make the log entry gibberish
|
||||
var/compression = signal.data["compression"]
|
||||
|
||||
@@ -79,10 +79,8 @@
|
||||
|
||||
/turf/open/floor/plating/asteroid/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill)
|
||||
for(var/turf/open/floor/plating/asteroid/M in range(1, drill.chassis))
|
||||
if(get_dir(drill.chassis,M)&drill.chassis.dir)
|
||||
for(var/I in GetComponents(/datum/component/archaeology))
|
||||
var/datum/component/archaeology/archy = I
|
||||
archy.gets_dug()
|
||||
if((get_dir(drill.chassis,M)&drill.chassis.dir) && !M.dug)
|
||||
M.getDug()
|
||||
drill.log_message("Drilled through [src]")
|
||||
drill.move_ores()
|
||||
|
||||
|
||||
@@ -62,7 +62,6 @@
|
||||
return
|
||||
//I couldn't feasibly fix the overlay bugs caused by cleaning items we are wearing.
|
||||
//So this is a workaround. This also makes more sense from an IC standpoint. ~Carn
|
||||
SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
|
||||
if(user.client && ((target in user.client.screen) && !user.is_holding(target)))
|
||||
to_chat(user, "<span class='warning'>You need to take that [target.name] off before cleaning it!</span>")
|
||||
else if(istype(target, /obj/effect/decal/cleanable))
|
||||
@@ -89,7 +88,7 @@
|
||||
var/obj/effect/decal/cleanable/C = locate() in target
|
||||
qdel(C)
|
||||
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
|
||||
SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
|
||||
SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
|
||||
target.wash_cream()
|
||||
return
|
||||
|
||||
@@ -169,4 +168,4 @@
|
||||
name = "Canned Laughter"
|
||||
desc = "Just looking at this makes you want to giggle."
|
||||
icon_state = "laughter"
|
||||
list_reagents = list("laughter" = 50)
|
||||
list_reagents = list("laughter" = 50)
|
||||
@@ -127,17 +127,19 @@
|
||||
self_delay = 20
|
||||
max_amount = 12
|
||||
|
||||
/obj/item/stack/medical/gauze/wirecutter_act(mob/living/user, obj/item/I)
|
||||
if(get_amount() < 2)
|
||||
to_chat(user, "<span class='warning'>You need at least two gauze to do this!</span>")
|
||||
return
|
||||
new /obj/item/stack/sheet/cloth(user.drop_location())
|
||||
user.visible_message("[user] cuts [src] into pieces of cloth with [I].", \
|
||||
"<span class='notice'>You cut [src] into pieces of cloth with [I].</span>", \
|
||||
"<span class='italics'>You hear cutting.</span>")
|
||||
var/obj/item/stack/medical/gauze/R = src
|
||||
src = null
|
||||
R.use(2)
|
||||
|
||||
/obj/item/stack/medical/gauze/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/wirecutters) || I.is_sharp())
|
||||
if(get_amount() < 2)
|
||||
to_chat(user, "<span class='warning'>You need at least two gauzes to do this!</span>")
|
||||
return
|
||||
new /obj/item/stack/sheet/cloth(user.drop_location())
|
||||
user.visible_message("[user] cuts [src] into pieces of cloth with [I].", \
|
||||
"<span class='notice'>You cut [src] into pieces of cloth with [I].</span>", \
|
||||
"<span class='italics'>You hear cutting.</span>")
|
||||
use(2)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/stack/medical/gauze/suicide_act(mob/living/user)
|
||||
user.visible_message("<span class='suicide'>[user] begins tightening \the [src] around [user.p_their()] neck! It looks like [user.p_they()] forgot how to use medical supplies!</span>")
|
||||
@@ -168,4 +170,4 @@
|
||||
|
||||
/obj/item/stack/medical/ointment/suicide_act(mob/living/user)
|
||||
user.visible_message("<span class='suicide'>[user] is squeezing \the [src] into [user.p_their()] mouth! [user.p_do(TRUE)]n't [user.p_they()] know that stuff is toxic?</span>")
|
||||
return TOXLOSS
|
||||
return TOXLOSS
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
var/postdig_icon_change = FALSE
|
||||
var/postdig_icon
|
||||
var/list/archdrops
|
||||
var/wet
|
||||
|
||||
var/footstep = null
|
||||
@@ -13,8 +12,6 @@
|
||||
. = ..()
|
||||
if(wet)
|
||||
AddComponent(/datum/component/wet_floor, wet, INFINITY, 0, INFINITY, TRUE)
|
||||
if(LAZYLEN(archdrops))
|
||||
AddComponent(/datum/component/archaeology, archdrops)
|
||||
|
||||
/turf/open/indestructible
|
||||
name = "floor"
|
||||
|
||||
@@ -13,8 +13,9 @@
|
||||
var/environment_type = "asteroid"
|
||||
var/turf_type = /turf/open/floor/plating/asteroid //Because caves do whacky shit to revert to normal
|
||||
var/floor_variance = 20 //probability floor has a different icon state
|
||||
archdrops = list(/obj/item/stack/ore/glass = list(ARCH_PROB = 100,ARCH_MAXDROP = 5))
|
||||
attachment_holes = FALSE
|
||||
var/obj/item/stack/digResult = /obj/item/stack/ore/glass/basalt
|
||||
var/dug
|
||||
|
||||
/turf/open/floor/plating/asteroid/Initialize()
|
||||
var/proper_name = name
|
||||
@@ -23,6 +24,14 @@
|
||||
if(prob(floor_variance))
|
||||
icon_state = "[environment_type][rand(0,12)]"
|
||||
|
||||
/turf/open/floor/plating/asteroid/proc/getDug()
|
||||
new digResult(src, 5)
|
||||
if(postdig_icon_change)
|
||||
if(!postdig_icon)
|
||||
icon_plating = "[environment_type]_dug"
|
||||
icon_state = "[environment_type]_dug"
|
||||
dug = TRUE
|
||||
|
||||
/turf/open/floor/plating/asteroid/try_replace_tile(obj/item/stack/tile/T, mob/user, params)
|
||||
return
|
||||
|
||||
@@ -36,11 +45,26 @@
|
||||
return
|
||||
|
||||
/turf/open/floor/plating/asteroid/attackby(obj/item/W, mob/user, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
if(istype(W, /obj/item/storage/bag/ore))
|
||||
for(var/obj/item/stack/ore/O in src)
|
||||
SEND_SIGNAL(W, COMSIG_PARENT_ATTACKBY, O)
|
||||
. = ..()
|
||||
if(!.)
|
||||
if(W.tool_behaviour == TOOL_SHOVEL || W.tool_behaviour == TOOL_MINING)
|
||||
if(dug)
|
||||
to_chat(user, "<span class='notice'>Looks like someone has dug here already.</span>")
|
||||
return TRUE
|
||||
|
||||
if(!isturf(user.loc))
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You start digging...</span>")
|
||||
|
||||
if(W.use_tool(src, user, 40, volume=50))
|
||||
to_chat(user, "<span class='notice'>You dig a hole.</span>")
|
||||
getDug()
|
||||
SSblackbox.record_feedback("tally", "pick_used_mining", 1, W.type)
|
||||
return TRUE
|
||||
else if(istype(W, /obj/item/storage/bag/ore))
|
||||
for(var/obj/item/stack/ore/O in src)
|
||||
SEND_SIGNAL(W, COMSIG_PARENT_ATTACKBY, O)
|
||||
|
||||
/turf/open/floor/plating/asteroid/singularity_act()
|
||||
if(is_planet_level(z))
|
||||
@@ -61,8 +85,8 @@
|
||||
icon_state = "basalt"
|
||||
icon_plating = "basalt"
|
||||
environment_type = "basalt"
|
||||
archdrops = list(/obj/item/stack/ore/glass/basalt = list(ARCH_PROB = 100,ARCH_MAXDROP = 5))
|
||||
floor_variance = 15
|
||||
digResult = /obj/item/stack/ore/glass/basalt
|
||||
|
||||
/turf/open/floor/plating/asteroid/basalt/lava //lava underneath
|
||||
baseturfs = /turf/open/lava/smooth
|
||||
@@ -73,9 +97,10 @@
|
||||
/turf/open/floor/plating/asteroid/basalt/Initialize()
|
||||
. = ..()
|
||||
set_basalt_light(src)
|
||||
GET_COMPONENT(arch, /datum/component/archaeology)
|
||||
ASSERT(isnull(arch.callback))
|
||||
arch.callback = CALLBACK(src, /atom/proc/set_light, 0)
|
||||
|
||||
/turf/open/floor/plating/asteroid/getDug()
|
||||
set_light(0)
|
||||
return ..()
|
||||
|
||||
/proc/set_basalt_light(turf/open/floor/B)
|
||||
switch(B.icon_state)
|
||||
@@ -276,10 +301,10 @@
|
||||
environment_type = "snow"
|
||||
flags_1 = NONE
|
||||
planetary_atmos = TRUE
|
||||
archdrops = list(/obj/item/stack/sheet/mineral/snow = list(ARCH_PROB = 100, ARCH_MAXDROP = 5))
|
||||
burnt_states = list("snow_dug")
|
||||
bullet_sizzle = TRUE
|
||||
bullet_bounce_sound = null
|
||||
digResult = /obj/item/stack/sheet/mineral/snow
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow/burn_tile()
|
||||
if(!burnt)
|
||||
@@ -312,4 +337,4 @@
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow/atmosphere
|
||||
initial_gas_mix = "o2=22;n2=82;TEMP=180"
|
||||
planetary_atmos = FALSE
|
||||
planetary_atmos = FALSE
|
||||
@@ -1,394 +0,0 @@
|
||||
#define BASIC_BUILDMODE 1
|
||||
#define ADV_BUILDMODE 2
|
||||
#define VAR_BUILDMODE 3
|
||||
#define THROW_BUILDMODE 4
|
||||
#define AREA_BUILDMODE 5
|
||||
#define COPY_BUILDMODE 6
|
||||
#define NUM_BUILDMODES 6
|
||||
|
||||
//Buildmode Shuttle
|
||||
//Builmode Move
|
||||
|
||||
/obj/screen/buildmode
|
||||
icon = 'icons/misc/buildmode.dmi'
|
||||
var/datum/buildmode/bd
|
||||
|
||||
/obj/screen/buildmode/New(bd)
|
||||
..()
|
||||
src.bd = bd
|
||||
|
||||
/obj/screen/buildmode/Destroy()
|
||||
bd.buttons -= src
|
||||
bd = null
|
||||
return ..()
|
||||
|
||||
/obj/screen/buildmode/mode
|
||||
icon_state = "buildmode1"
|
||||
name = "Toggle Mode"
|
||||
screen_loc = "NORTH,WEST"
|
||||
|
||||
/obj/screen/buildmode/mode/Click(location, control, params)
|
||||
var/list/pa = params2list(params)
|
||||
|
||||
if(pa.Find("left"))
|
||||
bd.toggle_modes()
|
||||
else if(pa.Find("right"))
|
||||
bd.change_settings(usr)
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/obj/screen/buildmode/mode/update_icon()
|
||||
icon_state = "buildmode[bd.mode]"
|
||||
return
|
||||
|
||||
/obj/screen/buildmode/help
|
||||
icon_state = "buildhelp"
|
||||
screen_loc = "NORTH,WEST+1"
|
||||
name = "Buildmode Help"
|
||||
|
||||
/obj/screen/buildmode/help/Click()
|
||||
bd.show_help(usr)
|
||||
return 1
|
||||
|
||||
/obj/screen/buildmode/bdir
|
||||
icon_state = "build"
|
||||
screen_loc = "NORTH,WEST+2"
|
||||
name = "Change Dir"
|
||||
|
||||
|
||||
/obj/screen/buildmode/bdir/update_icon()
|
||||
setDir(bd.build_dir)
|
||||
return
|
||||
|
||||
/obj/screen/buildmode/quit
|
||||
icon_state = "buildquit"
|
||||
screen_loc = "NORTH,WEST+3"
|
||||
name = "Quit Buildmode"
|
||||
|
||||
/obj/screen/buildmode/quit/Click()
|
||||
bd.quit()
|
||||
return 1
|
||||
|
||||
/obj/screen/buildmode/bdir/Click()
|
||||
bd.change_dir()
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/datum/buildmode
|
||||
var/mode = BASIC_BUILDMODE
|
||||
var/client/holder = null
|
||||
var/list/obj/screen/buttons = list()
|
||||
var/build_dir = SOUTH
|
||||
var/atom/movable/throw_atom = null
|
||||
var/turf/cornerA = null
|
||||
var/turf/cornerB = null
|
||||
var/generator_path = null
|
||||
var/varholder = "name"
|
||||
var/valueholder = "derp"
|
||||
var/objholder = /obj/structure/closet
|
||||
var/atom/movable/stored = null
|
||||
var/list/preview = list()
|
||||
|
||||
/datum/buildmode/New(client/c)
|
||||
create_buttons()
|
||||
holder = c
|
||||
holder.click_intercept = src
|
||||
holder.show_popup_menus = 0
|
||||
holder.screen += buttons
|
||||
|
||||
/datum/buildmode/proc/quit()
|
||||
holder.screen -= buttons
|
||||
holder.click_intercept = null
|
||||
holder.show_popup_menus = 1
|
||||
usr.client.images -= preview
|
||||
preview.Cut()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/datum/buildmode/Destroy()
|
||||
stored = null
|
||||
QDEL_LIST(buttons)
|
||||
throw_atom = null
|
||||
holder = null
|
||||
preview.Cut()
|
||||
cornerA = null
|
||||
cornerB = null
|
||||
return ..()
|
||||
|
||||
/datum/buildmode/proc/create_buttons()
|
||||
buttons += new /obj/screen/buildmode/mode(src)
|
||||
buttons += new /obj/screen/buildmode/help(src)
|
||||
buttons += new /obj/screen/buildmode/bdir(src)
|
||||
buttons += new /obj/screen/buildmode/quit(src)
|
||||
|
||||
/datum/buildmode/proc/toggle_modes()
|
||||
mode = (mode % NUM_BUILDMODES) +1
|
||||
Reset()
|
||||
return
|
||||
|
||||
/datum/buildmode/proc/show_help(mob/user)
|
||||
var/list/dat = list()
|
||||
switch(mode)
|
||||
if(BASIC_BUILDMODE)
|
||||
dat += "***********************************************************"
|
||||
dat += "Left Mouse Button = Construct / Upgrade"
|
||||
dat += "Right Mouse Button = Deconstruct / Delete / Downgrade"
|
||||
dat += "Left Mouse Button + ctrl = R-Window"
|
||||
dat += "Left Mouse Button + alt = Airlock"
|
||||
dat += ""
|
||||
dat += "Use the button in the upper left corner to"
|
||||
dat += "change the direction of built objects."
|
||||
dat += "***********************************************************"
|
||||
if(ADV_BUILDMODE)
|
||||
dat += "***********************************************************"
|
||||
dat += "Right Mouse Button on buildmode button = Set object type"
|
||||
dat += "Left Mouse Button + alt on turf/obj = Copy object type"
|
||||
dat += "Left Mouse Button on turf/obj = Place objects"
|
||||
dat += "Right Mouse Button = Delete objects"
|
||||
dat += ""
|
||||
dat += "Use the button in the upper left corner to"
|
||||
dat += "change the direction of built objects."
|
||||
dat += "***********************************************************"
|
||||
if(VAR_BUILDMODE)
|
||||
dat += "***********************************************************"
|
||||
dat += "Right Mouse Button on buildmode button = Select var(type) & value"
|
||||
dat += "Left Mouse Button on turf/obj/mob = Set var(type) & value"
|
||||
dat += "Right Mouse Button on turf/obj/mob = Reset var's value"
|
||||
dat += "***********************************************************"
|
||||
if(THROW_BUILDMODE)
|
||||
dat += "***********************************************************"
|
||||
dat += "Left Mouse Button on turf/obj/mob = Select"
|
||||
dat += "Right Mouse Button on turf/obj/mob = Throw"
|
||||
dat += "***********************************************************"
|
||||
if(AREA_BUILDMODE)
|
||||
dat += "***********************************************************"
|
||||
dat += "Left Mouse Button on turf/obj/mob = Select corner"
|
||||
dat += "Right Mouse Button on turf/obj/mob = Reset corner selection"
|
||||
dat += "Right Mouse Button on buildmode button = Select generator"
|
||||
dat += "***********************************************************"
|
||||
if(COPY_BUILDMODE)
|
||||
dat += "***********************************************************"
|
||||
dat += "Left Mouse Button on obj/turf/mob = Spawn a Copy of selected target"
|
||||
dat += "Right Mouse Button on obj/mob = Select target to copy"
|
||||
dat += "***********************************************************"
|
||||
to_chat(user, "<font color='blue'>[dat.Join("\n")]</font>")
|
||||
|
||||
/datum/buildmode/proc/change_settings(mob/user)
|
||||
switch(mode)
|
||||
if(BASIC_BUILDMODE)
|
||||
return 1
|
||||
if(ADV_BUILDMODE)
|
||||
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)
|
||||
objholder = /obj/structure/closet
|
||||
alert("That path is not allowed.")
|
||||
else
|
||||
if(ispath(objholder, /mob) && !check_rights(R_DEBUG,0))
|
||||
objholder = /obj/structure/closet
|
||||
if(VAR_BUILDMODE)
|
||||
var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine")
|
||||
|
||||
varholder = input(user,"Enter variable name:" ,"Name", "name")
|
||||
if(varholder in locked && !check_rights(R_DEBUG,0))
|
||||
return 1
|
||||
var/thetype = input(user,"Select variable type:" ,"Type") in list("text","number","mob-reference","obj-reference","turf-reference")
|
||||
if(!thetype)
|
||||
return 1
|
||||
switch(thetype)
|
||||
if("text")
|
||||
valueholder = input(user,"Enter variable value:" ,"Value", "value") as text
|
||||
if("number")
|
||||
valueholder = input(user,"Enter variable value:" ,"Value", 123) as num
|
||||
if("mob-reference")
|
||||
valueholder = input(user,"Enter variable value:" ,"Value") as mob in GLOB.mob_list
|
||||
if("obj-reference")
|
||||
valueholder = input(user,"Enter variable value:" ,"Value") as obj in world
|
||||
if("turf-reference")
|
||||
valueholder = input(user,"Enter variable value:" ,"Value") as turf in world
|
||||
if(AREA_BUILDMODE)
|
||||
var/list/gen_paths = subtypesof(/datum/mapGenerator)
|
||||
var/list/options = list()
|
||||
for(var/path in gen_paths)
|
||||
var/datum/mapGenerator/MP = path
|
||||
options[initial(MP.buildmode_name)] = path
|
||||
var/type = input(user,"Select Generator Type","Type") as null|anything in options
|
||||
if(!type)
|
||||
return
|
||||
|
||||
generator_path = options[type]
|
||||
cornerA = null
|
||||
cornerB = null
|
||||
|
||||
/datum/buildmode/proc/change_dir()
|
||||
switch(build_dir)
|
||||
if(NORTH)
|
||||
build_dir = EAST
|
||||
if(EAST)
|
||||
build_dir = SOUTH
|
||||
if(SOUTH)
|
||||
build_dir = WEST
|
||||
if(WEST)
|
||||
build_dir = NORTHWEST
|
||||
if(NORTHWEST)
|
||||
build_dir = NORTH
|
||||
return 1
|
||||
|
||||
/datum/buildmode/proc/Reset()//Reset temporary variables
|
||||
cornerA = null
|
||||
cornerB = null
|
||||
|
||||
/proc/togglebuildmode(mob/M in GLOB.player_list)
|
||||
set name = "Toggle Build Mode"
|
||||
set category = "Special Verbs"
|
||||
if(M.client)
|
||||
if(istype(M.client.click_intercept, /datum/buildmode))
|
||||
var/datum/buildmode/B = M.client.click_intercept
|
||||
B.quit()
|
||||
log_admin("[key_name(usr)] has left build mode.")
|
||||
else
|
||||
new/datum/buildmode(M.client)
|
||||
message_admins("[key_name(usr)] has entered build mode.")
|
||||
log_admin("[key_name(usr)] has entered build mode.")
|
||||
|
||||
|
||||
/datum/buildmode/proc/InterceptClickOn(user,params,atom/object) //Click Intercept
|
||||
var/list/pa = params2list(params)
|
||||
var/right_click = pa.Find("right")
|
||||
var/left_click = pa.Find("left")
|
||||
var/alt_click = pa.Find("alt")
|
||||
var/ctrl_click = pa.Find("ctrl")
|
||||
|
||||
//Clicking on UI elements shouldn't try to build things in nullspace.
|
||||
if(istype(object,/obj/screen))
|
||||
return FALSE
|
||||
|
||||
. = TRUE
|
||||
switch(mode)
|
||||
if(BASIC_BUILDMODE)
|
||||
if(isturf(object) && left_click && !alt_click && !ctrl_click)
|
||||
var/turf/T = object
|
||||
if(isspaceturf(object))
|
||||
T.PlaceOnTop(/turf/open/floor/plating)
|
||||
else if(isplatingturf(object))
|
||||
T.PlaceOnTop(/turf/open/floor/plasteel)
|
||||
else if(isfloorturf(object))
|
||||
T.PlaceOnTop(/turf/closed/wall)
|
||||
else if(iswallturf(object))
|
||||
T.PlaceOnTop(/turf/closed/wall/r_wall)
|
||||
log_admin("Build Mode: [key_name(user)] built [T] at [AREACOORD(T)]")
|
||||
return
|
||||
else if(right_click)
|
||||
log_admin("Build Mode: [key_name(user)] deleted [object] at [AREACOORD(object)]")
|
||||
if(isturf(object))
|
||||
var/turf/T = object
|
||||
T.ScrapeAway()
|
||||
else if(isobj(object))
|
||||
qdel(object)
|
||||
return
|
||||
else if(isturf(object) && alt_click && left_click)
|
||||
log_admin("Build Mode: [key_name(user)] built an airlock at [AREACOORD(object)]")
|
||||
new/obj/machinery/door/airlock(get_turf(object))
|
||||
else if(isturf(object) && ctrl_click && left_click)
|
||||
var/obj/structure/window/reinforced/window
|
||||
if(build_dir == NORTHWEST)
|
||||
window = new /obj/structure/window/reinforced/fulltile(get_turf(object))
|
||||
else
|
||||
window = new /obj/structure/window/reinforced(get_turf(object))
|
||||
window.setDir(build_dir)
|
||||
log_admin("Build Mode: [key_name(user)] built a window at [AREACOORD(object)]")
|
||||
if(ADV_BUILDMODE)
|
||||
if(left_click && alt_click)
|
||||
objholder = object.type
|
||||
to_chat(user, "<span class='notice'>[initial(object.name)] ([object.type]) selected.</span>")
|
||||
else if(left_click)
|
||||
if(ispath(objholder, /turf))
|
||||
var/turf/T = get_turf(object)
|
||||
log_admin("Build Mode: [key_name(user)] modified [T] in [AREACOORD(object)] to [objholder]")
|
||||
T.PlaceOnTop(objholder)
|
||||
else
|
||||
var/obj/A = new objholder (get_turf(object))
|
||||
A.setDir(build_dir)
|
||||
log_admin("Build Mode: [key_name(user)] modified [A]'s [COORD(A)] dir to [build_dir]")
|
||||
else if(right_click)
|
||||
if(isobj(object))
|
||||
log_admin("Build Mode: [key_name(user)] deleted [object] at [AREACOORD(object)]")
|
||||
qdel(object)
|
||||
|
||||
if(VAR_BUILDMODE)
|
||||
if(left_click) //I cant believe this shit actually compiles.
|
||||
if(object.vars.Find(varholder))
|
||||
if(object.vv_edit_var(varholder, valueholder))
|
||||
log_admin("Build Mode: [key_name(user)] modified [object.name]'s [varholder] to [valueholder]")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Varedit rejected</span>")
|
||||
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))
|
||||
if(object.vv_edit_var(varholder, initial(object.vars[varholder])))
|
||||
log_admin("Build Mode: [key_name(user)] modified [object.name]'s [varholder] to [valueholder]")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Varedit rejected</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[initial(object.name)] does not have a var called '[varholder]'</span>")
|
||||
|
||||
if(THROW_BUILDMODE)
|
||||
if(left_click)
|
||||
if(isturf(object))
|
||||
return
|
||||
throw_atom = object
|
||||
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] in [AREACOORD(object)]")
|
||||
if(AREA_BUILDMODE)
|
||||
if(left_click) //rectangular
|
||||
if(!cornerA)
|
||||
cornerA = get_turf(object)
|
||||
preview += image('icons/turf/overlays.dmi',cornerA,"greenOverlay")
|
||||
usr.client.images -= preview
|
||||
usr.client.images += preview
|
||||
return
|
||||
if(cornerA && !cornerB)
|
||||
cornerB = get_turf(object)
|
||||
preview += image('icons/turf/overlays.dmi',cornerB,"blueOverlay")
|
||||
usr.client.images -= preview
|
||||
usr.client.images += preview
|
||||
to_chat(user, "<span class='boldwarning'>Region selected, if you're happy with your selection left click again, otherwise right click.</span>")
|
||||
return
|
||||
if(cornerA && cornerB)
|
||||
if(!generator_path)
|
||||
to_chat(user, "<span class='warning'>Select generator type first.</span>")
|
||||
return
|
||||
var/datum/mapGenerator/G = new generator_path
|
||||
if(istype(G, /datum/mapGenerator/repair/reload_station_map))
|
||||
if(GLOB.reloading_map)
|
||||
to_chat(user, "<span class='boldwarning'>You are already reloading an area! Please wait for it to fully finish loading before trying to load another!</span>")
|
||||
return
|
||||
G.defineRegion(cornerA, cornerB, 1)
|
||||
for(var/t in G.map)
|
||||
preview += image('icons/turf/overlays.dmi', t ,"redOverlay")
|
||||
usr.client.images -= preview
|
||||
usr.client.images += preview
|
||||
var/confirm = alert("Are you sure you want run the map generator?", "Run generator", "Yes", "No")
|
||||
if(confirm == "Yes")
|
||||
G.generate()
|
||||
cornerA = null
|
||||
cornerB = null
|
||||
usr.client.images -= preview
|
||||
preview.Cut()
|
||||
return
|
||||
//Something wrong - Reset
|
||||
cornerA = null
|
||||
cornerB = null
|
||||
if(COPY_BUILDMODE)
|
||||
if(left_click)
|
||||
var/turf/T = get_turf(object)
|
||||
if(stored)
|
||||
DuplicateObject(stored,perfectcopy=1,newloc=T)
|
||||
else if(right_click)
|
||||
if(ismovableatom(object)) // No copying turfs for now.
|
||||
stored = object
|
||||
@@ -517,6 +517,25 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: [original_var]=[new_var]")
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s varlist [objectvar]: [original_var]=[new_var]")
|
||||
|
||||
/proc/vv_varname_lockcheck(param_var_name)
|
||||
if(param_var_name in GLOB.VVlocked)
|
||||
if(!check_rights(R_DEBUG))
|
||||
return FALSE
|
||||
if(param_var_name in GLOB.VVckey_edit)
|
||||
if(!check_rights(R_SPAWN|R_DEBUG))
|
||||
return FALSE
|
||||
if(param_var_name in GLOB.VVicon_edit_lock)
|
||||
if(!check_rights(R_FUN|R_DEBUG))
|
||||
return FALSE
|
||||
if(param_var_name in GLOB.VVpixelmovement)
|
||||
if(!check_rights(R_DEBUG))
|
||||
return FALSE
|
||||
var/prompt = alert(usr, "Editing this var may irreparably break tile gliding for the rest of the round. THIS CAN'T BE UNDONE", "DANGER", "ABORT ", "Continue", " ABORT")
|
||||
if (prompt != "Continue")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
/client/proc/modify_variables(atom/O, param_var_name = null, autodetect_class = 0)
|
||||
if(!check_rights(R_VAREDIT))
|
||||
return
|
||||
@@ -546,26 +565,12 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
return
|
||||
|
||||
var_value = O.vars[variable]
|
||||
|
||||
if(variable in GLOB.VVlocked)
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
if(variable in GLOB.VVckey_edit)
|
||||
if(!check_rights(R_SPAWN|R_DEBUG))
|
||||
return
|
||||
if(variable in GLOB.VVicon_edit_lock)
|
||||
if(!check_rights(R_FUN|R_DEBUG))
|
||||
return
|
||||
if(!vv_varname_lockcheck(variable))
|
||||
return
|
||||
if(istype(O, /datum/armor))
|
||||
var/prompt = alert(src, "Editing this var changes this value on potentially thousands of items that share the same combination of armor values. If you want to edit the armor of just one item, use the \"Modify armor values\" dropdown item", "DANGER", "ABORT ", "Continue", " ABORT")
|
||||
if (prompt != "Continue")
|
||||
return
|
||||
if(variable in GLOB.VVpixelmovement)
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
var/prompt = alert(src, "Editing this var may irreparably break tile gliding for the rest of the round. THIS CAN'T BE UNDONE", "DANGER", "ABORT ", "Continue", " ABORT")
|
||||
if (prompt != "Continue")
|
||||
return
|
||||
|
||||
|
||||
var/default = vv_get_class(variable, var_value)
|
||||
@@ -636,4 +641,4 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
var/msg = "[key_name_admin(src)] modified [original_name]'s [variable] from [var_value] to [var_new]"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(O, msg)
|
||||
return TRUE
|
||||
return TRUE
|
||||
@@ -25,6 +25,7 @@
|
||||
healable = FALSE
|
||||
spacewalk = TRUE
|
||||
sight = SEE_SELF
|
||||
throwforce = 0
|
||||
|
||||
see_in_dark = 8
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
|
||||
@@ -257,7 +257,7 @@
|
||||
reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_SUPER * (power_ratio / FUSION_ENERGY_DIVISOR_SUPER)
|
||||
cached_gases[/datum/gas/tritium][MOLES] += gases_fused * FUSION_GAS_CREATION_FACTOR_TRITIUM //60% of the gas is converted to energy, 40% to trit
|
||||
fusion_prepare_to_die_edition_rng = 100 //Wait a minute..
|
||||
do_explosion = TRUE
|
||||
do_explosion = TRUE
|
||||
zap_range = FUSION_ZAP_RANGE_SUPER
|
||||
|
||||
else if (power_ratio > FUSION_HIGH_TIER_THRESHOLD) //power ratio 20-50; High tier. The reaction is so energized that it fuses into a small amount of stimulum, and some pluoxium. Very dangerous, but super cool and super useful.
|
||||
@@ -433,7 +433,7 @@
|
||||
var/new_heat_capacity = air.heat_capacity()
|
||||
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
air.temperature = max(((air.temperature*old_heat_capacity - energy_taken)/new_heat_capacity),TCMB)
|
||||
|
||||
|
||||
|
||||
/datum/gas_reaction/miaster //dry heat sterilization: clears out pathogens in the air
|
||||
priority = -10 //after all the heating from fires etc. is done
|
||||
@@ -449,9 +449,8 @@
|
||||
/datum/gas_reaction/miaster/react(datum/gas_mixture/air, datum/holder)
|
||||
var/list/cached_gases = air.gases
|
||||
// As the name says it, it needs to be dry
|
||||
if(/datum/gas/water_vapor in cached_gases)
|
||||
if(cached_gases[/datum/gas/water_vapor]/air.total_moles() > 0.1)
|
||||
return
|
||||
if(cached_gases[/datum/gas/water_vapor] && cached_gases[/datum/gas/water_vapor][MOLES]/air.total_moles() > 0.1)
|
||||
return
|
||||
|
||||
//Replace miasma with oxygen
|
||||
var/cleaned_air = min(cached_gases[/datum/gas/miasma][MOLES], 20 + (air.temperature - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20)
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
# 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.
|
||||
|
||||
+ *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.
|
||||
|
||||
+ 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.
|
||||
|
||||
+ 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.
|
||||
|
||||
+ 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.
|
||||
@@ -0,0 +1,91 @@
|
||||
/datum/buildmode_mode
|
||||
var/key = "oops"
|
||||
|
||||
var/datum/buildmode/BM
|
||||
|
||||
// would corner selection work better as a component?
|
||||
var/use_corner_selection = FALSE
|
||||
var/list/preview
|
||||
var/turf/cornerA
|
||||
var/turf/cornerB
|
||||
|
||||
/datum/buildmode_mode/New(datum/buildmode/BM)
|
||||
src.BM = BM
|
||||
preview = list()
|
||||
return ..()
|
||||
|
||||
/datum/buildmode_mode/Destroy()
|
||||
cornerA = null
|
||||
cornerB = null
|
||||
QDEL_LIST(preview)
|
||||
preview = null
|
||||
return ..()
|
||||
|
||||
/datum/buildmode_mode/proc/enter_mode(datum/buildmode/BM)
|
||||
return
|
||||
|
||||
/datum/buildmode_mode/proc/exit_mode(datum/buildmode/BM)
|
||||
return
|
||||
|
||||
/datum/buildmode_mode/proc/get_button_iconstate()
|
||||
return "buildmode_[key]"
|
||||
|
||||
/datum/buildmode_mode/proc/show_help(client/c)
|
||||
CRASH("No help defined, yell at a coder")
|
||||
|
||||
/datum/buildmode_mode/proc/change_settings(client/c)
|
||||
to_chat(c, "<span class='warning'>There is no configuration available for this mode</span>")
|
||||
return
|
||||
|
||||
/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"
|
||||
|
||||
var/image/I = image('icons/turf/overlays.dmi', T, overlaystate)
|
||||
I.plane = ABOVE_LIGHTING_PLANE
|
||||
preview += I
|
||||
BM.holder.images += preview
|
||||
return T
|
||||
|
||||
/datum/buildmode_mode/proc/highlight_region(region)
|
||||
BM.holder.images -= preview
|
||||
for(var/t in region)
|
||||
var/image/I = image('icons/turf/overlays.dmi', t, "redOverlay")
|
||||
I.plane = ABOVE_LIGHTING_PLANE
|
||||
preview += I
|
||||
BM.holder.images += preview
|
||||
|
||||
/datum/buildmode_mode/proc/deselect_region()
|
||||
BM.holder.images -= preview
|
||||
preview.Cut()
|
||||
cornerA = null
|
||||
cornerB = null
|
||||
|
||||
/datum/buildmode_mode/proc/handle_click(client/c, 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
|
||||
if(cornerA && !cornerB)
|
||||
cornerB = select_tile(get_turf(object), AREASELECT_CORNERB)
|
||||
to_chat(c, "<span class='boldwarning'>Region selected, if you're happy with your selection left click again, otherwise right click.</span>")
|
||||
return
|
||||
handle_selected_area(c, params)
|
||||
deselect_region()
|
||||
else
|
||||
to_chat(c, "<span class='notice'>Region selection canceled!</span>")
|
||||
deselect_region()
|
||||
return
|
||||
|
||||
/datum/buildmode_mode/proc/handle_selected_area(client/c, params)
|
||||
@@ -0,0 +1,161 @@
|
||||
#define BM_SWITCHSTATE_NONE 0
|
||||
#define BM_SWITCHSTATE_MODE 1
|
||||
#define BM_SWITCHSTATE_DIR 2
|
||||
|
||||
/datum/buildmode
|
||||
var/build_dir = SOUTH
|
||||
var/datum/buildmode_mode/mode
|
||||
var/client/holder
|
||||
|
||||
// login callback
|
||||
var/li_cb
|
||||
|
||||
// SECTION UI
|
||||
var/list/buttons
|
||||
|
||||
// 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/buildmode/New(client/c)
|
||||
mode = new /datum/buildmode_mode/basic(src)
|
||||
holder = c
|
||||
buttons = list()
|
||||
li_cb = CALLBACK(src, .proc/post_login)
|
||||
holder.player_details.post_login_callbacks += li_cb
|
||||
holder.show_popup_menus = FALSE
|
||||
create_buttons()
|
||||
holder.screen += buttons
|
||||
holder.click_intercept = src
|
||||
mode.enter_mode(src)
|
||||
|
||||
/datum/buildmode/proc/quit()
|
||||
mode.exit_mode(src)
|
||||
holder.screen -= buttons
|
||||
holder.click_intercept = null
|
||||
holder.show_popup_menus = TRUE
|
||||
qdel(src)
|
||||
|
||||
/datum/buildmode/Destroy()
|
||||
close_switchstates()
|
||||
holder.player_details.post_login_callbacks -= li_cb
|
||||
holder = null
|
||||
QDEL_NULL(mode)
|
||||
QDEL_LIST(modeswitch_buttons)
|
||||
QDEL_LIST(dirswitch_buttons)
|
||||
return ..()
|
||||
|
||||
/datum/buildmode/proc/post_login()
|
||||
// since these will get wiped upon login
|
||||
holder.screen += buttons
|
||||
// re-open the according switch mode
|
||||
switch(switch_state)
|
||||
if(BM_SWITCHSTATE_MODE)
|
||||
open_modeswitch()
|
||||
if(BM_SWITCHSTATE_DIR)
|
||||
open_dirswitch()
|
||||
|
||||
/datum/buildmode/proc/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 lists of switching 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)
|
||||
|
||||
// this creates a nice offset grid for choosing between buildmode options,
|
||||
// because going "click click click ah hell" sucks.
|
||||
/datum/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/buildmode/proc/close_switchstates()
|
||||
switch(switch_state)
|
||||
if(BM_SWITCHSTATE_MODE)
|
||||
close_modeswitch()
|
||||
if(BM_SWITCHSTATE_DIR)
|
||||
close_dirswitch()
|
||||
|
||||
/datum/buildmode/proc/toggle_modeswitch()
|
||||
if(switch_state == BM_SWITCHSTATE_MODE)
|
||||
close_modeswitch()
|
||||
else
|
||||
close_switchstates()
|
||||
open_modeswitch()
|
||||
|
||||
/datum/buildmode/proc/open_modeswitch()
|
||||
switch_state = BM_SWITCHSTATE_MODE
|
||||
holder.screen += modeswitch_buttons
|
||||
|
||||
/datum/buildmode/proc/close_modeswitch()
|
||||
switch_state = BM_SWITCHSTATE_NONE
|
||||
holder.screen -= modeswitch_buttons
|
||||
|
||||
/datum/buildmode/proc/toggle_dirswitch()
|
||||
if(switch_state == BM_SWITCHSTATE_DIR)
|
||||
close_dirswitch()
|
||||
else
|
||||
close_switchstates()
|
||||
open_dirswitch()
|
||||
|
||||
/datum/buildmode/proc/open_dirswitch()
|
||||
switch_state = BM_SWITCHSTATE_DIR
|
||||
holder.screen += dirswitch_buttons
|
||||
|
||||
/datum/buildmode/proc/close_dirswitch()
|
||||
switch_state = BM_SWITCHSTATE_NONE
|
||||
holder.screen -= dirswitch_buttons
|
||||
|
||||
/datum/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/buildmode/proc/change_dir(newdir)
|
||||
build_dir = newdir
|
||||
close_dirswitch()
|
||||
dirbutton.update_icon()
|
||||
return 1
|
||||
|
||||
/datum/buildmode/proc/InterceptClickOn(mob/user, params, atom/object)
|
||||
mode.handle_click(user.client, params, object)
|
||||
return TRUE // no doing underlying actions
|
||||
|
||||
/proc/togglebuildmode(mob/M as mob in GLOB.player_list)
|
||||
set name = "Toggle Build Mode"
|
||||
set category = "Event"
|
||||
|
||||
if(M.client)
|
||||
if(istype(M.client.click_intercept,/datum/buildmode))
|
||||
var/datum/buildmode/B = M.client.click_intercept
|
||||
B.quit()
|
||||
log_admin("[key_name(usr)] has left build mode.")
|
||||
else
|
||||
new /datum/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
|
||||
@@ -0,0 +1,90 @@
|
||||
/obj/screen/buildmode
|
||||
icon = 'icons/misc/buildmode.dmi'
|
||||
var/datum/buildmode/bd
|
||||
// If we don't do this, we get occluded by item action buttons
|
||||
layer = ABOVE_HUD_LAYER
|
||||
|
||||
/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.client)
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/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(location, control, params)
|
||||
bd.mode.show_help(usr.client)
|
||||
return 1
|
||||
|
||||
/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
|
||||
return
|
||||
|
||||
/obj/screen/buildmode/bdir/Click()
|
||||
bd.toggle_dirswitch()
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
// 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 1
|
||||
|
||||
// used to switch between dirs
|
||||
/obj/screen/buildmode/dirswitch
|
||||
icon_state = "build"
|
||||
|
||||
/obj/screen/buildmode/dirswitch/New(bld, dir)
|
||||
src.dir = dir
|
||||
name = dir2text(dir)
|
||||
return ..(bld)
|
||||
|
||||
/obj/screen/buildmode/dirswitch/Click()
|
||||
bd.change_dir(dir)
|
||||
return 1
|
||||
|
||||
/obj/screen/buildmode/quit
|
||||
icon_state = "buildquit"
|
||||
screen_loc = "NORTH,WEST+3"
|
||||
name = "Quit Buildmode"
|
||||
|
||||
/obj/screen/buildmode/quit/Click()
|
||||
bd.quit()
|
||||
return 1
|
||||
@@ -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,50 @@
|
||||
/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(client/c)
|
||||
to_chat(c, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(c, "<span class='notice'>Right Mouse Button on buildmode button = Set object type</span>")
|
||||
to_chat(c, "<span class='notice'>Left Mouse Button on turf/obj = Place objects</span>")
|
||||
to_chat(c, "<span class='notice'>Right Mouse Button = Delete objects</span>")
|
||||
to_chat(c, "")
|
||||
to_chat(c, "<span class='notice'>Use the button in the upper left corner to</span>")
|
||||
to_chat(c, "<span class='notice'>change the direction of built objects.</span>")
|
||||
to_chat(c, "<span class='notice'>***********************************************************</span>")
|
||||
|
||||
/datum/buildmode_mode/advanced/change_settings(client/c)
|
||||
var/target_path = input(c, "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(client/c, params, obj/object)
|
||||
var/list/pa = params2list(params)
|
||||
var/left_click = pa.Find("left")
|
||||
var/right_click = pa.Find("right")
|
||||
if(left_click)
|
||||
if(ispath(objholder,/turf))
|
||||
var/turf/T = get_turf(object)
|
||||
log_admin("Build Mode: [key_name(c)] modified [T] in [AREACOORD(object)] 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(c)] modified [A]'s [COORD(A)] dir to [BM.build_dir]")
|
||||
else
|
||||
to_chat(c, "<span class='warning'>Select object type first.</span>")
|
||||
else if(right_click)
|
||||
if(isobj(object))
|
||||
log_admin("Build Mode: [key_name(c)] deleted [object] at [AREACOORD(object)]")
|
||||
qdel(object)
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/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/buildmode/BM)
|
||||
BM.holder.images += areaimage
|
||||
|
||||
/datum/buildmode_mode/area_edit/exit_mode(datum/buildmode/BM)
|
||||
areaimage.loc = null // de-color the area
|
||||
BM.holder.images -= areaimage
|
||||
return ..()
|
||||
|
||||
/datum/buildmode_mode/area_edit/Destroy()
|
||||
QDEL_NULL(areaimage)
|
||||
storedarea = null
|
||||
return ..()
|
||||
|
||||
/datum/buildmode_mode/area_edit/show_help(client/c)
|
||||
to_chat(c, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(c, "<span class='notice'>Left Mouse Button on obj/turf/mob = Paint area</span>")
|
||||
to_chat(c, "<span class='notice'>Right Mouse Button on obj/turf/mob = Select area to paint</span>")
|
||||
to_chat(c, "<span class='notice'>Right Mouse Button on buildmode button = Create new area</span>")
|
||||
to_chat(c, "<span class='notice'>***********************************************************</span>")
|
||||
|
||||
/datum/buildmode_mode/area_edit/change_settings(client/c)
|
||||
var/target_path = input(c, "Enter typepath:", "Typepath", "/area")
|
||||
var/areatype = text2path(target_path)
|
||||
if(ispath(areatype,/area))
|
||||
var/areaname = input(c, "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(client/c, 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(c, "<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)
|
||||
log_admin("Build Mode: [key_name(c)] added [AREACOORD(T)] to [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
|
||||
@@ -0,0 +1,52 @@
|
||||
/datum/buildmode_mode/basic
|
||||
key = "basic"
|
||||
|
||||
/datum/buildmode_mode/basic/show_help(client/c)
|
||||
to_chat(c, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(c, "<span class='notice'>Left Mouse Button = Construct / Upgrade</span>")
|
||||
to_chat(c, "<span class='notice'>Right Mouse Button = Deconstruct / Delete / Downgrade</span>")
|
||||
to_chat(c, "<span class='notice'>Left Mouse Button + ctrl = R-Window</span>")
|
||||
to_chat(c, "<span class='notice'>Left Mouse Button + alt = Airlock</span>")
|
||||
to_chat(c, "")
|
||||
to_chat(c, "<span class='notice'>Use the button in the upper left corner to</span>")
|
||||
to_chat(c, "<span class='notice'>change the direction of built objects.</span>")
|
||||
to_chat(c, "<span class='notice'>***********************************************************</span>")
|
||||
|
||||
/datum/buildmode_mode/basic/handle_click(client/c, 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(isspaceturf(object))
|
||||
T.PlaceOnTop(/turf/open/floor/plating)
|
||||
else if(isplatingturf(object))
|
||||
T.PlaceOnTop(/turf/open/floor/plasteel)
|
||||
else if(isfloorturf(object))
|
||||
T.PlaceOnTop(/turf/closed/wall)
|
||||
else if(iswallturf(object))
|
||||
T.PlaceOnTop(/turf/closed/wall/r_wall)
|
||||
log_admin("Build Mode: [key_name(c)] built [T] at [AREACOORD(T)]")
|
||||
return
|
||||
else if(right_click)
|
||||
log_admin("Build Mode: [key_name(c)] deleted [object] at [AREACOORD(object)]")
|
||||
if(isturf(object))
|
||||
var/turf/T = object
|
||||
T.ScrapeAway()
|
||||
else if(isobj(object))
|
||||
qdel(object)
|
||||
return
|
||||
else if(istype(object,/turf) && alt_click && left_click)
|
||||
log_admin("Build Mode: [key_name(c)] built an airlock at [AREACOORD(object)]")
|
||||
new/obj/machinery/door/airlock(get_turf(object))
|
||||
else if(istype(object,/turf) && ctrl_click && left_click)
|
||||
var/obj/structure/window/reinforced/window
|
||||
if(BM.build_dir == NORTHWEST)
|
||||
window = new /obj/structure/window/reinforced/fulltile(get_turf(object))
|
||||
else
|
||||
window = new /obj/structure/window/reinforced(get_turf(object))
|
||||
window.setDir(BM.build_dir)
|
||||
log_admin("Build Mode: [key_name(c)] built a window at [AREACOORD(object)]")
|
||||
@@ -0,0 +1,38 @@
|
||||
/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(client/c)
|
||||
to_chat(c, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(c, "<span class='notice'>Mouse Button on obj = Kaboom</span>")
|
||||
to_chat(c, "<span class='notice'>***********************************************************</span>")
|
||||
|
||||
/datum/buildmode_mode/boom/change_settings(client/c)
|
||||
devastation = input(c, "Range of total devastation. -1 to none", text("Input")) as num|null
|
||||
if(devastation == null)
|
||||
devastation = -1
|
||||
heavy = input(c, "Range of heavy impact. -1 to none", text("Input")) as num|null
|
||||
if(heavy == null)
|
||||
heavy = -1
|
||||
light = input(c, "Range of light impact. -1 to none", text("Input")) as num|null
|
||||
if(light == null)
|
||||
light = -1
|
||||
flash = input(c, "Range of flash. -1 to none", text("Input")) as num|null
|
||||
if(flash == null)
|
||||
flash = -1
|
||||
flames = input(c, "Range of flames. -1 to none", text("Input")) as num|null
|
||||
if(flames == null)
|
||||
flames = -1
|
||||
|
||||
/datum/buildmode_mode/boom/handle_click(client/c, params, obj/object)
|
||||
var/list/pa = params2list(params)
|
||||
var/left_click = pa.Find("left")
|
||||
|
||||
if(left_click)
|
||||
explosion(object, devastation, heavy, light, flash, FALSE, TRUE, flames)
|
||||
log_admin("Build Mode: [key_name(c)] caused an explosion(dev=[devastation], hvy=[heavy], lgt=[light], flash=[flash], flames=[flames]) at [AREACOORD(object)]")
|
||||
@@ -0,0 +1,28 @@
|
||||
/datum/buildmode_mode/copy
|
||||
key = "copy"
|
||||
var/atom/movable/stored = null
|
||||
|
||||
/datum/buildmode_mode/copy/Destroy()
|
||||
stored = null
|
||||
return ..()
|
||||
|
||||
/datum/buildmode_mode/copy/show_help(client/c)
|
||||
to_chat(c, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(c, "<span class='notice'>Left Mouse Button on obj/turf/mob = Spawn a Copy of selected target</span>")
|
||||
to_chat(c, "<span class='notice'>Right Mouse Button on obj/mob = Select target to copy</span>")
|
||||
to_chat(c, "<span class='notice'>***********************************************************</span>")
|
||||
|
||||
/datum/buildmode_mode/copy/handle_click(client/c, 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)
|
||||
log_admin("Build Mode: [key_name(c)] copied [stored] to [AREACOORD(object)]")
|
||||
else if(right_click)
|
||||
if(ismovableatom(object)) // No copying turfs for now.
|
||||
to_chat(c, "<span class='notice'>[object] set as template.</span>")
|
||||
stored = object
|
||||
@@ -0,0 +1,62 @@
|
||||
/datum/buildmode_mode/fill
|
||||
key = "fill"
|
||||
|
||||
use_corner_selection = TRUE
|
||||
var/objholder = null
|
||||
|
||||
/datum/buildmode_mode/fill/show_help(client/c)
|
||||
to_chat(c, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(c, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select corner</span>")
|
||||
to_chat(c, "<span class='notice'>Left Mouse Button + Alt on turf/obj/mob = Delete region</span>")
|
||||
to_chat(c, "<span class='notice'>Right Mouse Button on buildmode button = Select object type</span>")
|
||||
to_chat(c, "<span class='notice'>***********************************************************</span>")
|
||||
|
||||
/datum/buildmode_mode/fill/change_settings(client/c)
|
||||
var/target_path = input(c, "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(client/c, params, obj/object)
|
||||
if(isnull(objholder))
|
||||
to_chat(c, "<span class='warning'>Select an object type first.</span>")
|
||||
deselect_region()
|
||||
return
|
||||
..()
|
||||
|
||||
/datum/buildmode_mode/fill/handle_selected_area(client/c, 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)
|
||||
var/list/deletion_area = block(get_turf(cornerA),get_turf(cornerB))
|
||||
for(var/beep in deletion_area)
|
||||
var/turf/T = beep
|
||||
for(var/atom/movable/AM in T)
|
||||
qdel(AM)
|
||||
// extreme haircut
|
||||
T.ScrapeAway(INFINITY, CHANGETURF_DEFER_CHANGE)
|
||||
for(var/beep in deletion_area)
|
||||
var/turf/T = beep
|
||||
T.AfterChange()
|
||||
log_admin("Build Mode: [key_name(c)] deleted turfs from [AREACOORD(cornerA)] through [AREACOORD(cornerB)]")
|
||||
// if there's an analogous proc for this on tg lmk
|
||||
// empty_region(block(get_turf(cornerA),get_turf(cornerB)))
|
||||
else
|
||||
for(var/turf/T in block(get_turf(cornerA),get_turf(cornerB)))
|
||||
if(ispath(objholder,/turf))
|
||||
T.PlaceOnTop(objholder)
|
||||
else
|
||||
var/obj/A = new objholder(T)
|
||||
A.setDir(BM.build_dir)
|
||||
log_admin("Build Mode: [key_name(c)] with path [objholder], filled the region from [AREACOORD(cornerA)] through [AREACOORD(cornerB)]")
|
||||
@@ -0,0 +1,48 @@
|
||||
/datum/buildmode_mode/mapgen
|
||||
key = "mapgen"
|
||||
|
||||
use_corner_selection = TRUE
|
||||
var/generator_path
|
||||
|
||||
/datum/buildmode_mode/mapgen/show_help(client/c)
|
||||
to_chat(c, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(c, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select corner</span>")
|
||||
to_chat(c, "<span class='notice'>Right Mouse Button on buildmode button = Select generator</span>")
|
||||
to_chat(c, "<span class='notice'>***********************************************************</span>")
|
||||
|
||||
/datum/buildmode_mode/mapgen/change_settings(client/c)
|
||||
var/list/gen_paths = subtypesof(/datum/mapGenerator)
|
||||
var/list/options = list()
|
||||
for(var/path in gen_paths)
|
||||
var/datum/mapGenerator/MP = path
|
||||
options[initial(MP.buildmode_name)] = path
|
||||
var/type = input(c,"Select Generator Type","Type") as null|anything in options
|
||||
if(!type)
|
||||
return
|
||||
|
||||
generator_path = options[type]
|
||||
deselect_region()
|
||||
|
||||
/datum/buildmode_mode/mapgen/handle_click(client/c, params, obj/object)
|
||||
if(isnull(generator_path))
|
||||
to_chat(c, "<span class='warning'>Select generator type first.</span>")
|
||||
deselect_region()
|
||||
return
|
||||
..()
|
||||
|
||||
/datum/buildmode_mode/mapgen/handle_selected_area(client/c, params)
|
||||
var/list/pa = params2list(params)
|
||||
var/left_click = pa.Find("left")
|
||||
if(left_click)
|
||||
var/datum/mapGenerator/G = new generator_path
|
||||
if(istype(G, /datum/mapGenerator/repair/reload_station_map))
|
||||
if(GLOB.reloading_map)
|
||||
to_chat(c, "<span class='boldwarning'>You are already reloading an area! Please wait for it to fully finish loading before trying to load another!</span>")
|
||||
deselect_region()
|
||||
return
|
||||
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()
|
||||
log_admin("Build Mode: [key_name(c)] ran the map generator '[G.buildmode_name]' in the region from [AREACOORD(cornerA)] to [AREACOORD(cornerB)]")
|
||||
@@ -0,0 +1,29 @@
|
||||
/datum/buildmode_mode/throwing
|
||||
key = "throw"
|
||||
|
||||
var/atom/movable/throw_atom = null
|
||||
|
||||
/datum/buildmode_mode/throwing/Destroy()
|
||||
throw_atom = null
|
||||
return ..()
|
||||
|
||||
/datum/buildmode_mode/throwing/show_help(client/c)
|
||||
to_chat(c, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(c, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select</span>")
|
||||
to_chat(c, "<span class='notice'>Right Mouse Button on turf/obj/mob = Throw</span>")
|
||||
to_chat(c, "<span class='notice'>***********************************************************</span>")
|
||||
|
||||
/datum/buildmode_mode/throwing/handle_click(client/c, 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(c, "Selected object '[throw_atom]'")
|
||||
if(right_click)
|
||||
if(throw_atom)
|
||||
throw_atom.throw_at(object, 10, 1, c.mob)
|
||||
log_admin("Build Mode: [key_name(c)] threw [throw_atom] at [object] ([AREACOORD(object)])")
|
||||
@@ -0,0 +1,62 @@
|
||||
/datum/buildmode_mode/varedit
|
||||
key = "edit"
|
||||
// Varedit mode
|
||||
var/varholder = null
|
||||
var/valueholder = null
|
||||
|
||||
/datum/buildmode_mode/varedit/Destroy()
|
||||
varholder = null
|
||||
valueholder = null
|
||||
return ..()
|
||||
|
||||
/datum/buildmode_mode/varedit/show_help(client/c)
|
||||
to_chat(c, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(c, "<span class='notice'>Right Mouse Button on buildmode button = Select var(type) & value</span>")
|
||||
to_chat(c, "<span class='notice'>Left Mouse Button on turf/obj/mob = Set var(type) & value</span>")
|
||||
to_chat(c, "<span class='notice'>Right Mouse Button on turf/obj/mob = Reset var's value</span>")
|
||||
to_chat(c, "<span class='notice'>***********************************************************</span>")
|
||||
|
||||
/datum/buildmode_mode/varedit/Reset()
|
||||
. = ..()
|
||||
varholder = null
|
||||
valueholder = null
|
||||
|
||||
/datum/buildmode_mode/varedit/change_settings(client/c)
|
||||
varholder = input(c, "Enter variable name:" ,"Name", "name")
|
||||
|
||||
if(!vv_varname_lockcheck(varholder))
|
||||
return
|
||||
|
||||
var/temp_value = c.vv_get_value()
|
||||
if(isnull(temp_value["class"]))
|
||||
Reset()
|
||||
to_chat(c, "<span class='notice'>Variable unset.</span>")
|
||||
return
|
||||
valueholder = temp_value["value"]
|
||||
|
||||
/datum/buildmode_mode/varedit/handle_click(client/c, 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(c, "<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) == FALSE)
|
||||
to_chat(c, "<span class='warning'>Your edit was rejected by the object.</span>")
|
||||
return
|
||||
log_admin("Build Mode: [key_name(c)] modified [object.name]'s [varholder] to [valueholder]")
|
||||
else
|
||||
to_chat(c, "<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) == FALSE)
|
||||
to_chat(c, "<span class='warning'>Your edit was rejected by the object.</span>")
|
||||
return
|
||||
log_admin("Build Mode: [key_name(c)] modified [object.name]'s [varholder] to [reset_value]")
|
||||
else
|
||||
to_chat(c, "<span class='warning'>[initial(object.name)] does not have a var called '[varholder]'</span>")
|
||||
|
||||
@@ -28,7 +28,11 @@
|
||||
/datum/bounty/item/ship(obj/O)
|
||||
if(!applies_to(O))
|
||||
return
|
||||
shipped_count += 1
|
||||
if(istype(O,/obj/item/stack))
|
||||
var/obj/item/stack/O_is_a_stack = O
|
||||
shipped_count += O_is_a_stack.amount
|
||||
else
|
||||
shipped_count += 1
|
||||
|
||||
/datum/bounty/item/compatible_with(datum/other_bounty)
|
||||
return type != other_bounty.type
|
||||
|
||||
@@ -158,6 +158,18 @@
|
||||
crate_value -= I.cost
|
||||
new I.item(C)
|
||||
|
||||
/datum/supply_pack/emergency/plasma_spacesuit
|
||||
name = "Plasmaman Space Envirosuits"
|
||||
desc = "Contains two space-worthy envirosuits for Plasmamen. Order now and we'll throw in two free helmets! Requires EVA access to open."
|
||||
cost = 4000
|
||||
access = ACCESS_EVA
|
||||
contains = list(/obj/item/clothing/suit/space/eva/plasmaman,
|
||||
/obj/item/clothing/suit/space/eva/plasmaman,
|
||||
/obj/item/clothing/head/helmet/space/plasmaman,
|
||||
/obj/item/clothing/head/helmet/space/plasmaman)
|
||||
crate_name = "plasmaman EVA crate"
|
||||
crate_type = /obj/structure/closet/crate/secure
|
||||
|
||||
/datum/supply_pack/emergency/plasmaman
|
||||
name = "Plasmaman Supply Kit"
|
||||
desc = "Keep those Plasmamen alive with two sets of Plasmaman outfits. Each set contains a plasmaman jumpsuit, internals tank, and helmet."
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/datum/player_details
|
||||
var/list/player_actions = list()
|
||||
var/list/logging = list()
|
||||
var/list/post_login_callbacks = list()
|
||||
var/list/post_logout_callbacks = list()
|
||||
var/byond_version = "Unknown"
|
||||
@@ -142,6 +142,7 @@
|
||||
hud_used.throw_icon.icon_state = "act_throw_on"
|
||||
|
||||
/mob/proc/throw_item(atom/target)
|
||||
SEND_SIGNAL(src, COMSIG_MOB_THROW, target)
|
||||
return
|
||||
|
||||
/mob/living/carbon/throw_item(atom/target)
|
||||
|
||||
@@ -1470,6 +1470,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
log_combat(M, H, "attempted to touch")
|
||||
H.visible_message("<span class='warning'>[M] attempted to touch [H]!</span>")
|
||||
return 0
|
||||
SEND_SIGNAL(M, COMSIG_MOB_ATTACK_HAND, M, H, attacker_style)
|
||||
switch(M.a_intent)
|
||||
if("help")
|
||||
help(M, H, attacker_style)
|
||||
|
||||
@@ -41,12 +41,14 @@
|
||||
update_client_colour()
|
||||
update_mouse_pointer()
|
||||
if(client)
|
||||
client.click_intercept = null
|
||||
|
||||
client.change_view(CONFIG_GET(string/default_view)) // Resets the client.view in case it was changed.
|
||||
|
||||
if(client.player_details.player_actions.len)
|
||||
for(var/datum/action/A in client.player_details.player_actions)
|
||||
A.Grant(src)
|
||||
|
||||
for(var/foo in client.player_details.post_login_callbacks)
|
||||
var/datum/callback/CB = foo
|
||||
CB.Invoke()
|
||||
|
||||
log_message("Client [key_name(src)] has taken ownership of mob [src]([src.type])", LOG_OWNERSHIP)
|
||||
|
||||
@@ -9,4 +9,9 @@
|
||||
if(loc)
|
||||
loc.on_log(FALSE)
|
||||
|
||||
if(client)
|
||||
for(var/foo in client.player_details.post_logout_callbacks)
|
||||
var/datum/callback/CB = foo
|
||||
CB.Invoke()
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -604,7 +604,7 @@
|
||||
else
|
||||
prot = 1
|
||||
|
||||
if(prot > 0)
|
||||
if(prot > 0 || user.has_trait(TRAIT_RESISTHEAT) || user.has_trait(TRAIT_RESISTHEATHANDS))
|
||||
to_chat(user, "<span class='notice'>You remove the light [fitting].</span>")
|
||||
else if(istype(user) && user.dna.check_mutation(TK))
|
||||
to_chat(user, "<span class='notice'>You telekinetically remove the light [fitting].</span>")
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
host_mob.SetStun(0)
|
||||
host_mob.SetKnockdown(0)
|
||||
host_mob.SetUnconscious(0)
|
||||
host_mob.adjustStaminaLoss(-75)
|
||||
host_mob.adjustStaminaLoss(-10) //stimulants give stamina heal now
|
||||
host_mob.lying = 0
|
||||
host_mob.update_canmove()
|
||||
host_mob.reagents.add_reagent("stimulants", 1.5)
|
||||
|
||||
@@ -1,18 +1,34 @@
|
||||
/obj/vehicle/sealed/car
|
||||
layer = ABOVE_MOB_LAYER
|
||||
anchored = TRUE
|
||||
default_driver_move = FALSE
|
||||
var/car_traits = NONE //Bitflag for special behavior such as kidnapping
|
||||
var/engine_sound = 'sound/vehicles/carrev.ogg'
|
||||
var/last_enginesound_time
|
||||
var/engine_sound_length = 20 //Set this to the length of the engine sound
|
||||
var/escape_time = 200 //Time it takes to break out of the car
|
||||
|
||||
/obj/vehicle/sealed/car/Initialize()
|
||||
. = ..()
|
||||
LoadComponent(/datum/component/riding)
|
||||
|
||||
/obj/vehicle/sealed/car/generate_actions()
|
||||
. = ..()
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/remove_key, VEHICLE_CONTROL_DRIVE)
|
||||
if(car_traits & CAN_KIDNAP)
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/DumpKidnappedMobs, VEHICLE_CONTROL_DRIVE)
|
||||
|
||||
/obj/vehicle/sealed/car/driver_move(mob/user, direction)
|
||||
if(key_type && !is_key(inserted_key))
|
||||
to_chat(user, "<span class='warning'>[src] has no key inserted!</span>")
|
||||
return FALSE
|
||||
var/datum/component/riding/R = GetComponent(/datum/component/riding)
|
||||
R.handle_ride(user, direction)
|
||||
if(world.time < last_enginesound_time + engine_sound_length)
|
||||
return
|
||||
last_enginesound_time = world.time
|
||||
playsound(src, engine_sound, 100, TRUE)
|
||||
|
||||
/obj/vehicle/sealed/car/MouseDrop_T(atom/dropping, mob/M)
|
||||
if(!M.canmove || M.stat || M.restrained())
|
||||
return FALSE
|
||||
@@ -33,12 +49,6 @@
|
||||
mob_exit(M, silent)
|
||||
return TRUE
|
||||
|
||||
/obj/vehicle/sealed/car/after_move(direction)
|
||||
if(world.time < last_enginesound_time + engine_sound_length)
|
||||
return
|
||||
last_enginesound_time = world.time
|
||||
playsound(src, engine_sound, 100, TRUE)
|
||||
|
||||
/obj/vehicle/sealed/car/attacked_by(obj/item/I, mob/living/user)
|
||||
if(!I.force)
|
||||
return
|
||||
@@ -52,7 +62,7 @@
|
||||
if(!(car_traits & CAN_KIDNAP))
|
||||
return
|
||||
if(occupants[user])
|
||||
return
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start opening [src]'s trunk.</span>")
|
||||
if(do_after(user, 30))
|
||||
if(return_amount_of_controllers_with_flag(VEHICLE_CONTROL_KIDNAPPED))
|
||||
@@ -75,4 +85,4 @@
|
||||
if(!silent)
|
||||
M.visible_message("<span class='warning'>[M] is forced into \the [src]!</span>")
|
||||
M.forceMove(src)
|
||||
add_occupant(M, VEHICLE_CONTROL_KIDNAPPED)
|
||||
add_occupant(M, VEHICLE_CONTROL_KIDNAPPED)
|
||||
@@ -127,4 +127,4 @@
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/proc/StopDroppingOil()
|
||||
droppingoil = FALSE
|
||||
droppingoil = FALSE
|
||||
Reference in New Issue
Block a user