Merge remote-tracking branch 'citadel/master' into actual_ghost_newscasters
This commit is contained in:
@@ -106,6 +106,9 @@
|
||||
|
||||
#define COMSIG_CLICK "atom_click" //from base of atom/Click(): (location, control, params, mob/user)
|
||||
#define COMSIG_CLICK_SHIFT "shift_click" //from base of atom/ShiftClick(): (/mob)
|
||||
#define COMPONENT_ALLOW_EXAMINATE 1
|
||||
#define COMPONENT_DENY_EXAMINATE 2 //Higher priority compared to the above one
|
||||
|
||||
#define COMSIG_CLICK_CTRL "ctrl_click" //from base of atom/CtrlClickOn(): (/mob)
|
||||
#define COMSIG_CLICK_ALT "alt_click" //from base of atom/AltClick(): (/mob)
|
||||
#define COMSIG_CLICK_CTRL_SHIFT "ctrl_shift_click" //from base of atom/CtrlShiftClick(/mob)
|
||||
@@ -159,7 +162,6 @@
|
||||
|
||||
// /mob signals
|
||||
#define COMSIG_MOB_EXAMINATE "mob_examinate" //from base of /mob/verb/examinate(): (atom/A)
|
||||
#define COMPONENT_ALLOW_EXAMINE 1
|
||||
#define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed)
|
||||
#define COMPONENT_BLOCK_DEATH_BROADCAST 1 //stops the death from being broadcasted in deadchat.
|
||||
#define COMSIG_MOB_GHOSTIZE "mob_ghostize" //from base of mob/Ghostize(): (can_reenter_corpse, special, penalize)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#define NO_ASSASSIN (1<<0)
|
||||
#define WAROPS_ALWAYS_ALLOWED (1<<1)
|
||||
#define USE_PREF_WEIGHTS (1<<2)
|
||||
|
||||
#define ONLY_RULESET (1<<0)
|
||||
#define HIGHLANDER_RULESET (1<<1)
|
||||
|
||||
@@ -56,11 +56,12 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
|
||||
|
||||
|
||||
//Movement Types
|
||||
#define GROUND (1<<0)
|
||||
#define FLYING (1<<1)
|
||||
#define VENTCRAWLING (1<<2)
|
||||
#define FLOATING (1<<3)
|
||||
#define UNSTOPPABLE (1<<4) //When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped.
|
||||
#define GROUND (1<<0)
|
||||
#define FLYING (1<<1)
|
||||
#define VENTCRAWLING (1<<2)
|
||||
#define FLOATING (1<<3)
|
||||
#define UNSTOPPABLE (1<<4) //When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped.
|
||||
#define CRAWLING (1<<5) //Applied if you're crawling around on the ground/resting.
|
||||
|
||||
//Fire and Acid stuff, for resistance_flags
|
||||
#define LAVA_PROOF (1<<0)
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
#define ADD_REAGENT 2 // reagent added
|
||||
#define REM_REAGENT 3 // reagent removed (may still exist)
|
||||
|
||||
#define THRESHOLD_UNHUSK 50 // health threshold for synthflesh/rezadone to unhusk someone
|
||||
|
||||
//reagent bitflags, used for altering how they works
|
||||
#define REAGENT_DEAD_PROCESS (1<<0) //calls on_mob_dead() if present in a dead body
|
||||
#define REAGENT_DONOTSPLIT (1<<1) //Do not split the chem at all during processing
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#define ROLE_BLOODSUCKER "bloodsucker"
|
||||
//#define ROLE_MONSTERHUNTER "monster hunter" Disabled for now
|
||||
#define ROLE_GHOSTCAFE "ghostcafe"
|
||||
#define ROLE_MINOR_ANTAG "minorantag"
|
||||
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
|
||||
//The gamemode specific ones are just so the gamemodes can query whether a player is old enough
|
||||
//(in game days played) to play that role
|
||||
|
||||
@@ -11,3 +11,8 @@
|
||||
#define SHOULD_CALL_PARENT(X)
|
||||
#define UNLINT(X) X
|
||||
#endif
|
||||
|
||||
/world/proc/enable_debugger()
|
||||
var/dll = world.GetConfig("env", "EXTOOLS_DLL")
|
||||
if (dll)
|
||||
call(dll, "debug_initialize")()
|
||||
|
||||
@@ -46,7 +46,9 @@
|
||||
|
||||
#define STATUS_EFFECT_SLEEPING /datum/status_effect/incapacitating/sleeping //the affected is asleep
|
||||
|
||||
#define STATUS_EFFECT_TASED /datum/status_effect/no_combat_mode/electrode/ //the affected has been tased, preventing fine muscle control
|
||||
#define STATUS_EFFECT_TASED_WEAK /datum/status_effect/electrode //not as crippling, just slows down
|
||||
|
||||
#define STATUS_EFFECT_TASED /datum/status_effect/electrode/no_combat_mode //the affected has been tased, preventing fine muscle control
|
||||
|
||||
#define STATUS_EFFECT_PACIFY /datum/status_effect/pacify //the affected is pacified, preventing direct hostile actions
|
||||
|
||||
|
||||
@@ -233,9 +233,9 @@
|
||||
#define SLEEPING_CARP_TRAIT "sleeping_carp"
|
||||
#define RISING_BASS_TRAIT "rising_bass"
|
||||
#define ABDUCTOR_ANTAGONIST "abductor-antagonist"
|
||||
#define NUKEOP_ANTAGONIST "nukeop-antagonist"
|
||||
#define MADE_UNCLONEABLE "made-uncloneable"
|
||||
#define TIMESTOP_TRAIT "timestop"
|
||||
#define NUKEOP_TRAIT "nuke-op"
|
||||
#define CLOWNOP_TRAIT "clown-op"
|
||||
#define MEGAFAUNA_TRAIT "megafauna"
|
||||
#define DEATHSQUAD_TRAIT "deathsquad"
|
||||
|
||||
+12
-1
@@ -1,6 +1,17 @@
|
||||
#define PLURALITY_VOTING 0
|
||||
#define APPROVAL_VOTING 1
|
||||
#define RANKED_CHOICE_VOTING 2
|
||||
#define SCHULZE_VOTING 2
|
||||
#define SCORE_VOTING 3
|
||||
#define MAJORITY_JUDGEMENT_VOTING 4
|
||||
#define INSTANT_RUNOFF_VOTING 5
|
||||
|
||||
GLOBAL_LIST_INIT(vote_score_options,list("Bad","Poor","Acceptable","Good","Great"))
|
||||
|
||||
GLOBAL_LIST_INIT(vote_type_names,list(\
|
||||
"Plurality (default)" = PLURALITY_VOTING,\
|
||||
"Approval" = APPROVAL_VOTING,\
|
||||
"IRV (single winner ranked choice)" = INSTANT_RUNOFF_VOTING,\
|
||||
"Schulze (ranked choice, higher result=better)" = SCHULZE_VOTING,\
|
||||
"Raw Score (returns results from 0 to 1, winner is 1)" = SCORE_VOTING,\
|
||||
"Majority Judgement (single-winner score voting)" = MAJORITY_JUDGEMENT_VOTING,\
|
||||
))
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
#define POPCOUNT_SHUTTLE_ESCAPEES "shuttle_escapees" //Emergency shuttle only.
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/gather_roundend_feedback()
|
||||
var/datum/station_state/end_state = new /datum/station_state()
|
||||
end_state.count()
|
||||
station_integrity = min(PERCENT(GLOB.start_state.score(end_state)), 100)
|
||||
gather_antag_data()
|
||||
record_nuke_disk_location()
|
||||
var/json_file = file("[GLOB.log_directory]/round_end_data.json")
|
||||
@@ -71,9 +74,6 @@
|
||||
mob_data += list("name" = m.name, "typepath" = m.type)
|
||||
var/pos = length(file_data["[escaped]"]["[category]"]) + 1
|
||||
file_data["[escaped]"]["[category]"]["[pos]"] = mob_data
|
||||
var/datum/station_state/end_state = new /datum/station_state()
|
||||
end_state.count()
|
||||
var/station_integrity = min(PERCENT(GLOB.start_state.score(end_state)), 100)
|
||||
file_data["additional data"]["station integrity"] = station_integrity
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
SSblackbox.record_feedback("nested tally", "round_end_stats", num_survivors, list("survivors", "total"))
|
||||
@@ -111,7 +111,14 @@
|
||||
|
||||
if(A.objectives.len)
|
||||
for(var/datum/objective/O in A.objectives)
|
||||
var/result = O.check_completion() ? "SUCCESS" : "FAIL"
|
||||
var/result = "UNKNOWN"
|
||||
var/actual_result = O.check_completion()
|
||||
if(actual_result >= 1)
|
||||
result = "SUCCESS"
|
||||
else if(actual_result <= 0)
|
||||
result = "FAIL"
|
||||
else
|
||||
result = "[actual_result*100]%"
|
||||
antag_info["objectives"] += list(list("objective_type"=O.type,"text"=O.explanation_text,"result"=result))
|
||||
SSblackbox.record_feedback("associative", "antagonists", 1, antag_info)
|
||||
|
||||
@@ -550,10 +557,16 @@
|
||||
var/list/objective_parts = list()
|
||||
var/count = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
if(objective.check_completion())
|
||||
objective_parts += "<b>Objective #[count]</b>: [objective.explanation_text] <span class='greentext'>Success!</span>"
|
||||
if(objective.completable)
|
||||
var/completion = objective.check_completion()
|
||||
if(completion >= 1)
|
||||
objective_parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</span>"
|
||||
else if(completion <= 0)
|
||||
objective_parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
else
|
||||
objective_parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='yellowtext'>[completion*100]%</span>"
|
||||
else
|
||||
objective_parts += "<b>Objective #[count]</b>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
objective_parts += "<B>Objective #[count]</B>: [objective.explanation_text]"
|
||||
count++
|
||||
return objective_parts.Join("<br>")
|
||||
|
||||
|
||||
@@ -1537,4 +1537,9 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
if(190)
|
||||
return "."
|
||||
if(189)
|
||||
return "-"
|
||||
return "-"
|
||||
|
||||
/proc/generate_items_inside(list/items_list, where_to)
|
||||
for(var/each_item in items_list)
|
||||
for(var/i in 1 to items_list[each_item])
|
||||
new each_item(where_to)
|
||||
|
||||
@@ -319,9 +319,11 @@
|
||||
/mob/proc/ShiftClickOn(atom/A)
|
||||
A.ShiftClick(src)
|
||||
return
|
||||
|
||||
/atom/proc/ShiftClick(mob/user)
|
||||
SEND_SIGNAL(src, COMSIG_CLICK_SHIFT, user)
|
||||
user.examinate(src)
|
||||
var/flags = SEND_SIGNAL(src, COMSIG_CLICK_SHIFT, user)
|
||||
if(!(flags & COMPONENT_DENY_EXAMINATE) && user.client && (user.client.eye == user || user.client.eye == user.loc || flags & COMPONENT_ALLOW_EXAMINATE))
|
||||
user.examinate(src)
|
||||
return
|
||||
|
||||
/*
|
||||
|
||||
@@ -364,6 +364,29 @@
|
||||
runnable_modes[M] = final_weight
|
||||
return runnable_modes
|
||||
|
||||
/datum/controller/configuration/proc/get_runnable_storytellers()
|
||||
var/list/datum/dynamic_storyteller/runnable_storytellers = new
|
||||
var/list/probabilities = Get(/datum/config_entry/keyed_list/storyteller_weight)
|
||||
var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust)
|
||||
for(var/T in storyteller_cache)
|
||||
var/datum/dynamic_storyteller/S = T
|
||||
var/config_tag = initial(S.config_tag)
|
||||
var/final_weight = initial(S.weight)
|
||||
if(probabilities[config_tag]<=0)
|
||||
continue
|
||||
final_weight = probabilities[config_tag]
|
||||
if(SSpersistence.saved_storytellers.len == 3 && repeated_mode_adjust.len == 3)
|
||||
var/name = initial(S.name)
|
||||
var/recent_round = min(SSpersistence.saved_storytellers.Find(name),3)
|
||||
var/adjustment = 0
|
||||
while(recent_round)
|
||||
adjustment += repeated_mode_adjust[recent_round]
|
||||
recent_round = SSpersistence.saved_modes.Find(name,recent_round+1,0)
|
||||
final_weight *= ((100-adjustment)/100)
|
||||
runnable_storytellers[S] = final_weight
|
||||
return runnable_storytellers
|
||||
|
||||
|
||||
/datum/controller/configuration/proc/get_runnable_midround_modes(crew)
|
||||
var/list/datum/game_mode/runnable_modes = new
|
||||
var/list/probabilities = Get(/datum/config_entry/keyed_list/probability)
|
||||
|
||||
@@ -88,3 +88,7 @@
|
||||
/datum/config_entry/number/dynamic_warops_cost
|
||||
config_entry_value = 10
|
||||
min_val = 0
|
||||
|
||||
/datum/config_entry/keyed_list/storyteller_weight
|
||||
key_mode = KEY_MODE_TEXT
|
||||
value_mode = VALUE_MODE_NUM
|
||||
|
||||
@@ -267,6 +267,9 @@
|
||||
|
||||
/datum/config_entry/flag/tgstyle_maprotation
|
||||
|
||||
/datum/config_entry/string/map_vote_type
|
||||
config_entry_value = "SCORE"
|
||||
|
||||
/datum/config_entry/number/maprotatechancedelta
|
||||
config_entry_value = 0.75
|
||||
min_val = 0
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/datum/config_entry/number/snowflake_plushie_prob
|
||||
config_entry_value = 50
|
||||
|
||||
/datum/config_entry/keyed_list/snowflake_plushies
|
||||
key_mode = KEY_MODE_TEXT
|
||||
value_mode = VALUE_MODE_TEXT
|
||||
@@ -31,15 +31,18 @@ SUBSYSTEM_DEF(fail2topic)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/fail2topic/fire()
|
||||
for(var/i in 1 to length(rate_limiting))
|
||||
var/ip = rate_limiting[i]
|
||||
var/last_attempt = rate_limiting[ip]
|
||||
if (world.time - last_attempt > rate_limit)
|
||||
rate_limiting -= ip
|
||||
fail_counts -= ip
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
if(length(rate_limiting))
|
||||
var/i = 1
|
||||
while(i <= length(rate_limiting))
|
||||
var/ip = rate_limiting[i]
|
||||
var/last_attempt = rate_limiting[ip]
|
||||
if(world.time - last_attempt > rate_limit)
|
||||
rate_limiting -= ip
|
||||
fail_counts -= ip
|
||||
else //if we remove that, and the next element is in its place. check that instead of incrementing.
|
||||
++i
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/fail2topic/Shutdown()
|
||||
DropFirewallRule()
|
||||
|
||||
@@ -13,7 +13,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
var/list/saved_messages = list()
|
||||
var/list/saved_modes = list(1,2,3)
|
||||
var/list/saved_dynamic_rules = list(list(),list(),list())
|
||||
var/list/saved_storytellers = list("foo","bar","baz","foo again","bar again")
|
||||
var/list/saved_storytellers = list("foo","bar","baz")
|
||||
var/list/saved_maps
|
||||
var/list/saved_trophies = list()
|
||||
var/list/spawned_objects = list()
|
||||
@@ -191,6 +191,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
if(!json)
|
||||
return
|
||||
saved_storytellers = json["data"]
|
||||
saved_storytellers.len = 3
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadRecentMaps()
|
||||
var/json_file = file("data/RecentMaps.json")
|
||||
@@ -429,9 +430,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/CollectStoryteller(var/datum/game_mode/dynamic/mode)
|
||||
saved_storytellers.len = 5
|
||||
saved_storytellers[5] = saved_storytellers[4]
|
||||
saved_storytellers[4] = saved_storytellers[3]
|
||||
saved_storytellers.len = 3
|
||||
saved_storytellers[3] = saved_storytellers[2]
|
||||
saved_storytellers[2] = saved_storytellers[1]
|
||||
saved_storytellers[1] = mode.storyteller.name
|
||||
|
||||
@@ -35,7 +35,7 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
|
||||
var/list/my_quirks = cli.prefs.all_quirks.Copy()
|
||||
var/list/cut
|
||||
if(job?.blacklisted_quirks)
|
||||
cut = filter_quirks(my_quirks, job)
|
||||
cut = filter_quirks(my_quirks, job.blacklisted_quirks)
|
||||
for(var/V in my_quirks)
|
||||
var/datum/quirk/Q = quirks[V]
|
||||
if(Q)
|
||||
@@ -63,11 +63,11 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
|
||||
for(var/i in quirk_names)
|
||||
. += quirk_points_by_name(i)
|
||||
|
||||
/datum/controller/subsystem/processing/quirks/proc/filter_quirks(list/our_quirks, datum/job/job)
|
||||
/datum/controller/subsystem/processing/quirks/proc/filter_quirks(list/our_quirks, list/blacklisted_quirks)
|
||||
var/list/cut = list()
|
||||
var/list/banned_names = list()
|
||||
var/pointscut = 0
|
||||
for(var/i in job.blacklisted_quirks)
|
||||
for(var/i in blacklisted_quirks)
|
||||
var/name = quirk_name_by_path(i)
|
||||
if(name)
|
||||
banned_names += name
|
||||
|
||||
@@ -68,6 +68,8 @@ SUBSYSTEM_DEF(ticker)
|
||||
|
||||
var/modevoted = FALSE //Have we sent a vote for the gamemode?
|
||||
|
||||
var/station_integrity = 100 // stored at roundend for use in some antag goals
|
||||
|
||||
/datum/controller/subsystem/ticker/Initialize(timeofday)
|
||||
load_mode()
|
||||
|
||||
@@ -363,7 +365,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
var/turf/epi = bomb.loc
|
||||
qdel(bomb)
|
||||
if(epi)
|
||||
explosion(epi, 0, 256, 512, 0, TRUE, TRUE, 0, TRUE)
|
||||
explosion(epi, 512, 0, 0, 0, TRUE, TRUE, 0, TRUE)
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/create_characters()
|
||||
for(var/mob/dead/new_player/player in GLOB.player_list)
|
||||
@@ -475,7 +477,18 @@ SUBSYSTEM_DEF(ticker)
|
||||
if(CONFIG_GET(flag/tgstyle_maprotation))
|
||||
INVOKE_ASYNC(SSmapping, /datum/controller/subsystem/mapping/.proc/maprotate)
|
||||
else
|
||||
SSvote.initiate_vote("map","server",TRUE)
|
||||
var/vote_type = CONFIG_GET(string/map_vote_type)
|
||||
switch(vote_type)
|
||||
if("PLURALITY")
|
||||
SSvote.initiate_vote("map","server",hideresults=TRUE)
|
||||
if("APPROVAL")
|
||||
SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = APPROVAL_VOTING)
|
||||
if("IRV")
|
||||
SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = INSTANT_RUNOFF_VOTING)
|
||||
if("SCORE")
|
||||
SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = MAJORITY_JUDGEMENT_VOTING)
|
||||
// fallback
|
||||
SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = MAJORITY_JUDGEMENT_VOTING)
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/HasRoundStarted()
|
||||
return current_state >= GAME_STATE_PLAYING
|
||||
|
||||
@@ -188,22 +188,47 @@ SUBSYSTEM_DEF(vote)
|
||||
choices[score_name]++
|
||||
|
||||
/datum/controller/subsystem/vote/proc/calculate_scores(var/blackbox_text)
|
||||
var/list/scores_by_choice = list()
|
||||
for(var/choice in choices)
|
||||
scores_by_choice += "[choice]"
|
||||
scores_by_choice["[choice]"] = list()
|
||||
scores += "[choice]"
|
||||
scores["[choice]"] = 0
|
||||
for(var/ckey in voted)
|
||||
var/list/this_vote = voted[ckey]
|
||||
for(var/choice in choices)
|
||||
if("[choice]" in this_vote && "[choice]" in scores_by_choice)
|
||||
sorted_insert(scores_by_choice["[choice]"],this_vote["[choice]"],/proc/cmp_numeric_asc)
|
||||
var/middle_score = round(GLOB.vote_score_options.len/2,1)
|
||||
for(var/score_name in scores_by_choice)
|
||||
var/list/score = scores_by_choice[score_name]
|
||||
for(var/S in score)
|
||||
scores[score_name] += S-middle_score
|
||||
for(var/choice in this_vote)
|
||||
scores["[choice]"] += this_vote["[choice]"]
|
||||
var/min_score = 100
|
||||
var/max_score = -100
|
||||
for(var/score_name in scores) // normalize the scores from 0-1
|
||||
max_score=max(max_score,scores[score_name])
|
||||
min_score=min(min_score,scores[score_name])
|
||||
for(var/score_name in scores)
|
||||
if(max_score == min_score)
|
||||
scores[score_name] = 1
|
||||
else
|
||||
scores[score_name] = (scores[score_name]-min_score)/(max_score-min_score)
|
||||
SSblackbox.record_feedback("nested tally","voting",scores[score_name],list(blackbox_text,"Total scores",score_name))
|
||||
|
||||
/datum/controller/subsystem/vote/proc/get_runoff_results(var/blackbox_text)
|
||||
var/already_lost_runoff = list()
|
||||
var/list/cur_choices = choices.Copy()
|
||||
for(var/ckey in voted)
|
||||
choices[choices[voted[ckey][1]]]++ // jesus christ how horrifying
|
||||
for(var/_this_var_unused_ignore_it in 1 to choices.len) // if it takes more than this something REALLY wrong happened
|
||||
for(var/ckey in voted)
|
||||
cur_choices[cur_choices[voted[ckey][1]]]++ // jesus christ how horrifying
|
||||
var/least_vote = 100000
|
||||
var/least_voted
|
||||
for(var/i in 1 to cur_choices.len)
|
||||
var/option = cur_choices[i]
|
||||
if(cur_choices[option] > voted.len/2)
|
||||
return list(option)
|
||||
else if(cur_choices[option] < least_vote && !(option in already_lost_runoff))
|
||||
least_vote = cur_choices[option]
|
||||
least_voted = i
|
||||
already_lost_runoff += cur_choices[least_voted]
|
||||
for(var/ckey in voted)
|
||||
voted[ckey] -= least_voted
|
||||
for(var/option in cur_choices)
|
||||
cur_choices[option] = 0
|
||||
|
||||
/datum/controller/subsystem/vote/proc/announce_result()
|
||||
var/vote_title_text
|
||||
@@ -214,32 +239,29 @@ SUBSYSTEM_DEF(vote)
|
||||
else
|
||||
text += "<b>[capitalize(mode)] Vote</b>"
|
||||
vote_title_text = "[capitalize(mode)] Vote"
|
||||
if(vote_system == RANKED_CHOICE_VOTING)
|
||||
if(vote_system == SCHULZE_VOTING)
|
||||
calculate_condorcet_votes(vote_title_text)
|
||||
if(vote_system == SCORE_VOTING)
|
||||
calculate_majority_judgement_vote(vote_title_text)
|
||||
calculate_scores(vote_title_text)
|
||||
var/list/winners = get_result()
|
||||
if(vote_system == MAJORITY_JUDGEMENT_VOTING)
|
||||
calculate_majority_judgement_vote(vote_title_text) // nothing uses this at the moment
|
||||
var/list/winners = vote_system == INSTANT_RUNOFF_VOTING ? get_runoff_results() : get_result()
|
||||
var/was_roundtype_vote = mode == "roundtype" || mode == "dynamic"
|
||||
if(winners.len > 0)
|
||||
if(was_roundtype_vote)
|
||||
stored_gamemode_votes = list()
|
||||
if(!obfuscated && vote_system == RANKED_CHOICE_VOTING)
|
||||
text += "\nIt should be noted that this is not a raw tally of votes (impossible in ranked choice) but the score determined by the schulze method of voting, so the numbers will look weird!"
|
||||
if(mode == "mode tiers")
|
||||
for(var/score_name in scores)
|
||||
var/score = scores[score_name]
|
||||
if(!score)
|
||||
score = 0
|
||||
text = "\n<b>[score_name]:</b> [obfuscated ? "???" : score]"
|
||||
else
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
var/votes = choices[choices[i]]
|
||||
if(!votes)
|
||||
votes = 0
|
||||
if(was_roundtype_vote)
|
||||
stored_gamemode_votes[choices[i]] = votes
|
||||
text += "\n<b>[choices[i]]:</b> [obfuscated ? "???" : votes]" //CIT CHANGE - adds obfuscated votes
|
||||
if(!obfuscated)
|
||||
if(vote_system == SCHULZE_VOTING)
|
||||
text += "\nIt should be noted that this is not a raw tally of votes (impossible in ranked choice) but the score determined by the schulze method of voting, so the numbers will look weird!"
|
||||
if(vote_system == MAJORITY_JUDGEMENT_VOTING)
|
||||
text += "\nIt should be noted that this is not a raw tally of votes but the number of runoffs done by majority judgement!"
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
var/votes = choices[choices[i]]
|
||||
if(!votes)
|
||||
votes = 0
|
||||
if(was_roundtype_vote)
|
||||
stored_gamemode_votes[choices[i]] = votes
|
||||
text += "\n<b>[choices[i]]:</b> [obfuscated ? "???" : votes]" //CIT CHANGE - adds obfuscated votes
|
||||
if(mode != "custom")
|
||||
if(winners.len > 1 && !obfuscated) //CIT CHANGE - adds obfuscated votes
|
||||
text = "\n<b>Vote Tied Between:</b>"
|
||||
@@ -249,6 +271,15 @@ SUBSYSTEM_DEF(vote)
|
||||
text += "\n<b>Vote Result: [obfuscated ? "???" : .]</b>" //CIT CHANGE - adds obfuscated votes
|
||||
else
|
||||
text += "\n<b>Did not vote:</b> [GLOB.clients.len-voted.len]"
|
||||
else if(vote_system == SCORE_VOTING)
|
||||
for(var/score_name in scores)
|
||||
var/score = scores[score_name]
|
||||
if(!score)
|
||||
score = 0
|
||||
if(was_roundtype_vote)
|
||||
stored_gamemode_votes[score_name] = score
|
||||
text = "\n<b>[score_name]:</b> [obfuscated ? "???" : score]"
|
||||
. = 1
|
||||
else
|
||||
text += "<b>Vote Result: Inconclusive - No Votes!</b>"
|
||||
log_vote(text)
|
||||
@@ -258,7 +289,7 @@ SUBSYSTEM_DEF(vote)
|
||||
if(APPROVAL_VOTING,PLURALITY_VOTING)
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
SSblackbox.record_feedback("nested tally","voting",choices[choices[i]],list(vote_title_text,choices[i]))
|
||||
if(RANKED_CHOICE_VOTING)
|
||||
if(SCHULZE_VOTING,INSTANT_RUNOFF_VOTING)
|
||||
for(var/i=1,i<=voted.len,i++)
|
||||
var/list/myvote = voted[voted[i]]
|
||||
if(islist(myvote))
|
||||
@@ -266,13 +297,18 @@ SUBSYSTEM_DEF(vote)
|
||||
SSblackbox.record_feedback("nested tally","voting",1,list(vote_title_text,"[j]\th",choices[myvote[j]]))
|
||||
if(obfuscated) //CIT CHANGE - adds obfuscated votes. this messages admins with the vote's true results
|
||||
var/admintext = "Obfuscated results"
|
||||
if(vote_system == RANKED_CHOICE_VOTING)
|
||||
admintext += "\nIt should be noted that this is not a raw tally of votes (impossible in ranked choice) but the score determined by the schulze method of voting, so the numbers will look weird!"
|
||||
else if(vote_system == SCORE_VOTING)
|
||||
admintext += "\nIt should be noted that this is not a raw tally of votes but the number of runoffs done by majority judgement!"
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
var/votes = choices[choices[i]]
|
||||
admintext += "\n<b>[choices[i]]:</b> [votes]"
|
||||
if(vote_system != SCORE_VOTING)
|
||||
if(vote_system == SCHULZE_VOTING)
|
||||
admintext += "\nIt should be noted that this is not a raw tally of votes (impossible in ranked choice) but the score determined by the schulze method of voting, so the numbers will look weird!"
|
||||
else if(vote_system == MAJORITY_JUDGEMENT_VOTING)
|
||||
admintext += "\nIt should be noted that this is not a raw tally of votes but the number of runoffs done by majority judgement!"
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
var/votes = choices[choices[i]]
|
||||
admintext += "\n<b>[choices[i]]:</b> [votes]"
|
||||
else
|
||||
for(var/i=1,i<=scores.len,i++)
|
||||
var/score = scores[scores[i]]
|
||||
admintext += "\n<b>[scores[i]]:</b> [score]"
|
||||
message_admins(admintext)
|
||||
return .
|
||||
|
||||
@@ -316,15 +352,13 @@ SUBSYSTEM_DEF(vote)
|
||||
if("dynamic")
|
||||
if(SSticker.current_state > GAME_STATE_PREGAME)//Don't change the mode if the round already started.
|
||||
return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.")
|
||||
if(. == "Secret")
|
||||
GLOB.master_mode = "secret"
|
||||
SSticker.save_mode(.)
|
||||
message_admins("The gamemode has been voted for, and has been changed to: [GLOB.master_mode]")
|
||||
log_admin("Gamemode has been voted for and switched to: [GLOB.master_mode].")
|
||||
else
|
||||
GLOB.master_mode = "dynamic"
|
||||
var/datum/dynamic_storyteller/S = config.pick_storyteller(.)
|
||||
GLOB.dynamic_storyteller_type = S
|
||||
GLOB.master_mode = "dynamic"
|
||||
var/list/runnable_storytellers = config.get_runnable_storytellers()
|
||||
for(var/T in runnable_storytellers)
|
||||
var/datum/dynamic_storyteller/S = T
|
||||
runnable_storytellers[S] *= scores[initial(S.name)]
|
||||
var/datum/dynamic_storyteller/S = pickweightAllowZero(runnable_storytellers)
|
||||
GLOB.dynamic_storyteller_type = S
|
||||
if("map")
|
||||
var/datum/map_config/VM = config.maplist[.]
|
||||
message_admins("The map has been voted for and will change to: [VM.map_name]")
|
||||
@@ -375,7 +409,7 @@ SUBSYSTEM_DEF(vote)
|
||||
voted[usr.ckey] = list(vote)
|
||||
choices[choices[vote]]++
|
||||
return vote
|
||||
if(RANKED_CHOICE_VOTING)
|
||||
if(SCHULZE_VOTING,INSTANT_RUNOFF_VOTING)
|
||||
if(usr.ckey in voted)
|
||||
if(vote in voted[usr.ckey])
|
||||
voted[usr.ckey] -= vote
|
||||
@@ -384,7 +418,7 @@ SUBSYSTEM_DEF(vote)
|
||||
voted[usr.ckey] = list()
|
||||
voted[usr.ckey] += vote
|
||||
saved -= usr.ckey
|
||||
if(SCORE_VOTING)
|
||||
if(SCORE_VOTING,MAJORITY_JUDGEMENT_VOTING)
|
||||
if(!(usr.ckey in voted))
|
||||
voted += usr.ckey
|
||||
voted[usr.ckey] = list()
|
||||
@@ -444,19 +478,16 @@ SUBSYSTEM_DEF(vote)
|
||||
if("dynamic")
|
||||
for(var/T in config.storyteller_cache)
|
||||
var/datum/dynamic_storyteller/S = T
|
||||
var/recent_rounds = 0
|
||||
for(var/i in 1 to SSpersistence.saved_storytellers.len)
|
||||
if(SSpersistence.saved_storytellers[i] == initial(S.name))
|
||||
recent_rounds++
|
||||
if(recent_rounds < initial(S.weight))
|
||||
var/list/probabilities = CONFIG_GET(keyed_list/storyteller_weight)
|
||||
if(probabilities[initial(S.config_tag)] > 0)
|
||||
choices.Add(initial(S.name))
|
||||
choice_descs.Add(initial(S.desc))
|
||||
choices.Add("Secret")
|
||||
choice_descs.Add("Standard secret. Switches mode if it wins.")
|
||||
if("custom")
|
||||
question = stripped_input(usr,"What is the vote for?")
|
||||
if(!question)
|
||||
return 0
|
||||
var/system_string = input(usr,"Which voting type?",GLOB.vote_type_names[1]) in GLOB.vote_type_names
|
||||
vote_system = GLOB.vote_type_names[system_string]
|
||||
for(var/i=1,i<=10,i++)
|
||||
var/option = capitalize(stripped_input(usr,"Please enter an option or hit cancel to finish"))
|
||||
if(!option || mode || !usr.client)
|
||||
@@ -514,9 +545,9 @@ SUBSYSTEM_DEF(vote)
|
||||
. += "<h3>Vote one.</h3>"
|
||||
if(APPROVAL_VOTING)
|
||||
. += "<h3>Vote any number of choices.</h3>"
|
||||
if(RANKED_CHOICE_VOTING)
|
||||
if(SCHULZE_VOTING,INSTANT_RUNOFF_VOTING)
|
||||
. += "<h3>Vote by order of preference. Revoting will demote to the bottom. 1 is your favorite, and higher numbers are worse.</h3>"
|
||||
if(SCORE_VOTING)
|
||||
if(SCORE_VOTING,MAJORITY_JUDGEMENT_VOTING)
|
||||
. += "<h3>Grade the candidates by how much you like them.</h3>"
|
||||
. += "<h3>No-votes have no power--your opinion is only heard if you vote!</h3>"
|
||||
. += "Time Left: [DisplayTimeText(end_time-world.time)]<hr><ul>"
|
||||
@@ -536,7 +567,7 @@ SUBSYSTEM_DEF(vote)
|
||||
if(choice_descs.len >= i)
|
||||
. += "<li>[choice_descs[i]]</li>"
|
||||
. += "</ul><hr>"
|
||||
if(RANKED_CHOICE_VOTING)
|
||||
if(SCHULZE_VOTING,INSTANT_RUNOFF_VOTING)
|
||||
var/list/myvote = voted[C.ckey]
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
var/vote = (islist(myvote) ? (myvote.Find(i)) : 0)
|
||||
@@ -553,7 +584,7 @@ SUBSYSTEM_DEF(vote)
|
||||
. += "(Saved!)"
|
||||
. += "(<a href='?src=[REF(src)];vote=load'>Load vote from save</a>)"
|
||||
. += "(<a href='?src=[REF(src)];vote=reset'>Reset votes</a>)"
|
||||
if(SCORE_VOTING)
|
||||
if(SCORE_VOTING,MAJORITY_JUDGEMENT_VOTING)
|
||||
var/list/myvote = voted[C.ckey]
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
. += "<li><b>[choices[i]]</b>"
|
||||
@@ -656,7 +687,7 @@ SUBSYSTEM_DEF(vote)
|
||||
voted[usr.ckey] = SSpersistence.saved_votes[usr.ckey][mode]
|
||||
if(islist(voted[usr.ckey]))
|
||||
var/malformed = FALSE
|
||||
if(vote_system == SCORE_VOTING)
|
||||
if(vote_system == SCORE_VOTING || vote_system == MAJORITY_JUDGEMENT_VOTING)
|
||||
for(var/thing in voted[usr.ckey])
|
||||
if(!(thing in choices))
|
||||
malformed = TRUE
|
||||
@@ -670,7 +701,7 @@ SUBSYSTEM_DEF(vote)
|
||||
to_chat(usr,"Your saved vote was malformed! Start over!")
|
||||
voted -= usr.ckey
|
||||
else
|
||||
if(vote_system == SCORE_VOTING)
|
||||
if(vote_system == SCORE_VOTING || vote_system == MAJORITY_JUDGEMENT_VOTING)
|
||||
submit_vote(round(text2num(href_list["vote"])),round(text2num(href_list["score"])))
|
||||
else
|
||||
submit_vote(round(text2num(href_list["vote"])))
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/datum/crafting_recipe/bonearmor
|
||||
name = "Bone Armor"
|
||||
result = /obj/item/clothing/suit/armor/bone
|
||||
time = 30
|
||||
reqs = list(/obj/item/stack/sheet/bone = 6)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/bonetalisman
|
||||
name = "Bone Talisman"
|
||||
result = /obj/item/clothing/accessory/talisman
|
||||
@@ -29,13 +22,6 @@
|
||||
/obj/item/stack/sheet/sinew = 1)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/skullhelm
|
||||
name = "Skull Helmet"
|
||||
result = /obj/item/clothing/head/helmet/skull
|
||||
time = 30
|
||||
reqs = list(/obj/item/stack/sheet/bone = 4)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/goliathcloak
|
||||
name = "Goliath Cloak"
|
||||
result = /obj/item/clothing/suit/hooded/cloak/goliath
|
||||
@@ -62,13 +48,6 @@
|
||||
/obj/item/stack/sheet/sinew = 2)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/bonedagger
|
||||
name = "Bone Dagger"
|
||||
result = /obj/item/kitchen/knife/combat/bone
|
||||
time = 20
|
||||
reqs = list(/obj/item/stack/sheet/bone = 2)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/bonespear
|
||||
name = "Bone Spear"
|
||||
result = /obj/item/twohanded/bonespear
|
||||
|
||||
@@ -25,6 +25,7 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
var/unlock_code
|
||||
var/failsafe_code
|
||||
var/datum/ui_state/checkstate
|
||||
var/debug = FALSE
|
||||
|
||||
/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20, datum/ui_state/_checkstate)
|
||||
if(!isitem(parent))
|
||||
@@ -152,7 +153,7 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
if(I.restricted_roles.len)
|
||||
var/is_inaccessible = 1
|
||||
for(var/R in I.restricted_roles)
|
||||
if(R == user.mind.assigned_role)
|
||||
if(R == user.mind.assigned_role || debug)
|
||||
is_inaccessible = 0
|
||||
if(is_inaccessible)
|
||||
continue
|
||||
@@ -294,4 +295,4 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
if(!T)
|
||||
return
|
||||
explosion(T,1,2,3)
|
||||
qdel(parent) //Alternatively could brick the uplink.
|
||||
qdel(parent) //Alternatively could brick the uplink.
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
/datum/element/mob_holder
|
||||
element_flags = ELEMENT_BESPOKE
|
||||
id_arg_index = 2
|
||||
var/worn_state
|
||||
var/alt_worn
|
||||
var/right_hand
|
||||
var/left_hand
|
||||
var/inv_slots
|
||||
var/proctype //if present, will be invoked on headwear generation.
|
||||
|
||||
/datum/element/mob_holder/Attach(datum/target, _worn_state, _alt_worn, _right_hand, _left_hand, _inv_slots = NONE, _proctype)
|
||||
. = ..()
|
||||
|
||||
if(!isliving(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
|
||||
worn_state = _worn_state
|
||||
alt_worn = _alt_worn
|
||||
right_hand = _right_hand
|
||||
left_hand = _left_hand
|
||||
inv_slots = _inv_slots
|
||||
proctype = _proctype
|
||||
|
||||
RegisterSignal(target, COMSIG_CLICK_ALT, .proc/mob_try_pickup)
|
||||
RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/on_examine)
|
||||
|
||||
/datum/element/mob_holder/Detach(datum/source, force)
|
||||
. = ..()
|
||||
UnregisterSignal(source, COMSIG_CLICK_ALT)
|
||||
UnregisterSignal(source, COMSIG_PARENT_EXAMINE)
|
||||
|
||||
/datum/element/mob_holder/proc/on_examine(mob/living/source, mob/user, list/examine_list)
|
||||
if(ishuman(user) && !istype(source.loc, /obj/item/clothing/head/mob_holder))
|
||||
examine_list += "<span class='notice'>Looks like [source.p_they(TRUE)] can be picked up with <b>Alt+Click</b>!</span>"
|
||||
|
||||
/datum/element/mob_holder/proc/mob_try_pickup(mob/living/source, mob/user)
|
||||
if(!ishuman(user) || !user.Adjacent(source) || user.incapacitated())
|
||||
return FALSE
|
||||
if(user.get_active_held_item())
|
||||
to_chat(user, "<span class='warning'>Your hands are full!</span>")
|
||||
return FALSE
|
||||
if(source.buckled)
|
||||
to_chat(user, "<span class='warning'>[src] is buckled to something!</span>")
|
||||
return FALSE
|
||||
if(source == user)
|
||||
to_chat(user, "<span class='warning'>You can't pick yourself up.</span>")
|
||||
return FALSE
|
||||
source.visible_message("<span class='warning'>[user] starts picking up [source].</span>", \
|
||||
"<span class='userdanger'>[user] starts picking you up!</span>")
|
||||
if(!do_after(user, 20, target = src) || source.buckled)
|
||||
return FALSE
|
||||
|
||||
source.visible_message("<span class='warning'>[user] picks up [source]!</span>", \
|
||||
"<span class='userdanger'>[user] picks you up!</span>")
|
||||
to_chat(user, "<span class='notice'>You pick [src] up.</span>")
|
||||
source.drop_all_held_items()
|
||||
var/obj/item/clothing/head/mob_holder/holder = new(get_turf(source), source, worn_state, alt_worn, right_hand, left_hand, inv_slots)
|
||||
if(proctype)
|
||||
INVOKE_ASYNC(src, proctype, source, holder, user)
|
||||
user.put_in_hands(holder)
|
||||
return TRUE
|
||||
|
||||
/datum/element/mob_holder/proc/drone_worn_icon(mob/living/simple_animal/drone/D, obj/item/clothing/head/mob_holder/holder, mob/user)
|
||||
var/new_state = "[D.visualAppearence]_hat"
|
||||
holder.item_state = new_state
|
||||
holder.icon_state = new_state
|
||||
|
||||
|
||||
//The item itself,
|
||||
/obj/item/clothing/head/mob_holder
|
||||
name = "bugged mob"
|
||||
desc = "Yell at coderbrush."
|
||||
icon = null
|
||||
alternate_worn_icon = 'icons/mob/animals_held.dmi'
|
||||
righthand_file = 'icons/mob/animals_held_rh.dmi'
|
||||
lefthand_file = 'icons/mob/animals_held_lh.dmi'
|
||||
icon_state = ""
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
var/mob/living/held_mob
|
||||
|
||||
/obj/item/clothing/head/mob_holder/Initialize(mapload, mob/living/target, worn_state, alt_worn, right_hand, left_hand, slots = NONE)
|
||||
. = ..()
|
||||
|
||||
if(target)
|
||||
assimilate(target)
|
||||
|
||||
if(alt_worn)
|
||||
alternate_worn_icon = alt_worn
|
||||
if(worn_state)
|
||||
item_state = worn_state
|
||||
icon_state = worn_state
|
||||
if(left_hand)
|
||||
lefthand_file = left_hand
|
||||
if(right_hand)
|
||||
righthand_file = right_hand
|
||||
slot_flags = slots
|
||||
|
||||
/obj/item/clothing/head/mob_holder/proc/assimilate(mob/living/target)
|
||||
target.setDir(SOUTH)
|
||||
held_mob = target
|
||||
target.forceMove(src)
|
||||
var/image/I = new //work around to retain the same appearance to the mob idependently from inhands/worn states.
|
||||
I.appearance = target.appearance
|
||||
I.override = TRUE
|
||||
add_overlay(I)
|
||||
name = target.name
|
||||
desc = target.desc
|
||||
switch(target.mob_size)
|
||||
if(MOB_SIZE_TINY)
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
if(MOB_SIZE_SMALL)
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
if(MOB_SIZE_LARGE)
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
RegisterSignal(src, COMSIG_CLICK_SHIFT, .proc/examine_held_mob)
|
||||
|
||||
/obj/item/clothing/head/mob_holder/Destroy()
|
||||
if(held_mob)
|
||||
release()
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/head/mob_holder/proc/examine_held_mob(datum/source, mob/user)
|
||||
held_mob.ShiftClick(user)
|
||||
return COMPONENT_DENY_EXAMINATE
|
||||
|
||||
/obj/item/clothing/head/mob_holder/Exited(atom/movable/AM, atom/newloc)
|
||||
. = ..()
|
||||
if(AM == held_mob)
|
||||
held_mob.reset_perspective()
|
||||
held_mob = null
|
||||
qdel(src)
|
||||
|
||||
/obj/item/clothing/head/mob_holder/Entered(atom/movable/AM, atom/newloc)
|
||||
. = ..()
|
||||
if(AM != held_mob)
|
||||
var/destination = loc
|
||||
if(isliving(loc)) //the mob is held or worn, drop things on the floor
|
||||
destination = get_turf(loc)
|
||||
AM.forceMove(destination)
|
||||
|
||||
/obj/item/clothing/head/mob_holder/dropped()
|
||||
. = ..()
|
||||
if(held_mob && isturf(loc))//don't release on soft-drops
|
||||
release()
|
||||
|
||||
/obj/item/clothing/head/mob_holder/proc/release()
|
||||
if(held_mob)
|
||||
var/mob/living/L = held_mob
|
||||
held_mob = null
|
||||
L.forceMove(get_turf(L))
|
||||
L.reset_perspective()
|
||||
L.setDir(SOUTH)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/clothing/head/mob_holder/relaymove(mob/user)
|
||||
return
|
||||
|
||||
/obj/item/clothing/head/mob_holder/container_resist()
|
||||
if(isliving(loc))
|
||||
var/mob/living/L = loc
|
||||
L.visible_message("<span class='warning'>[src] escapes from [L]!</span>", "<span class='warning'>[src] escapes your grip!</span>")
|
||||
release()
|
||||
|
||||
/obj/item/clothing/head/mob_holder/assume_air(datum/gas_mixture/env)
|
||||
var/atom/location = loc
|
||||
if(!loc)
|
||||
return //null
|
||||
var/turf/T = get_turf(loc)
|
||||
while(location != T)
|
||||
location = location.loc
|
||||
if(ismob(location))
|
||||
return location.loc.assume_air(env)
|
||||
return loc.assume_air(env)
|
||||
|
||||
/obj/item/clothing/head/mob_holder/remove_air(amount)
|
||||
var/atom/location = loc
|
||||
if(!loc)
|
||||
return //null
|
||||
var/turf/T = get_turf(loc)
|
||||
while(location != T)
|
||||
location = location.loc
|
||||
if(ismob(location))
|
||||
return location.loc.remove_air(amount)
|
||||
return loc.remove_air(amount)
|
||||
@@ -30,6 +30,10 @@
|
||||
|
||||
RegisterSignal(target, COMSIG_MOB_ATTACK_HAND, .proc/on_attack_hand)
|
||||
|
||||
/datum/element/wuv/Detach(datum/source, force)
|
||||
. = ..()
|
||||
UnregisterSignal(source, COMSIG_MOB_ATTACK_HAND)
|
||||
|
||||
/datum/element/wuv/proc/on_attack_hand(datum/source, mob/user)
|
||||
var/mob/living/L = source
|
||||
|
||||
|
||||
@@ -458,6 +458,7 @@
|
||||
|
||||
var/list/allowed_types = list(
|
||||
/datum/objective/assassinate,
|
||||
/datum/objective/assassinate/once,
|
||||
/datum/objective/maroon,
|
||||
/datum/objective/debrain,
|
||||
/datum/objective/protect,
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
if(owner.getStaminaLoss())
|
||||
owner.adjustStaminaLoss(-0.3) //reduce stamina loss by 0.3 per tick, 6 per 2 seconds
|
||||
|
||||
|
||||
//UNCONSCIOUS
|
||||
/datum/status_effect/incapacitating/unconscious
|
||||
id = "unconscious"
|
||||
@@ -80,11 +79,11 @@
|
||||
desc = "You've fallen asleep. Wait a bit and you should wake up. Unless you don't, considering how helpless you are."
|
||||
icon_state = "asleep"
|
||||
|
||||
/datum/status_effect/no_combat_mode/
|
||||
/datum/status_effect/no_combat_mode
|
||||
id = "no_combat_mode"
|
||||
blocks_combatmode = TRUE
|
||||
alert_type = null
|
||||
status_type = STATUS_EFFECT_REPLACE
|
||||
blocks_combatmode = TRUE
|
||||
|
||||
/datum/status_effect/no_combat_mode/on_creation(mob/living/new_owner, set_duration)
|
||||
if(isnum(set_duration))
|
||||
@@ -113,31 +112,54 @@
|
||||
icon = 'icons/mob/actions/bloodsucker.dmi'
|
||||
icon_state = "power_mez"
|
||||
|
||||
/datum/status_effect/no_combat_mode/electrode
|
||||
/datum/status_effect/electrode
|
||||
id = "tased"
|
||||
var/slowdown = 1.5
|
||||
var/slowdown_priority = 50 //to make sure the stronger effect overrides
|
||||
var/affect_crawl = FALSE
|
||||
var/nextmove_modifier = 1
|
||||
var/stamdmg_per_ds = 1 //a 20 duration would do 20 stamdmg, disablers do 24 or something
|
||||
var/last_tick = 0 //fastprocess processing speed is a goddamn sham, don't trust it.
|
||||
|
||||
/datum/status_effect/no_combat_mode/electrode/on_creation(mob/living/new_owner, set_duration)
|
||||
/datum/status_effect/electrode/on_creation(mob/living/new_owner, set_duration)
|
||||
if(isnum(set_duration)) //TODO, figure out how to grab from subtype
|
||||
duration = set_duration
|
||||
. = ..()
|
||||
last_tick = world.time
|
||||
if(iscarbon(owner))
|
||||
var/mob/living/carbon/C = owner
|
||||
if(C.combatmode)
|
||||
C.toggle_combat_mode(TRUE)
|
||||
C.add_movespeed_modifier("[MOVESPEED_ID_TASED_STATUS]_[id]", TRUE, priority = slowdown_priority, override = TRUE, multiplicative_slowdown = slowdown, blacklisted_movetypes = affect_crawl? NONE : CRAWLING)
|
||||
|
||||
/datum/status_effect/electrode/on_remove()
|
||||
if(iscarbon(owner))
|
||||
var/mob/living/carbon/C = owner
|
||||
C.remove_movespeed_modifier("[MOVESPEED_ID_TASED_STATUS]_[id]")
|
||||
. = ..()
|
||||
|
||||
/datum/status_effect/electrode/tick()
|
||||
var/diff = world.time - last_tick
|
||||
if(owner)
|
||||
owner.adjustStaminaLoss(max(0, stamdmg_per_ds * diff)) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing.
|
||||
last_tick = world.time
|
||||
|
||||
/datum/status_effect/electrode/nextmove_modifier() //why is this a proc. its no big deal since this doesnt get called often at all but literally w h y
|
||||
return nextmove_modifier
|
||||
|
||||
/datum/status_effect/electrode/no_combat_mode
|
||||
id = "tased_strong"
|
||||
slowdown = 8
|
||||
slowdown_priority = 100
|
||||
nextmove_modifier = 2
|
||||
blocks_combatmode = TRUE
|
||||
|
||||
/datum/status_effect/electrode/no_combat_mode/on_creation(mob/living/new_owner, set_duration)
|
||||
. = ..()
|
||||
if(iscarbon(owner))
|
||||
var/mob/living/carbon/C = owner
|
||||
if(C.combatmode)
|
||||
C.toggle_combat_mode(TRUE)
|
||||
C.add_movespeed_modifier(MOVESPEED_ID_TASED_STATUS, TRUE, override = TRUE, multiplicative_slowdown = 8)
|
||||
|
||||
/datum/status_effect/no_combat_mode/electrode/on_remove()
|
||||
if(iscarbon(owner))
|
||||
var/mob/living/carbon/C = owner
|
||||
C.remove_movespeed_modifier(MOVESPEED_ID_TASED_STATUS)
|
||||
. = ..()
|
||||
|
||||
/datum/status_effect/no_combat_mode/electrode/tick()
|
||||
if(owner)
|
||||
owner.adjustStaminaLoss(5) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing.
|
||||
|
||||
/datum/status_effect/no_combat_mode/electrode/nextmove_modifier() //why is this a proc. its no big deal since this doesnt get called often at all but literally w h y
|
||||
return 2
|
||||
|
||||
//OTHER DEBUFFS
|
||||
/datum/status_effect/his_wrath //does minor damage over time unless holding His Grace
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
var/gain_text
|
||||
var/lose_text
|
||||
var/medical_record_text //This text will appear on medical records for the trait. Not yet implemented
|
||||
var/antag_removal_text // Text will be given to the quirk holder if they get an antag that has it blacklisted.
|
||||
var/mood_quirk = FALSE //if true, this quirk affects mood and is unavailable if moodlets are disabled
|
||||
var/mob_trait //if applicable, apply and remove this mob trait
|
||||
var/mob/living/quirk_holder
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
value = -2
|
||||
gain_text = "<span class='danger'>You feel your vigor slowly fading away.</span>"
|
||||
lose_text = "<span class='notice'>You feel vigorous again.</span>"
|
||||
antag_removal_text = "Your antagonistic nature has removed your blood deficiency."
|
||||
medical_record_text = "Patient requires regular treatment for blood loss due to low production of blood."
|
||||
|
||||
/datum/quirk/blooddeficiency/on_process()
|
||||
@@ -38,6 +39,8 @@
|
||||
var/obj/item/heirloom
|
||||
var/where
|
||||
|
||||
GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
|
||||
/datum/quirk/family_heirloom/on_spawn()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
var/obj/item/heirloom_type
|
||||
@@ -76,6 +79,7 @@
|
||||
/obj/item/lighter,
|
||||
/obj/item/dice/d20)
|
||||
heirloom = new heirloom_type(get_turf(quirk_holder))
|
||||
GLOB.family_heirlooms += heirloom
|
||||
var/list/slots = list(
|
||||
"in your left pocket" = SLOT_L_STORE,
|
||||
"in your right pocket" = SLOT_R_STORE,
|
||||
@@ -188,11 +192,7 @@
|
||||
gain_text = "<span class='danger'>You feel repulsed by the thought of violence!</span>"
|
||||
lose_text = "<span class='notice'>You think you can defend yourself again.</span>"
|
||||
medical_record_text = "Patient is unusually pacifistic and cannot bring themselves to cause physical harm."
|
||||
|
||||
/datum/quirk/nonviolent/on_process()
|
||||
if(quirk_holder.mind && LAZYLEN(quirk_holder.mind.antag_datums))
|
||||
to_chat(quirk_holder, "<span class='boldannounce'>Your antagonistic nature has caused you to renounce your pacifism.</span>")
|
||||
qdel(src)
|
||||
antag_removal_text = "Your antagonistic nature has caused you to renounce your pacifism."
|
||||
|
||||
/datum/quirk/paraplegic
|
||||
name = "Paraplegic"
|
||||
@@ -355,6 +355,7 @@
|
||||
gain_text = "<span class='danger'>You find yourself unable to speak!</span>"
|
||||
lose_text = "<span class='notice'>You feel a growing strength in your vocal chords.</span>"
|
||||
medical_record_text = "Functionally mute, patient is unable to use their voice in any capacity."
|
||||
antag_removal_text = "Your antagonistic nature has caused your voice to be heard."
|
||||
var/datum/brain_trauma/severe/mute/mute
|
||||
|
||||
/datum/quirk/mute/add()
|
||||
@@ -366,11 +367,6 @@
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
H?.cure_trauma_type(mute, TRAUMA_RESILIENCE_ABSOLUTE)
|
||||
|
||||
/datum/quirk/mute/on_process()
|
||||
if(quirk_holder.mind && LAZYLEN(quirk_holder.mind.antag_datums))
|
||||
to_chat(quirk_holder, "<span class='boldannounce'>Your antagonistic nature has caused your voice to be heard.</span>")
|
||||
qdel(src)
|
||||
|
||||
/datum/quirk/unstable
|
||||
name = "Unstable"
|
||||
desc = "Due to past troubles, you are unable to recover your sanity if you lose it. Be very careful managing your mood!"
|
||||
|
||||
@@ -41,7 +41,7 @@ GLOBAL_LIST_EMPTY(dynamic_forced_roundstart_ruleset)
|
||||
// Forced threat level, setting this to zero or higher forces the roundstart threat to the value.
|
||||
GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
|
||||
GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
|
||||
GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
|
||||
|
||||
/datum/game_mode/dynamic
|
||||
name = "dynamic mode"
|
||||
@@ -239,12 +239,20 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
|
||||
. += "<b>Peaceful Waypoint</b></center><BR>"
|
||||
. += "Your station orbits deep within controlled, core-sector systems and serves as a waypoint for routine traffic through Nanotrasen's trade empire. Due to the combination of high security, interstellar traffic, and low strategic value, it makes any direct threat of violence unlikely. Your primary enemies will be incompetence and bored crewmen: try to organize team-building events to keep staffers interested and productive. However, even deep in our territory there may be subversive elements, especially for such a high-value target as your station. Keep an eye out, but don't expect much trouble."
|
||||
set_security_level(SEC_LEVEL_GREEN)
|
||||
for(var/T in subtypesof(/datum/station_goal))
|
||||
var/datum/station_goal/G = new T
|
||||
if(!(G in station_goals))
|
||||
station_goals += G
|
||||
if(21 to 79)
|
||||
var/perc_green = 100-round(100*((threat_level-21)/(79-21)))
|
||||
if(prob(perc_green))
|
||||
. += "<b>Core Territory</b></center><BR>"
|
||||
. += "Your station orbits within reliably mundane, secure space. Although Nanotrasen has a firm grip on security in your region, the valuable resources and strategic position aboard your station make it a potential target for infiltrations. Monitor crew for non-loyal behavior, but expect a relatively tame shift free of large-scale destruction. We expect great things from your station."
|
||||
set_security_level(SEC_LEVEL_GREEN)
|
||||
for(var/T in subtypesof(/datum/station_goal))
|
||||
var/datum/station_goal/G = new T
|
||||
if(!(G in station_goals))
|
||||
station_goals += G
|
||||
else if(prob(perc_green))
|
||||
. += "<b>Contested System</b></center><BR>"
|
||||
. += "Your station's orbit passes along the edge of Nanotrasen's sphere of influence. While subversive elements remain the most likely threat against your station, hostile organizations are bolder here, where our grip is weaker. Exercise increased caution against elite Syndicate strike forces, or Executives forbid, some kind of ill-conceived unionizing attempt."
|
||||
@@ -273,7 +281,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
|
||||
if(GLOB.security_level >= SEC_LEVEL_BLUE)
|
||||
priority_announce("A summary has been copied and printed to all communications consoles.", "Security level elevated.", "intercept")
|
||||
else
|
||||
priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no likely threats to [station_name()]. Have a secure shift!", "Security Report", "commandreport")
|
||||
priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no likely threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", "commandreport")
|
||||
|
||||
// Yes, this is copy pasted from game_mode
|
||||
/datum/game_mode/dynamic/check_finished(force_ending)
|
||||
@@ -346,7 +354,8 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
|
||||
generate_threat()
|
||||
|
||||
storyteller.start_injection_cooldowns()
|
||||
|
||||
SSevents.frequency_lower = storyteller.event_frequency_lower // 6 minutes by default
|
||||
SSevents.frequency_upper = storyteller.event_frequency_upper // 20 minutes by default
|
||||
log_game("DYNAMIC: Dynamic Mode initialized with a Threat Level of... [threat_level]!")
|
||||
initial_threat_level = threat_level
|
||||
return TRUE
|
||||
@@ -395,7 +404,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
|
||||
|
||||
/datum/game_mode/dynamic/post_setup(report)
|
||||
update_playercounts()
|
||||
|
||||
|
||||
for(var/datum/dynamic_ruleset/roundstart/rule in executed_rules)
|
||||
addtimer(CALLBACK(src, /datum/game_mode/dynamic/.proc/execute_roundstart_rule, rule), rule.delay)
|
||||
..()
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
assigned += M.mind
|
||||
M.mind.special_role = antag_flag
|
||||
M.mind.add_antag_datum(antag_datum)
|
||||
log_admin("[M.name] was made into a [name] by dynamic.")
|
||||
message_admins("[M.name] was made into a [name] by dynamic.")
|
||||
return TRUE
|
||||
|
||||
//////////////////////////////////////////////
|
||||
@@ -72,12 +74,6 @@
|
||||
property_weights = list("story_potential" = 2, "trust" = -1, "extended" = 1)
|
||||
always_max_weight = TRUE
|
||||
|
||||
/datum/dynamic_ruleset/latejoin/infiltrator/execute()
|
||||
. = ..()
|
||||
for(var/datum/mind/M in assigned)
|
||||
log_admin("[M.name] was made into a traitor by dynamic.")
|
||||
message_admins("[M.name] was made into a traitor by dynamic.")
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// REVOLUTIONARY PROVOCATEUR //
|
||||
@@ -225,3 +221,25 @@
|
||||
log_admin("[M.name] was made into a bloodsucker by dynamic.")
|
||||
message_admins("[M.name] was made into a bloodsucker by dynamic.")
|
||||
return TRUE
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// COLLECTOR //
|
||||
// //
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/datum/dynamic_ruleset/latejoin/collector
|
||||
name = "Contraband Collector"
|
||||
config_tag = "latejoin_collector"
|
||||
antag_datum = /datum/antagonist/collector
|
||||
antag_flag = ROLE_MINOR_ANTAG
|
||||
restricted_roles = list("AI", "Cyborg")
|
||||
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
|
||||
required_candidates = 1
|
||||
weight = 5
|
||||
cost = 1
|
||||
requirements = list(10,10,10,10,10,10,10,10,10,10)
|
||||
high_population_requirement = 10
|
||||
repeatable = TRUE
|
||||
flags = TRAITOR_RULESET
|
||||
property_weights = list("story_potential" = 2, "trust" = -1, "extended" = 2)
|
||||
|
||||
@@ -494,7 +494,7 @@
|
||||
high_population_requirement = 50
|
||||
repeatable_weight_decrease = 2
|
||||
repeatable = TRUE
|
||||
property_weights = list("story_potential" = 1, "trust" = 1, "extended" = 1, "valid" = 2, "integrity" = 2)
|
||||
property_weights = list("story_potential" = 1, "trust" = 1, "extended" = 1, "valid" = 2, "integrity" = 1)
|
||||
var/list/spawn_locs = list()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/nightmare/execute()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/datum/dynamic_storyteller
|
||||
var/name = "none"
|
||||
var/config_tag = null
|
||||
var/desc = "A coder's idiocy."
|
||||
var/list/property_weights = list()
|
||||
var/curve_centre = 0
|
||||
@@ -7,6 +8,8 @@
|
||||
var/forced_threat_level = -1
|
||||
var/flags = 0
|
||||
var/weight = 3 // how many rounds need to have been recently played for this storyteller to be left out of the vote
|
||||
var/event_frequency_lower = 6 MINUTES
|
||||
var/event_frequency_upper = 20 MINUTES
|
||||
var/datum/game_mode/dynamic/mode = null
|
||||
|
||||
/**
|
||||
@@ -20,14 +23,6 @@ Property weights are:
|
||||
"conversion" -- Basically a bool. Conversion antags, well, convert. It's its own class for a good reason.
|
||||
*/
|
||||
|
||||
/datum/dynamic_storyteller/New()
|
||||
..()
|
||||
if (istype(SSticker.mode, /datum/game_mode/dynamic))
|
||||
mode = SSticker.mode
|
||||
GLOB.dynamic_curve_centre = curve_centre
|
||||
GLOB.dynamic_curve_width = curve_width
|
||||
GLOB.dynamic_forced_threat_level = forced_threat_level
|
||||
|
||||
/datum/dynamic_storyteller/proc/start_injection_cooldowns()
|
||||
var/latejoin_injection_cooldown_middle = 0.5*(GLOB.dynamic_first_latejoin_delay_max + GLOB.dynamic_first_latejoin_delay_min)
|
||||
mode.latejoin_injection_cooldown = round(CLAMP(EXP_DISTRIBUTION(latejoin_injection_cooldown_middle), GLOB.dynamic_first_latejoin_delay_min, GLOB.dynamic_first_latejoin_delay_max)) + world.time
|
||||
@@ -42,7 +37,28 @@ Property weights are:
|
||||
return
|
||||
|
||||
/datum/dynamic_storyteller/proc/on_start()
|
||||
return
|
||||
if (istype(SSticker.mode, /datum/game_mode/dynamic))
|
||||
mode = SSticker.mode
|
||||
GLOB.dynamic_curve_centre = curve_centre
|
||||
GLOB.dynamic_curve_width = curve_width
|
||||
if(flags & USE_PREF_WEIGHTS)
|
||||
var/voters = 0
|
||||
var/mean = 0
|
||||
for(var/client/c in GLOB.clients)
|
||||
var/vote = c.prefs.preferred_chaos
|
||||
if(vote)
|
||||
voters += 1
|
||||
switch(vote)
|
||||
if(CHAOS_NONE)
|
||||
mean -= 5
|
||||
if(CHAOS_LOW)
|
||||
mean -= 2.5
|
||||
if(CHAOS_HIGH)
|
||||
mean += 2.5
|
||||
if(CHAOS_MAX)
|
||||
mean += 5
|
||||
GLOB.dynamic_curve_centre += (mean/voters)
|
||||
GLOB.dynamic_forced_threat_level = forced_threat_level
|
||||
|
||||
/datum/dynamic_storyteller/proc/get_midround_cooldown()
|
||||
var/midround_injection_cooldown_middle = 0.5*(GLOB.dynamic_midround_delay_max + GLOB.dynamic_midround_delay_min)
|
||||
@@ -154,12 +170,15 @@ Property weights are:
|
||||
|
||||
/datum/dynamic_storyteller/cowabunga
|
||||
name = "Chaotic"
|
||||
config_tag = "chaotic"
|
||||
curve_centre = 10
|
||||
desc = "Chaos: high. Variation: high. Likely antags: clock cult, revs, wizard."
|
||||
property_weights = list("extended" = -1, "chaos" = 10)
|
||||
weight = 2
|
||||
weight = 1
|
||||
event_frequency_lower = 2 MINUTES
|
||||
event_frequency_upper = 10 MINUTES
|
||||
flags = WAROPS_ALWAYS_ALLOWED
|
||||
var/refund_cooldown
|
||||
var/refund_cooldown = 0
|
||||
|
||||
/datum/dynamic_storyteller/cowabunga/get_midround_cooldown()
|
||||
return ..() / 4
|
||||
@@ -169,12 +188,13 @@ Property weights are:
|
||||
|
||||
/datum/dynamic_storyteller/cowabunga/do_process()
|
||||
if(refund_cooldown < world.time)
|
||||
mode.refund_threat(10)
|
||||
mode.log_threat("Cowabunga it is. Refunded 10 threat. Threat is now [mode.threat].")
|
||||
refund_cooldown = world.time + 300 SECONDS
|
||||
mode.refund_threat(20)
|
||||
mode.log_threat("Cowabunga it is. Refunded 20 threat. Threat is now [mode.threat].")
|
||||
refund_cooldown = world.time + 600 SECONDS
|
||||
|
||||
/datum/dynamic_storyteller/team
|
||||
name = "Teamwork"
|
||||
config_tag = "teamwork"
|
||||
desc = "Chaos: high. Variation: low. Likely antags: nukies, clockwork cult, wizard, blob, xenomorph."
|
||||
curve_centre = 2
|
||||
curve_width = 1.5
|
||||
@@ -187,6 +207,7 @@ Property weights are:
|
||||
|
||||
/datum/dynamic_storyteller/conversion
|
||||
name = "Conversion"
|
||||
config_tag = "conversion"
|
||||
desc = "Chaos: high. Variation: medium. Likely antags: cults, bloodsuckers, revs."
|
||||
curve_centre = 3
|
||||
curve_width = 1
|
||||
@@ -196,24 +217,33 @@ Property weights are:
|
||||
|
||||
/datum/dynamic_storyteller/classic
|
||||
name = "Random"
|
||||
config_tag = "random"
|
||||
desc = "Chaos: varies. Variation: highest. No special weights attached."
|
||||
weight = 6
|
||||
flags = USE_PREF_WEIGHTS
|
||||
curve_width = 4
|
||||
|
||||
/datum/dynamic_storyteller/memes
|
||||
name = "Story"
|
||||
config_tag = "story"
|
||||
desc = "Chaos: varies. Variation: high. Likely antags: abductors, nukies, wizard, traitor."
|
||||
weight = 4
|
||||
flags = USE_PREF_WEIGHTS
|
||||
curve_width = 4
|
||||
property_weights = list("story_potential" = 10)
|
||||
|
||||
/datum/dynamic_storyteller/suspicion
|
||||
name = "Intrigue"
|
||||
config_tag = "intrigue"
|
||||
desc = "Chaos: low. Variation: high. Likely antags: traitor, bloodsucker. Rare: revs, blood cult."
|
||||
weight = 4
|
||||
flags = USE_PREF_WEIGHTS
|
||||
curve_width = 4
|
||||
property_weights = list("trust" = -5)
|
||||
|
||||
/datum/dynamic_storyteller/liteextended
|
||||
name = "Calm"
|
||||
config_tag = "calm"
|
||||
desc = "Chaos: low. Variation: medium. Likely antags: bloodsuckers, traitors, sentient disease, revenant."
|
||||
curve_centre = -5
|
||||
curve_width = 0.5
|
||||
@@ -226,10 +256,12 @@ Property weights are:
|
||||
|
||||
/datum/dynamic_storyteller/extended
|
||||
name = "Extended"
|
||||
config_tag = "extended"
|
||||
desc = "Chaos: none. Variation: none. Likely antags: none."
|
||||
curve_centre = -20
|
||||
weight = 2
|
||||
weight = 0
|
||||
curve_width = 0.5
|
||||
|
||||
/datum/dynamic_storyteller/extended/on_start()
|
||||
..()
|
||||
GLOB.dynamic_forced_extended = TRUE
|
||||
|
||||
@@ -6,7 +6,8 @@ GLOBAL_LIST_EMPTY(gangs)
|
||||
name = "gang war"
|
||||
config_tag = "gang"
|
||||
antag_flag = ROLE_GANG
|
||||
restricted_jobs = list("Security Officer", "Warden", "Detective", "AI", "Cyborg","Captain", "Head of Personnel", "Head of Security")
|
||||
restricted_jobs = list("AI", "Cyborg")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
|
||||
required_players = 15
|
||||
required_enemies = 0
|
||||
recommended_enemies = 2
|
||||
|
||||
@@ -9,9 +9,10 @@ GLOBAL_LIST_EMPTY(objectives)
|
||||
var/explanation_text = "Nothing" //What that person is supposed to do.
|
||||
var/team_explanation_text //For when there are multiple owners.
|
||||
var/datum/mind/target = null //If they are focused on a particular person.
|
||||
var/target_amount = 0 //If they are focused on a particular number. Steal objectives have their own counter.
|
||||
var/completed = 0 //currently only used for custom objectives.
|
||||
var/martyr_compatible = 0 //If the objective is compatible with martyr objective, i.e. if you can still do it while dead.
|
||||
var/target_amount = FALSE //If they are focused on a particular number. Steal objectives have their own counter.
|
||||
var/completed = FALSE //currently only used for custom objectives.
|
||||
var/completable = TRUE //Whether this objective shows greentext when completed
|
||||
var/martyr_compatible = FALSE //If the objective is compatible with martyr objective, i.e. if you can still do it while dead.
|
||||
|
||||
/datum/objective/New(var/text)
|
||||
GLOB.objectives += src // CITADEL EDIT FOR CRYOPODS
|
||||
@@ -172,6 +173,26 @@ GLOBAL_LIST_EMPTY(objectives)
|
||||
/datum/objective/assassinate/admin_edit(mob/admin)
|
||||
admin_simple_target_pick(admin)
|
||||
|
||||
/datum/objective/assassinate/once
|
||||
name = "kill once"
|
||||
var/won = FALSE
|
||||
|
||||
/datum/objective/assassinate/once/update_explanation_text()
|
||||
..()
|
||||
if(target && target.current)
|
||||
explanation_text = "Kill [target.name], the [!target_role_type ? target.assigned_role : target.special_role]. You only need to kill them once; if they come back, you've still succeeded."
|
||||
START_PROCESSING(SSprocessing,src)
|
||||
else
|
||||
explanation_text = "Free Objective"
|
||||
|
||||
/datum/objective/assassinate/once/check_completion()
|
||||
return won || ..()
|
||||
|
||||
/datum/objective/assassinate/once/process()
|
||||
won = check_completion()
|
||||
if(won)
|
||||
STOP_PROCESSING(SSprocessing,src)
|
||||
|
||||
/datum/objective/assassinate/internal
|
||||
var/stolen = 0 //Have we already eliminated this target?
|
||||
|
||||
@@ -365,6 +386,28 @@ GLOBAL_LIST_EMPTY(objectives)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/objective/breakout
|
||||
name = "breakout"
|
||||
martyr_compatible = 1
|
||||
var/target_role_type = 0
|
||||
var/human_check = TRUE
|
||||
|
||||
/datum/objective/breakout/check_completion()
|
||||
return !target || considered_escaped(target)
|
||||
|
||||
/datum/objective/breakout/find_target_by_role(role, role_type=0, invert=0)
|
||||
if(!invert)
|
||||
target_role_type = role_type
|
||||
..()
|
||||
return target
|
||||
|
||||
/datum/objective/breakout/update_explanation_text()
|
||||
..()
|
||||
if(target && target.current)
|
||||
explanation_text = "Make sure [target.name], the [!target_role_type ? target.assigned_role : target.special_role] escapes on the shuttle or an escape pod alive and without being in custody."
|
||||
else
|
||||
explanation_text = "Free Objective"
|
||||
|
||||
/datum/objective/escape/escape_with_identity
|
||||
name = "escape with identity"
|
||||
var/target_real_name // Has to be stored because the target's real_name can change over the course of the round
|
||||
@@ -582,7 +625,6 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
||||
explanation_text = "Do not give up or lose [targetinfo.name]."
|
||||
steal_target = targetinfo.targetitem
|
||||
|
||||
|
||||
/datum/objective/download
|
||||
name = "download"
|
||||
|
||||
@@ -786,40 +828,10 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
||||
/datum/objective/destroy/internal
|
||||
var/stolen = FALSE //Have we already eliminated this target?
|
||||
|
||||
/datum/objective/steal_five_of_type
|
||||
name = "steal five of"
|
||||
explanation_text = "Steal at least five items!"
|
||||
var/list/wanted_items = list(/obj/item)
|
||||
|
||||
/datum/objective/steal_five_of_type/New()
|
||||
..()
|
||||
wanted_items = typecacheof(wanted_items)
|
||||
|
||||
/datum/objective/steal_five_of_type/summon_guns
|
||||
name = "steal guns"
|
||||
explanation_text = "Steal at least five guns!"
|
||||
wanted_items = list(/obj/item/gun)
|
||||
|
||||
/datum/objective/steal_five_of_type/summon_magic
|
||||
name = "steal magic"
|
||||
explanation_text = "Steal at least five magical artefacts!"
|
||||
wanted_items = list(/obj/item/spellbook, /obj/item/gun/magic, /obj/item/clothing/suit/space/hardsuit/wizard, /obj/item/scrying, /obj/item/antag_spawner/contract, /obj/item/necromantic_stone)
|
||||
|
||||
/datum/objective/steal_five_of_type/check_completion()
|
||||
var/list/datum/mind/owners = get_owners()
|
||||
var/stolen_count = 0
|
||||
for(var/datum/mind/M in owners)
|
||||
if(!isliving(M.current))
|
||||
continue
|
||||
var/list/all_items = M.current.GetAllContents() //this should get things in cheesewheels, books, etc.
|
||||
for(var/obj/I in all_items) //Check for wanted items
|
||||
if(is_type_in_typecache(I, wanted_items))
|
||||
stolen_count++
|
||||
return stolen_count >= 5
|
||||
|
||||
//Created by admin tools
|
||||
/datum/objective/custom
|
||||
name = "custom"
|
||||
completable = FALSE
|
||||
|
||||
/datum/objective/custom/admin_edit(mob/admin)
|
||||
var/expl = stripped_input(admin, "Custom objective:", "Objective", explanation_text)
|
||||
@@ -997,4 +1009,147 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
||||
command_staff_only = TRUE
|
||||
|
||||
|
||||
/datum/objective/hoard
|
||||
name = "hoard"
|
||||
var/obj/item/hoarded_item = null
|
||||
|
||||
/datum/objective/hoard/get_target()
|
||||
return hoarded_item
|
||||
|
||||
/datum/objective/hoard/proc/set_target(obj/item/I)
|
||||
if(I)
|
||||
hoarded_item = I
|
||||
explanation_text = "Keep [I] on your person at all times."
|
||||
return hoarded_item
|
||||
else
|
||||
explanation_text = "Free objective"
|
||||
return
|
||||
|
||||
/datum/objective/hoard/check_completion()
|
||||
var/list/datum/mind/owners = get_owners()
|
||||
if(!hoarded_item)
|
||||
return TRUE
|
||||
for(var/datum/mind/M in owners)
|
||||
if(!isliving(M.current))
|
||||
continue
|
||||
|
||||
var/list/all_items = M.current.GetAllContents() //this should get things in cheesewheels, books, etc.
|
||||
|
||||
for(var/obj/I in all_items) //Check for items
|
||||
if(I == hoarded_item)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/objective/hoard/heirloom
|
||||
name = "steal heirloom"
|
||||
|
||||
/datum/objective/hoard/heirloom/find_target()
|
||||
set_target(pick(GLOB.family_heirlooms))
|
||||
|
||||
GLOBAL_LIST_EMPTY(traitor_contraband)
|
||||
|
||||
GLOBAL_LIST_EMPTY(cult_contraband)
|
||||
|
||||
/datum/objective/hoard/collector
|
||||
name = "Hoard contraband"
|
||||
|
||||
/datum/objective/collector/New()
|
||||
..()
|
||||
if(!GLOB.traitor_contraband.len)//Only need to fill the list when it's needed.
|
||||
GLOB.traitor_contraband = list(/obj/item/card/emag/empty,/obj/item/clothing/glasses/phantomthief,/obj/item/clothing/gloves/chameleon/broken)
|
||||
if(!GLOB.cult_contraband.len)
|
||||
GLOB.cult_contraband = list(/obj/item/clockwork/slab,/obj/item/clockwork/component/belligerent_eye,/obj/item/clockwork/component/belligerent_eye/lens_gem,/obj/item/shuttle_curse,/obj/item/cult_shift)
|
||||
|
||||
/datum/objective/hoard/collector/find_target()
|
||||
var/obj/item/I
|
||||
var/I_type
|
||||
if(prob(50))
|
||||
I_type = pick_n_take(GLOB.traitor_contraband) // always unique unless it's run out, in which case we refill it anyway
|
||||
else
|
||||
I_type = pick_n_take(GLOB.cult_contraband)
|
||||
I = new I_type
|
||||
I.forceMove(get_turf(owner))
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.equip_in_one_of_slots(I, list("backpack" = SLOT_IN_BACKPACK))
|
||||
hoarded_item = I
|
||||
|
||||
|
||||
|
||||
GLOBAL_LIST_EMPTY(possible_sabotages)
|
||||
// For saboteurs. Go in and cause some trouble somewhere. Not necessarily breaking things, just sufficiently troublemaking.
|
||||
/datum/objective/sabotage
|
||||
name = "sabotage"
|
||||
var/datum/sabotage_objective/targetinfo = null //composition > inheritance.
|
||||
|
||||
/datum/objective/sabotage/get_target()
|
||||
return targetinfo.sabotage_type
|
||||
|
||||
/datum/objective/sabotage/New()
|
||||
..()
|
||||
if(!GLOB.possible_sabotages.len)//Only need to fill the list when it's needed.
|
||||
for(var/I in subtypesof(/datum/sabotage_objective))
|
||||
new I
|
||||
|
||||
/datum/objective/sabotage/find_target()
|
||||
var/list/datum/mind/owners = get_owners()
|
||||
var/approved_targets = list()
|
||||
check_sabotages:
|
||||
for(var/datum/sabotage_objective/possible_sabotage in GLOB.possible_sabotages)
|
||||
if(!is_unique_objective(possible_sabotage.sabotage_type) || possible_sabotage.check_conditions())
|
||||
continue
|
||||
for(var/datum/mind/M in owners)
|
||||
if(M.current.mind.assigned_role in possible_sabotage.excludefromjob)
|
||||
continue check_sabotages
|
||||
approved_targets += possible_sabotage
|
||||
return set_target(safepick(approved_targets))
|
||||
|
||||
/datum/objective/sabotage/proc/set_target(datum/sabotage_objective/sabo)
|
||||
if(sabo)
|
||||
targetinfo = sabo
|
||||
explanation_text = "[targetinfo.name]"
|
||||
give_special_equipment(targetinfo.special_equipment)
|
||||
return sabo
|
||||
else
|
||||
explanation_text = "Free objective"
|
||||
return
|
||||
|
||||
/datum/objective/sabotage/check_completion()
|
||||
return targetinfo.check_conditions()
|
||||
|
||||
/datum/objective/flavor
|
||||
name = "flavor"
|
||||
completable = FALSE
|
||||
var/flavor_file
|
||||
|
||||
/datum/objective/flavor/proc/get_flavor_list()
|
||||
return world.file2list(flavor_file)
|
||||
|
||||
/datum/objective/flavor/proc/forge_objective()
|
||||
var/flavor_list = get_flavor_list()
|
||||
explanation_text = pick(flavor_list)
|
||||
|
||||
/datum/objective/flavor/traitor
|
||||
name = "traitor flavor"
|
||||
flavor_file = "strings/flavor_objectives/traitor.txt"
|
||||
|
||||
/datum/objective/flavor/traitor/get_flavor_list()
|
||||
. = ..()
|
||||
switch(owner.assigned_role)
|
||||
if("Station Engineer", "Atmospheric Technician")
|
||||
. += world.file2list("strings/flavor_objectives/traitor/engineering.txt")
|
||||
if("Medical Doctor","Chemist","Virologist","Geneticist")
|
||||
. += world.file2list("strings/flavor_objectives/traitor/medical.txt")
|
||||
if("Scientist","Roboticist","Geneticist")
|
||||
. += world.file2list("strings/flavor_objectives/traitor/science.txt")
|
||||
if("Assistant")
|
||||
. += world.file2list("strings/flavor_objectives/traitor/assistant.txt")
|
||||
|
||||
/datum/objective/flavor/ninja_helping
|
||||
flavor_file = "strings/flavor_objectives/ninja_helping.txt"
|
||||
|
||||
/datum/objective/flavor/ninja_syndie
|
||||
flavor_file = "strings/flavor_objectives/ninja_syndie.txt"
|
||||
|
||||
/datum/objective/flavor/wizard
|
||||
flavor_file = "strings/flavor_objectives/wizard.txt"
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/datum/sabotage_objective
|
||||
var/name = "Free Objective"
|
||||
var/sabotage_type = "nothing"
|
||||
var/special_equipment = list()
|
||||
var/list/excludefromjob = list()
|
||||
|
||||
/datum/sabotage_objective/New()
|
||||
..()
|
||||
if(sabotage_type!="nothing")
|
||||
GLOB.possible_sabotages += src
|
||||
|
||||
/datum/sabotage_objective/proc/check_conditions()
|
||||
return TRUE
|
||||
|
||||
/datum/sabotage_objective/processing
|
||||
var/won = FALSE
|
||||
|
||||
/datum/sabotage_objective/processing/New()
|
||||
..()
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
|
||||
/datum/sabotage_objective/processing/proc/check_condition_processing()
|
||||
return 100
|
||||
|
||||
/datum/sabotage_objective/processing/process()
|
||||
check_condition_processing()
|
||||
if(won >= 100)
|
||||
STOP_PROCESSING(SSprocessing,src)
|
||||
|
||||
/datum/sabotage_objective/processing/check_conditions()
|
||||
return won
|
||||
|
||||
/datum/sabotage_objective/processing/power_sink
|
||||
name = "Drain at least 1 gigajoule of power using a power sink."
|
||||
sabotage_type = "powersink"
|
||||
special_equipment = list(/obj/item/powersink)
|
||||
var/sink_found = FALSE
|
||||
var/count = 0
|
||||
|
||||
/datum/sabotage_objective/processing/power_sink/check_condition_processing()
|
||||
count += 1
|
||||
if(count==10 || sink_found) // doesn't need to fire that often unless a sink exists
|
||||
var/sink_found_this_time = FALSE
|
||||
for(var/datum/powernet/PN in GLOB.powernets)
|
||||
for(var/obj/item/powersink/sink in PN.nodes)
|
||||
sink_found_this_time = TRUE
|
||||
won = max(won,sink.power_drained/1e9)
|
||||
sink_found = sink_found_this_time
|
||||
count = 0
|
||||
return FALSE
|
||||
|
||||
/obj/item/paper/guides/antag/supermatter_sabotage
|
||||
info = "Ways to sabotage a supermatter:<br>\
|
||||
<ul>\
|
||||
<li>Set the air alarm's operating mode to anything that isn't 'draught' (yes, anything, though 'off' works best). Or just smash the air alarm, that works too.</li>\
|
||||
<li>Wrench a pipe (the junction to the cold loop is most effective, but some setups will robust through this no issue; best to try for multiple)</li>\
|
||||
<li>Pump in as much carbon dioxide, oxygen, plasma or tritium as you can find (this will likely also cause a singularity or tesla delamination, so watch out!)</li>\
|
||||
<li>Unset the filters on the cooling loop, or, perhaps more insidious, set them to oxygen/plasma.</li>\
|
||||
<li>Deactivate the digital valve that sends the exhaust gases to space (note: only works on box station; others you must unwrench).</li>\
|
||||
<li>There are many other ways; be creative!</li>\
|
||||
</ul>"
|
||||
|
||||
/datum/sabotage_objective/processing/supermatter
|
||||
name = "Sabotage the supermatter so that it goes under 50% integrity. If it is delaminated, you will fail."
|
||||
sabotage_type = "supermatter"
|
||||
special_equipment = list(/obj/item/paper/guides/antag/supermatter_sabotage)
|
||||
var/list/supermatters = list()
|
||||
excludefromjob = list("Chief Engineer", "Station Engineer", "Atmospheric Technician")
|
||||
|
||||
/datum/sabotage_objective/processing/supermatter/check_condition_processing()
|
||||
if(!supermatters.len)
|
||||
supermatters = list()
|
||||
for(var/obj/machinery/power/supermatter_crystal/S in GLOB.machines)
|
||||
// Delaminating, not within coverage, not on a tile.
|
||||
if (!isturf(S.loc) || !(is_station_level(S.z) || is_mining_level(S.z)))
|
||||
continue
|
||||
supermatters.Add(S)
|
||||
for(var/obj/machinery/power/supermatter_crystal/S in supermatters) // you can win this with a wishgranter... lol.
|
||||
won = max(1-((S.get_integrity()-50)/50),won)
|
||||
return FALSE
|
||||
|
||||
/datum/sabotage_objective/station_integrity
|
||||
name = "Make sure the station is at less than 80% integrity by the end. Smash walls, windows etc. to reach this goal."
|
||||
sabotage_type = "integrity"
|
||||
|
||||
/datum/sabotage_objective/station_integrity/check_conditions()
|
||||
return 5-(max(SSticker.station_integrity*4,320)/80)
|
||||
|
||||
/datum/sabotage_objective/cloner
|
||||
name = "Destroy all Nanotrasen cloning machines."
|
||||
sabotage_type = "cloner"
|
||||
|
||||
/datum/sabotage_objective/cloner/check_conditions()
|
||||
return !(locate(/obj/machinery/clonepod) in GLOB.machines)
|
||||
|
||||
/datum/sabotage_objective/ai_law
|
||||
name = "Upload a hacked law to the AI."
|
||||
sabotage_type = "ailaw"
|
||||
special_equipment = list(/obj/item/aiModule/syndicate)
|
||||
excludefromjob = list("Chief Engineer","Research Director","Head of Personnel","Captain","Chief Medical Officer","Head Of Security")
|
||||
|
||||
/datum/sabotage_objective/ai_law/check_conditions()
|
||||
for (var/i in GLOB.ai_list)
|
||||
var/mob/living/silicon/ai/aiPlayer = i
|
||||
if(aiPlayer.mind && length(aiPlayer.laws.hacked))
|
||||
return TRUE
|
||||
return FALSE
|
||||
@@ -430,6 +430,6 @@
|
||||
/obj/machinery/jukebox/disco/process()
|
||||
. = ..()
|
||||
if(active)
|
||||
for(var/mob/M in rangers)
|
||||
for(var/mob/living/M in rangers)
|
||||
if(prob(5+(allowed(M)*4)) && M.canmove)
|
||||
dance(M)
|
||||
|
||||
@@ -348,6 +348,26 @@
|
||||
spark_system.start() //creates some sparks because they look cool
|
||||
qdel(cover) //deletes the cover - no need on keeping it there!
|
||||
|
||||
//turret healing
|
||||
/obj/machinery/porta_turret/examine(mob/user)
|
||||
. = ..()
|
||||
if(obj_integrity < max_integrity)
|
||||
. += "<span class='notice'>Use a welder to fix it.</span>"
|
||||
|
||||
/obj/machinery/porta_turret/welder_act(mob/living/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(obj_integrity < max_integrity)
|
||||
if(!I.tool_start_check(user, amount=0))
|
||||
return
|
||||
user.visible_message("[user] is welding the turret.", \
|
||||
"<span class='notice'>You begin repairing the turret...</span>", \
|
||||
"<span class='italics'>You hear welding.</span>")
|
||||
if(I.use_tool(src, user, 40, volume=50))
|
||||
obj_integrity = max_integrity
|
||||
user.visible_message("[user.name] has repaired [src].", \
|
||||
"<span class='notice'>You finish repairing the turret.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>The turret doesn't need repairing.</span>")
|
||||
|
||||
|
||||
/obj/machinery/porta_turret/process()
|
||||
@@ -672,6 +692,7 @@
|
||||
lethal_projectile_sound = 'sound/weapons/laser.ogg'
|
||||
desc = "An energy blaster auto-turret."
|
||||
|
||||
|
||||
/obj/machinery/porta_turret/syndicate/energy/heavy
|
||||
icon_state = "standard_stun"
|
||||
base_icon_state = "standard"
|
||||
@@ -683,6 +704,11 @@
|
||||
lethal_projectile_sound = 'sound/weapons/lasercannonfire.ogg'
|
||||
desc = "An energy blaster auto-turret."
|
||||
|
||||
/obj/machinery/porta_turret/syndicate/energy/pirate
|
||||
max_integrity = 260
|
||||
integrity_failure = 20
|
||||
armor = list("melee" = 50, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90)
|
||||
|
||||
|
||||
/obj/machinery/porta_turret/syndicate/setup()
|
||||
return
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
var/poster_item_name = "hypothetical poster"
|
||||
var/poster_item_desc = "This hypothetical poster item should not exist, let's be honest here."
|
||||
var/poster_item_icon_state = "rolled_poster"
|
||||
var/poster_item_type = /obj/item/poster
|
||||
|
||||
/obj/structure/sign/poster/Initialize()
|
||||
. = ..()
|
||||
@@ -114,7 +115,7 @@
|
||||
/obj/structure/sign/poster/proc/roll_and_drop(loc)
|
||||
pixel_x = 0
|
||||
pixel_y = 0
|
||||
var/obj/item/poster/P = new(loc, src)
|
||||
var/obj/item/poster/P = new poster_item_type(loc, src)
|
||||
forceMove(P)
|
||||
return P
|
||||
|
||||
|
||||
@@ -163,6 +163,10 @@ again.
|
||||
icon_state = "plastitaniumwindow_spawner"
|
||||
spawn_list = list(/obj/structure/grille, /obj/structure/window/plastitanium)
|
||||
|
||||
//plastitanium pirate window
|
||||
|
||||
/obj/effect/spawner/structure/window/plastitanium/pirate
|
||||
spawn_list = list(/obj/structure/grille, /obj/structure/window/plastitanium/pirate)
|
||||
|
||||
//ice window
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
/obj/structure/sign/poster/wanted
|
||||
var/wanted_name
|
||||
poster_item_type = /obj/item/poster/wanted
|
||||
|
||||
/obj/structure/sign/poster/wanted/Initialize(mapload, icon/person_icon, person_name, description)
|
||||
. = ..()
|
||||
|
||||
@@ -128,6 +128,9 @@
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/card/emag/empty
|
||||
uses = 0
|
||||
|
||||
/obj/item/emagrecharge
|
||||
name = "electromagnet charging device"
|
||||
desc = "A small cell with two prongs lazily jabbed into it. It looks like it's made for charging the small batteries found in electromagnetic devices, sadly this can't be recharged like a normal cell."
|
||||
@@ -538,4 +541,15 @@ update_label("John Doe", "Clowny")
|
||||
id_color = "#0000FF"
|
||||
|
||||
/obj/item/card/id/knight/captain
|
||||
id_color = "#FFD700"
|
||||
id_color = "#FFD700"
|
||||
|
||||
/obj/item/card/id/debug
|
||||
name = "\improper Debug ID"
|
||||
desc = "A debug ID card. Has ALL the all access, you really shouldn't have this."
|
||||
icon_state = "ert_janitor"
|
||||
assignment = "Jannie"
|
||||
|
||||
/obj/item/card/id/debug/Initialize()
|
||||
access = get_all_accesses()+get_all_centcom_access()+get_all_syndicate_access()
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/* This file contains standalone items for debug purposes. */
|
||||
|
||||
/obj/item/debug/human_spawner
|
||||
name = "human spawner"
|
||||
desc = "Spawn a human by aiming at a turf and clicking. Use in hand to change type."
|
||||
icon = 'icons/obj/guns/magic.dmi'
|
||||
icon_state = "nothingwand"
|
||||
item_state = "wand"
|
||||
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/datum/species/selected_species
|
||||
var/valid_species = list()
|
||||
|
||||
/obj/item/debug/human_spawner/afterattack(atom/target, mob/user, proximity)
|
||||
..()
|
||||
if(isturf(target))
|
||||
var/mob/living/carbon/human/H = new /mob/living/carbon/human(target)
|
||||
if(selected_species)
|
||||
H.set_species(selected_species)
|
||||
|
||||
/obj/item/debug/human_spawner/attack_self(mob/user)
|
||||
..()
|
||||
var/choice = input("Select a species", "Human Spawner", null) in GLOB.species_list
|
||||
selected_species = GLOB.species_list[choice]
|
||||
|
||||
/* Revive this once we purge all the istype checks for tools for tool_behaviour
|
||||
/obj/item/debug/omnitool
|
||||
name = "omnitool"
|
||||
desc = "The original hypertool, born before them all. Use it in hand to unleash it's true power."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "hypertool"
|
||||
item_state = "hypertool"
|
||||
toolspeed = 0.1
|
||||
tool_behaviour = null
|
||||
|
||||
/obj/item/debug/omnitool/examine()
|
||||
. = ..()
|
||||
. += " The mode is: [tool_behaviour]"
|
||||
|
||||
/obj/item/debug/omnitool/proc/check_menu(mob/user)
|
||||
if(!istype(user))
|
||||
return FALSE
|
||||
if(user.incapacitated() || !user.Adjacent(src))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/debug/omnitool/attack_self(mob/user)
|
||||
if(!user)
|
||||
return
|
||||
var/list/tool_list = list(
|
||||
"Crowbar" = image(icon = 'icons/obj/tools.dmi', icon_state = "crowbar"),
|
||||
"Multitool" = image(icon = 'icons/obj/device.dmi', icon_state = "multitool"),
|
||||
"Screwdriver" = image(icon = 'icons/obj/tools.dmi', icon_state = "screwdriver_map"),
|
||||
"Wirecutters" = image(icon = 'icons/obj/tools.dmi', icon_state = "cutters_map"),
|
||||
"Wrench" = image(icon = 'icons/obj/tools.dmi', icon_state = "wrench"),
|
||||
"Welding Tool" = image(icon = 'icons/obj/tools.dmi', icon_state = "miniwelder"),
|
||||
"Analyzer" = image(icon = 'icons/obj/device.dmi', icon_state = "analyzer"),
|
||||
"Mining Tool" = image(icon = 'icons/obj/mining.dmi', icon_state = "minipick"),
|
||||
"Shovel" = image(icon = 'icons/obj/mining.dmi', icon_state = "spade"),
|
||||
"Retractor" = image(icon = 'icons/obj/surgery.dmi', icon_state = "retractor"),
|
||||
"Hemostat" = image(icon = 'icons/obj/surgery.dmi', icon_state = "hemostat"),
|
||||
"Cautery" = image(icon = 'icons/obj/surgery.dmi', icon_state = "cautery"),
|
||||
"Drill" = image(icon = 'icons/obj/surgery.dmi', icon_state = "drill"),
|
||||
"Scalpel" = image(icon = 'icons/obj/surgery.dmi', icon_state = "scalpel"),
|
||||
"Saw" = image(icon = 'icons/obj/surgery.dmi', icon_state = "saw")
|
||||
)
|
||||
var/tool_result = show_radial_menu(user, src, tool_list, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
|
||||
if(!check_menu(user))
|
||||
return
|
||||
switch(tool_result)
|
||||
if("Crowbar")
|
||||
tool_behaviour = TOOL_CROWBAR
|
||||
if("Multitool")
|
||||
tool_behaviour = TOOL_MULTITOOL
|
||||
if("Screwdriver")
|
||||
tool_behaviour = TOOL_SCREWDRIVER
|
||||
if("Wirecutters")
|
||||
tool_behaviour = TOOL_WIRECUTTER
|
||||
if("Wrench")
|
||||
tool_behaviour = TOOL_WRENCH
|
||||
if("Welding Tool")
|
||||
tool_behaviour = TOOL_WELDER
|
||||
if("Analyzer")
|
||||
tool_behaviour = TOOL_ANALYZER
|
||||
if("Mining Tool")
|
||||
tool_behaviour = TOOL_MINING
|
||||
if("Shovel")
|
||||
tool_behaviour = TOOL_SHOVEL
|
||||
if("Retractor")
|
||||
tool_behaviour = TOOL_RETRACTOR
|
||||
if("Hemostat")
|
||||
tool_behaviour = TOOL_HEMOSTAT
|
||||
if("Cautery")
|
||||
tool_behaviour = TOOL_CAUTERY
|
||||
if("Drill")
|
||||
tool_behaviour = TOOL_DRILL
|
||||
if("Scalpel")
|
||||
tool_behaviour = TOOL_SCALPEL
|
||||
if("Saw")
|
||||
tool_behaviour = TOOL_SAW
|
||||
*/
|
||||
@@ -8,6 +8,7 @@
|
||||
var/mob/owner = null //Carp doesn't attack owner, set when using in hand
|
||||
var/owned = 0 //Boolean, no owner to begin with
|
||||
var/mobtype = /mob/living/simple_animal/hostile/carp //So admins can change what mob spawns via var fuckery
|
||||
can_random_spawn = FALSE
|
||||
|
||||
//Attack self
|
||||
/obj/item/toy/plush/carpplushie/dehy_carp/attack_self(mob/user)
|
||||
|
||||
@@ -100,7 +100,8 @@
|
||||
bot_access_flags = CLEAN_BOT
|
||||
|
||||
/obj/item/cartridge/lawyer
|
||||
name = "\improper P.R.O.V.E. cartridge"
|
||||
name = "\improper S.P.A.M. cartridge"
|
||||
desc = "Introducing the Station Public Announcement Messenger cartridge, featuring the unique ability to broadcast-mark messages, designed for lawyers across Nanotrasen to advertise their useful and important services."
|
||||
icon_state = "cart-law"
|
||||
access = CART_SECURITY
|
||||
spam_enabled = 1
|
||||
|
||||
@@ -82,8 +82,9 @@
|
||||
|
||||
/obj/item/implant/explosive/proc/boom_goes_the_weasel()
|
||||
explosion(get_turf(imp_in ? imp_in : src), heavy, medium, weak, weak, flame_range = weak)
|
||||
imp_in?.gib(TRUE)
|
||||
qdel(src)
|
||||
if(!QDELETED(imp_in))
|
||||
imp_in.gib(TRUE)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/implant/explosive/macro
|
||||
name = "macrobomb implant"
|
||||
|
||||
+108
-400
@@ -31,7 +31,16 @@
|
||||
var/normal_desc
|
||||
//--end of love :'(--
|
||||
|
||||
/obj/item/toy/plush/Initialize()
|
||||
var/snowflake_id //if we set from a config snowflake plushie.
|
||||
var/can_random_spawn = TRUE //if this is FALSE, don't spawn this for random plushies.
|
||||
|
||||
/obj/item/toy/plush/random_snowflake/Initialize(mapload, set_snowflake_id)
|
||||
. = ..()
|
||||
var/list/configlist = CONFIG_GET(keyed_list/snowflake_plushies)
|
||||
var/id = pick(configlist)
|
||||
set_snowflake_from_config(id)
|
||||
|
||||
/obj/item/toy/plush/Initialize(mapload, set_snowflake_id)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/squeak, squeak_override)
|
||||
|
||||
@@ -50,6 +59,9 @@
|
||||
|
||||
normal_desc = desc
|
||||
|
||||
if(set_snowflake_id)
|
||||
set_snowflake_from_config(set_snowflake_id)
|
||||
|
||||
/obj/item/toy/plush/Destroy()
|
||||
QDEL_NULL(grenade)
|
||||
|
||||
@@ -97,6 +109,44 @@
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/toy/plush/proc/set_snowflake_from_config(id)
|
||||
var/list/configlist = CONFIG_GET(keyed_list/snowflake_plushies)
|
||||
var/list/jsonlist = configlist[id]
|
||||
ASSERT(jsonlist)
|
||||
jsonlist = json_decode(jsonlist)
|
||||
if(jsonlist["inherit_from"])
|
||||
var/path = text2path(jsonlist["inherit_from"])
|
||||
if(!ispath(path, /obj/item/toy/plush))
|
||||
stack_trace("Invalid path for inheritance")
|
||||
else
|
||||
var/obj/item/toy/plush/P = new path //can't initial() lists
|
||||
name = P.name
|
||||
desc = P.desc
|
||||
icon_state = P.icon_state
|
||||
item_state = P.item_state
|
||||
icon = P.icon
|
||||
squeak_override = P.squeak_override
|
||||
attack_verb = P.attack_verb
|
||||
gender = P.gender
|
||||
qdel(P)
|
||||
if(jsonlist["name"])
|
||||
name = jsonlist["name"]
|
||||
if(jsonlist["desc"])
|
||||
desc = jsonlist["desc"]
|
||||
if(jsonlist["gender"])
|
||||
gender = jsonlist["gender"]
|
||||
if(jsonlist["icon_state"])
|
||||
icon_state = jsonlist["icon_state"]
|
||||
item_state = jsonlist["item_state"]
|
||||
icon = 'config/plushies/sprites.dmi'
|
||||
if(jsonlist["attack_verb"])
|
||||
attack_verb = jsonlist["attack_verb"]
|
||||
if(jsonlist["squeak_override"])
|
||||
squeak_override = jsonlist["squeak_override"]
|
||||
if(squeak_override)
|
||||
var/datum/component/squeak/S = GetComponent(/datum/component/squeak)
|
||||
S?.override_squeak_sounds = squeak_override
|
||||
|
||||
/obj/item/toy/plush/handle_atom_del(atom/A)
|
||||
if(A == grenade)
|
||||
grenade = null
|
||||
@@ -367,13 +417,22 @@
|
||||
if(mood_message)
|
||||
desc += mood_message
|
||||
|
||||
GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
|
||||
/proc/valid_plushie_paths()
|
||||
. = list()
|
||||
for(var/i in subtypesof(/obj/item/toy/plush))
|
||||
var/obj/item/toy/plush/abstract = i
|
||||
if(!initial(abstract.can_random_spawn))
|
||||
continue
|
||||
. += i
|
||||
|
||||
/obj/item/toy/plush/random
|
||||
name = "Illegal plushie"
|
||||
desc = "Something fucked up"
|
||||
var/blacklisted_plushes = list(/obj/item/toy/plush/carpplushie/dehy_carp, /obj/item/toy/plush/awakenedplushie, /obj/item/toy/plush/random)
|
||||
can_random_spawn = FALSE
|
||||
|
||||
/obj/item/toy/plush/random/Initialize()
|
||||
var/newtype = pick(subtypesof(/obj/item/toy/plush) - typecacheof(blacklisted_plushes))
|
||||
var/newtype = prob(CONFIG_GET(number/snowflake_plushie_prob))? /obj/item/toy/plush/random_snowflake : pick(GLOB.valid_plushie_paths)
|
||||
new newtype(loc)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
@@ -504,115 +563,12 @@
|
||||
attack_verb = list("clawed", "hissed", "tail slapped")
|
||||
squeak_override = list('sound/weapons/slash.ogg' = 1)
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/durgit
|
||||
icon_state = "durgit"
|
||||
item_state = "durgit"
|
||||
squeak_override = list('modular_citadel/sound/voice/weh.ogg' = 1) //Durgit's the origin of the sound
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/rio
|
||||
icon_state = "rio"
|
||||
item_state = "rio"
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/dan
|
||||
icon_state = "dan"
|
||||
item_state = "dan"
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/urinsu
|
||||
icon_state = "urinsu"
|
||||
item_state = "urinsu"
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/arfrehn
|
||||
icon_state = "arfrehn"
|
||||
item_state = "arfrehn"
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/soars
|
||||
icon_state = "soars"
|
||||
item_state = "soars"
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/ghostie
|
||||
icon_state = "ghostie"
|
||||
item_state = "ghostie"
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/amber
|
||||
icon_state = "amber"
|
||||
item_state = "amber"
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/cyan
|
||||
icon_state = "cyan"
|
||||
item_state = "cyan"
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/meena
|
||||
icon_state = "meena"
|
||||
item_state = "meena"
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/stalks
|
||||
icon_state = "stalks"
|
||||
item_state = "stalks"
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/kobold
|
||||
name = "kobold plushie"
|
||||
desc = "An adorable stuffed toy that resembles a kobold."
|
||||
icon_state = "kobold"
|
||||
item_state = "kobold"
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/gorgi
|
||||
icon_state = "gorgi"
|
||||
item_state = "gorgi"
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/almaz
|
||||
icon_state = "almaz"
|
||||
item_state = "almaz"
|
||||
squeak_override = list('modular_citadel/sound/voice/raptor_purr.ogg' = 1)
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/garou
|
||||
icon_state = "garou"
|
||||
item_state = "garou"
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/augments
|
||||
icon_state = "augments"
|
||||
item_state = "augments"
|
||||
squeak_override = list('modular_citadel/sound/voice/weh.ogg' = 1) //I have no mouth and I must weh
|
||||
attack_verb = list("hugged", "patted", "snugged", "booped")
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/xekov
|
||||
icon_state = "xekov"
|
||||
item_state = "xekov"
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/greg
|
||||
icon_state = "greg"
|
||||
item_state = "greg"
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/sin
|
||||
icon_state = "sin"
|
||||
item_state = "sin"
|
||||
desc = "An adorable stuffed toy that resembles a lizardperson.. It faintly smells of sulfur."
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/ends
|
||||
icon_state = "ends"
|
||||
item_state = "ends"
|
||||
|
||||
/obj/item/toy/plush/lizardplushie/lyssa
|
||||
icon_state = "lyssa"
|
||||
item_state = "lyssa"
|
||||
|
||||
/obj/item/toy/plush/snakeplushie
|
||||
name = "snake plushie"
|
||||
desc = "An adorable stuffed toy that resembles a snake. Not to be mistaken for the real thing."
|
||||
icon_state = "plushie_snake"
|
||||
item_state = "plushie_snake"
|
||||
attack_verb = list("bitten", "hissed", "tail slapped")
|
||||
squeak_override = list('modular_citadel/sound/voice/hiss.ogg' = 1)
|
||||
|
||||
/obj/item/toy/plush/snakeplushie/sasha
|
||||
icon_state = "sasha"
|
||||
item_state = "sasha"
|
||||
|
||||
/obj/item/toy/plush/snakeplushie/shay
|
||||
icon_state = "shay"
|
||||
item_state = "shay"
|
||||
|
||||
/obj/item/toy/plush/snakeplushie/vulken
|
||||
icon_state = "vulken"
|
||||
item_state = "vulken"
|
||||
|
||||
/obj/item/toy/plush/nukeplushie
|
||||
name = "operative plushie"
|
||||
desc = "A stuffed toy that resembles a syndicate nuclear operative. The tag claims operatives to be purely fictitious."
|
||||
@@ -630,29 +586,17 @@
|
||||
squeak_override = list('sound/effects/blobattack.ogg' = 1)
|
||||
gender = FEMALE //given all the jokes and drawings, I'm not sure the xenobiologists would make a slimeboy
|
||||
|
||||
/obj/item/toy/plush/slimeplushie/annie
|
||||
desc = "An adorable stuffed toy that resembles a slimey crewmember."
|
||||
icon_state = "annie"
|
||||
item_state = "annie"
|
||||
|
||||
/obj/item/toy/plush/slimeplushie/paxton
|
||||
desc = "An adorable stuffed toy that resembles a slimey crewmember."
|
||||
icon_state = "paxton"
|
||||
item_state = "paxton"
|
||||
attack_verb = list("CQC'd", "jabroni'd", "powergamed", "robusted", "cakehatted")
|
||||
gender = MALE
|
||||
|
||||
/obj/item/toy/plush/awakenedplushie
|
||||
name = "awakened plushie"
|
||||
desc = "An ancient plushie that has grown enlightened to the true nature of reality."
|
||||
icon_state = "plushie_awake"
|
||||
item_state = "plushie_awake"
|
||||
can_random_spawn = FALSE
|
||||
|
||||
/obj/item/toy/plush/awakenedplushie/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/edit_complainer)
|
||||
|
||||
|
||||
/obj/item/toy/plush/beeplushie
|
||||
name = "bee plushie"
|
||||
desc = "A cute toy that resembles an even cuter bee."
|
||||
@@ -668,21 +612,7 @@
|
||||
icon_state = "bumble"
|
||||
item_state = "bumble"
|
||||
squeak_override = list('modular_citadel/sound/voice/mothsqueak.ogg' = 1)
|
||||
|
||||
/obj/item/toy/plush/mothplushie/nameko
|
||||
icon_state = "nameko"
|
||||
item_state = "nameko"
|
||||
|
||||
/obj/item/toy/plush/mothplushie/suru
|
||||
icon_state = "suru"
|
||||
item_state = "suru"
|
||||
|
||||
/obj/item/toy/plush/xeno
|
||||
name = "xenohybrid plushie"
|
||||
desc = "An adorable stuffed toy that resmembles a xenomorphic crewmember."
|
||||
icon_state = "seras"
|
||||
item_state = "seras"
|
||||
squeak_override = list('sound/voice/hiss2.ogg' = 1)
|
||||
can_random_spawn = FALSE
|
||||
|
||||
/obj/item/toy/plush/lampplushie
|
||||
name = "lamp plushie"
|
||||
@@ -736,20 +666,6 @@
|
||||
icon_state = "scrubpuppy"
|
||||
item_state = "scrubpuppy"
|
||||
|
||||
/obj/item/toy/plush/borgplushie/seeking
|
||||
icon_state = "seeking"
|
||||
item_state = "seeking"
|
||||
|
||||
/obj/item/toy/plush/borgplushie/neeb
|
||||
icon_state = "neeb"
|
||||
item_state = "neeb"
|
||||
|
||||
/obj/item/toy/plush/borgplushie/bhijn
|
||||
desc = "An adorable stuffed toy of a IPC."
|
||||
icon_state = "bhijn"
|
||||
item_state = "bhijn"
|
||||
attack_verb = list("closed", "reworked", "merged")
|
||||
|
||||
/obj/item/toy/plush/aiplush
|
||||
name = "AI plushie"
|
||||
desc = "A little stuffed toy AI core... it appears to be malfunctioning."
|
||||
@@ -758,246 +674,22 @@
|
||||
attack_verb = list("hacked", "detonated", "overloaded")
|
||||
squeak_override = list('sound/machines/beep.ogg' = 9, 'sound/machines/buzz-two.ogg' = 1)
|
||||
|
||||
/obj/item/toy/plush/bird
|
||||
name = "bird plushie"
|
||||
desc = "An adorable stuffed plushie that resembles an avian."
|
||||
icon_state = "sylas"
|
||||
item_state = "sylas"
|
||||
attack_verb = list("peeped", "beeped", "poofed")
|
||||
squeak_override = list('modular_citadel/sound/voice/peep.ogg' = 1)
|
||||
|
||||
/obj/item/toy/plush/bird/esela
|
||||
icon_state = "esela"
|
||||
item_state = "esela"
|
||||
|
||||
/obj/item/toy/plush/bird/jahonna
|
||||
icon_state = "jahonna"
|
||||
item_state = "jahonna"
|
||||
|
||||
/obj/item/toy/plush/bird/krick
|
||||
icon_state = "krick"
|
||||
item_state = "krick"
|
||||
|
||||
/obj/item/toy/plush/bird/birddi
|
||||
icon_state = "birddi"
|
||||
item_state = "birddi"
|
||||
|
||||
/obj/item/toy/plush/bird/jewel
|
||||
icon_state = "jewel"
|
||||
item_state = "jewel"
|
||||
|
||||
/obj/item/toy/plush/sergal
|
||||
name = "sergal plushie"
|
||||
desc = "An adorable stuffed plushie that resembles a sagaru."
|
||||
icon_state = "faux"
|
||||
item_state = "faux"
|
||||
squeak_override = list('modular_citadel/sound/voice/merp.ogg' = 1)
|
||||
|
||||
/obj/item/toy/plush/sergal/gladwyn
|
||||
icon_state = "gladwyn"
|
||||
item_state = "gladwyn"
|
||||
|
||||
/obj/item/toy/plush/sergal/jermaine
|
||||
icon_state = "jermaine"
|
||||
item_state = "jermaine"
|
||||
|
||||
/obj/item/toy/plush/mammal
|
||||
name = "mammal plushie"
|
||||
desc = "An adorable stuffed toy resembling some sort of crew member."
|
||||
icon_state = "dubious"
|
||||
item_state = "dubious"
|
||||
|
||||
/obj/item/toy/plush/mammal/gavin
|
||||
icon_state = "gavin"
|
||||
item_state = "gavin"
|
||||
|
||||
/obj/item/toy/plush/mammal/blep
|
||||
icon_state = "blep"
|
||||
item_state = "blep"
|
||||
|
||||
/obj/item/toy/plush/mammal/circe
|
||||
desc = "A luxuriously soft toy that resembles a nine-tailed kitsune."
|
||||
icon_state = "circe"
|
||||
item_state = "circe"
|
||||
attack_verb = list("medicated", "tailhugged", "kissed")
|
||||
|
||||
/obj/item/toy/plush/mammal/robin
|
||||
icon_state = "robin"
|
||||
item_state = "robin"
|
||||
|
||||
/obj/item/toy/plush/mammal/pavel
|
||||
icon_state = "pavel"
|
||||
item_state = "pavel"
|
||||
|
||||
/obj/item/toy/plush/mammal/mason
|
||||
icon_state = "mason"
|
||||
item_state = "mason"
|
||||
|
||||
/obj/item/toy/plush/mammal/oten
|
||||
icon_state = "oten"
|
||||
item_state = "oten"
|
||||
|
||||
/obj/item/toy/plush/mammal/ray
|
||||
icon_state = "ray"
|
||||
item_state = "ray"
|
||||
|
||||
/obj/item/toy/plush/mammal/redtail
|
||||
icon_state = "redtail"
|
||||
item_state = "redtail"
|
||||
|
||||
/obj/item/toy/plush/mammal/dawud
|
||||
icon_state = "dawud"
|
||||
item_state = "dawud"
|
||||
|
||||
/obj/item/toy/plush/mammal/edgar
|
||||
icon_state = "edgar"
|
||||
item_state = "edgar"
|
||||
attack_verb = list("collared", "tricked", "headpatted")
|
||||
|
||||
/obj/item/toy/plush/mammal/frank
|
||||
icon_state = "frank"
|
||||
item_state = "frank"
|
||||
|
||||
/obj/item/toy/plush/mammal/poojawa
|
||||
icon_state = "poojawa"
|
||||
item_state = "poojawa"
|
||||
|
||||
/obj/item/toy/plush/mammal/hazel
|
||||
icon_state = "hazel"
|
||||
item_state = "hazel"
|
||||
|
||||
/obj/item/toy/plush/mammal/joker
|
||||
icon_state = "joker"
|
||||
item_state = "joker"
|
||||
|
||||
/obj/item/toy/plush/mammal/gunther
|
||||
icon_state = "gunther"
|
||||
item_state = "gunther"
|
||||
|
||||
/obj/item/toy/plush/mammal/fox
|
||||
icon_state = "fox"
|
||||
item_state = "fox"
|
||||
|
||||
/obj/item/toy/plush/mammal/rae
|
||||
desc = "An adorable stuffed toy of an artic fox."
|
||||
icon_state = "rae"
|
||||
item_state = "rae"
|
||||
/obj/item/toy/plush/snakeplushie
|
||||
name = "snake plushie"
|
||||
desc = "An adorable stuffed toy that resembles a snake. Not to be mistaken for the real thing."
|
||||
icon_state = "plushie_snake"
|
||||
item_state = "plushie_snake"
|
||||
attack_verb = list("bitten", "hissed", "tail slapped")
|
||||
squeak_override = list('modular_citadel/sound/voice/hiss.ogg' = 1)
|
||||
|
||||
/obj/item/toy/plush/mammal/zed
|
||||
desc = "A masked stuffed toy that resembles a fierce miner. He even comes with his own little crusher!"
|
||||
icon_state = "zed"
|
||||
item_state = "zed"
|
||||
attack_verb = list("ENDED", "CRUSHED", "GNOMED")
|
||||
|
||||
/obj/item/toy/plush/mammal/justin
|
||||
icon_state = "justin"
|
||||
item_state = "justin"
|
||||
attack_verb = list("buttslapped", "fixed")
|
||||
|
||||
/obj/item/toy/plush/mammal/reece
|
||||
icon_state = "reece"
|
||||
item_state = "reece"
|
||||
attack_verb = list("healed", "cured", "demoted")
|
||||
|
||||
/obj/item/toy/plush/mammal/redwood
|
||||
desc = "An adorable stuffed toy resembling a Nanotrasen Captain. That just happens to be a bunny."
|
||||
icon_state = "redwood"
|
||||
item_state = "redwood"
|
||||
attack_verb = list("ordered", "bapped", "reprimanded")
|
||||
|
||||
/obj/item/toy/plush/mammal/marisol
|
||||
desc = "An adorable stuffed toy resembling a demi-wolf security officer."
|
||||
icon_state = "marisol"
|
||||
item_state = "marisol"
|
||||
attack_verb = list("arrested", "harmbattoned", "lasered")
|
||||
|
||||
/obj/item/toy/plush/mammal/minty
|
||||
desc = "An adorable stuffed toy resembling some sort of crew member. It smells like mint.."
|
||||
icon_state = "minty"
|
||||
item_state = "minty"
|
||||
attack_verb = list("freshened", "brushed")
|
||||
|
||||
/obj/item/toy/plush/mammal/dog
|
||||
desc = "An adorable stuffed toy that resembles a canine."
|
||||
icon_state = "katlin"
|
||||
item_state = "katlin"
|
||||
attack_verb = list("barked", "boofed", "borked")
|
||||
squeak_override = list(
|
||||
'modular_citadel/sound/voice/bark1.ogg' = 1,
|
||||
'modular_citadel/sound/voice/bark2.ogg' = 1
|
||||
)
|
||||
|
||||
/obj/item/toy/plush/mammal/dog/frost
|
||||
icon_state = "frost"
|
||||
item_state = "frost"
|
||||
|
||||
/obj/item/toy/plush/mammal/dog/atticus
|
||||
icon_state = "atticus"
|
||||
item_state = "atticus"
|
||||
|
||||
/obj/item/toy/plush/mammal/dog/fletch
|
||||
icon_state = "fletch"
|
||||
item_state = "fletch"
|
||||
|
||||
/obj/item/toy/plush/mammal/dog/vincent
|
||||
icon_state = "vincent"
|
||||
item_state = "vincent"
|
||||
|
||||
/obj/item/toy/plush/mammal/dog/zigfried
|
||||
desc = "An adorable stuffed toy of a very good boy."
|
||||
icon_state = "zigfried"
|
||||
item_state = "zigfried"
|
||||
|
||||
/obj/item/toy/plush/mammal/dog/nikolai
|
||||
icon_state = "nikolai"
|
||||
item_state = "nikolai"
|
||||
|
||||
/obj/item/toy/plush/mammal/dog/flynn
|
||||
icon_state = "flynn"
|
||||
item_state = "flynn"
|
||||
|
||||
/obj/item/toy/plush/mammal/dog/fritz
|
||||
icon_state = "fritz"
|
||||
item_state = "fritz"
|
||||
attack_verb = list("barked", "boofed", "shotgun'd")
|
||||
obj_flags = UNIQUE_RENAME
|
||||
unique_reskin = list("Goodboye" = "fritz", "Badboye" = "fritz_bad")
|
||||
|
||||
/obj/item/toy/plush/mammal/dog/jesse
|
||||
desc = "An adorable wolf toy that resembles a cream-colored wolf. He has a little pride flag!"
|
||||
icon_state = "jesse"
|
||||
item_state = "jesse"
|
||||
attack_verb = list("greeted", "merc'd", "howdy'd")
|
||||
|
||||
/obj/item/toy/plush/catgirl
|
||||
name = "feline plushie"
|
||||
desc = "An adorable stuffed toy that resembles a feline."
|
||||
icon_state = "bailey"
|
||||
item_state = "bailey"
|
||||
attack_verb = list("headbutt", "scritched", "bit")
|
||||
squeak_override = list('modular_citadel/sound/voice/nya.ogg' = 1)
|
||||
|
||||
/obj/item/toy/plush/catgirl/mikeel
|
||||
desc = "An adorable stuffed toy of some tauric cat person."
|
||||
icon_state = "mikeel"
|
||||
item_state = "mikeel"
|
||||
|
||||
/obj/item/toy/plush/catgirl/skylar
|
||||
desc = "An adorable stuffed toy that resembles a degenerate."
|
||||
icon_state = "skylar2"
|
||||
item_state = "skylar2"
|
||||
attack_verb = list("powergamed", "merged", "tabled")
|
||||
squeak_override = list('sound/effects/meow1.ogg' = 1)
|
||||
|
||||
/obj/item/toy/plush/catgirl/drew
|
||||
icon_state = "drew"
|
||||
item_state = "drew"
|
||||
|
||||
/obj/item/toy/plush/catgirl/trilby
|
||||
desc = "A masked stuffed toy that resembles a feline scientist."
|
||||
icon_state = "trilby"
|
||||
item_state = "trilby"
|
||||
attack_verb = list("PR'd", "coded", "remembered")
|
||||
/obj/item/toy/plush/mammal
|
||||
name = "mammal plushie"
|
||||
desc = "An adorable stuffed toy resembling some sort of crew member."
|
||||
can_random_spawn = FALSE
|
||||
|
||||
/obj/item/toy/plush/catgirl/fermis
|
||||
name = "medcat plushie"
|
||||
@@ -1007,20 +699,36 @@
|
||||
attack_verb = list("cuddled", "petpatted", "wigglepurred")
|
||||
squeak_override = list('modular_citadel/sound/voice/merowr.ogg' = 1)
|
||||
|
||||
/obj/item/toy/plush/catgirl/mariaf
|
||||
desc = "An adorable stuffed toy that resembles a very tall cat girl."
|
||||
icon_state = "mariaf"
|
||||
item_state = "mariaf"
|
||||
attack_verb = list("hugged", "stabbed", "licked")
|
||||
/obj/item/toy/plush/xeno
|
||||
name = "xenohybrid plushie"
|
||||
desc = "An adorable stuffed toy that resmembles a xenomorphic crewmember."
|
||||
squeak_override = list('sound/voice/hiss2.ogg' = 1)
|
||||
can_random_spawn = FALSE
|
||||
|
||||
/obj/item/toy/plush/catgirl/maya
|
||||
desc = "An adorable stuffed toy that resembles an angry cat girl. She has her own tiny nuke disk!"
|
||||
icon_state = "maya"
|
||||
item_state = "maya"
|
||||
attack_verb = list("nuked", "arrested", "harmbatonned")
|
||||
/obj/item/toy/plush/bird
|
||||
name = "bird plushie"
|
||||
desc = "An adorable stuffed plushie that resembles an avian."
|
||||
attack_verb = list("peeped", "beeped", "poofed")
|
||||
squeak_override = list('modular_citadel/sound/voice/peep.ogg' = 1)
|
||||
can_random_spawn = FALSE
|
||||
|
||||
/obj/item/toy/plush/catgirl/marisa
|
||||
desc = "An adorable stuffed toy that resembles a crew member, or maybe a witch. Having it makes you feel you can win."
|
||||
icon_state = "marisa"
|
||||
item_state = "marisa"
|
||||
attack_verb = list("blasted", "sparked", "dazzled")
|
||||
/obj/item/toy/plush/sergal
|
||||
name = "sergal plushie"
|
||||
desc = "An adorable stuffed plushie that resembles a sagaru."
|
||||
squeak_override = list('modular_citadel/sound/voice/merp.ogg' = 1)
|
||||
can_random_spawn = FALSE
|
||||
|
||||
/obj/item/toy/plush/mammal/dog
|
||||
desc = "An adorable stuffed toy that resembles a canine."
|
||||
attack_verb = list("barked", "boofed", "borked")
|
||||
squeak_override = list(
|
||||
'modular_citadel/sound/voice/bark1.ogg' = 1,
|
||||
'modular_citadel/sound/voice/bark2.ogg' = 1
|
||||
)
|
||||
|
||||
/obj/item/toy/plush/catgirl
|
||||
name = "feline plushie"
|
||||
desc = "An adorable stuffed toy that resembles a feline."
|
||||
attack_verb = list("headbutt", "scritched", "bit")
|
||||
squeak_override = list('modular_citadel/sound/voice/nya.ogg' = 1)
|
||||
can_random_spawn = FALSE
|
||||
|
||||
@@ -698,6 +698,16 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
|
||||
/*
|
||||
* Bones
|
||||
*/
|
||||
|
||||
GLOBAL_LIST_INIT(bone_recipes, list(
|
||||
new /datum/stack_recipe("Bone Dagger", /obj/item/kitchen/knife/combat/bone, 2, time = 20), \
|
||||
new /datum/stack_recipe("Skull Helmet", /obj/item/clothing/head/helmet/skull, 4, time = 30), \
|
||||
new /datum/stack_recipe("Bone Armor", /obj/item/clothing/suit/armor/bone, 6, time = 30)))
|
||||
|
||||
/obj/item/stack/sheet/bone/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.bone_recipes
|
||||
. = ..()
|
||||
|
||||
/obj/item/stack/sheet/bone
|
||||
name = "bones"
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
@@ -714,6 +724,10 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
|
||||
grind_results = list(/datum/reagent/carbon = 10)
|
||||
merge_type = /obj/item/stack/sheet/bone
|
||||
|
||||
/*
|
||||
* Plastic
|
||||
*/
|
||||
|
||||
GLOBAL_LIST_INIT(plastic_recipes, list(
|
||||
new /datum/stack_recipe("see-through plastic flaps", /obj/structure/plasticflaps, 5, one_per_turf = TRUE, on_floor = TRUE, time = 40), \
|
||||
new /datum/stack_recipe("opaque plastic flaps", /obj/structure/plasticflaps/opaque, 5, one_per_turf = TRUE, on_floor = TRUE, time = 40), \
|
||||
|
||||
@@ -244,3 +244,6 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
|
||||
|
||||
/obj/item/storage/book/bible/syndicate/add_blood_DNA(list/blood_dna)
|
||||
return FALSE
|
||||
|
||||
/obj/item/storage/book/bible/syndicate/empty
|
||||
uses = 0
|
||||
|
||||
@@ -1288,3 +1288,62 @@
|
||||
/obj/item/storage/box/marshmallow/PopulateContents()
|
||||
for (var/i in 1 to 5)
|
||||
new /obj/item/reagent_containers/food/snacks/marshmallow(src)
|
||||
|
||||
/obj/item/storage/box/material/PopulateContents() //less uranium because radioactive
|
||||
var/static/items_inside = list(
|
||||
/obj/item/stack/sheet/metal/fifty=1,\
|
||||
/obj/item/stack/sheet/glass/fifty=1,\
|
||||
/obj/item/stack/sheet/rglass=50,\
|
||||
/obj/item/stack/sheet/plasmaglass=50,\
|
||||
/obj/item/stack/sheet/titaniumglass=50,\
|
||||
/obj/item/stack/sheet/plastitaniumglass=50,\
|
||||
/obj/item/stack/sheet/plasteel=50,\
|
||||
/obj/item/stack/sheet/mineral/plastitanium=50,\
|
||||
/obj/item/stack/sheet/mineral/titanium=50,\
|
||||
/obj/item/stack/sheet/mineral/gold=50,\
|
||||
/obj/item/stack/sheet/mineral/silver=50,\
|
||||
/obj/item/stack/sheet/mineral/plasma=50,\
|
||||
/obj/item/stack/sheet/mineral/uranium=50,\
|
||||
/obj/item/stack/sheet/mineral/diamond=50,\
|
||||
/obj/item/stack/sheet/bluespace_crystal=50,\
|
||||
/obj/item/stack/sheet/mineral/bananium=50,\
|
||||
/obj/item/stack/sheet/mineral/wood=50,\
|
||||
/obj/item/stack/sheet/plastic/fifty=1,\
|
||||
/obj/item/stack/sheet/runed_metal/fifty=1
|
||||
)
|
||||
generate_items_inside(items_inside, src)
|
||||
|
||||
/obj/item/storage/box/debugtools
|
||||
name = "box of debug tools"
|
||||
icon_state = "syndiebox"
|
||||
|
||||
/obj/item/storage/box/debugtools/PopulateContents()
|
||||
var/static/items_inside = list(
|
||||
/obj/item/flashlight/emp/debug=1,\
|
||||
/obj/item/pda=1,\
|
||||
/obj/item/modular_computer/tablet/preset/advanced=1,\
|
||||
/obj/item/geiger_counter=1,\
|
||||
/obj/item/construction/rcd/combat/admin=1,\
|
||||
/obj/item/pipe_dispenser=1,\
|
||||
/obj/item/card/emag=1,\
|
||||
/obj/item/healthanalyzer/advanced=1,\
|
||||
/obj/item/disk/tech_disk/debug=1,\
|
||||
/obj/item/uplink/debug=1,\
|
||||
/obj/item/uplink/nuclear/debug=1,\
|
||||
/obj/item/storage/box/beakers/bluespace=1,\
|
||||
/obj/item/storage/box/beakers/variety=1,\
|
||||
/obj/item/storage/box/material=1,\
|
||||
/obj/item/storage/belt/medical/surgery_belt_adv
|
||||
)
|
||||
generate_items_inside(items_inside, src)
|
||||
|
||||
/obj/item/storage/box/beakers/variety
|
||||
name = "beaker variety box"
|
||||
|
||||
/obj/item/storage/box/beakers/variety/PopulateContents()
|
||||
new /obj/item/reagent_containers/glass/beaker(src)
|
||||
new /obj/item/reagent_containers/glass/beaker/large(src)
|
||||
new /obj/item/reagent_containers/glass/beaker/plastic(src)
|
||||
new /obj/item/reagent_containers/glass/beaker/meta(src)
|
||||
new /obj/item/reagent_containers/glass/beaker/noreact(src)
|
||||
new /obj/item/reagent_containers/glass/beaker/bluespace(src)
|
||||
|
||||
@@ -453,6 +453,7 @@
|
||||
force_wielded = 0
|
||||
attack_verb = list("attacked", "struck", "hit")
|
||||
total_mass_on = TOTAL_MASS_TOY_SWORD
|
||||
sharpness = IS_BLUNT
|
||||
|
||||
/obj/item/twohanded/dualsaber/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
return FALSE
|
||||
@@ -472,6 +473,7 @@
|
||||
attack_verb = list("attacked", "struck", "hit")
|
||||
total_mass_on = TOTAL_MASS_TOY_SWORD
|
||||
slowdown_wielded = 0
|
||||
sharpness = IS_BLUNT
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
return FALSE
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
structureclimber.visible_message("<span class='warning'>[structureclimber] has been knocked off [src].", "You're knocked off [src]!", "You see [structureclimber] get knocked off [src].</span>")
|
||||
|
||||
/obj/structure/ui_act(action, params)
|
||||
..()
|
||||
. = ..()
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/structure/MouseDrop_T(atom/movable/O, mob/user)
|
||||
|
||||
@@ -8,14 +8,16 @@
|
||||
max_integrity = 1
|
||||
armor = list("melee" = 0, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 20)
|
||||
var/obj/item/holosign_creator/projector
|
||||
var/init_vis_overlay = TRUE
|
||||
|
||||
/obj/structure/holosign/Initialize(mapload, source_projector)
|
||||
. = ..()
|
||||
if(source_projector)
|
||||
projector = source_projector
|
||||
projector.signs += src
|
||||
SSvis_overlays.add_vis_overlay(src, icon, icon_state, ABOVE_MOB_LAYER, plane, dir, alpha, RESET_ALPHA) //you see mobs under it, but you hit them like they are above it
|
||||
alpha = 0
|
||||
if(init_vis_overlay)
|
||||
SSvis_overlays.add_vis_overlay(src, icon, icon_state, ABOVE_MOB_LAYER, plane, dir, alpha, RESET_ALPHA) //you see mobs under it, but you hit them like they are above it
|
||||
alpha = 0
|
||||
|
||||
/obj/structure/holosign/Destroy()
|
||||
if(projector)
|
||||
@@ -74,8 +76,10 @@
|
||||
icon_state = "holo_fan"
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
layer = ABOVE_NORMAL_TURF_LAYER
|
||||
CanAtmosPass = ATMOS_PASS_NO
|
||||
alpha = 150
|
||||
init_vis_overlay = FALSE
|
||||
|
||||
/obj/structure/holosign/barrier/atmos/Initialize()
|
||||
. = ..()
|
||||
@@ -100,7 +104,9 @@
|
||||
max_integrity = 30
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
layer = ABOVE_NORMAL_TURF_LAYER
|
||||
alpha = 150
|
||||
init_vis_overlay = FALSE
|
||||
CanAtmosPass = ATMOS_PASS_NO
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
|
||||
@@ -595,6 +595,14 @@
|
||||
/obj/structure/window/plastitanium/unanchored
|
||||
anchored = FALSE
|
||||
|
||||
//pirate ship windows
|
||||
/obj/structure/window/plastitanium/pirate
|
||||
desc = "Yarr this window be explosion proof!"
|
||||
explosion_block = 30
|
||||
|
||||
/obj/structure/window/plastitanium/pirate/unanchored
|
||||
anchored = FALSE
|
||||
|
||||
/obj/structure/window/reinforced/clockwork
|
||||
name = "brass window"
|
||||
desc = "A paper-thin pane of translucent yet reinforced brass."
|
||||
|
||||
+1
-1
@@ -129,7 +129,7 @@ GLOBAL_LIST_INIT(freqtospan, list(
|
||||
/atom/movable/proc/attach_spans(input, list/spans)
|
||||
var/customsayverb = findtext(input, "*")
|
||||
if(customsayverb)
|
||||
input = capitalize(copytext(input, length(input[customsayverb]) + 1))
|
||||
input = capitalize(copytext(input, customsayverb + length(input[customsayverb])))
|
||||
if(input)
|
||||
return "[message_spans_start(spans)][input]</span>"
|
||||
else
|
||||
|
||||
@@ -302,4 +302,4 @@
|
||||
|
||||
/turf/closed/wall/mineral/plastitanium/copyTurf(turf/T)
|
||||
. = ..()
|
||||
T.transform = transform
|
||||
T.transform = transform
|
||||
@@ -258,3 +258,22 @@
|
||||
/turf/closed/wall/r_wall/syndicate/overspace
|
||||
icon_state = "map-overspace"
|
||||
fixed_underlay = list("space"=1)
|
||||
|
||||
/////////////////////Pirate Ship walls/////////////////////
|
||||
|
||||
/turf/closed/wall/r_wall/syndicate/pirate
|
||||
desc = "Yarr just try to blow this to smithereens!"
|
||||
explosion_block = 30
|
||||
canSmoothWith = list(/turf/closed/wall/r_wall/syndicate/pirate, /obj/machinery/door/airlock/shuttle, /obj/machinery/door/airlock, /obj/structure/window/plastitanium/pirate, /obj/structure/shuttle/engine, /obj/structure/falsewall/plastitanium)
|
||||
|
||||
/turf/closed/wall/r_wall/syndicate/pirate/nodiagonal
|
||||
smooth = SMOOTH_MORE
|
||||
icon_state = "map-shuttle_nd"
|
||||
|
||||
/turf/closed/wall/r_wall/syndicate/pirate/nosmooth
|
||||
icon = 'icons/turf/shuttle.dmi'
|
||||
icon_state = "wall"
|
||||
|
||||
/turf/closed/wall/r_wall/syndicate/pirate/overspace
|
||||
icon_state = "map-overspace"
|
||||
fixed_underlay = list("space"=1)
|
||||
|
||||
@@ -171,7 +171,8 @@
|
||||
var/turf/T = user.loc //get user's location for delay checks
|
||||
|
||||
//the istype cascade has been spread among various procs for easy overriding
|
||||
if(try_clean(W, user, T) || try_wallmount(W, user, T) || try_decon(W, user, T) || try_destroy(W, user, T))
|
||||
var/srctype = type
|
||||
if(try_clean(W, user, T) || try_wallmount(W, user, T) || try_decon(W, user, T) || (type == srctype && try_destroy(W, user, T)))
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
@@ -8,6 +8,7 @@ GLOBAL_LIST(topic_status_cache)
|
||||
//This happens after the Master subsystem new(s) (it's a global datum)
|
||||
//So subsystems globals exist, but are not initialised
|
||||
/world/New()
|
||||
enable_debugger()
|
||||
|
||||
log_world("World loaded at [TIME_STAMP("hh:mm:ss", FALSE)]!")
|
||||
|
||||
|
||||
@@ -214,4 +214,4 @@ GLOBAL_VAR(antag_prototypes)
|
||||
var/datum/browser/panel = new(usr, "traitorpanel", "", 600, 600)
|
||||
panel.set_content(out)
|
||||
panel.open()
|
||||
return
|
||||
return
|
||||
|
||||
@@ -20,6 +20,7 @@ GLOBAL_LIST_EMPTY(antagonists)
|
||||
var/show_in_antagpanel = TRUE //This will hide adding this antag type in antag panel, use only for internal subtypes that shouldn't be added directly but still show if possessed by mind
|
||||
var/antagpanel_category = "Uncategorized" //Antagpanel will display these together, REQUIRED
|
||||
var/show_name_in_check_antagonists = FALSE //Will append antagonist name in admin listings - use for categories that share more than one antag type
|
||||
var/list/blacklisted_quirks = list(/datum/quirk/nonviolent,/datum/quirk/mute) // Quirks that will be removed upon gaining this antag. Pacifist and mute are default.
|
||||
|
||||
/datum/antagonist/New()
|
||||
GLOB.antagonists += src
|
||||
@@ -70,6 +71,7 @@ GLOBAL_LIST_EMPTY(antagonists)
|
||||
greet()
|
||||
apply_innate_effects()
|
||||
give_antag_moodies()
|
||||
remove_blacklisted_quirks()
|
||||
if(is_banned(owner.current) && replace_banned)
|
||||
replace_banned_player()
|
||||
|
||||
@@ -117,6 +119,18 @@ GLOBAL_LIST_EMPTY(antagonists)
|
||||
return
|
||||
SEND_SIGNAL(owner.current, COMSIG_CLEAR_MOOD_EVENT, "antag_moodlet")
|
||||
|
||||
/datum/antagonist/proc/remove_blacklisted_quirks()
|
||||
var/mob/living/L = owner.current
|
||||
if(istype(L))
|
||||
var/list/my_quirks = L.client?.prefs.all_quirks.Copy()
|
||||
SSquirks.filter_quirks(my_quirks,blacklisted_quirks)
|
||||
for(var/q in L.roundstart_quirks)
|
||||
var/datum/quirk/Q = q
|
||||
if(!(SSquirks.quirk_name_by_path(Q.type) in my_quirks))
|
||||
if(initial(Q.antag_removal_text))
|
||||
to_chat(L, "<span class='boldannounce'>[initial(Q.antag_removal_text)]</span>")
|
||||
L.remove_quirk(Q.type)
|
||||
|
||||
//Returns the team antagonist belongs to if any.
|
||||
/datum/antagonist/proc/get_team()
|
||||
return
|
||||
@@ -134,7 +148,7 @@ GLOBAL_LIST_EMPTY(antagonists)
|
||||
if(objectives.len)
|
||||
report += printobjectives(objectives)
|
||||
for(var/datum/objective/objective in objectives)
|
||||
if(!objective.check_completion())
|
||||
if(objective.completable && !objective.check_completion())
|
||||
objectives_complete = FALSE
|
||||
break
|
||||
|
||||
|
||||
@@ -36,11 +36,17 @@
|
||||
var/win = TRUE
|
||||
var/objective_count = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
if(objective.check_completion())
|
||||
report += "<B>Objective #[objective_count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</span>"
|
||||
if(objective.completable)
|
||||
var/completion = objective.check_completion()
|
||||
if(completion >= 1)
|
||||
report += "<B>Objective #[objective_count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</span>"
|
||||
else if(completion <= 0)
|
||||
report += "<B>Objective #[objective_count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
win = FALSE
|
||||
else
|
||||
report += "<B>Objective #[objective_count]</B>: [objective.explanation_text] <span class='yellowtext'>[completion*100]%</span>"
|
||||
else
|
||||
report += "<B>Objective #[objective_count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
win = FALSE
|
||||
report += "<B>Objective #[objective_count]</B>: [objective.explanation_text]"
|
||||
objective_count++
|
||||
if(win)
|
||||
report += "<span class='greentext'>The [name] was successful!</span>"
|
||||
|
||||
@@ -31,12 +31,11 @@
|
||||
if(was_running)
|
||||
user.toggle_move_intent()
|
||||
ADD_TRAIT(user, TRAIT_NORUNNING, "cloak of darkness")
|
||||
while(bloodsuckerdatum && ContinueActive(user) || user.m_intent == MOVE_INTENT_RUN)
|
||||
while(bloodsuckerdatum && ContinueActive(user))
|
||||
// Pay Blood Toll (if awake)
|
||||
owner.alpha = max(20, owner.alpha - min(75, 10 + 5 * level_current))
|
||||
bloodsuckerdatum.AddBloodVolume(-0.2)
|
||||
sleep(5) // Check every few ticks that we haven't disabled this power
|
||||
// Return to Running (if you were before)
|
||||
|
||||
/datum/action/bloodsucker/cloak/ContinueActive(mob/living/user, mob/living/target)
|
||||
if (!..())
|
||||
|
||||
@@ -108,11 +108,17 @@
|
||||
var/win = TRUE
|
||||
var/objective_count = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
if(objective.check_completion())
|
||||
parts += "<B>Objective #[objective_count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</span>"
|
||||
if(objective.completable)
|
||||
var/completion = objective.check_completion()
|
||||
if(completion >= 1)
|
||||
parts += "<B>Objective #[objective_count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</span>"
|
||||
else if(completion <= 0)
|
||||
parts += "<B>Objective #[objective_count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
win = FALSE
|
||||
else
|
||||
parts += "<B>Objective #[objective_count]</B>: [objective.explanation_text] <span class='yellowtext'>[completion*100]%</span>"
|
||||
else
|
||||
parts += "<B>Objective #[objective_count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
win = FALSE
|
||||
parts += "<B>Objective #[objective_count]</B>: [objective.explanation_text]"
|
||||
objective_count++
|
||||
if(win)
|
||||
parts += "<span class='greentext'>The blood brothers were successful!</span>"
|
||||
|
||||
@@ -54,8 +54,10 @@
|
||||
var/honorific
|
||||
if(owner.current.gender == FEMALE)
|
||||
honorific = "Ms."
|
||||
else
|
||||
else if(owner.current.gender == MALE)
|
||||
honorific = "Mr."
|
||||
else
|
||||
honorific = "Mx."
|
||||
if(GLOB.possible_changeling_IDs.len)
|
||||
changelingID = pick(GLOB.possible_changeling_IDs)
|
||||
GLOB.possible_changeling_IDs -= changelingID
|
||||
@@ -552,11 +554,17 @@
|
||||
if(objectives.len)
|
||||
var/count = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
if(objective.check_completion())
|
||||
parts += "<b>Objective #[count]</b>: [objective.explanation_text] <span class='greentext'>Success!</b></span>"
|
||||
if(objective.completable)
|
||||
var/completion = objective.check_completion()
|
||||
if(completion >= 1)
|
||||
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</span>"
|
||||
else if(completion <= 0)
|
||||
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
changelingwin = FALSE
|
||||
else
|
||||
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='yellowtext'>[completion*100]%</span>"
|
||||
else
|
||||
parts += "<b>Objective #[count]</b>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
changelingwin = 0
|
||||
parts += "<B>Objective #[count]</B>: [objective.explanation_text]"
|
||||
count++
|
||||
|
||||
if(changelingwin)
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/datum/antagonist/collector
|
||||
name = "Contraband Collector"
|
||||
show_in_antagpanel = FALSE
|
||||
show_name_in_check_antagonists = FALSE
|
||||
blacklisted_quirks = list() // no blacklist, these guys are harmless
|
||||
|
||||
/datum/antagonist/collector/proc/forge_objectives()
|
||||
var/datum/objective/hoard/collector/O = new
|
||||
O.owner = owner
|
||||
O.find_target()
|
||||
objectives += O
|
||||
|
||||
/datum/antagonist/collector/on_gain()
|
||||
forge_objectives()
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/collector/greet()
|
||||
to_chat(owner, "<B>You are a contraband collector!</B>")
|
||||
owner.announce_objectives()
|
||||
@@ -425,10 +425,16 @@
|
||||
parts += "<b>The cultists' objectives were:</b>"
|
||||
var/count = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
if(objective.check_completion())
|
||||
parts += "<b>Objective #[count]</b>: [objective.explanation_text] <span class='greentext'>Success!</span>"
|
||||
if(objective.completable)
|
||||
var/completion = objective.check_completion()
|
||||
if(completion >= 1)
|
||||
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</span>"
|
||||
else if(completion <= 0)
|
||||
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
else
|
||||
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='yellowtext'>[completion*100]%</span>"
|
||||
else
|
||||
parts += "<b>Objective #[count]</b>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
parts += "<B>Objective #[count]</B>: [objective.explanation_text]"
|
||||
count++
|
||||
|
||||
if(members.len)
|
||||
|
||||
@@ -44,11 +44,17 @@
|
||||
var/objectives_text = ""
|
||||
var/count = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
if(objective.check_completion())
|
||||
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'>Success!</span>"
|
||||
if(objective.completable)
|
||||
var/completion = objective.check_completion()
|
||||
if(completion >= 1)
|
||||
result += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</span>"
|
||||
else if(completion <= 0)
|
||||
result += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
win = FALSE
|
||||
else
|
||||
result += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='yellowtext'>[completion*100]%</span>"
|
||||
else
|
||||
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
win = FALSE
|
||||
result += "<B>Objective #[count]</B>: [objective.explanation_text]"
|
||||
count++
|
||||
|
||||
result += objectives_text
|
||||
|
||||
@@ -63,10 +63,10 @@
|
||||
possible_targets.Cut(index,index+1)
|
||||
|
||||
if(is_bad_guy ^ helping_station) //kill (good-ninja + bad-guy or bad-ninja + good-guy)
|
||||
var/datum/objective/assassinate/O = new /datum/objective/assassinate()
|
||||
var/datum/objective/assassinate/once/O = new /datum/objective/assassinate()
|
||||
O.owner = owner
|
||||
O.target = M
|
||||
O.explanation_text = "Slay \the [M.current.real_name], the [M.assigned_role]."
|
||||
O.explanation_text = "Slay \the [M.current.real_name], the [M.assigned_role]. You may let [M.p_they()] live, if they come back from death."
|
||||
objectives += O
|
||||
else //protect
|
||||
var/datum/objective/protect/O = new /datum/objective/protect()
|
||||
@@ -74,23 +74,16 @@
|
||||
O.target = M
|
||||
O.explanation_text = "Protect \the [M.current.real_name], the [M.assigned_role], from harm."
|
||||
objectives += O
|
||||
if(4) //debrain/capture
|
||||
if(!possible_targets.len) continue
|
||||
var/selected = rand(1,possible_targets.len)
|
||||
var/datum/mind/M = possible_targets[selected]
|
||||
var/is_bad_guy = possible_targets[M]
|
||||
possible_targets.Cut(selected,selected+1)
|
||||
|
||||
if(is_bad_guy ^ helping_station) //debrain (good-ninja + bad-guy or bad-ninja + good-guy)
|
||||
var/datum/objective/debrain/O = new /datum/objective/debrain()
|
||||
if(4) //flavor
|
||||
if(helping_station)
|
||||
var/datum/objective/flavor/ninja_helping/O = new /datum/objective/flavor/ninja_helping
|
||||
O.owner = owner
|
||||
O.target = M
|
||||
O.explanation_text = "Steal the brain of [M.current.real_name]."
|
||||
O.forge_objective()
|
||||
objectives += O
|
||||
else //capture
|
||||
var/datum/objective/capture/O = new /datum/objective/capture()
|
||||
else
|
||||
var/datum/objective/flavor/ninja_syndie/O = new /datum/objective/flavor/ninja_helping
|
||||
O.owner = owner
|
||||
O.gen_amount_goal()
|
||||
O.forge_objective()
|
||||
objectives += O
|
||||
else
|
||||
break
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
|
||||
/datum/antagonist/nukeop/clownop/on_gain()
|
||||
. = ..()
|
||||
ADD_TRAIT(owner, TRAIT_CLOWN_MENTALITY, NUKEOP_ANTAGONIST)
|
||||
ADD_TRAIT(owner, TRAIT_CLOWN_MENTALITY, CLOWNOP_TRAIT)
|
||||
|
||||
/datum/antagonist/nukeop/clownop/on_removal()
|
||||
REMOVE_TRAIT(owner, TRAIT_CLOWN_MENTALITY, NUKEOP_ANTAGONIST)
|
||||
REMOVE_TRAIT(owner, TRAIT_CLOWN_MENTALITY, CLOWNOP_TRAIT)
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/nukeop/leader/clownop
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "Survivalist"
|
||||
show_in_antagpanel = FALSE
|
||||
show_name_in_check_antagonists = TRUE
|
||||
blacklisted_quirks = list(/datum/quirk/nonviolent) // mutes are allowed
|
||||
var/greet_message = ""
|
||||
|
||||
/datum/antagonist/survivalist/proc/forge_objectives()
|
||||
@@ -19,20 +20,8 @@
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/survivalist/guns
|
||||
greet_message = "Your own safety matters above all else, and the only way to ensure your safety is to stockpile weapons! Grab as many guns as possible, by any means necessary. Kill anyone who gets in your way."
|
||||
|
||||
/datum/antagonist/survivalist/guns/forge_objectives()
|
||||
var/datum/objective/steal_five_of_type/summon_guns/guns = new
|
||||
guns.owner = owner
|
||||
objectives += guns
|
||||
..()
|
||||
greet_message = "Your own safety matters above all else, and the only way to ensure your safety is to stockpile weapons! Grab as many guns as possible, and don't let anyone take them!"
|
||||
|
||||
/datum/antagonist/survivalist/magic
|
||||
name = "Amateur Magician"
|
||||
greet_message = "Grow your newfound talent! Grab as many magical artefacts as possible, by any means necessary. Kill anyone who gets in your way."
|
||||
|
||||
/datum/antagonist/survivalist/magic/forge_objectives()
|
||||
var/datum/objective/steal_five_of_type/summon_magic/magic = new
|
||||
magic.owner = owner
|
||||
objectives += magic
|
||||
..()
|
||||
greet_message = "This magic stuff is... so powerful. You want more. More! They want your power. They can't have it! Don't let them have it!"
|
||||
|
||||
@@ -77,19 +77,23 @@
|
||||
var/is_hijacker = FALSE
|
||||
var/datum/game_mode/dynamic/mode
|
||||
var/is_dynamic = FALSE
|
||||
var/hijack_prob = 0
|
||||
if(istype(SSticker.mode,/datum/game_mode/dynamic))
|
||||
mode = SSticker.mode
|
||||
is_dynamic = TRUE
|
||||
if(mode.storyteller.flags & NO_ASSASSIN)
|
||||
is_hijacker = FALSE
|
||||
if(mode.threat >= CONFIG_GET(number/dynamic_hijack_cost))
|
||||
hijack_prob = CLAMP(mode.threat_level-50,0,20)
|
||||
if(GLOB.joined_player_list.len>=GLOB.dynamic_high_pop_limit)
|
||||
is_hijacker = (prob(10) && mode.threat_level > CONFIG_GET(number/dynamic_hijack_high_population_requirement))
|
||||
is_hijacker = (prob(hijack_prob) && mode.threat_level > CONFIG_GET(number/dynamic_hijack_high_population_requirement))
|
||||
else
|
||||
var/indice_pop = min(10,round(GLOB.joined_player_list.len/mode.pop_per_requirement)+1)
|
||||
is_hijacker = (prob(10) && (mode.threat_level >= CONFIG_GET(number_list/dynamic_hijack_requirements)[indice_pop]))
|
||||
is_hijacker = (prob(hijack_prob) && (mode.threat_level >= CONFIG_GET(number_list/dynamic_hijack_requirements)[indice_pop]))
|
||||
if(mode.storyteller.flags & NO_ASSASSIN)
|
||||
is_hijacker = FALSE
|
||||
else if (GLOB.joined_player_list.len >= 30) // Less murderboning on lowpop thanks
|
||||
hijack_prob = 10
|
||||
is_hijacker = prob(10)
|
||||
var/martyr_chance = prob(20)
|
||||
var/martyr_chance = prob(hijack_prob*2)
|
||||
var/objective_count = is_hijacker //Hijacking counts towards number of objectives
|
||||
if(!SSticker.mode.exchange_blue && SSticker.mode.traitors.len >= 8) //Set up an exchange if there are enough traitors
|
||||
if(!SSticker.mode.exchange_red)
|
||||
@@ -170,7 +174,7 @@
|
||||
if(istype(SSticker.mode,/datum/game_mode/dynamic))
|
||||
mode = SSticker.mode
|
||||
is_dynamic = TRUE
|
||||
assassin_prob = mode.threat_level*(2/3)
|
||||
assassin_prob = max(0,mode.threat_level-20)
|
||||
if(prob(assassin_prob))
|
||||
if(is_dynamic)
|
||||
var/threat_spent = CONFIG_GET(number/dynamic_assassinate_cost)
|
||||
@@ -187,22 +191,37 @@
|
||||
maroon_objective.owner = owner
|
||||
maroon_objective.find_target()
|
||||
add_objective(maroon_objective)
|
||||
else
|
||||
else if(prob(max(0,assassin_prob-20)))
|
||||
var/datum/objective/assassinate/kill_objective = new
|
||||
kill_objective.owner = owner
|
||||
kill_objective.find_target()
|
||||
add_objective(kill_objective)
|
||||
else
|
||||
var/datum/objective/assassinate/once/kill_objective = new
|
||||
kill_objective.owner = owner
|
||||
kill_objective.find_target()
|
||||
add_objective(kill_objective)
|
||||
else
|
||||
if(prob(15) && !(locate(/datum/objective/download) in objectives) && !(owner.assigned_role in list("Research Director", "Scientist", "Roboticist")))
|
||||
var/datum/objective/download/download_objective = new
|
||||
download_objective.owner = owner
|
||||
download_objective.gen_amount_goal()
|
||||
add_objective(download_objective)
|
||||
else
|
||||
else if(prob(40)) // cum. not counting download: 40%.
|
||||
var/datum/objective/steal/steal_objective = new
|
||||
steal_objective.owner = owner
|
||||
steal_objective.find_target()
|
||||
add_objective(steal_objective)
|
||||
else if(prob(100/3)) // cum. not counting download: 20%.
|
||||
var/datum/objective/sabotage/sabotage_objective = new
|
||||
sabotage_objective.owner = owner
|
||||
sabotage_objective.find_target()
|
||||
add_objective(sabotage_objective)
|
||||
else // cum. not counting download: 40%
|
||||
var/datum/objective/flavor/traitor/flavor_objective = new
|
||||
flavor_objective.owner = owner
|
||||
flavor_objective.forge_objective()
|
||||
add_objective(flavor_objective)
|
||||
|
||||
/datum/antagonist/traitor/proc/forge_single_AI_objective()
|
||||
.=1
|
||||
@@ -369,11 +388,17 @@
|
||||
if(objectives.len)//If the traitor had no objectives, don't need to process this.
|
||||
var/count = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
if(objective.check_completion())
|
||||
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'>Success!</span>"
|
||||
if(objective.completable)
|
||||
var/completion = objective.check_completion()
|
||||
if(completion >= 1)
|
||||
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</span>"
|
||||
else if(completion <= 0)
|
||||
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
traitorwin = FALSE
|
||||
else
|
||||
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <span class='yellowtext'>[completion*100]%</span>"
|
||||
else
|
||||
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
traitorwin = FALSE
|
||||
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text]"
|
||||
count++
|
||||
|
||||
if(uplink_true)
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
var/objectives_complete = TRUE
|
||||
if(objectives.len)
|
||||
for(var/datum/objective/objective in objectives)
|
||||
if(!objective.check_completion())
|
||||
if(objective.completable && !objective.check_completion())
|
||||
objectives_complete = FALSE
|
||||
break
|
||||
|
||||
|
||||
@@ -61,9 +61,9 @@
|
||||
owner.current.forceMove(pick(GLOB.wizardstart))
|
||||
|
||||
/datum/antagonist/wizard/proc/create_objectives()
|
||||
var/datum/objective/new_objective = new("Cause as much creative mayhem as you can aboard the station! The more outlandish your methods of achieving this, the better! Make sure there's a decent amount of crew alive to tell of your tale.")
|
||||
new_objective.completed = TRUE //So they can greentext without admin intervention.
|
||||
var/datum/objective/flavor/wizard/new_objective = new
|
||||
new_objective.owner = owner
|
||||
new_objective.forge_objective()
|
||||
objectives += new_objective
|
||||
|
||||
if (!(locate(/datum/objective/escape) in objectives))
|
||||
@@ -94,6 +94,7 @@
|
||||
to_chat(owner, "<span class='boldannounce'>You are the Space Wizard!</span>")
|
||||
to_chat(owner, "<B>The Space Wizards Federation has given you the following tasks:</B>")
|
||||
owner.announce_objectives()
|
||||
to_chat(owner, "<B>These are merely guidelines! The federation are your masters, but you forge your own path!</B>")
|
||||
to_chat(owner, "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.")
|
||||
to_chat(owner, "The spellbook is bound to you, and others cannot use it.")
|
||||
to_chat(owner, "In your pockets you will find a teleport scroll. Use it as needed.")
|
||||
@@ -265,11 +266,17 @@
|
||||
var/count = 1
|
||||
var/wizardwin = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
if(objective.check_completion())
|
||||
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'>Success!</span>"
|
||||
if(objective.completable)
|
||||
var/completion = objective.check_completion()
|
||||
if(completion >= 1)
|
||||
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</span>"
|
||||
else if(completion <= 0)
|
||||
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
wizardwin = FALSE
|
||||
else
|
||||
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='yellowtext'>[completion*100]%</span>"
|
||||
else
|
||||
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
wizardwin = 0
|
||||
parts += "<B>Objective #[count]</B>: [objective.explanation_text]"
|
||||
count++
|
||||
|
||||
if(wizardwin)
|
||||
|
||||
@@ -81,8 +81,8 @@
|
||||
desc = "An old russian crate full of surplus armor that they used to use! Has two sets of bulletproff armor, a few union suits and some warm hats!"
|
||||
contraband = TRUE
|
||||
cost = 5750 // Its basicly sec suits, good boots/gloves
|
||||
contains = list(/obj/item/clothing/suit/security/officer/russian,
|
||||
/obj/item/clothing/suit/security/officer/russian,
|
||||
contains = list(/obj/item/clothing/suit/armor/navyblue/russian,
|
||||
/obj/item/clothing/suit/armor/navyblue/russian,
|
||||
/obj/item/clothing/shoes/combat,
|
||||
/obj/item/clothing/shoes/combat,
|
||||
/obj/item/clothing/head/ushanka,
|
||||
@@ -104,7 +104,7 @@
|
||||
contraband = TRUE
|
||||
access = FALSE
|
||||
cost = 5500 //
|
||||
contains = list(/obj/item/clothing/suit/security/officer/russian,
|
||||
contains = list(/obj/item/clothing/suit/armor/navyblue/russian,
|
||||
/obj/item/clothing/shoes/combat,
|
||||
/obj/item/clothing/head/ushanka,
|
||||
/obj/item/clothing/suit/armor/bulletproof,
|
||||
@@ -141,15 +141,15 @@
|
||||
cost = 3250
|
||||
contains = list(/obj/item/clothing/under/rank/security/navyblue,
|
||||
/obj/item/clothing/under/rank/security/navyblue,
|
||||
/obj/item/clothing/suit/security/officer,
|
||||
/obj/item/clothing/suit/security/officer,
|
||||
/obj/item/clothing/suit/armor/navyblue,
|
||||
/obj/item/clothing/suit/armor/navyblue,
|
||||
/obj/item/clothing/head/beret/sec/navyofficer,
|
||||
/obj/item/clothing/head/beret/sec/navyofficer,
|
||||
/obj/item/clothing/under/rank/warden/navyblue,
|
||||
/obj/item/clothing/suit/security/warden,
|
||||
/obj/item/clothing/suit/armor/vest/warden/navyblue,
|
||||
/obj/item/clothing/head/beret/sec/navywarden,
|
||||
/obj/item/clothing/under/rank/head_of_security/navyblue,
|
||||
/obj/item/clothing/suit/security/hos,
|
||||
/obj/item/clothing/suit/armor/hos/navyblue,
|
||||
/obj/item/clothing/head/beret/sec/navyhos)
|
||||
crate_name = "security clothing crate"
|
||||
|
||||
|
||||
@@ -488,4 +488,47 @@
|
||||
if(client && client.prefs.uses_glasses_colour && glasses_equipped)
|
||||
add_client_colour(G.glass_colour_type)
|
||||
else
|
||||
remove_client_colour(G.glass_colour_type)
|
||||
remove_client_colour(G.glass_colour_type)
|
||||
|
||||
/obj/item/clothing/glasses/debug
|
||||
name = "debug glasses"
|
||||
desc = "Medical, security and diagnostic hud. Alt click to toggle xray."
|
||||
icon_state = "nvgmeson"
|
||||
item_state = "nvgmeson"
|
||||
flags_cover = GLASSESCOVERSEYES
|
||||
darkness_view = 8
|
||||
flash_protect = 2
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
glass_colour_type = FALSE
|
||||
clothing_flags = SCAN_REAGENTS
|
||||
vision_flags = SEE_TURFS
|
||||
var/list/hudlist = list(DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC_ADVANCED, DATA_HUD_SECURITY_ADVANCED)
|
||||
var/xray = FALSE
|
||||
|
||||
/obj/item/clothing/glasses/debug/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
if(slot != ITEM_SLOT_EYES)
|
||||
return
|
||||
if(ishuman(user))
|
||||
for(var/hud in hudlist)
|
||||
var/datum/atom_hud/H = GLOB.huds[hud]
|
||||
H.add_hud_to(user)
|
||||
|
||||
/obj/item/clothing/glasses/debug/dropped(mob/user)
|
||||
. = ..()
|
||||
if(ishuman(user))
|
||||
for(var/hud in hudlist)
|
||||
var/datum/atom_hud/H = GLOB.huds[hud]
|
||||
H.remove_hud_from(user)
|
||||
|
||||
/obj/item/clothing/glasses/debug/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(ishuman(user))
|
||||
if(xray)
|
||||
vision_flags -= SEE_MOBS|SEE_OBJS
|
||||
else
|
||||
vision_flags += SEE_MOBS|SEE_OBJS
|
||||
xray = !xray
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.update_sight()
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
var/transfer_blood = 0
|
||||
strip_delay = 20
|
||||
equip_delay_other = 40
|
||||
var/strip_mod = 1 //how much they alter stripping items time by, higher is quicker
|
||||
var/strip_silence = FALSE //if it shows a warning when stripping
|
||||
|
||||
/obj/item/clothing/gloves/ComponentInitialize()
|
||||
. = ..()
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
item_state = "boxing"
|
||||
equip_delay_other = 60
|
||||
species_exception = list(/datum/species/golem) // now you too can be a golem boxing champion
|
||||
strip_mod = 0.5
|
||||
|
||||
/obj/item/clothing/gloves/boxing/green
|
||||
icon_state = "boxinggreen"
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
permeability_coefficient = 1
|
||||
resistance_flags = NONE
|
||||
transfer_prints = TRUE
|
||||
strip_mod = 0.8
|
||||
|
||||
/obj/item/clothing/gloves/cut/family
|
||||
desc = "The old gloves your great grandfather stole from Engineering, many moons ago. They've seen some tough times recently."
|
||||
@@ -76,6 +77,7 @@
|
||||
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
|
||||
resistance_flags = NONE
|
||||
var/can_be_cut = 1
|
||||
strip_mod = 1.2
|
||||
|
||||
/obj/item/clothing/gloves/color/black/hos
|
||||
item_color = "hosred" //Exists for washing machines. Is not different from black gloves in any way.
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
equip_delay_other = 20
|
||||
cold_protection = HANDS
|
||||
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
|
||||
strip_mod = 0.9
|
||||
|
||||
/obj/item/clothing/gloves/botanic_leather
|
||||
name = "botanist's leather gloves"
|
||||
@@ -23,6 +24,7 @@
|
||||
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
|
||||
resistance_flags = NONE
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 30)
|
||||
strip_mod = 0.9
|
||||
|
||||
/obj/item/clothing/gloves/combat
|
||||
name = "combat gloves"
|
||||
@@ -38,6 +40,7 @@
|
||||
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
|
||||
resistance_flags = NONE
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50)
|
||||
strip_mod = 1.5
|
||||
|
||||
|
||||
/obj/item/clothing/gloves/bracer
|
||||
@@ -103,3 +106,15 @@
|
||||
|
||||
/obj/item/clothing/gloves/rapid/hug/attack_self(mob/user)
|
||||
return FALSE
|
||||
|
||||
/obj/item/clothing/gloves/thief
|
||||
name = "black gloves"
|
||||
desc = "Gloves made with completely frictionless, insulated cloth, easier to steal from people with."
|
||||
icon_state = "thief"
|
||||
item_state = "blackgloves"
|
||||
siemens_coefficient = 0
|
||||
permeability_coefficient = 0.05
|
||||
strip_delay = 80
|
||||
transfer_prints = FALSE
|
||||
strip_mod = 5
|
||||
strip_silence = TRUE
|
||||
@@ -39,6 +39,12 @@
|
||||
/obj/item/clothing/mask/gas/welding/attack_self(mob/user)
|
||||
weldingvisortoggle(user)
|
||||
|
||||
/obj/item/clothing/mask/gas/welding/up
|
||||
|
||||
/obj/item/clothing/mask/gas/welding/up/Initialize()
|
||||
..()
|
||||
visor_toggling()
|
||||
|
||||
|
||||
// ********************************************************************
|
||||
|
||||
|
||||
@@ -427,14 +427,27 @@
|
||||
/datum/outfit/debug //Debug objs plus hardsuit
|
||||
name = "Debug outfit"
|
||||
uniform = /obj/item/clothing/under/patriotsuit
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/syndi/elite
|
||||
shoes = /obj/item/clothing/shoes/magboots/advance
|
||||
suit_store = /obj/item/tank/internals/oxygen
|
||||
mask = /obj/item/clothing/mask/gas/welding
|
||||
belt = /obj/item/storage/belt/utility/chief/full
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
id = /obj/item/card/id/ert
|
||||
glasses = /obj/item/clothing/glasses/meson/night
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/syndi/elite/debug
|
||||
glasses = /obj/item/clothing/glasses/debug
|
||||
ears = /obj/item/radio/headset/headset_cent/commander
|
||||
mask = /obj/item/clothing/mask/gas/welding/up
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
belt = /obj/item/storage/belt/utility/chief/full
|
||||
l_pocket = /obj/item/gun/magic/wand/resurrection/debug
|
||||
r_pocket = /obj/item/gun/magic/wand/death/debug
|
||||
shoes = /obj/item/clothing/shoes/magboots/advance/debug
|
||||
id = /obj/item/card/id/debug
|
||||
suit_store = /obj/item/tank/internals/oxygen
|
||||
back = /obj/item/storage/backpack/holding
|
||||
backpack_contents = list(/obj/item/card/emag=1, /obj/item/flashlight/emp/debug=1, /obj/item/construction/rcd/combat=1, /obj/item/gun/magic/wand/resurrection/debug=1, /obj/item/melee/transforming/energy/axe=1)
|
||||
box = /obj/item/storage/box/debugtools
|
||||
internals_slot = ITEM_SLOT_SUITSTORE
|
||||
backpack_contents = list(
|
||||
/obj/item/melee/transforming/energy/axe=1,\
|
||||
/obj/item/storage/part_replacer/bluespace/tier4=1,\
|
||||
/obj/item/debug/human_spawner=1,\
|
||||
)
|
||||
|
||||
/datum/outfit/debug/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
var/obj/item/card/id/W = H.wear_id
|
||||
W.registered_name = H.real_name
|
||||
W.update_label()
|
||||
|
||||
@@ -30,8 +30,9 @@
|
||||
magpulse = !magpulse
|
||||
icon_state = "[magboot_state][magpulse]"
|
||||
to_chat(user, "<span class='notice'>You [magpulse ? "enable" : "disable"] the mag-pulse traction system.</span>")
|
||||
user.update_inv_shoes() //so our mob-overlays update
|
||||
user.update_gravity(user.has_gravity())
|
||||
if(user)
|
||||
user.update_inv_shoes() //so our mob-overlays update
|
||||
user.update_gravity(user.has_gravity())
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
@@ -52,6 +53,11 @@
|
||||
slowdown_active = SHOES_SLOWDOWN
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
|
||||
/obj/item/clothing/shoes/magboots/advance/debug
|
||||
|
||||
/obj/item/clothing/shoes/magboots/advance/debug/Initialize()
|
||||
attack_self(src)
|
||||
|
||||
/obj/item/clothing/shoes/magboots/syndie
|
||||
desc = "Reverse-engineered magnetic boots that have a heavy magnetic pull. Property of Gorlex Marauders."
|
||||
name = "blood-red magboots"
|
||||
|
||||
@@ -269,7 +269,7 @@
|
||||
item_state = "syndie_helm"
|
||||
item_color = "syndi"
|
||||
armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90)
|
||||
on = TRUE
|
||||
on = FALSE
|
||||
var/obj/item/clothing/suit/space/hardsuit/syndi/linkedsuit = null
|
||||
actions_types = list(/datum/action/item_action/toggle_helmet_mode)
|
||||
visor_flags_inv = HIDEMASK|HIDEEYES|HIDEFACE|HIDEFACIALHAIR
|
||||
@@ -367,6 +367,12 @@
|
||||
on = FALSE
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/syndi/elite/debug
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/syndi/elite/debug/Initialize()
|
||||
. = ..()
|
||||
soundloop.volume = 0
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/syndi/elite
|
||||
name = "elite syndicate hardsuit"
|
||||
desc = "An elite version of the syndicate hardsuit, with improved armour and fireproofing. It is in travel mode."
|
||||
@@ -380,6 +386,9 @@
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC|STYLE_PAW_TAURIC
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/syndi/elite/debug
|
||||
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite/debug
|
||||
slowdown = 0
|
||||
|
||||
//The Owl Hardsuit
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/syndi/owl
|
||||
|
||||
@@ -15,6 +15,13 @@
|
||||
if(!allowed)
|
||||
allowed = GLOB.security_vest_allowed
|
||||
|
||||
/obj/item/clothing/suit/armor/navyblue
|
||||
name = "security officer's jacket"
|
||||
desc = "This jacket is for those special occasions when a security officer isn't required to wear their armor."
|
||||
icon_state = "officerbluejacket"
|
||||
item_state = "officerbluejacket"
|
||||
body_parts_covered = CHEST|ARMS
|
||||
|
||||
/obj/item/clothing/suit/armor/vest
|
||||
name = "armor vest"
|
||||
desc = "A slim Type I armored vest that provides decent protection against most types of damage."
|
||||
@@ -52,8 +59,17 @@
|
||||
heat_protection = CHEST|GROIN|LEGS|ARMS
|
||||
strip_delay = 80
|
||||
|
||||
/obj/item/clothing/suit/armor/hos/navyblue
|
||||
name = "head of security's jacket"
|
||||
desc = "This piece of clothing was specifically designed for asserting superior authority."
|
||||
icon_state = "hosbluejacket"
|
||||
item_state = "hosbluejacket"
|
||||
body_parts_covered = CHEST|ARMS
|
||||
cold_protection = CHEST|ARMS
|
||||
heat_protection = CHEST|ARMS
|
||||
|
||||
/obj/item/clothing/suit/armor/hos/trenchcoat
|
||||
name = "armored trenchoat"
|
||||
name = "armored trenchcoat"
|
||||
desc = "A trenchcoat enhanced with a special lightweight kevlar. The epitome of tactical plainclothes."
|
||||
icon_state = "hostrench"
|
||||
item_state = "hostrench"
|
||||
@@ -78,6 +94,13 @@
|
||||
desc = "A red jacket with silver rank pips and body armor strapped on top."
|
||||
icon_state = "warden_jacket"
|
||||
|
||||
/obj/item/clothing/suit/armor/vest/warden/navyblue
|
||||
name = "warden's jacket"
|
||||
desc = "Perfectly suited for the warden that wants to leave an impression of style on those who visit the brig."
|
||||
icon_state = "wardenbluejacket"
|
||||
item_state = "wardenbluejacket"
|
||||
body_parts_covered = CHEST|ARMS
|
||||
|
||||
/obj/item/clothing/suit/armor/vest/leather
|
||||
name = "security overcoat"
|
||||
desc = "Lightly armored leather overcoat meant as casual wear for high-ranking officers. Bears the crest of Nanotrasen Security."
|
||||
|
||||
@@ -155,28 +155,6 @@
|
||||
blood_overlay_type = "armor" //it's the less thing that I can put here
|
||||
body_parts_covered = NONE
|
||||
|
||||
//Security
|
||||
/obj/item/clothing/suit/security/officer
|
||||
name = "security officer's jacket"
|
||||
desc = "This jacket is for those special occasions when a security officer isn't required to wear their armor."
|
||||
icon_state = "officerbluejacket"
|
||||
item_state = "officerbluejacket"
|
||||
body_parts_covered = CHEST|ARMS
|
||||
|
||||
/obj/item/clothing/suit/security/warden
|
||||
name = "warden's jacket"
|
||||
desc = "Perfectly suited for the warden that wants to leave an impression of style on those who visit the brig."
|
||||
icon_state = "wardenbluejacket"
|
||||
item_state = "wardenbluejacket"
|
||||
body_parts_covered = CHEST|ARMS
|
||||
|
||||
/obj/item/clothing/suit/security/hos
|
||||
name = "head of security's jacket"
|
||||
desc = "This piece of clothing was specifically designed for asserting superior authority."
|
||||
icon_state = "hosbluejacket"
|
||||
item_state = "hosbluejacket"
|
||||
body_parts_covered = CHEST|ARMS
|
||||
|
||||
//Surgeon
|
||||
/obj/item/clothing/suit/apron/surgical
|
||||
name = "surgical apron"
|
||||
|
||||
@@ -317,7 +317,7 @@
|
||||
flags_cover = HEADCOVERSEYES
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
|
||||
|
||||
/obj/item/clothing/suit/security/officer/russian
|
||||
/obj/item/clothing/suit/armor/navyblue/russian
|
||||
name = "\improper Russian officer's jacket"
|
||||
desc = "This jacket is for those special occasions when a russian officer isn't required to wear their armor."
|
||||
icon_state = "officertanjacket"
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
/datum/round_event/meteor_wave/setup()
|
||||
announceWhen = 1
|
||||
startWhen = rand(60, 90) //Yeah for SOME REASON this is measured in seconds and not deciseconds???
|
||||
startWhen = rand(90, 180) // Apparently it is by 2 seconds, so 90 is actually 180 seconds, and 180 is 360 seconds. So this is 3-6 minutes
|
||||
if(GLOB.singularity_counter)
|
||||
startWhen *= 1 - min(GLOB.singularity_counter * SINGULO_BEACON_DISTURBANCE, SINGULO_BEACON_MAX_DISTURBANCE)
|
||||
endWhen = startWhen + 60
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
shuttleId = "pirateship"
|
||||
icon_screen = "syndishuttle"
|
||||
icon_keyboard = "syndie_key"
|
||||
resistance_flags = INDESTRUCTIBLE
|
||||
light_color = LIGHT_COLOR_RED
|
||||
possible_destinations = "pirateship_away;pirateship_home;pirateship_custom"
|
||||
|
||||
@@ -184,6 +185,7 @@
|
||||
name = "pirate shuttle navigation computer"
|
||||
desc = "Used to designate a precise transit location for the pirate shuttle."
|
||||
shuttleId = "pirateship"
|
||||
resistance_flags = INDESTRUCTIBLE
|
||||
lock_override = CAMERA_LOCK_STATION
|
||||
shuttlePortId = "pirateship_custom"
|
||||
x_offset = 9
|
||||
@@ -226,6 +228,7 @@
|
||||
desc = "This sophisticated machine scans the nearby space for items of value."
|
||||
icon = 'icons/obj/machines/research.dmi'
|
||||
icon_state = "tdoppler"
|
||||
resistance_flags = INDESTRUCTIBLE
|
||||
density = TRUE
|
||||
var/cooldown = 300
|
||||
var/next_use = 0
|
||||
@@ -259,6 +262,7 @@
|
||||
name = "cargo hold pad"
|
||||
icon = 'icons/obj/telescience.dmi'
|
||||
icon_state = "lpad-idle-o"
|
||||
resistance_flags = INDESTRUCTIBLE
|
||||
var/idle_state = "lpad-idle-o"
|
||||
var/warmup_state = "lpad-idle"
|
||||
var/sending_state = "lpad-beam"
|
||||
@@ -272,6 +276,7 @@
|
||||
|
||||
/obj/machinery/computer/piratepad_control
|
||||
name = "cargo hold control terminal"
|
||||
resistance_flags = INDESTRUCTIBLE
|
||||
var/status_report = "Idle"
|
||||
var/obj/machinery/piratepad/pad
|
||||
var/warmup_time = 100
|
||||
|
||||
@@ -71,9 +71,10 @@
|
||||
reagents_add = list(/datum/reagent/consumable/nutriment = 0.05)
|
||||
rarity = 30
|
||||
|
||||
/obj/item/seeds/poppy/lily/trumpet/Initialize()
|
||||
..()
|
||||
unset_mutability(/datum/plant_gene/reagent/polypyr, PLANT_GENE_EXTRACTABLE)
|
||||
/obj/item/seeds/poppy/lily/trumpet/Initialize(mapload, nogenes = FALSE)
|
||||
. = ..()
|
||||
if(!nogenes)
|
||||
unset_mutability(/datum/plant_gene/reagent/polypyr, PLANT_GENE_EXTRACTABLE)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/trumpet
|
||||
seed = /obj/item/seeds/poppy/lily/trumpet
|
||||
|
||||
@@ -82,9 +82,10 @@
|
||||
mutatelist = list()
|
||||
reagents_add = list(/datum/reagent/consumable/nutriment = 0.05, /datum/reagent/medicine/silibinin = 0.1)
|
||||
|
||||
/obj/item/seeds/galaxythistle/Initialize()
|
||||
..()
|
||||
unset_mutability(/datum/plant_gene/trait/invasive, PLANT_GENE_REMOVABLE)
|
||||
/obj/item/seeds/galaxythistle/Initialize(mapload, nogenes = FALSE)
|
||||
. = ..()
|
||||
if(!nogenes)
|
||||
unset_mutability(/datum/plant_gene/trait/invasive, PLANT_GENE_REMOVABLE)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/galaxythistle
|
||||
seed = /obj/item/seeds/galaxythistle
|
||||
|
||||
@@ -217,10 +217,11 @@
|
||||
growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi'
|
||||
reagents_add = list(/datum/reagent/consumable/nutriment = 0.1)
|
||||
|
||||
/obj/item/seeds/chanterelle/jupitercup/Initialize()
|
||||
..()
|
||||
unset_mutability(/datum/plant_gene/reagent/liquidelectricity, PLANT_GENE_EXTRACTABLE)
|
||||
unset_mutability(/datum/plant_gene/trait/plant_type/carnivory, PLANT_GENE_REMOVABLE)
|
||||
/obj/item/seeds/chanterelle/jupitercup/Initialize(mapload, nogenes = FALSE)
|
||||
. = ..()
|
||||
if(!nogenes)
|
||||
unset_mutability(/datum/plant_gene/reagent/liquidelectricity, PLANT_GENE_EXTRACTABLE)
|
||||
unset_mutability(/datum/plant_gene/trait/plant_type/carnivory, PLANT_GENE_REMOVABLE)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/mushroom/jupitercup
|
||||
seed = /obj/item/seeds/chanterelle/jupitercup
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
return !istype(S, /obj/item/seeds/sample) // Samples can't accept new genes
|
||||
|
||||
/datum/plant_gene/proc/Copy()
|
||||
return new type
|
||||
var/datum/plant_gene/G = new type
|
||||
G.mutability_flags = mutability_flags
|
||||
return G
|
||||
|
||||
/datum/plant_gene/proc/apply_vars(obj/item/seeds/S) // currently used for fire resist, can prob. be further refactored
|
||||
return
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
var/weed_rate = 1 //If the chance below passes, then this many weeds sprout during growth
|
||||
var/weed_chance = 5 //Percentage chance per tray update to grow weeds
|
||||
|
||||
/obj/item/seeds/Initialize(loc, nogenes = 0)
|
||||
/obj/item/seeds/Initialize(mapload, nogenes = 0)
|
||||
. = ..()
|
||||
pixel_x = rand(-8, 8)
|
||||
pixel_y = rand(-8, 8)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
display_order = JOB_DISPLAY_ORDER_MIME
|
||||
|
||||
/datum/job/mime/after_spawn(mob/living/carbon/human/H, mob/M)
|
||||
. = ..()
|
||||
H.apply_pref_name("mime", M.client)
|
||||
|
||||
/datum/outfit/job/mime
|
||||
|
||||
@@ -559,7 +559,7 @@
|
||||
health = round(maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute, DAMAGE_PRECISION)
|
||||
staminaloss = round(total_stamina, DAMAGE_PRECISION)
|
||||
update_stat()
|
||||
if(((maxHealth - total_burn) < HEALTH_THRESHOLD_DEAD) && stat == DEAD )
|
||||
if(((maxHealth - total_burn) < HEALTH_THRESHOLD_DEAD*2) && stat == DEAD )
|
||||
become_husk("burn")
|
||||
med_hud_set_health()
|
||||
if(stat == SOFT_CRIT)
|
||||
@@ -986,4 +986,4 @@
|
||||
if(H.clothing_flags & SCAN_REAGENTS)
|
||||
return TRUE
|
||||
if(isclothing(wear_mask) && (wear_mask.clothing_flags & SCAN_REAGENTS))
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
@@ -274,7 +274,7 @@
|
||||
return
|
||||
|
||||
if(health >= 0 && !(HAS_TRAIT(src, TRAIT_FAKEDEATH)))
|
||||
|
||||
var/friendly_check = FALSE
|
||||
if(lying)
|
||||
if(buckled)
|
||||
to_chat(M, "<span class='warning'>You need to unbuckle [src] first to do that!")
|
||||
@@ -289,39 +289,35 @@
|
||||
playsound(src, 'sound/items/Nose_boop.ogg', 50, 0)
|
||||
|
||||
else if(check_zone(M.zone_selected) == "head")
|
||||
var/mob/living/carbon/human/H = src
|
||||
var/datum/species/pref_species = H.dna.species
|
||||
var/datum/species/S
|
||||
if(ishuman(src))
|
||||
S = dna.species
|
||||
|
||||
M.visible_message("<span class='notice'>[M] gives [H] a pat on the head to make [p_them()] feel better!</span>", \
|
||||
"<span class='notice'>You give [H] a pat on the head to make [p_them()] feel better!</span>")
|
||||
M.visible_message("<span class='notice'>[M] gives [src] a pat on the head to make [p_them()] feel better!</span>", \
|
||||
"<span class='notice'>You give [src] a pat on the head to make [p_them()] feel better!</span>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "headpat", /datum/mood_event/headpat)
|
||||
if(HAS_TRAIT(M, TRAIT_FRIENDLY))
|
||||
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
|
||||
if (mood.sanity >= SANITY_GREAT)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/besthug, M)
|
||||
else if (mood.sanity >= SANITY_DISTURBED)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/betterhug, M)
|
||||
if(H.dna.species.can_wag_tail(H))
|
||||
if("tail_human" in pref_species.default_features)
|
||||
if(H.dna.features["tail_human"] == "None")
|
||||
friendly_check = TRUE
|
||||
if(S?.can_wag_tail(src))
|
||||
if("tail_human" in S.default_features)
|
||||
if(dna.features["tail_human"] == "None")
|
||||
return
|
||||
else
|
||||
if(!H.dna.species.is_wagging_tail())
|
||||
H.emote("wag")
|
||||
if(!dna.species.is_wagging_tail())
|
||||
emote("wag")
|
||||
|
||||
if("tail_lizard" in pref_species.default_features)
|
||||
if(H.dna.features["tail_lizard"] == "None")
|
||||
if("tail_lizard" in S.default_features)
|
||||
if(dna.features["tail_lizard"] == "None")
|
||||
return
|
||||
else
|
||||
if(!H.dna.species.is_wagging_tail())
|
||||
H.emote("wag")
|
||||
if(!dna.species.is_wagging_tail())
|
||||
emote("wag")
|
||||
|
||||
if("mam_tail" in pref_species.default_features)
|
||||
if(H.dna.features["mam_tail"] == "None")
|
||||
if("mam_tail" in S.default_features)
|
||||
if(dna.features["mam_tail"] == "None")
|
||||
return
|
||||
else
|
||||
if(!H.dna.species.is_wagging_tail())
|
||||
H.emote("wag")
|
||||
if(!dna.species.is_wagging_tail())
|
||||
emote("wag")
|
||||
|
||||
else
|
||||
return
|
||||
@@ -335,8 +331,11 @@
|
||||
M.visible_message("<span class='notice'>[M] hugs [src] to make [p_them()] feel better!</span>", \
|
||||
"<span class='notice'>You hug [src] to make [p_them()] feel better!</span>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "hug", /datum/mood_event/hug)
|
||||
if(HAS_TRAIT(M, TRAIT_FRIENDLY))
|
||||
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
|
||||
friendly_check = TRUE
|
||||
|
||||
if(friendly_check && HAS_TRAIT(M, TRAIT_FRIENDLY))
|
||||
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
|
||||
if(mood)
|
||||
if (mood.sanity >= SANITY_GREAT)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/besthug, M)
|
||||
else if (mood.sanity >= SANITY_DISTURBED)
|
||||
|
||||
@@ -16,10 +16,6 @@
|
||||
. += "[t_He] [t_is] wearing [wear_mask.get_examine_string(user)] on [t_his] face."
|
||||
if (wear_neck)
|
||||
. += "[t_He] [t_is] wearing [wear_neck.get_examine_string(user)] around [t_his] neck.\n"
|
||||
if(can_be_held)
|
||||
. += "[t_He] looks small enough to be picked up with <b>Alt+Click</b>!\n"
|
||||
|
||||
|
||||
|
||||
for(var/obj/item/I in held_items)
|
||||
if(!(I.item_flags & ABSTRACT))
|
||||
@@ -116,4 +112,5 @@
|
||||
. += "[t_He] look[p_s()] very happy."
|
||||
if(MOOD_LEVEL_HAPPY4 to INFINITY)
|
||||
. += "[t_He] look[p_s()] ecstatic."
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .)
|
||||
. += "*---------*</span>"
|
||||
|
||||
@@ -396,6 +396,7 @@
|
||||
var/temp_flavor = print_flavor_text_2()
|
||||
if(temp_flavor)
|
||||
. += temp_flavor
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .)
|
||||
. += "*---------*</span>"
|
||||
|
||||
/mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects!
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/mob/living/carbon/human/proc/examine_nutrition()
|
||||
var/message = ""
|
||||
var/nutrition_examine = round(nutrition)
|
||||
var/t_He = "It" //capitalised for use at the start of each line.
|
||||
var/t_His = "Its"
|
||||
var/t_his = "its"
|
||||
var/t_is = "is"
|
||||
var/t_has = "has"
|
||||
switch(gender)
|
||||
if(MALE)
|
||||
t_He = "He"
|
||||
t_his = "his"
|
||||
t_His = "His"
|
||||
if(FEMALE)
|
||||
t_He = "She"
|
||||
t_his = "her"
|
||||
t_His = "Her"
|
||||
if(PLURAL)
|
||||
t_He = "They"
|
||||
t_his = "their"
|
||||
t_His = "Their"
|
||||
t_is = "are"
|
||||
t_has = "have"
|
||||
if(NEUTER)
|
||||
t_He = "It"
|
||||
t_his = "its"
|
||||
t_His = "Its"
|
||||
switch(nutrition_examine)
|
||||
if(0 to 49)
|
||||
message = "<span class='warning'>[t_He] [t_is] starving! You can hear [t_his] stomach snarling from across the room!</span>\n"
|
||||
if(50 to 99)
|
||||
message = "<span class='warning'>[t_He] [t_is] extremely hungry. A deep growl occasionally rumbles from [t_his] empty stomach.</span>\n"
|
||||
if(100 to 499)
|
||||
return message //Well that's pretty normal, really.
|
||||
if(500 to 864) // Fat.
|
||||
message = "[t_He] [t_has] a stuffed belly, bloated fat and round from eating too much.\n"
|
||||
if(1200 to 1934) // One person fully digested.
|
||||
message = "<span class='warning'>[t_He] [t_is] sporting a large, round, sagging stomach. It's contains at least their body weight worth of glorping slush.</span>\n"
|
||||
if(1935 to 3004) // Two people.
|
||||
message = "<span class='warning'>[t_He] [t_is] engorged with a huge stomach that sags and wobbles as they move. [t_He] must have consumed at least twice their body weight. It looks incredibly soft.</span>\n"
|
||||
if(3005 to 4074) // Three people.
|
||||
message = "<span class='warning'>[t_His] stomach is firmly packed with digesting slop. [t_He] must have eaten at least a few times worth their body weight! It looks hard for them to stand, and [t_his] gut jiggles when they move.</span>\n"
|
||||
if(4075 to 10000) // Four or more people.
|
||||
message = "<span class='warning'>[t_He] [t_is] so absolutely stuffed that you aren't sure how it's possible to move. [t_He] can't seem to swell any bigger. The surface of [t_his] belly looks sorely strained!</span>\n"
|
||||
return message
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user