diff --git a/modular_chomp/code/modules/mob/living/simple_mob/subtypes/humanoid/eclipse/eclipse.dm b/modular_chomp/code/modules/mob/living/simple_mob/subtypes/humanoid/eclipse/eclipse.dm new file mode 100644 index 0000000000..6d2082e5bf --- /dev/null +++ b/modular_chomp/code/modules/mob/living/simple_mob/subtypes/humanoid/eclipse/eclipse.dm @@ -0,0 +1,586 @@ +/////////////////////////////// +// Eclipse Mobs Go Here +/////////////////////////////// + +// Basic Version, the knife merc, or blood ininiate. Don't use them, or the eclipsesolar, lunar base versions either. +/mob/living/simple_mob/humanoid/eclipse + name = "Eclipse Initiate" + tt_desc = "E Homo sapiens" + desc = "A silver cladded, dangerous looking indivual." + icon = 'modular_chomp/icons/mob/animal_ch.dmi' + icon_state = "syndicate" + icon_living = "syndicate" + icon_dead = "statisgem" + icon_gib = "syndicate_gib" + + faction = "eclipse" + movement_cooldown = 3 + + status_flags = 0 + + response_help = "pokes" + response_disarm = "shoves" + response_harm = "hits" + + health = 100 + maxHealth = 100 + harm_intent_damage = 5 + melee_damage_lower = 15 //Tac Knife damage + melee_damage_upper = 15 + attack_sharp = 1 //CHOMPEdit + attack_edge = 1 + attacktext = list("slashed", "stabbed") + projectile_dispersion = 8 + projectile_accuracy = -20 + armor = list(melee = 50, bullet = 50, laser = 50, energy = 50, bomb = 50, bio = 100, rad = 100) // Simple mob immunuties plus base Eclipse foe stuff + + can_be_drop_prey = FALSE //CHOMP Add + pass_flags = PASSTABLE //mostly for the melee mobs. + softfall = TRUE //highly advanced spacesuit stuff + + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + heat_damage_per_tick = 0 + + projectiletype = /obj/item/projectile/bullet/pistol/medium. + projectilesound = 'sound/weapons/Gunshot_light.ogg' + + needs_reload = TRUE + reload_max = 7 // Not the best default, but it fits the pistol + ai_holder_type = /datum/ai_holder/simple_mob/merc/eclipse/ranged + + // Grenade special attack vars + var/grenade_type = /obj/item/weapon/grenade/shooter/energy/laser + var/grenade_timer = 50 //CHOMPEdit + special_attack_cooldown = 45 SECONDS + special_attack_min_range = 2 + special_attack_max_range = 7 + + +//////////////////////////////// +// Grenade Attack +//////////////////////////////// + +// Any merc can use this, just set special_attack_charges to a positive value + +// Check if we should bother with the grenade +/mob/living/simple_mob/humanoid/eclipse/should_special_attack(atom/A) + var/mob_count = 0 // Are there enough mobs to consider grenading? + var/turf/T = get_turf(A) + for(var/mob/M in range(T, 2)) + if(M.faction == faction) // Don't grenade our friends + return FALSE + if(M in oview(src, special_attack_max_range)) // And lets check if we can actually see at least two people before we throw a grenade + if(!M.stat) // Dead things don't warrant a grenade + mob_count ++ + if(mob_count < 2) + return FALSE + else + return TRUE + +// Yes? Throw the grenade +/mob/living/simple_mob/humanoid/eclipse/do_special_attack(atom/A) + set waitfor = FALSE + set_AI_busy(TRUE) + + var/obj/item/weapon/grenade/G = new grenade_type(get_turf(src)) + if(istype(G)) + G.throw_at(A, G.throw_range, G.throw_speed, src) + G.det_time = grenade_timer //CHOMPEdit + G.activate(src) //CHOMPEdit + special_attack_charges = max(special_attack_charges-1, 0) + + set_AI_busy(FALSE) + +//////////////////////////////// +// Stealing Merc AI Types +//////////////////////////////// +/datum/ai_holder/simple_mob/merc/eclipse + threaten = FALSE + vision_range = 8 + +/datum/ai_holder/simple_mob/merc/eclipse/hunter + vision_range = 10 + +/datum/ai_holder/simple_mob/merc/eclipse/ranged + pointblank = TRUE // They get close? Just shoot 'em! + firing_lanes = TRUE // But not your buddies! + +/datum/ai_holder/simple_mob/merc/eclipse/ranged/sniper + vision_range = 15 // We're a person with a long-ranged gun. + +/datum/ai_holder/simple_mob/merc/eclipse/ranged/sniper/max_range(atom/movable/AM) + return holder.ICheckRangedAttack(AM) ? 16 : 1 + +//////////////////////////////// +//The solar part of the faction, highly resistant to burns and stuff +/mob/living/simple_mob/humanoid/eclipse/solar + name = "Solar Eclipse Initiate" + desc = "A silver cladded, dangerous looking indivual." + + armor = list(melee = 50, bullet = 50, laser = 95, energy = 95, bomb = 50, bio = 100, rad = 100) //Solar members are nigh immune to burns. + armor_soak = list(melee = 0, bullet = 0, laser = 5, energy = 5, bomb = 0, bio = 0, rad = 0) + +/mob/living/simple_mob/humanoid/eclipse/solar/teslanoodle + name = "Solar Eclipse Tesla Serpent" + health = 125 + maxHealth = 125 + icon_state = "eclipse_tesla" + icon_living = "eclipse_tesla" + reload_max = 5 + + projectiletype = /obj/item/projectile/energy/electrode/eclipse + +/mob/living/simple_mob/humanoid/eclipse/solar/firemoff + name = "Solar Eclipse Inferno Moth" + health = 90 + maxHealth = 90 + icon_state = "eclipse_moth" + icon_living = "eclipse_moth" + reload_max = 10 + + var/energy = 100 + var/max_energy = 100 + + special_attack_cooldown = 5 SECONDS + special_attack_min_range = 0 + special_attack_max_range = 4 + + projectiletype = /obj/item/projectile/energy/blob/moth + + var/datum/effect/effect/system/smoke_spread/fire/smoke_special + +/mob/living/simple_mob/humanoid/eclipse/solar/firemoff/handle_special() + ..() + + if(energy < max_energy) + energy++ + +/mob/living/simple_mob/humanoid/eclipse/solar/firemoff/Stat() + ..() + if(client.statpanel == "Status") + statpanel("Status") + if(emergency_shuttle) + var/eta_status = emergency_shuttle.get_status_panel_eta() + if(eta_status) + stat(null, eta_status) + stat("Energy", energy) + +/mob/living/simple_mob/humanoid/eclipse/solar/firemoff/should_special_attack(atom/A) + if(energy >= 20) + return TRUE + return FALSE + +/mob/living/simple_mob/humanoid/eclipse/solar/firemoff/do_special_attack(atom/A) + . = TRUE + switch(a_intent) + if(I_DISARM) + if(energy < 20) + return FALSE + + energy -= 20 + + if(smoke_special) + smoke_special.set_up(7,0,src) + smoke_special.start() + return TRUE + + return FALSE + + +/mob/living/simple_mob/humanoid/eclipse/solar/snipertesh + name = "Solar Eclipse Sniper" + health = 75 + maxHealth = 75 + movement_cooldown = 1 + + icon_state = "eclipse_snipertesh" + icon_living = "eclipse_snipertesh" + + projectiletype = /obj/item/projectile/beam/sniper/eclipse + + projectile_accuracy = 75 + + reload_max = 5 + reload_time = 2.0 SECONDS + + ai_holder_type = /datum/ai_holder/simple_mob/merc/eclipse/ranged/sniper + + ranged_attack_delay = 0.5 SECONDS + +/mob/living/simple_mob/humanoid/eclipse/solar/snipertesh/ranged_pre_animation(atom/A) + Beam(get_turf(A), icon_state = "sniper_beam", time = 1 SECONDS, maxdistance = 15) + . = ..() + +/mob/living/simple_mob/humanoid/eclipse/solar/snipertesh/shoot_target(atom/A) + set waitfor = FALSE + + if(!istype(A) || QDELETED(A)) + return + + setClickCooldown(get_attack_speed()) + + face_atom(A) + + var/atom/orig_targ = A + + if(ranged_attack_delay) + A = get_turf(orig_targ) + ranged_pre_animation(A) + handle_attack_delay(A, ranged_attack_delay) // This will sleep this proc for a bit, which is why waitfor is false. + + if(needs_reload) + if(reload_count >= reload_max) + try_reload() + return FALSE + + visible_message("\The [src] fires at \the [orig_targ]!") + shoot(A) + if(casingtype) + new casingtype(loc) + + if(ranged_attack_delay) + ranged_post_animation(A) + + return TRUE + + +/mob/living/simple_mob/humanoid/eclipse/solar/radiation + name = "Solar Eclipse Irradiator" + health = 150 + maxHealth = 150 + glow_toggle = TRUE + reload_max = 3 + + icon_state = "eclipse_rad" + icon_living = "eclipse_rad" + + projectiletype = /obj/item/projectile/energy/declone/burn + var/rads = 25 + +/mob/living/simple_mob/humanoid/eclipse/solar/radiation/handle_special() + if(stat != DEAD) + irradiate() + ..() + +/mob/living/simple_mob/humanoid/eclipse/solar/radiation/proc/irradiate() + SSradiation.radiate(src, rads) + + +//The lunar mobs, highly resistant to brute based damage. +/mob/living/simple_mob/humanoid/eclipse/lunar + name = "Lunar Eclipse Initiate" + desc = "A silver cladded, dangerous looking indivual." + + armor = list(melee = 95, bullet = 95, laser = 50, energy = 50, bomb = 50, bio = 100, rad = 100) //Lunar members are nigh immune to burns. + armor_soak = list(melee = 15, bullet = 5, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) //15 because every melee weapon has dumb amount of AP + +/mob/living/simple_mob/humanoid/eclipse/lunar/silvernoodle //Bouncing bullet extreme + name = "Lunar Eclipse Silver Serpent" + health = 125 + maxHealth = 125 + reload_max = 15 + + icon_state = "eclipse_silver" + icon_living = "eclipse_silver" + + projectiletype = /obj/item/projectile/bullet/pistol/medium/ap/eclipse + +/mob/living/simple_mob/humanoid/eclipse/lunar/silvernoodle/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(O.force) + if(prob(15)) + visible_message("\The [O] is absorbed by the armor!") + if(user) + ai_holder.react_to_attack(user) + return + else + ..() + else + to_chat(user, "This weapon is ineffective, it does no damage.") + visible_message("\The [user] gently taps [src] with \the [O].") + +/mob/living/simple_mob/humanoid/eclipse/lunar/silvernoodle/bullet_act(var/obj/item/projectile/Proj) + if(!Proj) return + if(prob(15)) + visible_message("The [Proj] is absorbed by the armor!") + if(Proj.firer) + ai_holder.react_to_attack(Proj.firer) + return + else + ..() + +/mob/living/simple_mob/humanoid/eclipse/lunar/shotgunner //wuff with shotgun + name = "Lunar Eclipse Shotgunner" + health = 90 + maxHealth = 90 + reload_max = 2 + + icon_state = "eclipse_shotwuff" + icon_living = "eclipse_shotwuff" + + projectiletype = /obj/item/projectile/bullet/pellet/shotgun/eclipse + + ranged_attack_delay = 0.5 SECONDS + +/mob/living/simple_mob/humanoid/eclipse/lunar/bulletstorm //tesh got a gun + name = "Lunar Eclipse Judge" + health = 75 + maxHealth = 75 + icon_state = "eclipse_shottesh" + icon_living = "eclipse_shottesh" + + + projectiletype = /obj/item/projectile/bullet/shotgun + reload_max = 6 + + projectile_dispersion = 50 + projectile_accuracy = -100 + base_attack_cooldown = 0 + +/mob/living/simple_mob/humanoid/eclipse/lunar/ravanger //Tanky boi. Very deadly melee + name = "Lunar Eclipse Ravanger" + health = 150 + maxHealth = 150 + icon_state = "eclipse_ravanger" + icon_living = "eclipse_ravanger" + + attack_armor_pen = 25 + + melee_damage_lower = 20 + melee_damage_upper = 25 + + projectiletype = null + ai_holder_type = /datum/ai_holder/simple_mob/merc/eclipse + + var/poison_chance = 50 + var/poison_per_bite = 20 + var/poison_type = "hyperzine" + + + +/obj/item/projectile/energy/blob/moth + splatter = TRUE + damage = 20 + armor_penetration = 25 + my_chems = list("fuel") + modifier_type_to_apply = /datum/modifier/fire + modifier_duration = 6 SECONDS + color = "#38b9ff" + +/obj/item/projectile/bullet/pistol/medium/ap/eclipse + armor_penetration = 25 + ricochets = 1 + ricochets_max = 5 + ricochet_chance = 100 + +/obj/item/projectile/energy/electrode/eclipse + damage = 30 + damage_type = BURN + color = "#38b9ff" + +/obj/item/projectile/bullet/pellet/shotgun/eclipse + pellets = 8 + range_step = 1 + spread_step = 1 + +/obj/item/projectile/beam/sniper/eclipse + armor_penetration = 50 + +/obj/item/projectile/energy/declone/burn + damage = 20 + armor_penetration = 25 + nodamage = 0 + + +////////////////////////////////////////////// +//Boss mob time. Or somewhat bosses anyway. +///////////////////////////////////////////// + +/mob/living/simple_mob/humanoid/eclipse/solar/hellhound + name = "Solar Eclipse Hound" + health = 200 + maxHealth = 200 + ai_holder_type = /datum/ai_holder/simple_mob/intentional/adv_dark_gygax + projectiletype = /obj/item/projectile/energy/flash + movement_cooldown = 1 + melee_damage_lower = 20 + melee_damage_upper = 35 + attack_armor_pen = 20 + reload_max = 5 + icon_state = "eclipse_hound" + icon_living = "eclipse_hound" + size_multiplier = 1.25 + var/poison_chance = 100 + var/poison_per_bite = 8 + var/poison_type = "stoxin" + + +/mob/living/simple_mob/humanoid/eclipse/lunar/wheel + name = "Lunar Eclipse Wheel" + health = 200 + maxHealth = 200 + melee_damage_lower = 15 + melee_damage_upper = 25 + attack_armor_pen = 50 + reload_max = 3 + icon_state = "eclipse_wheel" + icon_living = "eclipse_wheel" + ai_holder_type = /datum/ai_holder/simple_mob/intentional/adv_dark_gygax + projectiletype = /obj/item/projectile/beam/energy_net + movement_cooldown = 2 + + var/cloaked_alpha = 50 // Lower = Harder to see. + var/cloak_cooldown = 5 SECONDS // Amount of time needed to re-cloak after losing it. + var/last_uncloak = 0 // world.time + +/mob/living/simple_mob/humanoid/eclipse/lunar/wheel/cloak() + if(cloaked) + return + animate(src, alpha = cloaked_alpha, time = 1 SECOND) + cloaked = TRUE + + +/mob/living/simple_mob/humanoid/eclipse/lunar/wheel/uncloak() + last_uncloak = world.time // This is assigned even if it isn't cloaked already, to 'reset' the timer if the spider is continously getting attacked. + if(!cloaked) + return + animate(src, alpha = initial(alpha), time = 1 SECOND) + cloaked = FALSE + +// Check if cloaking if possible. +/mob/living/simple_mob/humanoid/eclipse/lunar/wheel/proc/can_cloak() + if(stat) + return FALSE + if(last_uncloak + cloak_cooldown > world.time) + return FALSE + + return TRUE + +// Called by things that break cloaks, like Technomancer wards. +/mob/living/simple_mob/humanoid/eclipse/lunar/wheel/break_cloak() + uncloak() + + +/mob/living/simple_mob/humanoid/eclipse/lunar/wheel/is_cloaked() + return cloaked + + +// Cloaks the spider automatically, if possible. +/mob/living/simple_mob/humanoid/eclipse/lunar/wheel/handle_special() + if(!cloaked && can_cloak()) + cloak() + +/mob/living/simple_mob/humanoid/eclipse/lunar/wheel/bullet_act(obj/item/projectile/P) + . = ..() + break_cloak() + +/mob/living/simple_mob/humanoid/eclipse/lunar/wheel/hit_with_weapon(obj/item/O, mob/living/user, effective_force, hit_zone) + . = ..() + break_cloak() + + + +/mob/living/simple_mob/humanoid/eclipse/solar/hellhound/apply_melee_effects(var/atom/A) + if(isliving(A)) + var/mob/living/L = A + if(L.reagents) + var/target_zone = pick(BP_TORSO,BP_TORSO,BP_TORSO,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_HEAD) + if(L.can_inject(src, null, target_zone)) + inject_poison(L, target_zone) + +// Does actual poison injection, after all checks passed. +/mob/living/simple_mob/humanoid/eclipse/solar/hellhound/proc/inject_poison(mob/living/L, target_zone) + if(prob(poison_chance)) + to_chat(L, "You feel a tiny prick.") + L.reagents.add_reagent(poison_type, poison_per_bite) + +/mob/living/simple_mob/humanoid/eclipse/lunar/ravanger/apply_melee_effects(var/atom/A) + if(isliving(A)) + var/mob/living/L = A + if(L.reagents) + var/target_zone = pick(BP_TORSO,BP_TORSO,BP_TORSO,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_HEAD) + if(L.can_inject(src, null, target_zone)) + inject_poison(L, target_zone) + +// Does actual poison injection, after all checks passed. +/mob/living/simple_mob/humanoid/eclipse/lunar/ravanger/proc/inject_poison(mob/living/L, target_zone) + if(prob(poison_chance)) + to_chat(L, "You feel a tiny prick.") + L.reagents.add_reagent(poison_type, poison_per_bite) + + +///////////////// +//Mecha Killers// +///////////////// +/mob/living/simple_mob/humanoid/eclipse/solar/guardian + name = "Solar Eclipse Guardian" + projectiletype = /obj/item/projectile/ion + icon_state = "eclipse_guardian" + icon_living = "eclipse_guardian" + reload_max = 10 + +/mob/living/simple_mob/humanoid/eclipse/solar/guardian/handle_special() + if(stat != DEAD) + heal_aura() + ..() + +/mob/living/simple_mob/humanoid/eclipse/solar/guardian/proc/heal_aura() + for(var/mob/living/L in view(src, 2)) + if(L.stat == DEAD || !IIsAlly(L)) + continue + L.add_modifier(/datum/modifier/aura/slime_heal, null, src) + + +/mob/living/simple_mob/humanoid/eclipse/lunar/pummler + name = "Lunar Eclipse Punnler" + projectiletype = /obj/item/projectile/bullet/shotgun/ion/eclipse + ai_holder_type = /datum/ai_holder/simple_mob/intentional/adv_dark_gygax + melee_damage_lower = 20 + melee_damage_upper = 30 + attack_armor_pen = 30 + movement_cooldown = 1 + icon_state = "eclipse_pummler" + icon_living = "eclipse_pummler" + reload_max = 25 + size_multiplier = 1.5 + var/poison_per_bite = 5 + var/poison_type = "shredding_nanites" + var/poison_chance = 50 + var/shock_chance = 30 + +/mob/living/simple_mob/humanoid/eclipse/lunar/pummler/apply_melee_effects(var/atom/A) + if(isliving(A)) + var/mob/living/L = A + if(prob(shock_chance)) + A.emp_act(4) //The weakest strength of EMP + playsound(src, 'sound/weapons/Egloves.ogg', 75, 1) + L.Weaken(4) + L.Stun(4) + L.stuttering = max(L.stuttering, 4) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, L) + s.start() + visible_message("The pummler releases a powerful shock!") + else + if(L.reagents) + var/target_zone = pick(BP_TORSO,BP_TORSO,BP_TORSO,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_HEAD) + if(L.can_inject(src, null, target_zone)) + inject_poison(L, target_zone) + + +/mob/living/simple_mob/humanoid/eclipse/lunar/pummler/proc/inject_poison(mob/living/L, target_zone) + if(prob(poison_chance)) + to_chat(L, "You feel a small shock rushing through your veins.") + L.reagents.add_reagent(poison_type, poison_per_bite) + + +/obj/item/projectile/bullet/shotgun/ion/eclipse + damage = 25 + armor_penetration = 30 \ No newline at end of file diff --git a/modular_chomp/code/modules/mob/living/simple_mob/subtypes/humanoid/eclipse/noms.dm b/modular_chomp/code/modules/mob/living/simple_mob/subtypes/humanoid/eclipse/noms.dm new file mode 100644 index 0000000000..5c2766ca2a --- /dev/null +++ b/modular_chomp/code/modules/mob/living/simple_mob/subtypes/humanoid/eclipse/noms.dm @@ -0,0 +1,36 @@ +/mob/living/simple_mob/humanoid/eclipse + vore_active = 1 + vore_capacity = 2 + vore_max_size = RESIZE_HUGE + vore_min_size = RESIZE_SMALL + vore_pounce_chance = 0 // Beat them into crit before eating. + vore_icons = null + + can_be_drop_prey = FALSE //CHOMP Add + +/mob/living/simple_mob/humanoid/eclipse/Login() + . = ..() + if(!riding_datum) + riding_datum = new /datum/riding/simple_mob(src) + verbs |= /mob/living/simple_mob/proc/animal_mount + verbs |= /mob/living/proc/toggle_rider_reins + movement_cooldown = 3 + +/mob/living/simple_mob/humanoid/eclipse/MouseDrop_T(mob/living/M, mob/living/user) + return + +/mob/living/simple_mob/humanoid/eclipse/init_vore() + if(!voremob_loaded) + return + .=..() + var/obj/belly/B = vore_selected + B.name = "stomach" + B.desc = "The fearsome preadtor gets a firm grip upon you, before dunking you into it's maw, then with a powerful swift gulp you're sent tumbling into it's stomach.." + + B.emote_lists[DM_HOLD] = list( + "Your surroundings are momentarily filled with tour predator's pleased rumbling, its hands stroking over the taut swell you make in its belly.",) + + B.emote_lists[DM_DIGEST] = list( + "Every clench of the predator's stomach grinds powerful digestive fluids into your body, forcibly churning away your strength!",) + +//This is placeholder code. Going to add special vorny for each of them slowly but surely. \ No newline at end of file diff --git a/modular_chomp/icons/mob/animal_ch.dmi b/modular_chomp/icons/mob/animal_ch.dmi index 3903fa4530..d025acb60d 100644 Binary files a/modular_chomp/icons/mob/animal_ch.dmi and b/modular_chomp/icons/mob/animal_ch.dmi differ diff --git a/vorestation.dme b/vorestation.dme index c283ffba84..9f2a5fb028 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -4607,6 +4607,8 @@ #include "modular_chomp\code\modules\mob\living\simple_mob\subtypes\animal\space\alien.dm" #include "modular_chomp\code\modules\mob\living\simple_mob\subtypes\horror\Master.dm" #include "modular_chomp\code\modules\mob\living\simple_mob\subtypes\humanoid\cultist_ch.dm" +#include "modular_chomp\code\modules\mob\living\simple_mob\subtypes\humanoid\eclipse\eclipse.dm" +#include "modular_chomp\code\modules\mob\living\simple_mob\subtypes\humanoid\eclipse\noms.dm" #include "modular_chomp\code\modules\mob\living\simple_mob\subtypes\mechanical\disbot.dm" #include "modular_chomp\code\modules\mob\living\simple_mob\subtypes\mechanical\drones\combat_drone.dm" #include "modular_chomp\code\modules\mob\living\simple_mob\subtypes\mechanical\hivebot\precusor_hivebots.dm"