mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-31 00:58:26 +01:00
Merge pull request #3053 from ChuckTheSheep/Recursive-Fixes-and-Deaf-Bug-Fix
Fixes Deaf Bug and Recursive stuff
This commit is contained in:
+391
-403
@@ -1,403 +1,391 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
|
||||
|
||||
/proc/get_area(O)
|
||||
var/atom/location = O
|
||||
var/i
|
||||
for(i=1, i<=20, i++)
|
||||
if(isarea(location))
|
||||
return location
|
||||
else if (istype(location))
|
||||
location = location.loc
|
||||
else
|
||||
return null
|
||||
return 0
|
||||
|
||||
/proc/get_area_master(O)
|
||||
var/area/A = get_area(O)
|
||||
if(A && A.master)
|
||||
A = A.master
|
||||
return A
|
||||
|
||||
/proc/get_area_name(N) //get area by its name
|
||||
for(var/area/A in world)
|
||||
if(A.name == N)
|
||||
return A
|
||||
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/alone_in_area(var/area/the_area, var/mob/must_be_alone, var/check_type = /mob/living/carbon)
|
||||
var/area/our_area = get_area_master(the_area)
|
||||
for(var/C in living_mob_list)
|
||||
if(!istype(C, check_type))
|
||||
continue
|
||||
if(C == must_be_alone)
|
||||
continue
|
||||
if(our_area == get_area_master(C))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
//Magic constants obtained by using linear regression on right-angled triangles of sides 0<x<1, 0<y<1
|
||||
//They should approximate pythagoras theorem well enough for our needs.
|
||||
#define k1 0.934
|
||||
#define k2 0.427
|
||||
/proc/cheap_hypotenuse(Ax,Ay,Bx,By) // T is just the second atom to check distance to center with
|
||||
var/dx = abs(Ax - Bx) //sides of right-angled triangle
|
||||
var/dy = abs(Ay - By)
|
||||
if(dx>=dy) return (k1*dx) + (k2*dy) //No sqrt or powers :)
|
||||
else return (k2*dx) + (k1*dy)
|
||||
#undef k1
|
||||
#undef k2
|
||||
|
||||
/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/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
|
||||
|
||||
// Better recursive loop, technically sort of not actually recursive cause that shit is retarded, enjoy.
|
||||
//No need for a recursive limit either
|
||||
|
||||
|
||||
proc/recursive_mob_check(var/atom/O, var/client_check=1, var/sight_check=1, var/include_radio=1)
|
||||
|
||||
var/list/processing_list = list(O)
|
||||
var/list/processed_list = list()
|
||||
var/list/found_mobs = list()
|
||||
|
||||
if(!O.contents.len)
|
||||
return found_mobs
|
||||
|
||||
while(processing_list.len)
|
||||
|
||||
var/atom/A = processing_list[1]
|
||||
|
||||
var/passed = 1
|
||||
|
||||
if(ismob(A))
|
||||
var/mob/A_tmp = A
|
||||
|
||||
if(client_check && !A_tmp.client)
|
||||
passed=0
|
||||
|
||||
if(A_tmp && sight_check && !isInSight(A_tmp, O))
|
||||
passed=0
|
||||
|
||||
else if(include_radio && istype(A, /obj/item/device/radio))
|
||||
if(sight_check && !isInSight(A, O))
|
||||
passed=0
|
||||
|
||||
else passed = 0
|
||||
|
||||
if(passed)
|
||||
if(!(A in found_mobs)) found_mobs += A
|
||||
|
||||
for(var/atom/B in A)
|
||||
if(!(B in processed_list) && (istype(A, /obj/item/device/radio)||ismob(B)) )
|
||||
processing_list += B
|
||||
|
||||
processing_list-=A
|
||||
processed_list += A
|
||||
|
||||
return found_mobs
|
||||
|
||||
|
||||
|
||||
/proc/get_mobs_in_view(var/R, var/atom/source)
|
||||
// Returns a list of mobs in range of R from source. Used in radio and say code.
|
||||
|
||||
var/turf/T = get_turf(source)
|
||||
var/list/hear = list()
|
||||
|
||||
if(!T)
|
||||
return hear
|
||||
|
||||
var/list/range = hear(R, T)
|
||||
|
||||
for(var/atom/A in range)
|
||||
|
||||
/*if(ismob(A))
|
||||
var/mob/M = A
|
||||
if(M.client)
|
||||
hear += M
|
||||
//world.log << "Start = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])"
|
||||
else if(istype(A, /obj/item/device/radio))
|
||||
hear += A*/
|
||||
|
||||
if(isobj(A) || ismob(A))
|
||||
hear += recursive_mob_check(A, 1, 0, 1)
|
||||
|
||||
return hear
|
||||
|
||||
|
||||
|
||||
/proc/get_mobs_in_radio_ranges(var/list/obj/item/device/radio/radios)
|
||||
|
||||
set background = BACKGROUND_ENABLED
|
||||
|
||||
. = list()
|
||||
// Returns a list of mobs who can hear any of the radios given in @radios
|
||||
var/list/speaker_coverage = list()
|
||||
for(var/i = 1; i <= radios.len; i++)
|
||||
var/obj/item/device/radio/R = radios[i]
|
||||
if(R)
|
||||
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)
|
||||
if(speaker_coverage[ear])
|
||||
. |= M
|
||||
return .
|
||||
|
||||
#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<X2)
|
||||
b+=m
|
||||
while(X1!=X2 || Y1!=Y2)
|
||||
if(round(m*X1+b-Y1))
|
||||
Y1+=signY //Line exits tile vertically
|
||||
else
|
||||
X1+=signX //Line exits tile horizontally
|
||||
T=locate(X1,Y1,Z)
|
||||
if(T.opacity)
|
||||
return 0
|
||||
return 1
|
||||
#undef SIGN
|
||||
|
||||
proc/isInSight(var/atom/A, var/atom/B)
|
||||
var/turf/Aturf = get_turf(A)
|
||||
var/turf/Bturf = get_turf(B)
|
||||
|
||||
if(!Aturf || !Bturf)
|
||||
return 0
|
||||
|
||||
if(inLineOfSight(Aturf.x,Aturf.y, Bturf.x,Bturf.y,Aturf.z))
|
||||
return 1
|
||||
|
||||
else
|
||||
return 0
|
||||
|
||||
/proc/get_cardinal_step_away(atom/start, atom/finish) //returns the position of a step from start away from finish, in one of the cardinal directions
|
||||
//returns only NORTH, SOUTH, EAST, or WEST
|
||||
var/dx = finish.x - start.x
|
||||
var/dy = finish.y - start.y
|
||||
if(abs(dy) > 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/try_move_adjacent(atom/movable/AM)
|
||||
var/turf/T = get_turf(AM)
|
||||
for(var/direction in cardinal)
|
||||
if(AM.Move(get_step(T, direction)))
|
||||
break
|
||||
|
||||
/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_candidates(be_special_flag=0, afk_bracket=3000)
|
||||
var/list/candidates = list()
|
||||
// Keep looping until we find a non-afk candidate within the time bracket (we limit the bracket to 10 minutes (6000))
|
||||
while(!candidates.len && afk_bracket < 6000)
|
||||
for(var/mob/dead/observer/G in player_list)
|
||||
if(G.client != null)
|
||||
if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
|
||||
if(!G.client.is_afk(afk_bracket) && (G.client.prefs.be_special & be_special_flag))
|
||||
candidates += G.client
|
||||
afk_bracket += 600 // Add a minute to the bracket, for every attempt
|
||||
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 = clients
|
||||
for(var/client/C in group)
|
||||
C.screen += O
|
||||
if(delay)
|
||||
spawn(delay)
|
||||
for(var/client/C in group)
|
||||
C.screen -= O
|
||||
|
||||
/proc/flick_overlay(image/I, list/show_to, duration)
|
||||
for(var/client/C in show_to)
|
||||
C.images += I
|
||||
sleep(duration)
|
||||
for(var/client/C in show_to)
|
||||
C.images -= I
|
||||
|
||||
/proc/get_active_player_count()
|
||||
// Get active players who are playing in the round
|
||||
var/active_players = 0
|
||||
for(var/i = 1; i <= player_list.len; i++)
|
||||
var/mob/M = player_list[i]
|
||||
if(M && M.client)
|
||||
if(istype(M, /mob/new_player)) // exclude people in the lobby
|
||||
continue
|
||||
else if(isobserver(M)) // Ghosts are fine if they were playing once (didn't start as observers)
|
||||
var/mob/dead/observer/O = M
|
||||
if(O.started_as_observer) // Exclude people who started as observers
|
||||
continue
|
||||
active_players++
|
||||
return active_players
|
||||
|
||||
/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)
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
|
||||
|
||||
/proc/get_area(O)
|
||||
var/atom/location = O
|
||||
var/i
|
||||
for(i=1, i<=20, i++)
|
||||
if(isarea(location))
|
||||
return location
|
||||
else if (istype(location))
|
||||
location = location.loc
|
||||
else
|
||||
return null
|
||||
return 0
|
||||
|
||||
/proc/get_area_master(O)
|
||||
var/area/A = get_area(O)
|
||||
if(A && A.master)
|
||||
A = A.master
|
||||
return A
|
||||
|
||||
/proc/get_area_name(N) //get area by its name
|
||||
for(var/area/A in world)
|
||||
if(A.name == N)
|
||||
return A
|
||||
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/alone_in_area(var/area/the_area, var/mob/must_be_alone, var/check_type = /mob/living/carbon)
|
||||
var/area/our_area = get_area_master(the_area)
|
||||
for(var/C in living_mob_list)
|
||||
if(!istype(C, check_type))
|
||||
continue
|
||||
if(C == must_be_alone)
|
||||
continue
|
||||
if(our_area == get_area_master(C))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
//Magic constants obtained by using linear regression on right-angled triangles of sides 0<x<1, 0<y<1
|
||||
//They should approximate pythagoras theorem well enough for our needs.
|
||||
#define k1 0.934
|
||||
#define k2 0.427
|
||||
/proc/cheap_hypotenuse(Ax,Ay,Bx,By) // T is just the second atom to check distance to center with
|
||||
var/dx = abs(Ax - Bx) //sides of right-angled triangle
|
||||
var/dy = abs(Ay - By)
|
||||
if(dx>=dy) return (k1*dx) + (k2*dy) //No sqrt or powers :)
|
||||
else return (k2*dx) + (k1*dy)
|
||||
#undef k1
|
||||
#undef k2
|
||||
|
||||
/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/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
|
||||
|
||||
// Better recursive loop, technically sort of not actually recursive cause that shit is retarded, enjoy.
|
||||
//No need for a recursive limit either
|
||||
|
||||
|
||||
proc/recursive_mob_check(var/atom/O,var/client_check=1,var/sight_check=1,var/include_radio=1)
|
||||
|
||||
var/list/processing_list = list(O)
|
||||
var/list/processed_list = list()
|
||||
var/list/found_mobs = list()
|
||||
|
||||
while(processing_list.len)
|
||||
|
||||
var/atom/A = processing_list[1]
|
||||
var/passed = 0
|
||||
|
||||
if(ismob(A))
|
||||
var/mob/A_tmp = A
|
||||
passed=1
|
||||
|
||||
if(client_check && !A_tmp.client)
|
||||
passed=0
|
||||
|
||||
if(sight_check && !isInSight(A_tmp, O))
|
||||
passed=0
|
||||
|
||||
else if(include_radio && istype(A, /obj/item/device/radio))
|
||||
passed=1
|
||||
|
||||
if(sight_check && !isInSight(A, O))
|
||||
passed=0
|
||||
|
||||
if(passed)
|
||||
found_mobs |= A
|
||||
|
||||
for(var/atom/B in A)
|
||||
if(!(B in processed_list))
|
||||
processing_list |= B
|
||||
|
||||
processing_list -= A
|
||||
processed_list |= A
|
||||
|
||||
return found_mobs
|
||||
|
||||
|
||||
proc/get_mobs_in_view(var/R, var/atom/source)
|
||||
// Returns a list of mobs in range of R from source. Used in radio and say code.
|
||||
|
||||
var/turf/T = get_turf(source)
|
||||
var/list/hear = list()
|
||||
|
||||
if(!T)
|
||||
return hear
|
||||
|
||||
var/list/range = hear(R, T)
|
||||
|
||||
for(var/atom/A in range)
|
||||
|
||||
if(istype(A, /obj/item/device/radio) || ismob(A))
|
||||
hear |= recursive_mob_check(A, 1, 0, 1)
|
||||
|
||||
return hear
|
||||
|
||||
|
||||
|
||||
/proc/get_mobs_in_radio_ranges(var/list/obj/item/device/radio/radios)
|
||||
|
||||
set background = BACKGROUND_ENABLED
|
||||
|
||||
. = list()
|
||||
// Returns a list of mobs who can hear any of the radios given in @radios
|
||||
var/list/speaker_coverage = list()
|
||||
for(var/i = 1; i <= radios.len; i++)
|
||||
var/obj/item/device/radio/R = radios[i]
|
||||
if(R)
|
||||
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)
|
||||
if(speaker_coverage[ear])
|
||||
. |= M
|
||||
return .
|
||||
|
||||
#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<X2)
|
||||
b+=m
|
||||
while(X1!=X2 || Y1!=Y2)
|
||||
if(round(m*X1+b-Y1))
|
||||
Y1+=signY //Line exits tile vertically
|
||||
else
|
||||
X1+=signX //Line exits tile horizontally
|
||||
T=locate(X1,Y1,Z)
|
||||
if(T.opacity)
|
||||
return 0
|
||||
return 1
|
||||
#undef SIGN
|
||||
|
||||
proc/isInSight(var/atom/A, var/atom/B)
|
||||
var/turf/Aturf = get_turf(A)
|
||||
var/turf/Bturf = get_turf(B)
|
||||
|
||||
if(!Aturf || !Bturf)
|
||||
return 0
|
||||
|
||||
if(inLineOfSight(Aturf.x,Aturf.y, Bturf.x,Bturf.y,Aturf.z))
|
||||
return 1
|
||||
|
||||
else
|
||||
return 0
|
||||
|
||||
/proc/get_cardinal_step_away(atom/start, atom/finish) //returns the position of a step from start away from finish, in one of the cardinal directions
|
||||
//returns only NORTH, SOUTH, EAST, or WEST
|
||||
var/dx = finish.x - start.x
|
||||
var/dy = finish.y - start.y
|
||||
if(abs(dy) > 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/try_move_adjacent(atom/movable/AM)
|
||||
var/turf/T = get_turf(AM)
|
||||
for(var/direction in cardinal)
|
||||
if(AM.Move(get_step(T, direction)))
|
||||
break
|
||||
|
||||
/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_candidates(be_special_flag=0, afk_bracket=3000)
|
||||
var/list/candidates = list()
|
||||
// Keep looping until we find a non-afk candidate within the time bracket (we limit the bracket to 10 minutes (6000))
|
||||
while(!candidates.len && afk_bracket < 6000)
|
||||
for(var/mob/dead/observer/G in player_list)
|
||||
if(G.client != null)
|
||||
if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
|
||||
if(!G.client.is_afk(afk_bracket) && (G.client.prefs.be_special & be_special_flag))
|
||||
candidates += G.client
|
||||
afk_bracket += 600 // Add a minute to the bracket, for every attempt
|
||||
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 = clients
|
||||
for(var/client/C in group)
|
||||
C.screen += O
|
||||
if(delay)
|
||||
spawn(delay)
|
||||
for(var/client/C in group)
|
||||
C.screen -= O
|
||||
|
||||
/proc/flick_overlay(image/I, list/show_to, duration)
|
||||
for(var/client/C in show_to)
|
||||
C.images += I
|
||||
sleep(duration)
|
||||
for(var/client/C in show_to)
|
||||
C.images -= I
|
||||
|
||||
/proc/get_active_player_count()
|
||||
// Get active players who are playing in the round
|
||||
var/active_players = 0
|
||||
for(var/i = 1; i <= player_list.len; i++)
|
||||
var/mob/M = player_list[i]
|
||||
if(M && M.client)
|
||||
if(istype(M, /mob/new_player)) // exclude people in the lobby
|
||||
continue
|
||||
else if(isobserver(M)) // Ghosts are fine if they were playing once (didn't start as observers)
|
||||
var/mob/dead/observer/O = M
|
||||
if(O.started_as_observer) // Exclude people who started as observers
|
||||
continue
|
||||
active_players++
|
||||
return active_players
|
||||
|
||||
/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)
|
||||
@@ -256,7 +256,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
if(R) R.fields["name"] = newname
|
||||
|
||||
//update our pda and id if we have them on our person
|
||||
var/list/searching = GetAllContents(3)
|
||||
var/list/searching = GetAllContents()
|
||||
var/search_id = 1
|
||||
var/search_pda = 1
|
||||
|
||||
@@ -596,7 +596,6 @@ proc/anim(turf/location as turf,target as mob|obj,a_icon,a_icon_state as text,fl
|
||||
|
||||
atom/proc/GetAllContents()
|
||||
var/list/processing_list = list(src)
|
||||
var/list/processed = list()
|
||||
var/list/assembled = list()
|
||||
|
||||
while(processing_list.len)
|
||||
@@ -604,14 +603,14 @@ atom/proc/GetAllContents()
|
||||
processing_list -= A
|
||||
|
||||
for(var/atom/a in A)
|
||||
if(!(a in processed))
|
||||
processing_list += a
|
||||
if(!(a in assembled))
|
||||
processing_list |= a
|
||||
|
||||
if(!(A in assembled))
|
||||
assembled += A
|
||||
assembled |= A
|
||||
|
||||
return assembled
|
||||
|
||||
|
||||
atom/proc/GetTypeInAllContents(typepath)
|
||||
var/list/processing_list = list(src)
|
||||
var/list/processed = list()
|
||||
@@ -627,10 +626,9 @@ atom/proc/GetTypeInAllContents(typepath)
|
||||
|
||||
for(var/atom/a in A)
|
||||
if(!(a in processed))
|
||||
processing_list += a
|
||||
processing_list |= a
|
||||
|
||||
if(!(A in processed))
|
||||
processed += A
|
||||
processed |= A
|
||||
|
||||
return found
|
||||
|
||||
@@ -1288,4 +1286,4 @@ proc/check_target_facings(mob/living/initator, mob/living/target)
|
||||
if(initator.dir + 4 == target.dir || initator.dir - 4 == target.dir) //mobs are facing each other
|
||||
return 2
|
||||
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 3
|
||||
Reference in New Issue
Block a user