Bleeding edgy refresh (#303)

* not code stuff

* other things

* global vars, defines, helpers

* onclick hud stuff, orphans, world.dm

* controllers and datums

* game folder

* everything not client/mobs in modules

* client folder

* stage 1 mob stuff

* simple animal things

* silicons

* carbon things

* ayylmaos and monkeys

* hyoomahn

* icons n shit

* sprite fixes

* compile fixes

* some fixes I cherrypicked.

* qdel fixes

* forgot brain refractors
This commit is contained in:
Poojawa
2017-03-21 11:44:10 -05:00
committed by GitHub
parent 099a6c8764
commit f67e9f6d87
1476 changed files with 344416 additions and 40694 deletions
+5 -1
View File
@@ -12,7 +12,7 @@
//print a testing-mode debug message to world.log and world
#ifdef TESTING
#define testing(msg) log_world("## TESTING: [msg]"); world << "## TESTING: [msg]"
#define testing(msg) log_world("## TESTING: [msg]"); to_chat(world, "## TESTING: [msg]")
#else
#define testing(msg)
#endif
@@ -89,6 +89,10 @@
if (config.log_pda)
diary << "\[[time_stamp()]]CHAT: [text]"
/proc/log_sql(text)
if(config.sql_enabled)
diary << "\[[time_stamp()]]SQL: [text]"
//This replaces world.log so it displays both in DD and the file
/proc/log_world(text)
if(config && config.log_runtimes)
+4 -5
View File
@@ -2,14 +2,13 @@
/client/proc/join_date_check(y,m,d)
var/DBQuery/query = dbcon.NewQuery("SELECT DATEDIFF(Now(),'[y]-[m]-[d]')")
var/DBQuery/query_datediff = dbcon.NewQuery("SELECT DATEDIFF(Now(),'[y]-[m]-[d]')")
if(!query.Execute())
log_world("SQL ERROR doing datediff. Error : \[[query.ErrorMsg()]\]\n")
if(!query_datediff.Execute())
return FALSE
if(query.NextRow())
var/diff = text2num(query.item[1])
if(query_datediff.NextRow())
var/diff = text2num(query_datediff.item[1])
if(config.use_account_age_for_jobs)
player_age = max(0,diff) //So job code soesn't freak out if they are time traveling.
if(diff < YOUNG)
+4 -6
View File
@@ -29,15 +29,13 @@ var/cmp_field = "name"
/proc/cmp_ckey_dsc(client/a, client/b)
return sorttext(a.ckey, b.ckey)
/proc/cmp_subsystem_init(datum/subsystem/a, datum/subsystem/b)
/proc/cmp_subsystem_init(datum/controller/subsystem/a, datum/controller/subsystem/b)
return b.init_order - a.init_order
/proc/cmp_subsystem_display(datum/subsystem/a, datum/subsystem/b)
if(a.display_order == b.display_order)
return sorttext(b.name, a.name)
return a.display_order - b.display_order
/proc/cmp_subsystem_display(datum/controller/subsystem/a, datum/controller/subsystem/b)
return sorttext(b.name, a.name)
/proc/cmp_subsystem_priority(datum/subsystem/a, datum/subsystem/b)
/proc/cmp_subsystem_priority(datum/controller/subsystem/a, datum/controller/subsystem/b)
return a.priority - b.priority
/proc/cmp_timer(datum/timedevent/a, datum/timedevent/b)
+2 -2
View File
@@ -39,7 +39,7 @@
var/extension = copytext(path,-4,0)
if( !fexists(path) || !(extension in valid_extensions) )
src << "<font color='red'>Error: browse_files(): File not found/Invalid file([path]).</font>"
to_chat(src, "<font color='red'>Error: browse_files(): File not found/Invalid file([path]).</font>")
return
return path
@@ -53,7 +53,7 @@
/client/proc/file_spam_check()
var/time_to_wait = fileaccess_timer - world.time
if(time_to_wait > 0)
src << "<font color='red'>Error: file_spam_check(): Spam. Please wait [round(time_to_wait/10)] seconds.</font>"
to_chat(src, "<font color='red'>Error: file_spam_check(): Spam. Please wait [round(time_to_wait/10)] seconds.</font>")
return 1
fileaccess_timer = world.time + FTPDELAY
return 0
+3
View File
@@ -0,0 +1,3 @@
#define HAS_SECONDARY_FLAG(atom, sflag) (atom.secondary_flags ? atom.secondary_flags[sflag] : FALSE)
#define SET_SECONDARY_FLAG(atom, sflag) if(!atom.secondary_flags) { atom.secondary_flags = list(); } atom.secondary_flags[sflag] = TRUE;
#define CLEAR_SECONDARY_FLAG(atom, sflag) if(atom.secondary_flags) atom.secondary_flags[sflag] = null
+31 -6
View File
@@ -422,20 +422,20 @@
window_flash(G.client)
switch(ignore_category ? askuser(G,Question,"Please answer in [poll_time/10] seconds!","Yes","No","Never for this round", StealFocus=0, Timeout=poll_time) : askuser(G,Question,"Please answer in [poll_time/10] seconds!","Yes","No", StealFocus=0, Timeout=poll_time))
if(1)
G << "<span class='notice'>Choice registered: Yes.</span>"
to_chat(G, "<span class='notice'>Choice registered: Yes.</span>")
if((world.time-time_passed)>poll_time)
G << "<span class='danger'>Sorry, you were too late for the consideration!</span>"
to_chat(G, "<span class='danger'>Sorry, you were too late for the consideration!</span>")
G << 'sound/machines/buzz-sigh.ogg'
else
candidates += G
if(2)
G << "<span class='danger'>Choice registered: No.</span>"
to_chat(G, "<span class='danger'>Choice registered: No.</span>")
if(3)
var/list/L = poll_ignore[ignore_category]
if(!L)
poll_ignore[ignore_category] = list()
poll_ignore[ignore_category] += G.ckey
G << "<span class='danger'>Choice registered: Never for this round.</span>"
to_chat(G, "<span class='danger'>Choice registered: Never for this round.</span>")
/proc/pollCandidates(var/Question, var/jobbanType, var/datum/game_mode/gametypeCheck, var/be_special_flag = 0, var/poll_time = 300, var/ignore_category = null, flashwindow = TRUE)
var/list/mob/dead/observer/candidates = list()
@@ -498,10 +498,10 @@
return new_character
/proc/send_to_playing_players(thing) //sends a whatever to all playing players; use instead of world << where needed
/proc/send_to_playing_players(thing) //sends a whatever to all playing players; use instead of to_chat(world, where needed)
for(var/M in player_list)
if(M && !isnewplayer(M))
M << thing
to_chat(M, thing)
/proc/window_flash(client/C, ignorepref = FALSE)
if(ismob(C))
@@ -511,3 +511,28 @@
if(!C || (!C.prefs.windowflashing && !ignorepref))
return
winset(C, "mainwindow", "flash=5")
/proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank)
if(ticker.current_state != GAME_STATE_PLAYING || !character)
return
var/area/A = get_area(character)
var/message = "<span class='game deadsay'><span class='name'>\
[character.real_name]</span> ([rank]) has arrived at the station at \
<span class='name'>[A.name]</span>.</span>"
deadchat_broadcast(message, follow_target = character, message_type=DEADCHAT_ARRIVALRATTLE)
if((!announcement_systems.len) || (!character.mind))
return
if((character.mind.assigned_role == "Cyborg") || (character.mind.assigned_role == character.mind.special_role))
return
var/obj/machinery/announcement_system/announcer = pick(announcement_systems)
announcer.announce("ARRIVAL", character.real_name, rank, list()) //make the list empty to make it announce it in common
/proc/GetRedPart(const/hexa)
return hex2num(copytext(hexa, 2, 4))
/proc/GetGreenPart(const/hexa)
return hex2num(copytext(hexa, 4, 6))
/proc/GetBluePart(const/hexa)
return hex2num(copytext(hexa, 6, 8))
+1 -1
View File
@@ -94,7 +94,7 @@
var/list/L = chemical_reactions_list[reaction]
for(var/t in L)
. += " has: [t]\n"
world << .
to_chat(world, .)
*/
//creates every subtype of prototype (excluding prototype) and adds it to list L.
+7 -5
View File
@@ -167,7 +167,7 @@ mob
Output_Icon()
set name = "2. Output Icon"
src<<"Icon is: \icon[getFlatIcon(src)]"
to_chat(src, "Icon is: \icon[getFlatIcon(src)]")
Label_Icon()
set name = "3. Label Icon"
@@ -869,7 +869,7 @@ The _flatIcons list is a cache for generated icon files.
text_image.color = AverageColour(atom_icon)
text_image.pixel_x = 7
text_image.pixel_y = 5
del(atom_icon)
qdel(atom_icon)
return text_image
var/global/list/friendly_animal_types = list()
@@ -954,6 +954,8 @@ var/global/list/humanoid_icon_cache = list()
if(outfit)
body.equipOutfit(outfit, TRUE)
SSoverlays.Flush()
var/icon/out_icon = icon('icons/effects/effects.dmi', "nothing")
body.setDir(NORTH)
@@ -993,7 +995,7 @@ var/list/freeze_item_icons = list()
return "\ref[initial(icon)]-[initial(icon_state)]"
/obj/proc/make_frozen_visual()
if(!is_frozen && (initial(icon) && initial(icon_state)))
if(!HAS_SECONDARY_FLAG(src, FROZEN) && (initial(icon) && initial(icon_state)))
var/index = freeze_icon_index()
var/icon/IC
var/icon/P = freeze_item_icons[index]
@@ -1007,10 +1009,10 @@ var/list/freeze_item_icons = list()
freeze_item_icons[index] = P
icon = P
name = "frozen [name]"
is_frozen = TRUE
SET_SECONDARY_FLAG(src, FROZEN)
//Assumes already frozed
obj/proc/make_unfrozen()
icon = initial(icon)
name = replacetext(name, "frozen ", "")
is_frozen = FALSE
CLEAR_SECONDARY_FLAG(src, FROZEN)
+1 -1
View File
@@ -139,7 +139,7 @@ var/list/sqrtTable = list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
var/size_factor = ((-cos(inputToDegrees) +1) /2) //returns a value from 0 to 1
return size_factor + scaling_modifier //scale mod of 0 results in a number from 0 to 1. A scale modifier of +0.5 returns 0.5 to 1.5
//world<< "Transform multiplier of [src] is [size_factor + scaling_modifer]"
//to_chat(world, "Transform multiplier of [src] is [size_factor + scaling_modifer]")
+21 -13
View File
@@ -259,16 +259,12 @@ Proc for attack log creation, because really why not
living_target = target
if(is_mob_user)
var/message = "\[[time_stamp()]\] <font color='red'>[user ? "[user.name][(user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] has [what_done] [target ? "[target.name][(is_mob_target && target.ckey) ? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][(living_target) ? " (NEWHP: [living_target.health])" : ""][(attack_location) ? "([attack_location.x],[attack_location.y],[attack_location.z])" : ""]</font>"
user.attack_log += message
if(user.mind)
user.mind.attack_log += message
var/message = "<font color='red'>has [what_done] [target ? "[target.name][(is_mob_target && target.ckey) ? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][(living_target) ? " (NEWHP: [living_target.health])" : ""][(attack_location) ? "([attack_location.x],[attack_location.y],[attack_location.z])" : ""]</font>"
user.log_message(message, INDIVIDUAL_ATTACK_LOG)
if(is_mob_target)
var/message = "\[[time_stamp()]\] <font color='orange'>[target ? "[target.name][(target.ckey) ? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] has been [what_done] by [user ? "[user.name][(is_mob_user && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][(living_target) ? " (NEWHP: [living_target.health])" : ""][(attack_location) ? "([attack_location.x],[attack_location.y],[attack_location.z])" : ""]</font>"
target.attack_log += message
if(target.mind)
target.mind.attack_log += message
var/message = "<font color='orange'>has been [what_done] by [user ? "[user.name][(is_mob_user && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][(living_target) ? " (NEWHP: [living_target.health])" : ""][(attack_location) ? "([attack_location.x],[attack_location.y],[attack_location.z])" : ""]</font>"
target.log_message(message, INDIVIDUAL_ATTACK_LOG)
log_attack("[user ? "[user.name][(is_mob_user && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] [what_done] [target ? "[target.name][(is_mob_target && target.ckey)? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][(living_target) ? " (NEWHP: [living_target.health])" : ""][(attack_location) ? "([attack_location.x],[attack_location.y],[attack_location.z])" : ""]")
@@ -450,7 +446,7 @@ Proc for attack log creation, because really why not
for(var/i in 1 to step_count)
step(X, pick(NORTH, SOUTH, EAST, WEST))
/proc/deadchat_broadcast(message, mob/follow_target=null, speaker_key=null, message_type=DEADCHAT_REGULAR)
/proc/deadchat_broadcast(message, mob/follow_target=null, turf/turf_target=null, speaker_key=null, message_type=DEADCHAT_REGULAR)
for(var/mob/M in player_list)
var/datum/preferences/prefs
if(M.client && M.client.prefs)
@@ -476,8 +472,20 @@ Proc for attack log creation, because really why not
if(prefs.toggles & DISABLE_ARRIVALRATTLE)
continue
if(isobserver(M) && follow_target)
var/link = FOLLOW_LINK(M, follow_target)
M << "[link] [message]"
if(isobserver(M))
var/rendered_message = message
if(follow_target)
var/F
if(turf_target)
F = FOLLOW_OR_TURF_LINK(M, follow_target, turf_target)
else
F = FOLLOW_LINK(M, follow_target)
rendered_message = "[F] [message]"
else if(turf_target)
var/turf_link = TURF_LINK(M, turf_target)
rendered_message = "[turf_link] [message]"
to_chat(M, rendered_message)
else
M << "[message]"
to_chat(M, message)
+28 -11
View File
@@ -1,3 +1,5 @@
#define ION_FILE "ion_laws.json"
/proc/lizard_name(gender)
if(gender == MALE)
return "[pick(lizard_names_male)]-[pick(lizard_names_male)]"
@@ -170,12 +172,16 @@ var/syndicate_code_response//Code response for traitors.
25; 5
)
var/safety[] = list(1,2,3)//Tells the proc which options to remove later on.
var/nouns[] = list("love","hate","anger","peace","pride","sympathy","bravery","loyalty","honesty","integrity","compassion","charity","success","courage","deceit","skill","beauty","brilliance","pain","misery","beliefs","dreams","justice","truth","faith","liberty","knowledge","thought","information","culture","trust","dedication","progress","education","hospitality","leisure","trouble","friendships", "relaxation")
var/drinks[] = list("vodka and tonic","gin fizz","bahama mama","manhattan","black Russian","whiskey soda","long island iced tea","margarita","Irish coffee"," manly dwarf","Irish cream","doctor's delight","Beepksy Smash","tequila sunrise","brave bull","gargle blaster","bloody mary","whiskey cola","white Russian","vodka martini","martini","Cuba libre","kahlua","vodka","wine","moonshine")
var/locations[] = teleportlocs.len ? teleportlocs : drinks//if null, defaults to drinks instead.
var/list/safety = list(1,2,3)//Tells the proc which options to remove later on.
var/nouns = strings(ION_FILE, "ionabstract")
var/objects = strings(ION_FILE, "ionobjects")
var/adjectives = strings(ION_FILE, "ionadjectives")
var/threats = strings(ION_FILE, "ionthreats")
var/foods = strings(ION_FILE, "ionfood")
var/drinks = strings(ION_FILE, "iondrinks")
var/list/locations = teleportlocs.len ? teleportlocs : drinks //if null, defaults to drinks instead.
var/names[] = list()
var/list/names = list()
for(var/datum/data/record/t in data_core.general)//Picks from crew manifest.
names += t.fields["name"]
@@ -205,23 +211,34 @@ var/syndicate_code_response//Code response for traitors.
code_phrase += pick(get_all_jobs())//Returns a job.
safety -= 1
if(2)
switch(rand(1,2))//Places or things.
switch(rand(1,3))//Food, drinks, or things. Only selectable once.
if(1)
code_phrase += pick(drinks)
code_phrase += lowertext(pick(drinks))
if(2)
code_phrase += lowertext(pick(foods))
if(3)
code_phrase += pick(locations)
safety -= 2
if(3)
switch(rand(1,3))//Nouns, adjectives, verbs. Can be selected more than once.
switch(rand(1,4))//Abstract nouns, objects, adjectives, threats. Can be selected more than once.
if(1)
code_phrase += pick(nouns)
code_phrase += lowertext(pick(nouns))
if(2)
code_phrase += pick(adjectives)
code_phrase += lowertext(pick(objects))
if(3)
code_phrase += pick(verbs)
code_phrase += lowertext(pick(adjectives))
if(4)
code_phrase += lowertext(pick(threats))
if(words==1)
code_phrase += "."
else
code_phrase += ", "
return code_phrase
/proc/change_station_name(designation)
if(config && config.server_name)
world.name = "[config.server_name]: [designation]"
else
world.name = designation
station_name = designation
+59 -3
View File
@@ -14,8 +14,8 @@
*/
// Run all strings to be used in an SQL query through this proc first to properly escape out injection attempts.
/proc/sanitizeSQL(t as text)
var/sqltext = dbcon.Quote(t);
/proc/sanitizeSQL(t)
var/sqltext = dbcon.Quote("[t]");
return copytext(sqltext, 2, lentext(sqltext));//Quote() adds quotes around input, we already do that
/proc/format_table_name(table as text)
@@ -553,4 +553,60 @@ var/list/binary = list("0","1")
var/list/tosend = list()
tosend["data"] = finalized
log << json_encode(tosend)
log << json_encode(tosend)
//Used for applying byonds text macros to strings that are loaded at runtime
/proc/apply_text_macros(string)
var/next_backslash = findtext(string, "\\")
if(!next_backslash)
return string
var/leng = length(string)
var/next_space = findtext(string, " ", next_backslash + 1)
if(!next_space)
next_space = leng - next_backslash
if(!next_space) //trailing bs
return string
var/base = next_backslash == 1 ? "" : copytext(string, 1, next_backslash)
var/macro = lowertext(copytext(string, next_backslash + 1, next_space))
var/rest = next_backslash > leng ? "" : copytext(string, next_space + 1)
//See http://www.byond.com/docs/ref/info.html#/DM/text/macros
switch(macro)
//prefixes/agnostic
if("the")
rest = text("\the []", rest)
if("a")
rest = text("\a []", rest)
if("an")
rest = text("\an []", rest)
if("proper")
rest = text("\proper []", rest)
if("improper")
rest = text("\improper []", rest)
if("roman")
rest = text("\roman []", rest)
//postfixes
if("th")
base = text("[]\th", rest)
if("s")
base = text("[]\s", rest)
if("he")
base = text("[]\he", rest)
if("she")
base = text("[]\she", rest)
if("his")
base = text("[]\his", rest)
if("himself")
base = text("[]\himself", rest)
if("herself")
base = text("[]\herself", rest)
if("hers")
base = text("[]\hers", rest)
. = base
if(rest)
. += .(rest)
+3 -2
View File
@@ -2,8 +2,9 @@
/proc/worldtime2text()
return gameTimestamp("hh:mm:ss")
/proc/time_stamp(format = "hh:mm:ss")
return time2text(world.timeofday, format)
/proc/time_stamp(format = "hh:mm:ss", show_ds)
var/time_string = time2text(world.timeofday, format)
return show_ds ? "[time_string]:[world.timeofday % 10]" : time_string
/proc/gameTimestamp(format = "hh:mm:ss") // Get the game time in text
return time2text(world.time - timezoneOffset + 432000 - round_start_time, format)
+61 -28
View File
@@ -186,15 +186,17 @@ Turf and target are seperate in case you want to teleport some distance from a t
return 1
//Generalised helper proc for letting mobs rename themselves. Used to be clname() and ainame()
/mob/proc/rename_self(role)
/mob/proc/rename_self(role, client/C)
if(!C)
C = client
var/oldname = real_name
var/newname
var/loop = 1
var/safety = 0
while(loop && safety < 5)
if(client && client.prefs.custom_names[role] && !safety)
newname = client.prefs.custom_names[role]
if(C && C.prefs.custom_names[role] && !safety)
newname = C.prefs.custom_names[role]
else
switch(role)
if("clown")
@@ -329,7 +331,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
moblist.Add(M)
for(var/mob/dead/observer/M in sortmob)
moblist.Add(M)
for(var/mob/new_player/M in sortmob)
for(var/mob/dead/new_player/M in sortmob)
moblist.Add(M)
for(var/mob/living/carbon/monkey/M in sortmob)
moblist.Add(M)
@@ -719,11 +721,12 @@ Turf and target are seperate in case you want to teleport some distance from a t
var/pixel_y_offset = AM.pixel_y + M.get_y_shift()
//Irregular objects
if(AM.bound_height != world.icon_size || AM.bound_width != world.icon_size)
var/icon/AMicon = icon(AM.icon, AM.icon_state)
var/icon/AMicon = icon(AM.icon, AM.icon_state)
var/icon/AMiconheight = AMicon.Height()
var/icon/AMiconwidth = AMicon.Width()
if(AMiconheight != world.icon_size || AMiconwidth != world.icon_size)
pixel_x_offset += ((AMicon.Width()/world.icon_size)-1)*(world.icon_size*0.5)
pixel_y_offset += ((AMicon.Height()/world.icon_size)-1)*(world.icon_size*0.5)
qdel(AMicon)
//DY and DX
var/rough_x = round(round(pixel_x_offset,world.icon_size)/world.icon_size)
@@ -731,6 +734,8 @@ Turf and target are seperate in case you want to teleport some distance from a t
//Find coordinates
var/turf/T = get_turf(AM) //use AM's turfs, as it's coords are the same as AM's AND AM's coords are lost if it is inside another atom
if(!T)
return null
var/final_x = T.x + rough_x
var/final_y = T.y + rough_y
@@ -832,20 +837,20 @@ var/list/WALLITEMS_INVERSE = typecacheof(list(
var/pressure = air_contents.return_pressure()
var/total_moles = air_contents.total_moles()
user << "<span class='notice'>Results of analysis of \icon[icon] [target].</span>"
to_chat(user, "<span class='notice'>Results of analysis of \icon[icon] [target].</span>")
if(total_moles>0)
user << "<span class='notice'>Pressure: [round(pressure,0.1)] kPa</span>"
to_chat(user, "<span class='notice'>Pressure: [round(pressure,0.1)] kPa</span>")
var/list/cached_gases = air_contents.gases
for(var/id in cached_gases)
var/gas_concentration = cached_gases[id][MOLES]/total_moles
if(id in hardcoded_gases || gas_concentration > 0.001) //ensures the four primary gases are always shown.
user << "<span class='notice'>[cached_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] %</span>"
to_chat(user, "<span class='notice'>[cached_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] %</span>")
user << "<span class='notice'>Temperature: [round(air_contents.temperature-T0C)] &deg;C</span>"
to_chat(user, "<span class='notice'>Temperature: [round(air_contents.temperature-T0C)] &deg;C</span>")
else
user << "<span class='notice'>[target] is empty!</span>"
to_chat(user, "<span class='notice'>[target] is empty!</span>")
return
/proc/check_target_facings(mob/living/initator, mob/living/target)
@@ -919,19 +924,6 @@ var/list/WALLITEMS_INVERSE = typecacheof(list(
return !QDELETED(D)
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
@@ -943,8 +935,8 @@ var/list/WALLITEMS_INVERSE = typecacheof(list(
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)
var/clockwise_A_dir = turn(A.dir, -45)
var/anticlockwise_A_dir = turn(B.dir, 45)
if(A.dir == goal_dir || clockwise_A_dir == goal_dir || anticlockwise_A_dir == goal_dir)
return 1
@@ -1321,6 +1313,42 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types())
else
. = ""
/var/mob/dview/dview_mob = new
//Version of view() which ignores darkness, because BYOND doesn't have it (I actually suggested it but it was tagged redundant, BUT HEARERS IS A T- /rant).
/proc/dview(var/range = world.view, var/center, var/invis_flags = 0)
if(!center)
return
dview_mob.loc = center
dview_mob.see_invisible = invis_flags
. = view(range, dview_mob)
dview_mob.loc = null
/mob/dview
invisibility = 101
density = 0
see_in_dark = 1e6
anchored = 1
/mob/dview/Destroy(force=0)
stack_trace("ALRIGHT WHICH FUCKER TRIED TO DELETE *MY* DVIEW?")
if (!force)
return QDEL_HINT_LETMELIVE
world.log << "EVACUATE THE SHITCODE IS TRYING TO STEAL MUH JOBS"
global.dview_mob = new
return QDEL_HINT_QUEUE
#define FOR_DVIEW(type, range, center, invis_flags) \
dview_mob.loc = center; \
dview_mob.see_invisible = invis_flags; \
for(type in view(range, dview_mob))
//can a window be here, or is there a window blocking it?
/proc/valid_window_location(turf/T, dir_to_check)
if(!T)
@@ -1371,7 +1399,7 @@ var/valid_HTTPSGet = FALSE
\______(_______;;; __;;;
*/
var/temp_file = "HTTPSGetOutput.txt"
var/command
var/command
if(world.system_type == MS_WINDOWS)
command = "powershell -Command \"wget [url] -OutFile [temp_file]\""
else if(world.system_type == UNIX)
@@ -1393,3 +1421,8 @@ var/valid_HTTPSGet = FALSE
. = file2text(f)
f = null
fdel(temp_file)
#define UNTIL(X) while(!(X)) stoplag()
/proc/to_chat(target, message)
target << message