Merge upstream

This commit is contained in:
Cyberboss
2017-03-27 09:32:08 -04:00
110 changed files with 1368 additions and 705 deletions
@@ -141,7 +141,7 @@
observer.real_name = observer.client.prefs.real_name
observer.name = observer.real_name
observer.update_icon()
observer.stopLobbySound()
observer.stop_sound_channel(CHANNEL_LOBBYMUSIC)
qdel(mind)
qdel(src)
@@ -471,7 +471,7 @@
. = new_character
if(.)
new_character.key = key //Manually transfer the key to log them in
new_character.stopLobbySound()
new_character.stop_sound_channel(CHANNEL_LOBBYMUSIC)
/mob/dead/new_player/proc/ViewManifest()
var/dat = "<html><body>"
@@ -145,8 +145,8 @@
parts -= picked
if(updating_health)
updatehealth()
if(update)
update_damage_overlays()
if(update)
update_damage_overlays()
// damage MANY bodyparts, in random order
/mob/living/carbon/take_overall_damage(brute, burn, updating_health = 1)
@@ -50,4 +50,4 @@ var/global/default_martial_art = new/datum/martial_art
var/datum/personal_crafting/handcrafting
can_buckle = TRUE
buckle_lying = FALSE
can_ride_typecache = list(/mob/living/carbon/human, /mob/living/simple_animal/slime)
can_ride_typecache = list(/mob/living/carbon/human, /mob/living/simple_animal/slime, /mob/living/simple_animal/parrot)
@@ -67,10 +67,7 @@
//modules
var/list/functions = list("nearbyscan","combat","shitcurity","chatter")
var/restrictedJob = 0
var/shouldUseDynamicProc = 0 // switch to make the AI control it's own proccessing
var/alternateProcessing = 1
var/forceProcess = 0
var/processTime = 8
var/lastProc = 0
var/walkdebug = 0 //causes sparks in our path target. used for debugging
var/debugexamine = 0 //If we show debug info in our examine
@@ -85,6 +82,7 @@
var/traitorScale = 0 // our ability as a traitor
var/traitorType = 0
var/voice_saved = FALSE
/// SNPC voice handling
@@ -96,6 +94,8 @@
knownStrings = list()
/mob/living/carbon/human/interactive/proc/saveVoice()
if(voice_saved)
return
var/savefile/S = new /savefile("data/npc_saves/snpc.sav")
S["knownStrings"] << knownStrings
@@ -145,8 +145,7 @@
retal_target = potentialAssault
..()
/client/proc/resetSNPC(var/mob/A in SSnpcpool.botPool_l)
/client/proc/resetSNPC(var/mob/A in SSnpcpool.processing)
set name = "Reset SNPC"
set desc = "Reset the SNPC"
set category = "Debug"
@@ -163,24 +162,7 @@
T.retal = 0
T.doing = 0
/client/proc/toggleSNPC(var/mob/A in SSnpcpool.botPool_l)
set name = "Toggle SNPC Proccessing Mode"
set desc = "Toggle SNPC Proccessing Mode"
set category = "Debug"
if(!holder)
return
if(A)
if(!istype(A,/mob/living/carbon/human/interactive))
return
var/mob/living/carbon/human/interactive/T = A
if(T)
T.alternateProcessing = !T.alternateProcessing
T.forceProcess = 1
to_chat(usr, "[T]'s processing has been switched to [T.alternateProcessing ? "High Profile" : "Low Profile"]")
/client/proc/customiseSNPC(var/mob/A in SSnpcpool.botPool_l)
/client/proc/customiseSNPC(var/mob/A in SSnpcpool.processing)
set name = "Customize SNPC"
set desc = "Customise the SNPC"
set category = "Debug"
@@ -390,7 +372,7 @@
doSetup()
SSnpcpool.insertBot(src)
START_PROCESSING(SSnpcpool, src)
loadVoice()
@@ -400,8 +382,9 @@
attitude += rand(-10,10)
slyness += rand(-10,10)
doProcess()
/mob/living/carbon/human/interactive/Destroy()
SSnpcpool.stop_processing(src)
return ..()
/mob/living/carbon/human/interactive/proc/retalTarget(var/target)
var/mob/living/carbon/human/M = target
@@ -533,12 +516,10 @@
/mob/living/carbon/human/interactive/proc/targetRange(towhere)
return get_dist(get_turf(towhere), get_turf(src))
/mob/living/carbon/human/interactive/Life()
..()
/mob/living/carbon/human/interactive/proc/InteractiveProcess()
if(SSticker.current_state == GAME_STATE_FINISHED)
saveVoice()
if(!alternateProcessing || forceProcess || world.time > lastProc + processTime)
doProcess()
doProcess()
/mob/living/carbon/human/interactive/death()
saveVoice()
@@ -550,22 +531,7 @@
..()
/mob/living/carbon/human/interactive/proc/doProcess()
set waitfor = 0
forceProcess = 0
lastProc = world.time
if(shouldUseDynamicProc)
var/isSeen = 0
for(var/mob/living/carbon/human/A in orange(12,src))
if(A.client)
isSeen = 1
alternateProcessing = isSeen
if(alternateProcessing)
forceProcess = 1
if(IsDeadOrIncap())
walk(src,0)
return
set waitfor = FALSE
//---------------------------
//---- interest flow control
if(interest < 0 || inactivity_period < 0)
@@ -587,10 +553,13 @@
if(istype(D,/obj/machinery/door/airlock))
var/obj/machinery/door/airlock/AL = D
if(!AL.CanAStarPass(RPID)) // only crack open doors we can't get through
inactivity_period = 20
AL.panel_open = 1
AL.update_icon()
AL.shock(src,(100 - smartness)/2)
sleep(5)
if(QDELETED(AL))
return
AL.unbolt()
if(!AL.wires.is_cut(WIRE_BOLTS))
AL.wires.cut(WIRE_BOLTS)
@@ -599,9 +568,15 @@
if(!AL.wires.is_cut(WIRE_POWER2))
AL.wires.cut(WIRE_POWER2)
sleep(5)
if(QDELETED(AL))
return
AL.panel_open = 0
AL.update_icon()
D.open()
D.open(2) //crowbar force
else
D.open()
else
D.open()
if(update_hands)
var/obj/item/l_hand = get_item_for_held_index(1)
@@ -633,7 +608,7 @@
//proc functions
for(var/Proc in functions)
if(!IsDeadOrIncap())
callfunction(Proc)
INVOKE_ASYNC(src, Proc)
//target interaction stays hardcoded
@@ -649,8 +624,8 @@
if(istype(TARGET, /obj/machinery/door))
var/obj/machinery/door/D = TARGET
if(D.check_access(MYID) && !istype(D,/obj/machinery/door/poddoor))
inactivity_period = 10
D.open()
//sleep(15)
var/turf/T = get_step(get_step(D.loc,dir),dir) //recursion yo
tryWalk(T)
//THIEVING SKILLS
@@ -672,15 +647,8 @@
insert_into_backpack()
//---------FASHION
if(istype(TARGET,/obj/item/clothing))
var/obj/item/clothing/C = TARGET
drop_item()
spawn(5)
take_to_slot(C,1)
if(!equip_to_appropriate_slot(C))
var/obj/item/I = get_item_by_slot(C)
dropItemToGround(I)
spawn(5)
equip_to_appropriate_slot(C)
dressup(TARGET)
update_hands = 1
if(MYPDA in src.loc || MYID in src.loc)
if(MYPDA in src.loc)
@@ -738,8 +706,19 @@
TARGET = traitorTarget
tryWalk(TARGET)
LAST_TARGET = TARGET
if(alternateProcessing)
addtimer(CALLBACK(src, .proc/doProcess), processTime)
/mob/living/carbon/human/interactive/proc/dressup(obj/item/clothing/C)
set waitfor = FALSE
inactivity_period = 12
sleep(5)
if(!QDELETED(C) && !QDELETED(src))
take_to_slot(C,1)
if(!equip_to_appropriate_slot(C))
var/obj/item/I = get_item_by_slot(C)
dropItemToGround(I)
sleep(5)
if(!QDELETED(src) && !QDELETED(C))
equip_to_appropriate_slot(C)
/mob/living/carbon/human/interactive/proc/favouredObjIn(var/list/inList)
var/list/outList = list()
@@ -751,11 +730,6 @@
outList = inList
return outList
/mob/living/carbon/human/interactive/proc/callfunction(Proc)
set waitfor = 0
spawn(0)
call(src,Proc)(src)
/mob/living/carbon/human/interactive/proc/tryWalk(turf/inTarget, override = 0)
if(restrictedJob && !override) // we're a job that has to stay in our home
if(!(get_turf(inTarget) in get_area_turfs(job2area(myjob))))
@@ -1143,7 +1117,8 @@
for(var/obj/item/I in allContents)
if(istype(I,/obj/item/weapon/restraints))
I.attack(TARGET,src) // go go bluespace restraint launcher!
sleep(25)
inactivity_period = 25
break
/mob/living/carbon/human/interactive/proc/clowning(obj)
if(shouldModulePass())
@@ -1225,7 +1200,7 @@
if(get_dist(src,C) <= 2)
src.say("Wait, [C], let me heal you!")
M.attack(C,src)
sleep(25)
inactivity_period = 25
else
tryWalk(get_turf(C))
else if(shouldTryHeal == 2)
@@ -1237,7 +1212,7 @@
if(get_dist(src,C) <= 2)
src.say("Wait, [C], let me heal you!")
HPS.attack(C,src)
sleep(25)
inactivity_period = 25
else
tryWalk(get_turf(C))
@@ -1265,7 +1240,7 @@
tryWalk(TC)
else
S.afterattack(TC,src)
sleep(25)
inactivity_period = 25
/mob/living/carbon/human/interactive/proc/customEmote(var/text)
visible_message("<span class='notice'>[text]</span>")
@@ -1354,7 +1329,7 @@
var/choice = pick(1,2)
if(choice == 1)
tryWalk(get_turf(D))
sleep(get_dist(src,D))
inactivity_period = get_dist(src,D)
D.attackby(RP,src)
else
cookingwithmagic(D)
@@ -1364,7 +1339,7 @@
var/choice = pick(1,2)
if(choice == 1)
tryWalk(get_turf(D))
sleep(get_dist(src,D))
inactivity_period = get_dist(src,D)
FD.attackby(KK,src)
else
cookingwithmagic(FD)
@@ -1374,7 +1349,7 @@
var/choice = pick(1,2)
if(choice == 1)
tryWalk(get_turf(D))
sleep(get_dist(src,D))
inactivity_period = get_dist(src,D)
CB.attackby(RP,src)
else
cookingwithmagic(CB)
@@ -1384,7 +1359,7 @@
var/choice = pick(1,2)
if(choice == 1)
tryWalk(get_turf(D))
sleep(get_dist(src,D))
inactivity_period = get_dist(src,D)
PD.attackby(KK,src)
else
cookingwithmagic(PD)
@@ -1533,6 +1508,7 @@
G.attack_self(src)
if(prob(smartness))
npcDrop(G,1)
inactivity_period = 15
sleep(15)
throw_item(TARGET)
@@ -1073,7 +1073,6 @@
return 1
else
user.do_attack_animation(target, ATTACK_EFFECT_DISARM)
add_logs(user, target, "disarmed")
if(target.w_uniform)
target.w_uniform.add_fingerprint(user)
@@ -1085,23 +1084,23 @@
"<span class='userdanger'>[user] has pushed [target]!</span>", null, COMBAT_MESSAGE_RANGE)
target.apply_effect(2, WEAKEN, target.run_armor_check(affecting, "melee", "Your armor prevents your fall!", "Your armor softens your fall!"))
target.forcesay(hit_appends)
add_logs(user, target, "disarmed", " pushing them to the ground")
return
var/talked = 0 // BubbleWrap
if(randn <= 60)
//BubbleWrap: Disarming breaks a pull
var/obj/item/I = null
if(target.pulling)
to_chat(target, "<span class='warning'>[user] has broken [target]'s grip on [target.pulling]!</span>")
talked = 1
target.stop_pulling()
//End BubbleWrap
if(!talked) //BubbleWrap
else
I = target.get_active_held_item()
if(target.drop_item())
target.visible_message("<span class='danger'>[user] has disarmed [target]!</span>", \
"<span class='userdanger'>[user] has disarmed [target]!</span>", null, COMBAT_MESSAGE_RANGE)
else
I = null
playsound(target, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
add_logs(user, target, "disarmed", "[I ? " removing \the [I]" : ""]")
return
@@ -1,7 +1,7 @@
/datum/species/golem
// Animated beings of stone. They have increased defenses, and do not need to breathe. They're also slow as fuuuck.
name = "Golem"
id = "iron"
id = "iron golem"
species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS)
speedmod = 2
armor = 55
@@ -12,6 +12,7 @@
no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform)
nojumpsuit = 1
sexes = 1
damage_overlay_type = ""
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem
// To prevent golem subtypes from overwhelming the odds when random species
// changes, only the Random Golem type can be chosen
@@ -21,6 +22,21 @@
fixed_mut_color = "aaa"
var/info_text = "As an <span class='danger'>Iron Golem</span>, you don't have any special traits."
var/prefix = "Iron"
var/list/special_names
/datum/species/golem/random_name(gender,unique,lastname)
var/golem_surname = pick(golem_names)
// 3% chance that our golem has a human surname, because
// cultural contamination
if(prob(3))
golem_surname = pick(last_names)
else if(special_names && prob(5))
golem_surname = pick(special_names)
var/golem_name = "[prefix] [golem_surname]"
return golem_name
/datum/species/golem/random
name = "Random Golem"
blacklisted = FALSE
@@ -36,21 +52,24 @@
/datum/species/golem/adamantine
name = "Adamantine Golem"
id = "adamantine"
id = "adamantine golem"
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem/adamantine
fixed_mut_color = "4ed"
info_text = "As an <span class='danger'>Adamantine Golem</span>, you don't have any special traits."
prefix = "Adamantine"
//Explodes on death
/datum/species/golem/plasma
name = "Plasma Golem"
id = "plasma"
id = "plasma golem"
fixed_mut_color = "a3d"
meat = /obj/item/weapon/ore/plasma
//Can burn and takes damage from heat
species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS)
info_text = "As a <span class='danger'>Plasma Golem</span>, you explode on death!"
burnmod = 1.5
prefix = "Plasma"
special_names = list("Flood","Fire","Bar","Man")
/datum/species/golem/plasma/spec_death(gibbed, mob/living/carbon/human/H)
explosion(get_turf(H),0,1,2,flame_range = 5)
@@ -60,35 +79,40 @@
//Harder to hurt
/datum/species/golem/diamond
name = "Diamond Golem"
id = "diamond"
id = "diamond golem"
fixed_mut_color = "0ff"
armor = 70 //up from 55
meat = /obj/item/weapon/ore/diamond
info_text = "As a <span class='danger'>Diamond Golem</span>, you are more resistant than the average golem."
prefix = "Diamond"
special_names = list("Back")
//Faster but softer and less armoured
/datum/species/golem/gold
name = "Gold Golem"
id = "gold"
id = "gold golem"
fixed_mut_color = "cc0"
speedmod = 1
armor = 25 //down from 55
meat = /obj/item/weapon/ore/gold
info_text = "As a <span class='danger'>Gold Golem</span>, you are faster but less resistant than the average golem."
prefix = "Golden"
//Heavier, thus higher chance of stunning when punching
/datum/species/golem/silver
name = "Silver Golem"
id = "silver"
id = "silver golem"
fixed_mut_color = "ddd"
punchstunthreshold = 9 //60% chance, from 40%
meat = /obj/item/weapon/ore/silver
info_text = "As a <span class='danger'>Silver Golem</span>, your attacks are heavier and have a higher chance of stunning."
prefix = "Silver"
special_names = list("Surfer", "Chariot", "Lining")
//Harder to stun, deals more damage, but it's even slower
/datum/species/golem/plasteel
name = "Plasteel Golem"
id = "plasteel"
id = "plasteel golem"
fixed_mut_color = "bbb"
stunmod = 0.40
punchdamagelow = 12
@@ -99,15 +123,17 @@
info_text = "As a <span class='danger'>Plasteel Golem</span>, you are slower, but harder to stun, and hit very hard when punching."
attack_verb = "smash"
attack_sound = 'sound/effects/meteorimpact.ogg' //hits pretty hard
prefix = "Plasteel"
//Immune to ash storms
/datum/species/golem/titanium
name = "Titanium Golem"
id = "titanium"
id = "titanium golem"
fixed_mut_color = "fff"
meat = /obj/item/weapon/ore/titanium
info_text = "As a <span class='danger'>Titanium Golem</span>, you are immune to ash storms, and slightly more resistant to burn damage."
burnmod = 0.9
prefix = "Titanium"
/datum/species/golem/titanium/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
@@ -120,11 +146,12 @@
//Immune to ash storms and lava
/datum/species/golem/plastitanium
name = "Plastitanium Golem"
id = "plastitanium"
id = "plastitanium golem"
fixed_mut_color = "888"
meat = /obj/item/weapon/ore/titanium
info_text = "As a <span class='danger'>Plastitanium Golem</span>, you are immune to both ash storms and lava, and slightly more resistant to burn damage."
burnmod = 0.8
prefix = "Plastitanium"
/datum/species/golem/plastitanium/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
@@ -139,12 +166,14 @@
//Fast and regenerates... but can only speak like an abductor
/datum/species/golem/alloy
name = "Alien Alloy Golem"
id = "alloy"
id = "alloy golem"
fixed_mut_color = "333"
meat = /obj/item/stack/sheet/mineral/abductor
mutant_organs = list(/obj/item/organ/tongue/abductor) //abductor tongue
speedmod = 1 //faster
info_text = "As an <span class='danger'>Alloy Golem</span>, you are made of advanced alien materials: you are faster and regenerate over time. You are, however, only able to be heard by other alloy golems."
prefix = "Alien"
special_names = list("Outsider", "Technology", "Watcher", "Stranger") //ominous and unknown
//Regenerates because self-repairing super-advanced alien tech
/datum/species/golem/alloy/spec_life(mob/living/carbon/human/H)
@@ -157,7 +186,7 @@
//Since this will usually be created from a collaboration between podpeople and free golems, wood golems are a mix between the two races
/datum/species/golem/wood
name = "Wood Golem"
id = "wood"
id = "wood golem"
fixed_mut_color = "49311c"
meat = /obj/item/stack/sheet/mineral/wood
//Can burn and take damage from heat
@@ -166,6 +195,13 @@
burnmod = 1.25
heatmod = 1.5
info_text = "As a <span class='danger'>Wooden Golem</span>, you have plant-like traits: you take damage from extreme temperatures, can be set on fire, and have lower armor than a normal golem. You regenerate when in the light and wither in the darkness."
prefix = "Wooden"
/datum/species/golem/wood/random_name(gender,unique,lastname)
var/plant_name = pick("Tomato", "Potato", "Broccoli", "Carrot", "Ambrosia", "Pumpkin", "Ivy", "Kudzu", "Banana", "Moss", "Flower", "Bloom", "Root", "Bark", "Glowshroom", "Petal", "Leaf", \
"Venus", "Sprout","Cocoa", "Strawberry", "Citrus", "Oak", "Cactus", "Pepper", "Juniper")
var/golem_name = "[prefix] [plant_name]"
return golem_name
/datum/species/golem/wood/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
@@ -204,13 +240,14 @@
//Radioactive
/datum/species/golem/uranium
name = "Uranium Golem"
id = "uranium"
id = "uranium golem"
fixed_mut_color = "7f0"
meat = /obj/item/weapon/ore/uranium
info_text = "As an <span class='danger'>Uranium Golem</span>, you emit radiation pulses every once in a while. It won't harm fellow golems, but organic lifeforms will be affected."
var/last_event = 0
var/active = null
prefix = "Uranium"
/datum/species/golem/uranium/spec_life(mob/living/carbon/human/H)
if(!active)
@@ -224,7 +261,7 @@
//Immune to physical bullets and resistant to brute, but very vulnerable to burn damage. Dusts on death.
/datum/species/golem/sand
name = "Sand Golem"
id = "sand"
id = "sand golem"
fixed_mut_color = "ffdc8f"
meat = /obj/item/weapon/ore/glass //this is sand
armor = 0
@@ -232,6 +269,7 @@
brutemod = 0.25
info_text = "As a <span class='danger'>Sand Golem</span>, you are immune to physical bullets and take very little brute damage, but are extremely vulnerable to burn damage. You will also turn to sand when dying, preventing any form of recovery."
attack_sound = 'sound/effects/shovel_dig.ogg'
prefix = "Sand"
/datum/species/golem/sand/spec_death(gibbed, mob/living/carbon/human/H)
H.visible_message("<span class='danger'>[H] turns into a pile of sand!</span>")
@@ -253,7 +291,7 @@
//Reflects lasers and resistant to burn damage, but very vulnerable to brute damage. Shatters on death.
/datum/species/golem/glass
name = "Glass Golem"
id = "glass"
id = "glass golem"
fixed_mut_color = "5a96b4aa" //transparent body
meat = /obj/item/weapon/shard
armor = 0
@@ -261,6 +299,7 @@
burnmod = 0.25
info_text = "As a <span class='danger'>Glass Golem</span>, you reflect lasers and energy weapons, and are very resistant to burn damage, but you are extremely vulnerable to brute damage. On death, you'll shatter beyond any hope of recovery."
attack_sound = 'sound/effects/Glassbr2.ogg'
prefix = "Glass"
/datum/species/golem/glass/spec_death(gibbed, mob/living/carbon/human/H)
playsound(H, "shatter", 70, 1)
@@ -295,12 +334,14 @@
//Teleports when hit or when it wants to
/datum/species/golem/bluespace
name = "Bluespace Golem"
id = "bluespace"
id = "bluespace golem"
fixed_mut_color = "33f"
meat = /obj/item/weapon/ore/bluespace_crystal
info_text = "As a <span class='danger'>Bluespace Golem</span>, are spatially unstable: you will teleport when hit, and you can teleport manually at a long distance."
attack_verb = "bluespace punch"
attack_sound = 'sound/effects/phasein.ogg'
prefix = "Bluespace"
special_names = list("Crystal", "Polycrystal")
var/datum/action/innate/unstable_teleport/unstable_teleport
var/teleport_cooldown = 100
@@ -384,7 +425,7 @@
//honk
/datum/species/golem/bananium
name = "Bananium Golem"
id = "bananium"
id = "bananium golem"
fixed_mut_color = "ff0"
say_mod = "honks"
punchdamagelow = 0
@@ -394,6 +435,7 @@
info_text = "As a <span class='danger'>Bananium Golem</span>, you are made for pranking. Your body emits natural honks, and you cannot hurt people when punching them. Your skin also emits bananas when damaged."
attack_verb = "honk"
attack_sound = 'sound/items/AirHorn2.ogg'
prefix = "Bananium"
var/last_honk = 0
var/honkooldown = 0
@@ -401,6 +443,11 @@
var/banana_cooldown = 100
var/active = null
/datum/species/golem/bananium/random_name(gender,unique,lastname)
var/clown_name = pick(clown_names)
var/golem_name = "[uppertext(clown_name)]"
return golem_name
/datum/species/golem/bananium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art)
..()
if(world.time > last_banana + banana_cooldown && M != H && M.a_intent != INTENT_HELP)
@@ -449,7 +496,7 @@
/datum/species/golem/runic
name = "Runic Golem"
id = "runic"
id = "runic golem"
limbs_id = "cultgolem"
sexes = FALSE
info_text = "As a <span class='danger'>Runic Golem</span>, you possess eldritch powers granted by the Elder God Nar'Sie."
@@ -459,6 +506,12 @@
var/obj/effect/proc_holder/spell/targeted/abyssal_gaze/abyssal_gaze
var/obj/effect/proc_holder/spell/targeted/dominate/dominate
/datum/species/golem/runic/random_name(gender,unique,lastname)
var/edgy_first_name = pick("Razor","Blood","Dark","Evil","Cold","Pale","Black","Silent","Chaos","Deadly")
var/edgy_last_name = pick("Edge","Night","Death","Razor","Blade","Steel","Calamity","Twilight","Shadow","Nightmare") //dammit Razor Razor
var/golem_name = "[edgy_first_name] [edgy_last_name]"
return golem_name
/datum/species/golem/runic/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
C.faction |= "cult"
@@ -491,7 +544,7 @@
/datum/species/golem/cloth
name = "Cloth Golem"
id = "cloth"
id = "cloth golem"
limbs_id = "clothgolem"
sexes = FALSE
info_text = "As a <span class='danger'>Cloth Golem</span>, you are able to reform yourself after death, provided your remains aren't burned or destroyed. You are, of course, very flammable."
@@ -502,6 +555,13 @@
punchdamagelow = 4
punchstunthreshold = 7
punchdamagehigh = 8 // not as heavy as stone
prefix = "Cloth"
/datum/species/golem/cloth/random_name(gender,unique,lastname)
var/pharaoh_name = pick("Neferkare", "Hudjefa", "Khufu", "Mentuhotep", "Ahmose", "Amenhotep", "Thutmose", "Hatshepsut", "Tutankhamun", "Ramses", "Seti", \
"Merenptah", "Djer", "Semerkhet", "Nynetjer", "Khafre", "Pepi", "Intef", "Ay") //yes, Ay was an actual pharaoh
var/golem_name = "[pharaoh_name] \Roman[rand(1,99)]"
return golem_name
/datum/species/golem/cloth/spec_life(mob/living/carbon/human/H)
if(H.fire_stacks < 1)
@@ -7,6 +7,7 @@
species_traits = list(MUTCOLORS,EYECOLOR,NOBLOOD,VIRUSIMMUNE,TOXINLOVER)
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/slime
exotic_blood = "slimejelly"
damage_overlay_type = ""
var/datum/action/innate/regenerate_limbs/regenerate_limbs
/datum/species/jelly/on_species_loss(mob/living/carbon/C)
@@ -117,17 +117,23 @@
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to lunge at [name]!</span>", \
"<span class='userdanger'>[M] has attempted to lunge at [name]!</span>", null, COMBAT_MESSAGE_RANGE)
if (M.a_intent == INTENT_DISARM)
var/obj/item/I = null
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
if(prob(95))
Weaken(10)
visible_message("<span class='danger'>[M] has tackled down [name]!</span>", \
"<span class='userdanger'>[M] has tackled down [name]!</span>", null, COMBAT_MESSAGE_RANGE)
else
I = get_active_held_item()
if(drop_item())
visible_message("<span class='danger'>[M] has disarmed [name]!</span>", \
"<span class='userdanger'>[M] has disarmed [name]!</span>", null, COMBAT_MESSAGE_RANGE)
add_logs(M, src, "disarmed")
else
I = null//did not manage to actually disarm the item, gross but no time to refactor
add_logs(M, src, "disarmed", "[I ? " removing \the [I]" : ""]")
updatehealth()
@@ -244,10 +244,6 @@
return 0
/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M)
if(isturf(loc) && istype(loc.loc, /area/start))
to_chat(M, "No attacking people at spawn, you jackass.")
return 0
switch(M.a_intent)
if ("help")
visible_message("<span class='notice'>[M] caresses [src] with its scythe like arm.</span>")
+78 -6
View File
@@ -84,6 +84,9 @@ var/list/ai_list = list()
var/obj/machinery/camera/portable/builtInCamera
var/obj/structure/AIcore/deactivated/linked_core //For exosuit control
var/mob/living/silicon/robot/deployed_shell = null //For shell control
var/datum/action/innate/deploy_shell/deploy_action = new
var/datum/action/innate/deploy_last_shell/redeploy_action = new
/mob/living/silicon/ai/Initialize(mapload, datum/ai_laws/L, mob/target_ai)
..()
@@ -138,6 +141,8 @@ var/list/ai_list = list()
radio = new /obj/item/device/radio/headset/ai(src)
aicamera = new/obj/item/device/camera/siliconcam/ai_camera(src)
deploy_action.Grant(src)
if(isturf(loc))
verbs.Add(/mob/living/silicon/ai/proc/ai_network_change, \
/mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \
@@ -247,13 +252,16 @@ var/list/ai_list = list()
for(var/mob/living/silicon/robot/R in connected_robots)
borg_area = get_area(R)
var/robot_status = "Nominal"
if(R.stat || !R.client)
if(R.shell)
robot_status = "AI SHELL"
else if(R.stat || !R.client)
robot_status = "OFFLINE"
else if(!R.cell || R.cell.charge <= 0)
robot_status = "DEPOWERED"
//Name, Health, Battery, Module, Area, and Status! Everything an AI wants to know about its borgies!
stat(null, text("[R.name] | S.Integrity: [R.health]% | Cell: [R.cell ? "[R.cell.charge]/[R.cell.maxcharge]" : "Empty"] | \
Module: [R.designation] | Loc: [borg_area.name] | Status: [robot_status]"))
Module: [R.designation] | Loc: [borg_area.name] | Status: [robot_status]"))
stat(null, text("AI shell beacons detected: [LAZYLEN(available_ai_shells)]")) //Count of total AI shells
else
stat(null, text("Systems nonfunctional"))
@@ -791,12 +799,13 @@ var/list/ai_list = list()
if(!..())
return
if(interaction == AI_TRANS_TO_CARD)//The only possible interaction. Upload AI mob to a card.
if(!mind)
to_chat(user, "<span class='warning'>No intelligence patterns detected.</span>" )
return
if(!can_be_carded)
to_chat(user, "<span class='boldwarning'>Transfer failed.</span>")
return
disconnect_shell() //If the AI is controlling a borg, force the player back to core!
if(!mind)
to_chat(user, "<span class='warning'>No intelligence patterns detected.</span>" )
return
ShutOffDoomsdayDevice()
new /obj/structure/AIcore/deactivated(loc)//Spawns a deactivated terminal at AI location.
ai_restore_power()//So the AI initially has power.
@@ -907,10 +916,73 @@ var/list/ai_list = list()
to_chat(src, "Hack complete. \The [apc] is now under your exclusive control.")
apc.update_icon()
/mob/living/silicon/ai/verb/deploy_to_shell(var/mob/living/silicon/robot/target)
set category = "AI Commands"
set name = "Deploy to Shell"
if(stat || lacks_power() || control_disabled)
to_chat(src, "<span class='danger'>Wireless networking module is offline.</span>")
return
var/list/possible = list()
for(var/borgie in available_ai_shells)
var/mob/living/silicon/robot/R = borgie
if(R.shell && !R.deployed && (R.stat != DEAD) && (!R.connected_ai ||(R.connected_ai == src)))
possible += R
if(!LAZYLEN(possible))
to_chat(src, "No usable AI shell beacons detected.")
if(!target || !(target in possible)) //If the AI is looking for a new shell, or its pre-selected shell is no longer valid
target = input(src, "Which body to control?") as null|anything in possible
if (!target || target.stat == DEAD || target.deployed || !(!target.connected_ai ||(target.connected_ai == src)))
return
else if(mind)
soullink(/datum/soullink/sharedbody, src, target)
deployed_shell = target
target.deploy_init(src)
mind.transfer_to(target)
diag_hud_set_deployed()
/datum/action/innate/deploy_shell
name = "Deploy to AI Shell"
desc = "Wirelessly control a specialized cyborg shell."
button_icon_state = "ai_shell"
/datum/action/innate/deploy_shell/Trigger()
var/mob/living/silicon/ai/AI = owner
if(!AI)
return
AI.deploy_to_shell()
/datum/action/innate/deploy_last_shell
name = "Reconnect to shell"
desc = "Reconnect to the most recently used AI shell."
button_icon_state = "ai_last_shell"
var/mob/living/silicon/robot/last_used_shell
/datum/action/innate/deploy_last_shell/Trigger()
if(!owner)
return
if(last_used_shell)
var/mob/living/silicon/ai/AI = owner
AI.deploy_to_shell(last_used_shell)
else
Remove(owner) //If the last shell is blown, destroy it.
/mob/living/silicon/ai/proc/disconnect_shell()
if(deployed_shell) //Forcibly call back AI in event of things such as damage, EMP or power loss.
to_chat(src, "<span class='danger'>Your remote connection has been reset!</span>")
deployed_shell.undeploy()
diag_hud_set_deployed()
/mob/living/silicon/ai/resist()
return
/mob/living/silicon/ai/spawned/Initialize(mapload, datum/ai_laws/L, mob/target_ai)
if(!target_ai)
target_ai = src //cheat! just give... ourselves as the spawned AI, because that's technically correct
..()
..()
@@ -22,6 +22,7 @@
return 0
/mob/living/silicon/ai/emp_act(severity)
disconnect_shell()
if (prob(30))
switch(pick(1,2))
if(1)
@@ -1,21 +1,23 @@
/mob/living/silicon/ai/examine(mob/user)
var/msg = "<span class='info'>*---------*\nThis is \icon[src] <EM>[src]</EM>!\n"
if (src.stat == DEAD)
if (stat == DEAD)
msg += "<span class='deadsay'>It appears to be powered-down.</span>\n"
else
msg += "<span class='warning'>"
if (src.getBruteLoss())
if (src.getBruteLoss() < 30)
if (getBruteLoss())
if (getBruteLoss() < 30)
msg += "It looks slightly dented.\n"
else
msg += "<B>It looks severely dented!</B>\n"
if (src.getFireLoss())
if (src.getFireLoss() < 30)
if (getFireLoss())
if (getFireLoss() < 30)
msg += "It looks slightly charred.\n"
else
msg += "<B>Its casing is melted and heat-warped!</B>\n"
msg += "</span>"
if (shunted == 0 && !src.client)
if(deployed_shell)
msg += "The wireless networking light is blinking.\n"
else if (!shunted && !client)
msg += "[src]Core.exe has stopped responding! NTOS is searching for a solution to the problem...\n"
msg += "*---------*</span>"
@@ -65,6 +65,7 @@
health = maxHealth - getOxyLoss() - getToxLoss() - getBruteLoss() - getFireLoss()
update_stat()
diag_hud_set_health()
disconnect_shell()
/mob/living/silicon/ai/update_stat()
if(status_flags & GODMODE)
@@ -163,6 +164,7 @@
update_sight()
/mob/living/silicon/ai/proc/ai_lose_power()
disconnect_shell()
aiRestorePowerRoutine = POWER_RESTORATION_START
blind_eyes(1)
update_sight()
@@ -36,9 +36,11 @@
if(is_servant_of_ratvar(src) && user.Adjacent(src) && !stat) //To counter pseudo-stealth by using headlamps
msg += "<span class='warning'>Its eyes are glowing a blazing yellow!</span>\n"
switch(src.stat)
switch(stat)
if(CONSCIOUS)
if(!src.client)
if(shell)
msg += "It appears to be an [deployed ? "active" : "empty"] AI shell.\n"
else if(!client)
msg += "It appears to be in stand-by mode.\n" //afk
if(UNCONSCIOUS)
msg += "<span class='warning'>It doesn't seem to be responding.</span>\n"
@@ -32,7 +32,9 @@
to_chat(who, "<b>Obey these laws:</b>")
laws.show_laws(who)
if (is_special_character(src) && connected_ai)
if (shell) //AI shell
to_chat(who, "<b>Remember, you are an AI remotely controlling your shell, other AIs can be ignored.</b>")
else if (is_special_character(src) && connected_ai)
to_chat(who, "<b>Remember, [connected_ai.name] is technically your master, but your objective comes first.</b>")
else if (connected_ai)
to_chat(who, "<b>Remember, [connected_ai.name] is your master, other AIs can be ignored.</b>")
+120 -8
View File
@@ -16,6 +16,10 @@
var/obj/item/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of..
var/obj/item/device/mmi/mmi = null
var/shell = FALSE
var/deployed = FALSE
var/mob/living/silicon/ai/mainframe = null
var/datum/action/innate/undeployment/undeployment_action = new
//Hud stuff
@@ -73,7 +77,7 @@
var/sight_mode = 0
var/updating = 0 //portable camera camerachunk update
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD)
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD)
var/list/upgrades = list()
@@ -129,8 +133,12 @@
update_icons()
..()
//If this body is meant to be a borg controlled by the AI player
if(shell)
make_shell()
//MMI stuff. Held togheter by magic. ~Miauw
if(!mmi || !mmi.brainmob)
else if(!mmi || !mmi.brainmob)
mmi = new (src)
mmi.brain = new /obj/item/organ/brain(mmi)
mmi.brain.name = "[real_name]'s brain"
@@ -170,6 +178,8 @@
mmi = null
if(connected_ai)
connected_ai.connected_robots -= src
if(shell)
available_ai_shells -= src
qdel(wires)
qdel(module)
qdel(eye_lights)
@@ -204,6 +214,8 @@
/mob/living/silicon/robot/proc/updatename()
if(shell)
return
var/changed_name = ""
if(custom_name)
changed_name = custom_name
@@ -424,7 +436,9 @@
update_icons()
else if(istype(W, /obj/item/weapon/screwdriver) && opened && cell) // radio
if(radio)
if(shell)
to_chat(user, "You cannot seem to open the radio compartment") //Prevent AI radio key theft
else if(radio)
radio.attackby(W,user)//Push it to the radio to let it handle everything
else
to_chat(user, "<span class='warning'>Unable to locate a radio!</span>")
@@ -453,6 +467,9 @@
if(!cell)
to_chat(user, "<span class='warning'>You need to install a power cell to do that!</span>")
return
if(shell) //AI shells always have the laws of the AI
to_chat(user, "<span class='warning'>[src] is controlled remotely! You cannot upload new laws this way!</span>")
return
if(emagged || (connected_ai && lawupdate)) //Can't be sure which, metagamers
emote("buzz-[user.name]")
return
@@ -813,12 +830,14 @@
if(!connected_ai)
return
switch(notifytype)
if(1) //New Cyborg
if(NEW_BORG) //New Cyborg
to_chat(connected_ai, "<br><br><span class='notice'>NOTICE - New cyborg connection detected: <a href='?src=\ref[connected_ai];track=[html_encode(name)]'>[name]</a></span><br>")
if(2) //New Module
if(NEW_MODULE) //New Module
to_chat(connected_ai, "<br><br><span class='notice'>NOTICE - Cyborg module change detected: [name] has loaded the [designation] module.</span><br>")
if(3) //New Name
if(RENAME) //New Name
to_chat(connected_ai, "<br><br><span class='notice'>NOTICE - Cyborg reclassification detected: [oldname] is now designated as [newname].</span><br>")
if(AI_SHELL) //New Shell
to_chat(connected_ai, "<br><br><span class='notice'>NOTICE - New cyborg shell detected: <a href='?src=\ref[connected_ai];track=[html_encode(name)]'>[name]</a></span><br>")
/mob/living/silicon/robot/canUseTopic(atom/movable/M, be_close = 0)
if(stat || lockcharge || low_power_mode)
@@ -901,6 +920,7 @@
update_headlamp()
diag_hud_set_status()
diag_hud_set_health()
diag_hud_set_aishell()
update_health_hud()
/mob/living/silicon/robot/revive(full_heal = 0, admin_revive = 0)
@@ -910,13 +930,13 @@
update_headlamp()
if(admin_revive)
locked = 1
notify_ai(1)
notify_ai(NEW_BORG)
. = 1
/mob/living/silicon/robot/fully_replace_character_name(oldname, newname)
..()
if(oldname != real_name)
notify_ai(3, oldname, newname)
notify_ai(RENAME, oldname, newname)
if(camera)
camera.c_tag = real_name
custom_name = newname
@@ -937,6 +957,7 @@
speed = 0
ionpulse = FALSE
revert_shell()
return 1
@@ -973,6 +994,97 @@
new_hat.forceMove(src)
update_icons()
/mob/living/silicon/robot/proc/make_shell(var/obj/item/borg/upgrade/ai/board)
if(!board)
upgrades |= new /obj/item/borg/upgrade/ai(src)
shell = TRUE
braintype = "AI Shell"
name = "[designation] AI Shell [rand(100,999)]"
real_name = name
available_ai_shells |= src
if(camera)
camera.c_tag = real_name //update the camera name too
diag_hud_set_aishell()
notify_ai(AI_SHELL)
/mob/living/silicon/robot/proc/revert_shell()
if(!shell)
return
undeploy()
for(var/obj/item/borg/upgrade/ai/boris in src)
//A player forced reset of a borg would drop the module before this is called, so this is for catching edge cases
qdel(boris)
shell = FALSE
available_ai_shells -= src
name = "Unformatted Cyborg [rand(100,999)]"
real_name = name
if(camera)
camera.c_tag = real_name
diag_hud_set_aishell()
/mob/living/silicon/robot/proc/deploy_init(var/mob/living/silicon/ai/AI)
real_name = "[AI.real_name] shell [rand(100, 999)] - [designation]" //Randomizing the name so it shows up seperately in the shells list
name = real_name
if(camera)
camera.c_tag = real_name //update the camera name too
mainframe = AI
deployed = TRUE
connected_ai = mainframe
mainframe.connected_robots |= src
lawupdate = TRUE
lawsync()
if(radio && AI.radio) //AI keeps all channels, including Syndie if it is a Traitor
if(AI.radio.syndie)
radio.make_syndie()
radio.subspace_transmission = TRUE
radio.channels = AI.radio.channels
for(var/chan in radio.channels)
radio.secure_radio_connections[chan] = add_radio(radio, radiochannels[chan])
diag_hud_set_aishell()
undeployment_action.Grant(src)
/datum/action/innate/undeployment
name = "Disconnect from shell"
desc = "Stop controlling your shell and resume normal core operations."
button_icon_state = "ai_core"
/datum/action/innate/undeployment/Trigger()
if(!..())
return FALSE
var/mob/living/silicon/robot/R = owner
R.undeploy()
return TRUE
/mob/living/silicon/robot/proc/undeploy()
if(!deployed || !mainframe)
return
mainframe.redeploy_action.Grant(mainframe)
mainframe.redeploy_action.last_used_shell = src
mind.transfer_to(mainframe)
deployed = FALSE
mainframe.deployed_shell = null
undeployment_action.Remove(src)
if(radio) //Return radio to normal
radio.recalculateChannels()
if(camera)
camera.c_tag = real_name //update the camera name too
diag_hud_set_aishell()
mainframe.diag_hud_set_deployed()
mainframe.show_laws() //Always remind the AI when switching
mainframe = null
/mob/living/silicon/robot/attack_ai(mob/user)
if(shell && (!connected_ai || connected_ai == user))
var/mob/living/silicon/ai/AI = user
AI.deploy_to_shell(src)
/mob/living/silicon/robot/shell
shell = TRUE
/mob/living/silicon/robot/MouseDrop_T(mob/living/M, mob/living/user)
. = ..()
if(!(M in buckled_mobs) && isliving(M))
@@ -16,11 +16,12 @@
if (M.a_intent == INTENT_DISARM)
if(!(lying))
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
if(get_active_held_item())
var/obj/item/I = get_active_held_item()
if(I)
uneq_active()
visible_message("<span class='danger'>[M] disarmed [src]!</span>", \
"<span class='userdanger'>[M] has disabled [src]'s active module!</span>", null, COMBAT_MESSAGE_RANGE)
add_logs(M, src, "disarmed")
add_logs(M, src, "disarmed", "[I ? " removing \the [I]" : ""]")
else
Stun(2)
step(src,get_dir(M,src))
@@ -92,6 +93,8 @@
if(locked)
to_chat(user, "<span class='notice'>You emag the cover lock.</span>")
locked = 0
if(shell) //A warning to Traitors who may not know that emagging AI shells does not slave them.
to_chat(user, "<span class='boldwarning'>[src] seems to be controlled remotely! Emagging the interface may not work as expected.</span>")
else
to_chat(user, "<span class='warning'>The cover is already unlocked!</span>")
return
@@ -125,6 +128,12 @@
log_game("[key_name(user)] attempted to emag cyborg [key_name(src)], but they were slaved to traitor AI [connected_ai].")
return
if(shell) //AI shells cannot be emagged, so we try to make it look like a standard reset. Smart players may see through this, however.
to_chat(user, "<span class='danger'>[src] is remotely controlled! Your emag attempt has triggered a system reset instead!</span>")
log_game("[key_name(user)] attempted to emag an AI shell belonging to [key_name(src) ? key_name(src) : connected_ai]. The shell has been reset as a result.")
ResetModule()
return
SetEmagged(1)
SetStunned(3) //Borgs were getting into trouble because they would attack the emagger before the new laws were shown
lawupdate = 0
@@ -218,7 +218,7 @@
R.SetLockdown(0)
R.anchored = FALSE
R.notransform = FALSE
R.notify_ai(2)
R.notify_ai(NEW_MODULE)
if(R.hud_used)
R.hud_used.update_robot_modules_display()
if(feedback_key && !did_feedback)
+1 -2
View File
@@ -21,8 +21,7 @@
var/designation = ""
var/radiomod = "" //Radio character used before state laws/arrivals announce to allow department transmissions, default, or none at all.
var/obj/item/device/camera/siliconcam/aicamera = null //photography
//hud_possible = list(DIAG_STAT_HUD, DIAG_HUD, ANTAG_HUD)
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD)
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_TRACK_HUD)
var/obj/item/device/radio/borg/radio = null //AIs dont use this but this is at the silicon level to advoid copypasta in say()
@@ -133,4 +133,4 @@
visual_effect_icon = ATTACK_EFFECT_PUNCH
else
visual_effect_icon = ATTACK_EFFECT_SMASH
..()
..()
@@ -67,6 +67,15 @@
var/visualAppearence = MAINTDRONE //What we appear as
var/hacked = 0 //If we have laws to destroy the station
var/can_be_held = TRUE //if assholes can pick us up
var/flavortext = \
"\n<big><span class='warning'>DO NOT INTERFERE WITH THE ROUND AS A DRONE OR YOU WILL BE DRONE BANNED</span></big>\n"+\
"<span class='notify'>Drones are a ghost role that are allowed to fix the station and build things. Interfering with the round as a drone is against the rules.</span>\n"+\
"<span class='notify'>Actions that constitute interference include, but are not limited to:</span>\n"+\
"<span class='notify'> - Interacting with round critical objects (IDs, weapons, contraband, powersinks, bombs, etc.)</span>\n"+\
"<span class='notify'> - Interacting with living beings (communication, attacking, healing, etc.)</span>\n"+\
"<span class='notify'> - Interacting with non-living beings (dragging bodies, looting bodies, etc.)</span>\n"+\
"<span class='warning'>These rules are at admin discretion and will be heavily enforced.</span>\n"+\
"<span class='warning'><u>If you do not have the regular drone laws, follow your laws to the best of your ability.</u></span>"
/mob/living/simple_animal/drone/Initialize()
. = ..()
@@ -121,6 +130,9 @@
..()
check_laws()
if(flavortext)
to_chat(src, "[flavortext]")
updateSeeStaticMobs()
if(!picked)
@@ -29,6 +29,7 @@
default_hatmask = /obj/item/clothing/head/helmet/space/hardsuit/syndi
seeStatic = 0 //Our programming is superior.
hacked = TRUE
flavortext = null
/mob/living/simple_animal/drone/syndrone/Initialize()
..()
@@ -119,6 +120,9 @@
hacked = TRUE
visualAppearence = CLOCKDRONE
can_be_held = FALSE
flavortext = "<span class='heavy_brass'>You are a cogscarab</span><b>, a clockwork creation of Ratvar. As a cogscarab, you have low health, an inbuilt proselytizer that can convert brass \
to liquified alloy, a set of relatively fast tools, </b><span class='heavy_brass'>can communicate over the Hierophant Network with :b</span><b>, and are immune to extreme \
temperatures and pressures. \nYour goal is to serve the Justiciar and his servants by repairing and defending all they create.</b>"
/mob/living/simple_animal/drone/cogscarab/ratvar //a subtype for spawning when ratvar is alive, has a slab that it can use and a normal proselytizer
default_storage = /obj/item/weapon/storage/toolbox/brass/prefilled/ratvar
@@ -138,10 +142,7 @@
/mob/living/simple_animal/drone/cogscarab/Login()
..()
add_servant_of_ratvar(src, TRUE)
to_chat(src, "<span class='heavy_brass'>You are a cogscarab</span><b>, a clockwork creation of Ratvar. As a cogscarab, you have low health, an inbuilt proselytizer that can convert brass \
to liquified alloy, a set of relatively fast tools, </b><span class='heavy_brass'>can communicate over the Hierophant Network with :b</span><b>, and are immune to extreme \
temperatures and pressures. \nYour goal is to serve the Justiciar and his servants by repairing and defending all they create. \
\nYou yourself are one of these servants, and will be able to utilize almost anything they can[ratvar_awakens ? "":", <i>excluding a clockwork slab</i>"].</b>")
to_chat(src,"<b>You yourself are one of these servants, and will be able to utilize almost anything they can[ratvar_awakens ? "":", <i>excluding a clockwork slab</i>"].</b>") // this can't go with flavortext because i'm assuming it requires them to be ratvar'd
/mob/living/simple_animal/drone/cogscarab/binarycheck()
return FALSE
+2 -2
View File
@@ -308,7 +308,7 @@
/mob/proc/AIize(transfer_after = TRUE)
if(client)
stopLobbySound()
stop_sound_channel(CHANNEL_LOBBYMUSIC)
var/turf/loc_landmark
for(var/obj/effect/landmark/start/sloc in landmarks_list)
@@ -385,7 +385,7 @@
R.loc = loc
R.job = "Cyborg"
R.notify_ai(1)
R.notify_ai(NEW_BORG)
. = R
qdel(src)