From 896b72018ce7076be01930cfe14e3effa660fbcf Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Sun, 11 Oct 2020 22:35:56 +0200 Subject: [PATCH] [MIRROR] Space Dragon QOL and Additional Features (#1246) * Space Dragon QOL and Additional Features * fix. Co-authored-by: IndieanaJones <47086570+IndieanaJones@users.noreply.github.com> Co-authored-by: Gandalf --- code/modules/events/space_dragon.dm | 43 ++++---- .../simple_animal/hostile/space_dragon.dm | 99 +++++++++++++++++- icons/mob/spacedragon.dmi | Bin 6148 -> 7686 bytes 3 files changed, 116 insertions(+), 26 deletions(-) diff --git a/code/modules/events/space_dragon.dm b/code/modules/events/space_dragon.dm index f8ccaa51883..ac2db2cf84c 100644 --- a/code/modules/events/space_dragon.dm +++ b/code/modules/events/space_dragon.dm @@ -3,8 +3,8 @@ typepath = /datum/round_event/ghost_role/space_dragon //max_occurrences = 1 //ORIGINAL max_occurrences = 0 //SKYRAT EDIT CHANGE - EVENTS - weight = 5 - earliest_start = 35 MINUTES + weight = 10 + max_occurrences = 1 min_players = 20 /datum/round_event/ghost_role/space_dragon @@ -16,29 +16,30 @@ priority_announce("A large organic energy flux has been recorded near [station_name()], please stand by.", "Lifesign Alert") /datum/round_event/ghost_role/space_dragon/spawn_role() + var/list/spawn_locs = list() + for(var/obj/effect/landmark/carpspawn/carp_spawn in GLOB.landmarks_list) + if(!isturf(carp_spawn.loc)) + stack_trace("Carp spawn found not on a turf: [carp_spawn.type] on [isnull(carp_spawn.loc) ? "null" : carp_spawn.loc.type]") + continue + spawn_locs += carp_spawn.loc + 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) if(!candidates.len) return NOT_ENOUGH_PLAYERS var/mob/dead/selected = pick(candidates) + var/key = selected.key - var/datum/mind/player_mind = new /datum/mind(selected.key) - player_mind.active = TRUE - - var/list/spawn_locs = list() - for(var/obj/effect/landmark/carpspawn/C in GLOB.landmarks_list) - spawn_locs += (C.loc) - if(!spawn_locs.len) - message_admins("No valid spawn locations found, aborting...") - return MAP_ERROR - - 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 + 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 return SUCCESSFUL_SPAWN 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 f4ef134d073..68a9d11baac 100644 --- a/code/modules/mob/living/simple_animal/hostile/space_dragon.dm +++ b/code/modules/mob/living/simple_animal/hostile/space_dragon.dm @@ -4,6 +4,8 @@ #define CHARGE_FINALWARNING 1 /// The carp rift is now fully charged. #define CHARGE_COMPLETED 2 +/// The darkness threshold for space dragon when choosing a color +#define DARKNESS_THRESHOLD 0.5 /** * # Space Dragon @@ -79,6 +81,8 @@ var/datum/action/innate/space_dragon/gust_attack/gust /// The innate ability to summon rifts var/datum/action/innate/space_dragon/summon_rift/rift + /// The color of the space dragon. + var/chosen_color /mob/living/simple_animal/hostile/space_dragon/Initialize(mapload) . = ..() @@ -91,9 +95,23 @@ rift = new rift.Grant(src) +/mob/living/simple_animal/hostile/space_dragon/Login() + . = ..() + if(!chosen_color) + dragon_name() + color_selection() + + /mob/living/simple_animal/hostile/space_dragon/Life(mapload) . = ..() tiredness = max(tiredness - 1, 0) + for(var/mob/living/consumed_mob in src) + if(consumed_mob.stat == DEAD) + continue + playsound(src, 'sound/effects/splat.ogg', 50, TRUE) + visible_message("[src] vomits up [consumed_mob]!") + consumed_mob.forceMove(loc) + consumed_mob.Paralyze(50) if(rifts_charged == 3 && !objective_complete) victory() if(riftTimer == -1) @@ -153,12 +171,72 @@ empty_contents() if(!objective_complete) destroy_rifts() + add_overlay() ..() /mob/living/simple_animal/hostile/space_dragon/wabbajack_act(mob/living/new_mob) empty_contents() . = ..() +/** + * Allows space dragon to choose its own name. + * + * Prompts the space dragon to choose a name, which it will then apply to itself. + * If the name is invalid, will re-prompt the dragon until a proper name is chosen. + */ +/mob/living/simple_animal/hostile/space_dragon/proc/dragon_name() + var/chosen_name = sanitize_name(reject_bad_text(stripped_input(src, "What would you like your name to be?", "Choose Your Name", real_name, MAX_NAME_LEN))) + if(!chosen_name) + to_chat(src, "Not a valid name, please try again.") + dragon_name() + return + visible_message("Your name is now [chosen_name], the feared Space Dragon.") + fully_replace_character_name(null, chosen_name) + +/** + * Allows space dragon to choose a color for itself. + * + * Prompts the space dragon to choose a color, from which it will then apply to itself. + * If an invalid color is given, will re-prompt the dragon until a proper color is chosen. + */ +/mob/living/simple_animal/hostile/space_dragon/proc/color_selection() + chosen_color = input(src,"What would you like your color to be?","Choose Your Color", COLOR_WHITE) as color|null + if(!chosen_color) //redo proc until we get a color + to_chat(src, "Not a valid color, please try again.") + color_selection() + return + var/temp_hsv = RGBtoHSV(chosen_color) + if(chosen_color == COLOR_BLACK) + chosen_color = COLOR_WHITE + else if(ReadHSV(temp_hsv)[3] < DARKNESS_THRESHOLD) + to_chat(src, "Invalid color. Your color is not bright enough.") + color_selection() + return + add_atom_colour(chosen_color, FIXED_COLOUR_PRIORITY) + add_dragon_overlay() + +/** + * Adds the proper overlay to the space dragon. + * + * Clears the current overlay on space dragon and adds a proper one for whatever animation he's in. + */ +/mob/living/simple_animal/hostile/space_dragon/proc/add_dragon_overlay() + cut_overlays() + if(stat == DEAD) + var/mutable_appearance/overlay = mutable_appearance(icon, "overlay_dead") + overlay.appearance_flags = RESET_COLOR + add_overlay(overlay) + return + if(!using_special) + var/mutable_appearance/overlay = mutable_appearance(icon, "overlay_base") + overlay.appearance_flags = RESET_COLOR + add_overlay(overlay) + return + if(using_special) + var/mutable_appearance/overlay = mutable_appearance(icon, "overlay_gust") + overlay.appearance_flags = RESET_COLOR + add_overlay(overlay) + /** * Determines a line of turfs from sources's position to the target with length range. * @@ -273,6 +351,7 @@ if(stat != DEAD) icon_state = "spacedragon" using_special = FALSE + add_dragon_overlay() /** * Handles Space Dragon's temporary empowerment after boosting a rift. @@ -284,11 +363,11 @@ /mob/living/simple_animal/hostile/space_dragon/proc/rift_empower(is_empowered) if(is_empowered) fully_heal() - color = "#FF0000" + add_filter("anger_glow", 3, list("type" = "outline", "color" = "#ff330030", "size" = 5)) set_varspeed(-0.5) addtimer(CALLBACK(src, .proc/rift_empower, FALSE), 300) else - color = "#FFFFFF" + remove_filter("anger_glow") set_varspeed(0) /** @@ -323,6 +402,10 @@ return pixel_y = 0 icon_state = "spacedragon_gust_2" + cut_overlays() + var/mutable_appearance/overlay = mutable_appearance(icon, "overlay_gust_2") + overlay.appearance_flags = RESET_COLOR + add_overlay(overlay) playsound(src, 'sound/effects/gravhit.ogg', 100, TRUE) var/gust_locs = spiral_range_turfs(3, get_turf(src)) var/list/hit_things = list() @@ -378,6 +461,7 @@ return S.using_special = TRUE S.icon_state = "spacedragon_gust" + S.add_dragon_overlay() S.useGust(0) /datum/action/innate/space_dragon/summon_rift @@ -480,9 +564,13 @@ var/obj/effect/temp_visual/heal/H = new /obj/effect/temp_visual/heal(get_turf(hostilehere)) H.color = "#0000FF" - // If we're fully charged, just start mass spawning carp. - if(charge_state == CHARGE_COMPLETED && DT_PROB(1.25, delta_time)) - new /mob/living/simple_animal/hostile/carp(loc) + // If we're fully charged, just start mass spawning carp and move around. + if(charge_state == CHARGE_COMPLETED) + if(DT_PROB(1.25, delta_time)) + new /mob/living/simple_animal/hostile/carp(loc) + if(DT_PROB(1.5, delta_time)) + var/rand_dir = pick(GLOB.cardinals) + Move(get_step(src, rand_dir), rand_dir) return // Increase time trackers and check for any updated states. @@ -577,3 +665,4 @@ #undef CHARGE_ONGOING #undef CHARGE_FINALWARNING #undef CHARGE_COMPLETED +#undef DARKNESS_THRESHOLD diff --git a/icons/mob/spacedragon.dmi b/icons/mob/spacedragon.dmi index 419b6ef260525e6af3acbd6b5d063beb23e773cc..3745284f422e696d5db42dbb53b4bca70e020145 100644 GIT binary patch literal 7686 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