/tg/ 4/14 (#367)

* outside code stuff

* defines, helpers, etc

* everything not module

* modules

* compiled fixes + missing sounds
This commit is contained in:
Poojawa
2017-04-14 23:28:04 -05:00
committed by GitHub
parent 884fb45516
commit 9e72b1b8fd
170 changed files with 4916 additions and 1221 deletions
-181
View File
@@ -1,181 +0,0 @@
/*
A Star pathfinding algorithm
Returns a list of tiles forming a path from A to B, taking dense objects as well as walls, and the orientation of
windows along the route into account.
Use:
your_list = AStar(start location, end location, moving atom, distance proc, max nodes, maximum node depth, minimum distance to target, adjacent proc, atom id, turfs to exclude, check only simulated)
Optional extras to add on (in order):
Distance proc : the distance used in every A* calculation (length of path and heuristic)
MaxNodes: The maximum number of nodes the returned path can be (0 = infinite)
Maxnodedepth: The maximum number of nodes to search (default: 30, 0 = infinite)
Mintargetdist: Minimum distance to the target before path returns, could be used to get
near a target, but not right to it - for an AI mob with a gun, for example.
Adjacent proc : returns the turfs to consider around the actually processed node
Simulated only : whether to consider unsimulated turfs or not (used by some Adjacent proc)
Also added 'exclude' turf to avoid travelling over; defaults to null
Actual Adjacent procs :
/turf/proc/reachableAdjacentTurfs : returns reachable turfs in cardinal directions (uses simulated_only)
/turf/proc/reachableAdjacentAtmosTurfs : returns turfs in cardinal directions reachable via atmos
*/
//////////////////////
//PathNode object
//////////////////////
//A* nodes variables
/PathNode
var/turf/source //turf associated with the PathNode
var/PathNode/prevNode //link to the parent PathNode
var/f //A* Node weight (f = g + h)
var/g //A* movement cost variable
var/h //A* heuristic variable
var/nt //count the number of Nodes traversed
/PathNode/New(s,p,pg,ph,pnt)
source = s
prevNode = p
g = pg
h = ph
f = g + h
nt = pnt
/PathNode/proc/calc_f()
f = g + h
//////////////////////
//A* procs
//////////////////////
//the weighting function, used in the A* algorithm
/proc/PathWeightCompare(PathNode/a, PathNode/b)
return a.f - b.f
//reversed so that the Heap is a MinHeap rather than a MaxHeap
/proc/HeapPathWeightCompare(PathNode/a, PathNode/b)
return b.f - a.f
//wrapper that returns an empty list if A* failed to find a path
/proc/get_path_to(caller, end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableAdjacentTurfs, id=null, turf/exclude=null, simulated_only = 1)
var/list/path = AStar(caller, end, dist, maxnodes, maxnodedepth, mintargetdist, adjacent,id, exclude, simulated_only)
if(!path)
path = list()
return path
//the actual algorithm
/proc/AStar(caller, end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableAdjacentTurfs, id=null, turf/exclude=null, simulated_only = 1)
var/list/pnodelist = list()
//sanitation
var/start = get_turf(caller)
if(!start)
return 0
if(maxnodes)
//if start turf is farther than maxnodes from end turf, no need to do anything
if(call(start, dist)(end) > maxnodes)
return 0
maxnodedepth = maxnodes //no need to consider path longer than maxnodes
var/Heap/open = new /Heap(/proc/HeapPathWeightCompare) //the open list
var/list/closed = new() //the closed list
var/list/path = null //the returned path, if any
var/PathNode/cur //current processed turf
//initialization
open.Insert(new /PathNode(start,null,0,call(start,dist)(end),0))
//then run the main loop
while(!open.IsEmpty() && !path)
//get the lower f node on the open list
cur = open.Pop() //get the lower f turf in the open list
closed.Add(cur.source) //and tell we've processed it
//if we only want to get near the target, check if we're close enough
var/closeenough
if(mintargetdist)
closeenough = call(cur.source,dist)(end) <= mintargetdist
//if too many steps, abandon that path
if(maxnodedepth && (cur.nt > maxnodedepth))
continue
//found the target turf (or close enough), let's create the path to it
if(cur.source == end || closeenough)
path = new()
path.Add(cur.source)
while(cur.prevNode)
cur = cur.prevNode
path.Add(cur.source)
break
//get adjacents turfs using the adjacent proc, checking for access with id
var/list/L = call(cur.source,adjacent)(caller,id, simulated_only)
for(var/turf/T in L)
if(T == exclude || (T in closed))
continue
var/newg = cur.g + call(cur.source,dist)(T)
var/PathNode/P = pnodelist[T]
if(!P)
//is not already in open list, so add it
var/PathNode/newnode = new /PathNode(T,cur,newg,call(T,dist)(end),cur.nt+1)
open.Insert(newnode)
pnodelist[T] = newnode
else //is already in open list, check if it's a better way from the current turf
if(newg < P.g)
P.prevNode = cur
P.g = (newg * L.len / 9)
P.calc_f()
P.nt = cur.nt + 1
open.ReSort(P)//reorder the changed element in the list
CHECK_TICK
//cleaning after us
pnodelist = null
//reverse the path to get it from start to finish
if(path)
for(var/i = 1; i <= path.len/2; i++)
path.Swap(i,path.len-i+1)
return path
//Returns adjacent turfs in cardinal directions that are reachable
//simulated_only controls whether only simulated turfs are considered or not
/turf/proc/reachableAdjacentTurfs(caller, ID, simulated_only)
var/list/L = new()
var/turf/T
for(var/dir in GLOB.cardinal)
T = get_step(src,dir)
if(simulated_only && !istype(T))
continue
if(!T.density && !LinkBlockedWithAccess(T,caller, ID))
L.Add(T)
return L
//Returns adjacent turfs in cardinal directions that are reachable via atmos
/turf/proc/reachableAdjacentAtmosTurfs()
return atmos_adjacent_turfs
/turf/proc/LinkBlockedWithAccess(turf/T, caller, ID)
var/adir = get_dir(src, T)
var/rdir = get_dir(T, src)
for(var/obj/structure/window/W in src)
if(!W.CanAStarPass(ID, adir))
return 1
for(var/obj/O in T)
if(!O.CanAStarPass(ID, rdir, caller))
return 1
return 0
+6 -6
View File
@@ -63,11 +63,11 @@ DBConnection/proc/Connect()
if(failed_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to connect anymore.
return FALSE
var/user = GLOB.sqlfdbklogin
var/pass = GLOB.sqlfdbkpass
var/db = GLOB.sqlfdbkdb
var/address = GLOB.sqladdress
var/port = GLOB.sqlport
var/user = global.sqlfdbklogin
var/pass = global.sqlfdbkpass
var/db = global.sqlfdbkdb
var/address = global.sqladdress
var/port = global.sqlport
doConnect("dbi:mysql:[db]:[address]:[port]","[user]","[pass]")
. = IsConnected()
@@ -98,7 +98,7 @@ DBConnection/proc/ErrorMsg() return _dm_db_error_msg(_db_con)
DBConnection/proc/SelectDB(database_name,dbi)
if(IsConnected()) Disconnect()
//return Connect("[dbi?"[dbi]":"dbi:mysql:[database_name]:[DB_SERVER]:[DB_PORT]"]",user,password)
return Connect("[dbi?"[dbi]":"dbi:mysql:[database_name]:[GLOB.sqladdress]:[GLOB.sqlport]"]",user,password)
return Connect("[dbi?"[dbi]":"dbi:mysql:[database_name]:[global.sqladdress]:[global.sqlport]"]",user,password)
DBConnection/proc/NewQuery(sql_query,cursor_handler=src.default_cursor) return new/DBQuery(sql_query,src,cursor_handler)
-60
View File
@@ -1,60 +0,0 @@
/proc/priority_announce(text, title = "", sound = 'sound/AI/attention.ogg', type)
if(!text)
return
var/announcement
if(type == "Priority")
announcement += "<h1 class='alert'>Priority Announcement</h1>"
if (title && length(title) > 0)
announcement += "<br><h2 class='alert'>[html_encode(title)]</h2>"
else if(type == "Captain")
announcement += "<h1 class='alert'>Captain Announces</h1>"
GLOB.news_network.SubmitArticle(text, "Captain's Announcement", "Station Announcements", null)
else
announcement += "<h1 class='alert'>[command_name()] Update</h1>"
if (title && length(title) > 0)
announcement += "<br><h2 class='alert'>[html_encode(title)]</h2>"
if(title == "")
GLOB.news_network.SubmitArticle(text, "Central Command Update", "Station Announcements", null)
else
GLOB.news_network.SubmitArticle(title + "<br><br>" + text, "Central Command", "Station Announcements", null)
announcement += "<br><span class='alert'>[html_encode(text)]</span><br>"
announcement += "<br>"
for(var/mob/M in GLOB.player_list)
if(!isnewplayer(M) && !M.ear_deaf)
to_chat(M, announcement)
if(M.client.prefs.toggles & SOUND_ANNOUNCEMENTS)
M << sound(sound)
/proc/print_command_report(text = "", title = null, announce=TRUE)
if(!title)
title = "Classified [command_name()] Update"
if(announce)
priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/AI/commandreport.ogg')
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && C.z == ZLEVEL_STATION)
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(C.loc)
P.name = "paper - '[title]'"
P.info = text
C.messagetitle.Add("[title]")
C.messagetext.Add(text)
P.update_icon()
/proc/minor_announce(message, title = "Attention:", alert)
if(!message)
return
for(var/mob/M in GLOB.player_list)
if(!isnewplayer(M) && !M.ear_deaf)
to_chat(M, "<b><font size = 3><font color = red>[title]</font color><BR>[message]</font size></b><BR>")
if(M.client.prefs.toggles & SOUND_ANNOUNCEMENTS)
if(alert)
M << sound('sound/misc/notice1.ogg')
else
M << sound('sound/misc/notice2.ogg')