mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 18:22:39 +00:00
Makes Technomancer use modifiers, fixes a few bugs
This commit is contained in:
@@ -191,6 +191,7 @@
|
||||
icon_state = "scepter"
|
||||
force = 15
|
||||
slot_flags = SLOT_BELT
|
||||
attack_verb = list("beaten", "smashed", "struck", "whacked")
|
||||
|
||||
/obj/item/weapon/scepter/attack_self(mob/living/carbon/human/user)
|
||||
var/obj/item/item_to_test = user.get_other_hand(src)
|
||||
|
||||
@@ -285,4 +285,4 @@
|
||||
to_chat(H, "<span class='warning'>The purple glow makes you feel strange...</span>")
|
||||
H.adjust_instability(outgoing_instability)
|
||||
|
||||
set_light(distance, distance * 2, l_color = "#C26DDE")
|
||||
set_light(distance, distance * 4, l_color = "#C26DDE")
|
||||
|
||||
@@ -21,5 +21,6 @@
|
||||
for(var/obj/item/weapon/inserted_spell/I in target)
|
||||
I.on_expire(dispelled = 1)
|
||||
log_and_message_admins("dispelled [I] on [target].")
|
||||
target.remove_modifiers_of_type(/datum/modifier/technomancer)
|
||||
user.adjust_instability(10)
|
||||
qdel(src)
|
||||
@@ -93,6 +93,9 @@
|
||||
var/walking = 0
|
||||
var/step_delay = 10
|
||||
|
||||
/mob/living/simple_animal/illusion/update_icon() // We don't want the appearance changing AT ALL unless by copy_appearance().
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/illusion/proc/copy_appearance(var/atom/movable/thing_to_copy)
|
||||
if(!thing_to_copy)
|
||||
return 0
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/datum/technomancer/spell/corona
|
||||
name = "Corona"
|
||||
desc = "Causes the victim to glow very brightly, which while harmless in itself, makes it easier for them to be hit. The \
|
||||
bright glow also makes it very difficult to be stealthy. The effect lasts for one minute."
|
||||
spell_power_desc = "Enemies become even easier to hit."
|
||||
cost = 50
|
||||
obj_path = /obj/item/weapon/spell/insert/corona
|
||||
ability_icon_state = "tech_corona"
|
||||
category = SUPPORT_SPELLS
|
||||
|
||||
/obj/item/weapon/spell/insert/corona
|
||||
name = "corona"
|
||||
desc = "How brillient!"
|
||||
icon_state = "radiance"
|
||||
cast_methods = CAST_RANGED
|
||||
aspect = ASPECT_LIGHT
|
||||
light_color = "#D9D900"
|
||||
spell_light_intensity = 5
|
||||
spell_light_range = 3
|
||||
inserting = /obj/item/weapon/inserted_spell/corona
|
||||
|
||||
|
||||
/obj/item/weapon/inserted_spell/corona
|
||||
var/evasion_reduction = 2 // We store this here because spell power may change when the spell expires.
|
||||
|
||||
/obj/item/weapon/inserted_spell/corona/on_insert()
|
||||
spawn(1)
|
||||
if(isliving(host))
|
||||
var/mob/living/L = host
|
||||
evasion_reduction = round(2 * spell_power_at_creation, 1)
|
||||
L.evasion -= evasion_reduction
|
||||
L.visible_message("<span class='warning'>You start to glow very brightly!</span>")
|
||||
spawn(1 MINUTE)
|
||||
if(src)
|
||||
on_expire()
|
||||
|
||||
/obj/item/weapon/inserted_spell/corona/on_expire()
|
||||
if(isliving(host))
|
||||
var/mob/living/L = host
|
||||
L.evasion += evasion_reduction
|
||||
L << "<span class='notice'>Your glow has ended.</span>"
|
||||
..()
|
||||
@@ -1,36 +0,0 @@
|
||||
/datum/technomancer/spell/haste
|
||||
name = "Haste"
|
||||
desc = "Allows the target to run at speeds that should not be possible for an ordinary being. For five seconds, the target \
|
||||
runs extremly fast, and cannot be slowed by any means."
|
||||
spell_power_desc = "Duration is scaled up."
|
||||
cost = 100
|
||||
obj_path = /obj/item/weapon/spell/insert/haste
|
||||
ability_icon_state = "tech_haste"
|
||||
category = SUPPORT_SPELLS
|
||||
|
||||
/obj/item/weapon/spell/insert/haste
|
||||
name = "haste"
|
||||
desc = "Now you can outrun a Teshari!"
|
||||
icon_state = "haste"
|
||||
cast_methods = CAST_RANGED
|
||||
aspect = ASPECT_FORCE
|
||||
light_color = "#FF5C5C"
|
||||
inserting = /obj/item/weapon/inserted_spell/haste
|
||||
|
||||
/obj/item/weapon/inserted_spell/haste/on_insert()
|
||||
spawn(1)
|
||||
if(isliving(host))
|
||||
var/mob/living/L = host
|
||||
L.force_max_speed = 1
|
||||
L << "<span class='notice'>You suddenly find it much easier to move.</span>"
|
||||
L.adjust_instability(10)
|
||||
spawn(round(5 SECONDS * spell_power_at_creation, 1))
|
||||
if(src)
|
||||
on_expire()
|
||||
|
||||
/obj/item/weapon/inserted_spell/haste/on_expire()
|
||||
if(isliving(host))
|
||||
var/mob/living/L = host
|
||||
L.force_max_speed = 0
|
||||
L << "<span class='warning'>You feel slow again.</span>"
|
||||
..()
|
||||
@@ -1,39 +0,0 @@
|
||||
/datum/technomancer/spell/repel_missiles
|
||||
name = "Repel Missiles"
|
||||
desc = "Places a repulsion field around you, which attempts to deflect incoming bullets and lasers, making them 30% less likely \
|
||||
to hit you. The field lasts for five minutes and can be granted to yourself or an ally."
|
||||
spell_power_desc = "Projectiles will be more likely to be deflected."
|
||||
cost = 25
|
||||
obj_path = /obj/item/weapon/spell/insert/repel_missiles
|
||||
ability_icon_state = "tech_repelmissiles"
|
||||
category = SUPPORT_SPELLS
|
||||
|
||||
/obj/item/weapon/spell/insert/repel_missiles
|
||||
name = "repel missiles"
|
||||
desc = "Use it before they start shooting at you!"
|
||||
icon_state = "generic"
|
||||
cast_methods = CAST_RANGED
|
||||
aspect = ASPECT_FORCE
|
||||
light_color = "#FF5C5C"
|
||||
inserting = /obj/item/weapon/inserted_spell/repel_missiles
|
||||
|
||||
/obj/item/weapon/inserted_spell/repel_missiles
|
||||
var/evasion_increased = 2 // We store this here because spell power may change when the spell expires.
|
||||
|
||||
/obj/item/weapon/inserted_spell/repel_missiles/on_insert()
|
||||
spawn(1)
|
||||
if(isliving(host))
|
||||
var/mob/living/L = host
|
||||
evasion_increased = round(2 * spell_power_at_creation, 1)
|
||||
L.evasion += evasion_increased
|
||||
L << "<span class='notice'>You have a repulsion field around you, which will attempt to deflect projectiles.</span>"
|
||||
spawn(5 MINUTES)
|
||||
if(src)
|
||||
on_expire()
|
||||
|
||||
/obj/item/weapon/inserted_spell/repel_missiles/on_expire()
|
||||
if(isliving(host))
|
||||
var/mob/living/L = host
|
||||
L.evasion -= evasion_increased
|
||||
L << "<span class='warning'>Your repulsion field has expired.</span>"
|
||||
..()
|
||||
33
code/game/gamemodes/technomancer/spells/modifier/corona.dm
Normal file
33
code/game/gamemodes/technomancer/spells/modifier/corona.dm
Normal file
@@ -0,0 +1,33 @@
|
||||
/datum/technomancer/spell/corona
|
||||
name = "Corona"
|
||||
desc = "Causes the victim to glow very brightly, which while harmless in itself, makes it easier for them to be hit. The \
|
||||
bright glow also makes it very difficult to be stealthy. The effect lasts for one minute."
|
||||
cost = 50
|
||||
obj_path = /obj/item/weapon/spell/modifier/corona
|
||||
ability_icon_state = "tech_corona"
|
||||
category = SUPPORT_SPELLS
|
||||
|
||||
/obj/item/weapon/spell/modifier/corona
|
||||
name = "corona"
|
||||
desc = "How brillient!"
|
||||
icon_state = "radiance"
|
||||
cast_methods = CAST_RANGED
|
||||
aspect = ASPECT_LIGHT
|
||||
light_color = "#D9D900"
|
||||
spell_light_intensity = 5
|
||||
spell_light_range = 3
|
||||
modifier_type = /datum/modifier/technomancer/corona
|
||||
modifier_duration = 1 MINUTE
|
||||
|
||||
/datum/modifier/technomancer/corona
|
||||
name = "corona"
|
||||
desc = "You appear to be glowing really bright. It doesn't seem to hurt, however hiding will be impossible."
|
||||
mob_overlay_state = "corona"
|
||||
|
||||
on_created_text = "<span class='warning'>You start to glow very brightly!</span>"
|
||||
on_expired_text = "<span class='notice'>Your glow has ended.</span>"
|
||||
evasion = -2
|
||||
stacks = MODIFIER_STACK_EXTEND
|
||||
|
||||
/datum/modifier/technomancer/corona/tick()
|
||||
holder.break_cloak()
|
||||
28
code/game/gamemodes/technomancer/spells/modifier/haste.dm
Normal file
28
code/game/gamemodes/technomancer/spells/modifier/haste.dm
Normal file
@@ -0,0 +1,28 @@
|
||||
/datum/technomancer/spell/haste
|
||||
name = "Haste"
|
||||
desc = "Allows the target to run at speeds that should not be possible for an ordinary being. For five seconds, the target \
|
||||
runs extremly fast, and cannot be slowed by any means."
|
||||
cost = 100
|
||||
obj_path = /obj/item/weapon/spell/modifier/haste
|
||||
ability_icon_state = "tech_haste"
|
||||
category = SUPPORT_SPELLS
|
||||
|
||||
/obj/item/weapon/spell/modifier/haste
|
||||
name = "haste"
|
||||
desc = "Now you can outrun a Teshari!"
|
||||
icon_state = "haste"
|
||||
cast_methods = CAST_RANGED
|
||||
aspect = ASPECT_FORCE
|
||||
light_color = "#FF5C5C"
|
||||
modifier_type = /datum/modifier/technomancer/haste
|
||||
modifier_duration = 5 SECONDS
|
||||
|
||||
/datum/modifier/technomancer/haste
|
||||
name = "haste"
|
||||
desc = "Moving is almost effortless!"
|
||||
mob_overlay_state = "haste"
|
||||
|
||||
on_created_text = "<span class='notice'>You suddenly find it much easier to move.</span>"
|
||||
on_expired_text = "<span class='warning'>You feel slow again.</span>"
|
||||
haste = TRUE
|
||||
stacks = MODIFIER_STACK_EXTEND
|
||||
31
code/game/gamemodes/technomancer/spells/modifier/modifier.dm
Normal file
31
code/game/gamemodes/technomancer/spells/modifier/modifier.dm
Normal file
@@ -0,0 +1,31 @@
|
||||
/obj/item/weapon/spell/modifier
|
||||
name = "modifier template"
|
||||
desc = "Tell a coder if you can read this in-game."
|
||||
icon_state = "purify"
|
||||
cast_methods = CAST_MELEE
|
||||
var/modifier_type = null
|
||||
var/modifier_duration = null // Will last forever by default. Final duration may differ due to 'spell power'
|
||||
// var/spell_color = "#03A728"
|
||||
var/spell_light_intensity = 2
|
||||
var/spell_light_range = 3
|
||||
|
||||
/obj/item/weapon/spell/modifier/New()
|
||||
..()
|
||||
set_light(spell_light_range, spell_light_intensity, l_color = light_color)
|
||||
|
||||
/obj/item/weapon/spell/modifier/on_melee_cast(atom/hit_atom, mob/user)
|
||||
if(istype(hit_atom, /mob/living))
|
||||
on_add_modifier(hit_atom)
|
||||
|
||||
/obj/item/weapon/spell/modifier/on_ranged_cast(atom/hit_atom, mob/user)
|
||||
if(istype(hit_atom, /mob/living))
|
||||
on_add_modifier(hit_atom)
|
||||
|
||||
|
||||
/obj/item/weapon/spell/modifier/proc/on_add_modifier(var/mob/living/L)
|
||||
var/duration = modifier_duration
|
||||
if(duration)
|
||||
duration = round(duration * calculate_spell_power(1.0), 1)
|
||||
L.add_modifier(modifier_type, duration)
|
||||
log_and_message_admins("has casted [src] on [L].")
|
||||
qdel(src)
|
||||
@@ -0,0 +1,28 @@
|
||||
/datum/technomancer/spell/repel_missiles
|
||||
name = "Repel Missiles"
|
||||
desc = "Places a repulsion field around you, which attempts to deflect incoming bullets and lasers, making them 30% less likely \
|
||||
to hit you. The field lasts for 10 minutes and can be granted to yourself or an ally."
|
||||
cost = 25
|
||||
obj_path = /obj/item/weapon/spell/modifier/repel_missiles
|
||||
ability_icon_state = "tech_repelmissiles"
|
||||
category = SUPPORT_SPELLS
|
||||
|
||||
/obj/item/weapon/spell/modifier/repel_missiles
|
||||
name = "repel missiles"
|
||||
desc = "Use it before they start shooting at you!"
|
||||
icon_state = "generic"
|
||||
cast_methods = CAST_RANGED
|
||||
aspect = ASPECT_FORCE
|
||||
light_color = "#FF5C5C"
|
||||
modifier_type = /datum/modifier/technomancer/repel_missiles
|
||||
modifier_duration = 10 MINUTES
|
||||
|
||||
/datum/modifier/technomancer/repel_missiles
|
||||
name = "repel_missiles"
|
||||
desc = "A repulsion field can always be useful to have."
|
||||
mob_overlay_state = "repel_missiles"
|
||||
|
||||
on_created_text = "<span class='notice'>You have a repulsion field around you, which will attempt to deflect projectiles.</span>"
|
||||
on_expired_text = "<span class='warning'>Your repulsion field has expired.</span>"
|
||||
evasion = 3
|
||||
stacks = MODIFIER_STACK_EXTEND
|
||||
@@ -20,10 +20,10 @@
|
||||
|
||||
/obj/item/weapon/spell/spawner/darkness/New()
|
||||
..()
|
||||
set_light(6, -5, l_color = "#FFFFFF")
|
||||
set_light(6, -20, l_color = "#FFFFFF")
|
||||
|
||||
/obj/effect/temporary_effect/darkness
|
||||
name = "darkness"
|
||||
time_to_die = 2 MINUTES
|
||||
new_light_range = 6
|
||||
new_light_power = -5
|
||||
new_light_power = -20
|
||||
@@ -13,9 +13,11 @@
|
||||
handle_embedded_objects() //Moving with objects stuck in you can cause bad times.
|
||||
|
||||
if(force_max_speed)
|
||||
return -3 // Returning -1 will actually result in a slowdown for Teshari.
|
||||
return -3
|
||||
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(!isnull(M.haste) && M.haste == TRUE)
|
||||
return -3 // Returning -1 will actually result in a slowdown for Teshari.
|
||||
if(!isnull(M.slowdown))
|
||||
tally += M.slowdown
|
||||
|
||||
|
||||
@@ -131,10 +131,11 @@ Please contact me on #coderbus IRC. ~Carn x
|
||||
#define LEGCUFF_LAYER 23
|
||||
#define L_HAND_LAYER 24
|
||||
#define R_HAND_LAYER 25
|
||||
#define FIRE_LAYER 26 //If you're on fire
|
||||
#define WATER_LAYER 27 //If you're submerged in water.
|
||||
#define TARGETED_LAYER 28 //BS12: Layer for the target overlay from weapon targeting system
|
||||
#define TOTAL_LAYERS 29
|
||||
#define MODIFIER_EFFECTS_LAYER 26
|
||||
#define FIRE_LAYER 27 //If you're on fire
|
||||
#define WATER_LAYER 28 //If you're submerged in water.
|
||||
#define TARGETED_LAYER 29 //BS12: Layer for the target overlay from weapon targeting system
|
||||
#define TOTAL_LAYERS 30
|
||||
//////////////////////////////////
|
||||
|
||||
/mob/living/carbon/human
|
||||
@@ -1118,6 +1119,18 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/update_modifier_visuals(var/update_icons=1)
|
||||
overlays_standing[MODIFIER_EFFECTS_LAYER] = null
|
||||
var/image/effects = new()
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(M.mob_overlay_state)
|
||||
var/image/I = image("icon" = 'icons/mob/modifier_effects.dmi', "icon_state" = M.mob_overlay_state)
|
||||
effects.overlays += I
|
||||
|
||||
overlays_standing[MODIFIER_EFFECTS_LAYER] = effects
|
||||
|
||||
if(update_icons)
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/human/update_fire(var/update_icons=1)
|
||||
overlays_standing[FIRE_LAYER] = null
|
||||
|
||||
@@ -958,6 +958,11 @@ default behaviour is:
|
||||
update_icons()
|
||||
return canmove
|
||||
|
||||
// Adds overlays for specific modifiers.
|
||||
// You'll have to add your own implementation for non-humans currently, just override this proc.
|
||||
/mob/living/proc/update_modifier_visuals()
|
||||
return
|
||||
|
||||
/mob/living/proc/update_water() // Involves overlays for humans. Maybe we'll get submerged sprites for borgs in the future?
|
||||
return
|
||||
|
||||
|
||||
@@ -439,3 +439,11 @@
|
||||
hud_used.hide_actions_toggle.screen_loc = hud_used.ButtonNumberToScreenCoords(button_number+1)
|
||||
//hud_used.SetButtonCoords(hud_used.hide_actions_toggle,button_number+1)
|
||||
client.screen += hud_used.hide_actions_toggle
|
||||
|
||||
// Returns a number to determine if something is harder or easier to hit than normal.
|
||||
/mob/living/proc/get_evasion()
|
||||
var/result = evasion // First we get the 'base' evasion. Generally this is zero.
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(!isnull(M.evasion))
|
||||
result += M.evasion
|
||||
return result
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
var/stacks = MODIFIER_STACK_FORBID // If true, attempts to add a second instance of this type will refresh expire_at instead.
|
||||
var/flags = 0 // Flags for the modifier, see mobs.dm defines for more details.
|
||||
|
||||
var/light_color = null // If set, the mob possessing the modifier will glow in this color. Not implemented yet.
|
||||
var/light_range = null // How far the light for the above var goes. Not implemented yet.
|
||||
var/light_intensity = null // Ditto. Not implemented yet.
|
||||
var/mob_overlay_state = null // Icon_state for an overlay to apply to a (human) mob while this exists. This is actually implemented.
|
||||
|
||||
// Now for all the different effects.
|
||||
// Percentage modifiers are expressed as a multipler. (e.g. +25% damage should be written as 1.25)
|
||||
var/max_health_flat // Adjusts max health by a flat (e.g. +20) amount. Note this is added to base health.
|
||||
@@ -29,6 +34,8 @@
|
||||
var/incoming_healing_percent // Adjusts amount of healing received.
|
||||
var/outgoing_melee_damage_percent // Adjusts melee damage inflicted by holder by a percentage. Affects attacks by melee weapons and hand-to-hand.
|
||||
var/slowdown // Negative numbers speed up, positive numbers slow down movement.
|
||||
var/haste // If set to 1, the mob will be 'hasted', which makes it ignore slowdown and go really fast.
|
||||
var/evasion // Positive numbers reduce the odds of being hit by 15% each. Negative numbers increase the odds.
|
||||
|
||||
/datum/modifier/New(var/new_holder)
|
||||
holder = new_holder
|
||||
@@ -44,12 +51,18 @@
|
||||
to_chat(holder, on_expired_text)
|
||||
on_expire()
|
||||
holder.modifiers.Remove(src)
|
||||
if(mob_overlay_state) // We do this after removing ourselves from the list so that the overlay won't remain.
|
||||
holder.update_modifier_visuals()
|
||||
qdel(src)
|
||||
|
||||
// Override this for special effects when it gets removed.
|
||||
/datum/modifier/proc/on_expire()
|
||||
return
|
||||
|
||||
// Called every Life() tick. Override for special behaviour.
|
||||
/datum/modifier/proc/tick()
|
||||
return
|
||||
|
||||
/mob/living
|
||||
var/list/modifiers = list() // A list of modifier datums, which can adjust certain mob numbers.
|
||||
|
||||
@@ -64,13 +77,16 @@
|
||||
// Get rid of anything we shouldn't have.
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
M.check_if_valid()
|
||||
// Remaining modifiers will now receive a tick(). This is in a second loop for safety in order to not tick() an expired modifier.
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
M.tick()
|
||||
|
||||
// Call this to add a modifier to a mob. First argument is the modifier type you want, second is how long it should last, in ticks.
|
||||
// The SECONDS/MINUTES macro is very helpful for this. E.g. M.add_modifier(/datum/modifier/example, 5 MINUTES)
|
||||
/mob/living/proc/add_modifier(var/modifier_type, var/expire_at = null)
|
||||
// First, check if the mob already has this modifier.
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(ispath(modifier_type, M.type))
|
||||
if(istype(modifier_type, M))
|
||||
switch(M.stacks)
|
||||
if(MODIFIER_STACK_FORBID)
|
||||
return // Stop here.
|
||||
@@ -89,6 +105,8 @@
|
||||
if(mod.on_created_text)
|
||||
to_chat(src, mod.on_created_text)
|
||||
modifiers.Add(mod)
|
||||
if(mod.mob_overlay_state)
|
||||
update_modifier_visuals()
|
||||
|
||||
// Removes a specific instance of modifier
|
||||
/mob/living/proc/remove_specific_modifier(var/datum/modifier/M, var/silent = FALSE)
|
||||
@@ -97,10 +115,17 @@
|
||||
// Removes all modifiers of a type
|
||||
/mob/living/proc/remove_modifiers_of_type(var/modifier_type, var/silent = FALSE)
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(ispath(modifier_type, M.type))
|
||||
if(istype(M, modifier_type))
|
||||
M.expire(silent)
|
||||
|
||||
// Removes all modifiers, useful if the mob's being deleted
|
||||
/mob/living/proc/remove_all_modifiers(var/silent = FALSE)
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
M.expire(silent)
|
||||
M.expire(silent)
|
||||
|
||||
// Checks if the mob has a modifier type.
|
||||
/mob/living/proc/has_modifier_of_type(var/modifier_type)
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(istype(M, modifier_type))
|
||||
return TRUE
|
||||
return FALSE
|
||||
@@ -173,7 +173,7 @@
|
||||
return
|
||||
|
||||
//roll to-hit
|
||||
miss_modifier = max(15*(distance-2) - round(15*accuracy) + miss_modifier + round(15*target_mob.evasion), 0)
|
||||
miss_modifier = max(15*(distance-2) - round(15*accuracy) + miss_modifier + round(15*target_mob.get_evasion()), 0)
|
||||
var/hit_zone = get_zone_with_miss_chance(def_zone, target_mob, miss_modifier, ranged_attack=(distance > 1 || original != target_mob)) //if the projectile hits a target we weren't originally aiming at then retain the chance to miss
|
||||
|
||||
var/result = PROJECTILE_FORCE_MISS
|
||||
|
||||
Reference in New Issue
Block a user