ID:1872243
 
Hey guys, I'm just gonna throw this out there. Anybody wanna kick in ideas for stuff that needs to go into a community-made stdlib?

My contributions:

Math:
+ floor()/ceil() (floor rounds left, while ceil rounds right)
+ clamp() (clamp a value between min and max)
+ inner()/outer() (round away from or toward zero, AKA truncation and inverse truncation)
+ decimal() (returns the decimal component of a number)
+ atan2()
+ ang2dir()
+ dir2ang()
+ getang()
+ to_places() (reduces a value to a set number of decimal places)
+ left_x() (the following 6 functions return absolute pixel coordinates of an object's bounding box)
+ right_x()
+ center_x()
+ bottom_y()
+ top_y()
+ center_y()
+ hypotenuse() (supply a and b to get c)

Strings:
+ begins_with()
+ begins_withEx()
+ ends_with()
+ ends_widthEx()
+ replace_text()
+ replace_textEx()
+ tokenize()
+ tokenizeEx()
+ trim_whitespace()
+ findtext_all()
+ findtextEx_all()
* findtext_last()
* findtextEx_last()
* JSON2datum()
* datum2JSON()
+ dir2text()
+ text2dir()
+ screen_loc2num()
+ copy_after()
+ copy_afterEx()
+ copy_before()
+ copy_beforeEx()

Object Management:
* datum.Cleanup() (replaces Del() to speed up garbage collection)
* datum.Clone() (override function for creating clones of objects)
+ islist()
+ ismovable()

Constants:
+ TICK_LAG
+ TILE_WIDTH
+ TILE_HEIGHT
+ FPS

Client-server utils:
* JS<->DM communication utilities and standard JS functions for working with DM
* client.browser_vendor
* client.browser_version
* client.JSCall()
* client.JSCallback()

Keyboard interaction:
+ key defs
+ key categories
+ key_category()
+ key_name()
+ name2keycode()
+ char2keycode()
+ keycode2char()

Interfaces:
+ appearance datum interface

LordAndrew's contributions:

+ tan()
+ arctan()
+ cot()
+ arccot()
+ sec()
+ arcsec()
+ csc()
+ arccsc()

Anybody else got anything good that needs to go into a DM stdlib?

Rickosay's contributions:

+ client.mouse_x
+ client.mouse_y
* client.mouse_state
+ client.mouse_buttons
We need round UP and round DOWN.
A working eval()
A working eval()

Never gonna happen. I've already written a DM parser and VM before, and I'm not impressed with how slow it is.
Missing trigonometry functions, maybe isclient()?

Ter13 wrote:
* datum.Cleanup() (replaces Del() to speed up garbage collection)

Could you elaborate more on how this works?

In response to LordAndrew
LordAndrew wrote:
Missing trigonometry functions, maybe isclient()?

Ter13 wrote:
* datum.Cleanup() (replaces Del() to speed up garbage collection)

Could you elaborate more on how this works?

I assume it looks through the variables and removes any and all references and then sets its loc to null
I wish i knew what any of this does and what you guys are talking about >.<.
I can't think of anything else right away, but I will try to remember to check back Monday, when I have time on the computer.
In response to Developous
Round up: ceil(n), or -round(-n).
Round down: floor(n), or round(n).
They're actually the first two things on the list.
A bunch of the math and dir stuff is done:

#define floor(x) round(x)
#define ceil(x) (-round(-(x)))
#define inner(x) (x<0 ? ceil(x) : floor(x))
#define outer(x) (x<0 ? floor(x) : ceil(x))

#define clamp(value,low,high) min(max(value,low),high)

#define to_places(v,p) (floor(10**p*v)/10**p)

#define ismovable(o) istype(o,/atom/movable)
#define islist(o) istype(o,/list)

var
list
__dir_ang = list(90,270,null,0,45,315,0,180,135,225,180,null,90,180,null)
__dir_names = list("north"=NORTH,"south"=SOUTH,null,"east"=EAST,"northeast"=NORTHEAST,"southeast"=SOUTHEAST,null,"west"=WEST,"northwest"=NORTHWEST,"southwest"=SOUTHWEST)
__euler_dirs = list(EAST,NORTHEAST,NORTH,NORTHWEST,WEST,SOUTHWEST,SOUTH,SOUTHEAST)

#define dir2ang(x) __dir_ang[x]
#define dir2text(x) __dir_names[x]
#define text2dir(name) __dir_names[lowertext(name)]

#define left_x(O) (O:x*TILE_WIDTH + (ismovable(O) ? O:step_x + O:bound_x : 0))
#define bottom_y(O) (O:y*TILE_HEIGHT + (ismovable(O) ? O:step_y + O:bound_y : 0))
#define center_x(O) (O:x*TILE_WIDTH + (ismovable(O) ? O:step_x + O:bound_x + O:bound_width/2 - 1 : floor(TILE_WIDTH/2)-1))
#define center_y(O) (O:y*TILE_HEIGHT + (ismovable(O) ? O:step_y + O:bound_y + O:bound_height/2 - 1 : floor(TILE_HEIGHT/2)-1))
#define right_x(O) (O:x*TILE_WIDTH + (ismovable(O) ? O:step_x + O:bound_x + O:bound_width - 1 : TILE_WIDTH-1))
#define top_y(O) (O:y*TILE_HEIGHT + (ismovable(O) ? O:step_y + O:bound_y + O:bound_height - 1 : TILE_HEIGHT-1))

proc
atan2(x,y)
return (x||y)&&(y>=0 ? arccos(x/sqrt(x*x+y*y)) : 360-arccos(x/sqrt(x*x+y*y)))

ang2dir(x)
//ensure that the angle is between 0 and 360
if(x<0)
x = x+360*ceil(x/-360)
. = __euler_dirs[floor(ceil(x/22.5)%16 / 2)+1]

getang(atom/a,atom/b)
. = atan2(center_x(b)-center_x(a),center_y(b)-center_y(a))

decimal(x)
. = x-round_inner(x)


And a bunch of the text stuff is done:

proc
str_ends_with(str,substr)
var/len = length(str)
var/slen = length(substr)
if(len>slen&&copytext(str,len-slen+1)==substr)
. = 1
else if(slen==len&&str==substr)
. = 1
else
. = 0

str_begins_with(str,substr)
var/len = length(str)
var/slen = length(substr)
if(len>slen&&copytext(str,1,slen+1)==substr)
. = 1
else if(slen==len&&str==substr)
. = 1
else
. = 0

str_replace(str,findstr,repstr)
. = ""
var/slen = length(str)
var/flen = length(findstr)
var/pos = 1
var/fpos
while(fpos&&pos<=slen)
fpos = findtext(str,findstr,pos)
if(fpos==pos)
. += repstr
else
. += copytext(str,pos,fpos) + repstr
pos = fpos + flen
if(pos<=slen)
. += copytext(str,pos)

tokenize(str,separator)
var/slen = length(str)
var/flen = length(separator)
var/pos = 1
var/fpos
. = list()
while(fpos&&pos<=slen)
fpos = findtext(str,separator,pos)
if(fpos==pos)
. += ""
else
. += copytext(str,pos,fpos)
pos = fpos + flen
if(pos<=slen)
. += copytext(str,pos)

trim_whitespace(str)
var/spos = 0
var/epos = length(str)
while(++spos<=epos)
switch(text2ascii(str,spos))
if(32,9 to 13,133,160)
continue
else
break
var/len = epos++
while(--epos>spos)
switch(text2ascii(str,epos))
if(32,9 to 13,133,160)
continue
else
break
if(spos<epos)
if(spos>1||epos<len)
. = copytext(str,spos,epos+1)
else
. = str
else
. = ""

findtext_all(str,findstr)
. = list()
var/pos = 1
var/fpos
var/len = length(str)
var/flen = length(findstr)
while(fpos&&pos<=len)
fpos = findtext(str,findstr,pos)
if(fpos)
. += fpos
pos = fpos+flen

findtextEx_all(str,findstr)
. = list()
var/pos = 1
var/fpos
var/len = length(str)
var/flen = length(findstr)
while(fpos&&pos<=len)
fpos = findtextEx(str,findstr,pos)
if(fpos)
. += fpos
pos = fpos+flen
In response to Kozuma3
Kozuma3 wrote:
LordAndrew wrote:
Missing trigonometry functions, maybe isclient()?

Ter13 wrote:
* datum.Cleanup() (replaces Del() to speed up garbage collection)

Could you elaborate more on how this works?

I assume it looks through the variables and removes any and all references and then sets its loc to null

Actually, no. That's the worst way you can do this.

By default, datum.Cleanup() does nothing. It's simply an analogue to a C++ destructor. I'm trying to wean this community off of del. It's slow and shitty.

datum
proc
Cleanup()

atom/movable
Cleanup()
..()
loc = null


It's intended to be a centralized destructor where developers manage their references and clean up anything that would prevent garbage collection.

Though I suppose that I could borrow a leaf out of SS13's book and develop a weak-ref checker that will wait one second and then call del on an object if it's still not been successfully garbage collected after Cleanup() has been called. That would ensure that Cleanup() actually works to destroy the object, but doesn't call del unless the developer has screwed up.
It might be too big to include, but line of sight comes to mind. I personally find it odd that someone had to develop a way to determine what is in a mobs line of sight their self, rather than have it available by default.

Again, might be too big, but given the wide variety of step and walk procs I'm surprised there is nothing built-in that efficiently tells a mob to walk from point A to point B and back x amount of times or infinitely. I saw some pretty interesting handling for this and a number of other walking things via nodes somewhere on the forum not long ago though.

I'm noticing a something almost any project can use kind of pattern, so a player tracking and counting proc or two might make sense. Seems like just about every game internally keeps track of who and/or how many are logged in now, but that's pretty easy to do and how they're sorted is up for debate so ehhh.

Probably pretty useless, crazy ideas for this lib set up but I saw all the major stuff, had a minute to post, and figured I'd mention the first things my mind thought of at least.
Yeah, They aren't bad ideas by themselves as far as things that would be of use.

The problem is that those kinds of things introduce impact to the project that not every project needs. Pathfinding in particular is one that just can't be generalized to every project, because making it flexible enough to be highly customizable by the end user will always introduce huge delays in processing. Pathfinding code is meant to be very tight, and writing generalized tight code is extremely difficult.
I notice that people around here handle angles and directions differently. I prefer this way (east being 0 and counterclockwise).
Yeah, that sounds about right. It's unfortunate, but some of the most useful stuff just can't be generalized enough to make it work for something like this.

I remember coming across this before with genre specific game foundation ideas. Great in theory, but way too hard to generalize most of the major ones. Otherwise I'd be trying to lead a campaign for creating a lib like this for side scrollers, turn based strategy, platformers, and so on.

Anyways. I haven't had any luck thinking of anything, unless something HUD or on-screen related could fit in here. Pretty sure it's too broad to cover, but much like the del() issue there are a lot of bad habits in desperate need of an assault that I know you've been going after.
I've got a pretty nice interface lib, but a lot of people don't like the way I manage object creation and configuration, so I haven't released it fully... I might think about putting it into a library soon.
In response to Ter13
Ter13 wrote:
Actually, no. That's the worst way you can do this.

By default, datum.Cleanup() does nothing. It's simply an analogue to a C++ destructor. I'm trying to wean this community off of del. It's slow and shitty.

> datum
> proc
> Cleanup()
>
> atom/movable
> Cleanup()
> ..()
> loc = null
>

It's intended to be a centralized destructor where developers manage their references and clean up anything that would prevent garbage collection.

Good luck with that.
A gamepad control for the webclient (I have a working source code for one, based on a library that someone had written a few months back but deleted) could fit well here too, correct?
A gamepad control for the webclient (I have a working source code for one, based on a library that someone had written a few months back but deleted) could fit well here too, correct?

I'm more thinking language features.
Maybe a mouse screen-loc?
Page: 1 2 3 4