Conflict resolution and adds sanitization to marking SQL handling.

This commit is contained in:
KasparoVy
2016-08-21 00:01:12 -04:00
74 changed files with 461 additions and 205 deletions
+4
View File
@@ -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
+11
View File
@@ -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"
-15
View File
@@ -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
+4
View File
@@ -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
+37 -8
View File
@@ -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.
+1 -6
View File
@@ -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
+1 -1
View File
@@ -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()
+2 -2
View File
@@ -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()
+4 -4
View File
@@ -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
+3 -3
View File
@@ -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
+2 -2
View File
@@ -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
+7
View File
@@ -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'
+4 -4
View File
@@ -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
..()
+12 -4
View File
@@ -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
+18 -13
View File
@@ -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
+5 -5
View File
@@ -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)
-15
View File
@@ -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
*/
+7 -9
View File
@@ -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]')
+6
View File
@@ -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)
+1 -1
View File
@@ -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)
+105 -1
View File
@@ -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)
+35
View File
@@ -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)
+10 -10
View File
@@ -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
+1
View File
@@ -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
+1 -1
View File
@@ -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.
+1 -1
View File
@@ -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.
+4 -1
View File
@@ -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
-1
View File
@@ -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.
+9 -1
View File
@@ -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>")
+7 -7
View File
@@ -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)
+1 -1
View File
@@ -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
+34
View File
@@ -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">
+34
View File
@@ -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"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB