2024-04-14 14:53:41 -05:00
globalThis . entityreport = { } ;
2024-03-13 03:51:44 -05:00
function obj _unique _name ( name , obj ) {
2024-09-26 11:36:09 -05:00
name = name . replaceAll ( "." , "_" ) ;
2023-12-24 09:14:46 -06:00
if ( ! ( name in obj ) ) return name ;
var t = 1 ;
var n = name + t ;
while ( n in obj ) {
t ++ ;
2024-03-13 03:51:44 -05:00
n = name + t ;
2023-12-24 09:14:46 -06:00
}
return n ;
}
2024-05-02 17:13:09 -05:00
function unique _name ( list , name = "new_object" ) {
2024-09-26 11:36:09 -05:00
var str = name . replaceAll ( "." , "_" ) ;
2024-05-02 17:13:09 -05:00
var n = 1 ;
var t = str ;
while ( list . indexOf ( t ) !== - 1 ) {
t = str + n ;
n ++ ;
}
return t ;
2024-09-26 11:36:09 -05:00
}
2024-05-02 17:13:09 -05:00
var entity = {
2024-07-22 19:07:02 -05:00
drawlayer : - 1 ,
2023-12-20 09:19:04 -06:00
get _comp _by _name ( name ) {
var comps = [ ] ;
2024-09-26 11:36:09 -05:00
for ( var c of Object . values ( this . components ) ) if ( c . comp === name ) comps . push ( c ) ;
2023-12-20 09:19:04 -06:00
if ( comps . length ) return comps ;
return undefined ;
} ,
2024-09-26 11:36:09 -05:00
2024-05-28 13:39:02 -05:00
rigidify ( ) {
this . body = os . make _body ( this . transform ) ;
} ,
2024-09-26 11:36:09 -05:00
2024-03-13 03:51:44 -05:00
path _from ( o ) {
var p = this . toString ( ) ;
var c = this . master ;
while ( c && c !== o && c !== world ) {
p = c . toString ( ) + "." + p ;
c = c . master ;
}
if ( c === world ) p = "world." + p ;
return p ;
} ,
2024-09-26 11:36:09 -05:00
2024-05-15 14:16:05 -05:00
drawlayer : 0 ,
2024-09-26 11:36:09 -05:00
full _path ( ) {
return this . path _from ( world ) ;
} ,
2024-03-13 03:51:44 -05:00
clear ( ) {
2024-09-30 19:00:09 -05:00
for ( var k in this . objects )
2024-03-13 03:51:44 -05:00
this . objects [ k ] . kill ( ) ;
this . objects = { } ;
} ,
2024-05-02 17:13:09 -05:00
sync ( ) {
2024-07-25 16:14:37 -05:00
for ( var c of Object . values ( this . components ) ) c . sync ? . ( ) ;
for ( var o of Object . values ( this . objects ) ) o . sync ( ) ;
2024-05-02 17:13:09 -05:00
} ,
2024-09-30 10:14:56 -05:00
delay ( fn , seconds ) { prosperon . add _timer ( this , fn , seconds ) ; } ,
2024-09-26 11:36:09 -05:00
cry ( file ) {
return audio . cry ( file ) ;
} ,
get pos ( ) {
return this . transform . pos ;
} ,
set pos ( x ) {
this . transform . pos = x ;
} ,
get angle ( ) {
return this . transform . angle ;
} ,
set angle ( x ) {
this . transform . angle = x ;
} ,
get scale ( ) {
return this . transform . scale ;
} ,
set scale ( x ) {
this . transform . scale = x ;
} ,
move ( vec ) {
this . pos = this . pos . add ( vec ) ;
} ,
rotate ( x ) {
this . transform . rotate ( x , [ 0 , 0 , - 1 ] ) ;
} ,
2024-05-02 17:13:09 -05:00
grow ( vec ) {
2024-09-26 11:36:09 -05:00
if ( typeof vec === "number" ) vec = [ vec , vec ] ;
this . scale = this . scale . map ( ( x , i ) => x * vec [ i ] ) ;
2024-04-07 13:16:54 -05:00
} ,
2024-09-26 11:36:09 -05:00
2024-05-02 17:13:09 -05:00
/* Reparent 'this' to be 'parent's child */
reparent ( parent ) {
assert ( parent , ` Tried to reparent ${ this . toString ( ) } to nothing. ` ) ;
if ( this . master === parent ) {
2024-08-28 13:49:24 -05:00
console . warn ( ` not reparenting ... ${ this . master } is the same as ${ parent } ` ) ;
2024-05-02 17:13:09 -05:00
return ;
}
2024-09-26 11:36:09 -05:00
2024-05-02 17:13:09 -05:00
var name = unique _name ( Object . keys ( parent ) , this . name ) ;
this . name = name ;
2024-09-26 11:36:09 -05:00
2024-05-02 17:13:09 -05:00
this . master ? . remove _obj ( this ) ;
this . master = parent ;
parent . objects [ this . guid ] = this ;
parent [ name ] = this ;
Object . hide ( parent , name ) ;
2024-04-07 13:16:54 -05:00
} ,
2024-09-26 11:36:09 -05:00
2024-05-02 17:13:09 -05:00
remove _obj ( obj ) {
2024-09-26 11:36:09 -05:00
if ( this . objects ) delete this . objects [ obj . guid ] ;
else console . warn ( ` Object ${ this . guid } has no objects file. ` ) ;
2024-05-02 17:13:09 -05:00
delete this [ obj . name ] ;
Object . unhide ( this , obj . name ) ;
2024-04-09 08:01:54 -05:00
} ,
2024-09-26 11:36:09 -05:00
2024-04-01 17:58:29 -05:00
spawn ( text , config , callback ) {
2024-10-02 09:55:32 -05:00
profile . report ( ` make_ ${ text } ` ) ;
2024-09-26 11:36:09 -05:00
var ent = class _use ( text , config , entity , function ( ent ) {
2024-08-05 15:26:18 -05:00
ent . transform = os . make _transform ( ) ;
ent . guid = prosperon . guid ( ) ;
ent . components = { } ;
ent . objects = { } ;
2024-08-07 16:55:08 -05:00
ent . timers = [ ] ;
2024-08-05 15:26:18 -05:00
ent . ur = { } ;
2024-08-22 13:31:00 -05:00
ent . urname = text ;
2024-08-05 15:26:18 -05:00
} ) ;
2024-09-26 11:36:09 -05:00
/ *
2024-05-02 17:13:09 -05:00
if ( ! text )
ent . ur = emptyur ;
2024-07-25 16:14:37 -05:00
else if ( text instanceof Object ) { // assume it's an ur
2024-04-04 17:28:11 -05:00
ent . ur = text ;
2024-04-12 13:53:00 -05:00
text = ent . ur . text ;
config = [ ent . ur . data , config ] . filter ( x => x ) . flat ( ) ;
}
else {
2024-04-04 17:28:11 -05:00
ent . ur = getur ( text , config ) ;
2024-04-12 13:53:00 -05:00
text = ent . ur . text ;
config = [ ent . ur . data , config ] ;
}
2024-08-05 15:26:18 -05:00
2024-04-04 17:28:11 -05:00
if ( typeof config === 'string' )
2024-04-06 19:41:14 -05:00
Object . merge ( ent , json . decode ( Resources . replstrs ( config ) ) ) ;
2024-04-04 17:28:11 -05:00
else if ( Array . isArray ( config ) )
2024-07-25 16:14:37 -05:00
for ( var path of config ) {
2024-04-11 17:17:49 -05:00
if ( typeof path === 'string' ) {
console . info ( ` ingesting ${ path } ... ` ) ;
2024-04-06 19:41:14 -05:00
Object . merge ( ent , json . decode ( Resources . replstrs ( path ) ) ) ;
2024-04-11 17:17:49 -05:00
}
2024-07-25 16:14:37 -05:00
else if ( path instanceof Object )
2024-04-06 19:41:14 -05:00
Object . merge ( ent , path ) ;
2024-07-25 16:14:37 -05:00
} ;
2024-08-05 15:26:18 -05:00
if ( typeof text === 'string' ) {
class _use (
use ( text , ent ) ;
}
else if ( Array . isArray ( text ) )
for ( var path of text ) use ( path , ent ) ;
* /
2024-04-03 17:17:32 -05:00
ent . reparent ( this ) ;
2024-09-26 11:36:09 -05:00
2024-03-13 03:51:44 -05:00
for ( var [ prop , p ] of Object . entries ( ent ) ) {
if ( ! p ) continue ;
2024-09-26 11:36:09 -05:00
if ( typeof p !== "object" ) continue ;
2024-03-13 03:51:44 -05:00
if ( ! p . comp ) continue ;
2024-05-28 13:39:02 -05:00
ent [ prop ] = component [ p . comp ] ( ent ) ;
2024-03-13 03:51:44 -05:00
Object . merge ( ent [ prop ] , p ) ;
ent . components [ prop ] = ent [ prop ] ;
2024-09-26 11:36:09 -05:00
}
2024-07-25 16:14:37 -05:00
2024-03-13 03:51:44 -05:00
check _registers ( ent ) ;
2024-07-25 16:14:37 -05:00
2024-09-13 17:56:02 -05:00
if ( ent . awake instanceof Function ) ent . awake ( ) ;
2024-08-29 16:55:01 -05:00
if ( sim . playing ( ) ) {
ent . _started = true ;
2024-07-25 16:14:37 -05:00
if ( ent . start instanceof Function ) ent . start ( ) ;
2024-08-29 16:55:01 -05:00
}
2024-09-26 11:36:09 -05:00
Object . hide ( ent , "ur" , "components" , "objects" , "timers" , "guid" , "master" , "guid" ) ;
2024-04-03 17:17:32 -05:00
ent . _ed = {
selectable : true ,
dirty : false ,
inst : false ,
2024-09-26 11:36:09 -05:00
urdiff : { } ,
2024-04-03 17:17:32 -05:00
} ;
2024-09-26 11:36:09 -05:00
Object . hide ( ent , "_ed" ) ;
2024-03-13 03:51:44 -05:00
ent . sync ( ) ;
2024-09-26 11:36:09 -05:00
2024-03-13 03:51:44 -05:00
if ( ! Object . empty ( ent . objects ) ) {
var o = ent . objects ;
delete ent . objects ;
2024-04-11 17:17:49 -05:00
ent . objects = { } ;
2024-03-13 03:51:44 -05:00
for ( var i in o ) {
2024-09-30 04:36:53 -05:00
console . info ( ` creating ${ i } on ${ ent . toString ( ) } ` ) ;
2024-04-04 17:28:11 -05:00
var newur = o [ i ] . ur ;
2024-03-13 03:51:44 -05:00
delete o [ i ] . ur ;
2024-04-04 17:28:11 -05:00
var n = ent . spawn ( ur [ newur ] , o [ i ] ) ;
ent . rename _obj ( n . toString ( ) , i ) ;
2024-03-13 03:51:44 -05:00
}
}
2024-09-26 11:36:09 -05:00
2024-04-03 00:44:08 -05:00
if ( ent . tag ) game . tag _add ( ent . tag , ent ) ;
2024-09-26 11:36:09 -05:00
2024-04-03 08:37:29 -05:00
if ( callback ) callback ( ent ) ;
2024-09-26 11:36:09 -05:00
2024-04-04 17:28:11 -05:00
ent . ur . fresh ? ? = json . decode ( json . encode ( ent ) ) ;
2024-04-09 08:01:54 -05:00
ent . ur . fresh . objects = { } ;
2024-09-26 11:36:09 -05:00
for ( var i in ent . objects ) ent . ur . fresh . objects [ i ] = ent . objects [ i ] . instance _obj ( ) ;
2024-05-21 18:50:53 -05:00
2024-10-02 09:55:32 -05:00
profile . endreport ( ` make_ ${ text } ` ) ;
2024-09-26 11:36:09 -05:00
2024-03-13 03:51:44 -05:00
return ent ;
} ,
2024-09-26 11:36:09 -05:00
disable ( ) {
for ( var x of this . components ) x . disable ( ) ;
} ,
enable ( ) {
for ( var x of this . components ) x . enable ( ) ;
} ,
this2screen ( pos ) {
return game . camera . world2view ( this . this2world ( pos ) ) ;
} ,
screen2this ( pos ) {
return this . world2this ( game . camera . view2world ( pos ) ) ;
} ,
2024-05-02 17:13:09 -05:00
/* Make a unique object the same as its prototype */
2024-09-26 11:36:09 -05:00
revert ( ) {
Object . merge ( this , this . ur . fresh ) ;
} ,
2024-05-02 17:13:09 -05:00
name : "new_object" ,
2024-09-26 11:36:09 -05:00
toString ( ) {
return this . name ;
} ,
2023-10-04 17:57:37 -05:00
width ( ) {
var bb = this . boundingbox ( ) ;
return bb . r - bb . l ;
} ,
2024-09-26 11:36:09 -05:00
2023-10-04 17:57:37 -05:00
height ( ) {
var bb = this . boundingbox ( ) ;
2024-03-13 03:51:44 -05:00
return bb . t - bb . b ;
2023-10-04 17:57:37 -05:00
} ,
2024-09-26 11:36:09 -05:00
flipx ( ) {
return this . scale . x < 0 ;
} ,
flipy ( ) {
return this . scale . y < 0 ;
} ,
mirror ( plane ) {
this . scale = Vector . reflect ( this . scale , plane ) ;
} ,
2024-03-13 03:51:44 -05:00
/* Bounding box of the object in world dimensions */
boundingbox ( ) {
var boxes = [ ] ;
boxes . push ( {
t : 0 ,
r : 0 ,
b : 0 ,
2024-09-26 11:36:09 -05:00
l : 0 ,
2024-03-13 03:51:44 -05:00
} ) ;
2024-09-26 11:36:09 -05:00
2024-03-13 03:51:44 -05:00
for ( var key in this . components ) {
2024-09-26 11:36:09 -05:00
if ( "boundingbox" in this . components [ key ] ) boxes . push ( this . components [ key ] . boundingbox ( ) ) ;
2024-03-13 03:51:44 -05:00
}
2024-09-26 11:36:09 -05:00
for ( var key in this . objects ) boxes . push ( this . objects [ key ] . boundingbox ( ) ) ;
2024-03-13 03:51:44 -05:00
var bb = boxes . shift ( ) ;
2024-09-26 11:36:09 -05:00
2024-07-25 16:14:37 -05:00
for ( var x of boxes ) bb = bbox . expand ( bb , x ) ;
2024-09-26 11:36:09 -05:00
2024-03-13 03:51:44 -05:00
bb = bbox . move ( bb , this . pos ) ;
2024-09-26 11:36:09 -05:00
2024-03-13 03:51:44 -05:00
return bb ? bb : bbox . fromcwh ( [ 0 , 0 ] , [ 0 , 0 ] ) ;
} ,
2024-08-08 13:25:47 -05:00
toJSON ( ) {
2024-09-26 11:36:09 -05:00
return { guid : this . guid } ;
2024-08-08 13:25:47 -05:00
} ,
2024-09-26 11:36:09 -05:00
2024-03-13 03:51:44 -05:00
/* The unique components of this object. Its diff. */
2024-09-26 11:36:09 -05:00
json _obj ( depth = 0 ) {
2024-04-04 17:28:11 -05:00
var fresh = this . ur . fresh ;
2024-03-13 03:51:44 -05:00
var thiso = json . decode ( json . encode ( this ) ) ; // TODO: SLOW. Used to ignore properties in toJSON of components.
2024-04-03 17:17:32 -05:00
var d = ediff ( thiso , fresh ) ;
2024-09-26 11:36:09 -05:00
2024-03-13 03:51:44 -05:00
d ? ? = { } ;
2024-09-26 11:36:09 -05:00
2024-04-03 17:17:32 -05:00
fresh . objects ? ? = { } ;
2024-03-13 03:51:44 -05:00
var curobjs = { } ;
2024-09-26 11:36:09 -05:00
for ( var o in this . objects ) curobjs [ o ] = this . objects [ o ] . instance _obj ( ) ;
2024-04-03 17:17:32 -05:00
var odiff = ediff ( curobjs , fresh . objects ) ;
2024-09-26 11:36:09 -05:00
if ( odiff ) d . objects = curobjs ;
2024-03-13 03:51:44 -05:00
delete d . pos ;
delete d . angle ;
delete d . scale ;
delete d . velocity ;
delete d . angularvelocity ;
return d ;
} ,
2024-09-26 11:36:09 -05:00
2024-03-13 03:51:44 -05:00
/* The object needed to store an object as an instance of a master */
instance _obj ( ) {
2024-09-01 13:59:34 -05:00
var t = os . make _transform ( ) ;
t = this . transform ;
2024-04-04 17:28:11 -05:00
t . ur = this . ur . name ;
2024-03-13 03:51:44 -05:00
return t ;
} ,
2024-09-26 11:36:09 -05:00
2024-03-13 03:51:44 -05:00
transform ( ) {
var t = { } ;
2024-04-09 16:48:15 -05:00
t . pos = this . get _pos ( this . master ) . map ( x => Math . places ( x , 0 ) ) ;
2024-04-09 08:01:54 -05:00
t . angle = Math . places ( this . get _angle ( this . master ) , 4 ) ;
2024-09-26 11:36:09 -05:00
t . scale = this . get _scale ( this . master ) . map ( x => Math . places ( x , 2 ) ) ;
2024-03-13 03:51:44 -05:00
return t ;
} ,
2024-09-26 11:36:09 -05:00
dup ( diff ) {
2024-04-04 17:28:11 -05:00
var n = this . master . spawn ( this . ur ) ;
2024-04-09 16:48:15 -05:00
Object . totalmerge ( n , this . transform ( ) ) ;
2024-03-13 03:51:44 -05:00
return n ;
} ,
2024-09-26 11:36:09 -05:00
2023-11-29 12:40:13 -06:00
kill ( ) {
2023-12-28 12:49:48 -06:00
if ( this . _ _kill ) return ;
this . _ _kill = true ;
2024-10-01 08:06:08 -05:00
this . timers . forEachRight ( x => x ( ) ) ;
2024-08-02 20:52:50 -05:00
delete this . timers ;
2024-01-03 17:19:13 -06:00
Event . rm _obj ( this ) ;
2024-04-03 08:37:29 -05:00
input . do _uncontrol ( this ) ;
2024-09-26 11:36:09 -05:00
2024-02-29 13:54:33 -06:00
if ( this . master ) {
this . master . remove _obj ( this ) ;
this . master = undefined ;
2023-11-29 12:40:13 -06:00
}
2024-09-26 11:36:09 -05:00
2023-11-29 12:40:13 -06:00
for ( var key in this . components ) {
2024-03-13 03:51:44 -05:00
this . components [ key ] . kill ? . ( ) ;
2023-12-19 15:34:36 -06:00
this . components [ key ] . gameobject = undefined ;
2024-05-28 13:39:02 -05:00
this . components [ key ] . enabled = false ;
2023-12-18 17:12:05 -06:00
delete this . components [ key ] ;
2023-11-29 12:40:13 -06:00
}
2024-09-26 11:36:09 -05:00
2024-04-02 07:41:46 -05:00
delete this . components ;
2024-09-26 11:36:09 -05:00
2023-11-29 12:40:13 -06:00
this . clear ( ) ;
2024-07-25 16:14:37 -05:00
if ( this . stop instanceof Function ) this . stop ( ) ;
2024-09-26 11:36:09 -05:00
if ( typeof this . garbage === "function" ) this . garbage ( ) ;
if ( typeof this . then === "function" ) this . then ( ) ;
2024-04-03 00:44:08 -05:00
game . tag _clear _guid ( this . guid ) ;
2024-09-25 12:46:59 -05:00
rmactor ( this ) ;
2024-09-26 11:36:09 -05:00
2024-04-02 07:41:46 -05:00
for ( var i in this ) {
2024-07-25 16:14:37 -05:00
if ( this [ i ] instanceof Object || this [ i ] instanceof Function ) delete this [ i ] ;
2024-04-02 07:41:46 -05:00
}
2023-11-29 12:40:13 -06:00
} ,
2024-09-26 11:36:09 -05:00
2023-10-09 18:10:10 -05:00
make _objs ( objs ) {
for ( var prop in objs ) {
2024-02-29 13:54:33 -06:00
say ( ` spawning ${ json . encode ( objs [ prop ] ) } ` ) ;
var newobj = this . spawn ( objs [ prop ] ) ;
2023-10-09 18:10:10 -05:00
}
} ,
2024-09-26 11:36:09 -05:00
2023-10-02 17:03:01 -05:00
rename _obj ( name , newname ) {
if ( ! this . objects [ name ] ) {
2024-09-30 04:36:53 -05:00
console . warn ( ` No object with name ${ name } . Could not rename to ${ newname } . ` ) ;
2023-10-02 17:03:01 -05:00
return ;
}
2023-10-26 11:48:02 -05:00
if ( name === newname ) {
Object . hide ( this , name ) ;
return ;
}
2024-09-26 11:36:09 -05:00
if ( this . objects [ newname ] ) return ;
2023-10-02 17:03:01 -05:00
this . objects [ newname ] = this . objects [ name ] ;
2023-10-17 12:22:06 -05:00
this [ newname ] = this [ name ] ;
2024-09-26 11:36:09 -05:00
this [ newname ] . toString = function ( ) {
return newname ;
} ;
2023-10-26 11:48:02 -05:00
Object . hide ( this , newname ) ;
2023-10-02 17:03:01 -05:00
delete this . objects [ name ] ;
2023-10-17 12:22:06 -05:00
delete this [ name ] ;
2023-10-02 17:03:01 -05:00
return this . objects [ newname ] ;
} ,
2024-09-26 11:36:09 -05:00
2024-05-28 13:39:02 -05:00
add _component ( comp , data ) {
var name = prosperon . guid ( ) ;
this . components [ name ] = comp ( this ) ;
if ( data ) {
Object . assign ( this . components [ name ] , data ) ;
this . components [ name ] . sync ? . ( ) ;
}
return this . components [ name ] ;
2023-11-02 17:25:00 -05:00
} ,
2024-05-02 17:13:09 -05:00
} ;
2024-03-20 16:07:23 -05:00
2024-05-02 17:13:09 -05:00
var gameobject = {
check _dirty ( ) {
this . _ed . urdiff = this . json _obj ( ) ;
this . _ed . dirty = ! Object . empty ( this . _ed . urdiff ) ;
return ; // TODO: IMPLEMENT
var lur = this . master . ur ;
if ( ! lur ) return ;
var lur = lur . objects [ this . toString ( ) ] ;
var d = ediff ( this . _ed . urdiff , lur ) ;
2024-09-26 11:36:09 -05:00
if ( ! d || Object . empty ( d ) ) this . _ed . inst = true ;
else this . _ed . inst = false ;
2024-05-02 17:13:09 -05:00
} ,
namestr ( ) {
var s = this . toString ( ) ;
if ( this . _ed ? . dirty )
if ( this . _ed . inst ) s += "#" ;
else s += "*" ;
return s ;
} ,
urstr ( ) {
var str = this . ur . name ;
if ( this . _ed . dirty ) str = "*" + str ;
return str ;
} ,
/* pin this object to the to object */
pin ( to ) {
2024-09-26 11:36:09 -05:00
var p = joint . pin ( this , to ) ;
2024-05-02 17:13:09 -05:00
} ,
2024-09-26 11:36:09 -05:00
slide ( to , a = [ 0 , 0 ] , b = [ 0 , 0 ] , min = 0 , max = 50 ) {
2024-05-02 17:13:09 -05:00
var p = joint . slide ( this , to , a , b , min , max ) ;
p . max _force = 500 ;
p . break ( ) ;
} ,
pivot ( to , piv = this . pos ) {
var p = joint . pivot ( this , to , piv ) ;
} ,
/* groove is on to, from local points a and b, anchored to this at local anchor */
2024-09-26 11:36:09 -05:00
groove ( to , a , b , anchor = [ 0 , 0 ] ) {
2024-05-02 17:13:09 -05:00
var p = joint . groove ( to , this , a , b , anchor ) ;
} ,
2024-09-26 11:36:09 -05:00
damped _spring ( to , length = Vector . length ( this . pos , to . pos ) , stiffness = 1 , damping = 1 ) {
2024-05-02 17:13:09 -05:00
var dc = 2 * Math . sqrt ( stiffness * this . mass ) ;
var p = joint . damped _spring ( this , to , [ 0 , 0 ] , [ 0 , 0 ] , stiffness , damping * dc ) ;
} ,
damped _rotary _spring ( to , angle = 0 , stiffness = 1 , damping = 1 ) {
/* calculate actual damping value from the damping ratio */
/* damping = 1 is critical */
var dc = 2 * Math . sqrt ( stiffness * this . get _moi ( ) ) ; /* critical damping number */
/* zeta = actual/critical */
var p = joint . damped _rotary ( this , to , angle , stiffness , damping * dc ) ;
} ,
rotary _limit ( to , min , max ) {
var p = joint . rotary ( this , to , Math . turn2rad ( min ) , Math . turn2rad ( max ) ) ;
} ,
ratchet ( to , ratch ) {
var phase = this . angle - to . angle ;
var p = joint . ratchet ( this , to , phase , Math . turn2rad ( ratch ) ) ;
} ,
gear ( to , ratio = 1 , phase = 0 ) {
var phase = this . angle - to . angle ;
var p = joint . gear ( this , to , phase , ratio ) ;
} ,
motor ( to , rate ) {
var p = joint . motor ( this , to , rate ) ;
} ,
set _pos ( x , relative = world ) {
var newpos = relative . this2world ( x ) ;
var move = newpos . sub ( this . pos ) ;
this . rpos = newpos ;
2024-07-25 16:14:37 -05:00
for ( var o of this . objects ) o . move ( move ) ;
2024-05-02 17:13:09 -05:00
} ,
2024-09-26 11:36:09 -05:00
2024-05-02 17:13:09 -05:00
set _angle ( x , relative = world ) {
var newangle = relative . angle + x ;
var diff = newangle - this . angle ;
this . rangle = newangle ;
2024-07-25 16:14:37 -05:00
for ( var obj of this . objects ) {
2024-05-02 17:13:09 -05:00
obj . rotate ( diff ) ;
obj . set _pos ( Vector . rotate ( obj . get _pos ( obj . master ) , diff ) , obj . master ) ;
2024-07-25 16:14:37 -05:00
}
2024-05-02 17:13:09 -05:00
} ,
2024-09-26 11:36:09 -05:00
2024-05-02 17:13:09 -05:00
set _scale ( x , relative = world ) {
2024-09-26 11:36:09 -05:00
if ( typeof x === "number" ) x = [ x , x , x ] ;
var newscale = relative . scale . map ( ( s , i ) => x [ i ] * s ) ;
var pct = this . scale . map ( ( s , i ) => newscale [ i ] / s ) ;
2024-05-02 17:13:09 -05:00
this . rscale = newscale ;
2024-07-25 16:14:37 -05:00
for ( var obj of this . objects ) {
2024-05-02 17:13:09 -05:00
obj . grow ( pct ) ;
2024-09-26 11:36:09 -05:00
obj . set _pos (
obj . get _pos ( obj . master ) . map ( ( x , i ) => x * pct [ i ] ) ,
obj . master ,
) ;
}
2024-05-02 17:13:09 -05:00
} ,
2024-09-26 11:36:09 -05:00
2024-05-02 17:13:09 -05:00
get _pos ( relative = world ) {
if ( relative === world ) return this . pos ;
return relative . world2this ( this . pos ) ;
//return this.pos.sub(relative.pos);
} ,
2024-09-26 11:36:09 -05:00
2024-05-02 17:13:09 -05:00
get _angle ( relative = world ) {
if ( relative === world ) return this . angle ;
return this . angle - relative . angle ;
} ,
2024-09-26 11:36:09 -05:00
2024-05-02 17:13:09 -05:00
get _scale ( relative = world ) {
if ( relative === world ) return this . scale ;
var masterscale = relative . scale ;
2024-09-26 11:36:09 -05:00
return this . scale . map ( ( x , i ) => x / masterscale [ i ] ) ;
} ,
in _air ( ) {
return this . in _air ( ) ;
2024-05-02 17:13:09 -05:00
} ,
2024-09-26 11:36:09 -05:00
2024-05-02 17:13:09 -05:00
/* Velocity and angular velocity of the object */
phys _obj ( ) {
var phys = { } ;
phys . velocity = this . velocity ;
phys . angularvelocity = this . angularvelocity ;
return phys ;
} ,
2024-09-26 11:36:09 -05:00
2024-05-02 17:13:09 -05:00
set category ( n ) {
if ( n === 0 ) {
this . categories = n ;
return ;
}
2024-09-26 11:36:09 -05:00
var cat = 1 << ( n - 1 ) ;
2024-05-02 17:13:09 -05:00
this . categories = cat ;
} ,
get category ( ) {
if ( this . categories === 0 ) return 0 ;
var pos = 0 ;
var num = this . categories ;
while ( num > 0 ) {
2024-09-26 11:36:09 -05:00
if ( num & 1 ) {
break ;
}
pos ++ ;
num >>>= 1 ;
2024-05-02 17:13:09 -05:00
}
2024-09-26 11:36:09 -05:00
return pos + 1 ;
} ,
} ;
2024-03-20 16:07:23 -05:00
2024-05-02 17:13:09 -05:00
entity . spawn . doc = ` Spawn an entity of type 'ur' on this entity. Returns the spawned entity. ` ;
2023-09-20 13:33:11 -05:00
2023-10-23 08:08:11 -05:00
gameobject . doc = {
doc : "All objects in the game created through spawning have these attributes." ,
2024-02-29 13:54:33 -06:00
pos : "Position of the object, relative to its master." ,
angle : "Rotation of this object, relative to its master." ,
2023-10-23 08:08:11 -05:00
velocity : "Velocity of the object, relative to world." ,
angularvelocity : "Angular velocity of the object, relative to the world." ,
2024-02-29 13:54:33 -06:00
scale : "Scale of the object, relative to its master." ,
2023-11-15 16:42:39 -06:00
flipx : "Check if the object is flipped on its x axis." ,
flipy : "Check if the object is flipped on its y axis." ,
2024-03-19 23:01:31 -05:00
elasticity : ` When two objects collide, their elasticities are multiplied together. Their velocities are then multiplied by this value to find √their resultant velocities. ` ,
2023-10-23 08:08:11 -05:00
friction : ` When one object touches another, friction slows them down. ` ,
mass : ` The higher the mass of the object, the less forces will affect it. ` ,
2024-03-09 18:22:06 -06:00
phys : ` Set to 0, 1, or 2, representing dynamic, kinematic, and static. ` ,
2023-10-23 08:08:11 -05:00
worldpos : ` Function returns the world position of the object. ` ,
2024-04-07 13:16:54 -05:00
set _pos : ` Function to set the position of the object in world coordinates. ` ,
2023-10-23 08:08:11 -05:00
worldangle : ` Function to get the angle of the entity in the world. ` ,
rotate : ` Function to rotate this object by x degrees. ` ,
2024-09-26 11:36:09 -05:00
move : "Move an object by x,y,z. If the first parameter is an array, uses up to the first three array values." ,
2023-10-23 08:08:11 -05:00
pulse : ` Apply an impulse to this body in world coordinates. Impulse is a short force. ` ,
shove : ` Apply a force to this body in world coordinates. Should be used over many frames. ` ,
2024-09-26 11:36:09 -05:00
shove _at : "Apply a force to this body, at a position relative to itself." ,
max _velocity : "The max linear velocity this object can travel." ,
max _angularvelocity : "The max angular velocity this object can rotate." ,
2023-10-23 08:08:11 -05:00
on _ground : ` Return true if the object is on the ground. ` ,
spawn : ` Create an instance of a supplied ur-type on this object. Optionally provide a data object to modify the created entity. ` ,
hide : ` Make this object invisible. ` ,
show : ` Make this object visible. ` ,
width : ` The total width of the object and all its components. ` ,
height : ` The total height of the object. ` ,
move : ` Move this object the given amount. ` ,
boundingbox : ` The boundingbox of the object. ` ,
dup : ` Make an exact copy of this object. ` ,
transform : ` Return an object representing the transform state of this object. ` ,
kill : ` Remove this object from the world. ` ,
2024-02-29 13:54:33 -06:00
master : "The entity this entity belongs to." ,
2024-09-26 11:36:09 -05:00
delay : "Run the given function after the given number of seconds has elapsed." ,
cry : "Make a sound. Can only make one at a time." ,
add _component : "Add a component to the object by name." ,
pin : "Pin joint to another object. Acts as if a rigid rod is between the two objects." ,
slide : "Slide joint, similar to a pin but with min and max allowed distances." ,
pivot : "Pivot joint to an object, with the pivot given in world coordinates." ,
groove : "Groove joint. The groove is on to, from to local coordinates a and b, with this object anchored at anchor." ,
damped _spring : "Damped spring to another object. Length is the distance it wants to be, stiffness is the spring constant, and damping is the damping ratio. 1 is critical, < 1 is underdamped, > 1 is overdamped." ,
damped _rotary _spring : "Similar to damped spring but for rotation. Rest angle is the attempted angle." ,
rotary _limit : "Limit the angle relative to the to body between min and max." ,
ratchet : "Like a socket wrench, relative to to. ratch is the distance between clicks." ,
gear : "Keeps the angular velocity ratio of this body and to constant. Ratio is the gear ratio." ,
motor : "Keeps the relative angular velocity of this body to to at a constant rate. The most simple idea is for one of the bodies to be static, to the other is kept at rate." ,
layer : "Bitmask for collision layers." ,
drawlayer : "Layer for drawing. Higher numbers draw above lower ones." ,
warp _filter : "Bitmask for selecting what warps should affect this entity." ,
2023-10-23 08:08:11 -05:00
} ;
2024-03-04 11:15:55 -06:00
global . ur = { } ;
2024-03-02 00:00:35 -06:00
2024-09-26 11:36:09 -05:00
if ( io . exists ( ` ${ io . dumpfolder } /ur.json ` ) ) ur = json . decode ( io . slurp ( ` ${ io . dumpfolder } /ur.json ` ) ) ;
2024-03-02 00:00:35 -06:00
else {
ur = { } ;
ur . _list = [ ] ;
}
2024-02-29 13:54:33 -06:00
/ * U R O B J E C T
ur {
name : fully qualified name of ur
text : file path to the script
data : file path to data
proto : resultant object of a freshly made entity
2023-11-17 15:16:13 -06:00
}
2024-02-29 13:54:33 -06:00
* /
2023-11-17 15:16:13 -06:00
2024-02-29 13:54:33 -06:00
/* Apply an ur u to an entity e */
/* u is given as */
2024-04-11 07:38:28 -05:00
function apply _ur ( u , ent ) {
2024-09-26 11:36:09 -05:00
if ( typeof u !== "string" ) {
2024-02-29 13:54:33 -06:00
console . warn ( "Must give u as a string." ) ;
return ;
}
2024-03-13 03:51:44 -05:00
2024-09-26 11:36:09 -05:00
var urs = u . split ( "." ) ;
2024-04-11 07:38:28 -05:00
if ( ! urs . every ( u => ur [ u ] ) ) {
console . error ( ` Attempted to make ur combo ${ u } but not every ur in the chain exists. ` ) ;
return ;
2024-02-29 13:54:33 -06:00
}
2024-09-26 11:36:09 -05:00
2024-04-11 07:38:28 -05:00
for ( var u of urs ) {
var text = u . text ;
var data = u . data ;
2024-09-26 11:36:09 -05:00
if ( typeof text === "string" ) use ( text , ent ) ;
else if ( Array . isArray ( text ) ) for ( var path of text ) use ( path , ent ) ;
if ( typeof data === "string" ) Object . merge ( ent , json . decode ( Resources . replstrs ( data ) ) ) ;
2024-04-11 07:38:28 -05:00
else if ( Array . isArray ( data ) ) {
2024-07-25 16:14:37 -05:00
for ( var path of data ) {
2024-09-26 11:36:09 -05:00
if ( typeof path === "string" ) Object . merge ( ent , json . decode ( Resources . replstrs ( data ) ) ) ;
else if ( path instanceof Object ) Object . merge ( ent , path ) ;
}
2024-04-11 07:38:28 -05:00
}
2024-02-29 13:54:33 -06:00
}
2023-11-17 15:16:13 -06:00
}
2024-05-02 17:13:09 -05:00
var emptyur = {
2024-09-26 11:36:09 -05:00
name : "empty" ,
} ;
2024-05-02 17:13:09 -05:00
2024-09-26 11:36:09 -05:00
var getur = function ( text , data ) {
2024-05-02 17:13:09 -05:00
if ( ! text && ! data ) {
2024-09-26 11:36:09 -05:00
console . info ( "empty ur" ) ;
2024-05-02 17:13:09 -05:00
return {
2024-09-26 11:36:09 -05:00
name : "empty" ,
2024-05-02 17:13:09 -05:00
} ;
}
2024-07-24 14:17:32 -05:00
var urstr = text ;
2024-09-26 11:36:09 -05:00
if ( data ) urstr += "+" + data ;
2024-07-24 14:17:32 -05:00
2024-04-04 17:28:11 -05:00
if ( ! ur [ urstr ] ) {
ur [ urstr ] = {
name : urstr ,
text : text ,
2024-09-26 11:36:09 -05:00
data : data ,
} ;
2024-04-04 17:28:11 -05:00
}
return ur [ urstr ] ;
2024-09-26 11:36:09 -05:00
} ;
2024-04-04 17:28:11 -05:00
2024-09-26 11:36:09 -05:00
var ur _from _file = function ( file ) {
2024-04-11 07:38:28 -05:00
var urname = file . name ( ) ;
if ( ur [ urname ] ) {
console . warn ( ` Tried to make another ur with the name ${ urname } from ${ file } , but it already exists. ` ) ;
return undefined ;
}
var newur = {
2024-09-26 11:36:09 -05:00
name : urname ,
2024-04-11 07:38:28 -05:00
} ;
ur [ urname ] = newur ;
ur . _list . push ( urname ) ;
return newur ;
2024-09-26 11:36:09 -05:00
} ;
2024-04-11 07:38:28 -05:00
2024-09-26 11:36:09 -05:00
game . loadurs = function ( ) {
2024-09-25 20:51:20 -05:00
return ;
2024-03-04 11:15:55 -06:00
ur = { } ;
ur . _list = [ ] ;
/* FIND ALL URS IN A PROJECT */
2024-04-04 17:28:11 -05:00
for ( var file of io . glob ( "**.ur" ) ) {
2024-04-11 07:38:28 -05:00
var newur = ur _from _file ( file ) ;
if ( ! newur ) continue ;
2024-04-12 13:53:00 -05:00
var uur = Resources . replstrs ( file ) ;
var urjson = json . decode ( uur ) ;
2024-04-11 07:38:28 -05:00
Object . assign ( newur , urjson ) ;
2024-04-04 17:28:11 -05:00
}
2024-09-26 11:36:09 -05:00
2024-04-14 14:53:41 -05:00
for ( var file of io . glob ( "**.jso" ) . filter ( f => ! ur [ f . name ( ) ] ) ) {
2024-09-26 11:36:09 -05:00
if ( file [ 0 ] === "." || file [ 0 ] === "_" ) continue ;
2024-04-11 07:38:28 -05:00
var newur = ur _from _file ( file ) ;
if ( ! newur ) continue ;
2024-09-26 11:36:09 -05:00
newur . text = file ;
2024-04-11 17:17:49 -05:00
var data = file . set _ext ( ".json" ) ;
if ( io . exists ( data ) ) {
console . info ( ` Found matching json ${ data } for ${ file } ` ) ;
newur . data = data ;
}
2024-03-04 11:15:55 -06:00
}
2024-03-01 11:45:06 -06:00
} ;
2024-03-21 11:33:36 -05:00
2024-04-12 13:53:00 -05:00
game . ur = { } ;
2024-09-26 11:36:09 -05:00
game . ur . load = function ( str ) { } ;
game . ur . add _data = function ( str , data ) {
2024-04-12 13:53:00 -05:00
var nur = ur [ str ] ;
if ( ! nur ) {
console . warn ( ` Cannot add data to the ur ${ str } . ` ) ;
return ;
}
if ( ! Array . isArray ( ur . data ) ) {
var arr = [ ] ;
if ( ur . data ) arr . push ( ur . data ) ;
ur . data = arr ;
}
2024-09-26 11:36:09 -05:00
2024-04-12 13:53:00 -05:00
ur . data . push ( data ) ;
2024-09-26 11:36:09 -05:00
} ;
2024-04-12 13:53:00 -05:00
2024-09-26 11:36:09 -05:00
game . ur . save = function ( str ) {
2024-04-12 13:53:00 -05:00
var nur = ur [ str ] ;
if ( ! nur ) {
console . warn ( ` Cannot save ur ${ str } . ` ) ;
return ;
}
2024-09-26 11:36:09 -05:00
} ;
2024-04-12 13:53:00 -05:00
2024-09-26 11:36:09 -05:00
return { entity } ;