# def editor_interface( layout, obj ):
#
-# Classtype 1
+# 000: Intrinsic
+# ---------------------------------------------------------------------------- #
+
+# Purpose: intrinsic bone type, stores collision information and limits too
+#
+class classtype_bone(Structure):
+#{
+ _pack_ = 1
+ _fields_ = [("flags",c_uint32),
+ ("ik_target",c_uint32),
+ ("ik_pole",c_uint32),
+ ("hitbox",(c_float*3)*2),
+ ("conevx",c_float*3),
+ ("conevy",c_float*3),
+ ("coneva",c_float*3),
+ ("conet",c_float)]
+
+ def encode_obj(_, node,node_def):
+ #{
+ node.classtype = 1
+
+ armature_def = node_def['linked_armature']
+ obj = node_def['bone']
+
+ _.flags = node_def['deform']
+
+ if 'ik_target' in node_def:
+ #{
+ _.flags |= 0x2
+ _.ik_target = armature_def['bones'].index( node_def['ik_target'] )
+ _.ik_pole = armature_def['bones'].index( node_def['ik_pole'] )
+ #}
+
+ # For ragdolls
+ #
+ if obj.cv_data.collider != 'collider_none':
+ #{
+ if obj.cv_data.collider == 'collider_box':
+ _.flags |= 0x4
+ else:
+ _.flags |= 0x8
+
+ _.hitbox[0][0] = obj.cv_data.v0[0]
+ _.hitbox[0][1] = obj.cv_data.v0[2]
+ _.hitbox[0][2] = -obj.cv_data.v1[1]
+ _.hitbox[1][0] = obj.cv_data.v1[0]
+ _.hitbox[1][1] = obj.cv_data.v1[2]
+ _.hitbox[1][2] = -obj.cv_data.v0[1]
+ #}
+
+ if obj.cv_data.con0:
+ #{
+ _.flags |= 0x100
+ _.conevx[0] = obj.cv_data.conevx[0]
+ _.conevx[1] = obj.cv_data.conevx[2]
+ _.conevx[2] = -obj.cv_data.conevx[1]
+ _.conevy[0] = obj.cv_data.conevy[0]
+ _.conevy[1] = obj.cv_data.conevy[2]
+ _.conevy[2] = -obj.cv_data.conevy[1]
+ _.coneva[0] = obj.cv_data.coneva[0]
+ _.coneva[1] = obj.cv_data.coneva[2]
+ _.coneva[2] = -obj.cv_data.coneva[1]
+ _.conet = obj.cv_data.conet
+ #}
+ #}
+#}
+
+# Purpose: defines the allocation requirements for a skeleton
+#
+class classtype_skeleton(Structure):
+#{
+ _pack_ = 1
+ _fields_ = [("channels",c_uint32),
+ ("ik_count",c_uint32),
+ ("collider_count",c_uint32),
+ ("anim_start",c_uint32),
+ ("anim_count",c_uint32)]
+
+ def encode_obj(_, node,node_def):
+ #{
+ node.classtype = 2
+
+ _.channels = len( node_def['bones'] )
+ _.ik_count = node_def['ik_count']
+ _.collider_count = node_def['collider_count']
+ _.anim_start = node_def['anim_start']
+ _.anim_count = node_def['anim_count']
+ #}
+#}
+
+# Purpose: links an mesh node to a type 11
+#
+class classtype_skin(Structure):
+#{
+ _pack_ = 1
+ _fields_ = [("skeleton",c_uint32)]
+
+ def encode_obj(_, node,node_def):
+ #{
+ node.classtype = 3
+
+ armature_def = node_def['linked_armature']
+ _.skeleton = armature_def['obj'].cv_data.uid
+ #}
+#}
+
+# Purpose: world light
#
+class classtype_world_light( Structure ):
+#{
+ _pack_ = 1
+ _fields_ = [("type",c_uint32),
+ ("colour",c_float*4),
+ ("angle",c_float),
+ ("range",c_float)]
+
+ def encode_obj(_, node, node_def):
+ #{
+ node.classtype = 4
+
+ obj = node_def['obj']
+ data = obj.data
+ _.colour[0] = data.color[0]
+ _.colour[1] = data.color[1]
+ _.colour[2] = data.color[2]
+ _.colour[3] = data.energy
+ _.range = data.cutoff_distance # this has to be manually set
+ # TODO: At some point, automate a min
+ # threshold value
+
+ if obj.data.type == 'POINT':
+ #{
+ _.type = 0
+ _.angle = 0.0
+ #}
+ elif obj.data.type == 'SPOT':
+ #{
+ _.type = 1
+ _.angle = data.spot_size*0.5
+ #}
+
+ if data.cv_data.bp0:
+ _.type += 2
+ #}
+
+ @staticmethod
+ def editor_interface( layout, obj ):
+ #{
+ pass
+ #}
+#}
+
+# 100: Gates
+# ---------------------------------------------------------------------------- #
+
# Purpose: A rift. must target another gate, the target gate can not have more
# than one target nodes of its own.
#
def encode_obj(_, node,node_def):
#{
- node.classtype = 1
+ node.classtype = 100
obj = node_def['obj']
#{
def encode_obj(_,node,node_def):
#{
- node.classtype = 300
+ node.classtype = 101
obj = node_def['obj']
_.target = encoder_process_pstr( node_def['obj'].cv_data.strp )
#}
#}
-# Classtype 3
-#
+# 200: Spawns/Waypoints
+# ---------------------------------------------------------------------------- #
+
# Purpose: player can reset here, its a safe place
# spawns can share the same name, the closest one will be picked
#
def encode_obj(_, node,node_def):
#{
- node.classtype = 3
+ node.classtype = 200
_.pstr_alias = encoder_process_pstr( node_def['obj'].cv_data.strp )
#}
#}
#}
-# Classtype 4
-#
+# 300: Water
+# ---------------------------------------------------------------------------- #
+
# Purpose: Tells the game to draw water HERE, at this entity.
#
class classtype_water(Structure):
def encode_obj(_, node,node_def):
#{
- node.classtype = 4
+ node.classtype = 300
# no data, spooky
#}
#}
-# Classtype 8
-#
-# Purpose: Defines a route node and links to up to two more nodes
-#
-class classtype_route_node(Structure):
-#{
- _pack_ = 1
- _fields_ = [("target",c_uint32),
- ("target1",c_uint32)]
-
- def encode_obj(_, node,node_def):
- #{
- node.classtype = 8
- obj = node_def['obj']
-
- if obj.cv_data.target != None:
- _.target = obj.cv_data.target.cv_data.uid
- if obj.cv_data.target1 != None:
- _.target1 = obj.cv_data.target1.cv_data.uid
- #}
-
- @staticmethod
- def draw_scene_helpers( obj ):
- #{
- global cv_view_verts, cv_view_colours
-
- sw = Vector((0.4,0.4,0.4,0.2))
- sw2 = Vector((1.5,0.2,0.2,0.0))
- if obj.cv_data.target != None:
- cv_draw_bpath( obj, obj.cv_data.target, sw, sw )
- if obj.cv_data.target1 != None:
- cv_draw_bpath( obj, obj.cv_data.target1, sw, sw )
-
- cv_draw_bhandle( obj, 1.0, (0.8,0.8,0.8,1.0) )
- cv_draw_bhandle( obj, -1.0, (0.4,0.4,0.4,1.0) )
-
- p1 = obj.location+ \
- obj.matrix_world.to_quaternion() @ Vector((0,0,-6+1.5))
- cv_draw_arrow( obj.location, p1, sw )
- #}
-
- @staticmethod
- def editor_interface( layout, obj ):
- #{
- layout.prop( obj.cv_data, "target", text="Left" )
- layout.prop( obj.cv_data, "target1", text="Right" )
- #}
-#}
-
-# Classtype 9
-#
-# Purpose: Defines a route, its 'starting' point, and the colour to use for it
-#
-class classtype_route(Structure):
-#{
- _pack_ = 1
- _fields_ = [("id_start",c_uint32),
- ("pstr_name",c_uint32),
- ("colour",c_float*3)]
-
- def encode_obj(_, node,node_def):
- #{
- node.classtype = 9
- obj = node_def['obj']
-
- _.colour[0] = obj.cv_data.colour[0]
- _.colour[1] = obj.cv_data.colour[1]
- _.colour[2] = obj.cv_data.colour[2]
- _.pstr_name = encoder_process_pstr( obj.cv_data.strp )
-
- if obj.cv_data.target != None:
- _.id_start = obj.cv_data.target.cv_data.uid
- #}
-
- @staticmethod
- def draw_scene_helpers( obj ):
- #{
- global cv_view_verts, cv_view_colours, cv_view_course_i
-
- if obj.cv_data.target:
- cv_draw_arrow( obj.location, obj.cv_data.target.location, [1,1,1,1] )
-
- # Tries to simulate how we do it in the game
- #
- stack = [None]*64
- stack_i = [0]*64
- stack[0] = obj.cv_data.target
- si = 1
- loop_complete = False
-
- while si > 0:
- #{
- if stack_i[si-1] == 2:
- #{
- si -= 1
- continue
-
- if si == 0: # Loop failed to complete
- break
- #}
-
- node = stack[si-1]
-
- targets = [None,None]
- targets[0] = node.cv_data.target
-
- if node.cv_data.classtype == 'classtype_route_node':
- #{
- targets[1] = node.cv_data.target1
- #}
-
- nextnode = targets[stack_i[si-1]]
- stack_i[si-1] += 1
-
- if nextnode != None: # branch
- #{
- if nextnode == stack[0]: # Loop completed
- #{
- loop_complete = True
- break
- #}
-
- valid=True
- for sj in range(si):
- #{
- if stack[sj] == nextnode: # invalidated path
- #{
- valid=False
- break
- #}
- #}
-
- if valid:
- #{
- stack_i[si] = 0
- stack[si] = nextnode
- si += 1
- continue
- #}
- #}
- #}
-
- if loop_complete:
- #{
- cc = Vector((obj.cv_data.colour[0],\
- obj.cv_data.colour[1],\
- obj.cv_data.colour[2],\
- 1.0))
-
- for sj in range(si):
- #{
- sk = (sj+1)%si
-
- if stack[sj].cv_data.classtype == 'classtype_gate' and \
- stack[sk].cv_data.classtype == 'classtype_gate':
- #{
- dist = (stack[sj].location-stack[sk].location).magnitude
- cv_draw_sbpath( stack[sj], stack[sk], cc*0.4, cc, dist, dist )
- #}
- else:
- cv_draw_bpath( stack[sj], stack[sk], cc, cc )
- #}
-
- cv_view_course_i += 1
- #}
- #}
-
- @staticmethod
- def editor_interface( layout, obj ):
- #{
- layout.prop( obj.cv_data, "target", text="'Start' from" )
- layout.prop( obj.cv_data, "colour" )
- layout.prop( obj.cv_data, "strp", text="Name" )
- #}
-#}
-
-# Classtype 12
-#
-# Purpose: links an mesh node to a type 11
-#
-class classtype_skin(Structure):
-#{
- _pack_ = 1
- _fields_ = [("skeleton",c_uint32)]
-
- def encode_obj(_, node,node_def):
- #{
- node.classtype = 12
-
- armature_def = node_def['linked_armature']
- _.skeleton = armature_def['obj'].cv_data.uid
- #}
-#}
-
-# Classtype 11
-#
-# Purpose: defines the allocation requirements for a skeleton
-#
-class classtype_skeleton(Structure):
-#{
- _pack_ = 1
- _fields_ = [("channels",c_uint32),
- ("ik_count",c_uint32),
- ("collider_count",c_uint32),
- ("anim_start",c_uint32),
- ("anim_count",c_uint32)]
-
- def encode_obj(_, node,node_def):
- #{
- node.classtype = 11
-
- _.channels = len( node_def['bones'] )
- _.ik_count = node_def['ik_count']
- _.collider_count = node_def['collider_count']
- _.anim_start = node_def['anim_start']
- _.anim_count = node_def['anim_count']
- #}
-#}
-
-
-# Classtype 10
-#
-# Purpose: intrinsic bone type, stores collision information and limits too
-#
-class classtype_bone(Structure):
-#{
- _pack_ = 1
- _fields_ = [("flags",c_uint32),
- ("ik_target",c_uint32),
- ("ik_pole",c_uint32),
- ("hitbox",(c_float*3)*2),
- ("conevx",c_float*3),
- ("conevy",c_float*3),
- ("coneva",c_float*3),
- ("conet",c_float)]
-
- def encode_obj(_, node,node_def):
- #{
- node.classtype = 10
-
- armature_def = node_def['linked_armature']
- obj = node_def['bone']
-
- _.flags = node_def['deform']
-
- if 'ik_target' in node_def:
- #{
- _.flags |= 0x2
- _.ik_target = armature_def['bones'].index( node_def['ik_target'] )
- _.ik_pole = armature_def['bones'].index( node_def['ik_pole'] )
- #}
-
- # For ragdolls
- #
- if obj.cv_data.collider != 'collider_none':
- #{
- if obj.cv_data.collider == 'collider_box':
- _.flags |= 0x4
- else:
- _.flags |= 0x8
-
- _.hitbox[0][0] = obj.cv_data.v0[0]
- _.hitbox[0][1] = obj.cv_data.v0[2]
- _.hitbox[0][2] = -obj.cv_data.v1[1]
- _.hitbox[1][0] = obj.cv_data.v1[0]
- _.hitbox[1][1] = obj.cv_data.v1[2]
- _.hitbox[1][2] = -obj.cv_data.v0[1]
- #}
-
- if obj.cv_data.con0:
- #{
- _.flags |= 0x100
- _.conevx[0] = obj.cv_data.conevx[0]
- _.conevx[1] = obj.cv_data.conevx[2]
- _.conevx[2] = -obj.cv_data.conevx[1]
- _.conevy[0] = obj.cv_data.conevy[0]
- _.conevy[1] = obj.cv_data.conevy[2]
- _.conevy[2] = -obj.cv_data.conevy[1]
- _.coneva[0] = obj.cv_data.coneva[0]
- _.coneva[1] = obj.cv_data.coneva[2]
- _.coneva[2] = -obj.cv_data.coneva[1]
- _.conet = obj.cv_data.conet
- #}
- #}
-#}
-
-# Classtype 100
-#
-# Purpose: sends a signal to another entity
-#
-class classtype_trigger(Structure):
-#{
- _pack_ = 1
- _fields_ = [("target",c_uint32)]
-
- def encode_obj(_, node,node_def ):
- #{
- node.classtype = 100
- if node_def['obj'].cv_data.target:
- _.target = node_def['obj'].cv_data.target.cv_data.uid
- #}
-
- @staticmethod
- def draw_scene_helpers( obj ):
- #{
- global cv_view_verts, cv_view_colours
- cv_draw_ucube( obj.matrix_world, [0,1,0,1] )
-
- white = (1,1,1,1)
-
- if obj.cv_data.target:
- cv_draw_arrow( obj.location, obj.cv_data.target.location, white, 0.7 )
- #}
-
- @staticmethod
- def editor_interface( layout, obj ):
- #{
- layout.prop( obj.cv_data, "target", text="Triggers" )
- #}
-#}
-
-# Classtype 101
-#
-# Purpose: Gives the player an achievement.
-# No cheating! You shouldn't use this entity anyway, since only ME can
-# add achievements to the steam ;)
-#
-class classtype_logic_achievement(Structure):
-#{
- _pack_ = 1
- _fields_ = [("pstr_name",c_uint32)]
-
- def encode_obj(_, node,node_def ):
- #{
- node.classtype = 101
- _.pstr_name = encoder_process_pstr( node_def['obj'].cv_data.strp )
- #}
-
- @staticmethod
- def editor_interface( layout, obj ):
- #{
- layout.prop( obj.cv_data, "strp", text="Achievement ID" )
- #}
-#}
-
-class union_128bit_data(Union):
-#{
- _pack_ = 1
- _fields_ = [("f32",c_float),
- ("u32",c_uint32),
- ("i32",c_int32),
- ("v4f",c_float*4)]
-#}
-
-# Class type 105
-#
-# Purpose:
-#
-class classtype_logic_wire(Structure):
-#{
- _pack_ = 1
- _fields_ = [("next",c_uint32),
- ("function",c_uint32),
- ("data",union_128bit_data),
- ("data_type",c_uint32),
- ("enabled",c_uint32)]
-
- function_enum = [('0',"pass along",""),
- ('1',"enable",""),
- ('2',"disable",""),
- ('3',"","")]
-
- def encode_obj(_,node,node_def):
- #{
- node.classtype = 105
-
- obj = node_def['obj']
-
- if obj.cv_data.target: _.next = obj.cv_data.target.cv_data.uid
-
- _.data_type = obj.cv_data.intp1
- _.function = int(obj.cv_data.function)
- _.enabled = obj.cv_data.bp0
-
- if _.data_type == 1: # an integer
- _.data.i32 = obj.cv_data.intp
- elif _.data_type == 2: # a number
- _.data.f32 = obj.cv_data.fltp
- elif _.data_type == 3: # a target
- if obj.cv_data.target2:
- _.data.u32 = obj.cv_data.target2.cv_data.uid
- elif _.data_type == 4: # a string
- _.data.u32 = encoder_process_pstr( obj.cv_data.strp )
- #}
-
- @staticmethod
- def editor_interface( layout, obj ):
- #{
- layout.prop( obj.cv_data, "bp0", text="Start disabled" )
- box = layout.box()
- box.label( text="Target" )
- box.prop( obj.cv_data, "target", text="connection" )
-
- row = box.row()
- if not obj.cv_data.target:
- row.enabled=False
- row.prop( obj.cv_data, "function", text="function" )
-
- box = layout.box()
- box.label( text="Data packet" )
- box.prop( obj.cv_data, "intp1", text="type" )
-
- if obj.cv_data.intp1 == 1:
- box.prop( obj.cv_data, "intp", text="Signed Integer" )
- elif obj.cv_data.intp1 == 2:
- box.prop( obj.cv_data, "fltp", text="Float" )
- elif obj.cv_data.intp1 == 3:
- box.prop( obj.cv_data, "target2", text="Object reference" )
- elif obj.cv_data.intp1 == 4:
- box.prop( obj.cv_data, "strp", text="String" )
- else:
- #{
- row = box.row()
- row.enabled=False
- row.label( text="this wire will not impart any data" )
- #}
- #}
-
- @staticmethod
- def draw_scene_helpers( obj ):
- #{
- global cv_view_verts, cv_view_colours
-
- white = (1,1,1,1)
- purple = (0.5,0.2,1,1)
-
- if obj.cv_data.target:
- cv_draw_arrow( obj.location, obj.cv_data.target.location, white, 0.7 )
- if (obj.cv_data.target2) and (obj.cv_data.intp1 == 3):
- cv_draw_arrow( obj.cv_data.target2.location, obj.location,purple, 0.7 )
- #}
-
- @staticmethod
- def get_targeted_methods( scene, context ):
- #{
- obj = context.object
- invalid = [('0',"",""),
- ('1',"",""),
- ('2',"",""),
- ('3',"","")]
-
- if obj.cv_data.target:
- #{
- classtype = obj.cv_data.target.cv_data.classtype
- if classtype == 'classtype_none' or classtype not in globals():
- #{
- return invalid
- #}
- else:
- #{
- cl = globals()[ classtype ]
- if getattr( cl, "function_enum", None ):
- #{
- return cl.function_enum
- #}
- else:
- #{
- return invalid
- #}
- #}
- #}
- else:
- #{
- return invalid
- #}
- #}
-#}
-
-# Class type 108
-#
-# Purpose:
-#
-class classtype_particle_box(Structure):
-#{
- _pack_ = 1
- _fields_ = [("target",c_uint32),
- ("rate",c_float)]
-
- function_enum = [('0',"set rate",""),
- ('1',"",""),
- ('2',"",""),
- ('3',"","")]
-
- def encode_obj(_, node,node_def ):
- #{
- node.classtype = 108
-
- obj = node_def['obj']
-
- _.rate = obj.cv_data.fltp
- if obj.cv_data.target:
- _.target = obj.cv_data.target.cv_data.uid
- #}
-
- @staticmethod
- def draw_scene_helpers( obj ):
- #{
- global cv_view_verts, cv_view_colours
- cv_draw_ucube( obj.matrix_world, [1,0.8,0,1] )
-
- white = (1,1,1,1)
- if obj.cv_data.target:
- cv_draw_arrow( obj.location, obj.cv_data.target.location, white, 0.7 )
- #}
-
- @staticmethod
- def editor_interface( layout, obj ):
- #{
- layout.prop( obj.cv_data, "target", text="Triggers" )
- layout.prop( obj.cv_data, "fltp", text="count per second" )
- #}
-#}
-
-# Class type 109
-#
-# Purpose:
-#
-class classtype_signal_splitter(Structure):
-#{
- _pack_ = 1
- _fields_ = [("next",c_uint32*4)]
-
- function_enum = [('0',"pass along",""),
- ('1',"",""),
- ('2',"",""),
- ('3',"","")]
-
- def encode_obj(_,node,node_def):
- #{
- node.classtype = 109
-
- obj = node_def['obj']
-
- if obj.cv_data.target: _.next[0] = obj.cv_data.target.cv_data.uid
- if obj.cv_data.target1: _.next[1] = obj.cv_data.target1.cv_data.uid
- if obj.cv_data.target2: _.next[2] = obj.cv_data.target2.cv_data.uid
- if obj.cv_data.target3: _.next[3] = obj.cv_data.target3.cv_data.uid
- #}
-
- @staticmethod
- def editor_interface( layout, obj ):
- #{
- layout.label( text="The split signals will run in order" )
- layout.prop( obj.cv_data, "target", text="#0" )
- layout.prop( obj.cv_data, "target1", text="#1" )
- layout.prop( obj.cv_data, "target2", text="#2" )
- layout.prop( obj.cv_data, "target3", text="#3" )
- #}
-
- @staticmethod
- def draw_scene_helpers( obj ):
- #{
- global cv_view_verts, cv_view_colours
-
- c0 = (1,0.5,0.2,1)
- c1 = (0.8,1,0.1,1)
- c2 = (0.3,0.9,0.4,1)
- c3 = (0.1,0.4,1.0,1)
-
- if obj.cv_data.target:
- cv_draw_arrow( obj.location, obj.cv_data.target.location, c0, 0.7 )
- if obj.cv_data.target1:
- cv_draw_arrow( obj.location, obj.cv_data.target1.location, c1, 0.7 )
- if obj.cv_data.target2:
- cv_draw_arrow( obj.location, obj.cv_data.target2.location, c2, 0.7 )
- if obj.cv_data.target3:
- cv_draw_arrow( obj.location, obj.cv_data.target3.location, c3, 0.7 )
- #}
-#}
+# 400: Routes
+# ---------------------------------------------------------------------------- #
-# Class type 106
-#
-# Purpose:
+# Purpose: Defines a route, its 'starting' point, and the colour to use for it
#
-class classtype_soundscape(Structure):
+class classtype_route(Structure):
#{
_pack_ = 1
- _fields_ = [("max_instances",c_uint32),
- ("allow_transitions",c_uint32),
- ("transition_duration",c_float),
- ("label",c_uint32)]
-
- function_enum = [('0',"play",""),
- ('1',"set position",""),
- ('2',"",""),
- ('3',"","")]
+ _fields_ = [("id_start",c_uint32),
+ ("pstr_name",c_uint32),
+ ("colour",c_float*3)]
- def encode_obj(_,node,node_def):
+ def encode_obj(_, node,node_def):
#{
- node.classtype = 106
-
+ node.classtype = 400
obj = node_def['obj']
- _.max_instances = obj.cv_data.intp
- _.allow_transitions = obj.cv_data.bp0
- _.transition_duration = obj.cv_data.fltp
- _.label = encoder_process_pstr( obj.cv_data.strp )
+ _.colour[0] = obj.cv_data.colour[0]
+ _.colour[1] = obj.cv_data.colour[1]
+ _.colour[2] = obj.cv_data.colour[2]
+ _.pstr_name = encoder_process_pstr( obj.cv_data.strp )
+
+ if obj.cv_data.target != None:
+ _.id_start = obj.cv_data.target.cv_data.uid
#}
@staticmethod
- def editor_interface( layout, obj ):
+ def draw_scene_helpers( obj ):
#{
- layout.prop( obj.cv_data, "intp", text="max instances" )
- layout.prop( obj.cv_data, "strp", text="label" )
+ global cv_view_verts, cv_view_colours, cv_view_course_i
- box = layout.box()
- box.label( text="If its a 3d sound, where can it spawn?" )
- box.prop( obj.cv_data, "bp1", text="Only in water" )
- box.prop( obj.cv_data, "bp2", text="Only on grass" )
- box.prop( obj.cv_data, "bp3", text="Only on wood" )
+ if obj.cv_data.target:
+ cv_draw_arrow( obj.location, obj.cv_data.target.location, [1,1,1,1] )
+
+ # Tries to simulate how we do it in the game
+ #
+ stack = [None]*64
+ stack_i = [0]*64
+ stack[0] = obj.cv_data.target
+ si = 1
+ loop_complete = False
- box = layout.box()
- box.prop( obj.cv_data, "bp0", text="allow transitions" )
+ while si > 0:
+ #{
+ if stack_i[si-1] == 2:
+ #{
+ si -= 1
+ continue
- row = box.row()
- if not obj.cv_data.bp0:
- row.enabled=False
- row.prop( obj.cv_data, "fltp", text="transition duration" )
- #}
-#}
+ if si == 0: # Loop failed to complete
+ break
+ #}
-class classtype_logic_chances(Structure):
-#{
- _pack_ = 1
- _fields_ = [("targets",c_uint32*2),
- ("p",c_float)]
+ node = stack[si-1]
- function_enum = [('0',"pass along",""),
- ('1',"set ratio",""),
- ('2',"",""),
- ('3',"","")]
+ targets = [None,None]
+ targets[0] = node.cv_data.target
- def encode_obj(_,node,node_def):
- #{
- node.classtype = 107
+ if node.cv_data.classtype == 'classtype_route_node':
+ #{
+ targets[1] = node.cv_data.target1
+ #}
+
+ nextnode = targets[stack_i[si-1]]
+ stack_i[si-1] += 1
- obj = node_def['obj']
+ if nextnode != None: # branch
+ #{
+ if nextnode == stack[0]: # Loop completed
+ #{
+ loop_complete = True
+ break
+ #}
- if obj.cv_data.target: _.targets[0] = obj.cv_data.target.cv_data.uid
- if obj.cv_data.target1: _.targets[1] = obj.cv_data.target1.cv_data.uid
-
- _.p = obj.cv_data.fltp
- #}
+ valid=True
+ for sj in range(si):
+ #{
+ if stack[sj] == nextnode: # invalidated path
+ #{
+ valid=False
+ break
+ #}
+ #}
- @staticmethod
- def editor_interface( layout, obj ):
- #{
- box = layout.box()
- box.prop( obj.cv_data, "target", text="red" )
- box.prop( obj.cv_data, "target1", text="black" )
- box.prop( obj.cv_data, "fltp", text="p(red)" )
+ if valid:
+ #{
+ stack_i[si] = 0
+ stack[si] = nextnode
+ si += 1
+ continue
+ #}
+ #}
+ #}
+
+ if loop_complete:
+ #{
+ cc = Vector((obj.cv_data.colour[0],\
+ obj.cv_data.colour[1],\
+ obj.cv_data.colour[2],\
+ 1.0))
+
+ for sj in range(si):
+ #{
+ sk = (sj+1)%si
+
+ if stack[sj].cv_data.classtype == 'classtype_gate' and \
+ stack[sk].cv_data.classtype == 'classtype_gate':
+ #{
+ dist = (stack[sj].location-stack[sk].location).magnitude
+ cv_draw_sbpath( stack[sj], stack[sk], cc*0.4, cc, dist, dist )
+ #}
+ else:
+ cv_draw_bpath( stack[sj], stack[sk], cc, cc )
+ #}
+
+ cv_view_course_i += 1
+ #}
#}
@staticmethod
- def draw_scene_helpers( obj ):
+ def editor_interface( layout, obj ):
#{
- global cv_view_verts, cv_view_colours
-
- red = (1,0,0,1)
- black = (0,0,0,1)
-
- if obj.cv_data.target:
- cv_draw_arrow( obj.location, obj.cv_data.target.location, red, 0.7 )
- if obj.cv_data.target1:
- cv_draw_arrow( obj.location, obj.cv_data.target1.location, black, 0.7 )
+ layout.prop( obj.cv_data, "target", text="'Start' from" )
+ layout.prop( obj.cv_data, "colour" )
+ layout.prop( obj.cv_data, "strp", text="Name" )
#}
#}
-# Classtype 102 [ DEPRECATED ]
-#
-# Purpose: sends a signal to another entity
+# Purpose: Defines a route node and links to up to two more nodes
#
-class classtype_logic_relay(Structure):
+class classtype_route_node(Structure):
#{
_pack_ = 1
- _fields_ = [("targets",c_uint32*4)]
+ _fields_ = [("target",c_uint32),
+ ("target1",c_uint32)]
- def encode_obj(_, node,node_def ):
+ def encode_obj(_, node,node_def):
#{
- node.classtype = 102
+ node.classtype = 401
obj = node_def['obj']
- if obj.cv_data.target:
- _.targets[0] = obj.cv_data.target.cv_data.uid
- if obj.cv_data.target1:
- _.targets[1] = obj.cv_data.target1.cv_data.uid
- if obj.cv_data.target2:
- _.targets[2] = obj.cv_data.target2.cv_data.uid
- if obj.cv_data.target3:
- _.targets[3] = obj.cv_data.target3.cv_data.uid
+
+ if obj.cv_data.target != None:
+ _.target = obj.cv_data.target.cv_data.uid
+ if obj.cv_data.target1 != None:
+ _.target1 = obj.cv_data.target1.cv_data.uid
#}
@staticmethod
#{
global cv_view_verts, cv_view_colours
- if obj.cv_data.target:
- cv_draw_arrow( obj.location, obj.cv_data.target.location, [1,1,1,1] )
- if obj.cv_data.target1:
- cv_draw_arrow( obj.location, obj.cv_data.target1.location, [1,1,1,1] )
- if obj.cv_data.target2:
- cv_draw_arrow( obj.location, obj.cv_data.target2.location, [1,1,1,1] )
- if obj.cv_data.target3:
- cv_draw_arrow( obj.location, obj.cv_data.target3.location, [1,1,1,1] )
+ sw = Vector((0.4,0.4,0.4,0.2))
+ sw2 = Vector((1.5,0.2,0.2,0.0))
+ if obj.cv_data.target != None:
+ cv_draw_bpath( obj, obj.cv_data.target, sw, sw )
+ if obj.cv_data.target1 != None:
+ cv_draw_bpath( obj, obj.cv_data.target1, sw, sw )
+
+ cv_draw_bhandle( obj, 1.0, (0.8,0.8,0.8,1.0) )
+ cv_draw_bhandle( obj, -1.0, (0.4,0.4,0.4,1.0) )
+
+ p1 = obj.location+ \
+ obj.matrix_world.to_quaternion() @ Vector((0,0,-6+1.5))
+ cv_draw_arrow( obj.location, p1, sw )
#}
@staticmethod
def editor_interface( layout, obj ):
#{
- layout.prop( obj.cv_data, "target", text="Triggers" )
- layout.prop( obj.cv_data, "target1", text="Triggers" )
- layout.prop( obj.cv_data, "target2", text="Triggers" )
- layout.prop( obj.cv_data, "target3", text="Triggers" )
+ layout.prop( obj.cv_data, "target", text="Left" )
+ layout.prop( obj.cv_data, "target1", text="Right" )
#}
#}
-# Classtype 14
-#
-# Purpose: Plays some audio (44100hz .ogg vorbis only)
-# NOTE: There is a 32mb limit on the audio buffer, world audio is
-# decompressed and stored in signed 16 bit integers (2 bytes)
-# per sample.
-#
-# volume: not used if has 3D flag
+
+# 500: Audio
+# ---------------------------------------------------------------------------- #
+
+AUDIO_SPRITE_CATEGORIES_ENUM = [
+ ('0', "Bird", ""),
+ ('1', "Nocturnal Bird", ""),
+ ('2', "Grass", ""),
+ ('3', "Wave",""),
+ ('4', "Wind",""),
+ ('5', "Wood Creaks", ""),
+ ]
+
# flags:
# AUDIO_FLAG_LOOP 0x1
# AUDIO_FLAG_SPACIAL_3D 0x4 (Probably what you want)
-# AUDIO_FLAG_AUTO_START 0x8 (Play when the world starts)
-# ......
-# the rest are just internal flags, only use the above 3.
#
class classtype_audio(Structure):
#{
("flags",c_uint32),
("volume",c_float)]
+ dynamic_enum = [
+ ('0', "mono", ""),
+ ('1', "stereo", ""),
+ ('2', "remain compressed", ""),
+ ('3', "synthetic bird",""),
+ ]
+
def encode_obj(_, node,node_def ):
#{
- node.classtype = 14
+ node.classtype = 500
obj = node_def['obj']
if obj.cv_data.bp1: flags |= 0x4
if obj.cv_data.bp2: flags |= 0x8
- if obj.cv_data.audio_format == 'stereo':
- flags |= 0x200
- if obj.cv_data.audio_format == 'remain compressed':
- flags |= 0x400
- if obj.cv_data.audio_format == 'synthetic bird':
- flags |= 0x1000
+ if obj.cv_data.dynamic_enum == '1': flags |= 0x200
+ if obj.cv_data.dynamic_enum == '2': flags |= 0x400
+ if obj.cv_data.dynamic_enum == '3': flags |= 0x1000
_.flags = flags
_.volume = obj.cv_data.fltp
@staticmethod
def editor_interface( layout, obj ):
#{
- layout.prop( obj.cv_data, "strp", text = "File (.ogg)" )
+ layout.prop( obj.cv_data, "strp", text = "File (.ogg/DATA)" )
layout.prop( obj.cv_data, "bp0", text = "Looping" )
layout.prop( obj.cv_data, "bp1", text = "3D Audio" )
- layout.prop( obj.cv_data, "bp2", text = "Auto Start" )
- layout.prop( obj.cv_data, "audio_format" )
+ layout.prop( obj.cv_data, "bp2", text = "Play here" )
+ layout.prop( obj.cv_data, "dynamic_enum" )
layout.prop( obj.cv_data, "fltp", text = "Volume (0-1)" )
#}
#{
global cv_view_verts, cv_view_colours
- cv_draw_sphere( obj.location, obj.scale[0], [1,1,0,1] )
+ if bpy.context.active_object == obj:
+ cv_draw_sphere( obj.location, obj.scale[0], [1,1,0,1] )
#}
#}
-
-# Classtype 200
-#
-# Purpose: world light
-#
-class classtype_world_light( Structure ):
+class classtype_audio_sprite(Structure):
#{
_pack_ = 1
- _fields_ = [("type",c_uint32),
- ("colour",c_float*4),
- ("angle",c_float),
- ("range",c_float)]
+ _fields_ = [("audio",c_uint32),
+ ("category",c_uint32),
+ ("probability",c_float)]
- def encode_obj(_, node, node_def):
- #{
- node.classtype = 200
+ dynamic_enum = AUDIO_SPRITE_CATEGORIES_ENUM
- obj = node_def['obj']
- data = obj.data
- _.colour[0] = data.color[0]
- _.colour[1] = data.color[1]
- _.colour[2] = data.color[2]
- _.colour[3] = data.energy
- _.range = data.cutoff_distance # this has to be manually set
- # TODO: At some point, automate a min
- # threshold value
+ def encode_obj(_, node,node_def ):
+ #{
+ node.classtype = 501
+ obj = node_def['obj']
- if obj.data.type == 'POINT':
- #{
- _.type = 0
- _.angle = 0.0
- #}
- elif obj.data.type == 'SPOT':
- #{
- _.type = 1
- _.angle = data.spot_size*0.5
- #}
+ _.category = int( obj.cv_data.dynamic_enum )
+ _.probability = obj.cv_data.fltp
- if data.cv_data.bp0:
- _.type += 2
+ if obj.cv_data.target:
+ _.audio = obj.cv_data.target.cv_data.uid
#}
@staticmethod
def editor_interface( layout, obj ):
#{
- pass
+ layout.prop( obj.cv_data, "dynamic_enum", text="Category" )
+ layout.prop( obj.cv_data, "target", text="Sound" )
+ layout.prop( obj.cv_data, "fltp", text="Probability" )
+ #}
+
+ @staticmethod
+ def draw_scene_helpers( obj ):
+ #{
+ global cv_view_verts, cv_view_colours
+
+ purple = (0.5,0.2,1,1)
+ if obj.cv_data.target:
+ cv_draw_arrow( obj.location, obj.cv_data.target.location, purple, 0.1 )
#}
#}
-# Classtype 201
-#
-# Purpose: lighting settings for world
-#
-class classtype_lighting_info(Structure):
+
+# 600: Volumes
+# ---------------------------------------------------------------------------- #
+
+class classtype_volume_audio(Structure):
#{
_pack_ = 1
- _fields_ = [("colours",(c_float*3)*3),
- ("directions",(c_float*2)*3),
- ("states",c_uint32*3),
- ("shadow_spread",c_float),
- ("shadow_length",c_float),
- ("ambient",c_float*3)]
+ _fields_ = [("category",c_uint32)]
- def encode_obj(_, node, node_def):
+ dynamic_enum = AUDIO_SPRITE_CATEGORIES_ENUM
+
+ def encode_obj(_, node,node_def ):
#{
- node.classtype = 201
+ node.classtype = 600
+
+ obj = node_def['obj']
+ _.category = int(obj.cv_data.dynamic_enum)
+ #}
- # TODO
+ @staticmethod
+ def draw_scene_helpers( obj ):
+ #{
+ global cv_view_verts, cv_view_colours
+ cv_draw_ucube( obj.matrix_world, [1,0.8,0,1] )
#}
@staticmethod
def editor_interface( layout, obj ):
#{
- pass
+ layout.prop( obj.cv_data, "dynamic_enum", text="Category" )
#}
#}
-class classtype_spawn_link(Structure):
+class classtype_volume_event(Structure):
#{
_pack_ = 1
- _fields_ = [("connections",c_uint32*4)]
+ _fields_ = [("event",c_uint32)]
def encode_obj(_, node,node_def ):
#{
- node.classtype = 0
- #}
-
- @staticmethod
- def editor_interface( layout, obj ):
- #{
- pass
+ node.classtype = 601
+ obj = node_def['obj']
+ _.event = encoder_process_pstr( obj.cv_data.strp )
#}
@staticmethod
def draw_scene_helpers( obj ):
#{
global cv_view_verts, cv_view_colours
-
- count = 0
-
- for obj1 in bpy.context.collection.objects:
- #{
- if (obj1.cv_data.classtype != 'classtype_spawn_link') and \
- (obj1.cv_data.classtype != 'classtype_spawn') :
- continue
-
- if (obj1.location - obj.location).length < 40.0:
- #{
- cv_draw_line( obj.location, obj1.location, [1,1,1,1] )
- count +=1
- #}
-
- if count == 4:
- break
- #}
-
- cv_draw_sphere( obj.location, 20.0, [0.5,0,0.2,0.4] )
+ cv_draw_ucube( obj.matrix_world, [0.0,1.0,0,1] )
#}
#}
#}
#}
+def cv_variable_enum( scene, context ):
+#{
+ obj = context.object
+ invalid = [('0',"",""),
+ ('1',"",""),
+ ('2',"",""),
+ ('3',"",""),
+ ('4',"",""),
+ ('5',"",""),
+ ('6',"",""),
+ ('7',"",""),
+ ('8',"",""),
+ ('9',"","")]
+
+ classtype = obj.cv_data.classtype
+
+ if classtype in globals():
+ #{
+ cl = globals()[ classtype ]
+ if getattr( cl, "dynamic_enum", None ):
+ if len(cl.dynamic_enum)>0:
+ return cl.dynamic_enum
+ #}
+
+ return invalid
+#}
+
class CV_OBJ_SETTINGS(bpy.types.PropertyGroup):
#{
uid: bpy.props.IntProperty( name="" )
colour: bpy.props.FloatVectorProperty( name="colour",subtype='COLOR',\
min=0.0,max=1.0)
- function: bpy.props.EnumProperty(
- name="Function",
- items= classtype_logic_wire.get_targeted_methods
+ dynamic_enum: bpy.props.EnumProperty(
+ name="",
+ items = cv_variable_enum
)
classtype: bpy.props.EnumProperty(
- name="Format",
- items = [
- ('classtype_none', "classtype_none", "", 0),
- ('classtype_gate', "classtype_gate", "", 1),
- ('classtype_spawn', "classtype_spawn", "", 3),
- ('classtype_water', "classtype_water", "", 4),
- ('classtype_route_node', "classtype_route_node", "", 8 ),
- ('classtype_route', "classtype_route", "", 9 ),
- ('classtype_audio',"classtype_audio","",14),
- ('classtype_trigger',"classtype_trigger","",100),
- ('classtype_logic_achievement',"classtype_logic_achievement","",101),
- ('classtype_logic_relay',"classtype_logic_relay","",102),
- ('classtype_logic_wire',"classtype_logic_wire","",105),
- ('classtype_soundscape',"classtype_soundscape","",106),
- ('classtype_logic_chances',"classtype_logic_chances","",107),
- ('classtype_particle_box',"classtype_particle_box","",108),
- ('classtype_signal_splitter',"classtype_signal_splitter","",109),
- ('classtype_spawn_link',"classtype_spawn_link","",150),
- ('classtype_nonlocal_gate', "classtype_nonlocal_gate", "", 300)
- ])
-
- audio_format: bpy.props.EnumProperty(
- name="Loaded format",
+ name="Class",
items = [
- ('mono', "mono", "", 0),
- ('stereo', "stereo", "", 1),
- ('remain compressed', "remain compressed", "", 2),
- ('synthetic bird',"synthetic bird","",3)
+ ('classtype_none', "None", ""), #000
+ ('classtype_gate', "Gate", ""), #100
+ ('classtype_nonlocal_gate', "Gate:NonLocal", ""), #101
+ ('classtype_spawn', "Spawn", ""), #200
+ ('classtype_water', "Water Surface", ""), #300
+ ('classtype_route', "Route", ""), #400
+ ('classtype_route_node', "Route:Node", ""), #401
+ ('classtype_audio', "Audio:File", ""), #500
+ ('classtype_audio_player', "Audio:Player", ""), #501
+ ('classtype_audio_sprite', "Audio:Sprite", ""), #502
+ ('classtype_volume_audio', "Volume:Audio", ""), #600
+ ('classtype_volume_event', "Volume:Event", ""), #601
+
+ ('300', "ERROR", "",300)
])
#}