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

This commit is contained in:
keronshb
2021-09-19 18:09:18 -04:00
143 changed files with 5772 additions and 4116 deletions
@@ -111,6 +111,19 @@
sigil_name = "Sigil of Submission"
var/glow_type = /obj/effect/temp_visual/ratvar/sigil/submission
/obj/effect/clockwork/sigil/submission/Crossed(atom/movable/AM)
. = ..()
if(istype(AM, /obj/item/aicard))
var/obj/item/aicard/cardy = AM
if(!cardy.AI)
return
var/mob/living/silicon/ai/aiconvert = cardy.AI
if(aiconvert.stat > stat_affected)
return
if(is_servant_of_ratvar(aiconvert) || !(aiconvert.mind || aiconvert.has_status_effect(STATUS_EFFECT_SIGILMARK)))
return
sigil_effects(aiconvert)
/obj/effect/clockwork/sigil/submission/sigil_effects(mob/living/L)
var/turf/T = get_turf(src)
var/has_sigil = FALSE
-146
View File
@@ -1,146 +0,0 @@
/datum/antagonist/ninja
name = "Ninja"
antagpanel_category = "Ninja"
job_rank = ROLE_NINJA
show_name_in_check_antagonists = TRUE
show_to_ghosts = TRUE
antag_moodlet = /datum/mood_event/focused
threat = 8
var/helping_station = FALSE
var/give_objectives = TRUE
var/give_equipment = TRUE
/datum/antagonist/ninja/threat()
return helping_station ? -(..()) : ..()
/datum/antagonist/ninja/apply_innate_effects(mob/living/mob_override)
var/mob/living/M = mob_override || owner.current
update_ninja_icons_added(M)
/datum/antagonist/ninja/remove_innate_effects(mob/living/mob_override)
var/mob/living/M = mob_override || owner.current
update_ninja_icons_removed(M)
/datum/antagonist/ninja/proc/equip_space_ninja(mob/living/carbon/human/H = owner.current)
return H.equipOutfit(/datum/outfit/ninja)
/datum/antagonist/ninja/proc/addMemories()
antag_memory += "I am an elite mercenary assassin of the mighty Spider Clan. A <font color='red'><B>SPACE NINJA</B></font>!<br>"
antag_memory += "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by clicking the initialize UI button, to use abilities like stealth)!<br>"
antag_memory += "Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.<br>"
/datum/antagonist/ninja/proc/addObjectives(quantity = 6)
var/list/possible_targets = list()
for(var/datum/mind/M in SSticker.minds)
if(M.current && M.current.stat != DEAD)
if(ishuman(M.current))
if(M.special_role)
possible_targets[M] = 0 //bad-guy
else if(M.assigned_role in GLOB.command_positions)
possible_targets[M] = 1 //good-guy
var/list/possible_objectives = list(1,2,3,4)
while(objectives.len < quantity)
switch(pick_n_take(possible_objectives))
if(1) //research
var/datum/objective/download/O = new /datum/objective/download()
O.owner = owner
O.gen_amount_goal()
objectives += O
if(2) //steal
var/datum/objective/steal/special/O = new /datum/objective/steal/special()
O.owner = owner
O.find_target()
objectives += O
if(3) //protect/kill
if(!possible_targets.len) continue
var/index = rand(1,possible_targets.len)
var/datum/mind/M = possible_targets[index]
var/is_bad_guy = possible_targets[M]
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/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]. 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()
O.owner = owner
O.target = M
O.explanation_text = "Protect \the [M.current.real_name], the [M.assigned_role], from harm."
objectives += O
if(4) //flavor
var/datum/objective/flavor/O = helping_station ? new /datum/objective/flavor/ninja_helping : new /datum/objective/flavor/ninja_syndie
O.owner = owner
O.forge_objective()
objectives += O
else
break
var/datum/objective/O = new /datum/objective/survive()
O.owner = owner
objectives += O
/proc/remove_ninja(mob/living/L)
if(!L || !L.mind)
return FALSE
var/datum/antagonist/datum = L.mind.has_antag_datum(/datum/antagonist/ninja)
datum.on_removal()
return TRUE
/proc/is_ninja(mob/living/M)
return M && M.mind && M.mind.has_antag_datum(/datum/antagonist/ninja)
/datum/antagonist/ninja/greet()
SEND_SOUND(owner.current, sound('sound/effects/ninja_greeting.ogg'))
to_chat(owner.current, "I am an elite mercenary assassin of the mighty Spider Clan. A <font color='red'><B>SPACE NINJA</B></font>!")
to_chat(owner.current, "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by right clicking on it, to use abilities like stealth)!")
to_chat(owner.current, "Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.")
owner.announce_objectives()
return
/datum/antagonist/ninja/on_gain()
if(give_objectives)
addObjectives()
addMemories()
if(give_equipment)
equip_space_ninja(owner.current)
. = ..()
/datum/antagonist/ninja/admin_add(datum/mind/new_owner,mob/admin)
var/adj
switch(input("What kind of ninja?", "Ninja") as null|anything in list("Random","Syndicate","Nanotrasen","No objectives"))
if("Random")
helping_station = pick(TRUE,FALSE)
adj = ""
if("Syndicate")
helping_station = FALSE
adj = "syndie"
if("Nanotrasen")
helping_station = TRUE
adj = "friendly"
if("No objectives")
give_objectives = FALSE
adj = "objectiveless"
else
return
new_owner.assigned_role = ROLE_NINJA
new_owner.special_role = ROLE_NINJA
new_owner.add_antag_datum(src)
message_admins("[key_name_admin(admin)] has [adj] ninja'ed [new_owner.current].")
log_admin("[key_name(admin)] has [adj] ninja'ed [new_owner.current].")
/datum/antagonist/ninja/proc/update_ninja_icons_added(var/mob/living/carbon/human/ninja)
var/datum/atom_hud/antag/ninjahud = GLOB.huds[ANTAG_HUD_NINJA]
ninjahud.join_hud(ninja)
set_antag_hud(ninja, "ninja")
/datum/antagonist/ninja/proc/update_ninja_icons_removed(var/mob/living/carbon/human/ninja)
var/datum/atom_hud/antag/ninjahud = GLOB.huds[ANTAG_HUD_NINJA]
ninjahud.leave_hud(ninja)
set_antag_hud(ninja, null)
@@ -68,6 +68,11 @@
desc = "An integrated tracking device, jury-rigged to search for living Syndicate operatives."
flags_1 = NONE
/obj/item/pinpointer/spider_cyborg // Cyborg pinpointers just look for a random space ninja.
name = "cyborg spider clan pinpointer"
desc = "An integrated tracking device, jury-rigged to search for living Spider Clan members."
flags_1 = NONE
/obj/item/pinpointer/syndicate_cyborg/Initialize()
. = ..()
@@ -85,3 +90,20 @@
if(closest_operative)
target = closest_operative
..()
/obj/item/pinpointer/spider_cyborg/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_NODROP, CYBORG_ITEM_TRAIT)
/obj/item/pinpointer/spider_cyborg/scan_for_target()
target = null
var/list/possible_targets = list()
var/turf/here = get_turf(src)
for(var/V in get_antag_minds(/datum/antagonist/ninja))
var/datum/mind/M = V
if(ishuman(M.current) && M.current.stat != DEAD)
possible_targets |= M.current
var/mob/living/closest_weeaboo = get_closest_atom(/mob/living/carbon/human, possible_targets, here)
if(closest_weeaboo)
target = closest_weeaboo
..()
+41 -26
View File
@@ -35,9 +35,9 @@
healable = 0
environment_smash = ENVIRONMENT_SMASH_STRUCTURES
obj_damage = 50
melee_damage_lower = 22.5 // reduced from 30 to 22.5 with wounds since they get big buffs to slicing wounds
melee_damage_upper = 22.5
wound_bonus = -10
melee_damage_lower = 30 // buffed back to 30, the wounds don't do much
melee_damage_upper = 30
wound_bonus = 0
bare_wound_bonus = 0
sharpness = SHARP_EDGED
see_in_dark = 8
@@ -49,17 +49,13 @@
Pulling a dead or unconscious mob while you enter a pool will pull them in with you, allowing you to feast and regain your health. \
You move quickly upon leaving a pool of blood, but the material world will soon sap your strength and leave you sluggish. \
You gain strength the more attacks you land on live humanoids, though this resets when you return to the blood zone. You can also \
launch a devastating slam attack with ctrl+shift+click, capable of smashing bones in one strike.</B>"
launch a devastating slam attack, capable of smashing bones in one strike.</B>"
loot = list(/obj/effect/decal/cleanable/blood, \
/obj/effect/decal/cleanable/blood/innards, \
/obj/item/organ/heart/demon)
del_on_death = 1
deathmessage = "screams in anger as it collapses into a puddle of viscera!"
// How long it takes for the alt-click slam attack to come off cooldown
var/slam_cooldown_time = 45 SECONDS
// The actual instance var for the cooldown
var/slam_cooldown = 0
// How many times we have hit humanoid targets since we last bloodcrawled, scaling wounding power
var/current_hitstreak = 0
// How much both our wound_bonus and bare_wound_bonus go up per hitstreak hit
@@ -70,37 +66,56 @@
var/list/consumed_mobs = list()
//buffs only happen when hearts are eaten, so this needs to be kept track separately
var/consumed_buff = 0
//slam mode for action button
var/slam_mode = FALSE
var/datum/action/cooldown/slam
/mob/living/simple_animal/slaughter/Initialize()
..()
var/obj/effect/proc_holder/spell/bloodcrawl/bloodspell = new
AddSpell(bloodspell)
slam = new /datum/action/cooldown/slam
slam.Grant(src)
if(istype(loc, /obj/effect/dummy/phased_mob/slaughter))
bloodspell.phased = TRUE
/mob/living/simple_animal/slaughter/CtrlShiftClickOn(atom/A)
if(!isliving(A))
return ..()
if(slam_cooldown + slam_cooldown_time > world.time)
to_chat(src, "<span class='warning'>Your slam ability is still on cooldown!</span>")
return
if(!isopenturf(loc))
to_chat(src, "<span class='warning'>You need to be on open flooring to do that!")
return
/datum/action/cooldown/slam
name = "Slaughter Slam"
desc = "Launch enemies and break bones in one strike."
icon_icon = 'icons/mob/actions/actions_minor_antag.dmi'
background_icon_state = "bg_demon"
button_icon_state = "slam"
cooldown_time = 45 SECONDS
face_atom(A)
var/mob/living/victim = A
victim.take_bodypart_damage(brute=20, wound_bonus=wound_bonus) // don't worry, there's more punishment when they hit something
visible_message("<span class='danger'>[src] slams into [victim] with monstrous strength!</span>", "<span class='danger'>You slam into [victim] with monstrous strength!</span>", ignored_mobs=victim)
to_chat(victim, "<span class='userdanger'>[src] slams into you with monstrous strength, sending you flying like a ragdoll!</span>")
var/turf/yeet_target = get_edge_target_turf(victim, dir)
victim.throw_at(yeet_target, 10, 5, src)
slam_cooldown = world.time
log_combat(src, victim, "slaughter slammed")
/datum/action/cooldown/slam/Trigger()
. = ..()
if(!.)
return
var/mob/living/simple_animal/slaughter/user = owner
user.slam_mode = !user.slam_mode
to_chat(user, user.slam_mode ? "Ready to slam!" : "Maybe not now.")
/mob/living/simple_animal/slaughter/UnarmedAttack(atom/A, proximity)
if(iscarbon(A))
var/mob/living/carbon/target = A
if(slam_mode)
if(!isopenturf(loc))
to_chat(src, "<span class='warning'>You need to be on open flooring to do that!")
return
face_atom(A)
var/mob/living/victim = A
var/body_pick = pick(BODY_ZONE_CHEST, BODY_ZONE_HEAD, BODY_ZONE_L_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_ARM, BODY_ZONE_R_LEG)
var/datum/wound/blunt/critical/wound_major = new
var/obj/item/bodypart/body_wound = victim.get_bodypart(body_pick)
wound_major.apply_wound(body_wound)
visible_message("<span class='danger'>[src] slams into [victim] with monstrous strength!</span>", "<span class='danger'>You slam into [victim] with monstrous strength!</span>", ignored_mobs=victim)
to_chat(victim, "<span class='userdanger'>[src] slams into you with monstrous strength, sending you flying like a ragdoll!</span>")
var/turf/yeet_target = get_edge_target_turf(victim, dir)
victim.throw_at(yeet_target, 10, 14, src)
slam_mode = FALSE
slam.StartCooldown()
log_combat(src, victim, "slaughter slammed")
if(target.stat != DEAD && target.mind && current_hitstreak < wound_bonus_hitstreak_max)
current_hitstreak++
wound_bonus += wound_bonus_per_hit
@@ -0,0 +1,131 @@
/datum/antagonist/ninja
name = "Space Ninja"
antagpanel_category = "Space Ninja"
job_rank = ROLE_NINJA
antag_hud_type = ANTAG_HUD_NINJA
antag_hud_name = "space_ninja"
show_name_in_check_antagonists = TRUE
show_to_ghosts = TRUE
antag_moodlet = /datum/mood_event/focused
///Whether or not this ninja will obtain objectives
var/give_objectives = TRUE
///Whether or not this ninja receives the standard equipment
var/give_equipment = TRUE
/proc/is_ninja(mob/living/M)
return M && M.mind && M.mind.has_antag_datum(/datum/antagonist/ninja)
/datum/antagonist/ninja/apply_innate_effects(mob/living/mob_override)
var/mob/living/ninja = mob_override || owner.current
add_antag_hud(antag_hud_type, antag_hud_name, ninja)
/datum/antagonist/ninja/remove_innate_effects(mob/living/mob_override)
var/mob/living/ninja = mob_override || owner.current
remove_antag_hud(antag_hud_type, ninja)
/**
* Proc that equips the space ninja outfit on a given individual. By default this is the owner of the antagonist datum.
*
* Proc that equips the space ninja outfit on a given individual. By default this is the owner of the antagonist datum.
* Arguments:
* * ninja - The human to receive the gear
* * Returns a proc call on the given human which will equip them with all the gear.
*/
/datum/antagonist/ninja/proc/equip_space_ninja(mob/living/carbon/human/ninja = owner.current)
return ninja.equipOutfit(/datum/outfit/ninja)
/**
* Proc that adds the proper memories to the antag datum
*
* Proc that adds the ninja starting memories to the owner of the antagonist datum.
*/
/datum/antagonist/ninja/proc/addMemories()
antag_memory += "I am an elite mercenary of the mighty Spider Clan. A <font color='red'><B>SPACE NINJA</B></font>!<br>"
antag_memory += "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by clicking the initialize UI button, to use abilities like stealth)!<br>"
/datum/objective/cyborg_hijack
explanation_text = "Use your gloves to convert at least one cyborg to aide you in sabotaging the station."
/datum/objective/door_jack
///How many doors that need to be opened using the gloves to pass the objective
var/doors_required = 0
/datum/objective/plant_explosive
var/area/detonation_location
/datum/objective/security_scramble
explanation_text = "Use your gloves on a security console to set everyone to arrest at least once. Note that the AI will be alerted once you begin!"
/datum/objective/terror_message
explanation_text = "Use your gloves on a communication console in order to bring another threat to the station. Note that the AI will be alerted once you begin!"
/**
* Proc that adds all the ninja's objectives to the antag datum.
*
* Proc that adds all the ninja's objectives to the antag datum. Called when the datum is gained.
*/
/datum/antagonist/ninja/proc/addObjectives()
//Cyborg Hijack: Flag set to complete in the DrainAct in ninjaDrainAct.dm
var/datum/objective/hijack = new /datum/objective/cyborg_hijack()
objectives += hijack
//Research stealing
var/datum/objective/download/research = new /datum/objective/download()
research.owner = owner
research.gen_amount_goal()
objectives += research
//Door jacks, flag will be set to complete on when the last door is hijacked
var/datum/objective/door_jack/doorobjective = new /datum/objective/door_jack()
doorobjective.doors_required = rand(15,40)
doorobjective.explanation_text = "Use your gloves to doorjack [doorobjective.doors_required] airlocks on the station."
objectives += doorobjective
//Explosive plant, the bomb will register its completion on priming
var/datum/objective/plant_explosive/bombobjective = new /datum/objective/plant_explosive()
for(var/sanity in 1 to 100) // 100 checks at most.
var/area/selected_area = pick(GLOB.sortedAreas)
if(!is_station_level(selected_area.z) || !selected_area.area_flags == VALID_TERRITORY)
continue
bombobjective.detonation_location = selected_area
break
if(bombobjective.detonation_location)
bombobjective.explanation_text = "Detonate your starter bomb in [bombobjective.detonation_location]. Note that the bomb will not work anywhere else!"
objectives += bombobjective
//Security Scramble, set to complete upon using your gloves on a security console
var/datum/objective/securityobjective = new /datum/objective/security_scramble()
objectives += securityobjective
//Message of Terror, set to complete upon using your gloves a communication console
var/datum/objective/communicationobjective = new /datum/objective/terror_message()
objectives += communicationobjective
//Survival until end
var/datum/objective/survival = new /datum/objective/survive()
survival.owner = owner
objectives += survival
/datum/antagonist/ninja/greet()
SEND_SOUND(owner.current, sound('sound/effects/ninja_greeting.ogg'))
to_chat(owner.current, "I am an elite mercenary of the mighty Spider Clan. A <font color='red'><B>SPACE NINJA</B></font>!")
to_chat(owner.current, "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by right clicking on it, to use abilities like stealth)!")
owner.announce_objectives()
/datum/antagonist/ninja/on_gain()
if(give_objectives)
addObjectives()
addMemories()
if(give_equipment)
equip_space_ninja(owner.current)
owner.current.mind.assigned_role = ROLE_NINJA
owner.current.mind.special_role = ROLE_NINJA
return ..()
/datum/antagonist/ninja/admin_add(datum/mind/new_owner,mob/admin)
new_owner.assigned_role = ROLE_NINJA
new_owner.special_role = ROLE_NINJA
new_owner.add_antag_datum(src)
message_admins("[key_name_admin(admin)] has ninja'ed [key_name_admin(new_owner)].")
log_admin("[key_name(admin)] has ninja'ed [key_name(new_owner)].")