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 Creación de Puertas by Lerfox13 (spanish)

This is the mini tutorial about doors done by Lerfox13. It explain three diferent ways to use doors in Severance: Blade of Darkness.

Posted by on - Basic Mapping/Technical

Creación de Puertas

Nota: El código que puedo asegurar que es correcto es el que está al final de la página. Es el que debes usar, el resto es una pequeña explicación de los que se hacen.

Lo primero que hay que decir es que en Blade parece que no existen puertas de apertura de bisagra, como las que tienes en casa. Sólo existen puertas de apertura horizontal o vertical.

Para crear una puerta hay que hacerlo desde código directamente.

El procedimiento es el siguiente:

  1. En el lugar donde queremos la puerta hay que colocar un sector, que será el que ocupe la puerta.
  2. Creamos la puerta desde código python y le decimos un punto dentro del sector, para indicar que sector tiene que ocupar.
  3. Creamos los objetos que hacen posible que se abra y cierre la puerta.

Como observáis, el procedimiento es fácil y mecánico. Una vez que tengas una puerta, el resto serán muy parecidas.

El sector en el LED

Lo primero que hay que hacer es preparar el sector como si fuera un paso entre dos habitaciones. Prácticamente se diseña igual que el paso si no hubiera puerta. He dicho prácticamente igual por el siguiente motivo: las texturas que se aplican a la puerta. Supongamos que tenemos el siguiente mapa:

La habitación A se comunica con la B por medio de P. Este P será nuestra puerta. Las texturas que se aplicarán a nuestra puerta serán las de la pared A y B que pegan contra nuestra puerta. Normalmente no queremos hacer esto, sino que la puerta tiene que tener una textura diferente. Por ejemplo, la pared será de roca y la puerta de madera. Para hacer esto:

Vemos que la puerta se ha trasformado en 3 sectores. Los sectores marrones y el amarillo. Realmente la puerta va a ser el sector amarillo, mientras que los sectores marrones nos van a servir para poner las texturas a la puerta y actuar de marco. La puerta va a tener las texturas de los lados de los sectores marrones que lindan con ella. Observa también que el sector amarillo es más grande. Esto sirve para simular las superficies por donde se desliza la puerto. Aquí es todo cuestión de imaginación.

En este ejemplo, podemos dar en alturas al sector A 0-10, a B 0-10, a P 0-3 y la los 2 amarillos 0-2.9 y probar el efecto en la vista openGL que será algo parecido a:

Por último, otro factor importante es la textura que va a tener la parte inferior de la puerta (si se abre hacia arriba). Pues bien, como imagináis, esta textura es la del techo del sector que ocupa la puerta.

Crear la puerta

Una vez que tenemos nuestro mapa con el sector preparado para la puerta, el código para crear la puerta es:

p1=Doors.CreateDoor( "p1" , (5858.75, -1110.78, 257.54) , (0,1,0) , 0 , 3000 , Doors.CLOSED)

El primer argumento es el nombre de la puerta. Este no necesita explicación.

El segundo es tu terna de números que indica un punto dentro del sector que queremos que sea la puerta. En principio da igual que punto sea mientras esté dentro del sector.

Según Genesis, cuando se dejaba caer por el foro de RebelAct,
"Basta con que el punto especificado por esas coordenadas esté dentro del sector, es solo para indicarle a la engine que sector quieres usar para convertirlo en puerta (bueno, en realidad también se usa como referencia para colocar los sonidos, si los hay, asociados a la puerta, por lo que es recomendable que dicho punto esté más o menos centrado)"
.

Según indica BirdMadBoy es mejor tomar el valor de este punto desde el juego, ya que el LED no es muy preciso. Para ello sólo hay que situar el jugador en el lugar que queramos y en la consola escribir char.Position.

El tercer argumento es la normal de la superficie del sector que vas a mover. 0,1,0 indica que se mueva hacia arriba. 0,-1,0 indica que se mueva hacia abajo. Las coordenadas son X,-Z,Y

X - Izquierda / derecha -1,1
Z - Arriba / Abajo -1,1
Y - Norte / Sur 1,-1

Los siguientes argumentos: [0,3000]...El 0 es el valor tope de la puerta. El 3000 es el tamaño de la puerta, que normalmente coincide con la altura de nuestro sector (si este empieza desde 0). La única forma de entender bien estos parámetros, así como los siguientes que trataré de explicar, es jugando con ellos.

El último argumento es el estado inicial de la puerta, que puede ser CLOSED u OPEN.

Bueno, ya tenemos nuestra puerta...pues no, todavía hay que ralizar algunas acciones más. Hay que indicarle como baja y sube la puerta.

p1.opentype=Doors.UNIF
p1.o_med_vel=-700
p1.o_med_displ=3000

p1.closetype=Doors.AC
p1.c_init_displ=3000
p1.c_med_vel=8000

Los primeros tres valores son para la apertura y los siguientes para cerrarla. Para el opentype y el closetype existen varios valores, pero los que he visto por los mapas son los aquí indicados. Para las velocidades sólo hay que tener en cuenta que para arriba siempre negativo, como diría un famoso entrenador de fútbol. El c_init_displ supongo que será el inicio del desplazamiento para cerrar la puerta y el o_med_displ será cuánto se desplaza la puerta. Como dije antes, la mejor forma de enterarse para que sirven estos valores es probar y jugar con ellos, nos pueden quedar cosas muy interesantes.

Abrir y cerrar la puerta.

Bueno ya tenemos nuestra bonita puerta...ahora, si no queremos que sea simple decoración, necesitamos que se abra y cierre.

Vamos a explicar 3 formas de hacerlo: mediante una palanca, mediante cerradura y matando a un enemigo.

Mediante una Palanca

La forma más fácil de abrir/cerrar una puerta es mediante una palanca. Para ello utilizamos el siguiente código:

palan=Levers.PlaceLever ( "palan" , Levers.LeverType3, (5100, -1460 , 2500),(0.49 , 0.49 , 0.50, -0.50),0.8)
palan.mode=1

Donde los valores de LeverType son, como podéis imaginar la posición, orientación y escala.

palan.OnTurnOnFunc=Abredoor1
palan.OnTurnOnArgs=()

palan.OnTurnOffFunc=Cierradoor1
palan.OnTurnOffArgs=()

Lo primero que hacemos es crear la palanca. Para ello usamos la función Levers.PlaceLevers....que actúa como constructor de la palanca. Como casi siempre (o siempre) el primer argumento es el nombre de la palanca. El siguiente el tipo. Según el archivo levers.py hay estos tipos:

  • LeverType1 = "Zocalo1" + "Palanca1"
  • LeverType2 = "Zocalo2" + "Palanca2"
  • LeverType3 = "Zocalo3" + "Palanca3"
  • LeverTypeFloor = "ZocaloSuelo" + "PalancaSuelo"
  • LeverTypeSnake = "ZocaloSerpiente" + "MandibulaSerpiente"

Los dos siguiente son la posición y la orientación y el último es la escala.

El palan.mode=1 no se exactamente lo que es, pero así funciona ;-)

Lo siguiente es indicar qué hacer cuando se activa o desactiva la palanca. En nuestro caso cuando se activa se llama a la función Abredoor1 sin ningún argumento y cuando se cierra a la función Cierradoor1. Estas funciones tienen que estar previamente definidas de la siguiente forma:

def Abredoor1():
p1.OpenDoor()
def Cierradoor1():
p1.CloseDoor()

Fácil, ¿no?

Mediante una Cerradura

Bueno, la cosa se complica ahora ya que para abrir o cerrar la puerta actúan varios elementos: la llave adecuada y la cerradura.

El código que muestro a continuación está sacado del código de uno de los niveles de Blade.

Creamos la cerradura:

cerradurp4=Locks.PlaceLock("cerradurp4","Cerraduracutre", (5220,-1240,1830),(0.0 , 0.008 ,0.71,-0.7),2.5)

Estos parámetros son los mismos que en la función PlaceLever que vimos antes. En este caso "Cerraduracutre" es el tipo de cerradura.

Establecemos la llave que necesita para abrirse o cerrarse:

cerradurp4.key="llave4

Establecemos el texto que se muestra en la cerradura:

darfuncs.SetHint(cerradurp4.obj,"Cerradura de la puerta")

Y ahora, como en la palanca, debemos indicar las funciones que se llaman cuando se abre o cierra la cerradura:

cerradurp4.OnUnLockFunc=Abredoor1
cerradurp4.OnUnLockArgs=()

cerradurp4.OnLockFunc=Cierradoor1
cerradurp4.OnLockArgs=()

Las funciones son iguales que en el caso anterior. Si queremos que no tengamos más la llave una vez que la usamos debemos añadir cerradurp4.key="" en el código de la función de apertura.

Ahora tenemos que crear la llave para poder abrir la cerradura. Se crea igual que cualquier objeto:

llave=Bladex.CreateEntity ( "llave4" ,"Llavecutre",5000.0 ,-1460.0 , 400.0 , "Physic")
llave.Scale=1.0
llave.Orientation=0.567, 0.024639, -0.822649 , 0.031350
darfuncs.SetHint(llave,"Llave de la puerta")
Stars.Twinkle("llave4")

Añadimos la función SetHint para indicar el texto mostrado y Stars.Twinkle le pone estrellitas a la llave.

¿Lioso? Al final pondré el código completo.

Matando a un Enemigo

Otro caso es que al matar a un enemigo se abra la puerta.

Lo primero que hay que hacer es crear un enemigo, por ejemplo un orco:

pers=Bladex.CreateEntity ("1ORC" ,"Ork" ,-769, -1114, 2209, "Person")
pers.Angle=1.23404798421
pers.Level=0
pers.Deaf= 1
pers.Blind= 1
EnemyTypes.EnemyDefaultFuncs(pers)

En este caso le hemos dicho que no ataque.

Ahora tenemos que definir la función que se llama cuando se mata al orco:

def EnemigoMuere(entity):
Abredoor1()
me = Bladex.GetEntity(entity)
if me.Data.OldImDeadFunc:
me.Data.OldImDeadFunc(entity)

Como se ve, se llama primero a la función de apertura de la puerta, después se llama a la función original de muerte que hemos guardado mediante las ordenes:

pers.Data.OldImDeadFunc = pers.ImDeadFunc
pers.ImDeadFunc = EnemigoMuere

Con esto, cuando matemos al orco la puerta se abrirá.

Sonido al abrir y cerrar la puerta

Todo esto sería más real si al abrir y cerrar la puerta se oyera el ruido que hace. El de la palanca y el de la cerradura ya suenan, pero el de la puerta tenemos que crearlo nosotros.

El mecanismo que utiliza Blade para hacer esto, es tener dos sonidos independientes. Uno para el deslizamiento y otro para cuando se termina. Para ello demos crear dos objetos sonido:

spuertar1d=Sounds.CreateEntitySound ("..\\..\\Sounds\\puerta-madera-deslizando.wav", "MaderaDesliz")
spuertar1d.MaxDistance=20000
spuertar1d.MinDistance=1000
spuertar1d.Volume=1.0

spuertar1g=Sounds.CreateEntitySound ("..\\..\\Sounds\\puerta-madera-golpe.wav", "MaderaGolpe")
spuertar1g.MaxDistance=20000
spuertar1g.MinDistance=2000
spuertar1g.Volume=1.0

Ahora hay que asociar los sonidos a la puerta:

p1.SetWhileOpenSound(spuertar1d)
p1.SetEndOpenSound(spuertar1g)

p1.SetWhileCloseSound(spuertar1d)
p1.SetEndCloseSound(spuertar1g)

Bueno, esta parte a sido fácil, parece ser que los chicos de RAS se han currado bien esto.

Código completo

Bueno, vamos a poner el código completo para que todo sea más claro. Algunos nombres pueden no coincidir con lo que hay en la explicación. espero no haber metido ningún error al pasar el código al tutorial. También sobrarán algunos import.

Apertura con palanca

import Bladex
import Doors
import Levers
import Locks
import Objects
import Sounds
import Button
import ReadGSFile
import AuxFuncs
import darfuncs
import Stars

#################### SONIDOS ############################
spuertar1d=Sounds.CreateEntitySound ("..\\..\\Sounds\\puerta-madera-deslizando.wav", "MaderaDesliz")
spuertar1d.MaxDistance=20000
spuertar1d.MinDistance=1000
spuertar1d.Volume=1.0

spuertar1g=Sounds.CreateEntitySound ("..\\..\\Sounds\\puerta-madera-golpe.wav", "MaderaGolpe")
spuertar1g.MaxDistance=20000
spuertar1g.MinDistance=2000
spuertar1g.Volume=1.0

################### FUNCIONES PARA ABRIR/CERRAR ###################

def Abredoor1():
p1.OpenDoor()

def Cierradoor1():
p1.CloseDoor()

##################### CREAMOS LA PUERTA #####################

p1=Doors.CreateDoor("p1", (5858.759, -1110.789, 257.542 ) , (0,1,0) ,0,3000,Doors.CLOSED)

p1.opentype=Doors.UNIF
p1.o_med_vel=-700
p1.o_med_displ=3000

p1.closetype=Doors.AC
p1.c_init_displ=3000
p1.c_med_vel=8000
p1.SetWhileOpenSound(spuertar1d)
p1.SetEndOpenSound(spuertar1g)

################### SONIDOS PARA LA PUERTA ####################

p1.SetWhileCloseSound(spuertar1d)
p1.SetEndCloseSound(spuertar1g)

################# PALANCA ################################

palan=Levers.PlaceLever("palan",Levers.LeverType3, (5100, -1460 , 2500),(0.495 ,0.49 ,0.50,-0.50) ,0.8)
palan.mode=1

palan.OnTurnOnFunc=Abredoor1
palan.OnTurnOnArgs=()

palan.OnTurnOffFunc=Cierradoor1
palan.OnTurnOffArgs=()

Abrir mediante una cerradura

import Bladex
import Doors
import Levers
import Locks
import Objects
import Sounds
import Button
import ReadGSFile
import AuxFuncs
import darfuncs
import Stars

#################### SONIDOS ############################
spuertar1d=Sounds.CreateEntitySound ("..\\..\\Sounds\\puerta-madera-deslizando.wav", "MaderaDesliz")
spuertar1d.MaxDistance=20000
spuertar1d.MinDistance=1000
spuertar1d.Volume=1.0

spuertar1g=Sounds.CreateEntitySound ("..\\..\\Sounds\\puerta-madera-golpe.wav", "MaderaGolpe")
spuertar1g.MaxDistance=20000
spuertar1g.MinDistance=2000
spuertar1g.Volume=1.0

################### FUNCIONES PARA ABRIR/CERRAR ###################

def Abredoor1():
p1.OpenDoor()

def Cierradoor1():
p1.CloseDoor()

##################### CREAMOS LA PUERTA #####################

p1=Doors.CreateDoor("p1", (5858.759, -1110.789, 257.5421) , (0,1,0) ,0,3000,Doors.CLOSED)

p1.opentype=Doors.UNIF
p1.o_med_vel=-700
p1.o_med_displ=3000

p1.closetype=Doors.AC
p1.c_init_displ=3000
p1.c_med_vel=8000
p1.SetWhileOpenSound(spuertar1d)
p1.SetEndOpenSound(spuertar1g)

################### SONIDOS PARA LA PUERTA ####################

p1.SetWhileCloseSound(spuertar1d)
p1.SetEndCloseSound(spuertar1g)

##################### CREAMOS CERRADURA ######################

cerradurp4=Locks.PlaceLock ("cerradurp4","Cerraduracutre", (5000,-1240,1500) , (0,0.008,0.7,-0.7),2.5)
cerradurp4.key="llave4"

darfuncs.SetHint (cerradurp4.obj,"Cerradura de la puerta")

cerradurp4.OnUnLockFunc=Abredoor1
cerradurp4.OnUnLockArgs=()

cerradurp4.OnLockFunc=Cierradoor1
cerradurp4.OnLockArgs=()

############## LLAVE ################################

o=Bladex.CreateEntity ("llave4","Llavecutre", 5000, -1460, 400,"Physic")
o.Scale=1.0
o.Orientation=0.567150,0.024639,-0.822649,0.031350
darfuncs.SetHint(o,"Llave de la puerta")
Stars.Twinkle("llave4")

Matando a un enemigo

import Bladex
import Doors
import Levers
import Locks
import Objects
import Sounds
import Button
import ReadGSFile
import AuxFuncs
import darfuncs
import Stars
import EnemyTypes

#################### SONIDOS ############################
spuertar1d=Sounds.CreateEntitySound ("..\\..\\Sounds\\puerta-madera-deslizando.wav", "MaderaDesliz")
spuertar1d.MaxDistance=20000
spuertar1d.MinDistance=1000
spuertar1d.Volume=1.0

spuertar1g=Sounds.CreateEntitySound ("..\\..\\Sounds\\puerta-madera-golpe.wav", "MaderaGolpe")
spuertar1g.MaxDistance=20000
spuertar1g.MinDistance=2000
spuertar1g.Volume=1.0

################### FUNCIONES PARA ABRIR/CERRAR ###################

def Abredoor1():
p1.OpenDoor()

def Cierradoor1():
p1.CloseDoor()

##################### CREAMOS LA PUERTA #####################

p1=Doors.CreateDoor ("p1" , (5858.75, -1110.78, 257.542) , (0,1,0) , 0, 3000,Doors.CLOSED)

p1.opentype=Doors.UNIF
p1.o_med_vel=-700
p1.o_med_displ=3000

p1.closetype=Doors.AC
p1.c_init_displ=3000
p1.c_med_vel=8000
p1.SetWhileOpenSound(spuertar1d)
p1.SetEndOpenSound(spuertar1g)

################### SONIDOS PARA LA PUERTA ####################

p1.SetWhileCloseSound(spuertar1d)
p1.SetEndCloseSound(spuertar1g)

############### CREAMOS ENEMIGO ##############

pers=Bladex.CreateEntity("1ORC","Ork",-769, -1114, 2209,"Person")
pers.Angle=1.23404798421
pers.Level=0
pers.Deaf= 1
pers.Blind= 1
EnemyTypes.EnemyDefaultFuncs(pers)

def EnemigoMuere(entity):
Abredoor1()
me = Bladex.GetEntity(entity)
if me.Data.OldImDeadFunc:
me.Data.OldImDeadFunc(entity)

pers.Data.OldImDeadFunc = pers.ImDeadFunc
pers.ImDeadFunc = EnemigoMuere

** Bueno, espero que os ayude en algo. Ya sabéis, si tenías alguna duda, queja, comentario, escribidnos a BladeRecursos

By lerfox13

Post a comment

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