[Cult 3.0] Lots of construct-related stuff (#20192)

* new construct sprites

* rebase

* juggerwall

* juggerdash

* cultvox&plasmasuits

* wraithphase

* artificer HUD

* artificer uses forge

* jhgjhlhluijkj

* artificer ray

* hex et caetera

* safety

* fixes

* aaa

* generic

* ok travis you win
This commit is contained in:
DeityLink
2018-10-15 20:30:29 +02:00
committed by MadmanMartian
parent ba2a7e6381
commit 2f82cbcbb7
49 changed files with 982 additions and 49 deletions

View File

@@ -896,6 +896,7 @@ SEE_PIXELS 256
#define STATUS_HUD_OOC "status_ooc" // STATUS_HUD without virus db check for someone being ill.
#define DIAG_HEALTH_HUD "diag_health" // Diagnostic HUD - health bar
#define DIAG_CELL_HUD "diag_cell" // Diagnostic HUD - power cell status for cyborgs, mechs
#define CONSTRUCT_HUD "const_health" // Artificer HUD
// Hypothermia - using the swiss staging system. - called by the proc undergoing_hypothermia() in handle_hypothermia.dm
#define NO_HYPOTHERMIA 0 // >35C - Fine

View File

@@ -1676,9 +1676,9 @@ Game Mode config tags:
A.starting = T
A.yo = U.y - T.y
A.xo = U.x - T.x
playsound(T, fire_sound, 50, 1)
A.OnFired()
playsound(T, fire_sound, 75, 1)
spawn()
A.OnFired()
A.process()

View File

@@ -285,6 +285,7 @@
stoplag(1)
/datum/radial_menu/Destroy()
if(current_user)
current_user.radial_menus -= anchor
Reset()
hide()

View File

@@ -105,6 +105,9 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
/mob/living/simple_animal/hostile/necromorph/leaper/can_ventcrawl()
return TRUE
/mob/living/simple_animal/shade/can_ventcrawl()
return TRUE
/mob/living/carbon/alien/can_ventcrawl()
if(handcuffed)
to_chat(src, "<span class='warning'>You can't vent crawl while you're restrained!</span>")

View File

@@ -128,7 +128,13 @@
//might add some hallucinations or brain damage later, checks for cultist chaplains, etc
return 1
/obj/structure/cult/attack_construct(var/mob/user)
if (!Adjacent(user))
return 0
if(istype(user,/mob/living/simple_animal/construct/builder))
cultist_act(user)
return 1
return 0
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //Spawned from the Raise Structure rune. Available from the beginning. Trigger progress to ACT I
@@ -467,7 +473,7 @@ var/list/cult_spires = list()
to_chat(user,"<span class='warning'>Come back to acquire another mark once your cult is a step closer to its goal.</span>")
return
var/tattoo = show_radial_menu(user,loc,choices,'icons/obj/cult_radial2.dmi',"radial-cult")//spawning on loc so we aren't offset by pixel_x/pixel_y, or affected by animate()
var/tattoo = show_radial_menu(user,loc,choices,'icons/obj/cult_radial2.dmi',"radial-cult2")//spawning on loc so we aren't offset by pixel_x/pixel_y, or affected by animate()
for (var/tat in C.tattoos)
var/datum/cult_tattoo/CT = C.tattoos[tat]
@@ -712,13 +718,13 @@ var/list/cult_spires = list()
var/list/choices = list(
list("Forge Blade", "radial_blade", "Deity please add details"),
list("Forge Construct Shell", "radial_constructshell", "Deity please add details"),
list("Forge Helmet", "radial_helmet", "Deity please add details"),
list("Forge Armor", "radial_armor", "The quote originates from the Spider-Man 2 video game released in June 2004. Near the beginning of the game, Peter Parker as Spider-Man is given free roam through New York City. The first mission is to make it to Doctor Connors' class on time, which is emphasized in a quote spoken by Parker before having to get to class.")
list("Forge Blade", "radial_blade", "A powerful ritual blade, the signature weapon of the bloodthirsty cultists. Features a notch in which a Soul Gem can fit."),
list("Forge Construct Shell", "radial_constructshell", "A polymorphic sculpture that can be shaped into a powerful ally by inserting a full Soul Gem or Shard."),
list("Forge Helmet", "radial_helmet", "This protective helmet offers the same enhancing powers that a Cult Hood provides, on top of being space proof."),
list("Forge Armor", "radial_armor", "This protective armor offers the same enhancing powers that Cult Robes provide, on top of being space proof."),
)
var/task = show_radial_menu(user,loc,choices,'icons/obj/cult_radial.dmi',"radial-cult") //deity please customize "radial-cult" in tooltip.html //spawning on loc so we aren't offset by pixel_x/pixel_y, or affected by animate()
var/task = show_radial_menu(user,loc,choices,'icons/obj/cult_radial.dmi',"radial-cult")//spawning on loc so we aren't offset by pixel_x/pixel_y, or affected by animate()
if (template || !Adjacent(user) || !task )
return
var/forge_icon = ""
@@ -736,7 +742,7 @@ var/list/cult_spires = list()
timeleft = 8
forge_icon = "forge_helmet"
if ("Forge Construct Shell")
template = /obj/structure/constructshell/cult
template = /obj/structure/constructshell/cult/alt
timeleft = 25
forge_icon = "forge_shell"
timetotal = timeleft

View File

@@ -928,6 +928,7 @@ var/list/arcane_tomes = list()
body_parts_covered = EARS|HEAD
siemens_coefficient = 0
heat_conductivity = SPACESUIT_HEAT_CONDUCTIVITY
species_fit = list(VOX_SHAPED)
/obj/item/clothing/head/culthood/get_cult_power()
return 20
@@ -947,6 +948,7 @@ var/list/arcane_tomes = list()
siemens_coefficient = 0.7
heat_conductivity = INS_SHOE_HEAT_CONDUCTIVITY
max_heat_protection_temperature = SHOE_MAX_HEAT_PROTECTION_TEMPERATURE
species_fit = list(VOX_SHAPED)
/obj/item/clothing/head/culthood/get_cult_power()
return 10
@@ -966,6 +968,8 @@ var/list/arcane_tomes = list()
allowed = list(/obj/item/weapon/melee/cultblade,/obj/item/weapon/melee/soulblade,/obj/item/weapon/tome,/obj/item/weapon/talisman,/obj/item/weapon/blood_tesseract)
armor = list(melee = 50, bullet = 30, laser = 30,energy = 20, bomb = 25, bio = 25, rad = 0)
siemens_coefficient = 0
species_fit = list(VOX_SHAPED)
clothing_flags = ONESIZEFITSALL
/obj/item/clothing/suit/cultrobes/get_cult_power()
return 50
@@ -1023,6 +1027,10 @@ var/list/arcane_tomes = list()
item_state = "culthelmet"
armor = list(melee = 60, bullet = 50, laser = 50,energy = 15, bomb = 50, bio = 30, rad = 30)
siemens_coefficient = 0
species_fit = list(VOX_SHAPED, UNDEAD_SHAPED)
clothing_flags = PLASMAGUARD|CONTAINPLASMAMAN
max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
/obj/item/clothing/head/helmet/space/cult/get_cult_power()
return 30
@@ -1043,6 +1051,9 @@ var/list/arcane_tomes = list()
slowdown = HARDSUIT_SLOWDOWN_MED
armor = list(melee = 60, bullet = 50, laser = 50,energy = 15, bomb = 50, bio = 30, rad = 30)
siemens_coefficient = 0
species_fit = list(VOX_SHAPED, UNDEAD_SHAPED)
clothing_flags = PLASMAGUARD|CONTAINPLASMAMAN|ONESIZEFITSALL
max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE
/obj/item/clothing/suit/space/cult/get_cult_power()
return 60
@@ -1057,10 +1068,12 @@ var/list/arcane_tomes = list()
/obj/item/clothing/head/culthood/old
icon_state = "culthood_old"
item_state = "culthood_old"
species_fit = list()
/obj/item/clothing/suit/cultrobes/old
icon_state = "cultrobes_old"
item_state = "cultrobes_old"
species_fit = list()
/obj/item/clothing/head/magus
name = "magus helm"

View File

@@ -0,0 +1,439 @@
/////////////////Juggernaut///////////////
/mob/living/simple_animal/construct/armoured/perfect
icon_state = "juggernaut2"
icon_living = "juggernaut2"
icon_dead = "juggernaut2"
construct_spells = list(
/spell/aoe_turf/conjure/forcewall/greater,
/spell/juggerdash,
)
see_in_dark = 7
var/dash_dir = null
var/turf/crashing = null
/mob/living/simple_animal/construct/armoured/perfect/New()
..()
setupfloat()
/mob/living/simple_animal/construct/armoured/perfect/to_bump(var/atom/obstacle)
if(src.throwing)
var/breakthrough = 0
if(istype(obstacle, /obj/structure/window/))
obstacle.Destroy(brokenup = 1)
breakthrough = 1
else if(istype(obstacle, /obj/structure/grille/))
var/obj/structure/grille/G = obstacle
G.health = (0.25*initial(G.health))
G.broken = 1
G.icon_state = "[initial(G.icon_state)]-b"
G.setDensity(FALSE)
getFromPool(/obj/item/stack/rods, get_turf(G.loc))
breakthrough = 1
else if(istype(obstacle, /obj/structure/table))
var/obj/structure/table/T = obstacle
T.destroy()
breakthrough = 1
else if(istype(obstacle, /obj/structure/rack))
new /obj/item/weapon/rack_parts(obstacle.loc)
qdel(obstacle)
breakthrough = 1
else if(istype(obstacle, /turf/simulated/wall))
var/turf/simulated/wall/W = obstacle
if (W.hardness <= 60)
playsound(W, 'sound/weapons/heavysmash.ogg', 75, 1)
W.dismantle_wall(1)
breakthrough = 1
else
src.throwing = 0
src.crashing = null
else if(istype(obstacle, /obj/structure/reagent_dispensers/fueltank))
obstacle.ex_act(1)
else if(istype(obstacle, /mob/living))
var/mob/living/L = obstacle
if (L.flags & INVULNERABLE)
src.throwing = 0
src.crashing = null
else if (!(L.status_flags & CANKNOCKDOWN) || (M_HULK in L.mutations) || istype(L,/mob/living/silicon))
//can't be knocked down? you'll still take the damage.
src.throwing = 0
src.crashing = null
L.take_overall_damage(5,0)
if(L.locked_to)
L.locked_to.unlock_atom(L)
else
L.take_overall_damage(5,0)
if(L.locked_to)
L.locked_to.unlock_atom(L)
L.Stun(5)
L.Knockdown(5)
L.apply_effect(STUTTER, 5)
playsound(src, 'sound/weapons/heavysmash.ogg', 50, 0, 0)
breakthrough = 1
else
src.throwing = 0
src.crashing = null
if(breakthrough)
if(crashing && !istype(crashing,/turf/space))
spawn(1)
src.throw_at(crashing, 50, src.throw_speed)
else
spawn(1)
crashing = get_distant_turf(get_turf(src), dash_dir, 2)
src.throw_at(crashing, 50, src.throw_speed)
if(istype(obstacle, /obj))
var/obj/O = obstacle
if(!O.anchored)
step(obstacle,src.dir)
else
obstacle.Bumped(src)
else if(istype(obstacle, /mob))
step(obstacle,src.dir)
else
obstacle.Bumped(src)
////////////////////Wraith/////////////////////////
/mob/living/simple_animal/construct/wraith/perfect
icon_state = "wraith2"
icon_living = "wraith2"
icon_dead = "wraith2"
see_in_dark = 7
construct_spells = list(/spell/targeted/ethereal_jaunt/shift/alt)
var/ranged_cooldown = 0
var/ammo = 3
var/ammo_recharge = 0
/mob/living/simple_animal/construct/wraith/perfect/New()
..()
setupfloat()
/mob/living/simple_animal/construct/wraith/perfect/Life()
if(timestopped)
return 0
. = ..()
ranged_cooldown = max(0,ranged_cooldown-1)
if (ammo < 3)
ammo_recharge++
if (ammo_recharge >= 3)
ammo_recharge = 0
ammo++
/mob/living/simple_animal/construct/wraith/perfect/RangedAttack(var/atom/A, var/params)
if(ranged_cooldown <= 0 && ammo)
ammo--
generic_projectile_fire(A, src, /obj/item/projectile/wraithnail, 'sound/weapons/hivehand.ogg')
return ..()
/obj/item/projectile/wraithnail
icon = 'icons/obj/projectiles_experimental.dmi'
icon_state = "wraithnail"
damage = 5
/obj/item/projectile/wraithnail/to_bump(var/atom/A)
if(bumped)
return 0
bumped = 1
if(A)
setDensity(FALSE)
invisibility = 101
kill_count = 0
var/obj/effect/overlay/wraithnail/nail = new (A.loc)
nail.transform = transform
if(isliving(A))
nail.stick_to(A)
var/mob/living/L = A
L.take_overall_damage(damage,0)
else if(loc)
var/turf/T = get_turf(src)
nail.stick_to(T,get_dir(src,A))
bullet_die()
/obj/item/projectile/wraithnail/bump_original_check()
if(!bumped)
if(loc == get_turf(original))
if(!(original in permutated))
to_bump(original)
/obj/effect/overlay/wraithnail
name = "red bolt"
desc = "A pointy red nail, lodged into the ground."
icon = 'icons/effects/effects.dmi'
icon_state = "wraithnail"
anchored = 1
density = 0
plane = ABOVE_HUMAN_PLANE
layer = CLOSED_CURTAIN_LAYER
var/atom/stuck_to = null
var/duration = 100
/obj/effect/overlay/wraithnail/New()
..()
pixel_x = rand(-4, 4) * PIXEL_MULTIPLIER
pixel_y = rand(-4, 4) * PIXEL_MULTIPLIER
/obj/effect/overlay/wraithnail/Destroy()
if(stuck_to)
unlock_atom(stuck_to)
stuck_to = null
..()
/obj/effect/overlay/wraithnail/proc/stick_to(var/atom/A, var/side = null)
pixel_x = rand(-4, 4) * PIXEL_MULTIPLIER
pixel_y = rand(-4, 4) * PIXEL_MULTIPLIER
playsound(A, 'sound/items/metal_impact.ogg', 30, 1)
var/turf/T = get_turf(A)
loc = T
playsound(T, 'sound/weapons/hivehand_empty.ogg', 75, 1)
if(isturf(A))
switch(side)
if(NORTH)
pixel_y = WORLD_ICON_SIZE/2
if(SOUTH)
pixel_y = -WORLD_ICON_SIZE/2
if(EAST)
pixel_x = WORLD_ICON_SIZE/2
if(WEST)
pixel_x = -WORLD_ICON_SIZE/2
else if(isliving(A) && !isspace(T))
stuck_to = A
visible_message("<span class='warning'>\the [src] nails \the [A] to \the [T].</span>")
lock_atom(A, /datum/locking_category/buckle)
spawn(duration)
qdel(src)
/obj/effect/overlay/wraithnail/attack_hand(var/mob/user)
if (do_after(user,src,15))
unstick()
/obj/effect/overlay/wraithnail/proc/unstick()
if(stuck_to)
unlock_atom(stuck_to)
qdel(src)
////////////////////Artificer/////////////////////////
/mob/living/simple_animal/construct/builder/perfect
icon_state = "artificer2"
icon_living = "artificer2"
icon_dead = "artificer2"
see_in_dark = 7
construct_spells = list(
/spell/aoe_turf/conjure/struct,
/spell/aoe_turf/conjure/wall,
/spell/aoe_turf/conjure/floor,
/spell/aoe_turf/conjure/pylon,
/spell/aoe_turf/conjure/hex,
)
var/mob/living/simple_animal/construct/heal_target = null
var/obj/effect/overlay/artificerray/ray = null
var/heal_range = 2
var/list/minions = list()
/mob/living/simple_animal/construct/builder/perfect/New()
..()
setupfloat()
/mob/living/simple_animal/construct/builder/perfect/Life()
if(timestopped)
return 0
. = ..()
if(. && heal_target)
heal_target.health = min(heal_target.maxHealth, heal_target.health + round(heal_target.maxHealth/10))
anim(target = heal_target, a_icon = 'icons/effects/effects.dmi', flick_anim = "const_heal", lay = NARSIE_GLOW, plane = LIGHTING_PLANE)
move_ray()
process_construct_hud(src)
/mob/living/simple_animal/construct/builder/perfect/Move(NewLoc,Dir=0,step_x=0,step_y=0,var/glide_size_override = 0)
. = ..()
if (ray)
move_ray()
/mob/living/simple_animal/construct/builder/perfect/proc/start_ray(var/mob/living/simple_animal/construct/target)
if (!istype(target))
return
if (locate(src) in target.healers)
to_chat(src, "<span class='warning'>You are already healing \the [target].</span>")
return
if (ray)
end_ray()
target.healers.Add(src)
heal_target = target
ray = new (loc)
to_chat(src, "<span class='notice'>You are now healing \the [target].</span>")
move_ray()
/mob/living/simple_animal/construct/builder/perfect/proc/move_ray()
if(heal_target && ray && heal_target.health < heal_target.maxHealth && get_dist(heal_target, src) <= heal_range && isturf(loc) && isturf(heal_target.loc))
ray.forceMove(loc)
var/disty = heal_target.y - src.y
var/distx = heal_target.x - src.x
var/newangle
if(!disty)
if(distx >= 0)
newangle = 90
else
newangle = 270
else
newangle = arctan(distx/disty)
if(disty < 0)
newangle += 180
else if(distx < 0)
newangle += 360
var/matrix/M = matrix()
if (ray.oldloc_source && ray.oldloc_target && get_dist(src,ray.oldloc_source) <= 1 && get_dist(heal_target,ray.oldloc_target) <= 1)
animate(ray, transform = turn(M.Scale(1,sqrt(distx*distx+disty*disty)),newangle),time = 1)
else
ray.transform = turn(M.Scale(1,sqrt(distx*distx+disty*disty)),newangle)
ray.oldloc_source = src.loc
ray.oldloc_target = heal_target.loc
else
end_ray()
/mob/living/simple_animal/construct/builder/perfect/proc/end_ray()
if (heal_target)
heal_target.healers.Remove(src)
heal_target = null
if (ray)
qdel(ray)
ray = null
/obj/effect/overlay/artificerray
name = "ray"
icon = 'icons/effects/96x96.dmi'
icon_state = "artificer_ray"
layer = FLY_LAYER
plane = LYING_MOB_PLANE
anchored = 1
mouse_opacity = 0
pixel_x = -32
pixel_y = -29
var/turf/oldloc_source = null
var/turf/oldloc_target = null
/obj/effect/overlay/artificerray/cultify()
return
/obj/effect/overlay/artificerray/ex_act()
return
/obj/effect/overlay/artificerray/emp_act()
return
/obj/effect/overlay/artificerray/blob_act()
return
/obj/effect/overlay/artificerray/singularity_act()
return
/mob/living/simple_animal/hostile/hex
name = "\improper Hex"
desc = "A lesser construct, crafted by an Artificer."
stop_automated_movement_when_pulled = 1
ranged_cooldown_cap = 1
icon = 'icons/mob/mob.dmi'
icon_state = "hex"
icon_living = "hex"
icon_dead = "hex"
speak_chance = 0
turns_per_move = 8
response_help = "gently taps"
response_disarm = "shoves"
response_harm = "hits"
speed = 0.2
maxHealth = 50
health = 50
can_butcher = 0
ranged = 1
retreat_distance = 4
minimum_distance = 4
projectilesound = 'sound/effects/forge.ogg'
projectiletype = /obj/item/projectile/bloodslash
move_to_delay = 1
mob_property_flags = MOB_SUPERNATURAL
harm_intent_damage = 10
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = "grips"
attack_sound = 'sound/weapons/rapidslice.ogg'
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
speed = 5
supernatural = 1
faction = "cult"
flying = 1
environment_smash_flags = 0
var/mob/living/simple_animal/construct/builder/perfect/master = null
/mob/living/simple_animal/hostile/hex/New()
..()
overlays = 0
var/overlay_layer = ABOVE_LIGHTING_LAYER
var/overlay_plane = LIGHTING_PLANE
var/image/glow = image(icon,"glow-[icon_state]",overlay_layer)
glow.plane = overlay_plane
overlays += glow
animate(src, pixel_y = 4 * PIXEL_MULTIPLIER , time = 10, loop = -1, easing = SINE_EASING)
animate(pixel_y = 2 * PIXEL_MULTIPLIER, time = 10, loop = -1, easing = SINE_EASING)
/mob/living/simple_animal/hostile/hex/Destroy()
if (master)
master.minions.Remove(src)
master = null
..()
/mob/living/simple_animal/hostile/hex/Cross(var/atom/movable/mover, var/turf/target, var/height=1.5, var/air_group = 0)
if(istype(mover, /obj/item/projectile/bloodslash))//stop hitting yourself ffs!
return 1
return ..()
/mob/living/simple_animal/hostile/hex/death(var/gibbed = FALSE)
..(TRUE) //If they qdel, they gib regardless
for(var/i=0;i<3;i++)
new /obj/item/weapon/ectoplasm (src.loc)
visible_message("<span class='warning'>\The [src] collapses in a shattered heap. </span>")
qdel (src)
/mob/living/simple_animal/hostile/hex/Found(var/atom/the_target)
if(ismob(the_target))
var/mob/M = the_target
if(isanycultist(M))
return 0
return ..(the_target)
/mob/living/simple_animal/hostile/hex/CanAttack(var/atom/the_target)
if(ismob(the_target))
var/mob/M = the_target
if(isanycultist(M))
return 0
return ..(the_target)
/mob/living/simple_animal/hostile/hex/cultify()
return

View File

@@ -244,10 +244,14 @@
var/obj/effect/rune/R = spell_holder
R.one_pulse()
if (locate(/obj/structure/cult) in R.loc)
if (locate(/obj/structure/cult) in range(R.loc,1))
abort(RITUALABORT_BLOCKED)
return
if (locate(/obj/machinery/door/mineral/cult) in range(R.loc,1))
abort(RITUALABORT_NEAR)
return
var/mob/living/user = activator
if (veil_thickness >= CULT_ACT_II)
var/spawnchoice = alert(user,"As the veil is getting thinner, new possibilities arise.","[name]","Altar","Forge","Spire")

View File

@@ -102,8 +102,14 @@
icon_state = "construct-cult"
desc = "This eerie contraption looks like it would come alive if supplied with a missing ingredient."
/obj/structure/constructshell/cult/alt
icon = 'icons/obj/cult.dmi'
icon_state = "shell"
/obj/structure/constructshell/attackby(obj/item/O as obj, mob/user as mob)
if(istype(O, /obj/item/device/soulstone))
if(istype(O, /obj/item/device/soulstone/gem))
O.transfer_soul("PERFECT",src,user)
else if(istype(O, /obj/item/device/soulstone))
O.transfer_soul("CONSTRUCT",src,user)
@@ -243,7 +249,7 @@
else if(istype(add_target,/mob/living/carbon/human))
body = add_target
var/true_name = "a nobody"
var/true_name = "Unknown"
if(body)
true_name = body.real_name
@@ -302,9 +308,9 @@
var/mob/living/simple_animal/shade/shadeMob = new(src)//put shade in stone
shadeMob.status_flags |= GODMODE //So they won't die inside the stone somehow
shadeMob.canmove = 0//Can't move out of the soul stone
shadeMob.name = "Shade of [true_name]"
shadeMob.name = "[true_name] the Shade"
shadeMob.real_name = "[true_name]"
shadeMob.ckey = targetClient.ckey
body.mind.transfer_to(shadeMob)
shadeMob.cancel_camera()
//Changing the soulstone's icon and description
@@ -320,10 +326,11 @@
to_chat(shadeMob, "Your soul has been captured! You are now bound to [user.name]'s will, help them suceed in their goals at all costs.")
to_chat(user, "<span class='notice'>[true_name]'s soul has been ripped from their body and stored within the soul stone.</span>")
//Is our user a cultist? Then you're a cultist too now!
if (iscultist(user))
var/datum/role/cultist/newCultist = new
newCultist.AssignToRole(user.mind,1)
newCultist.AssignToRole(shadeMob.mind,1)
var/datum/faction/bloodcult/cult = find_active_faction_by_type(/datum/faction/bloodcult)
if (!cult)
cult = ticker.mode.CreateFaction(/datum/faction/bloodcult, null, 1)
@@ -391,7 +398,7 @@
if (iscultist(U) && !iscultist(T))
var/datum/role/cultist/newCultist = new
newCultist.AssignToRole(U.mind,1)
newCultist.AssignToRole(T.mind,1)
var/datum/faction/bloodcult/cult = find_active_faction_by_type(/datum/faction/bloodcult)
if (!cult)
cult = ticker.mode.CreateFaction(/datum/faction/bloodcult, null, 1)
@@ -404,20 +411,27 @@
var/mob/living/simple_animal/shade/A = locate() in C
var/mob/living/simple_animal/construct/Z
if(A)
var/construct_class = alert(U, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer")
var/list/choices = list(
list("Artificer", "radial_artificer", "Though fragile, this construct can reshape its surroundings, conjuring walls, floors, and most importantly, repair other constructs. Additionally, they may operate some cult structures."),
list("Wraith", "radial_wraith", "The fastest of deadliest of constructs, at the cost of a relatively fragile build. Can easily scout and escape by phasing through the veil. Its claws can pry open unpowered airlocks."),
list("Juggernaut", "radial_juggernaut", "Sturdy, powerful, at the cost of a snail's pace. However, its fists can break walls apart, along with some machinery. Can conjure a temporary forcefield."),
)
var/construct_class = show_radial_menu(U,T,choices,'icons/obj/cult_radial3.dmi',"radial-cult2")
if (!T.Adjacent(U) || (C != U.get_active_hand()) || !construct_class || A.loc != C)
return
switch(construct_class)
if("Juggernaut")
Z = new /mob/living/simple_animal/construct/armoured (get_turf(T.loc))
Z.key = A.key
A.mind.transfer_to(Z)
qdel(T)
to_chat(Z, "<B>You are a Juggernaut. Though slow, your shell can withstand extreme punishment, your body can reflect energy and laser weapons, and you can create temporary shields that blocks pathing and projectiles. You fists can punch people and regular walls appart.</B>")
to_chat(Z, "<B>You are a Juggernaut. Though slow, your shell can withstand extreme punishment, your body can reflect energy and laser weapons, and you can create temporary shields that blocks pathing and projectiles. You fists can punch people and regular walls apart.</B>")
to_chat(Z, "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>")
Z.cancel_camera()
deleteafter = 1
if("Wraith")
Z = new /mob/living/simple_animal/construct/wraith (get_turf(T.loc))
Z.key = A.key
A.mind.transfer_to(Z)
qdel(T)
to_chat(Z, "<B>You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls for a few seconds. Use it both for surprise attacks and strategic retreats.</B>")
to_chat(Z, "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>")
@@ -426,7 +440,7 @@
if("Artificer")
Z = new /mob/living/simple_animal/construct/builder (get_turf(T.loc))
Z.key = A.key
A.mind.transfer_to(Z)
qdel(T)
to_chat(Z, "<B>You are an Artificer. You are incredibly weak and fragile, but you can heal both yourself and other constructs (by clicking on yourself/them). You can build (and deconstruct) new walls and floors, or replace existing ones by clicking on them, as well as place pylons that act as light source (these block paths but can be easily broken),</B><I>and most important of all you can produce the tools to create new constructs</I><B> (remember to periodically produce new soulstones for your master, and place empty shells in your hideout or when asked.).</B>")
to_chat(Z, "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>")
@@ -436,10 +450,64 @@
var/datum/faction/cult/narsie/cult_round = find_active_faction_by_member(U.mind.GetRole(LEGACY_CULTIST))
if(cult_round && istype(cult_round))
cult_round.HandleRecruitedMind(Z.mind)
Z.real_name = A.real_name
Z.name = "[Z.real_name] the [construct_class]"
name = "Soul Stone Shard"
else
to_chat(U, "<span class='warning'><b>Creation failed!</b>: The soul stone is empty! Go kill someone!</span>")
to_chat(U, "<span class='warning'>\The [src] is empty! The shell doesn't react.</span>")
if("PERFECT")
var/obj/structure/constructshell/T = target
var/obj/item/device/soulstone/C = src
var/mob/living/simple_animal/shade/A = locate() in C
var/mob/living/simple_animal/construct/Z
if(A)
var/list/choices = list(
list("Artificer", "radial_artificer2", "Though fragile, this construct can reshape its surroundings, conjuring walls, floors, and most importantly, repair other constructs. Additionally, they may operate some cult structures. <b>Can open gateways to summon eldritch monsters from the realm of Nar-Sie.</b>"),
list("Wraith", "radial_wraith2", "The fastest of deadliest of constructs, at the cost of a relatively fragile build. Can easily scout and escape by phasing through the veil. Its claws can pry open unpowered airlocks. <b>Can fire bolts that nail their victims to the floor.</b>"),
list("Juggernaut", "radial_juggernaut2", "Sturdy, powerful, at the cost of a snail's pace. However, its fists can break walls apart, along with some machinery. Can conjure a temporary forcefield. <b>Can dash forward over a large distance, knocking down anyone in front of them.</b>"),
)
var/construct_class = show_radial_menu(U,T,choices,'icons/obj/cult_radial3.dmi',"radial-cult2")
if (!T.Adjacent(U) || (C != U.get_active_hand()) || !construct_class || A.loc != C)
return
switch(construct_class)
if("Juggernaut")
Z = new /mob/living/simple_animal/construct/armoured/perfect (get_turf(T.loc))
A.mind.transfer_to(Z)
qdel(T)
to_chat(Z, "<B>You are a Juggernaut. Though slow, your shell can withstand extreme punishment, your body can reflect energy and laser weapons, and you can create temporary shields that blocks pathing and projectiles. You fists can punch people and regular walls apart.</B>")
to_chat(Z, "<B>You can dash over a large distance, knocking down anyone on your path.</B>")
to_chat(Z, "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>")
Z.cancel_camera()
deleteafter = 1
if("Wraith")
Z = new /mob/living/simple_animal/construct/wraith/perfect (get_turf(T.loc))
A.mind.transfer_to(Z)
qdel(T)
to_chat(Z, "<B>You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls for a few seconds. Use it both for surprise attacks and strategic retreats.</B>")
to_chat(Z, "<B>You can fire red bolts that can temporarily prevent their victims from moving. You recharge a bolt every 5 seconds, up to 3 bolts.</B>")
to_chat(Z, "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>")
Z.cancel_camera()
deleteafter = 1
if("Artificer")
Z = new /mob/living/simple_animal/construct/builder/perfect (get_turf(T.loc))
A.mind.transfer_to(Z)
qdel(T)
to_chat(Z, "<B>You are an Artificer. You are incredibly weak and fragile, but you can heal both yourself and other constructs (by clicking on yourself/them). You can build (and deconstruct) new walls and floors, or replace existing ones by clicking on them, as well as place pylons that act as light source (these block paths but can be easily broken),</B><I>and most important of all you can produce the tools to create new constructs</I><B> (remember to periodically produce new soulstones for your master, and place empty shells in your hideout or when asked.).</B>")
to_chat(Z, "<B>You can channel a gateway from the realm of Nar-Sie to summon a minion to protect an area.</B>")
to_chat(Z, "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>")
Z.cancel_camera()
deleteafter = 1
if(islegacycultist(U))
var/datum/faction/cult/narsie/cult_round = find_active_faction_by_member(U.mind.GetRole(LEGACY_CULTIST))
if(cult_round && istype(cult_round))
cult_round.HandleRecruitedMind(Z.mind)
Z.real_name = A.real_name
Z.name = "[Z.real_name] the [construct_class]"
name = "Soul Stone Shard"
else
to_chat(U, "<span class='warning'>\The [src] is empty! The shell doesn't react.</span>")
if(deleteafter)
for(var/atom/A in src)//we get rid of the empty shade once we've transferred its mind to the construct, so it isn't dropped on the floor when the soulstone is destroyed.
qdel(A)

View File

@@ -533,6 +533,13 @@
M.dash_dir = dir
src.throwing = 2// mechas will crash through windows, grilles, tables, people, you name it
var/afterimage = 0
if(istype(src,/mob/living/simple_animal/construct/armoured/perfect))
var/mob/living/simple_animal/construct/armoured/perfect/M = src
M.dash_dir = dir
src.throwing = 2
afterimage = 1
var/dist_x = abs(target.x - src.x)
var/dist_y = abs(target.y - src.y)
@@ -571,6 +578,8 @@
if(kinetic_acceleration>kinetic_sum)
fly_speed += kinetic_acceleration-kinetic_sum
kinetic_sum = kinetic_acceleration
if(afterimage)
new /obj/effect/red_afterimage(loc,src)
if(error < 0)
var/atom/step = get_step(src, dy)
if(!step) // going off the edge of the map makes get_step return null, don't let things go off the edge
@@ -610,6 +619,8 @@
if(kinetic_acceleration>0)
fly_speed += kinetic_acceleration
kinetic_acceleration = 0
if(afterimage)
new /obj/effect/red_afterimage(loc,src)
if(error < 0)
var/atom/step = get_step(src, dx)
if(!step) // going off the edge of the map makes get_step return null, don't let things go off the edge

View File

@@ -242,3 +242,28 @@ proc/process_sec_hud(var/mob/M, var/advanced_mode,var/mob/eye)
O.process_hud(src)
if(!druggy)
see_invisible = SEE_INVISIBLE_LIVING
//Artificer HUD
proc/process_construct_hud(var/mob/M, var/mob/eye)
if(!M)
return
if(!M.client)
return
var/client/C = M.client
var/image/holder
var/turf/T
if(eye)
T = get_turf(eye)
else
T = get_turf(M)
for(var/mob/living/simple_animal/construct/construct in range(T))
if(!check_HUD_visibility(construct, M))
continue
holder = construct.hud_list[CONSTRUCT_HUD]
if(holder)
if(construct.isDead())
holder.icon_state = "consthealth0"
else
holder.icon_state = "consthealth[10*round((construct.health/construct.maxHealth)*10)]"
C.images += holder

View File

@@ -69,6 +69,17 @@
set_broken()
..()
/obj/machinery/computer/attack_construct(var/mob/user)
if (!Adjacent(user))
return 0
if(istype(user,/mob/living/simple_animal/construct/armoured))
if(!(stat & BROKEN))
shake(1, 3)
playsound(src, 'sound/weapons/heavysmash.ogg', 75, 1)
set_broken()
return 1
return 0
/obj/machinery/computer/blob_act()
if (prob(75))
for(var/x in verbs)

View File

@@ -1059,6 +1059,7 @@ About the new airlock wires panel:
else
density ? open(1):close(1)
//You can ALWAYS screwdriver a door. Period. Well, at least you can even if it's open
/obj/machinery/door/airlock/togglePanelOpen(var/obj/toggleitem, mob/user)
if(!operating)

View File

@@ -108,6 +108,8 @@ var/list/all_doors = list()
user = null
if(allowed(user))
if (isshade(user))
user.forceMove(loc)//They're basically slightly tangible ghosts, they can fit through doors as soon as they begin openning.
open()
else if(!operating)
denied()

View File

@@ -229,6 +229,18 @@ var/global/list/alert_overlays_global = list()
/obj/machinery/door/firedoor/attack_alien(mob/living/carbon/alien/humanoid/user)
force_open(user)
/obj/machinery/door/firedoor/attack_construct(var/mob/user)
if (!Adjacent(user))
return 0
if(istype(user,/mob/living/simple_animal/construct/armoured))
shake(1, 3)
playsound(user, 'sound/weapons/heavysmash.ogg', 75, 1)
to_chat(user, "<span class = 'warning'>You smash with all your strength but \the [src] doesn't budge. If only your arms were sharp enough to pry the door open.</span>")
if(istype(user,/mob/living/simple_animal/construct/wraith))
force_open(user)
return 1
return 0
/obj/machinery/door/firedoor/attackby(obj/item/weapon/C as obj, mob/user as mob)
add_fingerprint(user)
if(operating)

View File

@@ -675,15 +675,15 @@ var/global/num_vending_terminals = 1
else
src.icon_state = "[initial(icon_state)]"
/obj/machinery/vending/proc/damaged()
src.health -= 4
/obj/machinery/vending/proc/damaged(var/coef=1)
src.health -= 4*coef
if(src.health <= 0)
stat |= BROKEN
src.update_vicon()
return
if(prob(2)) //Jackpot!
if(prob(2*coef)) //Jackpot!
malfunction()
if(prob(2))
if(prob(2*coef))
src.TurnOff(600) //A whole minute
/*if(prob(1))
to_chat(usr, "<span class='warning'>You fall down and break your leg!</span>")
@@ -695,6 +695,16 @@ var/global/num_vending_terminals = 1
damaged()
/obj/machinery/vending/attack_construct(var/mob/user)
if (!Adjacent(user))
return 0
if(istype(user,/mob/living/simple_animal/construct/armoured))
shake(1, 3)
playsound(src, 'sound/weapons/heavysmash.ogg', 75, 1)
damaged(4)
return 1
return 0
/obj/machinery/vending/attack_hand(mob/living/user as mob)
if(stat & (BROKEN))
to_chat(user, "<span class='notice'>The glass in \the [src] is broken, it refuses to work.</span>")

View File

@@ -131,6 +131,9 @@ var/explosion_shake_message_cooldown = 0
if(D.density && D.explosion_block)
dist += D.explosion_block
for (var/obj/effect/forcefield/F in Trajectory.contents)
dist += F.explosion_block
if(dist < devastation_range)
dist = 1
else if(dist < heavy_impact_range)

View File

@@ -99,12 +99,14 @@
if(M.environment_smash_flags & SMASH_WALLS)
if(istype(src, /turf/simulated/wall/r_wall))
if(M.environment_smash_flags & SMASH_RWALLS)
playsound(src, 'sound/weapons/heavysmash.ogg', 75, 1)
dismantle_wall(1)
M.visible_message("<span class='danger'>[M] smashes through \the [src].</span>", \
"<span class='attack'>You smash through \the [src].</span>")
else
to_chat(M, "<span class='info'>This [src] is far too strong for you to destroy.</span>")
else
playsound(src, 'sound/weapons/heavysmash.ogg', 75, 1)
dismantle_wall(1)
M.visible_message("<span class='danger'>[M] smashes through \the [src].</span>", \
"<span class='attack'>You smash through \the [src].</span>")

View File

@@ -745,6 +745,20 @@ var/global/list/loopModeNames=list(
update_music()
update_icon()
/obj/machinery/media/jukebox/attack_construct(var/mob/user)
if (!Adjacent(user))
return 0
if(istype(user,/mob/living/simple_animal/construct/armoured))
playsound(src, 'sound/weapons/heavysmash.ogg', 75, 1)
shake(1, 3)
if(stat & NOPOWER || any_power_cut())
return
playing=!playing
update_music()
update_icon()
return 1
return 0
/obj/machinery/media/jukebox/bar
department = "Civilian"
req_access = list(access_bar)

View File

@@ -183,6 +183,9 @@ turf/unsimulated/mineral/ChangeTurf(var/turf/N, var/tell_universe=1, var/force_l
var/obj/structure/bed/chair/vehicle/gigadrill/G = AM
G.drill(src)
else if(istype(AM,/mob/living/simple_animal/construct/armoured))
attack_construct(AM)
/turf/unsimulated/mineral/proc/MineralSpread()
if(mineral && mineral.spread)
for(var/trydir in cardinal)
@@ -399,6 +402,16 @@ turf/unsimulated/mineral/ChangeTurf(var/turf/N, var/tell_universe=1, var/force_l
if(M.environment_smash_flags & SMASH_ASTEROID && prob(30))
GetDrilled(0)
/turf/unsimulated/mineral/attack_construct(var/mob/user)
if (!Adjacent(user))
return 0
if(istype(user,/mob/living/simple_animal/construct/armoured))
playsound(src, 'sound/weapons/heavysmash.ogg', 75, 1)
if(do_after(user, src, 40))
GetDrilled(0)
return 1
return 0
/turf/unsimulated/mineral/proc/DropMineral()
if(!mineral)
return

View File

@@ -345,6 +345,15 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set name = "Ghost"
set desc = "Relinquish your life and enter the land of the dead."
if(iscultist(src) && (ishuman(src)||isconstruct(src)) && veil_thickness > CULT_PROLOGUE)
var/response = alert(src, "It doesn't have to end here, the veil is thin and the dark energies in you soul cling to this plane. You may forsake this body and materialize as a Shade.","Sacrifice Body","Shade","Ghost","Stay in body")
switch (response)
if ("Shade")
dust()
return
if ("Stay in body")
return
if(src.health < 0 && stat != DEAD) //crit people
succumb()
ghostize(1)

View File

@@ -43,10 +43,14 @@
qdel(src)
/mob/living/carbon/human/Destroy()
if(mind && species && (species.name == "Manifested"))
var/datum/role/cultist = mind.GetRole(CULTIST)
if(cultist)//manifested ghosts are removed from the cult once their bodies are destroyed
cultist.RemoveFromRole(mind)
if(client && iscultist(src) && veil_thickness > CULT_PROLOGUE)
var/turf/T = get_turf(src)
if (T)
var/mob/living/simple_animal/shade/shade = new (T)
shade.name = "[real_name] the Shade"
shade.real_name = "[real_name]"
mind.transfer_to(shade)
to_chat(shade, "<span class='sinister'>Dark energies rip your dying body appart, anchoring your soul inside the form of a Shade. You retain your memories, and devotion to the cult.</span>")
if(species)
qdel(species)

View File

@@ -98,6 +98,7 @@
species.handle_environment(environment, src)
if(breath)
loc.assume_air(breath)

View File

@@ -19,6 +19,9 @@
burn_mod = 0.5
brute_mod = 1.5
head_icons = 'icons/mob/species/plasmaman/head.dmi'
wear_suit_icons = 'icons/mob/species/plasmaman/suit.dmi'
has_organ = list(
"heart" = /datum/organ/internal/heart,
"lungs" = /datum/organ/internal/lungs/plasmaman,

View File

@@ -39,6 +39,16 @@
var/list/construct_spells = list()
var/list/hud_list = list()
var/list/healers = list()
/mob/living/simple_animal/construct/Move(NewLoc,Dir=0,step_x=0,step_y=0,var/glide_size_override = 0)
. = ..()
if (healers.len > 0)
for (var/mob/living/simple_animal/construct/builder/perfect/P in healers)
P.move_ray()
/mob/living/simple_animal/construct/say(var/message)
. = ..(message, "C")
@@ -77,13 +87,12 @@
/mob/living/simple_animal/construct/New()
..()
name = text("[initial(name)] ([rand(1, 1000)])")
real_name = name
hud_list[CONSTRUCT_HUD] = image('icons/mob/hud.dmi', src, "consthealth100")
add_language(LANGUAGE_CULT)
default_language = all_languages[LANGUAGE_CULT]
for(var/spell in construct_spells)
src.add_spell(new spell, "const_spell_ready")
updateicon()
src.add_spell(new spell, "cult_spell_ready", /obj/abstract/screen/movable/spell_master/bloodcult)
setupglow()
/mob/living/simple_animal/construct/death(var/gibbed = FALSE)
..(TRUE) //If they qdel, they gib regardless
@@ -92,6 +101,18 @@
for(var/mob/M in viewers(src, null))
if((M.client && !( M.blinded )))
M.show_message("<span class='warning'>[src] collapses in a shattered heap. </span>")
if(client && iscultist(src))
var/turf/T = get_turf(src)
if (T)
var/mob/living/simple_animal/shade/shade = new (T)
var/true_name = "a nobody"
if (real_name && real_name != "unknown")
true_name = real_name
shade.name = "Shade of [true_name]"
shade.real_name = "Shade of [true_name]"
mind.transfer_to(shade)
to_chat(shade, "<span class='sinister'>Dark energies rip your dying body appart, anchoring your soul inside the form of a Shade. You retain your memories, and devotion to the cult.</span>")
else
ghostize()
qdel (src)
@@ -110,13 +131,25 @@
to_chat(user, msg)
/mob/living/simple_animal/construct/attack_construct(var/mob/user)
if(istype(user,/mob/living/simple_animal/construct/builder/perfect) && get_dist(user,src)<=2)
attack_animal(user)
return 1
return 0
/mob/living/simple_animal/construct/attack_animal(mob/living/simple_animal/M)
if(istype(M, /mob/living/simple_animal/construct/builder))
if(istype(M, /mob/living/simple_animal/construct/builder/perfect))
if(src.health >= src.maxHealth)
to_chat(M, "<span class='notice'>[src] has nothing to mend.</span>")
to_chat(M, "<span class='notice'>\The [src] has nothing to mend.</span>")
return
var/mob/living/simple_animal/construct/builder/perfect/P = M
P.start_ray(src)
else if(istype(M, /mob/living/simple_animal/construct/builder))
if(src.health >= src.maxHealth)
to_chat(M, "<span class='notice'>\The [src] has nothing to mend.</span>")
return
health = min(maxHealth, health + 5) // Constraining health to maxHealth
anim(target = src, a_icon = 'icons/effects/effects.dmi', flick_anim = "const_heal", lay = NARSIE_GLOW, plane = LIGHTING_PLANE)
M.visible_message("[M] mends some of \the <EM>[src]'s</EM> wounds.","You mend some of \the <em>[src]'s</em> wounds.")
else
M.unarmed_attack_mob(src)
@@ -206,11 +239,13 @@
melee_damage_upper = 25
attacktext = "slashes"
speed = 1
environment_smash_flags = SMASH_LIGHT_STRUCTURES | SMASH_CONTAINERS
environment_smash_flags = SMASH_LIGHT_STRUCTURES | SMASH_CONTAINERS | OPEN_DOOR_WEAK
see_in_dark = 7
attack_sound = 'sound/weapons/rapidslice.ogg'
construct_spells = list(/spell/targeted/ethereal_jaunt/shift)
/mob/living/simple_animal/construct/wraith/get_unarmed_sharpness(mob/living/victim)
return 1.5
/////////////////////////////Artificer/////////////////////////
@@ -302,7 +337,7 @@
change_sight(adding = SEE_MOBS)
////////////////Glow//////////////////
/mob/living/simple_animal/construct/proc/updateicon()
/mob/living/simple_animal/construct/proc/setupglow()
overlays = 0
var/overlay_layer = ABOVE_LIGHTING_LAYER
var/overlay_plane = LIGHTING_PLANE
@@ -314,6 +349,12 @@
glow.plane = overlay_plane
overlays += glow
////////////////Float//////////////////
/mob/living/simple_animal/construct/proc/setupfloat()
animate(src, pixel_y = 6 * PIXEL_MULTIPLIER , time = 7, loop = -1, easing = SINE_EASING)
animate(pixel_y = 2 * PIXEL_MULTIPLIER, time = 7, loop = -1, easing = SINE_EASING)
////////////////Powers//////////////////
@@ -418,6 +459,9 @@
/mob/living/simple_animal/construct/builder/regular_hud_updates()
..()
process_construct_hud(src)
if(healths)
switch(health)
if(50 to INFINITY)

View File

@@ -1,9 +1,16 @@
//They're basically slightly tangible ghosts, they can't move through airtight stuff but they should be able to fit in vents
/mob/living/simple_animal/shade/verb/ventcrawl()
set name = "Dive into Vent"
set desc = "Enter an air vent and move through the pipe system."
set category = "Object"
var/pipe = start_ventcrawl()
if(pipe)
handle_ventcrawl(pipe)
// SPELLS THAT SHADES GET IN SOUL BLADES ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Giving the spells
/mob/living/simple_animal/shade/proc/give_blade_powers()
if (!istype(loc, /obj/item/weapon/melee/soulblade))

View File

@@ -114,6 +114,16 @@
busy = 0
return
/obj/structure/boulder/attack_construct(var/mob/user)
if (!Adjacent(user))
return 0
if(istype(user,/mob/living/simple_animal/construct/armoured))
playsound(loc, 'sound/weapons/heavysmash.ogg', 75, 1)
if(do_after(user, src, 20))
returnToPool(src)
return 1
return 0
/obj/structure/boulder/Bumped(AM)
. = ..()
if(istype(AM,/mob/living/carbon/human))
@@ -132,3 +142,6 @@
var/obj/mecha/M = AM
if(istype(M.selected,/obj/item/mecha_parts/mecha_equipment/tool/drill))
M.selected.action(src)
else if(istype(AM,/mob/living/simple_animal/construct/armoured))
attack_construct(AM)

View File

@@ -22,7 +22,7 @@
charge_max = 1800
summon_type = list(/obj/structure/constructshell/cult)
hud_state = "const_shell"
override_base = "const"
override_base = "cult"
/spell/aoe_turf/conjure/floor
name = "Floor Construction"
@@ -36,6 +36,7 @@
range = 3
summon_type = list(/turf/simulated/floor/engine/cult)
override_base = "cult"
hud_state = "const_floor"
cast_sound = 'sound/items/welder.ogg'
@@ -45,6 +46,7 @@
/spell/aoe_turf/conjure/floor/conjure_animation(var/atom/movable/overlay/animation, var/turf/target)
animation.icon_state = "cultfloor"
flick("cultfloor",animation)
shadow(target,holder.loc,"artificer_convert")
spawn(10)
qdel(animation)
animation = null
@@ -61,6 +63,7 @@
range = 3
summon_type = list(/turf/simulated/wall/cult)
override_base = "cult"
hud_state = "const_wall"
cast_sound = 'sound/items/welder.ogg'
@@ -70,6 +73,7 @@
/spell/aoe_turf/conjure/wall/conjure_animation(var/atom/movable/overlay/animation, var/turf/target)
animation.icon_state = "cultwall"
flick("cultwall",animation)
shadow(target,holder.loc,"artificer_convert")
spawn(10)
qdel(animation)
animation = null
@@ -103,7 +107,7 @@
summon_type = list(/obj/item/device/soulstone)
hud_state = "const_stone"
override_base = "const"
override_base = "cult"
/spell/aoe_turf/conjure/pylon
name = "Red Pylon"
@@ -120,6 +124,7 @@
cast_sound = 'sound/items/welder.ogg'
hud_state = "const_pylon"
override_base = "cult"
/spell/aoe_turf/conjure/pylon/cast(list/targets)
..()
@@ -143,6 +148,7 @@
summon_type = list(/obj/effect/forcefield/cult)
duration = 200
override_base = "cult"
hud_state = "const_juggwall"
//Code for the Juggernaut construct's forcefield, that seemed like a good place to put it.
@@ -155,5 +161,200 @@
luminosity = 2
invisibility = 0
/obj/effect/forcefield/cult/New()
..()
set_light(2)
/obj/effect/forcefield/cult/cultify()
return
////////////////////////////////////////////////////NEW CULT 3.0 STUFF////////////////////////////////////////////////
/spell/aoe_turf/conjure/forcewall/greater
name = "Jugger-Wall"
desc = "Raise a temporary line of indestructible walls to block your enemies' path and protect your allies."
user_type = USER_TYPE_CULT
charge_max = 250
spell_flags = 0
invocation = "none"
invocation_type = SpI_NONE
range = 0
summon_type = list(/obj/effect/forcefield/cult/large)
duration = 200
hud_state = "const_juggwall2"
override_base = "cult"
/spell/aoe_turf/conjure/forcewall/greater/on_creation(var/obj/effect/forcefield/cult/large/AM, var/mob/user)
playsound(user, 'sound/effects/stonedoor_openclose.ogg', 100, 1)
user.throwing = 0
AM.layer++
var/turf/turf_left = null
var/turf/turf_right = null
switch (user.dir)
if (SOUTH)
turf_left = get_step(AM, EAST)
turf_right = get_step(AM, WEST)
if (NORTH)
turf_left = get_step(AM, WEST)
turf_right = get_step(AM, EAST)
if (EAST)
turf_left = get_step(AM, NORTH)
turf_right = get_step(AM, SOUTH)
if (WEST)
turf_left = get_step(AM, SOUTH)
turf_right = get_step(AM, NORTH)
if (!turf_left.density && !turf_left.has_dense_content())
AM.side1 = new (AM.loc)
AM.side1.icon_state += "_side"
AM.side1.dir = get_dir(AM, turf_left)
spawn (1)
AM.side1.forceMove(turf_left)
if (!turf_right.density && !turf_right.has_dense_content())
AM.side2 = new (AM.loc)
AM.side2.icon_state += "_side"
AM.side2.dir = get_dir(AM, turf_right)
spawn (1)
AM.side2.forceMove(turf_right)
if (!AM.side1 && AM.side2)
var/turf/extra = get_step(turf_right,AM.side2.dir)
if (!extra.density && !extra.has_dense_content())
spawn (2)
AM.side2.forceMove(extra)
AM.side1 = new (AM.loc)
AM.side1.icon_state += "_mid"
AM.side1.dir = get_dir(AM, turf_right)
AM.side1.forceMove(turf_right)
if (AM.side1 && !AM.side2)
var/turf/extra = get_step(turf_left,AM.side1.dir)
if (!extra.density && !extra.has_dense_content())
spawn (2)
AM.side1.forceMove(get_step(turf_left,AM.side1.dir))
AM.side2 = new (AM.loc)
AM.side2.icon_state += "_mid"
AM.side2.dir = get_dir(AM, turf_left)
AM.side2.forceMove(turf_left)
/obj/effect/forcefield/cult/large
desc = "That eerie looking obstacle seems to have been pulled from another dimension through sheer force."
name = "Juggerwall"
icon = 'icons/effects/effects.dmi'
icon_state = "juggerwall"
light_color = LIGHT_COLOR_RED
luminosity = 2
invisibility = 0
explosion_block = 200
var/obj/effect/forcefield/cult/large/side1 = null
var/obj/effect/forcefield/cult/large/side2 = null
/obj/effect/forcefield/cult/large/Destroy()
if (loc)
new /obj/effect/red_afterimage(loc,src)
if (side1)
qdel(side1)
if (side2)
qdel(side2)
side1 = null
side2 = null
..()
/spell/juggerdash
name = "Jugger-Dash"
desc = "Charge in a line and knock down anything in your way, even some walls."
user_type = USER_TYPE_CULT
hud_state = "const_juggdash"
override_base = "cult"
charge_max = 150
spell_flags = 0
var/dash_range = 20
/spell/juggerdash/choose_targets(var/mob/user = usr)
return list(user)
/spell/juggerdash/cast_check(var/skipcharge = FALSE, var/mob/user = usr)
if(user.throwing)
return FALSE
else
return ..()
/spell/juggerdash/cast(var/list/targets, var/mob/user)
playsound(user, 'sound/effects/juggerdash.ogg', 100, 1)
var/mob/living/simple_animal/construct/armoured/perfect/jugg = user
jugg.crashing = null
var/landing = get_distant_turf(get_turf(user), jugg.dir, dash_range)
jugg.throw_at(landing, dash_range , 2)
/spell/aoe_turf/conjure/hex
name = "Conjure Hex"
desc = "Build a lesser construct to defend an area."
user_type = USER_TYPE_CULT
charge_max = 600
spell_flags = 0
invocation = "none"
invocation_type = SpI_NONE
range = 0
summon_type = list(/mob/living/simple_animal/hostile/hex)
override_base = "cult"
hud_state = "const_hex"
cast_sound = 'sound/items/welder.ogg'
/spell/aoe_turf/conjure/hex/choose_targets(mob/user = usr)
return list(get_turf(user))
/spell/aoe_turf/conjure/hex/before_channel(var/mob/user)
var/mob/living/simple_animal/construct/builder/perfect/artificer = user
if (artificer.minions.len >= 3)
to_chat(user,"<span class='warning'>You cannot sustain more than 3 lesser constructs alive.</span>")
return 1
return 0
/spell/aoe_turf/conjure/hex/on_creation(var/mob/living/simple_animal/hostile/hex/AM, var/mob/user)
AM.master = user
AM.master.minions.Add(AM)
/spell/aoe_turf/conjure/struct
name = "Conjure Structure"
desc = "Raise a cult structure that you may then operate."
user_type = USER_TYPE_CULT
charge_max = 200
spell_flags = 0
invocation = "none"
invocation_type = SpI_NONE
range = 0
summon_type = list(/obj/structure/cult/altar)
override_base = "cult"
hud_state = "const_struct"
cast_sound = 'sound/items/welder.ogg'
/spell/aoe_turf/conjure/struct/choose_targets(mob/user = usr)
return list(get_turf(user))
/spell/aoe_turf/conjure/struct/before_channel(var/mob/user)
if (locate(/obj/structure/cult) in range(user,1))
to_chat(user, "<span class='warning'>You cannot perform this ritual that close from another similar structure.</span>")
return 1
var/turf/T = user.loc
if (!istype(T))
return 1
var/list/choices = list(
list("Altar", "radial_altar", "Allows for crafting soul gems, and performing various other cult rituals."),
list("Spire", "radial_spire", "Lets human cultists acquire Arcane Tattoos."),
list("Forge", "radial_forge", "Enables the forging of cult blades and armor, as well as new construct shells. Raise the temperature of nearby creatures."),
)
var/structure = show_radial_menu(user,T,choices,'icons/obj/cult_radial3.dmi',"radial-cult")
if (!T.Adjacent(user) || !structure )
return 1
switch(structure)
if("Altar")
summon_type = list(/obj/structure/cult/altar)
if("Spire")
summon_type = list(/obj/structure/cult/spire)
if("Forge")
summon_type = list(/obj/structure/cult/forge)
return 0

View File

@@ -40,6 +40,8 @@
density = 1
invisibility = 100
var/explosion_block = 20 //making this spell marginally more useful
/obj/effect/forcefield/bullet_act(var/obj/item/projectile/Proj, var/def_zone)
var/turf/T = get_turf(src.loc)
if(T)

View File

@@ -37,7 +37,7 @@
return
target.unlock_from()
//Begin jaunting with an animation
anim(location = mobloc, target = target, a_icon = 'icons/mob/mob.dmi', flick_anim = enteranim, direction = target.dir, name = "water")
anim(location = mobloc, a_icon = 'icons/mob/mob.dmi', flick_anim = enteranim, direction = target.dir, name = target.name,lay = target.layer+1,plane = target.plane)
if(mist)
target.ExtinguishMob()
var/datum/effect/effect/system/steam_spread/steam = new /datum/effect/effect/system/steam_spread()
@@ -69,7 +69,7 @@
target.delayNextMove(25)
target.dir = SOUTH
sleep(20)
anim(location = mobloc, target = target, a_icon = 'icons/mob/mob.dmi', flick_anim = exitanim, direction = target.dir, name = "water")
anim(location = mobloc, a_icon = 'icons/mob/mob.dmi', flick_anim = exitanim, direction = target.dir, name = target.name,lay = target.layer+1,plane = target.plane)
sleep(5)
//Forcemove him onto the tile and make him visible and vulnerable
@@ -139,6 +139,14 @@
exitanim = "phase_shift2"
mist = 0
/spell/targeted/ethereal_jaunt/shift/alt
desc = "Vibrate through the veil for about 5 seconds, letting you move around freely through any obstacle."
charge_max = 170
hud_state = "const_phase"
enteranim = "wraith2_phaseenter"
exitanim = "wraith2_phaseexit"
override_base = "cult"
/spell/targeted/ethereal_jaunt/vamp
name = "Mist Form"
desc = "This spell allows you to pass through walls and other dense objects."

View File

@@ -46,8 +46,10 @@
/* Radial Tooltips */
.radial-default .wrap {border-color: #2B2B33;}
.radial-default .content {color: #6087A0; border-color: #2B2B33; background-color: #36363C;}
.radial-cult .wrap {border-color: #2f0000;}
.radial-cult .content {font-family: 'Comic Sans MS'; color: #940000 ; border-color: #000000; background-color:#221817;}
.radial-cult .wrap {border-color: #000000;}
.radial-cult .content {font-family: 'Courier New'; color: #ffec66 ; border-color: #FF0000; background-color:#180404;}
.radial-cult2 .wrap {border-color: #2f0000;}
.radial-cult2 .content {font-family: 'Courier New'; color: #940000 ; border-color: #000000; background-color:#221817;}
/* TG: Themes */
/* ScreenUI */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 573 KiB

After

Width:  |  Height:  |  Size: 567 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 500 KiB

After

Width:  |  Height:  |  Size: 506 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 KiB

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 753 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
icons/obj/cult_radial3.dmi Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.