//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 /proc/dopage(src,target) var/href_list var/href href_list = params2list("src=\ref[src]&[target]=1") href = "src=\ref[src];[target]=1" src:temphtml = null src:Topic(href, href_list) return null /proc/is_on_same_plane_or_station(var/z1, var/z2) if(z1 == z2) return 1 if((z1 in using_map.station_levels) && (z2 in using_map.station_levels)) return 1 return 0 /proc/max_default_z_level() var/max_z = 0 for(var/z in using_map.station_levels) max_z = max(z, max_z) for(var/z in using_map.admin_levels) max_z = max(z, max_z) for(var/z in using_map.player_levels) max_z = max(z, max_z) return max_z /proc/get_area(atom/A) if(isarea(A)) return A var/turf/T = get_turf(A) return T ? T.loc : null /proc/get_area_name(atom/X, format_text = FALSE) var/area/A = isarea(X) ? X : get_area(X) if(!A) return null return format_text ? format_text(A.name) : A.name /proc/get_area_master(const/O) var/area/A = get_area(O) if (isarea(A)) return A /** Checks if any living humans are in a given area. */ /proc/area_is_occupied(var/area/myarea) // Testing suggests looping over human_mob_list is quicker than looping over area contents for(var/mob/living/carbon/human/H in human_mob_list) if(H.stat >= DEAD) //Conditions for exclusion here, like if disconnected people start blocking it. continue var/area/A = get_area(H) if(A == myarea) //The loc of a turf is the area it is in. return 1 return 0 /proc/in_range(source, user) if(get_dist(source, user) <= 1) return 1 return 0 //not in range and not telekinetic // Like view but bypasses luminosity check /proc/hear(var/range, var/atom/source) var/lum = source.luminosity source.luminosity = 6 var/list/heard = view(range, source) source.luminosity = lum return heard /proc/isStationLevel(var/level) return level in using_map.station_levels /proc/isNotStationLevel(var/level) return !isStationLevel(level) /proc/isPlayerLevel(var/level) return level in using_map.player_levels /proc/isAdminLevel(var/level) return level in using_map.admin_levels /proc/isNotAdminLevel(var/level) return !isAdminLevel(level) /proc/circlerange(center=usr,radius=3) var/turf/centerturf = get_turf(center) var/list/turfs = new/list() var/rsq = radius * (radius+0.5) for(var/atom/T in range(radius, centerturf)) var/dx = T.x - centerturf.x var/dy = T.y - centerturf.y if(dx*dx + dy*dy <= rsq) turfs += T //turfs += centerturf return turfs /proc/circleview(center=usr,radius=3) var/turf/centerturf = get_turf(center) var/list/atoms = new/list() var/rsq = radius * (radius+0.5) for(var/atom/A in view(radius, centerturf)) var/dx = A.x - centerturf.x var/dy = A.y - centerturf.y if(dx*dx + dy*dy <= rsq) atoms += A //turfs += centerturf return atoms /proc/trange(rad = 0, turf/centre = null) //alternative to range (ONLY processes turfs and thus less intensive) if(!centre) return var/turf/x1y1 = locate(((centre.x-rad)<1 ? 1 : centre.x-rad),((centre.y-rad)<1 ? 1 : centre.y-rad),centre.z) var/turf/x2y2 = locate(((centre.x+rad)>world.maxx ? world.maxx : centre.x+rad),((centre.y+rad)>world.maxy ? world.maxy : centre.y+rad),centre.z) return block(x1y1,x2y2) /proc/get_dist_euclidian(atom/Loc1 as turf|mob|obj,atom/Loc2 as turf|mob|obj) var/dx = Loc1.x - Loc2.x var/dy = Loc1.y - Loc2.y var/dist = sqrt(dx**2 + dy**2) return dist /proc/circlerangeturfs(center=usr,radius=3) var/turf/centerturf = get_turf(center) var/list/turfs = new/list() var/rsq = radius * (radius+0.5) for(var/turf/T in range(radius, centerturf)) var/dx = T.x - centerturf.x var/dy = T.y - centerturf.y if(dx*dx + dy*dy <= rsq) turfs += T return turfs /proc/circleviewturfs(center=usr,radius=3) //Is there even a diffrence between this proc and circlerangeturfs()? var/turf/centerturf = get_turf(center) var/list/turfs = new/list() var/rsq = radius * (radius+0.5) for(var/turf/T in view(radius, centerturf)) var/dx = T.x - centerturf.x var/dy = T.y - centerturf.y if(dx*dx + dy*dy <= rsq) turfs += T return turfs //var/debug_mob = 0 // Will recursively loop through an atom's contents and check for mobs, then it will loop through every atom in that atom's contents. // It will keep doing this until it checks every content possible. This will fix any problems with mobs, that are inside objects, // being unable to hear people due to being in a box within a bag. /proc/recursive_content_check(var/atom/O, var/list/L = list(), var/recursion_limit = 3, var/client_check = 1, var/sight_check = 1, var/include_mobs = 1, var/include_objects = 1, var/ignore_show_messages = 0) if(!recursion_limit) return L for(var/I in O.contents) if(ismob(I)) if(!sight_check || isInSight(I, O)) L |= recursive_content_check(I, L, recursion_limit - 1, client_check, sight_check, include_mobs, include_objects) if(include_mobs) if(client_check) var/mob/M = I if(M.client) L |= M else L |= I else if(istype(I,/obj/)) var/obj/check_obj = I if(ignore_show_messages || check_obj.show_messages) if(!sight_check || isInSight(I, O)) L |= recursive_content_check(I, L, recursion_limit - 1, client_check, sight_check, include_mobs, include_objects) if(include_objects) L |= I return L // Returns a list of mobs and/or objects in range of R from source. Used in radio and say code. /proc/get_mobs_or_objects_in_view(var/R, var/atom/source, var/include_mobs = 1, var/include_objects = 1) var/turf/T = get_turf(source) var/list/hear = list() if(!T) return hear var/list/range = hear(R, T) for(var/I in range) if(ismob(I)) hear |= recursive_content_check(I, hear, 3, 1, 0, include_mobs, include_objects) if(include_mobs) var/mob/M = I if(M.client) hear += M else if(istype(I,/obj/)) hear |= recursive_content_check(I, hear, 3, 1, 0, include_mobs, include_objects) var/obj/O = I if(O.show_messages && include_objects) hear += I return hear /proc/get_mobs_in_radio_ranges(var/list/obj/item/device/radio/radios) set background = 1 . = list() // Returns a list of mobs who can hear any of the radios given in @radios var/list/speaker_coverage = list() for(var/obj/item/device/radio/R in radios) if(R) //Cyborg checks. Receiving message uses a bit of cyborg's charge. var/obj/item/device/radio/borg/BR = R if(istype(BR) && BR.myborg) var/mob/living/silicon/robot/borg = BR.myborg var/datum/robot_component/CO = borg.get_component("radio") if(!CO) continue //No radio component (Shouldn't happen) if(!borg.is_component_functioning("radio") || !borg.cell_use_power(CO.active_usage)) continue //No power. var/turf/speaker = get_turf(R) if(speaker) for(var/turf/T in hear(R.canhear_range,speaker)) speaker_coverage[T] = T // Try to find all the players who can hear the message for(var/i = 1; i <= player_list.len; i++) var/mob/M = player_list[i] if(M) var/turf/ear = get_turf(M) if(ear) // Ghostship is magic: Ghosts can hear radio chatter from anywhere if(speaker_coverage[ear] || (istype(M, /mob/observer/dead) && M.is_preference_enabled(/datum/client_preference/ghost_radio))) . |= M // Since we're already looping through mobs, why bother using |= ? This only slows things down. return . //Uses dview to quickly return mobs and objects in view, // then adds additional mobs or objects if they are in range 'smartly', // based on their presence in lists of players or registered objects // Type: 1-audio, 2-visual, 0-neither /proc/get_mobs_and_objs_in_view_fast(var/turf/T, var/range, var/type = 1, var/remote_ghosts = TRUE) var/list/mobs = list() var/list/objs = list() var/list/hear = dview(range,T,INVISIBILITY_MAXIMUM) var/list/hearturfs = list() for(var/thing in hear) if(istype(thing,/obj)) objs += thing hearturfs |= get_turf(thing) else if(istype(thing,/mob)) mobs += thing hearturfs |= get_turf(thing) //A list of every mob with a client for(var/mob in player_list) //VOREStation Edit - Trying to fix some vorestation bug. if(!istype(mob, /mob)) player_list -= mob crash_with("There is a null or non-mob reference inside player_list ([mob]).") continue //VOREStation Edit End - Trying to fix some vorestation bug. if(get_turf(mob) in hearturfs) mobs |= mob continue var/mob/M = mob if(M && M.stat == DEAD && remote_ghosts && !M.forbid_seeing_deadchat) switch(type) if(1) //Audio messages use ghost_ears if(M.is_preference_enabled(/datum/client_preference/ghost_ears)) mobs |= M if(2) //Visual messages use ghost_sight if(M.is_preference_enabled(/datum/client_preference/ghost_sight)) mobs |= M //For objects below the top level who still want to hear for(var/obj in listening_objects) if(get_turf(obj) in hearturfs) objs |= obj return list("mobs" = mobs, "objs" = objs) #define SIGN(X) ((X<0)?-1:1) proc inLineOfSight(X1,Y1,X2,Y2,Z=1,PX1=16.5,PY1=16.5,PX2=16.5,PY2=16.5) var/turf/T if(X1==X2) if(Y1==Y2) return 1 //Light cannot be blocked on same tile else var/s = SIGN(Y2-Y1) Y1+=s while(Y1!=Y2) T=locate(X1,Y1,Z) if(T.opacity) return 0 Y1+=s else var/m=(32*(Y2-Y1)+(PY2-PY1))/(32*(X2-X1)+(PX2-PX1)) var/b=(Y1+PY1/32-0.015625)-m*(X1+PX1/32-0.015625) //In tiles var/signX = SIGN(X2-X1) var/signY = SIGN(Y2-Y1) if(X1 abs (dx)) //slope is above 1:1 (move horizontally in a tie) if(dy > 0) return get_step(start, SOUTH) else return get_step(start, NORTH) else if(dx > 0) return get_step(start, WEST) else return get_step(start, EAST) /proc/get_mob_by_key(var/key) for(var/mob/M in mob_list) if(M.ckey == lowertext(key)) return M return null // Will return a list of active candidates. It increases the buffer 5 times until it finds a candidate which is active within the buffer. /proc/get_active_candidates(var/buffer = 1) var/list/candidates = list() //List of candidate KEYS to assume control of the new larva ~Carn var/i = 0 while(candidates.len <= 0 && i < 5) for(var/mob/observer/dead/G in player_list) if(((G.client.inactivity/10)/60) <= buffer + i) // the most active players are more likely to become an alien if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD)) candidates += G.key i++ return candidates // Same as above but for alien candidates. /proc/get_alien_candidates() var/list/candidates = list() //List of candidate KEYS to assume control of the new larva ~Carn var/i = 0 while(candidates.len <= 0 && i < 5) for(var/mob/observer/dead/G in player_list) if(G.client.prefs.be_special & BE_ALIEN) if(((G.client.inactivity/10)/60) <= ALIEN_SELECT_AFK_BUFFER + i) // the most active players are more likely to become an alien if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD)) candidates += G.key i++ return candidates /proc/ScreenText(obj/O, maptext="", screen_loc="CENTER-7,CENTER-7", maptext_height=480, maptext_width=480) if(!isobj(O)) O = new /obj/screen/text() O.maptext = maptext O.maptext_height = maptext_height O.maptext_width = maptext_width O.screen_loc = screen_loc return O /proc/Show2Group4Delay(obj/O, list/group, delay=0) if(!isobj(O)) return if(!group) group = GLOB.clients for(var/client/C in group) C.screen += O if(delay) spawn(delay) for(var/client/C in group) C.screen -= O datum/projectile_data var/src_x var/src_y var/time var/distance var/power_x var/power_y var/dest_x var/dest_y /datum/projectile_data/New(var/src_x, var/src_y, var/time, var/distance, \ var/power_x, var/power_y, var/dest_x, var/dest_y) src.src_x = src_x src.src_y = src_y src.time = time src.distance = distance src.power_x = power_x src.power_y = power_y src.dest_x = dest_x src.dest_y = dest_y /proc/projectile_trajectory(var/src_x, var/src_y, var/rotation, var/angle, var/power) // returns the destination (Vx,y) that a projectile shot at [src_x], [src_y], with an angle of [angle], // rotated at [rotation] and with the power of [power] // Thanks to VistaPOWA for this function var/power_x = power * cos(angle) var/power_y = power * sin(angle) var/time = 2* power_y / 10 //10 = g var/distance = time * power_x var/dest_x = src_x + distance*sin(rotation); var/dest_y = src_y + distance*cos(rotation); return new /datum/projectile_data(src_x, src_y, time, distance, power_x, power_y, dest_x, dest_y) /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)) /proc/GetHexColors(const/hexa) return list( GetRedPart(hexa), GetGreenPart(hexa), GetBluePart(hexa) ) /proc/MixColors(const/list/colors) var/list/reds = list() var/list/blues = list() var/list/greens = list() var/list/weights = list() for (var/i = 0, ++i <= colors.len) reds.Add(GetRedPart(colors[i])) blues.Add(GetBluePart(colors[i])) greens.Add(GetGreenPart(colors[i])) weights.Add(1) var/r = mixOneColor(weights, reds) var/g = mixOneColor(weights, greens) var/b = mixOneColor(weights, blues) return rgb(r,g,b) /proc/mixOneColor(var/list/weight, var/list/color) if (!weight || !color || length(weight)!=length(color)) return 0 var/contents = length(weight) var/i //normalize weights var/listsum = 0 for(i=1; i<=contents; i++) listsum += weight[i] for(i=1; i<=contents; i++) weight[i] /= listsum //mix them var/mixedcolor = 0 for(i=1; i<=contents; i++) mixedcolor += weight[i]*color[i] mixedcolor = round(mixedcolor) //until someone writes a formal proof for this algorithm, let's keep this in // if(mixedcolor<0x00 || mixedcolor>0xFF) // return 0 //that's not the kind of operation we are running here, nerd mixedcolor=min(max(mixedcolor,0),255) return mixedcolor /** * Gets the highest and lowest pressures from the tiles in cardinal directions * around us, then checks the difference. */ /proc/getOPressureDifferential(var/turf/loc) var/minp=16777216; var/maxp=0; for(var/dir in GLOB.cardinal) var/turf/simulated/T=get_turf(get_step(loc,dir)) var/cp=0 if(T && istype(T) && T.zone) var/datum/gas_mixture/environment = T.return_air() cp = environment.return_pressure() else if(istype(T,/turf/simulated)) continue if(cpmaxp)maxp=cp return abs(minp-maxp) /proc/convert_k2c(var/temp) return ((temp - T0C)) /proc/convert_c2k(var/temp) return ((temp + T0C)) /proc/getCardinalAirInfo(var/turf/loc, var/list/stats=list("temperature")) var/list/temps = new/list(4) for(var/dir in GLOB.cardinal) var/direction switch(dir) if(NORTH) direction = 1 if(SOUTH) direction = 2 if(EAST) direction = 3 if(WEST) direction = 4 var/turf/simulated/T=get_turf(get_step(loc,dir)) var/list/rstats = new /list(stats.len) if(T && istype(T) && T.zone) var/datum/gas_mixture/environment = T.return_air() for(var/i=1;i<=stats.len;i++) if(stats[i] == "pressure") rstats[i] = environment.return_pressure() else rstats[i] = environment.vars[stats[i]] else if(istype(T, /turf/simulated)) rstats = null // Exclude zone (wall, door, etc). else if(istype(T, /turf)) // Should still work. (/turf/return_air()) var/datum/gas_mixture/environment = T.return_air() for(var/i=1;i<=stats.len;i++) if(stats[i] == "pressure") rstats[i] = environment.return_pressure() else rstats[i] = environment.vars[stats[i]] temps[direction] = rstats return temps /proc/MinutesToTicks(var/minutes) return SecondsToTicks(60 * minutes) /proc/SecondsToTicks(var/seconds) return seconds * 10 /proc/window_flash(var/client_or_usr) if (!client_or_usr) return winset(client_or_usr, "mainwindow", "flash=5")