Merge pull request #3064 from Zuhayr/master

Projectile pinning, staggering, vox whitelist removal, vox raider spawn verb.
This commit is contained in:
Chinsky
2013-06-15 00:21:24 -07:00
30 changed files with 458 additions and 74 deletions
+79 -23
View File
@@ -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>")
+5 -5
View File
@@ -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
+33 -1
View File
@@ -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
View File
@@ -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
+1
View File
@@ -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
+4 -1
View File
@@ -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)
+1 -5
View File
@@ -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
+1 -1
View File
@@ -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