mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-08-24 05:38:15 +01:00
Astral Collective Part 1. (#12361)
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
shock_resist = -0.2
|
||||
deflect_chance = 0
|
||||
movement_cooldown = 10
|
||||
damage_fatigue_mult = 0
|
||||
status_flags = null
|
||||
special_attack_min_range = 0
|
||||
special_attack_max_range = 14
|
||||
|
||||
+2
-2
@@ -812,7 +812,7 @@
|
||||
return
|
||||
var/list/potential_targets = ai_holder.list_targets()
|
||||
for(var/atom/entry in potential_targets)
|
||||
if(istype(entry, /mob/living/simple_mob/humanoid/eclipse))
|
||||
if(istype(entry, /mob/living/simple_mob/mechanical/mecha/eclipse))
|
||||
potential_targets -= entry
|
||||
if(potential_targets.len)
|
||||
var/iteration = clamp(potential_targets.len, 1, 3)
|
||||
@@ -860,7 +860,7 @@
|
||||
return
|
||||
var/list/potential_targets = ai_holder.list_targets()
|
||||
for(var/atom/entry in potential_targets)
|
||||
if(istype(entry, /mob/living/simple_mob/humanoid/eclipse))
|
||||
if(istype(entry, /mob/living/simple_mob/mechanical/mecha/eclipse))
|
||||
potential_targets -= entry
|
||||
if(potential_targets.len)
|
||||
var/iteration = clamp(potential_targets.len, 1, 3)
|
||||
|
||||
+157
-476
@@ -1,421 +1,57 @@
|
||||
//Most mechas have a strange defense mechanism
|
||||
//This one however, is the simplest one, more meant as an intro
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/antipersonal_unit //Melts folks with lasers
|
||||
name = "Eclipse Expirmental Anti-Infantary Unit"
|
||||
health = 400
|
||||
maxHealth = 400
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/lorge
|
||||
armor = list(melee = 60, bullet = 60, laser = 60, energy = 60, bomb = 90, bio = 100, rad = 100)
|
||||
icon_state = "orb"
|
||||
wreckage = /obj/structure/loot_pile/mecha/odd_gygax
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/antipersonal_unit/do_special_attack(atom/A)
|
||||
switch(a_intent)
|
||||
if(I_DISARM) //phase3
|
||||
if(attackcycle == 1)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(random_firing), A, 20, rng_cycle, 10), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 2)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(dual_spin), A, rng_cycle, 10), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 3)
|
||||
rng_cycle = rand(1,3)
|
||||
Beam(A, icon_state = "solar_beam", time = 2 SECONDS, maxdistance = INFINITY)
|
||||
addtimer(CALLBACK(src, PROC_REF(singleproj), A, rng_cycle), 2 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
|
||||
if(I_HURT) //phase1
|
||||
if(attackcycle == 1)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(random_firing), A, 8, rng_cycle, 15), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 2)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(cross_spin), A, rng_cycle, 15), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 3)
|
||||
rng_cycle = rand(1,3)
|
||||
Beam(A, icon_state = "solar_beam", time = 2 SECONDS, maxdistance = INFINITY)
|
||||
addtimer(CALLBACK(src, PROC_REF(singleproj), A, rng_cycle), 2 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(I_GRAB) // Phase 2
|
||||
if(attackcycle == 1)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(random_firing), A, 12, rng_cycle, 10), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 2)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(cross_spin), A, rng_cycle, 10), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 3)
|
||||
rng_cycle = rand(1,3)
|
||||
Beam(A, icon_state = "solar_beam", time = 1.5 SECONDS, maxdistance = INFINITY)
|
||||
addtimer(CALLBACK(src, PROC_REF(singleproj), A, rng_cycle), 1 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
|
||||
|
||||
|
||||
//Nigh unbreakable defenses except during certian attack phases.
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/mining_guard //Explosive death
|
||||
name = "Eclipse Expirmental Mining Mecha"
|
||||
desc = "You mecha guarded by a powerful shield. Perhaps it will drop at some point."
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/lorgealien
|
||||
armor = list(melee = 99, bullet = 99, laser = 99, energy = 99, bomb = 90, bio = 100, rad = 100)
|
||||
icon_state = "shielded_mining_mecha"
|
||||
shock_resist = 1
|
||||
wreckage = /obj/structure/loot_pile/mecha/odd_ripley
|
||||
attackcycle = 1
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/mining_guard/do_special_attack(atom/A)
|
||||
switch(a_intent)
|
||||
if(I_DISARM) //phase3
|
||||
if(attackcycle == 1)
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/lorgealien
|
||||
addtimer(CALLBACK(src, PROC_REF(quad_random_firing), A, 12, 2, 10), 1 SECOND, TIMER_DELETE_ME)
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 100)
|
||||
icon_state = "mining_mecha"
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 2)
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/lorgealien
|
||||
addtimer(CALLBACK(src, PROC_REF(hole_in_wall), A, 3, 15), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
armor = list(melee = 99, bullet = 99, laser = 99, energy = 99, bomb = 90, bio = 100, rad = 100)
|
||||
icon_state = "shielded_mining_mecha"
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 3)
|
||||
specialattackprojectile = /obj/item/projectile/arc/blue_energy/precusor
|
||||
addtimer(CALLBACK(src, PROC_REF(chain_burst), A, 1, 15), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
armor = list(melee = 99, bullet = 99, laser = 99, energy = 99, bomb = 90, bio = 100, rad = 100)
|
||||
icon_state = "shielded_mining_mecha"
|
||||
attackcycle = 0
|
||||
if(I_HURT) //phase1
|
||||
if(attackcycle == 1)
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/lorgealien
|
||||
addtimer(CALLBACK(src, PROC_REF(random_firing), A, 6, 2, 10), 1 SECOND, TIMER_DELETE_ME)
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 100)
|
||||
icon_state = "mining_mecha"
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 2)
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/lorgealien
|
||||
addtimer(CALLBACK(src, PROC_REF(hole_in_wall), A, 3, 20), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
armor = list(melee = 99, bullet = 99, laser = 99, energy = 99, bomb = 90, bio = 100, rad = 100)
|
||||
icon_state = "shielded_mining_mecha"
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 3)
|
||||
specialattackprojectile = /obj/item/projectile/arc/blue_energy/precusor
|
||||
addtimer(CALLBACK(src, PROC_REF(chain_burst), A, 1, 20), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
armor = list(melee = 99, bullet = 99, laser = 99, energy = 99, bomb = 90, bio = 100, rad = 100)
|
||||
icon_state = "shielded_mining_mecha"
|
||||
attackcycle = 0
|
||||
if(I_GRAB) // Phase 2
|
||||
if(attackcycle == 1)
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/lorgealien
|
||||
addtimer(CALLBACK(src, PROC_REF(random_firing), A, 8, 2, 10), 1 SECOND, TIMER_DELETE_ME)
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 100)
|
||||
icon_state = "mining_mecha"
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 2)
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/lorgealien
|
||||
addtimer(CALLBACK(src, PROC_REF(hole_in_wall), A, 3, 15), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
armor = list(melee = 99, bullet = 99, laser = 99, energy = 99, bomb = 90, bio = 100, rad = 100)
|
||||
icon_state = "shielded_mining_mecha"
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 3)
|
||||
specialattackprojectile = /obj/item/projectile/arc/blue_energy/precusor
|
||||
addtimer(CALLBACK(src, PROC_REF(chain_burst), A, 1, 15), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
armor = list(melee = 99, bullet = 99, laser = 99, energy = 99, bomb = 90, bio = 100, rad = 100)
|
||||
icon_state = "shielded_mining_mecha"
|
||||
attackcycle = 0
|
||||
|
||||
|
||||
//radidation gimmick go brrrr
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/engimecha
|
||||
name = "Eclipse Expirmental Enginering Mecha"
|
||||
health = 300
|
||||
maxHealth = 300
|
||||
desc = "A mecha made for enginering purposes, with several alterations to be an odd ball combat unit."
|
||||
specialattackprojectile = /obj/item/projectile/energy/excavate/weak
|
||||
armor = list(melee = 30, bullet = 30, laser = 30, energy = 40, bomb = 90, bio = 100, rad = 100)
|
||||
icon_state = "engi_spider"
|
||||
shock_resist = 1
|
||||
projectiletype = /obj/item/projectile/beam/chain_lightning
|
||||
reload_max = 1
|
||||
reload_time = 0.5 SECONDS
|
||||
ranged_attack_delay = 2 SECONDS
|
||||
|
||||
glow_color = "#14ff20"
|
||||
light_color = "#14ff20"
|
||||
glow_range = 5
|
||||
glow_intensity = 3
|
||||
|
||||
special_attack_cooldown = 60
|
||||
|
||||
pilot_type = /mob/living/simple_mob/humanoid/eclipse/head/engineer
|
||||
|
||||
var/rads = 5
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/engimecha/do_special_attack(atom/A)
|
||||
rads += 15
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/engimecha/handle_special()
|
||||
if(stat != DEAD)
|
||||
irradiate()
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/engimecha/proc/irradiate()
|
||||
SSradiation.radiate(src, rads)
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/engimecha/ranged_pre_animation(atom/A)
|
||||
Beam(get_turf(A), icon_state = "sniper_beam", time = 2 SECONDS, maxdistance = 15)
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/engimecha/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
|
||||
|
||||
/*
|
||||
* CHOMP Addition: This section here is (duplicated) special snowflake code because sniper does not call parent. Basically, this is a non-stupid version of the above intended for ranged mobs.
|
||||
* ranged_attack_delay is stupid because it sleeps the entire mob.
|
||||
* This new ranged_cooldown_time is smarter in the sense that it is an internalized timer. Try not to confuse the names.
|
||||
*/
|
||||
if(ranged_cooldown_time) //If you have a non-zero number in a mob's variables, this pattern begins.
|
||||
if(ranged_cooldown <= world.time) //Further down, a timer keeps adding to the ranged_cooldown variable automatically.
|
||||
visible_message(span_bolddanger("\The [src]") + " fires at \the [A]!") //Leave notice of shooting.
|
||||
shoot(A) //Perform the shoot action
|
||||
if(casingtype) //If the mob is designated to leave casings...
|
||||
new casingtype(loc) //... leave the casing.
|
||||
ranged_cooldown = world.time + ranged_cooldown_time + ((injury_level / 2) SECONDS) //Special addition here. This is a timer. Keeping updating the time after shooting. Add that ranged cooldown time specified in the mob to the world time.
|
||||
return TRUE //End these commands here.
|
||||
// CHOMPAddition End
|
||||
|
||||
visible_message(span_bolddanger("\The [src]") + " fires at \the [orig_targ]!")
|
||||
shoot(A)
|
||||
if(casingtype)
|
||||
new casingtype(loc)
|
||||
|
||||
if(ranged_attack_delay)
|
||||
ranged_post_animation(A)
|
||||
|
||||
return TRUE
|
||||
|
||||
//High overall defense, swaps between Burn and brute defense based off what was just used.
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/darkmatter_assualt/armored //The final boss
|
||||
name = "Eclipse Expirmental Janus"
|
||||
desc = "A powerful looking mecha, it's shield appears to swap to protect itself against the most rescent damage type."
|
||||
armor = list(melee = 60, bullet = 60, laser = 60, energy = 60, bomb = 80, bio = 100, rad = 100)
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/janusjavelin
|
||||
pilot_type =/mob/living/simple_mob/mechanical/mecha/eclipse/darkmatter_assualt/phasetwo
|
||||
wreckage = /obj/item/prop/tyrlore/monodisc
|
||||
icon_state = "eclipse_janus"
|
||||
attackcycle = 1
|
||||
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/darkmatter_assualt/armored/bullet_act(obj/item/projectile/P)
|
||||
.= ..()
|
||||
if(istype(P, /obj/item/projectile/bullet))
|
||||
armor = list(melee = 90, bullet = 90, laser = 30, energy = 30, bomb = 80, bio = 100, rad = 100)
|
||||
icon_state = "eclipse_janus_red"
|
||||
visible_message(span_cult("[P] has been adapted too!."))
|
||||
else
|
||||
armor = list(melee = 30, bullet = 30, laser = 80, energy = 80, bomb = 80, bio = 100, rad = 100)
|
||||
icon_state = "eclipse_janus_orange"
|
||||
visible_message(span_cult("[P] has been adapted too!."))
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/darkmatter_assualt/armored/do_special_attack(atom/A)
|
||||
switch(a_intent)
|
||||
if(I_DISARM) //phase3
|
||||
if(attackcycle == 1)
|
||||
rng_cycle = rand(1,4)
|
||||
addtimer(CALLBACK(src, PROC_REF(teleport_attack), A, rng_cycle, 2), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 2)
|
||||
rng_cycle = rand(1,4)
|
||||
specialattackprojectile = /obj/item/projectile/arc/blue_energy/precusor
|
||||
addtimer(CALLBACK(src, PROC_REF(dual_burst), A, rng_cycle), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 3)
|
||||
rng_cycle = rand(1,4)
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/janusjavelin
|
||||
addtimer(CALLBACK(src, PROC_REF(quad_random_firing), A, 8, rng_cycle, 5), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 4)
|
||||
rng_cycle = rand(1,4)
|
||||
specialattackprojectile = /obj/item/projectile/arc/blue_energy/precusor
|
||||
addtimer(CALLBACK(src, PROC_REF(chain_burst), A, rng_cycle), 1 SECOND, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(I_HURT) //phase1 simple projectiles
|
||||
if(attackcycle == 1)
|
||||
rng_cycle = rand(1,4)
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/janusjavelin
|
||||
addtimer(CALLBACK(src, PROC_REF(random_firing), A, 8, rng_cycle, 5), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 2)
|
||||
rng_cycle = rand(1,4)
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/janusjavelin
|
||||
addtimer(CALLBACK(src, PROC_REF(cross_spin), A, rng_cycle, 5), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 3)
|
||||
rng_cycle = rand(1,4)
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/janusjavelin
|
||||
Beam(A, icon_state = "solar_beam", time = 2 SECONDS, maxdistance = INFINITY)
|
||||
addtimer(CALLBACK(src, PROC_REF(singleproj), A, rng_cycle), 2 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 4)
|
||||
rng_cycle = rand(1,4)
|
||||
addtimer(CALLBACK(src, PROC_REF(teleport_attack), A, rng_cycle, 3), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(I_GRAB) // Phase 2
|
||||
if(attackcycle == 1)
|
||||
rng_cycle = rand(1,4)
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/janusjavelin
|
||||
addtimer(CALLBACK(src, PROC_REF(quad_random_firing), A, 8, rng_cycle, 5), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 2)
|
||||
rng_cycle = rand(1,4)
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/janusjavelin
|
||||
addtimer(CALLBACK(src, PROC_REF(dual_spin), A, rng_cycle, 5), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 3)
|
||||
rng_cycle = rand(1,4)
|
||||
addtimer(CALLBACK(src, PROC_REF(teleport_attack), A, rng_cycle, 2), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 4)
|
||||
rng_cycle = rand(1,4)
|
||||
specialattackprojectile = /obj/item/projectile/arc/blue_energy/precusor
|
||||
addtimer(CALLBACK(src, PROC_REF(checker_board), A, rng_cycle), 1 SECOND, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/darkmatter_assualt/phasetwo //we ain't done yet
|
||||
name = "Collapsing Janus"
|
||||
armor = list(melee = 30, bullet = 30, laser = 30, energy = 30, bomb = 80, bio = 100, rad = 100) //our shielding is gone
|
||||
health = 400
|
||||
maxHealth = 400
|
||||
desc = "The mecha is smoking, it's drone and shield is broken, but it's pilot is pushing it further."
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/janusjavelin
|
||||
wreckage = /obj/item/prop/tyrlore/neonjanus
|
||||
pilot_type = /mob/living/simple_mob/mechanical/mecha/eclipse/sniper
|
||||
has_repair_droid = FALSE //broken mecha
|
||||
icon_state = "eclipse_janus"
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/darkmatter_assualt/phasetwo/do_special_attack(atom/A)
|
||||
if(attackcycle == 1)
|
||||
attackcycle = rand(4,6)
|
||||
addtimer(CALLBACK(src, PROC_REF(random_firing), A, 14, attackcycle, 5), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
else if(attackcycle == 2)
|
||||
addtimer(CALLBACK(src, PROC_REF(cross_spin), A, attackcycle, 5), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = rand(4,6)
|
||||
else if(attackcycle == 3)
|
||||
addtimer(CALLBACK(src, PROC_REF(hole_in_wall), A, attackcycle, 15), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = rand(4,6)
|
||||
else if(attackcycle == 4)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(dual_spin), A, rng_cycle, 5), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 5)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(quad_random_firing), A, 7, rng_cycle, 15), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 6)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(teleport_attack), A, rng_cycle, 5), 3 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/sniper //one last stand
|
||||
name = "Eclipse Lead Pilot"
|
||||
icon_state = "captian"
|
||||
icon_living = "captian"
|
||||
health = 200
|
||||
maxHealth = 200
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/intentional/three_phases
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 50, bio = 100, rad = 100)
|
||||
specialattackprojectile = /obj/item/projectile/arc/explosive_rocket
|
||||
wreckage = /obj/item/prop/tyrlore/truegoal
|
||||
has_repair_droid = FALSE
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/sniper/do_special_attack(atom/A)
|
||||
. = TRUE
|
||||
if(attackcycle == 1)
|
||||
addtimer(CALLBACK(src, PROC_REF(teleport_attack), A, 2, 4), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 2)
|
||||
specialattackprojectile = /obj/item/projectile/beam/heavylaser/cannon
|
||||
Beam(A, icon_state = "solar_beam", time = 0.75 SECONDS, maxdistance = INFINITY)
|
||||
addtimer(CALLBACK(src, PROC_REF(singleproj), A, 1), 1 SECOND, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/battle_top
|
||||
name = "eclipse cryo top"
|
||||
name = "astral collective cryo top"
|
||||
icon_state = "mecha_top"
|
||||
icon_living = "mecha_top"
|
||||
health = 3000
|
||||
maxHealth = 3000
|
||||
wreckage = /obj/item/melee/energy/sword/top_shield
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/chillingwind
|
||||
desc = "It appears to be spinning at rapid speeds; enough to deflect projectiles. The air around it feels frigid.."
|
||||
desc = "It appears to be spinning at rapid speeds; enough to deflect projectiles. The air around it feels frigid."
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse_boss/chillingwind
|
||||
projectiletype = /obj/item/projectile/energy/eclipse_boss/chillingwind
|
||||
pilot_type = /mob/living/simple_mob/humanoid/astral_collective/purity
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/battle_top/do_special_attack(atom/A)
|
||||
var/rng_cycle
|
||||
rng_cycle = rand(1,3)
|
||||
switch(a_intent)
|
||||
if(I_DISARM) //phase3
|
||||
if(attackcycle == 1)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(quad_random_firing), A, 20, rng_cycle, 20), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 2)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(bomb_chaos), A, rng_cycle), 2.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 3)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(dual_spin), A, rng_cycle, 15), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
|
||||
if(I_HURT) //phase1
|
||||
if(attackcycle == 1)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(random_firing), A, 20, rng_cycle, 20), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 2)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(bomb_lines), A, rng_cycle), 2.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 3)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(cross_spin), A, rng_cycle, 15), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
|
||||
if(I_GRAB) // Phase 2
|
||||
if(attackcycle == 1)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(quad_random_firing), A, 20, rng_cycle, 25), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 2)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(bomb_lines), A, rng_cycle), 2.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 3)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(cross_spin), A, rng_cycle, 15), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
|
||||
switch(attackcycle)
|
||||
if(1)
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse_boss/chillingwind
|
||||
addtimer(CALLBACK(src, PROC_REF(rising_star), A, rng_cycle, 7), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(2)
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse_boss/chillingwind
|
||||
addtimer(CALLBACK(src, PROC_REF(hole_in_wall), A, rng_cycle, 18), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(3)
|
||||
addtimer(CALLBACK(src, PROC_REF(summon_puddles), A, rng_cycle, /datum/modifier/mmo_drop/eclipse_iceball), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(I_GRAB) //phase2
|
||||
switch(attackcycle)
|
||||
if(1)
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse_boss/chillingwind
|
||||
addtimer(CALLBACK(src, PROC_REF(bullet_blossom), A, 3, 8), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(2)
|
||||
specialattackprojectile = /obj/item/projectile/arc/blue_energy/precusor
|
||||
addtimer(CALLBACK(src, PROC_REF(chain_burst), A, rng_cycle, 6), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(3)
|
||||
addtimer(CALLBACK(src, PROC_REF(summon_puddles), A, rng_cycle, /datum/modifier/mmo_drop/eclipse_iceball), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(I_DISARM) //phase3
|
||||
switch(attackcycle)
|
||||
if(1)
|
||||
addtimer(CALLBACK(src, PROC_REF(summon_puddles), A, rng_cycle, /datum/modifier/mmo_drop/eclipse_iceball), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(2)
|
||||
specialattackprojectile = /obj/item/projectile/arc/blue_energy/precusor
|
||||
addtimer(CALLBACK(src, PROC_REF(checker_board), A, rng_cycle), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(3)
|
||||
projectiletype = /obj/item/projectile/energy/eclipse_boss/chillingwind
|
||||
addtimer(CALLBACK(src, PROC_REF(dual_spin), A, rng_cycle, 8), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/battle_top/handle_special()
|
||||
@@ -428,72 +64,117 @@
|
||||
if(!IIsAlly(L))
|
||||
L.add_modifier(/datum/modifier/chilled, 3, src)
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/excavate_head
|
||||
name = "Xenoarch Lead"
|
||||
desc = "A unathi wearing what appears to be a modified breacher suit. Something seems off though"
|
||||
icon_state = "cursor_guard"
|
||||
icon_living = "cursor_guard"
|
||||
armor = list(melee = 80, bullet = 80, laser = 80, energy = 80, bomb = 80, bio = 100, rad = 100)
|
||||
wreckage = /obj/item/prop/tyrlore/stolenbreacher
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/mining
|
||||
desc = "A being wearing what appears to be a modified breacher outfit."
|
||||
projectiletype = /obj/item/projectile/arc/explosive_rocket
|
||||
ranged_cooldown = 50
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/tankyboss/crystal_boss/ufo
|
||||
name = "astral collective deflection saucer"
|
||||
icon_state = "UPshield_mecha"
|
||||
icon_living = "UPshield_mecha"
|
||||
desc = "A metallic flying saucer, a reflective barrier around it."
|
||||
faction = FACTION_ECLIPSE
|
||||
icon = 'modular_chomp/icons/mob/eclipse.dmi'
|
||||
health = 1500
|
||||
maxHealth = 1500
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse_boss/metalsphere
|
||||
projectiletype = /obj/item/projectile/energy/eclipse_boss/metalsphere
|
||||
wreckage = /obj/item/prop/deconstructable/gigacell
|
||||
pilot_type = /mob/living/simple_mob/humanoid/astral_collective/purity
|
||||
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/excavate_head/updatehealth()
|
||||
. = ..()
|
||||
if(health < maxHealth*0.3)
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 100)
|
||||
else if(health < maxHealth*0.6)
|
||||
armor = list(melee = 30, bullet = 30, laser = 30, energy = 30, bomb = 30, bio = 100, rad = 100)
|
||||
else if (health < maxHealth*0.9)
|
||||
armor = list(melee = 60, bullet = 60, laser = 60, energy = 50, bomb = 60, bio = 100, rad = 100)
|
||||
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/excavate_head/do_special_attack(atom/A)
|
||||
var/rng_cycle
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/tankyboss/crystal_boss/ufo/do_special_attack(atom/A)
|
||||
switch(a_intent)
|
||||
if(I_DISARM) //phase3
|
||||
if(attackcycle == 1)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(random_firing), A, 20, rng_cycle, 10), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 2)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(dual_spin), A, rng_cycle, 10), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 3)
|
||||
rng_cycle = rand(1,3)
|
||||
Beam(A, icon_state = "solar_beam", time = 2 SECONDS, maxdistance = INFINITY)
|
||||
addtimer(CALLBACK(src, PROC_REF(singleproj), A, rng_cycle), 2 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
|
||||
if(I_HURT) //phase1
|
||||
if(attackcycle == 1)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(random_firing), A, 8, rng_cycle, 15), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 2)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(cross_spin), A, rng_cycle, 15), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 3)
|
||||
rng_cycle = rand(1,3)
|
||||
Beam(A, icon_state = "solar_beam", time = 2 SECONDS, maxdistance = INFINITY)
|
||||
addtimer(CALLBACK(src, PROC_REF(singleproj), A, rng_cycle), 2 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(I_GRAB) // Phase 2
|
||||
if(attackcycle == 1)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(random_firing), A, 12, rng_cycle, 10), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 2)
|
||||
rng_cycle = rand(1,3)
|
||||
addtimer(CALLBACK(src, PROC_REF(cross_spin), A, rng_cycle, 10), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
else if(attackcycle == 3)
|
||||
rng_cycle = rand(1,3)
|
||||
Beam(A, icon_state = "solar_beam", time = 1.5 SECONDS, maxdistance = INFINITY)
|
||||
addtimer(CALLBACK(src, PROC_REF(singleproj), A, rng_cycle), 1 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
switch(attackcycle)
|
||||
if(1)
|
||||
addtimer(CALLBACK(src, PROC_REF(cross_spin), A, 2, 5), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
parry_chance = 100
|
||||
icon_state = "UPshield_mecha"
|
||||
if(2)
|
||||
addtimer(CALLBACK(src, PROC_REF(rising_star), A, 3, 7), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
parry_chance = 100
|
||||
icon_state = "UPshield_mecha"
|
||||
if(3)
|
||||
addtimer(CALLBACK(src, PROC_REF(random_firing), A, 10, 1, 7), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
icon_state = "shield_mecha"
|
||||
if(I_GRAB) //phase2
|
||||
switch(attackcycle)
|
||||
if(1)
|
||||
addtimer(CALLBACK(src, PROC_REF(dual_spin), A, 2, 5), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
parry_chance = 100
|
||||
icon_state = "UPshield_mecha"
|
||||
if(2)
|
||||
addtimer(CALLBACK(src, PROC_REF(bullet_blossom), A, 3, 8), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
parry_chance = 100
|
||||
icon_state = "UPshield_mecha"
|
||||
if(3)
|
||||
addtimer(CALLBACK(src, PROC_REF(quad_random_firing), A, 10, 1, 7), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
icon_state = "shield_mecha"
|
||||
if(I_DISARM) //phase3
|
||||
switch(attackcycle)
|
||||
if(1)
|
||||
addtimer(CALLBACK(src, PROC_REF(dual_spin), A, 2, 4), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
parry_chance = 100
|
||||
icon_state = "UPshield_mecha"
|
||||
if(2)
|
||||
addtimer(CALLBACK(src, PROC_REF(hole_in_wall), A, 3, 15), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
parry_chance = 100
|
||||
icon_state = "UPshield_mecha"
|
||||
if(3)
|
||||
addtimer(CALLBACK(src, PROC_REF(quad_random_firing), A, 10, 1, 5), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
parry_chance = 0
|
||||
icon_state = "shield_mecha"
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/janus
|
||||
name = "astral collective janus"
|
||||
icon_state = "astral_janus"
|
||||
icon_living = "astral_janus"
|
||||
desc = "A janus made from stolen tech."
|
||||
health = 4500
|
||||
maxHealth = 4500
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse_boss/energyjavelin
|
||||
projectiletype = /obj/item/projectile/energy/eclipse_boss/energyjavelin
|
||||
wreckage = /obj/item/prop/deconstructable/gigacell
|
||||
pilot_type = /mob/living/simple_mob/humanoid/astral_collective/purity
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/janus/do_special_attack(atom/A)
|
||||
rng_cycle = rand(1,3)
|
||||
switch(a_intent)
|
||||
if(I_HURT) //phase1
|
||||
switch(attackcycle)
|
||||
if(1)
|
||||
addtimer(CALLBACK(src, PROC_REF(gattlingfire), A, rng_cycle, 4, 7), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(2)
|
||||
addtimer(CALLBACK(src, PROC_REF(rising_star), A, rng_cycle, 7), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(3)
|
||||
addtimer(CALLBACK(src, PROC_REF(quad_random_firing), A, 4, rng_cycle, 5), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(I_GRAB) //phase2
|
||||
switch(attackcycle)
|
||||
if(1)
|
||||
addtimer(CALLBACK(src, PROC_REF(death_wall), A, rng_cycle, 9), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(2)
|
||||
addtimer(CALLBACK(src, PROC_REF(bomb_chaos), A, rng_cycle), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(3)
|
||||
addtimer(CALLBACK(src, PROC_REF(bullet_blossom), A, rng_cycle, 7), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(I_DISARM) //phase3
|
||||
switch(attackcycle)
|
||||
if(1)
|
||||
addtimer(CALLBACK(src, PROC_REF(summon_puddles), A, rng_cycle, /datum/modifier/mmo_drop/blade_boss_short), 2.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(2)
|
||||
addtimer(CALLBACK(src, PROC_REF(hole_in_wall), A, 3, 12), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
if(3)
|
||||
addtimer(CALLBACK(src, PROC_REF(cross_spin), A, rng_cycle, 3), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
attackcycle = 0
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
size_multiplier = 2
|
||||
maxHealth = 600
|
||||
health = 600
|
||||
projectiletype = /obj/item/projectile/energy/wallbreaker/boss
|
||||
wreckage = /obj/structure/loot_pile/surface/alien/engineering
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/intentional/three_phases/no_movement
|
||||
anchored = 1
|
||||
|
||||
+45
@@ -42,6 +42,51 @@
|
||||
s2.start()
|
||||
attackcycle = next_cycle
|
||||
|
||||
/obj/effect/artillery_attack
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
unacidable = TRUE
|
||||
mouse_opacity = 0
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "drop_marker"
|
||||
var/ammmotype = /obj/effect/falling_effect/callstrike_bomb
|
||||
|
||||
/obj/effect/artillery_attack/Initialize(mapload)
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/effect/artillery_attack/LateInitialize()
|
||||
var/delay = rand(25, 30)
|
||||
addtimer(CALLBACK(src, PROC_REF(spawner)), delay, TIMER_DELETE_ME)
|
||||
|
||||
/obj/effect/artillery_attack/proc/spawner()
|
||||
new ammmotype(src.loc)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), src), 0.7 SECONDS, TIMER_DELETE_ME)
|
||||
|
||||
/obj/effect/falling_effect/callstrike_bomb
|
||||
falling_type = /obj/effect/callstrike
|
||||
crushing = FALSE
|
||||
|
||||
/obj/effect/callstrike
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
mouse_opacity = 0
|
||||
icon ='modular_chomp/icons/obj/guns/precursor/tyr.dmi'
|
||||
|
||||
/obj/effect/callstrike/Initialize(mapload)
|
||||
.=..()
|
||||
icon_state = "arti"
|
||||
|
||||
/obj/effect/callstrike/end_fall(var/crushing = FALSE)
|
||||
for(var/mob/living/L in loc)
|
||||
var/target_zone = ran_zone()
|
||||
var/blocked = L.run_armor_check(target_zone, "laser")
|
||||
|
||||
if(!L.apply_damage(70, BURN, target_zone, blocked))
|
||||
break
|
||||
playsound(src, 'sound/effects/clang2.ogg', 50, 1)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), src), 0.25 SECONDS, TIMER_DELETE_ME)
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/proc/gravity_surge(atom/target, var/next_cycle, var/pull_radius, var/pull_strength)
|
||||
if(!target)
|
||||
return
|
||||
|
||||
+8
@@ -68,6 +68,7 @@
|
||||
/obj/item/projectile/bullet/incendiary/dragonflame/occult
|
||||
range = 4
|
||||
speed = 4
|
||||
damage = 10
|
||||
|
||||
/obj/item/grenade/shooter/auto_explode/occult_fireball
|
||||
spread_range = 2
|
||||
@@ -75,3 +76,10 @@
|
||||
|
||||
/datum/modifier/mmo_drop/occult_fireball
|
||||
puddleitem = /obj/item/grenade/shooter/auto_explode/occult_fireball
|
||||
|
||||
/obj/item/grenade/shooter/auto_explode/eclipse_iceball
|
||||
spread_range = 2
|
||||
projectile_types = list(/obj/item/projectile/energy/eclipse_boss/chillingwind)
|
||||
|
||||
/datum/modifier/mmo_drop/eclipse_iceball
|
||||
puddleitem = /obj/item/grenade/shooter/auto_explode/eclipse_iceball
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
icon_living = "poison_boss"
|
||||
wreckage = /obj/item/prop/tyrlore/acid_boss
|
||||
specialattackprojectile = /obj/item/projectile/energy/neurotoxin/toxic/tyr_flora
|
||||
projectiletype = /obj/item/projectile/energy/neurotoxin/toxic/tyr_flora
|
||||
var/regeneration_strength = -20
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/tankyboss/acid_boss/load_default_bellies()
|
||||
@@ -94,7 +95,7 @@
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/tankyboss/sonic_boss
|
||||
name = "experiment 10"
|
||||
desc = "A strange furball, the air vibrating around it."
|
||||
specialattackprojectile = /obj/item/projectile/knockback/slow
|
||||
specialattackprojectile = /obj/item/projectile/energy/eclipse/tyrjavelin
|
||||
icon_state = "sonic_boss"
|
||||
icon_living = "sonic_boss"
|
||||
projectiletype = /obj/item/projectile/knockback/slow
|
||||
@@ -204,7 +205,26 @@
|
||||
melee_attack_delay = 2.5 SECONDS
|
||||
movement_cooldown = 4
|
||||
special_attack_cooldown = 8 SECONDS
|
||||
evasion = 200 //forced to fight in melee lol
|
||||
var/parry_chance = 100
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/tankyboss/crystal_boss/bullet_act(obj/item/projectile/P)
|
||||
if(prob(parry_chance))
|
||||
visible_message(span_danger("The [P.name] gets reflected by [src]'s armor!"), \
|
||||
span_userdanger("The [P.name] gets reflected by [src]'s armor!"))
|
||||
|
||||
// Find a turf near or on the original location to bounce to
|
||||
if(P.starting)
|
||||
var/new_x = P.starting.x + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3)
|
||||
var/new_y = P.starting.y + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3)
|
||||
var/turf/curloc = get_turf(src)
|
||||
|
||||
// redirect the projectile
|
||||
P.redirect(new_x, new_y, curloc, src)
|
||||
P.reflected = 1
|
||||
|
||||
return -1 // complete projectile permutation
|
||||
|
||||
return (..(P))
|
||||
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/tankyboss/crystal_boss/do_special_attack(atom/A)
|
||||
addtimer(CALLBACK(src, PROC_REF(bomb_chaos), A, 4), 1.5 SECONDS, TIMER_DELETE_ME)
|
||||
@@ -286,8 +306,8 @@
|
||||
/mob/living/simple_mob/mechanical/mecha/eclipse/tankyboss/swarm_ai
|
||||
name = "swarm controler"
|
||||
desc = "A massive hivebot that has shifting bits of metal upon it's body."
|
||||
health = 700
|
||||
maxHealth = 700
|
||||
health = 400
|
||||
maxHealth = 400
|
||||
icon_state = "bright_green"
|
||||
icon_living = "bright_green"
|
||||
icon = 'modular_chomp/icons/mob/hivebot.dmi'
|
||||
@@ -363,16 +383,3 @@
|
||||
adjustToxLoss(-1000)
|
||||
adjustOxyLoss(-1000)
|
||||
adjustCloneLoss(-1000)
|
||||
/*
|
||||
/mob/living/simple_mob/mechanical/hivebot/tyr/heart
|
||||
name = "barrier unit"
|
||||
icon = 'modular_chomp/icons/mob/tyr.dmi'
|
||||
icon_state = "guardian"
|
||||
icon_living = "guardian"
|
||||
maxHealth = 1.5 LASERS_TO_KILL // 60 hp
|
||||
health = 1.5 LASERS_TO_KILL
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 10
|
||||
attack_armor_pen = 80
|
||||
movement_cooldown = 4
|
||||
*/
|
||||
|
||||
+441
@@ -0,0 +1,441 @@
|
||||
/mob/living/simple_mob/humanoid/astral_collective
|
||||
name = "Astral Collective Unit"
|
||||
tt_desc = "E Homo sapiens"
|
||||
desc = "You shouldn't be seeing this."
|
||||
icon = 'modular_chomp/icons/mob/eclipse.dmi'
|
||||
icon_state = "medi"
|
||||
icon_living = "medi"
|
||||
icon_dead = "medi"
|
||||
taser_kill = 0
|
||||
|
||||
faction = FACTION_ECLIPSE
|
||||
movement_cooldown = 0
|
||||
|
||||
status_flags = 0
|
||||
|
||||
response_help = "pokes"
|
||||
response_disarm = "shoves"
|
||||
response_harm = "hits"
|
||||
|
||||
health = 100
|
||||
maxHealth = 100
|
||||
harm_intent_damage = 0
|
||||
melee_damage_lower = 25
|
||||
melee_damage_upper = 25
|
||||
melee_attack_delay = 0.75 SECONDS
|
||||
evasion = 20
|
||||
attack_sharp = 1
|
||||
attack_edge = 1
|
||||
attacktext = list("slashed", "stabbed")
|
||||
projectile_dispersion = 0
|
||||
armor = list(melee = 30, bullet = 30, laser = 30, energy = 60, bomb = 20, bio = 100, rad = 100) // Simple mob immunuties plus minour armor
|
||||
|
||||
can_be_drop_prey = FALSE
|
||||
can_be_drop_pred = TRUE
|
||||
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
|
||||
|
||||
projectilesound = 'sound/weapons/Gunshot_light.ogg'
|
||||
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/ranged/astral_collective
|
||||
|
||||
special_attack_cooldown = 15 SECONDS
|
||||
special_attack_min_range = 0
|
||||
special_attack_max_range = 14
|
||||
|
||||
swallowTime = 3 SECONDS
|
||||
vore_active = 1
|
||||
vore_capacity = 1
|
||||
vore_bump_chance = 10
|
||||
vore_stomach_name = "Stomach"
|
||||
vore_default_item_mode = IM_DIGEST
|
||||
vore_pounce_chance = 50
|
||||
vore_pounce_cooldown = 10
|
||||
vore_pounce_successrate = 75
|
||||
vore_pounce_falloff = 0
|
||||
vore_pounce_maxhealth = 100
|
||||
vore_standing_too = TRUE
|
||||
unacidable = TRUE
|
||||
|
||||
movement_cooldown = 0
|
||||
|
||||
loot_list = list(/obj/item/slime_extract/sepia = 75,
|
||||
/obj/item/bone/skull = 100,
|
||||
/obj/item/seeds/random = 60,
|
||||
/obj/random/powercell = 20,
|
||||
/obj/random/medical/pillbottle = 7,
|
||||
/obj/random/firstaid = 3,
|
||||
/obj/random/grenade/box = 5,
|
||||
/obj/random/tool/power = 30,
|
||||
/obj/random/tool/alien = 20,
|
||||
/obj/random/tech_supply/component/nofail = 40,
|
||||
/obj/random/medical = 12,
|
||||
/obj/random/cash/big = 25,
|
||||
/obj/random/material = 60,
|
||||
/obj/random/material/refined = 50,
|
||||
/obj/random/material/precious = 40,
|
||||
/obj/random/janusmodule = 3,
|
||||
/obj/item/dnainjector/random_verybad = 10,
|
||||
/obj/item/stock_parts/scanning_module/omni = 10,
|
||||
/obj/item/stock_parts/micro_laser/omni = 10,
|
||||
/obj/item/stock_parts/capacitor/omni = 10,
|
||||
/obj/item/stock_parts/manipulator/omni = 10,
|
||||
/obj/item/stock_parts/matter_bin/omni = 10,
|
||||
/obj/item/stock_parts/scanning_module/hyper = 25,
|
||||
/obj/item/stock_parts/micro_laser/hyper = 25,
|
||||
/obj/item/stock_parts/capacitor/hyper = 25,
|
||||
/obj/item/stock_parts/manipulator/hyper = 25,
|
||||
/obj/item/stock_parts/matter_bin/hyper = 25,
|
||||
/obj/item/assembly/signaler/anomaly/flux = 7,
|
||||
/obj/item/assembly/signaler/anomaly/bluespace = 7,
|
||||
/obj/item/assembly/signaler/anomaly/grav = 7,
|
||||
/obj/item/assembly/signaler/anomaly/dimensional = 7,
|
||||
/obj/item/assembly/signaler/anomaly/bioscrambler = 7,
|
||||
/obj/item/assembly/signaler/anomaly/hallucination = 7,
|
||||
/obj/item/assembly/signaler/anomaly/pyro = 7,
|
||||
/obj/item/assembly/signaler/anomaly/weather = 7,
|
||||
)
|
||||
|
||||
|
||||
var/expirmental
|
||||
|
||||
/mob/living/simple_mob/humanoid/astral_collective/Initialize(mapload)
|
||||
. = ..()
|
||||
expirmental = rand(1,7)
|
||||
expirmentresult()
|
||||
|
||||
/datum/modifier/astralcollect_swift
|
||||
slowdown = -0.5
|
||||
evasion = 20
|
||||
|
||||
/datum/modifier/astralcollect_regen
|
||||
mob_overlay_state = "poisoned"
|
||||
|
||||
/datum/modifier/astralcollect_regen/tick()
|
||||
holder.adjustBruteLoss(-8)
|
||||
holder.adjustFireLoss(-8)
|
||||
holder.adjustToxLoss(-8)
|
||||
holder.adjustOxyLoss(-8)
|
||||
holder.adjustCloneLoss(-8)
|
||||
|
||||
/datum/modifier/astralcollect_titan
|
||||
max_health_percent = 1.8
|
||||
|
||||
/datum/modifier/astralcollect_armour
|
||||
incoming_damage_percent = 0.65
|
||||
|
||||
/datum/modifier/astralcollect_mistake
|
||||
mob_overlay_state = "poisoned"
|
||||
incoming_damage_percent = 1.35
|
||||
slowdown = 1
|
||||
max_health_percent = 0.75
|
||||
|
||||
/datum/modifier/astralcollect_solar
|
||||
mob_overlay_state = "red_electricity_constant"
|
||||
incoming_brute_damage_percent = 2
|
||||
incoming_fire_damage_percent = 0.3
|
||||
|
||||
/datum/modifier/astralcollect_lunar
|
||||
mob_overlay_state = "blue_electricity_constant"
|
||||
incoming_brute_damage_percent = 0.3
|
||||
incoming_fire_damage_percent = 2
|
||||
|
||||
/mob/living/simple_mob/humanoid/astral_collective/proc/expirmentresult()
|
||||
switch(expirmental)
|
||||
if(1)
|
||||
add_modifier(/datum/modifier/astralcollect_swift, null, src)
|
||||
size_multiplier -= 0.3
|
||||
if(2)
|
||||
add_modifier(/datum/modifier/astralcollect_regen, null, src)
|
||||
if(3)
|
||||
add_modifier(/datum/modifier/astralcollect_titan, null, src)
|
||||
size_multiplier += 0.6
|
||||
if(4)
|
||||
add_modifier(/datum/modifier/astralcollect_armour, null, src)
|
||||
size_multiplier += 0.3
|
||||
if(5)
|
||||
add_modifier(/datum/modifier/astralcollect_mistake, null, src)
|
||||
if(6)
|
||||
add_modifier(/datum/modifier/astralcollect_solar, null, src)
|
||||
if(7)
|
||||
add_modifier(/datum/modifier/astralcollect_lunar, null, src)
|
||||
if(8)
|
||||
ai_holder_type = /datum/ai_holder/hostile/ranged/robust
|
||||
if(9)
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/intentional/adv_dark_gygax
|
||||
if(10)
|
||||
projectile_dispersion = 10
|
||||
|
||||
/datum/ai_holder/simple_mob/ranged/astral_collective
|
||||
pointblank = TRUE
|
||||
can_breakthrough = TRUE
|
||||
violent_breakthrough = TRUE
|
||||
unconscious_vore = TRUE
|
||||
handle_corpse = TRUE
|
||||
hostile = TRUE
|
||||
mauling = TRUE
|
||||
destructive = TRUE
|
||||
|
||||
/datum/ai_holder/simple_mob/ranged/astral_collective/pre_ranged_attack(atom/A)
|
||||
holder.IMove(get_step(holder, pick(GLOB.alldirs)))
|
||||
holder.face_atom(A)
|
||||
|
||||
|
||||
/datum/ai_holder/simple_mob/ranged/astral_collective/post_ranged_attack(atom/A)
|
||||
holder.IMove(get_step(holder, pick(GLOB.alldirs)))
|
||||
holder.face_atom(A)
|
||||
|
||||
/datum/ai_holder/simple_mob/ranged/astral_collective/post_melee_attack(atom/A)
|
||||
holder.IMove(get_step_away(holder, A))
|
||||
holder.face_atom(A)
|
||||
|
||||
/datum/ai_holder/simple_mob/melee/evasive/astral_collective
|
||||
|
||||
/datum/ai_holder/simple_mob/melee/evasive/astral_collective/pre_special_attack(atom/A)
|
||||
holder.IMove(get_step(holder, pick(GLOB.alldirs)))
|
||||
holder.face_atom(A)
|
||||
|
||||
|
||||
/datum/ai_holder/simple_mob/melee/evasive/astral_collective/post_special_attack(atom/A)
|
||||
holder.IMove(get_step(holder, pick(GLOB.alldirs)))
|
||||
holder.face_atom(A)
|
||||
|
||||
/mob/living/simple_mob/humanoid/astral_collective/purity
|
||||
name = "Astral Collective Purity"
|
||||
desc = "A strange living bioweapon"
|
||||
icon_state = "purity"
|
||||
icon_living = "purity"
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive/astral_collective
|
||||
melee_damage_lower = 32 //25ish with explo voidsuit
|
||||
melee_damage_upper = 32
|
||||
attack_armor_pen = 20
|
||||
melee_attack_delay = 1.5 SECONDS
|
||||
|
||||
health = 200
|
||||
maxHealth = 200
|
||||
|
||||
special_attack_cooldown = 3 SECONDS
|
||||
special_attack_min_range = 0
|
||||
special_attack_max_range = 14
|
||||
|
||||
/mob/living/simple_mob/humanoid/astral_collective/purity/do_special_attack(atom/A)
|
||||
adjustBruteLoss(-3)
|
||||
adjustFireLoss(-3)
|
||||
adjustToxLoss(-3)
|
||||
adjustOxyLoss(-3)
|
||||
adjustCloneLoss(-3)
|
||||
|
||||
//the ranged mobs
|
||||
/mob/living/simple_mob/humanoid/astral_collective/ranged
|
||||
name = "Astral Collective Unit"
|
||||
projectile_accuracy = 10
|
||||
needs_reload = TRUE
|
||||
special_attack_cooldown = 7 SECONDS
|
||||
reload_max = 7
|
||||
reload_time = 1.5 SECONDS
|
||||
ranged_cooldown = 65
|
||||
|
||||
//snake creature
|
||||
/mob/living/simple_mob/humanoid/astral_collective/ranged/noodle
|
||||
desc = "A naga wrapped up in strange glowing armour."
|
||||
icon_state = "noodle"
|
||||
icon_living = "noodle"
|
||||
projectiletype = /obj/item/projectile/energy/astral_collective/anti_mecha
|
||||
|
||||
/mob/living/simple_mob/humanoid/astral_collective/ranged/noodle/do_special_attack(atom/A)
|
||||
if((health / maxHealth) <= 0.5)
|
||||
alpha = 180
|
||||
teleport_self(A)
|
||||
|
||||
//taur creature
|
||||
/mob/living/simple_mob/humanoid/astral_collective/ranged/taur
|
||||
desc = "A quadrapel creature with expirmental gear."
|
||||
icon_state = "taur"
|
||||
icon_living = "taur"
|
||||
projectiletype = /obj/item/projectile/energy/astral_collective/armour_breaker
|
||||
health = 125
|
||||
maxHealth = 125
|
||||
|
||||
/mob/living/simple_mob/humanoid/astral_collective/ranged/taur/do_special_attack(atom/A)
|
||||
expirmental = rand(1,5)
|
||||
switch(expirmental)
|
||||
if(1)
|
||||
teleport_attack(A)
|
||||
if(2)
|
||||
gravity_surge(A)
|
||||
if(3)
|
||||
air_strike(A)
|
||||
if(4)
|
||||
repair_self(A)
|
||||
if(5)
|
||||
teleport_self(A)
|
||||
|
||||
//teshari
|
||||
/mob/living/simple_mob/humanoid/astral_collective/ranged/tesh
|
||||
desc = "A teshari contained within prototype equipment."
|
||||
icon_state = "tesh"
|
||||
icon_living = "tesh"
|
||||
projectiletype = /obj/item/projectile/energy/astral_collective/particle
|
||||
health = 75
|
||||
maxHealth = 75
|
||||
|
||||
/mob/living/simple_mob/humanoid/astral_collective/ranged/tesh/do_special_attack(atom/A)
|
||||
if((health / maxHealth) <= 0.5)
|
||||
selfexplode_attack(A)
|
||||
else
|
||||
teleport_attack(A)
|
||||
|
||||
//cannine
|
||||
/mob/living/simple_mob/humanoid/astral_collective/ranged/wolf
|
||||
desc = "A humanoid armored cannine folk."
|
||||
icon_state = "wolf"
|
||||
icon_living = "wolf"
|
||||
projectiletype = /obj/item/projectile/energy/astral_collective/green
|
||||
|
||||
/mob/living/simple_mob/humanoid/astral_collective/ranged/wolf/do_special_attack(atom/A)
|
||||
gravity_surge(A)
|
||||
|
||||
//lizard
|
||||
/mob/living/simple_mob/humanoid/astral_collective/ranged/lizard
|
||||
desc = "A humanoid heavily armoured lizardfolk."
|
||||
icon_state = "breacher"
|
||||
icon_living = "breacher"
|
||||
projectiletype = /obj/item/projectile/energy/astral_collective/searing
|
||||
health = 150
|
||||
maxHealth = 150
|
||||
|
||||
/mob/living/simple_mob/humanoid/astral_collective/ranged/lizard/do_special_attack(atom/A)
|
||||
if((health / maxHealth) <= 0.5)
|
||||
repair_self(A)
|
||||
air_strike(A)
|
||||
|
||||
//zaddat
|
||||
/mob/living/simple_mob/humanoid/astral_collective/ranged/zaddat
|
||||
desc = "An armoured zaddat."
|
||||
icon_state = "zaddat"
|
||||
icon_living = "zaddat"
|
||||
special_attack_cooldown = 1 SECOND
|
||||
|
||||
/mob/living/simple_mob/humanoid/astral_collective/ranged/zaddat/do_special_attack(atom/A)
|
||||
projectiletype = pick(/obj/item/projectile/energy/astral_collective/anti_mecha, /obj/item/projectile/energy/astral_collective/armour_breaker, /obj/item/projectile/energy/astral_collective/searing, /obj/item/projectile/energy/astral_collective/green, /obj/item/projectile/energy/astral_collective/particle)
|
||||
|
||||
/mob/living/simple_mob/humanoid/astral_collective/ranged/zaddat/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(!Proj)
|
||||
return
|
||||
if(prob(60))
|
||||
visible_message(span_bolddanger("[Proj] is blocked by the shield."))
|
||||
if(Proj.firer)
|
||||
ai_holder.react_to_attack(Proj.firer)
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/humanoid/astral_collective/proc/teleport_attack(atom/target)
|
||||
// Teleport attack.
|
||||
if(!target)
|
||||
to_chat(src, span_warning("There's nothing to teleport to."))
|
||||
return FALSE
|
||||
|
||||
var/list/nearby_things = range(2, src)
|
||||
var/list/valid_turfs = list()
|
||||
|
||||
// All this work to just go to a non-dense tile.
|
||||
for(var/turf/potential_turf in nearby_things)
|
||||
var/valid_turf = TRUE
|
||||
if(potential_turf.density)
|
||||
continue
|
||||
for(var/atom/movable/AM in potential_turf)
|
||||
if(AM.density)
|
||||
valid_turf = FALSE
|
||||
if(valid_turf)
|
||||
valid_turfs.Add(potential_turf)
|
||||
|
||||
if(!(valid_turfs.len))
|
||||
to_chat(src, span_warning("There wasn't an unoccupied spot to teleport to."))
|
||||
return FALSE
|
||||
|
||||
var/turf/target_turf = pick(valid_turfs)
|
||||
|
||||
do_teleport(target, target_turf, channel = TELEPORT_CHANNEL_QUANTUM)
|
||||
|
||||
/mob/living/simple_mob/humanoid/astral_collective/proc/selfexplode_attack(atom/target)
|
||||
if(!target)
|
||||
return FALSE
|
||||
explosion(src.loc, 2, 3, 4, 5)
|
||||
|
||||
/mob/living/simple_mob/humanoid/astral_collective/proc/gravity_surge(atom/target)
|
||||
if(!target)
|
||||
return FALSE
|
||||
playsound(src, 'sound/weapons/wave.ogg', 75, 1)
|
||||
for(target in range(7, src))
|
||||
target.singularity_pull(src, 3)
|
||||
|
||||
/mob/living/simple_mob/humanoid/astral_collective/proc/air_strike(atom/target)
|
||||
if(!target)
|
||||
return FALSE
|
||||
for(var/mob/living/L in orange(src, 14))
|
||||
if(L.stat != DEAD && !IIsAlly(L))
|
||||
L.add_modifier(/datum/modifier/mmo_drop/blade_boss_short, 3, src)
|
||||
|
||||
/mob/living/simple_mob/humanoid/astral_collective/proc/repair_self(atom/target)
|
||||
if(!target)
|
||||
return FALSE
|
||||
adjustBruteLoss(-70)
|
||||
adjustFireLoss(-70)
|
||||
adjustToxLoss(-70)
|
||||
adjustOxyLoss(-70)
|
||||
adjustCloneLoss(-70)
|
||||
|
||||
/mob/living/simple_mob/humanoid/astral_collective/proc/teleport_self(atom/A)
|
||||
// Teleport attack.
|
||||
if(!A)
|
||||
to_chat(src, span_warning("There's nothing to teleport to."))
|
||||
return FALSE
|
||||
|
||||
var/list/nearby_things = range(4, A)
|
||||
var/list/valid_turfs = list()
|
||||
|
||||
// All this work to just go to a non-dense tile.
|
||||
for(var/turf/potential_turf in nearby_things)
|
||||
var/valid_turf = TRUE
|
||||
if(potential_turf.density)
|
||||
continue
|
||||
for(var/atom/movable/AM in potential_turf)
|
||||
if(AM.density)
|
||||
valid_turf = FALSE
|
||||
if(valid_turf)
|
||||
valid_turfs.Add(potential_turf)
|
||||
|
||||
if(!(valid_turfs.len))
|
||||
to_chat(src, span_warning("There wasn't an unoccupied spot to teleport to."))
|
||||
return FALSE
|
||||
|
||||
var/turf/target_turf = pick(valid_turfs)
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/s1 = new /datum/effect/effect/system/spark_spread
|
||||
s1.set_up(5, 1, T)
|
||||
var/datum/effect/effect/system/spark_spread/s2 = new /datum/effect/effect/system/spark_spread
|
||||
s2.set_up(5, 1, target_turf)
|
||||
|
||||
|
||||
T.visible_message(span_warning("\The [src] vanishes!"))
|
||||
s1.start()
|
||||
|
||||
forceMove(target_turf)
|
||||
playsound(target_turf, 'sound/effects/phasein.ogg', 50, 1)
|
||||
to_chat(src, span_notice("You teleport to \the [target_turf]."))
|
||||
|
||||
target_turf.visible_message(span_warning("\The [src] appears!"))
|
||||
s2.start()
|
||||
-1019
File diff suppressed because it is too large
Load Diff
@@ -1,668 +0,0 @@
|
||||
/mob/living/simple_mob/humanoid/eclipse/head
|
||||
name = "Eclipse Head"
|
||||
desc = "You shouldn't be seeing this. This is going to be rough"
|
||||
health = 315
|
||||
maxHealth = 315 //A 20 damage shot will need to land 35 times
|
||||
projectile_dispersion = 8
|
||||
projectile_accuracy = 0
|
||||
ranged_cooldown = 5
|
||||
grab_resist = 100
|
||||
|
||||
damage_fatigue_mult = 0
|
||||
|
||||
armor = list(melee = 34, bullet = 34, laser = 34, energy = 34, bomb = 100, bio = 100, rad = 100)
|
||||
has_heal_droid = TRUE
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/security
|
||||
name = "Eclipse Head Of Security"
|
||||
icon_state = "fleetsec"
|
||||
projectiletype = /obj/item/projectile/energy/flamecrystal
|
||||
special_attack_cooldown = 10 SECONDS
|
||||
special_attack_min_range = 1
|
||||
special_attack_max_range = 8
|
||||
has_heal_droid = TRUE
|
||||
specialattackprojectile = /obj/item/projectile/bullet/dragon
|
||||
loot_list = list(/obj/item/gun/energy/flamegun = 100,
|
||||
/obj/item/prop/tyrlore/neonsec = 100,
|
||||
/obj/item/bone/skull = 100
|
||||
)
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/security/do_special_attack(atom/A)
|
||||
if(vore_fullness > 3)
|
||||
bomb_chaos(A)
|
||||
else if(vore_fullness > 0)
|
||||
visible_message(span_warning("\The [src]'s maw glows!"))
|
||||
Beam(A, icon_state = "sat_beam", time = 2.5 SECONDS, maxdistance = INFINITY)
|
||||
addtimer(CALLBACK(src, PROC_REF(special_projectile), A), 3 SECONDS, TIMER_DELETE_ME)
|
||||
else
|
||||
if(prob(50))
|
||||
visible_message(span_warning("\The [src] throws out a chain!"))
|
||||
Beam(A, icon_state = "chain", time = 3 SECONDS, maxdistance = INFINITY)
|
||||
addtimer(CALLBACK(src, PROC_REF(gravity_pull), A), 3 SECOND, TIMER_DELETE_ME)
|
||||
else
|
||||
visible_message(span_warning("\The [src] throws out a chain!"))
|
||||
Beam(A, icon_state = "chain", time = 3 SECONDS, maxdistance = INFINITY)
|
||||
addtimer(CALLBACK(src, PROC_REF(itemyoink), A), 3 SECOND, TIMER_DELETE_ME)
|
||||
|
||||
/obj/item/projectile/energy/flamecrystal
|
||||
name = "Flame Crystal"
|
||||
icon = 'modular_chomp/icons/mob/eclipse.dmi' //commiting sin
|
||||
icon_state = "firecrystal"
|
||||
damage = 15
|
||||
armor_penetration = 40 //Large pointy crystal
|
||||
damage_type = BRUTE
|
||||
check_armour = "bullet"
|
||||
range = 12
|
||||
hud_state = "laser_sniper"
|
||||
|
||||
/obj/item/projectile/energy/flamecrystal/on_hit(atom/target, blocked = 0, def_zone)
|
||||
. = ..()
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
L.adjust_fire_stacks(5)
|
||||
L.ignite_mob()
|
||||
|
||||
/obj/item/projectile/bullet/flamegun
|
||||
use_submunitions = 1
|
||||
only_submunitions = 1
|
||||
range = 0
|
||||
embed_chance = 0
|
||||
submunition_spread_max = 800
|
||||
submunition_spread_min = 200
|
||||
submunitions = list(/obj/item/projectile/energy/flamecrystal = 3)
|
||||
hud_state = "laser_heat"
|
||||
|
||||
/obj/item/projectile/bullet/flamegun/on_range()
|
||||
qdel(src)
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/scientist
|
||||
name = "Eclipse Lead Researcher"
|
||||
icon_state = "fleetsci"
|
||||
maxHealth = 60
|
||||
health = 60
|
||||
special_attack_cooldown = 5 SECONDS
|
||||
special_attack_min_range = 1
|
||||
special_attack_max_range = 10
|
||||
projectiletype = /obj/item/projectile/bullet/pistol/ap
|
||||
|
||||
loot_list = list(/obj/item/circuitboard/mecha/imperion/targeting = 60,
|
||||
/obj/item/circuitboard/mecha/gygax/peripherals = 60,
|
||||
/obj/item/prop/alien/phasecoil = 60,
|
||||
/obj/item/circuitboard/mecha/durand/peripherals = 60,
|
||||
/obj/item/bluespace_harpoon = 10,
|
||||
/obj/item/bone/skull = 100,
|
||||
/obj/item/prop/tyrlore/neonsci = 100
|
||||
)
|
||||
|
||||
var/obj/item/shield_projector/shield1 = null
|
||||
var/obj/item/shield_projector/shield2 = null
|
||||
var/obj/item/shield_projector/shield3 = null
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/scientist/Initialize(mapload)
|
||||
shield1 = new /obj/item/shield_projector/rectangle/automatic/eclipse(src)
|
||||
shield2 = new /obj/item/shield_projector/rectangle/automatic/eclipse/medium(src)
|
||||
shield3 = new /obj/item/shield_projector/rectangle/automatic/eclipse/big(src)
|
||||
return ..()
|
||||
|
||||
/obj/item/shield_projector/rectangle/automatic/eclipse
|
||||
name = "cult shield stone"
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "implant_melted"
|
||||
shield_health = 100
|
||||
max_shield_health = 100
|
||||
shield_regen_delay = 120 SECONDS
|
||||
shield_regen_amount = 100
|
||||
size_x = 1
|
||||
size_y = 1
|
||||
color = "#FF6600"
|
||||
high_color = "#0099CC"
|
||||
low_color = "#660066"
|
||||
|
||||
/obj/item/shield_projector/rectangle/automatic/eclipse/medium
|
||||
size_x = 2
|
||||
size_y = 2
|
||||
|
||||
/obj/item/shield_projector/rectangle/automatic/eclipse/big
|
||||
size_x = 3
|
||||
size_y = 3
|
||||
|
||||
/mob/living/simple_mob/mechanical/hivebot/swarm/eclipse
|
||||
faction = FACTION_ECLIPSE
|
||||
|
||||
/mob/living/simple_mob/mechanical/combat_drone/artillery
|
||||
faction = FACTION_ECLIPSE
|
||||
projectiletype = /obj/item/projectile/arc/blue_energy
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/captain
|
||||
name = "Eclipse Expedition Leader"
|
||||
icon_state = "captain"
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/tyrlead
|
||||
name = "Eclipse Precursor Overseer"
|
||||
icon_state = "overseer_shield"
|
||||
icon_living = "overseer_shield"
|
||||
special_attack_cooldown = 4 SECONDS
|
||||
special_attack_min_range = 1
|
||||
special_attack_max_range = 8
|
||||
projectiletype = /obj/item/projectile/energy/homing_bolt
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/intentional/adv_dark_gygax
|
||||
loot_list = list(/obj/item/prop/tyrlore/baseneon = 100,
|
||||
/obj/item/disposable_teleporter = 100,
|
||||
/obj/item/hand_tele = 10,
|
||||
/obj/item/bone/skull = 100
|
||||
)
|
||||
var/fullshield = 140
|
||||
var/shieldrage = 3
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/tyrlead/bullet_act(obj/item/projectile/P) //Projectiles will be absorbed by the shield. Note to self do funky sprite. 4 hits to remove
|
||||
if(fullshield > 0)
|
||||
fullshield -= P.damage
|
||||
if(P == /obj/item/projectile/ion)
|
||||
fullshield = 0
|
||||
visible_message(span_boldwarning(span_orange("[P] breaks the shield!!.")))
|
||||
icon_state = "overseer"
|
||||
if(fullshield > 0)
|
||||
visible_message(span_boldwarning(span_orange("[P] is absorbed by the shield!.")))
|
||||
else
|
||||
visible_message(span_boldwarning(span_orange("[P] breaks the shield!!.")))
|
||||
icon_state = "overseer"
|
||||
else
|
||||
..()
|
||||
shieldrage--
|
||||
if(shieldrage == 0)
|
||||
shieldrage = 3
|
||||
fullshield = 140
|
||||
visible_message(span_boldwarning(span_orange("The shield reactivates!!.")))
|
||||
icon_state = "overseer_shield"
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/tyrlead/do_special_attack(atom/A)
|
||||
var/deathdir = rand(1,3)
|
||||
switch(deathdir)
|
||||
if(1)
|
||||
teleport(A)
|
||||
if(2)
|
||||
bomb_chaos(A)
|
||||
if(3)
|
||||
bomb_lines(A)
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/engineer //teshari
|
||||
name = "Eclipse Chief Engineer"
|
||||
icon_state = "engi"
|
||||
icon_living = "engi"
|
||||
health = 50
|
||||
maxHealth = 50
|
||||
melee_damage_lower = 60 //Durasteel fireaxe
|
||||
melee_damage_upper = 60
|
||||
projectiletype = null
|
||||
|
||||
loot_list = list(/obj/item/stock_parts/matter_bin/omni = 60,
|
||||
/obj/item/material/twohanded/fireaxe = 60,
|
||||
/obj/item/storage/toolbox/syndicate/powertools = 60,
|
||||
/obj/item/rig/ce = 60,
|
||||
/obj/item/rig_module/teleporter = 5,
|
||||
/obj/item/prop/tyrlore/neonengi = 100
|
||||
)
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/engineer/Initialize(mapload)
|
||||
add_modifier(/datum/modifier/technomancer/haste, null, src) // tesh goes nyooooom
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/medical
|
||||
name = "Eclipse Chief Medical Officer"
|
||||
icon_state = "medi"
|
||||
icon_living = "medi"
|
||||
health = 150
|
||||
maxHealth = 150
|
||||
special_attack_cooldown = 5 SECONDS
|
||||
special_attack_min_range = 0
|
||||
special_attack_max_range = 7
|
||||
melee_damage_lower = 15 //Durasteel fireaxe
|
||||
melee_damage_upper = 15
|
||||
attack_armor_pen = 60
|
||||
projectiletype = null
|
||||
|
||||
loot_list = list(/obj/item/rig_module/atmos_shield = 60,
|
||||
/obj/item/rig_module/rad_shield/advanced = 60,
|
||||
/obj/item/rig/baymed = 60,
|
||||
/obj/item/ammo_casing/microbattery/medical/brute3 = 15,
|
||||
/obj/item/ammo_casing/microbattery/medical/burn3 = 15,
|
||||
/obj/item/ammo_casing/microbattery/medical/toxin3 = 15,
|
||||
/obj/item/prop/tyrlore/neonmedi = 100,
|
||||
/obj/item/ammo_casing/microbattery/medical/omni3 = 5
|
||||
)
|
||||
|
||||
var/cloaked_alpha = 45 // 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
|
||||
var/poison_type = REAGENT_ID_STOXIN
|
||||
var/poison_per_bite = 8
|
||||
var/poison_chance = 80
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/medical/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)
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/medical/proc/inject_poison(mob/living/L, target_zone)
|
||||
if(prob(poison_chance))
|
||||
to_chat(L, span_warning("You feel a tiny prick."))
|
||||
L.reagents.add_reagent(poison_type, poison_per_bite)
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/medical/cloak()
|
||||
if(cloaked)
|
||||
return
|
||||
animate(src, alpha = cloaked_alpha, time = 1 SECOND)
|
||||
cloaked = TRUE
|
||||
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/medical/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/head/medical/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/head/medical/break_cloak()
|
||||
uncloak()
|
||||
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/medical/is_cloaked()
|
||||
return cloaked
|
||||
|
||||
|
||||
// Cloaks the spider automatically, if possible.
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/medical/handle_special()
|
||||
if(!cloaked && can_cloak())
|
||||
cloak()
|
||||
|
||||
|
||||
//special attack things
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/scientist/do_special_attack(atom/A)
|
||||
addtimer(CALLBACK(src, PROC_REF(summon_drones), A, 3, 0.5 SECONDS), 0.5 SECONDS, TIMER_DELETE_ME)
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/proc/summon_drones(atom/target, var/amount, var/fire_delay)
|
||||
if(!target)
|
||||
return
|
||||
var/deathdir = rand(1,3)
|
||||
switch(deathdir)
|
||||
if(1)
|
||||
new /mob/living/simple_mob/mechanical/mining_drone/scavenger/eclipse(src.loc)
|
||||
if(2)
|
||||
new /mob/living/simple_mob/mechanical/hivebot/swarm/eclipse(src.loc)
|
||||
if(3)
|
||||
new /mob/living/simple_mob/mechanical/combat_drone/artillery(src.loc)
|
||||
amount--
|
||||
if(amount > 0)
|
||||
addtimer(CALLBACK(src, PROC_REF(summon_drones), target, amount, fire_delay), fire_delay, TIMER_DELETE_ME)
|
||||
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/medical/do_special_attack(atom/A)
|
||||
if(!cloaked)
|
||||
teleport(A)
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/proc/teleport(atom/A)
|
||||
// Teleport attack.
|
||||
if(!A)
|
||||
to_chat(src, span_warning("There's nothing to teleport to."))
|
||||
return FALSE
|
||||
|
||||
var/list/nearby_things = range(4, A)
|
||||
var/list/valid_turfs = list()
|
||||
|
||||
// All this work to just go to a non-dense tile.
|
||||
for(var/turf/potential_turf in nearby_things)
|
||||
var/valid_turf = TRUE
|
||||
if(potential_turf.density)
|
||||
continue
|
||||
for(var/atom/movable/AM in potential_turf)
|
||||
if(AM.density)
|
||||
valid_turf = FALSE
|
||||
if(valid_turf)
|
||||
valid_turfs.Add(potential_turf)
|
||||
|
||||
if(!(valid_turfs.len))
|
||||
to_chat(src, span_warning("There wasn't an unoccupied spot to teleport to."))
|
||||
return FALSE
|
||||
|
||||
var/turf/target_turf = pick(valid_turfs)
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/s1 = new /datum/effect/effect/system/spark_spread
|
||||
s1.set_up(5, 1, T)
|
||||
var/datum/effect/effect/system/spark_spread/s2 = new /datum/effect/effect/system/spark_spread
|
||||
s2.set_up(5, 1, target_turf)
|
||||
|
||||
|
||||
T.visible_message(span_warning("\The [src] vanishes!"))
|
||||
s1.start()
|
||||
|
||||
forceMove(target_turf)
|
||||
playsound(target_turf, 'sound/effects/phasein.ogg', 50, 1)
|
||||
to_chat(src, span_notice("You teleport to \the [target_turf]."))
|
||||
|
||||
target_turf.visible_message(span_warning("\The [src] appears!"))
|
||||
s2.start()
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/cargomaster //Naga
|
||||
name = "Eclipse Cargo Master"
|
||||
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/proc/bomb_lines(atom/A)
|
||||
if(!A)
|
||||
return
|
||||
var/list/potential_targets = ai_holder.list_targets()
|
||||
for(var/atom/entry in potential_targets)
|
||||
if(istype(entry, /mob/living/simple_mob/humanoid/eclipse))
|
||||
potential_targets -= entry
|
||||
if(potential_targets.len)
|
||||
var/iteration = clamp(potential_targets.len, 1, 3)
|
||||
for(var/i = 0, i < iteration, i++)
|
||||
if(!(potential_targets.len))
|
||||
break
|
||||
var/mob/target = pick(potential_targets)
|
||||
potential_targets -= target
|
||||
spawn_lines(target)
|
||||
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/proc/spawn_lines(atom/target)
|
||||
var/alignment = rand(1,2) // 1 for vertical, 2 for horizontal
|
||||
var/list/line_range = list()
|
||||
var/turf/T = get_turf(target)
|
||||
line_range += T
|
||||
for(var/i = 1, i <= 7, i++)
|
||||
switch(alignment)
|
||||
if(1)
|
||||
if(T.x-i > 0)
|
||||
line_range += locate(T.x-i, T.y-i, T.z)
|
||||
if(T.x+i <= world.maxx)
|
||||
line_range += locate(T.x+i, T.y+i, T.z)
|
||||
if(T.y-i > 0)
|
||||
line_range += locate(T.x+i, T.y-i, T.z)
|
||||
if(T.y+i <= world.maxy)
|
||||
line_range += locate(T.x-i, T.y+i, T.z)
|
||||
if(2)
|
||||
if(T.x-i > 0)
|
||||
line_range += locate(T.x-i, T.y, T.z)
|
||||
if(T.x+i <= world.maxx)
|
||||
line_range += locate(T.x+i, T.y, T.z)
|
||||
if(T.y-i > 0)
|
||||
line_range += locate(T.x, T.y-i, T.z)
|
||||
if(T.y+i <= world.maxy)
|
||||
line_range += locate(T.x, T.y+i, T.z)
|
||||
for(var/turf/dropspot in line_range)
|
||||
new artidrop(dropspot)
|
||||
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/proc/bomb_chaos(atom/A)
|
||||
if(!A)
|
||||
return
|
||||
var/list/potential_targets = ai_holder.list_targets()
|
||||
for(var/atom/entry in potential_targets)
|
||||
if(istype(entry, /mob/living/simple_mob/humanoid/eclipse))
|
||||
potential_targets -= entry
|
||||
if(potential_targets.len)
|
||||
var/iteration = clamp(potential_targets.len, 1, 3)
|
||||
for(var/i = 0, i < iteration, i++)
|
||||
if(!(potential_targets.len))
|
||||
break
|
||||
var/mob/target = pick(potential_targets)
|
||||
potential_targets -= target
|
||||
chaos_lines(target)
|
||||
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/proc/chaos_lines(atom/target)
|
||||
var/alignment = rand(1,2)
|
||||
var/list/line_range = list()
|
||||
var/turf/T = get_turf(target)
|
||||
line_range += T
|
||||
for(var/i = 1, i <= 7, i++)
|
||||
switch(alignment)
|
||||
if(1)
|
||||
if(T.x-i > 0)
|
||||
var/zed = rand(1,3)
|
||||
line_range += locate(T.x+zed, T.y-i, T.z)
|
||||
if(T.x+i <= world.maxx)
|
||||
var/zed = rand(1,3)
|
||||
line_range += locate(T.x+zed, T.y+i, T.z)
|
||||
if(T.y-i > 0)
|
||||
var/zed = rand(1,3)
|
||||
line_range += locate(T.x+i, T.y+zed, T.z)
|
||||
if(T.y+i <= world.maxy)
|
||||
var/zed = rand(1,3)
|
||||
line_range += locate(T.x-i, T.y+zed, T.z)
|
||||
if(2)
|
||||
if(T.x-i > 0)
|
||||
var/zed = rand(1,3)
|
||||
line_range += locate(T.x-i, T.y-zed, T.z)
|
||||
if(T.x+i <= world.maxx)
|
||||
var/zed = rand(1,3)
|
||||
line_range += locate(T.x+i, T.y-zed, T.z)
|
||||
if(T.y-i > 0)
|
||||
var/zed = rand(1,3)
|
||||
line_range += locate(T.x-zed, T.y-i, T.z)
|
||||
if(T.y+i <= world.maxy)
|
||||
var/zed = rand(1,3)
|
||||
line_range += locate(T.x-zed, T.y+i, T.z)
|
||||
for(var/turf/dropspot in line_range)
|
||||
new artidrop(dropspot)
|
||||
|
||||
|
||||
/obj/effect/artillery_attack
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
unacidable = TRUE
|
||||
mouse_opacity = 0
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "drop_marker"
|
||||
var/ammmotype = /obj/effect/falling_effect/callstrike_bomb
|
||||
|
||||
/obj/effect/artillery_attack/Initialize(mapload)
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/effect/artillery_attack/LateInitialize()
|
||||
var/delay = rand(25, 30)
|
||||
addtimer(CALLBACK(src, PROC_REF(spawner)), delay, TIMER_DELETE_ME)
|
||||
|
||||
/obj/effect/artillery_attack/proc/spawner()
|
||||
new ammmotype(src.loc)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), src), 0.7 SECONDS, TIMER_DELETE_ME)
|
||||
|
||||
/obj/effect/falling_effect/callstrike_bomb
|
||||
falling_type = /obj/effect/callstrike
|
||||
crushing = FALSE
|
||||
|
||||
/obj/effect/callstrike
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
mouse_opacity = 0
|
||||
icon ='modular_chomp/icons/obj/guns/precursor/tyr.dmi'
|
||||
|
||||
/obj/effect/callstrike/Initialize(mapload)
|
||||
.=..()
|
||||
icon_state = "arti"
|
||||
|
||||
/obj/effect/callstrike/end_fall(var/crushing = FALSE)
|
||||
for(var/mob/living/L in loc)
|
||||
var/target_zone = ran_zone()
|
||||
var/blocked = L.run_armor_check(target_zone, "laser")
|
||||
|
||||
if(!L.apply_damage(70, BURN, target_zone, blocked))
|
||||
break
|
||||
playsound(src, 'sound/effects/clang2.ogg', 50, 1)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), src), 0.25 SECONDS, TIMER_DELETE_ME)
|
||||
|
||||
//Spacing
|
||||
/obj/effect/falling_effect/callstrike_slime
|
||||
falling_type = /obj/effect/callstrike_slime
|
||||
crushing = FALSE
|
||||
|
||||
/obj/effect/callstrike_slime
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
mouse_opacity = 0
|
||||
icon ='modular_chomp/icons/obj/guns/precursor/tyr.dmi'
|
||||
|
||||
/obj/effect/callstrike_slime/Initialize(mapload)
|
||||
.=..()
|
||||
icon_state = "squish"
|
||||
|
||||
/obj/effect/callstrike_slime/end_fall(var/crushing = FALSE)
|
||||
for(var/mob/living/L in loc)
|
||||
var/target_zone = ran_zone()
|
||||
var/blocked = L.run_armor_check(target_zone, "energy")
|
||||
|
||||
if(!L.apply_damage(50, BURN, target_zone, blocked))
|
||||
break
|
||||
playsound(src, 'sound/effects/squelch1.ogg', 50, 1)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), src), 0.25 SECONDS, TIMER_DELETE_ME)
|
||||
|
||||
|
||||
/obj/effect/artillery_attack/goop
|
||||
ammmotype = /obj/effect/falling_effect/callstrike_slime
|
||||
|
||||
/obj/effect/falling_effect/callstrike_slimezone
|
||||
falling_type = /obj/effect/slimeattack
|
||||
crushing = FALSE
|
||||
|
||||
/obj/effect/slimeattack
|
||||
name = "slime goop"
|
||||
desc = "A pool of acidic slime"
|
||||
icon_state = "pool"
|
||||
icon ='modular_chomp/icons/obj/guns/precursor/tyr.dmi'
|
||||
var/health = 5
|
||||
var/modifiertype = /datum/modifier/poisoned/weak
|
||||
|
||||
/obj/effect/slimeattack/Crossed(atom/movable/source)
|
||||
if(source.is_incorporeal())
|
||||
return
|
||||
Bumped(source)
|
||||
|
||||
/obj/effect/slimeattack/attackby(var/obj/item/W, var/mob/user)
|
||||
user.setClickCooldown(user.get_attack_speed(W))
|
||||
|
||||
if(LAZYLEN(W.attack_verb))
|
||||
visible_message(span_warning("\The [src] has been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]"))
|
||||
else
|
||||
visible_message(span_warning("\The [src] has been attacked with \the [W][(user ? " by [user]." : ".")]"))
|
||||
|
||||
var/damage = W.force / 4.0
|
||||
|
||||
health -= damage
|
||||
healthcheck()
|
||||
|
||||
|
||||
/obj/effect/slimeattack/bullet_act(var/obj/item/projectile/Proj)
|
||||
..()
|
||||
health -= Proj.get_structure_damage()
|
||||
healthcheck()
|
||||
|
||||
/obj/effect/slimeattack/proc/die()
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/slimeattack/proc/healthcheck()
|
||||
if(health <= 0)
|
||||
die()
|
||||
|
||||
/obj/effect/slimeattack/Bumped(mob/M as mob|obj)
|
||||
if(istype(M, /obj/mecha))
|
||||
return
|
||||
|
||||
if(istype(M, /mob/living/))
|
||||
var/mob/living/mob = M
|
||||
if(!mob.hovering || !mob.flying)
|
||||
attack_mob(M)
|
||||
|
||||
|
||||
/obj/effect/slimeattack/proc/attack_mob(mob/living/L)
|
||||
var/target_zone = pick(BP_ALL)
|
||||
var/amount_blocked = L.run_armor_check(target_zone, "bio")
|
||||
|
||||
var/damage = rand(5,5)
|
||||
|
||||
if(amount_blocked >= 40)
|
||||
return
|
||||
|
||||
L.apply_damage(damage, BURN, target_zone, amount_blocked, used_weapon = "slime")
|
||||
L.add_modifier(modifiertype, 5 SECONDS)
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/minion
|
||||
name = "Eclipse Expirment"
|
||||
desc = "A being in an armored spacesuit"
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/minion/squish_sphere
|
||||
name = "Eclipse Bio-Sphere"
|
||||
desc = "A floating orb of slime"
|
||||
health = 7
|
||||
maxHealth = 7
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 100)
|
||||
icon_state = "squishblob"
|
||||
icon_living = "squishblob"
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/intentional/adv_dark_gygax
|
||||
melee_damage_lower = 1
|
||||
melee_damage_upper = 1
|
||||
attack_armor_pen = 100 //90% sure we need damage for the application of mods to proc
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/minion/squish_sphere/apply_melee_effects(var/atom/A) //bring curea, a synth or gamble hard enough.
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
L.add_modifier(/datum/modifier/poisoned, 120 SECONDS)
|
||||
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/stargazer //starhunter boss replacement
|
||||
name = "Eclipse Stargazer"
|
||||
desc = "A being in an armored spacesuit"
|
||||
icon_state = "medi" //place holdery
|
||||
icon_living = "medi" //place holdery
|
||||
health = 600
|
||||
maxHealth = 600
|
||||
glow_toggle = TRUE
|
||||
glow_override = TRUE
|
||||
glow_color = "#FFA723"
|
||||
glow_range = 16
|
||||
armor = list(melee = 49, bullet = 49, laser = 49, energy = 49, bomb = 100, bio = 100, rad = 100)
|
||||
projectiletype = /obj/item/projectile/energy/homing_bolt
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/intentional/adv_dark_gygax
|
||||
loot_list = list(/obj/item/slime_extract/sepia = 25,
|
||||
/obj/item/slime_extract/ruby = 25,
|
||||
/obj/item/slime_extract/bluespace = 25,
|
||||
/obj/item/slime_extract/light_pink = 25,
|
||||
/obj/item/slime_extract/yellow = 25,
|
||||
/obj/item/slime_extract/oil = 25,
|
||||
)
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/stargazer/bullet_act(obj/item/projectile/P)
|
||||
..()
|
||||
for(var/i =1 to 3)
|
||||
new /mob/living/simple_mob/humanoid/eclipse/minion/squish_sphere
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/stargazer/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
..()
|
||||
new /mob/living/simple_mob/humanoid/eclipse/minion/squish_sphere
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/stargazer/do_special_attack(atom/A)
|
||||
if(prob(50))
|
||||
artidrop = /obj/effect/artillery_attack/goop
|
||||
if(prob(50))
|
||||
bomb_lines(A)
|
||||
else
|
||||
chaos_lines(A)
|
||||
else
|
||||
artidrop = /obj/effect/falling_effect/callstrike_slime
|
||||
if(prob(50))
|
||||
bomb_lines(A)
|
||||
else
|
||||
chaos_lines(A)
|
||||
@@ -1,153 +0,0 @@
|
||||
/datum/category_item/catalogue/fauna/eclipse
|
||||
name = "The Eclipse"
|
||||
desc = "Life on the Frontier is hard, and unregulated. Unlike life in \
|
||||
more 'civlized' areas of the Galaxy, violence and piracy remain common \
|
||||
this far out. The Eclipse cares naught for this, rather their attention \
|
||||
shifting to the fallen kingdoms and empires of the past. \
|
||||
Salavaging secerts and materials long forgotton and stiching them \
|
||||
togther in new, strange creations."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
unlocked_by_any = list(/datum/category_item/catalogue/fauna/eclipse)
|
||||
|
||||
|
||||
/datum/category_item/catalogue/fauna/eclipse/teslanoodle
|
||||
name = "The Tesla Armor"
|
||||
desc = "The tesla's units armor crackles with eletrical current. \
|
||||
Manifestation of such energy seeming to be summoned at will or at \
|
||||
random. This creation seems to be in a prototype phase."
|
||||
value = CATALOGUER_REWARD_MEDIUM
|
||||
|
||||
/datum/category_item/catalogue/fauna/eclipse/firemoff
|
||||
name = "Eclipse Shielding"
|
||||
desc = "Eclipse armor and uniform is unlike most others, seeming wide \
|
||||
and varied, but in reality is simplified to two diffrent types. \
|
||||
One of the Eclipse's first studies was a mix of precursor ablative and \
|
||||
bullet proof technolgy. They have gotten an understanding of it, they \
|
||||
are able to fuse it with many diffrent uniforms, allowing for a more \
|
||||
diverse apperance."
|
||||
value = CATALOGUER_REWARD_MEDIUM
|
||||
|
||||
/datum/category_item/catalogue/fauna/eclipse/snipertesh
|
||||
name = "Cult-like rituals"
|
||||
desc = "The Eclipse started off as a strange mixutre of a friendly \
|
||||
band, and lower tier orginization. as their technolgy has evolved, so did \
|
||||
their behaviors. Some sects begining to worship and heavly praise the fallen \
|
||||
precusor empires. Some going as far to try and revivive them, always to \
|
||||
mixed results, rarely resulting in in-fighting."
|
||||
value = CATALOGUER_REWARD_MEDIUM
|
||||
|
||||
|
||||
/datum/category_item/catalogue/fauna/eclipse/radiation
|
||||
name = "Nuclear Failures"
|
||||
desc = "Failure is not an option for the Eclipse. More so, failure \
|
||||
is just another opportunity to learn. Their radiation units coming\
|
||||
from serveral failures of nuclear power soruces alongside failures amongst, \
|
||||
nuclear weaponry. Eventually creating quality weapons, and refitting their \
|
||||
power sources to radiation field generators."
|
||||
value = CATALOGUER_REWARD_MEDIUM
|
||||
|
||||
|
||||
/datum/category_item/catalogue/fauna/eclipse/silvernoodle
|
||||
name = "Failed Selling"
|
||||
desc = "While one would think the Eclipse would become rather wealthy and \
|
||||
fame from their line of work, they are instead rather average due to most \
|
||||
of their products having a high chance of failure. For every working weapon, \
|
||||
armor, tool, there are at least 10 failures. Resleeving and high quality \
|
||||
medication are one of the few reasons they have not wiped themselves out."
|
||||
value = CATALOGUER_REWARD_MEDIUM
|
||||
|
||||
|
||||
|
||||
/datum/category_item/catalogue/fauna/eclipse/shotgunner
|
||||
name = "Specialized Arms"
|
||||
desc = "The Eclipse's focus on utilizing precursor tech leads them down \
|
||||
strange weaponry. Even with firearms, they are always modified slightly \
|
||||
just to fufill having some form of what they see as future tech. \
|
||||
Although this leads to weapon failures, or creation accidents."
|
||||
value = CATALOGUER_REWARD_MEDIUM
|
||||
|
||||
|
||||
/datum/category_item/catalogue/fauna/eclipse/bulletstorm
|
||||
name = "Open Joining"
|
||||
desc = "The Eclipse has many varying memebers, of all diffrent shapes, \
|
||||
sizes, and heritages. This is due to a varity of factors, which includes \
|
||||
high mortality rates, mutations, and body modification expermintation."
|
||||
value = CATALOGUER_REWARD_MEDIUM
|
||||
|
||||
/datum/category_item/catalogue/fauna/eclipse/ravanger
|
||||
name = "Resleeving Failures"
|
||||
desc = "The Eclipse has precourdered many bits of resleeving equipment \
|
||||
but like most of that comes into their grasp it has become more dangerous \
|
||||
and expirmental. Corruption and malformed bodies have become common place, \
|
||||
minds becoming lost. But failure is non-exsistant, instead being repurosed \
|
||||
such as shaping them into ravanger units."
|
||||
value = CATALOGUER_REWARD_MEDIUM
|
||||
|
||||
/datum/category_item/catalogue/fauna/eclipse/hellhound
|
||||
name = "Hellhound Units"
|
||||
desc = "Equiped with specialized armor, the systems of the suit pairing \
|
||||
with their nervous system in an attempt to allow for better hunting. \
|
||||
Venom is found within their claws and fangs, the chemical compound being, \
|
||||
akin to soporific, The hellhound units are both useful for single target \
|
||||
hunting, and frontal assualt."
|
||||
value = CATALOGUER_REWARD_MEDIUM
|
||||
|
||||
/datum/category_item/catalogue/fauna/eclipse/wheel
|
||||
name = "Armadillo"
|
||||
desc = "With several strange creatures among their ranks, the Eclipse \
|
||||
has attempted strange and usual armors and tatics. With several being able \
|
||||
to curl up into a ball shape, the wheel armor was created, trying to turn \
|
||||
a rolling motion into an offensive force."
|
||||
value = CATALOGUER_REWARD_MEDIUM
|
||||
|
||||
/datum/category_item/catalogue/fauna/eclipse/guardian
|
||||
name = "Slime Pits"
|
||||
desc = "Another potential of failed resleeves are the slime pits, \
|
||||
the failed body being merged with one of their many slimes, creating something \
|
||||
akin to a promethean but having a mind more akin to a drone. Some of the \
|
||||
slime creations the similiar abilties to their slime counter parts, or \
|
||||
renamants of the donator's DNA."
|
||||
value = CATALOGUER_REWARD_MEDIUM
|
||||
|
||||
/datum/category_item/catalogue/fauna/eclipse/pummler
|
||||
name = "Hunter Unit - Pummler"
|
||||
desc = "Another drone like creation, meld with alien sea life, and traces \
|
||||
renamants of solar grubs. Was orginally meant for assualting mecha pilots, \
|
||||
and tearing them free from the mechas, but prooved to be too variable with \
|
||||
results. Instead their desgin changing to that of hunting down single \
|
||||
targets across any and all terrains."
|
||||
value = CATALOGUER_REWARD_MEDIUM
|
||||
|
||||
/datum/category_item/catalogue/fauna/eclipse/aeroblaster
|
||||
name = "Eclipse Drones"
|
||||
desc = "Sometimes, the failed resleeves only leave the fragments of a mind \
|
||||
behind. But even that is useful, latching onto the renamants of loyalty and \
|
||||
the brain's remaining procressing power to create special circuits for, \
|
||||
their drones."
|
||||
value = CATALOGUER_REWARD_MEDIUM
|
||||
|
||||
/datum/category_item/catalogue/fauna/eclipse/miner
|
||||
name = "Bio-tech Unit"
|
||||
desc = "One benefit of the slime units is they're able to easily interface \
|
||||
with the drone units. Cooperation is keenly unquie between the slime and \
|
||||
drone units. This is espically helpful within hazardous mining conditions \
|
||||
both being able to flee or alter plans as soon as either noitces."
|
||||
value = CATALOGUER_REWARD_MEDIUM
|
||||
|
||||
|
||||
/datum/category_item/catalogue/fauna/eclipse/froststalker
|
||||
name = "Mindless Ice"
|
||||
desc = "Cryogel expermination has been one of the most active fronts, but \
|
||||
with it, countless failures. Whilst not on purpose, many of their number\
|
||||
have had their bodies freeze over, transforming into sentient creatures, \
|
||||
of ice. Their minds sometimes lost alongside their orginal form."
|
||||
value = CATALOGUER_REWARD_MEDIUM
|
||||
|
||||
/datum/category_item/catalogue/fauna/eclipse/cryomancer
|
||||
name = "Cryomancers"
|
||||
desc = "One of the few success in the Pluto Intitative, but one that \
|
||||
yields great results. Highly resistant to cold, and heat, more so then it's \
|
||||
contemparies, all the while wielding expirmental frost weaponry to deadly \
|
||||
effecieny. Rare and vaulable pieces in the Eclipse's army, they are rarely seen \
|
||||
but when utilized, that area is of high priority. "
|
||||
value = CATALOGUER_REWARD_MEDIUM
|
||||
@@ -1,149 +0,0 @@
|
||||
/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 = 30
|
||||
vore_icons = null
|
||||
|
||||
can_be_drop_prey = FALSE
|
||||
can_be_drop_pred = TRUE
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/Login()
|
||||
. = ..()
|
||||
if(!riding_datum)
|
||||
riding_datum = new /datum/riding/simple_mob(src)
|
||||
add_verb(src,/mob/living/simple_mob/proc/animal_mount) //CHOMPEdit TGPanel
|
||||
add_verb(src,/mob/living/proc/toggle_rider_reins) //CHOMPEdit TGPanel
|
||||
movement_cooldown = 3
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/MouseDrop_T(mob/living/M, mob/living/user)
|
||||
return
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/load_default_bellies()
|
||||
. = ..()
|
||||
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.
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/scientist
|
||||
vore_active = 1
|
||||
vore_capacity = 6
|
||||
vore_max_size = RESIZE_HUGE
|
||||
vore_min_size = RESIZE_SMALL
|
||||
vore_pounce_chance = 0 // Beat them into crit before eating.
|
||||
|
||||
can_be_drop_prey = FALSE //CHOMP Add
|
||||
digestable = 0
|
||||
devourable = 0
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/scientist/Login()
|
||||
. = ..()
|
||||
if(!riding_datum)
|
||||
riding_datum = new /datum/riding/simple_mob(src)
|
||||
add_verb(src,/mob/living/simple_mob/proc/animal_mount) //CHOMPEdit TGPanel
|
||||
add_verb(src,/mob/living/proc/toggle_rider_reins) //CHOMPEdit TGPanel
|
||||
movement_cooldown = 1
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/scientist/MouseDrop_T(mob/living/M, mob/living/user)
|
||||
return
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/scientist/load_default_bellies()
|
||||
. = ..()
|
||||
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.",
|
||||
"Your surrondings glow with a neon red, dashes and spirals of pitch black flowing through the red gummy flesh as if it were a strange sky.",
|
||||
"Your satsified predator sways their bloated gullet happily, their warm rumbling vibrarting the stomach, and by extension you.",)
|
||||
|
||||
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!",
|
||||
"The caustic red acid splashes, and washes over your frame, your sense of smell being overwhelmed by acid and sulfur as you're turned to nutrion.",
|
||||
"Every swift swap of the predator's hips sends you slamming against the glowing red sides, your vision blurring further as you contunie to weaken." ,)
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/security
|
||||
vore_active = 1
|
||||
vore_capacity = 6
|
||||
vore_max_size = RESIZE_HUGE
|
||||
vore_min_size = RESIZE_SMALL
|
||||
vore_pounce_chance = 0 // Beat them into crit before eating.
|
||||
|
||||
can_be_drop_prey = FALSE //CHOMP Add
|
||||
digestable = 0
|
||||
devourable = 0
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/security/Login()
|
||||
. = ..()
|
||||
if(!riding_datum)
|
||||
riding_datum = new /datum/riding/simple_mob(src)
|
||||
add_verb(src,/mob/living/simple_mob/proc/animal_mount) //CHOMPEdit TGPanel
|
||||
add_verb(src,/mob/living/proc/toggle_rider_reins) //CHOMPEdit TGPanel
|
||||
movement_cooldown = 1
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/security/MouseDrop_T(mob/living/M, mob/living/user)
|
||||
return
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/security/load_default_bellies()
|
||||
. = ..()
|
||||
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.",
|
||||
"Your surrondings glow with a neon red, dashes and spirals of pitch black flowing through the red gummy flesh as if it were a strange sky.",
|
||||
"Your satsified predator sways their bloated gullet happily, their warm rumbling vibrarting the stomach, and by extension you.",)
|
||||
|
||||
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!",
|
||||
"The caustic red acid splashes, and washes over your frame, your sense of smell being overwhelmed by acid and sulfur as you're turned to nutrion.",
|
||||
"Every swift swap of the predator's hips sends you slamming against the glowing red sides, your vision blurring further as you contunie to weaken." ,)
|
||||
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/captain
|
||||
vore_active = 1
|
||||
vore_capacity = 6
|
||||
vore_max_size = RESIZE_HUGE
|
||||
vore_min_size = RESIZE_SMALL
|
||||
vore_pounce_chance = 0 // Beat them into crit before eating.
|
||||
|
||||
can_be_drop_prey = FALSE //CHOMP Add
|
||||
digestable = 0
|
||||
devourable = 0
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/captain/Login()
|
||||
. = ..()
|
||||
if(!riding_datum)
|
||||
riding_datum = new /datum/riding/simple_mob(src)
|
||||
add_verb(src,/mob/living/simple_mob/proc/animal_mount) //CHOMPEdit TGPanel
|
||||
add_verb(src,/mob/living/proc/toggle_rider_reins) //CHOMPEdit TGPanel
|
||||
movement_cooldown = 1
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/captain/MouseDrop_T(mob/living/M, mob/living/user)
|
||||
return
|
||||
|
||||
/mob/living/simple_mob/humanoid/eclipse/head/captain/load_default_bellies()
|
||||
. = ..()
|
||||
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.",
|
||||
"Your surrondings glow with a neon red, dashes and spirals of pitch black flowing through the red gummy flesh as if it were a strange sky.",
|
||||
"Your satsified predator sways their bloated gullet happily, their warm rumbling vibrarting the stomach, and by extension you.",)
|
||||
|
||||
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!",
|
||||
"The caustic red acid splashes, and washes over your frame, your sense of smell being overwhelmed by acid and sulfur as you're turned to nutrion.",
|
||||
"Every swift swap of the predator's hips sends you slamming against the glowing red sides, your vision blurring further as you contunie to weaken." ,)
|
||||
-219
@@ -1,219 +0,0 @@
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/clone
|
||||
name = "Avatar Of The Serpent"
|
||||
icon_state = "avatar"
|
||||
health = 15
|
||||
maxHealth = 15
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/ranged/aggressive/starhunter
|
||||
projectiletype = /obj/item/projectile/energy/ninjastar
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/avatar
|
||||
name = "Avatar Of The Serpent"
|
||||
icon_state = "avatar"
|
||||
health = 1000 //50 hits from 20 damage
|
||||
maxHealth = 1000 //50 hits from 20 damage
|
||||
damage_fatigue_mult = 0
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/ranged/aggressive/starhunter
|
||||
special_attack_cooldown = 20 SECONDS
|
||||
special_attack_min_range = 1
|
||||
special_attack_max_range = 7
|
||||
projectiletype = /obj/item/projectile/energy/ninjastar
|
||||
digestable = 0
|
||||
devourable = 0
|
||||
//note to self, expand the loot list later
|
||||
loot_list = list(/obj/item/storage/belt/holding = 60,
|
||||
/obj/item/clothing/glasses/omni = 60,
|
||||
/obj/item/kinetic_crusher/glaive = 60,
|
||||
/obj/item/slime_extract/sepia = 60,
|
||||
/obj/item/circuitboard/defenseonelisk = 60,
|
||||
/obj/item/circuitboard/paradoxrift = 60,
|
||||
/obj/item/capture_crystal = 60
|
||||
)
|
||||
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/avatar/updatehealth()
|
||||
. = ..()
|
||||
|
||||
if(health < maxHealth*0.25)
|
||||
special_attack_cooldown = 5 SECONDS
|
||||
projectiletype = /obj/item/projectile/bullet/ninjaburst
|
||||
else if(health < maxHealth*0.5)
|
||||
special_attack_cooldown = 10 SECONDS
|
||||
projectiletype = /obj/item/projectile/energy/kunai
|
||||
else if (health < maxHealth*0.75)
|
||||
special_attack_cooldown = 15 SECONDS
|
||||
projectiletype = /obj/item/projectile/energy/chakaram
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/avatar/do_special_attack(atom/A)
|
||||
if(health < maxHealth*0.4)
|
||||
if(prob(20))
|
||||
lightingstorm(A)
|
||||
if(prob(20))
|
||||
lightingline(A)
|
||||
if(prob(20))
|
||||
lightpillar(A)
|
||||
if(prob(20))
|
||||
clones(A)
|
||||
else
|
||||
rapidfire_windup(A)
|
||||
else if(health < maxHealth*0.7)
|
||||
if(prob(25))
|
||||
lightingstorm(A)
|
||||
if(prob(25))
|
||||
lightingline(A)
|
||||
if(prob(25))
|
||||
lightpillar(A)
|
||||
else
|
||||
rapidfire_windup(A)
|
||||
else
|
||||
if(prob(50))
|
||||
lightingstrike(A)
|
||||
else
|
||||
lightpillar(A)
|
||||
|
||||
/obj/item/projectile/energy/kunai //chip damage
|
||||
name = "Energy Kunai"
|
||||
icon = 'modular_chomp/icons/mob/starhunters.dmi' //commiting sin
|
||||
icon_state = "kunai"
|
||||
damage = 5
|
||||
armor_penetration = 65 //Gets into the gaps
|
||||
speed = 2
|
||||
damage_type = BURN
|
||||
check_armour = "laser"
|
||||
|
||||
/obj/item/projectile/energy/chakaram //slower but hits harder
|
||||
name = "Energy Chakaram"
|
||||
icon = 'modular_chomp/icons/mob/starhunters.dmi' //commiting sin
|
||||
icon_state = "chakaram"
|
||||
damage = 25
|
||||
armor_penetration = 25 //Gets into the gaps
|
||||
speed = 5
|
||||
damage_type = BURN
|
||||
check_armour = "laser"
|
||||
|
||||
/obj/item/projectile/bullet/ninjaburst
|
||||
use_submunitions = 1
|
||||
only_submunitions = 1
|
||||
range = 0
|
||||
embed_chance = 0
|
||||
submunition_spread_max = 2600
|
||||
submunition_spread_min = 150
|
||||
submunitions = list(/obj/item/projectile/energy/kunai = 3, /obj/item/projectile/energy/chakaram = 1, /obj/item/projectile/energy/ninjastar = 3)
|
||||
|
||||
/datum/ai_holder/simple_mob/ranged/aggressive/starhunter
|
||||
vision_range = 14
|
||||
closest_distance = 5
|
||||
returns_home = TRUE // Stay close to the base...
|
||||
wander = TRUE // ... but "patrol" a little.
|
||||
intelligence_level = AI_SMART // Also knows not to walk while confused if it risks death.
|
||||
mauling = TRUE
|
||||
call_distance = 0 //Trying to disable this for the mobs
|
||||
retaliate = TRUE
|
||||
hostile = FALSE
|
||||
violent_breakthrough = TRUE
|
||||
respect_alpha = FALSE
|
||||
pointblank = TRUE
|
||||
|
||||
/obj/effect/calldown_attack_lighting
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
unacidable = TRUE
|
||||
mouse_opacity = 0
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "drop_marker"
|
||||
|
||||
/obj/effect/calldown_attack_lighting/Initialize(mapload)
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/effect/calldown_attack_fire/LateInitialize()
|
||||
var/delay = rand(25, 30)
|
||||
spawn(delay-7)
|
||||
lightning_strike(src.loc)
|
||||
spawn(delay)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/avatar/proc/lightingstorm(atom/A)
|
||||
var/list/potential_targets = ai_holder.list_targets()
|
||||
for(var/atom/entry in potential_targets)
|
||||
if(istype(entry, /mob/living/simple_mob/humanoid/starhunter/hunter))
|
||||
potential_targets -= entry
|
||||
if(potential_targets.len)
|
||||
var/iteration = clamp(potential_targets.len, 1, 3)
|
||||
for(var/i = 0, i < iteration, i++)
|
||||
if(!(potential_targets.len))
|
||||
break
|
||||
var/mob/target = pick(potential_targets)
|
||||
potential_targets -= target
|
||||
lightingstormfollow(target)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/avatar/proc/lightingstormfollow(atom/target)
|
||||
var/list/bomb_range = block(locate(target.x-6, target.y-6, target.z), locate(target.x+6, target.y+6, target.z))
|
||||
new /obj/effect/calldown_attack(get_turf(target))
|
||||
bomb_range -= get_turf(target)
|
||||
for(var/i = 0, i < 4, i++)
|
||||
var/turf/T = pick(bomb_range)
|
||||
new /obj/effect/calldown_attack_lighting(T)
|
||||
bomb_range -= T
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/avatar/proc/lightingline(atom/A)
|
||||
var/list/potential_targets = ai_holder.list_targets()
|
||||
for(var/atom/entry in potential_targets)
|
||||
if(istype(entry, /mob/living/simple_mob/humanoid/starhunter/hunter))
|
||||
potential_targets -= entry
|
||||
if(potential_targets.len)
|
||||
var/iteration = clamp(potential_targets.len, 1, 3)
|
||||
for(var/i = 0, i < iteration, i++)
|
||||
if(!(potential_targets.len))
|
||||
break
|
||||
var/mob/target = pick(potential_targets)
|
||||
potential_targets -= target
|
||||
lightinglinefollow(target)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/avatar/proc/lightinglinefollow(atom/target)
|
||||
var/alignment = rand(1,2) // 1 for vertical, 2 for horizontal
|
||||
var/list/line_range = list()
|
||||
var/turf/T = get_turf(target)
|
||||
line_range += T
|
||||
for(var/i = 1, i <= 7, i++)
|
||||
switch(alignment)
|
||||
if(1)
|
||||
if(T.x-i > 0)
|
||||
line_range += locate(T.x-i, T.y, T.z)
|
||||
if(T.x+i <= world.maxx)
|
||||
line_range += locate(T.x+i, T.y, T.z)
|
||||
if(2)
|
||||
if(T.y-i > 0)
|
||||
line_range += locate(T.x, T.y-i, T.z)
|
||||
if(T.y+i <= world.maxy)
|
||||
line_range += locate(T.x, T.y+i, T.z)
|
||||
for(var/turf/dropspot in line_range)
|
||||
new /obj/effect/calldown_attack_lighting(dropspot)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/avatar/proc/clones(atom/A)
|
||||
new /mob/living/simple_mob/humanoid/starhunter/hunter/clone (src.loc)
|
||||
new /mob/living/simple_mob/humanoid/starhunter/hunter/clone (src.loc)
|
||||
new /mob/living/simple_mob/humanoid/starhunter/hunter/clone (src.loc)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/avatar/proc/lightingstrike(atom/A)
|
||||
var/list/nearby_things = range(1, A)
|
||||
var/list/valid_turfs = list()
|
||||
|
||||
// All this work to just go to a non-dense tile.
|
||||
for(var/turf/potential_turf in nearby_things)
|
||||
var/valid_turf = TRUE
|
||||
if(potential_turf.density)
|
||||
continue
|
||||
for(var/atom/movable/AM in potential_turf)
|
||||
if(AM.density)
|
||||
valid_turf = FALSE
|
||||
if(valid_turf)
|
||||
valid_turfs.Add(potential_turf)
|
||||
|
||||
if(!(valid_turfs.len))
|
||||
to_chat(src, span_warning("There wasn't an unoccupied spot to teleport to."))
|
||||
return FALSE
|
||||
|
||||
var/turf/target_turf = pick(valid_turfs)
|
||||
|
||||
new/obj/effect/calldown_attack_lighting(target_turf)
|
||||
-156
@@ -1,156 +0,0 @@
|
||||
/mob/living/simple_mob/humanoid/starhunter
|
||||
name = "Starhunter Initiate"
|
||||
desc = "A strange critter cladded in strange armor."
|
||||
icon = 'modular_chomp/icons/mob/starhunters.dmi'
|
||||
icon_state = "sun"
|
||||
icon_living = "sun"
|
||||
icon_dead = "statisgem"
|
||||
icon_gib = "syndicate_gib"
|
||||
taser_kill = 0
|
||||
|
||||
faction = "starhunter"
|
||||
movement_cooldown = 0
|
||||
|
||||
status_flags = 0
|
||||
|
||||
response_help = "pokes"
|
||||
response_disarm = "shoves"
|
||||
response_harm = "hits"
|
||||
|
||||
health = 120 //This may be high, but intend for the combative ones to be on their own.
|
||||
maxHealth = 120
|
||||
harm_intent_damage = 5
|
||||
melee_damage_lower = 17 //machette
|
||||
melee_damage_upper = 17 //beg knife go brrr
|
||||
attack_sharp = 1
|
||||
attack_edge = 1
|
||||
attacktext = list("slashed", "stabbed")
|
||||
projectile_dispersion = 8
|
||||
projectile_accuracy = -20
|
||||
armor = list(melee = 40, bullet = 70, laser = 10, energy = 0, bomb = 50, bio = 100, rad = 100) // Critters are more ortiented torwards melee and bullet
|
||||
ranged_cooldown = 5
|
||||
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/starhunter
|
||||
|
||||
can_be_drop_prey = FALSE
|
||||
pass_flags = PASSTABLE
|
||||
softfall = TRUE
|
||||
|
||||
//spaceproofing things
|
||||
minbodytemp = 0 // Minimum "okay" temperature in kelvin
|
||||
maxbodytemp = 600 // Maximum of above
|
||||
|
||||
min_oxy = 0 // Oxygen in moles, minimum, 0 is 'no minimum'
|
||||
max_oxy = 0 // Oxygen in moles, maximum, 0 is 'no maximum'
|
||||
min_tox = 0 // Phoron min
|
||||
max_tox = 0 // Phoron max
|
||||
min_co2 = 0 // CO2 min
|
||||
max_co2 = 0 // CO2 max
|
||||
min_n2 = 0 // N2 min
|
||||
max_n2 = 0
|
||||
|
||||
/datum/ai_holder/simple_mob/starhunter
|
||||
returns_home = TRUE // Stay close to the base...
|
||||
wander = TRUE // ... but "patrol" a little.
|
||||
intelligence_level = AI_SMART // Also knows not to walk while confused if it risks death.
|
||||
can_flee = TRUE // If they're even allowed to flee.
|
||||
flee_when_dying = TRUE // If they should flee when low on health.
|
||||
dying_threshold = 0.2 // How low on health the holder needs to be before fleeing. Defaults to 30% or lower health.
|
||||
mauling = TRUE
|
||||
call_distance = 0 //Trying to disable this for the mobs
|
||||
vision_range = 10
|
||||
retaliate = TRUE
|
||||
hostile = FALSE
|
||||
violent_breakthrough = TRUE
|
||||
respect_alpha = FALSE
|
||||
pointblank = TRUE
|
||||
|
||||
/datum/ai_holder/simple_mob/starhunter/aggro
|
||||
hostile = TRUE
|
||||
|
||||
//basic aggro stahunters
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/starhunter/aggro
|
||||
special_attack_cooldown = 30 SECONDS
|
||||
special_attack_min_range = 1
|
||||
special_attack_max_range = 7
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/harvester
|
||||
icon_state = "snekdruid"
|
||||
icon_state = "snekdruid"
|
||||
melee_damage_lower = 25
|
||||
melee_damage_upper = 25
|
||||
melee_attack_delay = 2.5 SECOND
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/harvester/handle_special() //wierd movement
|
||||
if(prob(20))
|
||||
step(src, pick(GLOB.cardinal))
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/ninja
|
||||
icon_state = "suneswift"
|
||||
icon_living = "suneswift"
|
||||
movement_cooldown = -3
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
melee_attack_delay = 1.5 SECOND
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/ninja/do_special_attack(atom/target)
|
||||
if(prob(50))
|
||||
teleportnompf(target)
|
||||
else
|
||||
smokebomb(target)
|
||||
//Special attack procs
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/proc/teleportnompf(atom/target)
|
||||
var/list/nearby_things = range(1, target)
|
||||
var/list/valid_turfs = list()
|
||||
|
||||
for(var/turf/potential_turf in nearby_things)
|
||||
var/valid_turf = TRUE
|
||||
if(potential_turf.density)
|
||||
continue
|
||||
for(var/atom/movable/AM in potential_turf)
|
||||
if(AM.density)
|
||||
valid_turf = FALSE
|
||||
if(valid_turf)
|
||||
valid_turfs.Add(potential_turf)
|
||||
|
||||
if(!(valid_turfs.len))
|
||||
to_chat(src, span_warning("There wasn't an unoccupied spot to teleport to."))
|
||||
return FALSE
|
||||
|
||||
var/turf/target_turf = pick(valid_turfs)
|
||||
|
||||
forceMove(target_turf)
|
||||
|
||||
var/mob/living/L = target
|
||||
var/obj/belly/belly_dest
|
||||
|
||||
if(L.can_be_drop_prey && L.devourable)
|
||||
L.forceMove(belly_dest)
|
||||
to_chat(target, span_danger("[src] materializes around you, as you end up in their [belly_dest]!"))
|
||||
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/proc/smokebomb(atom/target)
|
||||
var/list/nearby_things = range(1, target)
|
||||
var/list/valid_turfs = list()
|
||||
|
||||
// All this work to just go to a non-dense tile.
|
||||
for(var/turf/potential_turf in nearby_things)
|
||||
var/valid_turf = TRUE
|
||||
if(potential_turf.density)
|
||||
continue
|
||||
for(var/atom/movable/AM in potential_turf)
|
||||
if(AM.density)
|
||||
valid_turf = FALSE
|
||||
if(valid_turf)
|
||||
valid_turfs.Add(potential_turf)
|
||||
|
||||
if(!(valid_turfs.len))
|
||||
to_chat(src, span_warning("There wasn't an unoccupied spot to teleport to."))
|
||||
return FALSE
|
||||
|
||||
var/turf/target_turf = pick(valid_turfs)
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/s2 = new /datum/effect/effect/system/smoke_spread
|
||||
s2.set_up(5, 1, target_turf)
|
||||
-108
@@ -1,108 +0,0 @@
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/druid
|
||||
vore_active = 1
|
||||
vore_capacity = 6
|
||||
vore_max_size = RESIZE_HUGE
|
||||
vore_min_size = RESIZE_SMALL
|
||||
vore_pounce_chance = 0 // Beat them into crit before eating.
|
||||
|
||||
can_be_drop_prey = FALSE //CHOMP Add
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/druid/Login()
|
||||
. = ..()
|
||||
if(!riding_datum)
|
||||
riding_datum = new /datum/riding/simple_mob(src)
|
||||
add_verb(src,/mob/living/simple_mob/proc/animal_mount) //CHOMPEdit TGPanel
|
||||
add_verb(src,/mob/living/proc/toggle_rider_reins) //CHOMPEdit TGPanel
|
||||
movement_cooldown = 1
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/druid/MouseDrop_T(mob/living/M, mob/living/user)
|
||||
return
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/druid/load_default_bellies()
|
||||
. = ..()
|
||||
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.",
|
||||
"Your surrondings glow with a neon red, dashes and spirals of pitch black flowing through the red gummy flesh as if it were a strange sky.",
|
||||
"Your satsified predator sways their bloated gullet happily, their warm rumbling vibrarting the stomach, and by extension you.",)
|
||||
|
||||
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!",
|
||||
"The caustic red acid splashes, and washes over your frame, your sense of smell being overwhelmed by acid and sulfur as you're turned to nutrion.",
|
||||
"Every swift swap of the predator's hips sends you slamming against the glowing red sides, your vision blurring further as you contunie to weaken." ,)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/champion
|
||||
vore_active = 1
|
||||
vore_capacity = 6
|
||||
vore_max_size = RESIZE_HUGE
|
||||
vore_min_size = RESIZE_SMALL
|
||||
vore_pounce_chance = 0 // Beat them into crit before eating.
|
||||
|
||||
can_be_drop_prey = FALSE //CHOMP Add
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/champion/Login()
|
||||
. = ..()
|
||||
if(!riding_datum)
|
||||
riding_datum = new /datum/riding/simple_mob(src)
|
||||
add_verb(src,/mob/living/simple_mob/proc/animal_mount) //CHOMPEdit TGPanel
|
||||
add_verb(src,/mob/living/proc/toggle_rider_reins) //CHOMPEdit TGPanel
|
||||
movement_cooldown = 1
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/champion/MouseDrop_T(mob/living/M, mob/living/user)
|
||||
return
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/champion/load_default_bellies()
|
||||
. = ..()
|
||||
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.",
|
||||
"Your surrondings glow with a neon red, dashes and spirals of pitch black flowing through the red gummy flesh as if it were a strange sky.",
|
||||
"Your satsified predator sways their bloated gullet happily, their warm rumbling vibrarting the stomach, and by extension you.",)
|
||||
|
||||
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!",
|
||||
"The caustic red acid splashes, and washes over your frame, your sense of smell being overwhelmed by acid and sulfur as you're turned to nutrion.",
|
||||
"Every swift swap of the predator's hips sends you slamming against the glowing red sides, your vision blurring further as you contunie to weaken." ,)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/avatar
|
||||
vore_active = 1
|
||||
vore_capacity = 6
|
||||
vore_max_size = RESIZE_HUGE
|
||||
vore_min_size = RESIZE_SMALL
|
||||
vore_pounce_chance = 0 // Beat them into crit before eating.
|
||||
vore_icons = SA_ICON_LIVING
|
||||
|
||||
can_be_drop_prey = FALSE //CHOMP Add
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/avatar/Login()
|
||||
. = ..()
|
||||
if(!riding_datum)
|
||||
riding_datum = new /datum/riding/simple_mob(src)
|
||||
add_verb(src,/mob/living/simple_mob/proc/animal_mount) //CHOMPEdit TGPanel
|
||||
add_verb(src,/mob/living/proc/toggle_rider_reins) //CHOMPEdit TGPanel
|
||||
movement_cooldown = 1
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/avatar/MouseDrop_T(mob/living/M, mob/living/user)
|
||||
return
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/avatar/load_default_bellies()
|
||||
. = ..()
|
||||
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.",
|
||||
"Your surrondings glow with a neon red, dashes and spirals of pitch black flowing through the red gummy flesh as if it were a strange sky.",
|
||||
"Your satsified predator sways their bloated gullet happily, their warm rumbling vibrarting the stomach, and by extension you.",)
|
||||
|
||||
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!",
|
||||
"The caustic red acid splashes, and washes over your frame, your sense of smell being overwhelmed by acid and sulfur as you're turned to nutrion.",
|
||||
"Every swift swap of the predator's hips sends you slamming against the glowing red sides, your vision blurring further as you contunie to weaken." ,)
|
||||
-242
@@ -1,242 +0,0 @@
|
||||
//beg critters
|
||||
//kitsune is bullet hell esque in a traditonal sense
|
||||
//naga does a bunch of spawning and CoC
|
||||
//This are both training for the bigger dude I'll make later
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/druid
|
||||
name = "Starhunter Druid"
|
||||
health = 200 //20 hits from 20 damage
|
||||
maxHealth = 200 //20 hits from 20 damage
|
||||
damage_fatigue_mult = 0
|
||||
icon_state = "snekdruid"
|
||||
icon_living = "snekdruid"
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/druid/do_special_attack(atom/A)
|
||||
if(prob(50))
|
||||
lightpillar(A)
|
||||
else
|
||||
fire_lines(A)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/bullet_act(obj/item/projectile/P)
|
||||
if(istype(P, /obj/item/projectile/energy/lightpillar))
|
||||
visible_message(span_bolddanger(span_orange("[P] seems ineffective!."))) //immune to their own attack
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/proc/lightpillar(atom/A)
|
||||
var/list/potential_targets = ai_holder.list_targets()
|
||||
for(var/atom/entry in potential_targets)
|
||||
if(istype(entry, /mob/living/simple_mob/humanoid/starhunter/hunter))
|
||||
potential_targets -= entry
|
||||
if(potential_targets.len)
|
||||
var/iteration = clamp(potential_targets.len, 1, 3)
|
||||
for(var/i = 0, i < iteration, i++)
|
||||
if(!(potential_targets.len))
|
||||
break
|
||||
var/mob/target = pick(potential_targets)
|
||||
potential_targets -= target
|
||||
spawn_lightpillar(target)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/proc/spawn_lightpillar(atom/target)
|
||||
var/list/bomb_range = block(locate(target.x-4, target.y-4, target.z), locate(target.x+4, target.y+4, target.z))
|
||||
new /obj/effect/calldown_attack(get_turf(target))
|
||||
bomb_range -= get_turf(target)
|
||||
for(var/i = 0, i < 4, i++)
|
||||
var/turf/T = pick(bomb_range)
|
||||
new /mob/living/simple_mob/humanoid/starhunter/hunter/prop(T)
|
||||
bomb_range -= T
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/prop //This ain't a mob to spawn, but something apart of other mobs attacks and self deletes
|
||||
health = 1000
|
||||
maxHealth = 1000
|
||||
projectile_dispersion = 0
|
||||
projectile_accuracy = 100
|
||||
armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100)
|
||||
projectiletype = /obj/item/projectile/energy/lightpillar
|
||||
ranged_attack_delay = 1.5 SECONDS
|
||||
icon_state = "prism"
|
||||
icon_living = "prism"
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/prop/ranged_pre_animation(atom/A)
|
||||
Beam(get_turf(A), icon_state = "sniper_beam", time = 2 SECONDS, maxdistance = 10)
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/prop/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
|
||||
|
||||
/*
|
||||
* CHOMP Addition: This section here is (duplicated) special snowflake code because sniper does not call parent. Basically, this is a non-stupid version of the above intended for ranged mobs.
|
||||
* ranged_attack_delay is stupid because it sleeps the entire mob.
|
||||
* This new ranged_cooldown_time is smarter in the sense that it is an internalized timer. Try not to confuse the names.
|
||||
*/
|
||||
if(ranged_cooldown_time) //If you have a non-zero number in a mob's variables, this pattern begins.
|
||||
if(ranged_cooldown <= world.time) //Further down, a timer keeps adding to the ranged_cooldown variable automatically.
|
||||
visible_message(span_danger(span_bold("\The [src]") + " fires at \the [A]!")) //Leave notice of shooting.
|
||||
shoot(A) //Perform the shoot action
|
||||
if(casingtype) //If the mob is designated to leave casings...
|
||||
new casingtype(loc) //... leave the casing.
|
||||
ranged_cooldown = world.time + ranged_cooldown_time + ((injury_level / 2) SECONDS) //Special addition here. This is a timer. Keeping updating the time after shooting. Add that ranged cooldown time specified in the mob to the world time.
|
||||
qdel(src)
|
||||
return TRUE //End these commands here.
|
||||
// CHOMPAddition End
|
||||
|
||||
visible_message(span_danger(span_bold("\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/starhunter/hunter/proc/fire_lines(atom/A)
|
||||
var/list/potential_targets = ai_holder.list_targets()
|
||||
for(var/atom/entry in potential_targets)
|
||||
if(istype(entry, /mob/living/simple_mob/humanoid/starhunter/hunter))
|
||||
potential_targets -= entry
|
||||
if(potential_targets.len)
|
||||
var/iteration = clamp(potential_targets.len, 1, 3)
|
||||
for(var/i = 0, i < iteration, i++)
|
||||
if(!(potential_targets.len))
|
||||
break
|
||||
var/mob/target = pick(potential_targets)
|
||||
potential_targets -= target
|
||||
spawn_fire(target)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/proc/spawn_fire(atom/target)
|
||||
var/alignment = rand(1,2) // 1 for vertical, 2 for horizontal
|
||||
var/list/line_range = list()
|
||||
var/turf/T = get_turf(target)
|
||||
line_range += T
|
||||
for(var/i = 1, i <= 7, i++)
|
||||
switch(alignment)
|
||||
if(1)
|
||||
if(T.x-i > 0)
|
||||
line_range += locate(T.x-i, T.y, T.z)
|
||||
if(T.x+i <= world.maxx)
|
||||
line_range += locate(T.x+i, T.y, T.z)
|
||||
if(2)
|
||||
if(T.y-i > 0)
|
||||
line_range += locate(T.x, T.y-i, T.z)
|
||||
if(T.y+i <= world.maxy)
|
||||
line_range += locate(T.x, T.y+i, T.z)
|
||||
for(var/turf/dropspot in line_range)
|
||||
new /obj/effect/calldown_attack_fire(dropspot)
|
||||
|
||||
|
||||
/obj/effect/calldown_attack_fire
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
unacidable = TRUE
|
||||
mouse_opacity = 0
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "drop_marker"
|
||||
|
||||
/obj/effect/calldown_attack_fire/Initialize(mapload)
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/effect/calldown_attack_fire/LateInitialize()
|
||||
var/delay = rand(25, 30)
|
||||
spawn(delay-7)
|
||||
new /obj/fire(src.loc)
|
||||
spawn(delay)
|
||||
qdel(src)
|
||||
|
||||
|
||||
//Kitsune Stuff
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/champion
|
||||
name = "Starhunter Starweilder"
|
||||
health = 200 //10 hits from 20 damage
|
||||
maxHealth = 200
|
||||
damage_fatigue_mult = 0
|
||||
projectiletype = /obj/item/projectile/energy/ninjastar
|
||||
icon_state = "suneswift"
|
||||
icon_living = "suneswift"
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/champion/do_special_attack(atom/A)
|
||||
if(prob(50))
|
||||
bullethell(A)
|
||||
else
|
||||
rapidfire_windup(A)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/proc/bullethell(atom/A)
|
||||
set waitfor = FALSE
|
||||
|
||||
var/sd = dir2angle(dir)
|
||||
var/list/offsets = list(45, 45, 20, 10)
|
||||
|
||||
for(var/i = 0, i<4, i++)
|
||||
for(var/j = 0, j <4, j++)
|
||||
var/obj/item/projectile/energy/slow_orb/shot = new(get_turf(src))
|
||||
shot.firer = src
|
||||
shot.fire(sd)
|
||||
sd += 90
|
||||
sd += pick(offsets)
|
||||
sleep(20)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/proc/rapidfire_windup(atom/A)
|
||||
var/list/potential_targets = ai_holder.list_targets()
|
||||
for(var/atom/entry in potential_targets)
|
||||
if(istype(entry, /mob/living/simple_mob/humanoid/starhunter/hunter))
|
||||
potential_targets -= entry
|
||||
if(potential_targets.len)
|
||||
var/iteration = clamp(potential_targets.len, 1, 3)
|
||||
for(var/i = 0, i < iteration, i++)
|
||||
if(!(potential_targets.len))
|
||||
break
|
||||
var/mob/target = pick(potential_targets)
|
||||
potential_targets -= target
|
||||
rapidfire(target)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/hunter/proc/rapidfire(atom/target)
|
||||
var/list/bomb_range = block(locate(target.x-4, target.y-4, target.z), locate(target.x+4, target.y+4, target.z))
|
||||
var/obj/item/projectile/P = new /obj/item/projectile/energy/ninjastar(get_turf(src))
|
||||
bomb_range -= get_turf(target)
|
||||
for(var/i = 0, i < 4, i++)
|
||||
var/turf/T = pick(bomb_range)
|
||||
P.launch_projectile(target, BP_TORSO, src)
|
||||
bomb_range -= T
|
||||
|
||||
|
||||
/obj/item/projectile/energy/lightpillar
|
||||
name = "Light Pillar"
|
||||
icon = 'modular_chomp/icons/mob/starhunters.dmi' //commiting sin
|
||||
icon_state = "lightpillar"
|
||||
damage = 30 //DIVINE JUDGMENT
|
||||
armor_penetration = 50 //DIVINE JUDGMENT
|
||||
light_range = 5
|
||||
light_power = 5
|
||||
damage_type = BURN
|
||||
check_armour = "laser"
|
||||
light_color = "#FF6600"
|
||||
range = 7
|
||||
speed = 13
|
||||
|
||||
/obj/item/projectile/energy/ninjastar
|
||||
name = "Energy Star"
|
||||
icon = 'modular_chomp/icons/mob/starhunters.dmi' //commiting sin
|
||||
icon_state = "ninjastar"
|
||||
damage = 15
|
||||
armor_penetration = 25 //Gets into the gaps
|
||||
damage_type = BURN
|
||||
check_armour = "laser"
|
||||
-128
@@ -1,128 +0,0 @@
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/weaponsmith
|
||||
name = "Starhunter Weapon Smith"
|
||||
icon_state = "sunetrader"
|
||||
icon_living = "sunetrader"
|
||||
products = list(/obj/item/gun/energy/sickshot = 5,
|
||||
/obj/item/material/twohanded/fireaxe/scythe = 3,
|
||||
/obj/item/material/twohanded/spear/lance = 3,
|
||||
/obj/item/beartrap = 12,
|
||||
/obj/item/material/barbedwire = 12,
|
||||
/obj/item/material/sword/battleaxe = 3
|
||||
|
||||
) // For each, use the following pattern:
|
||||
|
||||
premium = list(/obj/item/gun/energy/maghowitzer) //This may be a mistake
|
||||
|
||||
prices = list(/obj/item/gun/energy/maghowitzer = 8000,
|
||||
/obj/item/gun/energy/sickshot = 800,
|
||||
/obj/item/material/twohanded/fireaxe/scythe = 400,
|
||||
/obj/item/material/twohanded/spear/lance = 400,
|
||||
/obj/item/beartrap = 80,
|
||||
/obj/item/material/barbedwire = 80,
|
||||
/obj/item/material/sword/battleaxe = 400
|
||||
)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/reliccollecter
|
||||
name = "Starhunter Relic Collector"
|
||||
icon_state = "snektrader"
|
||||
icon_living = "snektrader"
|
||||
products = list(/obj/item/clothing/head/helmet/combat/crusader = 3,
|
||||
/obj/item/clothing/suit/armor/combat/crusader = 3,
|
||||
/obj/item/clothing/head/culthood = 3,
|
||||
/obj/item/clothing/suit/cultrobes = 3,
|
||||
/obj/item/clothing/head/helmet/space/cult = 3,
|
||||
/obj/item/clothing/suit/space/cult = 3,
|
||||
/obj/item/soulstone = 8,
|
||||
/obj/item/clothing/glasses/monocoole = 3,
|
||||
/obj/item/storage/belt/holding = 1,
|
||||
/obj/item/clothing/gloves/regen = 1
|
||||
) // For each, use the following pattern:
|
||||
|
||||
premium = list(/obj/item/clothing/glasses/omni) //I am unsure why but this feels right
|
||||
|
||||
prices = list(/obj/item/clothing/head/helmet/combat/crusader = 600,
|
||||
/obj/item/clothing/suit/armor/combat/crusader = 600,
|
||||
/obj/item/clothing/head/culthood = 600,
|
||||
/obj/item/clothing/suit/cultrobes = 600,
|
||||
/obj/item/clothing/head/helmet/space/cult = 600,
|
||||
/obj/item/clothing/suit/space/cult = 600,
|
||||
/obj/item/soulstone = 80,
|
||||
/obj/item/clothing/glasses/monocoole = 1200,
|
||||
/obj/item/storage/belt/holding = 1800,
|
||||
/obj/item/clothing/gloves/regen = 1800,
|
||||
/obj/item/clothing/glasses/omni = 2600
|
||||
)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/miner
|
||||
name = "Starhunter Miner"
|
||||
icon_state = "snektrader"
|
||||
icon_living = "snektrader"
|
||||
products = list(/obj/item/kinetic_crusher/glaive = 5,
|
||||
/obj/item/kinetic_crusher = 3,
|
||||
/obj/item/gun/energy/mininglaser = 3,
|
||||
/obj/item/melee/shock_maul = 3,
|
||||
/obj/item/stack/material/phoron = 50,
|
||||
/obj/item/stack/material/uranium = 50,
|
||||
/obj/item/stack/material/tritium = 50,
|
||||
/obj/item/stack/material/deuterium = 50,
|
||||
/obj/item/stack/material/bronze = 50,
|
||||
/obj/item/circuitboard/paradoxrift = 3
|
||||
) // For each, use the following pattern:
|
||||
|
||||
premium = list(/obj/item/circuitboard/defenseonelisk) // No specified amount = only one in stock
|
||||
|
||||
prices = list(/obj/item/kinetic_crusher/glaive = 600,
|
||||
/obj/item/kinetic_crusher = 600,
|
||||
/obj/item/gun/energy/mininglaser = 800,
|
||||
/obj/item/melee/shock_maul = 600,
|
||||
/obj/item/stack/material/phoron = 12,
|
||||
/obj/item/stack/material/uranium = 12,
|
||||
/obj/item/stack/material/tritium = 12,
|
||||
/obj/item/stack/material/deuterium = 12,
|
||||
/obj/item/stack/material/bronze = 12,
|
||||
/obj/item/circuitboard/paradoxrift = 2400,
|
||||
/obj/item/circuitboard/defenseonelisk = 5000
|
||||
)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/farmer
|
||||
name = "Starhunter Farmer"
|
||||
icon_state = "sunetrader"
|
||||
icon_living = "sunetrader"
|
||||
products = list(/obj/item/slime_extract/sepia =3,
|
||||
/obj/item/slime_extract/ruby = 3,
|
||||
/obj/item/slime_extract/bluespace = 3,
|
||||
/obj/item/slime_extract/oil = 3,
|
||||
/obj/item/slime_extract/sapphire = 3,
|
||||
/obj/item/slime_extract/emerald = 3,
|
||||
/obj/item/seeds/shrinkshroom = 12,
|
||||
/obj/item/seeds/megashroom = 12,
|
||||
/obj/item/seeds/pitcherseed = 6,
|
||||
/obj/item/seeds/deathberryseed = 6,
|
||||
/obj/item/seeds/ambrosiainfernusseed = 6,
|
||||
/obj/item/seeds/thaadra = 6,
|
||||
/obj/item/seeds/icepepperseed = 6,
|
||||
/obj/item/seeds/jurlmah = 6,
|
||||
/obj/item/seeds/amauri = 6,
|
||||
/obj/item/seeds/gelthi = 6,
|
||||
/obj/item/seeds/vale = 6
|
||||
) // For each, use the following pattern:
|
||||
|
||||
premium = list() // No specified amount = only one in stock
|
||||
|
||||
prices = list(/obj/item/slime_extract/sepia = 2500,
|
||||
/obj/item/slime_extract/ruby = 2250,
|
||||
/obj/item/slime_extract/bluespace = 2250,
|
||||
/obj/item/slime_extract/oil = 2250,
|
||||
/obj/item/slime_extract/sapphire = 2250,
|
||||
/obj/item/slime_extract/emerald = 2250,
|
||||
/obj/item/seeds/shrinkshroom = 50,
|
||||
/obj/item/seeds/megashroom = 50,
|
||||
/obj/item/seeds/pitcherseed = 125,
|
||||
/obj/item/seeds/deathberryseed = 125,
|
||||
/obj/item/seeds/ambrosiainfernusseed = 125,
|
||||
/obj/item/seeds/thaadra = 125,
|
||||
/obj/item/seeds/icepepperseed = 125,
|
||||
/obj/item/seeds/jurlmah = 125,
|
||||
/obj/item/seeds/amauri = 125,
|
||||
/obj/item/seeds/gelthi = 125,
|
||||
/obj/item/seeds/vale = 125)
|
||||
-392
@@ -1,392 +0,0 @@
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader
|
||||
var/vend_ready = 1 //Are we ready to vend?? Is it time??
|
||||
var/vend_delay = 10 //How long does it take to vend?
|
||||
var/categories = CAT_NORMAL // Bitmask of cats we're currently showing
|
||||
var/datum/stored_item/vending_product/currently_vending = null // What we're requesting payment for right now
|
||||
var/vending_sound = "machines/vending/vending_drop.ogg"
|
||||
|
||||
/*
|
||||
Variables used to initialize the product list
|
||||
These are used for initialization only, and so are optional if
|
||||
product_records is specified
|
||||
*/
|
||||
var/list/products = list() // For each, use the following pattern:
|
||||
var/list/contraband = list() // list(/type/path = amount,/type/path2 = amount2)
|
||||
var/list/premium = list() // No specified amount = only one in stock
|
||||
/// Set automatically, allows coin use
|
||||
var/has_premium = FALSE
|
||||
var/list/prices = list() // Prices for each item, list(/type/path = price), items not in the list don't have a price.
|
||||
/// Set automatically, enables pricing
|
||||
var/has_prices = FALSE
|
||||
// This one is used for refill cartridge use.
|
||||
var/list/refill = list() // For each, use the following pattern:
|
||||
// Enables refilling with appropriate cartridges
|
||||
var/refillable = TRUE
|
||||
var/obj/item/coin/coin
|
||||
var/list/log = list()
|
||||
var/has_logs = 0
|
||||
var/list/product_records = list()
|
||||
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/Initialize(mapload)
|
||||
. = ..()
|
||||
build_inventory()
|
||||
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/proc/build_inventory()
|
||||
var/list/all_products = list(
|
||||
list(products, CAT_NORMAL),
|
||||
list(contraband, CAT_HIDDEN),
|
||||
list(premium, CAT_COIN))
|
||||
|
||||
for(var/current_list in all_products)
|
||||
var/category = current_list[2]
|
||||
|
||||
for(var/entry in current_list[1])
|
||||
var/datum/stored_item/vending_product/product = new/datum/stored_item/vending_product(src, entry)
|
||||
|
||||
product.price = (entry in prices) ? prices[entry] : 0
|
||||
product.amount = (current_list[1][entry]) ? current_list[1][entry] : 1
|
||||
product.category = category
|
||||
|
||||
GLOB.vending_products[entry] = 1
|
||||
|
||||
if(LAZYLEN(prices))
|
||||
has_prices = TRUE
|
||||
if(LAZYLEN(premium))
|
||||
has_premium = TRUE
|
||||
|
||||
|
||||
LAZYCLEARLIST(products)
|
||||
LAZYCLEARLIST(contraband)
|
||||
LAZYCLEARLIST(premium)
|
||||
LAZYCLEARLIST(prices)
|
||||
all_products.Cut()
|
||||
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/attackby(obj/item/W as obj, mob/user as mob)
|
||||
var/obj/item/card/id/I = W.GetID()
|
||||
|
||||
if(I || istype(W, /obj/item/spacecash))
|
||||
attack_hand(user)
|
||||
return
|
||||
else if(istype(W, /obj/item/coin) && has_premium)
|
||||
user.drop_item()
|
||||
W.forceMove(src)
|
||||
coin = W
|
||||
categories |= CAT_COIN
|
||||
to_chat(user, span_notice("You insert \the [W] into \the [src]."))
|
||||
SStgui.update_uis(src)
|
||||
return
|
||||
else
|
||||
|
||||
for(var/datum/stored_item/vending_product/R in product_records)
|
||||
if(istype(W, R.item_path) && (W.name == R.item_name))
|
||||
stock(W, R, user)
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/proc/pay_with_cash(var/obj/item/spacecash/cashmoney, mob/user)
|
||||
if(currently_vending.price > cashmoney.worth)
|
||||
|
||||
// This is not a status display message, since it's something the character
|
||||
// themselves is meant to see BEFORE putting the money in
|
||||
to_chat(usr, "[icon2html(cashmoney,user.client)] " + span_warning("That is not enough money."))
|
||||
return 0
|
||||
|
||||
if(istype(cashmoney, /obj/item/spacecash))
|
||||
|
||||
visible_message(span_info("\The [usr] inserts some cash into \the [src]."))
|
||||
cashmoney.worth -= currently_vending.price
|
||||
|
||||
if(cashmoney.worth <= 0)
|
||||
usr.drop_from_inventory(cashmoney)
|
||||
qdel(cashmoney)
|
||||
else
|
||||
cashmoney.update_icon()
|
||||
|
||||
// Vending machines have no idea who paid with cash
|
||||
credit_purchase("(cash)")
|
||||
return 1
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/proc/credit_purchase(var/target as text)
|
||||
GLOB.vendor_account.money += currently_vending.price
|
||||
|
||||
var/datum/transaction/T = new()
|
||||
T.target_name = target
|
||||
T.purpose = "Purchase of [currently_vending.item_name]"
|
||||
T.amount = "[currently_vending.price]"
|
||||
T.source_terminal = name
|
||||
T.date = GLOB.current_date_string
|
||||
T.time = stationtime2text()
|
||||
GLOB.vendor_account.transaction_log.Add(T)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Vending", name)
|
||||
ui.open()
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
var/list/listed_products = list()
|
||||
|
||||
data["chargesMoney"] = has_prices ? TRUE : FALSE
|
||||
|
||||
data["products"] = listed_products
|
||||
|
||||
if(coin)
|
||||
data["coin"] = coin.name
|
||||
else
|
||||
data["coin"] = FALSE
|
||||
|
||||
if(currently_vending)
|
||||
data["actively_vending"] = currently_vending.item_name
|
||||
else
|
||||
data["actively_vending"] = null
|
||||
|
||||
var/mob/living/carbon/human/H
|
||||
var/obj/item/card/id/C
|
||||
|
||||
data["guestNotice"] = "Please present cash.";
|
||||
data["userMoney"] = 0
|
||||
data["user"] = null
|
||||
if(ishuman(user))
|
||||
H = user
|
||||
C = H.GetIdCard()
|
||||
var/obj/item/spacecash/S = H.get_active_hand()
|
||||
if(istype(S))
|
||||
data["userMoney"] = S.worth
|
||||
data["guestNotice"] = "Accepting [S.initial_name]. You have: [S.worth]₮."
|
||||
else if(istype(C))
|
||||
var/datum/money_account/A = get_account(C.associated_account_number)
|
||||
if(istype(A))
|
||||
data["user"] = list()
|
||||
data["user"]["name"] = A.owner_name
|
||||
data["userMoney"] = A.money
|
||||
data["user"]["job"] = (istype(C) && C.rank) ? C.rank : "No Job"
|
||||
else
|
||||
data["guestNotice"] = "Unlinked ID detected. Present cash to pay.";
|
||||
|
||||
return data
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/tgui_act(action, params)
|
||||
if(usr.stat || usr.restrained())
|
||||
return
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
. = TRUE
|
||||
switch(action)
|
||||
if("remove_coin")
|
||||
if(issilicon(usr))
|
||||
return FALSE
|
||||
|
||||
if(!coin)
|
||||
to_chat(usr, span_filter_notice("There is no coin in this machine."))
|
||||
return
|
||||
|
||||
coin.forceMove(src.loc)
|
||||
if(!usr.get_active_hand())
|
||||
usr.put_in_hands(coin)
|
||||
|
||||
to_chat(usr, span_notice("You remove \the [coin] from \the [src]."))
|
||||
coin = null
|
||||
categories &= ~CAT_COIN
|
||||
return TRUE
|
||||
if("vend")
|
||||
if(!vend_ready)
|
||||
to_chat(usr, span_warning("[src] is busy!"))
|
||||
return
|
||||
|
||||
var/key = text2num(params["vend"])
|
||||
var/datum/stored_item/vending_product/R = product_records[key]
|
||||
|
||||
// This should not happen unless the request from NanoUI was bad
|
||||
if(!(R.category & categories))
|
||||
return
|
||||
|
||||
if(!can_buy(R, usr))
|
||||
return
|
||||
|
||||
if(R.price <= 0)
|
||||
vend(R, usr)
|
||||
add_fingerprint(usr)
|
||||
return TRUE
|
||||
|
||||
if(issilicon(usr)) //If the item is not free, provide feedback if a synth is trying to buy something.
|
||||
to_chat(usr, span_danger("Lawed unit recognized. Lawed units cannot complete this transaction. Purchase canceled."))
|
||||
return
|
||||
if(!ishuman(usr))
|
||||
return
|
||||
|
||||
vend_ready = FALSE // From this point onwards, vendor is locked to performing this transaction only, until it is resolved.
|
||||
|
||||
var/mob/living/carbon/human/H = usr
|
||||
var/obj/item/card/id/C = H.GetIdCard()
|
||||
|
||||
if(!GLOB.vendor_account || GLOB.vendor_account.suspended)
|
||||
to_chat(usr, span_filter_notice("Vendor account offline. Unable to process transaction."))
|
||||
flick("[icon_state]-deny",src)
|
||||
vend_ready = TRUE
|
||||
return
|
||||
|
||||
currently_vending = R
|
||||
|
||||
var/paid = FALSE
|
||||
|
||||
if(istype(usr.get_active_hand(), /obj/item/spacecash))
|
||||
var/obj/item/spacecash/cash = usr.get_active_hand()
|
||||
paid = pay_with_cash(cash, usr)
|
||||
else if(istype(usr.get_active_hand(), /obj/item/spacecash/ewallet))
|
||||
var/obj/item/spacecash/ewallet/wallet = usr.get_active_hand()
|
||||
paid = pay_with_ewallet(wallet)
|
||||
else if(istype(C, /obj/item/card))
|
||||
paid = pay_with_card(C, usr)
|
||||
/*else if(usr.can_advanced_admin_interact())
|
||||
to_chat(usr, span_notice("Vending object due to admin interaction."))
|
||||
paid = TRUE*/
|
||||
else
|
||||
to_chat(usr, span_warning("Payment failure: you have no ID or other method of payment."))
|
||||
vend_ready = TRUE
|
||||
flick("[icon_state]-deny",src)
|
||||
return TRUE // we set this because they shouldn't even be able to get this far, and we want the UI to update.
|
||||
if(paid)
|
||||
vend(currently_vending, usr) // vend will handle vend_ready
|
||||
. = TRUE
|
||||
else
|
||||
to_chat(usr, span_warning("Payment failure: unable to process payment."))
|
||||
vend_ready = TRUE
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/proc/vend(datum/stored_item/vending_product/R, mob/user)
|
||||
if(!can_buy(R, user))
|
||||
return
|
||||
|
||||
if(!R.amount)
|
||||
to_chat(user, span_warning("[src] has ran out of that product."))
|
||||
vend_ready = TRUE
|
||||
return
|
||||
|
||||
vend_ready = FALSE //One thing at a time!!
|
||||
SStgui.update_uis(src)
|
||||
|
||||
if(R.category & CAT_COIN)
|
||||
if(!coin)
|
||||
to_chat(user, span_notice("You need to insert a coin to get this item."))
|
||||
return
|
||||
else
|
||||
qdel(coin)
|
||||
coin = null
|
||||
categories &= ~CAT_COIN
|
||||
|
||||
flick("[icon_state]-vend",src)
|
||||
addtimer(CALLBACK(src, PROC_REF(delayed_vend), R, user), vend_delay)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/proc/delayed_vend(datum/stored_item/vending_product/R, mob/user)
|
||||
R.get_product(get_turf(src))
|
||||
|
||||
playsound(src, "sound/[vending_sound]", 100, 1, 1)
|
||||
|
||||
GLOB.items_sold_shift_roundstat++
|
||||
|
||||
vend_ready = 1
|
||||
currently_vending = null
|
||||
SStgui.update_uis(src)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/proc/stock(obj/item/W, var/datum/stored_item/vending_product/R, var/mob/user)
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
|
||||
to_chat(user, span_notice("You insert \the [W] in the product receptor."))
|
||||
R.add_product(W)
|
||||
if(has_logs)
|
||||
do_logging(R, user)
|
||||
|
||||
SStgui.update_uis(src)
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/proc/pay_with_ewallet(var/obj/item/spacecash/ewallet/wallet)
|
||||
visible_message(span_info("\The [usr] swipes \the [wallet] through \the [src]."))
|
||||
playsound(src, 'sound/machines/id_swipe.ogg', 50, 1)
|
||||
if(currently_vending.price > wallet.worth)
|
||||
to_chat(usr, span_warning("Insufficient funds on chargecard."))
|
||||
return 0
|
||||
else
|
||||
wallet.worth -= currently_vending.price
|
||||
credit_purchase("[wallet.owner_name] (chargecard)")
|
||||
return 1
|
||||
|
||||
/**
|
||||
* Scan a card and attempt to transfer payment from associated account.
|
||||
*
|
||||
* Takes payment for whatever is the currently_vending item. Returns 1 if
|
||||
* successful, 0 if failed
|
||||
*/
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/proc/pay_with_card(obj/item/card/id/I, mob/M)
|
||||
visible_message(span_info("[M] swipes a card through [src]."))
|
||||
playsound(src, 'sound/machines/id_swipe.ogg', 50, 1)
|
||||
|
||||
var/datum/money_account/customer_account = get_account(I.associated_account_number)
|
||||
if(!customer_account)
|
||||
to_chat(M, span_warning("Error: Unable to access account. Please contact technical support if problem persists."))
|
||||
return FALSE
|
||||
|
||||
if(customer_account.suspended)
|
||||
to_chat(M, span_warning("Unable to access account: account suspended."))
|
||||
return FALSE
|
||||
|
||||
// Have the customer punch in the PIN before checking if there's enough money. Prevents people from figuring out acct is
|
||||
// empty at high security levels
|
||||
if(customer_account.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2)
|
||||
var/attempt_pin = tgui_input_number(usr, "Enter pin code", "Vendor transaction")
|
||||
customer_account = attempt_account_access(I.associated_account_number, attempt_pin, 2)
|
||||
|
||||
if(!customer_account)
|
||||
to_chat(M, span_warning("Unable to access account: incorrect credentials."))
|
||||
return FALSE
|
||||
|
||||
if(currently_vending.price > customer_account.money)
|
||||
to_chat(M, span_warning("Insufficient funds in account."))
|
||||
return FALSE
|
||||
|
||||
// Okay to move the money at this point
|
||||
|
||||
// debit money from the purchaser's account
|
||||
customer_account.money -= currently_vending.price
|
||||
|
||||
// create entry in the purchaser's account log
|
||||
var/datum/transaction/T = new()
|
||||
T.target_name = "[GLOB.vendor_account.owner_name] (via [name])"
|
||||
T.purpose = "Purchase of [currently_vending.item_name]"
|
||||
if(currently_vending.price > 0)
|
||||
T.amount = "([currently_vending.price])"
|
||||
else
|
||||
T.amount = "[currently_vending.price]"
|
||||
T.source_terminal = name
|
||||
T.date = GLOB.current_date_string
|
||||
T.time = stationtime2text()
|
||||
customer_account.transaction_log.Add(T)
|
||||
|
||||
// Give the vendor the money. We use the account owner name, which means
|
||||
// that purchases made with stolen/borrowed card will look like the card
|
||||
// owner made them
|
||||
credit_purchase(customer_account.owner_name)
|
||||
return 1
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/proc/do_logging(datum/stored_item/vending_product/R, mob/user, var/vending = 0)
|
||||
if(user.GetIdCard())
|
||||
var/obj/item/card/id/tempid = user.GetIdCard()
|
||||
var/list/list_item = list()
|
||||
if(vending)
|
||||
list_item += "vend"
|
||||
else
|
||||
list_item += "stock"
|
||||
list_item += tempid.registered_name
|
||||
list_item += stationtime2text()
|
||||
list_item += R.item_name
|
||||
log[++log.len] = list_item
|
||||
|
||||
/mob/living/simple_mob/humanoid/starhunter/trader/proc/can_buy(datum/stored_item/vending_product/R, mob/user)
|
||||
return TRUE
|
||||
@@ -27,37 +27,52 @@
|
||||
list(mode_name="shotgun", fire_delay=15, projectile_type=/obj/item/projectile/bullet/frostshotgun, charge_cost = 240),
|
||||
)
|
||||
|
||||
/obj/item/gun/energy/flamegun
|
||||
name = "Flame Crystal Projector"
|
||||
desc = "A strange gun pulsing with energy, it's touch warming you up."
|
||||
icon = 'modular_chomp/icons/obj/guns/precursor/eclipse.dmi'
|
||||
icon_state = "flamegun"
|
||||
item_state = "flamegun"
|
||||
wielded_item_state = "flame-wielded"
|
||||
/obj/item/grenade/chem_grenade/frost
|
||||
name = "frost grenade"
|
||||
desc = "Currently in the testing phase, pratical purposes are unknown."
|
||||
icon_state = "foam"
|
||||
path = 1
|
||||
stage = 2
|
||||
sealed = TRUE
|
||||
|
||||
w_class = ITEMSIZE_LARGE
|
||||
/obj/item/grenade/chem_grenade/frost/Initialize(mapload)
|
||||
. = ..()
|
||||
var/obj/item/reagent_containers/glass/beaker/bluespace/B1 = new(src)
|
||||
var/obj/item/reagent_containers/glass/beaker/bluespace/B2 = new(src)
|
||||
|
||||
accept_cell_type = /obj/item/cell/device
|
||||
cell_type = /obj/item/cell/device/weapon
|
||||
projectile_type = /obj/item/projectile/energy/flamecrystal
|
||||
B1.reagents.add_reagent(REAGENT_ID_CRYOSLURRY, 150)
|
||||
B1.reagents.add_reagent(REAGENT_ID_POTASSIUM, 150)
|
||||
B2.reagents.add_reagent(REAGENT_ID_PHOSPHORUS, 150)
|
||||
B2.reagents.add_reagent(REAGENT_ID_SUGAR, 150)
|
||||
|
||||
matter = list(MAT_DURASTEEL = 1000, MAT_MORPHIUM = 500)
|
||||
origin_tech = list(TECH_COMBAT = 6, TECH_POWER = 5, TECH_PRECURSOR = 3)
|
||||
detonator = new/obj/item/assembly_holder/timer_igniter(src)
|
||||
|
||||
recoil_mode = 0
|
||||
charge_meter = 1
|
||||
beakers += B1
|
||||
|
||||
move_delay = 0
|
||||
/obj/item/projectile/bullet/frostshotgun
|
||||
use_submunitions = 1
|
||||
only_submunitions = 1
|
||||
range = 0
|
||||
embed_chance = 0
|
||||
submunition_spread_max = 1200
|
||||
submunition_spread_min = 500
|
||||
submunitions = list(/obj/item/projectile/energy/frostsphere = 4)
|
||||
|
||||
charge_cost = 80
|
||||
hud_state = "plasma_sphere"
|
||||
|
||||
reload_time = 10
|
||||
/obj/item/projectile/bullet/frostshotgun/on_range()
|
||||
qdel(src)
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="normal", fire_delay=5, projectile_type=/obj/item/projectile/energy/flamecrystal, charge_cost = 80),
|
||||
list(mode_name="shotgun", fire_delay=15, projectile_type=/obj/item/projectile/bullet/flamegun, charge_cost = 240),
|
||||
list(mode_name="explosive", fire_delay=10, projectile_type=/obj/item/projectile/energy/fireball, charge_cost = 160),
|
||||
)
|
||||
/obj/item/projectile/energy/frostsphere
|
||||
name = "frost sphere"
|
||||
icon_state = "ice_2"
|
||||
fire_sound = 'sound/weapons/pulse3.ogg'
|
||||
damage = 20
|
||||
modifier_type_to_apply = /datum/modifier/cryogelled
|
||||
modifier_duration = 0.25 MINUTE
|
||||
speed = 2.5
|
||||
range = 12
|
||||
hud_state = "water"
|
||||
|
||||
/obj/item/projectile/energy/mechahack
|
||||
name = "remote hack"
|
||||
@@ -95,72 +110,68 @@
|
||||
else
|
||||
target_mob.electrocute_act(power, src, 0.75, BP_TORSO)
|
||||
|
||||
/obj/item/projectile/bullet/crystaline
|
||||
name = "crystal bullet"
|
||||
icon = 'modular_chomp/icons/obj/guns/precursor/eclipse.dmi'
|
||||
icon_state = "crystal"
|
||||
damage = 30
|
||||
armor_penetration = 20
|
||||
embed_chance = 0
|
||||
speed = 2
|
||||
|
||||
/obj/item/projectile/energy/eclipse
|
||||
/obj/item/projectile/energy/eclipse_boss
|
||||
name = "experimental laser"
|
||||
icon = 'modular_chomp/icons/obj/guns/precursor/eclipse.dmi'
|
||||
icon_state = "laser"
|
||||
check_armour = "laser"
|
||||
damage = 30
|
||||
armor_penetration = 20
|
||||
penetrating = 2
|
||||
speed = 2
|
||||
speed = 10
|
||||
crawl_destroy = TRUE
|
||||
|
||||
//The normal laser respects more armor, but deals more damage if you don't have it.precursor will thwack folks equally.
|
||||
/obj/item/projectile/energy/eclipse/lorge
|
||||
damage = 60
|
||||
armor_penetration = 30
|
||||
icon_state = "mega_laser"
|
||||
speed = 10
|
||||
|
||||
/obj/item/projectile/energy/eclipse/lorgealien
|
||||
damage = 20
|
||||
armor_penetration = 60
|
||||
icon_state = "mega_laser_p"
|
||||
speed = 10
|
||||
|
||||
/obj/item/projectile/bullet/crystalineburst
|
||||
use_submunitions = 1
|
||||
range = 0
|
||||
embed_chance = 0
|
||||
spread_submunition_damage = FALSE
|
||||
submunition_spread_max = 120
|
||||
submunition_spread_min = 60
|
||||
submunitions = list(/obj/item/projectile/bullet/crystaline = 5)
|
||||
|
||||
/obj/item/projectile/energy/eclipse/janusjavelin //This will end you
|
||||
name = "energy javelin"
|
||||
icon_state = "javelin"
|
||||
damage_type = SEARING
|
||||
check_armour = "bullet"
|
||||
damage = 45
|
||||
armor_penetration = 95
|
||||
speed = 10
|
||||
|
||||
/obj/item/projectile/energy/eclipse/chillingwind
|
||||
/obj/item/projectile/energy/eclipse_boss/chillingwind
|
||||
name = "ice winds"
|
||||
icon_state = "ice_wind"
|
||||
damage = 15
|
||||
armor_penetration = 70
|
||||
speed = 10
|
||||
modifier_type_to_apply = /datum/modifier/cryogelled
|
||||
modifier_duration = 0.25 MINUTE
|
||||
|
||||
/obj/item/projectile/energy/eclipse/mining
|
||||
name = "drill"
|
||||
icon_state = "drill"
|
||||
/obj/item/projectile/energy/eclipse_boss/metalsphere
|
||||
name = "metal sphere"
|
||||
icon_state = "metal_sphere"
|
||||
damage_type = BRUTE
|
||||
check_armour = "bullet"
|
||||
damage = 20
|
||||
agony = 10
|
||||
armor_penetration = 50
|
||||
|
||||
/obj/item/projectile/energy/eclipse_boss/energyjavelin
|
||||
name = "searing javelin"
|
||||
icon_state = "javelin"
|
||||
damage_type = SEARING
|
||||
damage = 40
|
||||
armor_penetration = 30
|
||||
speed = 10
|
||||
excavation_amount = 100
|
||||
|
||||
//projectiles
|
||||
/obj/item/projectile/energy/astral_collective
|
||||
name = "abnormal energy"
|
||||
speed = 2
|
||||
damage = 28 //roughly 25 with intended armour
|
||||
damage_type = BURN //BRUTE, BURN, TOX, OXY, CLONE, HALLOSS, ELECTROCUTE, BIOACID, SEARING are the only things that should be in here
|
||||
check_armour = "laser" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb //Cael - bio and rad are also valid
|
||||
|
||||
/obj/item/projectile/energy/astral_collective/anti_mecha
|
||||
damage_type = BIOACID
|
||||
icon_state = "declone"
|
||||
|
||||
/obj/item/projectile/energy/astral_collective/armour_breaker
|
||||
damage = 10
|
||||
dephasing = TRUE
|
||||
hits_phased = TRUE
|
||||
icon_state = "fuel-deuterium"
|
||||
penetrating = 10
|
||||
armor_penetration = 100
|
||||
|
||||
/obj/item/projectile/energy/astral_collective/searing
|
||||
damage_type = SEARING
|
||||
icon_state = "bolter"
|
||||
|
||||
/obj/item/projectile/energy/astral_collective/green
|
||||
icon_state = "energy"
|
||||
irradiate = 40
|
||||
|
||||
/obj/item/projectile/energy/astral_collective/particle
|
||||
icon_state = "particle"
|
||||
damage_type = ELECTROMAG
|
||||
incendiary = 1
|
||||
flammability = 1
|
||||
|
||||
Reference in New Issue
Block a user