From 342927d54dd8af47936d790678d8cb915e59fc10 Mon Sep 17 00:00:00 2001 From: ChuckTheSheep Date: Tue, 11 Mar 2014 23:56:48 -0400 Subject: [PATCH] Fixes Deaf Bug and Recursive stuff --- code/__HELPERS/game.dm | 794 ++++++++++++++++++------------------- code/__HELPERS/unsorted.dm | 18 +- 2 files changed, 399 insertions(+), 413 deletions(-) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index a11ae456196..226f17d1dcb 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -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=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 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=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 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) \ No newline at end of file diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 9af5088107d..c29a796a39a 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -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 \ No newline at end of file