Blade of Darkness holds true to the greatest of hack and slash legends, combining sorcery, knights, and swords with god forsaken enemies that deserve to have their arms slashed off with a broadsward. Blade of Darkness looked excellent in 2001, and still delivers its gore well today. Holding True to it's genre it offers modders both custom maps and scripts. Relevent Links Fansite Mod List Modding Community

Post tutorial Report RSS Level Editing Scripting by Prospero. Part. 19

A Painless Way to install New Models (Objects or characters)

Posted by on - Basic Client Side Coding

A Painless Way to Install New Objects.

I think I have finally found a good way to install new models (objects or characters). Previously, in demo maps I have made, it was necessary to manually copy .BOD files to the correct directory. The new method makes the map completely plug'n'play. The maps must be made as a 'Mod' and installed from the BODLoader 'Mods' directory.

Step1.

Make a folder in your map named 'To3DObjs'. Put all your new .BOD files for Objects in here. For new Characters, put the .BOD files in another folder named To3DChars.

Step2.

At the end of the file 'BLModInfo.py', add this code:

python code:
inststuff=0

if inststuff==0:
  execfile("../../BODLoader/Mods/MyMapName/Installnewstuff.py")
        instuff=1
else:
  print "Install stuff already done"

Step3.

Create a file 'Installnewstuff.py' in your map folder. The content of the file goes like this:

python code:
import os
import shutil
import stat

def getmtime(filename):
      st = os.stat(filename)
      return st[stat.ST_MTIME]

Odst= ('../../3DObjs')

ObjFiles=os.listdir('../../BODLoader/Mods/WizardsDomain/To3DObjs')
for file in ObjFiles:
  newfile = os.path.basename (file)
  Osrc=  ('../../BODLoader/Mods/WizardsDomain/To3DObjs/'+newfile)

  if os.path.exists('../../3DObjs/'+newfile):
    print "Exists file: ",newfile
    # if file already exists in dest dir, check for for mod time
    if getmtime('../../3DObjs/'+newfile) < getmtime(Osrc):
      shutil.copy(Osrc,Odst)
      print "overwriting : ",newfile
  else:
    print "NOT exists: ",newfile
    #if file does not already exist at dest dir, copy it straight to dest dir
    shutil.copy(Osrc,Odst)
    print "copying: ",newfile

--------------------------------------------------------------------

When the game starts, all the contents of the To3DObjs folder are copied to the main BOD/3Dobjs folder. BUT only of a file of the same name does not exist there. However, if you update your model at any time and put the updated .BOD file in the To3DObjs folder, the pre-existing file in the main 3DObjs folder will be overwritten by the new modified version. To install to other directories, simply edit this code, e.g:

Cdst= ('../../3DChars')

and replace Odst with Cdst in the following block of code.

Update. Ignore the following Step 4.
For better method, go to first post on page 5 >>>>>

Step4.

After this code, add blocks of code for each object installed.

python code:
if os.path.exists ("../../3dObjs/mynewobject.BOD"):
  if not os.path.exists ("../../Config/mynewobject.cfg"):
          listapp = open("../../BodLink.list", "a")                    
            listapp.write("..\\..\\3dObjs\\mynewobject.BOD\n")
            listapp.write("MyNewObject\n")
            listapp.close()
            cfgfile = open("../../Config/mynewobject.cfg","w")
            cfgfile.write("The presense of this file ensures that the BodLink.list is not repeatedly appended.\n")
            cfgfile.close()

Add a version of this block of code for each new Object

The name in Yellow is the internal name of your object (Name used to create it)

The name in Pink is the name of the .BOD file. These can be the same.

Once this routine is set up within the map the new object is permanently installed. This allows the object to be created in any other map even if the map from where it was installed is uninstalled.
So every time you wish to install a new object, just put the .BOD file in the relevant folder, copy/paste/edit the block of code that writes to the BodLink.list and thats it. If you modify the .BOD file at any time, the copy in the main directory will be updated.

Note. This code installs to basic model and allows it to be created in a map. The texture (.mmp) file is also needed. This can be installed in the main 3DObjs folder simply by putting it in the To3DObjs folder. (Load it from the .lvl file in the usual manner.) Or it can be kept local to the map by including it in the file list in the BLModInfo file.

Physical objects need extra code to make them solid. Weapons and pickupable objects need extra code (See Lib/Reference.py) to define their data and onscreen name. This is usualy done within the map from DefFuncs.py e.g:

python code:
import Reference

Reference.DefaultObjectData['MyNewSword']= [Reference.OBJ_WEAPON, 2, 0, 2.0,  Reference.THR_SPINNING, [Reference.W_FLAG_1H,]]
Reference.DefaultSelectionData['MyNewSword']=(8.0,4000.0, "My New Sword")


For savegame integrity, add the same code to a file 'ActorsInit.py'

This is not strictly necessary, but the save will crash on load if the Player happens to have a new object in his inventory when you saved.

New Characters need a lot more data. (See eariler tuts)

I have been using this routine for a while now and it seems fairly idiotproof. It's as well to us this method even if you are just testing/experimenting. Avoid manually editing the BodLink.list if at all possible. Certain text editors seem to confuse Python as to where the end of a file is and after manually editing the BodLink.list can become corrupted. It's easily fixed but still annoying.
Even more painless way to install new 3d Models.

This method was discovered by Vasja and does away with any writing to the BodLink.list.

Follow the method above until Step 4. Then instead of adding the the blocks of code for each object, make another file: InitNewChars.py (name not critical) with this content:

python code:
import BBLibc

# Load Bods

BBLibc.LoadBOD("..\\..\\3DObjs\\AnimalClaw.BOD")
BBLibc.ReadBOD("..\\..\\3DObjs\\AnimalClaw.BOD")

BBLibc.LoadBOD("..\\..\\3DChars\\BigCat_A.BOD")
BBLibc.ReadBOD("..\\..\\3DChars\\BigCat_A.BOD")

BBLibc.LoadBOD("..\\..\\3DChars\\Enano7.BOD")
BBLibc.ReadBOD("..\\..\\3DChars\\Enano7.BOD")

# and so on for each obj/char

This file should be exec'd from cfg.py before BladeInit.py:

python code:
execfile("..\\..\\Scripts\sys_init.py")
Bladex.ReadLevel("WizardsDomain.lvl")
execfile("InitNewChars.py")# just here
execfile("..\\..\\Scripts\BladeInit.py")

For savegame integrity this file should be executed from file ActorInit.py.

Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: