mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-24 12:37:26 +01:00
Merge branch 'bleeding-edge-freeze' of https://github.com/Baystation12/Baystation12 into bs12_with_tgport
Conflicts: baystation12.dme code/defines/procs/global_lists.dm code/game/gamemodes/events.dm code/game/gamemodes/events/space_ninja.dm code/game/mecha/working/ripley.dm code/modules/mob/living/carbon/human/human_attackalien.dm code/modules/mob/living/carbon/human/life.dm code/modules/mob/new_player/preferences.dm icons/mob/items_lefthand.dmi icons/mob/items_righthand.dmi icons/mob/mask.dmi Signed-off-by: Cael_Aislinn <cael_aislinn@yahoo.com.au>
This commit is contained in:
+120
-78
@@ -10,24 +10,75 @@
|
||||
dust_swarm("weak")*/
|
||||
if (!event)
|
||||
//CARN: checks to see if random events are enabled.
|
||||
if(config.allow_random_events && prob(eventchance))
|
||||
event()
|
||||
hadevent = 1
|
||||
if(config.allow_random_events)
|
||||
hadevent = event()
|
||||
else
|
||||
Holiday_Random_Event()
|
||||
else
|
||||
event = 0
|
||||
sleep(2400)
|
||||
|
||||
// Doesn't necessarily trigger an event, but might. Returns 1 if it did.
|
||||
/proc/event()
|
||||
event = 1
|
||||
if(!sent_ninja_to_station)
|
||||
choose_space_ninja()
|
||||
return
|
||||
|
||||
var/eventNumbersToPickFrom = list(1,2,4,5,6,7,8,9,10,11,12,13,14, 15) //so ninjas don't cause "empty" events.
|
||||
var/minutes_passed = world.time/600
|
||||
|
||||
if((world.time/10)>=3600 && toggle_space_ninja && !sent_ninja_to_station)//If an hour has passed, relatively speaking. Also, if ninjas are allowed to spawn and if there is not already a ninja for the round.
|
||||
eventNumbersToPickFrom += 3
|
||||
switch(pick(eventNumbersToPickFrom))
|
||||
if(1)
|
||||
var/engineer_count = number_active_with_role("Engineer")
|
||||
var/security_count = number_active_with_role("Security")
|
||||
var/medical_count = number_active_with_role("Medical")
|
||||
var/AI_count = number_active_with_role("AI")
|
||||
|
||||
// Maps event names to event chances
|
||||
// For each chance, 100 represents "normal likelihood", anything below 100 is "reduced likelihood", anything above 100 is "increased likelihood"
|
||||
var/list/possibleEvents = list()
|
||||
|
||||
// Check for additional possible events
|
||||
possibleEvents["Carp"] = 50 + 50 * engineer_count
|
||||
possibleEvents["Lights"] = 100
|
||||
possibleEvents["Communications"] = 50 + 50 * AI_count
|
||||
possibleEvents["Alien"] = 10
|
||||
if(AI_count >= 1)
|
||||
possibleEvents["Ion Storm"] = AI_count * 50 + engineer_count * 10
|
||||
if(engineer_count >= 1 && minutes_passed >= 30) // Give engineers time to set up engine
|
||||
possibleEvents["Meteor"] = 80 * engineer_count
|
||||
possibleEvents["Blob"] = 30 * engineer_count
|
||||
possibleEvents["Spacevine"] = 30 * engineer_count
|
||||
if(medical_count >= 1)
|
||||
possibleEvents["Radiation"] = medical_count * 100
|
||||
possibleEvents["Virus"] = medical_count * 50
|
||||
possibleEvents["Appendicitis"] = medical_count * 50
|
||||
if(security_count >= 1)
|
||||
possibleEvents["Prison Break"] = security_count * 50
|
||||
possibleEvents["Space Ninja"] = security_count * 10 // very low chance for space ninja event
|
||||
|
||||
var/picked_event = pick(possibleEvents)
|
||||
var/chance = possibleEvents[picked_event]
|
||||
|
||||
var/base_chance = 0.4
|
||||
switch(player_list.len)
|
||||
if(5 to 10)
|
||||
base_chance = 0.6
|
||||
if(11 to 15)
|
||||
base_chance = 0.7
|
||||
if(16 to 20)
|
||||
base_chance = 0.8
|
||||
if(21 to 25)
|
||||
base_chance = 0.9
|
||||
if(26 to 30)
|
||||
base_chance = 1.0
|
||||
if(30 to 100000)
|
||||
base_chance = 1.1
|
||||
|
||||
// Trigger the event based on how likely it currently is.
|
||||
if(!prob(chance * eventchance * base_chance / 100)) // "normal" event chance at 20 players
|
||||
return 0
|
||||
|
||||
switch(picked_event)
|
||||
if("Meteor")
|
||||
command_alert("Meteors have been detected on collision course with the station.", "Meteor Alert")
|
||||
world << sound('sound/AI/meteors.ogg')
|
||||
spawn(100)
|
||||
@@ -36,33 +87,34 @@
|
||||
spawn(700)
|
||||
meteor_wave()
|
||||
spawn_meteors()
|
||||
if(4)
|
||||
if("Blob")
|
||||
mini_blob_event()
|
||||
|
||||
if(5)
|
||||
if("Space Ninja")
|
||||
//Handled in space_ninja.dm. Doesn't announce arrival, all sneaky-like.
|
||||
choose_space_ninja()
|
||||
if("Radiation")
|
||||
high_radiation_event()
|
||||
if(6)
|
||||
if("Virus")
|
||||
viral_outbreak()
|
||||
if(7)
|
||||
if(prob(10))
|
||||
alien_infestation()
|
||||
if(8)
|
||||
if("Alien")
|
||||
alien_infestation()
|
||||
if("Prison Break")
|
||||
prison_break()
|
||||
if(9)
|
||||
if("Carp")
|
||||
carp_migration()
|
||||
/*if(10)
|
||||
immovablerod()*/
|
||||
if(11)
|
||||
if("Lights")
|
||||
lightsout(1,2)
|
||||
if(12)
|
||||
if("Appendicitis")
|
||||
appendicitis()
|
||||
if(13)
|
||||
if("Ion Storm")
|
||||
IonStorm()
|
||||
if(14)
|
||||
if("Spacevine")
|
||||
spacevine_infestation()
|
||||
if(15)
|
||||
if("Communications")
|
||||
communications_blackout()
|
||||
|
||||
return 1
|
||||
|
||||
/proc/communications_blackout(var/silent = 1)
|
||||
|
||||
if(!silent)
|
||||
@@ -170,61 +222,16 @@
|
||||
break
|
||||
|
||||
/proc/viral_outbreak(var/virus = null)
|
||||
// command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert")
|
||||
// world << sound('sound/AI/outbreak7.ogg')
|
||||
var/virus_type
|
||||
if(!virus)
|
||||
virus_type = pick(/datum/disease/dnaspread,/datum/disease/flu,/datum/disease/cold,/datum/disease/brainrot,/datum/disease/magnitis,/datum/disease/pierrot_throat)
|
||||
else
|
||||
switch(virus)
|
||||
if("fake gbs")
|
||||
virus_type = /datum/disease/fake_gbs
|
||||
if("gbs")
|
||||
virus_type = /datum/disease/gbs
|
||||
if("magnitis")
|
||||
virus_type = /datum/disease/magnitis
|
||||
if("rhumba beat")
|
||||
virus_type = /datum/disease/rhumba_beat
|
||||
if("brain rot")
|
||||
virus_type = /datum/disease/brainrot
|
||||
if("cold")
|
||||
virus_type = /datum/disease/cold
|
||||
if("retrovirus")
|
||||
virus_type = /datum/disease/dnaspread
|
||||
if("flu")
|
||||
virus_type = /datum/disease/flu
|
||||
// if("t-virus")
|
||||
// virus_type = /datum/disease/t_virus
|
||||
if("pierrot's throat")
|
||||
virus_type = /datum/disease/pierrot_throat
|
||||
for(var/mob/living/carbon/human/H in living_mob_list)
|
||||
|
||||
var/foundAlready = 0 // don't infect someone that already has the virus
|
||||
for(var/datum/disease/D in H.viruses)
|
||||
foundAlready = 1
|
||||
if(H.stat == 2 || foundAlready)
|
||||
for(var/mob/living/carbon/human/H in world)
|
||||
if((H.virus2) || (H.stat == 2) || prob(30))
|
||||
continue
|
||||
|
||||
if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work.
|
||||
if((!H.dna) || (H.sdisabilities & BLIND)) //A blindness disease would be the worst.
|
||||
continue
|
||||
var/datum/disease/dnaspread/D = new
|
||||
D.strain_data["name"] = H.real_name
|
||||
D.strain_data["UI"] = H.dna.uni_identity
|
||||
D.strain_data["SE"] = H.dna.struc_enzymes
|
||||
D.carrier = 1
|
||||
D.holder = H
|
||||
D.affected_mob = H
|
||||
H.viruses += D
|
||||
break
|
||||
else
|
||||
var/datum/disease/D = new virus_type
|
||||
D.carrier = 1
|
||||
D.holder = H
|
||||
D.affected_mob = H
|
||||
H.viruses += D
|
||||
break
|
||||
spawn(rand(1500, 3000)) //Delayed announcements to keep the crew on their toes.
|
||||
infect_mob_random_lesser(H)
|
||||
break
|
||||
|
||||
command_alert("An unknown virus has been detected onboard the ship.", "Virus Alert")
|
||||
|
||||
spawn(rand(0, 3000)) //Delayed announcements to keep the crew on their toes.
|
||||
command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert")
|
||||
world << sound('sound/AI/outbreak7.ogg')
|
||||
|
||||
@@ -482,4 +489,39 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is
|
||||
world << "Finished processing FIREDOORS. Processed: [firedoornum]"
|
||||
|
||||
world << "Ion Storm Main Done"
|
||||
*/
|
||||
*/
|
||||
|
||||
// Returns how many characters are currently active(not logged out, not AFK for more than 10 minutes)
|
||||
// with a specific role.
|
||||
// Note that this isn't sorted by department, because e.g. having a roboticist shouldn't make meteors spawn.
|
||||
proc/number_active_with_role(role)
|
||||
var/count = 0
|
||||
for(var/mob/M in player_list)
|
||||
if(!M.client || M.client.inactivity > 10 * 10 * 60) // longer than 10 minutes AFK counts them as inactive
|
||||
continue
|
||||
switch(role)
|
||||
if("Engineer")
|
||||
if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "engineering robot module")
|
||||
count++
|
||||
if(M.mind.assigned_role in list("Chief Engineer", "Station Engineer"))
|
||||
count++
|
||||
if("Medical")
|
||||
if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "medical robot module")
|
||||
count++
|
||||
if(M.mind.assigned_role in list("Chief Medical Officer", "Medical Doctor"))
|
||||
count++
|
||||
if("Security")
|
||||
if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "security robot module")
|
||||
count++
|
||||
if(M.mind.assigned_role in security_positions)
|
||||
count++
|
||||
if("Scientist")
|
||||
if(M.mind.assigned_role in list("Research Director", "Scientist"))
|
||||
count++
|
||||
if("AI")
|
||||
if(M.mind.assigned_role == "AI")
|
||||
count++
|
||||
if("Cyborg")
|
||||
if(M.mind.assigned_role == "Cyborg")
|
||||
count++
|
||||
return count
|
||||
@@ -93,15 +93,34 @@ When I already created about 4 new objectives, this doesn't seem terribly import
|
||||
/var/global/toggle_space_ninja = 1//If ninjas can spawn or not.
|
||||
/var/global/sent_ninja_to_station = 0//If a ninja is already on the station.
|
||||
|
||||
var/ninja_selection_id = 1
|
||||
var/ninja_selection_active = 0
|
||||
var/ninja_confirmed_selection = 0
|
||||
/proc/choose_space_ninja()
|
||||
var/list/candidates = list() //list of candidate keys
|
||||
for(var/mob/dead/observer/G in player_list)
|
||||
if(G.client && ((G.client.inactivity/10)/60) <= 5 && G.client.be_spaceninja)
|
||||
if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
|
||||
candidates += G
|
||||
if(!candidates.len) return
|
||||
candidates = shuffle(candidates)//Incorporating Donkie's list shuffle
|
||||
|
||||
/proc/space_ninja_arrival(var/assign_key = null, var/assign_mission = null)
|
||||
|
||||
if(ninja_selection_active)
|
||||
usr << "\red Ninja selection already in progress. Please wait until it ends."
|
||||
return
|
||||
//loop over all viable candidates, giving them a popup asking if they want to be space ninja
|
||||
var/mob/dead/observer/accepted_ghost
|
||||
while(candidates.len && !accepted_ghost)
|
||||
//ask a different random candidate
|
||||
var/mob/dead/observer/G = pick(candidates)
|
||||
//give the popup a 30 second timeout in case the player is AFK
|
||||
if(sd_Alert(G, "A space ninja is about to spawn. Would you like to play as the ninja?", "Space Ninja", list("Yes","No"), "Yes", 300, 1, "350x125") == "Yes")
|
||||
accepted_ghost = G
|
||||
else
|
||||
candidates -= G
|
||||
|
||||
if(accepted_ghost)
|
||||
//someone accepted
|
||||
space_ninja_arrival(accepted_ghost)
|
||||
|
||||
/proc/space_ninja_arrival(var/mob/dead/observer/G)
|
||||
if(!G)
|
||||
return choose_space_ninja()
|
||||
|
||||
var/datum/game_mode/current_mode = ticker.mode
|
||||
var/datum/mind/current_mind
|
||||
@@ -146,24 +165,12 @@ Malf AIs/silicons aren't added. Monkeys aren't added. Messes with objective comp
|
||||
if(L.name == "ninjaspawn")
|
||||
spawn_list.Add(L)
|
||||
|
||||
if(!spawn_list.len)
|
||||
for(var/obj/effect/landmark/L in landmarks_list)
|
||||
if(L.name == "carpspawn")
|
||||
spawn_list.Add(L)
|
||||
|
||||
var/ninja_key = null
|
||||
|
||||
if(assign_key)
|
||||
ninja_key = assign_key
|
||||
else
|
||||
|
||||
var/list/candidates = list() //list of candidate keys
|
||||
for(var/mob/dead/observer/G in player_list)
|
||||
if(G.client && !G.client.holder && ((G.client.inactivity/10)/60) <= 5)
|
||||
if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
|
||||
candidates += G.key
|
||||
if(!candidates.len) return
|
||||
candidates = shuffle(candidates)//Incorporating Donkie's list shuffle
|
||||
//The ninja will be created on the right spawn point or at late join.
|
||||
var/mob/living/carbon/human/new_ninja = create_space_ninja(pick(spawn_list.len ? spawn_list : latejoin ))
|
||||
new_ninja.key = G.ckey
|
||||
new_ninja.wear_suit:randomize_param()//Give them a random set of suit parameters.
|
||||
new_ninja.internal = new_ninja.s_store //So the poor ninja has something to breath when they spawn in spess.
|
||||
new_ninja.internals.icon_state = "internal1"
|
||||
|
||||
ninja_key = pick(candidates)
|
||||
|
||||
|
||||
@@ -318,6 +318,8 @@ Whitespace:Seperator;
|
||||
if(applicant)
|
||||
candidates += applicant
|
||||
drafted.Remove(applicant)
|
||||
log_admin("[applicant.key] drafted into antagonist role against their preferences.")
|
||||
message_admins("[applicant.key] drafted into antagonist role against their preferences.")
|
||||
|
||||
else // Not enough scrubs, ABORT ABORT ABORT
|
||||
break
|
||||
|
||||
@@ -148,18 +148,6 @@ var/global/datum/controller/gameticker/ticker
|
||||
spawn(3000)
|
||||
statistic_cycle() // Polls population totals regularly and stores them in an SQL DB -- TLE
|
||||
|
||||
//setup vermin spawn areas
|
||||
var/list/vermin_spawn_areas = list("/area/maintenance","/area/mine/maintenance","/area/crew_quarters/locker/locker_toilet","/area/crew_quarters/toilet")
|
||||
vermin_spawn_turfs = new/list()
|
||||
for(var/area_text in vermin_spawn_areas)
|
||||
var/area_base_type = text2path(area_text)
|
||||
for(var/area in typesof(area_base_type))
|
||||
var/list/area_turfs = get_area_turfs(area)
|
||||
for(var/turf/T in area_turfs)
|
||||
if(T.density)
|
||||
area_turfs -= T
|
||||
vermin_spawn_turfs.Add(area_turfs)
|
||||
|
||||
return 1
|
||||
|
||||
/datum/controller/gameticker
|
||||
|
||||
@@ -379,6 +379,84 @@ datum/objective/survive
|
||||
return 0
|
||||
return 1
|
||||
|
||||
// Similar to the anti-rev objective, but for traitors
|
||||
datum/objective/brig
|
||||
var/already_completed = 0
|
||||
|
||||
find_target()
|
||||
..()
|
||||
if(target && target.current)
|
||||
explanation_text = "Have [target.current.real_name], the [target.assigned_role] brigged for 10 minutes."
|
||||
else
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
|
||||
find_target_by_role(role, role_type=0)
|
||||
..(role, role_type)
|
||||
if(target && target.current)
|
||||
explanation_text = "Have [target.current.real_name], the [!role_type ? target.assigned_role : target.special_role] brigged for 10 minutes."
|
||||
else
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
check_completion()
|
||||
if(already_completed)
|
||||
return 1
|
||||
|
||||
if(target && target.current)
|
||||
if(target.current.stat == DEAD)
|
||||
return 0
|
||||
// Make the actual required time a bit shorter than the official time
|
||||
if(target.is_brigged(10 * 60 * 5))
|
||||
already_completed = 1
|
||||
return 1
|
||||
return 0
|
||||
return 0
|
||||
|
||||
// Harm a crew member, making an example of them
|
||||
datum/objective/harm
|
||||
var/already_completed = 0
|
||||
|
||||
find_target()
|
||||
..()
|
||||
if(target && target.current)
|
||||
explanation_text = "Make an example of [target.current.real_name], the [target.assigned_role]. Break one of their bones, detach one of their limbs or disfigure their face. Make sure they're alive when you do it."
|
||||
else
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
|
||||
find_target_by_role(role, role_type=0)
|
||||
..(role, role_type)
|
||||
if(target && target.current)
|
||||
explanation_text = "Make an example of [target.current.real_name], the [!role_type ? target.assigned_role : target.special_role]. Break one of their bones, detach one of their limbs or disfigure their face. Make sure they're alive when you do it."
|
||||
else
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
check_completion()
|
||||
if(already_completed)
|
||||
return 1
|
||||
|
||||
if(target && target.current && istype(target.current, /mob/living/carbon/human))
|
||||
if(target.current.stat == DEAD)
|
||||
return 0
|
||||
|
||||
var/mob/living/carbon/human/H = target.current
|
||||
for(var/datum/organ/external/E in H.organs)
|
||||
if(E.status & ORGAN_BROKEN)
|
||||
already_completed = 1
|
||||
return 1
|
||||
if(E.status & ORGAN_DESTROYED && !E.amputated)
|
||||
already_completed = 1
|
||||
return 1
|
||||
|
||||
var/datum/organ/external/head/head = H.get_organ("head")
|
||||
if(head.disfigured)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
datum/objective/nuclear
|
||||
explanation_text = "Destroy the station with a nuclear device."
|
||||
|
||||
@@ -94,11 +94,21 @@
|
||||
|
||||
else
|
||||
switch(rand(1,100))
|
||||
if(1 to 50)
|
||||
if(1 to 33)
|
||||
var/datum/objective/assassinate/kill_objective = new
|
||||
kill_objective.owner = traitor
|
||||
kill_objective.find_target()
|
||||
traitor.objectives += kill_objective
|
||||
if(34 to 50)
|
||||
var/datum/objective/brig/brig_objective = new
|
||||
brig_objective.owner = traitor
|
||||
brig_objective.find_target()
|
||||
traitor.objectives += brig_objective
|
||||
if(51 to 66)
|
||||
var/datum/objective/harm/harm_objective = new
|
||||
harm_objective.owner = traitor
|
||||
harm_objective.find_target()
|
||||
traitor.objectives += harm_objective
|
||||
else
|
||||
var/datum/objective/steal/steal_objective = new
|
||||
steal_objective.owner = traitor
|
||||
@@ -140,6 +150,13 @@
|
||||
..()
|
||||
return//Traitors will be checked as part of check_extra_completion. Leaving this here as a reminder.
|
||||
|
||||
/datum/game_mode/traitor/process()
|
||||
// Make sure all objectives are processed regularly, so that objectives
|
||||
// which can be checked mid-round are checked mid-round.
|
||||
for(var/datum/mind/traitor_mind in traitors)
|
||||
for(var/datum/objective/objective in traitor_mind.objectives)
|
||||
objective.check_completion()
|
||||
return 0
|
||||
|
||||
/datum/game_mode/proc/add_law_zero(mob/living/silicon/ai/killer)
|
||||
var/law = "Accomplish your objectives at all costs."
|
||||
@@ -273,4 +290,4 @@
|
||||
else
|
||||
traitor_mob << "Unfortunately, the Syndicate did not provide you with a code response."
|
||||
traitor_mob << "Use the code words in the order provided, during regular conversation, to identify other agents. Proceed with caution, however, as everyone is a potential foe."
|
||||
//End code phrase.
|
||||
//End code phrase.
|
||||
|
||||
@@ -69,9 +69,6 @@
|
||||
else
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/handcuffs(H), slot_in_backpack)
|
||||
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
|
||||
L.imp_in = H
|
||||
L.implanted = 1
|
||||
return 1
|
||||
|
||||
|
||||
@@ -121,9 +118,6 @@
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/evidence(H), slot_in_backpack)
|
||||
H.equip_to_slot_or_del(new /obj/item/device/detective_scanner(H), slot_in_backpack)
|
||||
|
||||
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
|
||||
L.imp_in = H
|
||||
L.implanted = 1
|
||||
return 1
|
||||
|
||||
|
||||
@@ -157,7 +151,4 @@
|
||||
else
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/handcuffs(H), slot_in_backpack)
|
||||
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
|
||||
L.imp_in = H
|
||||
L.implanted = 1
|
||||
return 1
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
anchored = 0
|
||||
density = 1
|
||||
|
||||
|
||||
/obj/machinery/iv_drip/var/mob/living/carbon/human/attached = null
|
||||
/obj/machinery/iv_drip/var/mode = "give" // mode can be "give" or "take"
|
||||
/obj/machinery/iv_drip/var/obj/item/weapon/reagent_containers/beaker = null
|
||||
|
||||
/obj/machinery/iv_drip/update_icon()
|
||||
@@ -68,7 +70,8 @@
|
||||
set background = 1
|
||||
|
||||
..()
|
||||
if(src.attached && src.beaker && src.beaker.volume > 0)
|
||||
|
||||
if(src.attached)
|
||||
if(!(get_dist(src, src.attached) <= 1))
|
||||
visible_message("The needle is ripped out of [src.attached], doesn't that hurt?")
|
||||
src.attached:apply_damage(3, BRUTE, pick("r_arm", "l_arm"))
|
||||
@@ -76,12 +79,65 @@
|
||||
src.update_icon()
|
||||
return
|
||||
|
||||
var/transfer_amount = REAGENTS_METABOLISM
|
||||
if(istype(src.beaker, /obj/item/weapon/reagent_containers/blood))
|
||||
// speed up transfer on blood packs
|
||||
transfer_amount = 4
|
||||
src.beaker.reagents.trans_to(src.attached, transfer_amount)
|
||||
update_icon()
|
||||
if(src.attached && src.beaker)
|
||||
// Give blood
|
||||
if(mode == "give" && src.beaker.volume > 0)
|
||||
var/transfer_amount = REAGENTS_METABOLISM
|
||||
if(istype(src.beaker, /obj/item/weapon/reagent_containers/blood))
|
||||
// speed up transfer on blood packs
|
||||
transfer_amount = 4
|
||||
src.beaker.reagents.trans_to(src.attached, transfer_amount)
|
||||
update_icon()
|
||||
|
||||
// Take blood
|
||||
else if(mode == "take")
|
||||
var/amount = beaker.reagents.maximum_volume - beaker.reagents.total_volume
|
||||
amount = min(amount, 4)
|
||||
// If the beaker is full, ping
|
||||
if(amount == 0)
|
||||
if(prob(5)) visible_message("\The [src] pings.")
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/T = attached
|
||||
|
||||
if(!istype(T)) return
|
||||
var/datum/reagent/B = new /datum/reagent/blood
|
||||
if(!T.dna)
|
||||
return
|
||||
if(NOCLONE in T.mutations)
|
||||
return
|
||||
// If the human is losing too much blood, beep.
|
||||
if(T.vessel.get_reagent_amount("blood") < BLOOD_VOLUME_SAFE) if(prob(5))
|
||||
visible_message("\The [src] beeps loudly.")
|
||||
if(T.vessel.get_reagent_amount("blood") < amount)
|
||||
return
|
||||
B.holder = beaker
|
||||
B.volume = amount
|
||||
//set reagent data
|
||||
B.data["donor"] = T
|
||||
|
||||
if(T.virus2)
|
||||
B.data["virus2"] = T.virus2.getcopy()
|
||||
|
||||
B.data["blood_DNA"] = copytext(T.dna.unique_enzymes,1,0)
|
||||
if(T.resistances && T.resistances.len)
|
||||
B.data["resistances"] = T.resistances.Copy()
|
||||
|
||||
B.data["blood_type"] = copytext(T.dna.b_type,1,0)
|
||||
|
||||
var/list/temp_chem = list()
|
||||
for(var/datum/reagent/R in T.reagents.reagent_list)
|
||||
temp_chem += R.name
|
||||
temp_chem[R.name] = R.volume
|
||||
B.data["trace_chem"] = list2params(temp_chem)
|
||||
B.data["antibodies"] = T.antibodies
|
||||
|
||||
T.vessel.remove_reagent("blood",amount) // Removes blood if human
|
||||
|
||||
beaker.reagents.reagent_list += B
|
||||
beaker.reagents.update_total()
|
||||
beaker.on_reagent_change()
|
||||
beaker.reagents.handle_reactions()
|
||||
|
||||
/obj/machinery/iv_drip/attack_hand(mob/user as mob)
|
||||
if(src.beaker)
|
||||
@@ -91,6 +147,22 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/machinery/iv_drip/verb/toggle_mode()
|
||||
set name = "Toggle Mode"
|
||||
set src in view(1)
|
||||
|
||||
if(!istype(usr, /mob/living))
|
||||
usr << "\red You can't do that."
|
||||
return
|
||||
|
||||
if(mode == "give")
|
||||
mode = "take"
|
||||
usr << "The IV drip is now taking blood."
|
||||
else if(mode == "take")
|
||||
mode = "give"
|
||||
usr << "The IV drip is now giving blood."
|
||||
|
||||
/obj/machinery/iv_drip/examine()
|
||||
set src in view()
|
||||
..()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
desc = "An aging combat exosuit utilized by the Nanotrasen corporation. Originally developed to combat hostile alien lifeforms."
|
||||
name = "Durand"
|
||||
icon_state = "durand"
|
||||
initial_icon = "durand"
|
||||
step_in = 4
|
||||
dir_in = 1 //Facing North.
|
||||
health = 400
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
desc = "A lightweight, security exosuit. Popular among private and corporate security."
|
||||
name = "Gygax"
|
||||
icon_state = "gygax"
|
||||
initial_icon = "gygax"
|
||||
step_in = 3
|
||||
dir_in = 1 //Facing North.
|
||||
health = 300
|
||||
@@ -19,6 +20,7 @@
|
||||
desc = "A lightweight exosuit used by Nanotrasen Death Squads. A significantly upgraded Gygax security mech."
|
||||
name = "Dark Gygax"
|
||||
icon_state = "darkgygax"
|
||||
initial_icon = "darkgygax"
|
||||
health = 400
|
||||
deflect_chance = 25
|
||||
damage_absorption = list("brute"=0.6,"fire"=0.8,"bullet"=0.6,"laser"=0.5,"energy"=0.65,"bomb"=0.8)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
desc = "Produced by \"Tyranny of Honk, INC\", this exosuit is designed as heavy clown-support. Used to spread the fun and joy of life. HONK!"
|
||||
name = "H.O.N.K"
|
||||
icon_state = "honker"
|
||||
initial_icon = "honker"
|
||||
step_in = 2
|
||||
health = 140
|
||||
deflect_chance = 60
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
desc = "Heavy-duty, combat exosuit, developed after the Durand model. Rarely found among civilian populations."
|
||||
name = "Marauder"
|
||||
icon_state = "marauder"
|
||||
initial_icon = "marauder"
|
||||
step_in = 5
|
||||
health = 500
|
||||
deflect_chance = 25
|
||||
@@ -25,6 +26,7 @@
|
||||
desc = "Heavy-duty, command-type exosuit. This is a custom model, utilized only by high-ranking military personnel."
|
||||
name = "Seraph"
|
||||
icon_state = "seraph"
|
||||
initial_icon = "seraph"
|
||||
operation_req_access = list(access_cent_creed)
|
||||
step_in = 3
|
||||
health = 550
|
||||
@@ -37,6 +39,7 @@
|
||||
desc = "Heavy-duty, combat exosuit, developed off of the existing Marauder model."
|
||||
name = "Mauler"
|
||||
icon_state = "mauler"
|
||||
initial_icon = "mauler"
|
||||
operation_req_access = list(access_syndicate)
|
||||
wreckage = /obj/effect/decal/mecha_wreckage/mauler
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
desc = "An exosuit which can only be described as 'WTF?'."
|
||||
name = "Phazon"
|
||||
icon_state = "phazon"
|
||||
initial_icon = "phazon"
|
||||
step_in = 1
|
||||
dir_in = 1 //Facing North.
|
||||
step_energy_drain = 3
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
unacidable = 1 //and no deleting hoomans inside
|
||||
layer = MOB_LAYER //icon draw layer
|
||||
infra_luminosity = 15 //byond implementation is bugged.
|
||||
var/initial_icon = "" //Mech type for resetting icon.
|
||||
var/can_move = 1
|
||||
var/mob/living/carbon/occupant = null
|
||||
var/step_in = 10 //make a step in step_in/10 sec.
|
||||
@@ -666,6 +667,7 @@
|
||||
|
||||
/obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
|
||||
|
||||
if(istype(W, /obj/item/device/mmi))
|
||||
if(mmi_move_inside(W,user))
|
||||
user << "[src]-MMI interface initialized successfuly"
|
||||
@@ -1011,7 +1013,7 @@
|
||||
src.add_fingerprint(H)
|
||||
src.forceMove(src.loc)
|
||||
src.log_append_to_last("[H] moved in as pilot.")
|
||||
src.icon_state = initial(icon_state)
|
||||
src.icon_state = src.reset_icon()
|
||||
dir = dir_in
|
||||
playsound(src, 'sound/machines/windowdoor.ogg', 50, 1)
|
||||
if(!hasInternalDamage())
|
||||
@@ -1070,7 +1072,7 @@
|
||||
src.verbs -= /obj/mecha/verb/eject
|
||||
src.Entered(mmi_as_oc)
|
||||
src.Move(src.loc)
|
||||
src.icon_state = initial(icon_state)
|
||||
src.icon_state = src.reset_icon()
|
||||
dir = dir_in
|
||||
src.log_message("[mmi_as_oc] moved in as pilot.")
|
||||
if(!hasInternalDamage())
|
||||
@@ -1159,7 +1161,7 @@
|
||||
src.occupant.canmove = 0
|
||||
src.verbs += /obj/mecha/verb/eject
|
||||
src.occupant = null
|
||||
src.icon_state = initial(icon_state)+"-open"
|
||||
src.icon_state = src.reset_icon()+"-open"
|
||||
src.dir = dir_in
|
||||
return
|
||||
|
||||
@@ -1669,6 +1671,9 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/mecha/proc/reset_icon()
|
||||
icon_state = initial_icon
|
||||
return icon_state
|
||||
|
||||
//////////////////////////////////////////
|
||||
//////// Mecha global iterators ////////
|
||||
@@ -1799,4 +1804,4 @@
|
||||
//src.health = initial(src.health)/2.2
|
||||
//src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
|
||||
return
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
desc = "These exosuits are developed and produced by Vey-Med. (© All rights reserved)."
|
||||
name = "Odysseus"
|
||||
icon_state = "odysseus"
|
||||
initial_icon = "odysseus"
|
||||
step_in = 2
|
||||
max_temperature = 1500
|
||||
health = 120
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
desc = "Autonomous Power Loader Unit. The workhorse of the exosuit world."
|
||||
name = "APLU \"Ripley\""
|
||||
icon_state = "ripley"
|
||||
initial_icon = "ripley"
|
||||
step_in = 6
|
||||
max_temperature = 1000
|
||||
health = 200
|
||||
@@ -19,7 +20,7 @@
|
||||
desc = "Standart APLU chassis was refitted with additional thermal protection and cistern."
|
||||
name = "APLU \"Firefighter\""
|
||||
icon_state = "firefighter"
|
||||
max_temperature = 4500
|
||||
initial_icon = "firefighter" max_temperature = 4500
|
||||
health = 250
|
||||
lights_power = 8
|
||||
damage_absorption = list("fire"=0.5,"bullet"=0.8,"bomb"=0.5)
|
||||
@@ -29,6 +30,7 @@
|
||||
desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE"
|
||||
name = "DEATH-RIPLEY"
|
||||
icon_state = "deathripley"
|
||||
initial_icon = "deathripley"
|
||||
step_in = 2
|
||||
opacity=0
|
||||
lights_power = 60
|
||||
@@ -44,6 +46,7 @@
|
||||
/obj/mecha/working/ripley/mining
|
||||
desc = "An old, dusty mining ripley."
|
||||
name = "APLU \"Miner\""
|
||||
initial_icon = "ripley"
|
||||
|
||||
/obj/mecha/working/ripley/mining/New()
|
||||
..()
|
||||
@@ -110,4 +113,16 @@
|
||||
return
|
||||
|
||||
|
||||
/obj/mecha/working/ripley/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
|
||||
if(istype(W, /obj/item/weapon/fluff/butcher_royce_1))
|
||||
src.icon_state = "titan"
|
||||
src.initial_icon = "titan"
|
||||
src.name = "APLU \"Titan's Fist\""
|
||||
src.desc = "This ordinary mining Ripley has been customized to look like a unit of the Titans Fist."
|
||||
user << "You spend some quality time with the Ripley, customising it to look like a \"Titan's Fist\" APLU."
|
||||
user.drop_item()
|
||||
del(W)
|
||||
return
|
||||
else
|
||||
..()
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
/obj/item/weapon/contraband/poster
|
||||
name = "rolled-up poster"
|
||||
desc = "The poster comes with its own automatic adhesive mechanism, for easy pinning to any vertical surface. Its vulgar themes have marked it as Contraband aboard Nanotrasen© Space Facilities."
|
||||
desc = "The poster comes with its own automatic adhesive mechanism, for easy pinning to any vertical surface."
|
||||
icon_state = "rolled_poster"
|
||||
var/serial_number = 0
|
||||
var/obj/effect/decal/poster/resulting_poster = null //The poster that will be created is initialised and stored through contraband/poster's constructor
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
..()
|
||||
|
||||
human
|
||||
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/up,/obj/effect/decal/cleanable/blood/gibs/down,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/body,/obj/effect/decal/cleanable/blood/gibs/limb,/obj/effect/decal/cleanable/blood/gibs/core)
|
||||
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/down,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/core)
|
||||
gibamounts = list(1,1,1,1,1,1,1)
|
||||
|
||||
New()
|
||||
|
||||
@@ -14,14 +14,20 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa
|
||||
epicenter = get_turf(epicenter)
|
||||
if(!epicenter) return
|
||||
|
||||
|
||||
playsound(epicenter, 'sound/effects/explosionfar.ogg', 100, 1, round(devastation_range*2,1) )
|
||||
playsound(epicenter, "explosion", 100, 1, round(devastation_range,1) )
|
||||
|
||||
var/close = range(world.view+round(devastation_range,1), epicenter)
|
||||
// to all distanced mobs play a different sound
|
||||
for(var/mob/M in world) if(M.z == epicenter.z) if(!(M in close))
|
||||
// check if the mob can hear
|
||||
if(M.ear_deaf <= 0 || !M.ear_deaf) if(!istype(M.loc,/turf/space))
|
||||
M << 'explosionfar.ogg'
|
||||
if(adminlog)
|
||||
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z])")
|
||||
log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range]) in area [epicenter.loc.name] ")
|
||||
|
||||
playsound(epicenter, 'sound/effects/explosionfar.ogg', 100, 1, round(devastation_range*2,1) )
|
||||
playsound(epicenter, "explosion", 100, 1, round(devastation_range,1) )
|
||||
|
||||
|
||||
var/lighting_controller_was_processing = lighting_controller.processing //Pause the lighting updates for a bit
|
||||
lighting_controller.processing = 0
|
||||
var/powernet_rebuild_was_deferred_already = defer_powernet_rebuild
|
||||
@@ -74,4 +80,4 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa
|
||||
|
||||
proc/secondaryexplosion(turf/epicenter, range)
|
||||
for(var/turf/tile in range(range, epicenter))
|
||||
tile.ex_act(2)
|
||||
tile.ex_act(2)
|
||||
|
||||
@@ -192,7 +192,7 @@
|
||||
if(surgery_steps == null) build_surgery_steps_list()
|
||||
for(var/datum/surgery_step/S in surgery_steps)
|
||||
//check if tool is right or close enough
|
||||
if(istype(src, S.required_tool) || (S.allowed_tools && src.type in S.allowed_tools ))
|
||||
if(istype(src, S.required_tool) || (S.allowed_tools && (src.type in S.allowed_tools) ))
|
||||
if(S.can_use(user, M, user.zone_sel.selecting, src)) //is this step possible?
|
||||
S.begin_step(user, M, user.zone_sel.selecting, src)
|
||||
if(do_mob(user, M, rand(S.min_duration, S.max_duration)))
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
var/access_security = 0
|
||||
var/access_engine = 0
|
||||
var/access_medical = 0
|
||||
var/access_manifest = 0
|
||||
var/access_manifest = 1 // Make all jobs able to access the manifest
|
||||
var/access_clown = 0
|
||||
var/access_mime = 0
|
||||
var/access_janitor = 0
|
||||
@@ -268,9 +268,8 @@ Code:
|
||||
|
||||
menu = "<h4><img src=pda_notes.png> Crew Manifest</h4>"
|
||||
menu += "Entries cannot be modified from this terminal.<br><br>"
|
||||
if(!isnull(data_core.general))
|
||||
for (var/datum/data/record/t in sortRecord(data_core.general))
|
||||
menu += "[t.fields["name"]] - [t.fields["rank"]]<br>"
|
||||
if(data_core)
|
||||
menu += data_core.get_manifest(1) // make it monochrome
|
||||
menu += "<br>"
|
||||
|
||||
|
||||
|
||||
@@ -322,6 +322,7 @@ var/list/mechtoys = list(
|
||||
//manifest finalisation
|
||||
slip.info += "</ul><br>"
|
||||
slip.info += "CHECK CONTENTS AND STAMP BELOW THE LINE TO CONFIRM RECEIPT OF GOODS<hr>"
|
||||
if (SP.contraband) slip.loc = null //we are out of blanks for Form #44-D Ordering Illicit Drugs.
|
||||
|
||||
while(0<mech_redeem)
|
||||
if(!clear_turfs.len) break
|
||||
|
||||
Reference in New Issue
Block a user