Merge branch 'master' of https://github.com/tgstation/-tg-station into WhatGoofSays

This commit is contained in:
blah
2016-08-21 20:00:21 +01:00
77 changed files with 1157 additions and 2664 deletions
+10
View File
@@ -1,3 +1,13 @@
19 August 2016, by Shadowlight213
Changed appearance bans to be jobbans.
UPDATE 'feedback'.`ban` SET `job` = "appearance", `bantype` = "JOB_PERMABAN" WHERE `bantype` = "APPEARANCE_PERMABAN"
Remember to add a prefix to the table name if you use them
----------------------------------------------------
3 July 2016, by Jordie0608
Modified table 'poll_question', adding column 'dontshow' which was recently added to the server schema.
-348
View File
@@ -1,348 +0,0 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
"aa" = (
/turf/open/space,
/area/space)
"ab" = (
/turf/closed/indestructible/riveted,
/area/hades)
"ac" = (
/obj/structure/bookcase/random/religion,
/turf/open/floor/plasteel/hades,
/area/hades)
"ad" = (
/obj/structure/piano,
/turf/open/floor/plasteel/hades,
/area/hades)
"ae" = (
/obj/effect/gibspawner/human,
/turf/open/floor/plasteel/hades,
/area/hades)
"af" = (
/turf/open/floor/plasteel/hades,
/area/hades)
"ag" = (
/obj/structure/window/fulltile,
/turf/open/floor/plasteel/hades,
/area/hades)
"ah" = (
/obj/structure/window/reinforced,
/turf/open/floor/plasteel/hades,
/area/hades)
"ai" = (
/obj/effect/gibspawner/human,
/mob/living/simple_animal/hostile/hadesacolyte,
/turf/open/floor/plasteel/hades,
/area/hades)
"aj" = (
/mob/living/simple_animal/hostile/hadesacolyte,
/turf/open/floor/plasteel/hades,
/area/hades)
"ak" = (
/obj/structure/window/reinforced,
/obj/structure/window/reinforced{
dir = 4
},
/obj/structure/window/fulltile,
/turf/open/floor/plasteel/hades,
/area/hades)
"al" = (
/obj/structure/table/reinforced/brass,
/obj/item/candle/infinite,
/turf/open/floor/plasteel/hades,
/area/hades)
"am" = (
/obj/structure/table/reinforced/brass,
/obj/item/candle/infinite,
/obj/structure/window/reinforced{
dir = 4
},
/turf/open/floor/plasteel/hades,
/area/hades)
"an" = (
/obj/structure/table/reinforced/brass,
/turf/open/floor/plasteel/hades,
/area/hades)
"ao" = (
/obj/structure/table/reinforced/brass,
/obj/item/candle/infinite,
/obj/structure/window/reinforced{
dir = 8
},
/turf/open/floor/plasteel/hades,
/area/hades)
"ap" = (
/obj/structure/window/reinforced,
/obj/structure/window/reinforced{
dir = 8
},
/obj/structure/window/fulltile,
/turf/open/floor/plasteel/hades,
/area/hades)
"aq" = (
/turf/open/floor/carpet,
/area/hades)
"ar" = (
/obj/structure/chair/wood/normal{
icon_state = "wooden_chair";
dir = 1
},
/mob/living/simple_animal/hostile/hadesacolyte,
/turf/open/floor/plasteel/hades,
/area/hades)
"as" = (
/obj/structure/chair/wood/normal{
icon_state = "wooden_chair";
dir = 1
},
/turf/open/floor/plasteel/hades,
/area/hades)
"at" = (
/obj/effect/gibspawner/human,
/turf/open/floor/carpet,
/area/hades)
"au" = (
/obj/effect/landmark/event_spawn,
/turf/open/floor/carpet,
/area/hades)
"av" = (
/obj/structure/dresser,
/turf/open/floor/carpet,
/area/hades)
"aw" = (
/obj/structure/table/wood,
/obj/item/trash/candle,
/turf/open/floor/carpet,
/area/hades)
"ax" = (
/obj/structure/flora/grass/green,
/turf/open/floor/grass,
/area/hades)
"ay" = (
/obj/structure/flora/ausbushes/ppflowers,
/turf/open/floor/grass,
/area/hades)
"az" = (
/obj/structure/flora/ausbushes/palebush,
/turf/open/floor/grass,
/area/hades)
"aA" = (
/obj/structure/flora/ausbushes/ywflowers,
/turf/open/floor/grass,
/area/hades)
"aB" = (
/obj/structure/bookcase/random/nonfiction,
/turf/open/floor/carpet,
/area/hades)
"aC" = (
/obj/structure/bookcase/random/fiction,
/turf/open/floor/carpet,
/area/hades)
"aD" = (
/obj/structure/bookcase/random/adult,
/turf/open/floor/carpet,
/area/hades)
"aE" = (
/obj/structure/bookcase/random/religion,
/turf/open/floor/carpet,
/area/hades)
"aF" = (
/obj/structure/kitchenspike,
/turf/open/floor/mineral/diamond,
/area/hades)
"aG" = (
/mob/living/simple_animal/hostile/hadesacolyte,
/turf/open/floor/mineral/gold,
/area/hades)
"aH" = (
/turf/open/floor/mineral/gold,
/area/hades)
"aI" = (
/obj/structure/table/wood,
/turf/open/floor/carpet,
/area/hades)
"aJ" = (
/obj/structure/flora/ausbushes/grassybush,
/turf/open/floor/grass,
/area/hades)
"aK" = (
/obj/structure/flora/ausbushes/stalkybush,
/turf/open/floor/grass,
/area/hades)
"aL" = (
/obj/structure/flora/ausbushes/genericbush,
/turf/open/floor/grass,
/area/hades)
"aM" = (
/obj/structure/bookcase/random/reference,
/turf/open/floor/carpet,
/area/hades)
"aN" = (
/obj/structure/closet/cabinet,
/turf/open/floor/carpet,
/area/hades)
"aO" = (
/obj/structure/table/wood,
/obj/item/weapon/paper/hades_instructions,
/turf/open/floor/carpet,
/area/hades)
"aP" = (
/obj/structure/flora/ausbushes/fernybush,
/turf/open/floor/grass,
/area/hades)
"aQ" = (
/obj/structure/bed,
/obj/item/weapon/bedsheet/black,
/turf/open/floor/carpet,
/area/hades)
"aR" = (
/mob/living/simple_animal/hostile/hadesacolyte,
/turf/open/floor/carpet,
/area/hades)
"aS" = (
/obj/structure/table/wood,
/obj/item/weapon/storage/box/matches,
/turf/open/floor/carpet,
/area/hades)
"aT" = (
/obj/structure/grille,
/obj/structure/window/reinforced/fulltile,
/turf/open/floor/plasteel,
/area/hades)
"aU" = (
/obj/machinery/door/airlock/wood,
/turf/open/floor/plasteel/hades,
/area/hades)
"aV" = (
/obj/structure/table/wood,
/obj/item/weapon/lipstick,
/turf/open/floor/carpet,
/area/hades)
"aW" = (
/obj/structure/table/wood,
/obj/item/weapon/storage/fancy/candle_box,
/turf/open/floor/carpet,
/area/hades)
"aX" = (
/obj/structure/chair/wood/normal{
icon_state = "wooden_chair";
dir = 4
},
/turf/open/floor/carpet,
/area/hades)
"aY" = (
/obj/structure/chair/wood/normal{
icon_state = "wooden_chair";
dir = 8
},
/turf/open/floor/carpet,
/area/hades)
"aZ" = (
/obj/structure/table/wood,
/obj/item/weapon/storage/crayons,
/turf/open/floor/carpet,
/area/hades)
"ba" = (
/obj/structure/table/wood,
/obj/item/weapon/razor,
/turf/open/floor/carpet,
/area/hades)
"bb" = (
/obj/machinery/door/airlock/wood,
/turf/open/floor/carpet,
/area/hades)
"bc" = (
/obj/structure/chair/hades,
/turf/open/floor/mineral/diamond,
/area/hades)
"bd" = (
/obj/machinery/vending/cola,
/turf/open/floor/carpet,
/area/hades)
"be" = (
/obj/machinery/vending/snack,
/turf/open/floor/carpet,
/area/hades)
"bf" = (
/obj/structure/table/wood,
/obj/machinery/chem_dispenser/drinks/beer,
/turf/open/floor/carpet,
/area/hades)
"bg" = (
/obj/structure/table/wood,
/obj/machinery/microwave,
/turf/open/floor/carpet,
/area/hades)
"bh" = (
/obj/structure/table/wood,
/obj/item/weapon/storage/box/donkpockets,
/turf/open/floor/carpet,
/area/hades)
"bi" = (
/obj/machinery/chem_dispenser/drinks,
/obj/structure/table/wood,
/turf/open/floor/carpet,
/area/hades)
"bj" = (
/obj/structure/chair/wood/normal,
/mob/living/simple_animal/hostile/hadesacolyte,
/turf/open/floor/carpet,
/area/hades)
"bk" = (
/obj/structure/table/wood,
/obj/item/weapon/kitchen/fork,
/turf/open/floor/carpet,
/area/hades)
"bl" = (
/obj/structure/chair/wood/normal{
icon_state = "wooden_chair";
dir = 1
},
/turf/open/floor/carpet,
/area/hades)
"bm" = (
/obj/structure/table/wood,
/obj/item/weapon/storage/box/drinkingglasses,
/turf/open/floor/carpet,
/area/hades)
(
1,
1,
1) = {"
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaabacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaabadaeafafafafaeafafafabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaababababagahahaiafafajahahagababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaabacacacakalamananananaoalapacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaabaeafafafafajaqaqaqaqajafafafafaeabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaabafafafaeafafaqaqaqaqafafaeafafafabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaabafarasasasafaqataqaqafarasasarafabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaabafafafafafafaqaqaqaqafafafafafafabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaabafasasarasafaqaqaqaqafasarasasafabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaabafafaeafafafaqataqaqafafaeafafafabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaabafasasasarafaqaqaqaqafasasarasafabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaabafafafaeafafaqauaqaqafafafafaeafabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaabafarasasasafaqaqataqafasarasasafabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaabaeafafafafafaqaqaqaqafafafafafaeabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaabababababababaqaqaqaqababababababababababababababababababababababaa
aaaaabavavavavavabawaqaqaqabaxayazaAaxabaBaBaCaCaDaEabaFaGaHaHaHaGaFabaa
aaaaabaqaqaqaqaqabaIaqaqaqabaJaKaLaAayabaMaqaqaqaqaMabafafafaHafafafabaa
aaaaabaNaqaqaqaNabaOaqaqaqabaPayaJaxazabaMaqaqaqaqaCabafafafaHafafafabaa
aaaaabaQaRaqaqaQabaSaqaqaqabaTaTaTaTaTabaEaqaRaRaqaBaUafafafaHafafafabaa
aaaaabaVaqaqaqaOabaWaqaqaqabaXaqaqaqaYabaEaqaRaRaqaBabafafafaHafafafabaa
aaaaabaQaqaqaqaQabaZaqaqaqabaXaqaqaqaYabaEaqaqaqaqaCabafafafaHafafafabaa
aaaaabaIaqaqaRbaabaIaqaqaqbbaqaqaqaqaqabababbbababababaFaGaHbcaHaGaFabaa
aaaaabaQaRaqaqaQabaqaqaqaqabaqaqaqaqaqabaEaBaqaCaBaEabafafafaHafafafabaa
aaaaabababbbababababababababaqaqaqaqaqabaEaqaqaqaRaBabafafafaHafafafabaa
aaaaabaqaqaqaqbdbebfbgbhbiabaXaqaqaRaYabaBaqaqaqaqaEabafafafaHafafafabaa
aaaaabaqbjbjaqaqaqaqaqaqaqabaXaqaqaqaYabaCaqaqaqaqaMabafafafaHafafafabaa
aaaaabaXbkaIaYaqaqaqaqaqaqbbaqaqaqaqaqbbaqaqaRaqaqaEabafafafaHafafafabaa
aaaaabaqblblaqaqaqbmaIaIaOabaqaqaqaqaqabaMaMaBaDaCaMabaFaGaHaHaHaGaFabaa
aaaaabababababababababababababababababababababababababababababababababaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
"}
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -14,7 +14,7 @@
#define BANTYPE_JOB_PERMA 3
#define BANTYPE_JOB_TEMP 4
#define BANTYPE_ANY_FULLBAN 5 //used to locate stuff to unban.
#define BANTYPE_APPEARANCE 6
#define BANTYPE_ADMIN_PERMA 7
#define BANTYPE_ADMIN_TEMP 8
#define BANTYPE_ANY_JOB 9 //used to remove jobbans
+7 -1
View File
@@ -78,4 +78,10 @@
#define WEAPON_LIGHT 0
#define WEAPON_MEDIUM 1
#define WEAPON_HEAVY 2
#define WEAPON_HEAVY 2
//Health Defines
#define HEALTH_THRESHOLD_CRIT 0
#define HEALTH_THRESHOLD_DEAD -100
+8
View File
@@ -67,6 +67,14 @@
return 0
return L[A.type]
//returns a new list with only atoms that are in typecache L
/proc/typecache_filter_list(list/atoms, list/typecache)
. = list()
for (var/thing in atoms)
var/atom/A = thing
if (typecache[A.type])
. += A
//Like typesof() or subtypesof(), but returns a typecache instead of a list
/proc/typecacheof(path, ignore_root_path)
if(ispath(path))
+2 -1
View File
@@ -543,7 +543,8 @@ Turf and target are seperate in case you want to teleport some distance from a t
return 0
if(current.opacity)
return 0
for(var/atom/A in current)
for(var/thing in current)
var/atom/A = thing
if(A.opacity)
return 0
current = get_step_towards(current, target_turf)
+7 -7
View File
@@ -137,9 +137,6 @@
var/alert_desc_red_downto = "The station's destruction has been averted. There is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised."
var/alert_desc_delta = "Destruction of the station is imminent. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill."
var/health_threshold_crit = 0
var/health_threshold_dead = -100
var/revival_pod_plants = 1
var/revival_cloning = 1
var/revival_brain_life = -1
@@ -167,6 +164,8 @@
var/silent_ai = 0
var/silent_borg = 0
var/damage_multiplier = 1 //Modifier for damage to all mobs. Impacts healing as well.
var/allowwebclient = 0
var/webclientmembersonly = 0
@@ -213,6 +212,7 @@
var/client_error_message = "Your version of byond is too old, may have issues, and is blocked from accessing this server."
var/cross_name = "Other server"
var/showircname = 0
/datum/configuration/New()
var/list/L = subtypesof(/datum/game_mode)
@@ -380,6 +380,8 @@
global.medal_hub = value
if("medal_hub_password")
global.medal_pass = value
if("show_irc_name")
config.showircname = 1
if("see_own_notes")
config.see_own_notes = 1
if("soft_popcap")
@@ -452,10 +454,8 @@
else if(type == "game_options")
switch(name)
if("health_threshold_crit")
config.health_threshold_crit = text2num(value)
if("health_threshold_dead")
config.health_threshold_dead = text2num(value)
if("damage_multiplier")
config.damage_multiplier = text2num(value)
if("revival_pod_plants")
config.revival_pod_plants = text2num(value)
if("revival_cloning")
+66
View File
@@ -0,0 +1,66 @@
var/datum/subsystem/persistence/SSpersistence
/datum/subsystem/persistence
name = "Persistence"
init_order = -100
flags = SS_NO_FIRE
var/savefile/secret_satchels
var/list/satchel_blacklist = list() //this is a typecache
var/list/new_secret_satchels = list() //these are objects
var/list/old_secret_satchels = list() //these are just vars
/datum/subsystem/persistence/New()
NEW_SS_GLOBAL(SSpersistence)
/datum/subsystem/persistence/Initialize()
PlaceSecretSatchel()
..()
/datum/subsystem/persistence/proc/CollectData()
CollectSecretSatchels()
/datum/subsystem/persistence/proc/PlaceSecretSatchel()
var/list/satchels = list()
secret_satchels = new /savefile("data/npc_saves/SecretSatchels_[MAP_NAME].sav")
satchel_blacklist = typecacheof(list(/obj/item/stack/tile/plasteel, /obj/item/weapon/crowbar))
secret_satchels >> satchels
if(!satchels.len || satchels.len < 20) //guards against low drop pools assuring that one player can reliably find his own gear.
return
var/list/chosen_satchel = pick_n_take(satchels)
old_secret_satchels = satchels
secret_satchels << old_secret_satchels
if(chosen_satchel.len != 3) //Malformed
return
var/path = text2path(chosen_satchel[3]) //If the item no longer exist, this returns null
if(!path)
return
var/obj/item/weapon/storage/backpack/satchel/flat/F = new()
F.x = chosen_satchel[1]
F.y = chosen_satchel[2]
F.z = ZLEVEL_STATION
if(istype(F.loc,/turf/open/floor) && !istype(F.loc,/turf/open/floor/plating/))
F.hide(1)
new path(F)
/datum/subsystem/persistence/proc/CollectSecretSatchels()
for(var/A in new_secret_satchels)
var/obj/item/weapon/storage/backpack/satchel/flat/F = A
if(qdeleted(F) || F.z != ZLEVEL_STATION || F.invisibility != INVISIBILITY_MAXIMUM)
continue
var/list/savable_obj = list()
for(var/obj/O in F)
if(is_type_in_typecache(O, satchel_blacklist) || O.admin_spawned)
continue
if(O.persistence_replacement)
savable_obj += O.persistence_replacement
else
savable_obj += O.type
if(savable_obj.len < 1)
continue
old_secret_satchels.len += 1
old_secret_satchels[old_secret_satchels.len] = list(F.x, F.y, "[pick(savable_obj)]")
secret_satchels << old_secret_satchels
+2
View File
@@ -451,6 +451,8 @@ var/datum/subsystem/ticker/ticker
dellog += "Failures : [SSgarbage.didntgc[path]] \n"
world.log << dellog
//Collects persistence features
SSpersistence.CollectData()
return 1
/datum/subsystem/ticker/proc/send_tip_of_the_round()
+13
View File
@@ -262,6 +262,7 @@ var/global/list/internal_byond_list_vars = list("contents" = TRUE, "verbs" = TRU
if(ismob(D))
body += "<option value='?_src_=vars;give_spell=\ref[D]'>Give Spell</option>"
body += "<option value='?_src_=vars;remove_spell=\ref[D]'>Remove Spell</option>"
body += "<option value='?_src_=vars;give_disease=\ref[D]'>Give Disease</option>"
body += "<option value='?_src_=vars;ninja=\ref[D]'>Make Space Ninja</option>"
body += "<option value='?_src_=vars;godmode=\ref[D]'>Toggle Godmode</option>"
@@ -562,6 +563,18 @@ body
src.give_spell(M)
href_list["datumrefresh"] = href_list["give_spell"]
else if(href_list["remove_spell"])
if(!check_rights(0))
return
var/mob/M = locate(href_list["remove_spell"])
if(!istype(M))
usr << "This can only be used on instances of type /mob"
return
remove_spell(M)
href_list["datumrefresh"] = href_list["remove_spell"]
else if(href_list["give_disease"])
if(!check_rights(0))
return
+1 -1
View File
@@ -515,7 +515,7 @@
H.Weaken(4)
if(H.staminaloss && !H.sleeping)
var/total_health = (H.health - H.staminaloss)
if(total_health <= config.health_threshold_crit && !H.stat)
if(total_health <= HEALTH_THRESHOLD_CRIT && !H.stat)
H.visible_message("<span class='warning'>[user] delivers a heavy hit to [H]'s head, knocking them out cold!</span>", \
"<span class='userdanger'>[user] knocks you unconscious!</span>")
H.SetSleeping(30)
+1 -1
View File
@@ -5,7 +5,7 @@
// the same logical /area have the parent /area object... well, you would be mistaken. If you
// want to find machines, mobs, etc, in the same logical area, you will need to check all the
// related areas. This returns a master contents list to assist in that.
/proc/area_contents(var/area/A)
/proc/area_contents(area/A)
if(!istype(A)) return null
var/list/contents = list()
for(var/area/LSA in A.related)
+1 -1
View File
@@ -41,7 +41,7 @@
//MIND PROCS
//these are called by mind.transfer_to()
/datum/mind/proc/transfer_antag_huds(var/datum/atom_hud/antag/newhud)
/datum/mind/proc/transfer_antag_huds(datum/atom_hud/antag/newhud)
leave_all_huds()
ticker.mode.set_antag_hud(current, antag_hud_icon_state)
if(newhud)
+2 -2
View File
@@ -239,7 +239,7 @@
if(host)
var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5)
if(iscarbon(host))
resulthealth = round((abs(config.health_threshold_dead - host.health) / abs(config.health_threshold_dead - host.maxHealth)) * 100)
resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)
stat(null, "Host Health: [resulthealth]%")
if(ratvar_awakens)
stat(null, "You are [recovering ? "un" : ""]able to deploy!")
@@ -444,7 +444,7 @@
return 0
var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5)
if(iscarbon(host))
resulthealth = round((abs(config.health_threshold_dead - host.health) / abs(config.health_threshold_dead - host.maxHealth)) * 100)
resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)
if(!ratvar_awakens && host.stat != DEAD && resulthealth > 60) //if above 20 health, fails
src << "<span class='warning'>Your host must be at 60% or less health to emerge like this!</span>"
return
@@ -59,6 +59,8 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed
for(var/i in used_cache_components)
if(used_cache_components[i])
clockwork_component_cache[i] += consumed_components[i]
else if(slab && !slab.no_cost) //if the slab exists and isn't debug, log the scripture as being used
feedback_add_details("clockcult_scripture_recited", name)
if(slab)
slab.busy = null
qdel(src)
@@ -1,727 +0,0 @@
#define STATE_JUDGE 0
#define STATE_WRATH 1
#define STATE_FLEE 2
/mob/living/simple_animal/hostile/hades
name = "hades"
real_name = "hades"
desc = "A strange being, clad in dark robes. Their very presence radiates an uneasy power."
speak_emote = list("preaches","announces","spits","conveys")
emote_hear = list("hums.","prays.")
response_help = "kneels before"
response_disarm = "flails at"
response_harm = "punches"
icon = 'icons/mob/EvilPope.dmi'
icon_state = "EvilPope"
icon_living = "EvilPope"
icon_dead = "popedeath"
speed = 1
a_intent = "harm"
status_flags = CANPUSH
attack_sound = 'sound/magic/MAGIC_MISSILE.ogg'
death_sound = 'sound/magic/Teleport_diss.ogg'
atmos_requirements = list("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
maxbodytemp = INFINITY
faction = list("hades")
attacktext = "strikes with an unholy rage at"
maxHealth = 1000
health = 1000
healable = 0
environment_smash = 3
melee_damage_lower = 15
melee_damage_upper = 20
see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
loot = list(/obj/effect/decal/cleanable/blood)
del_on_death = 0
deathmessage = "begins to sizzle and pop, their flesh peeling away like paper."
var/isDoingDeath = FALSE
var/isFleeing = FALSE
var/fleeTimes = 0
var/currentState = STATE_JUDGE
var/rageLevel = 0
var/maxWrathTimer = 150
var/lastWrathTimer = 0
var/timeBetweenGrabs = 60
var/lastGrabTime = 0
var/list/validSins = list("Greed","Gluttony","Pride","Lust","Envy","Sloth","Wrath")
var/lastsinPerson = 0
var/sinPersonTime = 300
var/lastFlee = 0
var/fleeTimer = 30
var/fakesinPersonChance = 60
var/list/sinPersonsayings = list("You revel in only your own greed.",\
"There is nothing but your absolution.",\
"Your choices have led you to this.",\
"There is only one way out.",\
"The only way to be free is to be free of yourself.",\
"Wallow in sin, and give yourself unto darkness.",\
"Only the truly sinful may stand.",\
"Find yourself and you will find Absolution.",\
"Forego the pain of this process, and submit.",\
"We can be one in suffering.",\
"You stand on the precipice of ascension, give in.",\
"You cannot fathom what lies beyond",\
"Repent your sins.",\
"This is the eve of your last days.",\
"Darkness comes.")
var/list/creepyasssounds = list('sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/behind_you2.ogg', \
'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg',\
'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\
'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg',\
'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\
'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg')
var/obj/effect/proc_holder/spell/targeted/lightning/sinLightning
var/list/currentAcolytes = list()
/mob/living/simple_animal/hostile/hades/New()
..()
sinLightning = new/obj/effect/proc_holder/spell/targeted/lightning(src)
sinLightning.charge_max = 1
sinLightning.clothes_req = 0
sinLightning.range = 32
sinLightning.cooldown_min = 1
lastsinPerson = world.time
var/list/possible_titles = list("Pope","Bishop","Lord","Cardinal","Deacon","Pontiff")
var/chosen = "Hades, [pick(possible_titles)] of Sin"
name = chosen
real_name = chosen
world << "<span class='warning'><font size=4>[name] has entered your reality. Kneel before them.</font></span>"
world << 'sound/effects/pope_entry.ogg'
Appear(get_turf(src))
/mob/living/simple_animal/hostile/hades/handle_environment(datum/gas_mixture/environment)
//space popes are from space, they need not your fickle "oxygen"
return
/mob/living/simple_animal/hostile/hades/handle_temperature_damage()
//space popes are from space, they don't uh.. something fire burny death
return
/mob/living/simple_animal/hostile/hades/death(gibbed)
if(!isDoingDeath)
notransform = TRUE
anchored = TRUE
src.visible_message("<span class='warning'><font size=4>[src] begins to twist and distort, before snapping backwards with a sickening crunch.</font></span>")
spawn(20)
src.visible_message("<span class='warning'><font size=4>[src] is being sucked back to their own realm, destabilizing the fabric of time and space itself!</font></span>")
playsound(get_turf(src), 'sound/effects/hyperspace_begin.ogg', 100, 1)
isDoingDeath = TRUE
AIStatus = AI_OFF
SpinAnimation()
for(var/i in 1 to 5)
for(var/turf/T in spiral_range_turfs(i,src))
addtimer(src, "sinShed", i*10, FALSE, T)
spawn(60) // required to be spawn so we can call death's ..() to complete death.
SpinAnimation(0,0)
explosion(get_turf(src), 0, 2, 4, 6, flame_range = 6)
..()
var/area/A = locate(/area/hades) in world
if(A)
var/turf/T = get_turf(locate(/obj/effect/landmark/event_spawn) in A)
if(T)
src.visible_message("<span class='warning'><font size=4>[src]'s Staff is flung free as their body explodes.</font></span>")
var/obj/structure/ladder/unbreakable/hades/churchLadder = new/obj/structure/ladder/unbreakable/hades(T)
var/obj/structure/ladder/unbreakable/hades/bodyLadder = new/obj/structure/ladder/unbreakable/hades(get_turf(src))
var/obj/item/weapon/hades_staff/HS = new/obj/item/weapon/hades_staff(get_turf(src))
HS.throw_at_fast(pick(orange(src,7)),10,1)
churchLadder.up = bodyLadder
bodyLadder.down = churchLadder
qdel(src)
/mob/living/simple_animal/hostile/hades/attackby(obj/item/I, mob/user, params)
..()
Defend(user,I)
/mob/living/simple_animal/hostile/hades/grabbedby(mob/living/carbon/user, supress_message = 0)
..()
Defend(user,user)
/mob/living/simple_animal/hostile/hades/hitby(atom/movable/AM, skipcatch, hitpush, blocked)
..()
lastsinPerson -= (sinPersonTime/4)
if(istype(AM,/obj/item))
var/obj/item/throwCast = AM
Defend(throwCast.thrownby,AM)
/mob/living/simple_animal/hostile/hades/bullet_act(obj/item/projectile/P, def_zone)
//don't call ..() because we're going to deflect it
lastsinPerson -= (sinPersonTime/4)
Defend(P.firer,P)
return -1
/mob/living/simple_animal/hostile/hades/attack_hand(mob/living/carbon/human/M)
..()
lastsinPerson -= (sinPersonTime/4)
Defend(M,M)
/mob/living/simple_animal/hostile/hades/proc/Defend(var/mob/attacker,var/source)
if(!isDoingDeath)
rageLevel += 5
src.visible_message("<span class='warning'>[src] rounds on the [attacker], gazing at them with a [pick("cold","frosty","freezing","dark")] [pick("glare","gaze","glower","stare")].</span>")
if(istype(source,/obj/item/projectile))
src.visible_message("<span class='warning'>[src] [pick("calmly","silently","nonchalantly")] waves their hand, deflecting the [source].</span>")
var/obj/item/projectile/P = source
if(P.starting)
var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/turf/curloc = get_turf(src)
P.original = locate(new_x, new_y, P.z)
P.starting = curloc
P.current = curloc
P.firer = src
P.yo = new_y - curloc.y
P.xo = new_x - curloc.x
P.Angle = null
else
if(prob(20))
var/chosenDefend = rand(1,3)
switch(chosenDefend)
if(1)
attacker.visible_message("<span class='warning'>[attacker] is lifted from the ground, shadowy powers tossing them aside.</span>")
attacker.throw_at_fast(pick(orange(src,7)),10,1)
if(2)
attacker.visible_message("<span class='warning'>[attacker] crackles with electricity, a bolt leaping from [src] to them.</span>")
sinLightning.Bolt(src,attacker,30,5,src)
if(3)
src.visible_message("<span class='warning'>[src] points his staff at [attacker], a swarm of eyeballs lurching fourth!</span>")
for(var/i in 1 to 4)
var/mob/living/simple_animal/hostile/carp/eyeball/E = new/mob/living/simple_animal/hostile/carp/eyeball(pick(orange(attacker,1)))
E.faction = faction
addtimer(E, "gib", 150, FALSE)
/mob/living/simple_animal/hostile/hades/proc/sinShed(var/turf/T)
var/obj/effect/overlay/temp/cult/sparks/S = PoolOrNew(/obj/effect/overlay/temp/cult/sparks, T)
S.anchored = FALSE
S.throw_at_fast(src,10,1)
PoolOrNew(/obj/effect/overlay/temp/hadesBlood, T)
/mob/living/simple_animal/hostile/hades/proc/Transfer(var/mob/living/taken, var/turf/transferTarget)
if(transferTarget)
playsound(get_turf(taken), 'sound/magic/Ethereal_Enter.ogg', 50, 1, -1)
PoolOrNew(/obj/effect/overlay/temp/hadesFlick, get_turf(taken))
taken.forceMove(transferTarget)
Appear(get_turf(taken))
/mob/living/simple_animal/hostile/hades/proc/Appear(var/turf/where)
var/obj/effect/timestop/hades/TS = new /obj/effect/timestop/hades(where)
TS.immune = list(src)
/mob/living/simple_animal/hostile/hades/Life()
if(..() && !isDoingDeath) // appropriately check if we're alive now we leave a corpse
if(health > maxHealth/4 && !isFleeing)
if(rageLevel > 50)
lastWrathTimer = world.time
currentState = STATE_WRATH
else
currentState = STATE_JUDGE
else
if(world.time > lastFlee + fleeTimer)
lastFlee = world.time
isFleeing = TRUE
currentState = STATE_FLEE
var/area/healthCheck = get_area(src)
if(istype(healthCheck,/area/chapel/main))
if(currentState == STATE_FLEE)
lastWrathTimer = world.time
currentState = STATE_WRATH
if(health < maxHealth/2)
health += 10 // slowly regain hp in the chapel, up to a maximum of half our max
var/spokenThisTurn = FALSE
for(var/mob/living/A in currentAcolytes)
if(!A)
currentAcolytes -= A
continue
if(A.health <= 0)
rageLevel += 5
if(!spokenThisTurn)
spokenThisTurn = TRUE
var/list/lossSayings = list("They were weak.","For every death, two more rise.",\
"What is but one servant lost?","Darkness engulf you!","To the Pit with them.",\
"Fools! All of you!","You can't stop me. You. Will. Be. JUDGED.")
src.say(pick(lossSayings))
currentAcolytes -= A
A.gib()
if(currentState == STATE_WRATH) // we have been enraged.
if(world.time > lastWrathTimer + maxWrathTimer)
rageLevel = 0 // wind down if we're wrathful too long.
rageLevel -= 1 // rage phase starts at 50, meaning roughly 20s of rage.
if(currentAcolytes.len == 0)
src.say("Rise, Servants. AID YOUR MASTER.")
playsound(get_turf(src), 'sound/magic/CastSummon.ogg', 100, 1)
for(var/i in 1 to 5)
var/mob/living/simple_animal/hostile/hadesacolyte/HA = new/mob/living/simple_animal/hostile/hadesacolyte(get_turf(pick(orange(2,src))))
HA.master = src
currentAcolytes += HA
if(target)
if(world.time > lastGrabTime + timeBetweenGrabs)
if(get_dist(src,target) > 4) // you can't run from us. upped to 4 to give more leeway.
lastGrabTime = world.time
var/list/fleeSayings = list("There is no escape from your sins, [target]","Fleeing will only make your punishment worse [target]!",\
"There is nowhere you can hide, [target]!","You can't run, [target]!","Get back here, [target]!","You coward, [target]!",\
"I will find you, [target]!","Return to me, [target]!")
src.say(pick(fleeSayings))
var/mob/living/toGrab = target
toGrab.Beam(src,"blood",'icons/effects/beam.dmi',10)
toGrab.Weaken(6)
playsound(get_turf(src), 'sound/magic/CastSummon.ogg', 100, 1)
toGrab.throw_at_fast(src,10,1)
if(rageLevel >= 100)
rageLevel = 50
var/list/overboardSayings = list("Ashes! It will all be ashes!","I will bring about the apocolypse!",\
"There will be nothing but your withered husks!","Face your doom, cretins!","There. Will. Be. ORDER!",\
"I am your Lord, lay down your arms and submit.","Your souls will be cremated!",\
"Only in death will you obey!","This is no person's fault but your own!")
src.say(pick(overboardSayings))
var/turf/StartLoc = get_turf(src)
var/list/nearby = orange(6,src)
var/slashCount = 0
var/aoeType = rand(1,2) // just for future proofing
for(var/mob/living/A in nearby)
slashCount++
A.Beam(src,"blood",'icons/effects/beam.dmi',10)
spawn(slashCount + 3)
if(aoeType == 1)
// no more cheaping it out with non-player mobs like turrets or carps
loc = get_turf(A)
sinShed(StartLoc)
A.attack_animal(src)
PoolOrNew(/obj/effect/overlay/temp/hadesBlood,get_turf(A))
playsound(get_turf(A), 'sound/magic/SummonItems_generic.ogg', 100, 1)
if(aoeType == 2)
sinShed(StartLoc)
PoolOrNew(/obj/effect/overlay/temp/hadesBite,get_turf(A))
A.Weaken(6)
var/obj/effect/timestop/hades/large/TS = new /obj/effect/timestop/hades/large(StartLoc)
TS.immune = list(src)
spawn((slashCount+1)+3)
loc = StartLoc
if(currentState == STATE_FLEE) // we've been wounded, let us flee and lick our wounds
var/area/A = locate(/area/chapel/main) in world
if(A)
var/turf/T = get_turf(locate(/obj/effect/landmark/event_spawn) in A)
if(!T)
T = get_turf(src) // no event spawn in chapel, fall back to doing it on the spot.
if(T)
fleeTimes++
Transfer(src,T)
AIStatus = AI_OFF
notransform = TRUE
anchored = TRUE
for(var/i in 1 to 5)
spawn(i*10)
for(var/turf/S in oview(i,src) - oview((i)-1,src))
sinShed(S)
health += maxHealth/(10*fleeTimes) // every flee we gain less HP
spawn(50)
isFleeing = FALSE
notransform = FALSE
anchored = FALSE
AIStatus = AI_ON
currentState = STATE_JUDGE
lastsinPerson = 0 // immediately teleport away to judge
if(currentState == STATE_JUDGE) // our default state, judge a few people and tell them they're rude or something
if(world.time > lastsinPerson + sinPersonTime)
if(prob(fakesinPersonChance))
lastsinPerson = world.time
visible_message("<span class='warning'><font size=3>[pick(sinPersonsayings)]</font></span>")
playsound(get_turf(src), pick(creepyasssounds), 100, 1)
else
lastsinPerson = world.time
var/mob/living/carbon/human/sinPerson = pick(living_mob_list)
var/depth = living_mob_list.len + 1 // just in case
if(sinPerson) // no more finding nullcakes
if(!sinPerson.ckey)
while(!sinPerson.ckey && depth > 0)
--depth
var/checkPerson = pick(living_mob_list)
if(checkPerson)
sinPerson = checkPerson
if(!sinPerson || !sinPerson.ckey)
// double check ensure that if the above loop fails to get a ckey target
// we don't go and use the last mob checked, causing odd situations
return
if(prob(65)) // moderately high chance for us to go to them, else they come here.
Transfer(src,get_turf(pick(oview(1,sinPerson))))
else
Transfer(sinPerson,get_turf(pick(oview(1,src))))
var/sinPersonchoice = pick(validSins)
src.say("Your sin, [sinPerson], is [sinPersonchoice].")
var/isIndulged = prob(50)
if(isIndulged)
src.say("I will indulge your sin, [sinPerson].")
else
src.say("Your sin will be punished, [sinPerson]!")
switch(sinPersonchoice)
if("Greed")
sin_Greed(sinPerson, isIndulged)
if("Gluttony")
sin_Gluttony(sinPerson, isIndulged)
if("Pride")
sin_Pride(sinPerson, isIndulged)
if("Lust")
sin_Lust(sinPerson, isIndulged)
if("Envy")
sin_Envy(sinPerson, isIndulged)
if("Sloth")
sin_Sloth(sinPerson, isIndulged)
if("Wrath")
sin_Wrath(sinPerson, isIndulged)
///Sin related things
//global Sin procs, shared between staff and pope
/proc/sin_Greed(var/mob/living/carbon/human/sinPerson, var/isIndulged)
if(isIndulged)
sinPerson << "<span class='warning'>You feel like you deserve more, in fact, you want everything.</span>"
var/list/greed = list(/obj/item/stack/sheet/mineral/gold,/obj/item/stack/sheet/mineral/silver,/obj/item/stack/sheet/mineral/diamond)
for(var/i in 1 to 10)
var/greed_type = pick(greed)
new greed_type(get_turf(sinPerson))
else
sinPerson << "<span class='warning'>Your body begins to shift and bend, changing to reflect your inner greed.</span>"
var/mob/living/M = sinPerson.change_mob_type(/mob/living/simple_animal/cockroach,get_turf(sinPerson),"Greedroach",1)
M.AddSpell(new/obj/effect/proc_holder/spell/targeted/mind_transfer)
/proc/sin_Gluttony(var/mob/living/carbon/human/sinPerson, var/isIndulged)
if(isIndulged)
sinPerson << "<span class='warning'>Your stomach growls, you feel hungry.</span>"
var/list/allTypes = list()
for(var/A in typesof(/obj/item/weapon/reagent_containers/food/snacks))
var/obj/item/weapon/reagent_containers/food/snacks/O = A
if(initial(O.cooked_type))
allTypes += A
for(var/i in 1 to 10)
var/greed_type = pick(allTypes)
new greed_type(get_turf(sinPerson))
else
sinPerson << "<span class='warning'>Your body begins to bloat and stretch, bile rising in your throat.</span>"
sinPerson.reagents.add_reagent("nutriment",1000)
/proc/sin_Pride(var/mob/living/carbon/human/sinPerson, var/isIndulged)
var/obj/item/weapon/twohanded/sin_pride/pride_hammer = new(get_turf(sinPerson))
pride_hammer.pride_direction = !isIndulged
if(isIndulged)
sinPerson << "<span class='warning'>You feel strong enough to take on the world.</span>"
pride_hammer.name = "Indulged [pride_hammer.name]"
else
sinPerson << "<span class='warning'>You feel small and weak, like the entire world is against you.</span>"
pride_hammer.name = "Punished [pride_hammer.name]"
/proc/sin_Lust(var/mob/living/carbon/human/sinPerson, var/isIndulged)
var/obj/item/lovestone/lovestone = new(get_turf(sinPerson))
lovestone.lust_direction = !isIndulged
if(isIndulged)
sinPerson << "<span class='warning'>You feel confident, like everything and everyone is drawn to you.</span>"
lovestone.name = "Indulged [lovestone.name]"
else
sinPerson << "<span class='warning'>You feel lonely... the wish for the warmth of another spark through your mind.</span>"
lovestone.name = "Punished [lovestone.name]"
/proc/sin_Envy(var/mob/living/carbon/human/sinPerson, var/isIndulged)
if(isIndulged)
for(var/mob/living/carbon/human/H in player_list) // name lottery
if(H == sinPerson)
continue
if(prob(25))
sinPerson.name = H.name
sinPerson.real_name = H.real_name
var/datum/dna/lottery = H.dna
lottery.transfer_identity(sinPerson, transfer_SE=1)
sinPerson.updateappearance(mutcolor_update=1)
sinPerson.domutcheck()
sinPerson << "<span class='warning'>You feel envious of [sinPerson.name], and your body shifts to reflect that!</span>"
else
var/sinPersonspecies = pick(species_list)
var/newtype = species_list[sinPersonspecies]
sinPerson << "<span class='warning'>You wish for more from yourself.. your body shifts to suit your wish.</span>"
sinPerson.set_species(newtype)
/proc/sin_Sloth(var/mob/living/carbon/human/sinPerson, var/isIndulged)
if(isIndulged)
sinPerson << "<span class='warning'>You feel tired...</span>"
sinPerson.drowsyness += 100
else
sinPerson << "<span class='warning'>A chill comes over your body, the feeling of frostbite nipping at your fingers.</span>"
sinPerson.reagents.add_reagent("frostoil", 50)
/proc/sin_Wrath(var/mob/living/carbon/human/sinPerson, var/isIndulged)
if(isIndulged)
sinPerson << "<span class='warning'>You feel wrathful, like you want to destroy everyone and everything.</span>"
sinPerson.change_mob_type(/mob/living/simple_animal/slaughter,get_turf(sinPerson),"Wrath Demon",1)
else
sinPerson << "<span class='warning'>Your chest feels tight, and the world begins to spin around you.</span>"
sinPerson.reagents.add_reagent("lexorin", 29)
sinPerson.reagents.add_reagent("mindbreaker", 29)
/obj/effect/overlay/temp/hadesFlick
name = "transdimensional waste"
icon = 'icons/mob/mob.dmi'
icon_state = "liquify"
duration = 15
/obj/effect/overlay/temp/hadesBite
name = "biting tendril"
icon = 'icons/effects/effects.dmi'
icon_state = "tendril_bite"
duration = 15
/obj/effect/overlay/temp/hadesBlood
name = "blood plume"
icon = 'icons/effects/128x128.dmi'
icon_state = "spray_plume"
duration = 30
/obj/effect/timestop/hades // custom timeslip to make him immune
name = "Frozen Time"
desc = "Time has slowed to a halt."
/obj/effect/timestop/hades/New()
spawn(5)
..()
/obj/effect/timestop/hades/large
freezerange = 6
icon_state = "huge_rune"
icon = 'icons/effects/224x224.dmi'
/obj/item/weapon/twohanded/sin_pride
icon_state = "mjollnir0"
name = "Pride-struck Hammer"
desc = "It resonates an aura of Pride."
force = 5
throwforce = 15
w_class = 4
slot_flags = SLOT_BACK
force_unwielded = 5
force_wielded = 20
attack_verb = list("attacked", "smashed", "crushed", "splattered", "cracked")
hitsound = 'sound/weapons/blade1.ogg'
var/pride_direction = FALSE
/obj/item/weapon/twohanded/sin_pride/update_icon()
icon_state = "mjollnir[wielded]"
return
/obj/item/weapon/twohanded/sin_pride/afterattack(atom/A as mob|obj|turf|area, mob/user, proximity)
if(!proximity) return
if(wielded)
if(istype(A,/mob/living/carbon/human))
var/mob/living/carbon/H = A
var/mob/living/carbon/U = user
if(H)
if(pride_direction == FALSE)
U.reagents.trans_to(H, user.reagents.total_volume, 1, 1, 0)
U << "Your pride reflects on [H]."
if(H.health > 0)
U.health += force
U.updatehealth()
H.health -= force
H.updatehealth()
H << "You feel insecure, taking on [user]'s burden."
else if(pride_direction == TRUE)
H.reagents.trans_to(user, H.reagents.total_volume, 1, 1, 0)
H << "Your pride reflects on [user]."
if(U.health > 0)
U.health -= force
U.updatehealth()
H.health += force
H.updatehealth()
U << "You feel insecure, taking on [H]'s burden."
/obj/item/lovestone
name = "Stone of Lust"
desc = "It lays within your hand, radiating pulses of uncomfortable warmth."
icon = 'icons/obj/wizard.dmi'
icon_state = "lovestone"
item_state = "lovestone"
w_class = 1
var/lust_direction = FALSE
var/lastUsage = 0
var/usageTimer = 300
/obj/item/lovestone/attack_self(mob/user)
if(world.time > lastUsage + usageTimer)
lastUsage = world.time
user.visible_message("<span class='warning'>[user] grips the [src] tightly, causing it to vibrate and pulse brightly.</span>")
spawn(25)
if(lust_direction == FALSE)
var/list/throwAt = list()
for(var/atom/movable/AM in oview(7,user))
if(!AM.anchored && AM != user)
throwAt.Add(AM)
for(var/counter = 1, counter < throwAt.len, ++counter)
var/atom/movable/cast = throwAt[counter]
cast.throw_at_fast(user,10,1)
else if(lust_direction == 1)
var/mob/living/carbon/human/H = user
var/mob/living/carbon/human/foundLover = locate(/mob/living/carbon/human) in orange(3,H)
if(!foundLover)
H << "As you hold the stone, loneliness grips you, your heart feeling heavy and you struggle to breath."
for(var/i in 1 to 10)
addtimer(H.reagents, "add_reagent", i*10, FALSE, "initropidril", i)
else
H << "You take comfort in the presence of [foundLover]"
H.reagents.add_reagent("omnizine",25)
H.Beam(foundLover,"r_beam",'icons/effects/beam.dmi',10)
foundLover << "You take comfort in the presence of [H]"
foundLover.reagents.add_reagent("omnizine",25)
else
user << "The stone lays inert. It is still recharging."
/mob/living/simple_animal/hostile/hadesacolyte
name = "Acolyte of Hades"
desc = "Darkness seethes from their every pore."
icon_state = "hades_acolyte"
icon_living = "hades_acolyte"
icon_dead = "hades_acolyte_dead"
speak_chance = 0
turns_per_move = 5
response_help = "trembles in fear of"
response_disarm = "slaps wildly at"
response_harm = "hits"
speed = 1
maxHealth = 45
health = 45
harm_intent_damage = 5
melee_damage_lower = 5
melee_damage_upper = 15
attacktext = "strikes at"
attack_sound = 'sound/weapons/bladeslice.ogg'
butcher_results = list(/obj/item/clothing/mask/gas/cyborg/hades = 1,/obj/item/clothing/suit/hooded/chaplain_hoodie/hades = 1,/obj/item/weapon/hades_staff/fake = 1)
unsuitable_atmos_damage = 0
del_on_death = 0
faction = list("hades")
var/mob/living/simple_animal/hostile/hades/master
/mob/living/simple_animal/hostile/hadesacolyte/Life()
if(..())
if(master)
if(get_dist(src,master) > 5)
PoolOrNew(/obj/effect/overlay/temp/hadesFlick,get_turf(src))
src.visible_message("<span class='warning'>[src] twists and distorts, before vanishing in a snap.</span>")
src.forceMove(get_turf(pick(orange(2,master))))
//acolyte of hades outfit
/obj/item/clothing/mask/gas/cyborg/hades
name = "Skull Mask"
desc = "It's a skull mask, made of a thin, cool metal."
/obj/item/clothing/suit/hooded/chaplain_hoodie/hades
name = "Dark robes"
desc = "A dark, soft robe."
hooded = 1
hoodtype = /obj/item/clothing/head/chaplain_hood/hades
/obj/item/clothing/head/chaplain_hood/hades
name = "Dark hood"
desc = "A dark, soft hood."
body_parts_covered = HEAD
flags_inv = HIDEHAIR|HIDEEARS
//end hades outfit
/obj/item/hades_summoner
name = "Dark Seed"
desc = "The stone lays inert, but even when holding it you hear maddened whispers."
icon = 'icons/obj/wizard.dmi'
icon_state = "dark_seed_inert"
item_state = "dark_seed_inert"
w_class = 1
var/isActivated = FALSE
var/whoActivated
var/countDownToSummon = 10
var/absorbedHP = 0
/obj/item/hades_summoner/attack_self(mob/user)
if(!isActivated)
var/choice = input(user,"Rub the stone?",name) in list("Yes","No")
if(choice == "Yes")
if(prob(15))
user << "<span class='warning'><font size=3>You rub the stone.. and a voice springs fourth!</font></span>"
user << "<span class='warning'><font size=3>You hear a voice in your head.. 'Bring me the flesh of a living being.. and we shall bargain.'</font></span>"
whoActivated = user
isActivated = TRUE
desc = "The stone hums with a soft glow, whispering to you."
icon_state = "dark_seed"
else
user << "<span class='warning'><font size=3>The stone shivers, but nothing happens. Perhaps try again later?</font></span>"
else
if(user != whoActivated)
user << "<span class='warning'><font size=3>The stone lays inert.</font></span>"
else
if(countDownToSummon > 0)
user << "<span class='warning'><font size=3>You hear a voice in your head.. 'I still require [countDownToSummon] vessels worth of flesh. Bring them to me'</font></span>"
else
user << "<span class='warning'><font size=3>I thank you, acolyte.</font></span>"
var/mob/living/simple_animal/hostile/hadesacolyte/HA = user.change_mob_type(/mob/living/simple_animal/hostile/hadesacolyte,get_turf(user),"[user.name]",1)
var/mob/living/simple_animal/hostile/hades/H = new/mob/living/simple_animal/hostile/hades(get_turf(user))
H.maxHealth = absorbedHP
H.health = H.maxHealth
if(H.maxHealth < initial(H.maxHealth))
HA << "<span class='warning'><font size=3>You.. you fool! How dare you summon me with such dirty flesh!</font></span>"
HA.faction -= "hades"
if(H.maxHealth > initial(H.maxHealth))
HA << "<span class='warning'><font size=3>Such.. power! You have exceeded yourself, acolyte. Drink of my might!</font></span>"
HA.maxHealth = 250
HA.health = 250
qdel(src)
/obj/item/hades_summoner/afterattack(atom/A as mob|obj|turf|area, mob/user, proximity)
if(!proximity)
return
if(istype(A,/mob/living))
var/mob/living/M = A
if(countDownToSummon > 0)
if(M.health > 0 && M.maxHealth > 200)
// no absorbing super strong creatures unless they're dead
user << "<span class='warning'><font size=3>Such power.. Slay this [M] so that I may partake of its being.</font></span>"
return
user << "<span class='warning'><font size=3>I accept your offering.</font></span>"
absorbedHP += M.maxHealth
if(!M.ckey)
M.gib()
else
M << "<span class='warning'><font size=3>You feel the flesh being stripped from your bones. You're overwhelmed with maddening pain, before reforming into another being!</font></span>"
M.change_mob_type(/mob/living/simple_animal/hostile/hadesacolyte,get_turf(user),"[user.name]",1)
countDownToSummon--
if(countDownToSummon <= 0)
user << "<span class='warning'><font size=3>I am ready to ascend, my acolyte.</font></span>"
#undef STATE_JUDGE
#undef STATE_WRATH
#undef STATE_FLEE
@@ -1,143 +0,0 @@
/area/hades
name = "Chapel of Sin"
icon_state = "yellow"
requires_power = 0
has_gravity = 1
/turf/open/floor/plasteel/hades
name = "Sin-touched Floor"
icon_state = "cult"
/obj/structure/chair/hades
name = "Cross of Hades"
desc = "An inverted cross, with straps on it to support the weight of a living being."
icon_state = "chair_hades"
var/list/watchedSpikes = list()
/obj/structure/chair/hades/New()
..()
flags |= NODECONSTRUCT
for(var/obj/structure/kitchenspike/KS in range(12))
watchedSpikes += KS
/obj/structure/chair/hades/proc/considerReady()
//buckled_mobs seems to work inconsistently, so we're doing some custom searching here.
if(!buckled_mobs)
return FALSE
if(!buckled_mobs.len)
return FALSE
for(var/obj/structure/kitchenspike/KS in watchedSpikes)
var/mob/living/M = locate(/mob/living) in get_turf(KS)
if(!M)
return FALSE
return TRUE
/obj/structure/chair/hades/proc/completeRitual()
for(var/obj/structure/kitchenspike/KS in watchedSpikes)
var/mob/living/M = locate(/mob/living) in get_turf(KS)
M.gib()
playsound(get_turf(src), 'sound/effects/pope_entry.ogg', 100, 1)
sleep(100)
playsound(get_turf(src), 'sound/effects/hyperspace_end.ogg', 100, 1)
new/obj/item/weapon/hades_staff/imbued(get_turf(src))
src.visible_message("<span class='warning'>[src] shatters into a thousand shards, a staff falling from it.</span>")
qdel(src)
/obj/structure/chair/hades/attackby(obj/item/weapon/W, mob/user, params)
..()
if(istype(W, /obj/item/weapon/hades_staff))
var/obj/item/weapon/hades_staff/HS = W
if(!HS.isKey)
return
src.visible_message("<span class='warning'>[user] inserts the [W] into the [src], giving it a quick turn.</span>")
if(considerReady())
qdel(W)
src.visible_message("<span class='warning'>[src] shudders, the sound of moving gears arising...</span>")
for(var/mob/living/M in buckled_mobs)
M.gib()
for(var/i in 1 to 4)
addtimer(GLOBAL_PROC, "playsound", i*10, FALSE, get_turf(src), 'sound/effects/clang.ogg', 100, 1)
spawn(50)
src.visible_message("<span class='warning'>[src] begins to lower into the ground...</span>")
icon_state = "chair_hades_slide"
addtimer(src, "completeRitual", 50, FALSE)
else
src.visible_message("<span class='warning'>[src] clunks, the sound of grinding gears arising. Nothing happens.</span>")
/obj/structure/ladder/unbreakable/hades
name = "Dimensional Rift"
desc = "Where does it lead?"
icon = 'icons/mob/EvilPope.dmi'
icon_state = "popedeath"
anchored = TRUE
/obj/structure/ladder/unbreakable/hades/update_icon()
return
/obj/item/weapon/paper/hades_instructions
name = "paper- 'Hastily Scrawled Letter'"
info = "The Master has instructed us to collect corpses for the ritual, and told us to deposity them in the Ritual Room, behind a bookcase in the library. The Master has locked the device to only work with his key, so no more accidents happen."
/obj/item/weapon/hades_staff
name = "Staff of Hades"
desc = "A large, dark staff, with a set of key-like prongs on the end."
icon_state = "staffofchange"
icon = 'icons/obj/guns/magic.dmi'
item_state = "staffofchange"
slot_flags = SLOT_BELT | SLOT_BACK
force = 25
throwforce = 5
w_class = 3
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("slapped", "shattered", "blasphemed", "smashed", "whacked", "crushed", "hammered")
block_chance = 25
var/isKey = 1
/obj/item/weapon/hades_staff/fake
name = "Inert Staff of Hades"
desc = "A large, dark staff."
isKey = 0
/obj/item/weapon/hades_staff/imbued
name = "Imbued Staff of Hades"
desc = " Bestowed with the power of wayward souls, this Staff allows the wielder to judge a target."
force = 75
throwforce = 35
block_chance = 75
var/lastJudge = 0
var/judgeCooldown = 150
/obj/item/weapon/hades_staff/imbued/attack(mob/living/carbon/human/M, mob/living/carbon/human/user)
if(!istype(M))
return ..()
if(world.time > lastJudge + judgeCooldown)
var/mob/living/sinPerson = M
lastJudge = world.time
var/sinPersonchoice = pick("Greed","Gluttony","Pride","Lust","Envy","Sloth","Wrath")
src.say("Your sin, [sinPerson], is [sinPersonchoice].")
var/isIndulged = prob(50)
if(isIndulged)
src.say("I will indulge your sin, [sinPerson].")
else
src.say("Your sin will be punished, [sinPerson]!")
switch(sinPersonchoice)
if("Greed")
sin_Greed(sinPerson, isIndulged)
if("Gluttony")
sin_Gluttony(sinPerson, isIndulged)
if("Pride")
sin_Pride(sinPerson, isIndulged)
if("Lust")
sin_Lust(sinPerson, isIndulged)
if("Envy")
sin_Envy(sinPerson, isIndulged)
if("Sloth")
sin_Sloth(sinPerson, isIndulged)
if("Wrath")
sin_Wrath(sinPerson, isIndulged)
else
..()
user << "The [src] is still recharging."
@@ -486,6 +486,7 @@ This is here to make the tiles around the station mininuke change when it's arme
name = "nuclear authentication disk"
desc = "Better keep this safe."
icon_state = "nucleardisk"
persistence_replacement = /obj/item/weapon/disk/fakenucleardisk
/obj/item/weapon/disk/nuclear/New()
..()
@@ -556,3 +557,8 @@ This is here to make the tiles around the station mininuke change when it's arme
log_game("[src] has been destroyed in [COORD(diskturf)]. Moving it to \
[COORD(targetturf)].")
return QDEL_HINT_LETMELIVE //Cancel destruction unless forced
/obj/item/weapon/disk/fakenucleardisk
name = "cheap plastic imitation of the nuclear authentication disk"
desc = "Broken dreams and a faint oder of cheese."
icon_state = "nucleardisk"
+2 -14
View File
@@ -385,20 +385,6 @@
limit = 3
category = "Assistance"
/datum/spellbook_entry/item/hadesstone
name = "Dark Seed"
desc = "A small, dark stone that whispers to you menacingly.\
The seed calls for the corpses of living beings,\
in order to summon an ancient, powerful being.\
The power and tenacity of the summoned being directly\
correlates to the power of the absorbed beings,\
so choose your targets wisely."
item_path = /obj/item/hades_summoner
cost = 2
log_name = "DS"
limit = 1
category = "Assistance"
/datum/spellbook_entry/item/mjolnir
name = "Mjolnir"
desc = "A mighty hammer on loan from Thor, God of Thunder. It crackles with barely contained power."
@@ -514,6 +500,7 @@
throw_speed = 2
throw_range = 5
w_class = 1
persistence_replacement = /obj/item/weapon/spellbook/oneuse/random
var/uses = 10
var/temp = null
var/tab = null
@@ -704,6 +691,7 @@
name = "spellbook of "
uses = 1
desc = "This template spellbook was never meant for the eyes of man..."
persistence_replacement = null
/obj/item/weapon/spellbook/oneuse/New()
..()
+1 -1
View File
@@ -135,7 +135,7 @@
data["occupant"]["stat"] = occupant.stat
data["occupant"]["health"] = occupant.health
data["occupant"]["maxHealth"] = occupant.maxHealth
data["occupant"]["minHealth"] = config.health_threshold_dead
data["occupant"]["minHealth"] = HEALTH_THRESHOLD_DEAD
data["occupant"]["bruteLoss"] = occupant.getBruteLoss()
data["occupant"]["oxyLoss"] = occupant.getOxyLoss()
data["occupant"]["toxLoss"] = occupant.getToxLoss()
+4 -4
View File
@@ -182,8 +182,8 @@
icon_state = "pod_1"
//Get the clone body ready
H.adjustCloneLoss(CLONE_INITIAL_DAMAGE) //Yeah, clones start with very low health, not with random, because why would they start with random health
H.adjustBrainLoss(CLONE_INITIAL_DAMAGE)
H.setCloneLoss(CLONE_INITIAL_DAMAGE) //Yeah, clones start with very low health, not with random, because why would they start with random health
H.setBrainLoss(CLONE_INITIAL_DAMAGE)
H.Paralyse(4)
if(grab_ghost_when == CLONER_FRESH_CLONE)
@@ -231,10 +231,10 @@
occupant.Paralyse(4)
//Slowly get that clone healed and finished.
occupant.adjustCloneLoss(-((speed_coeff/2)))
occupant.adjustCloneLoss(-((speed_coeff/2) * config.damage_multiplier))
//Premature clones may have brain damage.
occupant.adjustBrainLoss(-((speed_coeff/2)))
occupant.adjustBrainLoss(-((speed_coeff/2) * config.damage_multiplier))
//So clones don't die of oxyloss in a running pod.
if (occupant.reagents.get_reagent_amount("salbutamol") < 30)
+11 -4
View File
@@ -21,9 +21,18 @@ The console is located at computer/gulag_teleporter.dm
var/jumpsuit_type = /obj/item/clothing/under/rank/prisoner
var/shoes_type = /obj/item/clothing/shoes/sneakers/orange
var/obj/machinery/gulag_item_reclaimer/linked_reclaimer = null
var/list/required_items
/obj/machinery/gulag_teleporter/New()
..()
required_items = typecacheof(list(
/obj/item/weapon/implant,
/obj/item/clothing/suit/space/eva/plasmaman,
/obj/item/clothing/under/plasmaman,
/obj/item/clothing/head/helmet/space/plasmaman,
/obj/item/weapon/tank/internals,
/obj/item/clothing/mask/breath,
/obj/item/clothing/mask/gas))
var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/gulag_teleporter(null)
B.apply_default_parts(src)
addtimer(src, "locate_reclaimer", 5)
@@ -128,12 +137,10 @@ The console is located at computer/gulag_teleporter.dm
if(linked_reclaimer)
linked_reclaimer.stored_items[occupant] = list()
for(var/obj/item/W in occupant)
if(occupant.unEquip(W))
if(!is_type_in_typecache(W, required_items) && occupant.unEquip(W))
if(istype(W, /obj/item/weapon/restraints/handcuffs))
W.forceMove(get_turf(src))
continue
if(istype(W, /obj/item/weapon/implant/storage))
continue
if(linked_reclaimer)
linked_reclaimer.stored_items[occupant] += W
linked_reclaimer.contents += W
@@ -146,7 +153,7 @@ The console is located at computer/gulag_teleporter.dm
return
strip_occupant()
var/mob/living/carbon/human/prisoner = occupant
if(jumpsuit_type)
if(!isplasmaman(prisoner) && jumpsuit_type)
prisoner.equip_to_appropriate_slot(new jumpsuit_type)
if(shoes_type)
prisoner.equip_to_appropriate_slot(new shoes_type)
+1 -1
View File
@@ -354,7 +354,7 @@
return 1
/obj/item/weapon/twohanded/shockpaddles/attack(mob/M, mob/user)
var/halfwaycritdeath = (config.health_threshold_crit + config.health_threshold_dead) / 2
var/halfwaycritdeath = (HEALTH_THRESHOLD_CRIT + HEALTH_THRESHOLD_DEAD) / 2
if(busy)
return
@@ -28,7 +28,18 @@
/obj/item/weapon/implanter/uplink
name = "implanter (uplink)"
persistence_replacement = /obj/item/weapon/implanter/weakuplink
/obj/item/weapon/implanter/uplink/New()
imp = new /obj/item/weapon/implant/uplink(src)
..()
/obj/item/weapon/implanter/weakuplink
name = "implanter (uplink)"
/obj/item/weapon/implanter/weakuplink/New()
imp = new /obj/item/weapon/implant/uplink/weak(src)
..()
/obj/item/weapon/implant/uplink/weak/New()
..()
hidden_uplink.telecrystals = 5
@@ -288,6 +288,7 @@
..()
PoolOrNew(/obj/item/stack/tile/plasteel, src)
new /obj/item/weapon/crowbar(src)
SSpersistence.new_secret_satchels += src
/obj/item/weapon/storage/backpack/satchel/flat/secret/
var/list/reward_one_of_these = list() //Intended for map editing
+2
View File
@@ -18,6 +18,8 @@
var/on_blueprints = FALSE //Are we visible on the station blueprints at roundstart?
var/force_blueprints = FALSE //forces the obj to be on the blueprints, regardless of when it was created.
var/persistence_replacement = null //have something WAY too amazing to live to the next round? Set a new path here. Overuse of this var will make me upset.
/obj/New()
..()
-2
View File
@@ -16,8 +16,6 @@
/obj/structure/lattice/New()
..()
if(!(istype(src.loc, /turf/open/space)))
qdel(src)
for(var/obj/structure/lattice/LAT in src.loc)
if(LAT != src)
qdel(LAT)
-10
View File
@@ -36,10 +36,6 @@
if(BANTYPE_JOB_TEMP)
bantype_str = "JOB_TEMPBAN"
bantype_pass = 1
if(BANTYPE_APPEARANCE)
bantype_str = "APPEARANCE_PERMABAN"
duration = -1
bantype_pass = 1
if(BANTYPE_ADMIN_PERMA)
bantype_str = "ADMIN_PERMABAN"
duration = -1
@@ -160,9 +156,6 @@
if(BANTYPE_JOB_TEMP)
bantype_str = "JOB_TEMPBAN"
bantype_pass = 1
if(BANTYPE_APPEARANCE)
bantype_str = "APPEARANCE_PERMABAN"
bantype_pass = 1
if(BANTYPE_ADMIN_PERMA)
bantype_str = "ADMIN_PERMABAN"
bantype_pass = 1
@@ -361,7 +354,6 @@
output += "<option value='[BANTYPE_TEMP]'>TEMPBAN</option>"
output += "<option value='[BANTYPE_JOB_PERMA]'>JOB PERMABAN</option>"
output += "<option value='[BANTYPE_JOB_TEMP]'>JOB TEMPBAN</option>"
output += "<option value='[BANTYPE_APPEARANCE]'>IDENTITY BAN</option>"
output += "<option value='[BANTYPE_ADMIN_PERMA]'>ADMIN PERMABAN</option>"
output += "<option value='[BANTYPE_ADMIN_TEMP]'>ADMIN TEMPBAN</option>"
output += "</select></td>"
@@ -453,8 +445,6 @@
typedesc = "<b>JOBBAN</b><br><font size='2'>([job])"
if("JOB_TEMPBAN")
typedesc = "<b>TEMP JOBBAN</b><br><font size='2'>([job])<br>([duration] minutes [(unbanned) ? "" : "(<a href=\"byond://?src=\ref[src];dbbanedit=duration;dbbanid=[banid]\">Edit</a>))"]<br>Expires [expiration]"
if("APPEARANCE_PERMABAN")
typedesc = "<b>IDENTITY PERMABAN</b>"
if("ADMIN_PERMABAN")
typedesc = "<b>ADMIN PERMABAN</b>"
if("ADMIN_TEMPBAN")
+15 -1
View File
@@ -525,16 +525,30 @@ var/list/admin_verbs_hideable = list(
var/obj/effect/proc_holder/spell/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spell_list
if(!S)
return
S = spell_list[S]
feedback_add_details("admin_verb","GS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] gave [key_name(T)] the spell [S].")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] gave [key_name(T)] the spell [S].</span>")
S = spell_list[S]
if(T.mind)
T.mind.AddSpell(new S)
else
T.AddSpell(new S)
message_admins("<span class='danger'>Spells given to mindless mobs will not be transferred in mindswap or cloning!</span>")
/client/proc/remove_spell(mob/T in mob_list)
set category = "Fun"
set name = "Remove Spell"
set desc = "Remove a spell from the selected mob."
if(T && T.mind)
var/obj/effect/proc_holder/spell/S = input("Choose the spell to remove", "NO ABRAKADABRA") as null|anything in T.mind.spell_list
if(S)
T.mind.RemoveSpell(S)
log_admin("[key_name(usr)] removed the spell [S] from [key_name(T)].")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] removed the spell [S] from [key_name(T)].</span>")
feedback_add_details("admin_verb","RS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/give_disease(mob/T in mob_list)
set category = "Fun"
-110
View File
@@ -1,110 +0,0 @@
//ban people from using custom names and appearances. that'll show 'em.
var/appearanceban_runonce //Updates legacy bans with new info
var/appearance_keylist[0] //to store the keys
/proc/appearance_fullban(mob/M, reason)
if (!M || !M.key) return
appearance_keylist.Add(text("[M.ckey] ## [reason]"))
appearance_savebanfile()
/proc/appearance_client_fullban(ckey)
if (!ckey) return
appearance_keylist.Add(text("[ckey]"))
appearance_savebanfile()
//returns a reason if M is banned, returns 0 otherwise
/proc/appearance_isbanned(mob/M)
if(M)
for(var/s in appearance_keylist)
if(findtext(s, "[M.ckey]") == 1)
var/startpos = findtext(s, "## ") + 3
if(startpos && startpos < length(s))
var/text = copytext(s, startpos, 0)
if(text)
return text
return "Reason Unspecified"
return 0
/*
DEBUG
/mob/verb/list_all_appearances()
set name = "list all appearances"
for(var/s in appearance_keylist)
world << s
/mob/verb/reload_appearances()
set name = "reload appearances"
appearance_loadbanfile()
*/
/proc/appearance_loadbanfile()
if(config.ban_legacy_system)
var/savefile/S=new("data/appearance_full.ban")
S["keys[0]"] >> appearance_keylist
log_admin("Loading appearance_rank")
S["runonce"] >> appearanceban_runonce
if (!length(appearance_keylist))
appearance_keylist=list()
log_admin("appearance_keylist was empty")
else
if(!establish_db_connection())
world.log << "Database connection failed. Reverting to the legacy ban system."
diary << "Database connection failed. Reverting to the legacy ban system."
config.ban_legacy_system = 1
appearance_loadbanfile()
return
//appearance bans
var/DBQuery/query = dbcon.NewQuery("SELECT ckey FROM [format_table_name("ban")] WHERE bantype = 'APPEARANCE_PERMABAN' AND NOT unbanned = 1")
query.Execute()
while(query.NextRow())
var/ckey = query.item[1]
appearance_keylist.Add("[ckey]")
/proc/appearance_savebanfile()
var/savefile/S=new("data/appearance_full.ban")
S["keys[0]"] << appearance_keylist
/proc/appearance_unban(mob/M)
appearance_remove("[M.ckey]")
appearance_savebanfile()
/proc/appearance_updatelegacybans()
if(!appearanceban_runonce)
log_admin("Updating appearancefile!")
// Updates bans.. Or fixes them. Either way.
for(var/T in appearance_keylist)
if(!T)
continue
appearanceban_runonce++ //don't run this update again
/proc/appearance_remove(X)
for (var/i = 1; i <= length(appearance_keylist); i++)
if( findtext(appearance_keylist[i], "[X]") )
appearance_keylist.Remove(appearance_keylist[i])
appearance_savebanfile()
return 1
return 0
/*
/proc/DB_ban_isappearancebanned(var/playerckey)
establish_db_connection()
if(!dbcon.IsConnected())
return
var/sqlplayerckey = sanitizeSQL(ckey(playerckey))
var/DBQuery/query = dbcon.NewQuery("SELECT id FROM [format_table_name("ban")] WHERE CKEY = '[sqlplayerckey]' AND ((bantype = 'APPEARANCE_PERMABAN') OR (bantype = 'APPEARANCE_TEMPBAN' AND expiration_time > Now())) AND unbanned != 1")
query.Execute()
while(query.NextRow())
return 1
return 0
*/
+23 -23
View File
@@ -346,7 +346,7 @@
for(var/datum/mind/N in ticker.mode.syndicates)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
else
@@ -375,20 +375,20 @@
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[N]'>[N.name]([N.key])</a><i>Head Revolutionary body destroyed!</i></td>"
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
else
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Leader)</b>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Leader)</b>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
for(var/datum/mind/N in ticker.mode.revolutionaries)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table><table cellspacing=5><tr><td><B>Target(s)</B></td><td></td><td><B>Location</B></td></tr>"
for(var/datum/mind/N in ticker.mode.get_living_heads())
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
var/turf/mob_loc = get_turf(M)
@@ -406,13 +406,13 @@
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[N]'>[N.name]([N.key])</a><i>Gang Boss body destroyed!</i></td>"
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
else
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Boss)</b>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Boss)</b>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
for(var/datum/mind/N in G.gangsters)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td></tr>"
dat += "</table>"
@@ -421,7 +421,7 @@
for(var/datum/mind/changeling in ticker.mode.changelings)
var/mob/M = changeling.current
if(M)
dat += "<tr><td>[M.mind.changeling.changelingID] as <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td>[M.mind.changeling.changelingID] as <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
@@ -435,7 +435,7 @@
for(var/datum/mind/wizard in ticker.mode.wizards)
var/mob/M = wizard.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
@@ -449,7 +449,7 @@
for(var/datum/mind/apprentice in ticker.mode.apprentices)
var/mob/M = apprentice.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
@@ -463,7 +463,7 @@
for(var/datum/mind/N in ticker.mode.cult)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
@@ -483,7 +483,7 @@
for(var/datum/mind/N in ticker.mode.red_deities)
var/mob/M = N.current
if(M)
dat += "<tr><td>Red Deity: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td>Red Deity: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
@@ -493,7 +493,7 @@
for(var/datum/mind/N in ticker.mode.blue_deities)
var/mob/M = N.current
if(M)
dat += "<tr><td>Blue Deity: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td>Blue Deity: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
@@ -503,7 +503,7 @@
for(var/datum/mind/N in ticker.mode.red_deity_prophets)
var/mob/M = N.current
if(M)
dat += "<tr><td>Red Deity Prophet: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td>Red Deity Prophet: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
@@ -513,7 +513,7 @@
for(var/datum/mind/N in ticker.mode.blue_deity_prophets)
var/mob/M = N.current
if(M)
dat += "<tr><td>Blue Deity Prophet: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td>Blue Deity Prophet: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
@@ -523,7 +523,7 @@
for(var/datum/mind/N in ticker.mode.red_deity_followers)
var/mob/M = N.current
if(M)
dat += "<tr><td>Red Deity Followers: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td>Red Deity Followers: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
@@ -533,7 +533,7 @@
for(var/datum/mind/N in ticker.mode.blue_deity_followers)
var/mob/M = N.current
if(M)
dat += "<tr><td>Blue Deity Followers: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td>Blue Deity Followers: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
@@ -543,7 +543,7 @@
for(var/datum/mind/traitor in ticker.mode.traitors)
var/mob/M = traitor.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
@@ -557,7 +557,7 @@
for(var/datum/mind/abductor in ticker.mode.abductors)
var/mob/M = abductor.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
@@ -570,7 +570,7 @@
for(var/datum/mind/abductee in E.abductee_minds)
var/mob/M = abductee.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
@@ -585,7 +585,7 @@
var/datum/mind/devil = X
var/mob/M = devil.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name] : [devil.devilinfo.truename]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name] : [devil.devilinfo.truename]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
dat += "<td><A HREF='?_src_=holder;admincheckdevilinfo=\ref[M]'>Show all devil info</A></td></tr>"
@@ -600,7 +600,7 @@
var/datum/mind/sintouched = X
var/mob/M = sintouched.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
else
@@ -622,7 +622,7 @@
for(var/datum/mind/blob in blob_minds)
var/mob/M = blob.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
else
@@ -638,7 +638,7 @@
for(var/datum/mind/eek in mode.ape_infectees)
var/mob/M = eek.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
else
+11 -15
View File
@@ -203,12 +203,6 @@
if(!banckey || !banreason || !banjob || !banduration)
usr << "Not enough parameters (Requires ckey, reason and job)."
return
if(BANTYPE_APPEARANCE)
if(!banckey || !banreason)
usr << "Not enough parameters (Requires ckey and reason)."
return
banduration = null
banjob = null
if(BANTYPE_ADMIN_PERMA)
if(!banckey || !banreason)
usr << "Not enough parameters (Requires ckey and reason)."
@@ -517,15 +511,16 @@
usr << "This mob has no ckey"
return
var/banreason = appearance_isbanned(M)
if(banreason)
switch(alert("Reason: '[banreason]' Remove appearance ban?","Please Confirm","Yes","No"))
if(jobban_isbanned(M, "appearance"))
switch(alert("Remove appearance ban?","Please Confirm","Yes","No"))
if("Yes")
ban_unban_log_save("[key_name(usr)] removed [key_name(M)]'s appearance ban.")
log_admin("[key_name(usr)] removed [key_name(M)]'s appearance ban.")
feedback_inc("ban_appearance_unban", 1)
DB_ban_unban(M.ckey, BANTYPE_APPEARANCE)
appearance_unban(M)
DB_ban_unban(M.ckey, BANTYPE_ANY_JOB, "appearance")
if(M.client)
jobban_buildcache(M.client)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] removed [key_name_admin(M)]'s appearance ban.</span>")
M << "<span class='boldannounce'><BIG>[usr.client.ckey] has removed your appearance ban.</BIG></span>"
@@ -537,8 +532,9 @@
ban_unban_log_save("[key_name(usr)] appearance banned [key_name(M)]. reason: [reason]")
log_admin("[key_name(usr)] appearance banned [key_name(M)]. \nReason: [reason]")
feedback_inc("ban_appearance",1)
DB_ban_record(BANTYPE_APPEARANCE, M, -1, reason)
appearance_fullban(M, "[reason]; By [usr.ckey] on [time2text(world.realtime)]")
DB_ban_record(BANTYPE_JOB_PERMA, M, -1, reason, "appearance")
if(M.client)
jobban_buildcache(M.client)
add_note(M.ckey, "Appearance banned - [reason]", null, usr.ckey, 0)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] appearance banned [key_name_admin(M)].</span>")
M << "<span class='boldannounce'><BIG>You have been appearance banned by [usr.client.ckey].</BIG></span>"
@@ -987,7 +983,7 @@
msg += ", [job]"
add_note(M.ckey, "Banned from [msg] - [reason]", null, usr.ckey, 0)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] banned [key_name_admin(M)] from [msg] for [mins] minutes.</span>")
M << "<span class='boldannounce'><BIG>You have been jobbanned by [usr.client.ckey] from: [msg].</BIG></span>"
M << "<span class='boldannounce'><BIG>You have been [(msg == ("ooc" || "appearance")) ? "banned" : "jobbanned"] by [usr.client.ckey] from: [msg].</BIG></span>"
M << "<span class='boldannounce'>The reason is: [reason]</span>"
M << "<span class='danger'>This jobban will be lifted in [mins] minutes.</span>"
href_list["jobban2"] = 1 // lets it fall through and refresh
@@ -1010,7 +1006,7 @@
msg += ", [job]"
add_note(M.ckey, "Banned from [msg] - [reason]", null, usr.ckey, 0)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] banned [key_name_admin(M)] from [msg].</span>")
M << "<span class='boldannounce'><BIG>You have been jobbanned by [usr.client.ckey] from: [msg].</BIG></span>"
M << "<span class='boldannounce'><BIG>You have been [(msg == ("ooc" || "appearance")) ? "banned" : "jobbanned"] by [usr.client.ckey] from: [msg].</BIG></span>"
M << "<span class='boldannounce'>The reason is: [reason]</span>"
M << "<span class='danger'>Jobban can be lifted only upon request.</span>"
href_list["jobban2"] = 1 // lets it fall through and refresh
+10 -2
View File
@@ -1,4 +1,4 @@
/proc/keywords_lookup(msg)
/proc/keywords_lookup(msg,irc)
//This is a list of words which are ignored by the parser when comparing message contents for names. MUST BE IN LOWER CASE!
var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","alien","as", "i")
@@ -10,6 +10,7 @@
var/list/surnames = list()
var/list/forenames = list()
var/list/ckeys = list()
var/founds = ""
for(var/mob/M in mob_list)
var/list/indexing = list(M.real_name, M.name)
if(M.mind)
@@ -56,9 +57,16 @@
var/is_antag = 0
if(found.mind && found.mind.special_role)
is_antag = 1
founds += "Name: [found.name]([found.real_name]) Ckey: [found.ckey] [is_antag ? "(Antag)" : null] "
msg += "[original_word]<font size='1' color='[is_antag ? "red" : "black"]'>(<A HREF='?_src_=holder;adminmoreinfo=\ref[found]'>?</A>|<A HREF='?_src_=holder;adminplayerobservefollow=\ref[found]'>F</A>)</font> "
continue
msg += "[original_word] "
if(irc)
if(founds == "")
return "Search Failed"
else
return founds
return msg
@@ -160,4 +168,4 @@
message["key"] = global.comms_key
message["crossmessage"] = type
world.Export("[global.cross_address]?[list2params(message)]")
world.Export("[global.cross_address]?[list2params(message)]")
+2 -1
View File
@@ -190,6 +190,7 @@
var/client/C = directory[target]
var/static/stealthkey
var/adminname = config.showircname ? "[sender](IRC)" : "Administrator"
if(!C)
return "No client"
@@ -206,7 +207,7 @@
msg = emoji_parse(msg)
C << "<font color='red' size='4'><b>-- Administrator private message --</b></font>"
C << "<font color='red'>Admin PM from-<b><a href='?priv_msg=[stealthkey]'>Administrator</A></b>: [msg]</font>"
C << "<font color='red'>Admin PM from-<b><a href='?priv_msg=[stealthkey]'>[adminname]</A></b>: [msg]</font>"
C << "<font color='red'><i>Click on the administrator's name to reply.</i></font>"
//always play non-admin recipients the adminhelp sound
@@ -212,7 +212,7 @@
occupantData["stat"] = occupant.stat
occupantData["health"] = occupant.health
occupantData["maxHealth"] = occupant.maxHealth
occupantData["minHealth"] = config.health_threshold_dead
occupantData["minHealth"] = HEALTH_THRESHOLD_DEAD
occupantData["bruteLoss"] = occupant.getBruteLoss()
occupantData["oxyLoss"] = occupant.getOxyLoss()
occupantData["toxLoss"] = occupant.getToxLoss()
+1 -1
View File
@@ -151,7 +151,7 @@ var/list/preferences_datums = list()
dat += "<a href='?_src_=prefs;preference=job;task=menu'>Set Occupation Preferences</a><br></center>"
dat += "<h2>Identity</h2>"
dat += "<table width='100%'><tr><td width='75%' valign='top'>"
if(appearance_isbanned(user))
if(jobban_isbanned(user, "appearance"))
dat += "<b>You are banned from using custom names and appearances. You can continue to adjust your characters, but you will be randomised once you join the game.</b><br>"
dat += "<a href='?_src_=prefs;preference=name;task=random'>Random Name</A> "
dat += "<a href='?_src_=prefs;preference=name'>Always Random Name: [be_random_name ? "Yes" : "No"]</a><BR>"
+10
View File
@@ -558,6 +558,8 @@
setting = FALSE
return
var/area/A = get_area(T)
var/obj/docking_port/stationary/landing_zone = new /obj/docking_port/stationary(T)
landing_zone.id = "colony_drop(\ref[src])"
landing_zone.name = "Landing Zone"
@@ -566,6 +568,8 @@
landing_zone.width = width
landing_zone.height = height
landing_zone.setDir(lz_dir)
landing_zone.turf_type = T.baseturf
landing_zone.area_type = A.type
for(var/obj/machinery/computer/shuttle/S in machines)
if(S.shuttleId == shuttle_id)
@@ -637,6 +641,9 @@
for(var/S in SSshuttle.stationary)
var/obj/docking_port/stationary/SM = S //SM is declared outside so it can be checked for null
if(SM.id == "mining_home" || SM.id == "mining_away")
var/area/A = get_area(landing_spot)
Mport = new(landing_spot)
Mport.id = "landing_zone_dock"
Mport.name = "landing zone dock"
@@ -645,6 +652,9 @@
Mport.width = SM.width
Mport.height = SM.height
Mport.setDir(dir)
Mport.turf_type = landing_spot.baseturf
Mport.area_type = A.type
break
if(!Mport)
user << "<span class='warning'>This station is not equipped with an approprite mining shuttle. Please contact Nanotrasen Support.</span>"
-12
View File
@@ -6,18 +6,6 @@
log_say("Ghost/[src.key] : [message]")
if(jobban_isbanned(src, "OOC"))
src << "<span class='danger'>You have been banned from deadchat.</span>"
return
if (src.client)
if(src.client.prefs.muted & MUTE_DEADCHAT)
src << "<span class='danger'>You cannot talk in deadchat (muted).</span>"
return
if (src.client.handle_spam_prevention(message,MUTE_DEADCHAT))
return
. = src.say_dead(message)
/mob/dead/observer/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
@@ -20,7 +20,7 @@
if(health<= -maxHealth || !getorgan(/obj/item/organ/brain))
death()
return
if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= config.health_threshold_crit)
if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT)
if(stat == CONSCIOUS)
stat = UNCONSCIOUS
blind_eyes(1)
@@ -56,7 +56,7 @@
/mob/living/carbon/brain/can_be_revived()
. = 1
if(!container || health <= config.health_threshold_dead)
if(!container || health <= HEALTH_THRESHOLD_DEAD)
return 0
/mob/living/carbon/brain/update_sight()
@@ -68,7 +68,7 @@
if(brainmob)
if(brainmob.client)
if(brainmob.health <= config.health_threshold_dead)
if(brainmob.health <= HEALTH_THRESHOLD_DEAD)
user << "It's lifeless and severely damaged."
else
user << "You can feel the small spark of life still left in this one."
+1 -1
View File
@@ -22,7 +22,7 @@
/mob/living/carbon/brain/update_stat()
if(status_flags & GODMODE)
return
if(health <= config.health_threshold_dead)
if(health <= HEALTH_THRESHOLD_DEAD)
if(stat != DEAD)
death()
var/obj/item/organ/brain/BR
+3 -3
View File
@@ -634,7 +634,7 @@
if(!client)
return
if(stat == UNCONSCIOUS && health <= config.health_threshold_crit)
if(stat == UNCONSCIOUS && health <= HEALTH_THRESHOLD_CRIT)
var/severity = 0
switch(health)
if(-20 to -10) severity = 1
@@ -712,10 +712,10 @@
if(status_flags & GODMODE)
return
if(stat != DEAD)
if(health<= config.health_threshold_dead || !getorgan(/obj/item/organ/brain))
if(health<= HEALTH_THRESHOLD_DEAD || !getorgan(/obj/item/organ/brain))
death()
return
if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= config.health_threshold_crit)
if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT)
if(stat == CONSCIOUS)
stat = UNCONSCIOUS
blind_eyes(1)
@@ -837,7 +837,7 @@
var/they_breathe = (!(NOBREATH in C.dna.species.specflags))
var/they_lung = C.getorganslot("lungs")
if(C.health > config.health_threshold_crit)
if(C.health > HEALTH_THRESHOLD_CRIT)
return
src.visible_message("[src] performs CPR on [C.name]!", "<span class='notice'>You perform CPR on [C.name].</span>")
@@ -10,7 +10,7 @@
total_burn += BP.burn_dam
health = maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute
update_stat()
if(((maxHealth - total_burn) < config.health_threshold_dead) && stat == DEAD )
if(((maxHealth - total_burn) < HEALTH_THRESHOLD_DEAD) && stat == DEAD )
ChangeToHusk()
if(on_fire)
shred_clothing()
@@ -113,7 +113,7 @@
return 1//Humans can use guns and such
/mob/living/carbon/human/InCritical()
return (health <= config.health_threshold_crit && stat == UNCONSCIOUS)
return (health <= HEALTH_THRESHOLD_CRIT && stat == UNCONSCIOUS)
/mob/living/carbon/human/reagent_check(datum/reagent/R)
return dna.species.handle_chemicals(R,src)
@@ -479,7 +479,7 @@
H.losebreath = 0
var/takes_crit_damage = (!(NOCRITDAMAGE in specflags))
if((H.health < config.health_threshold_crit) && takes_crit_damage)
if((H.health < HEALTH_THRESHOLD_CRIT) && takes_crit_damage)
H.adjustBruteLoss(1)
/datum/species/proc/spec_death(gibbed, mob/living/carbon/human/H)
@@ -1169,7 +1169,7 @@
if(!breath || (breath.total_moles() == 0) || !lungs)
if(H.reagents.has_reagent("epinephrine") && lungs)
return
if(H.health >= config.health_threshold_crit)
if(H.health >= HEALTH_THRESHOLD_CRIT)
H.adjustOxyLoss(HUMAN_MAX_OXYLOSS)
if(!lungs)
H.adjustOxyLoss(1)
@@ -1329,7 +1329,7 @@
if(!H || !safe_breath_min) //the other args are either: Ok being 0 or Specifically handled.
return 0
if(!(NOBREATH in specflags) || (H.health <= config.health_threshold_crit))
if(!(NOBREATH in specflags) || (H.health <= HEALTH_THRESHOLD_CRIT))
if(prob(20))
H.emote("gasp")
if(breath_pp > 0)
@@ -37,7 +37,7 @@
// If whispering your last words, limit the whisper based on how close you are to death.
if(critical)
var/health_diff = round(-config.health_threshold_dead + health)
var/health_diff = round(-HEALTH_THRESHOLD_DEAD + health)
// If we cut our message short, abruptly end it with a-..
var/message_len = length(message)
message = copytext(message, 1, health_diff) + "[message_len > health_diff ? "-.." : "..."]"
+2 -2
View File
@@ -48,7 +48,7 @@
var/datum/gas_mixture/breath
if(health <= config.health_threshold_crit || (pulledby && pulledby.grab_state >= GRAB_KILL && !getorganslot("breathing_tube")))
if(health <= HEALTH_THRESHOLD_CRIT || (pulledby && pulledby.grab_state >= GRAB_KILL && !getorganslot("breathing_tube")))
losebreath++
//Suffocate
@@ -311,7 +311,7 @@
if(sleeping)
handle_dreams()
AdjustSleeping(-1)
if(prob(10) && health>config.health_threshold_crit)
if(prob(10) && health>HEALTH_THRESHOLD_CRIT)
emote("snore")
var/restingpwr = 1 + 4 * resting
+9 -19
View File
@@ -1,13 +1,3 @@
/* I am informed this was added by Giacom to reduce mob-stacking in escape pods.
It's sorta problematic atm due to the shuttle changes I am trying to do
Sorry Giacom. Please don't be mad :(
/mob/living/Life()
..()
var/area/A = get_area(loc)
if(A && A.push_dir)
push_mob_back(src, A.push_dir)
*/
/mob/living/New()
. = ..()
generateStaticOverlay()
@@ -216,7 +206,7 @@ Sorry Giacom. Please don't be mad :(
set hidden = 1
if (InCritical())
src.attack_log += "[src] has [whispered ? "whispered his final words" : "succumbed to death"] with [round(health, 0.1)] points of health!"
src.adjustOxyLoss(src.health - config.health_threshold_dead)
src.adjustOxyLoss(src.health - HEALTH_THRESHOLD_DEAD)
updatehealth()
if(!whispered)
src << "<span class='notice'>You have given up life and succumbed to death.</span>"
@@ -272,7 +262,7 @@ Sorry Giacom. Please don't be mad :(
/mob/living/proc/adjustBruteLoss(amount, updating_health=1)
if(status_flags & GODMODE)
return 0
bruteloss = Clamp(bruteloss + amount, 0, maxHealth*2)
bruteloss = Clamp((bruteloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
if(updating_health)
updatehealth()
@@ -282,7 +272,7 @@ Sorry Giacom. Please don't be mad :(
/mob/living/proc/adjustOxyLoss(amount, updating_health=1)
if(status_flags & GODMODE)
return 0
oxyloss = Clamp(oxyloss + amount, 0, maxHealth*2)
oxyloss = Clamp((oxyloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
if(updating_health)
updatehealth()
@@ -299,7 +289,7 @@ Sorry Giacom. Please don't be mad :(
/mob/living/proc/adjustToxLoss(amount, updating_health=1)
if(status_flags & GODMODE)
return 0
toxloss = Clamp(toxloss + amount, 0, maxHealth*2)
toxloss = Clamp((toxloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
if(updating_health)
updatehealth()
return amount
@@ -317,7 +307,7 @@ Sorry Giacom. Please don't be mad :(
/mob/living/proc/adjustFireLoss(amount, updating_health=1)
if(status_flags & GODMODE)
return 0
fireloss = Clamp(fireloss + amount, 0, maxHealth*2)
fireloss = Clamp((fireloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
if(updating_health)
updatehealth()
@@ -327,7 +317,7 @@ Sorry Giacom. Please don't be mad :(
/mob/living/proc/adjustCloneLoss(amount, updating_health=1)
if(status_flags & GODMODE)
return 0
cloneloss = Clamp(cloneloss + amount, 0, maxHealth*2)
cloneloss = Clamp((cloneloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
if(updating_health)
updatehealth()
@@ -344,7 +334,7 @@ Sorry Giacom. Please don't be mad :(
/mob/living/proc/adjustBrainLoss(amount)
if(status_flags & GODMODE)
return 0
brainloss = Clamp(brainloss + amount, 0, maxHealth*2)
brainloss = Clamp((brainloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
/mob/living/proc/setBrainLoss(amount)
if(status_flags & GODMODE)
@@ -541,7 +531,7 @@ Sorry Giacom. Please don't be mad :(
//proc called by revive(), to check if we can actually ressuscitate the mob (we don't want to revive him and have him instantly die again)
/mob/living/proc/can_be_revived()
. = 1
if(health <= config.health_threshold_dead)
if(health <= HEALTH_THRESHOLD_DEAD)
return 0
/mob/living/proc/update_damage_overlays()
@@ -1026,7 +1016,7 @@ Sorry Giacom. Please don't be mad :(
/mob/living/carbon/human/update_stamina()
if(staminaloss)
var/total_health = (health - staminaloss)
if(total_health <= config.health_threshold_crit && !stat)
if(total_health <= HEALTH_THRESHOLD_CRIT && !stat)
src << "<span class='notice'>You're too exhausted to keep going...</span>"
Weaken(5)
setStaminaLoss(health - 2)
+1 -1
View File
@@ -60,7 +60,7 @@
if(status_flags & GODMODE)
return
if(stat != DEAD)
if(health <= config.health_threshold_dead)
if(health <= HEALTH_THRESHOLD_DEAD)
death()
return
else if(stat == UNCONSCIOUS)
@@ -152,7 +152,7 @@ var/global/list/parasites = list() //all currently existing/living guardians
if(summoner)
var/resulthealth
if(iscarbon(summoner))
resulthealth = round((abs(config.health_threshold_dead - summoner.health) / abs(config.health_threshold_dead - summoner.maxHealth)) * 100)
resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - summoner.health) / abs(HEALTH_THRESHOLD_DEAD - summoner.maxHealth)) * 100)
else
resulthealth = round((summoner.health / summoner.maxHealth) * 100, 0.5)
stat(null, "Summoner Health: [resulthealth]%")
@@ -197,7 +197,7 @@ var/global/list/parasites = list() //all currently existing/living guardians
if(summoner && hud_used && hud_used.healths)
var/resulthealth
if(iscarbon(summoner))
resulthealth = round((abs(config.health_threshold_dead - summoner.health) / abs(config.health_threshold_dead - summoner.maxHealth)) * 100)
resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - summoner.health) / abs(HEALTH_THRESHOLD_DEAD - summoner.maxHealth)) * 100)
else
resulthealth = round((summoner.health / summoner.maxHealth) * 100, 0.5)
hud_used.healths.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#efeeef'>[resulthealth]%</font></div>"
@@ -83,26 +83,21 @@
//////////////HOSTILE MOB TARGETTING AND AGGRESSION////////////
/mob/living/simple_animal/hostile/proc/ListTargets()//Step 1, find out what we can see
. = list()
if(!search_objects)
var/list/Mobs = hearers(vision_range, targets_from) - src //Remove self, so we don't suicide
. += Mobs
var/hostile_machines = list()
for(var/mecha in mechas_list)
hostile_machines += mecha
for(var/obj/machinery/porta_turret/P in machines)
hostile_machines += P
for(var/M in hostile_machines)
if(get_dist(M, targets_from) <= vision_range && can_see(targets_from, M, vision_range))
. += M
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha))
for(var/HM in typecache_filter_list(range(vision_range, targets_from), hostile_machines))
if(can_see(targets_from, HM, vision_range))
. += HM
else
var/list/Objects = oview(vision_range, targets_from)
. += Objects
/mob/living/simple_animal/hostile/proc/FindTarget(var/list/possible_targets, var/HasTargetsList = 0)//Step 2, filter down possible targets to things we actually care about
. = list()
if(!HasTargetsList)
@@ -290,23 +290,23 @@
/mob/living/simple_animal/adjustBruteLoss(amount)
if(damage_coeff[BRUTE])
. = adjustHealth(amount*damage_coeff[BRUTE])
. = adjustHealth(amount * damage_coeff[BRUTE] * config.damage_multiplier)
/mob/living/simple_animal/adjustFireLoss(amount)
if(damage_coeff[BURN])
. = adjustHealth(amount*damage_coeff[BURN])
. = adjustHealth(amount * damage_coeff[BURN] * config.damage_multiplier)
/mob/living/simple_animal/adjustOxyLoss(amount)
if(damage_coeff[OXY])
. = adjustHealth(amount*damage_coeff[OXY])
. = adjustHealth(amount * damage_coeff[OXY] * config.damage_multiplier)
/mob/living/simple_animal/adjustToxLoss(amount)
if(damage_coeff[TOX])
. = adjustHealth(amount*damage_coeff[TOX])
. = adjustHealth(amount * damage_coeff[TOX] * config.damage_multiplier)
/mob/living/simple_animal/adjustCloneLoss(amount)
if(damage_coeff[CLONE])
. = adjustHealth(amount*damage_coeff[CLONE])
. = adjustHealth(amount * damage_coeff[CLONE] * config.damage_multiplier)
/mob/living/simple_animal/adjustStaminaLoss(amount)
return
@@ -234,7 +234,7 @@
Feedstop(0, 0)
return
add_nutrition(rand(7,15))
add_nutrition((rand(7,15) * config.damage_multiplier))
//Heal yourself.
adjustBruteLoss(-3)
+1 -1
View File
@@ -419,7 +419,7 @@
var/mob/living/carbon/human/new_character = new(loc)
if(config.force_random_names || appearance_isbanned(src))
if(config.force_random_names || jobban_isbanned(src, "appearance"))
client.prefs.random_character()
client.prefs.real_name = client.prefs.pref_species.random_name(gender,1)
client.prefs.copy_to(new_character)
+12
View File
@@ -35,6 +35,18 @@
usr << "<span class='danger'>Speech is currently admin-disabled.</span>"
return
if(jobban_isbanned(src, "OOC"))
src << "<span class='danger'>You have been banned from deadchat.</span>"
return
if (src.client)
if(src.client.prefs.muted & MUTE_DEADCHAT)
src << "<span class='danger'>You cannot talk in deadchat (muted).</span>"
return
if(src.client.handle_spam_prevention(message,MUTE_DEADCHAT))
return
var/mob/dead/observer/O = src
if(isobserver(src) && O.deadchat_name)
name = "[O.deadchat_name]"
@@ -13,7 +13,7 @@
base_idle_power_usage = 100
base_active_power_usage = 500
max_hardware_size = 3
steel_sheet_cost = 20
steel_sheet_cost = 10
light_strength = 2
_max_damage = 300
_break_damage = 150
+1 -1
View File
@@ -1,6 +1,6 @@
/obj/item/weapon/gun/medbeam
name = "Medical Beamgun"
desc = "Delivers medical nanites in a focused beam."
desc = "Don't cross the streams!"
icon = 'icons/obj/chronos.dmi'
icon_state = "chronogun"
item_state = "chronogun"
+2 -2
View File
@@ -96,8 +96,8 @@
/obj/item/bodypart/proc/take_damage(brute, burn)
if(owner && (owner.status_flags & GODMODE))
return 0 //godmode
brute = max(brute,0)
burn = max(burn,0)
brute = max(brute * config.damage_multiplier,0)
burn = max(burn * config.damage_multiplier,0)
if(status == ORGAN_ROBOTIC) //This makes robolimbs not damageable by chems and makes it stronger
+7 -1
View File
@@ -39,7 +39,6 @@ var/global/list/map_transition_config = MAP_TRANSITION_CONFIG
load_admins()
if(config.usewhitelist)
load_whitelist()
appearance_loadbanfile()
LoadBans()
investigate_reset()
@@ -169,6 +168,13 @@ var/last_irc_status = 0
else
return IrcPm(input["adminmsg"],input["msg"],input["sender"])
else if("namecheck" in input)
if(!key_valid)
return "Bad Key"
else
log_admin("IRC Name Check: [input["sender"]] on [input["namecheck"]]")
message_admins("IRC name checking on [input["namecheck"]] from [input["sender"]]")
return keywords_lookup(input["namecheck"],1)
/world/Reboot(var/reason, var/feedback_c, var/feedback_r, var/time)
+3
View File
@@ -172,6 +172,9 @@ ALLOW_HOLIDAYS
##Remove the # mark if you are going to use the SVN irc bot to relay adminhelps
#USEIRCBOT
##Uncomment to show the names of the admin sending a pm from IRC instead of showing as a stealthmin.
#SHOW_IRC_NAME
##Defines the ticklag for the world. 0.9 is the normal one, 0.5 is smoother.
TICKLAG 0.5
+2 -6
View File
@@ -1,11 +1,7 @@
### HEALTH ###
# level of health at which a mob becomes unconscious (crit)
HEALTH_THRESHOLD_CRIT 0
# level of health at which a mob becomes dead
HEALTH_THRESHOLD_DEAD -100
#Damage multiplier, effects both weapons and healing on all mobs. For example, 1.25 would result in 25% higher damage.
DAMAGE_MULTIPLIER 1
### REVIVAL ###
+53 -74
View File
@@ -55,6 +55,59 @@
-->
<div class="commit sansserif">
<h2 class="date">21 August 2016</h2>
<h3 class="author">Ergovisavi updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">Consolidates the fulton packs into a single item and makes them more user friendly</li>
</ul>
<h3 class="author">Google Play Store updated:</h3>
<ul class="changes bgimages16">
<li class="spellcheck">Minor Text Fixes.</li>
</ul>
<h3 class="author">Incoming5643 updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Smuggler satchels left behind hidden on the station can now reappear in a later round.</li>
<li class="experiment">There's absolutely no way of knowing when exactly it will reappear however...</li>
<li class="rscadd">Only one item in the satchel will remain when the satchel reappears.</li>
<li class="rscadd">Items are saved in their <b>initial</b> forms, so saving things like chemical grenades will only disappoint you.</li>
<li class="rscadd">The item pool is map specific and needs to be a certain size before satchels can start reappearing, so get to hiding that loot!</li>
<li class="rscadd">The staff of change has been expanded to turn you into even more things that don't have hands.</li>
</ul>
<h3 class="author">Jalleo updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Gulag Teleporter of two issues any more please report them.</li>
</ul>
<h3 class="author">Jordie0608 updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Advanced Energy Guns once again have a chance to irradiate you if EMPed.</li>
</ul>
<h3 class="author">Kor updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Kinetic Accelerators are now modular. You can find mod kits in the mining vendor and in RnD.</li>
<li class="bugfix">Chaplain's dormant spellblade is no longer invisible.</li>
</ul>
<h3 class="author">Papa Bones updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">A new, scandalous outfit is now available as contraband from the clothesmate vendor, check it out! Fulfill your deep, dark fantasies.</li>
</ul>
<h3 class="author">Shadowlight213 updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">Service and cargo have lost roundstart tablets and engineering has gained them</li>
<li class="tweak">you can now charge battery modules in cell chargers. Use a screwdriver on a computer to remove them. As a note, tablets and laptops can be charged directly by placing them in a security charger.</li>
</ul>
<h3 class="author">WJohnston updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Metastation and Boxstation now boast auxillary mining construction rooms in arrivals. These allow you to build a base and then launch it to wherever you want on lavaland.</li>
</ul>
<h3 class="author">Wjohnston, Gun Hog updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Aliens with Neurotoxic Spit readied will now have drooling animations.</li>
<li class="rscadd">Hunters may now safely leap over lava.</li>
<li class="tweak">Hulk punches no longer stun Xenos.</li>
<li class="tweak">Alien evolve and promotion buttons updated to current Xeno sprites</li>
<li class="bugfix">Handcuff sprites for Xenos now show properly.</li>
</ul>
<h2 class="date">17 August 2016</h2>
<h3 class="author">Basilman updated:</h3>
<ul class="changes bgimages16">
@@ -1141,80 +1194,6 @@
<li class="rscadd">For slime people the above mechanic also adds/drains slime jelly. So yes inhaling plasma is now a valid way to build jelly (but you'll still suffocate if there's no oxygen).</li>
<li class="rscadd">Pod people now mutate if shot with the mutation setting of the floral somatoray.</li>
</ul>
<h2 class="date">19 June 2016</h2>
<h3 class="author">Joan updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">Assassin holoparasite attack damage increased from 13 to 15, stealth cooldown decreased from 20 seconds to 16 seconds.</li>
<li class="tweak">Charger holoparasite charge cooldown decreased from 5 seconds to 4 seconds.</li>
<li class="tweak">Chaos holoparasite attack damage decreased from 10 to 7, range decreased from 10 to 7.</li>
<li class="tweak">Lightning holoparasite attack damage increased from 5 to 7, chain damage increased by 33%.</li>
<li class="rscdel">Clock cult scripture unlock now only counts humans and silicons.</li>
<li class="rscadd">Servants of ratvar can now create cogscarab shells with a Script scripture. Adding a soul vessel to one will produce a small, drone-like being with an inbuilt proselytizer and tools.</li>
<li class="imageadd">Clockwork mobs have their own speechbubble icons.</li>
<li class="tweak">Invoking Sevtug now causes massive hallucinations, brain damage, confusion, and dizziness for all non-servant humans on the same zlevel as the invoker.</li>
<li class="rscdel">Invoking Sevtug is no longer mind control. RIP mind control 2016-2016.</li>
<li class="tweak">Clockwork slabs now produce a component every 50 seconds, from 40, Tinkerer's Caches now produce(if near a clockwork wall) a component every 35 seconds, from 30.</li>
<li class="experiment">Tinkerer's daemons have a slightly higher cooldown for each component of the type they chose to produce that's already in the cache: This is very slight, but it'll add up if you have a lot of one component type and are trying to get more of it with daemons; 5 of a component type will add a second of delay.</li>
</ul>
<h3 class="author">Kor and Iamgoofball updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Miners can now purchase fulton extraction packs.</li>
<li class="rscadd">Miners can now purchase fulton medivac packs.</li>
<li class="rscadd">Two new fulton related bundles are available for purchase with vouchers.</li>
</ul>
<h3 class="author">Quiltyquilty updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Beepsky now has his own home in the labor shuttle room.</li>
</ul>
<h3 class="author">Wizard's Federation updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">We've fired the old Pope, who was actually an apprentice in disguise. We've a-pope-riately replaced him with a much more experienced magic user.</li>
<li class="rscadd">Some less-then-sane people have been sighted forming mysterious cults in lieu of recent Pope sightings, lashing out at anyone who speaks ill of him.</li>
<li class="bugfix">We've rejiggered our trans-dimensional rifts, and almost all cases of clergy members being flung into nothingness should be resolved.</li>
<li class="bugfix">All members of the Space Wizard's Clergy have been appropriately warned about usage of skin-to-stone spells, and such there should be no more instances of permanent statueification.</li>
</ul>
<h3 class="author">Xhuis updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">Revenants have been renamed to umbras and have undergone some tweaks.</li>
</ul>
<h3 class="author">coiax updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Drones can hear robotic talk, but cannot communicate on it. AIs and cyborgs are encouraged to share information with station repair drones.</li>
<li class="rscadd">Potted plants can now be ordered from cargo.</li>
<li class="rscdel">AI turrets no longer fire at drones.</li>
</ul>
<h2 class="date">16 June 2016</h2>
<h3 class="author">GunHog updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">In response to alarmingly high mining cyborg losses, Nanotrasen has equipped the units with an internal positioning beacon, as standard within the module.</li>
</ul>
<h3 class="author">Joan updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">You can now strike a Tinkerer's Cache with a Clockwork Proselytizer to refill the Proselytizer from the global component cache.</li>
<li class="tweak">The Clockwork Proselytizer requires slightly less alloy to convert windows and windoors.</li>
<li class="tweak">Several clockwork objects have more useful descriptions, most notably including structures, which will show a general health level to non-servants and exact health to servants.</li>
<li class="imageadd">The Clockwork Proselytizer has new, more appropriate inhands.</li>
<li class="tweak">Invoking Inath-Neq, the Resonant Cogwheel, now gives total invulnerability to all servants in range for 15 seconds instead of buffing maximum health.</li>
<li class="tweak">Impaling a target with a ratvarian spear no longer breaks the spear.</li>
<li class="tweak">Judicial Markers(the things spawned from Ratvar's Flame, in turn spawned from a Judicial Visor) explode one second faster.</li>
<li class="rscdel">Removed Dementia Doctrine, replacing it with an Application sigil.</li>
<li class="rscadd">Adds the Sigil of Accession, the previously-mentioned Application sigil, which is much like a Sigil of Submission, except it isn't removed on converting un-mindshielded targets and will disappear after converting a mindshielded target.</li>
<li class="tweak">Sigil of Submission is now a Script instead of a Driver; It's unlocked one tier up, so you have to rely on the Drivers you have until you get Scripts, instead of spamming both Driver sigils for free converts.</li>
<li class="rscadd">To replace Sigil of Submission in the Driver tier; Added Taunting Tirade, which is a chanted scripture with a very fast invocation, which, on chanting, confuses, dizzies, and briefly stuns nearby non-servants and allows the invoker a brief time to relocate before continuing the chant.</li>
<li class="rscadd">Ghosts can now see the Gateway to the Celestial Derelict's remaining time as a countdown.</li>
<li class="tweak">Anima Fragments are now slightly slower if not at maximum health and no longer drop a soul vessel when destroyed.</li>
</ul>
<h3 class="author">Quiltyquilty updated:</h3>
<ul class="changes bgimages16">
<li class="rscdel">Patches now hold only 40u.</li>
<li class="rscdel">Patches in first aid kits now only contain 20u of chemicals.</li>
</ul>
<h3 class="author">coiax updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Polymorphed mobs now have the same name, and where possible, the same equipment as their previous form.</li>
</ul>
</div>
<b>GoonStation 13 Development Team</b>
+45
View File
@@ -6680,3 +6680,48 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
key presses. Movements should now be ~25-50ms more responsive.
Shadowlight213:
- rscadd: Adds modular computers
2016-08-21:
Ergovisavi:
- tweak: Consolidates the fulton packs into a single item and makes them more user
friendly
Google Play Store:
- spellcheck: Minor Text Fixes.
Incoming5643:
- rscadd: Smuggler satchels left behind hidden on the station can now reappear in
a later round.
- experiment: There's absolutely no way of knowing when exactly it will reappear
however...
- rscadd: Only one item in the satchel will remain when the satchel reappears.
- rscadd: Items are saved in their <b>initial</b> forms, so saving things like chemical
grenades will only disappoint you.
- rscadd: The item pool is map specific and needs to be a certain size before satchels
can start reappearing, so get to hiding that loot!
- rscadd: The staff of change has been expanded to turn you into even more things
that don't have hands.
Jalleo:
- bugfix: Gulag Teleporter of two issues any more please report them.
Jordie0608:
- rscadd: Advanced Energy Guns once again have a chance to irradiate you if EMPed.
Kor:
- rscadd: Kinetic Accelerators are now modular. You can find mod kits in the mining
vendor and in RnD.
- bugfix: Chaplain's dormant spellblade is no longer invisible.
Papa Bones:
- rscadd: A new, scandalous outfit is now available as contraband from the clothesmate
vendor, check it out! Fulfill your deep, dark fantasies.
Shadowlight213:
- tweak: Service and cargo have lost roundstart tablets and engineering has gained
them
- tweak: you can now charge battery modules in cell chargers. Use a screwdriver
on a computer to remove them. As a note, tablets and laptops can be charged
directly by placing them in a security charger.
WJohnston:
- rscadd: Metastation and Boxstation now boast auxillary mining construction rooms
in arrivals. These allow you to build a base and then launch it to wherever
you want on lavaland.
Wjohnston, Gun Hog:
- rscadd: Aliens with Neurotoxic Spit readied will now have drooling animations.
- rscadd: Hunters may now safely leap over lava.
- tweak: Hulk punches no longer stun Xenos.
- tweak: Alien evolve and promotion buttons updated to current Xeno sprites
- bugfix: Handcuff sprites for Xenos now show properly.
@@ -1,4 +0,0 @@
author: "WJohnston"
delete-after: True
changes:
- rscadd: "Metastation and Boxstation now boast auxillary mining construction rooms in arrivals. These allow you to build a base and then launch it to wherever you want on lavaland."
@@ -1,4 +0,0 @@
author: "Jordie0608"
delete-after: True
changes:
- rscadd: "Advanced Energy Guns once again have a chance to irradiate you if EMPed."
@@ -1,8 +0,0 @@
author: "Wjohnston, Gun Hog"
delete-after: True
changes:
- rscadd: "Aliens with Neurotoxic Spit readied will now have drooling animations."
- rscadd: "Hunters may now safely leap over lava."
- tweak: "Hulk punches no longer stun Xenos."
- tweak: "Alien evolve and promotion buttons updated to current Xeno sprites"
- bugfix: "Handcuff sprites for Xenos now show properly."
@@ -1,4 +0,0 @@
author: "Incoming5643"
delete-after: True
changes:
- rscadd: "The staff of change has been expanded to turn you into even more things that don't have hands."
@@ -1,4 +0,0 @@
author: "Google Play Store"
delete-after: True
changes:
- spellcheck: "Minor Text Fixes."
@@ -1,5 +0,0 @@
author: "Shadowlight213"
delete-after: True
changes:
- tweak: "Service and cargo have lost roundstart tablets and engineering has gained them"
- tweak: "you can now charge battery modules in cell chargers. Use a screwdriver on a computer to remove them. As a note, tablets and laptops can be charged directly by placing them in a security charger."
@@ -1,4 +0,0 @@
author: "Papa Bones"
delete-after: True
changes:
- rscadd: "A new, scandalous outfit is now available as contraband from the clothesmate vendor, check it out! Fulfill your deep, dark fantasies."
@@ -1,4 +0,0 @@
author: "Kor"
delete-after: True
changes:
- rscadd: "Kinetic Accelerators are now modular. You can find mod kits in the mining vendor and in RnD."
@@ -1,4 +0,0 @@
author: "Ergovisavi"
delete-after: True
changes:
- tweak: "Consolidates the fulton packs into a single item and makes them more user friendly"
@@ -1,4 +0,0 @@
author: "Kor"
delete-after: True
changes:
- bugfix: "Chaplain's dormant spellblade is no longer invisible."
+1 -3
View File
@@ -152,6 +152,7 @@
#include "code\controllers\subsystem\npcpool.dm"
#include "code\controllers\subsystem\objects.dm"
#include "code\controllers\subsystem\pai.dm"
#include "code\controllers\subsystem\persistence.dm"
#include "code\controllers\subsystem\pool.dm"
#include "code\controllers\subsystem\radio.dm"
#include "code\controllers\subsystem\server_maintenance.dm"
@@ -378,8 +379,6 @@
#include "code\game\gamemodes\miniantags\abduction\machinery\pad.dm"
#include "code\game\gamemodes\miniantags\bot_swarm\swarmer.dm"
#include "code\game\gamemodes\miniantags\bot_swarm\swarmer_event.dm"
#include "code\game\gamemodes\miniantags\hades\hades.dm"
#include "code\game\gamemodes\miniantags\hades\hades_chapel.dm"
#include "code\game\gamemodes\miniantags\monkey\monkey.dm"
#include "code\game\gamemodes\miniantags\morph\morph.dm"
#include "code\game\gamemodes\miniantags\revenant\revenant.dm"
@@ -840,7 +839,6 @@
#include "code\modules\admin\admin_memo.dm"
#include "code\modules\admin\admin_ranks.dm"
#include "code\modules\admin\admin_verbs.dm"
#include "code\modules\admin\banappearance.dm"
#include "code\modules\admin\banjob.dm"
#include "code\modules\admin\create_mob.dm"
#include "code\modules\admin\create_object.dm"