diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 84a256a78a8..fea07054b5c 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -931,6 +931,8 @@ #define COMSIG_MOB_FIRED_GUN "mob_fired_gun" ///called in /obj/item/gun/process_fire (user, target, params, zone_override) #define COMSIG_GUN_FIRED "gun_fired" +///called in /obj/item/gun/ballistic/process_chamber (casing) +#define COMSIG_CASING_EJECTED "casing_ejected" // /obj/effect/proc_holder/spell signals diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 5ace6d01a99..dec2891b2cb 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -398,6 +398,7 @@ GLOBAL_LIST_INIT(pda_styles, sortList(list(MONO, VT, ORBITRON, SHARE))) #define DUMMY_HUMAN_SLOT_PREFERENCES "dummy_preference_preview" #define DUMMY_HUMAN_SLOT_ADMIN "admintools" #define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation" +#define DUMMY_HUMAN_SLOT_CTF "dummy_ctf_preview_generation" #define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round //This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored diff --git a/code/datums/components/shielded.dm b/code/datums/components/shielded.dm index 2920bfe34b5..7450c92295e 100644 --- a/code/datums/components/shielded.dm +++ b/code/datums/components/shielded.dm @@ -13,12 +13,16 @@ var/recharge_start_delay = 20 SECONDS /// Once we go unhit long enough to recharge, we replenish charges this often. The floor is effectively 1 second, AKA how often SSdcs processes var/charge_increment_delay = 1 SECONDS + /// How many charges we recover on each charge increment + var/charge_recovery = 1 /// What .dmi we're pulling the shield icon from var/shield_icon_file = 'icons/effects/effects.dmi' /// What icon is used when someone has a functional shield up var/shield_icon = "shield-old" /// Do we still shield if we're being held in-hand? If FALSE, it needs to be equipped to a slot to work var/shield_inhand = FALSE + /// Should the shield lose charges equal to the damage dealt by a hit? + var/lose_multiple_charges = FALSE /// The cooldown tracking when we were last hit COOLDOWN_DECLARE(recently_hit_cd) /// The cooldown tracking when we last replenished a charge @@ -26,13 +30,15 @@ /// A callback for the sparks/message that play when a charge is used, see [/datum/component/shielded/proc/default_run_hit_callback] var/datum/callback/on_hit_effects -/datum/component/shielded/Initialize(max_charges = 3, recharge_start_delay = 20 SECONDS, charge_increment_delay = 1 SECONDS, shield_icon_file = 'icons/effects/effects.dmi', shield_icon = "shield-old", shield_inhand = FALSE, run_hit_callback) +/datum/component/shielded/Initialize(max_charges = 3, recharge_start_delay = 20 SECONDS, charge_increment_delay = 1 SECONDS, charge_recovery = 1, lose_multiple_charges = FALSE, shield_icon_file = 'icons/effects/effects.dmi', shield_icon = "shield-old", shield_inhand = FALSE, run_hit_callback) if(!isitem(parent) || max_charges <= 0) return COMPONENT_INCOMPATIBLE src.max_charges = max_charges src.recharge_start_delay = recharge_start_delay src.charge_increment_delay = charge_increment_delay + src.charge_recovery = charge_recovery + src.lose_multiple_charges = lose_multiple_charges src.shield_icon_file = shield_icon_file src.shield_icon = shield_icon src.shield_inhand = shield_inhand @@ -73,13 +79,16 @@ var/obj/item/item_parent = parent COOLDOWN_START(src, charge_add_cd, charge_increment_delay) - current_charges++ - if(wearer && current_charges == 1) - wearer.update_appearance(UPDATE_ICON) + adjust_charge(charge_recovery) // set the number of charges to current + recovery per increment, clamped from zero to max_charges playsound(item_parent, 'sound/magic/charge.ogg', 50, TRUE) if(current_charges == max_charges) playsound(item_parent, 'sound/machines/ding.ogg', 50, TRUE) +/datum/component/shielded/proc/adjust_charge(change) + current_charges = clamp(current_charges + change, 0, max_charges) + if(wearer) + wearer.update_appearance(UPDATE_ICON) + /// Check if we've been equipped to a valid slot to shield /datum/component/shielded/proc/on_equipped(datum/source, mob/user, slot) SIGNAL_HANDLER @@ -121,7 +130,13 @@ if(current_charges <= 0) return . = COMPONENT_HIT_REACTION_BLOCK - current_charges = max(current_charges - 1, 0) + + var/charge_loss = 1 // how many charges do we lose + + if(lose_multiple_charges) // if the shield has health like damage we'll lose charges equal to the damage of the hit + charge_loss = damage + + adjust_charge(-charge_loss) INVOKE_ASYNC(src, .proc/actually_run_hit_callback, owner, attack_text, current_charges) @@ -130,8 +145,6 @@ qdel(src) return - if(!current_charges) - wearer.update_appearance(UPDATE_ICON) START_PROCESSING(SSdcs, src) // if we DO recharge, start processing so we can do that /// The wrapper to invoke the on_hit callback, so we don't have to worry about blocking in the signal handler diff --git a/code/datums/elements/delete_on_drop.dm b/code/datums/elements/delete_on_drop.dm new file mode 100644 index 00000000000..bc4d0fdccf7 --- /dev/null +++ b/code/datums/elements/delete_on_drop.dm @@ -0,0 +1,21 @@ +/** + * Attaches to an item, if that item is dropped on the floor delete it + */ +/datum/element/delete_on_drop + element_flags = ELEMENT_DETACH + var/list/myvar = list() + +/datum/element/delete_on_drop/Attach(datum/target) + . = ..() + if(!isitem(target)) + return COMPONENT_INCOMPATIBLE + RegisterSignal(target, list(COMSIG_ITEM_DROPPED, COMSIG_CASING_EJECTED), .proc/del_on_drop) + +/datum/element/delete_on_drop/Detach(datum/source) + . = ..() + UnregisterSignal(source, list(COMSIG_ITEM_DROPPED, COMSIG_CASING_EJECTED)) + +/datum/element/delete_on_drop/proc/del_on_drop(atom/source) + SIGNAL_HANDLER + if(isturf(source.loc)) + qdel(source) diff --git a/code/game/objects/effects/temporary_visuals/projectiles/impact.dm b/code/game/objects/effects/temporary_visuals/projectiles/impact.dm index 379923bd7f0..c504bb4f7b2 100644 --- a/code/game/objects/effects/temporary_visuals/projectiles/impact.dm +++ b/code/game/objects/effects/temporary_visuals/projectiles/impact.dm @@ -40,3 +40,7 @@ /obj/effect/projectile/impact/laser/emitter name = "emitter impact" icon_state = "impact_emitter" + +/obj/effect/projectile/impact/solar + name = "solar impact" + icon_state = "impact_solar" diff --git a/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm b/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm index 35d57e17be8..a26141d80a8 100644 --- a/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm +++ b/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm @@ -32,3 +32,6 @@ /obj/effect/projectile/muzzle/laser/emitter name = "emitter flash" icon_state = "muzzle_emitter" + +/obj/effect/projectile/muzzle/solar + icon_state = "muzzle_solar" diff --git a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm index ab669ca20f6..c0fa093a2fe 100644 --- a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm +++ b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm @@ -55,6 +55,10 @@ name = "heavy laser" icon_state = "beam_heavy" +/obj/effect/projectile/tracer/solar + name = "solar beam" + icon_state = "solar" + //BEAM RIFLE /obj/effect/projectile/tracer/tracer/beam_rifle icon_state = "tracer_beam" diff --git a/code/modules/capture_the_flag/ctf_classes.dm b/code/modules/capture_the_flag/ctf_classes.dm new file mode 100644 index 00000000000..52ad1af5315 --- /dev/null +++ b/code/modules/capture_the_flag/ctf_classes.dm @@ -0,0 +1,227 @@ +// GENERIC CLASSES + +/datum/outfit/ctf + name = "CTF Rifleman (Solo)" + ears = /obj/item/radio/headset + uniform = /obj/item/clothing/under/syndicate + suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf + toggle_helmet = FALSE // see the whites of their eyes + shoes = /obj/item/clothing/shoes/combat + gloves = /obj/item/clothing/gloves/combat + id = /obj/item/card/id/away + belt = /obj/item/gun/ballistic/automatic/pistol/deagle/ctf + l_pocket = /obj/item/ammo_box/magazine/recharge/ctf + r_pocket = /obj/item/ammo_box/magazine/recharge/ctf + r_hand = /obj/item/gun/ballistic/automatic/laser/ctf + + ///Description to be shown in the class selection menu + var/class_description = "General purpose combat class. Armed with a laser rifle and backup pistol." + ///Radio frequency to assign players with this outfit + var/team_radio_freq = FREQ_COMMON // they won't be able to use this on the centcom z-level, so ffa players cannot use radio + ///Icon file for the class radial menu icons + var/icon = 'icons/hud/radial_ctf.dmi' + ///Icon state for this class + var/icon_state = "ctf_rifleman" + ///Do they get a headset? + var/has_radio = TRUE + ///Do they get an ID? + var/has_card = TRUE + ///Which slots to apply TRAIT_NODROP to the items in + var/list/nodrop_slots = list(ITEM_SLOT_OCLOTHING, ITEM_SLOT_GLOVES, ITEM_SLOT_FEET, ITEM_SLOT_ICLOTHING, ITEM_SLOT_EARS) + +/datum/outfit/ctf/post_equip(mob/living/carbon/human/human_to_equip, visualsOnly=FALSE) + if(visualsOnly) + return + var/list/no_drops = list() + + if(has_card) + var/obj/item/card/id/idcard = human_to_equip.wear_id + no_drops += idcard + idcard.registered_name = human_to_equip.real_name + idcard.update_label() + idcard.update_icon() + + // Make clothing in the specified slots NODROP + for(var/slot in nodrop_slots) + no_drops += human_to_equip.get_item_by_slot(slot) + // Make items in the hands NODROP + for(var/obj/item/held_item in human_to_equip.held_items) + no_drops += held_item + listclearnulls(no_drops) // For any slots we didn't have filled + // Apply TRAIT_NODROP to everything + for(var/obj/item/item_to_nodrop as anything in no_drops) + ADD_TRAIT(item_to_nodrop, TRAIT_NODROP, CAPTURE_THE_FLAG_TRAIT) + + if(has_radio) + var/obj/item/radio/headset = human_to_equip.ears + headset.set_frequency(team_radio_freq) + headset.freqlock = TRUE + headset.independent = TRUE + human_to_equip.dna.species.stunmod = 0 + +/datum/outfit/ctf/instagib + name = "CTF Instagib (Solo)" + r_hand = /obj/item/gun/energy/laser/instakill + shoes = /obj/item/clothing/shoes/jackboots/fast + icon_state = "ctf_instakill" + class_description = "General purpose combat class. Armed with a laser rifle and backup pistol." + +/datum/outfit/ctf/assault + name = "CTF Assaulter (Solo)" + suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/light + r_hand = /obj/item/gun/ballistic/shotgun/ctf + gloves = /obj/item/clothing/gloves/tackler/rocket + l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/shotgun + r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/shotgun + belt = null + icon_state = "ctf_assaulter" + class_description = "Close combat class. Armed with a shotgun and rocket gloves." + +/datum/outfit/ctf/marksman + name = "CTF Marksman (Solo)" + r_hand = /obj/item/gun/ballistic/automatic/laser/ctf/marksman + l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/marksman + r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/marksman + belt = null + icon_state = "ctf_marksman" + class_description = "Long range class. Armed with a hitscan laser rifle." + +// RED TEAM CLASSES + +/datum/outfit/ctf/red + name = "CTF Rifleman (Red)" + suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/red + r_hand = /obj/item/gun/ballistic/automatic/laser/ctf/red + l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/rifle/red + r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/rifle/red + id = /obj/item/card/id/red //it's red + team_radio_freq = FREQ_CTF_RED + +/datum/outfit/ctf/red/instagib + name = "CTF Instagib (Red)" + r_hand = /obj/item/gun/energy/laser/instakill/red + shoes = /obj/item/clothing/shoes/jackboots/fast + team_radio_freq = FREQ_CTF_RED + +/datum/outfit/ctf/assault/red + name = "CTF Assaulter (Red)" + suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/light/red + r_hand = /obj/item/gun/ballistic/shotgun/ctf/red + l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/shotgun/red + r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/shotgun/red + id = /obj/item/card/id/red + team_radio_freq = FREQ_CTF_RED + +/datum/outfit/ctf/marksman/red + name = "CTF Marksman (Red)" + suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/red + r_hand = /obj/item/gun/ballistic/automatic/laser/ctf/marksman/red + l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/marksman/red + r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/marksman/red + id = /obj/item/card/id/red + team_radio_freq = FREQ_CTF_RED + +// BLUE TEAM CLASSES + +/datum/outfit/ctf/blue + name = "CTF Rifleman (Blue)" + suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/blue + r_hand = /obj/item/gun/ballistic/automatic/laser/ctf/blue + l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/rifle/blue + r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/rifle/blue + id = /obj/item/card/id/blue //it's blue + team_radio_freq = FREQ_CTF_BLUE + +/datum/outfit/ctf/blue/instagib + name = "CTF Instagib (Blue)" + r_hand = /obj/item/gun/energy/laser/instakill/blue + shoes = /obj/item/clothing/shoes/jackboots/fast + team_radio_freq = FREQ_CTF_BLUE + +/datum/outfit/ctf/assault/blue + name = "CTF Assaulter (Blue)" + suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/light/blue + r_hand = /obj/item/gun/ballistic/shotgun/ctf/blue + l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/shotgun/blue + r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/shotgun/blue + id = /obj/item/card/id/blue + team_radio_freq = FREQ_CTF_BLUE + +/datum/outfit/ctf/marksman/blue + name = "CTF Marksman (Blue)" + suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/blue + r_hand = /obj/item/gun/ballistic/automatic/laser/ctf/marksman/blue + l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/marksman/blue + r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/marksman/blue + id = /obj/item/card/id/blue + team_radio_freq = FREQ_CTF_BLUE + +// GREEN TEAM CLASSES + +/datum/outfit/ctf/green + name = "CTF Rifleman (Green)" + suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/green + r_hand = /obj/item/gun/ballistic/automatic/laser/ctf/green + l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/rifle/green + r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/rifle/green + id = /obj/item/card/id/green //it's green + team_radio_freq = FREQ_CTF_GREEN + +/datum/outfit/ctf/green/instagib + name = "CTF Instagib (Green)" + r_hand = /obj/item/gun/energy/laser/instakill/green + shoes = /obj/item/clothing/shoes/jackboots/fast + team_radio_freq = FREQ_CTF_GREEN + +/datum/outfit/ctf/assault/green + name = "CTF Assaulter (Green)" + suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/light/green + r_hand = /obj/item/gun/ballistic/shotgun/ctf/green + l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/shotgun/green + r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/shotgun/green + id = /obj/item/card/id/green + team_radio_freq = FREQ_CTF_GREEN + +/datum/outfit/ctf/marksman/green + name = "CTF Marksman (Blue)" + suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/green + r_hand = /obj/item/gun/ballistic/automatic/laser/ctf/marksman/green + l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/marksman/green + r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/marksman/green + id = /obj/item/card/id/green + team_radio_freq = FREQ_CTF_GREEN + +// YELLOW TEAM CLASSES + +/datum/outfit/ctf/yellow + name = "CTF Rifleman (Yellow)" + suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/yellow + r_hand = /obj/item/gun/ballistic/automatic/laser/ctf/yellow + l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/rifle/yellow + r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/rifle/yellow + id = /obj/item/card/id/yellow //it's yellow + team_radio_freq = FREQ_CTF_YELLOW + +/datum/outfit/ctf/yellow/instagib + name = "CTF Instagib (Yellow)" + r_hand = /obj/item/gun/energy/laser/instakill/yellow + shoes = /obj/item/clothing/shoes/jackboots/fast + team_radio_freq = FREQ_CTF_YELLOW + +/datum/outfit/ctf/assault/yellow + name = "CTF Assaulter (Yellow)" + suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/light/yellow + r_hand = /obj/item/gun/ballistic/shotgun/ctf/yellow + l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/shotgun/yellow + r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/shotgun/yellow + id = /obj/item/card/id/yellow + team_radio_freq = FREQ_CTF_YELLOW + +/datum/outfit/ctf/marksman/yellow + name = "CTF Marksman (Blue)" + suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/yellow + r_hand = /obj/item/gun/ballistic/automatic/laser/ctf/marksman/yellow + l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/marksman/yellow + r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/marksman/yellow + id = /obj/item/card/id/yellow + team_radio_freq = FREQ_CTF_YELLOW diff --git a/code/modules/capture_the_flag/ctf_equipment.dm b/code/modules/capture_the_flag/ctf_equipment.dm new file mode 100644 index 00000000000..5cf4ce17846 --- /dev/null +++ b/code/modules/capture_the_flag/ctf_equipment.dm @@ -0,0 +1,605 @@ + +// GENERIC PROJECTILE + +/obj/projectile/beam/ctf + damage = 0 + icon_state = "omnilaser" + +/obj/projectile/beam/ctf/prehit_pierce(atom/target) + if(!is_ctf_target(target)) + damage = 0 + return PROJECTILE_PIERCE_NONE /// hey uhhh don't hit anyone behind them + . = ..() + +/obj/projectile/beam/ctf/on_hit(atom/target, blocked = FALSE) + . = ..() + if(is_ctf_target(target) && blocked == FALSE) + if(iscarbon(target)) + var/mob/living/carbon/target_mob = target + target_mob.adjustBruteLoss(150, 0) + return BULLET_ACT_HIT + +/obj/item/ammo_box/magazine/recharge/ctf + ammo_type = /obj/item/ammo_casing/caseless/laser/ctf + +/obj/item/ammo_box/magazine/recharge/ctf/Initialize() + . = ..() + AddElement(/datum/element/delete_on_drop) + + +/obj/item/ammo_casing/caseless/laser/ctf + projectile_type = /obj/projectile/beam/ctf/ + +/obj/item/ammo_casing/caseless/laser/ctf/Initialize() + . = ..() + AddElement(/datum/element/delete_on_drop) + +// LASER RIFLE + +/obj/item/gun/ballistic/automatic/laser/ctf + mag_type = /obj/item/ammo_box/magazine/recharge/ctf/rifle + desc = "This looks like it could really hurt in melee." + force = 50 + weapon_weight = WEAPON_HEAVY + slot_flags = null + +/obj/item/gun/ballistic/automatic/laser/ctf/Initialize() + . = ..() + AddElement(/datum/element/delete_on_drop) + + +/obj/item/ammo_box/magazine/recharge/ctf/rifle + ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/rifle + + +/obj/item/ammo_casing/caseless/laser/ctf/rifle + projectile_type = /obj/projectile/beam/ctf/rifle + + +/obj/projectile/beam/ctf/rifle + damage = 45 + light_color = LIGHT_COLOR_BLUE + impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser + +// LASER SHOTGUN + +/obj/item/gun/ballistic/shotgun/ctf + name = "laser shotgun" + desc = "This looks like it could really hurt in melee." + icon_state = "ctfshotgun" + inhand_icon_state = "shotgun_combat" + worn_icon_state = "gun" + slot_flags = null + mag_type = /obj/item/ammo_box/magazine/recharge/ctf/shotgun + empty_indicator = TRUE + fire_sound = 'sound/weapons/gun/shotgun/shot_alt.ogg' + semi_auto = TRUE + internal_magazine = FALSE + tac_reloads = TRUE + +/obj/item/gun/ballistic/shotgun/ctf/Initialize() + . = ..() + AddElement(/datum/element/delete_on_drop) + +/obj/item/ammo_box/magazine/recharge/ctf/shotgun + ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/shotgun + max_ammo = 6 + + +/obj/item/ammo_casing/caseless/laser/ctf/shotgun + projectile_type = /obj/projectile/beam/ctf/shotgun + pellets = 6 + variance = 25 + + +/obj/projectile/beam/ctf/shotgun + damage = 15 + light_color = LIGHT_COLOR_BLUE + impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser + +// MARKSMAN RIFLE + +/obj/item/gun/ballistic/automatic/laser/ctf/marksman + name = "designated marksman rifle" + icon_state = "ctfmarksman" + inhand_icon_state = "ctfmarksman" + mag_type = /obj/item/ammo_box/magazine/recharge/ctf/marksman + fire_delay = 1 SECONDS + +/obj/item/ammo_box/magazine/recharge/ctf/marksman + ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/marksman + max_ammo = 10 + +/obj/item/ammo_casing/caseless/laser/ctf/marksman + projectile_type = /obj/projectile/beam/ctf/marksman + +/obj/projectile/beam/ctf/marksman + damage = 30 + hitscan = TRUE + tracer_type = /obj/effect/projectile/tracer/laser/blue + muzzle_type = /obj/effect/projectile/muzzle/laser/blue + impact_type = /obj/effect/projectile/impact/laser/blue + +// DESERT EAGLE + +/obj/item/gun/ballistic/automatic/pistol/deagle/ctf + desc = "This looks like it could really hurt in melee." + force = 75 + mag_type = /obj/item/ammo_box/magazine/recharge/ctf/deagle + +/obj/item/gun/ballistic/automatic/pistol/deagle/ctf/Initialize() + . = ..() + AddElement(/datum/element/delete_on_drop) + + +/obj/item/ammo_box/magazine/recharge/ctf/deagle + ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/deagle + max_ammo = 7 + + +/obj/item/ammo_casing/caseless/laser/ctf/deagle + projectile_type = /obj/projectile/beam/ctf/deagle + + +/obj/projectile/beam/ctf/deagle + icon_state = "bullet" + damage = 60 + light_color = COLOR_WHITE + impact_effect_type = /obj/effect/temp_visual/impact_effect + +// INSTAKILL RIFLE + +/obj/item/gun/energy/laser/instakill + name = "instakill rifle" + icon_state = "instagib" + inhand_icon_state = "instagib" + desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit." + w_class = WEIGHT_CLASS_BULKY + ammo_type = list(/obj/item/ammo_casing/energy/instakill) + force = 60 + slot_flags = null + charge_sections = 5 + ammo_x_offset = 2 + shaded_charge = FALSE + +/obj/item/gun/energy/laser/instakill/Initialize() + . = ..() + AddElement(/datum/element/delete_on_drop) + +/obj/item/gun/energy/laser/instakill/emp_act() //implying you could stop the instagib + return + +/obj/item/ammo_casing/energy/instakill + projectile_type = /obj/projectile/beam/instakill + e_cost = 0 + select_name = "DESTROY" + +/obj/projectile/beam/instakill + name = "instagib laser" + icon_state = "purple_laser" + damage = 200 + damage_type = BURN + impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser + light_color = LIGHT_COLOR_PURPLE + +/obj/projectile/beam/instakill/on_hit(atom/target) + . = ..() + if(iscarbon(target)) + var/mob/living/carbon/target_mob = target + target_mob.visible_message(span_danger("[target_mob] explodes into a shower of gibs!")) + target_mob.gib() + +// SHIELDED HARDSUIT + +/obj/item/clothing/suit/space/hardsuit/shielded/ctf + name = "white shielded hardsuit" + desc = "Standard issue hardsuit for playing capture the flag." + icon_state = "ert_medical" + inhand_icon_state = "ert_medical" + hardsuit_type = "ert_medical" + // Adding TRAIT_NODROP is done when the CTF spawner equips people + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) // CTF gear gives no protection outside of the shield + allowed = null + slowdown = 0 + max_charges = 150 + recharge_amount = 30 + lose_multiple_charges = TRUE + +/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf + name = "shielded hardsuit helmet" + desc = "Standard issue hardsuit helmet for playing capture the flag." + icon_state = "hardsuit0-ert_medical" + inhand_icon_state = "hardsuit0-ert_medical" + hardsuit_type = "ert_medical" + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) + +// LIGHT SHIELDED HARDSUIT + +/obj/item/clothing/suit/space/hardsuit/shielded/ctf/light + name = "light white shielded hardsuit" + desc = "Lightweight hardsuit for playing capture the flag." + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/light + max_charges = 30 + slowdown = -0.25 + +/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/light + name = "light shielded hardsuit helmet" + desc = "Lightweight hardsuit helmet for playing capture the flag." + +// RED TEAM GUNS + +// Rifle +/obj/item/gun/ballistic/automatic/laser/ctf/red + mag_type = /obj/item/ammo_box/magazine/recharge/ctf/rifle/red + +/obj/item/ammo_box/magazine/recharge/ctf/rifle/red + ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/rifle/red + +/obj/item/ammo_casing/caseless/laser/ctf/rifle/red + projectile_type = /obj/projectile/beam/ctf/rifle/red + +/obj/projectile/beam/ctf/rifle/red + icon_state = "laser" + light_color = COLOR_SOFT_RED + impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser + + +// Shotgun +/obj/item/gun/ballistic/shotgun/ctf/red + mag_type = /obj/item/ammo_box/magazine/recharge/ctf/shotgun/red + +/obj/item/ammo_box/magazine/recharge/ctf/shotgun/red + ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/shotgun/red + +/obj/item/ammo_casing/caseless/laser/ctf/shotgun/red + projectile_type = /obj/projectile/beam/ctf/shotgun/red + +/obj/projectile/beam/ctf/shotgun/red + icon_state = "laser" + light_color = COLOR_SOFT_RED + impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser + + +// DMR +/obj/item/gun/ballistic/automatic/laser/ctf/marksman/red + mag_type = /obj/item/ammo_box/magazine/recharge/ctf/marksman/red + +/obj/item/ammo_box/magazine/recharge/ctf/marksman/red + ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/marksman/red + +/obj/item/ammo_casing/caseless/laser/ctf/marksman/red + projectile_type = /obj/projectile/beam/ctf/marksman/red + +/obj/projectile/beam/ctf/marksman/red + icon_state = "laser" + tracer_type = /obj/effect/projectile/tracer/laser + muzzle_type = /obj/effect/projectile/muzzle/laser + impact_type = /obj/effect/projectile/impact/laser + + +// Instakill +/obj/item/gun/energy/laser/instakill/red + desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit. This one has a red design." + icon_state = "instagibred" + inhand_icon_state = "instagibred" + ammo_type = list(/obj/item/ammo_casing/energy/instakill/red) + +/obj/item/ammo_casing/energy/instakill/red + projectile_type = /obj/projectile/beam/instakill/red + +/obj/projectile/beam/instakill/red + icon_state = "red_laser" + impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser + light_color = COLOR_SOFT_RED + +// BLUE TEAM GUNS + +// Rifle +/obj/item/gun/ballistic/automatic/laser/ctf/blue + mag_type = /obj/item/ammo_box/magazine/recharge/ctf/rifle/blue + +/obj/item/ammo_box/magazine/recharge/ctf/rifle/blue + ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/rifle/blue + +/obj/item/ammo_casing/caseless/laser/ctf/rifle/blue + projectile_type = /obj/projectile/beam/ctf/rifle/blue + +/obj/projectile/beam/ctf/rifle/blue + icon_state = "bluelaser" + impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser + +// Shotgun +/obj/item/gun/ballistic/shotgun/ctf/blue + mag_type = /obj/item/ammo_box/magazine/recharge/ctf/shotgun/blue + +/obj/item/ammo_box/magazine/recharge/ctf/shotgun/blue + ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/shotgun/blue + +/obj/item/ammo_casing/caseless/laser/ctf/shotgun/blue + projectile_type = /obj/projectile/beam/ctf/shotgun/blue + +/obj/projectile/beam/ctf/shotgun/blue + icon_state = "bluelaser" + impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser + + +// DMR +/obj/item/gun/ballistic/automatic/laser/ctf/marksman/blue + mag_type = /obj/item/ammo_box/magazine/recharge/ctf/marksman/blue + +/obj/item/ammo_box/magazine/recharge/ctf/marksman/blue + ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/marksman/blue + +/obj/item/ammo_casing/caseless/laser/ctf/marksman/blue + projectile_type = /obj/projectile/beam/ctf/marksman/blue + +/obj/projectile/beam/ctf/marksman/blue + + +// Instakill +/obj/item/gun/energy/laser/instakill/blue + desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit. This one has a blue design." + icon_state = "instagibblue" + inhand_icon_state = "instagibblue" + ammo_type = list(/obj/item/ammo_casing/energy/instakill/blue) + +/obj/item/ammo_casing/energy/instakill/blue + projectile_type = /obj/projectile/beam/instakill/blue + +/obj/projectile/beam/instakill/blue + icon_state = "blue_laser" + impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser + light_color = LIGHT_COLOR_BLUE + +// GREEN TEAM GUNS + +// Rifle +/obj/item/gun/ballistic/automatic/laser/ctf/green + mag_type = /obj/item/ammo_box/magazine/recharge/ctf/rifle/green + +/obj/item/ammo_box/magazine/recharge/ctf/rifle/green + ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/rifle/green + +/obj/item/ammo_casing/caseless/laser/ctf/rifle/green + projectile_type = /obj/projectile/beam/ctf/rifle/green + +/obj/projectile/beam/ctf/rifle/green + icon_state = "xray" + light_color = COLOR_VERY_PALE_LIME_GREEN + impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser + + +// Shotgun +/obj/item/gun/ballistic/shotgun/ctf/green + mag_type = /obj/item/ammo_box/magazine/recharge/ctf/shotgun/green + +/obj/item/ammo_box/magazine/recharge/ctf/shotgun/green + ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/shotgun/green + +/obj/item/ammo_casing/caseless/laser/ctf/shotgun/green + projectile_type = /obj/projectile/beam/ctf/shotgun/green + +/obj/projectile/beam/ctf/shotgun/green + icon_state = "xray" + light_color = COLOR_VERY_PALE_LIME_GREEN + impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser + + +// DMR +/obj/item/gun/ballistic/automatic/laser/ctf/marksman/green + mag_type = /obj/item/ammo_box/magazine/recharge/ctf/marksman/green + +/obj/item/ammo_box/magazine/recharge/ctf/marksman/green + ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/marksman/green + +/obj/item/ammo_casing/caseless/laser/ctf/marksman/green + projectile_type = /obj/projectile/beam/ctf/marksman/green + +/obj/projectile/beam/ctf/marksman/green + icon_state = "xray" + tracer_type = /obj/effect/projectile/tracer/xray + muzzle_type = /obj/effect/projectile/muzzle/xray + impact_type = /obj/effect/projectile/impact/xray + + +// Instakill +/obj/item/gun/energy/laser/instakill/green + desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit. This one has a green design." + icon_state = "instagibgreen" + inhand_icon_state = "instagibgreen" + ammo_type = list(/obj/item/ammo_casing/energy/instakill/green) + +/obj/item/ammo_casing/energy/instakill/green + projectile_type = /obj/projectile/beam/instakill/green + +/obj/projectile/beam/instakill/green + icon_state = "green_laser" + impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser + light_color = COLOR_VERY_PALE_LIME_GREEN + +// YELLOW TEAM GUNS + +// Rifle +/obj/item/gun/ballistic/automatic/laser/ctf/yellow + mag_type = /obj/item/ammo_box/magazine/recharge/ctf/rifle/yellow + +/obj/item/ammo_box/magazine/recharge/ctf/rifle/yellow + ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/rifle/yellow + +/obj/item/ammo_casing/caseless/laser/ctf/rifle/yellow + projectile_type = /obj/projectile/beam/ctf/rifle/yellow + +/obj/projectile/beam/ctf/rifle/yellow + icon_state = "gaussstrong" + light_color = COLOR_VERY_SOFT_YELLOW + impact_effect_type = /obj/effect/temp_visual/impact_effect/yellow_laser + + +// Shotgun +/obj/item/gun/ballistic/shotgun/ctf/yellow + mag_type = /obj/item/ammo_box/magazine/recharge/ctf/shotgun/yellow + +/obj/item/ammo_box/magazine/recharge/ctf/shotgun/yellow + ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/shotgun/yellow + +/obj/item/ammo_casing/caseless/laser/ctf/shotgun/yellow + projectile_type = /obj/projectile/beam/ctf/shotgun/yellow + +/obj/projectile/beam/ctf/shotgun/yellow + icon_state = "gaussstrong" + light_color = COLOR_VERY_SOFT_YELLOW + impact_effect_type = /obj/effect/temp_visual/impact_effect/yellow_laser + + +// DMR +/obj/item/gun/ballistic/automatic/laser/ctf/marksman/yellow + mag_type = /obj/item/ammo_box/magazine/recharge/ctf/marksman/yellow + +/obj/item/ammo_box/magazine/recharge/ctf/marksman/yellow + ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/marksman/yellow + +/obj/item/ammo_casing/caseless/laser/ctf/marksman/yellow + projectile_type = /obj/projectile/beam/ctf/marksman/yellow + +/obj/projectile/beam/ctf/marksman/yellow + icon_state = "gaussstrong" + tracer_type = /obj/effect/projectile/tracer/solar + muzzle_type = /obj/effect/projectile/muzzle/solar + impact_type = /obj/effect/projectile/impact/solar + + +// Instakill +/obj/item/gun/energy/laser/instakill/yellow + desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit. This one has a yellow design." + icon_state = "instagibyellow" + inhand_icon_state = "instagibyellow" + ammo_type = list(/obj/item/ammo_casing/energy/instakill/yellow) + +/obj/item/ammo_casing/energy/instakill/yellow + projectile_type = /obj/projectile/beam/instakill/yellow + +/obj/projectile/beam/instakill/yellow + icon_state = "yellow_laser" + impact_effect_type = /obj/effect/temp_visual/impact_effect/yellow_laser + light_color = COLOR_VERY_SOFT_YELLOW + +// RED TEAM SUITS + +// Regular +/obj/item/clothing/suit/space/hardsuit/shielded/ctf/red + name = "red shielded hardsuit" + icon_state = "ert_security" + inhand_icon_state = "ert_security" + hardsuit_type = "ert_security" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/red + shield_icon = "shield-red" + +/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/red + icon_state = "hardsuit0-ert_security" + inhand_icon_state = "hardsuit0-ert_security" + hardsuit_type = "ert_security" + +// Light +/obj/item/clothing/suit/space/hardsuit/shielded/ctf/light/red + name = "light red shielded hardsuit" + icon_state = "ert_security" + inhand_icon_state = "ert_security" + hardsuit_type = "ert_security" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/light/red + shield_icon = "shield-red" + +/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/light/red + icon_state = "hardsuit0-ert_security" + inhand_icon_state = "hardsuit0-ert_security" + hardsuit_type = "ert_security" + +// BLUE TEAM SUITS + +// Regular +/obj/item/clothing/suit/space/hardsuit/shielded/ctf/blue + name = "blue shielded hardsuit" + icon_state = "ert_command" + inhand_icon_state = "ert_command" + hardsuit_type = "ert_commander" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/blue + shield_icon = "shield-old" + +/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/blue + icon_state = "hardsuit0-ert_commander" + inhand_icon_state = "hardsuit0-ert_commander" + hardsuit_type = "ert_commander" + +// Light +/obj/item/clothing/suit/space/hardsuit/shielded/ctf/light/blue + name = "light blue shielded hardsuit" + icon_state = "ert_command" + inhand_icon_state = "ert_command" + hardsuit_type = "ert_commander" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/light/blue + shield_icon = "shield-old" + +/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/light/blue + icon_state = "hardsuit0-ert_commander" + inhand_icon_state = "hardsuit0-ert_commander" + hardsuit_type = "ert_commander" + +// GREEN TEAM SUITS + +// Regular +/obj/item/clothing/suit/space/hardsuit/shielded/ctf/green + name = "green shielded hardsuit" + icon_state = "ert_green" + inhand_icon_state = "ert_green" + hardsuit_type = "ert_green" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/green + shield_icon = "shield-green" + +/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/green + icon_state = "hardsuit0-ert_green" + inhand_icon_state = "hardsuit0-ert_green" + hardsuit_type = "ert_green" + +// Light +/obj/item/clothing/suit/space/hardsuit/shielded/ctf/light/green + name = "light green shielded hardsuit" + icon_state = "ert_green" + inhand_icon_state = "ert_green" + hardsuit_type = "ert_green" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/light/green + shield_icon = "shield-green" + +/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/light/green + icon_state = "hardsuit0-ert_green" + inhand_icon_state = "hardsuit0-ert_green" + hardsuit_type = "ert_green" + +// YELLOW TEAM SUITS + +// Regular +/obj/item/clothing/suit/space/hardsuit/shielded/ctf/yellow + name = "yellow shielded hardsuit" + icon_state = "ert_engineer" + inhand_icon_state = "ert_engineer" + hardsuit_type = "ert_engineer" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/yellow + shield_icon = "shield-yellow" + +// Light +/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/yellow + icon_state = "hardsuit0-ert_engineer" + inhand_icon_state = "hardsuit0-ert_engineer" + hardsuit_type = "ert_engineer" + +/obj/item/clothing/suit/space/hardsuit/shielded/ctf/light/yellow + name = "light yellow shielded hardsuit" + icon_state = "ert_engineer" + inhand_icon_state = "ert_engineer" + hardsuit_type = "ert_engineer" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/light/yellow + shield_icon = "shield-yellow" + +/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/light/yellow + icon_state = "hardsuit0-ert_engineer" + inhand_icon_state = "hardsuit0-ert_engineer" + hardsuit_type = "ert_engineer" diff --git a/code/modules/capture_the_flag/capture_the_flag.dm b/code/modules/capture_the_flag/ctf_game.dm similarity index 68% rename from code/modules/capture_the_flag/capture_the_flag.dm rename to code/modules/capture_the_flag/ctf_game.dm index 9bd0ad23eba..efe67ff08dd 100644 --- a/code/modules/capture_the_flag/capture_the_flag.dm +++ b/code/modules/capture_the_flag/ctf_game.dm @@ -43,10 +43,6 @@ reset.flag = src RegisterSignal(src, COMSIG_PARENT_PREQDELETED, .proc/reset_flag) //just in case CTF has some map hazards (read: chasms). -/obj/item/ctf/ComponentInitialize() - . = ..() - AddComponent(/datum/component/two_handed, require_twohands = TRUE) - /obj/item/ctf/process() if(is_ctf_target(loc)) //pickup code calls temporary drops to test things out, we need to make sure the flag doesn't reset from return PROCESS_KILL @@ -223,7 +219,7 @@ var/list/recently_dead_ckeys = list() var/ctf_enabled = FALSE ///assoc list for classes. If there's only one, it'll just equip. Otherwise, it lets you pick which outfit! - var/list/ctf_gear = list("white" = /datum/outfit/ctf) + var/list/ctf_gear = list("Rifleman" = /datum/outfit/ctf, "Assaulter" = /datum/outfit/ctf/assault, "Marksman" = /datum/outfit/ctf/marksman) var/instagib_gear = /datum/outfit/ctf/instagib var/ammo_type = /obj/effect/powerup/ammo/ctf // Fast paced gameplay, no real time for burn infections. @@ -246,7 +242,7 @@ continue // Anyone in crit, automatically reap var/mob/living/living_participant = i - if(HAS_TRAIT(living_participant, TRAIT_CRITICAL_CONDITION) || living_participant.stat == DEAD) + if(HAS_TRAIT(living_participant, TRAIT_CRITICAL_CONDITION) || living_participant.stat == DEAD || !living_participant.client) // If they're critted, dead or no longer in their body, dust them ctf_dust_old(living_participant) else // The changes that you've been hit with no shield but not @@ -259,7 +255,7 @@ icon_state = "syndbeacon" team = RED_TEAM team_span = "redteamradio" - ctf_gear = list("red" = /datum/outfit/ctf/red) + ctf_gear = list("Rifleman" = /datum/outfit/ctf/red, "Assaulter" = /datum/outfit/ctf/assault/red, "Marksman" = /datum/outfit/ctf/marksman/red) instagib_gear = /datum/outfit/ctf/red/instagib /obj/machinery/capture_the_flag/blue @@ -267,7 +263,7 @@ icon_state = "bluebeacon" team = BLUE_TEAM team_span = "blueteamradio" - ctf_gear = list("blue" = /datum/outfit/ctf/blue) + ctf_gear = list("Rifleman" = /datum/outfit/ctf/blue, "Assaulter" = /datum/outfit/ctf/assault/blue, "Marksman" = /datum/outfit/ctf/marksman/blue) instagib_gear = /datum/outfit/ctf/blue/instagib /obj/machinery/capture_the_flag/green @@ -275,7 +271,7 @@ icon_state = "greenbeacon" team = GREEN_TEAM team_span = "greenteamradio" - ctf_gear = list("green" = /datum/outfit/ctf/green) + ctf_gear = list("Rifleman" = /datum/outfit/ctf/green, "Assaulter" = /datum/outfit/ctf/assault/green, "Marksman" = /datum/outfit/ctf/marksman/green) instagib_gear = /datum/outfit/ctf/green/instagib /obj/machinery/capture_the_flag/yellow @@ -283,7 +279,7 @@ icon_state = "yellowbeacon" team = YELLOW_TEAM team_span = "yellowteamradio" - ctf_gear = list("yellow" = /datum/outfit/ctf/yellow) + ctf_gear = list("Rifleman" = /datum/outfit/ctf/yellow, "Assaulter" = /datum/outfit/ctf/assault/yellow, "Marksman" = /datum/outfit/ctf/marksman/yellow) instagib_gear = /datum/outfit/ctf/yellow/instagib //ATTACK GHOST IGNORING PARENT RETURN VALUE @@ -335,11 +331,13 @@ if(CTF.team_members.len < src.team_members.len) to_chat(user, span_warning("[src.team] has more team members than [CTF.team]! Try joining [CTF.team] team to even things up.")) return + var/client/new_team_member = user.client - if(user.mind && user.mind.current) - ctf_dust_old(user.mind.current) + team_members |= new_team_member.ckey + to_chat(user, "You are now a member of [src.team]. Get the enemy flag and bring it back to your team's controller!") spawn_team_member(new_team_member) + //does not add to recently dead, because it dusts and that triggers ctf_qdelled_player /obj/machinery/capture_the_flag/proc/ctf_dust_old(mob/living/body) if(isliving(body) && (team in body.faction)) @@ -360,21 +358,28 @@ /obj/machinery/capture_the_flag/proc/spawn_team_member(client/new_team_member) var/datum/outfit/chosen_class + if(ctf_gear.len == 1) //no choices to make for(var/key in ctf_gear) chosen_class = ctf_gear[key] - else if(ctf_gear.len > 3) //a lot of choices, so much that we can't use a basic alert - var/result = input(new_team_member, "Select a class.", "CTF") as null|anything in sortList(ctf_gear) - if(!result || !(GLOB.ghost_role_flags & GHOSTROLE_MINIGAME) || (new_team_member.ckey in recently_dead_ckeys) || !isobserver(new_team_member.mob)) - return //picked nothing, admin disabled it, cheating to respawn faster, cheating to respawn... while in game? - chosen_class = ctf_gear[result] - else //2-3 choices - var/list/names_only = assoc_list_strip_value(ctf_gear) - names_only.len += 1 //create a new null entry so if it's a 2-sized list, names_only[3] is null instead of out of bounds - var/result = tgui_alert(new_team_member, "Select a class.", "CTF", list(names_only[1], names_only[2], names_only[3])) - if(!result || !(GLOB.ghost_role_flags & GHOSTROLE_MINIGAME) || (new_team_member.ckey in recently_dead_ckeys) || !isobserver(new_team_member.mob)) - return //picked nothing, admin disabled it, cheating to respawn faster, cheating to respawn... while in game? - chosen_class = ctf_gear[result] + + else //there's a choice to make, present a radial menu + var/list/display_classes = list() + + for(var/key in ctf_gear) + var/datum/outfit/ctf/class = ctf_gear[key] + var/datum/radial_menu_choice/option = new + option.image = image(icon = initial(class.icon), icon_state = initial(class.icon_state)) + option.info = "[initial(class.class_description)]" + display_classes[key] = option + + sortList(display_classes) + var/choice = show_radial_menu(new_team_member.mob, src, display_classes, radius = 38) + if(!choice || !(GLOB.ghost_role_flags & GHOSTROLE_MINIGAME) || (new_team_member.ckey in recently_dead_ckeys) || !isobserver(new_team_member.mob) || src.ctf_enabled == FALSE || !(new_team_member.ckey in src.team_members)) + return //picked nothing, admin disabled it, cheating to respawn faster, cheating to respawn... while in game?, + //there isn't a game going on any more, you are no longer a member of this team (perhaps a new match already started?) + chosen_class = ctf_gear[choice] + var/mob/living/carbon/human/M = new /mob/living/carbon/human(get_turf(src)) new_team_member.prefs.copy_to(M) M.set_species(/datum/species/synth) @@ -385,7 +390,6 @@ for(var/trait in player_traits) ADD_TRAIT(M, trait, CAPTURE_THE_FLAG_TRAIT) spawned_mobs[M] = chosen_class - team_members |= new_team_member.ckey return M //used in medisim.dm /obj/machinery/capture_the_flag/Topic(href, href_list) @@ -446,7 +450,7 @@ dead_barricades.Cut() - notify_ghosts("[name] has been activated!", enter_link="(Click to join the [team] team!) or click on the controller directly!", source = src, action=NOTIFY_ATTACK, header = "CTF has been activated") + notify_ghosts("[name] has been activated!", source = src, action=NOTIFY_ORBIT, header = "CTF has been activated") if(!arena_reset) reset_the_arena() @@ -497,256 +501,6 @@ CTF.ctf_gear = initial(ctf_gear) CTF.respawn_cooldown = DEFAULT_RESPAWN -/obj/item/gun/ballistic/automatic/pistol/deagle/ctf - desc = "This looks like it could really hurt in melee." - force = 75 - mag_type = /obj/item/ammo_box/magazine/m50/ctf - -/obj/item/gun/ballistic/automatic/pistol/deagle/ctf/dropped() - . = ..() - addtimer(CALLBACK(src, .proc/floor_vanish), 1) - -/obj/item/gun/ballistic/automatic/pistol/deagle/ctf/proc/floor_vanish() - if(isturf(loc)) - qdel(src) - -/obj/item/ammo_box/magazine/m50/ctf - ammo_type = /obj/item/ammo_casing/a50/ctf - -/obj/item/ammo_casing/a50/ctf - projectile_type = /obj/projectile/bullet/ctf - -/obj/projectile/bullet/ctf - damage = 0 - -/obj/projectile/bullet/ctf/prehit_pierce(atom/target) - if(is_ctf_target(target)) - damage = 60 - return PROJECTILE_PIERCE_NONE /// hey uhh don't hit anyone behind them - . = ..() - -/obj/item/gun/ballistic/automatic/laser/ctf - mag_type = /obj/item/ammo_box/magazine/recharge/ctf - desc = "This looks like it could really hurt in melee." - force = 50 - -/obj/item/gun/ballistic/automatic/laser/ctf/dropped() - . = ..() - addtimer(CALLBACK(src, .proc/floor_vanish), 1) - -/obj/item/gun/ballistic/automatic/laser/ctf/proc/floor_vanish() - if(isturf(loc)) - qdel(src) - -/obj/item/ammo_box/magazine/recharge/ctf - ammo_type = /obj/item/ammo_casing/caseless/laser/ctf - -/obj/item/ammo_box/magazine/recharge/ctf/dropped() - . = ..() - addtimer(CALLBACK(src, .proc/floor_vanish), 1) - -/obj/item/ammo_box/magazine/recharge/ctf/proc/floor_vanish() - if(isturf(loc)) - qdel(src) - -/obj/item/ammo_casing/caseless/laser/ctf - projectile_type = /obj/projectile/beam/ctf - -/obj/projectile/beam/ctf - damage = 0 - icon_state = "omnilaser" - -/obj/projectile/beam/ctf/prehit_pierce(atom/target) - if(is_ctf_target(target)) - damage = 150 - return PROJECTILE_PIERCE_NONE /// hey uhhh don't hit anyone behind them - . = ..() - -/proc/is_ctf_target(atom/target) - . = FALSE - if(istype(target, /obj/structure/barricade/security/ctf)) - . = TRUE - if(ishuman(target)) - var/mob/living/carbon/human/H = target - for(var/obj/machinery/capture_the_flag/CTF in GLOB.machines) - if(H in CTF.spawned_mobs) - . = TRUE - break - -// RED TEAM GUNS - -/obj/item/gun/ballistic/automatic/laser/ctf/red - mag_type = /obj/item/ammo_box/magazine/recharge/ctf/red - -/obj/item/ammo_box/magazine/recharge/ctf/red - ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/red - -/obj/item/ammo_casing/caseless/laser/ctf/red - projectile_type = /obj/projectile/beam/ctf/red - -/obj/projectile/beam/ctf/red - icon_state = "laser" - impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser - -// BLUE TEAM GUNS - -/obj/item/gun/ballistic/automatic/laser/ctf/blue - mag_type = /obj/item/ammo_box/magazine/recharge/ctf/blue - -/obj/item/ammo_box/magazine/recharge/ctf/blue - ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/blue - -/obj/item/ammo_casing/caseless/laser/ctf/blue - projectile_type = /obj/projectile/beam/ctf/blue - -/obj/projectile/beam/ctf/blue - icon_state = "bluelaser" - impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser - -// GREEN TEAM GUNS - -/obj/item/gun/ballistic/automatic/laser/ctf/green - mag_type = /obj/item/ammo_box/magazine/recharge/ctf/green - -/obj/item/ammo_box/magazine/recharge/ctf/green - ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/green - -/obj/item/ammo_casing/caseless/laser/ctf/green - projectile_type = /obj/projectile/beam/ctf/green - -/obj/projectile/beam/ctf/green - icon_state = "xray" - impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser - -// YELLOW TEAM GUNS - -/obj/item/gun/ballistic/automatic/laser/ctf/yellow - mag_type = /obj/item/ammo_box/magazine/recharge/ctf/yellow - -/obj/item/ammo_box/magazine/recharge/ctf/yellow - ammo_type = /obj/item/ammo_casing/caseless/laser/ctf/yellow - -/obj/item/ammo_casing/caseless/laser/ctf/yellow - projectile_type = /obj/projectile/beam/ctf/yellow - -/obj/projectile/beam/ctf/yellow - icon_state = "gaussstrong" - impact_effect_type = /obj/effect/temp_visual/impact_effect/yellow_laser - -/datum/outfit/ctf - name = "CTF" - ears = /obj/item/radio/headset - uniform = /obj/item/clothing/under/syndicate - suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf - toggle_helmet = FALSE // see the whites of their eyes - shoes = /obj/item/clothing/shoes/combat - gloves = /obj/item/clothing/gloves/combat - id = /obj/item/card/id/away - belt = /obj/item/gun/ballistic/automatic/pistol/deagle/ctf - l_pocket = /obj/item/ammo_box/magazine/recharge/ctf - r_pocket = /obj/item/ammo_box/magazine/recharge/ctf - r_hand = /obj/item/gun/ballistic/automatic/laser/ctf - -/datum/outfit/ctf/post_equip(mob/living/carbon/human/H, visualsOnly=FALSE) - if(visualsOnly) - return - var/list/no_drops = list() - var/obj/item/card/id/W = H.wear_id - no_drops += W - W.registered_name = H.real_name - W.update_label() - W.update_icon() - - no_drops += H.get_item_by_slot(ITEM_SLOT_OCLOTHING) - no_drops += H.get_item_by_slot(ITEM_SLOT_GLOVES) - no_drops += H.get_item_by_slot(ITEM_SLOT_FEET) - no_drops += H.get_item_by_slot(ITEM_SLOT_ICLOTHING) - no_drops += H.get_item_by_slot(ITEM_SLOT_EARS) - for(var/i in no_drops) - var/obj/item/I = i - ADD_TRAIT(I, TRAIT_NODROP, CAPTURE_THE_FLAG_TRAIT) - -/datum/outfit/ctf/instagib - r_hand = /obj/item/gun/energy/laser/instakill - shoes = /obj/item/clothing/shoes/jackboots/fast - -/datum/outfit/ctf/red - suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/red - r_hand = /obj/item/gun/ballistic/automatic/laser/ctf/red - l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/red - r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/red - id = /obj/item/card/id/red //it's red - -/datum/outfit/ctf/red/instagib - r_hand = /obj/item/gun/energy/laser/instakill/red - shoes = /obj/item/clothing/shoes/jackboots/fast - -/datum/outfit/ctf/blue - suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/blue - r_hand = /obj/item/gun/ballistic/automatic/laser/ctf/blue - l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/blue - r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/blue - id = /obj/item/card/id/blue //it's blue - -/datum/outfit/ctf/blue/instagib - r_hand = /obj/item/gun/energy/laser/instakill/blue - shoes = /obj/item/clothing/shoes/jackboots/fast - -/datum/outfit/ctf/green - suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/green - r_hand = /obj/item/gun/ballistic/automatic/laser/ctf/green - l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/green - r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/green - id = /obj/item/card/id/green //it's green - -/datum/outfit/ctf/green/instagib - r_hand = /obj/item/gun/energy/laser/instakill/green - shoes = /obj/item/clothing/shoes/jackboots/fast - -/datum/outfit/ctf/yellow - suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/yellow - r_hand = /obj/item/gun/ballistic/automatic/laser/ctf/yellow - l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/yellow - r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/yellow - id = /obj/item/card/id/yellow //it's yellow - -/datum/outfit/ctf/yellow/instagib - r_hand = /obj/item/gun/energy/laser/instakill/yellow - shoes = /obj/item/clothing/shoes/jackboots/fast - -/datum/outfit/ctf/red/post_equip(mob/living/carbon/human/H) - ..() - var/obj/item/radio/R = H.ears - R.set_frequency(FREQ_CTF_RED) - R.freqlock = TRUE - R.independent = TRUE - H.dna.species.stunmod = 0 - -/datum/outfit/ctf/blue/post_equip(mob/living/carbon/human/H) - ..() - var/obj/item/radio/R = H.ears - R.set_frequency(FREQ_CTF_BLUE) - R.freqlock = TRUE - R.independent = TRUE - H.dna.species.stunmod = 0 - -/datum/outfit/ctf/green/post_equip(mob/living/carbon/human/H) - ..() - var/obj/item/radio/R = H.ears - R.set_frequency(FREQ_CTF_GREEN) - R.freqlock = TRUE - R.independent = TRUE - H.dna.species.stunmod = 0 - -/datum/outfit/ctf/yellow/post_equip(mob/living/carbon/human/H) - ..() - var/obj/item/radio/R = H.ears - R.set_frequency(FREQ_CTF_YELLOW) - R.freqlock = TRUE - R.independent = TRUE - H.dna.species.stunmod = 0 - - /obj/structure/trap/ctf name = "Spawn protection" desc = "Stay outta the enemy spawn!" @@ -869,6 +623,17 @@ to_chat(M, span_userdanger("[user.real_name] has captured \the [src], claiming it for [CTF.team]! Go take it back!")) break +/proc/is_ctf_target(atom/target) + . = FALSE + if(istype(target, /obj/structure/barricade/security/ctf)) + . = TRUE + if(ishuman(target)) + var/mob/living/carbon/human/H = target + for(var/obj/machinery/capture_the_flag/CTF in GLOB.machines) + if(H in CTF.spawned_mobs) + . = TRUE + break + #undef WHITE_TEAM #undef RED_TEAM #undef BLUE_TEAM diff --git a/code/modules/capture_the_flag/map_loading.dm b/code/modules/capture_the_flag/ctf_map_loading.dm similarity index 100% rename from code/modules/capture_the_flag/map_loading.dm rename to code/modules/capture_the_flag/ctf_map_loading.dm diff --git a/code/modules/capture_the_flag/medieval_sim/medisim_classes.dm b/code/modules/capture_the_flag/medieval_sim/medisim_classes.dm new file mode 100644 index 00000000000..3361b2e0626 --- /dev/null +++ b/code/modules/capture_the_flag/medieval_sim/medisim_classes.dm @@ -0,0 +1,50 @@ +/datum/outfit/ctf/medisim + name = "Redfield Castle Knight" + icon_state = "medisim_knight" + + uniform = /obj/item/clothing/under/color/red + shoes = /obj/item/clothing/shoes/plate/red + suit = /obj/item/clothing/suit/armor/riot/knight/red + gloves = /obj/item/clothing/gloves/plate/red + head = /obj/item/clothing/head/helmet/knight/red + r_hand = /obj/item/claymore + + ears = null + id = null + belt = null + l_pocket = null + r_pocket = null + + has_radio = FALSE + has_card = FALSE + + nodrop_slots = list(ITEM_SLOT_OCLOTHING, ITEM_SLOT_GLOVES, ITEM_SLOT_FEET, ITEM_SLOT_ICLOTHING, ITEM_SLOT_EARS, ITEM_SLOT_BELT, ITEM_SLOT_HEAD) + + class_description = "Melee class. Armed with a claymore." + +/datum/outfit/ctf/medisim/archer + name = "Redfield Castle Archer" + icon_state = "medisim_archer" + + belt = /obj/item/storage/bag/quiver + suit = /obj/item/clothing/suit/armor/vest/cuirass + r_hand = /obj/item/gun/ballistic/bow + + class_description = "Ranged class. Armed with a bow and arrows." + +/datum/outfit/ctf/medisim/blue + name = "Bluesworth Hold Knight" + + uniform = /obj/item/clothing/under/color/blue + shoes = /obj/item/clothing/shoes/plate/blue + suit = /obj/item/clothing/suit/armor/riot/knight/blue + gloves = /obj/item/clothing/gloves/plate/blue + head = /obj/item/clothing/head/helmet/knight/blue + +/datum/outfit/ctf/medisim/archer/blue + name = "Bluesworth Hold Archer" + + uniform = /obj/item/clothing/under/color/blue + shoes = /obj/item/clothing/shoes/plate/blue + gloves = /obj/item/clothing/gloves/plate/blue + head = /obj/item/clothing/head/helmet/knight/blue diff --git a/code/modules/capture_the_flag/medieval_sim/medisim_game.dm b/code/modules/capture_the_flag/medieval_sim/medisim_game.dm new file mode 100644 index 00000000000..8b9215dd8b6 --- /dev/null +++ b/code/modules/capture_the_flag/medieval_sim/medisim_game.dm @@ -0,0 +1,74 @@ +///These are for the medisim shuttle + +#define REDFIELD_TEAM "Red" +#define BLUESWORTH_TEAM "Blue" + +/obj/machinery/capture_the_flag/medisim + game_id = "medieval" + game_area = /area/shuttle/escape/simulation + ammo_type = null //no guns, no need + victory_rejoin_text = "Teams have been cleared. The next game is starting automatically. Rejoin a team if you wish!" + player_traits = list() + +/obj/machinery/capture_the_flag/medisim/Initialize(mapload) + . = ..() + start_ctf() //both machines initialize, so both will call start_ctf instead of toggle_id_ctf calling it for both, twice. + +/obj/machinery/capture_the_flag/medisim/victory() + . = ..() + toggle_id_ctf(null, game_id, automated = TRUE)//only one machine runs the victory proc, start_ctf proc would break the other machine + +/obj/machinery/capture_the_flag/medisim/spawn_team_member(client/new_team_member) + . = ..() + if(!.) + return + var/mob/living/carbon/human/human_knight = . + randomize_human(human_knight) + human_knight.dna.update_dna_identity() + human_knight.dna.add_mutation(MEDIEVAL, MUT_OTHER) + var/oldname = human_knight.name + var/title = "error" + switch (human_knight.gender) + if (MALE) + title = pick(list("Sir", "Lord")) + if (FEMALE) + title = pick(list("Dame", "Lady")) + else + title = "Noble" + human_knight.real_name = "[title] [oldname]" + human_knight.name = human_knight.real_name + +/obj/machinery/capture_the_flag/medisim/red + name = "\improper Redfield Data Realizer" + icon_state = "syndbeacon" + team = REDFIELD_TEAM + team_span = "redteamradio" + ctf_gear = list("knight" = /datum/outfit/ctf/medisim, "archer" = /datum/outfit/ctf/medisim/archer) + +/obj/machinery/capture_the_flag/medisim/blue + name = "\improper Bluesworth Data Realizer" + icon_state = "bluebeacon" + team = BLUESWORTH_TEAM + team_span = "blueteamradio" + ctf_gear = list("knight" = /datum/outfit/ctf/medisim/blue, "archer" = /datum/outfit/ctf/medisim/archer/blue) + +/obj/item/ctf/red/medisim + name = "\improper Redfield Castle Fair Maiden" + desc = "Protect your maiden, and capture theirs!" + icon = 'icons/obj/plushes.dmi' + icon_state = "plushie_nuke" + force = 0 + game_area = /area/shuttle/escape + movement_type = FLOATING //there are chasms, and resetting when they fall in is really lame so lets minimize that + +/obj/item/ctf/blue/medisim + name = "\improper Bluesworth Hold Fair Maiden" + desc = "Protect your maiden, and capture theirs!" + icon = 'icons/obj/plushes.dmi' + icon_state = "plushie_slime" + force = 0 + game_area = /area/shuttle/escape + movement_type = FLOATING //there are chasms, and resetting when they fall in is really lame so lets minimize that + +#undef REDFIELD_TEAM +#undef BLUESWORTH_TEAM diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index 022812aaefc..1357f6fcf7d 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -784,6 +784,10 @@ var/recharge_delay = 20 SECONDS /// How quickly the shield recharges each charge once it starts charging var/recharge_rate = 1 SECONDS + /// How many charges are recovered on each recharge + var/recharge_amount = 1 + /// Should the shield lose charges equal to the damage dealt by a hit? + var/lose_multiple_charges = FALSE /// The icon for the shield var/shield_icon = "shield-old" @@ -791,92 +795,12 @@ . = ..() if(!allowed) allowed = GLOB.advanced_hardsuit_allowed - AddComponent(/datum/component/shielded, max_charges = max_charges, recharge_start_delay = recharge_delay, charge_increment_delay = recharge_rate, shield_icon = shield_icon) + AddComponent(/datum/component/shielded, max_charges = max_charges, recharge_start_delay = recharge_delay, charge_increment_delay = recharge_rate, charge_recovery = recharge_amount, lose_multiple_charges = lose_multiple_charges, shield_icon = shield_icon) /obj/item/clothing/head/helmet/space/hardsuit/shielded resistance_flags = FIRE_PROOF | ACID_PROOF -///////////////Capture the Flag//////////////////// - -/obj/item/clothing/suit/space/hardsuit/shielded/ctf - name = "white shielded hardsuit" - desc = "Standard issue hardsuit for playing capture the flag." - icon_state = "ert_medical" - inhand_icon_state = "ert_medical" - hardsuit_type = "ert_medical" - // Adding TRAIT_NODROP is done when the CTF spawner equips people - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf - armor = list(MELEE = 0, BULLET = 30, LASER = 30, ENERGY = 40, BOMB = 50, BIO = 100, RAD = 100, FIRE = 95, ACID = 95) - slowdown = 0 - max_charges = 5 - -/obj/item/clothing/suit/space/hardsuit/shielded/ctf/red - name = "red shielded hardsuit" - icon_state = "ert_security" - inhand_icon_state = "ert_security" - hardsuit_type = "ert_security" - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/red - shield_icon = "shield-red" - -/obj/item/clothing/suit/space/hardsuit/shielded/ctf/blue - name = "blue shielded hardsuit" - desc = "Standard issue hardsuit for playing capture the flag." - icon_state = "ert_command" - inhand_icon_state = "ert_command" - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/blue - -/obj/item/clothing/suit/space/hardsuit/shielded/ctf/green - name = "green shielded hardsuit" - icon_state = "ert_green" - inhand_icon_state = "ert_green" - hardsuit_type = "ert_green" - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/green - shield_icon = "shield-green" - -/obj/item/clothing/suit/space/hardsuit/shielded/ctf/yellow - name = "yellow shielded hardsuit" - icon_state = "ert_engineer" - inhand_icon_state = "ert_engineer" - hardsuit_type = "ert_engineer" - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/yellow - shield_icon = "shield-yellow" - - -/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf - name = "shielded hardsuit helmet" - desc = "Standard issue hardsuit helmet for playing capture the flag." - icon_state = "hardsuit0-ert_medical" - inhand_icon_state = "hardsuit0-ert_medical" - hardsuit_type = "ert_medical" - armor = list(MELEE = 0, BULLET = 30, LASER = 30, ENERGY = 40, BOMB = 50, BIO = 100, RAD = 100, FIRE = 95, ACID = 95) - - -/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/red - icon_state = "hardsuit0-ert_security" - inhand_icon_state = "hardsuit0-ert_security" - hardsuit_type = "ert_security" - -/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/blue - name = "shielded hardsuit helmet" - desc = "Standard issue hardsuit helmet for playing capture the flag." - icon_state = "hardsuit0-ert_commander" - inhand_icon_state = "hardsuit0-ert_commander" - hardsuit_type = "ert_commander" - -/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/green - icon_state = "hardsuit0-ert_green" - inhand_icon_state = "hardsuit0-ert_green" - hardsuit_type = "ert_green" - -/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/yellow - icon_state = "hardsuit0-ert_engineer" - inhand_icon_state = "hardsuit0-ert_engineer" - hardsuit_type = "ert_engineer" - - - //////Syndicate Version - /obj/item/clothing/suit/space/hardsuit/shielded/syndi name = "blood-red hardsuit" desc = "An advanced hardsuit with built in energy shielding." diff --git a/code/modules/projectiles/ammunition/energy/special.dm b/code/modules/projectiles/ammunition/energy/special.dm index 908ff5cbc75..6f3ddb5fd86 100644 --- a/code/modules/projectiles/ammunition/energy/special.dm +++ b/code/modules/projectiles/ammunition/energy/special.dm @@ -58,23 +58,6 @@ select_name = "snare" harmful = FALSE -/obj/item/ammo_casing/energy/instakill - projectile_type = /obj/projectile/beam/instakill - e_cost = 0 - select_name = "DESTROY" - -/obj/item/ammo_casing/energy/instakill/blue - projectile_type = /obj/projectile/beam/instakill/blue - -/obj/item/ammo_casing/energy/instakill/red - projectile_type = /obj/projectile/beam/instakill/red - -/obj/item/ammo_casing/energy/instakill/green - projectile_type = /obj/projectile/beam/instakill/green - -/obj/item/ammo_casing/energy/instakill/yellow - projectile_type = /obj/projectile/beam/instakill/yellow - /obj/item/ammo_casing/energy/tesla_cannon fire_sound = 'sound/magic/lightningshock.ogg' e_cost = 30 diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index 163e39a0cbc..3ca48f81890 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -218,6 +218,7 @@ if(casing_ejector || !from_firing) AC.forceMove(drop_location()) //Eject casing onto ground. AC.bounce_away(TRUE) + SEND_SIGNAL(AC, COMSIG_CASING_EJECTED) chambered = null else if(empty_chamber) chambered = null diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm index 51a0f40ca8c..be8700dda0e 100644 --- a/code/modules/projectiles/guns/ballistic/automatic.dm +++ b/code/modules/projectiles/guns/ballistic/automatic.dm @@ -395,6 +395,7 @@ w_class = WEIGHT_CLASS_BULKY inhand_icon_state = "arg" mag_type = /obj/item/ammo_box/magazine/recharge + empty_indicator = TRUE fire_delay = 2 can_suppress = FALSE burst_size = 0 diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 54a411e7a5d..1a0a3efc2f3 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -323,45 +323,6 @@ desc = "A weapon that can only be used to its full potential by the truly robust." pin = /obj/item/firing_pin -/obj/item/gun/energy/laser/instakill - name = "instakill rifle" - icon_state = "instagib" - inhand_icon_state = "instagib" - desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit." - w_class = WEIGHT_CLASS_BULKY - ammo_type = list(/obj/item/ammo_casing/energy/instakill) - force = 60 - charge_sections = 5 - ammo_x_offset = 2 - shaded_charge = FALSE - -/obj/item/gun/energy/laser/instakill/red - desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit. This one has a red design." - icon_state = "instagibred" - inhand_icon_state = "instagibred" - ammo_type = list(/obj/item/ammo_casing/energy/instakill/red) - -/obj/item/gun/energy/laser/instakill/blue - desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit. This one has a blue design." - icon_state = "instagibblue" - inhand_icon_state = "instagibblue" - ammo_type = list(/obj/item/ammo_casing/energy/instakill/blue) - -/obj/item/gun/energy/laser/instakill/green - desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit. This one has a green design." - icon_state = "instagibgreen" - inhand_icon_state = "instagibgreen" - ammo_type = list(/obj/item/ammo_casing/energy/instakill/green) - -/obj/item/gun/energy/laser/instakill/yellow - desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit. This one has a yellow design." - icon_state = "instagibyellow" - inhand_icon_state = "instagibyellow" - ammo_type = list(/obj/item/ammo_casing/energy/instakill/yellow) - -/obj/item/gun/energy/laser/instakill/emp_act() //implying you could stop the instagib - return - /obj/item/gun/energy/gravity_gun name = "one-point gravitational manipulator" desc = "An experimental, multi-mode device that fires bolts of Zero-Point Energy, causing local distortions in gravity. Requires a gravitational anomaly core to function." diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index d846833a5da..e60cc243bd3 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -202,41 +202,6 @@ /obj/projectile/beam/lasertag/bluetag/hitscan hitscan = TRUE -/obj/projectile/beam/instakill - name = "instagib laser" - icon_state = "purple_laser" - damage = 200 - damage_type = BURN - impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser - light_color = LIGHT_COLOR_PURPLE - -/obj/projectile/beam/instakill/blue - icon_state = "blue_laser" - impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser - light_color = LIGHT_COLOR_BLUE - -/obj/projectile/beam/instakill/red - icon_state = "red_laser" - impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser - light_color = COLOR_SOFT_RED - -/obj/projectile/beam/instakill/green - icon_state = "green_laser" - impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser - light_color = COLOR_VERY_PALE_LIME_GREEN - -/obj/projectile/beam/instakill/yellow - icon_state = "yellow_laser" - impact_effect_type = /obj/effect/temp_visual/impact_effect/yellow_laser - light_color = COLOR_VERY_SOFT_YELLOW - -/obj/projectile/beam/instakill/on_hit(atom/target) - . = ..() - if(iscarbon(target)) - var/mob/living/carbon/M = target - M.visible_message(span_danger("[M] explodes into a shower of gibs!")) - M.gib() - //a shrink ray that shrinks stuff, which grows back after a short while. /obj/projectile/beam/shrink name = "shrink ray" diff --git a/code/modules/shuttle/medisim.dm b/code/modules/shuttle/medisim.dm index d51297a786d..77cbf52a9af 100644 --- a/code/modules/shuttle/medisim.dm +++ b/code/modules/shuttle/medisim.dm @@ -1,132 +1,5 @@ ///These are for the medisim shuttle -#define REDFIELD_TEAM "Red" -#define BLUESWORTH_TEAM "Blue" - -/obj/machinery/capture_the_flag/medisim - game_id = "medieval" - game_area = /area/shuttle/escape/simulation - ammo_type = null //no guns, no need - victory_rejoin_text = "Teams have been cleared. The next game is starting automatically. Rejoin a team if you wish!" - -/obj/machinery/capture_the_flag/medisim/Initialize(mapload) - . = ..() - // Ensure that the historical simulation is extra bloody. - player_traits -= TRAIT_NEVER_WOUNDED - - start_ctf() //both machines initialize, so both will call start_ctf instead of toggle_id_ctf calling it for both, twice. - -/obj/machinery/capture_the_flag/medisim/victory() - . = ..() - toggle_id_ctf(null, game_id, automated = TRUE)//only one machine runs the victory proc, start_ctf proc would break the other machine - -/obj/machinery/capture_the_flag/medisim/spawn_team_member(client/new_team_member) - . = ..() - if(!.) - return - var/mob/living/carbon/human/human_knight = . - randomize_human(human_knight) - human_knight.dna.update_dna_identity() - human_knight.dna.add_mutation(MEDIEVAL, MUT_OTHER) - var/oldname = human_knight.name - var/title = "error" - switch (human_knight.gender) - if (MALE) - title = pick(list("Sir", "Lord")) - if (FEMALE) - title = pick(list("Dame", "Lady")) - else - title = "Noble" - human_knight.real_name = "[title] [oldname]" - human_knight.name = human_knight.real_name - -/obj/machinery/capture_the_flag/medisim/red - name = "\improper Redfield Data Realizer" - icon_state = "syndbeacon" - team = REDFIELD_TEAM - team_span = "redteamradio" - ctf_gear = list("knight" = /datum/outfit/medisim/red_knight, "archer" = /datum/outfit/medisim/red_archer) - -/obj/machinery/capture_the_flag/medisim/blue - name = "\improper Bluesworth Data Realizer" - icon_state = "bluebeacon" - team = BLUESWORTH_TEAM - team_span = "blueteamradio" - ctf_gear = list("knight" = /datum/outfit/medisim/blue_knight, "archer" = /datum/outfit/medisim/blue_archer) - -/obj/item/ctf/red/medisim - name = "\improper Redfield Castle Fair Maiden" - desc = "Protect your maiden, and capture theirs!" - icon = 'icons/obj/plushes.dmi' - icon_state = "plushie_nuke" - game_area = /area/shuttle/escape - movement_type = FLOATING //there are chasms, and resetting when they fall in is really lame so lets minimize that - -/obj/item/ctf/blue/medisim - name = "\improper Bluesworth Hold Fair Maiden" - desc = "Protect your maiden, and capture theirs!" - icon = 'icons/obj/plushes.dmi' - icon_state = "plushie_slime" - game_area = /area/shuttle/escape - movement_type = FLOATING //there are chasms, and resetting when they fall in is really lame so lets minimize that - -//everything except arrows -/datum/outfit/medisim/post_equip(mob/living/carbon/human/H, visualsOnly) - var/list/no_drops = list() - no_drops += H.get_item_by_slot(ITEM_SLOT_FEET) - no_drops += H.get_item_by_slot(ITEM_SLOT_BELT) - no_drops += H.get_item_by_slot(ITEM_SLOT_ICLOTHING) - no_drops += H.get_item_by_slot(ITEM_SLOT_OCLOTHING) - no_drops += H.get_item_by_slot(ITEM_SLOT_HEAD) - no_drops += H.get_item_by_slot(ITEM_SLOT_HANDS) - no_drops += H.get_item_by_slot(ITEM_SLOT_GLOVES) - listclearnulls(no_drops) //any slots we didn't have - for(var/_outfit_item in no_drops) - var/obj/item/outfit_item = _outfit_item - outfit_item.item_flags |= DROPDEL//so this all stays clean :) - -/datum/outfit/medisim/red_knight - name = "Redfield Castle Knight" - - uniform = /obj/item/clothing/under/color/red - shoes = /obj/item/clothing/shoes/plate/red - suit = /obj/item/clothing/suit/armor/riot/knight/red - gloves = /obj/item/clothing/gloves/plate/red - head = /obj/item/clothing/head/helmet/knight/red - r_hand = /obj/item/claymore - -/datum/outfit/medisim/blue_knight - name = "Bluesworth Hold Knight" - - uniform = /obj/item/clothing/under/color/blue - shoes = /obj/item/clothing/shoes/plate/blue - suit = /obj/item/clothing/suit/armor/riot/knight/blue - gloves = /obj/item/clothing/gloves/plate/blue - head = /obj/item/clothing/head/helmet/knight/blue - r_hand = /obj/item/claymore - -/datum/outfit/medisim/red_archer - name = "Redfield Castle Archer" - - uniform = /obj/item/clothing/under/color/red - belt = /obj/item/storage/bag/quiver - shoes = /obj/item/clothing/shoes/plate/red - suit = /obj/item/clothing/suit/armor/vest/cuirass - gloves = /obj/item/clothing/gloves/plate/red - head = /obj/item/clothing/head/helmet/knight/red - r_hand = /obj/item/gun/ballistic/bow - -/datum/outfit/medisim/blue_archer - name = "Bluesworth Hold Archer" - - uniform = /obj/item/clothing/under/color/blue - belt = /obj/item/storage/bag/quiver - shoes = /obj/item/clothing/shoes/plate/blue - suit = /obj/item/clothing/suit/armor/vest/cuirass - gloves = /obj/item/clothing/gloves/plate/blue - head = /obj/item/clothing/head/helmet/knight/blue - r_hand = /obj/item/gun/ballistic/bow - /obj/machinery/computer/reality_simulation name = "reality simulation computer" desc = "A computer calculating the medieval times. Uh, wow. Is this bad boy quantum?" @@ -143,6 +16,3 @@

the rest of the page is filled with various doodles of people fighting with swords."} - -#undef REDFIELD_TEAM -#undef BLUESWORTH_TEAM diff --git a/icons/hud/radial_ctf.dmi b/icons/hud/radial_ctf.dmi new file mode 100644 index 00000000000..9fd9a741a56 Binary files /dev/null and b/icons/hud/radial_ctf.dmi differ diff --git a/icons/mob/inhands/weapons/guns_lefthand.dmi b/icons/mob/inhands/weapons/guns_lefthand.dmi index 34611cbeb16..98316b40a46 100644 Binary files a/icons/mob/inhands/weapons/guns_lefthand.dmi and b/icons/mob/inhands/weapons/guns_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/guns_righthand.dmi b/icons/mob/inhands/weapons/guns_righthand.dmi index 98313a39d28..02c03f721bc 100644 Binary files a/icons/mob/inhands/weapons/guns_righthand.dmi and b/icons/mob/inhands/weapons/guns_righthand.dmi differ diff --git a/icons/obj/guns/ballistic.dmi b/icons/obj/guns/ballistic.dmi index 3cfad7ed030..62479e6c25b 100644 Binary files a/icons/obj/guns/ballistic.dmi and b/icons/obj/guns/ballistic.dmi differ diff --git a/tgstation.dme b/tgstation.dme index c417e55417f..80b850bbe30 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -741,6 +741,7 @@ #include "code\datums\elements\curse_announcement.dm" #include "code\datums\elements\cursed.dm" #include "code\datums\elements\deferred_aquarium_content.dm" +#include "code\datums\elements\delete_on_drop.dm" #include "code\datums\elements\digitalcamo.dm" #include "code\datums\elements\drag_pickup.dm" #include "code\datums\elements\dryable.dm" @@ -1981,8 +1982,12 @@ #include "code\modules\buildmode\submodes\smite.dm" #include "code\modules\buildmode\submodes\throwing.dm" #include "code\modules\buildmode\submodes\variable_edit.dm" -#include "code\modules\capture_the_flag\capture_the_flag.dm" -#include "code\modules\capture_the_flag\map_loading.dm" +#include "code\modules\capture_the_flag\ctf_classes.dm" +#include "code\modules\capture_the_flag\ctf_equipment.dm" +#include "code\modules\capture_the_flag\ctf_game.dm" +#include "code\modules\capture_the_flag\ctf_map_loading.dm" +#include "code\modules\capture_the_flag\medieval_sim\medisim_classes.dm" +#include "code\modules\capture_the_flag\medieval_sim\medisim_game.dm" #include "code\modules\cargo\bounty.dm" #include "code\modules\cargo\centcom_podlauncher.dm" #include "code\modules\cargo\coupon.dm"