[MIRROR] Basic Mob Carp Part VIII: Basic Mob Carp [MDB IGNORE] (#18344)

* Basic Mob Carp Part VIII: Basic Mob Carp

* maps

* missed killing main carp file

* shorki and ocean biomes

* shorki 2: pet-a-boogaloo

Co-authored-by: Jacquerel <hnevard@gmail.com>
Co-authored-by: tastyfish <crazychris32@gmail.com>
This commit is contained in:
SkyratBot
2023-01-09 05:48:50 -05:00
committed by GitHub
co-authored by Jacquerel tastyfish
parent 381bbef2f8
commit 7ee524f748
66 changed files with 3638 additions and 3296 deletions
@@ -63,7 +63,7 @@
if(!food_types)
food_types = src.food_types.Copy()
AddComponent(/datum/component/tameable, food_types = food_types, tame_chance = 25, bonus_tame_chance = 15, after_tame = CALLBACK(src, PROC_REF(tamed)))
AddElement(/datum/element/basic_eating, 10, food_types)
AddElement(/datum/element/basic_eating, 10, 0, null, food_types)
/mob/living/basic/cow/proc/tamed(mob/living/tamer)
buckle_lying = 0
@@ -34,7 +34,7 @@
var/static/list/food_types
if(!food_types)
food_types = src.food_types.Copy()
AddElement(/datum/element/basic_eating, 10, food_types)
AddElement(/datum/element/basic_eating, 10, 0, null, food_types)
AddComponent(/datum/component/tameable, food_types = food_types, tame_chance = 25, bonus_tame_chance = 15, after_tame = CALLBACK(src, PROC_REF(tamed)))
/mob/living/basic/cow/moonicorn/tamed(mob/living/tamer)
@@ -0,0 +1,215 @@
/**
* ## Space Carp
*
* A migratory dwarf fortress reference who swim through space and sometimes bump into the space station.
* Can be created in dehydrated form by traitors, and are also summoned through rifts by space dragons.
*
* Begin regenerating their health after a short time without taking any damage, and will try to run away to do this if they get hurt.
* Lethally attracted to loose plastic.
*
* Tameable by feeding them meat, and can follow basic instructions. Rideable.
* Owned as a pet both by the HoS (sometimes) and also the Nuclear Operatives.
*/
/mob/living/basic/carp
name = "space carp"
desc = "A ferocious, fang-bearing creature that resembles a fish."
icon = 'icons/mob/simple/carp.dmi'
icon_state = "base"
icon_living = "base"
icon_dead = "base_dead"
icon_gib = "carp_gib"
gold_core_spawnable = HOSTILE_SPAWN
mob_biotypes = MOB_ORGANIC | MOB_BEAST
movement_type = FLYING
health = 25
maxHealth = 25
pressure_resistance = 200
combat_mode = TRUE
obj_damage = 50
melee_damage_lower = 20
melee_damage_upper = 20
attack_sound = 'sound/weapons/bite.ogg'
attack_vis_effect = ATTACK_EFFECT_BITE
attack_verb_continuous = "bites"
attack_verb_simple = "bite"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
faction = list("carp")
butcher_results = list(/obj/item/food/fishmeat/carp = 2, /obj/item/stack/sheet/animalhide/carp = 1)
greyscale_config = /datum/greyscale_config/carp
ai_controller = /datum/ai_controller/basic_controller/carp
/// Cytology cells you can swab from this creature
var/cell_line = CELL_LINE_TABLE_CARP
/// What colour is our 'healing' outline?
var/regenerate_colour = COLOR_PALE_GREEN
/// Information to apply when treating this carp as a vehicle
var/ridable_data = /datum/component/riding/creature/carp
/// Commands you can give this carp once it is tamed, not static because subtypes can modify it
var/tamed_commands = list(
/datum/pet_command/idle,
/datum/pet_command/free,
/datum/pet_command/follow,
/datum/pet_command/point_targetting/attack/carp
)
/// Carp want to eat raw meat
var/static/list/desired_food = list(/obj/item/food/meat/slab, /obj/item/food/meat/rawcutlet)
/// Carp want to eat delicious six pack plastic rings
var/static/list/desired_trash = list(/obj/item/storage/cans)
/// Weighted list of colours a carp can be
/// Weighted list of usual carp colors
var/static/list/carp_colors = list(
COLOR_CARP_PURPLE = 7,
COLOR_CARP_PINK = 7,
COLOR_CARP_GREEN = 7,
COLOR_CARP_GRAPE = 7,
COLOR_CARP_SWAMP = 7,
COLOR_CARP_TURQUOISE = 7,
COLOR_CARP_BROWN = 7,
COLOR_CARP_TEAL = 7,
COLOR_CARP_LIGHT_BLUE = 7,
COLOR_CARP_RUSTY = 7,
COLOR_CARP_RED = 7,
COLOR_CARP_YELLOW = 7,
COLOR_CARP_BLUE = 7,
COLOR_CARP_PALE_GREEN = 7,
COLOR_CARP_SILVER = 1, // The rare silver carp
)
/mob/living/basic/carp/Initialize(mapload, mob/tamer)
. = ..()
apply_colour()
ADD_TRAIT(src, TRAIT_HEALS_FROM_CARP_RIFTS, INNATE_TRAIT)
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
if (cell_line)
AddElement(/datum/element/swabable, cell_line, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
AddElement(/datum/element/simple_flying)
AddElement(/datum/element/ai_flee_while_injured)
setup_eating()
AddComponent(/datum/component/regenerator, outline_colour = regenerate_colour)
if (tamer)
befriend(tamer)
on_tamed(tamer, FALSE)
else
AddComponent(/datum/component/tameable, food_types = list(/obj/item/food/meat), tame_chance = 10, bonus_tame_chance = 5, after_tame = CALLBACK(src, PROC_REF(on_tamed)))
/// Tell the elements and the blackboard what food we want to eat
/mob/living/basic/carp/proc/setup_eating()
AddElement(/datum/element/basic_eating, 10, 0, null, desired_food)
AddElement(/datum/element/basic_eating, 0, 10, BRUTE, desired_trash) // We are killing our planet
ai_controller.blackboard[BB_BASIC_FOODS] = desired_food + desired_trash
/// Set a random colour on the carp, override to do something else
/mob/living/basic/carp/proc/apply_colour()
if (!greyscale_config)
return
set_greyscale(colors = list(pick_weight(carp_colors)))
/// Called when another mob has forged a bond of friendship with this one, passed the taming mob as 'tamer'
/mob/living/basic/carp/proc/on_tamed(mob/tamer, feedback = TRUE)
buckle_lying = 0
AddElement(/datum/element/ridable, ridable_data)
AddComponent(/datum/component/obeys_commands, tamed_commands)
if (!feedback)
return
spin(spintime = 10, speed = 1)
visible_message("[src] spins in a circle as it seems to bond with [tamer].")
/**
* Holographic carp from the holodeck
*/
/mob/living/basic/carp/holographic
icon_state = "holocarp"
icon_living = "holocarp"
gold_core_spawnable = NO_SPAWN
greyscale_config = NONE
basic_mob_flags = DEL_ON_DEATH
cell_line = NONE
regenerate_colour = "#ffffff"
/// Holocarp don't eat food
/mob/living/basic/carp/holographic/setup_eating()
return FALSE
/**
* Pet carp, abstract carp which just holds some shared properties.
*/
/mob/living/basic/carp/pet
speak_emote = list("squeaks")
gold_core_spawnable = NO_SPAWN
gender = FEMALE // Both current existing pet carp are female but you can remove this if someone else gets a male one?
ai_controller = /datum/ai_controller/basic_controller/carp/pet
/mob/living/basic/carp/pet/Initialize(mapload)
. = ..()
AddElement(/datum/element/ai_retaliate)
AddElement(/datum/element/pet_bonus, "bloops happily!")
/**
* Lia - Sometimes the pet of the Head of Security.
* Has a lot more health than a normal carp because she's meant to be a mildly more threatening pet to have to assassinate than an aging corgi.
*/
/mob/living/basic/carp/pet/lia
name = "Lia"
real_name = "Lia"
desc = "A failed experiment of Nanotrasen to create weaponised carp technology. This less than intimidating carp now serves as the Head of Security's pet."
faction = list("neutral")
maxHealth = 200
health = 200
icon_dead = "magicarp_dead"
icon_gib = "magicarp_gib"
icon_living = "magicarp"
icon_state = "magicarp"
greyscale_config = NONE
/// Boosted chance for Cayenne to be silver
#define RARE_CAYENNE_CHANCE 10
/**
* Cayenne - Loyal member of the nuclear operatives.
* Spawns in the nuke op shuttle, can be made sapient if they want to do that for some reason.
* Is very talented and also capable of holding the nuclear disk.
*/
/mob/living/basic/carp/pet/cayenne
name = "Cayenne"
real_name = "Cayenne"
desc = "A failed Syndicate experiment in weaponized space carp technology, it now serves as a lovable mascot."
faction = list(ROLE_SYNDICATE)
/// Overlay to apply to display the disk
var/mutable_appearance/disk_overlay
/// Overlay to apply over the disk so it looks like cayenne is holding it
var/mutable_appearance/mouth_overlay
/mob/living/basic/carp/pet/cayenne/Initialize(mapload)
. = ..()
var/datum/callback/got_disk = CALLBACK(src, PROC_REF(got_disk))
var/datum/callback/display_disk = CALLBACK(src, PROC_REF(display_disk))
AddComponent(/datum/component/nuclear_bomb_operator, got_disk, display_disk)
/mob/living/basic/carp/pet/cayenne/apply_colour()
if (prob(RARE_CAYENNE_CHANCE))
set_greyscale(colors = list(COLOR_CARP_SILVER))
else
return ..()
/// She did it! Treats for Cayenne!
/mob/living/basic/carp/pet/cayenne/proc/got_disk(obj/item/disk/nuclear/disky)
if (disky.fake) // Never mind she didn't do it
return
client.give_award(/datum/award/achievement/misc/cayenne_disk, src)
/// Adds an overlay to show the disk on Cayenne
/mob/living/basic/carp/pet/cayenne/proc/display_disk(list/new_overlays)
if (!mouth_overlay)
mouth_overlay = mutable_appearance(SSgreyscale.GetColoredIconByType(/datum/greyscale_config/carp/disk_mouth, greyscale_colors), "disk_mouth")
new_overlays += mouth_overlay
if (!disk_overlay)
disk_overlay = mutable_appearance('icons/mob/simple/carp.dmi', "disk_overlay")
new_overlays += disk_overlay
#undef RARE_CAYENNE_CHANCE
@@ -0,0 +1,29 @@
/**
* # Magicarp Bolt
* Holder ability simply for "firing a projectile with a cooldown".
* Probably won't do anything if assigned via VV unless you also VV in a projectile for it.
*/
/datum/action/cooldown/mob_cooldown/projectile_attack/magicarp_bolt
name = "Magicarp Blast"
desc = "Unleash a bolt of magical force at a target you click on."
button_icon = 'icons/obj/weapons/guns/projectiles.dmi'
button_icon_state = "arcane_barrage"
cooldown_time = 5 SECONDS
projectile_sound = 'sound/weapons/emitter.ogg'
melee_cooldown_time = 0 SECONDS // Without this they become extremely hesitant to bite anyone ever
shared_cooldown = MOB_SHARED_COOLDOWN_2
/datum/action/cooldown/mob_cooldown/projectile_attack/magicarp_bolt/chaos/attack_sequence(mob/living/firer, atom/target)
playsound(get_turf(firer), projectile_sound, 100, vary = TRUE)
return ..()
/// Chaos variant picks one from a list
/datum/action/cooldown/mob_cooldown/projectile_attack/magicarp_bolt/chaos
/// List of things we can cast
var/list/permitted_projectiles = list()
/datum/action/cooldown/mob_cooldown/projectile_attack/magicarp_bolt/chaos/attack_sequence(mob/living/firer, atom/target)
if (!length(permitted_projectiles))
return
projectile_type = pick(permitted_projectiles)
return ..()
@@ -0,0 +1,74 @@
#define MAGICARP_SPELL_TARGET_SEEK_RANGE 4
/datum/pet_command/point_targetting/attack/carp
attack_behaviour = /datum/ai_behavior/basic_melee_attack/carp
/datum/pet_command/point_targetting/use_ability/magicarp
pet_ability_key = BB_MAGICARP_SPELL
/datum/ai_planning_subtree/basic_melee_attack_subtree/carp
melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/carp
/datum/ai_behavior/basic_melee_attack/carp
action_cooldown = 1.5 SECONDS
/datum/ai_planning_subtree/attack_obstacle_in_path/carp
attack_behaviour = /datum/ai_behavior/attack_obstructions/carp
/datum/ai_behavior/attack_obstructions/carp
action_cooldown = 1.5 SECONDS
/// As basic attack tree but interrupt if your health gets low or if your spell is off cooldown
/datum/ai_planning_subtree/basic_melee_attack_subtree/magicarp
melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/carp/magic
/// Interrupt your attack chain if: you have a spell, it's not on cooldown, and it has a target
/datum/ai_behavior/basic_melee_attack/carp/magic
/datum/ai_behavior/basic_melee_attack/carp/magic/perform(delta_time, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key, health_ratio_key)
var/datum/action/cooldown/using_action = controller.blackboard[BB_MAGICARP_SPELL]
if (QDELETED(using_action))
return ..()
if (!controller.blackboard[BB_MAGICARP_SPELL_SPECIAL_TARGETTING] && using_action.IsAvailable())
finish_action(controller, succeeded = FALSE)
return
return ..()
/**
* Find a target for the magicarp's spell
* This gets weird because different spells want different targetting
* but I didn't want a new ai controller for every different spell
*/
/datum/ai_planning_subtree/find_nearest_magicarp_spell_target
/datum/ai_planning_subtree/find_nearest_magicarp_spell_target/SelectBehaviors(datum/ai_controller/controller, delta_time)
var/datum/action/cooldown/using_action = controller.blackboard[BB_MAGICARP_SPELL]
if (QDELETED(using_action))
return
if (!using_action.IsAvailable())
return
var/spell_targetting = controller.blackboard[BB_MAGICARP_SPELL_SPECIAL_TARGETTING]
if (!spell_targetting)
controller.queue_behavior(/datum/ai_behavior/find_potential_targets/nearest/magicarp, BB_MAGICARP_SPELL_TARGET, BB_TARGETTING_DATUM, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
return
switch(spell_targetting)
if (MAGICARP_SPELL_CORPSES)
controller.queue_behavior(/datum/ai_behavior/find_and_set/friendly_corpses, BB_MAGICARP_SPELL_TARGET, MAGICARP_SPELL_TARGET_SEEK_RANGE)
return
if (MAGICARP_SPELL_OBJECTS)
controller.queue_behavior(/datum/ai_behavior/find_and_set/animatable, BB_MAGICARP_SPELL_TARGET, MAGICARP_SPELL_TARGET_SEEK_RANGE)
return
if (MAGICARP_SPELL_WALLS)
controller.queue_behavior(/datum/ai_behavior/find_and_set/nearest_wall, BB_MAGICARP_SPELL_TARGET, MAGICARP_SPELL_TARGET_SEEK_RANGE)
return
/// This subtype only exists because if you queue multiple of the same action with different arguments it deletes their stored arguments
/datum/ai_behavior/find_potential_targets/nearest/magicarp
/// Then use it on that target
/datum/ai_planning_subtree/targetted_mob_ability/magicarp
ability_key = BB_MAGICARP_SPELL
target_key = BB_MAGICARP_SPELL_TARGET
use_ability_behaviour = /datum/ai_behavior/try_mob_ability/and_clear_target
@@ -0,0 +1,62 @@
/**
* AI controller for carp
* Expected flow is:
* * If health is low, mark that we want to run away.
* * If we want to run away, find nearest target and run out of view of it.
* * Look for anything we want to eat in the area and target it.
* * If we don't have a target already, find something to attack.
* * Go and attack our target (which might be food, or might be a mob).
*/
/datum/ai_controller/basic_controller/carp
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/allow_items(),
BB_PET_TARGETTING_DATUM = new /datum/targetting_datum/not_friends()
)
ai_movement = /datum/ai_movement/basic_avoidance
idle_behavior = /datum/idle_behavior/idle_random_walk
planning_subtrees = list(
/datum/ai_planning_subtree/pet_planning,
/datum/ai_planning_subtree/simple_find_nearest_target_to_flee,
/datum/ai_planning_subtree/flee_target,
/datum/ai_planning_subtree/find_food,
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/attack_obstacle_in_path/carp,
/datum/ai_planning_subtree/basic_melee_attack_subtree/carp,
)
/**
* Carp which bites back, but doesn't look for targets.
* 'Not hunting targets' includes food (and can rings), because they have been well trained.
*/
/datum/ai_controller/basic_controller/carp/pet
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/ignore_faction(),
BB_PET_TARGETTING_DATUM = new /datum/targetting_datum/not_friends()
)
ai_traits = STOP_MOVING_WHEN_PULLED
planning_subtrees = list(
/datum/ai_planning_subtree/pet_planning,
/datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee,
/datum/ai_planning_subtree/flee_target,
/datum/ai_planning_subtree/target_retaliate,
/datum/ai_planning_subtree/attack_obstacle_in_path/carp,
/datum/ai_planning_subtree/basic_melee_attack_subtree/carp,
)
/**
* AI for carp with a spell.
* Flow is basically the same as regular carp, except it will try and cast a spell at its target whenever possible and not fleeing.
*/
/datum/ai_controller/basic_controller/carp/ranged
planning_subtrees = list(
/datum/ai_planning_subtree/pet_planning,
/datum/ai_planning_subtree/simple_find_nearest_target_to_flee,
/datum/ai_planning_subtree/flee_target,
/datum/ai_planning_subtree/find_food,
/datum/ai_planning_subtree/find_nearest_magicarp_spell_target,
/datum/ai_planning_subtree/targetted_mob_ability/magicarp,
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/attack_obstacle_in_path/carp,
/datum/ai_planning_subtree/basic_melee_attack_subtree/magicarp,
)
@@ -0,0 +1,136 @@
/// A list of spells magicarp can use and a corresponding name prefix to apply
GLOBAL_LIST_INIT(magicarp_spell_types, list(
/obj/projectile/magic/animate = "dancing",
/obj/projectile/magic/arcane_barrage = "arcane",
/obj/projectile/magic/change = "transforming",
/obj/projectile/magic/death = "grim",
/obj/projectile/magic/door = "unbarred",
/obj/projectile/magic/fireball = "blazing",
/obj/projectile/magic/resurrection = "vital",
/obj/projectile/magic/spellblade = "vorpal",
/obj/projectile/magic/teleport = "warping",
/obj/projectile/magic/babel = "babbling",
))
/// A reduced list of spells for magicarp spawned in xenobiology, less disruptive
GLOBAL_LIST_INIT(xenobiology_magicarp_spell_types, list(
/obj/projectile/magic/animate = "dancing",
/obj/projectile/magic/teleport = "warping",
/obj/projectile/magic/door = "unbarred",
/obj/projectile/magic/fireball = "blazing",
/obj/projectile/magic/spellblade = "vorpal",
/obj/projectile/magic/arcane_barrage = "arcane",
))
/// Associative list of magicarp spells to colours, expand this list if you expand the other lists
GLOBAL_LIST_INIT(magicarp_spell_colours, list(
/obj/projectile/magic/animate = COLOR_CARP_RUSTY,
/obj/projectile/magic/arcane_barrage = COLOR_CARP_PURPLE,
/obj/projectile/magic/change = COLOR_CARP_PINK,
/obj/projectile/magic/death = COLOR_CARP_DARK_BLUE,
/obj/projectile/magic/door = COLOR_CARP_GREEN,
/obj/projectile/magic/fireball = COLOR_CARP_RED,
/obj/projectile/magic/resurrection = COLOR_CARP_PALE_GREEN,
/obj/projectile/magic/spellblade = COLOR_CARP_SILVER,
/obj/projectile/magic/teleport = COLOR_CARP_GRAPE,
/obj/projectile/magic/babel = COLOR_CARP_BROWN,
))
/**
* # Magicarp
*
* Carp who can cast spells!
* Mostly created via wizard event or transformation.
* Come in 'does one thing' and 'does random things' varieties.
*/
/mob/living/basic/carp/magic
name = "magicarp"
desc = "50% magic, 50% carp, 100% horrible."
icon_gib = "magicarp_gib"
maxHealth = 50
health = 50
gold_core_spawnable = NO_SPAWN
greyscale_config = /datum/greyscale_config/carp_magic
ai_controller = /datum/ai_controller/basic_controller/carp/ranged
tamed_commands = list(
/datum/pet_command/idle,
/datum/pet_command/free,
/datum/pet_command/follow,
/datum/pet_command/point_targetting/attack/carp,
/datum/pet_command/point_targetting/use_ability/magicarp,
)
/// List of all projectiles we can fire.
/// Non-static, because subtypes can have their own lists.
var/list/allowed_projectile_types
/// Our magic attack
var/datum/action/cooldown/mob_cooldown/projectile_attack/magicarp_bolt/spell
/mob/living/basic/carp/magic/Initialize(mapload)
. = ..()
allowed_projectile_types = spell_list()
assign_spell()
/// Returns the list of spells we are allowed to cast
/mob/living/basic/carp/magic/proc/spell_list()
return GLOB.magicarp_spell_types
/// Updates name based on chosen spell
/mob/living/basic/carp/magic/proc/assign_spell()
var/obj/projectile/spell_type = pick(allowed_projectile_types)
name = "[GLOB.magicarp_spell_types[spell_type]] [name]"
set_greyscale(colors = list(GLOB.magicarp_spell_colours[spell_type]))
spell = new (src)
spell.projectile_type = spell_type
spell.button_icon_state = initial(spell_type.icon_state)
spell.Grant(src)
ai_controller.blackboard[BB_MAGICARP_SPELL] = spell
assign_spell_ai(spell_type)
/// If you have certain spells, use a different targetting datum
/mob/living/basic/carp/magic/proc/assign_spell_ai(spell_type)
var/static/list/spell_special_targetting = list(
/obj/projectile/magic/animate = MAGICARP_SPELL_OBJECTS,
/obj/projectile/magic/door = MAGICARP_SPELL_WALLS,
/obj/projectile/magic/resurrection = MAGICARP_SPELL_CORPSES,
)
ai_controller.blackboard[BB_MAGICARP_SPELL_SPECIAL_TARGETTING] = spell_special_targetting[spell_type]
/// Shoot when you click away from you
/mob/living/basic/carp/magic/RangedAttack(atom/atom_target, modifiers)
spell.Trigger(target = atom_target)
/***
* # Chaos Magicarp
*
* Fires a random spell (and changes colour) every time, also beefier.
* Sometimes actually more durable than the much larger megacarp. That's magic for you.
* They trade off for this with a tendency to fireball themselves.
*/
/mob/living/basic/carp/magic/chaos
name = "chaos magicarp"
desc = "50% carp, 100% magic, 150% horrible."
maxHealth = 75
health = 75
/mob/living/basic/carp/magic/chaos/assign_spell()
var/datum/action/cooldown/mob_cooldown/projectile_attack/magicarp_bolt/chaos/chaos_bolt = new(src)
chaos_bolt.permitted_projectiles = allowed_projectile_types
chaos_bolt.Grant(src)
spell = chaos_bolt
ai_controller.blackboard[BB_MAGICARP_SPELL] = spell
RegisterSignal(spell, COMSIG_ACTION_TRIGGER, PROC_REF(apply_colour))
/// Has a more limited spell pool but can appear from gold slime cores
/mob/living/basic/carp/magic/xenobiology
gold_core_spawnable = HOSTILE_SPAWN
/mob/living/basic/carp/magic/xenobiology/spell_list()
return GLOB.xenobiology_magicarp_spell_types
/mob/living/basic/carp/magic/chaos/xenobiology
gold_core_spawnable = HOSTILE_SPAWN
/mob/living/basic/carp/magic/chaos/xenobiology/spell_list()
return GLOB.xenobiology_magicarp_spell_types
@@ -0,0 +1,34 @@
/**
* ## Mega Space Carp
*
* A bigger space carp with more health and greater ability to smash objects.
* Brings in some buddies when it starts fleeing as a distraction.
* Has mildly randomised stats for some inexplicable reason, makes it somewhat more like a randomised Diablo mob.
*/
/mob/living/basic/carp/mega
icon = 'icons/mob/simple/broadMobs.dmi'
name = "Mega Space Carp"
desc = "A ferocious, fang bearing creature that resembles a shark. This one seems especially ticked off."
icon_state = "megacarp_greyscale"
icon_living = "megacarp_greyscale"
icon_dead = "megacarp_dead_greyscale"
icon_gib = "megacarp_gib"
health_doll_icon = "megacarp"
maxHealth = 20
health = 20
pixel_x = -16
base_pixel_x = -16
mob_size = MOB_SIZE_LARGE
obj_damage = 80
cell_line = CELL_LINE_TABLE_MEGACARP
ridable_data = /datum/component/riding/creature/megacarp
greyscale_config = /datum/greyscale_config/carp_mega
butcher_results = list(/obj/item/food/fishmeat/carp = 2, /obj/item/stack/sheet/animalhide/carp = 3)
/mob/living/basic/carp/mega/Initialize(mapload)
. = ..()
name = "[pick(GLOB.megacarp_first_names)] [pick(GLOB.megacarp_last_names)]"
melee_damage_lower += rand(2, 10)
melee_damage_upper += rand(10,20)
maxHealth += rand(30,60)
health = maxHealth