|
|
(59 intermediate revisions by 6 users not shown) |
Line 1: |
Line 1: |
| {{XML_File_Header | type=ONLV | prev=ONLD | next=ONSK | name=Oni Game Level}} | | {{XML_File_Header | prev=ONLD | type=ONLV | next=ONSK | name=Oni Game Level}} |
| {{finish}}
| |
| ;Todo list
| |
| | |
| * tips with cutscene charas: sync pelvis OBAN and partner TRAM
| |
| * notes on camera and film import ?
| |
| * make new demo level after implementation of final scene import/export, dae-based CRSA import/export, shared folder bugfix, ENVP recycler
| |
| ** try to clean page a bit
| |
| ** also, import section of v0.9.99.0+ no longer supports node tags
| |
| | |
| <Import Path="env/lab_motorcycle.dae">
| |
| <Node Id="motorcycle">
| |
| <ScriptId>9</ScriptId>
| |
| <GunkFlags>NoCollision</GunkFlags>
| |
| </Node>
| |
| </Import>
| |
|
| |
| use instead:
| |
|
| |
| <Import Path="env/lab_motorcycle.dae">
| |
| <ScriptId>9</ScriptId>
| |
| <GunkFlags>NoCollision</GunkFlags>
| |
| </Import>
| |
| | |
|
| |
|
| __TOC__ | | __TOC__ |
|
| |
|
|
| |
|
| ==Level releases, forum threads and wiki pages==
| | ONLV and AKEV should not be extracted as XML unless it is for the purpose of trouble shooting or research. The extracted XMLs cannot be used for level creation. |
| ;Custom levels that have been created so far
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?id=2698 Wilderness Preserve] (19/1/14) uses level 17
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?id=2656 Island Level] (7/9/13) uses level 29
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?id=2640 City Level Part 1] (12/7/13) uses level 28
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?id=2619 Fight Club] (1/6/13) uses level 25
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?id=2357 Old China] (12/5/12) uses level 24
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?id=2302 Boss Battle] (18/3/12) uses level 23
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?id=2271 De Dust Deluxe] (12/2/12) uses level 22
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?id=2242 Parkour Challenge 2] (23/1/12) uses level 21
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?id=2235 Parkour Challenge] (16/1/12) uses level 21
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?id=2001 Mini-Partenon] (25/7/11)uses level 5
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?id=2024 Muro's Lair - Preview] (3/10/11) uses level 20
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?id=1957 Hexagon] (3/7/11) uses level 16
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?id=1938 Junkyard] (23/6/11) uses level 15
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?id=1736 Arena] (8/11/10) uses level 7
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?id=1506 Maze] (15/2/10) uses level 5
| |
| | |
| ;Fun facts:
| |
| * the [http://mods.oni2.net/node/327 Martian colony] level a.k.a. "Silly World" was one of the earliest levels imported (using OniSplit v0.9.29.0) but hasn't reached yet it's final release state
| |
| ** [http://oni.bungie.org/forum/viewtopic.php?pid=50565#p50565 OCF post]
| |
| | |
| | |
| ;OCF threads about level creation
| |
| * '''[http://oni.bungie.org/community/forum/viewtopic.php?id=2087 "Creating the Lair - A level tutorial"]'''
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?id=1515 "Creating new levels"]
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?pid=33838 "Create levels with pathfinding grids"]
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?id=2000 "More questions about levels"]
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?id=2003 "Sketchup tutorials for making levels"]
| |
| * [http://oni.bungie.org/community/forum/viewtopic.php?pid=37252#p37252 "Modding Existing levels - Beta" ("Moveable furniture" post)]
| |
| | |
| ;Wiki pages about levels
| |
| * [[New_levels]]
| |
| * [[Lightmapping_levels]]
| |
| * [[SketchUp_tutorials_and_tips|SketchUp tutorials and tips]]
| |
| | |
| ;Free texture resources
| |
| * [http://vk.com/gameready various game meshes]
| |
| * [http://www.tutorialsforblender3d.com/Textures/Textures_index.html various game textures]
| |
| * [http://www.cgtextures.com/ various game textures]
| |
| * [http://www.redsorceress.com/skybox.html redsorceress free skyboxes]
| |
| * [http://forums.epicgames.com/threads/603122-Remus-high-resolution-skydome-texture-pack skies and objects of the solar system]
| |
| * [http://blenderartists.org/forum/showthread.php?224065-New-High-resolution-sky-pack-for-Blender skies] <!-- (http://www.wuala.com/Olson/Photos/Optikz_360_Skies/) -->
| |
| * [http://blenderartists.org/forum/showthread.php?24038-Free-high-res-skymaps-%28Massive-07-update!%29 skies]
| |
| | |
| ==Concept phase==
| |
| Be aware of limitation of level and engine.
| |
| | |
| * triangle limit of a game level: ca. 520.000 (500.000 to be on save side)
| |
| * {{ModTool}} can save dae files with max. 64.000 triangles per object
| |
| * when polygons are too tightly packed the cam will look at too many of them and glitches appear: the visible GQs (GunkQuads) limit is 8192 (2^13), higher numbers will cause render bugs and call BSL message "Exceeded max visible GQs ''number''"; limited solutions to this:
| |
| ** decrease the gs_farclipplane_set value
| |
| ** hide objects by [[#.3CModel.3E|env_show]]
| |
| ** hide objects by ''level design''
| |
| *** for example departments in a building could be quite detailed because the view at the other departments/rooms is blocked by non-transparent walls
| |
| * The camera can look at 2049 transparent textures at once, one more and Oni crashes.
| |
| * characters are visible ''only'' within 4099|4099|4099 and -4099|-4099|-4099 world units
| |
| * geometry stops at ca. X=4228|Z=4228 and -4228|-4228 (height not tested)
| |
| * chr_debug_spheres = 1 visualizes collision spheres of characters, then you can check if they fit through a new entrance
| |
| | |
| | |
| ==Notes on Mod Tool and Google Sketchup==
| |
| Re-saving a dae file - that was originally made in Sketchup - in Mod Tool can result in a surprising change in size within Oni.
| |
| | |
| That due to a difference in the length specification.
| |
| | |
| : For example Sketchup dae file has: <unit meter="0.0254000" name="inch" />
| |
| : Re-saved Mod Tool dae file has: <unit meter="0.1" name="decimetre"></unit>
| |
| | |
| In that case you would need to open the new dae inside a text editor and change the length specification again.
| |
| | |
| | |
| ==Level import with OniSplit [http://mods.oni2.net/node/38 v0.9.82.0+]==
| |
| '''Demo files'''
| |
| | |
| Demo files can be downloaded [http://mods.oni2.net/node/299 here].
| |
| | |
| First put the new "OniSplit.exe" into the second "lab" folder alongside the xml files.
| |
| | |
| There's a "build.cmd" file. Those two are the important lines:
| |
| | |
| OniSplit.exe -create:level out lab.xml
| |
| OniSplit.exe -import:pc out level3_Final.dat
| |
| | |
| The first line create the *.oni files from a master.xml file, in this case "lab.xml". If final, the oni files can be put into a new AE package. | |
| | |
| The second line creates level archives which can be used '''for fast tests'''. They don't require you to install a package.
| |
| | |
| Instead of "nosep" you can now also use "pc" for the import. Mac does still use "sep".
| |
| | |
| If the game crashes while loading (at ca. 90% progress), be sure that the texture's x and y (pixel) dimension are power of two: 512, 256, 128, 64, etc.
| |
| | |
| If the game crashes while loading (at ca. 50-60% progress), be sure that the BINACJBOCharacters/AISA file has a player character.
| |
| | |
| If the game crashes while loading (at ca. 5-10% progress), check if all textures were inside the "out" folder.
| |
| | |
| : You can extract the AKEV file to xml, then search for the [[XML:AKEV#TXMA|TXMP array]].
| |
| | |
| : [https://dl.dropboxusercontent.com/u/139715/OniGalore/AKEV_texture_checker.vbs THIS] script checks which textures are missing by comparing the AKEV*.xml with its *.oni files folder. Adapt the two paths so that it works for you. Alt + 4, insert code, then F5.
| |
| | |
| "TXMP_marker_door" and "TXMP_marker_ghost" will be missing in the demo's "out" folder.
| |
| | |
| You can add this between the other two lines in the build.cmd to prevent a crash.
| |
| OniSplit.exe -create:txmp out env/markers/*.tga
| |
| | |
| | |
| ===The master xml file===
| |
| File paths can be either absolute or relative.
| |
| | |
| The '''master xml file name''' determine the '''bsl folder name''' and the '''AKEV and ONLV file name''' in the output folder.
| |
| | |
| | |
| '''Mandatory files''' for level import:
| |
| * ''level_environment''.dae
| |
| * ''level_bnv''.dae
| |
| * ''level_textures.tga/jpg/png''
| |
| * Character.xml or AISA with player
| |
| * ONSK name in <Sky> (on PC can be just a fake name; Mac need files ?)
| |
| * ONLD file (for new levels; read on [[Making_a_mod_package#Mod_Info.cfg|HERE]] about savegame unlocking)
| |
|
| |
|
| | If you want to create a new level check out the '''[[Creating a level|corresponding tutorial]]'''. |
|
| |
|
| | ==ONLV== |
| {| class="wikitable" width="100%" | | {| class="wikitable" width="100%" |
| !width=150px| XML tag | | !width=150px| XML tag |
| !width=120px| content type | | !width=120px| Content type |
| ! description | | ! Description |
| |-
| |
| | <?xml version="1.0" encoding="utf-8"?>
| |
| |valign="top"| float, flag
| |
| |valign="top"| Ignore this.
| |
| |-
| |
| | <Oni>
| |
| | -
| |
| |
| |
| |-
| |
| |valign="top"| <Level SharedPath="...">
| |
| |valign="top"| link
| |
| | The master xml file can link to other xml files, most of them are [[OBD:BINA/OBJC#OBJC_types|BINACJBO]] files. The file type gets declared inside the file, so the file name itself doesn't have to contain the type. Ergo, "BINACJBOCharacter.xml" can be given a simpler name like "Character.xml".
| |
| | |
| Some resources used by those xml files can be found in a "shared" folder. OniSplit copies textures and "physics" objects into the output folder; furniture objects will be integrate into the AKEV. Unused resources in the shared folder will be ignored. That way the final level archive / AE package contains only necessary files which saves the end-user space.
| |
| | |
| In the demo are various subfolders in shared folder: consoles, doors, furniture, triggers and turrets.
| |
| Following file types comes there without their file prefixes: CONS, DOOR, TRIG, OFGA. OniSplit recognize them nonetheless.
| |
| |-
| |
| | <Environment>
| |
| | -
| |
| |
| |
| |-
| |
| | <Model>
| |
| | -
| |
| | Used to import level geometry and static objects. See [[#<Model>|HERE]] for detailed information.
| |
| |-
| |
| | <Import Path="..."/>
| |
| | link
| |
| |
| |
| |-
| |
| | <Node Id="...">
| |
| | string
| |
| | informative (space for notes so to say)
| |
| |-
| |
| |valign="top"| <ScriptId>
| |
| |valign="top"| integer
| |
| | Tested with BSL command ...
| |
| : [[#<Model>|env_show Id 1]] (use 0 to hide)
| |
| : [[#Breakable glass with BSL recognition|env_broken Id [Id]]] (if also second Id is used then objects in that range get counted e.g. 3001, 3018 = 18)
| |
| : [[#Texture exchange|env_texswap Id texture]] (no file prefix/suffix allowed)
| |
| : [[#env_shade|env_shade Id Id R G B]]
| |
| Static objects store their Id in [[XML:AKEV#IDXA_.28quad_group_id.29|one of AKEV's IDXA instances]].
| |
| |-
| |
| |valign="top"| <GunkFlags>
| |
| |valign="top"| flag
| |
| |
| |
| ;AGQG (Gunk) flags (trimmed list)
| |
| see ''OniSplit -help enums'' for more flags
| |
| :None
| |
| :NoCollision
| |
| :NoObjectCollision
| |
| :NoCharacterCollision
| |
| :NoDecal
| |
| :TwoSided
| |
| :Invisible
| |
| |-
| |
| |valign="top"| <Rooms>
| |
| |valign="top"| -
| |
| | For detailed information see [[#<Rooms>|HERE]].
| |
| | |
| For Google Sketchup BNV tutorial see [http://oni.bungie.org/community/forum/viewtopic.php?pid=36760#p36760 HERE].
| |
| |-
| |
| | <Import Path="..."/>
| |
| | link
| |
| | File path to *.dae file. BNV data, used to create pathfinding.
| |
| |-
| |
| | <Textures> {{Anchor|textures_tag}}
| |
| | -
| |
| | With OniSplit v0.9.94.0+ you can use attributes to set the default import formats and max dimensions. For example:
| |
| | |
| : <Textures Format="BGR" AlphaFormat="RGBA" MaxSize="512">
| |
| | |
| Textures that aren't power of two (2^x) or bigger than 512 will be scaled to be that way. For example: 2003x2000 becomes 512x512.
| |
| |-
| |
| | <Texture Name="...">
| |
| | string
| |
| | TXMP file name to generate.
| |
| |-
| |
| | <Flags>
| |
| | flag
| |
| | Optional tag. For list of flags see [[XML:TXMP|HERE]].
| |
| |-
| |
| |valign="top"| <Format>
| |
| |valign="top"| flag
| |
| |
| |
| :DXT1
| |
| :BGR
| |
| :RGBA
| |
| :BGR555
| |
| :BGRA5551
| |
| :BGRA4444
| |
| |-
| |
| |valign="top"| <GunkFlags>
| |
| |valign="top"| flag
| |
| |
| |
| ;AGQG (Gunk) flags (trimmed list)
| |
| see ''OniSplit -help enums'' for more flags
| |
| :None
| |
| :NoCollision
| |
| :NoObjectCollision
| |
| :NoCharacterCollision
| |
| :NoDecal
| |
| :TwoSided
| |
| :Invisible
| |
| |-
| |
| | <Image>
| |
| | link
| |
| | File path to *.tga/jpg file.
| |
| |-
| |
| |valign="top"| <Sky>
| |
| |valign="top"| string
| |
| | ONSKfile.oni (without file pre- and suffix)
| |
| | |
| The import doesn't work with an empty tag. <Sky>clear</Sky> helps here; any other fictional name will also do.
| |
| | |
| For detailed information see [[XML:ONSK|HERE]].
| |
| |-
| |
| | <Objects>
| |
| | -
| |
| |
| |
| |-
| |
| |valign="top"| <Import>
| |
| |valign="top"| link
| |
| | File path. Supported files:
| |
| : [[XML:BINA/OBJC/CHAR|Character.xml]] (has to contain player character if there's no AISA file with it)
| |
| : [[XML:BINA/OBJC/CONS|Console.xml]]
| |
| : [[XML:BINA/OBJC/DOOR|Door.xml]]
| |
| : [[XML:BINA/OBJC/FLAG|Flag.xml]]
| |
| : [[#Furniture.xml|Furniture.xml]]
| |
| : [[XML:BINA/OBJC/NEUT|Neutral.xml]]
| |
| : [[XML:BINA/OBJC/PART|Particle.xml]]
| |
| : [[XML:BINA/OBJC/PATR|PatrolPath.xml]]
| |
| : [[#Physics.xml|Physics.xml]]
| |
| : [[XML:BINA/OBJC/PWRU|PowerUp.xml]]
| |
| : [[XML:SNDD#BINACJBOSound.xml|Sound.xml]]
| |
| : [[XML:BINA/OBJC/TRIG|Trigger.xml]]
| |
| : [[XML:BINA/OBJC/TRGV|TriggerVolume.xml]]
| |
| : [[XML:BINA/OBJC/WEAP|Weapon.xml]]
| |
| |-
| |
| | <Films>
| |
| | -
| |
| |
| |
| |-
| |
| | <Import>
| |
| | link
| |
| | File path to *.xml file. OniSplit creates a [[XML:FILM|FILM]] file from it. Used for characters in cutscenes.
| |
| |-
| |
| | <Cameras>
| |
| | -
| |
| |
| |
| |-
| |
| | <Camera Path="...">
| |
| | link
| |
| | File path to *.dae file. OniSplit creates an OBAN file from it. Used for cutscenes.
| |
| |-
| |
| | <Animation Name="..."/>
| |
| | string
| |
| | Name for the OBAN file.
| |
| |}
| |
| | |
| | |
| This is a '''trimmed''' version of the master file "lab.xml" from the demo. It's meant to give you a first impression. -- We might upload a smaller demo someday with all features nonetheless.
| |
| | |
| <?xml version="1.0" encoding="utf-8" ?>
| |
| <Oni>
| |
| <Level SharedPath="../shared">
| |
| <Environment>
| |
| <Model>
| |
| <Import Path="env/lab_env.dae"/>
| |
| <Import Path="env/lab_bomber_window.dae"/>
| |
| <Import Path="env/lab_motorcycle.dae">
| |
| <Node Id="motorcycle">
| |
| <ScriptId>9</ScriptId>
| |
| <GunkFlags>NoCollision</GunkFlags>
| |
| </Node>
| |
| </Import>
| |
| </Model>
| |
| <Rooms>
| |
| <Import Path="env/lab_bnv.dae"/>
| |
| </Rooms>
| |
| <Textures>
| |
| <Texture Name="GOO">
| |
| <Format>bgra4444</Format>
| |
| <GunkFlags>NoCollision</GunkFlags>
| |
| <Image>env/images/GOO.tga</Image>
| |
| </Texture>
| |
| </Textures>
| |
| </Environment>
| |
| <Sky>sunset</Sky>
| |
| <Objects>
| |
| <Import>Character.xml</Import>
| |
| <Import>Furniture.xml</Import>
| |
| <Import>TriggerVolume.xml</Import>
| |
| <Import>Physics.xml</Import>
| |
| </Objects>
| |
| <Films>
| |
| <Import>films/BomberKonRun01.xml</Import>
| |
| <Import>films/BomberKonRun02.xml</Import>
| |
| </Films>
| |
| <Cameras>
| |
| <Camera Path="cameras/BomberCam01.dae">
| |
| <Animation Name="BomberCam01"/>
| |
| </Camera>
| |
| <Camera Path="cameras/BomberCam02.dae">
| |
| <Animation Name="BomberCam02"/>
| |
| </Camera>
| |
| </Cameras>
| |
| </Level>
| |
| </Oni>
| |
| | |
| | |
| ====<Model>====
| |
| This tag is mandatory (it must be present to avoid errors); the model section contains one import path to the AKEV (level) geometry (*.dae) and can contain additional import paths for exceptions (*.dae).
| |
| | |
| Data from the demo:
| |
| | |
| <Import Path="env/lab_env.dae"/>
| |
| <Import Path="env/lab_motorcycle.dae">
| |
| <Node Id="motorcycle">
| |
| <ScriptId>9</ScriptId>
| |
| <GunkFlags>NoCollision</GunkFlags>
| |
| </Node>
| |
| </Import>
| |
| | |
| | |
| '''env_show'''
| |
| | |
| The motorcycle has here script id 9. You can show and hide the object with bsl command env_show whereby the second parameter means true or false. '''Never use 0 as id''' because it won't work.
| |
| | |
| env_show 9 1
| |
| env_show 9 0
| |
| | |
| EdT demonstrates [http://youtu.be/Em6wa5JTQNM here] env_show. The objects have collision.
| |
| | |
| | |
| The last original level (syndicate mountain compound) has a big satellite dish platform that can be made hidden. Obviously, such objects/areas can be made to have pathfinding too.
| |
| | |
| | |
| ;More possible applications of env_show:
| |
| * ground/ceiling/objects for cutscenes that become partially destroyed
| |
| * destrucable walls [http://www.youtube.com/watch?v=qgJUbPWX5yE like in Deus Ex 3] (trigger volume, replacing punch anim with punch-through-wall anim)
| |
| * grids in front of ventilation shafts (a little door object could be an alternative)
| |
| ** at the moment this can't be done because characters can't sneak under the top edge of the opening (the characters collision spheres are too big)
| |
| * managing object groups with trigger volumes (save multiple objects in one dae file)
| |
| | |
| <!-- atm, the effort is not worth the work
| |
| https://dl.dropboxusercontent.com/u/139715/OniGalore/TV_triggered_env_show.png
| |
| : edit: replace 0 by 25
| |
| | |
| If the objects appear to ''flash'' we could replace the hide_all_object_groups function with individual TV exit functions.
| |
| | |
| func hide_all_object_groups
| |
| {
| |
| # env_show id [1|0]
| |
| env_show 1 0
| |
| env_show 2 0
| |
| # ...
| |
| env_show 25 0
| |
| }
| |
|
| |
| func show_object_group (int grpA, int grpB, int grpC, int grpD, int grpE, int grpF, int grpG, int grpH)
| |
| {
| |
| env_show (grpA, 1)
| |
| env_show (grpB, 1)
| |
| env_show (grpC, 1)
| |
| env_show (grpD, 1)
| |
| env_show (grpE, 1)
| |
| env_show (grpF, 1)
| |
| env_show (grpG, 1)
| |
| env_show (grpH, 1)
| |
|
| |
| # missing arguments are taken to be 0
| |
| }
| |
|
| |
| func TV_25_enter
| |
| {
| |
| hide_all_object_groups
| |
|
| |
| # show object group of entered TV and of neighboring TVs
| |
| # (center, north, north east, east, east south, south, south west, west, west north)
| |
| # there's a limit of 8 arguments per function
| |
| show_object_group 25 1 2 3 4 5 6 7
| |
| show_object_group 8
| |
| }
| |
|
| |
| # other examples
| |
| func TV_6_enter
| |
| {
| |
| hide_all_object_groups
| |
| show_object_group 0 0 00 0 00 00 00 00
| |
| show_object_group 22
| |
| }
| |
|
| |
| func TV_20_enter
| |
| {
| |
| hide_all_object_groups
| |
| show_object_group 20 21 6 19
| |
| }
| |
| -->
| |
| | |
| | |
| =====Import of object groups=====
| |
| '''Mod Tool versus Sketchup'''
| |
| | |
| The meaning and behavior of "groups" greatly differs in these two programs.
| |
| | |
| :'''In Sketchup you can group objects which enables you to easily duplicate all objects inside a group''' and to scale/rotate/translate all together.'''
| |
| | |
| :'''In Mod Tool''' grouped objects are still lose and duplicating a group won't duplicate the objects. To achieve the same effect as in Sketchup, '''you have to create a hierarchy whereby any object can be the "parent" and all others the "children".'''
| |
| | |
| | |
| '''Google Sketchup'''
| |
| | |
| To create a group select two or more objects, right-click on the selection, "make group".
| |
| | |
| | |
| [[Image:ModTool_can_import_objs_in_hierarchies.jpg|right|thumb|Mod Tool can import objects in hierarchies to Oni.]]
| |
| '''Mod Tool'''
| |
| | |
| Either use the Explorer (A) or the Schematics(B) to create a hierarchy.
| |
| | |
| :(A) In Explorer window, drag and drop one or more objects onto another one.
| |
| | |
| :(B) Open the constrain tab at the right side. Select parent object, click "Parent", click the child object(s). Check the result in the Schematics window.
| |
| | |
| :'''Mod Tool: caution when saving to dae!'''
| |
| | |
| :A normal selection won't do. You have to select the object tree to successfully save a hierarchy. This is same way you do with Oni characters.
| |
| <!--
| |
| | |
| | |
| =====Import of smart object groups=====
| |
| Let's say there are two groups. If an edit is made to one mesh the clone in the other group is instantly edited the same way.
| |
| | |
| So that's a smart group.
| |
| :In Sketchup it is named "component".
| |
| :In Mod Tool it's named ???.
| |
| ::(Can be imported from Sketchup dae file but cause a crash when re-saving. I guess a script is needed to do the job.)
| |
| -->
| |
| | |
| | |
| =====Breakable glass with BSL recognition=====
| |
| Broken env objects can be recognized by bsl command ''env_broken (ID_1, ID_N)''. However, this whole thing requires additional code to work.
| |
| | |
| An example is the training level. Let's determine how we can set up such a thing.
| |
| | |
| First we need a [[XML:BINA/OBJC/TRGV|trigger volume]] like in level 1.
| |
| | |
| <TRGV Id="11495">
| |
| <Header>
| |
| <Flags>Locked</Flags>
| |
| <Position>-714.6615 -298 -555.2073</Position>
| |
| <Rotation>0 0 0</Rotation>
| |
| </Header>
| |
| <OSD>
| |
| <Name>tv75</Name>
| |
| <Scripts>
| |
| <Entry></Entry>
| |
| <Inside>targets_gone</Inside>
| |
| <Exit></Exit>
| |
| </Scripts>
| |
| <Teams>255</Teams>
| |
| <Size>400 31 270</Size>
| |
| <TriggerVolumeId>75</TriggerVolumeId>
| |
| <ParentId>0</ParentId>
| |
| <Notes></Notes>
| |
| <Flags>PlayerOnly</Flags>
| |
| </OSD>
| |
| </TRGV>
| |
| | |
| Now we need some BSL code.
| |
| | |
| var int inside_target_function;
| |
|
| |
| func void enter_target_function(void)
| |
| {
| |
| dprint enter_target_function
| |
| inside_target_function = 1;
| |
| }
| |
|
| |
| func void exit_target_function(void)
| |
| {
| |
| dprint exit_target_function
| |
| inside_target_function = 0;
| |
| }
| |
|
| |
| func void targets_are_not_gone(void)
| |
| {
| |
| # CB: turn off the trigger volume and sleep for a second
| |
| # so as not to cause hideous performance loss
| |
| trigvolume_enable tv75 0
| |
| sleep 60
| |
| trigvolume_enable tv75 1
| |
| }
| |
|
| |
| func void targets_gone(string ai_name)
| |
| {
| |
| if(inside_target_function eq 0)
| |
| {
| |
| enter_target_function() # catch other "targets_gone" functions to let them do nothing
| |
|
| |
| var int num_broken = env_broken(3001, 3018);
| |
| # if you only one target use scheme: env_broke(3001, 3001)
| |
|
| |
| if (num_broken eq 18)
| |
| {
| |
| targets_are_gone();
| |
| }
| |
|
| |
| if (num_broken < 18)
| |
| {
| |
| targets_are_not_gone(); # to set check interval to one second
| |
| }
| |
|
| |
| exit_target_function
| |
| }
| |
| }
| |
|
| |
| func targets_are_gone
| |
| {
| |
| trigvolume_enable tv75 0
| |
| # [...]
| |
| }
| |
| | |
| ;Explanation:
| |
| | |
| Player enters the TV, "targets_gone" gets triggered. The variable "inside_target_function" should be 0 be default, so we are entering now the first if statement. Next, we can assume that the player didn't destroy all glass objects, so "num_broken" will be less than 18: "targets_are_not_gone" gets called.
| |
| | |
| The TV function "targets_gone" would be triggered every frame but "targets_are_not_gone" increases the pause between checks: The TV gets deactivated for 60 frames. Then the TV becomes enabled again and will start anew until all glass objects got destroyed or player left the TV.
| |
| | |
| Unnecessary "targets_gone" functions will do nothing because "inside_target_function" was set to 1 by the first one.
| |
| | |
| "targets_are_gone" eventually disables the TV to prevent memory overflow, the function contains also all things "[...]" that you want to happen after the glass target broke.
| |
| | |
| | |
| =====Texture exchange=====
| |
| BSL command supported by PC and Mac:
| |
| : env_texswap ID texture
| |
| | |
| Might be useful to switch on/off static and animated textures. (News screen: running or off or smashed. Lava stream: flowing or stagnating or cooled down. Etc.)
| |
| | |
| A similar effect can be achieved by showing/hiding geometries with different textures as EdT has demonstrated in a private test. That way it should also be possible to have different vertex coloring for an area.
| |
| | |
| | |
| =====[http://softimage.wiki.softimage.com/xsidocs/tex_vcolor_CreatingColoratVerticesCAVMaps.htm Vertex coloring]=====
| |
| Observation: The sniper tower from level 19 Syndicate Mountain Compound can be isolated and re-imported as it is. It will appear quite dark.
| |
| | |
| If we remove "_color" from the object the shadows will be gone next time we import the tower.
| |
| | |
| Mod Tool: Explorer [8]
| |
| | |
| Object
| |
| |
| |
| +-- Polygon Mesh
| |
| |
| |
| +-- Cluster
| |
| |
| |
| +-- Polygon
| |
| | |
| |
| | +-- [...]
| |
| |
| |
| +-- NodeProperties
| |
| |
| |
| +-- '''_color'''
| |
| +-- texcoord (Explicit UVWs)
| |
| |
| |
| +-- Vertex_Color_Def
| |
| | |
| So, how do we modify that data?
| |
| | |
| | |
| '''Single object shading'''
| |
| | |
| If there's already a vertex color property you can use Shift + W to activate "Paint Vertex Color Tool". With Control + W you can change the brush color. R + Hold Click + Move Mouse let you change the Brush size. The more vertices (points) you have the more detailed you can make the shadows/colors. But keep in mind that too many polygons can destroy collision which make characters fall through the ground.
| |
| | |
| If there's no vertex color property the first use of Shift + W will create that property. But you can also manually create it via Property > Color at Vertices Map.
| |
| | |
| Here you can see one of my [http://youtu.be/zWT0-LsjjBU early attempts of vertex coloring]. --[[User:Paradox-01|paradox-01]] ([[User talk:Paradox-01|talk]]) 18:18, 16 March 2013 (CET)
| |
| | |
| | |
| '''Level-wide shading'''
| |
| | |
| {| style="float:right"
| |
| |[http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/3D_modding/light_test_modtool_zps9c453b41.png http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/3D_modding/light_test_modtool_tn_zps9a3a3f2e.png]
| |
| | |
| [http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/3D_modding/light_test_ingame_zps08118244.png http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/3D_modding/light_test_ingame_tn_zps967c06a9.png]
| |
| |}
| |
| | |
| To get a general shading/lightning you can set up light sources. "Infinite" lights are useful as global lighting while "Light Box", "Point", "Neon" and "Spot" are more suitable as local light sources. They can be accessed via Primitives > Light.
| |
| | |
| By default a Mod Tool scene has one Infinite light but it doesn't shine in every direction so you might want to add more Infinite lights. Let's say one Infinite light for each direction (+X, -X, +Y, -Y, +Z, -Z) with an intensity of circa 0.25 (night) or 0.75 (day).
| |
| | |
| The illumination of those lights can be integrated into the vertex color property. There's some information [http://oni.bungie.org/community/forum/viewtopic.php?pid=29089#p29089 at OCF], the quoted information is somewhat triple so don't get confused by it: at first detailed, then summarized, then a checklist.
| |
| | |
| Basically you can go with the checklist:
| |
| | |
| * Property > Color At Vertices Map
| |
| * Property > Render Map
| |
| * In render map property page, under Sampling select Vertices Only
| |
| * Under Surface Color choose Enable, then in the box below select Vertex _Color, if that option does not appear click on the New button next to it.
| |
| * Under Map select Illumination only
| |
| * Finally, click on the button Regenerate Maps...
| |
| | |
| This must be done for all objects separately.
| |
| | |
| : [https://dl.dropbox.com/u/139715/OniGalore/vertex_color_script.txt There's a script] which can apply vertex color and render maps to all '''selected''' objects. Load it into the script editor [alt] + [4] and hit [F5] to run it. (Be sure the script language was set to vb script.)
| |
| : The variable "overwrite_VC" can be changed.
| |
| :: With "1" all existing CAV maps of selected objects will be overwritten. This can take some time.
| |
| :: With "0" only selected objects without CAV maps will be the script's target.
| |
| | |
| | |
| '''Notes on ModTool view modes'''
| |
| * "Constant" let you see the colors of the vertex coloring only.
| |
| * "Textured Decal" let you see object textures only.
| |
| * "Shaded" let you see the illumination only.
| |
| * "Textured" let you see the textured object with illumination and vertex coloring.
| |
| | |
| | |
| '''env_shade'''
| |
| | |
| If you use env_shade use it with caution. It completely overwrites the vertex coloring.
| |
| | |
| # BSL command
| |
| # env_shade obj_id obj_id R G B
| |
|
| |
| # examples
| |
| env_shade 7 7 # object 7 will be black
| |
| env_shade 7 7 0 0 0 # object 7 will be black
| |
| env_shade 7 7 .31 .999 .5 # object 7 will be quite green
| |
| env_shade 7 10 1 1 1 # object 7, 8, 9, 10 lose all their shading
| |
| | |
| | |
| =====Baked lightmaps=====
| |
| A.k.a shadow maps.
| |
| | |
| A drawback of this method is the high amount of [[XML:BINA/TMBD|TMBD]] changes and new textures hence a lot of memory is needed.
| |
| | |
| How to create shadow maps:
| |
| | |
| * http://www.game-artist.net/forums/support-tech-discussion/5622-burning-shadows-onto-texture-xsi.html
| |
| <!-- http://caffeineabuse.blogspot.de/2008/12/cast-shadow-only-lights-in-xsi.html might be also interesting -->
| |
| | |
| Notes on map options:
| |
| * "Surface color and illumination": outputs used texture with added shadows
| |
| ** can be used to replace original texture
| |
| * "illumination only": output a texture that only contains the shadows
| |
| ** can be used on a new overlying, transparent surface
| |
| | |
| | |
| =====Standalone lightmaps=====
| |
| There are two meshes whereby the shadow effects get drawn in front of the regular level texture.
| |
| | |
| Compared to the "baked lightmaps" method, this needs more polygons of course. These polygons are transparent which is a problem with Oni's limited render ability for such textures. However, standalone lighmaps needs only a few new textures if used wisely.
| |
| | |
| Read on [[Lightmapping_levels|HERE]] for lightmap creation for this method.
| |
| | |
| [[Image:Oni_Lightmaps_double_polygon_method.jpg|center]]
| |
| | |
| ====<Rooms>====
| |
| The Rooms tag is mandatory. It contains an import path to BNV and ghosts (*.dae) which are used to create pathfinding grids. For information on binary data see [[OBD:AKVA|HERE]].
| |
| | |
| Exemplary code piece of the master xml file:
| |
| <Import Path="env/lab_bnv.dae"/>
| |
| | |
| | |
| '''Fundamentals'''
| |
| * '''BNV''' are '''volumes''' (sometimes also named '''rooms''') that have a pathfinding grid assigned to them.
| |
| * For practical reasons you only need '''floors and ramps''' to build BNV. (Like seen in [http://edt.oni2.net/images/Hideout_BNV.jpg HERE.])
| |
| ** A BNV polygon can consist of 3 or more points but it's recommended to use '''shapes with 4 points''' because the other shapes usually waste more grid space. At the moment you can import only '''[[wikipedia:Convex|convex]]''' shapes.
| |
| * Secondly there are so called '''ghosts''' (vertical quads) that connect '''neighbouring BNV'''. AI can transit BNV only through ghosts.
| |
| : OniSplit gives error messages for ghosts that don't have 2 neighbouring BNV, for example:
| |
| BNV Builder: Ghost 'grid2' has no '''adjacencies''' at <-72,41 1,999 -166,6> and <-71 1,999 -168,21>, ignoring
| |
| | |
| | |
| '''Tolerance values'''
| |
| * horizontal distance from ''room'' to ''ghost'': 1
| |
| * vertical distance from ''room'' to ''ghost'': 18
| |
| * ''ghost'' horizontal dimension must be bigger than 0
| |
| * under optimal circumstances pathfinding works on a plane that is +4 world units above or -0,5 beneath the pathfinding grid
| |
| * normally characters can't pass low verticals like at staircases/curbs if those don't have a ramp, near ground level Y=0 is an exception where characters are allowed to step on a plane that is 4 world units above pathfinding grid; higher planes need a ramp
| |
| * max degree of ramp you can go on is 70°; bigger degrees make characters fall through to death (in those cases you might want to add invisible walls/boxes)
| |
| | |
| | |
| '''More notes on PF processing'''
| |
| * Actually, BNV and ghosts can have any name and don't need any texture.
| |
| * During pathfinding calculation OniSplit creates a new folder called "temp" and a subfolder "grids". There again is a file "''levelname''_grids.dae". That file contains ''rooms'' with textures "bnv_grid_''N''.tga" marking obstacles in the pathfinding. ''Ghosts'' will have a transparent texture "'''_marker_ghost'''.tga". You get those things also when you export a level. Transparent ''ghosts'' make it easier to see the rest of your level if you have many of those planes.
| |
| * In Mod Tool ''ghosts'' and ''rooms'' can be grouped under a null object. Right-click the null object to select all its children, then use "Selection Only [x]" as saving option. That way all the planes can be quickly saved to a *.dae file.
| |
| * You can influence the pathfinding creation of dangerous zones with danger quads. Read on [[#marker textures|HERE]].
| |
| * Another kind of influence is the [[#<Model>|gunk flag]] IgnoreGrid. It can be used to let OniSplit ignore the object during pathfinding creation. The grids in that place will be white.
| |
| | |
| | |
| [[Image:Pathfinding_grid.JPG|thumb|200px|right|''ai2_showgrids = 1'' in action]]
| |
| '''BSL commands'''
| |
| * chr_show_bnv = 1
| |
| :: shows number of bnv the player is standing on
| |
| * ai2_showgrids = 1
| |
| :: shows pathfinding grids
| |
| * ai2_chump
| |
| :: spawns a friendly striker that follows the player if possible, makes also pathfinding grids visible
| |
| * ai2_chump_stop = 1
| |
| :: striker stops to follow you
| |
| * ai2_chump_stop = 0
| |
| :: striker follows you again
| |
| | |
| | |
| =====Pathfinding on uneven ground=====
| |
| Pathfinding works on slight uneven ground as long as the polygons are 0,5 world units beneath or 4 world units above the BNV.
| |
| | |
| For bigger surface irregularities we can use a trick:
| |
| * The problematic polygons must be saved to an dae file and then referenced in the model section as an individual object.
| |
| * Then the <GunkFlags> tag needs to be '''''GridIgnore'''''.
| |
| * Additionally we create a plain (invisible if necessary) under the object so that Oni doesn't think there's a hole.
| |
| * The ghosts must be taller than the highest polygon to walk on. (This has been tested up to a height of 2000 world units.)
| |
| | |
| | |
| '''Symptoms of too small ghosts'''
| |
| | |
| A) AI can't run at all.
| |
| | |
| B) AI loses PF if tracked enemy performs animations that are out of the pathfinding volume. [http://youtu.be/vfKPzP5hiCo Here's] a video about of the "B" symptoms.
| |
| | |
| | |
| '''Missing boundaries'''
| |
| | |
| Let's say you have a BNV, tall ghosts, and a GridIgnore-flagged hill with trees and brushes and stuff.
| |
| | |
| Why do AI run against the trees?
| |
| : '''Cause:''' There are no red/orange grids that limits the AI movement. Normally, objects will produce red pathfinding grids. But objects that are 20 world units above the BNV are ignored just like objects with the IgnoreGrid flag.
| |
| : '''Solution:''' Add simple geometries like ''_marker_impassable fences'' or danger quads near the BNV.
| |
| | |
| | |
| '''Disappearing AIs'''
| |
| | |
| The ground is sometimes not solid. Then player and AIs will fall through it.
| |
| | |
| There's another case of disappearing AIs and it happens even if the ground is solid: on GridIgnore-flagged uneven ground AIs can fall through when they get out of view. Use one of these two BSL commands to avoid this problem:
| |
| : chr_lock_active ''AI_name''
| |
| : chr_all_active = 1
| |
| | |
| | |
| =====Debugging (OniSplit v0.9.93.0+)=====
| |
| [[Image:OniBrowser.jpg|thumb|200px|right|OniBrowser. Displaying level geometry plus PF and ghosts.]]
| |
| | |
| * '''env_show_ghostgqs = 1''' makes the ghost quads visible
| |
| ** the original ghost quads can't be seen, Neo: "they are not included in the octtree and bsp tree"
| |
| ** to see them you must use the -debug option in the level creation command (available with OniSplit '''v0.9.93.0+''')
| |
| OniSplit.exe -create:level ''output_folder'' '''-debug''' ''input_folder''/''master_xml_file''.xml
| |
| | |
| Not all debugging/testing needs to be done in Oni. There also a [http://mods.oni2.net/node/256 file browser] which can display the whole level.
| |
| | |
| For example you can load an AKEV*.oni, select the level name and use hotkeys [B] and [P] to display BNV and ghosts.
| |
| | |
| '''Bug prevention:'''
| |
| | |
| After all tests you should recompile the level a last time but without the -debug option.
| |
| | |
| AIs appear to have trouble to shot through ghost quads that got registered in the octtree/bsp tree [https://www.youtube.com/watch?v=-ZugVBgBVKc as seen here].
| |
| | |
| | |
| =====When OniSplit fails to connect PF quads=====
| |
| [[Image:pathfing_creation__merge_polygons_to_fix_connections.jpg|thumb|200px|right|Fixed PF in compound level after underground constructions...]]
| |
| It can help to merge polygones to one object and merge their edges. These become white. (Outer edges are blue.)
| |
| | |
| ====[[#textures_tag|<Textures>]]====
| |
| =====... used for exceptions=====
| |
| This tag is mandatory.
| |
| | |
| AKEV textures will be imported by the master xml file automatically, you don't need to write them into that file.
| |
| | |
| : With OniSplit v0.9.82-93.0, the textures' formats will be DXT1 and BGRA4444 (for transparent ones).
| |
| : With OniSplit v0.9.94.0+ the textures' formats will be BGR and RGBA (for transparent ones).
| |
| | |
| To change the default texture import format, use the Texture'''s''' tag. (Possible with OniSplit v0.9.94.0+)
| |
| | |
| To change the format/flag/gunkflag of a specific texture, use the Texture tag.
| |
| | |
| An example:
| |
| | |
| <Textures Format="BGR" AlphaFormat="RGBA" MaxSize="512">
| |
| <Texture Name="GOO">
| |
| <Flags>TwoSided</Flags>
| |
| <Format>BGRA4444</Format>
| |
| <GunkFlags>NoCollision</GunkFlags>
| |
| <Image>env/images/GOO.tga</Image>
| |
| </Texture>
| |
| </Textures>
| |
| | |
| * Use gunkflag "TwoSided" to make surfaces visible from both sides.
| |
| * If the texture comes with gunkflag "NoCollision" then all objects with that texture will have no collision. Characters would fall through it.
| |
| | |
| Transparency and no collision makes both sense, let's say, for a water-like substance. The biolab use this for an area with green acid.
| |
| | |
| {| style="float:right"
| |
| |[http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/3D_modding/making_a_surface_transparent_and_twosided_zpsa8950d1f.png http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/3D_modding/making_a_surface_transparent_and_twosided_tn_zpsae6709f0.png]
| |
| | |
| '''Figure 1'''
| |
| |}
| |
| | |
| [[Image:AKEV_single_object_multiple_textures.png|thumb|200px|right|'''Figure 2'''<br>one object with multiple textures, one per polygon cluster]]
| |
| [[Image:AKEV_single_object_multiple_textures_ingame.png|thumb|200px|right|'''Figure 3'''<br>blue: twosided<br>glass: twosided and transparent<br>random metal: no flag (onesided)]]
| |
| | |
| | |
| '''TwoSided and transparent objects'''
| |
| | |
| It's also possible to set this in Mod Tool. For TwoSided-ness use one image source for diffuse and transparency. (It won't work with two image sources even if both sources use the same image.)
| |
| | |
| For transparency additionally use the three checkboxes:
| |
| * Transparency: Enable
| |
| * Transparency: Use Alpha
| |
| * Transparency: Invert
| |
| | |
| See '''Figure 1'''.
| |
| | |
| | |
| =====Regular textures=====
| |
| OniSplit automatically imports textures of objects in the [[#<Model>|<Model> section]]. Those objects could be considered as AKEV core geometry.
| |
| | |
| | |
| '''one texture per object'''
| |
| | |
| Furniture and Physics objects are allowed to have only one texture per object.
| |
| | |
| AKEV core geometry can have one texture or multiple textures - that's up to you to decide.
| |
| | |
| | |
| '''Multiple textures per object'''
| |
| | |
| '''Question:''' How do we apply multiple textures to an AKEV core object?
| |
| | |
| '''Answer:''' Assuming you are using Mod Tool the procedure will be like this. Repeat this for each cluster you create (except for projection). See also '''Figure 2 and 3'''.
| |
| | |
| * select some polygons
| |
| * goto Material > Phong
| |
| * hit [7] to open Render Tree
| |
| * add a texture and connect "Image" with "Phong", choose "diffuse" as illumination mode
| |
| * double-click "Image" to open Material page
| |
| * in Texture Projection section, click on "New" and choose a suitable projection
| |
| ** do this only if there isn't a projection in the "Texture_Coordinates_AUTO" cluster yet
| |
| ** OniSplit processes only one texture projection, see '''Figure 4'''
| |
| * choose texture and UV, fine-tune UV via [alt]+[7]
| |
| | |
| | |
| [[Image:AKEV_multiple_textures_one_projection.png|thumb|200px|right|'''Figure 4'''<br>use only one texture projection per object]]
| |
| | |
| | |
| Caution: textures will be fixed to one set of flags. You can't use the same texture A for an onesided cluster/object B and twosided cluster/object C. You would need to create a different named clone of that texture and apply that to cluster/object C.
| |
| | |
| | |
| =====Marker textures=====
| |
| Marker textures are used to import certain objects with special flags. Import those object alongside [[#<Model>|AKEV core]] geometry.
| |
| | |
| Marker textures aren't imported automatically. Add those textures to the final package / plugin, e.g. by some sort of batch code.
| |
| | |
| OniSplit.exe -create:txmp out env/markers/*.tga
| |
| | |
| | |
| The flags Transparent TwoSided NoOcclusion are only set if the same texture source is used for diffuse and transparency and if transparency setting are enabled. See subsection of "[[#... used for exceptions|... used for exceptions]]": "TwoSided and transparent objects".
| |
| | |
| | |
| '''danger quads'''
| |
| | |
| The pathfinding grids can have different colors with different meanings.
| |
| * white/gray - clear space
| |
| * green light - nearwall
| |
| * green - semipassable
| |
| * green dark - stairs
| |
| * blue very light - border 1
| |
| * blue light - border 2
| |
| * blue - border 3
| |
| * blue dark - border 4
| |
| * '''orange - danger'''
| |
| * red - impassable
| |
| | |
| For detailed information on colors see [[OBD_talk:AKVA/0x24#EFFECTS_of_various_pathfinding_grid_tile_types|HERE]].
| |
| | |
| Normally, OniSplit decide how to color the grids. But it's possible to add own danger quads to fine tune zones of great danger. Those orange areas will be generated with the 4 different blue borders around it.
| |
| | |
| Danger quads must have "'''_marker_danger'''" as texture name.
| |
| | |
| Results in flags: Transparent TwoSided NoCollision Invisible NoOcclusion Danger
| |
| | |
| | |
| '''_marker_barrier'''
| |
| <!-- Originally this is only used for "end-of-level" walls? -->
| |
| | |
| Results in flags: Transparent TwoSided(double-check) Invisible NoObjectCollision NoOcclusion
| |
| | |
| | |
| '''COLLISION (boxes)'''
| |
| | |
| AIs can get stuck in detailed geometry. This can be prevented with collision boxes. Ingame the box will be invisible and has collision so characters can't get through. The pathfinding grid will be red where it comes in contact with the box, red is followed by a light green and then green.
| |
| | |
| [[XML:OFGA|OFGA]] use COLLISION texture. Onisplit doesn't automatically applies gunk flags to it. You need the xml tags for that.
| |
| | |
| Typically it gets <GunkFlags>Invisible NoObjectCollision</GunkFlags>
| |
| | |
| | |
| '''stairs'''
| |
| | |
| texture: '''_marker_stairs'''
| |
| | |
| Normally, characters can't move on stairs if they contain verticals. In this case you can use a sloping quad that is above or inside the staircases. It's possible to set the desired flags at the <Model> section but doing so and exporting self-made stair ramps is wasted time. So apply simply _marker_stairs to that quad, characters will move on that surface.
| |
| | |
| Results in flags: Stairs Transparent TwoSided Invisible NoObjectCollision NoOcclusion
| |
| | |
| No effect to pathfinding creation. Regularly textured stair geometry (that intersect the marker quad) will be flagged as NoCharacterCollision.
| |
| | |
| | |
| '''impassable'''
| |
| | |
| texture: '''_marker_impassable'''
| |
| | |
| Results in flags: Transparent TwoSided(double-check) Invisible NoOcclusion
| |
| | |
| Impassable walls are very similar to collision boxes except that particle can also collide with it. The pathfinding grids will be also red, light green, and green.
| |
| | |
| | |
| '''blackness a.k.a. jello fix'''
| |
| | |
| texture: '''_marker_blackness'''
| |
| | |
| Results in flags: TwoSided NoCollision
| |
| | |
| Simply black walls. No effect to pathfinding creation. The purpose of these walls in Oni is to block out areas outside of a level's outermost wall. See [[Jello-cam]] for details.
| |
| | |
| | |
| '''doors'''
| |
| | |
| texture: '''_marker_door'''
| |
| | |
| Results in flags: DoorFrame Transparent TwoSided NoCollision NoOcclusion
| |
| | |
| Don't use this.
| |
| | |
| | |
| ====<Objects>====
| |
| Information on regular object lists can be looked up here:
| |
| : [[XML:BINA/OBJC/CHAR|Character.xml]] (has to contain player character if there's no AISA file with it)
| |
| : [[XML:BINA/OBJC/CONS|Console.xml]]
| |
| : [[XML:BINA/OBJC/DOOR|Door.xml]]
| |
| : [[XML:BINA/OBJC/FLAG|Flag.xml]]
| |
| : [[XML:BINA/OBJC/NEUT|Neutral.xml]]
| |
| : [[XML:BINA/OBJC/PART|Particle.xml]]
| |
| : [[XML:BINA/OBJC/PATR|PatrolPath.xml]]
| |
| : [[XML:BINA/OBJC/PWRU|PowerUp.xml]]
| |
| : [[XML:SNDD#BINACJBOSound.xml|Sound.xml]]
| |
| : [[XML:BINA/OBJC/TRIG|Trigger.xml]]
| |
| : [[XML:BINA/OBJC/TRGV|TriggerVolume.xml]]
| |
| : [[XML:BINA/OBJC/WEAP|Weapon.xml]]
| |
| | |
| | |
| =====Furniture.xml=====
| |
| The AKEV core geometry is more or less unique while this furniture file adds standard objects (e.g. crates and desks) to it.
| |
| | |
| {| class="wikitable" width="100%"
| |
| !width=150px| XML tag
| |
| !width=120px| content type
| |
| ! description
| |
| |-
| |
| | <?xml version="1.0" encoding="utf-8"?>
| |
| |valign="top"| float, flag
| |
| |valign="top"| Ignore this.
| |
| |-
| |
| | <Oni>
| |
| | -
| |
| |
| |
| |-
| |
| | <Objects>
| |
| | -
| |
| | This tag marks the file as BINACJBO.
| |
| |-
| |
| | <Furniture>
| |
| | -
| |
| | This tag marks the file as FURN.
| |
| |-
| |
| | <Header>
| |
| |
| |
| |
| |
| |-
| |
| |valign="top"| <Flags>
| |
| |valign="top"| flag
| |
| | Optional tag. Ignore it. Those flags were used in the past.
| |
| :None
| |
| :Locked
| |
| :PlacedInGame
| |
| :Temporary
| |
| :Gunk
| |
| |-
| |
| | <Position>
| |
| | float x3
| |
| | Optional tag. X Y Z position.
| |
| |-
| |
| | <Rotation>
| |
| | float x3
| |
| | Optional tag. X Y Z rotation.
| |
| |-
| |
| | <OSD>
| |
| | -
| |
| |
| |
| |-
| |
| |valign="top"| <Class>
| |
| |valign="top"| link
| |
| | File path to an [[XML:OFGA|OFGA]] (*.oni) file. Make sure that the OFGA comes also with the files it needs: M3GM and TXMP.
| |
| | |
| OFGA can hold multiple M3GM. That 3d content will be integrate into the AKEV.
| |
| |-
| |
| |valign="top"| <Particle>
| |
| |valign="top"| string
| |
| | This name gets written into <Tag> inside ONLV (ENVP section) and can be used with BSL commands.
| |
| | |
| E.g. you can take control over a particle via "particle BSL_name start". For more commands see [[XML:BINA/OBJC/PART#BSL_support|HERE]].
| |
| | |
| Caution with new OFGA files. The particle name will be composed of 2 parts and always includes an "_" underscore. '''Examples:'''
| |
| | |
| : FURN <Particle>test</Particle> + OFGA <Tag>streetlight</Tag> = '''test_streetlight'''
| |
| : FURN <Particle></Particle> + OFGA <Tag>streetlight</Tag> = '''_streetlight'''
| |
| : FURN <Particle>test</Particle> + OFGA <Tag></Tag> = '''test_'''
| |
| |}
| |
| | |
| | |
| ;Example
| |
| | |
| <?xml version="1.0" encoding="utf-8"?>
| |
| <Oni>
| |
| <Objects>
| |
| | |
| <Furniture>
| |
| <Header>
| |
| <Flags>Gunk</Flags>
| |
| <Position>-62.692 -29 108.35</Position>
| |
| <Rotation>181.522 356.021 178.114</Rotation>
| |
| </Header>
| |
| <OSD>
| |
| <Class>furniture/V_tctf_bigvan.oni</Class>
| |
| <Particle></Particle>
| |
| </OSD>
| |
| </Furniture>
| |
| | |
| </Objects>
| |
| </Oni>
| |
| | |
| | |
| =====Physics.xml=====
| |
| This file is for objects with "physics". Unlike AKEV core geometry or furniture, those objects can be animated.
| |
| | |
| : Little video tutorial: how to create [http://www.youtube.com/watch?v=ufDqgTXD7lQ a simple animated object]
| |
| | |
| {| class="wikitable" width="100%"
| |
| !width=150px| XML tag
| |
| !width=120px| content type
| |
| ! description
| |
| |-
| |
| | <?xml version="1.0" encoding="utf-8"?>
| |
| |valign="top"| float, flag
| |
| |valign="top"| Ignore this.
| |
| |-
| |
| | <Oni>
| |
| | -
| |
| |
| |
| |-
| |
| | <Physics>
| |
| | -
| |
| |
| |
| |-
| |
| | <Object Name="...">
| |
| | string
| |
| | Use an unique name for each object.
| |
| |-
| |
| |valign="top"| <ScriptId>
| |
| |valign="top"| integer
| |
| | Tested with BSL command ...
| |
| :obj_create Id [Id]
| |
| :obj_kill Id [Id]
| |
| :env_anim Id [Id]
| |
| :env_setanim Id [Id]
| |
| The script Id will be stored in ONLV's OBOA instance.
| |
| |-
| |
| |valign="top"| <Flags>
| |
| |valign="top"| flag
| |
| |
| |
| ;Object setup flags
| |
| :None
| |
| :InUse
| |
| :NoCollision
| |
| :NoGravity
| |
| :FaceCollision
| |
| |-
| |
| |valign="top"| <Physics>
| |
| |valign="top"| flag
| |
| | Optional tag of Object.
| |
| :None
| |
| :Static
| |
| :Linear
| |
| :Animated
| |
| :Newton (used with <Flags> FaceCollision to [http://www.youtube.com/watch?v=YICB7qugrtc make object pushable])
| |
| :: For a pushable object don't use import sub-tags such as animation name, flags, etc. Just use <Import Path="..." '''/'''> or <Import Url="..." '''/'''>
| |
| |-
| |
| | <Position>
| |
| | float x3
| |
| | Optional tag of Object. Only used for non-animated objects. X Y Z position.
| |
| |-
| |
| | <Rotation>
| |
| | float x3
| |
| | Optional tag of Object. Only used for non-animated objects. X Y Z rotation.
| |
| |-
| |
| | <Scale>
| |
| | float
| |
| | Optional tag of Object. Only used for non-animated objects.
| |
| |-
| |
| |
| |
| <Import Path="...">
| |
| | |
| <Import Url="...">
| |
| |valign="top"| link
| |
| |valign="top"| This tag comes in two variants. It doesn't matter what variant you use.
| |
| |-
| |
| | <Animation Name="...">
| |
| | link
| |
| | File path to *.dae file.
| |
| |-
| |
| |valign="top"| <Flags>
| |
| |valign="top"| flag
| |
| | Optional tag of Animation. For more information on those flags look [[XML:OBAN|OBAN]] page.
| |
| | |
| ;Object animation flags
| |
| :None
| |
| :Loop
| |
| :PingPong
| |
| :RandomStart
| |
| :AutoStart
| |
| :Local
| |
| |-
| |
| | <End>
| |
| | integer
| |
| | Optional tag of Animation. Frame number. Used to define the end of an OBAN from an *.dae file.
| |
| |-
| |
| | <Start>
| |
| | integer
| |
| | Optional tag of Animation. Frame number. Used to define the start of an OBAN from an *.dae file.
| |
| |}
| |
| | |
| | |
| ;Example
| |
| | |
| For documentation purpose the file here has been trimmed down.
| |
| <?xml version="1.0" encoding="utf-8"?>
| |
| <Oni>
| |
| <Physics>
| |
| | |
| <Object Name="motorcycle">
| |
| <ScriptId>8</ScriptId>
| |
| <Flags>FaceCollision</Flags>
| |
| <Import Url="motorcycle/export.dae">
| |
| <Animation Name="motorcycle02">
| |
| <Flags>AutoStart</Flags>
| |
| <End>880</End>
| |
| </Animation>
| |
| <Animation Name="motorcycle02_stop">
| |
| <Start>881</Start>
| |
| </Animation>
| |
| </Import>
| |
| </Object>
| |
| | |
| </Physics>
| |
| </Oni>
| |
| | |
| In this example OniSplit takes the "export.dae" file, looks what parts it contains and creates geometry files from it.
| |
| * M3GMhubs_rear.oni
| |
| * M3GMhubs.oni
| |
| * M3GMmotocycle.oni
| |
| It's a nice feature that hierarchies are supported here.
| |
| | |
| The motorcycle is made of 3 parts so 3 object animations ([[XML:OBAN|OBAN]]) will be created up to frame 880. Then OniSplit creates 3 more OBANs starting from frame 881.
| |
| | |
| The reason for the interruption at frame 880 is probably to give barabas a few more frames of glory in the cutscene.
| |
| * OBANmotorcycle0200.oni
| |
| * OBANmotorcycle0201.oni
| |
| * OBANmotorcycle0202.oni
| |
| * OBANmotorcycle02_stop00.oni
| |
| * OBANmotorcycle02_stop01.oni
| |
| * OBANmotorcycle02_stop02.oni
| |
| | |
| | |
| ;Notes about BSL usage:
| |
| | |
| The bio lab script file use the motorcycle objects and animations like this:
| |
| env_show 9 0 # hide static motorcycle parts (because they get visible at level start)
| |
| # in the original game the motorcycle is separated in object 8, 9 and 10
| |
| # also the OBAN files have a bit different names
| |
|
| |
| # static and animated objects are totally independent from each other
| |
| # they are stored in different arrays so their script ids can be the same or different
| |
|
| |
| obj_create 8 10 # create animation-ready motorcycle parts
| |
| env_anim 8 10 # animate those parts (not necessary if OBAN flag is "AutoStart")
| |
|
| |
| # the first animations would loop because of "AutoStart"
| |
| # so get the right timing to apply the other animations
| |
| # "motorcycle02_stop00" and the others will not loop because they don't have "AutoStart"
| |
| env_setanim 8 motorcycle02_stop00 # motorcycle
| |
| env_setanim 9 motorcycle02_stop01 # hubs
| |
| env_setanim 10 motorcycle02_stop02 # hubs_rear
| |
|
| |
| obj_kill 8 10 # delete animated parts
| |
| env_show 9 1 # show static motorcycle parts
| |
| | |
| | |
| =====Corpses.xml (OniSplit v0.9.96.0+)=====
| |
| '''(Import)'''
| |
| | |
| CRSA can now be imported from an xml file if registered in the master file. See [[#CRSA|HERE]]. (Two formats available.)
| |
| | |
| Direct import is not yet supported by OniTools.
| |
| | |
| ----
| |
| | |
| For indirect import, see [http://oni.bungie.org/community/forum/viewtopic.php?id=2657 HERE] (OniTools v7.1.5+) how to get corpse data.
| |
| | |
| When you process your xml master file use onisplit version 0.9.94.0+
| |
| | |
| Older onisplit versions (like 0.9.86.0) may generate ONLV files that are not re-packable with newer versions.
| |
| | |
| | |
| '''(Export)'''
| |
| | |
| With Neo's matrix to euler code the rotations can be recovered from CRSA. But due to the character's hierarchy things get [https://dl.dropboxusercontent.com/u/139715/OniGalore/CRSA_to_Mod_Tool_wip.png messy again.] ([https://dl.dropboxusercontent.com/u/139715/temp/CRSA_to_Mod_Tool.txt Wip code])
| |
| | |
| A workaround might be to save characters without animations, destroy their hierarchy, apply the local rotations / global translation and glue everything together again.
| |
| | |
| ==Level reimport==
| |
| ===Export of static geometry===
| |
| After the oni files have been exported, the extraction of objects can fail if their textures can't be found. Those objects probably use textures stored in level 0.
| |
| | |
| In that case use the "-search" argument to make correct extractions. In total the commands will look like this:
| |
| | |
| OniSplit.exe -export level0_files level0.dat
| |
| OniSplit.exe -export levelX_files levelX.dat
| |
| OniSplit.exe -extract:dae levelX_geometry levelX_files/AKEV*.oni -search level0_files
| |
| | |
| Possible output files:
| |
| * ''level''_bnv.dae
| |
| * ''level''_cons.dae
| |
| * ''level''_door.dae
| |
| * ''level''_env.dae
| |
| * ''level''_env_markers.dae
| |
| * ''level''_furn.dae
| |
| * ''level''_script_''N''.dae (by OniSplit v0.9.90.0+)
| |
| * ''level''_trig.dae
| |
| * ''level''_turr.dae
| |
| | |
| Reimporting dae files (except for env_markers) will merge them with env (AKEV core geometry).
| |
| | |
| | |
| ===Export of animated geometry and cameras (OniSplit v0.9.90.0+)===
| |
| This is also known as scene export. All content exported by the scene file will be combined and saved in one single dae.
| |
| | |
| OniSplit.exe -extract:dae path_to/output_directory path_to/scene.xml
| |
| | |
| For the following example the scene.xml must be present in a folder containing all files used by the scene. In this case it's level3_Final (biolab).
| |
| | |
| <Scene>
| |
| <Node Name="camera">
| |
| <Camera />
| |
| <Animation>OBANCamout01.oni</Animation>
| |
| <Animation>OBANCamout02.oni</Animation>
| |
| <Animation>OBANCamout03.oni</Animation>
| |
| <Animation>OBANCamout04.oni</Animation>
| |
| <Animation>OBANCamout05.oni</Animation>
| |
| <Animation>OBANCamout06.oni</Animation>
| |
| </Node>
| |
| <Node Name="motorcycle02">
| |
| <Geometry>M3GMmotorcycle02.oni</Geometry>
| |
| <Animation>OBANmotorcycle02.oni</Animation>
| |
| <Animation>OBANmotorcycle02_stop.oni</Animation>
| |
| <Node Name="hubs">
| |
| <Geometry>M3GMhubs.oni</Geometry>
| |
| <Animation>OBANhubs.oni</Animation>
| |
| <Animation>OBANhubs_stop.oni</Animation>
| |
| </Node>
| |
| <Node Name="hubs_rear">
| |
| <Geometry>M3GMhubs_rear.oni</Geometry>
| |
| <Animation>OBANhubs_rear.oni</Animation>
| |
| <Animation>OBANhubs_rear_stop.oni</Animation>
| |
| </Node>
| |
| </Node>
| |
| </Scene>
| |
| | |
| When you load the dae in [[Mod_Tool|XSI]] you'll find the motorcycle and the lab level intro camera. If you select the camera (for better visibility) and press play you'll get to see the motorcycle into animation like you see it in game.
| |
| | |
| For real-time playback click on "Playback" option button and then "Real-Time Playback".
| |
| | |
| | |
| ;File structure
| |
| * The scene contains one or more '''nodes'''.
| |
| * Each node represents '''either one 3D object or one camera''' whereby the node name determines the object name inside the dae.
| |
| ** 3D objects do have a '''<Geometry>''' tag.
| |
| ** Cameras do have a '''<Camera />''' tag.
| |
| ** Each 3D object or camera can have '''one or multiple <Animation>''' tags. Multiple animations will be combined.
| |
| ** 3D objects can be organized in a '''hierarchy''' that gets created by the help of '''sub-nodes'''. Each sub-node can also have animations.
| |
| | |
| | |
| ;Scene import
| |
| <s>According to Neo that feature is still under development.</s> RIP.
| |
| | |
| | |
| ===Recycle object lists===
| |
| Following files can be reused at <Objects> without any drawback:
| |
| * BINACJBOCharacter.xml
| |
| * BINACJBOFlag.xml
| |
| * BINACJBONeutral.xml
| |
| * BINACJBOParticle.xml
| |
| * BINACJBOPatrol Path.xml
| |
| * BINACJBOPowerUp.xml
| |
| * BINACJBOSound.xml
| |
| * BINACJBOTrigger Volume.xml
| |
| * BINACJBOWeapon.xml
| |
| | |
| | |
| ===Locklights===
| |
| Door locklights must be transfered by hand from old ONLV (ENVP instance) to a) new ONLV or b) CJBO particle file.
| |
| | |
| For method b) you could use [https://dl.dropboxusercontent.com/u/139715/OniGalore/extract_ENVP.vbs THIS] script. [http://youtu.be/8HbPeNYqdY0 Demo vid].
| |
| | |
| The advantage is that you don't need to edit the new ONLV afterwards.
| |
| | |
| | |
| ===CJBO and vertex coloring===
| |
| * Object (xml) import via <Object> tag (master xml file) will get you objects without vertex coloring. (onisplit will pick *.oni class files from the shared folder.)
| |
| * Object (dae) import via <Model> tag (master xml file) should get you objects with vertex coloring but no functions. In that case add corresponding CJBO files by hand.
| |
| | |
| You can chose between those two methods for consoles, triggers, turrets and furniture without particle.
| |
| | |
| Doors and furniture with particle need always the xml method.
| |
| | |
| | |
| ===Manual reimport of physics===
| |
| Don't want to make a scene.xml and physics.xml file? All animated physics can be restored if you aren't afraid of post-editing ONLV.
| |
| | |
| # Look into the original level folder and copy OBAN and M3GM files to your project's output folder.
| |
| # Create your level. Then convert the new ONLV to xml. Now you are able to compare the new and old ONLV file.
| |
| # Get all original OBOA instances that aren't doors or empty.
| |
| # Each OBOA has a <Geometry> tag which links to an M3GA instance by Id. So, collect also all M3GAs that are used by your OBOAs.
| |
| # Add these collected OBOAs and M3GAs to you new ONLV. Make sure that your M3GA Ids aren't already taken, change them if necessary.
| |
| # Save ONLV and convert to oni. Make package or plugin, and test your reimported level.
| |
| | |
| | |
| ===Demo files===
| |
| [https://dl.dropboxusercontent.com/u/139715/OniGalore/Level_19_reimport.zip level 19 reimport]
| |
| | |
| At the beginning of this page are already demo files (level 3 - biolab), also a reimport, but it uses a bit different setup.
| |
| | |
| For example, it imports animated objects from *.dae files which result in a few bugs: Konoko's motocycle is too low, at another point it is completely missing, and the van at the end of the level has some strange unnecessary gunks.
| |
| | |
| In this second demo, the ENVP and OBOA/M3GA instances were manually reimported. So, if you have fun to RE stuff, try to make sense of the second demo, too.
| |
| | |
| Known issues are:
| |
| * Doors and trigger don't have vertex shading. (Also not possible with normal level creation.)
| |
| * Consoles tend to have an collision issue with the player, keeping him trapped. (Jump backwards to escape.)
| |
| ** This issue might get solved by using a sole BINACJBOConsole.xml file. Or we try to edit the collision boxes of compound_cons.dae.
| |
| | |
| So now, how about accessible towers and underground passages / ventilation shafts? ;D
| |
| | |
| The prone mode is so useless right now, let's change this!
| |
| | |
| | |
| ==Level export==
| |
| This section is only about xml files. For dae export see [[#Level_reimport|HERE]].
| |
| | |
| The most parts of an Oni level are made of ONLV and AKEV. For AKEV's xml tags see [[XML:AKEV|HERE]].
| |
| | |
| You would only want to export those two files as xml if you want to check if a texture or an object really made it into the level or not.
| |
| | |
| | |
| ===ONLV===
| |
| {| class="wikitable" width="100%"
| |
| !width=150px| XML tag
| |
| !width=120px| content type
| |
| ! description
| |
| |- | | |- |
| |valign="top"| <ONLV id="..."> | | |valign="top"| <ONLV id="..."> |
Line 1,442: |
Line 25: |
| |valign="top"| <Environment> | | |valign="top"| <Environment> |
| |valign="top"| link | | |valign="top"| link |
| | Link to [[XML:AKEV|AKEV]] via '''file''' name (AKEV''name''), don't use file suffix .oni | | | Link to [[XML:AKEV|AKEV]] via '''file''' name (AKEV''name'', don't use file suffix .oni) |
| : Level geometry. | | : Level geometry. |
| |- | | |- |
Line 1,448: |
Line 31: |
| |valign="top"| link | | |valign="top"| link |
| | Link to [[#OBOA|OBOA]] via '''instance''' number (#''N''). | | | Link to [[#OBOA|OBOA]] via '''instance''' number (#''N''). |
| : The OBOA instance holds doors, animated objects (usually for cut scenes) and pushable object (they are not used the original game). | | : The OBOA instance holds doors, animated objects (usually for cutscenes) and pushable objects (which are not used the original game due to unfinished physics code). |
| |- | | |- |
| |valign="top"| <SkyBox> | | |valign="top"| <SkyBox> |
| |valign="top"| link | | |valign="top"| link |
| | Link to [[XML:ONSK|ONSK]] via '''file''' name (ONSK''name''), don't use file suffix .oni | | | Link to [[XML:ONSK|ONSK]] via '''file''' name (ONSK''name'', don't use file suffix .oni) |
| : This is the sky box. | | : This is the skybox. |
| |- | | |- |
| |valign="top"| <Characters> | | |valign="top"| <Characters> |
| |valign="top"| link | | |valign="top"| link |
| | Link to [[XML:AISA|AISA]] via '''file''' name (AISA''name''), don't use file suffix .oni | | | Link to [[XML:AISA|AISA]] via '''file''' name (AISA''name'', don't use file suffix .oni) |
| : This "AI Setup Array" is an alternative character list. [[XML:BINA/OBJC/CHAR|CHAR]] is more powerful. | | : This "AI Setup Array" is an alternative character list. [[XML:BINA/OBJC/CHAR|BINACHAR]] is more powerful. |
| |- | | |- |
| |valign="top"| <ObjectQuadMap> | | |valign="top"| <ObjectQuadMap> |
| |valign="top"| link | | |valign="top"| link |
| | Link to [[#ONOA|ONOA]] via '''instance''' number (#''N''). | | | Link to [[#ONOA|ONOA]] via '''instance''' number (#''N''). |
| : This "Object Array" holds functional objects - doors, furniture, turrets, triggers and consoles - in addition it appears that the engine only searches for door type. | | : This "Object Array" holds functional objects – doors, furniture, turrets, triggers and consoles. In addition, it appears that the engine only searches for door-type objects. |
| |- | | |- |
| |valign="top"| <Particles> | | |valign="top"| <Particles> |
| |valign="top"| link | | |valign="top"| link |
| | Link to [[#ENVP|ENVP]] via '''instance''' number (#''N''). | | | Link to [[#ENVP|ENVP]] via '''instance''' number (#''N''). |
| : Those "Environment Particle" contains traditionally only door lock lights and particles used by [[XML:OFGA|OFGA]]. | | : These "Environment Particle" are traditionally only used for door lock lights and particles used by [[XML:OFGA|OFGAs]]. |
| |- | | |- |
| |valign="top"| <Corpses> | | |valign="top"| <Corpses> |
| |valign="top"| link | | |valign="top"| link |
| | Link to [[#CRSA|CRSA]] via '''instance''' number (#''N''). | | | Link to [[#CRSA|CRSA]] via '''instance''' number (#''N''). |
| : This is a "Corpse Array". It's used to 'spawn dead characters' like Chung in level 1. | | : This is a "Corpse Array". It's used to spawn dead characters such as Chung in Chapter 1. |
| |} | | |} |
|
| |
|
| | | ==OBOA== |
| ===OBOA===
| |
| Used for movable/moving objects. | | Used for movable/moving objects. |
|
| |
|
| {| class="wikitable" width="100%" | | {| class="wikitable" width="100%" |
| !width=150px| XML tag | | !width=150px| XML tag |
| !width=120px| content type | | !width=120px| Content type |
| ! description | | ! Description |
| |- | | |- |
| | <OBOA id="..."> | | | <OBOA id="..."> |
| | integer | | | integer |
| | Instance Id. Should be 1. | | | Instance ID. Should be 1. |
| |- | | |- |
| | <Objects> | | | <Objects> |
Line 1,495: |
Line 77: |
| | <OBOAObject> | | | <OBOAObject> |
| | - | | | - |
| | There are always 32 empty objects plus those that are actually used. | | | There are always 32 empty objects plus those that are actually used |
| |- | | |- |
| | <Geometry> | | | <Geometry> |
| | "#" + integer | | | "#" + integer |
| | Link to M3GA instance. -- Doors are made of two parts: an animated and a static part. If this <Geometry> links to a door it will be the animated part. | | | Link to M3GA instance. Doors have two separate models: an animated and a static one. If this <Geometry> links to a door, it will be the animated model. |
| |- | | |- |
| | <Animation> | | | <Animation> |
| | link | | | link |
| | OBAN''name'' | | | OBAN''name''. |
| |- | | |- |
| | <Particle> | | | <Particle> |
| | # + integer | | | # + integer |
| | Link to ENVP instance. -- There can be multiple ENVP instances. One for locklights and other for those kind of particle. | | | Link to ENVP instance. There can be multiple ENVP instances – one for a lock light and others for additional particles. |
| |- | | |- |
| |valign="top"| <Flags> | | |valign="top"| <Flags> |
Line 1,514: |
Line 96: |
| : None | | : None |
| : InUse | | : InUse |
| : NoCollision | | : NoCollision (any effect? no collision is default behavior) |
| : NoGravity | | : NoGravity |
| : FaceCollision | | : FaceCollision (for doors) |
| |- | | |- |
| | <DoorGunkId> | | | <DoorGunkId> |
| | int32 | | | int32 |
| | the index of the door frame GQ for door objects? | | | The index of the door frame GQ (only used for door objects) |
| |- | | |- |
| | <DoorId> | | | <DoorId> |
| | int32 | | | int32 |
| | only used for doors; in the case of double doors both doors have the same id and they are flagged as "InUse FaceCollision" | | | Only used for doors; in the case of double doors, both doors have the same ID and they are flagged as "InUse FaceCollision" |
| |- | | |- |
| |valign="top"| <PhysicsType> | | |valign="top"| <PhysicsType> |
Line 1,531: |
Line 113: |
| : None | | : None |
| : Static | | : Static |
| : Linear (?) | | : Linear (pushable object) |
| : Animated (animated via OBAN) | | : Animated (animated via OBAN) |
| : Newton (pushable object) | | : Newton (same as Linear) |
| |- | | |- |
| | <ScriptId> | | | <ScriptId> |
| | int32 | | | int32 |
| | script Id; used by BSL function obj_create; 65535 = not used | | | Scripting ID; used by BSL function '''obj_create'''; "65535" means not used. |
| |- | | |- |
| | <Position> | | | <Position> |
Line 1,553: |
Line 135: |
| | <Transform> | | | <Transform> |
| | matrix | | | matrix |
| | Float 3*3 + 3 more float for X Y Z position of the object. For more information on the matrix see [[OBD:CRSA]]. Used for animated objects. | | | Float 3*3 + 3 more floats for the X Y Z position of the object. For more information on the matrix, see [[OBD:CRSA]]. Used for animated objects. |
| |- | | |- |
| | <Name> | | | <Name> |
| | char[64] | | | char[64] |
| | name of the object; informational only | | | Name of the object; informational only. |
| |} | | |} |
|
| |
|
| | | ==ONOA== |
| ===ONOA===
| |
| Used by static objects (imported by object list). | | Used by static objects (imported by object list). |
|
| |
|
| {| class="wikitable" width="100%" | | {| class="wikitable" width="100%" |
| !width=150px| XML tag | | !width=150px| XML tag |
| !width=120px| content type | | !width=120px| Content type |
| ! description | | ! Description |
| |- | | |- |
| | <ONOA id="..."> | | | <ONOA id="..."> |
| | integer | | | integer |
| | Instance Id. | | | Instance ID. |
| |- | | |- |
| | <Elements> | | | <Elements> |
Line 1,583: |
Line 164: |
| |valign="top"| <ObjectId> | | |valign="top"| <ObjectId> |
| |valign="top"| integer | | |valign="top"| integer |
| | Object Id and type to which this quad belongs (see AKEV's [[XML:AKEV#AGQG|AGQG]] for details). | | | Object ID and type to which this quad belongs (see AKEV's [[XML:AKEV#AGQG|AGQG]] for details). |
| : Actual object Ids can also be found in BINA/OBJC/####. | | : Actual object IDs can also be found in BINA/OBJC/####. |
| |- | | |- |
| | <QuadList> | | | <QuadList> |
Line 1,593: |
Line 174: |
| Where do the links go to again? | | Where do the links go to again? |
|
| |
|
| ONOA <ObjectId> -> AKEV AGQG -> BINA/OBJC/#### by type and Id | | ONOA <ObjectId> -> AKEV AGQG -> BINA/OBJC/#### by type and ID |
| ONOA <QuadList> -> ONOA IDXA -> AKEV AGQG by order | | ONOA <QuadList> -> ONOA IDXA -> AKEV AGQG by order |
|
| |
|
| | | ==ENVP== |
| ===ENVP===
| |
| {| class="wikitable" width="100%" | | {| class="wikitable" width="100%" |
| !width=150px| XML tag | | !width=150px| XML tag |
| !width=120px| content type | | !width=120px| Content type |
| ! description | | ! Description |
| |- | | |- |
| | <ENVP id="..."> | | | <ENVP id="..."> |
| | integer | | | integer |
| | Instance Id. | | | Instance ID. |
| |- | | |- |
| | <Particles> | | | <Particles> |
| | - | | | - |
| | This is an int16 array for the <ENVPParticle> tags. If there's no content <Particles /> is used. | | | This is an int16 array for the <ENVPParticle> tags. If there's not going to be any contents, you put <Particles /> here. |
| |- | | |- |
| | <ENVPParticle> | | | <ENVPParticle> |
Line 1,617: |
Line 197: |
| | <Class> | | | <Class> |
| | char[64] | | | char[64] |
| | <font color="#777777">BINA3RAP</font>file<font color="#777777">.oni</font> <font color="#777777">(don't use file prefix/suffix)</font> | | | <font color="#777777">BINA3RAP</font>file<font color="#777777">.oni</font> <font color="#777777">(don't use file prefix/suffix)</font>. |
| |- | | |- |
| | <Tag> | | | <Tag> |
| | char[48] | | | char[48] |
| | particle's name for BSL commands, see [[OFGA#tags|OFGA]] for more information on name composition | | | Particle's scripting name for BSL commands; see [[XML:OFGA#XML_tags|OFGA]] for more information on name composition. |
| |- | | |- |
| | <Transform> | | | <Transform> |
| | matrix | | | matrix |
| | Float 3*3 + 3 more float for X Y Z position of the particle. For more information on the matrix see [[OBD:CRSA]]. | | | Float 3*3 + 3 more floats for the X Y Z position of the particle. For more information on the matrix, see [[OBD:CRSA]]. |
| |- | | |- |
| | <DecalScale> | | | <DecalScale> |
Line 1,638: |
Line 218: |
| |} | | |} |
|
| |
|
| | | ==CRSA== |
| ===CRSA===
| |
| Wanted: "how to add corpses" tutorial
| |
| | |
| : Some related information can be found at [[AE:Authoring_custom_camera_animations|AE:Authoring custom camera animations]]
| |
| | |
| {| class="wikitable" width="100%" | | {| class="wikitable" width="100%" |
| !width=150px| XML tag | | !width=150px| XML tag |
| !width=120px| content type | | !width=120px| Content type |
| ! description | | ! Description |
| |- | | |- |
| | <CRSA id="..."> | | | <CRSA id="..."> |
| | integer | | | integer |
| | Instance Id. | | | Instance ID. |
| |- | | |- |
| |valign="top"| <FixedCount> | | |valign="top"| <FixedCount> |
| |valign="top"| integer | | |valign="top"| integer |
| | The array capacity <Corpses> is larger than the number of "fixed"/"used" corpses to allow the engine to store new corpses at runtime. "Fixed" means that those corpses are never overwritten/deleted at runtime, all new corpses are stored after the "fixed" ones. This means that "fixed" <= "used" <= "capacity". | | | The array capacity of <Corpses> is larger than the number of "fixed"/"used" corpses in order to allow the engine to store new corpses at runtime. "Fixed" means that those corpses are never overwritten/deleted at runtime – all new corpses are stored after the "fixed" ones. This means that "fixed" <= "used" <= "capacity". |
| |- | | |- |
| | <UsedCount> | | | <UsedCount> |
Line 1,663: |
Line 238: |
| |valign="top"| <Corpses> | | |valign="top"| <Corpses> |
| |valign="top"| - | | |valign="top"| - |
| | This is an int32 array for the <CRSACorpse> tags. By default Oni wants 20 slots for corpses. Unused corpses have their matrix and bounding box filled with zeros. | | | This is an int32 array for the <CRSACorpse> tags. By default, Oni wants 20 slots for corpses. Unused corpses have their matrix and bounding box filled with zeroes. |
| |- | | |- |
| |valign="top"| <CRSACorpse> | | |valign="top"| <CRSACorpse> |
| |valign="top"| - | | |valign="top"| - |
| | [[AE:Authoring_custom_camera_animations|New corpses]] can be made with BSL command "make_corpse filename" and some hex-editing. | | | [[Authoring_custom_camera_animations|New corpses]] can be made with the BSL command '''make_corpse filename''' and some hex-editing. The pose of the corpse is taken from the player character. The contents of the files thus created can then be inserted as elements in a level's CRSA. |
| : The pose of the corpse is taken from the player character.
| |
| : The contents of the files thus created can then be inserted as elements in a level's CRSA.
| |
| |- | | |- |
| | <CharacterClass> | | | <CharacterClass> |
Line 1,681: |
Line 254: |
| | <Matrix4x3> | | | <Matrix4x3> |
| | matrix | | | matrix |
| | Float 3x3 + float x3 for the last 3 values (X Y Z position). For more information about the matrix see [[OBD:CRSA]]. | | | Float 3x3 + float x3 for the last 3 values (X Y Z position). For more information about the matrix, see [[OBD:CRSA]]. |
| |- | | |- |
| | <BoundingBox> | | | <BoundingBox> |
Line 1,696: |
Line 269: |
| |} | | |} |
|
| |
|
| The level importer supports importing corpses from an XML file with the same format as described above or the following simplified format:
| | ==M3GA== |
| | There can be one M3GA instance per animated object. Animated meshes of doors are embedded in ONLV. All other animated meshes are stored outside it as M3GM files. |
|
| |
|
| {| class="wikitable" width="100%" | | {| class="wikitable" width="100%" |
| !width=150px| XML tag | | !width=150px| XML tag |
| !width=120px| content type | | !width=120px| Content type |
| ! description | | ! Description |
| |-
| |
| | <Corpses>
| |
| |
| |
| |
| |
| |-
| |
| |valign="top"| <Corpse>
| |
| |valign="top"| -
| |
| |
| |
| |-
| |
| | <Class>
| |
| | link
| |
| | [[XML:ONCC|ONCC]]''name''
| |
| |-
| |
| | <Transforms>
| |
| | -
| |
| | There are 19 <Matrix> for each <Transforms> (which represents a body part).
| |
| |-
| |
| | <Matrix>
| |
| | matrix
| |
| | Float 3x3 + float x3 for the last 3 values (X Y Z position). For more information about the matrix see [[OBD:CRSA]].
| |
| |-
| |
| | <BoundingBox>
| |
| | -
| |
| | Bounding box of the whole corpse. Optional, if not provided OniSplit will generate an approximate one. Currently it doesn't try to locate the ONCC to compute an exact bounding box.
| |
| |-
| |
| | <Min>
| |
| | float x3
| |
| |
| |
| |-
| |
| | <Max>
| |
| | float x3
| |
| |
| |
| |}
| |
| | |
| An empty Corpse element ( <Corpse/> ) is treated as unused and placed at the end of the array. If no such empty elements are provided OniSplit automatically adds 5. OniSplit also ensures that there are at least 20 corpses in the array.
| |
| | |
| If you created CRSA data using the Mod Tool addon, add an <Oni> at the beginning and an </Oni> tag at the end of the file.
| |
| | |
| | |
| ===M3GA===
| |
| One M3GA instance per animated object.
| |
| | |
| Animated meshes of doors are embedded in ONLV. All other animated meshes are stored outside as M3GM files.
| |
| | |
| {| class="wikitable" width="100%"
| |
| !width=150px| XML tag
| |
| !width=120px| content type
| |
| ! description
| |
| |- | | |- |
| | <M3GA id="..."> | | | <M3GA id="..."> |
| | integer | | | integer |
| | Instance Id. | | | Instance ID. |
| |- | | |- |
| | <Geometries> | | | <Geometries> |
Line 1,764: |
Line 290: |
| : #''N'' (instance number) (for non-door) | | : #''N'' (instance number) (for non-door) |
| : M3GM''name'' (for door) | | : M3GM''name'' (for door) |
| It can happen that you see here references to dae files. This happens when the ONLV was created with some older OniSplit version (like 0.9.86.0) and if the ONLV was converted to xml in absence of the resources used by M3GA. | | It can happen that you see here references to DAE files. This happens when the ONLV was created with some older OniSplit version (like 0.9.86.0) and if the ONLV was converted to xml in absence of the resources used by M3GA. |
| |} | | |} |
|
| |
|
| | ==M3GM== |
| | Read about them here [[XML:M3GM|HERE]]. Note that M3GMs have their own component instances: PNTA, VCRA (x2), TXCA, IDXA (x2). Doors store their animated model in ONLV, while the static model comes from BINACJBODOOR.oni, which also links to M3GM files. |
|
| |
|
| ===M3GM=== | | ==IDXA== |
| Read on [[XML:M3GM|HERE]].
| |
| | |
| Note that M3GMs have their own instances: PNTA, VCRA (x2), TXCA, IDXA (x2).
| |
| | |
| Doors store their animated geometry in ONLV while the static part comes from BINACJBODOOR.oni which again link to M3GM files.
| |
| | |
| | |
| ===IDXA===
| |
| {| class="wikitable" width="100%" | | {| class="wikitable" width="100%" |
| !width=150px| XML tag | | !width=150px| XML tag |
| !width=120px| content type | | !width=120px| Content type |
| ! description | | ! Description |
| |- | | |- |
| | <IDXA id="..."> | | | <IDXA id="..."> |
| | integer | | | integer |
| | Instance Id. | | | Instance ID. |
| |- | | |- |
| | <Indices> | | | <Indices> |
Line 1,794: |
Line 314: |
| | | | | |
| ; From ONOA to AGQG elements | | ; From ONOA to AGQG elements |
| : Link to <AGQGQuad> in [[XML:AKEV#AGQG|AGQG]] by order. (The array in AGQG starts with 0, so for example <Int32>6</Int32> would link to 7th <AGQGQuad>.) | | : Link to <AGQGQuad>s in [[XML:AKEV#AGQG|AGQG]] by order. (The array in AGQG starts with 0, so for example <Int32>6</Int32> would link to the 7th <AGQGQuad>.) |
| ; From M3GM to PNTA elements | | ; From M3GM to PNTA elements |
| : Read on [[XML:M3GM#PNTA|HERE]]. | | : Read more [[XML:M3GM#PNTA|HERE]]. |
| ; From M3GM to VCRA elements | | ; From M3GM to VCRA elements |
| : Read on [[XML:M3GM#VCRA|HERE]]. | | : Read more [[XML:M3GM#VCRA|HERE]]. |
| |} | | |} |
|
| |
|
| |
|
| ==Level files hierarchy== | | ==Level files hierarchy== |
| {| width="100%" style="text-align:center; empty-cells: hide" | | {| width="100%" style="text-align:center; empty-cells: hide" |
| |width="20%" style="background-color:#CCFFCC;"| (un)colored cell = file | | |width="20%" style="background-color:#CCFFCC;"| (un)colored cell = file |
| |width="20%" style="background-color:#CCFFCC; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| stripped cell = embedded instance | | |width="20%" style="background-color:#CCFFCC; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| striped cell = embedded instance |
| |width="20%"| | | |width="20%"| |
| |width="20%"| | | |width="20%"| |
| |width="20%"| | | |width="20%"| |
| |} | | |} |
|
| |
|
| |
|
| |
|
| {|class="wikitable" width="100%" style="text-align:center" | | {|class="wikitable" width="100%" style="text-align:center" |
Line 1,820: |
Line 337: |
| |width="20%"| | | |width="20%"| |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF;"| AKEV | | |style="background-color:#CCCCFF;"| AKEV |
| | | | | |
Line 1,826: |
Line 343: |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| PNTA | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| PNTA |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| PLEA | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| PLEA |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| TXCA | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| TXCA |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AGQG | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AGQG |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AGQR | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AGQR |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AGQC | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AGQC |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AGQC | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AGQC |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AGDB | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AGDB |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| TXMA | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| TXMA |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20c.gif | | | [[Image:Chart turn right.gif]] |
| | TXMP | | | TXMP |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AKVA | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AKVA |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AKEB | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AKBA |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| IDXA | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| IDXA |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AKBP | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AKBP |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| ABNA | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| ABNA |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AKOT | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AKOT |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| OTIT | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| OTIT |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"|OTLF | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"|OTLF |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| QTNA | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| QTNA |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20c.gif | | | [[Image:Chart turn right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| IDXA | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| IDXA |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AKAA | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AKAA |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20c.gif | | | [[Image:Chart turn right.gif]] |
| |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AKDA | | |style="background-color:#CCCCFF; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| AKDA |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| OBOA | | |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| OBOA |
| | | | | |
Line 1,964: |
Line 481: |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| M3GA | | |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| M3GA |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20c.gif | | | [[Image:Chart turn right.gif]] |
| |style="background-color:#FFCCCC;"| M3GM | | |style="background-color:#FFCCCC;"| M3GM |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | | | | |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#FFCCCC; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| PNTA | | |style="background-color:#FFCCCC; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| PNTA |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | | | | |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#FFCCCC; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| VCRA | | |style="background-color:#FFCCCC; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| VCRA |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | | | | |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#FFCCCC; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| TXCA | | |style="background-color:#FFCCCC; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| TXCA |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | | | | |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#FFCCCC; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| IDXA | | |style="background-color:#FFCCCC; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| IDXA |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | | | | |
| | http://ssg.oni2.net/design/60x20c.gif | | | [[Image:Chart turn right.gif]] |
| | TXMP | | | TXMP |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| | OBAN | | | OBAN |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20c.gif | | | [[Image:Chart turn right.gif]] |
| |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| ENVP | | |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| ENVP |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| ONMA | | |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| ONMA |
| | | | | |
Line 2,024: |
Line 541: |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| ONFA | | |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| ONFA |
| | | | | |
Line 2,030: |
Line 547: |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| ONTA | | |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| ONTA |
| | | | | |
Line 2,036: |
Line 553: |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20c.gif | | | [[Image:Chart turn right.gif]] |
| | ONSK | | | ONSK |
| | | | | |
Line 2,042: |
Line 559: |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| | TXMP | | | TXMP |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| | AISA | | | AISA |
| | | | | |
Line 2,054: |
Line 571: |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| | ONCC | | | ONCC |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20c.gif | | | [[Image:Chart turn right.gif]] |
| | ONWC | | | ONWC |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| | AITR | | | AITR |
| | | | | |
Line 2,072: |
Line 589: |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| | ONSA | | | ONSA |
| | | | | |
Line 2,078: |
Line 595: |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| | OBDC | | | OBDC |
| | | | | |
Line 2,084: |
Line 601: |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20c.gif | | | [[Image:Chart turn right.gif]] |
| |style="background-color:#FFFFAA;"| M3GM | | |style="background-color:#FFFFAA;"| M3GM |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | | | | |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#FFFFAA; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| PNTA | | |style="background-color:#FFFFAA; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| PNTA |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | | | | |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#FFFFAA; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| VCRA | | |style="background-color:#FFFFAA; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| VCRA |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | | | | |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#FFFFAA; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| TXCA | | |style="background-color:#FFFFAA; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| TXCA |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | | | | |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#FFFFAA; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| IDXA | | |style="background-color:#FFFFAA; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| IDXA |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | | | | |
| | http://ssg.oni2.net/design/60x20c.gif | | | [[Image:Chart turn right.gif]] |
| | TXMP | | | TXMP |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| ONOA | | |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| ONOA |
| | | | | |
Line 2,126: |
Line 643: |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20a.gif | | | [[Image:Chart descend.gif]] |
| | http://ssg.oni2.net/design/60x20c.gif | | | [[Image:Chart turn right.gif]] |
| |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| IDXA | | |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| IDXA |
| | | | | |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20b.gif | | | [[Image:Chart fork right.gif]] |
| |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| ENVP | | |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| ENVP |
| | | | | |
Line 2,138: |
Line 655: |
| | | | | |
| |- | | |- |
| | http://ssg.oni2.net/design/60x20c.gif | | | [[Image:Chart turn right.gif]] |
| |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| CRSA | | |style="background-color:#DDDDDD; background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,.5) 10px, rgba(255,255,255,.5) 20px);"| CRSA |
| | | | | |
Line 2,145: |
Line 662: |
| |- | | |- |
| | | | | |
| | http://ssg.oni2.net/design/60x20c.gif | | | [[Image:Chart turn right.gif]] |
| | ONCC | | | ONCC |
| | | | | |
| | | | | |
| |} | | |} |
| | |
| | {{XML}} |