Author Topic: XML1 Conversion Resource Topic  (Read 4579 times)

Offline Teancum

  • Admin
  • Invincible Member
  • ******
  • Posts: 5768
  • Likes: 53
XML1 Conversion Resource Topic
« on: January 24, 2009, 09:35am »
Level Conversion
How-To topic
--It's a really, really good idea to read the whole topic, as it's a learn-as-you-go type of thing, and more/clearer information is listed later that builds on the earlier posts.
--This is also a good topic on converting NPC's XML files to XMLB

PY Scripts
Modding Rundown: PY Scripts
--A rundown of the most common functions and what they do (these files open in Notepad)

Coloring of effects
Reference Topic
--Once you get an effect converted from XML to XMLB, it needs colors.  The topic above helps with that

Where to get the assets
You need the PS2 version of X-Men Legends in order to help out.  If you don't have it but are willing to help out, you can ask for what you need on a per-file basis.  For example;  You say you want to convert the first visit to the Astral Plane.  That's cool, you just let all of us know and someone will upload the files you need to get started.  But honestly, I think XML1 PS2 is like 10 bucks, and if you don't have a PS2 you can always extract the files and let your friend/family member borrow the game for awhile.

ASSETS / TOOLS NEEDED (links are currently down)
XML1 for PS2.  Specifically the assetsfb.zip file (extract the contents of this zip to a working folder)
FB Extractor
XML converter SE
Extent converter
Ultimate alphabetizer
« Last Edit: March 11, 2014, 06:24am by Teancum »

Offline Teancum

  • Admin
  • Invincible Member
  • ******
  • Posts: 5768
  • Likes: 53
Re: WIP: The Complete XML1 Conversion Resource Topic
« Reply #1 on: January 24, 2009, 09:42am »
LEVEL CONVERSION

RAW PREP OF THE LEVEL:

PREPPING THE ENG (LEVEL INFO) FILE
1-Open the appropriate FB file with FB extractor. 
2-Once extracting is complete, browse to the new /maps/[directory]/[mapname].eng.  Run that through XML converter.
3-Run THAT converted file through Ultimate alphabetizer
4-Now run THAT converted file through Extent converter
5-Compile to [levelname].engb using XMLBCUI

PREPPING THE NAV FILE

The NAV file is basically a list of coordinates that tell your AI hero buddies how to follow you.  If you don't have this file they can get lost easily.
1-Browse to the new /maps/[directory]/[mapname].nav.  Run that through XML converter.
2-Run THAT converted file through Ultimate alphabetizer
3-Now run THAT converted file through Extent converter
4-Compile to [levelname].engb using XMLBCUI

PREPPING THE CHRB FILE

This file is a list of NPCs that the level needs to load from npcstat.engb.  At this point it's a raw conversion like the others, SO...
1-Browse to the new /maps/[directory]/[mapname].chr.  Run that through XML converter.
2-Run THAT converted file through Ultimate alphabetizer
3-Now run THAT converted file through Extent converter
4-Compile to [levelname].engb using XMLBCUI
« Last Edit: February 11, 2009, 01:46pm by Teancum »

Offline Teancum

  • Admin
  • Invincible Member
  • ******
  • Posts: 5768
  • Likes: 53
Re: WIP: The Complete XML1 Conversion Resource Topic
« Reply #2 on: January 24, 2009, 09:55am »
MAKING SOMETHING LIGHT ENOUGH TO PICK UP

One of the first things I noticed was that Wolvy couldn't pick up a mere trash can.  Well, things run a bit different by default in XML2, so to make objects that are light grab-able do the following.

1-Find the entry in the level's engb, as per the example below
Quote
   entity {
   classname = physent ;
   deatheffect = base/material/break/brk_metal ;
   deathsound = death_styles/ds_metal_hollow_s ;
   fxlevel = 1 ;
   health = 5 ;
   heaviness = 1 ;
   mass = 100 ;
   material = hollow_metal ;
   model = haarp/55galdrum ;
   name = 55galdrum_ha ;
   randompickups = 2 ;
   structure = 0 ;
   }

Change heaviness to 0.  Now any character can pick it up.


FIXING ZONE TRANSITION ISSUES

To get the zone link to appear in the correct spot remove the orient line.
Original (the link to escape the level does not appear in the right spot):
Quote
   entinst {
   type = zone_link01 ;
      inst {
      orient = 0 0 -1.17481
      name = zone_link01 ;
      pos = 18 1794 0 ;
      }

   }

After the removal (it now works):
Quote
   entinst {
   type = zone_link01 ;
      inst {
      name = zone_link01 ;
      pos = 18 1794 0 ;
      }

   }


FIXING BRIDGES
To make a bridge from xml1 work in mua, remove the following lines in the bridge entry in the level eng:

Quote
   stopfly =   ;
   stophero =   ;
   stopnpcaltenemy =   ;
   stopnpcenemy =   ;
   stopnpcneutral =   ;
   stopwalk =  ;


CONVERTING FIRE
Be sure that you copy the original name = [name here] ; entry
Code: [Select]
   entity {
   actontouch = true ;
   actrescheduledelay = 0.4 ;
   actrescheduledelaymin = 0.4 ;
   boxdamage = true ;
   classname = affectableharment ;
   damage = 3 ;
   damagemods = dmgmod_no_pain ;
   damagetype = dmg_fire ;
   firstact = 1 ;
   health = 1 ;
   knockback = 200 ;
   loopfx = map/common/fire_small ;
   loopfxstarton = true ;
   name = fire ;
   reactpower = extinguish ;
   spawnsoundloop = zone_shared/effects/fire_med ;
   stophero = false ;
   stopnpcaltenemy = false ;
   stopnpcenemy = false ;
   stopnpcneutral = false ;
   targetlockable = true ;
   }

to this one:
Code: [Select]
   entity {
   boxdamage = true ;
   classname = affectableharment ;
   damage = 3 5 ;
   damagemods = dmgmod_no_pain dmgmod_unblockable ;
   damagetype = dmg_fire ;
   extent = -17 -17 0 17 17 28 ;
   health = 1 ;
   knockback = 200 ;
   loopfx = map/common/fire_small ;
   loopfxstarton = true ;
   name = fire ;
   radiusdamage = false ;
   reactpower = extinguish ;
   spawnsoundloop = zone_shared/effects/fire_med ;
   stopprojectile = false ;
   targetlockable = true ;
   }
get the correct extent values from its entinst call. Also be sure you remove the structure = and smartfire = lines.


CONVERTING FIRE WALLS

Be sure that you copy the original name = [name here] ; entry
Code: [Select]
   entity {
   boxdamage = true ;
   classname = affectableharment ;
   damage = 3 ;
   damagemods = dmgmod_no_pain ;
   damagetype = dmg_fire ;
   extent = -120 -65 0 120 65 90 ;
   health = 1 ;
   knockback = 200 ;
   loopfx = map/common/fire_wall ;
   loopfxstarton = true ;
   name = fire_wall ;
   radiusdamage = false ;
   reactpower = extinguish ;
   smartfire = true ;
   spawnsoundloop = zone_shared/effects/fire_large ;
   startenabled = true ;
   stopprojectile = false ;
   structure = 2 ;
   targetlockable = true ;
   }

an example of a working entity that is made to harm something (after conversion and editing to make it work):
Code: [Select]
   entity {
   boxdamage = true ;
   classname = affectableharment ;
   damage = 3 ;
   damagemods = dmgmod_no_pain ;
   damagetype = dmg_fire ;
   extent = -14 -14 0 14 14 28 ;
   health = 1 ;
   knockback = 200 ;
   loopfx = map/common/fire_wall ;
   loopfxstarton = true ;
   name = fire_wall ;
   radiusdamage = false ;
   reactpower = extinguish ;
   spawnsoundloop = zone_shared/effects/fire_med ;
   stopprojectile = false ;
   targetlockable = true ;
   }


CONVERTING OBJECTIVES
Open the specific mission file with a text editor. remove the first lines until the first entry and replace it with a line indicating the act the level is on (see below).

before
Quote
XMLB MISSION {
descname = Sentinel flashback. ;
description = Nightcrawler's Danger Room Flashback ;
keepheroes = false ;
mapload =  ;
maxheros = 4 ;
minheros = 4 ;
remote = true ;
scriptstart = missions/mission_fmv_107 ;
skinset = 70s ;
teamselect = false ;

   REQUIREDHERO {
   name = nightcrawler ;
   }

   OBJECTIVE {
   descname = Battle the Sentinel. ;

After
Quote
XMLB MISSION {
   act = 1 ;
   REQUIREDHERO {
   name = nightcrawler ;
   }

   OBJECTIVE {
   descname = Battle the Sentinel. ;

Now remove all entries that dont start with OBJECTIVE (i am not sure if they are compatible with Mua) (see below)

Before
Quote
XMLB MISSION {
   act = 1 ;
   REQUIREDHERO {
   name = nightcrawler ;
   }


   OBJECTIVE {
   descname = Battle the Sentinel. ;

After
Quote
XMLB MISSION {
   act = 1 ;
   OBJECTIVE {
   descname = Battle the Sentinel. ;

Now remove all lines indicating xp, and replace them with rep (see below). Also add the line indicating whether the objective is optional or not, and add lines indicating the zone the mission will take place in, and add the line indicating that the type is normal (see below). You can also remove 'updatedescription' lines that dont actually contain information.

Before
Quote
   OBJECTIVE {
   descname = Battle the Sentinel. ;
   description = Defeat the Sentinel in combat. ;
   enabled = true ;
   name = sentinel1 ;
   updatedescription =  ;
   xp = 100 ;
   }

After
Quote
   OBJECTIVE {
   descname = Battle the Sentinel. ;
   description = Defeat the Sentinel in combat. ;
   enabled = true ;
   name = sentinel1 ;
   optional = false ;
   rep = 5 ;
   type = normal ;
   zone = nyc1 ;

   }

Follow the steps above for all the OBJECTIVE entries. Now go to the last entry. It is usually the main objective. If it has a line indicating xp = ; just remove that line. You might need to change the name of the OBJECTIVE from a name with spaces to one without spaces (ex: Protect the city --> Protect_the_city). If it is the main objective you can add the line '   major = true ;' and remember the name of this OBJECTIVE, it will be used as the 'parentname'. Now go look at the objectives, if they are all descendents of the main objective add the line '   parentname = Protect_the_city ;' to all of them (not to the main objective itself of course). If there are multiple parents you can use multiple parentname lines. And MAKE SURE everything is still in ALPHABETICAL order.

Now save the file and compile it. Remember the filename. decompile and open data/missions/missions. Add an entry indicating your new objective (see below). Now save and compile it.

Before
Quote
XMLB MISSIONS {
maxmissions = 25 ;
maxquestsperact = 75 ;
maxtotalquests = 300 ;
   MISSION {
   name = act1_heli ;
   }

   MISSION {
   name = act1_stark ;
   }

After
Quote
XMLB MISSIONS {
maxmissions = 25 ;
maxquestsperact = 75 ;
maxtotalquests = 300 ;
   MISSION {
   name = sent_fb ;
   }


   MISSION {
   name = act1_heli ;
   }

   MISSION {
   name = act1_stark ;
   }

Now decompile and open packages/generated/maps/package/missions. Add an entry for your new objective (see below). Save and compile.

Before
Quote
   xml {
   filename = data/missions/autotestquests ;
   }

   xml {
   filename = data/missions/missions ;
   }

}

After
Quote
   xml {
   filename = data/missions/autotestquests ;
   }

   xml {
   filename = data/missions/missions ;
   }

   xml {
   filename = data/missions/sent_fb ;
   }


}

Now decompile and open data/zoneinfo. Look for the line 'objective_category' for your mission. Change it to point to your new objective (see below). Save and compile.

Before
Quote
   texture = textures/zoneshot/act1_extract1 ;
   towncenter = true ;
   }

   zone {
   act = 1 ;
   build = normal ;
   extraction = true ;
   loading = textures/loadingxmen/sentinel_fb ;
   name = act1/fb/nyc1 ;
   objective_category = act1_heli ;
   savename = Seventh Ave. ;
   start_game = true ;
   state = 2 ;
   }

   zone {
   act = 1 ;

After
Quote
   texture = textures/zoneshot/act1_extract1 ;
   towncenter = true ;
   }

   zone {
   act = 1 ;
   build = normal ;
   extraction = true ;
   loading = textures/loadingxmen/sentinel_fb ;
   name = act1/fb/nyc1 ;
   objective_category = sent_fb ;
   savename = Seventh Ave. ;
   start_game = true ;
   state = 2 ;
   }

   zone {
   act = 1 ;

Now, open your level eng's that will use this new objective file. Add the line 'act = x ;' to the first entity, where 'x' is the number of the act you added in the objective file (see below). Save and recompile your objective files.

Before
Quote
XMLB world {
   entity {
   extent_max = 3000 3240 360 ;
   extent_min = 0 480 0 ;
   level = 8 ;
   name = world ;

After
Quote
XMLB world {
   entity {
   act = 1 ;
   extent_max = 3000 3240 360 ;
   extent_min = 0 480 0 ;
   level = 8 ;
   name = world ;

Now, if you changed any of the names in the mission file (ex: Protect_the_city) then you also have to change that name in all the scripts that refer to those objectives.

In some xml mission files, objectives contain counters, indicated by 'count = x'. If you do a straight conversion the way i described above, the counters wont appear in the objective menu, so you need to change a few things. You need to add to or overwrite the part in 'description' with the part in 'updatedescription' because the part in 'updatedescription' will not appear in the menu.

example:
Before
Quote
   OBJECTIVE {
   count = 2 ;
   descname = Defeat the Sentinels. ;
   description = Battle the Sentinels and destroy them. ;
   enabled = false ;
   name = sentinel2 ;
   optional = false ;
   parentname = Protect_the_city ;
   rep = 5 ;
   type = normal ;
   updatedescription =  You have defeated %d of %d Sentinels. ;
   zone = nyc2 ;
   }

After
Quote
   OBJECTIVE {
   count = 2 ;
   descname = Defeat the Sentinels. ;
   description = You have defeated %d of %d Sentinels. ;
   enabled = false ;
   name = sentinel2 ;
   optional = false ;
   parentname = Protect_the_city ;
   rep = 5 ;
   type = normal ;
   updatedescription = Battle the Sentinels and destroy them. ;
   zone = nyc2 ;
   }


MAKING THINGS BREAKABLE (SUCH AS WALLS)
to change walls (and possible other structures) to break, change the line in the entity from 'structure = x ;' to 'structure = 1 ;'

for example:
before (wall doesnt break)
Quote
   entity {
   classname = tileent ;
   deatheffect = base/material/tile/tile_haarp_int ;
   deathsound = death_styles/t_haarp_int ;
   deathspawn = tile_hall_haarp ;
   fxlevel = 3 ;
   health = 100 ;
   material = solid_metal ;
   name = tile_hall_haarp ;
   structure = 2 ;
   tilemodelfolder = tiles/haarpint/ ;
   }

After, wall breaks
Quote
   entity {
   classname = tileent ;
   deatheffect = base/material/tile/tile_haarp_int ;
   deathsound = death_styles/t_haarp_int ;
   deathspawn = tile_hall_haarp ;
   fxlevel = 3 ;
   health = 100 ;
   material = solid_metal ;
   name = tile_hall_haarp ;
   structure = 1 ;
   tilemodelfolder = tiles/haarpint/ ;
   }
« Last Edit: August 24, 2014, 10:33am by Teancum »

Offline Teancum

  • Admin
  • Invincible Member
  • ******
  • Posts: 5768
  • Likes: 53
Re: WIP: The Complete XML1 Conversion Resource Topic
« Reply #3 on: January 24, 2009, 10:15am »
To build a bridge you should have the following lines in your powerstyle:
Code: [Select]
      damagetype = dmg_magnetic ;
         damageMod {
         name = dmgmod_environment ;
         }
where dmg_magnetic can be changed to dmg_telekinesis for a phsycic bridge or dmg_cold for an ice bridge. To form Magma's bridge you should be able to do dmg_fire, but it does not seem to work in MUA. If this does not work in XML2 we will remedy this we will replace the magnetic bridge with the lava bridge, and give Magma's first power dmg_magnetic so that she can build bridges.

To extinguish a fire you should have the following line:
Code: [Select]
         damageMod {
         name = dmgmod_extinguish ;
         }

To be able to weld things, you should have: (Iceman and Storm could extinguish fires in XML1)
Code: [Select]
         damageMod {
         name = dmgmod_weld ;
         }

If an object will not react to PY script commands be sure it isn't a physent
« Last Edit: July 23, 2014, 12:24pm by Teancum »

Offline Teancum

  • Admin
  • Invincible Member
  • ******
  • Posts: 5768
  • Likes: 53
Re: XML1 Conversion Resource Topic
« Reply #4 on: July 23, 2014, 09:39am »
LOOPING SOUNDS
I am not sure if the level sounds are handled similar to character sounds, but I found that to have looping sounds in level sounds, there were some bytes that needed to be changed. Without changing those bytes, as an example the sounds of a fire would occur once, and not loop. Once I found which bytes to change, the fire sound looped and sounded like it was working correctly. The zsmeditor ignored these bytes and set them to 00, instead of converting them to match their original value (from the file they were imported from). These are also the same bytes that allow the music to work correctly when imported. I mentioned how to do it in this thread http://marvelmods.com/forum/index.php?topic=2249.0

Once you find the one you need to edit, go back two bytes. Overwrite the 00 with 22 (note that for looping sounds in the _m level sound files, like for fires, put 01 instead of 22).



How to convert death sounds in level _m sound files
It seems that the xml1 death sounds are not directly compatible with MUA, they have an a,b,c,.. style instead of 0,1,2. You can change them into MUA style by doing the following:

1. Decompile the level eng file that refers to the sound file being converted. Replace the death_styles in lines like:with death_style, so it looks like:
2. Make a sound file, import all the xml1 sounds, and for all the death_style sounds (starting with ds_) find new hashes with Zsm Editor and replace the old ones. Then save the new file.

*Example*
Using Zsm Editor, go to 'Text to Hash' (F3), then enter the text for the death sound. As an example, lets say in the level sound file there are the sounds ds_glass_l_a and ds_glass_l_b. The text to get the hash is:Use the hash you get after conversion for ds_glass_l_a (replace the old hashes in the Events tab), and add one to that hash for ds_glass_l_b. If there are ds_glass_l_c and more, keep adding one to the hash each time. If there is only one of the death sounds (only ds_glass_l_a), the text to get the hash should be:
After following these steps, the object death sounds will work in game.


MUSIC -- OST can be found at the following link: https://www.youtube.com/watch?v=fbVGtTotYjQ&list=PL8BF047BD350B8423
This describes how to convert music from the games MUA or XML2PC to custom sound sets. These are specifically meant for level sound files. The music sounds have the following hashes: music/XXX_c where XXX is the name that is referenced in the level eng/xml files on the line '   soundfile = XXX ;').

Required tools:
ZSM Editor 2.3 by Winstrol
Hex editor (example XVI32)

Step 1 Build custom sound set
You probably want to make the soundset a XXX_v.zss file if you're using your sound set for MUA, or XXX_c.zss if you're using XML2. Include all the files in your sound set using Zsm Editor. You can save yourself some time later if you put the _c music file as the first file on the list. It should be ID 00 (in the Files tab look under ID, and look for your YYY_c.wav file, where YYY is the name of the file where you are importing the music from). Since you imported the music from YYY, you may want to change the filename from YYY_c.wav to XXX_c.wav to avoid confusion later. You can change the name by clicking a few times on the part under the Files tab under 'File'.

Now you'll need to change the hash for the music file (and possibly many of the other files you imported, but that is beyond the scope of this 'how-to'). Using Zsm Editor, click 'Tools' then 'Text to hash'. This will allow you to get what your new hash should be. Where it says 'Input text' enter 'music/XXX_c' where XXX is the name that will be referenced by the level. Then click 'Convert' and a number will appear. Copy that number. Now get the ID of your XXX_c.wav file from the 'Files' tab. Go to the 'Events' tab and look for that same ID. Click on it, and paste your new hash over the old Event/Hash by double clicking or entering it in the tab below and clicking 'Add'.

Go to the 'Files' tab and mark down the 'Size' of the XXX_c.wav file. You will need it for Step 2.

Now save your new sound set.

Step 2 Copy game sound set data
Because Zsm Editor does not handle 41kHz stereo files, you will need to copy the data directly from its source. Open the sound set (with a hex editor) from where you imported the YYY_c.wav file. Search for 'YYY_c.wav' in the text portion (e.g., using cntrl+f for XVI32). If you go 8 bytes back you will see the file size (that you should have marked down before) in hex, and in little endian (so if it is 10 56 then the file size is 56 10 in hex). If you go four bytes before that (so 12 before the filename) you will see the offset to the data. Mark this number down (make sure to account for the endianness). Now go to that location in the file (the offset is the absolute value of which byte you should go to in the file).

You will now need to copy the data. You can block the set of bytes you need and then copy them. The amount of bytes you should block is the file size which you should have marked down.

Step 3 Paste game sound set data
You will now need to paste the sound set data into your custom sound set. Open your custom soundset with a hex editor. Using the same techniques described in step 2, find the offset for the data and go there. Now you will need to delete the number of bytes equal to the file size to remove the data which Zsm Editor included in the file. You then need to paste the data which you copied in step 2. If you don't want to delete, you can overwrite them instead, whatever you do, make sure the total file size of your sound file does not change. If it does, something wrong happened.

Step 4 Modifying parameters
You will now need to modify the parameters in your custom sound set to allow the sound to work correctly. Hopefully you put the XXX_c.wav file as ID 00. If yes, then in a hex editor, go to the beginning of the file and search for the hex string (not text) 22 56 00. It should be surrounded by other 22 56 00 entries after it (but not before it), like in the picture below. If you have put the XXX_c.wav file as ID 00, then the first one is the one you need to modify. If not, you will need to find the one you want to modify by using/matching the numbers beside the 22 56 00 entries and where you placed it in the file (as you can see in the picture, 4 bytes before the 2256 indicates the placement).



Once you find the one you need to edit, go back two bytes. Overwrite the 00 with 22 (note that for looping sounds in the _m level sound files, like for fires, put 01 instead of 22). If the music you took from the original game file is 41kHz, you will also need to change the 2256 to 28A0 (changing it from 22050Hz to 41kHz). If you're not sure you can try 2256 and run the game. If the music is really slow, bump it up to 28A0. It is also possible to check in the file where you imported the music from, that file should also have a 28A0 entry.

Now save the custom sound set, and you should be good to go.

Good luck
« Last Edit: July 23, 2014, 12:23pm by Teancum »