merge conflict and job/dept discounts support.

This commit is contained in:
Ghommie
2020-05-03 02:11:05 +02:00
308 changed files with 6846 additions and 9140 deletions
@@ -392,6 +392,8 @@
character.update_parallax_teleport()
job.standard_assign_skills(character.mind)
SSticker.minds += character.mind
var/mob/living/carbon/human/humanc
@@ -23,11 +23,7 @@
if(!pref_species)
var/rando_race = pick(GLOB.roundstart_races)
pref_species = new rando_race()
features = random_features(pref_species?.id)
if(gender == MALE || gender != FEMALE)
features["body_model"] = gender
else if(gender == PLURAL)
features["body_model"] = pick(MALE,FEMALE)
features = random_features(pref_species?.id, gender)
age = rand(AGE_MIN,AGE_MAX)
/datum/preferences/proc/update_preview_icon(equip_job = TRUE)
@@ -937,3 +937,20 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
spawners_menu = new(src)
spawners_menu.ui_interact(src)
/mob/dead/observer/verb/game_info()
set name = "Game info"
set desc = "Shows various info relating to the game mode, antagonists etc."
set category = "Ghost"
if(!started_as_observer && can_reenter_corpse)
to_chat(src, "You cannot see this info unless you are an observer or you've chosen Do Not Resuscitate!")
return
var/list/stuff = list("[SSticker.mode.name]")
stuff += "Antagonists:\n"
for(var/datum/antagonist/A in GLOB.antagonists)
if(A.owner)
stuff += "[A.owner] the [A.name]"
var/ghost_info = SSticker.mode.ghost_info()
if(ghost_info)
stuff += ghost_info
to_chat(src,stuff.Join("\n"))
+10 -16
View File
@@ -245,23 +245,17 @@
. = adjusted_amount
*/
/obj/item/organ/brain/on_life()
if(damage >= BRAIN_DAMAGE_DEATH) //rip
to_chat(owner, "<span class='userdanger'>The last spark of life in your brain fizzles out...</span>")
owner.death()
brain_death = TRUE
return
..()
/obj/item/organ/brain/on_death()
if(damage <= BRAIN_DAMAGE_DEATH) //rip
brain_death = FALSE
..()
/obj/item/organ/brain/applyOrganDamage(var/d, var/maximum = maxHealth)
..()
. = ..()
if(!. || !owner)
return
if(damage >= BRAIN_DAMAGE_DEATH) //rip
if(owner.stat != DEAD)
to_chat(owner, "<span class='userdanger'>The last spark of life in your brain fizzles out...</span>")
owner.death()
brain_death = TRUE
else
brain_death = FALSE
/obj/item/organ/brain/check_damage_thresholds(mob/M)
. = ..()
@@ -12,6 +12,13 @@
bubble_icon = "alien"
type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab/xeno
/// How much brute damage without armor piercing they do against mobs in melee
var/meleeSlashHumanPower = 20
/// How much power they have for DefaultCombatKnockdown when attacking humans
var/meleeKnockdownPower = 100
/// How much brute damage they do to simple animals
var/meleeSlashSAPower = 35
var/obj/item/card/id/wear_id = null // Fix for station bounced radios -- Skie
var/has_fine_manipulation = 0
var/move_delay_add = 0 // movement delay to add
@@ -4,6 +4,7 @@
maxHealth = 125
health = 125
icon_state = "aliend"
meleeKnockdownPower = 80
/mob/living/carbon/alien/humanoid/drone/Initialize()
AddAbility(new/obj/effect/proc_holder/alien/evolve(null))
@@ -1,9 +1,12 @@
/mob/living/carbon/alien/humanoid/hunter
name = "alien hunter"
caste = "h"
maxHealth = 125
health = 125
maxHealth = 170
health = 170
icon_state = "alienh"
meleeKnockdownPower = 75
meleeSlashHumanPower = 20
meleeSlashSAPower = 45
var/obj/screen/leap_icon = null
/mob/living/carbon/alien/humanoid/hunter/create_internal_organs()
@@ -68,6 +71,7 @@
else
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
L.DefaultCombatKnockdown(100)
L.Stagger(4 SECONDS)
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
step_towards(src,L)
@@ -1,9 +1,10 @@
/mob/living/carbon/alien/humanoid/sentinel
name = "alien sentinel"
caste = "s"
maxHealth = 150
health = 150
maxHealth = 140
health = 140
icon_state = "aliens"
meleeSlashHumanPower = 15
/mob/living/carbon/alien/humanoid/sentinel/Initialize()
AddAbility(new /obj/effect/proc_holder/alien/sneak)
@@ -112,7 +112,6 @@
return A
return FALSE
/mob/living/carbon/alien/humanoid/check_breath(datum/gas_mixture/breath)
if(breath && breath.total_moles() > 0 && !sneaking)
playsound(get_turf(src), pick('sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg'), 50, 0, -5)
@@ -1,4 +1,3 @@
/mob/living/carbon/alien/humanoid/grabbedby(mob/living/carbon/user, supress_message = 0)
if(user == src && pulling && grab_state >= GRAB_AGGRESSIVE && !pulling.anchored && iscarbon(pulling))
devour_mob(pulling, devour_time = 60)
@@ -1,5 +1,3 @@
/mob/living/carbon/alien/humanoid/proc/adjust_body_temperature(current, loc_temp, boost)
var/temperature = current
var/difference = abs(current-loc_temp) //get difference
@@ -11,6 +11,10 @@
pressure_resistance = 200 //Because big, stompy xenos should not be blown around like paper.
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/xeno = 20, /obj/item/stack/sheet/animalhide/xeno = 3)
meleeKnockdownPower = 125
meleeSlashHumanPower = 30
meleeSlashSAPower = 60
var/alt_inhands_file = 'icons/mob/alienqueen.dmi'
/mob/living/carbon/alien/humanoid/royal/can_inject(mob/user, error_msg, target_zone, penetrate_thick = FALSE, bypass_immunity = FALSE)
@@ -6,6 +6,7 @@
mob_size = MOB_SIZE_SMALL
density = FALSE
hud_type = /datum/hud/larva
mouse_opacity = MOUSE_OPACITY_OPAQUE
maxHealth = 25
health = 25
@@ -77,6 +77,9 @@
alien_powers = list(/obj/effect/proc_holder/alien/transfer)
/obj/item/organ/alien/plasmavessel/on_life()
. = ..()
if(!.)
return
//If there are alien weeds on the ground then heal if needed or give some plasma
if(locate(/obj/structure/alien/weeds) in owner.loc)
if(owner.health >= owner.maxHealth)
@@ -23,6 +23,8 @@
/obj/item/organ/body_egg/alien_embryo/on_life()
. = ..()
if(!owner)
return
switch(stage)
if(2, 3)
if(prob(2))
+3 -2
View File
@@ -7,6 +7,7 @@
update_body_parts() //to update the carbon's new bodyparts appearance
GLOB.carbon_list += src
blood_volume = (BLOOD_VOLUME_NORMAL * blood_ratio)
add_movespeed_modifier(/datum/movespeed_modifier/carbon_crawling)
/mob/living/carbon/Destroy()
//This must be done first, so the mob ghosts correctly before DNA etc is nulled
@@ -574,9 +575,9 @@
become_husk("burn")
med_hud_set_health()
if(stat == SOFT_CRIT)
add_movespeed_modifier(MOVESPEED_ID_CARBON_SOFTCRIT, TRUE, multiplicative_slowdown = SOFTCRIT_ADD_SLOWDOWN)
add_movespeed_modifier(/datum/movespeed_modifier/carbon_softcrit)
else
remove_movespeed_modifier(MOVESPEED_ID_CARBON_SOFTCRIT, TRUE)
remove_movespeed_modifier(/datum/movespeed_modifier/carbon_softcrit)
/mob/living/carbon/update_stamina()
var/stam = getStaminaLoss()
@@ -38,7 +38,7 @@
adjustCloneLoss(damage_amount, forced = forced)
if(STAMINA)
if(BP)
if(damage > 0 ? BP.receive_damage(0, 0, damage_amount) : BP.heal_damage(0, 0, abs(damage_amount)))
if(damage > 0 ? BP.receive_damage(0, 0, damage_amount) : BP.heal_damage(0, 0, abs(damage_amount), FALSE, FALSE))
update_damage_overlays()
else
adjustStaminaLoss(damage_amount, forced = forced)
@@ -1041,7 +1041,7 @@
return FALSE
/mob/living/carbon/human/proc/clear_shove_slowdown()
remove_movespeed_modifier(MOVESPEED_ID_SHOVE)
remove_movespeed_modifier(/datum/movespeed_modifier/shove)
var/active_item = get_active_held_item()
if(is_type_in_typecache(active_item, GLOB.shove_disarming_types))
visible_message("<span class='warning'>[src.name] regains their grip on \the [active_item]!</span>", "<span class='warning'>You regain your grip on \the [active_item]</span>", null, COMBAT_MESSAGE_RANGE)
@@ -1050,17 +1050,17 @@
. = ..()
if(HAS_TRAIT(src, TRAIT_IGNORESLOWDOWN))
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN)
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING)
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown)
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
return
var/stambufferinfluence = (bufferedstam*(100/stambuffer))*0.2 //CIT CHANGE - makes stamina buffer influence movedelay
var/health_deficiency = ((100 + stambufferinfluence) - health + (getStaminaLoss()*0.75))//CIT CHANGE - reduces the impact of staminaloss and makes stamina buffer influence it
if(health_deficiency >= 40)
add_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN, override = TRUE, multiplicative_slowdown = ((health_deficiency-39) / 75), blacklisted_movetypes = FLOATING|FLYING)
add_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING, override = TRUE, multiplicative_slowdown = ((health_deficiency-39) / 25), movetypes = FLYING, blacklisted_movetypes = FLOATING)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown, TRUE, (health_deficiency-39) / 75)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying, TRUE, (health_deficiency-39) / 25)
else
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN)
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING)
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown)
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
/mob/living/carbon/human/do_after_coefficent()
. = ..()
@@ -155,7 +155,7 @@
if(M.a_intent == INTENT_HARM)
if (w_uniform)
w_uniform.add_fingerprint(M)
var/damage = prob(90) ? 20 : 0
var/damage = prob(90) ? M.meleeSlashHumanPower : 0
if(!damage)
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has lunged at [src]!</span>", \
@@ -182,10 +182,7 @@
"<span class='userdanger'>[M] disarmed [src]!</span>")
else
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
if(!lying) //CITADEL EDIT
DefaultCombatKnockdown(100, TRUE, FALSE, 30, 25)
else
DefaultCombatKnockdown(100)
DefaultCombatKnockdown(M.meleeKnockdownPower)
log_combat(M, src, "tackled")
visible_message("<span class='danger'>[M] has tackled down [src]!</span>", \
"<span class='userdanger'>[M] has tackled down [src]!</span>")
@@ -1,11 +1,13 @@
/mob/living/carbon/human/get_movespeed_modifiers()
var/list/considering = ..()
. = considering
if(HAS_TRAIT(src, TRAIT_IGNORESLOWDOWN))
for(var/id in .)
var/list/data = .[id]
if(data[MOVESPEED_DATA_INDEX_FLAGS] & IGNORE_NOSLOW)
.[id] = data
. = list()
for(var/id in considering)
var/datum/movespeed_modifier/M = considering[id]
if(M.flags & IGNORE_NOSLOW || M.multiplicative_slowdown < 0)
.[id] = M
return
return considering
/mob/living/carbon/human/movement_delay()
. = ..()
+16 -16
View File
@@ -331,7 +331,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(mutant_bodyparts["meat_type"]) //I can't believe it's come to the meat
H.type_of_meat = GLOB.meat_types[H.dna.features["meat_type"]]
C.add_movespeed_modifier(MOVESPEED_ID_SPECIES, TRUE, 100, override=TRUE, multiplicative_slowdown=speedmod, movetypes=(~FLYING))
C.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/species, TRUE, multiplicative_slowdown = speedmod)
SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species)
@@ -349,7 +349,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
for(var/X in inherent_traits)
REMOVE_TRAIT(C, X, SPECIES_TRAIT)
C.remove_movespeed_modifier(MOVESPEED_ID_SPECIES)
C.remove_movespeed_modifier(/datum/movespeed_modifier/species)
if(mutant_bodyparts["meat_type"])
C.type_of_meat = GLOB.meat_types[C.dna.features["meat_type"]]
@@ -1299,14 +1299,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(H.overeatduration < 100)
to_chat(H, "<span class='notice'>You feel fit again!</span>")
REMOVE_TRAIT(H, TRAIT_FAT, OBESITY)
H.remove_movespeed_modifier(MOVESPEED_ID_FAT)
H.remove_movespeed_modifier(/datum/movespeed_modifier/obesity)
H.update_inv_w_uniform()
H.update_inv_wear_suit()
else
if(H.overeatduration >= 100)
to_chat(H, "<span class='danger'>You suddenly feel blubbery!</span>")
ADD_TRAIT(H, TRAIT_FAT, OBESITY)
H.add_movespeed_modifier(MOVESPEED_ID_FAT, multiplicative_slowdown = 1.5)
H.add_movespeed_modifier(/datum/movespeed_modifier/obesity)
H.update_inv_w_uniform()
H.update_inv_wear_suit()
@@ -1362,9 +1362,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(!HAS_TRAIT(H, TRAIT_NOHUNGER))
var/hungry = (500 - H.nutrition) / 5 //So overeat would be 100 and default level would be 80
if(hungry >= 70)
H.add_movespeed_modifier(MOVESPEED_ID_HUNGRY, override = TRUE, multiplicative_slowdown = (hungry / 50))
H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/hunger, multiplicative_slowdown = (hungry / 50))
else
H.remove_movespeed_modifier(MOVESPEED_ID_HUNGRY)
H.remove_movespeed_modifier(/datum/movespeed_modifier/hunger)
switch(H.nutrition)
if(NUTRITION_LEVEL_FULL to INFINITY)
@@ -1615,7 +1615,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
"You hear a slap."
)
return FALSE
else
user.do_attack_animation(target, ATTACK_EFFECT_DISARM)
@@ -1623,10 +1623,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
user.adjustStaminaLossBuffered(1)
else
user.adjustStaminaLossBuffered(3)
if(attacker_style && attacker_style.disarm_act(user,target))
return TRUE
if(target.w_uniform)
target.w_uniform.add_fingerprint(user)
//var/randomized_zone = ran_zone(user.zone_selected) CIT CHANGE - comments out to prevent compiling errors
@@ -1659,7 +1659,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
randn -= 25 //if you are a pugilist, you're slapping that item from them pretty reliably
if(HAS_TRAIT(target, TRAIT_PUGILIST))
randn += 25 //meanwhile, pugilists are less likely to get disarmed
if(randn <= 35)//CIT CHANGE - changes this back to a 35% chance to accomodate for the above being commented out in favor of right-click pushing
var/obj/item/I = null
if(target.pulling)
@@ -1932,8 +1932,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/obj/item/target_held_item = target.get_active_held_item()
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
target_held_item = null
if(!target.has_movespeed_modifier(MOVESPEED_ID_SHOVE))
target.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH)
if(!target.has_movespeed_modifier(/datum/movespeed_modifier/shove))
target.add_movespeed_modifier(/datum/movespeed_modifier/shove)
if(target_held_item)
if(!HAS_TRAIT(target_held_item, TRAIT_NODROP))
target.visible_message("<span class='danger'>[target.name]'s grip on \the [target_held_item] loosens!</span>",
@@ -2084,7 +2084,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "cold")
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "hot", /datum/mood_event/hot)
H.remove_movespeed_modifier(MOVESPEED_ID_COLD)
H.remove_movespeed_modifier(/datum/movespeed_modifier/cold)
var/burn_damage
var/firemodifier = H.fire_stacks / 50
@@ -2101,8 +2101,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
else if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTCOLD))
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot")
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "cold", /datum/mood_event/cold)
//Sorry for the nasty oneline but I don't want to assign a variable on something run pretty frequently
H.add_movespeed_modifier(MOVESPEED_ID_COLD, override = TRUE, multiplicative_slowdown = ((BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR), blacklisted_movetypes = FLOATING)
//Apply cold slowdown
H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/cold, multiplicative_slowdown = ((BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR))
switch(H.bodytemperature)
if(200 to BODYTEMP_COLD_DAMAGE_LIMIT)
H.apply_damage(COLD_DAMAGE_LEVEL_1*coldmod*H.physiology.cold_mod, BURN)
@@ -2112,7 +2112,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
H.apply_damage(COLD_DAMAGE_LEVEL_3*coldmod*H.physiology.cold_mod, BURN)
else
H.remove_movespeed_modifier(MOVESPEED_ID_COLD)
H.remove_movespeed_modifier(/datum/movespeed_modifier/cold)
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "cold")
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot")
@@ -101,12 +101,11 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
/obj/item/organ/dwarfgland/on_life() //Primary loop to hook into to start delayed loops for other loops..
. = ..()
dwarf_cycle_ticker()
if(owner && owner.stat != DEAD)
dwarf_cycle_ticker()
//Handles the delayed tick cycle by just adding on increments per each on_life() tick
/obj/item/organ/dwarfgland/proc/dwarf_cycle_ticker()
if(owner.stat == DEAD)
return //We make sure they are not dead, so they don't increment any tickers.
dwarf_eth_ticker++
dwarf_filth_ticker++
@@ -91,4 +91,9 @@
if((C.dna.features["spines"] != "None" ) && (C.dna.features["tail_lizard"] == "None")) //tbh, it's kinda ugly for them not to have a tail yet have floating spines
C.dna.features["tail_lizard"] = "Smooth"
C.update_body()
if(C.dna.features["legs"] != "digitigrade")
C.dna.features["legs"] = "digitigrade"
for(var/obj/item/bodypart/leggie in C.bodyparts)
if(leggie.body_zone == BODY_ZONE_L_LEG || leggie.body_zone == BODY_ZONE_R_LEG)
leggie.update_limb(FALSE, C)
return ..()
@@ -65,12 +65,11 @@
/mob/living/carbon/monkey/on_reagent_change()
. = ..()
remove_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE)
var/amount
if(reagents.has_reagent(/datum/reagent/medicine/morphine))
amount = -1
if(amount)
add_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/monkey_reagent_speedmod, TRUE, amount)
/mob/living/carbon/monkey/updatehealth()
. = ..()
@@ -78,7 +77,7 @@
var/health_deficiency = (100 - health)
if(health_deficiency >= 45)
slow += (health_deficiency / 25)
add_movespeed_modifier(MOVESPEED_ID_MONKEY_HEALTH_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = slow)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/monkey_health_speedmod, TRUE, slow)
/mob/living/carbon/monkey/adjust_bodytemperature(amount)
. = ..()
@@ -87,7 +86,7 @@
slow += (283.222 - bodytemperature) / 10 * 1.75
if(slow <= 0)
return
add_movespeed_modifier(MOVESPEED_ID_MONKEY_TEMPERATURE_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/monkey_temperature_speedmod, TRUE, slow)
/mob/living/carbon/monkey/Stat()
..()
@@ -99,7 +98,6 @@
if(changeling)
stat("Chemical Storage", "[changeling.chem_charges]/[changeling.chem_storage]")
stat("Absorbed DNA", changeling.absorbedcount)
return
/mob/living/carbon/monkey/verb/removeinternal()
+4 -2
View File
@@ -94,11 +94,13 @@
if(should_be_lying)
mobility_flags &= ~MOBILITY_STAND
setMovetype(movement_type | CRAWLING)
if(!lying) //force them on the ground
lying = pick(90, 270)
if(has_gravity() && !buckled)
playsound(src, "bodyfall", 20, 1)
else
setMovetype(movement_type & ~CRAWLING)
mobility_flags |= MOBILITY_STAND
lying = 0
@@ -161,8 +163,8 @@
if(!has_legs && has_arms < 2)
limbless_slowdown += 6 - (has_arms * 3)
if(limbless_slowdown)
add_movespeed_modifier(MOVESPEED_ID_LIVING_LIMBLESS, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=limbless_slowdown, blacklisted_movetypes = FLYING|FLOATING)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/limbless, multiplicative_slowdown = limbless_slowdown)
else
remove_movespeed_modifier(MOVESPEED_ID_LIVING_LIMBLESS, update=TRUE)
remove_movespeed_modifier(/datum/movespeed_modifier/limbless)
return mobility_flags
+6 -18
View File
@@ -36,38 +36,26 @@
sprint_stamina_cost = CONFIG_GET(number/movedelay/sprint_stamina_cost)
return ..()
/mob/living/movement_delay(ignorewalk = 0)
. = ..()
if(!CHECK_MOBILITY(src, MOBILITY_STAND))
. += 6
/// whether or not we can slide under another living mob. defaults to if we're not dense. CanPass should check "overriding circumstances" like buckled mobs/having PASSMOB flag, etc.
/mob/living/proc/can_move_under_living(mob/living/other)
return !density
/mob/living/proc/update_move_intent_slowdown()
var/mod = 0
if(m_intent == MOVE_INTENT_WALK)
mod = CONFIG_GET(number/movedelay/walk_delay)
else
mod = CONFIG_GET(number/movedelay/run_delay)
if(!isnum(mod))
mod = 1
add_movespeed_modifier(MOVESPEED_ID_MOB_WALK_RUN_CONFIG_SPEED, TRUE, 100, override = TRUE, multiplicative_slowdown = mod)
add_movespeed_modifier((m_intent == MOVE_INTENT_WALK)? /datum/movespeed_modifier/config_walk_run/walk : /datum/movespeed_modifier/config_walk_run/run)
/mob/living/proc/update_turf_movespeed(turf/open/T)
if(isopenturf(T) && !is_flying())
add_movespeed_modifier(MOVESPEED_ID_LIVING_TURF_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = T.slowdown)
if(isopenturf(T))
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/turf_slowdown, multiplicative_slowdown = T.slowdown)
else
remove_movespeed_modifier(MOVESPEED_ID_LIVING_TURF_SPEEDMOD)
remove_movespeed_modifier(/datum/movespeed_modifier/turf_slowdown)
/mob/living/proc/update_pull_movespeed()
if(pulling && isliving(pulling))
var/mob/living/L = pulling
if(drag_slowdown && L.lying && !L.buckled && grab_state < GRAB_AGGRESSIVE)
add_movespeed_modifier(MOVESPEED_ID_PRONE_DRAGGING, multiplicative_slowdown = PULL_PRONE_SLOWDOWN)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/bulky_drag, multiplicative_slowdown = PULL_PRONE_SLOWDOWN)
return
remove_movespeed_modifier(MOVESPEED_ID_PRONE_DRAGGING)
remove_movespeed_modifier(/datum/movespeed_modifier/bulky_drag)
/mob/living/canZMove(dir, turf/target)
return can_zTravel(target, dir) && (movement_type & FLYING)
+2 -2
View File
@@ -273,9 +273,9 @@
/mob/living/silicon/pai/Process_Spacemove(movement_dir = 0)
. = ..()
if(!.)
add_movespeed_modifier(MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD, TRUE, 100, multiplicative_slowdown = 2)
add_movespeed_modifier(/datum/movespeed_modifier/pai_spacewalk)
return TRUE
remove_movespeed_modifier(MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD, TRUE)
remove_movespeed_modifier(/datum/movespeed_modifier/pai_spacewalk)
return TRUE
/mob/living/silicon/pai/examine(mob/user)
@@ -237,7 +237,7 @@
return
if(!CONFIG_GET(flag/disable_secborg) && GLOB.security_level < CONFIG_GET(number/minimum_secborg_alert))
to_chat(src, "<span class='notice'>NOTICE: Due to local station regulations, the security cyborg module and its variants are only available during [num2seclevel(CONFIG_GET(number/minimum_secborg_alert))] alert and greater.</span>")
to_chat(src, "<span class='notice'>NOTICE: Due to local station regulations, the security cyborg module and its variants are only available during [NUM2SECLEVEL(CONFIG_GET(number/minimum_secborg_alert))] alert and greater.</span>")
var/list/modulelist = list("Standard" = /obj/item/robot_module/standard, \
"Engineering" = /obj/item/robot_module/engineering, \
@@ -1,3 +1,5 @@
/mob/living/silicon/KnockToFloor(disarm_items = FALSE, silent = TRUE, updating = TRUE)
return
/mob/living/silicon/grippedby(mob/living/user, instant = FALSE)
return //can't upgrade a simple pull into a more aggressive grab.
@@ -61,11 +61,10 @@
"<span class='userdanger'>[M] [response_disarm] [name]!</span>", null, COMBAT_MESSAGE_RANGE)
log_combat(M, src, "disarmed")
else
var/damage = rand(15, 30)
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
"<span class='userdanger'>[M] has slashed at [src]!</span>", null, COMBAT_MESSAGE_RANGE)
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
attack_threshold_check(damage)
attack_threshold_check(M.meleeSlashSAPower)
log_combat(M, src, "attacked")
/mob/living/simple_animal/attack_larva(mob/living/carbon/alien/larva/L)
@@ -19,6 +19,11 @@
path_image_color = "#993299"
weather_immunities = list("lava","ash")
var/clean_time = 50 //How long do we take to clean?
var/broom = FALSE //Do we have an speed buff from a broom?
var/adv_mop = FALSE //Do we have a cleaning buff from a better mop?
var/blood = 1
var/trash = 0
var/pests = 0
@@ -75,6 +80,26 @@
to_chat(user, "<span class='warning'>Please close the access panel before locking it.</span>")
else
to_chat(user, "<span class='notice'>\The [src] doesn't seem to respect your authority.</span>")
if(istype(W, /obj/item/mop/advanced))
if(bot_core.allowed(user) && open && adv_mop == TRUE)
to_chat(user, "<span class='notice'>You replace \the [src] old mop with a new better one!</span>")
adv_mop = TRUE
clean_time = 20 //2.5 the speed!
window_name = "Automatic Station Cleaner v2.1 BETA" //New!
qdel(W)
else
to_chat(user, "<span class='notice'>\the [src] already has this mop!</span>")
if(istype(W, /obj/item/twohanded/broom))
if(bot_core.allowed(user) && open && broom == TRUE)
to_chat(user, "<span class='notice'>You add to \the [src] a broom speeding it up!</span>")
broom = TRUE
base_speed = 1 //2x faster!
qdel(W)
else
to_chat(user, "<span class='notice'>\the [src] already has a broom!</span>")
else
return ..()
@@ -221,7 +246,7 @@
icon_state = "cleanbot-c"
visible_message("<span class='notice'>[src] begins to clean up [A].</span>")
mode = BOT_CLEANING
spawn(50)
spawn(clean_time)
if(mode == BOT_CLEANING)
if(A && isturf(A.loc))
var/atom/movable/AM = A
@@ -264,6 +264,9 @@
if((last_newpatient_speak + 300) < world.time) //Don't spam these messages!
var/list/messagevoice = list("Hey, [H.name]! Hold on, I'm coming." = 'sound/voice/medbot/coming.ogg',"Wait [H.name]! I want to help!" = 'sound/voice/medbot/help.ogg',"[H.name], you appear to be injured!" = 'sound/voice/medbot/injured.ogg')
var/message = pick(messagevoice)
if(prob(1) && ISINRANGE_EX(H.getFireLoss(), 0, 20))
message = "Notices your minor burns*OwO what's this?"
messagevoice[message] = 'sound/voice/medbot/owo.ogg'
speak(message)
playsound(loc, messagevoice[message], 50, 0)
last_newpatient_speak = world.time
@@ -7,7 +7,7 @@
icon_living = "carp"
icon_dead = "carp_dead"
icon_gib = "carp_gib"
threat = 0.2
threat = 0.1
mob_biotypes = MOB_ORGANIC|MOB_BEAST
speak_chance = 0
turns_per_move = 5
@@ -186,10 +186,10 @@
. = ..()
if(slowed_by_webs)
if(!(locate(/obj/structure/spider/stickyweb) in loc))
remove_movespeed_modifier(MOVESPEED_ID_TARANTULA_WEB)
remove_movespeed_modifier(/datum/movespeed_modifier/tarantula_web)
slowed_by_webs = FALSE
else if(locate(/obj/structure/spider/stickyweb) in loc)
add_movespeed_modifier(MOVESPEED_ID_TARANTULA_WEB, priority=100, multiplicative_slowdown=3)
add_movespeed_modifier(/datum/movespeed_modifier/tarantula_web)
slowed_by_webs = TRUE
//midwives are the queen of the spiders, can send messages to all them and web faster. That rare round where you get a queen spider and turn your 'for honor' players into 'r6siege' players will be a fun one.
@@ -1,5 +1,13 @@
/**
* Kudzu Flower Bud
*
* A flower created by flowering kudzu which spawns a venus human trap after a certain amount of time has passed.
*
* A flower created by kudzu with the flowering mutation. Spawns a venus human trap after 2 minutes under normal circumstances.
* Also spawns 4 vines going out in diagonal directions from the bud. Any living creature not aligned with plants is damaged by these vines.
* Once it grows a venus human trap, the bud itself will destroy itself.
*
*/
/obj/structure/alien/resin/flower_bud_enemy //inheriting basic attack/damage stuff from alien structures
name = "flower bud"
desc = "A large pulsating plant..."
@@ -9,9 +17,9 @@
opacity = 0
canSmoothWith = list()
smooth = SMOOTH_FALSE
/// The amount of time it takes to create a venus human trap, in deciseconds
var/growth_time = 1200
/obj/structure/alien/resin/flower_bud_enemy/Initialize()
. = ..()
var/list/anchors = list()
@@ -25,36 +33,49 @@
B.sleep_time = 10 //these shouldn't move, so let's slow down updates to 1 second (any slower and the deletion of the vines would be too slow)
addtimer(CALLBACK(src, .proc/bear_fruit), growth_time)
/**
* Spawns a venus human trap, then qdels itself.
*
* Displays a message, spawns a human venus trap, then qdels itself.
*/
/obj/structure/alien/resin/flower_bud_enemy/proc/bear_fruit()
visible_message("<span class='danger'>the plant has borne fruit!</span>")
visible_message("<span class='danger'>The plant has borne fruit!</span>")
new /mob/living/simple_animal/hostile/venus_human_trap(get_turf(src))
qdel(src)
/obj/effect/ebeam/vine
name = "thick vine"
mouse_opacity = MOUSE_OPACITY_ICON
desc = "A thick vine, painful to the touch."
/obj/effect/ebeam/vine/Crossed(atom/movable/AM)
. = ..()
if(isliving(AM))
var/mob/living/L = AM
if(!("vines" in L.faction))
if(!isvineimmune(L))
L.adjustBruteLoss(5)
to_chat(L, "<span class='alert'>You cut yourself on the thorny vines.</span>")
/**
* Venus Human Trap
*
* The result of a kudzu flower bud, these enemies use vines to drag prey close to them for attack.
*
* A carnivorious plant which uses vines to catch and ensnare prey. Spawns from kudzu flower buds.
* Each one has a maximum of four vines, which can be attached to a variety of things. Carbons are stunned when a vine is attached to them, and movable entities are pulled closer over time.
* Attempting to attach a vine to something with a vine already attached to it will pull all movable targets closer on command.
* Once the prey is in melee range, melee attacks from the venus human trap heals itself for 10% of its max health, assuming the target is alive.
* Akin to certain spiders, venus human traps can also be possessed and controlled by ghosts.
*
*/
/mob/living/simple_animal/hostile/venus_human_trap
name = "venus human trap"
desc = "Now you know how the fly feels."
icon_state = "venus_human_trap"
threat = 1
layer = SPACEVINE_MOB_LAYER
health = 50
maxHealth = 50
ranged = 1
ranged = TRUE
harm_intent_damage = 5
obj_damage = 60
melee_damage_lower = 25
@@ -63,65 +84,110 @@
attack_sound = 'sound/weapons/bladeslice.ogg'
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
unsuitable_atmos_damage = 0
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
faction = list("hostile","vines","plants")
var/list/grasping = list()
var/max_grasps = 4
var/grasp_chance = 20
var/grasp_pull_chance = 85
var/grasp_range = 4
del_on_death = 1
initial_language_holder = /datum/language_holder/venus
del_on_death = TRUE
/// A list of all the plant's vines
var/list/vines = list()
/// The maximum amount of vines a plant can have at one time
var/max_vines = 4
/// How far away a plant can attach a vine to something
var/vine_grab_distance = 5
/// Whether or not this plant is ghost possessable
var/playable_plant = FALSE //Normal plants can **not** have players.
/mob/living/simple_animal/hostile/venus_human_trap/Destroy()
for(var/L in grasping)
var/datum/beam/B = grasping[L]
if(B)
qdel(B)
grasping = null
return ..()
/mob/living/simple_animal/hostile/venus_human_trap/ghost_playable
playable_plant = TRUE //For admins that want to buss some harmless plants
/mob/living/simple_animal/hostile/venus_human_trap/handle_automated_action()
if(..())
for(var/mob/living/L in grasping)
if(L.stat == DEAD)
var/datum/beam/B = grasping[L]
if(B)
B.End()
grasping -= L
//Can attack+pull multiple times per cycle
if(L.Adjacent(src))
L.attack_animal(src)
else
if(prob(grasp_pull_chance))
setDir(get_dir(src,L) )//staaaare
step(L,get_dir(L,src)) //reel them in
L.DefaultCombatKnockdown(60) //you can't get away now~
if(grasping.len < max_grasps)
grasping:
for(var/mob/living/L in view(grasp_range, src))
if(L == src || faction_check_mob(L) || (L in grasping) || L == target)
continue
for(var/t in getline(src,L))
for(var/a in t)
var/atom/A = a
if(A.density && A != L)
continue grasping
if(prob(grasp_chance))
to_chat(L, "<span class='userdanger'>\The [src] has you entangled!</span>")
grasping[L] = Beam(L, "vine", time=INFINITY, maxdistance=5, beam_type=/obj/effect/ebeam/vine)
break //only take 1 new victim per cycle
/mob/living/simple_animal/hostile/venus_human_trap/Life()
. = ..()
pull_vines()
/mob/living/simple_animal/hostile/venus_human_trap/AttackingTarget()
. = ..()
if(isliving(target))
var/mob/living/L = target
if(L.stat != DEAD)
adjustHealth(-maxHealth * 0.1)
/mob/living/simple_animal/hostile/venus_human_trap/OpenFire(atom/the_target)
var/dist = get_dist(src,the_target)
Beam(the_target, "vine", time=dist*2, maxdistance=dist+2, beam_type=/obj/effect/ebeam/vine)
the_target.attack_animal(src)
for(var/datum/beam/B in vines)
if(B.target == the_target)
pull_vines()
ranged_cooldown = world.time + (ranged_cooldown_time * 0.5)
return
if(get_dist(src,the_target) > vine_grab_distance || vines.len == max_vines)
return
for(var/turf/T in getline(src,target))
if (T.density)
return
for(var/obj/O in T)
if(O.density)
return
var/datum/beam/newVine = Beam(the_target, "vine", time=INFINITY, maxdistance = vine_grab_distance, beam_type=/obj/effect/ebeam/vine)
RegisterSignal(newVine, COMSIG_PARENT_QDELETING, .proc/remove_vine, newVine)
vines += newVine
if(isliving(the_target))
var/mob/living/L = the_target
L.Paralyze(20)
ranged_cooldown = world.time + ranged_cooldown_time
/mob/living/simple_animal/hostile/venus_human_trap/CanAttack(atom/the_target)
/mob/living/simple_animal/hostile/venus_human_trap/Login()
. = ..()
to_chat(src, "<span class='boldwarning'>You a venus human trap! Protect the kudzu at all costs, and feast on those who oppose you!</span>")
/mob/living/simple_animal/hostile/venus_human_trap/attack_ghost(mob/user)
. = ..()
if(.)
if(the_target in grasping)
return 0
return
humanize_plant(user)
/**
* Sets a ghost to control the plant if the plant is eligible
*
* Asks the interacting ghost if they would like to control the plant.
* If they answer yes, and another ghost hasn't taken control, sets the ghost to control the plant.
* Arguments:
* * mob/user - The ghost to possibly control the plant
*/
/mob/living/simple_animal/hostile/venus_human_trap/proc/humanize_plant(mob/user)
if(key || !playable_plant || stat)
return
var/plant_ask = alert("Become a venus human trap?", "Are you reverse vegan?", "Yes", "No")
if(plant_ask == "No" || QDELETED(src))
return
if(key)
to_chat(user, "<span class='warning'>Someone else already took this plant!</span>")
return
key = user.key
log_game("[key_name(src)] took control of [name].")
/**
* Manages how the vines should affect the things they're attached to.
*
* Pulls all movable targets of the vines closer to the plant
* If the target is on the same tile as the plant, destroy the vine
* Removes any QDELETED vines from the vines list.
*/
/mob/living/simple_animal/hostile/venus_human_trap/proc/pull_vines()
for(var/datum/beam/B in vines)
if(istype(B.target, /atom/movable))
var/atom/movable/AM = B.target
if(!AM.anchored)
step(AM,get_dir(AM,src))
if(get_dist(src,B.target) == 0)
B.End()
/**
* Removes a vine from the list.
*
* Removes the vine from our list.
* Called specifically when the vine is about to be destroyed, so we don't have any null references.
* Arguments:
* * datum/beam/vine - The vine to be removed from the list.
*/
mob/living/simple_animal/hostile/venus_human_trap/proc/remove_vine(datum/beam/vine, force)
vines -= vine
@@ -292,8 +292,8 @@
/mob/living/simple_animal/proc/update_simplemob_varspeed()
if(speed == 0)
remove_movespeed_modifier(MOVESPEED_ID_SIMPLEMOB_VARSPEED, TRUE)
add_movespeed_modifier(MOVESPEED_ID_SIMPLEMOB_VARSPEED, TRUE, 100, multiplicative_slowdown = speed, override = TRUE)
remove_movespeed_modifier(/datum/movespeed_modifier/simplemob_varspeed)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/simplemob_varspeed, multiplicative_slowdown = speed)
/mob/living/simple_animal/Stat()
..()
@@ -147,25 +147,25 @@
/mob/living/simple_animal/slime/on_reagent_change()
. = ..()
remove_movespeed_modifier(MOVESPEED_ID_SLIME_REAGENTMOD, TRUE)
remove_movespeed_modifier(/datum/movespeed_modifier/slime_reagentmod)
var/amount = 0
if(reagents.has_reagent(/datum/reagent/medicine/morphine)) // morphine slows slimes down
amount = 2
if(reagents.has_reagent(/datum/reagent/consumable/frostoil)) // Frostoil also makes them move VEEERRYYYYY slow
amount = 5
if(amount)
add_movespeed_modifier(MOVESPEED_ID_SLIME_REAGENTMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/slime_reagentmod, multiplicative_slowdown = amount)
/mob/living/simple_animal/slime/updatehealth()
. = ..()
remove_movespeed_modifier(MOVESPEED_ID_SLIME_HEALTHMOD, FALSE)
remove_movespeed_modifier(/datum/movespeed_modifier/slime_healthmod)
var/health_deficiency = (100 - health)
var/mod = 0
if(health_deficiency >= 45)
mod += (health_deficiency / 25)
if(health <= 0)
mod += 2
add_movespeed_modifier(MOVESPEED_ID_SLIME_HEALTHMOD, TRUE, 100, multiplicative_slowdown = mod)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/slime_healthmod, multiplicative_slowdown = mod)
/mob/living/simple_animal/slime/adjust_bodytemperature()
. = ..()
@@ -173,9 +173,8 @@
if(bodytemperature >= 330.23) // 135 F or 57.08 C
mod = -1 // slimes become supercharged at high temperatures
else if(bodytemperature < 183.222)
mod = (283.222 - bodytemperature) / 10 * 1.75
if(mod)
add_movespeed_modifier(MOVESPEED_ID_SLIME_TEMPMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = mod)
mod = min(15, (283.222 - bodytemperature) / 10 * 1.75)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/slime_tempmod, multiplicative_slowdown = mod)
/mob/living/simple_animal/slime/ObjBump(obj/O)
if(!client && powerlevel > 0)
+32 -2
View File
@@ -622,10 +622,40 @@
tod = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)
update_stat()
///Unignores all slowdowns that lack the IGNORE_NOSLOW flag.
/mob/living/proc/unignore_slowdown(source)
REMOVE_TRAIT(src, TRAIT_IGNORESLOWDOWN, source)
update_movespeed(FALSE)
update_movespeed()
///Ignores all slowdowns that lack the IGNORE_NOSLOW flag.
/mob/living/proc/ignore_slowdown(source)
ADD_TRAIT(src, TRAIT_IGNORESLOWDOWN, source)
update_movespeed(FALSE)
update_movespeed()
///Ignores specific slowdowns. Accepts a list of slowdowns.
/mob/living/proc/add_movespeed_mod_immunities(source, slowdown_type, update = TRUE)
if(islist(slowdown_type))
for(var/listed_type in slowdown_type)
if(ispath(listed_type))
listed_type = "[listed_type]" //Path2String
LAZYADDASSOC(movespeed_mod_immunities, listed_type, source)
else
if(ispath(slowdown_type))
slowdown_type = "[slowdown_type]" //Path2String
LAZYADDASSOC(movespeed_mod_immunities, slowdown_type, source)
if(update)
update_movespeed()
///Unignores specific slowdowns. Accepts a list of slowdowns.
/mob/living/proc/remove_movespeed_mod_immunities(source, slowdown_type, update = TRUE)
if(islist(slowdown_type))
for(var/listed_type in slowdown_type)
if(ispath(listed_type))
listed_type = "[listed_type]" //Path2String
LAZYREMOVEASSOC(movespeed_mod_immunities, listed_type, source)
else
if(ispath(slowdown_type))
slowdown_type = "[slowdown_type]" //Path2String
LAZYREMOVEASSOC(movespeed_mod_immunities, slowdown_type, source)
if(update)
update_movespeed()
+11 -6
View File
@@ -1033,17 +1033,22 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
/// Updates the grab state of the mob and updates movespeed
/mob/setGrabState(newstate)
. = ..()
if(grab_state == GRAB_PASSIVE)
remove_movespeed_modifier(MOVESPEED_ID_MOB_GRAB_STATE, update=TRUE)
else
add_movespeed_modifier(MOVESPEED_ID_MOB_GRAB_STATE, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=grab_state*3, blacklisted_movetypes=FLOATING)
switch(grab_state)
if(GRAB_PASSIVE)
remove_movespeed_modifier(MOVESPEED_ID_MOB_GRAB_STATE)
if(GRAB_AGGRESSIVE)
add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/aggressive)
if(GRAB_NECK)
add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/neck)
if(GRAB_KILL)
add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/kill)
/mob/proc/update_equipment_speed_mods()
var/speedies = equipped_speed_mods()
if(!speedies)
remove_movespeed_modifier(MOVESPEED_ID_MOB_EQUIPMENT, update=TRUE)
remove_movespeed_modifier(/datum/movespeed_modifier/equipment_speedmod, update=TRUE)
else
add_movespeed_modifier(MOVESPEED_ID_MOB_EQUIPMENT, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=speedies, blacklisted_movetypes=FLOATING)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/equipment_speedmod, multiplicative_slowdown = speedies)
/// Gets the combined speed modification of all worn items
/// Except base mob type doesnt really wear items
+6 -1
View File
@@ -10,6 +10,8 @@
throwforce = 10
blocks_emissive = EMISSIVE_BLOCK_GENERIC
vis_flags = VIS_INHERIT_PLANE //when this be added to vis_contents of something it inherit something.plane, important for visualisation of mob in openspace.
var/lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
var/datum/mind/mind
var/list/datum/action/actions = list()
@@ -42,8 +44,11 @@
var/lying_prev = 0
var/is_shifted = FALSE
//MOVEMENT SPEED
/// List of movement speed modifiers applying to this mob
var/list/movespeed_modification //Lazy list, see mob_movespeed.dm
/// List of movement speed modifiers ignored by this mob. List -> List (id) -> List (sources)
var/list/movespeed_mod_immunities //Lazy list, see mob_movespeed.dm
/// The calculated mob speed slowdown based on the modifiers list
var/cached_multiplicative_slowdown
/////////////////
+6 -6
View File
@@ -80,12 +80,12 @@
var/oldloc = mob.loc
if(L.confused)
var/newdir = 0
if(L.confused > 40)
var/newdir = NONE
if((L.confused > 50) && prob(min(L.confused * 0.5, 50)))
newdir = pick(GLOB.alldirs)
else if(prob(L.confused * 1.5))
else if(prob(L.confused))
newdir = angle2dir(dir2angle(direction) + pick(90, -90))
else if(prob(L.confused * 3))
else if(prob(L.confused * 2))
newdir = angle2dir(dir2angle(direction) + pick(45, -45))
if(newdir)
direction = newdir
@@ -251,9 +251,9 @@
/mob/proc/update_gravity(has_gravity, override=FALSE)
var/speed_change = max(0, has_gravity - STANDARD_GRAVITY)
if(!speed_change)
remove_movespeed_modifier(MOVESPEED_ID_MOB_GRAVITY, update=TRUE)
remove_movespeed_modifier(/datum/movespeed_modifier/gravity)
else
add_movespeed_modifier(MOVESPEED_ID_MOB_GRAVITY, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=speed_change, blacklisted_movetypes=FLOATING)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/gravity, multiplicative_slowdown = speed_change)
//bodypart selection - Cyberboss
//8 toggles through head - eyes - mouth
-126
View File
@@ -1,126 +0,0 @@
/*Current movespeed modification list format: list(id = list(
priority,
flags,
legacy slowdown/speedup amount,
movetype_flags,
blacklisted_movetypes,
conflict
))
*/
//ANY ADD/REMOVE DONE IN UPDATE_MOVESPEED MUST HAVE THE UPDATE ARGUMENT SET AS FALSE!
/mob/proc/add_movespeed_modifier(id, update=TRUE, priority=0, flags=NONE, override=FALSE, multiplicative_slowdown=0, movetypes=ALL, blacklisted_movetypes=NONE, conflict=FALSE)
var/list/temp = list(priority, flags, multiplicative_slowdown, movetypes, blacklisted_movetypes, conflict) //build the modification list
var/resort = TRUE
if(LAZYACCESS(movespeed_modification, id))
var/list/existing_data = movespeed_modification[id]
if(movespeed_modifier_identical_check(existing_data, temp))
return FALSE
if(!override)
return FALSE
if(priority == existing_data[MOVESPEED_DATA_INDEX_PRIORITY])
resort = FALSE // We don't need to re-sort if we're replacing something already there and it's the same priority
LAZYSET(movespeed_modification, id, temp)
if(update)
update_movespeed(resort)
return TRUE
/mob/proc/remove_movespeed_modifier(id, update = TRUE)
if(!LAZYACCESS(movespeed_modification, id))
return FALSE
LAZYREMOVE(movespeed_modification, id)
UNSETEMPTY(movespeed_modification)
if(update)
update_movespeed(FALSE)
return TRUE
/mob/vv_edit_var(var_name, var_value)
var/slowdown_edit = (var_name == NAMEOF(src, cached_multiplicative_slowdown))
var/diff
if(slowdown_edit && isnum(cached_multiplicative_slowdown) && isnum(var_value))
remove_movespeed_modifier(MOVESPEED_ID_ADMIN_VAREDIT)
diff = var_value - cached_multiplicative_slowdown
. = ..()
if(. && slowdown_edit && isnum(diff))
add_movespeed_modifier(MOVESPEED_ID_ADMIN_VAREDIT, TRUE, 100, override = TRUE, multiplicative_slowdown = diff)
/mob/proc/has_movespeed_modifier(id)
return LAZYACCESS(movespeed_modification, id)
/mob/proc/update_config_movespeed()
add_movespeed_modifier(MOVESPEED_ID_CONFIG_SPEEDMOD, FALSE, 100, override = TRUE, multiplicative_slowdown = get_config_multiplicative_speed())
/mob/proc/get_config_multiplicative_speed()
if(!islist(GLOB.mob_config_movespeed_type_lookup) || !GLOB.mob_config_movespeed_type_lookup[type])
return 0
else
return GLOB.mob_config_movespeed_type_lookup[type]
/mob/proc/update_movespeed(resort = TRUE)
if(resort)
sort_movespeed_modlist()
. = 0
var/list/conflict_tracker = list()
for(var/id in get_movespeed_modifiers())
var/list/data = movespeed_modification[id]
if(!(data[MOVESPEED_DATA_INDEX_MOVETYPE] & movement_type)) // We don't affect any of these move types, skip
continue
if(data[MOVESPEED_DATA_INDEX_BL_MOVETYPE] & movement_type) // There's a movetype here that disables this modifier, skip
continue
var/conflict = data[MOVESPEED_DATA_INDEX_CONFLICT]
var/amt = data[MOVESPEED_DATA_INDEX_MULTIPLICATIVE_SLOWDOWN]
if(conflict)
// Conflicting modifiers prioritize the larger slowdown or the larger speedup
// We purposefuly don't handle mixing speedups and slowdowns on the same id
if(abs(conflict_tracker[conflict]) < abs(amt))
conflict_tracker[conflict] = amt
else
continue
. += amt
cached_multiplicative_slowdown = .
/mob/proc/get_movespeed_modifiers()
return movespeed_modification
/mob/proc/movespeed_modifier_identical_check(list/mod1, list/mod2)
if(!islist(mod1) || !islist(mod2) || mod1.len < MOVESPEED_DATA_INDEX_MAX || mod2.len < MOVESPEED_DATA_INDEX_MAX)
return FALSE
for(var/i in 1 to MOVESPEED_DATA_INDEX_MAX)
if(mod1[i] != mod2[i])
return FALSE
return TRUE
/mob/proc/total_multiplicative_slowdown()
. = 0
for(var/id in get_movespeed_modifiers())
var/list/data = movespeed_modification[id]
. += data[MOVESPEED_DATA_INDEX_MULTIPLICATIVE_SLOWDOWN]
/proc/movespeed_data_null_check(list/data) //Determines if a data list is not meaningful and should be discarded.
. = TRUE
if(data[MOVESPEED_DATA_INDEX_MULTIPLICATIVE_SLOWDOWN])
. = FALSE
/mob/proc/sort_movespeed_modlist() //Verifies it too. Sorts highest priority (first applied) to lowest priority (last applied)
if(!movespeed_modification)
return
var/list/assembled = list()
for(var/our_id in movespeed_modification)
var/list/our_data = movespeed_modification[our_id]
if(!islist(our_data) || (our_data.len < MOVESPEED_DATA_INDEX_PRIORITY) || movespeed_data_null_check(our_data))
movespeed_modification -= our_id
continue
var/our_priority = our_data[MOVESPEED_DATA_INDEX_PRIORITY]
var/resolved = FALSE
for(var/their_id in assembled)
var/list/their_data = assembled[their_id]
if(their_data[MOVESPEED_DATA_INDEX_PRIORITY] < our_priority)
assembled.Insert(assembled.Find(their_id), our_id)
assembled[our_id] = our_data
resolved = TRUE
break
if(!resolved)
assembled[our_id] = our_data
movespeed_modification = assembled
UNSETEMPTY(movespeed_modification)