Merge pull request #53702 from zxaber/kiltborg

[READY] Highlander mode now includes silicons
This commit is contained in:
nemvar
2020-10-02 17:39:16 +02:00
committed by GitHub
13 changed files with 148 additions and 20 deletions
+1 -1
View File
@@ -212,7 +212,7 @@
if(!R.robot_modules_background)
return
var/display_rows = CEILING(length(R.module.get_inactive_modules()) / 8, 1)
var/display_rows = max(CEILING(length(R.module.get_inactive_modules()) / 8, 1),1)
R.robot_modules_background.screen_loc = "CENTER-4:16,SOUTH+1:7 to CENTER+3:16,SOUTH+[display_rows]:7"
screenmob.client.screen += R.robot_modules_background
+13
View File
@@ -363,6 +363,19 @@ GLOBAL_LIST(admin_objective_list) //Prefilled admin assignable objective list
return FALSE
return SSshuttle.emergency.is_hijacked()
/datum/objective/hijack/highlander
name="highlander hijack"
explanation_text = "Escape on the shuttle alone. Ensure that nobody else makes it out."
/datum/objective/hijack/check_completion()
if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME)
return FALSE
var/list/datum/mind/owners = get_owners()
for(var/datum/mind/M in owners)
if(!considered_alive(M, enforce_human = FALSE) || !SSshuttle.emergency.shuttle_areas[get_area(M.current)])
return FALSE
return SSshuttle.emergency.is_hijacked(filter_by_human = FALSE, solo_hijack = TRUE)
/datum/objective/block
name = "no organics on shuttle"
explanation_text = "Do not allow any organic lifeforms to escape on the shuttle alive."
+23 -4
View File
@@ -134,7 +134,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
/obj/item/claymore/highlander/attack(mob/living/target, mob/living/user)
. = ..()
if(!QDELETED(target) && iscarbon(target) && target.stat == DEAD && target.mind && target.mind.special_role == "highlander")
if(!QDELETED(target) && target.stat == DEAD && target.mind && target.mind.special_role == "highlander")
user.fully_heal(admin_revive = FALSE) //STEAL THE LIFE OF OUR FALLEN FOES
add_notch(user)
target.visible_message("<span class='warning'>[target] crumbles to dust beneath [user]'s blows!</span>", "<span class='userdanger'>As you fall, your body crumbles to dust!</span>")
@@ -143,9 +143,13 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
/obj/item/claymore/highlander/attack_self(mob/living/user)
var/closest_victim
var/closest_distance = 255
for(var/mob/living/carbon/human/H in GLOB.player_list - user)
if(H.mind.special_role == "highlander" && (!closest_victim || get_dist(user, closest_victim) < closest_distance))
closest_victim = H
for(var/mob/living/carbon/human/scot in GLOB.player_list - user)
if(scot.mind.special_role == "highlander" && (!closest_victim || get_dist(user, closest_victim) < closest_distance))
closest_victim = scot
for(var/mob/living/silicon/robot/siliscot in GLOB.player_list - user)
if(siliscot.mind.special_role == "highlander" && (!closest_victim || get_dist(user, closest_victim) < closest_distance))
closest_victim = siliscot
if(!closest_victim)
to_chat(user, "<span class='warning'>[src] thrums for a moment and falls dark. Perhaps there's nobody nearby.</span>")
return
@@ -207,6 +211,21 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
name = new_name
playsound(user, 'sound/items/screwdriver2.ogg', 50, TRUE)
/obj/item/claymore/highlander/robot //BLOODTHIRSTY BORGS NOW COME IN PLAID
icon = 'icons/obj/items_cyborg.dmi'
icon_state = "claymore_cyborg"
var/mob/living/silicon/robot/robot
/obj/item/claymore/highlander/robot/Initialize()
var/obj/item/robot_module/kiltkit = loc
robot = kiltkit.loc
if(!istype(robot))
qdel(src)
return ..()
/obj/item/claymore/highlander/robot/process()
loc.layer = LARGE_MOB_LAYER
/obj/item/katana
name = "katana"
desc = "Woefully underpowered in D20."
+19
View File
@@ -17,6 +17,22 @@ GLOBAL_VAR_INIT(highlander, FALSE)
continue
H.make_scottish()
for(var/mob/living/silicon/ai/AI in GLOB.player_list)
if(!istype(AI) || AI.stat == DEAD)
continue
if(AI.deployed_shell)
AI.deployed_shell.undeploy()
AI.change_mob_type(/mob/living/silicon/robot , null, null)
AI.gib()
for(var/mob/living/silicon/robot/robot in GLOB.player_list)
if(!istype(robot) || robot.stat == DEAD)
continue
if(robot.shell)
robot.gib()
continue
robot.make_scottish()
message_admins("<span class='adminnotice'>[key_name_admin(usr)] used THERE CAN BE ONLY ONE!</span>")
log_admin("[key_name(usr)] used THERE CAN BE ONLY ONE.")
addtimer(CALLBACK(SSshuttle.emergency, /obj/docking_port/mobile/emergency.proc/request, null, 1), 50)
@@ -29,3 +45,6 @@ GLOBAL_VAR_INIT(highlander, FALSE)
/mob/living/carbon/human/proc/make_scottish()
mind.add_antag_datum(/datum/antagonist/highlander)
/mob/living/silicon/robot/proc/make_scottish()
mind.add_antag_datum(/datum/antagonist/highlander/robot)
@@ -9,22 +9,24 @@
var/mob/living/L = owner.current || mob_override
ADD_TRAIT(L, TRAIT_NOGUNS, "highlander")
ADD_TRAIT(L, TRAIT_NODISMEMBER, "highlander")
ADD_TRAIT(L, TRAIT_SHOCKIMMUNE, "highlander")
REMOVE_TRAIT(L, TRAIT_PACIFISM, ROUNDSTART_TRAIT)
/datum/antagonist/highlander/remove_innate_effects(mob/living/mob_override)
var/mob/living/L = owner.current || mob_override
REMOVE_TRAIT(L, TRAIT_NOGUNS, "highlander")
REMOVE_TRAIT(L, TRAIT_NODISMEMBER, "highlander")
REMOVE_TRAIT(L, TRAIT_SHOCKIMMUNE, "highlander")
if(L.has_quirk(/datum/quirk/nonviolent))
ADD_TRAIT(L, TRAIT_PACIFISM, ROUNDSTART_TRAIT)
/datum/antagonist/highlander/proc/forge_objectives()
var/datum/objective/steal/steal_objective = new
steal_objective.owner = owner
steal_objective.set_target(new /datum/objective_item/steal/nukedisc)
objectives += steal_objective
var/datum/objective/hijack/hijack_objective = new
hijack_objective.explanation_text = "Escape on the shuttle alone. Ensure that nobody else makes it out."
var/datum/objective/hijack/highlander/hijack_objective = new
hijack_objective.owner = owner
objectives += hijack_objective
@@ -54,7 +56,7 @@
H.regenerate_icons()
H.revive(full_heal = TRUE, admin_revive = TRUE)
H.equip_to_slot_or_del(new /obj/item/clothing/under/costume/kilt/highlander(H), ITEM_SLOT_ICLOTHING)
H.equip_to_slot_or_del(new /obj/item/radio/headset/heads/captain(H), ITEM_SLOT_EARS)
H.equip_to_slot_or_del(new /obj/item/radio/headset/syndicate(H), ITEM_SLOT_EARS)
H.equip_to_slot_or_del(new /obj/item/clothing/head/beret/highlander(H), ITEM_SLOT_HEAD)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(H), ITEM_SLOT_FEET)
H.equip_to_slot_or_del(new /obj/item/pinpointer/nuke(H), ITEM_SLOT_LPOCKET)
@@ -81,3 +83,22 @@
antiwelder.desc = "You are unable to hold anything in this hand until you're the last one left!"
antiwelder.icon_state = "bloodhand_right"
H.put_in_hands(antiwelder)
/datum/antagonist/highlander/robot
name="highlander"
/datum/antagonist/highlander/robot/greet()
to_chat(owner, "<span class='boldannounce'>Your integrated claymore cries out for blood. Claim the lives of others, and your own will be restored!\n\
Activate it in your hand, and it will lead to the nearest target. Attack the nuclear authentication disk with it, and you will store it.</span>")
/datum/antagonist/highlander/robot/give_equipment()
var/mob/living/silicon/robot/robotlander = owner.current
if(!istype(robotlander))
return ..()
robotlander.revive(full_heal = TRUE, admin_revive = TRUE)
robotlander.set_connected_ai() //DISCONNECT FROM AI
robotlander.laws.clear_inherent_laws()
robotlander.laws.set_zeroth_law("THERE CAN BE ONLY ONE")
robotlander.laws.show_laws(robotlander)
robotlander.module.transform_to(/obj/item/robot_module/syndicate/kiltborg)
sword = locate(/obj/item/claymore/highlander/robot) in robotlander.module.basic_modules
@@ -51,6 +51,10 @@
* * module_num - the slot number being equipped to.
*/
/mob/living/silicon/robot/proc/equip_module_to_slot(obj/item/item_module, module_num)
var/storage_was_closed = FALSE //Just to be consistant and all
if(!shown_robot_modules) //Tools may be invisible if the collection is hidden
hud_used.toggle_show_robot_modules()
storage_was_closed = TRUE
switch(module_num)
if(1)
item_module.screen_loc = inv1.screen_loc
@@ -72,6 +76,9 @@
update_sight()
observer_screen_update(item_module, TRUE)
if(storage_was_closed)
hud_used.toggle_show_robot_modules()
return TRUE
/**
@@ -73,7 +73,7 @@
var/lawupdate = 1 //Cyborgs will sync their laws with their AI by default
var/scrambledcodes = FALSE // Used to determine if a borg shows up on the robotics console. Setting to TRUE hides them.
var/lockcharge //Boolean of whether the borg is locked down or not
var/lockcharge = FALSE //Boolean of whether the borg is locked down or not
var/toner = 0
var/tonermax = 40
@@ -729,6 +729,8 @@
/mob/living/silicon/robot/updatehealth()
..()
if(!module.breakable_modules)
return
/// the current percent health of the robot (-1 to 1)
var/percent_hp = health/maxHealth
@@ -100,6 +100,9 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real
return
if(W.slot_flags & ITEM_SLOT_HEAD && hat_offset != INFINITY && user.a_intent == INTENT_HELP && !is_type_in_typecache(W, GLOB.blacklisted_borg_hats))
if(HAS_TRAIT(hat, TRAIT_NODROP))
to_chat(user, "<span class='warn'>You can't seem to remove [src]'s existing headwear!</span>")
return
to_chat(user, "<span class='notice'>You begin to place [W] on [src]'s head...</span>")
to_chat(src, "<span class='notice'>[user] is placing [W] on your head...</span>")
if(do_after(user, 30, target = src))
@@ -7,6 +7,8 @@
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
flags_1 = CONDUCT_1
///Host of this module
var/mob/living/silicon/robot/robot
var/list/basic_modules = list() //a list of paths, converted to a list of instances on New()
var/list/emag_modules = list() //ditto
@@ -24,6 +26,8 @@
var/can_be_pushed = TRUE
var/magpulsing = FALSE
var/clean_on_move = FALSE
var/breakable_modules = TRUE //Whether the borg loses tool slots with damage.
var/locked_transform = TRUE //Whether swapping to this module should lockcharge the borg
var/did_feedback = FALSE
@@ -183,6 +187,7 @@
/obj/item/robot_module/proc/transform_to(new_module_type)
var/mob/living/silicon/robot/R = loc
var/obj/item/robot_module/RM = new new_module_type(R)
RM.robot = R
if(!RM.be_transformed_to(src))
qdel(RM)
return
@@ -217,15 +222,15 @@
sleep(1)
flick("[cyborg_base_icon]_transform", R)
R.notransform = TRUE
R.SetLockdown(1)
R.set_anchored(TRUE)
if(locked_transform)
R.SetLockdown(TRUE)
R.set_anchored(TRUE)
R.logevent("Chassis configuration has been set to [name].")
sleep(1)
for(var/i in 1 to 4)
playsound(R, pick('sound/items/drill_use.ogg', 'sound/items/jaws_cut.ogg', 'sound/items/jaws_pry.ogg', 'sound/items/welder.ogg', 'sound/items/ratchet.ogg'), 80, TRUE, -1)
sleep(7)
if(!prev_lockcharge)
R.SetLockdown(0)
R.SetLockdown(prev_lockcharge)
R.setDir(SOUTH)
R.set_anchored(FALSE)
R.notransform = FALSE
@@ -643,6 +648,34 @@
hat_offset = -4
canDispose = TRUE
/obj/item/robot_module/syndicate/kiltborg
name = "Highlander"
basic_modules = list(
/obj/item/claymore/highlander/robot,
/obj/item/pinpointer/nuke,)
moduleselect_icon = "kilt"
cyborg_base_icon = "kilt"
hat_offset = -2
breakable_modules = FALSE
locked_transform = FALSE //GO GO QUICKLY AND SLAUGHTER THEM ALL
/obj/item/robot_module/syndicate/kiltborg/be_transformed_to(obj/item/robot_module/old_module)
. = ..()
qdel(robot.radio)
robot.radio = new /obj/item/radio/borg/syndicate(robot)
robot.scrambledcodes = TRUE
robot.maxHealth = 50 //DIE IN THREE HITS, LIKE A REAL SCOT
robot.break_cyborg_slot(3) //YOU ONLY HAVE TWO ITEMS ANYWAY
var/obj/item/pinpointer/nuke/diskyfinder = locate(/obj/item/pinpointer/nuke) in basic_modules
diskyfinder.attack_self(robot)
/obj/item/robot_module/syndicate/kiltborg/do_transform_delay() //AUTO-EQUIPPING THESE TOOLS ANY EARLIER CAUSES RUNTIMES OH YEAH
. = ..()
robot.equip_module_to_slot(locate(/obj/item/claymore/highlander/robot) in basic_modules, 1)
robot.equip_module_to_slot(locate(/obj/item/pinpointer/nuke) in basic_modules, 2)
robot.place_on_head(new /obj/item/clothing/head/beret/highlander(robot)) //THE ONLY PART MORE IMPORTANT THAN THE SWORD IS THE HAT
ADD_TRAIT(robot.hat, TRAIT_NODROP, HIGHLANDER)
/datum/robot_energy_storage
var/name = "Generic energy storage"
var/max_energy = 30000
+18 -7
View File
@@ -265,15 +265,26 @@
SSticker.emergency_reason = null
/obj/docking_port/mobile/emergency/proc/is_hijacked()
/**
* Proc that handles checking if the emergency shuttle was successfully hijacked
*
* Checks for all mobs on the shuttle, checks their status, and checks if they're
* borgs or simple animals. Depending on the args, certain mobs may be ignored,
* and the presence of other antags may or may not invalidate a hijack.
* Args:
* filter_by_human, default TRUE, tells the proc that only humans should block a hijack. Borgs and animals are ignored and will not block if this is TRUE.
* solo_hijack, default FALSE, tells the proc to fail with multiple hijackers, such as for Highlander mode.
*/
/obj/docking_port/mobile/emergency/proc/is_hijacked(filter_by_human = TRUE, solo_hijack = FALSE)
var/has_people = FALSE
var/hijacker_present = FALSE
var/hijacker_count = 0
for(var/mob/living/player in GLOB.player_list)
if(player.mind)
if(player.stat != DEAD)
if(issilicon(player)) //Borgs are technically dead anyways
if(issilicon(player) && filter_by_human) //Borgs are technically dead anyways
continue
if(isanimal(player)) //animals don't count
if(isanimal(player) && filter_by_human) //animals don't count
continue
if(isbrain(player)) //also technically dead
continue
@@ -287,7 +298,7 @@
var/prevent = FALSE
for(var/datum/antagonist/A in player.mind.antag_datums)
if(A.can_hijack == HIJACK_HIJACKER)
hijacker_present = TRUE
hijacker_count += 1
prevent = FALSE
break //If we have both prevent and hijacker antags assume we want to hijack.
else if(A.can_hijack == HIJACK_PREVENT)
@@ -295,8 +306,8 @@
if(prevent)
return FALSE
return has_people && hijacker_present
//has people AND either there's only one hijacker or there's any but solo_hijack is disabled
return has_people && ((hijacker_count == 1) || (hijacker_count && !solo_hijack))
/obj/docking_port/mobile/emergency/proc/ShuttleDBStuff()
set waitfor = FALSE
Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 KiB

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB