mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-19 02:54:41 +01:00
Merge branch 'master' of github.com:Baystation12/Baystation12
Conflicts: code/modules/mob/living/carbon/human/examine.dm code/modules/mob/living/carbon/human/life.dm
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
see_invisible = 15
|
||||
see_in_dark = 100
|
||||
verbs += /mob/dead/observer/proc/dead_tele
|
||||
verbs += /mob/dead/observer/proc/become_mouse
|
||||
taj_talk_understand = 1
|
||||
|
||||
if(body)
|
||||
@@ -17,10 +18,17 @@
|
||||
if(!body.original_name)
|
||||
body.original_name = real_name
|
||||
original_name = body.original_name
|
||||
name = body.original_name
|
||||
//name = body.original_name //original
|
||||
name = body.name
|
||||
real_name = body.real_name
|
||||
|
||||
if(!name)
|
||||
name = capitalize(pick(first_names_male) + " " + capitalize(pick(last_names)))
|
||||
real_name = name
|
||||
|
||||
if( original_name != real_name )
|
||||
name = name + " (died as [src.real_name])"
|
||||
|
||||
if(!safety)
|
||||
corpse = body
|
||||
verbs += /mob/dead/observer/proc/reenter_corpse
|
||||
@@ -76,6 +84,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
verbs -= /mob/proc/ghost
|
||||
if (ghost.client)
|
||||
ghost.client.eye = ghost
|
||||
/*if(issimpleanimal(src))
|
||||
ghost.name = src.name + " ([src.real_name])"
|
||||
ghost.voice_name = src.name + " ([src.real_name])"*/
|
||||
return
|
||||
|
||||
/mob/proc/adminghostize()
|
||||
@@ -153,6 +164,49 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
verbs += /mob/proc/ghost
|
||||
del(src)
|
||||
|
||||
/mob/dead/observer/proc/become_mouse()
|
||||
set category = "Ghost"
|
||||
set name = "Become mouse"
|
||||
|
||||
//locate an empty mouse
|
||||
var/list/eligible_targets = new()
|
||||
for(var/mob/living/simple_animal/mouse/M in world)
|
||||
if(!M.ckey && !M.stat)
|
||||
eligible_targets.Add(M)
|
||||
|
||||
var/mob/living/simple_animal/mouse/target_mouse
|
||||
if(ticker.spawn_vermin)
|
||||
if(eligible_targets.len)
|
||||
//grab a random existing one
|
||||
target_mouse = pick(eligible_targets)
|
||||
else
|
||||
//make a new mouse
|
||||
target_mouse = new(pick(ticker.vermin_spawn_turfs))
|
||||
|
||||
if(target_mouse)
|
||||
//move player into mouse
|
||||
//the mouse ai will deactivate itself
|
||||
client.mob = target_mouse
|
||||
target_mouse.original_name = src.original_name
|
||||
|
||||
//reset admin verbs
|
||||
if(client && client.holder && client.holder.state == 2)
|
||||
var/rank = client.holder.rank
|
||||
client.clear_admin_verbs()
|
||||
client.holder.state = 1
|
||||
client.update_admins(rank)
|
||||
|
||||
//update allowed verbs
|
||||
target_mouse.verbs += /mob/proc/ghost
|
||||
target_mouse.verbs -= /mob/verb/observe
|
||||
target_mouse.verbs -= /client/verb/toggle_ghost_ears
|
||||
target_mouse.verbs -= /client/verb/toggle_ghost_sight
|
||||
|
||||
del(src)
|
||||
|
||||
else
|
||||
client << "\red Unable to become a mouse!"
|
||||
|
||||
/mob/dead/observer/proc/dead_tele()
|
||||
set category = "Ghost"
|
||||
set name = "Teleport"
|
||||
|
||||
@@ -819,6 +819,8 @@ Radar-related things
|
||||
client.screen += closedradar
|
||||
|
||||
/mob/living/carbon/human/proc/start_radar()
|
||||
// this proc lags like hell, why is it even in
|
||||
return
|
||||
|
||||
for(var/obj/screen/x in client.screen)
|
||||
if(x.name == "radar closed" && x.icon == 'radar.dmi')
|
||||
|
||||
@@ -220,9 +220,10 @@
|
||||
|
||||
//BubbleWrap: people in handcuffs are always switched around as if they were on 'help' intent to prevent a person being pulled from being seperated from their puller
|
||||
if((tmob.a_intent == "help" || tmob.restrained()) && (a_intent == "help" || src.restrained()) && tmob.canmove && canmove) // mutual brohugs all around!
|
||||
var/turf/oldloc = loc
|
||||
loc = tmob.loc
|
||||
tmob.loc = oldloc
|
||||
if(tmob.swap_on_mobbump)
|
||||
var/turf/oldloc = loc
|
||||
loc = tmob.loc
|
||||
tmob.loc = oldloc
|
||||
now_pushing = 0
|
||||
for(var/mob/living/carbon/metroid/Metroid in view(1,tmob))
|
||||
if(Metroid.Victim == tmob)
|
||||
@@ -969,7 +970,7 @@
|
||||
// Gloves
|
||||
var/datum/organ/external/lo = organs["l_hand"]
|
||||
var/datum/organ/external/ro = organs["r_hand"]
|
||||
if (!(lo.status & ORGAN_DESTROYED && ro.status & ORGAN_DESTROYED))
|
||||
if (lo && ro && !(lo.status & ORGAN_DESTROYED && ro.status & ORGAN_DESTROYED))
|
||||
if (gloves)
|
||||
var/t1 = gloves.item_state
|
||||
if (!t1)
|
||||
@@ -1419,7 +1420,7 @@
|
||||
lying_icon.Blend(new /icon('human.dmi', "chest_[g]_l"), ICON_OVERLAY)
|
||||
|
||||
var/datum/organ/external/head = organs["head"]
|
||||
if(!(head.status & ORGAN_DESTROYED))
|
||||
if(head && !(head.status & ORGAN_DESTROYED))
|
||||
stand_icon.Blend(new /icon('human.dmi', "head_[g]_s"), ICON_OVERLAY)
|
||||
lying_icon.Blend(new /icon('human.dmi', "head_[g]_l"), ICON_OVERLAY)
|
||||
|
||||
|
||||
@@ -360,7 +360,7 @@
|
||||
emote("gasp")
|
||||
updatehealth()
|
||||
|
||||
if(damage)
|
||||
if(damage && organs.len)
|
||||
var/V = pick(organs)
|
||||
var/datum/organ/external/O = organs[V]
|
||||
if(istype(O)) O.add_wound("Radiation Poisoning", damage)
|
||||
@@ -565,6 +565,8 @@
|
||||
var/ratio = breath.toxins/safe_toxins_max
|
||||
adjustToxLoss(min(ratio, 10)) //Limit amount of damage toxin exposure can do per second
|
||||
toxins_alert = max(toxins_alert, 1)
|
||||
if(vsc.plc.PLASMA_HALLUCINATION && prob(20))
|
||||
hallucination += 20
|
||||
else
|
||||
toxins_alert = 0
|
||||
|
||||
@@ -578,12 +580,15 @@
|
||||
else if(SA_pp > 0.01) // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning
|
||||
if(prob(20) && isbreathing)
|
||||
spawn(0) emote(pick("giggle", "laugh"))
|
||||
if(vsc.plc.N2O_HALLUCINATION && prob(10) && isbreathing)
|
||||
hallucination += 30
|
||||
SA.moles = 0 //Hack to stop the damned surgeon from giggling.
|
||||
|
||||
|
||||
if(breath.temperature > (T0C+66) && !(COLD_RESISTANCE in mutations)) // Hot air hurts :(
|
||||
if(prob(20))
|
||||
src << "\red You feel a searing heat in your lungs!"
|
||||
take_overall_damage(0,2) //burn them a bit.
|
||||
fire_alert = max(fire_alert, 1)
|
||||
else
|
||||
fire_alert = 0
|
||||
@@ -602,8 +607,6 @@
|
||||
if(istype(loc, /turf/space))
|
||||
environment_heat_capacity = loc:heat_capacity
|
||||
loc_temp = 2.7
|
||||
else if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
|
||||
loc_temp = loc:air_contents.temperature
|
||||
else
|
||||
loc_temp = environment.temperature
|
||||
|
||||
@@ -691,7 +694,7 @@
|
||||
|
||||
|
||||
var/pressure = environment.return_pressure()
|
||||
if(!istype(wear_suit, /obj/item/clothing/suit/space) && !istype(wear_suit, /obj/item/clothing/suit/fire))
|
||||
if(!istype(wear_suit, /obj/item/clothing/suit/space) && !istype(wear_suit, /obj/item/clothing/suit/fire) && !istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
|
||||
/*if(pressure < 20)
|
||||
if(prob(25))
|
||||
src << "You feel the splittle on your lips and the fluid on your eyes boiling away, the capillteries in your skin breaking."
|
||||
@@ -819,6 +822,9 @@
|
||||
handle_chemicals_in_body()
|
||||
if(reagents && stat != 2) reagents.metabolize(src)
|
||||
if(vessel && stat != 2) vessel.metabolize(src)
|
||||
for(var/obj/item/I in src)
|
||||
if(I.contaminated)
|
||||
toxloss += vsc.plc.CONTAMINATION_LOSS
|
||||
|
||||
if(mutantrace == "plant") //couldn't think of a better place to place it, since it handles nutrition -- Urist
|
||||
var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
|
||||
|
||||
@@ -700,10 +700,15 @@ mob/living/carbon/metroid/var/temperature_resistance = T0C+75
|
||||
health = 150
|
||||
stat = 0
|
||||
|
||||
|
||||
/mob/living/carbon/metroid/proc/get_obstacle_ok(atom/A)
|
||||
var/direct = get_dir(src, A)
|
||||
var/obj/item/weapon/dummy/D = new /obj/item/weapon/dummy( src.loc )
|
||||
var/obj/item/weapon/dummy/D = locate() in DummyCache //See atom_procs.dm
|
||||
if(!D)
|
||||
D = new /obj/item/weapon/dummy( src.loc )
|
||||
else
|
||||
D.loc = src.loc
|
||||
DummyCache.Remove(D)
|
||||
|
||||
var/ok = 0
|
||||
|
||||
if ( (direct - 1) & direct)
|
||||
@@ -781,7 +786,8 @@ mob/living/carbon/metroid/var/temperature_resistance = T0C+75
|
||||
if(!border_obstacle.CanPass(D, D.loc, 1, 0))
|
||||
ok = 0
|
||||
|
||||
del(D)
|
||||
D.loc = null
|
||||
DummyCache.Add(D)
|
||||
if (!( ok ))
|
||||
return 0
|
||||
|
||||
|
||||
@@ -194,12 +194,12 @@ mob/living/parasite/meme/proc/select_indoctrinated(var/title, var/message)
|
||||
// A meme can make people hear things with the thought ability
|
||||
mob/living/parasite/meme/verb/Thought()
|
||||
set category = "Meme"
|
||||
set name = "Thought(150)"
|
||||
set name = "Thought(50)"
|
||||
set desc = "Implants a thought into the target, making them think they heard someone talk."
|
||||
|
||||
if(meme_points < 150)
|
||||
if(meme_points < 50)
|
||||
// just call use_points() to give the standard failure message
|
||||
use_points(150)
|
||||
use_points(50)
|
||||
return
|
||||
|
||||
var/list/candidates = indoctrinated.Copy()
|
||||
@@ -217,7 +217,7 @@ mob/living/parasite/meme/verb/Thought()
|
||||
if(!message) return
|
||||
|
||||
// Use the points at the end rather than the beginning, because the user might cancel
|
||||
if(!use_points(150)) return
|
||||
if(!use_points(50)) return
|
||||
|
||||
message = say_quote(message)
|
||||
var/rendered = "<span class='game say'><span class='name'>[speaker]</span> <span class='message'>[message]</span></span>"
|
||||
|
||||
@@ -253,7 +253,7 @@
|
||||
if (timeleft)
|
||||
stat(null, "ETA-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
|
||||
|
||||
if(ticker.mode.name == "AI malfunction")
|
||||
if(ticker.mode && ticker.mode.name == "AI malfunction")
|
||||
var/datum/game_mode/malfunction/malf = ticker.mode
|
||||
for (var/datum/mind/malfai in malf.malf_ai)
|
||||
if(connected_ai)
|
||||
|
||||
@@ -294,3 +294,5 @@ the mob is also allowed to move without any sort of restriction. For instance, i
|
||||
var/list/radar_blips = list() // list of screen objects, radar blips
|
||||
var/radar_open = 0 // nonzero is radar is open
|
||||
|
||||
var/swap_on_mobbump = 1 //by default, mob collisions will swap the two mobs (if allowed)
|
||||
|
||||
|
||||
@@ -326,7 +326,7 @@
|
||||
var/dat = "<html><body><center>"
|
||||
dat += "Round Duration: [round(hours)]h [round(mins)]m<br>"
|
||||
|
||||
if(emergency_shuttle) //In case Nanotrasen decides reposess CentComm's shuttles.
|
||||
if(emergency_shuttle) //In case NanoTrasen decides reposess CentComm's shuttles.
|
||||
if(emergency_shuttle.direction == 2) //Shuttle is going to centcomm, not recalled
|
||||
dat += "<font color='red'><b>The station has been evacuated.</b></font><br>"
|
||||
if(emergency_shuttle.direction == 1 && emergency_shuttle.timeleft() < 300) //Shuttle is past the point of no recall
|
||||
|
||||
@@ -62,7 +62,7 @@ datum/skill/management
|
||||
datum/skill/knowledge/law
|
||||
ID = "law"
|
||||
name = "NanoTrasen Law"
|
||||
desc = "Your knowledge of NanoTrasen law and procedures. This includes space law, as well as general station rulings and procedures. A low level in this skill is typical for security officers, a high level in this skill is typical for captains."
|
||||
desc = "Your knowledge of NanoTrasen law and procedures. This includes Space Law, as well as general station rulings and procedures. A low level in this skill is typical for security officers, a high level in this skill is typical for captains."
|
||||
field = "Security"
|
||||
secondary = 1
|
||||
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
#define BEAR_STANCE_IDLE 1
|
||||
#define BEAR_STANCE_ALERT 2
|
||||
#define BEAR_STANCE_ATTACK 3
|
||||
#define BEAR_STANCE_ATTACKING 4
|
||||
#define BEAR_STANCE_TIRED 5
|
||||
|
||||
//Space bears!
|
||||
/mob/living/simple_animal/bear
|
||||
name = "space bear"
|
||||
desc = "RawrRawr!!"
|
||||
icon_state = "bear"
|
||||
icon_living = "bear"
|
||||
icon_dead = "bear_dead"
|
||||
icon_gib = "bear_gib"
|
||||
speak = list("RAWR!","Rawr!","GRR!","Growl!")
|
||||
speak_emote = list("growls", "roars")
|
||||
emote_hear = list("rawrs","grumbles","grawls")
|
||||
emote_see = list("stares ferociously", "stomps")
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "pokes the"
|
||||
|
||||
stop_automated_movement_when_pulled = 0
|
||||
maxHealth = 60
|
||||
health = 60
|
||||
|
||||
//Space bears aren't affected by atmos.
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
|
||||
var/stance = BEAR_STANCE_IDLE //Used to determine behavior
|
||||
var/stance_step = 0 //Used to delay checks depending on what stance the bear is in
|
||||
var/mob/living/target_mob //Once the bear enters attack stance, it will try to chase this mob. This it to prevent it changing it's mind between multiple mobs.
|
||||
|
||||
/proc/isbear(var/mob/M)
|
||||
return istype(M, /mob/living/simple_animal/bear)
|
||||
|
||||
/mob/living/simple_animal/bear/Life()
|
||||
..()
|
||||
|
||||
if(!stat)
|
||||
if(loc && istype(loc,/turf/space))
|
||||
icon_state = "bear"
|
||||
else
|
||||
icon_state = "bearfloor"
|
||||
|
||||
switch(stance)
|
||||
if(BEAR_STANCE_IDLE)
|
||||
stop_automated_movement = 0
|
||||
stance_step++
|
||||
if(stance_step > 5)
|
||||
stance_step = 0
|
||||
for( var/mob/living/L in viewers(7,src) )
|
||||
if(isbear(L)) continue
|
||||
if(!L.stat)
|
||||
emote("stares alertly at [L]")
|
||||
stance = BEAR_STANCE_ALERT
|
||||
break
|
||||
if(BEAR_STANCE_ALERT)
|
||||
stop_automated_movement = 1
|
||||
var/found_mob = 0
|
||||
for( var/mob/living/L in viewers(7,src) )
|
||||
if(isbear(L)) continue
|
||||
if(!L.stat)
|
||||
stance_step = max(0, stance_step) //If we have not seen a mob in a while, the stance_step will be negative, we need to reset it to 0 as soon as we see a mob again.
|
||||
stance_step++
|
||||
found_mob = 1
|
||||
target_mob = L
|
||||
src.dir = get_dir(src,target_mob) //Keep staring at the mob
|
||||
|
||||
if(stance_step in list(1,4,7)) //every 3 ticks
|
||||
var/action = pick( list( "growls at [L]", "stares angrily at [L]", "prepares to attack [L]", "closely watches [L]" ) )
|
||||
if(action)
|
||||
emote(action)
|
||||
break
|
||||
if(!found_mob)
|
||||
stance_step--
|
||||
|
||||
if(stance_step <= -20) //If we have not found a mob for 20-ish ticks, revert to idle mode
|
||||
stance = BEAR_STANCE_IDLE
|
||||
if(stance_step >= 7) //If we have been staring at a mob for 7 ticks,
|
||||
stance = BEAR_STANCE_ATTACK
|
||||
if(BEAR_STANCE_ATTACK) //This one should only be active for one tick,
|
||||
stop_automated_movement = 1
|
||||
if(!target_mob || target_mob.stat)
|
||||
stance = BEAR_STANCE_ALERT
|
||||
stance_step = 5 //Make it very alert, so it quickly attacks again if a mob returns
|
||||
if(target_mob in viewers(7,src))
|
||||
walk_to(src, target_mob, 1, 3)
|
||||
stance = BEAR_STANCE_ATTACKING
|
||||
stance_step = 0
|
||||
if(BEAR_STANCE_ATTACKING)
|
||||
|
||||
stop_automated_movement = 1
|
||||
stance_step++
|
||||
if(!target_mob || target_mob.stat)
|
||||
stance = BEAR_STANCE_ALERT
|
||||
stance_step = 5 //Make it very alert, so it quickly attacks again if a mob returns
|
||||
return
|
||||
if(!(target_mob in viewers(7,src)))
|
||||
stance = BEAR_STANCE_ALERT
|
||||
stance_step = 5 //Make it very alert, so it quickly attacks again if a mob returns
|
||||
target_mob = null
|
||||
return
|
||||
if(get_dist(src, target_mob) <= 1) //Attacking
|
||||
emote( pick( list("slashes at [target_mob]", "bites [target_mob]") ) )
|
||||
|
||||
var/damage = rand(20,30)
|
||||
|
||||
if(ishuman(target_mob))
|
||||
var/mob/living/carbon/human/H = target_mob
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/datum/organ/external/affecting = H.get_organ(ran_zone(dam_zone))
|
||||
H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"))
|
||||
else if(isliving(target_mob))
|
||||
var/mob/living/L = target_mob
|
||||
L.adjustBruteLoss(damage)
|
||||
|
||||
if(stance_step >= 20) //attacks for 20 ticks, then it gets tired and needs to rest
|
||||
emote( "is worn out and needs to rest" )
|
||||
stance = BEAR_STANCE_TIRED
|
||||
stance_step = 0
|
||||
walk(src, 0) //This stops the bear's walking
|
||||
return
|
||||
if(BEAR_STANCE_TIRED)
|
||||
stop_automated_movement = 1
|
||||
stance_step++
|
||||
if(stance_step >= 10) //rests for 10 ticks
|
||||
if(target_mob && target_mob in viewers(7,src))
|
||||
stance = BEAR_STANCE_ATTACK //If the mob he was chasing is still nearby, resume the attack, otherwise go idle.
|
||||
else
|
||||
stance = BEAR_STANCE_IDLE
|
||||
|
||||
|
||||
/mob/living/simple_animal/bear/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if(stance != BEAR_STANCE_ATTACK && stance != BEAR_STANCE_ATTACKING)
|
||||
stance = BEAR_STANCE_ALERT
|
||||
stance_step = 6
|
||||
target_mob = user
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bear/attack_hand(mob/living/carbon/human/M as mob)
|
||||
if(stance != BEAR_STANCE_ATTACK && stance != BEAR_STANCE_ATTACKING)
|
||||
stance = BEAR_STANCE_ALERT
|
||||
stance_step = 6
|
||||
target_mob = M
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bear/Process_Spacemove(var/check_drift = 0)
|
||||
return //No drifting in space for space bears!
|
||||
@@ -0,0 +1,185 @@
|
||||
#define CARP_STANCE_IDLE 1
|
||||
#define CARP_STANCE_ATTACK 2
|
||||
#define CARP_STANCE_ATTACKING 3
|
||||
|
||||
/mob/living/simple_animal/carp
|
||||
name = "space carp"
|
||||
desc = "A ferocious, fang-bearing creature that resembles a fish."
|
||||
icon_state = "carp"
|
||||
icon_living = "carp"
|
||||
icon_dead = "carp_dead"
|
||||
icon_gib = "carp_gib"
|
||||
speak_chance = 0
|
||||
turns_per_move = 5
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "hits the"
|
||||
|
||||
stop_automated_movement_when_pulled = 0
|
||||
maxHealth = 25
|
||||
health = 25
|
||||
|
||||
harm_intent_damage = 8
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 15
|
||||
attacktext = "bites"
|
||||
attack_sound = 'bite.ogg'
|
||||
|
||||
//Space carp aren't affected by atmos.
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
minbodytemp = 0 //so they don't freeze in space
|
||||
maxbodytemp = 295 //if it's just 25 degrees, they start to burn up
|
||||
|
||||
var/stance = CARP_STANCE_IDLE //Used to determine behavior
|
||||
var/stance_step = 0 //Used to delay checks depending on what stance the bear is in
|
||||
var/mob/living/target_mob //Once the bear enters attack stance, it will try to chase this mob. This it to prevent it changing it's mind between multiple mobs.
|
||||
heat_damage_per_tick = 1
|
||||
|
||||
/mob/living/simple_animal/carp/elite
|
||||
desc = "A ferocious, fang-bearing creature that resembles a fish. It has an evil gleam in its eye."
|
||||
maxHealth = 50
|
||||
health = 50
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 20
|
||||
|
||||
/proc/iscarp(var/mob/M)
|
||||
return istype(M, /mob/living/simple_animal/carp)
|
||||
|
||||
/mob/living/simple_animal/carp/Life()
|
||||
..()
|
||||
|
||||
if(!stat)
|
||||
switch(stance)
|
||||
if(CARP_STANCE_IDLE)
|
||||
stop_automated_movement = 0
|
||||
stance_step++
|
||||
if(stance_step > 5)
|
||||
stance_step = 0
|
||||
for( var/mob/living/L in viewers(7,src) )
|
||||
if(iscarp(L)) continue
|
||||
if(!L.stat)
|
||||
if(prob(50))
|
||||
src.visible_message("<b>[src]</b> gnashes at [L]!")
|
||||
stance = CARP_STANCE_ATTACK
|
||||
target_mob = L
|
||||
break
|
||||
|
||||
if(CARP_STANCE_ATTACK) //This one should only be active for one tick
|
||||
stop_automated_movement = 1
|
||||
if(!target_mob || target_mob.stat)
|
||||
stance = CARP_STANCE_IDLE
|
||||
stance_step = 5 //Make it very alert, so it quickly attacks again if a mob returns
|
||||
if(target_mob in viewers(7,src))
|
||||
walk_to(src, target_mob, 1, 3)
|
||||
stance = CARP_STANCE_ATTACKING
|
||||
stance_step = 0
|
||||
|
||||
if(CARP_STANCE_ATTACKING)
|
||||
stop_automated_movement = 1
|
||||
stance_step++
|
||||
if(!target_mob || target_mob.stat)
|
||||
stance = CARP_STANCE_IDLE
|
||||
stance_step = 4 //Make it very alert, so it quickly attacks again if a mob returns
|
||||
target_mob = null
|
||||
walk(src,0)
|
||||
return
|
||||
if(!(target_mob in viewers(7,src)))
|
||||
stance = CARP_STANCE_IDLE
|
||||
stance_step = 1
|
||||
target_mob = null
|
||||
walk(src,0)
|
||||
return
|
||||
if(get_dist(src, target_mob) <= 1) //Attacking
|
||||
if(isliving(target_mob))
|
||||
var/mob/living/L = target_mob
|
||||
L.attack_animal(src)
|
||||
if(prob(10))
|
||||
L.Weaken(5)
|
||||
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
|
||||
|
||||
/mob/living/simple_animal/carp/Die()
|
||||
..()
|
||||
target_mob = null
|
||||
stance = CARP_STANCE_IDLE
|
||||
walk(src,0)
|
||||
|
||||
/mob/living/simple_animal/carp/Process_Spacemove(var/check_drift = 0)
|
||||
return 0 //No drifting in space for space carp! //original comments do not steal
|
||||
|
||||
/mob/living/simple_animal/carp/Process_Spaceslipping(var/prob_slip = 5)
|
||||
return 0
|
||||
|
||||
//----
|
||||
|
||||
/mob/living/simple_animal/carp/cyborg
|
||||
name = "cyborg space carp"
|
||||
desc = "A ferocious, fang-bearing cyborg that resembles a fish. It has glowing red eyes."
|
||||
speak = list("Objective established.","Goal: Terminate.","Mission parameters defined.","All casualties are acceptable.")
|
||||
speak_emote = list("beeps")
|
||||
emote_hear = list("makes a sinister clanking noise.","hisses and steams.","makes a menacing beeping noise.")
|
||||
emote_see = list("sparks slightly.","flashes a red light ominously.")
|
||||
speak_chance = 10
|
||||
var/firing = 0
|
||||
|
||||
/mob/living/simple_animal/carp/cyborg/Life()
|
||||
..()
|
||||
walk(src,0)
|
||||
|
||||
if(!stat)
|
||||
if(prob(5))
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
switch(stance)
|
||||
if(CARP_STANCE_ATTACKING)
|
||||
if(target_mob)
|
||||
src.dir = get_dir(src, target_mob)
|
||||
/*if(get_dist(src, target_mob) > 5)
|
||||
step_towards(src,target_mob)*/
|
||||
if(get_dist(src, target_mob) > 1 && !firing)
|
||||
//fire laser eyes
|
||||
firing = 1
|
||||
if(prob(40))
|
||||
emote("auto",1,"[pick("makes an ominous whining noise!","makes a low humming noise!","begins charging up something!")]")
|
||||
|
||||
spawn(40)
|
||||
if(!target_mob)
|
||||
return
|
||||
firing = 0
|
||||
//load_into_chamber()
|
||||
var/obj/item/projectile/beam/B = new(src)
|
||||
|
||||
B.firer = src
|
||||
//B.def_zone = targloc
|
||||
//in_chamber.def_zone = user.zone_sel.selecting
|
||||
|
||||
var/turf/targloc = get_turf(target_mob)
|
||||
var/turf/myloc = get_turf(src)
|
||||
|
||||
B.original = targloc
|
||||
B.loc = myloc
|
||||
B.starting = myloc
|
||||
B.silenced = 0
|
||||
B.current = myloc
|
||||
B.yo = targloc.y - myloc.y
|
||||
B.xo = targloc.x - myloc.x
|
||||
//
|
||||
B.fired()
|
||||
|
||||
//shake the camera? probably not, these lasers don't explode... yet
|
||||
/*for(var/mob/M in view(src,7))
|
||||
shake_camera(user, recoil + 1, recoil)*/
|
||||
playsound(src, pick('pulse.ogg','pulse2.ogg','pulse3.ogg'), 50, 1)
|
||||
|
||||
/mob/living/simple_animal/carp/cyborg/Die()
|
||||
if(prob(15))
|
||||
src.say_auto("I'll be back!")
|
||||
..()
|
||||
@@ -1,8 +1,7 @@
|
||||
//Cat
|
||||
/mob/living/simple_animal/cat
|
||||
name = "cat"
|
||||
desc = "Kitty!!"
|
||||
icon = 'mob.dmi'
|
||||
desc = "A domesticated, feline pet. Has a tendency to adopt crewmembers."
|
||||
icon_state = "cat"
|
||||
icon_living = "cat"
|
||||
icon_dead = "cat_dead"
|
||||
@@ -13,15 +12,48 @@
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/sliceable/meat
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "kicks the"
|
||||
var/turns_since_scan = 0
|
||||
var/mob/living/simple_animal/mouse/movement_target
|
||||
|
||||
/mob/living/simple_animal/cat/Life()
|
||||
//MICE!
|
||||
if((src.loc) && isturf(src.loc))
|
||||
if(!stat && !resting && !buckled)
|
||||
for(var/mob/living/simple_animal/mouse/M in view(1,src))
|
||||
if(!M.stat)
|
||||
M.splat()
|
||||
emote("splats \the [M]")
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
break
|
||||
|
||||
..()
|
||||
|
||||
if(!stat && !resting && !buckled)
|
||||
turns_since_scan++
|
||||
if(turns_since_scan > 5)
|
||||
walk_to(src,0)
|
||||
turns_since_scan = 0
|
||||
if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) ))
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
if( !movement_target || !(movement_target.loc in oview(src, 3)) )
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
for(var/mob/living/simple_animal/mouse/snack in oview(src,3))
|
||||
if(isturf(snack.loc) && !snack.stat)
|
||||
movement_target = snack
|
||||
break
|
||||
if(movement_target)
|
||||
stop_automated_movement = 1
|
||||
walk_to(src,movement_target,0,3)
|
||||
|
||||
//RUNTIME IS ALIVE! SQUEEEEEEEE~
|
||||
/mob/living/simple_animal/cat/Runtime
|
||||
name = "Runtime"
|
||||
desc = ""
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
desc = "Its fur has the look and feel of velvet, and it's tail quivers occasionally."
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
name = "\improper corgi"
|
||||
real_name = "corgi"
|
||||
desc = "It's a corgi."
|
||||
icon = 'mob.dmi'
|
||||
icon_state = "corgi"
|
||||
icon_living = "corgi"
|
||||
icon_dead = "corgi_dead"
|
||||
@@ -13,41 +12,16 @@
|
||||
emote_see = list("shakes its head", "shivers")
|
||||
speak_chance = 1
|
||||
turns_per_move = 10
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/sliceable/meat/corgi
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/corgi
|
||||
meat_amount = 3
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_disarm = "bops the"
|
||||
response_harm = "kicks the"
|
||||
see_in_dark = 5
|
||||
var/obj/item/inventory_head
|
||||
var/obj/item/inventory_back
|
||||
var/obj/item/inventory_mouth
|
||||
|
||||
/mob/living/simple_animal/corgi/update_clothing()
|
||||
overlays = list()
|
||||
|
||||
if(inventory_head)
|
||||
var/head_icon_state = inventory_head.icon_state
|
||||
if(health <= 0)
|
||||
head_icon_state += "2"
|
||||
|
||||
var/icon/head_icon = icon('corgi_head.dmi',head_icon_state)
|
||||
if(head_icon)
|
||||
overlays += head_icon
|
||||
|
||||
if(inventory_back)
|
||||
var/back_icon_state = inventory_back.icon_state
|
||||
if(health <= 0)
|
||||
back_icon_state += "2"
|
||||
|
||||
var/icon/back_icon = icon('corgi_back.dmi',back_icon_state)
|
||||
if(back_icon)
|
||||
overlays += back_icon
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/corgi/Life()
|
||||
..()
|
||||
rebuild_appearance()
|
||||
var/turns_since_scan = 0
|
||||
var/obj/movement_target
|
||||
|
||||
/mob/living/simple_animal/corgi/show_inv(mob/user as mob)
|
||||
/*
|
||||
@@ -104,7 +78,6 @@
|
||||
emote_hear = list("barks", "woofs", "yaps","pants")
|
||||
emote_see = list("shakes its head", "shivers")
|
||||
desc = "It's a corgi."
|
||||
src.ul_SetLuminosity(0)
|
||||
inventory_head.loc = src.loc
|
||||
inventory_head = null
|
||||
else
|
||||
@@ -148,7 +121,7 @@
|
||||
/obj/item/clothing/head/caphat,
|
||||
/obj/item/clothing/head/collectable/captain,
|
||||
/obj/item/clothing/head/that,
|
||||
/obj/item/clothing/head/helmet/that,
|
||||
/obj/item/clothing/head/that,
|
||||
/obj/item/clothing/head/kitty,
|
||||
/obj/item/clothing/head/collectable/kitty,
|
||||
/obj/item/clothing/head/rabbitears,
|
||||
@@ -166,13 +139,10 @@
|
||||
/obj/item/clothing/head/wizard/fake,
|
||||
/obj/item/clothing/head/wizard,
|
||||
/obj/item/clothing/head/collectable/wizard,
|
||||
/obj/item/clothing/head/helmet/hardhat,
|
||||
/obj/item/clothing/head/collectable/hardhat,
|
||||
/obj/item/clothing/head/helmet/hardhat/white,
|
||||
/obj/item/weapon/bedsheet,
|
||||
/obj/item/clothing/head/helmet/space/santahat,
|
||||
/obj/item/clothing/head/collectable/paper,
|
||||
/obj/item/clothing/head/cargosoft
|
||||
)
|
||||
|
||||
if( ! ( item_to_add.type in allowed_types ) )
|
||||
@@ -182,6 +152,7 @@
|
||||
usr.drop_item()
|
||||
item_to_add.loc = src
|
||||
src.inventory_head = item_to_add
|
||||
rebuild_appearance()
|
||||
|
||||
//Various hats and items (worn on his head) change Ian's behaviour. His attributes are reset when a HAT is removed.
|
||||
|
||||
@@ -239,11 +210,6 @@
|
||||
name = "Rudolph the Red-Nosed Corgi"
|
||||
emote_hear = list("barks christmas songs", "yaps")
|
||||
desc = "He has a very shiny nose."
|
||||
src.ul_SetLuminosity(6)
|
||||
if(/obj/item/clothing/head/cargosoft)
|
||||
name = "Corgi Tech [real_name]"
|
||||
speak = list("Needs a stamp!", "Request DENIED!", "Fill these out in triplicate!")
|
||||
desc = "The reason your yellow gloves have chew-marks."
|
||||
|
||||
if("back")
|
||||
if(inventory_back)
|
||||
@@ -269,29 +235,18 @@
|
||||
usr.drop_item()
|
||||
item_to_add.loc = src
|
||||
src.inventory_back = item_to_add
|
||||
update_clothing()
|
||||
rebuild_appearance()
|
||||
|
||||
//show_inv(usr) //Commented out because changing Ian's name and then calling up his inventory opens a new inventory...which is annoying.
|
||||
else
|
||||
..()
|
||||
|
||||
//IAN! SQUEEEEEEEEE~
|
||||
/mob/living/simple_animal/corgi/Ian
|
||||
name = "Ian"
|
||||
real_name = "Ian" //Intended to hold the name without altering it.
|
||||
gender = "male"
|
||||
desc = "It's a corgi."
|
||||
var/turns_since_scan = 0
|
||||
var/obj/movement_target
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
|
||||
/mob/living/simple_animal/corgi/Ian/Life()
|
||||
/mob/living/simple_animal/corgi/Life()
|
||||
..()
|
||||
rebuild_appearance()
|
||||
|
||||
//Feeding, chasing food, FOOOOODDDD
|
||||
if(alive && !resting && !buckled)
|
||||
if(!stat && !resting && !buckled)
|
||||
turns_since_scan++
|
||||
if(turns_since_scan > 5)
|
||||
turns_since_scan = 0
|
||||
@@ -338,11 +293,11 @@
|
||||
dir = i
|
||||
sleep(1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/sliceable/meat/corgi
|
||||
/obj/item/weapon/reagent_containers/food/snacks/meat/corgi
|
||||
name = "Corgi meat"
|
||||
desc = "Tastes like... well you know..."
|
||||
|
||||
/mob/living/simple_animal/corgi/Ian/Bump(atom/movable/AM as mob|obj, yes)
|
||||
/mob/living/simple_animal/corgi/Bump(atom/movable/AM as mob|obj, yes)
|
||||
|
||||
spawn( 0 )
|
||||
if ((!( yes ) || now_pushing))
|
||||
@@ -350,11 +305,11 @@
|
||||
now_pushing = 1
|
||||
if(ismob(AM))
|
||||
var/mob/tmob = AM
|
||||
/* if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations))
|
||||
if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations))
|
||||
if(prob(70))
|
||||
src << "\red <B>You fail to push [tmob]'s fat ass out of the way.</B>"
|
||||
now_pushing = 0
|
||||
return*/
|
||||
return
|
||||
if(tmob.nopush)
|
||||
now_pushing = 0
|
||||
return
|
||||
@@ -388,7 +343,7 @@
|
||||
|
||||
/mob/living/simple_animal/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
|
||||
if(istype(O, /obj/item/weapon/newspaper))
|
||||
if(alive)
|
||||
if(!stat)
|
||||
for(var/mob/M in viewers(user, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\blue [user] baps [name] on the nose with the rolled up [O]")
|
||||
@@ -397,4 +352,14 @@
|
||||
dir = i
|
||||
sleep(1)
|
||||
else
|
||||
..()
|
||||
..()
|
||||
|
||||
//IAN! SQUEEEEEEEEE~
|
||||
/mob/living/simple_animal/corgi/Ian
|
||||
name = "Ian"
|
||||
real_name = "Ian" //Intended to hold the name without altering it.
|
||||
gender = "male"
|
||||
desc = "It's a somewhat notorious corgi."
|
||||
response_help = "pets"
|
||||
response_disarm = "bops"
|
||||
response_harm = "kicks"
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
//Look Sir, free crabs!
|
||||
/mob/living/simple_animal/crab
|
||||
name = "crab"
|
||||
desc = "Free crabs!"
|
||||
icon = 'mob.dmi'
|
||||
desc = "A hard-shelled crustacean. Seems quite content to lounge around all the time."
|
||||
icon_state = "crab"
|
||||
icon_living = "crab"
|
||||
icon_dead = "crab_dead"
|
||||
@@ -11,59 +10,22 @@
|
||||
emote_see = list("clacks")
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/sliceable/meat
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "stomps the"
|
||||
stop_automated_movement = 1
|
||||
friendly = "pinches"
|
||||
var/obj/item/inventory_head
|
||||
var/obj/item/inventory_mask
|
||||
|
||||
/mob/living/simple_animal/crab/Life()
|
||||
..()
|
||||
//CRAB movement
|
||||
if(!ckey && alive)
|
||||
if(!ckey && !stat)
|
||||
if(isturf(src.loc) && !resting && !buckled) //This is so it only moves if it's not inside a closet, gentics machine, etc.
|
||||
turns_since_move++
|
||||
if(turns_since_move >= turns_per_move)
|
||||
Move(get_step(src,pick(4,8)))
|
||||
turns_since_move = 0
|
||||
|
||||
//COFFEE! SQUEEEEEEEEE!
|
||||
/mob/living/simple_animal/crab/Coffee
|
||||
name = "Coffee"
|
||||
desc = "It's Coffee, the other pet!"
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "stomps"
|
||||
|
||||
//LOOK AT THIS - ..()??
|
||||
/mob/living/simple_animal/crab/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if(istype(O, /obj/item/weapon/wirecutters))
|
||||
user << "\red \b This kills the crab."
|
||||
health -= 20
|
||||
Die()
|
||||
if(istype(O, /obj/item/stack/medical))
|
||||
if(alive)
|
||||
var/obj/item/stack/medical/MED = O
|
||||
if(health < maxHealth)
|
||||
if(MED.amount >= 1)
|
||||
health = min(maxHealth, health + MED.heal_brute)
|
||||
MED.amount -= 1
|
||||
if(MED.amount <= 0)
|
||||
del(MED)
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\blue [user] applies the [MED] on [src]")
|
||||
else
|
||||
user << "\blue this [src] is dead, medical items won't bring it back to life."
|
||||
else
|
||||
if(O.force)
|
||||
health -= O.force
|
||||
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
|
||||
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]. ")
|
||||
rebuild_appearance()
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
//kobold
|
||||
/mob/living/simple_animal/kobold
|
||||
name = "kobold"
|
||||
desc = "A small, rat-like creature."
|
||||
icon = 'mob.dmi'
|
||||
icon_state = "kobold_idle"
|
||||
icon_living = "kobold_idle"
|
||||
icon_dead = "kobold_dead"
|
||||
//speak = list("You no take candle!","Ooh, pretty shiny.","Me take?","Where gold here...","Me likey.")
|
||||
speak_emote = list("mutters","hisses","grumbles")
|
||||
emote_hear = list("mutters under it's breath.","grumbles.", "yips!")
|
||||
emote_see = list("looks around suspiciously.", "scratches it's arm.","putters around a bit.")
|
||||
speak_chance = 15
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/sliceable/meat
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "kicks the"
|
||||
minbodytemp = 250
|
||||
min_oxy = 1
|
||||
|
||||
/mob/living/simple_animal/kobold/Life()
|
||||
..()
|
||||
if(prob(15) && turns_since_move && !stat)
|
||||
flick("kobold_act",src)
|
||||
|
||||
/mob/living/simple_animal/kobold/Move(var/dir)
|
||||
..()
|
||||
if(!stat)
|
||||
flick("kobold_walk",src)
|
||||
@@ -1,414 +0,0 @@
|
||||
/mob/living/simple_animal
|
||||
name = "animal"
|
||||
var/icon_living = ""
|
||||
var/icon_dead = ""
|
||||
maxHealth = 20
|
||||
var/alive = 1
|
||||
var/list/speak = list()
|
||||
var/list/speak_emote = list()// Emotes while speaking IE: Ian [emote], [text] -- Ian barks, "WOOF!". Spoken text is generated from the speak variable.
|
||||
var/speak_chance = 0
|
||||
var/list/emote_hear = list() //EHearable emotes
|
||||
var/list/emote_see = list() //Unlike speak_emote, the list of things in this variable only show by themselves with no spoken text. IE: Ian barks, Ian yaps
|
||||
health = 20
|
||||
var/turns_per_move = 1
|
||||
var/turns_since_move = 0
|
||||
universal_speak = 1
|
||||
var/meat_amount = 0
|
||||
var/meat_type
|
||||
var/stop_automated_movement = 0 //Use this to temporarely stop random movement or to if you write special movement code for animals.
|
||||
|
||||
//Interaction
|
||||
var/response_help = "You try to help"
|
||||
var/response_disarm = "You try to disarm"
|
||||
var/response_harm = "You try to hurt"
|
||||
var/harm_intent_damage = 3
|
||||
|
||||
//Temperature effect
|
||||
var/minbodytemp = 270
|
||||
var/maxbodytemp = 370
|
||||
var/heat_damage_per_tick = 3 //amount of damage applied if animal's body temperature is higher than maxbodytemp
|
||||
var/cold_damage_per_tick = 2 //same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp
|
||||
|
||||
//Atmos effect - Yes, you can make creatures that require plasma or co2 to survive. N2O is a trace gas and handled separately, hence why it isn't here. It'd be hard to add it. Hard and me don't mix (Yes, yes make all the dick jokes you want with that.) - Errorage
|
||||
var/min_oxy = 5
|
||||
var/max_oxy = 0 //Leaving something at 0 means it's off - has no maximum
|
||||
var/min_tox = 0
|
||||
var/max_tox = 1
|
||||
var/min_co2 = 0
|
||||
var/max_co2 = 5
|
||||
var/min_n2 = 0
|
||||
var/max_n2 = 0
|
||||
var/unsuitable_atoms_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above
|
||||
|
||||
|
||||
//LETTING SIMPLE ANIMALS ATTACK? WHAT COULD GO WRONG. Defaults to zero so Ian can still be cuddly
|
||||
var/melee_damage_lower = 0
|
||||
var/melee_damage_upper = 0
|
||||
var/attacktext = "attacks"
|
||||
var/attack_sound = null
|
||||
var/friendly = "nuzzles" //If the mob does no damage with it's attack
|
||||
var/wall_smash = 0 //if they can smash walls
|
||||
|
||||
var/speed = 0 //LETS SEE IF I CAN SET SPEEDS FOR SIMPLE MOBS WITHOUT DESTROYING EVERYTHING. Higher speed is slower, negative speed is faster
|
||||
|
||||
var/obj/item/device/radio/headset/ears = null
|
||||
/mob/living/simple_animal/New()
|
||||
..()
|
||||
verbs -= /mob/verb/observe
|
||||
|
||||
/mob/living/simple_animal/Login()
|
||||
if(src && src.client)
|
||||
src.client.screen = null
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/Life()
|
||||
|
||||
//Health
|
||||
if(!alive)
|
||||
if(health > 0)
|
||||
icon_state = icon_living
|
||||
alive = 1
|
||||
stat = CONSCIOUS
|
||||
density = 1
|
||||
return
|
||||
|
||||
|
||||
if(health < 1)
|
||||
Die()
|
||||
|
||||
if(health > maxHealth)
|
||||
health = maxHealth
|
||||
|
||||
/*
|
||||
// Stun/Weaken
|
||||
|
||||
if (paralysis || stunned || weakened) //Stunned etc.
|
||||
if (stunned > 0)
|
||||
AdjustStunned(-1)
|
||||
stat = 0
|
||||
if (weakened > 0)
|
||||
AdjustWeakened(-1)
|
||||
lying = 1
|
||||
stat = 0
|
||||
if (paralysis > 0)
|
||||
AdjustParalysis(-1)
|
||||
blinded = 1
|
||||
lying = 1
|
||||
stat = 1
|
||||
var/h = hand
|
||||
hand = 0
|
||||
drop_item()
|
||||
hand = 1
|
||||
drop_item()
|
||||
hand = h
|
||||
|
||||
else //Not stunned.
|
||||
lying = 0
|
||||
stat = 0
|
||||
|
||||
if(paralysis || stunned || weakened || buckled)
|
||||
canmove = 0
|
||||
else
|
||||
canmove = 1
|
||||
*/
|
||||
//Movement
|
||||
if(!ckey && !stop_automated_movement)
|
||||
if(isturf(src.loc) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc.
|
||||
turns_since_move++
|
||||
if(turns_since_move >= turns_per_move)
|
||||
Move(get_step(src,pick(cardinal)))
|
||||
turns_since_move = 0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Speaking
|
||||
if(speak_chance)
|
||||
if(prob(speak_chance))
|
||||
if(speak && speak.len)
|
||||
if((emote_hear && emote_hear.len) || (emote_see && emote_see.len))
|
||||
var/length = speak.len
|
||||
if(emote_hear && emote_hear.len)
|
||||
length += emote_hear.len
|
||||
if(emote_see && emote_see.len)
|
||||
length += emote_see.len
|
||||
var/randomValue = rand(1,length)
|
||||
if(randomValue <= speak.len)
|
||||
say(pick(speak))
|
||||
else
|
||||
randomValue -= speak.len
|
||||
if(emote_see && randomValue <= emote_see.len)
|
||||
emote(pick(emote_see),1)
|
||||
else
|
||||
emote(pick(emote_hear),2)
|
||||
else
|
||||
say(pick(speak))
|
||||
else
|
||||
if(!(emote_hear && emote_hear.len) && (emote_see && emote_see.len))
|
||||
emote(pick(emote_see),1)
|
||||
if((emote_hear && emote_hear.len) && !(emote_see && emote_see.len))
|
||||
emote(pick(emote_hear),2)
|
||||
if((emote_hear && emote_hear.len) && (emote_see && emote_see.len))
|
||||
var/length = emote_hear.len + emote_see.len
|
||||
var/pick = rand(1,length)
|
||||
if(pick <= emote_see.len)
|
||||
emote(pick(emote_see),1)
|
||||
else
|
||||
emote(pick(emote_hear),2)
|
||||
|
||||
|
||||
//Atmos
|
||||
var/atmos_suitable = 1
|
||||
|
||||
var/atom/A = src.loc
|
||||
if(isturf(A))
|
||||
var/turf/T = A
|
||||
var/areatemp = T.temperature
|
||||
if( abs(areatemp - bodytemperature) > 50 )
|
||||
var/diff = areatemp - bodytemperature
|
||||
diff = diff / 5
|
||||
//world << "changed from [bodytemperature] by [diff] to [bodytemperature + diff]"
|
||||
bodytemperature += diff
|
||||
|
||||
if(istype(T,/turf/simulated))
|
||||
var/turf/simulated/ST = T
|
||||
if(ST.air)
|
||||
var/tox = ST.air.toxins
|
||||
var/oxy = ST.air.oxygen
|
||||
var/n2 = ST.air.nitrogen
|
||||
var/co2 = ST.air.carbon_dioxide
|
||||
|
||||
if(min_oxy)
|
||||
if(oxy < min_oxy)
|
||||
atmos_suitable = 0
|
||||
if(max_oxy)
|
||||
if(oxy > max_oxy)
|
||||
atmos_suitable = 0
|
||||
if(min_tox)
|
||||
if(tox < min_tox)
|
||||
atmos_suitable = 0
|
||||
if(max_tox)
|
||||
if(tox > max_tox)
|
||||
atmos_suitable = 0
|
||||
if(min_n2)
|
||||
if(n2 < min_n2)
|
||||
atmos_suitable = 0
|
||||
if(max_n2)
|
||||
if(n2 > max_n2)
|
||||
atmos_suitable = 0
|
||||
if(min_co2)
|
||||
if(co2 < min_co2)
|
||||
atmos_suitable = 0
|
||||
if(max_co2)
|
||||
if(co2 > max_co2)
|
||||
atmos_suitable = 0
|
||||
|
||||
//Atmos effect
|
||||
if(bodytemperature < minbodytemp)
|
||||
health -= cold_damage_per_tick
|
||||
else if(bodytemperature > maxbodytemp)
|
||||
health -= heat_damage_per_tick
|
||||
|
||||
if(!atmos_suitable)
|
||||
health -= unsuitable_atoms_damage
|
||||
|
||||
/mob/living/simple_animal/Bumped(AM as mob|obj)
|
||||
if(!AM) return
|
||||
if(isturf(src.loc) && !resting && !buckled)
|
||||
if(ismob(AM))
|
||||
var/newamloc = src.loc
|
||||
src.loc = AM:loc
|
||||
AM:loc = newamloc
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/gib()
|
||||
if(meat_amount && meat_type)
|
||||
for(var/i = 0; i < meat_amount; i++)
|
||||
new meat_type(src.loc)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/say_quote(var/text)
|
||||
if(speak_emote && speak_emote.len)
|
||||
var/emote = pick(speak_emote)
|
||||
if(emote)
|
||||
return "[emote], \"[text]\""
|
||||
return "says, \"[text]\"";
|
||||
|
||||
/mob/living/simple_animal/emote(var/act,var/m_type=1,var/message = null)
|
||||
switch(act)
|
||||
|
||||
if ("scream")
|
||||
message = "<B>[src]</B> screams!"
|
||||
m_type = 2
|
||||
|
||||
if ("custom")
|
||||
var/input = copytext(sanitize(input("Choose an emote to display.") as text|null),1,MAX_MESSAGE_LEN)
|
||||
if (!input)
|
||||
return
|
||||
var/input2 = input("Is this a visible or hearable emote?") in list("Visible","Hearable")
|
||||
if (input2 == "Visible")
|
||||
m_type = 1
|
||||
else if (input2 == "Hearable")
|
||||
m_type = 2
|
||||
else
|
||||
alert("Unable to use this emote, must be either hearable or visible.")
|
||||
return
|
||||
message = "<B>[src]</B> [input]"
|
||||
|
||||
if ("me")
|
||||
if(silent)
|
||||
return
|
||||
if (src.client && (client.muted || client.muted_complete))
|
||||
src << "You are muted."
|
||||
return
|
||||
if (stat)
|
||||
return
|
||||
if(!(message))
|
||||
return
|
||||
else
|
||||
if(cmptext(copytext(message, 1, 3), "v "))
|
||||
message = "<B>[src]</B> [copytext(message, 3)]"
|
||||
m_type = 1
|
||||
else if(cmptext(copytext(message, 1, 3), "h "))
|
||||
message = "<B>[src]</B> [copytext(message, 3)]"
|
||||
m_type = 2
|
||||
else
|
||||
message = "<B>[src]</B> [message]"
|
||||
else
|
||||
src << text("Invalid Emote: []", act)
|
||||
if ((message && src.stat == 0))
|
||||
if (m_type & 1)
|
||||
for(var/mob/O in viewers(src, null))
|
||||
O.show_message(message, m_type)
|
||||
else
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message(message, m_type)
|
||||
return
|
||||
|
||||
|
||||
/mob/living/simple_animal/attack_animal(mob/living/simple_animal/M as mob)
|
||||
if(M.melee_damage_upper == 0)
|
||||
M.emote("[M.friendly] [src]")
|
||||
else
|
||||
for(var/mob/O in viewers(src, null))
|
||||
O.show_message("\red <B>[M]</B> [M.attacktext] [src]!", 1)
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
health -= damage
|
||||
|
||||
/mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(!Proj) return
|
||||
src.health -= Proj.damage
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/attack_hand(mob/living/carbon/human/M as mob)
|
||||
..()
|
||||
|
||||
switch(M.a_intent)
|
||||
|
||||
if ("help")
|
||||
if (health > 0)
|
||||
for(var/mob/O in viewers(src, null))
|
||||
if ((O.client && !( O.blinded )))
|
||||
O.show_message("\blue [M] [response_help] [src]")
|
||||
|
||||
if ("grab")
|
||||
if (M == src)
|
||||
return
|
||||
if (nopush)
|
||||
return
|
||||
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M )
|
||||
G.assailant = M
|
||||
if (M.hand)
|
||||
M.l_hand = G
|
||||
else
|
||||
M.r_hand = G
|
||||
G.layer = 20
|
||||
G.affecting = src
|
||||
grabbed_by += G
|
||||
G.synch()
|
||||
|
||||
LAssailant = M
|
||||
|
||||
for(var/mob/O in viewers(src, null))
|
||||
if ((O.client && !( O.blinded )))
|
||||
O.show_message(text("\red [] has grabbed [] passively!", M, src), 1)
|
||||
|
||||
if ("hurt")
|
||||
health -= harm_intent_damage
|
||||
for(var/mob/O in viewers(src, null))
|
||||
if ((O.client && !( O.blinded )))
|
||||
O.show_message("\red [M] [response_harm] [src]")
|
||||
|
||||
if ("disarm")
|
||||
for(var/mob/O in viewers(src, null))
|
||||
if ((O.client && !( O.blinded )))
|
||||
O.show_message("\blue [M] [response_disarm] [src]")
|
||||
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
|
||||
if(istype(O, /obj/item/stack/medical))
|
||||
if(alive)
|
||||
var/obj/item/stack/medical/MED = O
|
||||
if(health < maxHealth)
|
||||
if(MED.amount >= 1)
|
||||
health = min(maxHealth, health + MED.heal_brute)
|
||||
MED.amount -= 1
|
||||
if(MED.amount <= 0)
|
||||
del(MED)
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\blue [user] applies the [MED] on [src]")
|
||||
else
|
||||
user << "\blue this [src] is dead, medical items won't bring it back to life."
|
||||
else
|
||||
if(O.force)
|
||||
health -= O.force
|
||||
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
|
||||
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/movement_delay()
|
||||
var/tally = 0 //Incase I need to add stuff other than "speed" later
|
||||
|
||||
tally = speed
|
||||
|
||||
return tally
|
||||
|
||||
/mob/living/simple_animal/Stat()
|
||||
..()
|
||||
|
||||
statpanel("Status")
|
||||
stat(null, "Health: [round((health / maxHealth) * 100)]%")
|
||||
|
||||
/mob/living/simple_animal/proc/Die()
|
||||
alive = 0
|
||||
icon_state = icon_dead
|
||||
stat = DEAD
|
||||
density = 0
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/ex_act(severity)
|
||||
flick("flash", flash)
|
||||
switch (severity)
|
||||
if (1.0)
|
||||
health -= 500
|
||||
gib()
|
||||
return
|
||||
|
||||
if (2.0)
|
||||
health -= 60
|
||||
|
||||
|
||||
if(3.0)
|
||||
health -= 30
|
||||
@@ -0,0 +1,146 @@
|
||||
/mob/living/simple_animal/mouse
|
||||
name = "mouse"
|
||||
real_name = "mouse"
|
||||
desc = "It's a small, disease-ridden rodent."
|
||||
icon_state = "mouse_gray"
|
||||
icon_living = "mouse_gray"
|
||||
icon_dead = "mouse_gray_dead"
|
||||
speak = list("Squeek!","SQUEEK!","Squeek?")
|
||||
speak_emote = list("squeeks","squeeks","squiks")
|
||||
emote_hear = list("squeeks","squeaks","squiks")
|
||||
emote_see = list("runs in a circle", "shakes", "scritches at something")
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
health = 5
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "splats the"
|
||||
density = 0
|
||||
var/color //brown, gray and white
|
||||
layer = 2.5 //so they can hide under objects
|
||||
swap_on_mobbump = 0
|
||||
|
||||
/mob/living/simple_animal/mouse/Life()
|
||||
..()
|
||||
if(!stat && prob(speak_chance))
|
||||
for(var/mob/M in view())
|
||||
M << 'sound/effects/mousesqueek.ogg'
|
||||
|
||||
/mob/living/simple_animal/mouse/gray
|
||||
color = "gray"
|
||||
icon_state = "mouse_gray"
|
||||
|
||||
/mob/living/simple_animal/mouse/white
|
||||
color = "white"
|
||||
icon_state = "mouse_white"
|
||||
|
||||
/mob/living/simple_animal/mouse/brown
|
||||
color = "brown"
|
||||
icon_state = "mouse_brown"
|
||||
|
||||
/mob/living/simple_animal/mouse/New()
|
||||
if(!color)
|
||||
color = pick( list("brown","gray","white") )
|
||||
icon_state = "mouse_[color]"
|
||||
icon_living = "mouse_[color]"
|
||||
icon_dead = "mouse_[color]_dead"
|
||||
desc = "It's a small [color] rodent, often seen hiding in maintenance areas and making a nuisance of itself."
|
||||
|
||||
/mob/living/simple_animal/mouse/proc/splat()
|
||||
src.health = 0
|
||||
src.stat = DEAD
|
||||
src.icon_dead = "mouse_[color]_splat"
|
||||
src.icon_state = "mouse_[color]_splat"
|
||||
|
||||
/proc/ismouse(var/obj/O)
|
||||
return istype(O,/mob/living/simple_animal/mouse)
|
||||
|
||||
//copy paste from alien/larva, if that func is updated please update this one also
|
||||
/mob/living/simple_animal/mouse/verb/ventcrawl()
|
||||
set name = "Crawl through Vent"
|
||||
set desc = "Enter an air vent and crawl through the pipe system."
|
||||
set category = "Mouse"
|
||||
|
||||
// if(!istype(V,/obj/machinery/atmoalter/siphs/fullairsiphon/air_vent))
|
||||
// return
|
||||
var/obj/machinery/atmospherics/unary/vent_pump/vent_found
|
||||
var/welded = 0
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src))
|
||||
if(!v.welded)
|
||||
vent_found = v
|
||||
break
|
||||
else
|
||||
welded = 1
|
||||
if(vent_found)
|
||||
if(vent_found.network&&vent_found.network.normal_members.len)
|
||||
var/list/vents = list()
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members)
|
||||
if(temp_vent.loc == loc)
|
||||
continue
|
||||
vents.Add(temp_vent)
|
||||
var/list/choices = list()
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/vent in vents)
|
||||
if(vent.loc.z != loc.z)
|
||||
continue
|
||||
var/atom/a = get_turf(vent)
|
||||
choices.Add(a.loc)
|
||||
var/turf/startloc = loc
|
||||
var/obj/selection = input("Select a destination.", "Duct System") in choices
|
||||
var/selection_position = choices.Find(selection)
|
||||
if(loc==startloc)
|
||||
var/obj/target_vent = vents[selection_position]
|
||||
if(target_vent)
|
||||
for(var/mob/O in oviewers(src, null))
|
||||
if ((O.client && !( O.blinded )))
|
||||
O.show_message(text("<B>[src] scrambles into the ventillation ducts!</B>"), 1)
|
||||
loc = target_vent.loc
|
||||
else
|
||||
src << "\blue You need to remain still while entering a vent."
|
||||
else
|
||||
src << "\blue This vent is not connected to anything."
|
||||
else if(welded)
|
||||
src << "\red That vent is welded."
|
||||
else
|
||||
src << "\blue You must be standing on or beside an air vent to enter it."
|
||||
return
|
||||
|
||||
//copy paste from alien/larva, if that func is updated please update this one alsoghost
|
||||
/mob/living/simple_animal/mouse/verb/hide()
|
||||
set name = "Hide"
|
||||
set desc = "Allows to hide beneath tables or certain items. Toggled on or off."
|
||||
set category = "Mouse"
|
||||
|
||||
if (layer != TURF_LAYER+0.2)
|
||||
layer = TURF_LAYER+0.2
|
||||
src << text("\blue You are now hiding.")
|
||||
for(var/mob/O in oviewers(src, null))
|
||||
if ((O.client && !( O.blinded )))
|
||||
O << text("<B>[] scurries to the ground!</B>", src)
|
||||
else
|
||||
layer = MOB_LAYER
|
||||
src << text("\blue You have stopped hiding.")
|
||||
for(var/mob/O in oviewers(src, null))
|
||||
if ((O.client && !( O.blinded )))
|
||||
O << text("[] slowly peaks up from the ground...", src)
|
||||
|
||||
//make mice fit under tables etc? this was hacky, and not working
|
||||
/*
|
||||
/mob/living/simple_animal/mouse/Move(var/dir)
|
||||
|
||||
var/turf/target_turf = get_step(src,dir)
|
||||
//CanReachThrough(src.loc, target_turf, src)
|
||||
var/can_fit_under = 0
|
||||
if(target_turf.ZCanPass(get_turf(src),1))
|
||||
can_fit_under = 1
|
||||
|
||||
..(dir)
|
||||
if(can_fit_under)
|
||||
src.loc = target_turf
|
||||
for(var/d in cardinal)
|
||||
var/turf/O = get_step(T,d)
|
||||
//Simple pass check.
|
||||
if(O.ZCanPass(T, 1) && !(O in open) && !(O in closed) && O in possibles)
|
||||
open += O
|
||||
*/
|
||||
@@ -2,26 +2,26 @@
|
||||
name = "\improper Parrot"
|
||||
desc = "It's a parrot! No dirty words!"
|
||||
icon = 'mob.dmi'
|
||||
icon_state = "cat"
|
||||
icon_living = "cat"
|
||||
icon_dead = "cat_dead"
|
||||
icon_state = "parrot"
|
||||
icon_living = "parrot"
|
||||
icon_dead = "parrot_dead"
|
||||
speak = list("Hi","Hello!","Cracker?","BAWWWWK george mellons griffing me")
|
||||
speak_emote = list("squawks","says","yells")
|
||||
emote_hear = list("squawks","bawks")
|
||||
emote_see = list("flutters its wings", "glares at you")
|
||||
speak_chance = 1
|
||||
emote_hear = list("squawks.","bawks.")
|
||||
emote_see = list("flutters its wings.", "glares at you.")
|
||||
speak_chance = 5
|
||||
turns_per_move = 5
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/cracker/
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently moves aside the"
|
||||
response_harm = "swats the"
|
||||
|
||||
ears = new /obj/item/device/radio/headset/heads/ce()
|
||||
l_ear = new /obj/item/device/radio/headset/headset_eng()
|
||||
|
||||
/mob/living/simple_animal/parrot/DrProfessor
|
||||
name = "Doctor Professor Parrot, PhD"
|
||||
desc = "That's the Doctor Professor. He has more degrees than all of the engineering team put together, and has several published papers on quantum cracker theory."
|
||||
speak = list(":e Check the singlo, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN RIG SUIT?",":e OH GOD ITS FREE CALL THE SHUTTLE")
|
||||
speak = list(":e Check the singlo, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN RIG SUIT?",":e OH GOD ITS FREE CALL THE SHUTTLE",":e Open secure storage please.",":e I think something happened to the containment field...")
|
||||
response_harm = "is attacked in the face by"
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/cracker/
|
||||
@@ -33,8 +33,8 @@
|
||||
if(user.stat) return
|
||||
|
||||
var/dat = "<div align='center'><b>Inventory of [name]</b></div><p>"
|
||||
if(ears)
|
||||
dat += "<br><b>Headset:</b> [ears] (<a href='?src=\ref[src];remove_inv=ears'>Remove</a>)"
|
||||
if(l_ear)
|
||||
dat += "<br><b>Headset:</b> [l_ear] (<a href='?src=\ref[src];remove_inv=ears'>Remove</a>)"
|
||||
else
|
||||
dat += "<br><b>Headset:</b> <a href='?src=\ref[src];add_inv=ears'>Nothing</a>"
|
||||
|
||||
@@ -54,10 +54,10 @@
|
||||
var/remove_from = href_list["remove_inv"]
|
||||
switch(remove_from)
|
||||
if("ears")
|
||||
if(ears)
|
||||
if(l_ear)
|
||||
src.say(":e BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
|
||||
ears.loc = src.loc
|
||||
ears = null
|
||||
l_ear.loc = src.loc
|
||||
l_ear = null
|
||||
else
|
||||
usr << "\red There is nothing to remove from its [remove_from]."
|
||||
return
|
||||
@@ -72,7 +72,7 @@
|
||||
return
|
||||
switch(add_to)
|
||||
if("ears")
|
||||
if(ears)
|
||||
if(l_ear)
|
||||
usr << "\red It's already wearing something."
|
||||
return
|
||||
else
|
||||
@@ -86,6 +86,6 @@
|
||||
|
||||
usr.drop_item()
|
||||
item_to_add.loc = src
|
||||
src.ears = item_to_add
|
||||
src.l_ear = item_to_add
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/mob/living/simple_animal
|
||||
name = "animal"
|
||||
icon = 'animal.dmi'
|
||||
var/icon_living = ""
|
||||
var/icon_dead = ""
|
||||
var/icon_gib = null //We only try to show a gibbing animation if this exists.
|
||||
maxHealth = 20
|
||||
var/list/speak = list()
|
||||
var/list/speak_emote = list()// Emotes while speaking IE: Ian [emote], [text] -- Ian barks, "WOOF!". Spoken text is generated from the speak variable.
|
||||
var/speak_chance = 0
|
||||
var/list/emote_hear = list() //EHearable emotes
|
||||
var/list/emote_see = list() //Unlike speak_emote, the list of things in this variable only show by themselves with no spoken text. IE: Ian barks, Ian yaps
|
||||
health = 20
|
||||
var/turns_per_move = 1
|
||||
var/turns_since_move = 0
|
||||
universal_speak = 1
|
||||
var/meat_amount = 0
|
||||
var/meat_type
|
||||
var/stop_automated_movement = 0 //Use this to temporarely stop random movement or to if you write special movement code for animals.
|
||||
var/stop_automated_movement_when_pulled = 1 //When set to 1 this stops the animal from moving when someone is pulling it.
|
||||
|
||||
//Interaction
|
||||
var/response_help = "You try to help"
|
||||
var/response_disarm = "You try to disarm"
|
||||
var/response_harm = "You try to hurt"
|
||||
var/harm_intent_damage = 3
|
||||
|
||||
//Temperature effect
|
||||
var/minbodytemp = 270
|
||||
var/maxbodytemp = 325
|
||||
var/heat_damage_per_tick = 3 //amount of damage applied if animal's body temperature is higher than maxbodytemp
|
||||
var/cold_damage_per_tick = 2 //same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp
|
||||
|
||||
//Atmos effect - Yes, you can make creatures that require plasma or co2 to survive. N2O is a trace gas and handled separately, hence why it isn't here. It'd be hard to add it. Hard and me don't mix (Yes, yes make all the dick jokes you want with that.) - Errorage
|
||||
var/min_oxy = 5
|
||||
var/max_oxy = 0 //Leaving something at 0 means it's off - has no maximum
|
||||
var/min_tox = 0
|
||||
var/max_tox = 1
|
||||
var/min_co2 = 0
|
||||
var/max_co2 = 5
|
||||
var/min_n2 = 0
|
||||
var/max_n2 = 0
|
||||
var/unsuitable_atoms_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above
|
||||
|
||||
|
||||
//LETTING SIMPLE ANIMALS ATTACK? WHAT COULD GO WRONG. Defaults to zero so Ian can still be cuddly
|
||||
var/melee_damage_lower = 0
|
||||
var/melee_damage_upper = 0
|
||||
var/attacktext = "attacks"
|
||||
var/attack_sound = null
|
||||
var/friendly = "nuzzles" //If the mob does no damage with it's attack
|
||||
var/wall_smash = 0 //if they can smash walls
|
||||
|
||||
var/speed = 5
|
||||
|
||||
var/can_open_doors = 0 //door opening kind of guy
|
||||
|
||||
var/obj/item/device/radio/headset/l_ear = null
|
||||
@@ -0,0 +1,95 @@
|
||||
|
||||
/mob/living/simple_animal/Life()
|
||||
|
||||
//Health
|
||||
if(stat == DEAD)
|
||||
if(health > 0)
|
||||
icon_state = icon_living
|
||||
stat = CONSCIOUS
|
||||
density = 1
|
||||
return
|
||||
else if(health < 1)
|
||||
Die()
|
||||
else if(health > maxHealth)
|
||||
health = maxHealth
|
||||
|
||||
//Movement
|
||||
if(!ckey && !stop_automated_movement)
|
||||
if(isturf(src.loc) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc.
|
||||
turns_since_move++
|
||||
if(turns_since_move >= turns_per_move)
|
||||
Move(get_step(src,pick(cardinal)))
|
||||
turns_since_move = 0
|
||||
|
||||
//Speaking
|
||||
if(!ckey && prob(speak_chance))
|
||||
var/length = (speak ? speak.len : 0) + (emote_see ? emote_see.len : 0) + (emote_hear ? emote_hear.len : 0)
|
||||
if(speak && speak.len && prob((speak.len / length) * 100))
|
||||
src.say_auto(pick(speak))
|
||||
else if(emote_see && emote_see.len && prob((emote_see.len / length) * 100))
|
||||
emote("auto",1,pick(emote_see))
|
||||
else if(emote_hear && emote_hear.len)
|
||||
emote("auto",2,pick(emote_hear))
|
||||
//var/act,var/m_type=1,var/message = null
|
||||
|
||||
//Atmos
|
||||
var/atmos_suitable = 1
|
||||
|
||||
var/atom/A = src.loc
|
||||
if(isturf(A))
|
||||
var/turf/T = A
|
||||
var/areatemp = T.temperature
|
||||
if( abs(areatemp - bodytemperature) > 50 )
|
||||
var/diff = areatemp - bodytemperature
|
||||
diff = diff / 5
|
||||
//world << "changed from [bodytemperature] by [diff] to [bodytemperature + diff]"
|
||||
bodytemperature += diff
|
||||
|
||||
if(istype(T,/turf/simulated))
|
||||
var/turf/simulated/ST = T
|
||||
if(ST.air)
|
||||
var/tox = ST.air.toxins
|
||||
var/oxy = ST.air.oxygen
|
||||
var/n2 = ST.air.nitrogen
|
||||
var/co2 = ST.air.carbon_dioxide
|
||||
|
||||
if(min_oxy)
|
||||
if(oxy < min_oxy)
|
||||
atmos_suitable = 0
|
||||
if(max_oxy)
|
||||
if(oxy > max_oxy)
|
||||
atmos_suitable = 0
|
||||
if(min_tox)
|
||||
if(tox < min_tox)
|
||||
atmos_suitable = 0
|
||||
if(max_tox)
|
||||
if(tox > max_tox)
|
||||
atmos_suitable = 0
|
||||
if(min_n2)
|
||||
if(n2 < min_n2)
|
||||
atmos_suitable = 0
|
||||
if(max_n2)
|
||||
if(n2 > max_n2)
|
||||
atmos_suitable = 0
|
||||
if(min_co2)
|
||||
if(co2 < min_co2)
|
||||
atmos_suitable = 0
|
||||
if(max_co2)
|
||||
if(co2 > max_co2)
|
||||
atmos_suitable = 0
|
||||
|
||||
//Atmos effect
|
||||
if(bodytemperature < minbodytemp)
|
||||
health -= cold_damage_per_tick
|
||||
if(prob(15))
|
||||
emote("auto",1,"shivers![prob(50) ? "[pick(" It seems quite cold."," It seems to be freezing.")]" : ""]")
|
||||
|
||||
else if(bodytemperature > maxbodytemp)
|
||||
health -= heat_damage_per_tick
|
||||
if(prob(15))
|
||||
emote("auto",1,"sweats![prob(50) ? "[pick(" It seems quite hot."," It seems to be burning up.")]" : ""]")
|
||||
|
||||
if(!atmos_suitable)
|
||||
health -= unsuitable_atoms_damage
|
||||
if(prob(15))
|
||||
emote("auto",1,"gasps![prob(50) ? "[pick(" It seems unable to breath."," It seems to be asphyxiating.")]" : ""]")
|
||||
@@ -0,0 +1,219 @@
|
||||
|
||||
/mob/living/simple_animal/Login()
|
||||
if(src && src.client)
|
||||
src.client.screen = null
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/Bumped(AM as mob|obj)
|
||||
if(!AM) return
|
||||
if(isturf(src.loc) && !resting && !buckled)
|
||||
if(ismob(AM))
|
||||
var/newamloc = src.loc
|
||||
src.loc = AM:loc
|
||||
AM:loc = newamloc
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/gib()
|
||||
if(meat_amount && meat_type)
|
||||
for(var/i = 0; i < meat_amount; i++)
|
||||
new meat_type(src.loc)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/say_quote(var/text)
|
||||
if(speak_emote && speak_emote.len)
|
||||
var/emote = pick(speak_emote)
|
||||
if(emote)
|
||||
return "<b>[src]</b> [emote], \"[text]\""
|
||||
return "says, \"[text]\"";
|
||||
|
||||
//when talking, simple_animals can only understand each other
|
||||
/mob/living/simple_animal/say(var/message)
|
||||
for(var/mob/M in view(src,7))
|
||||
if(istype(M, src.type) || M.universal_speak)
|
||||
M << say_quote(message)
|
||||
else
|
||||
M << "<b>[src]</b> [pick("makes some strange noises.","makes some strange noises.","makes some strange noises.","makes a small commotion.","kicks up a fuss about something.")]"
|
||||
return
|
||||
|
||||
//when talking, simple_animals can only understand each other
|
||||
/mob/living/simple_animal/proc/say_auto(var/message)
|
||||
for(var/mob/M in view(src,7))
|
||||
M << "<b>[src]</b> [pick(speak_emote)], \"[message]\""
|
||||
|
||||
/mob/living/simple_animal/emote(var/act,var/m_type=1,var/message = null)
|
||||
switch(act)
|
||||
if ("scream")
|
||||
message = "<B>[src]</B> makes a loud and pained whimper"
|
||||
m_type = 2
|
||||
|
||||
if ("custom")
|
||||
var/input = copytext(sanitize(input("Choose an emote to display.") as text|null),1,MAX_MESSAGE_LEN)
|
||||
if (!input)
|
||||
return
|
||||
var/input2 = input("Is this a visible or hearable emote?") in list("Visible","Hearable")
|
||||
if (input2 == "Visible")
|
||||
m_type = 1
|
||||
else if (input2 == "Hearable")
|
||||
m_type = 2
|
||||
else
|
||||
alert("Unable to use this emote, must be either hearable or visible.")
|
||||
return
|
||||
message = "<B>[src]</B> [input]"
|
||||
|
||||
if ("me")
|
||||
if(silent)
|
||||
return
|
||||
if (src.client && (client.muted || client.muted_complete))
|
||||
src << "You are muted."
|
||||
return
|
||||
if (stat)
|
||||
return
|
||||
if(!(message))
|
||||
return
|
||||
else
|
||||
if(cmptext(copytext(message, 1, 3), "v "))
|
||||
message = "<B>[src]</B> [copytext(message, 3)]"
|
||||
m_type = 1
|
||||
else if(cmptext(copytext(message, 1, 3), "h "))
|
||||
message = "<B>[src]</B> [copytext(message, 3)]"
|
||||
m_type = 2
|
||||
else
|
||||
message = "<B>[src]</B> [message]"
|
||||
if("auto")
|
||||
message = "<B>[src]</B> [message]"
|
||||
/*else
|
||||
if(!message)
|
||||
src << "Invalid Emote: [act]"*/
|
||||
if ((message && src.stat == 0))
|
||||
if (m_type & 1)
|
||||
for(var/mob/O in viewers(src, null))
|
||||
O.show_message(message, m_type)
|
||||
else
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message(message, m_type)
|
||||
return
|
||||
|
||||
|
||||
/mob/living/simple_animal/attack_animal(mob/living/simple_animal/M as mob)
|
||||
if(M.melee_damage_upper == 0)
|
||||
M.emote("[M.friendly] [src]")
|
||||
else
|
||||
for(var/mob/O in viewers(src, null))
|
||||
O.show_message("\red <B>[M]</B> [M.attacktext] [src]!", 1)
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
health -= damage
|
||||
|
||||
/mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(!Proj) return
|
||||
src.health -= Proj.damage
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/attack_hand(mob/living/carbon/human/M as mob)
|
||||
..()
|
||||
|
||||
switch(M.a_intent)
|
||||
|
||||
if ("help")
|
||||
if (health > 0)
|
||||
for(var/mob/O in viewers(src, null))
|
||||
if ((O.client && !( O.blinded )))
|
||||
O.show_message("\blue [M] [response_help] [src]")
|
||||
|
||||
if ("grab")
|
||||
if (M == src)
|
||||
return
|
||||
if (nopush)
|
||||
return
|
||||
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M )
|
||||
G.assailant = M
|
||||
if (M.hand)
|
||||
M.l_hand = G
|
||||
else
|
||||
M.r_hand = G
|
||||
G.layer = 20
|
||||
G.affecting = src
|
||||
grabbed_by += G
|
||||
G.synch()
|
||||
|
||||
LAssailant = M
|
||||
|
||||
for(var/mob/O in viewers(src, null))
|
||||
if ((O.client && !( O.blinded )))
|
||||
O.show_message(text("\red [] has grabbed [] passively!", M, src), 1)
|
||||
|
||||
if ("hurt")
|
||||
health -= harm_intent_damage
|
||||
for(var/mob/O in viewers(src, null))
|
||||
if ((O.client && !( O.blinded )))
|
||||
O.show_message("\red [M] [response_harm] [src]")
|
||||
|
||||
if ("disarm")
|
||||
for(var/mob/O in viewers(src, null))
|
||||
if ((O.client && !( O.blinded )))
|
||||
O.show_message("\blue [M] [response_disarm] [src]")
|
||||
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
|
||||
if(istype(O, /obj/item/stack/medical))
|
||||
if(stat != DEAD)
|
||||
var/obj/item/stack/medical/MED = O
|
||||
if(health < maxHealth)
|
||||
if(MED.amount >= 1)
|
||||
health = min(maxHealth, health + MED.heal_brute)
|
||||
MED.amount -= 1
|
||||
if(MED.amount <= 0)
|
||||
del(MED)
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\blue [user] applies the [MED] on [src]")
|
||||
else
|
||||
user << "\blue this [src] is dead, medical items won't bring it back to life."
|
||||
else
|
||||
if(O.force)
|
||||
health -= O.force
|
||||
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
|
||||
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/movement_delay()
|
||||
return speed
|
||||
|
||||
/mob/living/simple_animal/Stat()
|
||||
..()
|
||||
|
||||
statpanel("Status")
|
||||
stat(null, "Health: [round((health / maxHealth) * 100)]%")
|
||||
|
||||
/mob/living/simple_animal/proc/Die()
|
||||
icon_state = icon_dead
|
||||
stat = DEAD
|
||||
density = 0
|
||||
src << "\red You have died!"
|
||||
verbs -= /mob/living/simple_animal/say
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/ex_act(severity)
|
||||
flick("flash", flash)
|
||||
switch (severity)
|
||||
if (1.0)
|
||||
health -= 500
|
||||
gib()
|
||||
return
|
||||
|
||||
if (2.0)
|
||||
health -= 60
|
||||
|
||||
|
||||
if(3.0)
|
||||
health -= 30
|
||||
|
||||
/proc/issimpleanimal(var/mob/AM)
|
||||
return istype(AM,/mob/living/simple_animal)
|
||||
Reference in New Issue
Block a user