Merge pull request #4233 from Fox-McCloud/abduction

Abduction
This commit is contained in:
TheDZD
2016-04-20 11:01:55 -04:00
77 changed files with 2806 additions and 173 deletions

View File

@@ -749,6 +749,10 @@ var/global/nologevent = 0
if (ticker.mode.config_tag == "changeling")
return 2
return 1
if(M.mind in ticker.mode.abductors)
if (ticker.mode.config_tag == "abduction")
return 2
return 1
if(isrobot(M))
var/mob/living/silicon/robot/R = M
if(R.emagged)

View File

@@ -515,6 +515,12 @@
if(ticker.mode.shadowling_thralls.len)
dat += check_role_table("Shadowling Thralls", ticker.mode.shadowling_thralls, src)
if(ticker.mode.abductors.len)
dat += check_role_table("Abductors", ticker.mode.abductors, src)
if(ticker.mode.abductees.len)
dat += check_role_table("Abductees", ticker.mode.abductees, src)
if(ticker.mode.vampires.len)
dat += check_role_table("Vampires", ticker.mode.vampires, src)

View File

@@ -63,6 +63,10 @@
log_admin("[key_name(usr)] has spawned vox raiders.")
if(!src.makeVoxRaiders())
to_chat(usr, "\red Unfortunately there weren't enough candidates available.")
if("9")
log_admin("[key_name(usr)] has spawned an abductor team.")
if(!src.makeAbductorTeam())
to_chat(usr, "\red Unfortunately there weren't enough candidates available.")
else if(href_list["dbsearchckey"] || href_list["dbsearchadmin"] || href_list["dbsearchip"] || href_list["dbsearchcid"] || href_list["dbsearchbantype"])
var/adminckey = href_list["dbsearchadmin"]

View File

@@ -682,7 +682,6 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(M), slot_glasses)
M.equip_to_slot_or_del(new /obj/item/clothing/head/det_hat(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/weapon/cloaking_device(M), slot_r_store)
M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/automatic/proto(M), slot_r_hand)
M.equip_to_slot_or_del(new /obj/item/ammo_box/a357(M), slot_l_store)
@@ -814,7 +813,6 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/wcoat(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword/saber(M), slot_l_store)
M.equip_to_slot_or_del(new /obj/item/weapon/cloaking_device(M), slot_r_store)
var/obj/item/weapon/storage/secure/briefcase/sec_briefcase = new(M)
for(var/obj/item/briefcase_item in sec_briefcase)

View File

@@ -21,6 +21,7 @@ client/proc/one_click_antag()
<a href='?src=\ref[src];makeAntag=6'>Make Wizard (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=7'>Make Vampires</a><br>
<a href='?src=\ref[src];makeAntag=8'>Make Vox Raiders (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=9'>Make Abductor Team (Requires Ghosts)</a><br>
"}
usr << browse(dat, "window=oneclickantag;size=400x400")
return
@@ -308,8 +309,10 @@ client/proc/one_click_antag()
return 1
//Abductors
/datum/admins/proc/makeAbductorTeam()
new /datum/event/abductor
return 1
/datum/admins/proc/makeAliens()
alien_infestation(3)
@@ -396,7 +399,7 @@ client/proc/one_click_antag()
//First we spawn a dude.
var/mob/living/carbon/human/new_character = new(pick(latejoin))//The mob being spawned.
var/datum/preferences/A = new()
var/datum/preferences/A = new(G_found.client)
A.copy_to(new_character)
new_character.dna.ready_dna(new_character)

View File

@@ -25,6 +25,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
ROLE_NINJA = 21,
ROLE_MUTINEER = 21,
ROLE_MALF = 30,
ROLE_ABDUCTOR = 30,
)
/proc/player_old_enough_antag(client/C, role)

View File

@@ -0,0 +1,52 @@
/datum/event/abductor
/datum/event/abductor/start()
//spawn abductor team
processing = 0 //so it won't fire again in next tick
if(!makeAbductorTeam())
message_admins("Abductor event failed to find players. Retrying in 30s.")
spawn(300)
makeAbductorTeam()
/datum/event/abductor/proc/makeAbductorTeam()
var/list/mob/dead/observer/candidates = pollCandidates("Do you wish to be considered for an Abductor Team?", ROLE_ABDUCTOR, 1)
if(candidates.len >= 2)
//Oh god why we can't have static functions
var/number = ticker.mode.abductor_teams + 1
var/datum/game_mode/abduction/temp
if(ticker.mode.config_tag == "abduction")
temp = ticker.mode
else
temp = new
var/agent_mind = pick(candidates)
candidates -= agent_mind
var/scientist_mind = pick(candidates)
var/mob/living/carbon/human/agent=makeBody(agent_mind)
var/mob/living/carbon/human/scientist=makeBody(scientist_mind)
agent_mind = agent.mind
scientist_mind = scientist.mind
temp.scientists.len = number
temp.agents.len = number
temp.abductors.len = 2*number
temp.team_objectives.len = number
temp.team_names.len = number
temp.scientists[number] = scientist_mind
temp.agents[number] = agent_mind
temp.abductors |= list(agent_mind,scientist_mind)
temp.make_abductor_team(number,preset_scientist=scientist_mind,preset_agent=agent_mind)
temp.post_setup_team(number)
ticker.mode.abductor_teams++
if(ticker.mode.config_tag != "abduction")
ticker.mode.abductors |= temp.abductors
processing = 1 //So it will get gc'd
return 1
else
return 0

View File

@@ -48,6 +48,7 @@
return 0*/
/datum/event //NOTE: Times are measured in master controller ticks!
var/processing = 1
var/startWhen = 0 //When in the lifetime to call start().
var/announceWhen = 0 //When in the lifetime to call announce().
var/endWhen = 0 //When in the lifetime the event should end.
@@ -105,6 +106,9 @@
//Do not override this proc, instead use the appropiate procs.
//This proc will handle the calls to the appropiate procs.
/datum/event/proc/process()
if(!processing)
return
if(activeFor > startWhen && activeFor < endWhen || noAutoEnd)
tick()

View File

@@ -178,10 +178,11 @@ var/list/event_last_fired = list()
severity = EVENT_LEVEL_MAJOR
available_events = list(
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 1320),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 3), 1),
//new /datum/event_meta(EVENT_LEVEL_MAJOR, "Containment Breach", /datum/event/prison_break/station, 0, list(ASSIGNMENT_ANY = 5)),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 3), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 3), 1),
//new /datum/event_meta(EVENT_LEVEL_MAJOR, "Containment Breach", /datum/event/prison_break/station, 0, list(ASSIGNMENT_ANY = 5)),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 3), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Abductor Visit", /datum/event/abductor, 80, is_one_shot = 1),
new /datum/event_meta/alien(EVENT_LEVEL_MAJOR, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 30), 1),
)

View File

@@ -107,10 +107,10 @@
to_chat(player, msg_dead)
continue
else if(istype(player,/mob/dead) || ((src in player.languages) && check_special_condition(player)))
else if(istype(player,/mob/dead) || ((src in player.languages) && check_special_condition(player, speaker)))
to_chat(player, msg)
/datum/language/proc/check_special_condition(var/mob/other)
/datum/language/proc/check_special_condition(var/mob/other, var/mob/living/speaker)
return 1
/datum/language/proc/get_spoken_verb(var/msg_end)
@@ -409,6 +409,7 @@
key = "8"
flags = RESTRICTED | HIVEMIND
/datum/language/shadowling/broadcast(var/mob/living/speaker, var/message, var/speaker_mask)
if(speaker.mind && speaker.mind.special_role)
..(speaker, message, "([speaker.mind.special_role]) [speaker]")
@@ -422,6 +423,25 @@
else
..(speaker,message)
/datum/language/abductor
name = "Abductor Mindlink"
desc = "Abductors are incapable of speech, but have a psychic link attuned to their own team."
speech_verb = "gibbers"
ask_verb = "gibbers"
exclaim_verb = "gibbers"
colour = "abductor"
key = "zw" //doesn't matter, this is their default and only language
flags = RESTRICTED | HIVEMIND
/datum/language/abductor/broadcast(var/mob/living/speaker,var/message,var/speaker_mask)
..(speaker,message,speaker.real_name)
/datum/language/abductor/check_special_condition(var/mob/living/carbon/human/other, var/mob/living/carbon/human/speaker)
if(other.mind && other.mind.abductor)
if(other.mind.abductor.team == speaker.mind.abductor.team)
return 1
return 0
/datum/language/corticalborer
name = "Cortical Link"
desc = "Cortical borers possess a strange link between their tiny minds."

View File

@@ -112,6 +112,9 @@
/mob/living/carbon/human/grey/New(var/new_loc)
..(new_loc, "Grey")
/mob/living/carbon/human/abductor/New(var/new_loc)
..(new_loc, "Abductor")
/mob/living/carbon/human/human/New(var/new_loc)
..(new_loc, "Human")
@@ -688,6 +691,8 @@
//repurposed proc. Now it combines get_id_name() and get_face_name() to determine a mob's name variable. Made into a seperate proc as it'll be useful elsewhere
/mob/living/carbon/human/get_visible_name()
if(name_override)
return name_override
if(wear_mask && (wear_mask.flags_inv & HIDEFACE)) //Wearing a mask which hides our face, use id-name if possible
return get_id_name("Unknown")
if(head && (head.flags_inv & HIDEFACE))

View File

@@ -80,6 +80,8 @@
var/hand_blood_color
var/name_override //For temporary visible name changes
var/xylophone = 0 //For the spoooooooky xylophone cooldown
var/mob/remoteview_target = null

View File

@@ -0,0 +1,27 @@
/datum/species/abductor
name = "Abductor"
name_plural = "Abductors"
icobase = 'icons/mob/human_races/r_abductor.dmi'
deform = 'icons/mob/human_races/r_abductor.dmi'
path = /mob/living/carbon/human/abductor
language = "Abductor Mindlink"
default_language = "Abductor Mindlink"
unarmed_type = /datum/unarmed_attack/punch
darksight = 3
eyes = "blank_eyes"
flags = HAS_LIPS | NO_BLOOD | NO_BREATHE
virus_immune = 1
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
dietflags = DIET_OMNI
reagent_tag = PROCESS_ORG
blood_color = "#FF5AFF"
/datum/species/abductor/can_understand(var/mob/other) //Abductors can understand everyone, but they can only speak over their mindlink to another team-member
return 1
/datum/species/abductor/handle_post_spawn(var/mob/living/carbon/human/H)
H.gender = NEUTER
if(H.mind)
H.mind.abductor = new /datum/abductor
return ..()

View File

@@ -104,41 +104,6 @@ If you have any questions/constructive-comments/bugs-to-report/or have a massivl
Please contact me on #coderbus IRC. ~Carn x
*/
//Human Overlays Indexes/////////
#define MUTANTRACE_LAYER 1
#define TAIL_UNDERLIMBS_LAYER 2
#define LIMBS_LAYER 3
#define MARKINGS_LAYER 4
#define UNDERWEAR_LAYER 5
#define MUTATIONS_LAYER 6
#define DAMAGE_LAYER 7
#define UNIFORM_LAYER 8
#define ID_LAYER 9
#define SHOES_LAYER 10
#define GLOVES_LAYER 11
#define EARS_LAYER 12
#define SUIT_LAYER 13
#define GLASSES_LAYER 14
#define BELT_LAYER 15 //Possible make this an overlay of somethign required to wear a belt?
#define SUIT_STORE_LAYER 16
#define BACK_LAYER 17
#define TAIL_LAYER 18 //bs12 specific. this hack is probably gonna come back to haunt me
#define HAIR_LAYER 19 //TODO: make part of head layer?
#define HEAD_ACCESSORY_LAYER 20
#define FHAIR_LAYER 21
#define FACEMASK_LAYER 22
#define HEAD_LAYER 23
#define COLLAR_LAYER 24
#define HANDCUFF_LAYER 25
#define LEGCUFF_LAYER 26
#define L_HAND_LAYER 27
#define R_HAND_LAYER 28
#define TARGETED_LAYER 29 //BS12: Layer for the target overlay from weapon targeting system
#define FIRE_LAYER 30 //If you're on fire
#define TOTAL_LAYERS 30
/mob/living/carbon/human
var/list/overlays_standing[TOTAL_LAYERS]
var/previous_damage_appearance // store what the body last looked like, so we only have to update it if something changed
@@ -163,18 +128,26 @@ Please contact me on #coderbus IRC. ~Carn x
update_hud() //TODO: remove the need for this
var/stealth = 0
for(var/obj/item/weapon/cloaking_device/S in list(l_hand,r_hand,belt,l_store,r_store))
if(S.active)
var/obj/item/clothing/suit/armor/abductor/vest/V // Begin the most snowflakey bullshit code I've ever written. I'm so sorry, but there was no other way.
for(V in list(wear_suit))
if(V.stealth_active)
stealth = 1
break
if(stealth)
icon = 'icons/mob/human.dmi'
icon_state = "body_cloaked"
var/image/I = overlays_standing[L_HAND_LAYER]
if(istype(I)) overlays += I
I = overlays_standing[R_HAND_LAYER]
if(istype(I)) overlays += I
icon = V.disguise.icon //if the suit is active, reference the suit's current loaded icon and overlays; this does not include hand overlays
overlays.Cut()
for(var/thing in V.disguise.overlays)
if(thing)
overlays += thing
var/image/I = overlays_standing[L_HAND_LAYER] //manually add both left and right hand, so its independently updated
if(istype(I))
overlays += I
I = overlays_standing[R_HAND_LAYER]
if(istype(I))
overlays += I
else
icon = stand_icon
overlays.Cut()
@@ -1240,34 +1213,11 @@ var/global/list/damage_icon_parts = list()
O.sync_colour_to_human(src)
update_body(0)
//Human Overlays Indexes/////////
#undef MUTANTRACE_LAYER
#undef TAIL_UNDERLIMBS_LAYER
#undef LIMBS_LAYER
#undef MARKINGS_LAYER
#undef MUTATIONS_LAYER
#undef DAMAGE_LAYER
#undef UNIFORM_LAYER
#undef ID_LAYER
#undef SHOES_LAYER
#undef GLOVES_LAYER
#undef EARS_LAYER
#undef SUIT_LAYER
#undef GLASSES_LAYER
#undef FACEMASK_LAYER
#undef BELT_LAYER
#undef SUIT_STORE_LAYER
#undef BACK_LAYER
#undef TAIL_LAYER
#undef HAIR_LAYER
#undef HEAD_LAYER
#undef HEAD_ACCESSORY_LAYER
#undef FHAIR_LAYER
#undef COLLAR_LAYER
#undef HANDCUFF_LAYER
#undef LEGCUFF_LAYER
#undef L_HAND_LAYER
#undef R_HAND_LAYER
#undef TARGETED_LAYER
#undef FIRE_LAYER
#undef TOTAL_LAYERS
/mob/living/carbon/human/proc/get_overlays_copy(list/unwantedLayers)
var/list/out = new
for(var/i=1;i<=TOTAL_LAYERS;i++)
if(overlays_standing[i])
if(i in unwantedLayers)
continue
out += overlays_standing[i]
return out

View File

@@ -39,14 +39,6 @@
/mob/living/bullet_act(var/obj/item/projectile/P, var/def_zone)
//Being hit while using a cloaking device
var/obj/item/weapon/cloaking_device/C = locate((/obj/item/weapon/cloaking_device) in src)
if(C && C.active)
C.attack_self(src)//Should shut it off
update_icons()
to_chat(src, "\blue Your [C.name] was disrupted!")
Stun(2)
//Armor
var/armor = run_armor_check(def_zone, P.flag, armour_penetration = P.armour_penetration)
var/proj_sharp = is_sharp(P)

View File

@@ -230,4 +230,14 @@
build_type = PROTOLATHE
materials = list(MAT_METAL = 15000, MAT_GLASS = 5000, MAT_SILVER = 2500) //hardcore
build_path = /obj/item/weapon/storage/part_replacer/bluespace
category = list("Stock Parts")
/datum/design/alienalloy
name = "Alien Alloy"
desc = "A sheet of reverse-engineered alien alloy."
id = "alienalloy"
req_tech = list("abductor" = 1, "materials" = 7, "plasmatech" = 2)
build_type = PROTOLATHE
materials = list(MAT_METAL = 4000, MAT_PLASMA = 4000)
build_path = /obj/item/stack/sheet/mineral/abductor
category = list("Stock Parts")

View File

@@ -438,8 +438,9 @@ proc/CallMaterialName(ID)
if( new_item.type == /obj/item/weapon/storage/backpack/holding )
new_item.investigate_log("built by [key]","singulo")
new_item.reliability = 100
new_item.materials[MAT_METAL] /= coeff
new_item.materials[MAT_GLASS] /= coeff
if(!istype(new_item, /obj/item/stack/sheet)) // To avoid materials dupe glitches
new_item.materials[MAT_METAL] /= coeff
new_item.materials[MAT_GLASS] /= coeff
if(O)
var/obj/item/weapon/storage/lockbox/L = new/obj/item/weapon/storage/lockbox(linked_lathe.loc)
new_item.loc = L
@@ -706,6 +707,8 @@ proc/CallMaterialName(ID)
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A>"
dat += "<h3>Current Research Levels:</h3><BR><div class='statusDisplay'>"
for(var/datum/tech/T in files.known_tech)
if(T.level <= 0)
continue
dat += "[T.name]<BR>"
dat += "* Level: [T.level]<BR>"
dat += "* Summary: [T.desc]<HR>"
@@ -733,6 +736,8 @@ proc/CallMaterialName(ID)
dat += "<A href='?src=\ref[src];menu=1.2'>Return to Disk Operations</A><div class='statusDisplay'>"
dat += "<h3>Load Technology to Disk:</h3><BR>"
for(var/datum/tech/T in files.known_tech)
if(T.level <= 0)
continue
dat += "[T.name] "
dat += "<A href='?src=\ref[src];copy_tech=1;copy_tech_ID=[T.id]'>Copy to Disk</A><BR>"
dat += "</div>"

View File

@@ -117,7 +117,7 @@ research holder datum.
if(DesignHasReqs(PD))
AddDesign2Known(PD)
for(var/datum/tech/T in known_tech)
T = Clamp(T.level, 1, 20)
T = Clamp(T.level, 0, 20)
for(var/datum/design/D in known_designs)
D.CalcReliability(known_tech)
return
@@ -242,6 +242,13 @@ datum/tech/syndicate
max_level = 0 // Don't count towards maxed research, since it's illegal.
rare = 4
/datum/tech/abductor
name = "Alien Technologies Research"
desc = "The study of technologies used by the advanced alien race known as Abductors."
id = "abductor"
rare = 5
level = 0
/*
datum/tech/arcane
name = "Arcane Research"
@@ -278,8 +285,7 @@ datum/tech/robotics
return 0
var/cost = 0
var/i
for(i=current_level+1, i<=level, i++)
for(var/i=current_level+1, i<=level, i++)
if(i == initial(level))
continue
cost += i*5*rare

View File

@@ -315,6 +315,8 @@
dat += "[temp_server.name] Data ManagementP<BR><BR>"
dat += "Known Technologies<BR>"
for(var/datum/tech/T in temp_server.files.known_tech)
if(T.level <= 0)
continue
dat += "* [T.name] "
dat += "<A href='?src=\ref[src];reset_tech=[T.id]'>(Reset)</A><BR>" //FYI, these are all strings.
dat += "Known Designs<BR>"