mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-26 06:29:23 +01:00
Merge pull request #53702 from zxaber/kiltborg
[READY] Highlander mode now includes silicons
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 |
Reference in New Issue
Block a user