Merge remote-tracking branch 'upstream/master' into admin_mapsave

This commit is contained in:
Artur
2021-11-20 00:16:56 +02:00
129 changed files with 1185 additions and 1259 deletions
+15 -15
View File
@@ -319,38 +319,38 @@ GLOBAL_LIST_EMPTY(teleportlocs)
*
* Sends to all ai players, alert consoles, drones and alarm monitor programs in the world
*/
/area/proc/poweralert(state, obj/source)
/area/proc/poweralert(set_alarm, obj/source)
if (area_flags & NO_ALERTS)
return
if (state != poweralm)
poweralm = state
if (set_alarm != poweralm)
poweralm = set_alarm
if(istype(source)) //Only report power alarms on the z-level where the source is located.
for (var/item in GLOB.silicon_mobs)
var/mob/living/silicon/aiPlayer = item
if (state == 1)
aiPlayer.cancelAlarm("Power", src, source)
else
if (set_alarm)
aiPlayer.triggerAlarm("Power", src, cameras, source)
else
aiPlayer.cancelAlarm("Power", src, source)
for (var/item in GLOB.alert_consoles)
var/obj/machinery/computer/station_alert/a = item
if(state == 1)
a.cancelAlarm("Power", src, source)
else
if (set_alarm)
a.triggerAlarm("Power", src, cameras, source)
else
a.cancelAlarm("Power", src, source)
for (var/item in GLOB.drones_list)
var/mob/living/simple_animal/drone/D = item
if(state == 1)
D.cancelAlarm("Power", src, source)
else
if (set_alarm)
D.triggerAlarm("Power", src, cameras, source)
else
D.cancelAlarm("Power", src, source)
for(var/item in GLOB.alarmdisplay)
var/datum/computer_file/program/alarm_monitor/p = item
if(state == 1)
p.cancelAlarm("Power", src, source)
else
if (set_alarm)
p.triggerAlarm("Power", src, cameras, source)
else
p.cancelAlarm("Power", src, source)
/area/proc/atmosalert(danger_level, obj/source)
if (area_flags & NO_ALERTS)
+47 -15
View File
@@ -1,13 +1,16 @@
#define RULESET_STOP_PROCESSING 1
#define FAKE_REPORT_CHANCE 8
#define FAKE_REPORT_CHANCE 20
#define REPORT_NEG_DIVERGENCE -15
#define REPORT_POS_DIVERGENCE 15
#define EXTENDED_CURVE_CENTER -7
// Are HIGH_IMPACT_RULESETs allowed to stack?
GLOBAL_VAR_INIT(dynamic_no_stacking, TRUE)
// If enabled does not accept or execute any rulesets.
GLOBAL_VAR_INIT(dynamic_forced_extended, FALSE)
// Antags still allowed, but no roundstart antags + midrounds are low impact
GLOBAL_VAR_INIT(dynamic_extended, FALSE)
// How high threat is required for HIGH_IMPACT_RULESETs stacking.
// This is independent of dynamic_no_stacking.
GLOBAL_VAR_INIT(dynamic_stacking_limit, 90)
@@ -163,6 +166,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
dat += "Split parameters: centre = [roundstart_split_curve_centre] ; width = [roundstart_split_curve_width].<br/>"
dat += "<i>On average, <b>[peaceful_percentage]</b>% of the rounds are more peaceful.</i><br/>"
dat += "Forced extended: <a href='?src=\ref[src];[HrefToken()];forced_extended=1'><b>[GLOB.dynamic_forced_extended ? "On" : "Off"]</b></a><br/>"
dat += "Dynamic extended: <a href='?src=\ref[src];[HrefToken()];extended=1'><b>[GLOB.dynamic_extended ? "On" : "Off"]</b></a><br/>"
dat += "No stacking (only one round-ender): <a href='?src=\ref[src];[HrefToken()];no_stacking=1'><b>[GLOB.dynamic_no_stacking ? "On" : "Off"]</b></a><br/>"
dat += "Stacking limit: [GLOB.dynamic_stacking_limit] <a href='?src=\ref[src];[HrefToken()];stacking_limit=1'>\[Adjust\]</A>"
dat += "<br/>"
@@ -192,6 +196,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
return
if (href_list["forced_extended"])
GLOB.dynamic_forced_extended = !GLOB.dynamic_forced_extended
else if (href_list["extended"])
GLOB.dynamic_extended = !GLOB.dynamic_extended
else if (href_list["no_stacking"])
GLOB.dynamic_no_stacking = !GLOB.dynamic_no_stacking
else if (href_list["adjustthreat"])
@@ -309,9 +315,10 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
/// Generates the threat level using lorentz distribution and assigns peaceful_percentage.
/datum/game_mode/dynamic/proc/generate_threat()
if(GLOB.dynamic_extended)
threat_curve_centre = EXTENDED_CURVE_CENTER
var/relative_threat = LORENTZ_DISTRIBUTION(threat_curve_centre, threat_curve_width)
threat_level = round(lorentz_to_amount(relative_threat), 0.1)
peaceful_percentage = round(LORENTZ_CUMULATIVE_DISTRIBUTION(relative_threat, threat_curve_centre, threat_curve_width), 0.01)*100
SSblackbox.record_feedback("tally","dynamic_threat",threat_level,"Initial threat level")
@@ -321,14 +328,18 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
/// Generates the midround and roundstart budgets
/datum/game_mode/dynamic/proc/generate_budgets()
var/relative_round_start_budget_scale = LORENTZ_DISTRIBUTION(roundstart_split_curve_centre, roundstart_split_curve_width)
round_start_budget = round((lorentz_to_amount(relative_round_start_budget_scale) / 100) * threat_level, 0.1)
initial_round_start_budget = round_start_budget
mid_round_budget = threat_level - round_start_budget
if(GLOB.dynamic_extended)
mid_round_budget = threat_level
round_start_budget = 0
else
var/relative_round_start_budget_scale = LORENTZ_DISTRIBUTION(roundstart_split_curve_centre, roundstart_split_curve_width)
round_start_budget = round((lorentz_to_amount(relative_round_start_budget_scale) / 100) * threat_level, 0.1)
initial_round_start_budget = round_start_budget
mid_round_budget = threat_level - round_start_budget
/datum/game_mode/dynamic/proc/setup_parameters()
log_game("DYNAMIC: Dynamic mode parameters for the round:")
log_game("DYNAMIC: Centre is [threat_curve_centre], Width is [threat_curve_width], Forced extended is [GLOB.dynamic_forced_extended ? "Enabled" : "Disabled"], No stacking is [GLOB.dynamic_no_stacking ? "Enabled" : "Disabled"].")
log_game("DYNAMIC: Centre is [threat_curve_centre], Width is [threat_curve_width], Extended is [GLOB.dynamic_extended ? "Enabled" : "Disabled"], No stacking is [GLOB.dynamic_no_stacking ? "Enabled" : "Disabled"].")
log_game("DYNAMIC: Stacking limit is [GLOB.dynamic_stacking_limit].")
if(GLOB.dynamic_forced_threat_level >= 0)
threat_level = round(GLOB.dynamic_forced_threat_level, 0.1)
@@ -346,9 +357,15 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
shown_threat = clamp(threat_level + rand(REPORT_NEG_DIVERGENCE, REPORT_POS_DIVERGENCE), 0, 100)
/datum/game_mode/dynamic/proc/set_cooldowns()
var/coeff = GLOB.dynamic_extended ? 2 : 1
latejoin_delay_min *= coeff
latejoin_delay_max *= coeff
var/latejoin_injection_cooldown_middle = 0.5*(latejoin_delay_max + latejoin_delay_min)
latejoin_injection_cooldown = round(clamp(EXP_DISTRIBUTION(latejoin_injection_cooldown_middle), latejoin_delay_min, latejoin_delay_max)) + world.time
midround_delay_min *= coeff
midround_delay_max *= coeff
var/midround_injection_cooldown_middle = 0.5*(midround_delay_max + midround_delay_min)
midround_injection_cooldown = round(clamp(EXP_DISTRIBUTION(midround_injection_cooldown_middle), midround_delay_min, midround_delay_max)) + world.time
@@ -456,6 +473,9 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
if (GLOB.dynamic_forced_extended)
log_game("DYNAMIC: Starting a round of forced extended.")
return TRUE
if (GLOB.dynamic_extended)
log_game("DYNAMIC: Starting a round of dynamic extended.")
return TRUE
var/list/drafted_rules = list()
for (var/datum/dynamic_ruleset/roundstart/rule in roundstart_rules)
if (!rule.weight)
@@ -563,9 +583,10 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
return FALSE
// Check if the ruleset is high impact and if a high impact ruleset has been executed
else if(new_rule.flags & HIGH_IMPACT_RULESET)
if(threat_level < GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking)
if(high_impact_ruleset_executed)
return FALSE
if(GLOB.dynamic_extended)
return FALSE
if(high_impact_ruleset_executed && threat_level < GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking)
return FALSE
var/population = current_players[CURRENT_LIVING_PLAYERS].len
if((new_rule.acceptable(population, threat_level) && new_rule.cost <= mid_round_budget) || forced)
@@ -598,8 +619,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
/datum/game_mode/dynamic/proc/midround_rule_draft()
set waitfor = FALSE
if (midround_injection_cooldown < world.time)
/*if (GLOB.dynamic_forced_extended)
return*/
if (GLOB.dynamic_forced_extended)
return
// Somehow it managed to trigger midround multiple times so this was moved here.
// There is no way this should be able to trigger an injection twice now.
@@ -620,6 +641,11 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
for (var/datum/dynamic_ruleset/midround/rule in midround_rules)
if (!rule.weight)
continue
if(rule.flags & HIGH_IMPACT_RULESET)
if (high_impact_ruleset_executed && threat_level < GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking)
continue
if(GLOB.dynamic_extended)
continue
if (rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && mid_round_budget >= rule.cost)
rule.trim_candidates()
if (rule.ready())
@@ -642,11 +668,17 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
forced_injection = dry_run
return 100
var/chance = 0
var/max_pop_per_antag = max(5,15 - round(threat_level/10) - round(current_players[CURRENT_LIVING_PLAYERS].len/5))
var/effective_living_players = current_players[CURRENT_LIVING_PLAYERS].len
if(GLOB.dynamic_extended)
effective_living_players = min(effective_living_players, length(SSjob.get_living_sec())*2 + length(SSjob.get_living_heads()))
var/max_pop_per_antag = max(5,15 - round(threat_level/10) - round(effective_living_players/5))
if (!current_players[CURRENT_LIVING_ANTAGS].len)
chance += 50 // No antags at all? let's boost those odds!
if(GLOB.dynamic_extended)
chance += min(50,effective_living_players*5)
else
chance += 50 // No antags at all? let's boost those odds!
else
var/current_pop_per_antag = current_players[CURRENT_LIVING_PLAYERS].len / current_players[CURRENT_LIVING_ANTAGS].len
var/current_pop_per_antag = effective_living_players / current_players[CURRENT_LIVING_ANTAGS].len
if (current_pop_per_antag > max_pop_per_antag)
chance += min(50, 25+10*(current_pop_per_antag-max_pop_per_antag))
else
@@ -63,7 +63,7 @@
required_candidates = 1
weight = 7
cost = 5
requirements = list(40,30,20,10,10,10,10,10,10,10)
requirements = list(101,40,25,20,15,10,10,10,10,10)
repeatable = TRUE
//////////////////////////////////////////////
@@ -159,5 +159,5 @@
required_candidates = 1
weight = 4
cost = 10
requirements = list(101,101,101,50,40,10,10,10,10,10)
requirements = list(101,101,101,50,40,20,20,15,10,10)
repeatable = TRUE
@@ -254,7 +254,7 @@
antag_flag = ROLE_MALF
enemy_roles = list("Security Officer", "Warden","Detective","Head of Security", "Captain", "Scientist", "Chemist", "Research Director", "Chief Engineer")
exclusive_roles = list("AI")
required_enemies = list(4,4,4,4,4,4,2,2,2,0)
required_enemies = list(0,0,0,0,0,0,0,0,0,0)
required_candidates = 1
weight = 3
cost = 35
@@ -304,11 +304,11 @@
antag_flag = "wizard mid"
antag_flag_override = ROLE_WIZARD
enemy_roles = list("Security Officer","Detective","Head of Security", "Captain")
required_enemies = list(2,2,1,1,1,1,1,0,0,0)
required_enemies = list(0,0,0,0,0,0,0,0,0,0)
required_candidates = 1
weight = 2
cost = 20
requirements = list(101,101,100,80,50,30,20,10,10,10)
requirements = list(101,101,100,60,40,20,20,20,10,10)
repeatable = TRUE
var/datum/mind/wizard
@@ -351,11 +351,11 @@
antag_datum = /datum/antagonist/nukeop
antag_flag_override = ROLE_OPERATIVE
enemy_roles = list("AI", "Cyborg", "Security Officer", "Warden","Detective","Head of Security", "Captain")
required_enemies = list(3,3,3,3,3,2,1,1,0,0)
required_enemies = list(0,0,0,0,0,0,0,0,0,0)
required_candidates = 5
weight = 3
cost = 35
requirements = list(101,101,101,80,50,40,30,15,10,10)
requirements = list(101,101,101,60,40,30,20,15,10,10)
var/list/operative_cap = list(2,2,3,3,3,4,5,5,5,5)
var/datum/team/nuclear/nuke_team
flags = HIGH_IMPACT_RULESET
@@ -393,11 +393,11 @@
antag_datum = /datum/antagonist/blob
antag_flag = ROLE_BLOB
enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain")
required_enemies = list(2,2,1,1,1,1,1,0,0,0)
required_enemies = list(0,0,0,0,0,0,0,0,0,0)
required_candidates = 1
weight = 2
cost = 10
requirements = list(101,101,101,101,70,40,25,20,10,10)
requirements = list(101,101,101,101,50,40,30,20,10,10)
repeatable = TRUE
/datum/dynamic_ruleset/midround/from_ghosts/blob/generate_ruleset_body(mob/applicant)
@@ -412,11 +412,11 @@
protected_roles = list("Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain")
restricted_roles = list("Cyborg", "AI", "Positronic Brain")
enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain")
required_enemies = list(2,2,1,1,1,1,1,0,0,0)
required_enemies = list(0,0,0,0,0,0,0,0,0,0)
required_candidates = 1
weight = 2
cost = 10
requirements = list(101,101,101,101,70,40,25,20,10,10)
requirements = list(101,101,101,101,50,40,30,20,10,10)
repeatable = TRUE
/datum/dynamic_ruleset/midround/blob_infection/trim_candidates()
@@ -450,11 +450,11 @@
antag_datum = /datum/antagonist/xeno
antag_flag = ROLE_ALIEN
enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain")
required_enemies = list(2,2,1,1,1,1,1,0,0,0)
required_enemies = list(0,0,0,0,0,0,0,0,0,0)
required_candidates = 1
weight = 3
cost = 10
requirements = list(101,101,101,101,60,50,30,20,10,10)
requirements = list(101,101,101,101,50,40,30,20,10,10)
repeatable = TRUE
var/list/vents = list()
@@ -496,11 +496,11 @@
antag_flag = "Nightmare"
antag_flag_override = ROLE_ALIEN
enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain")
required_enemies = list(2,2,1,1,1,1,1,0,0,0)
required_enemies = list(0,0,0,0,0,0,0,0,0,0)
required_candidates = 1
weight = 4
cost = 10
requirements = list(101,101,101,40,30,20,10,10,10,10)
requirements = list(101,101,50,30,25,20,10,10,10,10)
repeatable = TRUE
var/list/spawn_locs = list()
@@ -542,11 +542,11 @@
antag_flag = ROLE_SPACE_DRAGON
antag_flag_override = ROLE_SPACE_DRAGON
enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain")
required_enemies = list(2,2,1,1,1,1,1,0,0,0)
required_enemies = list(0,0,0,0,0,0,0,0,0,0)
required_candidates = 1
weight = 3
cost = 10
requirements = list(101,101,101,101,60,50,30,20,10,10)
requirements = list(101,101,101,101,50,40,30,20,10,10)
repeatable = TRUE
var/list/spawn_locs = list()
@@ -586,12 +586,12 @@
antag_flag = "Abductor"
antag_flag_override = ROLE_ABDUCTOR
enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain")
required_enemies = list(2,2,1,1,1,1,1,0,0,0)
required_enemies = list(0,0,0,0,0,0,0,0,0,0)
required_candidates = 2
required_applicants = 2
weight = 3
cost = 10
requirements = list(101,101,101,101,101,40,25,20,10,10)
requirements = list(101,101,101,101,101,30,20,15,10,10)
repeatable = TRUE
var/datum/team/abductor_team/new_team
@@ -625,11 +625,11 @@
antag_flag_override = ROLE_ALIEN
required_type = /mob/dead/observer
enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain")
required_enemies = list(2,2,1,1,1,1,1,0,0,0)
required_enemies = list(0,0,0,0,0,0,0,0,0,0)
required_candidates = 0
weight = 3
cost = 10
requirements = list(101,101,101,101,60,50,30,20,10,10)
requirements = list(101,101,101,101,50,40,30,20,10,10)
repeatable = TRUE
/datum/dynamic_ruleset/midround/swarmers/execute()
@@ -658,11 +658,11 @@
antag_flag = "Space Ninja"
antag_flag_override = ROLE_NINJA
enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain")
required_enemies = list(2,2,1,1,1,1,1,0,0,0)
required_enemies = list(0,0,0,0,0,0,0,0,0,0)
required_candidates = 1
weight = 4
cost = 10
requirements = list(101,101,101,80,60,50,30,20,10,10)
requirements = list(101,101,101,60,50,30,10,10,10,10)
repeatable = TRUE
var/list/spawn_locs = list()
@@ -699,11 +699,11 @@
antag_flag = "Revenant"
antag_flag_override = ROLE_REVENANT
enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain")
required_enemies = list(2,2,1,1,1,1,1,0,0,0)
required_enemies = list(0,0,0,0,0,0,0,0,0,0)
required_candidates = 1
weight = 4
cost = 10
requirements = list(101,101,101,70,50,40,20,15,10,10)
requirements = list(101,101,50,30,25,20,10,10,10,10)
repeatable = TRUE
var/dead_mobs_required = 20
var/need_extra_spawns_value = 15
@@ -748,7 +748,7 @@
required_candidates = 1
weight = 4
cost = 10
requirements = list(101,101,101,70,50,40,20,15,10,10)
requirements = list(101,101,50,30,25,20,10,10,10,10)
repeatable = TRUE
/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease/generate_ruleset_body(mob/applicant)
@@ -765,11 +765,11 @@
antag_flag = "Space Pirates"
required_type = /mob/dead/observer
enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain")
required_enemies = list(2,2,1,1,1,1,1,0,0,0)
required_enemies = list(0,0,0,0,0,0,0,0,0,0)
required_candidates = 0
weight = 4
cost = 10
requirements = list(101,101,101,50,40,25,10,10,10,10)
requirements = list(101,101,101,40,30,20,10,10,10,10)
repeatable = TRUE
/datum/dynamic_ruleset/midround/pirates/acceptable(population=0, threat=0)
@@ -103,7 +103,7 @@
weight = 3
cost = 16
scaling_cost = 10
requirements = list(101,70,60,50,40,20,20,10,10,10)
requirements = list(101,60,50,40,30,20,15,10,10,10)
antag_cap = list("denominator" = 29)
/datum/dynamic_ruleset/roundstart/changeling/pre_execute(population)
@@ -138,7 +138,7 @@
weight = 3
cost = 15
scaling_cost = 9
requirements = list(101,101,101,55,40,25,20,15,10,10)//higher because of 'round end'
requirements = list(101,101,101,50,40,20,20,15,10,10)//higher because of 'round end'
antag_cap = list("denominator" = 24)
@@ -179,7 +179,7 @@
required_candidates = 1
weight = 3
cost = 20
requirements = list(101,101,100,80,50,40,30,20,10,10)//100 because of configt, otherwise equal to nukies
requirements = list(101,101,100,60,40,20,20,20,10,10)//100 because of configt, otherwise equal to nukies
var/list/roundstart_wizards = list()
/datum/dynamic_ruleset/roundstart/wizard/acceptable(population=0, threat=0)
@@ -223,7 +223,7 @@
weight = 2 //lower weight because of easy steamroll potential
cost = 20
//requirements = list(100,90,80,60,40,30,10,10,10,10)
requirements = list(101,101,101,101,60,40,20,10,10,10)
requirements = list(101,101,101,101,50,40,20,10,10,10)
flags = HIGH_IMPACT_RULESET
antag_cap = list("denominator" = 20, "offset" = 1)
var/datum/team/cult/main_cult
@@ -279,7 +279,7 @@
required_candidates = 5
weight = 3
cost = 20
requirements = list(101,101,101,80,50,40,30,15,10,10)
requirements = list(101,101,101,60,40,30,20,15,10,10)
flags = HIGH_IMPACT_RULESET
antag_cap = list("denominator" = 18, "offset" = 1)
var/datum/team/nuclear/nuke_team
@@ -365,7 +365,7 @@
weight = 2
delay = 7 MINUTES
cost = 20
requirements = list(101,101,101,101,60,40,20,10,10,10)
requirements = list(101,101,101,101,50,40,20,10,10,10)
antag_cap = 3
flags = HIGH_IMPACT_RULESET
blocking_rules = list(/datum/dynamic_ruleset/latejoin/provocateur)
@@ -445,7 +445,7 @@
required_candidates = 2
weight = 3 //higher weight than blood cult and revs because it's more balanced
cost = 20
requirements = list(101,101,101,101,60,40,20,10,10,10) //slightly higher than nukies
requirements = list(101,101,101,101,50,40,20,10,10,10) //slightly higher than nukies
flags = HIGH_IMPACT_RULESET
antag_cap = list("denominator" = 20, "offset" = 1)
var/datum/team/clockcult/main_clockcult
+102
View File
@@ -0,0 +1,102 @@
// like a recycler, but for plants only ig
/obj/machinery/autoloom
name = "autoloom"
desc = "A large processing machine used to process raw biological matter, like cotton or logs. It also looks like a recycler. There's a display on the side."
icon = 'icons/obj/recycling.dmi'
icon_state = "grinder-o0"
layer = ABOVE_ALL_MOB_LAYER // Overhead
density = TRUE
circuit = /obj/item/circuitboard/machine/autoloom
var/icon_name = "grinder-o"
var/eat_dir = WEST
var/process_efficiency = 0
var/static/list/can_process = typecacheof(list(
/obj/item/stack/sheet/cotton,
/obj/item/grown/log,
/obj/item/grown/cotton
))
/obj/machinery/autoloom/RefreshParts()
for(var/obj/item/stock_parts/manipulator/M in component_parts)
process_efficiency = M.rating
/obj/machinery/recycler/examine(mob/user)
. = ..()
. += "<span class='notice'>Biomatter processing efficiency at <b>[amount_produced*100]%</b>.</span>"
/obj/machinery/autoloom/power_change()
..()
update_icon()
/obj/machinery/autoloom/attackby(obj/item/I, mob/user, params)
if(default_deconstruction_screwdriver(user, "grinder-oOpen", "grinder-o0", I))
return
if(default_pry_open(I))
return
if(default_unfasten_wrench(user, I))
return
if(default_deconstruction_crowbar(I))
return
return ..()
/obj/machinery/autoloom/update_icon_state()
var/is_powered = !(stat & (BROKEN|NOPOWER))
icon_state = icon_name + "[is_powered]" // add the blood tag at the end
/obj/machinery/autoloom/CanPass(atom/movable/AM)
. = ..()
if(!anchored)
return
var/move_dir = get_dir(loc, AM.loc)
if(move_dir == eat_dir)
return TRUE
/obj/machinery/autoloom/Crossed(atom/movable/AM)
eat(AM)
. = ..()
/obj/machinery/autoloom/proc/eat(atom/movable/AM0, sound=TRUE)
if(stat & (BROKEN|NOPOWER))
return
if(!isturf(AM0.loc))
return //I don't know how you called Crossed() but stop it.
if(is_type_in_list(AM0, can_process))
process_item(AM0)
/obj/machinery/autoloom/proc/process_item(obj/item/I)
. = list()
for(var/A in I)
var/atom/movable/AM = A
AM.forceMove(loc)
if(AM.loc == loc)
. += AM
I.forceMove(loc)
if(istype(I, /obj/item/grown/log))
var/obj/item/grown/log/L = I
var/seed_modifier = 0
if(L.seed)
seed_modifier = round(L.seed.potency / 25)
new L.plank_type(src.loc, process_efficiency + seed_modifier)
qdel(L)
return
if(istype(I, /obj/item/stack/sheet/cotton))
var/obj/item/stack/sheet/cotton/RS = I
var/tomake = round((RS.amount / 4) * process_efficiency)
new RS.loom_result(src.loc, tomake)
qdel(RS)
return
if(istype(I, /obj/item/grown/cotton))
var/obj/item/grown/cotton/RC = I
var/cottonAmt = 1 + round(RC.seed.potency / 25)
var/newRaw = new RC.cotton_type(src.loc, cottonAmt)
qdel(RC)
process_item(newRaw)
return
+2 -3
View File
@@ -82,9 +82,8 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
// If it's a generic arcade machine, pick a random arcade
// circuit board for it and make the new machine
if(!circuit)
var/list/gameodds = list(/obj/item/circuitboard/computer/arcade/battle = 33,
/obj/item/circuitboard/computer/arcade/orion_trail = 33,
/obj/item/circuitboard/computer/arcade/minesweeper = 33,
var/list/gameodds = list(/obj/item/circuitboard/computer/arcade/battle = 50,
/obj/item/circuitboard/computer/arcade/orion_trail = 50,
/obj/item/circuitboard/computer/arcade/amputation = 2)
var/thegame = pickweight(gameodds)
var/obj/item/circuitboard/CB = new thegame()
@@ -1,413 +0,0 @@
#define MINESWEEPER_GAME_MAIN_MENU 0
#define MINESWEEPER_GAME_PLAYING 1
#define MINESWEEPER_GAME_LOST 2
#define MINESWEEPER_GAME_WON 3
#define MINESWEEPERIMG(what) {"<img style='border:0' <span class="minesweeper16x16 [#what]"></span>"} //Basically bypassing asset.icon_tag()
/obj/machinery/computer/arcade/minesweeper
name = "Minesweeper"
desc = "An arcade machine that generates grids. It seems that the machine sparks and screeches when a grid is generated, as if it cannot cope with the intensity of generating the grid."
icon_state = "arcade"
circuit = /obj/item/circuitboard/computer/arcade/minesweeper
var/area
var/difficulty = "" //To show what difficulty you are playing
var/flag_text = ""
var/flagging = FALSE
var/game_status = MINESWEEPER_GAME_MAIN_MENU
var/mine_limit = 0
var/mine_placed = 0
var/mine_sound = TRUE //So it doesn't get repeated when multiple mines are exposed
var/randomcolour = 1
var/randomnumber = 1 //Random emagged game iteration number to be displayed, put here so it is persistent across one individual arcade machine
var/safe_squares_revealed
var/saved_web = "" //To display the web if you click on the arcade
var/win_condition
var/rows = 1
var/columns = 1
var/table[31][51] //Make the board boys, 30x50 board
var/spark_spam = FALSE
/obj/machinery/computer/arcade/minesweeper/interact(mob/user)
var/emagged = CHECK_BITFIELD(obj_flags, EMAGGED)
var/dat
if(game_status == MINESWEEPER_GAME_MAIN_MENU)
dat += "<head><title>Minesweeper</title></head><div align='center'><b>Minesweeper[emagged ? " <font color='red'>EXTREME EDITION</font>: Iteration <font color='[randomcolour]'>#[randomnumber]</font>" : ""]</b><br>" //Different colour mix for every random number made
dat += "<font size='2'> [emagged ? "Explode in the game, explode in real life" : "Reveal all the squares without hitting a mine"]!<br>What difficulty do you want to play?<br><br><br><br><b><a href='byond://?src=[REF(src)];Easy=1'><font color='#cc66ff'>Easy (9x9 board, 10 mines)</font></a><br><a href='byond://?src=[REF(src)];Intermediate=1'><font color='#cc66ff'>Intermediate (16x16 board, 40 mines)</font></a><br><a href='byond://?src=[REF(src)];Hard=1'><font color='#cc66ff'>Hard (16x30 board, 99 mines)</font></a><br><a href='byond://?src=[REF(src)];Custom=1'><font color='#cc66ff'>Custom</font>"
else
dat = saved_web
user = usr
var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/simple/minesweeper)
assets.send(user)
user << browse(dat,"window=minesweeper,size=400x500")
add_fingerprint(user)
. = ..()
/obj/machinery/computer/arcade/minesweeper/proc/reset_spark_spam()
spark_spam = FALSE
/obj/machinery/computer/arcade/minesweeper/Topic(href, href_list)
. = ..()
if(.)
return
var/exploding_hell = FALSE //For emagged failures
var/reset_board = FALSE
var/mob/living/user = usr //To identify who the hell is using this window, this should also make things like aliens and monkeys able to use the machine!!
var/web_difficulty_menu = "<font size='2'> Reveal all the squares without hitting a mine!<br>What difficulty do you want to play?<br><br><br><br><b><a href='byond://?src=[REF(src)];Easy=1'><font color='#cc66ff'>Easy (9x9 board, 10 mines)</font></a><br><a href='byond://?src=[REF(src)];Intermediate=1'><font color='#cc66ff'>Intermediate (16x16 board, 40 mines)</font></a><br><a href='byond://?src=[REF(src)];Hard=1'><font color='#cc66ff'>Hard (16x30 board, 99 mines)</font></a><br><a href='byond://?src=[REF(src)];Custom=1'><font color='#cc66ff'>Custom</font>"
var/web = "<head><title>Minesweeper</title></head><div align='center'><b>Minesweeper</b><br>"
var/static_web = "<head><title>Minesweeper</title></head><div align='center'><b>Minesweeper</b><br>" //When we need to revert to the main menu we set web as this
web = static_web
if(CHECK_BITFIELD(obj_flags, EMAGGED))
web = "<head><title>Minesweeper</title></head><body><div align='center'><b>Minesweeper <font color='red'>EXTREME EDITION</font>: Iteration <font color='[randomcolour]'>#[randomnumber]</font></b><br>" //Different colour mix for every random number made
if(!spark_spam)
do_sparks(5, 1, src)
spark_spam = TRUE
addtimer(CALLBACK(src, .proc/reset_spark_spam), 30)
var/startup_sound = CHECK_BITFIELD(obj_flags, EMAGGED) ? 'sound/arcade/minesweeper_emag2.ogg' : 'sound/arcade/minesweeper_startup.ogg'
if(href_list["Main_Menu"])
game_status = MINESWEEPER_GAME_MAIN_MENU
mine_limit = 0
rows = 0
columns = 0
mine_placed = 0
if(href_list["Easy"])
playsound(loc, startup_sound, 50, FALSE, extrarange = -3)
flag_text = "OFF"
game_status = MINESWEEPER_GAME_PLAYING
reset_board = TRUE
difficulty = "Easy"
rows = 10 //9x9 board
columns = 10
mine_limit = 10
if(href_list["Intermediate"])
playsound(loc, startup_sound, 50, FALSE, extrarange = -3)
flag_text = "OFF"
game_status = MINESWEEPER_GAME_PLAYING
reset_board = TRUE
difficulty = "Intermediate"
rows = 17 //16x16 board
columns = 17
mine_limit = 40
if(href_list["Hard"])
playsound(loc, startup_sound, 50, FALSE, extrarange = -3)
flag_text = "OFF"
game_status = MINESWEEPER_GAME_PLAYING
reset_board = TRUE
difficulty = "Hard"
rows = 17 //16x30 board
columns = 31
mine_limit = 99
if(href_list["Custom"])
if(custom_generation(usr))
flag_text = "OFF"
game_status = MINESWEEPER_GAME_PLAYING
reset_board = TRUE
difficulty = "Custom"
playsound(loc, startup_sound, 50, FALSE, extrarange = -3)
if(href_list["Flag"])
playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, FALSE, extrarange = -3)
if(!flagging)
flagging = TRUE
flag_text = "ON"
else
flagging = FALSE
flag_text = "OFF"
if(game_status == MINESWEEPER_GAME_MAIN_MENU)
if(CHECK_BITFIELD(obj_flags, EMAGGED))
playsound(loc, 'sound/arcade/minesweeper_emag2.ogg', 50, FALSE, extrarange = -3)
web += "<font size='2'>Explode in the game, explode in real life!<br>What difficulty do you want to play?<br><br><br><br><b><a href='byond://?src=[REF(src)];Easy=1'><font color='#cc66ff'>Easy (9x9 board, 10 mines)</font></a><br><a href='byond://?src=[REF(src)];Intermediate=1'><font color='#cc66ff'>Intermediate (16x16 board, 40 mines)</font></a><br><a href='byond://?src=[REF(src)];Hard=1'><font color='#cc66ff'>Hard (16x30 board, 99 mines)</font></a><br><a href='byond://?src=[REF(src)];Custom=1'><font color='#cc66ff'>Custom</font>"
else
playsound(loc, 'sound/arcade/minesweeper_startup.ogg', 50, FALSE, extrarange = -3)
web += web_difficulty_menu
if(game_status == MINESWEEPER_GAME_PLAYING)
mine_sound = TRUE
area = (rows-1)*(columns-1)
if(reset_board)
mine_placed = 0
var/reset_everything = TRUE
make_mines(reset_everything)
safe_squares_revealed = 0
win_condition = area-mine_placed
if(game_status != MINESWEEPER_GAME_MAIN_MENU)
for(var/y1=1;y1<rows;y1++)
for(var/x1=1;x1<columns;x1++)
var/coordinates
coordinates = (y1*100)+x1
if(href_list["[coordinates]"])
if(game_status == MINESWEEPER_GAME_PLAYING) //Don't do anything if we won or something
if(!flagging)
if(table[y1][x1] < 10 && table[y1][x1] >= 0) //Check that it's not already revealed, and stop flag removal if we're out of flag mode
table[y1][x1] += 10
if(table[y1][x1] != 10)
playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, FALSE, extrarange = -3)
else
if(game_status != MINESWEEPER_GAME_LOST && game_status != MINESWEEPER_GAME_WON)
game_status = MINESWEEPER_GAME_LOST
if(CHECK_BITFIELD(obj_flags, EMAGGED) && !exploding_hell)
exploding_hell = TRUE
explode_EVERYTHING()
if(QDELETED(src))
return
if(mine_sound)
switch(rand(1,3)) //Play every time a mine is hit
if(1)
playsound(loc, 'sound/arcade/minesweeper_explosion1.ogg', 50, FALSE, extrarange = -3)
if(2)
playsound(loc, 'sound/arcade/minesweeper_explosion2.ogg', 50, FALSE, extrarange = -3)
if(3)
playsound(loc, 'sound/arcade/minesweeper_explosion3.ogg', 50, FALSE, extrarange = -3)
mine_sound = FALSE
else
playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, FALSE, extrarange = -3)
if(table[y1][x1] >= 0) //Check that it's not already flagged
table[y1][x1] -= 10
else if(table[y1][x1] < 0) //If flagged, remove the flag
table[y1][x1] += 10
if(table[y1][x1] > 10 && !reset_board)
safe_squares_revealed += 1
var/y2 = y1
var/x2 = x1
work_squares(y2, x2) //Work squares while in this loop so there's less load
reset_board = FALSE
CHECK_TICK
web += "<table>" //Start setting up the html table
web += "<tbody>"
for(var/y1=1;y1<rows;y1++)
web += "<tr>"
for(var/x1=1;x1<columns;x1++)
var/coordinates
coordinates = (y1*100)+x1
switch(table[y1][x1])
if(-10 to -1)
if(game_status != MINESWEEPER_GAME_PLAYING)
web += "<td>[MINESWEEPERIMG(flag)]</td>"
else
web += "<td><a href='byond://?src=[REF(src)];[coordinates]=1'>[MINESWEEPERIMG(flag)]</a></td>"
if(0)
if(game_status != MINESWEEPER_GAME_PLAYING)
web += "<td>[MINESWEEPERIMG(mine)]</td>"
else
web += "<td><a href='byond://?src=[REF(src)];[coordinates]=1'>[MINESWEEPERIMG(hidden)]</a></td>" //Make unique hrefs for every square
if(1 to 9)
if(game_status != MINESWEEPER_GAME_PLAYING)
web += "<td>[MINESWEEPERIMG(hidden)]</td>"
else
web += "<td><a href='byond://?src=[REF(src)];[coordinates]=1'>[MINESWEEPERIMG(hidden)]</a></td>" //Make unique hrefs for every square
if(10)
web += "<td>[MINESWEEPERIMG(minehit)]</td>"
if(11)
web += "<td>[MINESWEEPERIMG(empty)]</td>"
if(12)
web += "<td>[MINESWEEPERIMG(1)]</td>"
if(13)
web += "<td>[MINESWEEPERIMG(2)]</td>"
if(14)
web += "<td>[MINESWEEPERIMG(3)]</td>"
if(15)
web += "<td>[MINESWEEPERIMG(4)]</td>"
if(16)
web += "<td>[MINESWEEPERIMG(5)]</td>"
if(17)
web += "<td>[MINESWEEPERIMG(6)]</td>"
if(18)
web += "<td>[MINESWEEPERIMG(7)]</td>"
if(19)
web += "<td>[MINESWEEPERIMG(8)]</td>"
CHECK_TICK
web += "</tr>"
web += "</table>"
web += "</tbody>"
web += "<br>"
if(safe_squares_revealed >= win_condition && game_status == MINESWEEPER_GAME_PLAYING)
game_status = MINESWEEPER_GAME_WON
if(rows < 10 || columns < 10) //If less than easy difficulty
playsound(loc, 'sound/arcade/minesweeper_winfail.ogg', 50, FALSE, extrarange = -3)
say("You cleared the board of all mines, but you picked too small of a board! Try again with at least a 9x9 board!")
else
playsound(loc, 'sound/arcade/minesweeper_win.ogg', 50, FALSE, extrarange = -3)
say("You cleared the board of all mines! Congratulations!")
if(CHECK_BITFIELD(obj_flags, EMAGGED))
var/itemname
switch(rand(1,3))
if(1)
itemname = "a syndicate bomb beacon"
new /obj/item/sbeacondrop/bomb(loc)
if(2)
itemname = "a rocket launcher"
new /obj/item/gun/ballistic/rocketlauncher/unrestricted(loc)
new /obj/item/ammo_casing/caseless/rocket(loc)
new /obj/item/ammo_casing/caseless/rocket(loc)
new /obj/item/ammo_casing/caseless/rocket(loc)
if(3)
itemname = "two bags of c4"
new /obj/item/storage/backpack/duffelbag/syndie/c4(loc)
new /obj/item/storage/backpack/duffelbag/syndie/x4(loc)
message_admins("[key_name_admin(user)] won emagged Minesweeper and got [itemname]!")
visible_message("<span class='notice'>[src] dispenses [itemname]!</span>", "<span class='notice'>You hear a chime and a clunk.</span>")
DISABLE_BITFIELD(obj_flags, EMAGGED)
else
var/dope_prizes = (area >= 480) ? 6 : (area >= 256) ? 4 : 2
prizevend(user, dope_prizes)
if(game_status == MINESWEEPER_GAME_WON)
web += "[(rows < 10 || columns < 10) ? "<font size='4'>You won, but your board was too small! Pick a bigger board next time!" : "<font size='6'>Congratulations, you have won!"]<br><font size='3'>Want to play again?<br><b><a href='byond://?src=[REF(src)];Easy=1'><font color='#cc66ff'>Easy (9x9 board, 10 mines)</font></a><br><a href='byond://?src=[REF(src)];Intermediate=1'><font color='#cc66ff'>Intermediate (16x16 board, 40 mines)</font></a><br><a href='byond://?src=[REF(src)];Hard=1'><font color='#cc66ff'>Hard (16x30 board, 99 mines)</font></a><br><a href='byond://?src=[REF(src)];Custom=1'><font color='#cc66ff'>Custom</font></a></b><br><a href='byond://?src=[REF(src)];Main_Menu=1'><font color='#cc66ff'>Return to Main Menu</font></a></b><br>"
if(game_status == MINESWEEPER_GAME_LOST)
web += "<font size='6'>You have lost!<br><font size='3'>Try again?<br><b><a href='byond://?src=[REF(src)];Easy=1'><font color='#cc66ff'>Easy (9x9 board, 10 mines)</font></a><br><a href='byond://?src=[REF(src)];Intermediate=1'><font color='#cc66ff'>Intermediate (16x16 board, 40 mines)</font></a><br><a href='byond://?src=[REF(src)];Hard=1'><font color='#cc66ff'>Hard (16x30 board, 99 mines)</font></a><br><a href='byond://?src=[REF(src)];Custom=1'><font color='#cc66ff'>Custom</font></a></b><br><a href='byond://?src=[REF(src)];Main_Menu=1'><font color='#cc66ff'>Return to Main Menu</font></a></b><br>"
if(game_status == MINESWEEPER_GAME_PLAYING)
web += "<a href='byond://?src=[REF(src)];Main_Menu=1'><font color='#cc66ff'>Return to Main Menu</font></a><br>"
web += "<div align='right'>Difficulty: [difficulty]<br>Mines: [mine_placed]<br>Rows: [rows-1]<br>Columns: [columns-1]<br><a href='byond://?src=[REF(src)];Flag=1'><font color='#cc66ff'>Flagging mode: [flag_text]</font></a></div>"
web += "</div>"
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/simple/minesweeper)
saved_web = sheet.css_tag()
saved_web += web
updateDialog()
return
/obj/machinery/computer/arcade/minesweeper/emag_act(mob/user)
. = ..()
if(CHECK_BITFIELD(obj_flags, EMAGGED))
return
desc = "An arcade machine that generates grids. It's clunking and sparking everywhere, almost as if threatening to explode at any moment!"
do_sparks(5, 1, src)
randomnumber = rand(1,255)
randomcolour = rgb(randomnumber,randomnumber/2,randomnumber/3)
ENABLE_BITFIELD(obj_flags, EMAGGED)
if(game_status == MINESWEEPER_GAME_MAIN_MENU)
to_chat(user, "<span class='warning'>An ominous tune plays from the arcade's speakers!</span>")
playsound(user, 'sound/arcade/minesweeper_emag1.ogg', 100, FALSE, extrarange = 3)
else //Can't let you do that, star fox!
to_chat(user, "<span class='warning'>The machine buzzes and sparks... the game has been reset!</span>")
playsound(user, 'sound/machines/buzz-sigh.ogg', 100, FALSE, extrarange = 3) //Loud buzz
game_status = MINESWEEPER_GAME_MAIN_MENU
return TRUE
/obj/machinery/computer/arcade/minesweeper/proc/custom_generation(mob/user)
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, FALSE, extrarange = -3) //Entered into the menu so ping sound
var/new_rows = input(user, "How many rows do you want? (Minimum: 4, Maximum: 30)", "Minesweeper Rows") as null|num
if(!new_rows || !user.canUseTopic(src, !hasSiliconAccessInArea(user)))
return FALSE
new_rows = clamp(new_rows + 1, 4, 20)
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, FALSE, extrarange = -3)
var/new_columns = input(user, "How many columns do you want? (Minimum: 4, Maximum: 50)", "Minesweeper Squares") as null|num
if(!new_columns || !user.canUseTopic(src, !hasSiliconAccessInArea(user)))
return FALSE
new_columns = clamp(new_columns + 1, 4, 30)
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, FALSE, extrarange = -3)
var/grid_area = (new_rows - 1) * (new_columns - 1)
var/lower_limit = round(grid_area*0.156)
var/upper_limit = round(grid_area*0.85)
var/new_mine_limit = input(user, "How many mines do you want? (Minimum: [lower_limit], Maximum: [upper_limit])", "Minesweeper Mines") as null|num
if(!new_mine_limit || !user.canUseTopic(src, !hasSiliconAccessInArea(user)))
return FALSE
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, FALSE, extrarange = -3)
rows = new_rows
columns = new_columns
mine_limit = clamp(new_mine_limit, lower_limit, upper_limit)
return TRUE
/obj/machinery/computer/arcade/minesweeper/proc/make_mines(var/reset_everything)
if(mine_placed < mine_limit)
for(var/y1=1;y1<rows;y1++) //Board resetting and mine building
for(var/x1=1;x1<columns;x1++)
if(prob(area/mine_limit) && mine_placed < mine_limit && table[y1][x1] != 0) //Unlikely for this to happen but this has eaten mines before
table[y1][x1] = 0
mine_placed += 1
else if(reset_everything)
table[y1][x1] = 1
reset_everything = FALSE
make_mines() //In case the first pass doesn't generate enough mines
/obj/machinery/computer/arcade/minesweeper/proc/work_squares(var/y2, var/x2, var/y3, var/x3)
if(y3 > 0 && x3 > 0)
y2 = y3
x2 = x3
if(table[y2][x2] == 1)
for(y3=y2-1;y3<y2+2;y3++)
if(y3 >= rows || y3 < 1)
continue
for(x3=x2-1;x3<x2+2;x3++)
if(x3 >= columns || x3 < 1)
continue
if(table[y3][x3] == 0)
table[y2][x2] += 1
if(table[y2][x2] == 11)
for(y3=y2-1;y3<y2+2;y3++)
if(y3 >= rows || y3 < 1)
continue
for(x3=x2-1;x3<x2+2;x3++)
if(x3 >= columns || x3 < 1)
continue
if(table[y3][x3] > 0 && table[y3][x3] < 10)
table[y3][x3] += 10
work_squares(y3, x3) //Refresh so we check everything we might be missing
/obj/machinery/computer/arcade/minesweeper/proc/explode_EVERYTHING()
var/mob/living/user = usr
to_chat(user, "<span class='boldwarning'>You feel a great sense of dread wash over you, as if you just unleashed armageddon upon yourself!</span>")
var/row_limit = rows-1
var/column_limit = columns-1
var/mine_limit_v2 = mine_limit
if(rows > 21)
row_limit = 20
if(columns > 21)
column_limit = 20
if(mine_limit > (rows*columns) * 0.25)
mine_limit_v2 = 24
message_admins("[key_name_admin(user)] failed an emagged Minesweeper arcade and has unleashed an explosion armageddon of size [row_limit],[column_limit] around [ADMIN_LOOKUPFLW(user.loc)]!")
if(mine_limit_v2 < 10)
explosion(loc, 2, 5, 10, 15) //Thought you could survive by putting as few mines as possible, huh??
else
explosion(loc, 1, 3, rand(1,5), rand(1,10))
var/list/targets = list()
var/cur_y = y - round(row_limit * 0.5, 1)
var/starting_row = 1
if(cur_y < 1)
starting_row -= cur_y - 1
cur_y = 1
var/start_x = x - round(column_limit * 0.5, 1)
var/starting_column = 1
if(start_x < 1)
starting_column -= start_x - 1
start_x = 1
for(var/row in starting_row to length(table)) //translate the mines locations into actual turf coordinates.
if(!locate(cur_y, start_x, z))
break
var/cur_x = start_x
for(var/column in starting_column to length(table[row]))
var/coord_value = table[row][column]
if(coord_value == 10 || coord_value == 0) //there is a mine in here.
var/turf/T = locate(cur_y, cur_x, z)
if(!T)
break
targets += T
cur_x++
cur_y++
var/num_explosions = 0
for(var/T in shuffle(targets)) //Create a shitton of explosions in irl turfs if we lose, it will probably kill us
addtimer(CALLBACK(GLOBAL_PROC, /proc/explosion, T, 0, rand(1,2),rand(1,5),rand(3,10), FALSE), 15 * ++num_explosions)
if(num_explosions == mine_limit_v2)
return
#undef MINESWEEPERIMG
#undef MINESWEEPER_GAME_MAIN_MENU
#undef MINESWEEPER_GAME_PLAYING
#undef MINESWEEPER_GAME_LOST
#undef MINESWEEPER_GAME_WON
+2 -2
View File
@@ -62,7 +62,7 @@ GLOBAL_LIST_EMPTY(allConsoles)
update_icon()
/obj/machinery/requests_console/update_icon_state()
if(CHECK_BITFIELD(stat, NOPOWER))
if((stat & NOPOWER))
set_light(0)
else
set_light(1.4, 0.7, "#34D352")//green light
@@ -72,7 +72,7 @@ GLOBAL_LIST_EMPTY(allConsoles)
icon_state="req_comp_open"
else
icon_state="req_comp_rewired"
else if(CHECK_BITFIELD(stat, NOPOWER))
else if((stat & NOPOWER))
if(icon_state != "req_comp_off")
icon_state = "req_comp_off"
else
@@ -1,5 +1,5 @@
/*
The log console for viewing the entire telecomms
The log console for viewing the entire telecomms
network log
*/
@@ -15,7 +15,7 @@
var/network = "NULL" // the network to probe
var/notice = ""
var/universal_translate = FALSE // set to TRUE(1) if it can translate nonhuman speech
var/universal_translate = FALSE // set to TRUE(1) if it can translate nonhuman speech
/obj/machinery/computer/telecomms/server/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
@@ -53,7 +53,7 @@
if(!LAZYLEN(SelectedMachine.log_entries))
return data_out
for(var/datum/comm_log_entry/C in SelectedMachine.log_entries)
var/list/data = list()
data["name"] = C.name //name of the file
@@ -104,7 +104,7 @@
data["message"] = C.parameters["message"]
else
data["message"] = "(unintelligible)"
data_out["selected_logs"] += list(data)
return data_out
@@ -133,7 +133,7 @@
if(LAZYLEN(machinelist) > 0)
notice = "FAILED: Cannot probe when buffer full"
return
for(var/obj/machinery/telecomms/T in GLOB.telecomms_list) //telecomms just went global!
if(T.network == network)
LAZYADD(machinelist, T)
@@ -147,7 +147,7 @@
SelectedMachine = T
break
if("delete")
if(!src.allowed(usr) && !CHECK_BITFIELD(obj_flags, EMAGGED))
if(!src.allowed(usr) && !(obj_flags & EMAGGED))
to_chat(usr, "<span class='danger'>ACCESS DENIED.</span>")
return
@@ -156,7 +156,7 @@
return
var/datum/comm_log_entry/D = locate(params["value"])
if(!istype(D))
notice = "NOTICE: Object not found"
notice = "NOTICE: Object not found"
return
notice = "Deleted entry: [D.name]"
LAZYREMOVE(SelectedMachine.log_entries, D)
@@ -94,9 +94,9 @@
if(istype(S) && S.hack_software)
data_out["canhack"] = TRUE
data_out["hacking"] = (hacking || CHECK_BITFIELD(obj_flags, EMAGGED))
data_out["hacking"] = (hacking || (obj_flags & EMAGGED))
if(hacking)
data_out["borg"] = ((isAI(user) || iscyborg(user)) && !CHECK_BITFIELD(obj_flags, EMAGGED)) //even borgs can't read emag
data_out["borg"] = ((isAI(user) || iscyborg(user)) && !(obj_flags & EMAGGED)) //even borgs can't read emag
return data_out
data_out["servers"] = list()
@@ -324,7 +324,7 @@
update_static_data(usr)
/obj/machinery/computer/message_monitor/attackby(obj/item/O, mob/living/user, params)
if(O.tool_behaviour == TOOL_SCREWDRIVER && CHECK_BITFIELD(obj_flags, EMAGGED))
if(O.tool_behaviour == TOOL_SCREWDRIVER && (obj_flags & EMAGGED))
//Stops people from just unscrewing the monitor and putting it back to get the console working again.
//Why this though, you should make it emag to a board level. (i wont do it)
to_chat(user, "<span class='warning'>It is too hot to mess with!</span>")
@@ -333,12 +333,12 @@
/obj/machinery/computer/message_monitor/emag_act(mob/user)
. = ..()
if(CHECK_BITFIELD(obj_flags, EMAGGED))
if((obj_flags & EMAGGED))
return
if(isnull(linkedServer))
to_chat(user, "<span class='notice'>A no server error appears on the screen.</span>")
return
ENABLE_BITFIELD(obj_flags, EMAGGED)
obj_flags |= EMAGGED
spark_system.set_up(5, 0, src)
spark_system.start()
var/obj/item/paper/monitorkey/MK = new(loc, linkedServer)
@@ -366,7 +366,7 @@
message = ""
/obj/machinery/computer/message_monitor/proc/UnmagConsole()
DISABLE_BITFIELD(obj_flags, EMAGGED)
obj_flags &= ~(EMAGGED)
message = ""
/obj/machinery/computer/message_monitor/proc/ResetMessage()
@@ -119,7 +119,7 @@ GLOBAL_LIST_EMPTY(telecomms_list)
/obj/machinery/telecomms/proc/update_power()
if(toggled)
// if powered, on. if not powered, off. if too damaged, off
if(CHECK_BITFIELD(stat, (BROKEN | NOPOWER | EMPED)))
if(stat &(BROKEN | NOPOWER | EMPED))
on = FALSE
else
on = TRUE
@@ -137,11 +137,11 @@ GLOBAL_LIST_EMPTY(telecomms_list)
/obj/machinery/telecomms/emp_act(severity)
. = ..()
if(CHECK_BITFIELD(., EMP_PROTECT_SELF))
if((. & EMP_PROTECT_SELF))
return
if(prob(severity))
if(!CHECK_BITFIELD(stat, EMPED))
ENABLE_BITFIELD(stat, EMPED)
if(!(stat & EMPED))
stat |= EMPED
var/duration = severity * 35
spawn(rand(duration - 20, duration + 20)) // Takes a long time for the machines to reboot.
DISABLE_BITFIELD(stat, EMPED)
stat &= ~(EMPED)
@@ -276,7 +276,7 @@
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/critfail()
..()
if(reagents)
DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT)
reagents.reagents_holder_flags &= ~(NO_REACT)
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/can_attach(obj/mecha/medical/M)
if(..())
+5 -5
View File
@@ -450,8 +450,8 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
A.Remove(user)
if(item_flags & DROPDEL)
qdel(src)
DISABLE_BITFIELD(item_flags, IN_INVENTORY)
DISABLE_BITFIELD(item_flags, IN_STORAGE)
item_flags &= ~(IN_INVENTORY)
item_flags &= ~(IN_STORAGE)
SEND_SIGNAL(src, COMSIG_ITEM_DROPPED,user)
remove_outline()
// if(!silent)
@@ -529,8 +529,8 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
if(item_action_slot_check(slot, user, A)) //some items only give their actions buttons when in a specific slot.
A.Grant(user)
item_flags |= IN_INVENTORY
if(CHECK_BITFIELD(item_flags, IN_STORAGE)) // Left storage item but somehow has the bitfield active still.
DISABLE_BITFIELD(item_flags, IN_STORAGE)
if((item_flags & IN_STORAGE)) // Left storage item but somehow has the bitfield active still.
item_flags &= ~(IN_STORAGE)
// if(!initial)
// if(equip_sound && (slot_flags & slot))
// playsound(src, equip_sound, EQUIP_SOUND_VOLUME, TRUE, ignore_walls = FALSE)
@@ -1054,7 +1054,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
*/
/obj/item/proc/set_slowdown(new_slowdown)
slowdown = new_slowdown
if(CHECK_BITFIELD(item_flags, IN_INVENTORY))
if((item_flags & IN_INVENTORY))
var/mob/living/L = loc
if(istype(L))
L.update_equipment_speed_mods()
+5 -5
View File
@@ -190,7 +190,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
qdel(src)
return
// allowing reagents to react after being lit
DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT)
reagents.reagents_holder_flags &= ~(NO_REACT)
reagents.handle_reactions()
icon_state = icon_on
item_state = icon_on
@@ -762,7 +762,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(!screw)
screw = TRUE
to_chat(user, "<span class='notice'>You open the cap on [src].</span>")
ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER)
reagents.reagents_holder_flags |= OPENCONTAINER
if(obj_flags & EMAGGED)
add_overlay("vapeopen_high")
else if(super)
@@ -772,7 +772,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
else
screw = FALSE
to_chat(user, "<span class='notice'>You close the cap on [src].</span>")
DISABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER)
reagents.reagents_holder_flags &= ~(OPENCONTAINER)
cut_overlays()
if(O.tool_behaviour == TOOL_MULTITOOL)
@@ -822,7 +822,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(slot == SLOT_WEAR_MASK)
if(!screw)
to_chat(user, "<span class='notice'>You start puffing on the vape.</span>")
DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT)
reagents.reagents_holder_flags &= ~(NO_REACT)
START_PROCESSING(SSobj, src)
else //it will not start if the vape is opened.
to_chat(user, "<span class='warning'>You need to close the cap first!</span>")
@@ -831,7 +831,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
. = ..()
var/mob/living/carbon/C = user
if(C.get_item_by_slot(SLOT_WEAR_MASK) == src)
ENABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT)
reagents.reagents_holder_flags |= NO_REACT
STOP_PROCESSING(SSobj, src)
/obj/item/clothing/mask/vape/proc/hand_reagents()//had to rename to avoid duplicate error
@@ -259,11 +259,6 @@
build_path = /obj/machinery/computer/arcade/orion_trail
/obj/item/circuitboard/computer/arcade/minesweeper
name = "Minesweeper (Computer Board)"
icon_state = "generic"
build_path = /obj/machinery/computer/arcade/minesweeper
/obj/item/circuitboard/computer/holodeck// Not going to let people get this, but it's just here for future
name = "Holodeck Control (Computer Board)"
icon_state = "generic"
@@ -1295,6 +1295,15 @@
/obj/item/stock_parts/manipulator = 1)
needs_anchored = FALSE
/obj/item/circuitboard/machine/autoloom
name = "Autoloom (Machine Board)"
icon_state = "service"
build_path = /obj/machinery/autoloom
req_components = list(
/obj/item/stock_parts/matter_bin = 1,
/obj/item/stock_parts/manipulator = 1)
needs_anchored = FALSE
/obj/item/circuitboard/machine/seed_extractor
name = "Seed Extractor (Machine Board)"
icon_state = "service"
+27 -2
View File
@@ -72,6 +72,10 @@
var/datum/team/gang/gang //For marking territory.
var/gang_tag_delay = 30 //this is the delay for gang mode tag applications on anything that gang = true on.
var/precision_mode = FALSE
var/precision_x = 0
var/precision_y = 0
/obj/item/toy/crayon/proc/isValidSurface(surface)
return istype(surface, /turf/open/floor)
@@ -228,6 +232,12 @@
.["can_change_colour"] = can_change_colour
.["current_colour"] = paint_color
.["precision_mode"] = precision_mode
.["x"] = precision_x
.["y"] = precision_y
.["min_offset"] = -world.icon_size/2
.["max_offset"] = world.icon_size/2
/obj/item/toy/crayon/ui_act(action, list/params)
if(..())
return
@@ -256,6 +266,17 @@
. = TRUE
paint_mode = PAINT_NORMAL
drawtype = "a"
if("toggle_precision")
precision_mode = !precision_mode
. = TRUE
if("set_precision_x")
var/x = text2num(params["x"])
precision_x = x
. = TRUE
if("set_precision_y")
var/y = text2num(params["y"])
precision_y = y
. = TRUE
update_icon()
/obj/item/toy/crayon/proc/select_colour(mob/user)
@@ -400,8 +421,12 @@
if(PAINT_NORMAL)
var/obj/effect/decal/cleanable/crayon/C = new(target, paint_color, drawing, temp, graf_rot)
C.add_hiddenprint(user)
C.pixel_x = clickx
C.pixel_y = clicky
if(precision_mode)
C.pixel_x = clamp(precision_x, -(world.icon_size/2), world.icon_size/2)
C.pixel_y = clamp(precision_y, -(world.icon_size/2), world.icon_size/2)
else
C.pixel_x = clickx
C.pixel_y = clicky
affected_turfs += target
if(PAINT_LARGE_HORIZONTAL)
var/turf/left = locate(target.x-1,target.y,target.z)
@@ -326,7 +326,7 @@
cleaning_cycles--
cleaning = TRUE
for(var/mob/living/carbon/C in (touchable_items))
if((C.status_flags & GODMODE) || !CHECK_BITFIELD(C.vore_flags, DIGESTABLE))
if((C.status_flags & GODMODE) || !(C.vore_flags & DIGESTABLE))
items_preserved += C
else
C.adjustBruteLoss(2)
@@ -335,7 +335,7 @@
var/atom/target = pick(touchable_items)
if(iscarbon(target)) //Handle the target being a mob
var/mob/living/carbon/T = target
if(T.stat == DEAD && CHECK_BITFIELD(T.vore_flags, DIGESTABLE)) //Mob is now dead
if(T.stat == DEAD && (T.vore_flags & DIGESTABLE)) //Mob is now dead
message_admins("[key_name(hound)] has digested [key_name(T)] as a dogborg. ([hound ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[hound.x];Y=[hound.y];Z=[hound.z]'>JMP</a>" : "null"])")
to_chat(hound,"<span class='notice'>You feel your belly slowly churn around [T], breaking them down into a soft slurry to be used as power for your systems.</span>")
to_chat(T,"<span class='notice'>You feel [hound]'s belly slowly churn around your form, breaking you down into a soft slurry to be used as power for [hound]'s systems.</span>")
@@ -433,7 +433,7 @@
var/mob/living/silicon/robot/hound = get_host()
if(!hound || !istype(target) || !proximity || target.anchored)
return
if (!CHECK_BITFIELD(target.vore_flags,DEVOURABLE))
if (!(target.vore_flags & DEVOURABLE))
to_chat(user, "The target registers an error code. Unable to insert into [src].")
return
if(patient)
+3 -2
View File
@@ -23,7 +23,7 @@
max_integrity = 200
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70)
resistance_flags = FIRE_PROOF
wound_bonus = -110
wound_bonus = -40
bare_wound_bonus = 20
block_parry_data = /datum/block_parry_data/dual_esword
block_chance = 60
@@ -133,7 +133,7 @@
total_mass = initial(total_mass)
wielded = FALSE
hitsound = "swing_hit"
slowdown_wielded -= slowdown_wielded
slowdown -= slowdown_wielded
STOP_PROCESSING(SSobj, src)
set_light(0)
RemoveElement(/datum/element/sword_point)
@@ -278,6 +278,7 @@
desc = "A supermassive weapon envisioned to cleave the very fabric of space and time itself in twain, the hypereutactic blade dynamically flash-forges a hypereutactic crystaline nanostructure capable of passing through most known forms of matter like a hot knife through butter."
force = 7
hitsound_on = 'sound/weapons/nebhit.ogg'
wound_bonus = -20
armour_penetration = 60
light_color = "#37FFF7"
rainbow_colors = list("#FF0000", "#FFFF00", "#00FF00", "#00FFFF", "#0000FF","#FF00FF", "#3399ff", "#ff9900", "#fb008b", "#9800ff", "#00ffa3", "#ccff00")
+12 -12
View File
@@ -174,11 +174,11 @@
/obj/item/shield/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(ismovable(object))
var/atom/movable/AM = object
if(CHECK_BITFIELD(shield_flags, SHIELD_TRANSPARENT) && (AM.pass_flags & PASSGLASS))
if((shield_flags & SHIELD_TRANSPARENT) && (AM.pass_flags & PASSGLASS))
return BLOCK_NONE
if(CHECK_BITFIELD(shield_flags, SHIELD_NO_RANGED) && (attack_type & ATTACK_TYPE_PROJECTILE))
if((shield_flags & SHIELD_NO_RANGED) && (attack_type & ATTACK_TYPE_PROJECTILE))
return BLOCK_NONE
if(CHECK_BITFIELD(shield_flags, SHIELD_NO_MELEE) && (attack_type & ATTACK_TYPE_MELEE))
if((shield_flags & SHIELD_NO_MELEE) && (attack_type & ATTACK_TYPE_MELEE))
return BLOCK_NONE
if(attack_type & ATTACK_TYPE_THROWN)
final_block_chance += 30
@@ -249,15 +249,15 @@
if(attack_type & ATTACK_TYPE_MELEE)
var/obj/hittingthing = object
if(hittingthing.damtype == BURN)
if(CHECK_BITFIELD(shield_flags, SHIELD_ENERGY_WEAK))
if((shield_flags & SHIELD_ENERGY_WEAK))
final_damage *= 2
else if(CHECK_BITFIELD(shield_flags, SHIELD_ENERGY_STRONG))
else if((shield_flags & SHIELD_ENERGY_STRONG))
final_damage *= 0.5
if(hittingthing.damtype == BRUTE)
if(CHECK_BITFIELD(shield_flags, SHIELD_KINETIC_WEAK))
if((shield_flags & SHIELD_KINETIC_WEAK))
final_damage *= 2
else if(CHECK_BITFIELD(shield_flags, SHIELD_KINETIC_STRONG))
else if((shield_flags & SHIELD_KINETIC_STRONG))
final_damage *= 0.5
if(hittingthing.damtype == STAMINA || hittingthing.damtype == TOX || hittingthing.damtype == CLONE || hittingthing.damtype == BRAIN || hittingthing.damtype == OXY)
@@ -266,19 +266,19 @@
if(attack_type & ATTACK_TYPE_PROJECTILE)
var/obj/item/projectile/shootingthing = object
if(is_energy_reflectable_projectile(shootingthing))
if(CHECK_BITFIELD(shield_flags, SHIELD_ENERGY_WEAK))
if((shield_flags & SHIELD_ENERGY_WEAK))
final_damage *= 2
else if(CHECK_BITFIELD(shield_flags, SHIELD_ENERGY_STRONG))
else if((shield_flags & SHIELD_ENERGY_STRONG))
final_damage *= 0.5
if(!is_energy_reflectable_projectile(object))
if(CHECK_BITFIELD(shield_flags, SHIELD_KINETIC_WEAK))
if((shield_flags & SHIELD_KINETIC_WEAK))
final_damage *= 2
else if(CHECK_BITFIELD(shield_flags, SHIELD_KINETIC_STRONG))
else if((shield_flags & SHIELD_KINETIC_STRONG))
final_damage *= 0.5
if(shootingthing.damage_type == STAMINA)
if(CHECK_BITFIELD(shield_flags, SHIELD_DISABLER_DISRUPTED))
if((shield_flags & SHIELD_DISABLER_DISRUPTED))
final_damage *= 3 //disablers melt these kinds of shields. Really meant more for holoshields.
else
final_damage = 0
+2 -2
View File
@@ -1290,9 +1290,9 @@
var/toxic_risk = min(round(spess_current_year - expiration_date * 0.01), 1)
for(var/obj/item/reagent_containers/food/snacks/S in contents)
if(prob(gross_risk))
ENABLE_BITFIELD(S.foodtype, GROSS)
S.foodtype |= GROSS
if(prob(toxic_risk))
ENABLE_BITFIELD(S.foodtype, TOXIC)
S.foodtype |= TOXIC
/obj/item/storage/box/mre/menu1
name = "\improper Nanotrasen MRE Ration Kit Menu 1"
+1 -1
View File
@@ -370,7 +370,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
desc = replacetext(desc, "Danger", "Bouncy")
desc = replacetext(desc, "robust", "safe")
desc = replacetext(desc, "heavier", "bouncier")
DISABLE_BITFIELD(flags_1, CONDUCT_1)
flags_1 &= ~(CONDUCT_1)
custom_materials = null
damtype = STAMINA
force += 3 //to compensate the higher stamina K.O. threshold compared to actual health.
+1 -1
View File
@@ -48,7 +48,7 @@
var/obj/item/clothing/mask/M = check
if(M.mask_adjusted)
M.adjustmask(H)
if(CHECK_BITFIELD(check.clothing_flags, ALLOWINTERNALS))
if((check.clothing_flags & ALLOWINTERNALS))
internals = TRUE
if(!internals)
+2 -2
View File
@@ -291,10 +291,10 @@
status = !status
if(status)
to_chat(user, "<span class='notice'>You resecure [src] and close the fuel tank.</span>")
DISABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER)
reagents.reagents_holder_flags &= ~(OPENCONTAINER)
else
to_chat(user, "<span class='notice'>[src] can now be attached, modified, and refuelled.</span>")
ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER)
reagents.reagents_holder_flags |= OPENCONTAINER
add_fingerprint(user)
/obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user)
+1
View File
@@ -58,6 +58,7 @@
desc = "A wondrous decorated Christmas tree."
icon_state = "pine_c"
icon_states = null
resistance_flags = INDESTRUCTIBLE //Sorry grinch, not this time
/obj/structure/flora/tree/pine/xmas/presents
icon_state = "pinepresents"
@@ -800,6 +800,13 @@
/datum/outfit/ghostcafe/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source)
..()
if (isplasmaman(H))
head = /obj/item/clothing/head/helmet/space/plasmaman
uniform = /obj/item/clothing/under/plasmaman
l_hand= /obj/item/tank/internals/plasmaman/belt/full
mask = /obj/item/clothing/mask/breath
return
var/suited = !preference_source || preference_source.prefs.jumpsuit_style == PREF_SUIT
if (CONFIG_GET(flag/grey_assistants))
uniform = suited ? /obj/item/clothing/under/color/grey : /obj/item/clothing/under/color/jumpskirt/grey
@@ -809,6 +816,10 @@
else
uniform = suited ? /obj/item/clothing/under/color/random : /obj/item/clothing/under/color/jumpskirt/random
/datum/outfit/ghostcafe/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source)
H.internal = H.get_item_for_held_index(1)
H.update_internals_hud_icon(1)
/obj/item/storage/box/syndie_kit/chameleon/ghostcafe
name = "ghost cafe costuming kit"
desc = "Look just the way you did in life - or better!"
+7 -1
View File
@@ -247,7 +247,13 @@ GLOBAL_LIST_EMPTY(crematoriums)
locked = TRUE
update_icon()
for(var/mob/living/simple_animal/jacq/J in conts)
visible_message("<b>[src]</b> cackles, <span class='spooky'>\"You'll nae get rid a me that easily!\"</span>")
playsound(loc, 'sound/spookoween/ahaha.ogg', 100, 0.25)
J.poof()
locked = FALSE
update_icon()
return
for(var/mob/living/M in conts)
if (M.stat != DEAD)
M.emote("scream")
+1 -1
View File
@@ -512,7 +512,7 @@ GLOBAL_LIST_EMPTY(station_turfs)
/turf/shove_act(mob/living/target, mob/living/user, pre_act = FALSE)
var/list/possibilities
for(var/obj/O in contents)
if(CHECK_BITFIELD(O.obj_flags, SHOVABLE_ONTO))
if((O.obj_flags & SHOVABLE_ONTO))
LAZYADD(possibilities, O)
else if(!O.CanPass(target, src))
return FALSE