diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index 9cabc16a45..0983a19881 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -37,6 +37,7 @@ #define ROLE_INTERNAL_AFFAIRS "internal affairs agent" #define ROLE_GANG "gangster" #define ROLE_BLOODSUCKER "bloodsucker" +#define ROLE_SPACE_DRAGON "Space Dragon" //#define ROLE_MONSTERHUNTER "monster hunter" Disabled for now #define ROLE_GHOSTCAFE "ghostcafe" #define ROLE_MINOR_ANTAG "minorantag" @@ -70,6 +71,7 @@ GLOBAL_LIST_INIT(special_roles, list( ROLE_SENTIENCE, ROLE_GANG = /datum/game_mode/gang, ROLE_HERETIC = /datum/game_mode/heretics, + ROLE_SPACE_DRAGON, ROLE_BLOODSUCKER = /datum/game_mode/bloodsucker //ROLE_MONSTERHUNTER Disabled for now )) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index ded183ba0b..eee0889fb8 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -340,3 +340,4 @@ #define ACTIVE_PARRY_TRAIT "active_parry" #define STICKY_NODROP "sticky-nodrop" //sticky nodrop sounds like a bad soundcloud rapper's name #define TRAIT_SACRIFICED "sacrificed" //Makes sure that people cant be cult sacrificed twice. +#define TRAIT_SPACEWALK "spacewalk" diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index 26e0197deb..bbe801cfc2 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -123,7 +123,8 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_HIGH_BLOOD" = TRAIT_HIGH_BLOOD, "TRAIT_EMPATH" = TRAIT_EMPATH, "TRAIT_FRIENDLY" = TRAIT_FRIENDLY, - "TRAIT_IWASBATONED" = TRAIT_IWASBATONED + "TRAIT_IWASBATONED" = TRAIT_IWASBATONED, + "TRAIT_SPACEWALK" = TRAIT_SPACEWALK ), /obj/item/bodypart = list( "TRAIT_PARALYSIS" = TRAIT_PARALYSIS diff --git a/code/modules/antagonists/space_dragon/space_dragon.dm b/code/modules/antagonists/space_dragon/space_dragon.dm index 97f45bba53..330cb2a62a 100644 --- a/code/modules/antagonists/space_dragon/space_dragon.dm +++ b/code/modules/antagonists/space_dragon/space_dragon.dm @@ -1,31 +1,52 @@ /datum/antagonist/space_dragon name = "Space Dragon" - show_in_antagpanel = FALSE + roundend_category = "space dragons" + antagpanel_category = "Space Dragon" + job_rank = ROLE_SPACE_DRAGON + show_in_antagpanel = TRUE show_name_in_check_antagonists = TRUE + var/list/datum/mind/carp = list() /datum/antagonist/space_dragon/greet() - to_chat(owner, "I am Space Dragon, ex-space carp, and defender of the secrets of constellation, Draco.") - to_chat(owner, "Fabulous secret powers were revealed to me the day I held aloft a wizard's staff of change and said 'By the power of Draco, I have the power!'") - to_chat(owner, "The wizard was turned into the short-lived Pastry Cat while I became Space Dragon, the most powerful beast in the universe.") - to_chat(owner, "Clicking a tile will shoot fire onto that tile.") - to_chat(owner, "Alt-clicking will let me do a tail swipe, knocking down entities in a tile radius around me.") - to_chat(owner, "Attacking dead bodies will allow me to gib them to restore health.") - to_chat(owner, "From the wizard's writings, he had been studying this station and its hierarchy. From this, I know who leads the station, and will kill them so the station underlings see me as their new leader.") + to_chat(owner, "Endless time and space we have moved through. We do not remember from where we came, we do not know where we will go. All space belongs to us.\n\ + Space is an empty void, of which our kind is the apex predator, and there was little to rival our claim to this title.\n\ + But now, we find intruders spread out amongst our claim, willing to fight our teeth with magics unimaginable, their dens like lights flicking in the depths of space.\n\ + Today, we will snuff out one of those lights.") + to_chat(owner, "You have five minutes to find a safe location to place down the first rift. If you take longer than five minutes to place a rift, you will be returned from whence you came.") + owner.announce_objectives() owner.announce_objectives() SEND_SOUND(owner.current, sound('sound/magic/demon_attack1.ogg')) /datum/antagonist/space_dragon/proc/forge_objectives() - var/current_heads = SSjob.get_all_heads() - var/datum/objective/assassinate/killchosen = new - killchosen.owner = owner - var/datum/mind/selected = pick(current_heads) - killchosen.target = selected - killchosen.update_explanation_text() - objectives += killchosen - var/datum/objective/survive/survival = new - survival.owner = owner - objectives += survival + var/datum/objective/summon_carp/summon = new() + summon.dragon = src + objectives += summon /datum/antagonist/space_dragon/on_gain() forge_objectives() . = ..() + +/datum/objective/summon_carp + var/datum/antagonist/space_dragon/dragon + explanation_text = "Summon and protect the rifts to flood the station with carp." + +/datum/antagonist/space_dragon/roundend_report() + var/list/parts = list() + var/datum/objective/summon_carp/S = locate() in objectives + if(S.check_completion()) + parts += "The [name] has succeeded! Station space has been reclaimed by the space carp!" + parts += printplayer(owner) + var/objectives_complete = TRUE + if(objectives.len) + parts += printobjectives(objectives) + for(var/datum/objective/objective in objectives) + if(!objective.check_completion()) + objectives_complete = FALSE + break + if(objectives_complete) + parts += "The [name] was successful!" + else + parts += "The [name] has failed!" + parts += "The [name] was assisted by:" + parts += printplayerlist(carp) + return "
[parts.Join("
")]
" diff --git a/code/modules/events/space_dragon.dm b/code/modules/events/space_dragon.dm index ddf8e670c6..58e0dbdc58 100644 --- a/code/modules/events/space_dragon.dm +++ b/code/modules/events/space_dragon.dm @@ -1,17 +1,17 @@ /datum/round_event_control/space_dragon name = "Spawn Space Dragon" typepath = /datum/round_event/ghost_role/space_dragon - weight = 10 + weight = 8 max_occurrences = 1 min_players = 20 /datum/round_event/ghost_role/space_dragon minimum_required = 1 role_name = "Space Dragon" - fakeable = FALSE + announceWhen = 10 /datum/round_event/ghost_role/space_dragon/announce(fake) - priority_announce("It appears a lifeform with magical traces is approaching [station_name()], please stand-by.", "Lifesign Alert") + priority_announce("A large organic energy flux has been recorded near of [station_name()], please stand-by.", "Lifesign Alert") /datum/round_event/ghost_role/space_dragon/spawn_role() @@ -24,22 +24,23 @@ if(!spawn_locs.len) message_admins("No valid spawn locations found, aborting...") return MAP_ERROR - - var/list/candidates = get_candidates(ROLE_SPACE_DRAGON, null, ROLE_SPACE_DRAGON) + + var/list/candidates = get_candidates(ROLE_SPACE_DRAGON, ROLE_SPACE_DRAGON) if(!candidates.len) return NOT_ENOUGH_PLAYERS - + var/mob/dead/selected = pick(candidates) - var/key = selected.key - var/mob/living/simple_animal/hostile/space_dragon/dragon = new (pick(spawn_locs)) - dragon.key = key - dragon.mind.assigned_role = "Space Dragon" - dragon.mind.special_role = "Space Dragon" - dragon.mind.add_antag_datum(/datum/antagonist/space_dragon) - playsound(dragon, 'sound/magic/ethereal_exit.ogg', 50, TRUE, -1) - message_admins("[ADMIN_LOOKUPFLW(dragon)] has been made into a Space Dragon by an event.") - log_game("[key_name(dragon)] was spawned as a Space Dragon by an event.") - spawned_mobs += dragon + var/datum/mind/player_mind = new /datum/mind(selected.key) + player_mind.active = TRUE + + var/mob/living/simple_animal/hostile/space_dragon/S = new(pick(spawn_locs)) + player_mind.transfer_to(S) + player_mind.assigned_role = "Space Dragon" + player_mind.special_role = "Space Dragon" + player_mind.add_antag_datum(/datum/antagonist/space_dragon) + playsound(S, 'sound/magic/ethereal_exit.ogg', 50, TRUE, -1) + message_admins("[ADMIN_LOOKUPFLW(S)] has been made into a Space Dragon by an event.") + log_game("[key_name(S)] was spawned as a Space Dragon by an event.") + spawned_mobs += S return SUCCESSFUL_SPAWN - diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm index fb1b5d2ef1..6c1e9eef6e 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm @@ -543,75 +543,3 @@ Difficulty: Medium hit_list += M M.take_damage(45, BRUTE, "melee", 1) sleep(1.5) - - -/mob/living/simple_animal/hostile/megafauna/dragon/space_dragon - name = "space dragon" - maxHealth = 250 - health = 250 - faction = list("neutral") - desc = "A space carp turned dragon by vile magic. Has the same ferocity of a space carp, but also a much more enabling body." - icon = 'icons/mob/spacedragon.dmi' - icon_state = "spacedragon" - icon_living = "spacedragon" - icon_dead = "spacedragon_dead" - obj_damage = 80 - melee_damage_upper = 35 - melee_damage_lower = 35 - speed = 0 - mouse_opacity = MOUSE_OPACITY_ICON - loot = list() - crusher_loot = list() - butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/bone = 30) - move_force = MOVE_FORCE_NORMAL - move_resist = MOVE_FORCE_NORMAL - pull_force = MOVE_FORCE_NORMAL - deathmessage = "screeches as its wings turn to dust and it collapses on the floor, life estinguished." - var/datum/action/small_sprite/carpsprite = new/datum/action/small_sprite/spacedragon() - -/mob/living/simple_animal/hostile/megafauna/dragon/space_dragon/grant_achievement(medaltype,scoretype) - return - -/mob/living/simple_animal/hostile/megafauna/dragon/space_dragon/Initialize() - carpsprite.Grant(src) - mob_spell_list += new /obj/effect/proc_holder/spell/aoe_turf/repulse/spacedragon(src) - . = ..() - smallsprite.Remove(src) - -/mob/living/simple_animal/hostile/megafauna/dragon/space_dragon/proc/fire_stream(var/atom/at = target) - playsound(get_turf(src),'sound/magic/fireball.ogg', 200, 1) - if(QDELETED(src) || stat == DEAD) // we dead no fire - return - var/range = 20 - var/list/turfs = list() - turfs = line_target(0, range, at) - INVOKE_ASYNC(src, .proc/fire_line, turfs) - -/mob/living/simple_animal/hostile/megafauna/dragon/space_dragon/OpenFire() - if(swooping) - return - ranged_cooldown = world.time + ranged_cooldown_time - fire_stream() - -/obj/effect/proc_holder/spell/aoe_turf/repulse/spacedragon - name = "Tail Sweep" - desc = "Throw back attackers with a sweep of your tail." - sound = 'sound/magic/tail_swing.ogg' - charge_max = 150 - clothes_req = FALSE - antimagic_allowed = TRUE - range = 1 - cooldown_min = 150 - invocation_type = "none" - sparkle_path = /obj/effect/temp_visual/dir_setting/tailsweep - action_icon = 'icons/mob/actions/actions_xeno.dmi' - action_icon_state = "tailsweep" - action_background_icon_state = "bg_alien" - anti_magic_check = FALSE - -/obj/effect/proc_holder/spell/aoe_turf/repulse/spacedragon/cast(list/targets,mob/user = usr) - if(iscarbon(user)) - var/mob/living/carbon/C = user - playsound(C.loc,'sound/effects/hit_punch.ogg', 80, 1, 1) - C.spin(6,1) - ..(targets, user, 60) diff --git a/code/modules/mob/living/simple_animal/hostile/space_dragon.dm b/code/modules/mob/living/simple_animal/hostile/space_dragon.dm index 0f2d89a27a..b25c2db052 100644 --- a/code/modules/mob/living/simple_animal/hostile/space_dragon.dm +++ b/code/modules/mob/living/simple_animal/hostile/space_dragon.dm @@ -36,13 +36,11 @@ attack_verb_continuous = "chomps" attack_verb_simple = "chomp" attack_sound = 'sound/magic/demon_attack1.ogg' - attack_vis_effect = ATTACK_EFFECT_BITE deathsound = 'sound/creatures/space_dragon_roar.ogg' icon = 'icons/mob/spacedragon.dmi' icon_state = "spacedragon" icon_living = "spacedragon" icon_dead = "spacedragon_dead" - health_doll_icon = "spacedragon" obj_damage = 50 environment_smash = ENVIRONMENT_SMASH_NONE flags_1 = PREVENT_CONTENTS_EXPLOSION_1 | HEAR_1 @@ -52,6 +50,7 @@ armour_penetration = 30 pixel_x = -16 turns_per_move = 5 + movement_type = FLYING ranged = TRUE mouse_opacity = MOUSE_OPACITY_ICON butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/bone = 30) @@ -61,7 +60,6 @@ maxbodytemp = 1500 faction = list("carp") pressure_resistance = 200 - is_flying_animal = TRUE /// Current time since the the last rift was activated. If set to -1, does not increment. var/riftTimer = 0 /// Maximum amount of time which can pass without a rift before Space Dragon despawns. @@ -92,7 +90,6 @@ /mob/living/simple_animal/hostile/space_dragon/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT) - ADD_TRAIT(src, TRAIT_NO_FLOATING_ANIM, INNATE_TRAIT) rift = new rift.Grant(src) @@ -103,7 +100,7 @@ color_selection() -/mob/living/simple_animal/hostile/space_dragon/Life(delta_time = SSMOBS_DT, times_fired) +/mob/living/simple_animal/hostile/space_dragon/Life() . = ..() tiredness = max(tiredness - 1, 0) for(var/mob/living/consumed_mob in src) @@ -159,11 +156,12 @@ adjustHealth(-L.maxHealth * 0.5) return . = ..() - if(istype(target, /obj/vehicle/sealed/mecha)) - var/obj/vehicle/sealed/mecha/M = target + if(istype(target, /obj/mecha)) + var/obj/mecha/M = target M.take_damage(50, BRUTE, MELEE, 1) -/mob/living/simple_animal/hostile/space_dragon/ranged_secondary_attack(atom/target, modifiers) +/mob/living/simple_animal/hostile/space_dragon/CtrlClickOn(atom/A) + . = ..() if(using_special) return using_special = TRUE @@ -322,7 +320,7 @@ L.adjustFireLoss(30) to_chat(L, "You're hit by [src]'s fire breath!") // deals damage to mechs - for(var/obj/vehicle/sealed/mecha/M in T.contents) + for(var/obj/mecha/M in T.contents) if(M in hit_list) continue hit_list += M @@ -623,7 +621,7 @@ carp_stored++ icon_state = "carp_rift_carpspawn" if(light_color != LIGHT_COLOR_PURPLE) - set_light_color(LIGHT_COLOR_PURPLE) + light_color = LIGHT_COLOR_PURPLE update_light() notify_ghosts("The carp rift can summon an additional carp!", source = src, action = NOTIFY_ORBIT, flashwindow = FALSE, header = "Carp Spawn Available") last_carp_inc -= carp_interval @@ -635,7 +633,7 @@ priority_announce("Spatial object has reached peak energy charge in [initial(A.name)], please stand-by.", "Central Command Wildlife Observations") obj_integrity = INFINITY icon_state = "carp_rift_charged" - set_light_color(LIGHT_COLOR_YELLOW) + light_color = LIGHT_COLOR_YELLOW update_light() armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100) resistance_flags = INDESTRUCTIBLE @@ -652,7 +650,7 @@ if(charge_state < CHARGE_FINALWARNING && time_charged >= (max_charge * 0.5)) charge_state = CHARGE_FINALWARNING var/area/A = get_area(src) - priority_announce("A rift is causing an unnaturally large energy flux in [initial(A.name)]. Stop it at all costs!", "Central Command Wildlife Observations", ANNOUNCER_SPANOMALIES) + priority_announce("A rift is causing an unnaturally large energy flux in [initial(A.name)]. Stop it at all costs!", "Central Command Wildlife Observations", sound = 'sound/announcer/classic/spanomalies.ogg') /** * Used to create carp controlled by ghosts when the option is available. @@ -681,7 +679,7 @@ carp_stored-- if(carp_stored <= 0 && charge_state < CHARGE_COMPLETED) icon_state = "carp_rift" - set_light_color(LIGHT_COLOR_BLUE) + light_color = LIGHT_COLOR_BLUE update_light() return TRUE diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index c467605f37..2af68eab46 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -208,7 +208,7 @@ ///For moving in space ///return TRUE for movement 0 for none /mob/Process_Spacemove(movement_dir = 0) - if(spacewalk || ..()) + if(HAS_TRAIT(src, TRAIT_SPACEWALK) || spacewalk || ..()) return TRUE var/atom/movable/backup = get_spacemove_backup() if(backup) diff --git a/icons/obj/carp_rift.dmi b/icons/obj/carp_rift.dmi new file mode 100644 index 0000000000..9a07b3b16f Binary files /dev/null and b/icons/obj/carp_rift.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 9c09703fe8..5a300dd46f 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2801,6 +2801,7 @@ #include "code\modules\mob\living\simple_animal\hostile\russian.dm" #include "code\modules\mob\living\simple_animal\hostile\sharks.dm" #include "code\modules\mob\living\simple_animal\hostile\skeleton.dm" +#include "code\modules\mob\living\simple_animal\hostile\space_dragon.dm" #include "code\modules\mob\living\simple_animal\hostile\statue.dm" #include "code\modules\mob\living\simple_animal\hostile\stickman.dm" #include "code\modules\mob\living\simple_animal\hostile\syndicate.dm"