Large/Small Content Update (#7523)

This commit is contained in:
FluffMedic
2024-01-10 19:42:29 -05:00
committed by GitHub
parent 7f8306bcc7
commit 603db7270e
21 changed files with 7841 additions and 129 deletions
@@ -0,0 +1,9 @@
/obj/item/weapon/kinetic_crusher/glaive
name = "kinetic glaive"
icon_state = "crusher-glaive"
force = 20
detonation_damage = 20 // 40
backstab_bonus = 30 // 60
reach = 2
slot_flags = SLOT_BELT
w_class = ITEMSIZE_NORMAL
@@ -0,0 +1,219 @@
/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/weapon/storage/belt/holding = 60,
/obj/item/clothing/glasses/omni = 60,
/obj/item/weapon/kinetic_crusher/glaive = 60,
/obj/item/slime_extract/sepia = 60,
/obj/item/weapon/circuitboard/defenseonelisk = 60,
/obj/item/weapon/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)
@@ -0,0 +1,157 @@
/mob/living/simple_mob/humanoid/starhunter
name = "Starhunter Initiate"
tt_desc = "E Homo sapiens"
desc = "You shouldn't be seeing this."
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(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 class='danger'>[src] materializes around you, as you end up in their [belly_dest]!</span>")
/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)
@@ -0,0 +1,115 @@
/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)
verbs |= /mob/living/simple_mob/proc/animal_mount
verbs |= /mob/living/proc/toggle_rider_reins
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/init_vore()
if(!voremob_loaded)
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
B.desc = "The fearsome preadtor gets a firm grip upon you, before dunking you into it's maw, then with a powerful swift gulp you're sent tumbling into it's stomach.."
B.emote_lists[DM_HOLD] = list(
"Your surroundings are momentarily filled with tour predator's pleased rumbling, its hands stroking over the taut swell you make in its belly.",
"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)
verbs |= /mob/living/simple_mob/proc/animal_mount
verbs |= /mob/living/proc/toggle_rider_reins
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/init_vore()
if(!voremob_loaded)
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
B.desc = "The fearsome preadtor gets a firm grip upon you, before dunking you into it's maw, then with a powerful swift gulp you're sent tumbling into it's stomach.."
B.emote_lists[DM_HOLD] = list(
"Your surroundings are momentarily filled with tour predator's pleased rumbling, its hands stroking over the taut swell you make in its belly.",
"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)
verbs |= /mob/living/simple_mob/proc/animal_mount
verbs |= /mob/living/proc/toggle_rider_reins
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/init_vore()
if(!voremob_loaded)
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
B.desc = "The fearsome preadtor gets a firm grip upon you, before dunking you into it's maw, then with a powerful swift gulp you're sent tumbling into it's stomach.."
B.emote_lists[DM_HOLD] = list(
"Your surroundings are momentarily filled with tour predator's pleased rumbling, its hands stroking over the taut swell you make in its belly.",
"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." ,)
@@ -0,0 +1,242 @@
//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("<font color='orange'><B>[P] seems ineffective!.</B></font>") //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 class='danger'><b>\The [src]</b> fires at \the [A]!</span>") //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 class='danger'><b>\The [src]</b> fires at \the [orig_targ]!</span>")
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"
@@ -0,0 +1,120 @@
/mob/living/simple_mob/humanoid/starhunter/trader/weaponsmith
icon_state = "sunetrader"
products = list(/obj/item/weapon/gun/energy/sickshot = 5,
/obj/item/weapon/material/twohanded/fireaxe/scythe = 3,
/obj/item/weapon/material/twohanded/spear/lance = 3,
/obj/item/weapon/beartrap = 12,
/obj/item/weapon/material/barbedwire = 12,
/obj/item/weapon/material/sword/battleaxe = 3
) // For each, use the following pattern:
premium = list(/obj/item/weapon/gun/energy/maghowitzer) //This may be a mistake
prices = list(/obj/item/weapon/gun/energy/maghowitzer = 8000,
/obj/item/weapon/gun/energy/sickshot = 800,
/obj/item/weapon/material/twohanded/fireaxe/scythe = 400,
/obj/item/weapon/material/twohanded/spear/lance = 400,
/obj/item/weapon/beartrap = 80,
/obj/item/weapon/material/barbedwire = 80,
/obj/item/weapon/material/sword/battleaxe = 400
)
/mob/living/simple_mob/humanoid/starhunter/trader/reliccollecter
icon_state = "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/device/soulstone = 8,
/obj/item/clothing/glasses/monocoole = 3,
/obj/item/weapon/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/device/soulstone = 80,
/obj/item/clothing/glasses/monocoole = 1200,
/obj/item/weapon/storage/belt/holding = 1800,
/obj/item/clothing/gloves/regen = 1800,
/obj/item/clothing/glasses/omni = 2600
)
/mob/living/simple_mob/humanoid/starhunter/trader/miner
icon_state = "snektrader"
products = list(/obj/item/weapon/kinetic_crusher/glaive = 5,
/obj/item/weapon/kinetic_crusher = 3,
/obj/item/weapon/gun/energy/mininglaser = 3,
/obj/item/weapon/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/weapon/circuitboard/paradoxrift = 3
) // For each, use the following pattern:
premium = list(/obj/item/weapon/circuitboard/defenseonelisk) // No specified amount = only one in stock
prices = list(/obj/item/weapon/kinetic_crusher/glaive = 600,
/obj/item/weapon/kinetic_crusher = 600,
/obj/item/weapon/gun/energy/mininglaser = 800,
/obj/item/weapon/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/weapon/circuitboard/paradoxrift = 2400,
/obj/item/weapon/circuitboard/defenseonelisk = 5000
)
/mob/living/simple_mob/humanoid/starhunter/trader/farmer
icon_state = "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)
@@ -0,0 +1,162 @@
/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/weapon/coin/coin
/mob/living/simple_mob/humanoid/starhunter/trader/Initialize()
. = ..()
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/weapon/W as obj, mob/user as mob)
var/obj/item/weapon/card/id/I = W.GetID()
if(I || istype(W, /obj/item/weapon/spacecash))
attack_hand(user)
return
else if(istype(W, /obj/item/weapon/coin) && has_premium)
user.drop_item()
W.forceMove(src)
coin = W
categories |= CAT_COIN
to_chat(user, "<span class='notice'>You insert \the [W] into \the [src].</span>")
SStgui.update_uis(src)
return
/mob/living/simple_mob/humanoid/starhunter/trader/proc/pay_with_cash(var/obj/item/weapon/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, "\icon[cashmoney][bicon(cashmoney)] <span class='warning'>That is not enough money.</span>")
return 0
if(istype(cashmoney, /obj/item/weapon/spacecash))
visible_message("<span class='info'>\The [usr] inserts some cash into \the [src].</span>")
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)
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 = current_date_string
T.time = stationtime2text()
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/weapon/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/weapon/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
@@ -1,2 +1,237 @@
/mob/living/simple_mob/slime/xenobio/yellow
projectiletype = /obj/item/projectile/energy/mob/electric_spider
projectiletype = /obj/item/projectile/energy/mob/electric_spider
/mob/living/simple_mob/slime/xenobio/sepia
desc = "This slime is rather unknown and strange."
color = "#968473"
slime_color = "sepia"
coretype = /obj/item/slime_extract/sepia
reagent_injected = "stoxin"
mutation_chance = 100
slime_mutation = list(
/mob/living/simple_mob/slime/xenobio/sepia,
/mob/living/simple_mob/slime/xenobio/oil,
/mob/living/simple_mob/slime/xenobio/green,
/mob/living/simple_mob/slime/xenobio/ruby
)
/obj/item/slime_extract/sepia
name = "sepia slime extract"
icon_state = "sepia slime extract"
description_info = "Who knows what will happen."
slime_type = /mob/living/simple_mob/slime/xenobio/sepia
/decl/chemical_reaction/instant/slime/senseenhancer
name = "Slime Sense Enhancer"
id = "sepia_sh"
result = "senseenhancer"
required_reagents = list("phoron" = 5)
result_amount = 30
required = /obj/item/slime_extract/sepia
/decl/chemical_reaction/instant/slime/secertslime
name = "Secert Slime "
id = "sepia_swapm"
result = "change_drug_male"
required_reagents = list("water" = 1, "blood" = 1, "phoron" = 3)
result_amount = 1
required = /obj/item/slime_extract/sepia
/decl/chemical_reaction/instant/slime/secertslime/on_reaction(var/datum/reagents/holder)
holder.my_atom.visible_message("<span class='warning'>Infused with the mixture, the core begins to quiver and grow, and soon a new baby slime emerges from it!</span>")
new /mob/living/simple_mob/slime/xenobio/redspace(get_turf(holder.my_atom))
..()
/decl/chemical_reaction/instant/slime/genderswapf
name = "Slime Change F"
id = "sepia_swapf"
result = "change_drug_female"
required_reagents = list("water" = 5)
result_amount = 30
required = /obj/item/slime_extract/sepia
/decl/chemical_reaction/instant/slime/genderswapm
name = "Slime Change M"
id = "sepia_swapf"
result = "change_drug_male"
required_reagents = list("blood" = 5)
result_amount = 30
required = /obj/item/slime_extract/sepia
/decl/chemical_reaction/instant/slime/sepia_new_slime
name = "Slime Spawn"
id = "m_sepia_spawn"
result = null
required_reagents = list("slimejelly" = 5)
result_amount = 1
required = /obj/item/slime_extract/sepia
/decl/chemical_reaction/instant/slime/sepia_new_slime/on_reaction(var/datum/reagents/holder)
holder.my_atom.visible_message("<span class='warning'>Infused with slime jelly, the core begins to quiver and grow, and soon a new baby slime emerges from it!</span>")
new /mob/living/simple_mob/slime/xenobio/sepia(get_turf(holder.my_atom))
..()
/mob/living/simple_mob/slime/xenobio/redspace
desc = "This slime is rather unknown and strange."
color = "#A50021"
slime_color = "redspace"
coretype = /obj/item/slime_extract/redspace
reagent_injected = "mindbreaker"
mutation_chance = 0
slime_mutation = list(
/mob/living/simple_mob/slime/xenobio/dark,
/mob/living/simple_mob/slime/xenobio/redspace,
/mob/living/simple_mob/slime/xenobio/bluespace,
/mob/living/simple_mob/slime/xenobio/plague
)
/obj/item/slime_extract/redspace
name = "redspace slime extract"
icon_state = "ruby slime extract"
description_info = "Who knows what will happen."
slime_type = /mob/living/simple_mob/slime/xenobio/redspace
/decl/chemical_reaction/instant/slime/redspace_fire
name = "Slime Living Fire"
id = "m_liquid_fire"
result = "neoliquidfire"
required_reagents = list("phoron" = 5)
result_amount = 30
required = /obj/item/slime_extract/redspace
/decl/chemical_reaction/instant/slime/soulstone
name = "Slime Soulstone"
id = "m_redspace_soulstone"
required_reagents = list("blood" = 5)
result_amount = 1
required = /obj/item/slime_extract/redspace
/decl/chemical_reaction/instant/slime/soulstone/on_reaction(var/datum/reagents/holder)
new /obj/item/device/soulstone(get_turf(holder.my_atom))
..()
/decl/chemical_reaction/instant/slime/obj/item/slime_extract/redspace_smoke
name = "Slime Smoke"
id = "m_redspace_smoke"
required_reagents = list("water" = 5)
result_amount = 1
required = /obj/item/slime_extract/redspace
/decl/chemical_reaction/instant/slime/redspace_smoke/on_reaction(var/datum/reagents/holder)
var/location = get_turf(holder.my_atom)
var/datum/effect/effect/system/smoke_spread/chem/S = new /datum/effect/effect/system/smoke_spread/chem
S.attach(location)
S.set_up(holder, 120, 0, location)
playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3)
spawn(0)
S.start()
..()
/decl/chemical_reaction/instant/slime/slime_mindbreaker
name = "Slime Pyrotoxin"
id = "m_redspace_mindbreaker"
result = "mindbreaker"
required_reagents = list("slimejelly" = 5)
result_amount = 30
required = /obj/item/slime_extract/redspace
/mob/living/simple_mob/slime/xenobio/dark
desc = "This slime is rather unknown and strange."
color = "#080808"
slime_color = "dark"
coretype = /obj/item/slime_extract/dark
reagent_injected = "potassium_chlorophoride"
mutation_chance = 0
slime_mutation = list(
/mob/living/simple_mob/slime/xenobio/dark,
/mob/living/simple_mob/slime/xenobio/redspace,
/mob/living/simple_mob/slime/xenobio/bluespace,
/mob/living/simple_mob/slime/xenobio/plague
)
/obj/item/slime_extract/dark
name = "dark slime extract"
icon_state = "emerald slime extract"
description_info = "A strange extract, seems inert. Maybe something strange can be done one day"
slime_type = /mob/living/simple_mob/slime/xenobio/dark
/decl/chemical_reaction/instant/slime/dark_neofire
name = "Slime Healing Liquid"
id = "m_liquid_healing"
result = "healing_nanites"
required_reagents = list("neoliquidfire" = 5)
result_amount = 30
required = /obj/item/slime_extract/dark
/decl/chemical_reaction/instant/slime/dark_liquidfire
name = "Slime Secert Guard"
id = "m_slime_guardian"
required_reagents = list("liquidfire" = 5)
result_amount = 1
required = /obj/item/slime_extract/dark
/decl/chemical_reaction/instant/slime/dark_liquidfire/on_reaction(var/datum/reagents/holder)
for(var/mob/living/L in range(1, holder.my_atom))
L.add_modifier(/datum/modifier/feysight, 10 MINUTES, src)
..()
/mob/living/simple_mob/slime/xenobio/plague
desc = "This slime is rather unknown and strange."
color = "#A50021"
slime_color = "plague"
coretype = /obj/item/slime_extract/plague
mutation_chance = 0
slime_mutation = list(
/mob/living/simple_mob/slime/xenobio/dark,
/mob/living/simple_mob/slime/xenobio/redspace,
/mob/living/simple_mob/slime/xenobio/bluespace,
/mob/living/simple_mob/slime/xenobio/plague
)
/obj/item/slime_extract/plague
name = "plague slime extract"
icon_state = "emerald slime extract"
description_info = "Who knows what will happen."
slime_type = /mob/living/simple_mob/slime/xenobio/plague
/decl/chemical_reaction/instant/slime/plague_toxin
name = "Slime Living Fire"
id = "m_plague_toxin"
result = "neurophage_nanites"
required_reagents = list("phoron" = 5)
result_amount = 30
required = /obj/item/slime_extract/plague
/decl/chemical_reaction/instant/slime/virusdish
name = "Virus dish"
id = "m_plague_dish"
required_reagents = list("blood" = 5)
result_amount = 1
required = /obj/item/slime_extract/plague
/decl/chemical_reaction/instant/slime/virusdish/on_reaction(var/datum/reagents/holder)
new /obj/item/weapon/virusdish(get_turf(holder.my_atom))
..()
/decl/chemical_reaction/instant/slime/obj/item/slime_extract/plague_jelly
name = "Slime Smoke"
id = "m_slimejelly_alt"
result = "slimejelly"
required_reagents = list("water" = 5)
result_amount = 30
required = /obj/item/slime_extract/plague