mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 23:27:34 +01:00
Simple animal xenos are now basic animal xenos (#82187)
## About The Pull Request We currently have 2 types of xenos in the codebase, simple animal and carbon. I'd like to unite them both under basic, and I thought I should go for simple animal first since it's more of a conversion than a remake. This helps set a base for a future basic-only xeno, which would require the following: - Basic mobs (or just anything than Carbon) to have Organs, which we can then use for things like referring to their plasma sac for egg-laying, etc. - All xeno types having a basic mob variant, preferably with an AI so they would work without a player. - Something be done about larva, either we'd split basic xenos into "larva" and "adult" (like carbon) or have it be a separate path that can also have organs so they can still have hivemind. Everything else seems to have been done overtime as simple animals have been converted to basic (HUDs and holding things now seem possible, etc.) Even if this doesn't work out, at least this cuts off a good chunk of the remaining simple animals to convert to basic. Sprites used (for mapping helpers): Fire medkit Toxin medkit Oingo Boingo punch face (i tried to shrink it down) ## Why It's Good For The Game This helps advance us move away from simple animals, and helps move carbon xenos to basic mob later too if that's what we want to go for. ## Changelog 🆑 refactor: Xenomorphs (Lavaland & Oldstation ones) are now basic mobs. /🆑
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
/mob/living/basic/alien
|
||||
name = "alien hunter"
|
||||
desc = "Hiss!"
|
||||
icon = 'icons/mob/nonhuman-player/alien.dmi'
|
||||
icon_state = "alienh"
|
||||
icon_living = "alienh"
|
||||
icon_dead = "alienh_dead"
|
||||
icon_gib = "syndicate_gib"
|
||||
gender = FEMALE
|
||||
status_flags = CANPUSH
|
||||
butcher_results = list(
|
||||
/obj/item/food/meat/slab/xeno = 4,
|
||||
/obj/item/stack/sheet/animalhide/xeno = 1,
|
||||
)
|
||||
|
||||
maxHealth = 125
|
||||
health = 125
|
||||
bubble_icon = "alien"
|
||||
combat_mode = TRUE
|
||||
faction = list(ROLE_ALIEN)
|
||||
|
||||
// Going for a dark purple here
|
||||
lighting_cutoff_red = 30
|
||||
lighting_cutoff_green = 15
|
||||
lighting_cutoff_blue = 50
|
||||
unique_name = TRUE
|
||||
|
||||
basic_mob_flags = FLAMMABLE_MOB
|
||||
speed = 0
|
||||
obj_damage = 60
|
||||
|
||||
speak_emote = list("hisses")
|
||||
melee_damage_lower = 25
|
||||
melee_damage_upper = 25
|
||||
attack_verb_continuous = "slashes"
|
||||
attack_verb_simple = "slash"
|
||||
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_vis_effect = ATTACK_EFFECT_CLAW
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
death_sound = 'sound/voice/hiss6.ogg'
|
||||
death_message = "lets out a waning guttural screech, green blood bubbling from its maw..."
|
||||
|
||||
habitable_atmos = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
unsuitable_atmos_damage = FALSE
|
||||
unsuitable_heat_damage = 20
|
||||
|
||||
ai_controller = /datum/ai_controller/basic_controller/alien
|
||||
|
||||
///List of loot items to drop when deleted, if this is set then we apply DEL_ON_DEATH
|
||||
var/list/loot
|
||||
///Boolean on whether the xeno can plant weeds.
|
||||
var/can_plant_weeds = TRUE
|
||||
///Boolean on whether the xeno can lay eggs.
|
||||
var/can_lay_eggs = FALSE
|
||||
|
||||
/mob/living/basic/alien/Initialize(mapload)
|
||||
. = ..()
|
||||
if(length(loot))
|
||||
basic_mob_flags |= DEL_ON_DEATH
|
||||
loot = string_list(loot)
|
||||
AddElement(/datum/element/death_drops, loot)
|
||||
AddElement(/datum/element/footstep, footstep_type = FOOTSTEP_MOB_CLAW)
|
||||
|
||||
/mob/living/basic/alien/get_butt_sprite()
|
||||
return BUTT_SPRITE_XENOMORPH
|
||||
|
||||
///Places alien weeds on the turf the mob is currently standing on.
|
||||
/mob/living/basic/alien/proc/place_weeds()
|
||||
if(!isturf(loc) || isspaceturf(loc))
|
||||
return
|
||||
if(locate(/obj/structure/alien/weeds/node) in get_turf(src))
|
||||
return
|
||||
visible_message(span_alertalien("[src] plants some alien weeds!"))
|
||||
new /obj/structure/alien/weeds/node(loc)
|
||||
|
||||
///Lays an egg on the turf the mob is currently standing on.
|
||||
/mob/living/basic/alien/proc/lay_alien_egg()
|
||||
if(!isturf(loc) || isspaceturf(loc))
|
||||
return
|
||||
if(locate(/obj/structure/alien/egg) in get_turf(src))
|
||||
return
|
||||
visible_message(span_alertalien("[src] lays an egg!"))
|
||||
new /obj/structure/alien/egg(loc)
|
||||
@@ -0,0 +1,73 @@
|
||||
/datum/ai_controller/basic_controller/alien
|
||||
ai_movement = /datum/ai_movement/basic_avoidance
|
||||
idle_behavior = /datum/idle_behavior/idle_random_walk
|
||||
blackboard = list(
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
)
|
||||
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/attack_obstacle_in_path,
|
||||
/datum/ai_planning_subtree/basic_melee_attack_subtree,
|
||||
)
|
||||
|
||||
movement_delay = 0.8 SECONDS
|
||||
|
||||
/datum/ai_controller/basic_controller/alien/sentinel
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/attack_obstacle_in_path,
|
||||
/datum/ai_planning_subtree/basic_ranged_attack_subtree/alien,
|
||||
)
|
||||
|
||||
/datum/ai_controller/basic_controller/alien/drone
|
||||
idle_behavior = /datum/idle_behavior/idle_random_walk/plant_weeds
|
||||
|
||||
/datum/ai_controller/basic_controller/alien/queen
|
||||
idle_behavior = /datum/idle_behavior/idle_random_walk/plant_weeds/queen
|
||||
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/attack_obstacle_in_path,
|
||||
/datum/ai_planning_subtree/basic_ranged_attack_subtree/alien,
|
||||
)
|
||||
|
||||
/**
|
||||
* Alien projectile
|
||||
* Try to avoid friendly fire, and has a 3 second delay.
|
||||
*/
|
||||
/datum/ai_planning_subtree/basic_ranged_attack_subtree/alien
|
||||
ranged_attack_behavior = /datum/ai_behavior/basic_ranged_attack/alien
|
||||
|
||||
/datum/ai_behavior/basic_ranged_attack/alien
|
||||
action_cooldown = 3 SECONDS
|
||||
required_distance = 3
|
||||
avoid_friendly_fire = TRUE
|
||||
|
||||
/datum/idle_behavior/idle_random_walk/plant_weeds
|
||||
var/plant_cooldown = 30
|
||||
var/plants_off = 0
|
||||
|
||||
/datum/idle_behavior/idle_random_walk/plant_weeds/perform_idle_behavior(seconds_per_tick, datum/ai_controller/controller)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return .
|
||||
plant_cooldown--
|
||||
var/mob/living/basic/alien/alien_pawn = controller.pawn
|
||||
if(alien_pawn.can_plant_weeds && !plants_off && plant_cooldown <= 0)
|
||||
plant_cooldown = initial(plant_cooldown)
|
||||
alien_pawn.place_weeds()
|
||||
|
||||
/datum/idle_behavior/idle_random_walk/plant_weeds/queen
|
||||
var/eggs_off = 0
|
||||
var/egg_cooldown = 30
|
||||
|
||||
/datum/idle_behavior/idle_random_walk/plant_weeds/queen/perform_idle_behavior(seconds_per_tick, datum/ai_controller/controller)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return .
|
||||
egg_cooldown--
|
||||
var/mob/living/basic/alien/alien_pawn = controller.pawn
|
||||
if(alien_pawn.can_lay_eggs && !eggs_off && egg_cooldown <= 0)
|
||||
egg_cooldown = initial(egg_cooldown)
|
||||
alien_pawn.lay_alien_egg()
|
||||
@@ -0,0 +1,9 @@
|
||||
/mob/living/basic/alien/drone
|
||||
name = "alien drone"
|
||||
icon_state = "aliend"
|
||||
icon_living = "aliend"
|
||||
icon_dead = "aliend_dead"
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
|
||||
ai_controller = /datum/ai_controller/basic_controller/alien/drone
|
||||
@@ -0,0 +1,60 @@
|
||||
/mob/living/basic/alien/maid
|
||||
name = "lusty xenomorph maid"
|
||||
melee_damage_lower = 0
|
||||
melee_damage_upper = 0
|
||||
combat_mode = FALSE
|
||||
friendly_verb_continuous = "caresses"
|
||||
friendly_verb_simple = "caress"
|
||||
obj_damage = 0
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
gold_core_spawnable = HOSTILE_SPAWN
|
||||
icon_state = "maid"
|
||||
icon_living = "maid"
|
||||
icon_dead = "maid_dead"
|
||||
|
||||
/mob/living/basic/alien/maid/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/cleaning)
|
||||
RegisterSignal(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(pre_attack))
|
||||
|
||||
///Handles the maid attacking other players, cancelling the attack to clean up instead.
|
||||
/mob/living/basic/alien/maid/proc/pre_attack(mob/living/puncher, atom/target)
|
||||
SIGNAL_HANDLER
|
||||
target.wash(CLEAN_SCRUB)
|
||||
if(istype(target, /obj/effect/decal/cleanable))
|
||||
visible_message(span_notice("[src] cleans up \the [target]."))
|
||||
else
|
||||
visible_message(span_notice("[src] polishes \the [target]."))
|
||||
return COMPONENT_HOSTILE_NO_ATTACK
|
||||
|
||||
/**
|
||||
* Barmaid special type
|
||||
* Spawns on emergency shuttles, has access to them and godmode while inside of them.
|
||||
*/
|
||||
/mob/living/basic/alien/maid/barmaid
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
name = "Barmaid"
|
||||
desc = "A barmaid, a maiden found in a bar."
|
||||
pass_flags = PASSTABLE
|
||||
unique_name = FALSE
|
||||
initial_language_holder = /datum/language_holder/universal
|
||||
|
||||
ai_controller = null //they don't have their own AI and can uniquely only be controlled by players.
|
||||
|
||||
///The access card we use to store access to the emergency shuttle.
|
||||
var/obj/item/card/id/access_card
|
||||
|
||||
/mob/living/basic/alien/maid/barmaid/Initialize(mapload)
|
||||
. = ..()
|
||||
// Simple bot ID card that can hold all accesses. Someone turn access into a component at some point, please.
|
||||
access_card = new /obj/item/card/id/advanced/simple_bot(src)
|
||||
|
||||
var/datum/id_trim/job/cap_trim = SSid_access.trim_singletons_by_path[/datum/id_trim/job/captain]
|
||||
access_card.add_access(cap_trim.access + cap_trim.wildcard_access + list(ACCESS_CENT_BAR))
|
||||
|
||||
ADD_TRAIT(access_card, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT)
|
||||
AddComponentFrom(ROUNDSTART_TRAIT, /datum/component/area_based_godmode, area_type = /area/shuttle/escape, allow_area_subtypes = TRUE)
|
||||
|
||||
/mob/living/basic/alien/maid/barmaid/Destroy()
|
||||
QDEL_NULL(access_card)
|
||||
return ..()
|
||||
@@ -0,0 +1,40 @@
|
||||
/mob/living/basic/alien/queen
|
||||
name = "alien queen"
|
||||
icon_state = "alienq"
|
||||
icon_living = "alienq"
|
||||
icon_dead = "alienq_dead"
|
||||
health = 250
|
||||
maxHealth = 250
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
status_flags = NONE //can't shove the queen, kiddo.
|
||||
unique_name = FALSE
|
||||
|
||||
ai_controller = /datum/ai_controller/basic_controller/alien/queen
|
||||
|
||||
///The type of projectile that fires from attacks.
|
||||
var/projectiletype = /obj/projectile/neurotoxin/damaging
|
||||
///The sound that plays when the projectile is fired.
|
||||
var/projectilesound = 'sound/weapons/pierce.ogg'
|
||||
|
||||
/mob/living/basic/alien/queen/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/ranged_attacks, projectile_type = projectiletype, projectile_sound = projectilesound, cooldown_time = 1 SECONDS)
|
||||
|
||||
/mob/living/basic/alien/queen/large
|
||||
name = "alien empress"
|
||||
icon = 'icons/mob/nonhuman-player/alienqueen.dmi'
|
||||
icon_state = "alienq"
|
||||
icon_living = "alienq"
|
||||
icon_dead = "alienq_dead"
|
||||
health_doll_icon = "alienq"
|
||||
bubble_icon = "alienroyal"
|
||||
maxHealth = 400
|
||||
health = 400
|
||||
butcher_results = list(
|
||||
/obj/item/food/meat/slab/xeno = 10,
|
||||
/obj/item/stack/sheet/animalhide/xeno = 2,
|
||||
)
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/mob/living/basic/alien/sentinel
|
||||
name = "alien sentinel"
|
||||
icon_state = "aliens"
|
||||
icon_living = "aliens"
|
||||
icon_dead = "aliens_dead"
|
||||
health = 150
|
||||
maxHealth = 150
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
|
||||
ai_controller = /datum/ai_controller/basic_controller/alien/sentinel
|
||||
|
||||
///The type of projectile that fires from attacks.
|
||||
var/projectiletype = /obj/projectile/neurotoxin/damaging
|
||||
///The sound that plays when the projectile is fired.
|
||||
var/projectilesound = 'sound/weapons/pierce.ogg'
|
||||
|
||||
/mob/living/basic/alien/sentinel/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/ranged_attacks, projectile_type = projectiletype, projectile_sound = projectilesound, cooldown_time = 1 SECONDS)
|
||||
Reference in New Issue
Block a user