Conflict resolution and adds sanitization to marking SQL handling.
@@ -107,3 +107,7 @@
|
||||
#define GENE_INSTABILITY_MINOR 5
|
||||
#define GENE_INSTABILITY_MODERATE 10
|
||||
#define GENE_INSTABILITY_MAJOR 15
|
||||
|
||||
#define GENETIC_DAMAGE_STAGE_1 80
|
||||
#define GENETIC_DAMAGE_STAGE_2 65
|
||||
#define GENETIC_DAMAGE_STAGE_3 35
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
#define CLICK_CD_POINT 10
|
||||
#define CLICK_CD_RESIST 20
|
||||
|
||||
//Sizes of mobs, used by mob/living/var/mob_size
|
||||
#define MOB_SIZE_TINY 0
|
||||
#define MOB_SIZE_SMALL 1
|
||||
#define MOB_SIZE_HUMAN 2
|
||||
#define MOB_SIZE_LARGE 3
|
||||
///
|
||||
#define ROUNDSTART_LOGOUT_REPORT_TIME 6000 //Amount of time (in deciseconds) after the rounds starts, that the player disconnect report is issued.
|
||||
|
||||
@@ -160,6 +165,12 @@
|
||||
|
||||
#define MAX_STACK_SIZE 50
|
||||
|
||||
//check_target_facings() return defines
|
||||
#define FACING_FAILED 0
|
||||
#define FACING_SAME_DIR 1
|
||||
#define FACING_EACHOTHER 2
|
||||
#define FACING_INIT_FACING_TARGET_TARGET_FACING_PERPENDICULAR 3 //Do I win the most informative but also most stupid define award?
|
||||
|
||||
//unmagic-strings for types of polls
|
||||
#define POLLTYPE_OPTION "OPTION"
|
||||
#define POLLTYPE_TEXT "TEXT"
|
||||
|
||||
@@ -50,18 +50,3 @@
|
||||
HSL[3] = min(HSL[3],0.4)
|
||||
var/list/RGB = hsl2rgb(arglist(HSL))
|
||||
return "#[num2hex(RGB[1],2)][num2hex(RGB[2],2)][num2hex(RGB[3],2)]"
|
||||
|
||||
|
||||
// Sanitize inputs to avoid SQL injection attacks
|
||||
/proc/sql_sanitize_text(var/text)
|
||||
text = replacetext(text, "'", "''")
|
||||
text = replacetext(text, ";", "")
|
||||
text = replacetext(text, "&", "")
|
||||
return text
|
||||
|
||||
// Calls the above proc on each entry of a list to ensure its entries are clean
|
||||
/proc/sql_sanitize_text_list(var/list/l)
|
||||
var/list/new_list = l.Copy()
|
||||
for(var/text in new_list)
|
||||
sql_sanitize_text(text)
|
||||
return new_list
|
||||
@@ -15,6 +15,10 @@
|
||||
|
||||
// Run all strings to be used in an SQL query through this proc first to properly escape out injection attempts.
|
||||
/proc/sanitizeSQL(var/t as text)
|
||||
if(isnull(t))
|
||||
return null
|
||||
if(!istext(t))
|
||||
t = "[t]" // Just quietly assume any non-texts are supposed to be text
|
||||
var/sqltext = dbcon.Quote(t);
|
||||
return copytext(sqltext, 2, lentext(sqltext));//Quote() adds quotes around input, we already do that
|
||||
|
||||
|
||||
@@ -1355,20 +1355,19 @@ Standard way to write links -Sayu
|
||||
|
||||
return 1
|
||||
|
||||
proc/check_target_facings(mob/living/initator, mob/living/target)
|
||||
/proc/check_target_facings(mob/living/initator, mob/living/target)
|
||||
/*This can be used to add additional effects on interactions between mobs depending on how the mobs are facing each other, such as adding a crit damage to blows to the back of a guy's head.
|
||||
Given how click code currently works (Nov '13), the initiating mob will be facing the target mob most of the time
|
||||
That said, this proc should not be used if the change facing proc of the click code is overriden at the same time*/
|
||||
if(!!isliving(target) || target.lying || istype(target, /mob/living/silicon/pai))
|
||||
if(!ismob(target) || target.lying)
|
||||
//Make sure we are not doing this for things that can't have a logical direction to the players given that the target would be on their side
|
||||
return
|
||||
|
||||
return FACING_FAILED
|
||||
if(initator.dir == target.dir) //mobs are facing the same direction
|
||||
return 1
|
||||
if(initator.dir + 4 == target.dir || initator.dir - 4 == target.dir) //mobs are facing each other
|
||||
return 2
|
||||
return FACING_SAME_DIR
|
||||
if(is_A_facing_B(initator, target) && is_A_facing_B(target, initator)) //mobs are facing each other
|
||||
return FACING_EACHOTHER
|
||||
if(initator.dir + 2 == target.dir || initator.dir - 2 == target.dir || initator.dir + 6 == target.dir || initator.dir - 6 == target.dir) //Initating mob is looking at the target, while the target mob is looking in a direction perpendicular to the 1st
|
||||
return 3
|
||||
return FACING_INIT_FACING_TARGET_TARGET_FACING_PERPENDICULAR
|
||||
|
||||
|
||||
atom/proc/GetTypeInAllContents(typepath)
|
||||
@@ -1472,6 +1471,36 @@ var/mob/dview/dview_mob = new
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
//Get the dir to the RIGHT of dir if they were on a clock
|
||||
//NORTH --> NORTHEAST
|
||||
/proc/get_clockwise_dir(dir)
|
||||
. = angle2dir(dir2angle(dir)+45)
|
||||
|
||||
//Get the dir to the LEFT of dir if they were on a clock
|
||||
//NORTH --> NORTHWEST
|
||||
/proc/get_anticlockwise_dir(dir)
|
||||
. = angle2dir(dir2angle(dir)-45)
|
||||
|
||||
|
||||
//Compare A's dir, the clockwise dir of A and the anticlockwise dir of A
|
||||
//To the opposite dir of the dir returned by get_dir(B,A)
|
||||
//If one of them is a match, then A is facing B
|
||||
/proc/is_A_facing_B(atom/A, atom/B)
|
||||
if(!istype(A) || !istype(B))
|
||||
return 0
|
||||
if(isliving(A))
|
||||
var/mob/living/LA = A
|
||||
if(LA.lying)
|
||||
return 0
|
||||
var/goal_dir = angle2dir(dir2angle(get_dir(B, A)+180))
|
||||
var/clockwise_A_dir = get_clockwise_dir(A.dir)
|
||||
var/anticlockwise_A_dir = get_anticlockwise_dir(B.dir)
|
||||
|
||||
if(A.dir == goal_dir || clockwise_A_dir == goal_dir || anticlockwise_A_dir == goal_dir)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//This is just so you can stop an orbit.
|
||||
//orbit() can run without it (swap orbiting for A)
|
||||
//but then you can never stop it and that's just silly.
|
||||
|
||||
@@ -1644,9 +1644,4 @@
|
||||
/mob/living/simple_animal/construct/armoured/mind_initialize()
|
||||
..()
|
||||
mind.assigned_role = "Juggernaut"
|
||||
mind.special_role = SPECIAL_ROLE_CULTIST
|
||||
|
||||
/mob/living/simple_animal/vox/armalis/mind_initialize()
|
||||
..()
|
||||
mind.assigned_role = "Armalis"
|
||||
mind.special_role = SPECIAL_ROLE_RAIDER
|
||||
mind.special_role = SPECIAL_ROLE_CULTIST
|
||||
@@ -100,7 +100,7 @@
|
||||
var/mutation=0
|
||||
|
||||
// Activation probability
|
||||
var/activation_prob=45
|
||||
var/activation_prob=100
|
||||
|
||||
// Possible activation messages
|
||||
var/list/activation_messages=list()
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
desc = "Enables the subject to bend low levels of light around themselves, creating a cloaking effect."
|
||||
activation_messages = list("You begin to fade into the shadows.")
|
||||
deactivation_messages = list("You become fully visible.")
|
||||
activation_prob=10
|
||||
activation_prob=25
|
||||
mutation = CLOAK
|
||||
|
||||
/datum/dna/gene/basic/stealth/darkcloak/New()
|
||||
@@ -74,7 +74,7 @@
|
||||
desc = "The subject becomes able to subtly alter light patterns to become invisible, as long as they remain still."
|
||||
activation_messages = list("You feel one with your surroundings.")
|
||||
deactivation_messages = list("You feel oddly visible.")
|
||||
activation_prob=10
|
||||
activation_prob=25
|
||||
mutation = CHAMELEON
|
||||
|
||||
/datum/dna/gene/basic/stealth/chameleon/New()
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
deactivation_messages=list("You feel the need to breathe, once more.")
|
||||
instability = GENE_INSTABILITY_MODERATE
|
||||
mutation=NO_BREATH
|
||||
activation_prob=10
|
||||
activation_prob=25
|
||||
|
||||
/datum/dna/gene/basic/nobreath/New()
|
||||
block=NOBREATHBLOCK
|
||||
@@ -116,7 +116,7 @@
|
||||
deactivation_messages=list("Your muscles shrink.")
|
||||
instability = GENE_INSTABILITY_MAJOR
|
||||
mutation=HULK
|
||||
activation_prob=5
|
||||
activation_prob=15
|
||||
|
||||
/datum/dna/gene/basic/hulk/New()
|
||||
block=HULKBLOCK
|
||||
@@ -156,7 +156,7 @@
|
||||
deactivation_messages=list("the walls around you re-appear.")
|
||||
instability = GENE_INSTABILITY_MAJOR
|
||||
mutation=XRAY
|
||||
activation_prob=10
|
||||
activation_prob=15
|
||||
|
||||
/datum/dna/gene/basic/xray/New()
|
||||
block=XRAYBLOCK
|
||||
@@ -167,7 +167,7 @@
|
||||
deactivation_messages = list("You feel dumber.")
|
||||
instability = GENE_INSTABILITY_MAJOR
|
||||
mutation=TK
|
||||
activation_prob=10
|
||||
activation_prob=15
|
||||
|
||||
/datum/dna/gene/basic/tk/New()
|
||||
block=TELEBLOCK
|
||||
|
||||
@@ -160,6 +160,7 @@
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 360
|
||||
force_threshold = 10
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
environment_smash = 3
|
||||
gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
attacktext = "nips"
|
||||
friendly = "prods"
|
||||
wander = 0
|
||||
small = 1
|
||||
mob_size = MOB_SIZE_TINY
|
||||
density = 0
|
||||
pass_flags = PASSTABLE
|
||||
ventcrawler = 2
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
faction = list("swarmer")
|
||||
projectiletype = /obj/item/projectile/beam/disabler
|
||||
pass_flags = PASSTABLE
|
||||
mob_size = MOB_SIZE_TINY
|
||||
ventcrawler = 2
|
||||
ranged = 1
|
||||
ranged_cooldown_cap = 1
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
density = 0
|
||||
flying = 1
|
||||
anchored = 1
|
||||
mob_size = MOB_SIZE_TINY
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
|
||||
var/essence = 75 //The resource of revenants. Max health is equal to three times this amount
|
||||
|
||||
@@ -62,11 +62,11 @@
|
||||
|
||||
/obj/machinery/door/Bumped(atom/AM)
|
||||
if(p_open || operating) return
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
if(world.time - M.last_bumped <= 10) return //Can bump-open one airlock per second. This is to prevent shock spam.
|
||||
M.last_bumped = world.time
|
||||
if(!M.restrained() && !M.small)
|
||||
if(!M.restrained() && M.mob_size > MOB_SIZE_SMALL)
|
||||
bumpopen(M)
|
||||
return
|
||||
|
||||
|
||||
@@ -52,8 +52,8 @@
|
||||
return
|
||||
if(!ticker)
|
||||
return
|
||||
var/mob/M = AM
|
||||
if(!M.restrained() && !M.small)
|
||||
var/mob/living/M = AM
|
||||
if(!M.restrained() && M.mob_size > MOB_SIZE_SMALL)
|
||||
bumpopen(M)
|
||||
return
|
||||
|
||||
|
||||
@@ -64,6 +64,13 @@
|
||||
duration = 8
|
||||
randomdir = 0
|
||||
|
||||
/obj/effect/overlay/temp/kinetic_blast
|
||||
name = "kinetic explosion"
|
||||
icon = 'icons/obj/projectiles.dmi'
|
||||
icon_state = "kinetic_blast"
|
||||
layer = 4.1
|
||||
duration = 4
|
||||
|
||||
/obj/effect/overlay/palmtree_r
|
||||
name = "Palm tree"
|
||||
icon = 'icons/misc/beach2.dmi'
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
attack_verb = list("attacked", "coloured")
|
||||
var/colour = "#FF0000" //RGB
|
||||
var/drawtype = "rune"
|
||||
var/list/graffiti = list("body","amyjon","face","matt","revolution","engie","guy","end","dwarf","uboa","up","down","left","right","heart","borgsrogue","voxpox","shitcurity","catbeast","hieroglyphs1","hieroglyphs2","hieroglyphs3","security","syndicate1","syndicate2","nanotrasen","lie","valid")
|
||||
var/list/graffiti = list("body","amyjon","face","matt","revolution","engie","guy","end","dwarf","uboa","up","down","left","right","heart","borgsrogue","voxpox","shitcurity","catbeast","hieroglyphs1","hieroglyphs2","hieroglyphs3","security","syndicate1","syndicate2","nanotrasen","lie","valid","arrowleft","arrowright","arrowup","arrowdown","chicken","hailcrab","brokenheart","peace","scribble","scribble2","scribble3","skrek","squish","tunnelsnake","yip","youaredead")
|
||||
var/list/letters = list("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")
|
||||
var/uses = 30 //0 for unlimited uses
|
||||
var/instant = 0
|
||||
@@ -92,19 +92,19 @@
|
||||
if(uses)
|
||||
uses--
|
||||
if(!uses)
|
||||
to_chat(user, "<span class='danger'>You used up your [src.name]!</span>")
|
||||
to_chat(user, "<span class='danger'>You used up your [name]!</span>")
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/toy/crayon/attack(mob/M as mob, mob/user as mob)
|
||||
var/huffable = istype(src,/obj/item/toy/crayon/spraycan)
|
||||
if(M == user)
|
||||
to_chat(user, "You take a [huffable ? "huff" : "bite"] of the [src.name]. Delicious!")
|
||||
to_chat(user, "You take a [huffable ? "huff" : "bite"] of the [name]. Delicious!")
|
||||
user.nutrition += 5
|
||||
if(uses)
|
||||
uses -= 5
|
||||
if(uses <= 0)
|
||||
to_chat(user, "<span class='danger'>There is no more of [src.name] left!</span>")
|
||||
to_chat(user, "<span class='danger'>There is no more of [name] left!</span>")
|
||||
qdel(src)
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -241,12 +241,20 @@
|
||||
if(!(S.status & ORGAN_ROBOT) || user.a_intent != I_HELP || S.open == 2)
|
||||
return ..()
|
||||
|
||||
if(!isOn()) //why wasn't this being checked already?
|
||||
to_chat(user, "<span class='warning'>Turn on [src] before attempting repairs!</span>")
|
||||
return 1
|
||||
|
||||
if(S.brute_dam)
|
||||
if(S.brute_dam < ROBOLIMB_SELF_REPAIR_CAP)
|
||||
if(remove_fuel(0,null))
|
||||
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
|
||||
S.heal_damage(15,0,0,1)
|
||||
user.visible_message("<span class='alert'>\The [user] patches some dents on \the [M]'s [S.name] with \the [src].</span>")
|
||||
if(get_fuel() >= 1)
|
||||
if(H == user)
|
||||
if(!do_mob(user, H, 10))
|
||||
return 1
|
||||
if(remove_fuel(1,null))
|
||||
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
|
||||
S.heal_damage(15,0,0,1)
|
||||
user.visible_message("<span class='alert'>\The [user] patches some dents on \the [M]'s [S.name] with \the [src].</span>")
|
||||
else if(S.open != 2)
|
||||
to_chat(user, "<span class='warning'>Need more welding fuel!</span>")
|
||||
return 1
|
||||
|
||||
@@ -82,13 +82,6 @@
|
||||
user.put_in_inactive_hand(O)
|
||||
return
|
||||
|
||||
/obj/item/weapon/twohanded/mob_can_equip(mob/M, slot)
|
||||
//Cannot equip wielded items.
|
||||
if(wielded)
|
||||
to_chat(M, "<span class='warning'>Unwield the [name] first!</span>")
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/twohanded/dropped(mob/user)
|
||||
..()
|
||||
//handles unwielding a twohanded weapon when dropped as well as clearing up the offhand
|
||||
@@ -108,6 +101,12 @@
|
||||
else //Trying to wield it
|
||||
wield(user)
|
||||
|
||||
|
||||
/obj/item/weapon/twohanded/equip_to_best_slot(mob/M)
|
||||
if(..())
|
||||
unwield(M)
|
||||
return
|
||||
|
||||
///////////OFFHAND///////////////
|
||||
/obj/item/weapon/twohanded/offhand
|
||||
w_class = 5
|
||||
@@ -130,8 +129,8 @@
|
||||
return
|
||||
|
||||
/obj/item/weapon/twohanded/required/mob_can_equip(M as mob, slot)
|
||||
if(wielded)
|
||||
to_chat(M, "<span class='warning'>[src.name] is too cumbersome to carry with anything but your hands!</span>")
|
||||
if(wielded && !slot_flags)
|
||||
to_chat(M, "<span class='warning'>[src] is too cumbersome to carry with anything but your hands!</span>")
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
@@ -140,12 +139,18 @@
|
||||
if(get_dist(src,user) > 1)
|
||||
return 0
|
||||
if(H != null)
|
||||
to_chat(user, "<span class='notice'>[src.name] is too cumbersome to carry in one hand!</span>")
|
||||
to_chat(user, "<span class='notice'>[src] is too cumbersome to carry in one hand!</span>")
|
||||
return
|
||||
var/obj/item/weapon/twohanded/offhand/O = new(user)
|
||||
user.put_in_inactive_hand(O)
|
||||
if(loc != user)
|
||||
wield(user)
|
||||
..()
|
||||
wielded = 1
|
||||
|
||||
/obj/item/weapon/twohanded/required/equipped(mob/user, slot)
|
||||
..()
|
||||
if(slot == slot_l_hand || slot == slot_r_hand)
|
||||
wield(user)
|
||||
else
|
||||
unwield(user)
|
||||
|
||||
/*
|
||||
* Fireaxe
|
||||
|
||||
@@ -113,7 +113,7 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration =
|
||||
else
|
||||
adminwho += ", [C]"
|
||||
|
||||
reason = sql_sanitize_text(reason)
|
||||
reason = sanitizeSQL(reason)
|
||||
|
||||
if(maxadminbancheck)
|
||||
var/DBQuery/adm_query = dbcon.NewQuery("SELECT count(id) AS num FROM [format_table_name("ban")] WHERE (a_ckey = '[a_ckey]') AND (bantype = 'ADMIN_PERMABAN' OR (bantype = 'ADMIN_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
|
||||
@@ -244,14 +244,14 @@ datum/admins/proc/DB_ban_edit(var/banid = null, var/param = null)
|
||||
to_chat(usr, "Invalid ban id. Contact the database admin")
|
||||
return
|
||||
|
||||
reason = sql_sanitize_text(reason)
|
||||
reason = sanitizeSQL(reason)
|
||||
var/value
|
||||
|
||||
switch(param)
|
||||
if("reason")
|
||||
if(!value)
|
||||
value = input("Insert the new reason for [pckey]'s ban", "New Reason", "[reason]", null) as null|text
|
||||
value = sql_sanitize_text(value)
|
||||
value = sanitizeSQL(value)
|
||||
if(!value)
|
||||
to_chat(usr, "Cancelled")
|
||||
return
|
||||
@@ -417,8 +417,8 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
|
||||
|
||||
adminckey = ckey(adminckey)
|
||||
playerckey = ckey(playerckey)
|
||||
playerip = sql_sanitize_text(playerip)
|
||||
playercid = sql_sanitize_text(playercid)
|
||||
playerip = sanitizeSQL(playerip)
|
||||
playercid = sanitizeSQL(playercid)
|
||||
|
||||
if(adminckey || playerckey || playerip || playercid || dbbantype)
|
||||
|
||||
|
||||
@@ -92,18 +92,3 @@ DEBUG
|
||||
appearance_savebanfile()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/*
|
||||
proc/DB_ban_isappearancebanned(var/playerckey)
|
||||
establish_db_connection()
|
||||
if(!dbcon.IsConnected())
|
||||
return
|
||||
|
||||
var/sqlplayerckey = sql_sanitize_text(ckey(playerckey))
|
||||
|
||||
var/DBQuery/query = dbcon.NewQuery("SELECT id FROM [format_table_name("ban")] WHERE CKEY = '[sqlplayerckey]' AND ((bantype = 'APPEARANCE_BAN') OR (bantype = 'APPEARANCE_TEMPBAN' AND expiration_time > Now())) AND unbanned != 1")
|
||||
query.Execute()
|
||||
while(query.NextRow())
|
||||
return 1
|
||||
return 0
|
||||
*/
|
||||
@@ -368,9 +368,7 @@
|
||||
if(!dbcon.IsConnected())
|
||||
return
|
||||
|
||||
var/sql_ckey = sql_sanitize_text(src.ckey)
|
||||
|
||||
var/DBQuery/query = dbcon.NewQuery("SELECT id, datediff(Now(),firstseen) as age FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'")
|
||||
var/DBQuery/query = dbcon.NewQuery("SELECT id, datediff(Now(),firstseen) as age FROM [format_table_name("player")] WHERE ckey = '[ckey]'")
|
||||
query.Execute()
|
||||
var/sql_id = 0
|
||||
player_age = 0 // New players won't have an entry so knowing we have a connection we set this to zero to be updated if their is a record.
|
||||
@@ -397,7 +395,7 @@
|
||||
if(related_accounts_cid.len)
|
||||
log_access("Alts: [key_name(src)]:[jointext(related_accounts_cid, " - ")]")
|
||||
|
||||
var/watchreason = check_watchlist(sql_ckey)
|
||||
var/watchreason = check_watchlist(ckey)
|
||||
if(watchreason)
|
||||
message_admins("<font color='red'><B>Notice: </B></font><font color='blue'>[key_name_admin(src)] is on the watchlist and has just connected - Reason: [watchreason]</font>")
|
||||
send2adminirc("Watchlist - [key_name(src)] is on the watchlist and has just connected - Reason: [watchreason]")
|
||||
@@ -413,9 +411,9 @@
|
||||
if(src.holder)
|
||||
admin_rank = src.holder.rank
|
||||
|
||||
var/sql_ip = sql_sanitize_text(src.address)
|
||||
var/sql_computerid = sql_sanitize_text(src.computer_id)
|
||||
var/sql_admin_rank = sql_sanitize_text(admin_rank)
|
||||
var/sql_ip = sanitizeSQL(address)
|
||||
var/sql_computerid = sanitizeSQL(computer_id)
|
||||
var/sql_admin_rank = sanitizeSQL(admin_rank)
|
||||
|
||||
|
||||
if(sql_id)
|
||||
@@ -424,12 +422,12 @@
|
||||
query_update.Execute()
|
||||
else
|
||||
//New player!! Need to insert all the stuff
|
||||
var/DBQuery/query_insert = dbcon.NewQuery("INSERT INTO [format_table_name("player")] (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank) VALUES (null, '[sql_ckey]', Now(), Now(), '[sql_ip]', '[sql_computerid]', '[sql_admin_rank]')")
|
||||
var/DBQuery/query_insert = dbcon.NewQuery("INSERT INTO [format_table_name("player")] (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank) VALUES (null, '[ckey]', Now(), Now(), '[sql_ip]', '[sql_computerid]', '[sql_admin_rank]')")
|
||||
query_insert.Execute()
|
||||
|
||||
//Logging player access
|
||||
var/serverip = "[world.internet_address]:[world.port]"
|
||||
var/DBQuery/query_accesslog = dbcon.NewQuery("INSERT INTO `[format_table_name("connection_log")]`(`id`,`datetime`,`serverip`,`ckey`,`ip`,`computerid`) VALUES(null,Now(),'[serverip]','[sql_ckey]','[sql_ip]','[sql_computerid]');")
|
||||
var/DBQuery/query_accesslog = dbcon.NewQuery("INSERT INTO `[format_table_name("connection_log")]`(`id`,`datetime`,`serverip`,`ckey`,`ip`,`computerid`) VALUES(null,Now(),'[serverip]','[ckey]','[sql_ip]','[sql_computerid]');")
|
||||
query_accesslog.Execute()
|
||||
|
||||
|
||||
|
||||
@@ -1890,12 +1890,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
|
||||
if("be_special")
|
||||
var/r = href_list["role"]
|
||||
if(!(r in special_roles))
|
||||
var/cleaned_r = sql_sanitize_text(r)
|
||||
if(r != cleaned_r) // up to no good
|
||||
message_admins("[user] attempted an href exploit! (This could have possibly lead to a \"Bobby Tables\" exploit, so they're probably up to no good). String: [r] ID: [last_id] IP: [last_ip]")
|
||||
to_chat(user, "<span class='userdanger'>Stop right there, criminal scum</span>")
|
||||
else
|
||||
if(r in special_roles)
|
||||
be_special ^= r
|
||||
|
||||
if("name")
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
UI_style='[UI_style]',
|
||||
UI_style_color='[UI_style_color]',
|
||||
UI_style_alpha='[UI_style_alpha]',
|
||||
be_role='[list2params(sql_sanitize_text_list(be_special))]',
|
||||
be_role='[sanitizeSQL(list2params(be_special))]',
|
||||
default_slot='[default_slot]',
|
||||
toggles='[toggles]',
|
||||
sound='[sound]',
|
||||
@@ -237,6 +237,15 @@
|
||||
med_record = query.item[54]
|
||||
sec_record = query.item[55]
|
||||
gen_record = query.item[56]
|
||||
// Apparently, the preceding vars weren't always encoded properly...
|
||||
if(findtext(flavor_text, "<")) // ... so let's clumsily check for tags!
|
||||
flavor_text = html_encode(flavor_text)
|
||||
if(findtext(med_record, "<"))
|
||||
med_record = html_encode(med_record)
|
||||
if(findtext(sec_record, "<"))
|
||||
sec_record = html_encode(sec_record)
|
||||
if(findtext(gen_record, "<"))
|
||||
gen_record = html_encode(gen_record)
|
||||
disabilities = text2num(query.item[57])
|
||||
player_alt_titles = params2list(query.item[58])
|
||||
organ_data = params2list(query.item[59])
|
||||
@@ -276,11 +285,15 @@
|
||||
r_skin = sanitize_integer(r_skin, 0, 255, initial(r_skin))
|
||||
g_skin = sanitize_integer(g_skin, 0, 255, initial(g_skin))
|
||||
b_skin = sanitize_integer(b_skin, 0, 255, initial(b_skin))
|
||||
for(var/marking_location in m_colours)
|
||||
m_colours[marking_location] = sanitize_hexcolor(m_colours[marking_location], DEFAULT_MARKING_COLOURS[marking_location])
|
||||
r_headacc = sanitize_integer(r_headacc, 0, 255, initial(r_headacc))
|
||||
g_headacc = sanitize_integer(g_headacc, 0, 255, initial(g_headacc))
|
||||
b_headacc = sanitize_integer(b_headacc, 0, 255, initial(b_headacc))
|
||||
h_style = sanitize_inlist(h_style, hair_styles_list, initial(h_style))
|
||||
f_style = sanitize_inlist(f_style, facial_hair_styles_list, initial(f_style))
|
||||
for(var/marking_location in m_styles)
|
||||
m_styles[marking_location] = sanitize_inlist(m_styles[marking_location], marking_styles_list, DEFAULT_MARKING_STYLES[marking_location])
|
||||
ha_style = sanitize_inlist(ha_style, head_accessory_styles_list, initial(ha_style))
|
||||
alt_head = sanitize_inlist(alt_head, alt_heads_list, initial(alt_head))
|
||||
r_eyes = sanitize_integer(r_eyes, 0, 255, initial(r_eyes))
|
||||
@@ -313,8 +326,6 @@
|
||||
if(!player_alt_titles) player_alt_titles = new()
|
||||
if(!organ_data) src.organ_data = list()
|
||||
if(!rlimb_data) src.rlimb_data = list()
|
||||
if(!m_colours) m_colours = DEFAULT_MARKING_COLOURS
|
||||
if(!m_styles) m_styles = DEFAULT_MARKING_STYLES
|
||||
if(!gear) gear = list()
|
||||
|
||||
return 1
|
||||
@@ -324,6 +335,7 @@
|
||||
var/rlimblist
|
||||
var/playertitlelist
|
||||
var/gearlist
|
||||
|
||||
var/markingcolourslist = list2params(m_colours)
|
||||
var/markingstyleslist = list2params(m_styles)
|
||||
if(!isemptylist(organ_data))
|
||||
@@ -339,13 +351,13 @@
|
||||
firstquery.Execute()
|
||||
while(firstquery.NextRow())
|
||||
if(text2num(firstquery.item[1]) == default_slot)
|
||||
var/DBQuery/query = dbcon.NewQuery({"UPDATE [format_table_name("characters")] SET OOC_Notes='[sql_sanitize_text(metadata)]',
|
||||
real_name='[sql_sanitize_text(real_name)]',
|
||||
var/DBQuery/query = dbcon.NewQuery({"UPDATE [format_table_name("characters")] SET OOC_Notes='[sanitizeSQL(metadata)]',
|
||||
real_name='[sanitizeSQL(real_name)]',
|
||||
name_is_always_random='[be_random_name]',
|
||||
gender='[gender]',
|
||||
age='[age]',
|
||||
species='[sql_sanitize_text(species)]',
|
||||
language='[sql_sanitize_text(language)]',
|
||||
species='[sanitizeSQL(species)]',
|
||||
language='[sanitizeSQL(language)]',
|
||||
hair_red='[r_hair]',
|
||||
hair_green='[g_hair]',
|
||||
hair_blue='[b_hair]',
|
||||
@@ -362,15 +374,15 @@
|
||||
skin_red='[r_skin]',
|
||||
skin_green='[g_skin]',
|
||||
skin_blue='[b_skin]',
|
||||
marking_colours='[markingcolourslist]',
|
||||
marking_colours='[sanitizeSQL(markingcolourslist)]',
|
||||
head_accessory_red='[r_headacc]',
|
||||
head_accessory_green='[g_headacc]',
|
||||
head_accessory_blue='[b_headacc]',
|
||||
hair_style_name='[sql_sanitize_text(h_style)]',
|
||||
facial_style_name='[sql_sanitize_text(f_style)]',
|
||||
marking_styles='[markingstyleslist]',
|
||||
head_accessory_style_name='[sql_sanitize_text(ha_style)]',
|
||||
alt_head_name='[sql_sanitize_text(alt_head)]',
|
||||
hair_style_name='[sanitizeSQL(h_style)]',
|
||||
facial_style_name='[sanitizeSQL(f_style)]',
|
||||
marking_styles='[sanitizeSQL(markingstyleslist)]',
|
||||
head_accessory_style_name='[sanitizeSQL(ha_style)]',
|
||||
alt_head_name='[sanitizeSQL(alt_head)]',
|
||||
eyes_red='[r_eyes]',
|
||||
eyes_green='[g_eyes]',
|
||||
eyes_blue='[b_eyes]',
|
||||
@@ -391,10 +403,10 @@
|
||||
job_karma_high='[job_karma_high]',
|
||||
job_karma_med='[job_karma_med]',
|
||||
job_karma_low='[job_karma_low]',
|
||||
flavor_text='[sql_sanitize_text(html_decode(flavor_text))]',
|
||||
med_record='[sql_sanitize_text(html_decode(med_record))]',
|
||||
sec_record='[sql_sanitize_text(html_decode(sec_record))]',
|
||||
gen_record='[sql_sanitize_text(html_decode(gen_record))]',
|
||||
flavor_text='[sanitizeSQL(flavor_text)]',
|
||||
med_record='[sanitizeSQL(med_record)]',
|
||||
sec_record='[sanitizeSQL(sec_record)]',
|
||||
gen_record='[sanitizeSQL(gen_record)]',
|
||||
player_alt_titles='[playertitlelist]',
|
||||
disabilities='[disabilities]',
|
||||
organ_data='[organlist]',
|
||||
@@ -425,7 +437,11 @@
|
||||
skin_tone, skin_red, skin_green, skin_blue,
|
||||
marking_colours,
|
||||
head_accessory_red, head_accessory_green, head_accessory_blue,
|
||||
hair_style_name, facial_style_name, marking_styles, head_accessory_style_name, alt_head_name,
|
||||
hair_style_name,
|
||||
facial_style_name,
|
||||
marking_styles,
|
||||
head_accessory_style_name,
|
||||
alt_head_name,
|
||||
eyes_red, eyes_green, eyes_blue,
|
||||
underwear, undershirt,
|
||||
backbag, b_type, alternate_option,
|
||||
@@ -433,22 +449,29 @@
|
||||
job_medsci_high, job_medsci_med, job_medsci_low,
|
||||
job_engsec_high, job_engsec_med, job_engsec_low,
|
||||
job_karma_high, job_karma_med, job_karma_low,
|
||||
flavor_text, med_record, sec_record, gen_record,
|
||||
flavor_text,
|
||||
med_record,
|
||||
sec_record,
|
||||
gen_record,
|
||||
player_alt_titles,
|
||||
disabilities, organ_data, rlimb_data, nanotrasen_relation, speciesprefs,
|
||||
socks, body_accessory, gear)
|
||||
|
||||
VALUES
|
||||
('[C.ckey]', '[default_slot]', '[sql_sanitize_text(metadata)]', '[sql_sanitize_text(real_name)]', '[be_random_name]','[gender]',
|
||||
'[age]', '[sql_sanitize_text(species)]', '[sql_sanitize_text(language)]',
|
||||
('[C.ckey]', '[default_slot]', '[sanitizeSQL(metadata)]', '[sanitizeSQL(real_name)]', '[be_random_name]','[gender]',
|
||||
'[age]', '[sanitizeSQL(species)]', '[sanitizeSQL(language)]',
|
||||
'[r_hair]', '[g_hair]', '[b_hair]',
|
||||
'[r_hair_sec]', '[g_hair_sec]', '[b_hair_sec]',
|
||||
'[r_facial]', '[g_facial]', '[b_facial]',
|
||||
'[r_facial_sec]', '[g_facial_sec]', '[b_facial_sec]',
|
||||
'[s_tone]', '[r_skin]', '[g_skin]', '[b_skin]',
|
||||
'[markingcolourslist]',
|
||||
'[sanitizeSQL(markingcolourslist)]',
|
||||
'[r_headacc]', '[g_headacc]', '[b_headacc]',
|
||||
'[sql_sanitize_text(h_style)]', '[sql_sanitize_text(f_style)]', '[markingstyleslist]', '[sql_sanitize_text(ha_style)]', '[sql_sanitize_text(alt_head)]',
|
||||
'[sanitizeSQL(h_style)]',
|
||||
'[sanitizeSQL(f_style)]',
|
||||
'[sanitizeSQL(markingstyleslist)]',
|
||||
'[sanitizeSQL(ha_style)]',
|
||||
'[sanitizeSQL(alt_head)]',
|
||||
'[r_eyes]', '[g_eyes]', '[b_eyes]',
|
||||
'[underwear]', '[undershirt]',
|
||||
'[backbag]', '[b_type]', '[alternate_option]',
|
||||
@@ -456,7 +479,10 @@
|
||||
'[job_medsci_high]', '[job_medsci_med]', '[job_medsci_low]',
|
||||
'[job_engsec_high]', '[job_engsec_med]', '[job_engsec_low]',
|
||||
'[job_karma_high]', '[job_karma_med]', '[job_karma_low]',
|
||||
'[sql_sanitize_text(html_encode(flavor_text))]', '[sql_sanitize_text(html_encode(med_record))]', '[sql_sanitize_text(html_encode(sec_record))]', '[sql_sanitize_text(html_encode(gen_record))]',
|
||||
'[sanitizeSQL(flavor_text)]',
|
||||
'[sanitizeSQL(med_record)]',
|
||||
'[sanitizeSQL(sec_record)]',
|
||||
'[sanitizeSQL(gen_record)]',
|
||||
'[playertitlelist]',
|
||||
'[disabilities]', '[organlist]', '[rlimblist]', '[nanotrasen_relation]', '[speciesprefs]',
|
||||
'[socks]', '[body_accessory]', '[gearlist]')
|
||||
|
||||
@@ -30,6 +30,12 @@
|
||||
"Vulpkanin" = 'icons/obj/clothing/species/vulpkanin/hats.dmi',
|
||||
)
|
||||
|
||||
/obj/item/clothing/head/helmet/space/rig/equip_to_best_slot(mob/M)
|
||||
if(rig_restrict_helmet)
|
||||
to_chat(M, "<span class='warning'>You must fasten the helmet to a hardsuit first. (Target the head and use on a hardsuit)</span>") // Stop RIG helmet equipping
|
||||
return 0
|
||||
..()
|
||||
|
||||
/obj/item/clothing/head/helmet/space/rig/attack_self(mob/user)
|
||||
toggle_light(user)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
return
|
||||
|
||||
// Grab the info we want.
|
||||
var/DBQuery/query = dbcon.NewQuery("SELECT cuiPath, cuiPropAdjust, cuiJobMask, cuiDescription, cuiItemName FROM [format_table_name("customuseritems")] WHERE cuiCKey='[M.ckey]' AND (cuiRealName='[M.real_name]' OR cuiRealName='*')")
|
||||
var/DBQuery/query = dbcon.NewQuery("SELECT cuiPath, cuiPropAdjust, cuiJobMask, cuiDescription, cuiItemName FROM [format_table_name("customuseritems")] WHERE cuiCKey='[M.ckey]' AND (cuiRealName='[sanitizeSQL(M.real_name)]' OR cuiRealName='*')")
|
||||
query.Execute()
|
||||
|
||||
while(query.NextRow())
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
if(!istype(M))
|
||||
return
|
||||
|
||||
if(!buckled_mob && !M.buckled && !M.anchored && (M.small || prob(round(seed.get_trait(TRAIT_POTENCY)/6))))
|
||||
if(!buckled_mob && !M.buckled && !M.anchored && ((M.mob_size <= MOB_SIZE_SMALL) || prob(round(seed.get_trait(TRAIT_POTENCY)/6))))
|
||||
//wait a tick for the Entered() proc that called HasProximity() to finish (and thus the moving animation),
|
||||
//so we don't appear to teleport from two tiles away when moving into a turf adjacent to vines.
|
||||
spawn(1)
|
||||
|
||||
@@ -331,6 +331,7 @@
|
||||
new /datum/data/mining_equipment("Drone Melee Upgrade", /obj/item/device/mine_bot_ugprade, 400),
|
||||
new /datum/data/mining_equipment("Drone Health Upgrade",/obj/item/device/mine_bot_ugprade/health, 400),
|
||||
new /datum/data/mining_equipment("Drone Ranged Upgrade",/obj/item/device/mine_bot_ugprade/cooldown, 600),
|
||||
new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/weapon/twohanded/required/mining_hammer, 750),
|
||||
new /datum/data/mining_equipment("Drone AI Upgrade", /obj/item/slimepotion/sentience/mining, 1000),
|
||||
new /datum/data/mining_equipment("GAR mesons", /obj/item/clothing/glasses/meson/gar, 500),
|
||||
new /datum/data/mining_equipment("Brute First-Aid Kit", /obj/item/weapon/storage/firstaid/brute, 600),
|
||||
@@ -458,7 +459,7 @@
|
||||
..()
|
||||
|
||||
/obj/machinery/mineral/equipment_vendor/proc/RedeemVoucher(obj/item/weapon/mining_voucher/voucher, mob/redeemer)
|
||||
var/selection = input(redeemer, "Pick your equipment", "Mining Voucher Redemption") as null|anything in list("Kinetic Accelerator", "Resonator", "Mining Drone", "Advanced Scanner")
|
||||
var/selection = input(redeemer, "Pick your equipment", "Mining Voucher Redemption") as null|anything in list("Kinetic Accelerator", "Resonator", "Mining Drone", "Advanced Scanner", "Crusher")
|
||||
if(!selection || !Adjacent(redeemer) || voucher.loc != redeemer)
|
||||
return
|
||||
switch(selection)
|
||||
@@ -470,6 +471,8 @@
|
||||
new /obj/item/weapon/storage/box/drone_kit(src.loc)
|
||||
if("Advanced Scanner")
|
||||
new /obj/item/device/t_scanner/adv_mining_scanner(src.loc)
|
||||
if("Crusher")
|
||||
new /obj/item/weapon/twohanded/required/mining_hammer(loc)
|
||||
qdel(voucher)
|
||||
|
||||
/obj/machinery/mineral/equipment_vendor/ex_act(severity, target)
|
||||
@@ -1108,3 +1111,104 @@
|
||||
C.preserved = 1
|
||||
to_chat(user, "<span class='notice'>You inject the hivelord core with the stabilizer. It will no longer go inert.</span>")
|
||||
qdel(src)
|
||||
|
||||
/*********************Mining Hammer****************/
|
||||
/obj/item/weapon/twohanded/required/mining_hammer
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "mining_hammer1"
|
||||
item_state = "mining_hammer1"
|
||||
name = "proto-kinetic crusher"
|
||||
desc = "An early design of the proto-kinetic accelerator, it is little more than an combination of various mining tools cobbled together, forming a high-tech club.\
|
||||
While it is an effective mining tool, it did little to aid any but the most skilled and/or suicidal miners against local fauna. \
|
||||
\n<span class='info'>Mark a mob with the destabilizing force, then hit them in melee to activate it for extra damage. Extra damage if backstabbed in this fashion. \
|
||||
This weapon is only particularly effective against large creatures.</span>"
|
||||
force = 20 //As much as a bone spear, but this is significantly more annoying to carry around due to requiring the use of both hands at all times
|
||||
w_class = 4
|
||||
slot_flags = SLOT_BACK
|
||||
force_unwielded = 20 //It's never not wielded so these are the same
|
||||
force_wielded = 20
|
||||
throwforce = 5
|
||||
throw_speed = 4
|
||||
light_range = 4
|
||||
armour_penetration = 10
|
||||
materials = list(MAT_METAL=1150, MAT_GLASS=2075)
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("smashes", "crushes", "cleaves", "chops", "pulps")
|
||||
sharp = 1
|
||||
edge = 1
|
||||
var/charged = 1
|
||||
var/charge_time = 16
|
||||
var/atom/mark = null
|
||||
var/marked_image = null
|
||||
|
||||
/obj/item/projectile/destabilizer
|
||||
name = "destabilizing force"
|
||||
icon_state = "pulse1"
|
||||
damage = 0 //We're just here to mark people. This is still a melee weapon.
|
||||
damage_type = BRUTE
|
||||
flag = "bomb"
|
||||
range = 6
|
||||
var/obj/item/weapon/twohanded/required/mining_hammer/hammer_synced = null
|
||||
|
||||
/obj/item/projectile/destabilizer/on_hit(atom/target, blocked = 0, hit_zone)
|
||||
if(hammer_synced)
|
||||
if(hammer_synced.mark == target)
|
||||
return ..()
|
||||
if(isliving(target))
|
||||
if(hammer_synced.mark && hammer_synced.marked_image)
|
||||
hammer_synced.mark.underlays -= hammer_synced.marked_image
|
||||
hammer_synced.marked_image = null
|
||||
var/mob/living/L = target
|
||||
if(L.mob_size >= MOB_SIZE_LARGE)
|
||||
hammer_synced.mark = L
|
||||
var/image/I = image('icons/effects/effects.dmi', loc = L, icon_state = "shield2",pixel_y = (-L.pixel_y),pixel_x = (-L.pixel_x))
|
||||
L.underlays += I
|
||||
hammer_synced.marked_image = I
|
||||
var/target_turf = get_turf(target)
|
||||
if(istype(target_turf, /turf/simulated/mineral))
|
||||
var/turf/simulated/mineral/M = target_turf
|
||||
new /obj/effect/overlay/temp/kinetic_blast(M)
|
||||
M.gets_drilled(firer)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/twohanded/required/mining_hammer/afterattack(atom/target, mob/user, proximity_flag)
|
||||
if(!proximity_flag && charged)//Mark a target, or mine a tile.
|
||||
var/turf/proj_turf = get_turf(src)
|
||||
if(!istype(proj_turf, /turf))
|
||||
return
|
||||
var/datum/gas_mixture/environment = proj_turf.return_air()
|
||||
var/pressure = environment.return_pressure()
|
||||
if(pressure > 50)
|
||||
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
|
||||
return
|
||||
var/obj/item/projectile/destabilizer/D = new /obj/item/projectile/destabilizer(user.loc)
|
||||
D.preparePixelProjectile(target,get_turf(target), user)
|
||||
D.hammer_synced = src
|
||||
playsound(user, 'sound/weapons/plasma_cutter.ogg', 100, 1)
|
||||
D.fire()
|
||||
charged = 0
|
||||
icon_state = "mining_hammer1_uncharged"
|
||||
spawn(charge_time)
|
||||
Recharge()
|
||||
return
|
||||
if(proximity_flag && target == mark && isliving(target))
|
||||
var/mob/living/L = target
|
||||
new /obj/effect/overlay/temp/kinetic_blast(get_turf(L))
|
||||
mark = 0
|
||||
if(L.mob_size >= MOB_SIZE_LARGE)
|
||||
L.underlays -= marked_image
|
||||
qdel(marked_image)
|
||||
marked_image = null
|
||||
var/backstab = check_target_facings(user, L)
|
||||
var/def_check = L.getarmor(type = "bomb")
|
||||
if(backstab == FACING_INIT_FACING_TARGET_TARGET_FACING_PERPENDICULAR || backstab == FACING_SAME_DIR)
|
||||
L.apply_damage(80, BRUTE, blocked = def_check)
|
||||
playsound(user, 'sound/weapons/Kenetic_accel.ogg', 100, 1) //Seriously who spelled it wrong
|
||||
else
|
||||
L.apply_damage(50, BRUTE, blocked = def_check)
|
||||
|
||||
/obj/item/weapon/twohanded/required/mining_hammer/proc/Recharge()
|
||||
if(!charged)
|
||||
charged = 1
|
||||
icon_state = "mining_hammer1"
|
||||
playsound(loc, 'sound/weapons/kenetic_reload.ogg', 60, 1)
|
||||
@@ -161,6 +161,41 @@
|
||||
|
||||
return items
|
||||
|
||||
/obj/item/proc/equip_to_best_slot(mob/M)
|
||||
if(src != M.get_active_hand())
|
||||
to_chat(M, "<span class='warning'>You are not holding anything to equip!</span>")
|
||||
return 0
|
||||
|
||||
if(M.equip_to_appropriate_slot(src))
|
||||
if(M.hand)
|
||||
M.update_inv_l_hand(0)
|
||||
else
|
||||
M.update_inv_r_hand(0)
|
||||
return 1
|
||||
|
||||
if(M.s_active && M.s_active.can_be_inserted(src, 1)) //if storage active insert there
|
||||
M.s_active.handle_item_insertion(src)
|
||||
return 1
|
||||
|
||||
var/obj/item/weapon/storage/S = M.get_inactive_hand()
|
||||
if(istype(S) && S.can_be_inserted(src, 1)) //see if we have box in other hand
|
||||
S.handle_item_insertion(src)
|
||||
return 1
|
||||
|
||||
S = M.get_item_by_slot(slot_belt)
|
||||
if(istype(S) && S.can_be_inserted(src, 1)) //else we put in belt
|
||||
S.handle_item_insertion(src)
|
||||
return 1
|
||||
|
||||
S = M.get_item_by_slot(slot_back) //else we put in backpack
|
||||
if(istype(S) && S.can_be_inserted(src, 1))
|
||||
S.handle_item_insertion(src)
|
||||
playsound(loc, "rustle", 50, 1, -5)
|
||||
return 1
|
||||
|
||||
to_chat(M, "<span class='warning'>You are unable to equip that!</span>")
|
||||
return 0
|
||||
|
||||
/mob/proc/get_all_slots()
|
||||
return list(wear_mask, back, l_hand, r_hand)
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
health = 700
|
||||
icon_state = "alienq_s"
|
||||
status_flags = CANPARALYSE
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
move_delay_add = 3
|
||||
large = 1
|
||||
ventcrawler = 0
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
real_name = "alien larva"
|
||||
icon_state = "larva0"
|
||||
pass_flags = PASSTABLE | PASSMOB
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
|
||||
maxHealth = 30
|
||||
health = 30
|
||||
|
||||
@@ -756,10 +756,10 @@
|
||||
M = A
|
||||
break
|
||||
if(M)
|
||||
message = "<span class='danger'>[src]</span> slaps [M] across the face. Ouch!"
|
||||
message = "<span class='danger'>[src] slaps [M] across the face. Ouch!</span>"
|
||||
playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
|
||||
else
|
||||
message = "<span class='danger'>[src]</span> slaps \himself!"
|
||||
message = "<span class='danger'>[src] slaps \himself!</span>"
|
||||
playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
|
||||
src.adjustFireLoss(4)
|
||||
|
||||
|
||||
@@ -404,13 +404,12 @@
|
||||
if(M.melee_damage_upper == 0)
|
||||
M.custom_emote(1, "[M.friendly] [src]")
|
||||
else
|
||||
M.do_attack_animation(src)
|
||||
if(M.attack_sound)
|
||||
playsound(loc, M.attack_sound, 50, 1, 1)
|
||||
for(var/mob/O in viewers(src, null))
|
||||
O.show_message("<span class='danger'>[M]</span> [M.attacktext] [src]!", 1)
|
||||
M.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name] ([src.ckey])</font>")
|
||||
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>was attacked by [M.name] ([M.ckey])</font>")
|
||||
M.do_attack_animation(src)
|
||||
visible_message("<span class='danger'>[M] [M.attacktext] [src]!</span>", \
|
||||
"<span class='userdanger'>[M] [M.attacktext] [src]!</span>")
|
||||
add_logs(src, M, "attacked")
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
if(check_shields(damage, "the [M.name]", null, MELEE_ATTACK, M.armour_penetration))
|
||||
return 0
|
||||
|
||||
@@ -2,41 +2,9 @@
|
||||
set name = "quick-equip"
|
||||
set hidden = 1
|
||||
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
var/obj/item/I = H.get_active_hand()
|
||||
var/obj/item/weapon/storage/S = H.get_inactive_hand()
|
||||
if(!I)
|
||||
to_chat(H, "<span class='notice'>You are not holding anything to equip.</span>")
|
||||
return
|
||||
|
||||
if(istype(I, /obj/item/clothing/head/helmet/space/rig)) // If the item to be equipped is a rigid suit helmet
|
||||
var/obj/item/clothing/head/helmet/space/rig/C = I
|
||||
if(C.rig_restrict_helmet)
|
||||
to_chat(src, "\red You must fasten the helmet to a hardsuit first. (Target the head and use on a hardsuit)")// Stop eva helms equipping.
|
||||
|
||||
return 0
|
||||
|
||||
if(H.equip_to_appropriate_slot(I))
|
||||
if(hand)
|
||||
update_inv_l_hand(0)
|
||||
else
|
||||
update_inv_r_hand(0)
|
||||
else if(s_active && s_active.can_be_inserted(I,1)) //if storage active insert there
|
||||
s_active.handle_item_insertion(I)
|
||||
else if(istype(S, /obj/item/weapon/storage) && S.can_be_inserted(I,1)) //see if we have box in other hand
|
||||
S.handle_item_insertion(I)
|
||||
else
|
||||
S = H.get_item_by_slot(slot_belt)
|
||||
if(istype(S, /obj/item/weapon/storage) && S.can_be_inserted(I,1)) //else we put in belt
|
||||
S.handle_item_insertion(I)
|
||||
else
|
||||
S = H.get_item_by_slot(slot_back) //else we put in backpack
|
||||
if(istype(S, /obj/item/weapon/storage) && S.can_be_inserted(I,1))
|
||||
S.handle_item_insertion(I)
|
||||
else
|
||||
to_chat(H, "\red You are unable to equip that.")
|
||||
|
||||
var/obj/item/I = get_active_hand()
|
||||
if(I)
|
||||
I.equip_to_best_slot(src)
|
||||
|
||||
/mob/living/carbon/human/proc/equip_in_one_of_slots(obj/item/W, list/slots, del_on_fail = 1)
|
||||
for(var/slot in slots)
|
||||
|
||||
@@ -176,22 +176,22 @@
|
||||
if(gene.is_active(src))
|
||||
speech_problem_flag = 1
|
||||
gene.OnMobLife(src)
|
||||
if(gene_stability < 85)
|
||||
if(gene_stability < GENETIC_DAMAGE_STAGE_1)
|
||||
var/instability = DEFAULT_GENE_STABILITY - gene_stability
|
||||
if(prob(instability / 10))
|
||||
adjustFireLoss(min(6, instability / 12))
|
||||
if(prob(instability * 0.1))
|
||||
adjustFireLoss(min(5, instability * 0.67))
|
||||
to_chat(src, "<span class='danger'>You feel like your skin is burning and bubbling off!</span>")
|
||||
if(gene_stability < 70)
|
||||
if(prob(instability / 12))
|
||||
adjustCloneLoss(min(5, instability / 15))
|
||||
if(gene_stability < GENETIC_DAMAGE_STAGE_2)
|
||||
if(prob(instability * 0.83))
|
||||
adjustCloneLoss(min(4, instability * 0.05))
|
||||
to_chat(src, "<span class='danger'>You feel as if your body is warping.</span>")
|
||||
if(prob(instability / 10))
|
||||
adjustToxLoss(min(6, instability / 12))
|
||||
if(prob(instability * 0.1))
|
||||
adjustToxLoss(min(5, instability * 0.67))
|
||||
to_chat(src, "<span class='danger'>You feel weak and nauseous.</span>")
|
||||
if(gene_stability < 40 && prob(1))
|
||||
if(gene_stability < GENETIC_DAMAGE_STAGE_3 && prob(1))
|
||||
to_chat(src, "<span class='biggerdanger'>You feel incredibly sick... Something isn't right!</span>")
|
||||
spawn(300)
|
||||
if(gene_stability < 40)
|
||||
if(gene_stability < GENETIC_DAMAGE_STAGE_3)
|
||||
gib()
|
||||
|
||||
if(!(species.flags & RADIMMUNE))
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
var/implanting = 0 //Used for the mind-slave implant
|
||||
var/silent = 0 //Can't talk. Value goes down every life proc. //NOTE TO FUTURE CODERS: DO NOT INITIALIZE NUMERICAL VARS AS NULL OR I WILL MURDER YOU.
|
||||
var/floating = 0
|
||||
var/mob_size = MOB_SIZE_HUMAN
|
||||
var/nightvision = 0
|
||||
|
||||
var/bloodcrawl = 0 //0 No blood crawling, 1 blood crawling, 2 blood crawling+mob devour
|
||||
|
||||
@@ -41,6 +41,7 @@ var/list/ai_verbs_default = list(
|
||||
anchored = 1 // -- TLE
|
||||
density = 1
|
||||
status_flags = CANSTUN|CANPARALYSE|CANPUSH
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
can_strip = 0
|
||||
var/list/network = list("SS13","Telecomms","Research Outpost","Mining Outpost")
|
||||
var/obj/machinery/camera/current = null
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
robot_talk_understand = 0
|
||||
emote_type = 2 // pAIs emotes are heard, not seen, so they can be seen through a container (eg. person)
|
||||
small = 1
|
||||
mob_size = MOB_SIZE_TINY
|
||||
pass_flags = PASSTABLE
|
||||
density = 0
|
||||
holder_type = /obj/item/weapon/holder/pai
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
local_transmit = 1
|
||||
ventcrawler = 2
|
||||
magpulse = 1
|
||||
mob_size = MOB_SIZE_TINY
|
||||
|
||||
// We need to keep track of a few module items so we don't need to do list operations
|
||||
// every time we need them. These get set in New() after the module is chosen.
|
||||
|
||||
@@ -242,7 +242,7 @@
|
||||
set desc = "Sets an extended description of your character's features."
|
||||
set category = "IC"
|
||||
|
||||
flavor_text = sanitize(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text)
|
||||
update_flavor_text()
|
||||
|
||||
/mob/living/silicon/binarycheck()
|
||||
return 1
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
|
||||
|
||||
environment_smash = 2 //Walls can't stop THE LAW
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
|
||||
radio_channel = "Security"
|
||||
bot_type = SEC_BOT
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
|
||||
a_intent = "harm" //No swapping
|
||||
buckle_lying = 0
|
||||
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
radio_channel = "Supply"
|
||||
|
||||
bot_type = MULE_BOT
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
environment_smash = 2
|
||||
attack_sound = 'sound/weapons/punch3.ogg'
|
||||
status_flags = 0
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall)
|
||||
force_threshold = 11
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
density = 0
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
ventcrawler = 2
|
||||
mob_size = MOB_SIZE_TINY
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 0)
|
||||
gold_core_spawnable = CHEM_MOB_SPAWN_FRIENDLY
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
simplespecies = /mob/living/simple_animal/pet/cat
|
||||
childtype = /mob/living/simple_animal/pet/cat/kitten
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 3)
|
||||
|
||||
@@ -542,6 +542,7 @@
|
||||
shaved = 0
|
||||
density = 0
|
||||
pass_flags = PASSMOB
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
|
||||
//puppies cannot wear anything.
|
||||
/mob/living/simple_animal/pet/corgi/puppy/Topic(href, href_list)
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
icon_state = "crab"
|
||||
icon_living = "crab"
|
||||
icon_dead = "crab_dead"
|
||||
small = 1
|
||||
speak_emote = list("clicks")
|
||||
emote_hear = list("clicks")
|
||||
emote_see = list("clacks")
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
icon_dead = "nymph_dead"
|
||||
icon_resting = "nymph_sleep"
|
||||
pass_flags = PASSTABLE | PASSMOB
|
||||
small = 1
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
ventcrawler = 2
|
||||
|
||||
maxHealth = 50
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
ventcrawler = 2
|
||||
var/amount_grown = 0
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
small = 1
|
||||
mob_size = MOB_SIZE_TINY
|
||||
can_hide = 1
|
||||
can_collar = 1
|
||||
gold_core_spawnable = CHEM_MOB_SPAWN_FRIENDLY
|
||||
@@ -225,7 +225,7 @@ var/global/chicken_count = 0
|
||||
var/eggsleft = 0
|
||||
var/chicken_color
|
||||
pass_flags = PASSTABLE | PASSMOB
|
||||
small = 1
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
can_hide = 1
|
||||
can_collar = 1
|
||||
gold_core_spawnable = CHEM_MOB_SPAWN_FRIENDLY
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
icon_state = "lizard"
|
||||
icon_living = "lizard"
|
||||
icon_dead = "lizard-dead"
|
||||
small = 1
|
||||
speak_emote = list("hisses")
|
||||
health = 5
|
||||
maxHealth = 5
|
||||
@@ -19,6 +18,7 @@
|
||||
ventcrawler = 2
|
||||
density = 0
|
||||
pass_flags = PASSTABLE | PASSMOB
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
can_hide = 1
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 1)
|
||||
can_collar = 1
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
speak_emote = list("squeeks","squeeks","squiks")
|
||||
emote_hear = list("squeeks","squeaks","squiks")
|
||||
emote_see = list("runs in a circle", "shakes", "scritches at something")
|
||||
small = 1
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
@@ -22,6 +21,7 @@
|
||||
density = 0
|
||||
ventcrawler = 2
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
mob_size = MOB_SIZE_TINY
|
||||
var/mouse_color //brown, gray and white, leave blank for random
|
||||
layer = MOB_LAYER
|
||||
atmos_requirements = list("min_oxy" = 16, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/mob/living/simple_animal/pet
|
||||
icon = 'icons/mob/pets.dmi'
|
||||
can_collar = 1
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
|
||||
/mob/living/simple_animal/pet/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
|
||||
if(istype(O, /obj/item/weapon/newspaper))
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
var/syndie = 0 //IS WE SYNDICAT? (currently unused)
|
||||
speed = -1 //Spiderbots gotta go fast.
|
||||
//pass_flags = PASSTABLE //Maybe griefy?
|
||||
small = 1
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
speak_emote = list("beeps","clicks","chirps")
|
||||
can_hide = 1
|
||||
ventcrawler = 2
|
||||
|
||||
@@ -129,6 +129,7 @@
|
||||
move_to_delay = 4
|
||||
maxHealth = 400
|
||||
health = 400
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
gold_core_spawnable = CHEM_MOB_SPAWN_INVALID
|
||||
|
||||
/obj/item/projectile/neurotox
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
speed = 4
|
||||
maxHealth = 20
|
||||
health = 20
|
||||
|
||||
mob_size = MOB_SIZE_TINY
|
||||
harm_intent_damage = 8
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 10
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
flying = 1
|
||||
search_objects = 1 //have to find those plant trays!
|
||||
density = 0
|
||||
small = 1
|
||||
mob_size = MOB_SIZE_TINY
|
||||
|
||||
//Spaceborn beings don't get hurt by space
|
||||
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)
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
maxHealth = 65
|
||||
health = 65
|
||||
pixel_x = -16
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
|
||||
melee_damage_lower = 20
|
||||
melee_damage_upper = 20
|
||||
@@ -15,6 +15,7 @@
|
||||
var/icon_aggro = null // for swapping to when we get aggressive
|
||||
see_in_dark = 8
|
||||
see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Aggro()
|
||||
..()
|
||||
|
||||
@@ -118,6 +118,7 @@
|
||||
faction = list("syndicate")
|
||||
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
|
||||
mob_size = MOB_SIZE_TINY
|
||||
flying = 1
|
||||
gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE
|
||||
del_on_death = 1
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
speed = 1
|
||||
maxHealth = 250
|
||||
health = 250
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
|
||||
pixel_x = -16
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
icon_living = "parrot_fly"
|
||||
icon_dead = "parrot_dead"
|
||||
pass_flags = PASSTABLE
|
||||
small = 1
|
||||
can_collar = 1
|
||||
|
||||
var/list/clean_speak = list(
|
||||
@@ -54,6 +53,7 @@
|
||||
response_harm = "swats the"
|
||||
stop_automated_movement = 1
|
||||
universal_speak = 1
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
|
||||
var/parrot_state = PARROT_WANDER //Hunt for a perch when created
|
||||
var/parrot_sleep_max = 25 //The time the parrot sits while perched before looking around. Mosly a way to avoid the parrot's AI in process_ai() being run every single tick.
|
||||
|
||||
@@ -866,7 +866,10 @@ var/list/slot_equipment_priority = list( \
|
||||
/mob/MouseDrop(mob/M as mob)
|
||||
..()
|
||||
if(M != usr) return
|
||||
if(M.small) return // Stops pAI drones and small mobs (borers, parrots, crabs) from stripping people. --DZD
|
||||
if(isliving(M)) // Ewww
|
||||
var/mob/living/L = M
|
||||
if(L.mob_size <= MOB_SIZE_SMALL)
|
||||
return // Stops pAI drones and small mobs (borers, parrots, crabs) from stripping people. --DZD
|
||||
if(!M.can_strip) return
|
||||
if(usr == src) return
|
||||
if(!Adjacent(usr)) return
|
||||
|
||||
@@ -63,7 +63,6 @@
|
||||
var/canmove = 1
|
||||
var/lastpuke = 0
|
||||
var/unacidable = 0
|
||||
var/small = 0
|
||||
var/can_strip = 1
|
||||
var/list/pinned = list() //List of things pinning this creature to walls (see living_defense.dm)
|
||||
var/list/embedded = list() //Embedded items, since simple mobs don't have organs.
|
||||
|
||||
@@ -517,7 +517,15 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list(
|
||||
|
||||
if(S.burn_dam)
|
||||
if(S.burn_dam < ROBOLIMB_SELF_REPAIR_CAP)
|
||||
S.heal_damage(0,15,0,1)
|
||||
if(H == user)
|
||||
if(!do_mob(user, H, 10))
|
||||
return 1
|
||||
var/cable_to_use = 0
|
||||
for(cable_to_use in 1 to 5)
|
||||
if(cable_to_use == amount || (cable_to_use * 3) >= S.burn_dam)
|
||||
break
|
||||
use(cable_to_use)
|
||||
S.heal_damage(0, (cable_to_use * 3), 0, 1)
|
||||
user.visible_message("<span class='alert'>\The [user] repairs some burn damage on \the [M]'s [S.name] with \the [src].</span>")
|
||||
else if(S.open != 2)
|
||||
to_chat(user, "<span class='danger'>The damage is far too severe to patch over externally.</span>")
|
||||
|
||||
@@ -315,7 +315,7 @@ var/obj/machinery/blackbox_recorder/blackbox
|
||||
proc/feedback_set(var/variable,var/value)
|
||||
if(!blackbox) return
|
||||
|
||||
variable = sql_sanitize_text(variable)
|
||||
variable = sanitizeSQL(variable)
|
||||
|
||||
var/datum/feedback_variable/FV = blackbox.find_feedback_datum(variable)
|
||||
|
||||
@@ -326,7 +326,7 @@ proc/feedback_set(var/variable,var/value)
|
||||
proc/feedback_inc(var/variable,var/value)
|
||||
if(!blackbox) return
|
||||
|
||||
variable = sql_sanitize_text(variable)
|
||||
variable = sanitizeSQL(variable)
|
||||
|
||||
var/datum/feedback_variable/FV = blackbox.find_feedback_datum(variable)
|
||||
|
||||
@@ -337,7 +337,7 @@ proc/feedback_inc(var/variable,var/value)
|
||||
proc/feedback_dec(var/variable,var/value)
|
||||
if(!blackbox) return
|
||||
|
||||
variable = sql_sanitize_text(variable)
|
||||
variable = sanitizeSQL(variable)
|
||||
|
||||
var/datum/feedback_variable/FV = blackbox.find_feedback_datum(variable)
|
||||
|
||||
@@ -348,8 +348,8 @@ proc/feedback_dec(var/variable,var/value)
|
||||
proc/feedback_set_details(var/variable,var/details)
|
||||
if(!blackbox) return
|
||||
|
||||
variable = sql_sanitize_text(variable)
|
||||
details = sql_sanitize_text(details)
|
||||
variable = sanitizeSQL(variable)
|
||||
details = sanitizeSQL(details)
|
||||
|
||||
var/datum/feedback_variable/FV = blackbox.find_feedback_datum(variable)
|
||||
|
||||
@@ -360,8 +360,8 @@ proc/feedback_set_details(var/variable,var/details)
|
||||
proc/feedback_add_details(var/variable,var/details)
|
||||
if(!blackbox) return
|
||||
|
||||
variable = sql_sanitize_text(variable)
|
||||
details = sql_sanitize_text(details)
|
||||
variable = sanitizeSQL(variable)
|
||||
details = sanitizeSQL(details)
|
||||
|
||||
var/datum/feedback_variable/FV = blackbox.find_feedback_datum(variable)
|
||||
|
||||
|
||||
@@ -824,7 +824,7 @@
|
||||
return 1
|
||||
|
||||
var/mob/living/M = caller
|
||||
if(!M.ventcrawler && !M.small)
|
||||
if(!M.ventcrawler && M.mob_size > MOB_SIZE_SMALL)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
@@ -55,6 +55,40 @@
|
||||
|
||||
-->
|
||||
<div class="commit sansserif">
|
||||
<h2 class="date">19 August 2016</h2>
|
||||
<h3 class="author">Crazylemon updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">pAIs should now save</li>
|
||||
</ul>
|
||||
<h3 class="author">FalseIncarnate updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">Repairing burn damage to robotic limbs now consumes cable in the process. Each length used repairs 3 burn damage, up to 15 damage per click.</li>
|
||||
<li class="tweak">Repairing brute damage to robotic limbs now uses 1 fuel per repair (click). Heal amount unchanged.</li>
|
||||
<li class="tweak">Self-repairing with cables or welders now incurs a 1 second delay between click and heal completion. Being repaired by a friend is still no delay (but requires a friend).</li>
|
||||
</ul>
|
||||
<h3 class="author">Fox McCloud updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Adds in the Kinetic Smasher as a mining purchase</li>
|
||||
<li class="bugfix">Fixes slap emote text being the wrong partial color</li>
|
||||
<li class="bugfix">Fixes the attack text of simple animals attacking human mobs</li>
|
||||
</ul>
|
||||
<h3 class="author">IcyV updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Adds in an amount of new graffiti</li>
|
||||
<li class="bugfix">Fixes the issue of other graffiti only being able to be done in black.</li>
|
||||
</ul>
|
||||
<h3 class="author">Krausus updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">Flavor text and records are no longer horrifically butchered when saved in the database.</li>
|
||||
</ul>
|
||||
<h3 class="author">TheDZD updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">Lowered genetic instability damage thresholds by 5 across the board. Effectively meaning that you can have one additional minor power without shifting into the next threshold.</li>
|
||||
<li class="tweak">Lowered the rate at which damage scales with instability, and the decreased upper cap on each damage type.</li>
|
||||
<li class="tweak">The base activation probability for powers is now 100%, rather than 45%. Abilities affected include everything except Cloak of Darkness, Chameleon, No Breathing, Hulk, Telekinesis, and X-Ray Vision, which all have their own independent activation chances (varying from 5% to 10%).</li>
|
||||
<li class="tweak">Increases activation chances of TK (10% to 15%), No Breathing (10% to 25%), Cloak of Darkness (10% to 25%), Hulk (5% to 15%), X-Ray Vision (10% to 15%), and Chameleon (10% to 25%).</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">18 August 2016</h2>
|
||||
<h3 class="author">Alexshreds updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
|
||||
@@ -2808,3 +2808,37 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
|
||||
- bugfix: Gives proper mix_messages for Uplink, Synthignon, and Synth 'n Soda drinks
|
||||
tristan1333:
|
||||
- rscadd: Spacepod paint
|
||||
2016-08-19:
|
||||
Crazylemon:
|
||||
- bugfix: pAIs should now save
|
||||
FalseIncarnate:
|
||||
- tweak: Repairing burn damage to robotic limbs now consumes cable in the process.
|
||||
Each length used repairs 3 burn damage, up to 15 damage per click.
|
||||
- tweak: Repairing brute damage to robotic limbs now uses 1 fuel per repair (click).
|
||||
Heal amount unchanged.
|
||||
- tweak: Self-repairing with cables or welders now incurs a 1 second delay between
|
||||
click and heal completion. Being repaired by a friend is still no delay (but
|
||||
requires a friend).
|
||||
Fox McCloud:
|
||||
- rscadd: Adds in the Kinetic Smasher as a mining purchase
|
||||
- bugfix: Fixes slap emote text being the wrong partial color
|
||||
- bugfix: Fixes the attack text of simple animals attacking human mobs
|
||||
IcyV:
|
||||
- rscadd: Adds in an amount of new graffiti
|
||||
- bugfix: Fixes the issue of other graffiti only being able to be done in black.
|
||||
Krausus:
|
||||
- bugfix: Flavor text and records are no longer horrifically butchered when saved
|
||||
in the database.
|
||||
TheDZD:
|
||||
- tweak: Lowered genetic instability damage thresholds by 5 across the board. Effectively
|
||||
meaning that you can have one additional minor power without shifting into the
|
||||
next threshold.
|
||||
- tweak: Lowered the rate at which damage scales with instability, and the decreased
|
||||
upper cap on each damage type.
|
||||
- tweak: The base activation probability for powers is now 100%, rather than 45%.
|
||||
Abilities affected include everything except Cloak of Darkness, Chameleon, No
|
||||
Breathing, Hulk, Telekinesis, and X-Ray Vision, which all have their own independent
|
||||
activation chances (varying from 5% to 10%).
|
||||
- tweak: Increases activation chances of TK (10% to 15%), No Breathing (10% to 25%),
|
||||
Cloak of Darkness (10% to 25%), Hulk (5% to 15%), X-Ray Vision (10% to 15%),
|
||||
and Chameleon (10% to 25%).
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
author: Crazylemon
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "pAIs should now save"
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 172 KiB After Width: | Height: | Size: 172 KiB |
|
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 170 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |