Skip to content

Commit

Permalink
[MIRROR] New Operative Gamemode PR (A Ninja Rework) (#1125)
Browse files Browse the repository at this point in the history
Co-authored-by: BurpleBineapple <[email protected]>
  • Loading branch information
SierraHelper and BurpleBineapple authored Oct 11, 2023
1 parent 96c276b commit 66c5b52
Show file tree
Hide file tree
Showing 46 changed files with 999 additions and 3,511 deletions.
2 changes: 1 addition & 1 deletion code/__defines/gamemode.dm
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#define MODE_ERT "ert"
#define MODE_ACTOR "actor"
#define MODE_MERCENARY "mercenary"
#define MODE_NINJA "ninja"
#define MODE_NINJA "operatives"
#define MODE_RAIDER "raider"
#define MODE_WIZARD "wizard"
#define MODE_CHANGELING "changeling"
Expand Down
2 changes: 2 additions & 0 deletions code/_macros.dm
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@

#define isbeam(A) istype(A, /obj/item/projectile/beam)

#define ismagazine(A) istype(A, /obj/item/ammo_magazine)

#define isbrain(A) istype(A, /mob/living/carbon/brain)

#define iscarbon(A) istype(A, /mob/living/carbon)
Expand Down
4 changes: 2 additions & 2 deletions code/datums/uplink/hardsuit_modules.dm
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
name = "\improper Mounted Energy Gun"
desc = "A module that drains your power reserves in order to fire an arm mounted energy gun."
item_cost = 48
path = /obj/item/rig_module/mounted/egun
path = /obj/item/rig_module/mounted/energy/egun

/datum/uplink_item/item/hardsuit_modules/power_sink
name = "\improper Power Sink"
Expand All @@ -38,5 +38,5 @@
name = "\improper Mounted Laser Cannon"
desc = "A module capable of draining your suit's power reserves in order to fire a shoulder mounted laser cannon."
item_cost = 64
path = /obj/item/rig_module/mounted/lcannon
path = /obj/item/rig_module/mounted/energy/lcannon
antag_roles = list(MODE_MERCENARY)
55 changes: 27 additions & 28 deletions code/game/antagonist/outsider/ninja.dm
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ GLOBAL_DATUM_INIT(ninjas, /datum/antagonist/ninja, new)

/datum/antagonist/ninja
id = MODE_NINJA
role_text = "Ninja"
role_text_plural = "Ninja"
role_text = "Operative"
role_text_plural = "Operatives"
landmark_id = "ninjastart"
welcome_text = "<span class='info'>You are an elite mercenary assassin of the Spider Clan. You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor.</span>"
welcome_text = "<span class='info'>You are an elite operative of some interest group. You have a variety of abilities at your disposal, thanks to your advanced hardsuit.</span>"
flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_RANDSPAWN | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE
antaghud_indicator = "hudninja"

initial_spawn_req = 1
initial_spawn_target = 1
hard_cap = 1
initial_spawn_target = 2
hard_cap = 2
hard_cap_round = 3
min_player_age = 18

Expand Down Expand Up @@ -81,49 +81,48 @@ GLOBAL_DATUM_INIT(ninjas, /datum/antagonist/ninja, new)
player.StoreMemory("<B>Directive:</B> [SPAN_DANGER("[directive]")]<br>", /singleton/memory_options/system)
to_chat(player, "<b>Remember your directive:</b> [directive].")

/datum/antagonist/ninja/update_antag_mob(datum/mind/player)
..()
var/ninja_title = pick(GLOB.ninja_titles)
var/ninja_name = pick(GLOB.ninja_names)
var/mob/living/carbon/human/H = player.current
if(istype(H))
H.real_name = "[ninja_title] [ninja_name]"
H.SetName(H.real_name)
player.name = H.name

/datum/antagonist/ninja/equip(mob/living/carbon/human/player)
. = ..()
if(.)
var/obj/item/device/radio/R = new /obj/item/device/radio/headset(player)
var/obj/item/device/radio/R = new /obj/item/device/radio/headset/syndicate(player)
player.equip_to_slot_or_del(R, slot_l_ear)
player.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(player), slot_w_uniform)
player.equip_to_slot_or_del(new /obj/item/device/flashlight(player), slot_belt)
create_id("Infiltrator", player)
equip_rig(/obj/item/rig/light/ninja, player)
create_id("Operative", player)
var/obj/item/modular_computer/pda/syndicate/U = new
player.put_in_hands(U)
var/singleton/uplink_source/pda/uplink_source = new
uplink_source.setup_uplink_source(player, 0)
var/obj/item/ninja_kit/kit = new
player.put_in_hands(kit)

/datum/antagonist/ninja/equip_vox(mob/living/carbon/human/vox, mob/living/carbon/human/old)
vox.equip_to_slot_or_del(new /obj/item/clothing/under/vox/vox_casual(vox), slot_w_uniform)
vox.equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/vox(vox), slot_shoes)
vox.equip_to_slot_or_del(new /obj/item/clothing/gloves/vox(vox), slot_gloves)
vox.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/vox(vox), slot_wear_mask)
vox.equip_to_slot_or_del(new /obj/item/tank/nitrogen(vox), slot_back)
vox.put_in_hands(locate(/obj/item/modular_computer/pda/syndicate) in old.contents)
vox.set_internals(locate(/obj/item/tank) in vox.contents)

/datum/antagonist/ninja/proc/generate_ninja_directive(side)
var/directive = "[side=="face"?"[GLOB.using_map.company_name]":"A criminal syndicate"] is your employer. "//Let them know which side they're on.
switch(rand(1,19))
if(1)
directive += "The Spider Clan must not be linked to this operation. Remain hidden and covert when possible."
directive += "Your interest group must not be linked to this operation. Remain hidden and covert when possible."
if(2)
directive += "[GLOB.using_map.station_name] is financed by an enemy of the Spider Clan. Cause as much structural damage as desired."
directive += "[GLOB.using_map.station_name] is financed by an enemy of your interest group. Cause as much structural damage as desired."
if(3)
directive += "A wealthy animal rights activist has made a request we cannot refuse. Prioritize saving animal lives whenever possible."
if(4)
directive += "The Spider Clan absolutely cannot be linked to this operation. Eliminate witnesses at your discretion."
directive += "Your interest group absolutely cannot be linked to this operation. Eliminate witnesses at your discretion."
if(5)
directive += "We are currently negotiating with [GLOB.using_map.company_name] [GLOB.using_map.boss_name]. Prioritize saving human lives over ending them."
if(6)
directive += "We are engaged in a legal dispute over [GLOB.using_map.station_name]. If a laywer is present on board, force their cooperation in the matter."
if(7)
directive += "A financial backer has made an offer we cannot refuse. Implicate criminal involvement in the operation."
if(8)
directive += "Let no one question the mercy of the Spider Clan. Ensure the safety of all non-essential personnel you encounter."
directive += "Let no one question the mercy of your interest group. Ensure the safety of all non-essential personnel you encounter."
if(9)
directive += "A free agent has proposed a lucrative business deal. Implicate [GLOB.using_map.company_name] involvement in the operation."
if(10)
Expand All @@ -136,15 +135,15 @@ GLOBAL_DATUM_INIT(ninjas, /datum/antagonist/ninja, new)
directive += "Some disgruntled [GLOB.using_map.company_name] employees have been supportive of our operations. Be wary of any mistreatment by command staff."
if(14)
var/xenorace = pick(SPECIES_UNATHI, SPECIES_SKRELL)
directive += "A group of [xenorace] radicals have been loyal supporters of the Spider Clan. Favor [xenorace] crew whenever possible."
directive += "A group of [xenorace] radicals have been loyal supporters of your interest group. Favor [xenorace] crew whenever possible."
if(15)
directive += "The Spider Clan has recently been accused of religious insensitivity. Attempt to speak with the Chaplain and prove these accusations false."
directive += "Your interest group has recently been accused of religious insensitivity. Attempt to speak with the Chaplain and prove these accusations false."
if(16)
directive += "The Spider Clan has been bargaining with a competing prosthetics manufacturer. Try to shine [GLOB.using_map.company_name] prosthetics in a bad light."
directive += "Your interest group has been bargaining with a competing prosthetics manufacturer. Try to shine [GLOB.using_map.company_name] prosthetics in a bad light."
if(17)
directive += "The Spider Clan has recently begun recruiting outsiders. Consider suitable candidates and assess their behavior amongst the crew."
directive += "Your interest group has recently begun recruiting outsiders. Consider suitable candidates and assess their behavior amongst the crew."
if(18)
directive += "A cyborg liberation group has expressed interest in our serves. Prove the Spider Clan merciful towards law-bound synthetics."
directive += "A cyborg liberation group has expressed interest in our serves. Prove your interest group is merciful towards law-bound synthetics."
else
directive += "There are no special supplemental instructions at this time."
return directive
14 changes: 14 additions & 0 deletions code/game/atoms_movable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,20 @@
if(istype(hit_atom,/mob/living))
var/mob/living/M = hit_atom
M.hitby(src,TT)
var/obj/item/rig/rig = get_rig()
var/mob/living/carbon/human/lunger = src
var/mob/living/carbon/human/victim = M
if (istype(lunger) && istype(victim) && istype(rig)) ///Post-collision combat grab check. Independent of jumping.
for (var/obj/item/rig_module/actuators/R in rig.installed_modules)
if (R.active && R.combatType)
visible_message(
SPAN_WARNING("\The [lunger] latches onto \the [victim]!"),
SPAN_WARNING("You latch onto \the [victim] at the end of your lunge!")
)
lunger.species.attempt_grab(lunger, victim)
if(istype(lunger.get_active_hand(), /obj/item/grab/normal))
var/obj/item/grab/normal/G = lunger.get_active_hand()
G.upgrade()

else if(isobj(hit_atom))
var/obj/O = hit_atom
Expand Down
18 changes: 9 additions & 9 deletions code/game/gamemodes/ninja/ninja.dm
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
/datum/game_mode/ninja
name = "Ninja"
round_description = "An agent of the Spider Clan is onboard!"
name = "Operative"
round_description = "An elite operative is on board!"
extended_round_description = "What was that?! Was that a person or did your eyes just play tricks on you? \
You have no idea. That slim-suited, cryptic individual is an enigma to you and all of your knowledge. \
You have no idea. That hardsuited, cryptic individual is an enigma to you and all of your knowledge. \
Their purpose is unknown. Their mission is unknown. How they arrived to this secure and isolated \
section of the galaxy, you don't know. What you do know is that there is a silent shadow-stalker piercing \
through your defenses with technological capabilities eons ahead of your time. They can avoid \
the omniscience of the AI and rival the most hardened weapons your people are capable of. Tread lightly and \
only hope this unknown assassin isn't here for you."
config_tag = "ninja"
required_players = 5
section of the galaxy, you don't know. What you do know is that there is a smooth-criminal piercing \
through your defenses with technological capabilities decades ahead of your time. The equipment they \
carry is enough to turn heads far enough that they pop right off. Tread lightly and only hope this operative \
isn't here for you."
config_tag = "operative"
required_players = 10
required_enemies = 1
end_on_antag_death = FALSE
antag_tags = list(MODE_NINJA)
80 changes: 80 additions & 0 deletions code/game/objects/items/devices/personal_shield.dm
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,83 @@
SetName("activated [initial(name)]")
else
SetName(initial(name))

/obj/item/rig_module/personal_shield
name = "hardsuit energy shield"
desc = "Truly a life-saver: this device protects its user from being hit by objects moving very, very fast. It draws power from a hardsuit's internal battery."
icon = 'icons/obj/tools/batterer.dmi'
icon_state = "battereroff"
var/shield_type = /obj/aura/personal_shield/device
var/shield_power_cost = 100
var/obj/aura/personal_shield/device/shield

VAR_PRIVATE/currently_stored_power = 500
VAR_PRIVATE/max_stored_power = 500
VAR_PRIVATE/restored_power_per_tick = 5
VAR_PRIVATE/enable_when_powered = FALSE

toggleable = TRUE

interface_name = "energy shield"
interface_desc = "A device that protects its user from being hit by fast moving projectiles. Its internal capacitor can hold 5 charges at a time and recharges slowly over time."
module_cooldown = 10 SECONDS
origin_tech = list(TECH_MATERIAL = 5, TECH_POWER = 6, TECH_MAGNET = 6, TECH_ESOTERIC = 6, TECH_ENGINEERING = 7)
activate_string = "Enable Shield"
deactivate_string = "Disable Shield"

/obj/item/rig_module/personal_shield/Initialize()
. = ..()
if (holder.cell)
currently_stored_power = holder.cell.use(max_stored_power)

/obj/item/rig_module/personal_shield/activate()
if (!..())
return FALSE

var/mob/living/carbon/human/H = holder.wearer

if (shield || !H)
return FALSE
if (currently_stored_power < shield_power_cost)
to_chat(H, SPAN_WARNING("\The [src]'s internal capacitor does not have enough charge."))
return FALSE
shield = new shield_type(H, src)
return TRUE

/obj/item/rig_module/personal_shield/deactivate()
if (!..())
return FALSE

if (!shield)
return
QDEL_NULL(shield)
return TRUE

/obj/item/rig_module/personal_shield/Process(wait)
if (!holder.cell?.charge || currently_stored_power >= max_stored_power)
return PROCESS_KILL
var/amount_to_restore = min(restored_power_per_tick * wait, max_stored_power - currently_stored_power)
currently_stored_power += holder.cell.use(amount_to_restore)

if (enable_when_powered && currently_stored_power >= shield_power_cost)
activate(get_holder_of_type(src, /mob))

/obj/item/rig_module/personal_shield/proc/take_charge()
if (!actual_take_charge())
deactivate()
return FALSE
return TRUE

/obj/item/rig_module/personal_shield/proc/actual_take_charge()
if (!holder.cell)
return FALSE
if (currently_stored_power < shield_power_cost)
return FALSE

currently_stored_power -= shield_power_cost
START_PROCESSING(SSobj, src)

if (currently_stored_power < shield_power_cost)
enable_when_powered = TRUE
return FALSE
return TRUE
21 changes: 21 additions & 0 deletions code/game/objects/items/gunboxes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,24 @@
user.put_in_any_hand_if_possible(new_weapon)
to_chat(user, SPAN_NOTICE("You take \the [new_weapon] out of \the [src]."))
qdel(src)

/obj/item/ninja_kit
name = "loadout selection kit"
desc = "A secure box containing standard operation kit for special forces operatives."
icon = 'icons/obj/tools/xenoarcheology_tools.dmi'
icon_state = "excavation"
var/list/faction_options = list(
"Solar Special Operations Unit" = /obj/structure/closet/crate/ninja/sol,
"Gilgameshi Commando" = /obj/structure/closet/crate/ninja/gcc,
"Syndicate Mercenary" = /obj/structure/closet/crate/ninja/merc,
"Corporate Operative" = /obj/structure/closet/crate/ninja/corpo,
"Spider-Clan Ninja" = /obj/structure/closet/crate/ninja
)

/obj/item/ninja_kit/attack_self(mob/user)
var/choice = input(user, "What is your choice?") as null|anything in faction_options
if (choice && user.use_sanity_check(src))
var/new_item_path = faction_options[choice]
var/obj/new_item = new new_item_path(get_turf(src))
to_chat(user, SPAN_NOTICE("You have chosen \the [new_item]."))
qdel(src)
50 changes: 50 additions & 0 deletions code/game/objects/structures/crates_lockers/crates.dm
Original file line number Diff line number Diff line change
Expand Up @@ -316,3 +316,53 @@

/obj/structure/closet/crate/uranium/WillContain()
return list(/obj/item/stack/material/uranium/ten = 5)

///Base ninja equipment
/obj/structure/closet/crate/ninja
name = "ninja equipment crate"
desc = "An ominous equipment crate."
closet_appearance = /singleton/closet_appearance/crate/secure/weapon

/obj/structure/closet/crate/ninja/WillContain()
return list(
/obj/item/rig/light/ninja,
/obj/item/material/sword/katana,
/obj/item/storage/box/syndie_kit/silenced
)

///Ninja equipment loadouts. Overwritten in torch/structures/closets.dm because of away/example check evils
/obj/structure/closet/crate/ninja/sol
name = "sol equipment crate"
desc = "A tactical equipment crate."

/obj/structure/closet/crate/ninja/sol/WillContain()
return list(
/obj/item/rig/light/ninja/sol
)

/obj/structure/closet/crate/ninja/gcc
name = "gcc equipment crate"
desc = "A heavy equipment crate."

/obj/structure/closet/crate/ninja/gcc/WillContain()
return list(
/obj/item/rig/light/ninja/gcc
)

/obj/structure/closet/crate/ninja/corpo
name = "corporate equipment crate"
desc = "A patented equipment crate."

/obj/structure/closet/crate/ninja/corpo/WillContain()
return list(
/obj/item/rig/light/ninja/corpo
)

/obj/structure/closet/crate/ninja/merc
name = "mercenary equipment crate"
desc = "A traitorous equipment crate."

/obj/structure/closet/crate/ninja/merc/WillContain()
return list(
/obj/item/rig/merc/ninja
)
8 changes: 8 additions & 0 deletions code/modules/augment/active/armblades.dm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@
edge = TRUE
attack_verb = list("stabbed", "sliced", "cut")

/obj/item/material/armblade/mounted
name = "hardsuit armblade"
desc = "An extra large, extra sharp armblade. Rip and tear."
default_material = MATERIAL_PLASTEEL

/obj/item/material/armblade/mounted/dropped() /// This should not exist on its own
..()
QDEL_IN(src, 0)

/obj/item/organ/internal/augment/active/item/armblade
name = "embedded blade"
Expand Down
Loading

0 comments on commit 66c5b52

Please sign in to comment.