mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-01-09 17:02:23 +00:00
Merge with dev.
This commit is contained in:
@@ -1,2 +1,5 @@
|
||||
/mob/dead/observer/Login()
|
||||
..()
|
||||
..()
|
||||
if (ghostimage)
|
||||
ghostimage.icon_state = src.icon_state
|
||||
updateghostimages()
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
var/global/list/image/ghost_darkness_images = list() //this is a list of images for things ghosts should still be able to see when they toggle darkness
|
||||
var/global/list/image/ghost_sightless_images = list() //this is a list of images for things ghosts should still be able to see even without ghost sight
|
||||
|
||||
/mob/dead/observer
|
||||
name = "ghost"
|
||||
desc = "It's a g-g-g-g-ghooooost!" //jinkies!
|
||||
@@ -23,15 +26,22 @@
|
||||
var/atom/movable/following = null
|
||||
var/admin_ghosted = 0
|
||||
var/anonsay = 0
|
||||
var/image/ghostimage = null //this mobs ghost image, for deleting and stuff
|
||||
var/ghostvision = 1 //is the ghost able to see things humans can't?
|
||||
var/seedarkness = 1
|
||||
|
||||
/mob/dead/observer/New(mob/body)
|
||||
sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER_AI_EYE
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER
|
||||
see_in_dark = 100
|
||||
verbs += /mob/dead/observer/proc/dead_tele
|
||||
|
||||
stat = DEAD
|
||||
|
||||
ghostimage = image(src.icon,src,src.icon_state)
|
||||
ghost_darkness_images |= ghostimage
|
||||
updateallghostimages()
|
||||
|
||||
var/turf/T
|
||||
if(ismob(body))
|
||||
T = get_turf(body) //Where is the body located?
|
||||
@@ -70,7 +80,13 @@
|
||||
real_name = name
|
||||
..()
|
||||
|
||||
|
||||
/mob/dead/observer/Del()
|
||||
if (ghostimage)
|
||||
ghost_darkness_images -= ghostimage
|
||||
del(ghostimage)
|
||||
ghostimage = null
|
||||
updateallghostimages()
|
||||
..()
|
||||
|
||||
/mob/dead/observer/Topic(href, href_list)
|
||||
if (href_list["track"])
|
||||
@@ -213,8 +229,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
//world << "DEBUG: ticker not null"
|
||||
if(ticker.mode.name == "AI malfunction")
|
||||
//world << "DEBUG: malf mode ticker test"
|
||||
if(ticker.mode:malf_mode_declared)
|
||||
stat(null, "Time left: [max(ticker.mode:AI_win_timeleft/(ticker.mode:apcs/3), 0)]")
|
||||
if(malf.revealed)
|
||||
stat(null, "Time left: [max(malf.hack_time/(malf.hacked_apcs.len/3), 0)]")
|
||||
if(emergency_shuttle)
|
||||
var/eta_status = emergency_shuttle.get_status_panel_eta()
|
||||
if(eta_status)
|
||||
@@ -403,22 +419,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
src << "\blue Temperature: [round(environment.temperature-T0C,0.1)]°C ([round(environment.temperature,0.1)]K)"
|
||||
src << "\blue Heat Capacity: [round(environment.heat_capacity(),0.1)]"
|
||||
|
||||
|
||||
/mob/dead/observer/verb/toggle_sight()
|
||||
set name = "Toggle Sight"
|
||||
set category = "Ghost"
|
||||
|
||||
switch(see_invisible)
|
||||
if(SEE_INVISIBLE_OBSERVER_AI_EYE)
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER_NOOBSERVERS
|
||||
usr << "<span class='notice'>You no longer see other observers or the AI eye.</span>"
|
||||
if(SEE_INVISIBLE_OBSERVER_NOOBSERVERS)
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER_NOLIGHTING
|
||||
usr << "<span class='notice'>You no longer see darkness.</span>"
|
||||
else
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER_AI_EYE
|
||||
usr << "<span class='notice'>You again see everything.</span>"
|
||||
|
||||
/mob/dead/observer/verb/become_mouse()
|
||||
set name = "Become mouse"
|
||||
set category = "Ghost"
|
||||
@@ -459,9 +459,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
if(host)
|
||||
if(config.uneducated_mice)
|
||||
host.universal_understand = 0
|
||||
announce_ghost_joinleave(src, 0, "They are now a mouse.")
|
||||
host.ckey = src.ckey
|
||||
host << "<span class='info'>You are now a mouse. Try to avoid interaction with players, and do not give hints away that you are more than a simple rodent.</span>"
|
||||
announce_ghost_joinleave(host, 0, "They are now a mouse.")
|
||||
|
||||
/mob/dead/observer/verb/view_manfiest()
|
||||
set name = "View Crew Manifest"
|
||||
@@ -492,8 +492,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
var/ghosts_can_write
|
||||
if(ticker.mode.name == "cult")
|
||||
var/datum/game_mode/cult/C = ticker.mode
|
||||
if(C.cult.len > config.cult_ghostwriter_req_cultists)
|
||||
if(cult.current_antagonists.len > config.cult_ghostwriter_req_cultists)
|
||||
ghosts_can_write = 1
|
||||
|
||||
if(!ghosts_can_write)
|
||||
@@ -620,3 +619,43 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
/mob/dead/observer/canface()
|
||||
return 1
|
||||
|
||||
/mob/dead/observer/verb/toggle_ghostsee()
|
||||
set name = "Toggle Ghost Vision"
|
||||
set desc = "Toggles your ability to see things only ghosts can see, like other ghosts"
|
||||
set category = "Ghost"
|
||||
ghostvision = !(ghostvision)
|
||||
updateghostsight()
|
||||
usr << "You [(ghostvision?"now":"no longer")] have ghost vision."
|
||||
|
||||
/mob/dead/observer/verb/toggle_darkness()
|
||||
set name = "Toggle Darkness"
|
||||
set category = "Ghost"
|
||||
seedarkness = !(seedarkness)
|
||||
updateghostsight()
|
||||
|
||||
/mob/dead/observer/proc/updateghostsight()
|
||||
if (!seedarkness)
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER_NOLIGHTING
|
||||
else
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER
|
||||
if (!ghostvision)
|
||||
see_invisible = SEE_INVISIBLE_LIVING;
|
||||
updateghostimages()
|
||||
|
||||
/proc/updateallghostimages()
|
||||
for (var/mob/dead/observer/O in player_list)
|
||||
O.updateghostimages()
|
||||
|
||||
/mob/dead/observer/proc/updateghostimages()
|
||||
if (!client)
|
||||
return
|
||||
if (seedarkness || !ghostvision)
|
||||
client.images -= ghost_darkness_images
|
||||
client.images |= ghost_sightless_images
|
||||
else
|
||||
//add images for the 60inv things ghosts can normally see when darkness is enabled so they can see them now
|
||||
client.images -= ghost_sightless_images
|
||||
client.images |= ghost_darkness_images
|
||||
if (ghostimage)
|
||||
client.images -= ghostimage //remove ourself
|
||||
|
||||
@@ -149,9 +149,6 @@
|
||||
else
|
||||
healths.icon_state = "health7"
|
||||
|
||||
if(pullin)
|
||||
pullin.icon_state = "pull[pulling ? 1 : 0]"
|
||||
|
||||
if (client)
|
||||
client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)
|
||||
|
||||
|
||||
@@ -225,7 +225,6 @@
|
||||
else
|
||||
healths.icon_state = "health7"
|
||||
|
||||
if(pullin) pullin.icon_state = "pull[pulling ? 1 : 0]"
|
||||
if (client)
|
||||
client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)
|
||||
|
||||
|
||||
@@ -21,12 +21,11 @@
|
||||
if(germ_level < GERM_LEVEL_MOVE_CAP && prob(8))
|
||||
germ_level++
|
||||
|
||||
/mob/living/carbon/relaymove(var/mob/user, direction)
|
||||
if(user in src.stomach_contents)
|
||||
if(prob(40))
|
||||
for(var/mob/M in hearers(4, src))
|
||||
if(M.client)
|
||||
M.show_message(text("\red You hear something rumbling inside [src]'s stomach..."), 2)
|
||||
/mob/living/carbon/relaymove(var/mob/living/user, direction)
|
||||
if((user in src.stomach_contents) && istype(user))
|
||||
if(user.last_special <= world.time)
|
||||
user.last_special = world.time + 50
|
||||
src.visible_message("<span class='danger'>You hear something rumbling inside [src]'s stomach...</span>")
|
||||
var/obj/item/I = user.get_active_hand()
|
||||
if(I && I.force)
|
||||
var/d = rand(round(I.force / 4), I.force)
|
||||
@@ -40,9 +39,7 @@
|
||||
H.updatehealth()
|
||||
else
|
||||
src.take_organ_damage(d)
|
||||
for(var/mob/M in viewers(user, null))
|
||||
if(M.client)
|
||||
M.show_message(text("\red <B>[user] attacks [src]'s stomach wall with the [I.name]!"), 2)
|
||||
user.visible_message("<span class='danger'>[user] attacks [src]'s stomach wall with the [I.name]!</span>")
|
||||
playsound(user.loc, 'sound/effects/attackblob.ogg', 50, 1)
|
||||
|
||||
if(prob(src.getBruteLoss() - 50))
|
||||
@@ -192,6 +189,29 @@
|
||||
src.show_message(text("\t []My [] is [].",status=="OK"?"\blue ":"\red ",org.display_name,status),1)
|
||||
if((SKELETON in H.mutations) && (!H.w_uniform) && (!H.wear_suit))
|
||||
H.play_xylophone()
|
||||
else if (on_fire)
|
||||
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
if (M.on_fire)
|
||||
M.visible_message("<span class='warning'>[M] tries to pat out [src]'s flames, but to no avail!</span>", \
|
||||
"<span class='warning'>You try to pat out [src]'s flames, but to no avail! Put yourself out first!</span>")
|
||||
else
|
||||
M.visible_message("<span class='warning'>[M] tries to pat out [src]'s flames!</span>", \
|
||||
"<span class='warning'>You try to pat out [src]'s flames! Hot!</span>")
|
||||
if(do_mob(M, src, 15))
|
||||
if (prob(10) && (M.fire_stacks <= 0))
|
||||
src.fire_stacks -= 2
|
||||
M.fire_stacks += 1
|
||||
M.IgniteMob()
|
||||
if (M.on_fire)
|
||||
M.visible_message("<span class='danger'>The fire spreads from [src] to [M]!</span>", \
|
||||
"<span class='danger'>The fire spreads to you as well!</span>")
|
||||
else
|
||||
src.fire_stacks -= 3 //Less effective than stop, drop, and roll
|
||||
if (src.fire_stacks <= 0)
|
||||
M.visible_message("<span class='warning'>[M] successfully pats out [src]'s flames.</span>", \
|
||||
"<span class='warning'>You successfully pat out [src]'s flames.</span>")
|
||||
src.ExtinguishMob()
|
||||
src.fire_stacks = 0
|
||||
else
|
||||
var/t_him = "it"
|
||||
if (src.gender == MALE)
|
||||
@@ -218,7 +238,11 @@
|
||||
else
|
||||
M.visible_message("<span class='notice'>[M] hugs [src] to make [t_him] feel better!</span>", \
|
||||
"<span class='notice'>You hug [src] to make [t_him] feel better!</span>")
|
||||
|
||||
if(M.fire_stacks >= (src.fire_stacks + 3))
|
||||
src.fire_stacks += 1
|
||||
M.fire_stacks -= 1
|
||||
if(M.on_fire)
|
||||
src.IgniteMob()
|
||||
AdjustParalysis(-3)
|
||||
AdjustStunned(-3)
|
||||
AdjustWeakened(-3)
|
||||
|
||||
@@ -65,8 +65,6 @@
|
||||
if(ticker && ticker.mode)
|
||||
sql_report_death(src)
|
||||
ticker.mode.check_win()
|
||||
if(istype(ticker.mode,/datum/game_mode/heist))
|
||||
vox_kills++ //Bad vox. Shouldn't be killing humans.
|
||||
|
||||
return ..(gibbed,species.death_message)
|
||||
|
||||
|
||||
@@ -451,7 +451,6 @@
|
||||
msg += "\n[t_He] is [pose]"
|
||||
|
||||
user << msg
|
||||
..()
|
||||
|
||||
//Helper procedure. Called by /mob/living/carbon/human/examine() and /mob/living/carbon/human/Topic() to determine HUD access to security and medical records.
|
||||
/proc/hasHUD(mob/M as mob, hudtype)
|
||||
|
||||
@@ -48,8 +48,8 @@
|
||||
stat(null, "Intent: [a_intent]")
|
||||
stat(null, "Move Mode: [m_intent]")
|
||||
if(ticker && ticker.mode && ticker.mode.name == "AI malfunction")
|
||||
if(ticker.mode:malf_mode_declared)
|
||||
stat(null, "Time left: [max(ticker.mode:AI_win_timeleft/(ticker.mode:apcs/3), 0)]")
|
||||
if(malf.revealed)
|
||||
stat(null, "Time left: [max(malf.hack_time/(malf.hacked_apcs/3), 0)]")
|
||||
if(emergency_shuttle)
|
||||
var/eta_status = emergency_shuttle.get_status_panel_eta()
|
||||
if(eta_status)
|
||||
@@ -196,6 +196,7 @@
|
||||
var/obj/item/organ/external/affected = M.organs_by_name["head"]
|
||||
affected.implants += L
|
||||
L.part = affected
|
||||
L.implanted(src)
|
||||
|
||||
/mob/living/carbon/human/proc/is_loyalty_implanted(mob/living/carbon/human/M)
|
||||
for(var/L in M.contents)
|
||||
@@ -713,7 +714,7 @@
|
||||
if(species.has_fine_manipulation)
|
||||
return 1
|
||||
if(!silent)
|
||||
src << "<span class='warning'>You don't have the dexterity to use [src]!</span>"
|
||||
src << "<span class='warning'>You don't have the dexterity to use that!<span>"
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/abiotic(var/full_body = 0)
|
||||
|
||||
@@ -251,9 +251,6 @@ emp_act
|
||||
if(prob(I.force))
|
||||
apply_effect(20, PARALYZE, armor)
|
||||
visible_message("\red <B>[src] has been knocked unconscious!</B>")
|
||||
if(src != user && I.damtype == BRUTE)
|
||||
ticker.mode.remove_revolutionary(mind)
|
||||
|
||||
if(bloody)//Apply blood
|
||||
if(wear_mask)
|
||||
wear_mask.add_blood(src)
|
||||
@@ -319,7 +316,7 @@ emp_act
|
||||
if (O.throw_source)
|
||||
var/distance = get_dist(O.throw_source, loc)
|
||||
miss_chance = max(15*(distance-2), 0)
|
||||
zone = get_zone_with_miss_chance(zone, src, miss_chance)
|
||||
zone = get_zone_with_miss_chance(zone, src, miss_chance, ranged_attack=1)
|
||||
|
||||
if(!zone)
|
||||
visible_message("\blue \The [O] misses [src] narrowly!")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
//NOTE: Breathing happens once per FOUR TICKS, unless the last breath fails. In which case it happens once per ONE TICK! So oxyloss healing is done once per 4 ticks while oxyloss damage is applied once per tick!
|
||||
#define HUMAN_MAX_OXYLOSS 1 //Defines how much oxyloss humans can get per tick. A tile with no air at all (such as space) applies this value, otherwise it's a percentage of it.
|
||||
#define HUMAN_CRIT_MAX_OXYLOSS ( (last_tick_duration) /6) //The amount of damage you'll get when in critical condition. We want this to be a 5 minute deal = 300s. There are 50HP to get through, so (1/6)*last_tick_duration per second. Breaths however only happen every 4 ticks.
|
||||
#define HUMAN_CRIT_MAX_OXYLOSS ( (tickerProcess.getLastTickerTimeDuration()) / 6) //The amount of damage you'll get when in critical condition. We want this to be a 5 minute deal = 300s. There are 50HP to get through, so (1/6)*last_tick_duration per second. Breaths however only happen every 4 ticks.
|
||||
|
||||
#define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point
|
||||
#define HEAT_DAMAGE_LEVEL_2 4 //Amount of damage applied when your body temperature passes the 400K point
|
||||
@@ -1201,7 +1201,7 @@
|
||||
if(seer==1)
|
||||
var/obj/effect/rune/R = locate() in loc
|
||||
if(R && R.word1 == cultwords["see"] && R.word2 == cultwords["hell"] && R.word3 == cultwords["join"])
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER
|
||||
see_invisible = SEE_INVISIBLE_CULT
|
||||
else
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
seer = 0
|
||||
@@ -1218,6 +1218,8 @@
|
||||
glasses_processed = 1
|
||||
process_glasses(glasses)
|
||||
|
||||
if(!glasses_processed && (species.vision_flags > 0))
|
||||
sight |= species.vision_flags
|
||||
if(!seer && !glasses_processed)
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
|
||||
@@ -1250,9 +1252,6 @@
|
||||
if(pressure)
|
||||
pressure.icon_state = "pressure[pressure_alert]"
|
||||
|
||||
if(pullin)
|
||||
if(pulling) pullin.icon_state = "pull1"
|
||||
else pullin.icon_state = "pull0"
|
||||
// if(rest) //Not used with new UI
|
||||
// if(resting || lying || sleeping) rest.icon_state = "rest1"
|
||||
// else rest.icon_state = "rest0"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/mob/living/carbon/human/Login()
|
||||
..()
|
||||
update_hud()
|
||||
ticker.mode.update_all_synd_icons() //This proc only sounds CPU-expensive on paper. It is O(n^2), but the outer for-loop only iterates through syndicates, which are only prsenet in nuke rounds and even when they exist, there's usually 6 of them.
|
||||
if(species) species.handle_login_special(src)
|
||||
return
|
||||
@@ -37,6 +37,7 @@
|
||||
var/list/unarmed_attacks = null // For empty hand harm-intent attack
|
||||
var/brute_mod = 1 // Physical damage multiplier.
|
||||
var/burn_mod = 1 // Burn damage multiplier.
|
||||
var/vision_flags = 0 // Same flags as glasses.
|
||||
|
||||
// Death vars.
|
||||
var/gibber_type = /obj/effect/gibspawner/human
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
language = "Sol Common" //todo?
|
||||
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch)
|
||||
flags = IS_RESTRICTED | NO_BREATHE | NO_PAIN | NO_BLOOD | IS_SYNTHETIC | NO_SCAN | NO_POISON
|
||||
flags = IS_RESTRICTED | NO_BREATHE | NO_PAIN | NO_BLOOD | NO_SCAN | NO_POISON
|
||||
siemens_coefficient = 0
|
||||
|
||||
breath_type = null
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
breath_type = null
|
||||
poison_type = null
|
||||
|
||||
vision_flags = SEE_MOBS
|
||||
|
||||
has_organ = list(
|
||||
"heart" = /obj/item/organ/heart,
|
||||
"brain" = /obj/item/organ/brain/xeno,
|
||||
|
||||
@@ -439,9 +439,6 @@
|
||||
if(pressure)
|
||||
pressure.icon_state = "pressure[pressure_alert]"
|
||||
|
||||
if(pullin) pullin.icon_state = "pull[pulling ? 1 : 0]"
|
||||
|
||||
|
||||
if (toxin) toxin.icon_state = "tox[phoron_alert ? 1 : 0]"
|
||||
if (oxygen) oxygen.icon_state = "oxy[oxygen_alert ? 1 : 0]"
|
||||
if (fire) fire.icon_state = "fire[fire_alert ? 2 : 0]"
|
||||
|
||||
@@ -270,7 +270,7 @@
|
||||
//Unless its monkey mode monkeys cant use advanced tools
|
||||
/mob/living/carbon/monkey/IsAdvancedToolUser(var/silent)
|
||||
if(!silent)
|
||||
src << "<span class='warning'>You don't have the dexterity to use [src]!</span>"
|
||||
src << "<span class='warning'>You don't have the dexterity to use that!</span>"
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/monkey/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/italics=0, var/message_range = world.view, var/list/used_radios = list())
|
||||
|
||||
@@ -532,7 +532,7 @@
|
||||
del(G)
|
||||
if(GRAB_NECK)
|
||||
//If the you move when grabbing someone then it's easier for them to break free. Same if the affected mob is immune to stun.
|
||||
if (((world.time - G.assailant.l_move_time < 20 || !L.stunned) && prob(15)) || prob(3))
|
||||
if (((world.time - G.assailant.l_move_time < 30 || !L.stunned) && prob(15)) || prob(3))
|
||||
L.visible_message("<span class='warning'>[L] has broken free of [G.assailant]'s headlock!</span>")
|
||||
del(G)
|
||||
if(resisting)
|
||||
|
||||
@@ -6,21 +6,5 @@
|
||||
mind.active = 1 //indicates that the mind is currently synced with a client
|
||||
//If they're SSD, remove it so they can wake back up.
|
||||
player_logged = 0
|
||||
|
||||
//Round specific stuff like hud updates
|
||||
if(ticker && ticker.mode)
|
||||
switch(ticker.mode.name)
|
||||
if("revolution")
|
||||
if((mind in ticker.mode.revolutionaries) || (src.mind in ticker.mode:head_revolutionaries))
|
||||
ticker.mode.update_rev_icons_added(src.mind)
|
||||
if("cult")
|
||||
if(mind in ticker.mode:cult)
|
||||
ticker.mode.update_cult_icons_added(src.mind)
|
||||
if("mercenary")
|
||||
if(mind in ticker.mode:syndicates)
|
||||
ticker.mode.update_all_synd_icons()
|
||||
if("mutiny")
|
||||
var/datum/game_mode/mutiny/mode = get_mutiny_mode()
|
||||
if(mode)
|
||||
mode.update_all_icons()
|
||||
update_antag_icons(mind)
|
||||
return .
|
||||
|
||||
@@ -80,10 +80,12 @@ var/list/ai_verbs_default = list(
|
||||
/mob/living/silicon/ai/proc/add_ai_verbs()
|
||||
src.verbs |= ai_verbs_default
|
||||
src.verbs |= ai_verbs_subsystems
|
||||
src.verbs |= silicon_verbs_subsystems
|
||||
|
||||
/mob/living/silicon/ai/proc/remove_ai_verbs()
|
||||
src.verbs -= ai_verbs_default
|
||||
src.verbs -= ai_verbs_subsystems
|
||||
src.verbs -= silicon_verbs_subsystems
|
||||
|
||||
/mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0)
|
||||
announcement = new()
|
||||
@@ -187,7 +189,7 @@ var/list/ai_verbs_default = list(
|
||||
|
||||
src << radio_text
|
||||
|
||||
if (!(ticker && ticker.mode && (mind in ticker.mode.malf_ai)))
|
||||
if (!(ticker && ticker.mode && (mind in malf.current_antagonists)))
|
||||
show_laws()
|
||||
src << "<b>These laws may be changed by other players, or by you being the traitor.</b>"
|
||||
|
||||
@@ -195,6 +197,7 @@ var/list/ai_verbs_default = list(
|
||||
|
||||
/mob/living/silicon/ai/Del()
|
||||
ai_list -= src
|
||||
del(eyeobj)
|
||||
..()
|
||||
|
||||
/mob/living/silicon/ai/pointed(atom/A as mob|obj|turf in view())
|
||||
@@ -310,17 +313,15 @@ var/list/ai_verbs_default = list(
|
||||
|
||||
/mob/living/silicon/ai/proc/is_malf()
|
||||
if(ticker.mode.name == "AI malfunction")
|
||||
var/datum/game_mode/malfunction/malf = ticker.mode
|
||||
for (var/datum/mind/malfai in malf.malf_ai)
|
||||
for (var/datum/mind/malfai in malf.current_antagonists)
|
||||
if (mind == malfai)
|
||||
return malf
|
||||
return 0
|
||||
|
||||
// displays the malf_ai information if the AI is the malf
|
||||
/mob/living/silicon/ai/show_malf_ai()
|
||||
var/datum/game_mode/malfunction/malf = is_malf()
|
||||
if(malf && malf.apcs >= 3)
|
||||
stat(null, "Time until station control secured: [max(malf.AI_win_timeleft/(malf.apcs/3), 0)] seconds")
|
||||
if(malf && malf.hacked_apcs.len >= 3)
|
||||
stat(null, "Time until station control secured: [max(malf.hack_time/(malf.hacked_apcs/3), 0)] seconds")
|
||||
|
||||
// this verb lets the ai see the stations manifest
|
||||
/mob/living/silicon/ai/proc/ai_roster()
|
||||
@@ -428,25 +429,6 @@ var/list/ai_verbs_default = list(
|
||||
else
|
||||
src << "<span class='notice'>Unable to locate the holopad.</span>"
|
||||
|
||||
if (href_list["lawc"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
|
||||
var/L = text2num(href_list["lawc"])
|
||||
switch(lawcheck[L+1])
|
||||
if ("Yes") lawcheck[L+1] = "No"
|
||||
if ("No") lawcheck[L+1] = "Yes"
|
||||
// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1])
|
||||
checklaws()
|
||||
|
||||
if (href_list["lawi"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
|
||||
var/L = text2num(href_list["lawi"])
|
||||
switch(ioncheck[L])
|
||||
if ("Yes") ioncheck[L] = "No"
|
||||
if ("No") ioncheck[L] = "Yes"
|
||||
// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1])
|
||||
checklaws()
|
||||
|
||||
if (href_list["laws"]) // With how my law selection code works, I changed statelaws from a verb to a proc, and call it through my law selection panel. --NeoFite
|
||||
statelaws()
|
||||
|
||||
if (href_list["track"])
|
||||
var/mob/target = locate(href_list["track"]) in mob_list
|
||||
|
||||
@@ -602,16 +584,6 @@ var/list/ai_verbs_default = list(
|
||||
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo4"))
|
||||
return
|
||||
|
||||
/*/mob/living/silicon/ai/proc/corereturn()
|
||||
set category = "Malfunction"
|
||||
set name = "Return to Main Core"
|
||||
|
||||
var/obj/machinery/power/apc/apc = src.loc
|
||||
if(!istype(apc))
|
||||
src << "\blue You are already in your Main Core."
|
||||
return
|
||||
apc.malfvacate()*/
|
||||
|
||||
//Toggles the luminosity and applies it by re-entereing the camera.
|
||||
/mob/living/silicon/ai/proc/toggle_camera_light()
|
||||
set name = "Toggle Camera Light"
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
break
|
||||
callshuttle++
|
||||
|
||||
if(ticker.mode.name == "revolution" || ticker.mode.name == "AI malfunction" || sent_strike_team)
|
||||
if(ticker.mode.name == "revolution" || ticker.mode.name == "AI malfunction")
|
||||
callshuttle = 0
|
||||
|
||||
if(callshuttle == 3) //if all three conditions are met
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/mob/living/silicon/ai/examine(mob/user)
|
||||
if(!..(user))
|
||||
return
|
||||
|
||||
|
||||
var/msg = ""
|
||||
if (src.stat == DEAD)
|
||||
msg += "<span class='deadsay'>It appears to be powered-down.</span>\n"
|
||||
@@ -23,5 +23,14 @@
|
||||
msg += "</span>"
|
||||
msg += "*---------*</span>"
|
||||
|
||||
usr << msg
|
||||
return
|
||||
user << msg
|
||||
user.showLaws(src)
|
||||
|
||||
return
|
||||
|
||||
/mob/proc/showLaws(var/mob/living/silicon/S)
|
||||
return
|
||||
|
||||
/mob/dead/observer/showLaws(var/mob/living/silicon/S)
|
||||
if(antagHUD || is_admin(src))
|
||||
S.laws.show_laws(src)
|
||||
|
||||
@@ -75,8 +75,9 @@
|
||||
for(var/camera in cameras)
|
||||
var/obj/machinery/camera/c = camera
|
||||
|
||||
if(!c)
|
||||
if(!istype(c))
|
||||
cameras -= c
|
||||
continue
|
||||
|
||||
if(!c.can_use())
|
||||
continue
|
||||
|
||||
@@ -14,17 +14,34 @@
|
||||
status_flags = GODMODE // You can't damage it.
|
||||
see_in_dark = 7
|
||||
invisibility = INVISIBILITY_AI_EYE
|
||||
var/ghostimage = null
|
||||
|
||||
/mob/aiEye/New()
|
||||
ghostimage = image(src.icon,src,src.icon_state)
|
||||
ghost_darkness_images |= ghostimage //so ghosts can see the AI eye when they disable darkness
|
||||
ghost_sightless_images |= ghostimage //so ghosts can see the AI eye when they disable ghost sight
|
||||
updateallghostimages()
|
||||
..()
|
||||
|
||||
mob/aiEye/Del()
|
||||
if (ghostimage)
|
||||
ghost_darkness_images -= ghostimage
|
||||
ghost_sightless_images -= ghostimage
|
||||
del(ghostimage)
|
||||
ghostimage = null;
|
||||
updateallghostimages()
|
||||
..()
|
||||
|
||||
// Movement code. Returns 0 to stop air movement from moving it.
|
||||
/mob/aiEye/Move()
|
||||
return 0
|
||||
|
||||
/mob/aiEye/examinate(atom/A as mob|obj|turf in view())
|
||||
/mob/aiEye/examinate()
|
||||
set popup_menu = 0
|
||||
set src = usr.contents
|
||||
return 0
|
||||
|
||||
/mob/aiEye/pointed(atom/A as mob|obj|turf in view())
|
||||
/mob/aiEye/pointed()
|
||||
set popup_menu = 0
|
||||
set src = usr.contents
|
||||
return 0
|
||||
|
||||
@@ -36,9 +36,7 @@ var/global/list/empty_playable_ai_cores = list()
|
||||
if(mind.objectives.len)
|
||||
del(mind.objectives)
|
||||
mind.special_role = null
|
||||
else
|
||||
if(ticker.mode.name == "AutoTraitor")
|
||||
var/datum/game_mode/traitor/autotraitor/current_mode = ticker.mode
|
||||
current_mode.possible_traitors.Remove(src)
|
||||
|
||||
clear_antag_roles(mind)
|
||||
|
||||
del(src)
|
||||
@@ -15,7 +15,7 @@
|
||||
src.laws_sanity_check()
|
||||
src.laws.show_laws(who)
|
||||
|
||||
/mob/living/silicon/ai/proc/add_ion_law(var/law)
|
||||
/mob/living/silicon/ai/add_ion_law(var/law)
|
||||
src.laws_sanity_check()
|
||||
src.laws.add_ion_law(law)
|
||||
for(var/mob/living/silicon/robot/R in mob_list)
|
||||
@@ -25,4 +25,4 @@
|
||||
/mob/living/silicon/ai/proc/ai_checklaws()
|
||||
set category = "AI Commands"
|
||||
set name = "State Laws"
|
||||
checklaws()
|
||||
subsystem_law_manager()
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
var/list/ai_verbs_subsystems = list(
|
||||
/mob/living/silicon/ai/proc/subsystem_alarm_monitor,
|
||||
/mob/living/silicon/ai/proc/subsystem_crew_monitor,
|
||||
/mob/living/silicon/ai/proc/subsystem_power_monitor,
|
||||
/mob/living/silicon/ai/proc/subsystem_rcon
|
||||
)
|
||||
|
||||
/mob/living/silicon/ai
|
||||
var/
|
||||
var/list/ai_verbs_subsystems = list(
|
||||
/mob/living/silicon/ai/proc/subsystem_crew_monitor,
|
||||
/mob/living/silicon/ai/proc/subsystem_power_monitor,
|
||||
/mob/living/silicon/ai/proc/subsystem_rcon
|
||||
)
|
||||
|
||||
var/obj/nano_module/crew_monitor/crew_monitor
|
||||
var/obj/nano_module/rcon/rcon
|
||||
var/obj/nano_module/power_monitor/power_monitor
|
||||
@@ -19,26 +17,20 @@ var/list/ai_verbs_subsystems = list(
|
||||
rcon = new(src)
|
||||
power_monitor = new(src)
|
||||
|
||||
/mob/living/silicon/ai/proc/subsystem_alarm_monitor()
|
||||
set name = "Alarm Monitor"
|
||||
set category = "AI Subystems"
|
||||
|
||||
alarm_monitor.ui_interact(usr)
|
||||
|
||||
/mob/living/silicon/ai/proc/subsystem_crew_monitor()
|
||||
set category = "AI Subystems"
|
||||
set category = "Subystems"
|
||||
set name = "Crew Monitor"
|
||||
|
||||
crew_monitor.ui_interact(usr)
|
||||
|
||||
/mob/living/silicon/ai/proc/subsystem_power_monitor()
|
||||
set category = "AI Subystems"
|
||||
set category = "Subystems"
|
||||
set name = "Power Monitor"
|
||||
|
||||
power_monitor.ui_interact(usr)
|
||||
|
||||
/mob/living/silicon/ai/proc/subsystem_rcon()
|
||||
set category = "AI Subystems"
|
||||
set category = "Subystems"
|
||||
set name = "RCON"
|
||||
|
||||
rcon.ui_interact(usr)
|
||||
|
||||
@@ -1,22 +1,30 @@
|
||||
/mob/living/silicon
|
||||
var/datum/ai_laws/laws = null
|
||||
var/list/additional_law_channels = list("State")
|
||||
|
||||
/mob/living/silicon/proc/laws_sanity_check()
|
||||
if (!src.laws)
|
||||
laws = new base_law_type
|
||||
|
||||
/mob/living/silicon/proc/has_zeroth_law()
|
||||
return laws.zeroth
|
||||
return laws.zeroth_law != null
|
||||
|
||||
/mob/living/silicon/proc/set_zeroth_law(var/law, var/law_borg)
|
||||
laws_sanity_check()
|
||||
laws.set_zeroth_law(law, law_borg)
|
||||
|
||||
|
||||
/mob/living/silicon/robot/set_zeroth_law(var/law, var/law_borg)
|
||||
..()
|
||||
if(tracking_entities)
|
||||
src << "<span class='warning'>Internal camera is currently being accessed.</span>"
|
||||
|
||||
/mob/living/silicon/proc/add_inherent_law(var/law)
|
||||
/mob/living/silicon/proc/add_ion_law(var/law)
|
||||
laws_sanity_check()
|
||||
laws.add_inherent_law(law)
|
||||
laws.add_ion_law(law)
|
||||
|
||||
/mob/living/silicon/proc/add_inherent_law(var/law, var/state_law = 1)
|
||||
laws_sanity_check()
|
||||
laws.add_inherent_law(law, state_law)
|
||||
|
||||
/mob/living/silicon/proc/clear_inherent_laws()
|
||||
laws_sanity_check()
|
||||
@@ -26,15 +34,15 @@
|
||||
laws_sanity_check()
|
||||
laws.clear_ion_laws()
|
||||
|
||||
/mob/living/silicon/proc/add_supplied_law(var/number, var/law)
|
||||
/mob/living/silicon/proc/add_supplied_law(var/number, var/law, var/state_law = 1)
|
||||
laws_sanity_check()
|
||||
laws.add_supplied_law(number, law)
|
||||
laws.add_supplied_law(number, law, state_law)
|
||||
|
||||
/mob/living/silicon/proc/clear_supplied_laws()
|
||||
laws_sanity_check()
|
||||
laws.clear_supplied_laws()
|
||||
|
||||
/mob/living/silicon/proc/statelaws() // -- TLE
|
||||
/mob/living/silicon/proc/statelaws(var/datum/ai_laws/laws, var/use_statement_order = 1) // -- TLE
|
||||
var/prefix = ""
|
||||
switch(lawchannel)
|
||||
if(MAIN_CHANNEL) prefix = ";"
|
||||
@@ -42,9 +50,9 @@
|
||||
else
|
||||
prefix = get_radio_key_from_channel(lawchannel == "Holopad" ? "department" : lawchannel) + " "
|
||||
|
||||
dostatelaws(lawchannel, prefix)
|
||||
dostatelaws(lawchannel, prefix, laws, use_statement_order)
|
||||
|
||||
/mob/living/silicon/proc/dostatelaws(var/method, var/prefix)
|
||||
/mob/living/silicon/proc/dostatelaws(var/method, var/prefix, var/datum/ai_laws/laws, var/use_statement_order)
|
||||
if(stating_laws[prefix])
|
||||
src << "<span class='notice'>[method]: Already stating laws using this communication method.</span>"
|
||||
return
|
||||
@@ -53,34 +61,8 @@
|
||||
|
||||
var/can_state = statelaw("[prefix]Current Active Laws:")
|
||||
|
||||
//src.laws_sanity_check()
|
||||
//src.laws.show_laws(world)
|
||||
if (can_state && src.laws.zeroth)
|
||||
if (src.lawcheck[1] == "Yes") //This line and the similar lines below make sure you don't state a law unless you want to. --NeoFite
|
||||
can_state = statelaw("[prefix]0. [src.laws.zeroth]")
|
||||
|
||||
for (var/index = 1, can_state && index <= src.laws.ion.len, index++)
|
||||
var/law = src.laws.ion[index]
|
||||
var/num = ionnum()
|
||||
if (length(law) > 0)
|
||||
if (src.ioncheck[index] == "Yes")
|
||||
can_state = statelaw("[prefix][num]. [law]")
|
||||
|
||||
var/number = 1
|
||||
for (var/index = 1, can_state && index <= src.laws.inherent.len, index++)
|
||||
var/law = src.laws.inherent[index]
|
||||
if (length(law) > 0)
|
||||
if (src.lawcheck[index+1] == "Yes")
|
||||
can_state = statelaw("[prefix][number]. [law]")
|
||||
number++
|
||||
|
||||
for (var/index = 1, can_state && index <= src.laws.supplied.len, index++)
|
||||
var/law = src.laws.supplied[index]
|
||||
if (length(law) > 0)
|
||||
if(src.lawcheck.len >= number+1)
|
||||
if (src.lawcheck[number+1] == "Yes")
|
||||
can_state = statelaw("[prefix][number]. [law]")
|
||||
number++
|
||||
for(var/datum/ai_law/law in laws.laws_to_state())
|
||||
can_state = statelaw("[prefix][law.get_index(use_statement_order)]. [law.law]")
|
||||
|
||||
if(!can_state)
|
||||
src << "<span class='danger'>[method]: Unable to state laws. Communication method unavailable.</span>"
|
||||
@@ -93,43 +75,9 @@
|
||||
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/proc/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite
|
||||
var/list = "<b>Which laws do you want to include when stating them for the crew?</b><br><br>"
|
||||
|
||||
|
||||
if (src.laws.zeroth)
|
||||
if (!src.lawcheck[1])
|
||||
src.lawcheck[1] = "No" //Given Law 0's usual nature, it defaults to NOT getting reported. --NeoFite
|
||||
list += {"<A href='byond://?src=\ref[src];lawc=0'>[src.lawcheck[1]] 0:</A> [src.laws.zeroth]<BR>"}
|
||||
|
||||
for (var/index = 1, index <= src.laws.ion.len, index++)
|
||||
var/law = src.laws.ion[index]
|
||||
if (length(law) > 0)
|
||||
if (!src.ioncheck[index])
|
||||
src.ioncheck[index] = "Yes"
|
||||
list += {"<A href='byond://?src=\ref[src];lawi=[index]'>[src.ioncheck[index]] [ionnum()]:</A> [law]<BR>"}
|
||||
src.ioncheck.len += 1
|
||||
|
||||
var/number = 1
|
||||
for (var/index = 1, index <= src.laws.inherent.len, index++)
|
||||
var/law = src.laws.inherent[index]
|
||||
if (length(law) > 0)
|
||||
src.lawcheck.len += 1
|
||||
if (!src.lawcheck[number+1])
|
||||
src.lawcheck[number+1] = "Yes"
|
||||
list += {"<A href='byond://?src=\ref[src];lawc=[number]'>[src.lawcheck[number+1]] [number]:</A> [law]<BR>"}
|
||||
number++
|
||||
|
||||
for (var/index = 1, index <= src.laws.supplied.len, index++)
|
||||
var/law = src.laws.supplied[index]
|
||||
if (length(law) > 0)
|
||||
src.lawcheck.len += 1
|
||||
if (!src.lawcheck[number+1])
|
||||
src.lawcheck[number+1] = "Yes"
|
||||
list += {"<A href='byond://?src=\ref[src];lawc=[number]'>[src.lawcheck[number+1]] [number]:</A> [law]<BR>"}
|
||||
number++
|
||||
|
||||
list += {"<br><A href='byond://?src=\ref[src];lawr=1'>Channel: [src.lawchannel]</A><br>"}
|
||||
list += {"<A href='byond://?src=\ref[src];laws=1'>State Laws</A>"}
|
||||
|
||||
usr << browse(list, "window=laws")
|
||||
/mob/living/silicon/proc/law_channels()
|
||||
var/list/channels = new()
|
||||
channels += MAIN_CHANNEL
|
||||
channels += common_radio.channels
|
||||
channels += additional_law_channels
|
||||
return channels
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
/mob/living/silicon/Login()
|
||||
sleeping = 0
|
||||
if(mind && ticker && ticker.mode)
|
||||
ticker.mode.remove_cultist(mind, 1)
|
||||
ticker.mode.remove_revolutionary(mind, 1)
|
||||
..()
|
||||
@@ -43,8 +43,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates
|
||||
card.setPersonality(pai)
|
||||
card.looking_for_personality = 0
|
||||
|
||||
ticker.mode.update_cult_icons_removed(card.pai.mind)
|
||||
ticker.mode.update_rev_icons_removed(card.pai.mind)
|
||||
if(pai.mind) update_antag_icons(pai.mind)
|
||||
|
||||
pai_candidates -= candidate
|
||||
usr << browse(null, "window=findPai")
|
||||
|
||||
@@ -54,8 +54,6 @@
|
||||
|
||||
/mob/living/silicon/robot/drone/init()
|
||||
laws = new /datum/ai_laws/drone()
|
||||
connected_ai = null
|
||||
|
||||
aiCamera = new/obj/item/device/camera/siliconcam/drone_camera(src)
|
||||
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
|
||||
|
||||
@@ -287,7 +285,7 @@
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/drone/add_robot_verbs()
|
||||
src.verbs |= robot_verbs_subsystems
|
||||
src.verbs |= silicon_verbs_subsystems
|
||||
|
||||
/mob/living/silicon/robot/drone/remove_robot_verbs()
|
||||
src.verbs -= robot_verbs_subsystems
|
||||
src.verbs -= silicon_verbs_subsystems
|
||||
|
||||
@@ -39,4 +39,5 @@
|
||||
msg += "\nIt is [pose]"
|
||||
|
||||
user << msg
|
||||
user.showLaws(src)
|
||||
return
|
||||
|
||||
@@ -7,6 +7,17 @@
|
||||
|
||||
/*-------TODOOOOOOOOOO--------*/
|
||||
|
||||
//Verbs used by hotkeys.
|
||||
/mob/living/silicon/robot/verb/cmd_unequip_module()
|
||||
set name = "unequip-module"
|
||||
set hidden = 1
|
||||
uneq_active()
|
||||
|
||||
/mob/living/silicon/robot/verb/cmd_toggle_module(module as num)
|
||||
set name = "toggle-module"
|
||||
set hidden = 1
|
||||
toggle_module(module)
|
||||
|
||||
/mob/living/silicon/robot/proc/uneq_active()
|
||||
if(isnull(module_active))
|
||||
return
|
||||
|
||||
@@ -41,39 +41,11 @@
|
||||
/mob/living/silicon/robot/proc/lawsync()
|
||||
laws_sanity_check()
|
||||
var/datum/ai_laws/master = connected_ai ? connected_ai.laws : null
|
||||
var/temp
|
||||
if (master)
|
||||
laws.ion.len = master.ion.len
|
||||
for (var/index = 1, index <= master.ion.len, index++)
|
||||
temp = master.ion[index]
|
||||
if (length(temp) > 0)
|
||||
laws.ion[index] = temp
|
||||
|
||||
if (!is_special_character(src) || mind.original != src)
|
||||
if(master.zeroth_borg) //If the AI has a defined law zero specifically for its borgs, give it that one, otherwise give it the same one. --NEO
|
||||
temp = master.zeroth_borg
|
||||
else
|
||||
temp = master.zeroth
|
||||
laws.zeroth = temp
|
||||
|
||||
laws.inherent.len = master.inherent.len
|
||||
for (var/index = 1, index <= master.inherent.len, index++)
|
||||
temp = master.inherent[index]
|
||||
if (length(temp) > 0)
|
||||
laws.inherent[index] = temp
|
||||
|
||||
laws.supplied.len = master.supplied.len
|
||||
for (var/index = 1, index <= master.supplied.len, index++)
|
||||
temp = master.supplied[index]
|
||||
if (length(temp) > 0)
|
||||
laws.supplied[index] = temp
|
||||
master.sync(src)
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/proc/add_ion_law(var/law)
|
||||
laws_sanity_check()
|
||||
laws.add_ion_law(law)
|
||||
|
||||
/mob/living/silicon/robot/proc/robot_checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite
|
||||
/mob/living/silicon/robot/proc/robot_checklaws()
|
||||
set category = "Robot Commands"
|
||||
set name = "State Laws"
|
||||
checklaws()
|
||||
subsystem_law_manager()
|
||||
|
||||
@@ -221,18 +221,15 @@
|
||||
src.healths.icon_state = "health7"
|
||||
|
||||
if (src.syndicate && src.client)
|
||||
if(ticker.mode.name == "traitor")
|
||||
for(var/datum/mind/tra in ticker.mode.traitors)
|
||||
if(tra.current)
|
||||
var/I = image('icons/mob/mob.dmi', loc = tra.current, icon_state = "traitor")
|
||||
src.client.images += I
|
||||
if(src.connected_ai)
|
||||
src.connected_ai.connected_robots -= src
|
||||
src.connected_ai = null
|
||||
for(var/datum/mind/tra in traitors.current_antagonists)
|
||||
if(tra.current)
|
||||
var/I = image('icons/mob/mob.dmi', loc = tra.current, icon_state = "traitor")
|
||||
src.client.images += I
|
||||
src.disconnect_from_ai()
|
||||
if(src.mind)
|
||||
if(!src.mind.special_role)
|
||||
src.mind.special_role = "traitor"
|
||||
ticker.mode.traitors += src.mind
|
||||
traitors.current_antagonists |= src.mind
|
||||
|
||||
if (src.cells)
|
||||
if (src.cell)
|
||||
@@ -264,8 +261,6 @@
|
||||
else
|
||||
src.bodytemp.icon_state = "temp-2"
|
||||
|
||||
|
||||
if(src.pullin) src.pullin.icon_state = "pull[src.pulling ? 1 : 0]"
|
||||
//Oxygen and fire does nothing yet!!
|
||||
// if (src.oxygen) src.oxygen.icon_state = "oxy[src.oxygen_alert ? 1 : 0]"
|
||||
// if (src.fire) src.fire.icon_state = "fire[src.fire_alert ? 1 : 0]"
|
||||
|
||||
@@ -2,5 +2,7 @@
|
||||
..()
|
||||
regenerate_icons()
|
||||
show_laws(0)
|
||||
if(mind) ticker.mode.remove_revolutionary(mind)
|
||||
|
||||
winset(src, null, "mainwindow.macro=borgmacro hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5")
|
||||
|
||||
return
|
||||
@@ -1,8 +1,3 @@
|
||||
var/list/robot_verbs_default = list(
|
||||
/mob/living/silicon/robot/proc/sensor_mode,
|
||||
/mob/living/silicon/robot/proc/robot_checklaws
|
||||
)
|
||||
|
||||
#define CYBORG_POWER_USAGE_MULTIPLIER 2.5 // Multiplier for amount of power cyborgs use.
|
||||
|
||||
/mob/living/silicon/robot
|
||||
@@ -84,6 +79,11 @@ var/list/robot_verbs_default = list(
|
||||
var/tracking_entities = 0 //The number of known entities currently accessing the internal camera
|
||||
var/braintype = "Cyborg"
|
||||
|
||||
var/list/robot_verbs_default = list(
|
||||
/mob/living/silicon/robot/proc/sensor_mode,
|
||||
/mob/living/silicon/robot/proc/robot_checklaws
|
||||
)
|
||||
|
||||
/mob/living/silicon/robot/syndicate
|
||||
lawupdate = 0
|
||||
scrambledcodes = 1
|
||||
@@ -113,7 +113,7 @@ var/list/robot_verbs_default = list(
|
||||
robot_modules_background.layer = 19 //Objects that appear on screen are on layer 20, UI should be just below it.
|
||||
ident = rand(1, 999)
|
||||
module_sprites["Basic"] = "robot"
|
||||
icontype = "Default"
|
||||
icontype = "Basic"
|
||||
updatename("Default")
|
||||
updateicon()
|
||||
|
||||
@@ -165,11 +165,10 @@ var/list/robot_verbs_default = list(
|
||||
aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
|
||||
laws = new /datum/ai_laws/nanotrasen()
|
||||
additional_law_channels += "Binary"
|
||||
connected_ai = select_active_ai_with_fewest_borgs()
|
||||
if(connected_ai)
|
||||
connected_ai.connected_robots += src
|
||||
var/new_ai = select_active_ai_with_fewest_borgs()
|
||||
if(new_ai)
|
||||
lawupdate = 1
|
||||
sync()
|
||||
connect_to_ai(new_ai)
|
||||
else
|
||||
lawupdate = 0
|
||||
|
||||
@@ -366,7 +365,7 @@ var/list/robot_verbs_default = list(
|
||||
|
||||
choose_icon(6,module_sprites)
|
||||
radio.config(module.channels)
|
||||
notify_ai(2)
|
||||
notify_ai(ROBOT_NOTIFICATION_NEW_MODULE, module.name)
|
||||
|
||||
/mob/living/silicon/robot/proc/updatename(var/prefix as text)
|
||||
if(prefix)
|
||||
@@ -386,7 +385,7 @@ var/list/robot_verbs_default = list(
|
||||
else
|
||||
changed_name = "[modtype] [braintype]-[num2text(ident)]"
|
||||
|
||||
notify_ai(3, real_name, changed_name)
|
||||
notify_ai(ROBOT_NOTIFICATION_NEW_NAME, real_name, changed_name)
|
||||
real_name = changed_name
|
||||
name = real_name
|
||||
|
||||
@@ -507,15 +506,13 @@ var/list/robot_verbs_default = list(
|
||||
// this function shows information about the malf_ai gameplay type in the status screen
|
||||
/mob/living/silicon/robot/show_malf_ai()
|
||||
..()
|
||||
if(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)
|
||||
if(connected_ai.mind == malfai)
|
||||
if(malf.apcs >= 3)
|
||||
stat(null, "Time until station control secured: [max(malf.AI_win_timeleft/(malf.apcs/3), 0)] seconds")
|
||||
else if(ticker.mode:malf_mode_declared)
|
||||
stat(null, "Time left: [max(ticker.mode:AI_win_timeleft/(ticker.mode:apcs/3), 0)]")
|
||||
for (var/datum/mind/malfai in malf.current_antagonists)
|
||||
if(connected_ai)
|
||||
if(connected_ai.mind == malfai)
|
||||
if(malf.hacked_apcs >= 3)
|
||||
stat(null, "Time until station control secured: [max(malf.hack_time/(malf.hacked_apcs/3), 0)] seconds")
|
||||
else if(malf.revealed)
|
||||
stat(null, "Time left: [max(malf.hack_time/(malf.hacked_apcs.len/3), 0)]")
|
||||
return 0
|
||||
|
||||
|
||||
@@ -803,7 +800,7 @@ var/list/robot_verbs_default = list(
|
||||
if(prob(50))
|
||||
emagged = 1
|
||||
lawupdate = 0
|
||||
connected_ai = null
|
||||
disconnect_from_ai()
|
||||
user << "You emag [src]'s interface."
|
||||
message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.")
|
||||
log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.")
|
||||
@@ -1064,28 +1061,6 @@ var/list/robot_verbs_default = list(
|
||||
src << "Module isn't activated"
|
||||
installed_modules()
|
||||
return 1
|
||||
|
||||
if (href_list["lawc"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
|
||||
var/L = text2num(href_list["lawc"])
|
||||
switch(lawcheck[L+1])
|
||||
if ("Yes") lawcheck[L+1] = "No"
|
||||
if ("No") lawcheck[L+1] = "Yes"
|
||||
// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1])
|
||||
checklaws()
|
||||
return 1
|
||||
|
||||
if (href_list["lawi"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
|
||||
var/L = text2num(href_list["lawi"])
|
||||
switch(ioncheck[L])
|
||||
if ("Yes") ioncheck[L] = "No"
|
||||
if ("No") ioncheck[L] = "Yes"
|
||||
// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1])
|
||||
checklaws()
|
||||
return 1
|
||||
|
||||
if (href_list["laws"]) // With how my law selection code works, I changed statelaws from a verb to a proc, and call it through my law selection panel. --NeoFite
|
||||
statelaws()
|
||||
return 1
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/proc/radio_menu()
|
||||
@@ -1135,8 +1110,7 @@ var/list/robot_verbs_default = list(
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/proc/UnlinkSelf()
|
||||
if (src.connected_ai)
|
||||
src.connected_ai = null
|
||||
disconnect_from_ai()
|
||||
lawupdate = 0
|
||||
lockcharge = 0
|
||||
canmove = 1
|
||||
@@ -1217,11 +1191,11 @@ var/list/robot_verbs_default = list(
|
||||
|
||||
/mob/living/silicon/robot/proc/add_robot_verbs()
|
||||
src.verbs |= robot_verbs_default
|
||||
src.verbs |= robot_verbs_subsystems
|
||||
src.verbs |= silicon_verbs_subsystems
|
||||
|
||||
/mob/living/silicon/robot/proc/remove_robot_verbs()
|
||||
src.verbs -= robot_verbs_default
|
||||
src.verbs -= robot_verbs_subsystems
|
||||
src.verbs -= silicon_verbs_subsystems
|
||||
|
||||
// Uses power from cyborg's cell. Returns 1 on success or 0 on failure.
|
||||
// Properly converts using CELLRATE now! Amount is in Joules.
|
||||
@@ -1246,14 +1220,29 @@ var/list/robot_verbs_default = list(
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/robot/proc/notify_ai(var/notifytype, var/oldname, var/newname)
|
||||
/mob/living/silicon/robot/proc/notify_ai(var/notifytype, var/first_arg, var/second_arg)
|
||||
if(!connected_ai)
|
||||
return
|
||||
switch(notifytype)
|
||||
if(1) //New Robot
|
||||
if(ROBOT_NOTIFICATION_NEW_UNIT) //New Robot
|
||||
connected_ai << "<br><br><span class='notice'>NOTICE - New [lowertext(braintype)] connection detected: <a href='byond://?src=\ref[connected_ai];track2=\ref[connected_ai];track=\ref[src]'>[name]</a></span><br>"
|
||||
if(2) //New Module
|
||||
connected_ai << "<br><br><span class='notice'>NOTICE - [braintype] module change detected: [name] has loaded the [module.name].</span><br>"
|
||||
if(3) //New Name
|
||||
if(oldname != newname)
|
||||
connected_ai << "<br><br><span class='notice'>NOTICE - [braintype] reclassification detected: [oldname] is now designated as [newname].</span><br>"
|
||||
if(ROBOT_NOTIFICATION_NEW_MODULE) //New Module
|
||||
connected_ai << "<br><br><span class='notice'>NOTICE - [braintype] module change detected: [name] has loaded the [first_arg].</span><br>"
|
||||
if(ROBOT_NOTIFICATION_MODULE_RESET)
|
||||
connected_ai << "<br><br><span class='notice'>NOTICE - [braintype] module reset detected: [name] has unladed the [first_arg].</span><br>"
|
||||
if(ROBOT_NOTIFICATION_NEW_NAME) //New Name
|
||||
if(first_arg != second_arg)
|
||||
connected_ai << "<br><br><span class='notice'>NOTICE - [braintype] reclassification detected: [first_arg] is now designated as [second_arg].</span><br>"
|
||||
|
||||
/mob/living/silicon/robot/proc/disconnect_from_ai()
|
||||
if(connected_ai)
|
||||
connected_ai.connected_robots -= src
|
||||
connected_ai = null
|
||||
|
||||
/mob/living/silicon/robot/proc/connect_to_ai(var/mob/living/silicon/ai/AI)
|
||||
if(AI && AI != connected_ai)
|
||||
disconnect_from_ai()
|
||||
connected_ai = AI
|
||||
connected_ai.connected_robots |= src
|
||||
notify_ai(ROBOT_NOTIFICATION_NEW_UNIT)
|
||||
sync()
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
var/list/robot_verbs_subsystems = list(
|
||||
/mob/living/silicon/robot/proc/subsystem_alarm_monitor
|
||||
)
|
||||
|
||||
/mob/living/silicon/robot/proc/subsystem_alarm_monitor()
|
||||
set name = "Alarm Monitor"
|
||||
set category = "Robot Subystems"
|
||||
|
||||
alarm_monitor.ui_interact(usr)
|
||||
@@ -2,13 +2,9 @@
|
||||
gender = NEUTER
|
||||
voice_name = "synthesized voice"
|
||||
var/syndicate = 0
|
||||
var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS
|
||||
var/list/additional_law_channels = list("State")
|
||||
var/const/MAIN_CHANNEL = "Main Frequency"
|
||||
var/lawchannel = MAIN_CHANNEL // Default channel on which to state laws
|
||||
var/list/stating_laws = list()// Channels laws are currently being stated on
|
||||
var/lawcheck[1]
|
||||
var/ioncheck[1]
|
||||
var/obj/item/device/radio/common_radio
|
||||
|
||||
var/list/hud_list[10]
|
||||
@@ -22,9 +18,6 @@
|
||||
var/obj/item/device/camera/siliconcam/aiCamera = null //photography
|
||||
var/local_transmit //If set, can only speak to others of the same type within a short range.
|
||||
|
||||
// Subsystems
|
||||
var/obj/nano_module/alarm_monitor = null
|
||||
|
||||
var/sensor_mode = 0 //Determines the current HUD.
|
||||
|
||||
var/next_alarm_notice
|
||||
@@ -169,13 +162,12 @@
|
||||
|
||||
// This adds the basic clock, shuttle recall timer, and malf_ai info to all silicon lifeforms
|
||||
/mob/living/silicon/Stat()
|
||||
..()
|
||||
statpanel("Status")
|
||||
if (src.client.statpanel == "Status")
|
||||
if(statpanel("Status"))
|
||||
show_station_time()
|
||||
show_emergency_shuttle_eta()
|
||||
show_system_integrity()
|
||||
show_malf_ai()
|
||||
..()
|
||||
|
||||
// this function displays the stations manifest in a separate window
|
||||
/mob/living/silicon/proc/show_station_manifest()
|
||||
@@ -255,27 +247,6 @@
|
||||
/mob/living/silicon/binarycheck()
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if (href_list["lawr"]) // Selects on which channel to state laws
|
||||
var/list/channels = list(MAIN_CHANNEL)
|
||||
if(common_radio)
|
||||
for (var/ch_name in common_radio.channels)
|
||||
channels += ch_name
|
||||
|
||||
channels += additional_law_channels
|
||||
channels += "Cancel"
|
||||
|
||||
var/setchannel = input(usr, "Specify channel.", "Channel selection") in channels
|
||||
if(setchannel != "Cancel")
|
||||
lawchannel = setchannel
|
||||
checklaws()
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/ex_act(severity)
|
||||
if(!blinded)
|
||||
flick("flash", flash)
|
||||
@@ -299,6 +270,8 @@
|
||||
|
||||
/mob/living/silicon/proc/init_subsystems()
|
||||
alarm_monitor = new/obj/nano_module/alarm_monitor/borg(src)
|
||||
law_manager = new/obj/nano_module/law_manager(src)
|
||||
|
||||
for(var/datum/alarm_handler/AH in alarm_manager.all_handlers)
|
||||
AH.register(src, /mob/living/silicon/proc/receive_alarm)
|
||||
queued_alarms[AH] = list() // Makes sure alarms remain listed in consistent order
|
||||
|
||||
26
code/modules/mob/living/silicon/subystems.dm
Normal file
26
code/modules/mob/living/silicon/subystems.dm
Normal file
@@ -0,0 +1,26 @@
|
||||
/mob/living/silicon
|
||||
var/list/silicon_verbs_subsystems = list(
|
||||
/mob/living/silicon/proc/subsystem_alarm_monitor,
|
||||
/mob/living/silicon/proc/subsystem_law_manager
|
||||
)
|
||||
|
||||
// Subsystems
|
||||
var/obj/nano_module/alarm_monitor = null
|
||||
var/obj/nano_module/law_manager = null
|
||||
|
||||
/mob/living/silicon/robot/syndicate
|
||||
silicon_verbs_subsystems = list(
|
||||
/mob/living/silicon/proc/subsystem_law_manager
|
||||
)
|
||||
|
||||
/mob/living/silicon/proc/subsystem_alarm_monitor()
|
||||
set name = "Alarm Monitor"
|
||||
set category = "Subystems"
|
||||
|
||||
alarm_monitor.ui_interact(usr)
|
||||
|
||||
/mob/living/silicon/proc/subsystem_law_manager()
|
||||
set name = "Law Manager"
|
||||
set category = "Subystems"
|
||||
|
||||
law_manager.ui_interact(usr)
|
||||
@@ -1,5 +1,3 @@
|
||||
/datum/game_mode/var/list/borers = list()
|
||||
|
||||
/mob/living/simple_animal/borer
|
||||
name = "cortical borer"
|
||||
real_name = "cortical borer"
|
||||
@@ -155,7 +153,7 @@
|
||||
//If they're not a proper traitor, reset their antag status.
|
||||
if(host.mind.special_role == "Borer Thrall")
|
||||
host << "<span class ='danger'>You are no longer an antagonist.</span>"
|
||||
ticker.mode.borers -= host.mind
|
||||
borers.hosts -= host.mind
|
||||
host.mind.special_role = null
|
||||
|
||||
src.loc = get_turf(host)
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
//Update their traitor status.
|
||||
if(host.mind)
|
||||
if(!host.mind.special_role)
|
||||
ticker.mode.borers |= host.mind
|
||||
borers.hosts |= host.mind
|
||||
host.mind.special_role = "Borer Thrall"
|
||||
host << "<span class='danger'>A creeping lassitude surrounds you. Your mind is being invaded by an alien intelligence and that's just fine.</span>"
|
||||
host << "<span class = 'danger'>You are now a thrall to a cortical borer. Please listen to what they have to say; they're in your head.</span>"
|
||||
|
||||
@@ -1,312 +1,309 @@
|
||||
|
||||
/mob/living/simple_animal/construct
|
||||
name = "Construct"
|
||||
real_name = "Construct"
|
||||
desc = ""
|
||||
speak_emote = list("hisses")
|
||||
emote_hear = list("wails","screeches")
|
||||
response_help = "thinks better of touching"
|
||||
response_disarm = "flails at"
|
||||
response_harm = "punches"
|
||||
icon_dead = "shade_dead"
|
||||
speed = -1
|
||||
a_intent = "harm"
|
||||
stop_automated_movement = 1
|
||||
status_flags = CANPUSH
|
||||
universal_speak = 1
|
||||
attack_sound = 'sound/weapons/punch1.ogg'
|
||||
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
|
||||
faction = "cult"
|
||||
var/list/construct_spells = list()
|
||||
|
||||
/mob/living/simple_animal/construct/New()
|
||||
..()
|
||||
name = text("[initial(name)] ([rand(1, 1000)])")
|
||||
real_name = name
|
||||
for(var/spell in construct_spells)
|
||||
spell_list += new spell(src)
|
||||
|
||||
/mob/living/simple_animal/construct/death()
|
||||
new /obj/item/weapon/ectoplasm (src.loc)
|
||||
..(null,"collapses in a shattered heap.")
|
||||
ghostize()
|
||||
del src
|
||||
|
||||
|
||||
/mob/living/simple_animal/construct/attack_generic(var/mob/user)
|
||||
if(istype(user, /mob/living/simple_animal/construct/builder))
|
||||
if(health < maxHealth)
|
||||
adjustBruteLoss(-5)
|
||||
user.visible_message("<b>\The [user]</b> mends some of \the [src]'s wounds.")
|
||||
else
|
||||
user << "<span class='notice'>\The [src] is undamaged.</span>"
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/construct/examine(mob/user)
|
||||
..(user)
|
||||
var/msg = ""
|
||||
if (src.health < src.maxHealth)
|
||||
msg += "<span class='warning'>"
|
||||
if (src.health >= src.maxHealth/2)
|
||||
msg += "It looks slightly dented.\n"
|
||||
else
|
||||
msg += "<B>It looks severely dented!</B>\n"
|
||||
msg += "</span>"
|
||||
msg += "*---------*</span>"
|
||||
|
||||
user << msg
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/construct/Bump(atom/movable/AM as mob|obj, yes)
|
||||
if ((!( yes ) || now_pushing))
|
||||
return
|
||||
now_pushing = 1
|
||||
if(ismob(AM))
|
||||
var/mob/tmob = AM
|
||||
if(!(tmob.status_flags & CANPUSH))
|
||||
now_pushing = 0
|
||||
return
|
||||
|
||||
tmob.LAssailant = src
|
||||
now_pushing = 0
|
||||
..()
|
||||
if (!istype(AM, /atom/movable))
|
||||
return
|
||||
if (!( now_pushing ))
|
||||
now_pushing = 1
|
||||
if (!( AM.anchored ))
|
||||
var/t = get_dir(src, AM)
|
||||
if (istype(AM, /obj/structure/window))
|
||||
var/obj/structure/window/W = AM
|
||||
if(W.is_full_window())
|
||||
for(var/obj/structure/window/win in get_step(AM,t))
|
||||
now_pushing = 0
|
||||
return
|
||||
step(AM, t)
|
||||
now_pushing = null
|
||||
|
||||
/mob/living/simple_animal/construct/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if(O.force)
|
||||
var/damage = O.force
|
||||
if (O.damtype == HALLOSS)
|
||||
damage = 0
|
||||
adjustBruteLoss(damage)
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red \b [src] has been attacked with [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 [O]. ")
|
||||
|
||||
|
||||
|
||||
/////////////////Juggernaut///////////////
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/construct/armoured
|
||||
name = "Juggernaut"
|
||||
real_name = "Juggernaut"
|
||||
desc = "A possessed suit of armour driven by the will of the restless dead"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "behemoth"
|
||||
icon_living = "behemoth"
|
||||
maxHealth = 250
|
||||
health = 250
|
||||
response_harm = "harmlessly punches"
|
||||
harm_intent_damage = 0
|
||||
melee_damage_lower = 30
|
||||
melee_damage_upper = 30
|
||||
attacktext = "smashed their armoured gauntlet into"
|
||||
mob_size = 20
|
||||
speed = 3
|
||||
wall_smash = 1
|
||||
attack_sound = 'sound/weapons/punch3.ogg'
|
||||
status_flags = 0
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall)
|
||||
|
||||
/mob/living/simple_animal/construct/armoured/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if(O.force)
|
||||
if(O.force >= 11)
|
||||
var/damage = O.force
|
||||
if (O.damtype == HALLOSS)
|
||||
damage = 0
|
||||
adjustBruteLoss(damage)
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red \b [src] has been attacked with [O] by [user]. ")
|
||||
else
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red \b [O] bounces harmlessly off of [src]. ")
|
||||
else
|
||||
usr << "\red This weapon is ineffective, it does no damage."
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red [user] gently taps [src] with [O]. ")
|
||||
|
||||
|
||||
/mob/living/simple_animal/construct/armoured/Life()
|
||||
weakened = 0
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/construct/armoured/bullet_act(var/obj/item/projectile/P)
|
||||
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
|
||||
var/reflectchance = 80 - round(P.damage/3)
|
||||
if(prob(reflectchance))
|
||||
adjustBruteLoss(P.damage * 0.5)
|
||||
visible_message("<span class='danger'>\The [P] was reflected by \the [src]'s shell!</span>", \
|
||||
"<span class='userdanger'>\The [P] was reflected by \the [src]'s shell!</span>")
|
||||
|
||||
// Find a turf near or on the original location to bounce to
|
||||
if(P.starting)
|
||||
var/new_x = P.starting.x + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3)
|
||||
var/new_y = P.starting.y + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3)
|
||||
var/turf/curloc = get_turf(src)
|
||||
|
||||
// redirect the projectile
|
||||
P.redirect(new_x, new_y, curloc, src)
|
||||
|
||||
return -1 // complete projectile permutation
|
||||
|
||||
return (..(P))
|
||||
|
||||
|
||||
|
||||
////////////////////////Wraith/////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/construct/wraith
|
||||
name = "Wraith"
|
||||
real_name = "Wraith"
|
||||
desc = "A wicked bladed shell contraption piloted by a bound spirit"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "floating"
|
||||
icon_living = "floating"
|
||||
maxHealth = 75
|
||||
health = 75
|
||||
melee_damage_lower = 25
|
||||
melee_damage_upper = 25
|
||||
attacktext = "slashed"
|
||||
speed = -1
|
||||
see_in_dark = 7
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift)
|
||||
|
||||
|
||||
|
||||
/////////////////////////////Artificer/////////////////////////
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/construct/builder
|
||||
name = "Artificer"
|
||||
real_name = "Artificer"
|
||||
desc = "A bulbous construct dedicated to building and maintaining The Cult of Nar-Sie's armies"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "artificer"
|
||||
icon_living = "artificer"
|
||||
maxHealth = 50
|
||||
health = 50
|
||||
response_harm = "viciously beats"
|
||||
harm_intent_damage = 5
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 5
|
||||
attacktext = "rammed"
|
||||
speed = 0
|
||||
wall_smash = 1
|
||||
attack_sound = 'sound/weapons/punch2.ogg'
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser,
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/wall,
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/floor,
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone,)
|
||||
|
||||
|
||||
/////////////////////////////Behemoth/////////////////////////
|
||||
|
||||
|
||||
/mob/living/simple_animal/construct/behemoth
|
||||
name = "Behemoth"
|
||||
real_name = "Behemoth"
|
||||
desc = "The pinnacle of occult technology, Behemoths are the ultimate weapon in the Cult of Nar-Sie's arsenal."
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "behemoth"
|
||||
icon_living = "behemoth"
|
||||
maxHealth = 750
|
||||
health = 750
|
||||
speak_emote = list("rumbles")
|
||||
response_harm = "harmlessly punches"
|
||||
harm_intent_damage = 0
|
||||
melee_damage_lower = 50
|
||||
melee_damage_upper = 50
|
||||
attacktext = "brutally crushed"
|
||||
speed = 5
|
||||
wall_smash = 1
|
||||
attack_sound = 'sound/weapons/punch4.ogg'
|
||||
mob_size = 20
|
||||
var/energy = 0
|
||||
var/max_energy = 1000
|
||||
|
||||
/mob/living/simple_animal/construct/behemoth/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if(O.force)
|
||||
if(O.force >= 11)
|
||||
var/damage = O.force
|
||||
if (O.damtype == HALLOSS)
|
||||
damage = 0
|
||||
adjustBruteLoss(damage)
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red \b [src] has been attacked with [O] by [user]. ")
|
||||
else
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red \b [O] bounces harmlessly off of [src]. ")
|
||||
else
|
||||
usr << "\red This weapon is ineffective, it does no damage."
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red [user] gently taps [src] with [O]. ")
|
||||
|
||||
|
||||
|
||||
////////////////Powers//////////////////
|
||||
|
||||
|
||||
/*
|
||||
/client/proc/summon_cultist()
|
||||
set category = "Behemoth"
|
||||
set name = "Summon Cultist (300)"
|
||||
set desc = "Teleport a cultist to your location"
|
||||
if (istype(usr,/mob/living/simple_animal/constructbehemoth))
|
||||
|
||||
if(usr.energy<300)
|
||||
usr << "\red You do not have enough power stored!"
|
||||
return
|
||||
|
||||
if(usr.stat)
|
||||
return
|
||||
|
||||
usr.energy -= 300
|
||||
var/list/mob/living/cultists = new
|
||||
for(var/datum/mind/H in ticker.mode.cult)
|
||||
if (istype(H.current,/mob/living))
|
||||
cultists+=H.current
|
||||
var/mob/cultist = input("Choose the one who you want to summon", "Followers of Geometer") as null|anything in (cultists - usr)
|
||||
if(!cultist)
|
||||
return
|
||||
if (cultist == usr) //just to be sure.
|
||||
return
|
||||
cultist.loc = usr.loc
|
||||
usr.visible_message("/red [cultist] appears in a flash of red light as [usr] glows with power")*/
|
||||
|
||||
/mob/living/simple_animal/construct
|
||||
name = "Construct"
|
||||
real_name = "Construct"
|
||||
desc = ""
|
||||
speak_emote = list("hisses")
|
||||
emote_hear = list("wails","screeches")
|
||||
response_help = "thinks better of touching"
|
||||
response_disarm = "flails at"
|
||||
response_harm = "punches"
|
||||
icon_dead = "shade_dead"
|
||||
speed = -1
|
||||
a_intent = "harm"
|
||||
stop_automated_movement = 1
|
||||
status_flags = CANPUSH
|
||||
universal_speak = 1
|
||||
attack_sound = 'sound/weapons/punch1.ogg'
|
||||
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
|
||||
faction = "cult"
|
||||
var/list/construct_spells = list()
|
||||
|
||||
/mob/living/simple_animal/construct/New()
|
||||
..()
|
||||
name = text("[initial(name)] ([rand(1, 1000)])")
|
||||
real_name = name
|
||||
for(var/spell in construct_spells)
|
||||
spell_list += new spell(src)
|
||||
|
||||
/mob/living/simple_animal/construct/death()
|
||||
new /obj/item/weapon/ectoplasm (src.loc)
|
||||
..(null,"collapses in a shattered heap.")
|
||||
ghostize()
|
||||
del src
|
||||
|
||||
|
||||
/mob/living/simple_animal/construct/attack_generic(var/mob/user)
|
||||
if(istype(user, /mob/living/simple_animal/construct/builder))
|
||||
if(health < maxHealth)
|
||||
adjustBruteLoss(-5)
|
||||
user.visible_message("<b>\The [user]</b> mends some of \the [src]'s wounds.")
|
||||
else
|
||||
user << "<span class='notice'>\The [src] is undamaged.</span>"
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/construct/examine(mob/user)
|
||||
..(user)
|
||||
var/msg = ""
|
||||
if (src.health < src.maxHealth)
|
||||
msg += "<span class='warning'>"
|
||||
if (src.health >= src.maxHealth/2)
|
||||
msg += "It looks slightly dented.\n"
|
||||
else
|
||||
msg += "<B>It looks severely dented!</B>\n"
|
||||
msg += "</span>"
|
||||
msg += "*---------*</span>"
|
||||
|
||||
user << msg
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/construct/Bump(atom/movable/AM as mob|obj, yes)
|
||||
if ((!( yes ) || now_pushing))
|
||||
return
|
||||
now_pushing = 1
|
||||
if(ismob(AM))
|
||||
var/mob/tmob = AM
|
||||
if(!(tmob.status_flags & CANPUSH))
|
||||
now_pushing = 0
|
||||
return
|
||||
|
||||
tmob.LAssailant = src
|
||||
now_pushing = 0
|
||||
..()
|
||||
if (!istype(AM, /atom/movable))
|
||||
return
|
||||
if (!( now_pushing ))
|
||||
now_pushing = 1
|
||||
if (!( AM.anchored ))
|
||||
var/t = get_dir(src, AM)
|
||||
if (istype(AM, /obj/structure/window))
|
||||
var/obj/structure/window/W = AM
|
||||
if(W.is_full_window())
|
||||
for(var/obj/structure/window/win in get_step(AM,t))
|
||||
now_pushing = 0
|
||||
return
|
||||
step(AM, t)
|
||||
now_pushing = null
|
||||
|
||||
/mob/living/simple_animal/construct/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if(O.force)
|
||||
var/damage = O.force
|
||||
if (O.damtype == HALLOSS)
|
||||
damage = 0
|
||||
adjustBruteLoss(damage)
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red \b [src] has been attacked with [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 [O]. ")
|
||||
|
||||
|
||||
|
||||
/////////////////Juggernaut///////////////
|
||||
/mob/living/simple_animal/construct/armoured
|
||||
name = "Juggernaut"
|
||||
real_name = "Juggernaut"
|
||||
desc = "A possessed suit of armour driven by the will of the restless dead"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "behemoth"
|
||||
icon_living = "behemoth"
|
||||
maxHealth = 250
|
||||
health = 250
|
||||
response_harm = "harmlessly punches"
|
||||
harm_intent_damage = 0
|
||||
melee_damage_lower = 30
|
||||
melee_damage_upper = 30
|
||||
attacktext = "smashed their armoured gauntlet into"
|
||||
mob_size = 20
|
||||
speed = 3
|
||||
wall_smash = 1
|
||||
attack_sound = 'sound/weapons/punch3.ogg'
|
||||
status_flags = 0
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall)
|
||||
|
||||
/mob/living/simple_animal/construct/armoured/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if(O.force)
|
||||
if(O.force >= 11)
|
||||
var/damage = O.force
|
||||
if (O.damtype == HALLOSS)
|
||||
damage = 0
|
||||
adjustBruteLoss(damage)
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red \b [src] has been attacked with [O] by [user]. ")
|
||||
else
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red \b [O] bounces harmlessly off of [src]. ")
|
||||
else
|
||||
usr << "\red This weapon is ineffective, it does no damage."
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red [user] gently taps [src] with [O]. ")
|
||||
|
||||
|
||||
/mob/living/simple_animal/construct/armoured/Life()
|
||||
weakened = 0
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/construct/armoured/bullet_act(var/obj/item/projectile/P)
|
||||
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
|
||||
var/reflectchance = 80 - round(P.damage/3)
|
||||
if(prob(reflectchance))
|
||||
adjustBruteLoss(P.damage * 0.5)
|
||||
visible_message("<span class='danger'>\The [P] was reflected by \the [src]'s shell!</span>", \
|
||||
"<span class='userdanger'>\The [P] was reflected by \the [src]'s shell!</span>")
|
||||
|
||||
// Find a turf near or on the original location to bounce to
|
||||
if(P.starting)
|
||||
var/new_x = P.starting.x + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3)
|
||||
var/new_y = P.starting.y + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3)
|
||||
var/turf/curloc = get_turf(src)
|
||||
|
||||
// redirect the projectile
|
||||
P.redirect(new_x, new_y, curloc, src)
|
||||
|
||||
return -1 // complete projectile permutation
|
||||
|
||||
return (..(P))
|
||||
|
||||
|
||||
|
||||
////////////////////////Wraith/////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/construct/wraith
|
||||
name = "Wraith"
|
||||
real_name = "Wraith"
|
||||
desc = "A wicked bladed shell contraption piloted by a bound spirit"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "floating"
|
||||
icon_living = "floating"
|
||||
maxHealth = 75
|
||||
health = 75
|
||||
melee_damage_lower = 25
|
||||
melee_damage_upper = 25
|
||||
attacktext = "slashed"
|
||||
speed = -1
|
||||
see_in_dark = 7
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift)
|
||||
|
||||
|
||||
|
||||
/////////////////////////////Artificer/////////////////////////
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/construct/builder
|
||||
name = "Artificer"
|
||||
real_name = "Artificer"
|
||||
desc = "A bulbous construct dedicated to building and maintaining The Cult of Nar-Sie's armies"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "artificer"
|
||||
icon_living = "artificer"
|
||||
maxHealth = 50
|
||||
health = 50
|
||||
response_harm = "viciously beats"
|
||||
harm_intent_damage = 5
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 5
|
||||
attacktext = "rammed"
|
||||
speed = 0
|
||||
wall_smash = 1
|
||||
attack_sound = 'sound/weapons/punch2.ogg'
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser,
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/wall,
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/floor,
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone,)
|
||||
|
||||
|
||||
/////////////////////////////Behemoth/////////////////////////
|
||||
|
||||
|
||||
/mob/living/simple_animal/construct/behemoth
|
||||
name = "Behemoth"
|
||||
real_name = "Behemoth"
|
||||
desc = "The pinnacle of occult technology, Behemoths are the ultimate weapon in the Cult of Nar-Sie's arsenal."
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "behemoth"
|
||||
icon_living = "behemoth"
|
||||
maxHealth = 750
|
||||
health = 750
|
||||
speak_emote = list("rumbles")
|
||||
response_harm = "harmlessly punches"
|
||||
harm_intent_damage = 0
|
||||
melee_damage_lower = 50
|
||||
melee_damage_upper = 50
|
||||
attacktext = "brutally crushed"
|
||||
speed = 5
|
||||
wall_smash = 1
|
||||
attack_sound = 'sound/weapons/punch4.ogg'
|
||||
mob_size = 20
|
||||
var/energy = 0
|
||||
var/max_energy = 1000
|
||||
|
||||
/mob/living/simple_animal/construct/behemoth/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if(O.force)
|
||||
if(O.force >= 11)
|
||||
var/damage = O.force
|
||||
if (O.damtype == HALLOSS)
|
||||
damage = 0
|
||||
adjustBruteLoss(damage)
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red \b [src] has been attacked with [O] by [user]. ")
|
||||
else
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red \b [O] bounces harmlessly off of [src]. ")
|
||||
else
|
||||
usr << "\red This weapon is ineffective, it does no damage."
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red [user] gently taps [src] with [O]. ")
|
||||
|
||||
|
||||
|
||||
////////////////Powers//////////////////
|
||||
|
||||
|
||||
/*
|
||||
/client/proc/summon_cultist()
|
||||
set category = "Behemoth"
|
||||
set name = "Summon Cultist (300)"
|
||||
set desc = "Teleport a cultist to your location"
|
||||
if (istype(usr,/mob/living/simple_animal/constructbehemoth))
|
||||
|
||||
if(usr.energy<300)
|
||||
usr << "\red You do not have enough power stored!"
|
||||
return
|
||||
|
||||
if(usr.stat)
|
||||
return
|
||||
|
||||
usr.energy -= 300
|
||||
var/list/mob/living/cultists = new
|
||||
for(var/datum/mind/H in ticker.mode.cult)
|
||||
if (istype(H.current,/mob/living))
|
||||
cultists+=H.current
|
||||
var/mob/cultist = input("Choose the one who you want to summon", "Followers of Geometer") as null|anything in (cultists - usr)
|
||||
if(!cultist)
|
||||
return
|
||||
if (cultist == usr) //just to be sure.
|
||||
return
|
||||
cultist.loc = usr.loc
|
||||
usr.visible_message("/red [cultist] appears in a flash of red light as [usr] glows with power")*/
|
||||
207
code/modules/mob/living/simple_animal/constructs/soulstone.dm
Normal file
207
code/modules/mob/living/simple_animal/constructs/soulstone.dm
Normal file
@@ -0,0 +1,207 @@
|
||||
/obj/item/device/soulstone
|
||||
name = "Soul Stone Shard"
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "soulstone"
|
||||
item_state = "electronic"
|
||||
desc = "A fragment of the legendary treasure known simply as the 'Soul Stone'. The shard still flickers with a fraction of the full artefacts power."
|
||||
w_class = 1.0
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = "bluespace=4;materials=4"
|
||||
var/imprinted = "empty"
|
||||
|
||||
|
||||
//////////////////////////////Capturing////////////////////////////////////////////////////////
|
||||
|
||||
attack(mob/living/carbon/human/M as mob, mob/user as mob)
|
||||
if(!istype(M, /mob/living/carbon/human))//If target is not a human.
|
||||
return ..()
|
||||
if(istype(M, /mob/living/carbon/human/dummy))
|
||||
return..()
|
||||
|
||||
if(M.has_brain_worms()) //Borer stuff - RR
|
||||
user << "<span class='warning'>This being is corrupted by an alien intelligence and cannot be soul trapped.</span>"
|
||||
return..()
|
||||
|
||||
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their soul captured with [src.name] by [user.name] ([user.ckey])</font>")
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to capture the soul of [M.name] ([M.ckey])</font>")
|
||||
msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] to capture the soul of [M.name] ([M.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
|
||||
transfer_soul("VICTIM", M, user)
|
||||
return
|
||||
|
||||
/*attack(mob/living/simple_animal/shade/M as mob, mob/user as mob)//APPARENTLY THEY NEED THEIR OWN SPECIAL SNOWFLAKE CODE IN THE LIVING ANIMAL DEFINES
|
||||
if(!istype(M, /mob/living/simple_animal/shade))//If target is not a shade
|
||||
return ..()
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to capture the soul of [M.name] ([M.ckey])</font>")
|
||||
|
||||
transfer_soul("SHADE", M, user)
|
||||
return*/
|
||||
///////////////////Options for using captured souls///////////////////////////////////////
|
||||
|
||||
attack_self(mob/user)
|
||||
if (!in_range(src, user))
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = "<TT><B>Soul Stone</B><BR>"
|
||||
for(var/mob/living/simple_animal/shade/A in src)
|
||||
dat += "Captured Soul: [A.name]<br>"
|
||||
dat += {"<A href='byond://?src=\ref[src];choice=Summon'>Summon Shade</A>"}
|
||||
dat += "<br>"
|
||||
dat += {"<a href='byond://?src=\ref[src];choice=Close'> Close</a>"}
|
||||
user << browse(dat, "window=aicard")
|
||||
onclose(user, "aicard")
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
Topic(href, href_list)
|
||||
var/mob/U = usr
|
||||
if (!in_range(src, U)||U.machine!=src)
|
||||
U << browse(null, "window=aicard")
|
||||
U.unset_machine()
|
||||
return
|
||||
|
||||
add_fingerprint(U)
|
||||
U.set_machine(src)
|
||||
|
||||
switch(href_list["choice"])//Now we switch based on choice.
|
||||
if ("Close")
|
||||
U << browse(null, "window=aicard")
|
||||
U.unset_machine()
|
||||
return
|
||||
|
||||
if ("Summon")
|
||||
for(var/mob/living/simple_animal/shade/A in src)
|
||||
A.status_flags &= ~GODMODE
|
||||
A.canmove = 1
|
||||
A << "<b>You have been released from your prison, but you are still bound to [U.name]'s will. Help them suceed in their goals at all costs.</b>"
|
||||
A.loc = U.loc
|
||||
A.cancel_camera()
|
||||
src.icon_state = "soulstone"
|
||||
attack_self(U)
|
||||
|
||||
///////////////////////////Transferring to constructs/////////////////////////////////////////////////////
|
||||
/obj/structure/constructshell
|
||||
name = "empty shell"
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "construct"
|
||||
desc = "A wicked machine used by those skilled in magical arts. It is inactive"
|
||||
|
||||
/obj/structure/constructshell/attackby(obj/item/O as obj, mob/user as mob)
|
||||
if(istype(O, /obj/item/device/soulstone))
|
||||
O.transfer_soul("CONSTRUCT",src,user)
|
||||
|
||||
|
||||
////////////////////////////Proc for moving soul in and out off stone//////////////////////////////////////
|
||||
|
||||
|
||||
/obj/item/proc/transfer_soul(var/choice as text, var/target, var/mob/U as mob).
|
||||
switch(choice)
|
||||
if("VICTIM")
|
||||
var/mob/living/carbon/human/T = target
|
||||
var/obj/item/device/soulstone/C = src
|
||||
if(C.imprinted != "empty")
|
||||
U << "\red <b>Capture failed!</b>: \black The soul stone has already been imprinted with [C.imprinted]'s mind!"
|
||||
else
|
||||
if ((T.health + T.halloss) > config.health_threshold_crit)
|
||||
U << "\red <b>Capture failed!</b>: \black Kill or maim the victim first!"
|
||||
else
|
||||
if(T.client == null)
|
||||
U << "\red <b>Capture failed!</b>: \black The soul has already fled it's mortal frame."
|
||||
else
|
||||
if(C.contents.len)
|
||||
U << "\red <b>Capture failed!</b>: \black The soul stone is full! Use or free an existing soul to make room."
|
||||
else
|
||||
for(var/obj/item/W in T)
|
||||
T.drop_from_inventory(W)
|
||||
new /obj/effect/decal/remains/human(T.loc) //Spawns a skeleton
|
||||
T.invisibility = 101
|
||||
var/atom/movable/overlay/animation = new /atom/movable/overlay( T.loc )
|
||||
animation.icon_state = "blank"
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.master = T
|
||||
flick("dust-h", animation)
|
||||
del(animation)
|
||||
var/mob/living/simple_animal/shade/S = new /mob/living/simple_animal/shade( T.loc )
|
||||
S.loc = C //put shade in stone
|
||||
S.status_flags |= GODMODE //So they won't die inside the stone somehow
|
||||
S.canmove = 0//Can't move out of the soul stone
|
||||
S.name = "Shade of [T.real_name]"
|
||||
S.real_name = "Shade of [T.real_name]"
|
||||
S.icon = T.icon
|
||||
S.icon_state = T.icon_state
|
||||
S.overlays = T.overlays
|
||||
S.color = rgb(254,0,0)
|
||||
S.alpha = 127
|
||||
if (T.client)
|
||||
T.client.mob = S
|
||||
S.cancel_camera()
|
||||
C.icon_state = "soulstone2"
|
||||
C.name = "Soul Stone: [S.real_name]"
|
||||
S << "Your soul has been captured! You are now bound to [U.name]'s will, help them suceed in their goals at all costs."
|
||||
U << "\blue <b>Capture successful!</b>: \black [T.real_name]'s soul has been ripped from their body and stored within the soul stone."
|
||||
U << "The soulstone has been imprinted with [S.real_name]'s mind, it will no longer react to other souls."
|
||||
C.imprinted = "[S.name]"
|
||||
del T
|
||||
if("SHADE")
|
||||
var/mob/living/simple_animal/shade/T = target
|
||||
var/obj/item/device/soulstone/C = src
|
||||
if (T.stat == DEAD)
|
||||
U << "\red <b>Capture failed!</b>: \black The shade has already been banished!"
|
||||
else
|
||||
if(C.contents.len)
|
||||
U << "\red <b>Capture failed!</b>: \black The soul stone is full! Use or free an existing soul to make room."
|
||||
else
|
||||
if(T.name != C.imprinted)
|
||||
U << "\red <b>Capture failed!</b>: \black The soul stone has already been imprinted with [C.imprinted]'s mind!"
|
||||
else
|
||||
T.loc = C //put shade in stone
|
||||
T.status_flags |= GODMODE
|
||||
T.canmove = 0
|
||||
T.health = T.maxHealth
|
||||
C.icon_state = "soulstone2"
|
||||
T << "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form"
|
||||
U << "\blue <b>Capture successful!</b>: \black [T.name]'s has been recaptured and stored within the soul stone."
|
||||
if("CONSTRUCT")
|
||||
var/obj/structure/constructshell/T = target
|
||||
var/obj/item/device/soulstone/C = src
|
||||
var/mob/living/simple_animal/shade/A = locate() in C
|
||||
if(A)
|
||||
var/construct_class = alert(U, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer")
|
||||
switch(construct_class)
|
||||
if("Juggernaut")
|
||||
var/mob/living/simple_animal/construct/armoured/Z = new /mob/living/simple_animal/construct/armoured (get_turf(T.loc))
|
||||
Z.key = A.key
|
||||
if(iscultist(U))
|
||||
cult.add_antagonist(Z.mind)
|
||||
del(T)
|
||||
Z << "<B>You are playing a Juggernaut. Though slow, you can withstand extreme punishment, and rip apart enemies and walls alike.</B>"
|
||||
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
|
||||
Z.cancel_camera()
|
||||
del(C)
|
||||
|
||||
if("Wraith")
|
||||
var/mob/living/simple_animal/construct/wraith/Z = new /mob/living/simple_animal/construct/wraith (get_turf(T.loc))
|
||||
Z.key = A.key
|
||||
if(iscultist(U))
|
||||
cult.add_antagonist(Z.mind)
|
||||
del(T)
|
||||
Z << "<B>You are playing a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.</B>"
|
||||
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
|
||||
Z.cancel_camera()
|
||||
del(C)
|
||||
|
||||
if("Artificer")
|
||||
var/mob/living/simple_animal/construct/builder/Z = new /mob/living/simple_animal/construct/builder (get_turf(T.loc))
|
||||
Z.key = A.key
|
||||
if(iscultist(U))
|
||||
cult.add_antagonist(Z.mind)
|
||||
del(T)
|
||||
Z << "<B>You are playing an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, repair allied constructs (by clicking on them), and even create new constructs</B>"
|
||||
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
|
||||
Z.cancel_camera()
|
||||
del(C)
|
||||
else
|
||||
U << "\red <b>Creation failed!</b>: \black The soul stone is empty! Go kill someone!"
|
||||
return
|
||||
@@ -16,7 +16,7 @@
|
||||
speak_chance = 5
|
||||
turns_per_move = 5
|
||||
see_in_dark = 10
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "pokes"
|
||||
|
||||
@@ -239,7 +239,7 @@
|
||||
if (!(status_flags & CANPUSH))
|
||||
return
|
||||
|
||||
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src )
|
||||
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src)
|
||||
|
||||
M.put_in_active_hand(G)
|
||||
|
||||
@@ -308,9 +308,8 @@
|
||||
|
||||
/mob/living/simple_animal/death()
|
||||
icon_state = icon_dead
|
||||
stat = DEAD
|
||||
density = 0
|
||||
return ..()
|
||||
return ..(deathmessage = "no message")
|
||||
|
||||
/mob/living/simple_animal/ex_act(severity)
|
||||
if(!blinded)
|
||||
@@ -375,4 +374,4 @@
|
||||
|
||||
/mob/living/simple_animal/put_in_hands(var/obj/item/W) // No hands.
|
||||
W.loc = get_turf(src)
|
||||
return 1
|
||||
return 1
|
||||
|
||||
@@ -43,4 +43,7 @@
|
||||
client.perspective = EYE_PERSPECTIVE
|
||||
else
|
||||
client.eye = src
|
||||
client.perspective = MOB_PERSPECTIVE
|
||||
client.perspective = MOB_PERSPECTIVE
|
||||
|
||||
//set macro to normal incase it was overriden (like cyborg currently does)
|
||||
winset(src, null, "mainwindow.macro=macro hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5")
|
||||
|
||||
@@ -228,7 +228,7 @@ var/list/slot_equipment_priority = list( \
|
||||
|
||||
if((is_blind(src) || usr.stat) && !isobserver(src))
|
||||
src << "<span class='notice'>Something is there but you can't see it.</span>"
|
||||
return
|
||||
return 1
|
||||
|
||||
face_atom(A)
|
||||
A.examine(src)
|
||||
@@ -398,7 +398,7 @@ var/list/slot_equipment_priority = list( \
|
||||
if ((stat != 2 || !( ticker )))
|
||||
usr << "<span class='notice'><B>You must be dead to use this!</B></span>"
|
||||
return
|
||||
if (ticker.mode.name == "meteor" || ticker.mode.name == "epidemic") //BS12 EDIT
|
||||
if (ticker.mode.deny_respawn) //BS12 EDIT
|
||||
usr << "<span class='notice'>Respawn is disabled for this roundtype.</span>"
|
||||
return
|
||||
else
|
||||
@@ -616,6 +616,8 @@ var/list/slot_equipment_priority = list( \
|
||||
if(pulling)
|
||||
pulling.pulledby = null
|
||||
pulling = null
|
||||
if(pullin)
|
||||
pullin.icon_state = "pull0"
|
||||
|
||||
/mob/proc/start_pulling(var/atom/movable/AM)
|
||||
if ( !AM || !usr || src==AM || !isturf(src.loc) ) //if there's no person pulling OR the person is pulling themself OR the object being pulled is inside something: abort!
|
||||
@@ -642,6 +644,9 @@ var/list/slot_equipment_priority = list( \
|
||||
src.pulling = AM
|
||||
AM.pulledby = src
|
||||
|
||||
if(pullin)
|
||||
pullin.icon_state = "pull1"
|
||||
|
||||
if(ishuman(AM))
|
||||
var/mob/living/carbon/human/H = AM
|
||||
if(H.pull_damage())
|
||||
@@ -787,7 +792,8 @@ note dizziness decrements automatically in the mob's Life() proc.
|
||||
//reset the pixel offsets to zero
|
||||
is_floating = 0
|
||||
|
||||
|
||||
/proc/getStatName(var/datum/controller/process/process)
|
||||
return uppertext(copytext(process.name, 1, 4))
|
||||
|
||||
/mob/Stat()
|
||||
..()
|
||||
@@ -797,20 +803,49 @@ note dizziness decrements automatically in the mob's Life() proc.
|
||||
stat(null,"Location:\t([x], [y], [z])")
|
||||
stat(null,"CPU:\t[world.cpu]")
|
||||
stat(null,"Instances:\t[world.contents.len]")
|
||||
if(statpanel("Status") && master_controller)
|
||||
stat(null,"MasterController-[last_tick_duration] ([master_controller.processing?"On":"Off"]-[controller_iteration])")
|
||||
stat(null,"Air-[master_controller.air_cost]\tSun-[master_controller.sun_cost]")
|
||||
stat(null,"Mob-[master_controller.mobs_cost]\t#[mob_list.len]")
|
||||
stat(null,"Dis-[master_controller.diseases_cost]\t#[active_diseases.len]")
|
||||
stat(null,"Mch-[master_controller.machines_cost]\t#[machines.len]")
|
||||
stat(null,"Obj-[master_controller.objects_cost]\t#[processing_objects.len]")
|
||||
stat(null,"Net-[master_controller.networks_cost]\tPnet-[master_controller.powernets_cost]")
|
||||
stat(null,"NanoUI-[master_controller.nano_cost]\t#[nanomanager.processing_uis.len]")
|
||||
stat(null,"Event-[master_controller.events_cost]\t#[event_manager.active_events.len]")
|
||||
alarm_manager.stat_entry()
|
||||
stat(null,"Tick-[master_controller.ticker_cost]\tALL-[master_controller.total_cost]")
|
||||
if(statpanel("Status") && processScheduler.getIsRunning())
|
||||
var/datum/controller/process/process
|
||||
|
||||
process = processScheduler.getProcess("ticker")
|
||||
stat(null, "[getStatName(process)]\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("air")
|
||||
stat(null, "[getStatName(process)]\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("lighting")
|
||||
stat(null, "[getStatName(process)]\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("alarm")
|
||||
var/list/alarms = alarm_manager.active_alarms()
|
||||
stat(null, "[getStatName(process)]([alarms.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("mob")
|
||||
stat(null, "[getStatName(process)]([mob_list.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("machinery")
|
||||
stat(null, "[getStatName(process)]([machines.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("obj")
|
||||
stat(null, "[getStatName(process)]([processing_objects.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("pipenet")
|
||||
stat(null, "[getStatName(process)]([pipe_networks.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("powernet")
|
||||
stat(null, "[getStatName(process)]([powernets.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("nanoui")
|
||||
stat(null, "[getStatName(process)]([nanomanager.processing_uis.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("disease")
|
||||
stat(null, "[getStatName(process)]([active_diseases.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("sun")
|
||||
stat(null, "[getStatName(process)]\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
else
|
||||
stat(null,"MasterController-ERROR")
|
||||
stat(null, "processScheduler is not running.")
|
||||
|
||||
|
||||
if(listed_turf && client)
|
||||
if(!TurfAdjacent(listed_turf))
|
||||
|
||||
@@ -75,16 +75,15 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/isAI(A)
|
||||
if(istype(A, /mob/living/silicon/ai))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/proc/isSilicon()
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/isSilicon()
|
||||
return 1
|
||||
/proc/isAI(A)
|
||||
if(istype(A, /mob/living/silicon/ai))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/proc/isAI()
|
||||
return 0
|
||||
@@ -92,6 +91,12 @@
|
||||
/mob/living/silicon/ai/isAI()
|
||||
return 1
|
||||
|
||||
/mob/proc/isRobot()
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/robot/isRobot()
|
||||
return 1
|
||||
|
||||
/proc/ispAI(A)
|
||||
if(istype(A, /mob/living/silicon/pai))
|
||||
return 1
|
||||
@@ -157,6 +162,11 @@ proc/getsensorlevel(A)
|
||||
return U.sensor_mode
|
||||
return SUIT_SENSOR_OFF
|
||||
|
||||
|
||||
/proc/is_admin(var/mob/user)
|
||||
return check_rights(R_ADMIN, 0, user) != 0
|
||||
|
||||
|
||||
/proc/hsl2rgb(h, s, l)
|
||||
return //TODO: Implement
|
||||
|
||||
@@ -236,20 +246,26 @@ var/list/global/organ_rel_size = list(
|
||||
// Emulates targetting a specific body part, and miss chances
|
||||
// May return null if missed
|
||||
// miss_chance_mod may be negative.
|
||||
/proc/get_zone_with_miss_chance(zone, var/mob/target, var/miss_chance_mod = 0)
|
||||
/proc/get_zone_with_miss_chance(zone, var/mob/target, var/miss_chance_mod = 0, var/ranged_attack=0)
|
||||
zone = check_zone(zone)
|
||||
|
||||
// you can only miss if your target is standing and not restrained
|
||||
if(!target.buckled && !target.lying)
|
||||
var/miss_chance = 10
|
||||
if (zone in base_miss_chance)
|
||||
miss_chance = base_miss_chance[zone]
|
||||
miss_chance = max(miss_chance + miss_chance_mod, 0)
|
||||
if(prob(miss_chance))
|
||||
if(prob(70))
|
||||
return null
|
||||
return pick(base_miss_chance)
|
||||
// you cannot miss if your target is prone or restrained
|
||||
if(target.buckled || target.lying)
|
||||
return zone
|
||||
// if your target is being grabbed aggressively by someone you cannot miss either
|
||||
if(!ranged_attack)
|
||||
for(var/obj/item/weapon/grab/G in target.grabbed_by)
|
||||
if(G.state >= GRAB_AGGRESSIVE)
|
||||
return zone
|
||||
|
||||
var/miss_chance = 10
|
||||
if (zone in base_miss_chance)
|
||||
miss_chance = base_miss_chance[zone]
|
||||
miss_chance = max(miss_chance + miss_chance_mod, 0)
|
||||
if(prob(miss_chance))
|
||||
if(prob(70))
|
||||
return null
|
||||
return pick(base_miss_chance)
|
||||
return zone
|
||||
|
||||
|
||||
|
||||
@@ -453,23 +453,18 @@
|
||||
if(istype(turf,/turf/space))
|
||||
continue
|
||||
|
||||
if(istype(src,/mob/living/carbon/human/)) // Only humans can wear magboots, so we give them a chance to.
|
||||
var/mob/living/carbon/human/H = src
|
||||
if((istype(turf,/turf/simulated/floor)) && (src.lastarea.has_gravity == 0) && !(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags & NOSLIP)))
|
||||
continue
|
||||
|
||||
|
||||
else
|
||||
if((istype(turf,/turf/simulated/floor)) && (src.lastarea.has_gravity == 0)) // No one else gets a chance.
|
||||
continue
|
||||
|
||||
|
||||
|
||||
/*
|
||||
if(istype(turf,/turf/simulated/floor) && (src.flags & NOGRAV))
|
||||
continue
|
||||
*/
|
||||
|
||||
if(istype(turf,/turf/simulated/floor)) // Floors don't count if they don't have gravity
|
||||
var/area/A = turf.loc
|
||||
if(istype(A) && A.has_gravity == 0)
|
||||
var/can_walk = 0
|
||||
|
||||
if(ishuman(src)) // Only humans can wear magboots, so we give them a chance to.
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags & NOSLIP))
|
||||
can_walk = 1
|
||||
|
||||
if(!can_walk)
|
||||
continue
|
||||
|
||||
dense_object++
|
||||
break
|
||||
|
||||
@@ -358,8 +358,6 @@
|
||||
|
||||
ticker.mode.latespawn(character)
|
||||
|
||||
//ticker.mode.latespawn(character)
|
||||
|
||||
if(character.mind.assigned_role != "Cyborg")
|
||||
data_core.manifest_inject(character)
|
||||
ticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn
|
||||
|
||||
@@ -168,30 +168,7 @@ proc/setup_skills()
|
||||
|
||||
|
||||
mob/living/carbon/human/proc/GetSkillClass(points)
|
||||
// skill classes describe how your character compares in total points
|
||||
var/original_points = points
|
||||
points -= min(round((age - 20) / 2.5), 4) // every 2.5 years after 20, one extra skillpoint
|
||||
if(age > 30)
|
||||
points -= round((age - 30) / 5) // every 5 years after 30, one extra skillpoint
|
||||
if(original_points > 0 && points <= 0) points = 1
|
||||
switch(points)
|
||||
if(0)
|
||||
return "Unconfigured"
|
||||
if(1 to 3)
|
||||
return "Terrifying"
|
||||
if(4 to 6)
|
||||
return "Below Average"
|
||||
if(7 to 10)
|
||||
return "Average"
|
||||
if(11 to 14)
|
||||
return "Above Average"
|
||||
if(15 to 18)
|
||||
return "Exceptional"
|
||||
if(19 to 24)
|
||||
return "Genius"
|
||||
if(24 to 1000)
|
||||
return "God"
|
||||
|
||||
return CalculateSkillClass(points, age)
|
||||
|
||||
proc/show_skill_window(var/mob/user, var/mob/living/carbon/human/M)
|
||||
if(!istype(M)) return
|
||||
|
||||
@@ -168,7 +168,6 @@
|
||||
O.mmi.transfer_identity(src)
|
||||
|
||||
callHook("borgify", list(O))
|
||||
O.notify_ai(1)
|
||||
O.Namepick()
|
||||
|
||||
spawn(0)//To prevent the proc from returning null.
|
||||
|
||||
Reference in New Issue
Block a user