mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-30 07:27:57 +01:00
Merge pull request #3064 from Zuhayr/master
Projectile pinning, staggering, vox whitelist removal, vox raider spawn verb.
This commit is contained in:
@@ -45,7 +45,7 @@
|
||||
if(istype(tmob, /mob/living/carbon/human))
|
||||
|
||||
for(var/mob/M in range(tmob, 1))
|
||||
if( ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) )
|
||||
if(tmob.pinned.len || ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) )
|
||||
if ( !(world.time % 5) )
|
||||
src << "\red [tmob] is restrained, you cannot push past"
|
||||
now_pushing = 0
|
||||
@@ -1119,51 +1119,107 @@
|
||||
del(feet_blood_DNA)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/verb/yank_out_object()
|
||||
mob/living/carbon/human/verb/yank_out_object()
|
||||
set category = "IC"
|
||||
set name = "Yank out object"
|
||||
set desc = "Remove an embedded item at the cost of bleeding and pain."
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if(!isliving(usr) || usr.next_move > world.time)
|
||||
return
|
||||
usr.next_move = world.time + 20
|
||||
|
||||
var/list/valid_objects = get_visible_implants(1)
|
||||
if(usr.stat == 1)
|
||||
usr << "You are unconcious and cannot do that!"
|
||||
return
|
||||
|
||||
if(usr.restrained())
|
||||
usr << "You are restrained and cannot do that!"
|
||||
return
|
||||
|
||||
// /*
|
||||
var/list/valid_objects = list()
|
||||
var/datum/organ/external/affected = null
|
||||
var/mob/living/carbon/human/S = src
|
||||
var/mob/living/carbon/human/U = usr
|
||||
|
||||
if(!valid_objects.len)
|
||||
src << "You have nothing stuck in your wounds that is large enough to remove without surgery."
|
||||
return
|
||||
if(S == U) // Removing something from yourself.
|
||||
valid_objects = get_visible_implants(1)
|
||||
|
||||
if(src.stat == 1)
|
||||
src << "You are unconcious and cannot do that!"
|
||||
return
|
||||
if(!valid_objects.len)
|
||||
src << "You have nothing stuck in your wounds that is large enough to remove without surgery."
|
||||
return
|
||||
|
||||
if(src.restrained())
|
||||
src << "You are restrained and cannot do that!"
|
||||
return
|
||||
var/obj/item/weapon/selection = input("What do you want to yank out?", "Embedded objects") in valid_objects
|
||||
|
||||
var/obj/item/weapon/selection = input("What do you want to yank out?", "Embedded objects") in valid_objects
|
||||
for(var/datum/organ/external/organ in organs) //Grab the organ holding the implant. Messy as Hell, TBD: fix.
|
||||
for(var/obj/item/weapon/O in organ.implants)
|
||||
if(O == selection)
|
||||
affected = organ
|
||||
|
||||
for(var/datum/organ/external/organ in src.organs) //Grab the organ holding the implant. Messy as Hell, TBD: fix.
|
||||
for(var/obj/item/weapon/O in organ.implants)
|
||||
if(O == selection)
|
||||
affected = organ
|
||||
src << "<span class='warning'>You attempt to get a good grip on the [selection] in your [affected] with bloody fingers.</span>"
|
||||
bloody_hands(S)
|
||||
|
||||
src << "<span class='warning'>You attempt to get a good grip on the [selection] in your [affected] with bloody fingers.</span>"
|
||||
bloody_hands(src)
|
||||
if(!do_after(U, 80))
|
||||
return
|
||||
|
||||
if(!selection || !affected || !S || !U)
|
||||
return
|
||||
|
||||
spawn(80)
|
||||
visible_message("<span class='warning'><b>[src] rips [selection] out of their [affected] in a welter of blood.</b></span>","<span class='warning'><b>You rip [selection] out of your [affected] in a welter of blood.</b></span>")
|
||||
selection.loc = get_turf(src)
|
||||
affected.implants -= selection
|
||||
shock_stage+=10
|
||||
|
||||
for(var/obj/item/weapon/O in pinned)
|
||||
if(O == selection)
|
||||
pinned -= O
|
||||
anchored = 0
|
||||
|
||||
if(prob(10)) //I'M SO ANEMIC I COULD JUST -DIE-.
|
||||
var/datum/wound/internal_bleeding/I = new (15)
|
||||
affected.wounds += I
|
||||
src.custom_pain("Something tears wetly in your [affected] as [selection] is pulled free!", 1)
|
||||
return 1
|
||||
custom_pain("Something tears wetly in your [affected] as [selection] is pulled free!", 1)
|
||||
return 1
|
||||
|
||||
else // Removing something from someone else.
|
||||
valid_objects = src.get_visible_implants(1)
|
||||
|
||||
if(!valid_objects.len)
|
||||
U << "[src] has nothing stuck in their wounds that is large enough to remove without surgery."
|
||||
return
|
||||
|
||||
var/obj/item/weapon/selection = input("What do you want to yank out?", "Embedded objects") in valid_objects
|
||||
|
||||
for(var/datum/organ/external/organ in src.organs) //Grab the organ holding the implant. Messy as Hell, TBD: fix.
|
||||
for(var/obj/item/weapon/O in organ.implants)
|
||||
if(O == selection)
|
||||
affected = organ
|
||||
|
||||
U << "<span class='warning'>You attempt to get a good grip on the [selection] in [S]'s [affected] with bloody fingers.</span>"
|
||||
U.bloody_hands(S)
|
||||
|
||||
if(!do_after(U, 80))
|
||||
return
|
||||
|
||||
if(!selection || !affected || !S || !U)
|
||||
return
|
||||
|
||||
visible_message("<span class='warning'><b>[usr] rips [selection] out of [src]'s [affected] in a welter of blood.</b></span>","<span class='warning'><b>[src] rips [selection] out of your [affected] in a welter of blood.</b></span>")
|
||||
selection.loc = get_turf(usr)
|
||||
affected.implants -= selection
|
||||
src.shock_stage+=10
|
||||
|
||||
for(var/obj/item/weapon/O in S.pinned)
|
||||
if(O == selection)
|
||||
S.pinned -= O
|
||||
S.anchored = 0
|
||||
|
||||
if(prob(10)) //I'M SO ANEMIC I COULD JUST -DIE-.
|
||||
var/datum/wound/internal_bleeding/I = new (15)
|
||||
affected.wounds += I
|
||||
custom_pain("Something tears wetly in your [affected] as [selection] is pulled free!", 1)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/get_visible_implants(var/class = 0)
|
||||
|
||||
|
||||
@@ -226,15 +226,22 @@
|
||||
//Embedded projectile code.
|
||||
if(!organ) return
|
||||
if(istype(used_weapon,/obj/item/weapon))
|
||||
var/obj/item/weapon/W = used_weapon
|
||||
var/obj/item/weapon/W = used_weapon //Sharp objects will always embed if they do enough damage.
|
||||
if(damage > (5*W.w_class) && (prob(damage/W.w_class) || sharp)) //The larger it is, the harder it needs to hit to stick.
|
||||
W.loc = src //Sharp objects will always embed if they do enough damage.
|
||||
organ.implants += W
|
||||
visible_message("<span class='danger'>\The [W] sticks in the wound!</span>")
|
||||
W.add_blood(src)
|
||||
if(ismob(W.loc))
|
||||
var/mob/living/H = W.loc
|
||||
H.drop_item()
|
||||
W.loc = src
|
||||
|
||||
else if(istype(used_weapon,/obj/item/projectile)) //We don't want to use the actual projectile item, so we spawn some shrapnel.
|
||||
if(prob(50) && damagetype == BRUTE)
|
||||
var/obj/item/projectile/P = used_weapon
|
||||
var/obj/item/weapon/shard/shrapnel/S = new()
|
||||
S.name = "[P.name] shrapnel"
|
||||
S.desc = "[S.desc] It looks like it was fired from [P.shot_from]."
|
||||
S.loc = src
|
||||
organ.implants += S
|
||||
visible_message("<span class='danger'>The projectile sticks in the wound!</span>")
|
||||
|
||||
@@ -470,7 +470,7 @@
|
||||
reagents.add_reagent("plasma", Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))
|
||||
toxins_alert = max(toxins_alert, 1)
|
||||
else if(O2_pp > vox_oxygen_max && src.dna.mutantrace=="vox") //Oxygen is toxic to vox.
|
||||
var/ratio = (breath.oxygen/vox_oxygen_max) * 10
|
||||
var/ratio = (breath.oxygen/vox_oxygen_max) * 1000
|
||||
adjustToxLoss(Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))
|
||||
toxins_alert = max(toxins_alert, 1)
|
||||
else
|
||||
@@ -490,7 +490,7 @@
|
||||
|
||||
if( (abs(310.15 - breath.temperature) > 50) && !(COLD_RESISTANCE in mutations)) // Hot air hurts :(
|
||||
if(status_flags & GODMODE) return 1 //godmode
|
||||
if(breath.temperature < 260.15)
|
||||
if(breath.temperature < 260.15 && dna.mutantrace != "vox") //Vox are resistant to cold.
|
||||
if(prob(20))
|
||||
src << "\red You feel your face freezing and an icicle forming in your lungs!"
|
||||
else if(breath.temperature > 360.15)
|
||||
@@ -501,10 +501,10 @@
|
||||
if(-INFINITY to 120)
|
||||
apply_damage(COLD_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Cold")
|
||||
fire_alert = max(fire_alert, 1)
|
||||
if(120 to 200)
|
||||
if(120 to 200 && dna.mutantrace != "vox") //Vox are resistant to cold.
|
||||
apply_damage(COLD_GAS_DAMAGE_LEVEL_2, BURN, "head", used_weapon = "Excessive Cold")
|
||||
fire_alert = max(fire_alert, 1)
|
||||
if(200 to 260)
|
||||
if(200 to 260 && dna.mutantrace != "vox") //Vox are resistant to cold.
|
||||
apply_damage(COLD_GAS_DAMAGE_LEVEL_1, BURN, "head", used_weapon = "Excessive Cold")
|
||||
fire_alert = max(fire_alert, 1)
|
||||
if(360 to 400)
|
||||
@@ -602,7 +602,7 @@
|
||||
if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE)
|
||||
pressure_alert = -1
|
||||
else
|
||||
if( !(COLD_RESISTANCE in mutations) && src.dna.mutantrace!="vox")
|
||||
if( !(COLD_RESISTANCE in mutations) && src.dna.mutantrace!="vox") //Vox are resistant to pressure loss.
|
||||
adjustBruteLoss( LOW_PRESSURE_DAMAGE )
|
||||
pressure_alert = -2
|
||||
else
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
P.on_hit(src, absorb)
|
||||
return absorb
|
||||
|
||||
/mob/living/hitby(atom/movable/AM as mob|obj,var/speed)//Standardization and logging -Sieve
|
||||
/mob/living/hitby(atom/movable/AM as mob|obj,var/speed = 5)//Standardization and logging -Sieve
|
||||
if(istype(AM,/obj/))
|
||||
var/obj/O = AM
|
||||
var/zone = ran_zone("chest",75)//Hits a random part of the body, geared towards the chest
|
||||
@@ -73,11 +73,43 @@
|
||||
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [zone].", "Your armor has softened hit to your [zone].")
|
||||
if(armor < 2)
|
||||
apply_damage(O.throwforce*(speed/5), dtype, zone, armor, O.sharp, O)
|
||||
|
||||
if(!O.fingerprintslast)
|
||||
return
|
||||
|
||||
var/client/assailant = directory[ckey(O.fingerprintslast)]
|
||||
if(assailant && assailant.mob && istype(assailant.mob,/mob))
|
||||
var/mob/M = assailant.mob
|
||||
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been hit with [O], last touched by [M.name] ([assailant.ckey])</font>")
|
||||
M.attack_log += text("\[[time_stamp()]\] <font color='red'>Hit [src.name] ([src.ckey]) with [O]</font>")
|
||||
log_attack("<font color='red'>[src.name] ([src.ckey]) was hit by [O], last touched by [M.name] ([assailant.ckey])</font>")
|
||||
|
||||
// Begin BS12 momentum-transfer code.
|
||||
|
||||
if(speed > 20)
|
||||
var/obj/item/weapon/W = O
|
||||
var/momentum = speed/2
|
||||
var/dir = get_dir(M,src)
|
||||
visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!")
|
||||
|
||||
src.throw_at(get_edge_target_turf(src,dir),1,momentum)
|
||||
|
||||
if(near_wall(dir,2) && W.w_class >= 3 && W.sharp) //If they're close to a wall and the projectile is suitable.
|
||||
visible_message("<span class='warning'>[src] is pinned to the wall by [O]!</span>","<span class='warning'>You are pinned to the wall by [O]!</span>")
|
||||
src.anchored = 1
|
||||
src.pinned += O
|
||||
|
||||
|
||||
/mob/living/proc/near_wall(var/direction,var/distance=1)
|
||||
var/turf/T = get_step(get_turf(src),direction)
|
||||
var/i = 1
|
||||
while(i>0 && i<=distance)
|
||||
if(T.density) //Turf is a wall!
|
||||
return 1
|
||||
i++
|
||||
T = get_step(T,direction)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
// End BS12 momentum-transfer code.
|
||||
@@ -24,7 +24,6 @@
|
||||
//Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects.
|
||||
var/incorporeal_move = 0 //0 is off, 1 is normal, 2 is for ninjas.
|
||||
|
||||
|
||||
var/t_plasma = null
|
||||
var/t_oxygen = null
|
||||
var/t_sl_gas = null
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/mob/living/simple_animal/vox/armalis/
|
||||
|
||||
name = "serpentine alien"
|
||||
real_name = "serpentine alien"
|
||||
desc = "A one-eyed, serpentine creature, half-machine, easily nine feet from tail to beak!"
|
||||
icon = 'icons/mob/vox.dmi'
|
||||
icon_state = "armalis"
|
||||
icon_living = "armalis"
|
||||
maxHealth = 500
|
||||
health = 500
|
||||
response_harm = "flails ineffectually at the"
|
||||
harm_intent_damage = 0
|
||||
melee_damage_lower = 30
|
||||
melee_damage_upper = 40
|
||||
attacktext = "slammed its enormous claws into"
|
||||
speed = -1
|
||||
wall_smash = 1
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
status_flags = 0
|
||||
|
||||
/mob/living/simple_animal/vox/armalis/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if(O.force)
|
||||
if(O.force >= 25)
|
||||
var/damage = O.force
|
||||
if (O.damtype == HALLOSS)
|
||||
damage = 0
|
||||
health -= damage
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red \b [src] has been attacked with the [O] by [user]. ")
|
||||
else
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red \b The [O] bounces harmlessly off of [src]. ")
|
||||
else
|
||||
usr << "\red This weapon is ineffective, it does no damage."
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red [user] gently taps [src] with the [O]. ")
|
||||
|
||||
/mob/living/simple_animal/vox/armalis/verb/fire_quill(mob/target as mob in oview())
|
||||
|
||||
set name = "Fire quill"
|
||||
set desc = "Fires a viciously pointed quill at a high speed."
|
||||
set category = "Alien"
|
||||
|
||||
src << "\red You launch a razor-sharp quill at [target]!"
|
||||
for(var/mob/O in oviewers())
|
||||
if ((O.client && !( O.blinded )))
|
||||
O << "\red [src] launches a razor-sharp quill at [target]!"
|
||||
|
||||
var/obj/item/weapon/arrow/quill/Q = new(loc)
|
||||
Q.fingerprintslast = src
|
||||
Q.throw_at(target,10,15)
|
||||
+22
-15
@@ -583,24 +583,31 @@ var/list/slot_equipment_priority = list( \
|
||||
pulling = null
|
||||
|
||||
/mob/proc/start_pulling(var/atom/movable/AM)
|
||||
|
||||
if ( !AM || !usr || src==AM || !isturf(src.loc) ) //if there's no person pulling OR the person is pulling themself OR the object being pulled is inside something: abort!
|
||||
return
|
||||
if (!( AM.anchored ))
|
||||
if(pulling)
|
||||
var/pulling_old = pulling
|
||||
stop_pulling()
|
||||
// Are we pulling the same thing twice? Just stop pulling.
|
||||
if(pulling_old == AM)
|
||||
return
|
||||
src.pulling = AM
|
||||
AM.pulledby = src
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
if(!iscarbon(src))
|
||||
M.LAssailant = null
|
||||
else
|
||||
M.LAssailant = usr
|
||||
|
||||
if (AM.anchored)
|
||||
return
|
||||
|
||||
var/mob/M = AM
|
||||
if(ismob(AM))
|
||||
if(!iscarbon(src))
|
||||
M.LAssailant = null
|
||||
else
|
||||
M.LAssailant = usr
|
||||
if (M.pinned.len)
|
||||
usr << "They're pinned, gtfo."
|
||||
return
|
||||
|
||||
if(pulling)
|
||||
var/pulling_old = pulling
|
||||
stop_pulling()
|
||||
// Are we pulling the same thing twice? Just stop pulling.
|
||||
if(pulling_old == AM)
|
||||
return
|
||||
src.pulling = AM
|
||||
AM.pulledby = src
|
||||
|
||||
/mob/proc/can_use_hands()
|
||||
return
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
var/lastpuke = 0
|
||||
var/unacidable = 0
|
||||
var/small = 0
|
||||
var/list/pinned = list() //List of things pinning this creature to walls (see living_defense.dm)
|
||||
|
||||
var/name_archive //For admin things like possession
|
||||
|
||||
|
||||
@@ -256,7 +256,6 @@
|
||||
|
||||
if(!mob.canmove) return
|
||||
|
||||
|
||||
//if(istype(mob.loc, /turf/space) || (mob.flags & NOGRAV))
|
||||
// if(!mob.Process_Spacemove(0)) return 0
|
||||
|
||||
@@ -279,6 +278,10 @@
|
||||
src << "\blue You're restrained! You can't move!"
|
||||
return 0
|
||||
|
||||
if(mob.pinned.len)
|
||||
src << "\blue You're pinned to a wall by [mob.pinned[1]]!"
|
||||
return 0
|
||||
|
||||
move_delay = world.time//set move delay
|
||||
mob.last_move_intent = world.time + 10
|
||||
switch(mob.m_intent)
|
||||
|
||||
@@ -349,12 +349,8 @@
|
||||
if(is_alien_whitelisted(src, "Skrell"|| !config.usealienwhitelist))
|
||||
new_character.dna.mutantrace = "skrell"
|
||||
new_character.skrell_talk_understand = 1
|
||||
if(client.prefs.species == "Vox")
|
||||
if(is_alien_whitelisted(src, "Vox"|| !config.usealienwhitelist))
|
||||
new_character.dna.mutantrace = "vox"
|
||||
new_character.vox_talk_understand = 1
|
||||
if(client.prefs.species == "Kidan")
|
||||
if(is_alien_whitelisted(src, "Vox"|| !config.usealienwhitelist))
|
||||
if(is_alien_whitelisted(src, "Kidan"|| !config.usealienwhitelist))
|
||||
new_character.dna.mutantrace = "kidan"
|
||||
new_character.kidan_talk_understand = 1
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
if (is_speaking_tajaran)
|
||||
return "<span class='say_quote'>mrowls</span>, \"<span class='tajaran'>[text]</span>\"";
|
||||
if (is_speaking_vox)
|
||||
return "<span class='say_quote'>chirps</span>, \"<span class='vox'>[text]</span>\"";
|
||||
return "<span class='say_quote'>shrieks</span>, \"<span class='vox'>[text]</span>\"";
|
||||
if (is_speaking_kidan)
|
||||
return "<span class='say_quote'>chitters</span>, \"<span class='kidan'>[text]</span>\"";
|
||||
//Needs Virus2
|
||||
|
||||
Reference in New Issue
Block a user