]> git.llucax.com Git - z.facultad/75.07/algowars.git/commitdiff
Import inicial después del "/var incident". :(
authorLeandro Lucarella <llucax@gmail.com>
Sun, 23 Mar 2003 07:10:16 +0000 (07:10 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Sun, 23 Mar 2003 07:10:16 +0000 (07:10 +0000)
322 files changed:
bin/AlgoWars.exe [new file with mode: 0644]
bin/bitmaps/desconocido.bmp [new file with mode: 0644]
bin/bitmaps/desconocido_l.bmp [new file with mode: 0644]
bin/bitmaps/gameover.bmp [new file with mode: 0644]
bin/bitmaps/laser.bmp [new file with mode: 0644]
bin/bitmaps/meteorito.bmp [new file with mode: 0644]
bin/bitmaps/meteorito_l.bmp [new file with mode: 0644]
bin/bitmaps/misil.bmp [new file with mode: 0644]
bin/bitmaps/misildirigido.bmp [new file with mode: 0644]
bin/bitmaps/naveespia.bmp [new file with mode: 0644]
bin/bitmaps/naveespia_l.bmp [new file with mode: 0644]
bin/bitmaps/naveliviana.bmp [new file with mode: 0644]
bin/bitmaps/naveliviana_l.bmp [new file with mode: 0644]
bin/bitmaps/navepesada.bmp [new file with mode: 0644]
bin/bitmaps/navepesada_l.bmp [new file with mode: 0644]
bin/bitmaps/navepropia.bmp [new file with mode: 0644]
bin/bitmaps/navepropia_l.bmp [new file with mode: 0644]
bin/bitmaps/navesuicida.bmp [new file with mode: 0644]
bin/bitmaps/navesuicida_l.bmp [new file with mode: 0644]
bin/comun.eaw [new file with mode: 0644]
doc/AlgoWars.sdw [new file with mode: 0644]
doc/CHANGES.TXT [new file with mode: 0644]
doc/HISTORY.TXT [new file with mode: 0644]
doc/LICENCIA_GPL.TXT [new file with mode: 0644]
doc/Manual.sxw [new file with mode: 0644]
doc/README [new file with mode: 0644]
doc/consigna.sxw [new file with mode: 0644]
doc/ref/Armas.html [new file with mode: 0644]
doc/ref/Camara.html [new file with mode: 0644]
doc/ref/Camaras.html [new file with mode: 0644]
doc/ref/Coordenadas.html [new file with mode: 0644]
doc/ref/Descripcion.html [new file with mode: 0644]
doc/ref/ECameramanDestruido.html [new file with mode: 0644]
doc/ref/ENavePropiaDestruida.html [new file with mode: 0644]
doc/ref/EObservadorDestruido.html [new file with mode: 0644]
doc/ref/ERegExpr.html [new file with mode: 0644]
doc/ref/ESerializacion.html [new file with mode: 0644]
doc/ref/Espacio.html [new file with mode: 0644]
doc/ref/Filtro.html [new file with mode: 0644]
doc/ref/Filtros.html [new file with mode: 0644]
doc/ref/FormConfig.html [new file with mode: 0644]
doc/ref/FormMain.html [new file with mode: 0644]
doc/ref/Lista.html [new file with mode: 0644]
doc/ref/Meteorito.html [new file with mode: 0644]
doc/ref/Nave.html [new file with mode: 0644]
doc/ref/NaveEnemiga.html [new file with mode: 0644]
doc/ref/NavePropia.html [new file with mode: 0644]
doc/ref/NavesEnemigas.html [new file with mode: 0644]
doc/ref/Objeto.html [new file with mode: 0644]
doc/ref/ObjetoPersistente.html [new file with mode: 0644]
doc/ref/ObjetoVolador.html [new file with mode: 0644]
doc/ref/RegExpr.html [new file with mode: 0644]
doc/ref/SerializacionUtils.html [new file with mode: 0644]
doc/ref/TConfigForm.html [new file with mode: 0644]
doc/ref/TMainForm.html [new file with mode: 0644]
doc/ref/TRegExpr.html [new file with mode: 0644]
doc/ref/Tipos.html [new file with mode: 0644]
doc/ref/Vectores.html [new file with mode: 0644]
doc/ref/Vista.html [new file with mode: 0644]
doc/ref/algowars.ddp [new file with mode: 0644]
doc/ref/cArma.html [new file with mode: 0644]
doc/ref/cCamara.html [new file with mode: 0644]
doc/ref/cCamaraAbajo.html [new file with mode: 0644]
doc/ref/cCamaraArriba.html [new file with mode: 0644]
doc/ref/cCamaraFrontal.html [new file with mode: 0644]
doc/ref/cCamaraLatDer.html [new file with mode: 0644]
doc/ref/cCamaraLatIzq.html [new file with mode: 0644]
doc/ref/cCamaraMapa.html [new file with mode: 0644]
doc/ref/cCamaraTrasera.html [new file with mode: 0644]
doc/ref/cCoordenadas.html [new file with mode: 0644]
doc/ref/cEspacio.html [new file with mode: 0644]
doc/ref/cFiltro.html [new file with mode: 0644]
doc/ref/cFiltroAbajo.html [new file with mode: 0644]
doc/ref/cFiltroArriba.html [new file with mode: 0644]
doc/ref/cFiltroFrontal.html [new file with mode: 0644]
doc/ref/cFiltroLatDer.html [new file with mode: 0644]
doc/ref/cFiltroLatIzq.html [new file with mode: 0644]
doc/ref/cFiltroLock.html [new file with mode: 0644]
doc/ref/cFiltroMapa.html [new file with mode: 0644]
doc/ref/cFiltroTrasero.html [new file with mode: 0644]
doc/ref/cLaser.html [new file with mode: 0644]
doc/ref/cLista.html [new file with mode: 0644]
doc/ref/cMeteorito.html [new file with mode: 0644]
doc/ref/cMisil.html [new file with mode: 0644]
doc/ref/cMisilDirigido.html [new file with mode: 0644]
doc/ref/cNave.html [new file with mode: 0644]
doc/ref/cNaveEnemiga.html [new file with mode: 0644]
doc/ref/cNaveEspia.html [new file with mode: 0644]
doc/ref/cNaveLiviana.html [new file with mode: 0644]
doc/ref/cNavePesada.html [new file with mode: 0644]
doc/ref/cNavePropia.html [new file with mode: 0644]
doc/ref/cNaveSuicida.html [new file with mode: 0644]
doc/ref/cObjeto.html [new file with mode: 0644]
doc/ref/cObjetoPersistente.html [new file with mode: 0644]
doc/ref/cObjetoVolador.html [new file with mode: 0644]
doc/ref/cVector.html [new file with mode: 0644]
doc/ref/cVista.html [new file with mode: 0644]
doc/ref/constructors.gif [new file with mode: 0644]
doc/ref/functions.gif [new file with mode: 0644]
doc/ref/functions_big.gif [new file with mode: 0644]
doc/ref/index-class.html [new file with mode: 0644]
doc/ref/index-function.html [new file with mode: 0644]
doc/ref/index-unit.html [new file with mode: 0644]
doc/ref/index.html [new file with mode: 0644]
doc/ref/legend.html [new file with mode: 0644]
doc/ref/menue.html [new file with mode: 0644]
doc/ref/methods.gif [new file with mode: 0644]
doc/ref/private.gif [new file with mode: 0644]
doc/ref/private_big.gif [new file with mode: 0644]
doc/ref/property.gif [new file with mode: 0644]
doc/ref/protected.gif [new file with mode: 0644]
doc/ref/protected_big.gif [new file with mode: 0644]
doc/ref/public.gif [new file with mode: 0644]
doc/ref/public_big.gif [new file with mode: 0644]
doc/src-html/.htaccess [new file with mode: 0644]
doc/src-html/AlgoWars.html [new file with mode: 0644]
doc/src-html/auxiliares/Lista.pas [new file with mode: 0644]
doc/src-html/auxiliares/Objeto.pas [new file with mode: 0644]
doc/src-html/auxiliares/ObjetoPersistente.pas [new file with mode: 0644]
doc/src-html/auxiliares/RegExpr.pas [new file with mode: 0644]
doc/src-html/auxiliares/SerializacionUtils.pas [new file with mode: 0644]
doc/src-html/auxiliares/Tipos.pas [new file with mode: 0644]
doc/src-html/forms/FormConfig.pas [new file with mode: 0644]
doc/src-html/forms/FormMain.pas [new file with mode: 0644]
doc/src-html/modelo/Coordenadas.pas [new file with mode: 0644]
doc/src-html/modelo/Espacio.pas [new file with mode: 0644]
doc/src-html/modelo/Vectores.pas [new file with mode: 0644]
doc/src-html/modelo/ov/Armas.pas [new file with mode: 0644]
doc/src-html/modelo/ov/Meteorito.pas [new file with mode: 0644]
doc/src-html/modelo/ov/ObjetoVolador.pas [new file with mode: 0644]
doc/src-html/modelo/ov/naves/Nave.pas [new file with mode: 0644]
doc/src-html/modelo/ov/naves/NaveEnemiga.pas [new file with mode: 0644]
doc/src-html/modelo/ov/naves/NavePropia.pas [new file with mode: 0644]
doc/src-html/modelo/ov/naves/NavesEnemigas.pas [new file with mode: 0644]
doc/src-html/vista/Camara.pas [new file with mode: 0644]
doc/src-html/vista/Camaras.pas [new file with mode: 0644]
doc/src-html/vista/Filtro.pas [new file with mode: 0644]
doc/src-html/vista/Filtros.pas [new file with mode: 0644]
doc/src-html/vista/Vista.pas [new file with mode: 0644]
doc/uml/diagrama.dia [new file with mode: 0644]
doc/uml/diagrama.png [new file with mode: 0644]
doc/uml/estado.png [new file with mode: 0644]
doc/uml/jerarquia.dia [new file with mode: 0644]
doc/uml/jerarquia.png [new file with mode: 0644]
doc/uml/secuencia_actualizar.dia [new file with mode: 0644]
doc/uml/secuencia_actualizar.png [new file with mode: 0644]
doc/uml/secuencia_colisiones.dia [new file with mode: 0644]
doc/uml/secuencia_colisiones.png [new file with mode: 0644]
doc/uml/vista.dia [new file with mode: 0644]
doc/uml/vista.png [new file with mode: 0644]
download/algowars0.4.4_src.zip [new file with mode: 0644]
download/algowars0.5.5_src.zip [new file with mode: 0644]
download/algowars0.6.0_src.zip [new file with mode: 0644]
download/algowars0.8.0_src.zip [new file with mode: 0644]
download/algowars0.8.2_src.zip [new file with mode: 0644]
download/algowars0.9.8_src.zip [new file with mode: 0644]
download/algowars0.9.9.1_src.zip [new file with mode: 0644]
download/algowars_src.zip [new file with mode: 0644]
download/escenarios/meteoritos.eaw [new file with mode: 0644]
download/escenarios/naves.eaw [new file with mode: 0644]
download/instalar.exe [new file with mode: 0644]
download/skins/alfa.zip [new file with mode: 0644]
download/skins/alfa/laser.bmp [new file with mode: 0644]
download/skins/alfa/meteorito.bmp [new file with mode: 0644]
download/skins/alfa/meteorito_l.bmp [new file with mode: 0644]
download/skins/alfa/misil.bmp [new file with mode: 0644]
download/skins/alfa/misildirigido.bmp [new file with mode: 0644]
download/skins/alfa/naveespia.bmp [new file with mode: 0644]
download/skins/alfa/naveespia_l.bmp [new file with mode: 0644]
download/skins/alfa/naveliviana.bmp [new file with mode: 0644]
download/skins/alfa/naveliviana_l.bmp [new file with mode: 0644]
download/skins/alfa/navepesada.bmp [new file with mode: 0644]
download/skins/alfa/navepesada_l.bmp [new file with mode: 0644]
download/skins/alfa/navepropia.bmp [new file with mode: 0644]
download/skins/alfa/navesuicida.bmp [new file with mode: 0644]
download/skins/alfa/navesuicida_l.bmp [new file with mode: 0644]
download/skins/default.zip [new file with mode: 0644]
download/skins/default/laser.jpg [new file with mode: 0644]
download/skins/default/meteorito.jpg [new file with mode: 0644]
download/skins/default/misil.jpg [new file with mode: 0644]
download/skins/default/misildirigido.jpg [new file with mode: 0644]
download/skins/default/naveespia.jpg [new file with mode: 0644]
download/skins/default/naveliviana.jpg [new file with mode: 0644]
download/skins/default/navepesada.jpg [new file with mode: 0644]
download/skins/default/navepropia.jpg [new file with mode: 0644]
download/skins/default/navesuicida.jpg [new file with mode: 0644]
download/skins/maxx/naveliviana.bmp [new file with mode: 0644]
download/skins/maxx/navepesada.bmp [new file with mode: 0644]
download/skins/maxx/navepropia.bmp [new file with mode: 0644]
download/skins/maxx/navesuicida.bmp [new file with mode: 0644]
src/AlgoWars.am2 [new file with mode: 0644]
src/AlgoWars.bpg [new file with mode: 0644]
src/AlgoWars.cfg [new file with mode: 0644]
src/AlgoWars.dof [new file with mode: 0644]
src/AlgoWars.dpr [new file with mode: 0644]
src/AlgoWars.drc [new file with mode: 0644]
src/AlgoWars.dsk [new file with mode: 0644]
src/AlgoWars.iss [new file with mode: 0644]
src/AlgoWars.res [new file with mode: 0644]
src/AlgoWars.todo [new file with mode: 0644]
src/algowars.ico [new file with mode: 0644]
src/auxiliares/Lista.pas [new file with mode: 0644]
src/auxiliares/Objeto.pas [new file with mode: 0644]
src/auxiliares/ObjetoPersistente.pas [new file with mode: 0644]
src/auxiliares/RegExpr.pas [new file with mode: 0644]
src/auxiliares/SerializacionUtils.pas [new file with mode: 0644]
src/auxiliares/Tipos.pas [new file with mode: 0644]
src/forms/FormConfig.dfm [new file with mode: 0644]
src/forms/FormConfig.pas [new file with mode: 0644]
src/forms/FormMain.dfm [new file with mode: 0644]
src/forms/FormMain.pas [new file with mode: 0644]
src/modelo/Coordenadas.pas [new file with mode: 0644]
src/modelo/Espacio.pas [new file with mode: 0644]
src/modelo/Vectores.pas [new file with mode: 0644]
src/modelo/ov/Armas.pas [new file with mode: 0644]
src/modelo/ov/Meteorito.pas [new file with mode: 0644]
src/modelo/ov/ObjetoVolador.pas [new file with mode: 0644]
src/modelo/ov/naves/Nave.pas [new file with mode: 0644]
src/modelo/ov/naves/NaveEnemiga.pas [new file with mode: 0644]
src/modelo/ov/naves/NavePropia.pas [new file with mode: 0644]
src/modelo/ov/naves/NavesEnemigas.pas [new file with mode: 0644]
src/test/AlgoWars.test_camara+espacio+form.dpr [new file with mode: 0644]
src/test/AlgoWars.test_camara+espacio.dpr [new file with mode: 0644]
src/test/AlgoWars.test_camara.dpr [new file with mode: 0644]
src/test/AlgoWars.test_coordenadas.dpr [new file with mode: 0644]
src/test/AlgoWars.test_coordenadas2.dpr [new file with mode: 0644]
src/test/AlgoWars.test_espacio.dpr [new file with mode: 0644]
src/test/AlgoWars.test_objeto_volador.dpr [new file with mode: 0644]
src/test/AlgoWars.test_persecusion.dpr [new file with mode: 0644]
src/test/AlgoWars.test_vectores.dpr [new file with mode: 0644]
src/test/AlgoWars_test_espacio2.dpr [new file with mode: 0644]
src/test/AlgoWars_test_serializacion.cfg [new file with mode: 0644]
src/test/AlgoWars_test_serializacion.dfm [new file with mode: 0644]
src/test/AlgoWars_test_serializacion.dof [new file with mode: 0644]
src/test/AlgoWars_test_serializacion.dpr [new file with mode: 0644]
src/test/AlgoWars_test_serializacion.dsk [new file with mode: 0644]
src/test/AlgoWars_test_serializacion.res [new file with mode: 0644]
src/test/AlgoWars_test_serializacion.salida [new file with mode: 0644]
src/test/Serializacion.dfm [new file with mode: 0644]
src/test/Serializacion.pas [new file with mode: 0644]
src/test/cb/CajaBcaFinal.txt [new file with mode: 0644]
src/test/cb/NavesEnemigasTest.pas [new file with mode: 0644]
src/test/cb/negra..txt [new file with mode: 0644]
src/test/cn/SerializacionTest.dfm [new file with mode: 0644]
src/test/cn/SerializacionTest.pas [new file with mode: 0644]
src/test/cn/SerializationTest.cfg [new file with mode: 0644]
src/test/cn/SerializationTest.dof [new file with mode: 0644]
src/test/cn/SerializationTest.dpr [new file with mode: 0644]
src/test/cn/SerializationTest.dsk [new file with mode: 0644]
src/test/cn/SerializationTest.res [new file with mode: 0644]
src/test/cn/negra..txt [new file with mode: 0644]
src/test/serializado.eaw [new file with mode: 0644]
src/vista/Camara.pas [new file with mode: 0644]
src/vista/Camaras.pas [new file with mode: 0644]
src/vista/Filtro.pas [new file with mode: 0644]
src/vista/Filtros.pas [new file with mode: 0644]
src/vista/Vista.pas [new file with mode: 0644]
website/.htaccess [new file with mode: 0644]
website/Templates/normal.dwt [new file with mode: 0644]
website/barra.html [new file with mode: 0644]
website/configurar.html [new file with mode: 0644]
website/desarrollo.html [new file with mode: 0644]
website/downloads.html [new file with mode: 0644]
website/images/algowars.gif [new file with mode: 0644]
website/images/bullet.jpg [new file with mode: 0644]
website/images/desarrolladores.gif [new file with mode: 0644]
website/images/desconocido.jpg [new file with mode: 0644]
website/images/desconocido_l.jpg [new file with mode: 0644]
website/images/download.gif [new file with mode: 0644]
website/images/meteorito.jpg [new file with mode: 0644]
website/images/meteorito_l.jpg [new file with mode: 0644]
website/images/naveespia.jpg [new file with mode: 0644]
website/images/naveespia_l.jpg [new file with mode: 0644]
website/images/naveliviana.jpg [new file with mode: 0644]
website/images/naveliviana_l.jpg [new file with mode: 0644]
website/images/navepesada.jpg [new file with mode: 0644]
website/images/navepesada_l.jpg [new file with mode: 0644]
website/images/navepropia.jpg [new file with mode: 0644]
website/images/navepropia_l.jpg [new file with mode: 0644]
website/images/navesuicida.jpg [new file with mode: 0644]
website/images/navesuicida_l.jpg [new file with mode: 0644]
website/index.html [new file with mode: 0644]
website/instalar.html [new file with mode: 0644]
website/jugar.html [new file with mode: 0644]
website/main.html [new file with mode: 0644]
website/naves.html [new file with mode: 0644]
website/screenshots.html [new file with mode: 0644]
website/screenshots/configurar.jpg [new file with mode: 0644]
website/screenshots/configurar_tb.jpg [new file with mode: 0644]
website/screenshots/inst1.jpg [new file with mode: 0644]
website/screenshots/inst1_tb.jpg [new file with mode: 0644]
website/screenshots/inst2.jpg [new file with mode: 0644]
website/screenshots/inst2_tb.jpg [new file with mode: 0644]
website/screenshots/instalar.jpg [new file with mode: 0644]
website/screenshots/juego.jpg [new file with mode: 0644]
website/screenshots/juego2.jpg [new file with mode: 0644]
website/screenshots/juego2_tb.jpg [new file with mode: 0644]
website/screenshots/juego_tb.jpg [new file with mode: 0644]
website/screenshots/menu_escenario.jpg [new file with mode: 0644]
website/screenshots/menu_juego.jpg [new file with mode: 0644]
website/screenshots/no.jpg [new file with mode: 0644]
website/screenshots/si.jpg [new file with mode: 0644]
website/screenshots/siguiente.jpg [new file with mode: 0644]
website/screenshots/terminar.jpg [new file with mode: 0644]
website/skins.html [new file with mode: 0644]
website/stats/Apr-2002.html [new file with mode: 0644]
website/stats/Dec-2001.html [new file with mode: 0644]
website/stats/Feb-2002.html [new file with mode: 0644]
website/stats/Jan-2002.html [new file with mode: 0644]
website/stats/Mar-2002.html [new file with mode: 0644]
website/stats/Nov-2001.html [new file with mode: 0644]
website/stats/index.html [new file with mode: 0644]
website/stats/mgstat.hist [new file with mode: 0644]
website/stats/mgstat.pos [new file with mode: 0644]
website/test.php [new file with mode: 0644]
website/uml.html [new file with mode: 0644]
website/uml/diagrama.gif [new file with mode: 0644]
website/uml/estado.gif [new file with mode: 0644]
website/uml/jerarquia.gif [new file with mode: 0644]
website/uml/secuencia_actualizar.gif [new file with mode: 0644]
website/uml/secuencia_colisiones.gif [new file with mode: 0644]
website/uml/vista.gif [new file with mode: 0644]

diff --git a/bin/AlgoWars.exe b/bin/AlgoWars.exe
new file mode 100644 (file)
index 0000000..0a7871d
Binary files /dev/null and b/bin/AlgoWars.exe differ
diff --git a/bin/bitmaps/desconocido.bmp b/bin/bitmaps/desconocido.bmp
new file mode 100644 (file)
index 0000000..3811c79
Binary files /dev/null and b/bin/bitmaps/desconocido.bmp differ
diff --git a/bin/bitmaps/desconocido_l.bmp b/bin/bitmaps/desconocido_l.bmp
new file mode 100644 (file)
index 0000000..460e37c
Binary files /dev/null and b/bin/bitmaps/desconocido_l.bmp differ
diff --git a/bin/bitmaps/gameover.bmp b/bin/bitmaps/gameover.bmp
new file mode 100644 (file)
index 0000000..17d44f9
Binary files /dev/null and b/bin/bitmaps/gameover.bmp differ
diff --git a/bin/bitmaps/laser.bmp b/bin/bitmaps/laser.bmp
new file mode 100644 (file)
index 0000000..43cc7bb
Binary files /dev/null and b/bin/bitmaps/laser.bmp differ
diff --git a/bin/bitmaps/meteorito.bmp b/bin/bitmaps/meteorito.bmp
new file mode 100644 (file)
index 0000000..cd3fe83
Binary files /dev/null and b/bin/bitmaps/meteorito.bmp differ
diff --git a/bin/bitmaps/meteorito_l.bmp b/bin/bitmaps/meteorito_l.bmp
new file mode 100644 (file)
index 0000000..ad81796
Binary files /dev/null and b/bin/bitmaps/meteorito_l.bmp differ
diff --git a/bin/bitmaps/misil.bmp b/bin/bitmaps/misil.bmp
new file mode 100644 (file)
index 0000000..3d39b74
Binary files /dev/null and b/bin/bitmaps/misil.bmp differ
diff --git a/bin/bitmaps/misildirigido.bmp b/bin/bitmaps/misildirigido.bmp
new file mode 100644 (file)
index 0000000..5f57e4a
Binary files /dev/null and b/bin/bitmaps/misildirigido.bmp differ
diff --git a/bin/bitmaps/naveespia.bmp b/bin/bitmaps/naveespia.bmp
new file mode 100644 (file)
index 0000000..6803ee4
Binary files /dev/null and b/bin/bitmaps/naveespia.bmp differ
diff --git a/bin/bitmaps/naveespia_l.bmp b/bin/bitmaps/naveespia_l.bmp
new file mode 100644 (file)
index 0000000..7bc55fc
Binary files /dev/null and b/bin/bitmaps/naveespia_l.bmp differ
diff --git a/bin/bitmaps/naveliviana.bmp b/bin/bitmaps/naveliviana.bmp
new file mode 100644 (file)
index 0000000..cdeb974
Binary files /dev/null and b/bin/bitmaps/naveliviana.bmp differ
diff --git a/bin/bitmaps/naveliviana_l.bmp b/bin/bitmaps/naveliviana_l.bmp
new file mode 100644 (file)
index 0000000..7b5c073
Binary files /dev/null and b/bin/bitmaps/naveliviana_l.bmp differ
diff --git a/bin/bitmaps/navepesada.bmp b/bin/bitmaps/navepesada.bmp
new file mode 100644 (file)
index 0000000..f1c13cb
Binary files /dev/null and b/bin/bitmaps/navepesada.bmp differ
diff --git a/bin/bitmaps/navepesada_l.bmp b/bin/bitmaps/navepesada_l.bmp
new file mode 100644 (file)
index 0000000..d8c8ebc
Binary files /dev/null and b/bin/bitmaps/navepesada_l.bmp differ
diff --git a/bin/bitmaps/navepropia.bmp b/bin/bitmaps/navepropia.bmp
new file mode 100644 (file)
index 0000000..ffc1b7e
Binary files /dev/null and b/bin/bitmaps/navepropia.bmp differ
diff --git a/bin/bitmaps/navepropia_l.bmp b/bin/bitmaps/navepropia_l.bmp
new file mode 100644 (file)
index 0000000..3c56584
Binary files /dev/null and b/bin/bitmaps/navepropia_l.bmp differ
diff --git a/bin/bitmaps/navesuicida.bmp b/bin/bitmaps/navesuicida.bmp
new file mode 100644 (file)
index 0000000..378968d
Binary files /dev/null and b/bin/bitmaps/navesuicida.bmp differ
diff --git a/bin/bitmaps/navesuicida_l.bmp b/bin/bitmaps/navesuicida_l.bmp
new file mode 100644 (file)
index 0000000..c8899fd
Binary files /dev/null and b/bin/bitmaps/navesuicida_l.bmp differ
diff --git a/bin/comun.eaw b/bin/comun.eaw
new file mode 100644 (file)
index 0000000..c7bfd9b
--- /dev/null
@@ -0,0 +1,540 @@
+<eaw version=1.0>\r
+<navepropia>\r
+<id>BD604C</id>\r
+<posicion>\r
+<id>BD8C58</id>\r
+<X>0</X>\r
+<Y>0</Y>\r
+<Z>0</Z>\r
+</posicion>\r
+<velocidad>0</velocidad>\r
+<potencia>5</potencia>\r
+<energia>100</energia>\r
+<dimension>25</dimension>\r
+<coordenadas>\r
+<id>BD8AD8</id>\r
+<i>\r
+<id>BD60FC</id>\r
+<X>1</X>\r
+<Y>0</Y>\r
+<Z>0</Z>\r
+</i>\r
+<j>\r
+<id>BD8BD8</id>\r
+<X>0</X>\r
+<Y>1</Y>\r
+<Z>0</Z>\r
+</j>\r
+<k>\r
+<id>BD8C18</id>\r
+<X>0</X>\r
+<Y>0</Y>\r
+<Z>1</Z>\r
+</k>\r
+</coordenadas>\r
+<misiles>10</misiles>\r
+<misilesdirigidos>5</misilesdirigidos>\r
+<velmaxima>0,17</velmaxima>\r
+<retardolaser>50</retardolaser>\r
+<retardomisil>1000</retardomisil>\r
+<retardomisdir>2500</retardomisdir>\r
+<retardolasercont>0</retardolasercont>\r
+<retardomisilcont>0</retardomisilcont>\r
+<retardomisdircont>0</retardomisdircont>\r
+<lockeado class=0>nil</lockeado>\r
+<armaselec>6</armaselec>\r
+<lockfiltro>\r
+<id>BD8C98</id>\r
+<observador class=cMeteorito>\r
+<id>BD931C</id>\r
+<posicion>\r
+<id>BE15F4</id>\r
+<X>0</X>\r
+<Y>0</Y>\r
+<Z>0</Z>\r
+</posicion>\r
+<velocidad>0</velocidad>\r
+<potencia>5</potencia>\r
+<energia>20</energia>\r
+<dimension>5</dimension>\r
+<coordenadas>\r
+<id>BE1370</id>\r
+<i>\r
+<id>BE1570</id>\r
+<X>1</X>\r
+<Y>0</Y>\r
+<Z>0</Z>\r
+</i>\r
+<j>\r
+<id>BE159C</id>\r
+<X>0</X>\r
+<Y>1</Y>\r
+<Z>0</Z>\r
+</j>\r
+<k>\r
+<id>BE15C8</id>\r
+<X>0</X>\r
+<Y>0</Y>\r
+<Z>1</Z>\r
+</k>\r
+</coordenadas>\r
+</observador>\r
+<radiomaximo>2000</radiomaximo>\r
+<radiominimo>25</radiominimo>\r
+<cosapertura>0,696706709347165421</cosapertura>\r
+</lockfiltro>\r
+</navepropia>\r
+<objetos total=12>\r
+<objeto0 class=cNavePesada>\r
+<id>BD8D5C</id>\r
+<posicion>\r
+<id>BD8ED8</id>\r
+<X>3000</X>\r
+<Y>3300</Y>\r
+<Z>300</Z>\r
+</posicion>\r
+<velocidad>0,17</velocidad>\r
+<potencia>2</potencia>\r
+<energia>100</energia>\r
+<dimension>25</dimension>\r
+<coordenadas>\r
+<id>BD893C</id>\r
+<i>\r
+<id>BD8E18</id>\r
+<X>-0,707106781186547524</X>\r
+<Y>-0,707106781186547524</Y>\r
+<Z>0</Z>\r
+</i>\r
+<j>\r
+<id>BD8E58</id>\r
+<X>0,707106781186547524</X>\r
+<Y>-0,707106781186547524</Y>\r
+<Z>0</Z>\r
+</j>\r
+<k>\r
+<id>BD8E98</id>\r
+<X>0</X>\r
+<Y>0</Y>\r
+<Z>1</Z>\r
+</k>\r
+</coordenadas>\r
+<misiles>5</misiles>\r
+<misilesdirigidos>2</misilesdirigidos>\r
+<velmaxima>0,17</velmaxima>\r
+<retardolaser>1000</retardolaser>\r
+<retardomisil>60000</retardomisil>\r
+<retardomisdir>180000</retardomisdir>\r
+<retardolasercont>0</retardolasercont>\r
+<retardomisilcont>0</retardomisilcont>\r
+<retardomisdircont>0</retardomisdircont>\r
+<camporadar>5000</camporadar>\r
+<campominimo>500</campominimo>\r
+</objeto0>\r
+<objeto1 class=cNaveLiviana>\r
+<id>BD906C</id>\r
+<posicion>\r
+<id>BD91E8</id>\r
+<X>4000</X>\r
+<Y>-500</Y>\r
+<Z>-1000</Z>\r
+</posicion>\r
+<velocidad>0,18</velocidad>\r
+<potencia>1</potencia>\r
+<energia>60</energia>\r
+<dimension>15</dimension>\r
+<coordenadas>\r
+<id>BD85C0</id>\r
+<i>\r
+<id>BD9128</id>\r
+<X>-0,816496580927726033</X>\r
+<Y>0,408248290463863016</Y>\r
+<Z>0,408248290463863016</Z>\r
+</i>\r
+<j>\r
+<id>BD9168</id>\r
+<X>-0,447213595499957939</X>\r
+<Y>-0,894427190999915879</Y>\r
+<Z>0</Z>\r
+</j>\r
+<k>\r
+<id>BD91A8</id>\r
+<X>0,365148371670110742</X>\r
+<Y>-0,182574185835055371</Y>\r
+<Z>0,912870929175276856</Z>\r
+</k>\r
+</coordenadas>\r
+<misiles>0</misiles>\r
+<misilesdirigidos>0</misilesdirigidos>\r
+<velmaxima>0,18</velmaxima>\r
+<retardolaser>500</retardolaser>\r
+<retardomisil>60000</retardomisil>\r
+<retardomisdir>180000</retardomisdir>\r
+<retardolasercont>0</retardolasercont>\r
+<retardomisilcont>0</retardomisilcont>\r
+<retardomisdircont>0</retardomisdircont>\r
+<camporadar>3000</camporadar>\r
+<campominimo>250</campominimo>\r
+</objeto1>\r
+<objeto2 class=cNaveSuicida>\r
+<id>BD9368</id>\r
+<posicion>\r
+<id>BD94F0</id>\r
+<X>1000</X>\r
+<Y>600</Y>\r
+<Z>600</Z>\r
+</posicion>\r
+<velocidad>0,2</velocidad>\r
+<potencia>4</potencia>\r
+<energia>30</energia>\r
+<dimension>10</dimension>\r
+<coordenadas>\r
+<id>BD9404</id>\r
+<i>\r
+<id>BD9430</id>\r
+<X>-0,816496580927726033</X>\r
+<Y>0,408248290463863016</Y>\r
+<Z>-0,408248290463863016</Z>\r
+</i>\r
+<j>\r
+<id>BD9470</id>\r
+<X>-0,447213595499957939</X>\r
+<Y>-0,894427190999915879</Y>\r
+<Z>0</Z>\r
+</j>\r
+<k>\r
+<id>BD94B0</id>\r
+<X>-0,365148371670110742</X>\r
+<Y>0,182574185835055371</Y>\r
+<Z>0,912870929175276856</Z>\r
+</k>\r
+</coordenadas>\r
+<misiles>0</misiles>\r
+<misilesdirigidos>0</misilesdirigidos>\r
+<velmaxima>0,2</velmaxima>\r
+<retardolaser>1000</retardolaser>\r
+<retardomisil>60000</retardomisil>\r
+<retardomisdir>180000</retardomisdir>\r
+<retardolasercont>0</retardolasercont>\r
+<retardomisilcont>0</retardomisilcont>\r
+<retardomisdircont>0</retardomisdircont>\r
+<camporadar>2500</camporadar>\r
+</objeto2>\r
+<objeto3 class=cNaveEspia>\r
+<id>BD9670</id>\r
+<posicion>\r
+<id>BD97FC</id>\r
+<X>3000</X>\r
+<Y>-500</Y>\r
+<Z>-500</Z>\r
+</posicion>\r
+<velocidad>0,2</velocidad>\r
+<potencia>1</potencia>\r
+<energia>30</energia>\r
+<dimension>10</dimension>\r
+<coordenadas>\r
+<id>BD9710</id>\r
+<i>\r
+<id>BD973C</id>\r
+<X>-1</X>\r
+<Y>-5,42101086242752217E-20</Y>\r
+<Z>0</Z>\r
+</i>\r
+<j>\r
+<id>BD977C</id>\r
+<X>5,42101086242752217E-20</X>\r
+<Y>-1</Y>\r
+<Z>0</Z>\r
+</j>\r
+<k>\r
+<id>BD97BC</id>\r
+<X>0</X>\r
+<Y>0</Y>\r
+<Z>1</Z>\r
+</k>\r
+</coordenadas>\r
+<misiles>0</misiles>\r
+<misilesdirigidos>0</misilesdirigidos>\r
+<velmaxima>0,2</velmaxima>\r
+<retardolaser>1000</retardolaser>\r
+<retardomisil>60000</retardomisil>\r
+<retardomisdir>180000</retardomisdir>\r
+<retardolasercont>0</retardolasercont>\r
+<retardomisilcont>0</retardomisilcont>\r
+<retardomisdircont>0</retardomisdircont>\r
+<camporadar>2000</camporadar>\r
+<posicionenemiga>nil</posicionenemiga>\r
+</objeto3>\r
+<objeto4 class=cMeteorito>\r
+<id>BD7FCC</id>\r
+<posicion>\r
+<id>BD9A7C</id>\r
+<X>2000</X>\r
+<Y>1000</Y>\r
+<Z>1000</Z>\r
+</posicion>\r
+<velocidad>0</velocidad>\r
+<potencia>5</potencia>\r
+<energia>20</energia>\r
+<dimension>5</dimension>\r
+<coordenadas>\r
+<id>BD9990</id>\r
+<i>\r
+<id>BD99BC</id>\r
+<X>1</X>\r
+<Y>0</Y>\r
+<Z>0</Z>\r
+</i>\r
+<j>\r
+<id>BD99FC</id>\r
+<X>0</X>\r
+<Y>1</Y>\r
+<Z>0</Z>\r
+</j>\r
+<k>\r
+<id>BD9A3C</id>\r
+<X>0</X>\r
+<Y>0</Y>\r
+<Z>1</Z>\r
+</k>\r
+</coordenadas>\r
+</objeto4>\r
+<objeto5 class=cMeteorito>\r
+<id>BD9BFC</id>\r
+<posicion>\r
+<id>BD9D30</id>\r
+<X>2000</X>\r
+<Y>-1000</Y>\r
+<Z>1000</Z>\r
+</posicion>\r
+<velocidad>0</velocidad>\r
+<potencia>5</potencia>\r
+<energia>20</energia>\r
+<dimension>5</dimension>\r
+<coordenadas>\r
+<id>BD9C44</id>\r
+<i>\r
+<id>BD9C70</id>\r
+<X>1</X>\r
+<Y>0</Y>\r
+<Z>0</Z>\r
+</i>\r
+<j>\r
+<id>BD9CB0</id>\r
+<X>0</X>\r
+<Y>1</Y>\r
+<Z>0</Z>\r
+</j>\r
+<k>\r
+<id>BD9CF0</id>\r
+<X>0</X>\r
+<Y>0</Y>\r
+<Z>1</Z>\r
+</k>\r
+</coordenadas>\r
+</objeto5>\r
+<objeto6 class=cMeteorito>\r
+<id>BD9EB0</id>\r
+<posicion>\r
+<id>BD9FE4</id>\r
+<X>2000</X>\r
+<Y>-1000</Y>\r
+<Z>-1000</Z>\r
+</posicion>\r
+<velocidad>0</velocidad>\r
+<potencia>5</potencia>\r
+<energia>20</energia>\r
+<dimension>5</dimension>\r
+<coordenadas>\r
+<id>BD9EF8</id>\r
+<i>\r
+<id>BD9F24</id>\r
+<X>1</X>\r
+<Y>0</Y>\r
+<Z>0</Z>\r
+</i>\r
+<j>\r
+<id>BD9F64</id>\r
+<X>0</X>\r
+<Y>1</Y>\r
+<Z>0</Z>\r
+</j>\r
+<k>\r
+<id>BD9FA4</id>\r
+<X>0</X>\r
+<Y>0</Y>\r
+<Z>1</Z>\r
+</k>\r
+</coordenadas>\r
+</objeto6>\r
+<objeto7 class=cMeteorito>\r
+<id>BDA164</id>\r
+<posicion>\r
+<id>BDA298</id>\r
+<X>2000</X>\r
+<Y>1000</Y>\r
+<Z>-1000</Z>\r
+</posicion>\r
+<velocidad>0</velocidad>\r
+<potencia>5</potencia>\r
+<energia>20</energia>\r
+<dimension>5</dimension>\r
+<coordenadas>\r
+<id>BDA1AC</id>\r
+<i>\r
+<id>BDA1D8</id>\r
+<X>1</X>\r
+<Y>0</Y>\r
+<Z>0</Z>\r
+</i>\r
+<j>\r
+<id>BDA218</id>\r
+<X>0</X>\r
+<Y>1</Y>\r
+<Z>0</Z>\r
+</j>\r
+<k>\r
+<id>BDA258</id>\r
+<X>0</X>\r
+<Y>0</Y>\r
+<Z>1</Z>\r
+</k>\r
+</coordenadas>\r
+</objeto7>\r
+<objeto8 class=cMeteorito>\r
+<id>BDA418</id>\r
+<posicion>\r
+<id>BDA54C</id>\r
+<X>-2000</X>\r
+<Y>1000</Y>\r
+<Z>1000</Z>\r
+</posicion>\r
+<velocidad>0</velocidad>\r
+<potencia>5</potencia>\r
+<energia>20</energia>\r
+<dimension>5</dimension>\r
+<coordenadas>\r
+<id>BDA460</id>\r
+<i>\r
+<id>BDA48C</id>\r
+<X>1</X>\r
+<Y>0</Y>\r
+<Z>0</Z>\r
+</i>\r
+<j>\r
+<id>BDA4CC</id>\r
+<X>0</X>\r
+<Y>1</Y>\r
+<Z>0</Z>\r
+</j>\r
+<k>\r
+<id>BDA50C</id>\r
+<X>0</X>\r
+<Y>0</Y>\r
+<Z>1</Z>\r
+</k>\r
+</coordenadas>\r
+</objeto8>\r
+<objeto9 class=cMeteorito>\r
+<id>BDA6CC</id>\r
+<posicion>\r
+<id>BDA800</id>\r
+<X>-2000</X>\r
+<Y>-1000</Y>\r
+<Z>1000</Z>\r
+</posicion>\r
+<velocidad>0</velocidad>\r
+<potencia>5</potencia>\r
+<energia>20</energia>\r
+<dimension>5</dimension>\r
+<coordenadas>\r
+<id>BDA714</id>\r
+<i>\r
+<id>BDA740</id>\r
+<X>1</X>\r
+<Y>0</Y>\r
+<Z>0</Z>\r
+</i>\r
+<j>\r
+<id>BDA780</id>\r
+<X>0</X>\r
+<Y>1</Y>\r
+<Z>0</Z>\r
+</j>\r
+<k>\r
+<id>BDA7C0</id>\r
+<X>0</X>\r
+<Y>0</Y>\r
+<Z>1</Z>\r
+</k>\r
+</coordenadas>\r
+</objeto9>\r
+<objeto10 class=cMeteorito>\r
+<id>BDA980</id>\r
+<posicion>\r
+<id>BDAAB4</id>\r
+<X>-2000</X>\r
+<Y>1000</Y>\r
+<Z>-1000</Z>\r
+</posicion>\r
+<velocidad>0</velocidad>\r
+<potencia>5</potencia>\r
+<energia>20</energia>\r
+<dimension>5</dimension>\r
+<coordenadas>\r
+<id>BDA9C8</id>\r
+<i>\r
+<id>BDA9F4</id>\r
+<X>1</X>\r
+<Y>0</Y>\r
+<Z>0</Z>\r
+</i>\r
+<j>\r
+<id>BDAA34</id>\r
+<X>0</X>\r
+<Y>1</Y>\r
+<Z>0</Z>\r
+</j>\r
+<k>\r
+<id>BDAA74</id>\r
+<X>0</X>\r
+<Y>0</Y>\r
+<Z>1</Z>\r
+</k>\r
+</coordenadas>\r
+</objeto10>\r
+<objeto11 class=cMeteorito>\r
+<id>BDAC34</id>\r
+<posicion>\r
+<id>BDAD68</id>\r
+<X>-2000</X>\r
+<Y>-1000</Y>\r
+<Z>-1000</Z>\r
+</posicion>\r
+<velocidad>0</velocidad>\r
+<potencia>5</potencia>\r
+<energia>20</energia>\r
+<dimension>5</dimension>\r
+<coordenadas>\r
+<id>BDAC7C</id>\r
+<i>\r
+<id>BDACA8</id>\r
+<X>1</X>\r
+<Y>0</Y>\r
+<Z>0</Z>\r
+</i>\r
+<j>\r
+<id>BDACE8</id>\r
+<X>0</X>\r
+<Y>1</Y>\r
+<Z>0</Z>\r
+</j>\r
+<k>\r
+<id>BDAD28</id>\r
+<X>0</X>\r
+<Y>0</Y>\r
+<Z>1</Z>\r
+</k>\r
+</coordenadas>\r
+</objeto11>\r
+</objetos>\r
+</eaw>
\ No newline at end of file
diff --git a/doc/AlgoWars.sdw b/doc/AlgoWars.sdw
new file mode 100644 (file)
index 0000000..541dd80
Binary files /dev/null and b/doc/AlgoWars.sdw differ
diff --git a/doc/CHANGES.TXT b/doc/CHANGES.TXT
new file mode 100644 (file)
index 0000000..0956903
--- /dev/null
@@ -0,0 +1,148 @@
+AlgoWars - Episodio IV\r
+======================\r
+\r
+Para mayor información visite: http://www.algowars.llucax.hn.org/\r
+\r
+CAMBIOS:\r
+--------\r
+\r
+v1.0.1.3:\r
+   * Se corrige un BUG que hacía que en ciertas situaciones no\r
+      se puedan cargar los gráficos de la aplicación y el\r
+      escenario por defecto.\r
+\r
+v1.0.0.0:\r
+   * Versión definitiva.\r
+   * Sólo se realiza una limpieza del código. No hay cambios en\r
+      la funcionalidad del programa.\r
+\r
+v0.9.9.1:\r
+   * Se cambió la vista de misil por una más general: la vista\r
+      de arma. Esta es igual que la del misil pero puede\r
+      verse con ella a través de cualquier arma con que se\r
+      dispare. Esta vista esta ahora implementada y funcionando\r
+      correctamente.\r
+   * Se agregó un Mapa. Este no es de gran ayuda ya que por ahora\r
+      muestra las mismas imágenes que el resto de las vistas, por\r
+      lo que se hace un poco confuso.\r
+   * Se cambian las teclas de atajo, quedando para las vistas las\r
+      teclas de función (F1, F2, F3, etc) y para el Mapa la 'M'.\r
+   * Se agrega una opción en el Menú Vista: Cambio Automático.\r
+      Cuando está activada, se cambia automáticamente a la vista\r
+      del arma una vez que se dispara. Está desactivada por\r
+      defecto.\r
+   * Se elimina el Menú Ayuda ya que en la versión final no se\r
+      incluirá ayuda en línea por falta de tiempo.\r
+\r
+v0.9.8.5:\r
+   * Se elimina el escenario por defecto del código fuente,\r
+      pasándolo a un archivo ('comun.eaw'). Se puede cambiar\r
+      este archivo fácilmente para usar otro escenario por\r
+      defecto. Si no se encuentra este archivo, se comienza\r
+      con un escenario vacío.\r
+   * Se agrega en el título de la ventana principal el nombre\r
+      de la cámara con la que se está observando actualmente.\r
+\r
+v0.9.8.3:\r
+   * Se agregaron 6 nuevas vistas: Lateral Izquierda, Lateral\r
+      Derecha, Superior, Inferior, Trasera y De Misil. Todas,\r
+      exceptuando la última, están implementadas y funcionando\r
+      correctamente.\r
+   * Se permite cambiar la calidad de la vista. En modo de Alta\r
+      Calidad (modo por defecto) los fondos negros de las imágenes\r
+      se ven transparentes, logrando un mejor efecto visual. Por\r
+      contrapartida, es probable que el desempeño del juego se\r
+      vea disminuida. Por lo tanto, si se tienen problemas de\r
+      desempeño, se recomienda desactivar esta opción del menú\r
+      Vista -> Alta Calidad.\r
+   * Se agregaron y modificaron menús, entre los que se encuentra\r
+      el nuevo menú Vista del cual se puede seleccionar la vista\r
+      preferida así como cambiar la calidad de la misma.\r
+   * Se corrigieron algunos BUGs. El más importante era uno que\r
+      permitía que la nave propia comience el juego con una\r
+      velocidad superior a la máxima permitida. También se\r
+      restringieron ciertas opciones en situaciones en las que no\r
+      tenían ningún sentido (por ejemplo guardar un juego antes de\r
+      que este se inicie).\r
+\r
+v0.8.2.0:\r
+   * Se agrega la funcionalidad del almacenamiento y recuperación\r
+      de un escenario, quedando implementadas las opciones\r
+      'Abrir...' y 'Guardar...' del submenú Escenario del menú\r
+      Archivo. Puede seleccionarse el nombre y la ubicación del\r
+      archivo a guardar. El formato es prácticamente idéntico que\r
+      el del almacenamiento de un juego.\r
+\r
+v0.8.0.0:\r
+   * Se agrega la funcionalidad del almacenamiento y recuperación\r
+      de un juego, quedando implementadas las opciones 'Abrir...'\r
+      y 'Guardar...' del menú Archivo. Puede seleccionarse el\r
+      nombre y la ubicación del archivo a guardar.\r
+   * Se opta por un formato similar al XML para almacenar los\r
+      juegos. De esta manera se puede editar un juego guardado\r
+      con cualquier editor de textos y de una forma que resulta\r
+      muy familiar para la gente que este familiarizada con XML\r
+      e incluso con HTML. A pesar de esto es formato de los\r
+      archivos es más restringido. Entre estas restricciones se\r
+      encuentra que distingue entre mayúsculas y minúsculas y que\r
+      el orden de los TAG tiene importancia.\r
+   * Ya se encuentra disponible una versión preeliminar del Manual\r
+      de Usuario, aunque aún no está del todo completo.\r
+\r
+v0.6.0.3:\r
+   * Se termina de implementar los disparos. La nave del jugador\r
+      puede disparar lásers, misiles y misiles teledirigidos,\r
+      pudiendo seleccionar previamente el objetivo.\r
+      Las nuevas teclas para disparos son:\r
+         W: Selecciona el arma siguiente (con municiones)\r
+         S: Dispara\r
+         T: Selecciona el objetivo\r
+   * Se logro una notable mejora de el desempeño general del\r
+      juego. (ahora es notablemente más dinámico)\r
+   * Se agregaron más indicadores en la pantalla: Arma Actual.\r
+      Este indicador además muestra si el arma seleccionada está\r
+      está lista para disparar (en color verde) o si se está \r
+      recargando (en color rojo).\r
+   * Se agregaron nuevos gráficos para mostrar las naves lockeadas\r
+      así que el sistema de locking también es personalizable a\r
+      nivel de gráficos.\r
+   * Se mejoraron los gráficos utilizando transparencias. Ahora el\r
+      fondo negro de los bitmaps se muestra transparente.\r
+      (En el fututo se incluirá la opción para dejarlo sin\r
+      transparencias, ya que esto baja un poco el desempeño del\r
+      juego).\r
+\r
+v0.5.5.1:\r
+   * Se agregaron indicadores en la pantalla (Energía,\r
+      Velocidad, Misiles y Misiles Dirigidos).\r
+   * Las Naves Enemigas ya pueden disparar. La nave del jugador\r
+      todavía no.\r
+   * Se agregaron más menús pero todavía no se implementó\r
+      su funcionalidad.\r
+   * Se agregaron 2 nuevos movimientos para rotar la nave,\r
+      con las teclas 'U' y 'O'.\r
+   * Se mejoraron los gráficos.\r
+   * Se compiló sin símbolos para debug logrando que disminuya\r
+      el ejecutable a menos de una tercera parte del anterior.\r
+\r
+v0.4.4.1:\r
+   * Se corrigieron algunos BUGs.\r
+\r
+v0.4.2.1:\r
+   * Se corrigieron algunos BUGs.\r
+\r
+v0.4.0.0:\r
+   * Primera versión Pública.\r
+   * Solamente se puede recorrer el espacio, con movimientos\r
+      básicos:\r
+         I: Arriba\r
+         K: Abajo\r
+         L: Derecha\r
+         J: Izquierda\r
+         Q: Acelerar\r
+         A: Desacelerar\r
+   * Posibilidad de configurar el escenario: Opciones -> Configurar\r
+   * Gráficos personalizables. Se pueden cambiar los gráficos de las\r
+      naves muy fácilmente, reemplazando los bitmaps del directorio\r
+      'bitmaps'.\r
+   * Tiene muchos errores.\r
diff --git a/doc/HISTORY.TXT b/doc/HISTORY.TXT
new file mode 100644 (file)
index 0000000..7ca64d8
--- /dev/null
@@ -0,0 +1,113 @@
+\r
+UNIVERSIDAD DE BUENOS AIRES - Facultad de Ingeniería\r
+~~~~~~~~~~~~~~~~~~~~~~~~~~~   ======================\r
+\r
+  +-------------------------------+\r
+  | ALGORITMOS Y PROGRAMACIÓN III |  2do cuatrimestre de 2000\r
+  +-------------------------------+\r
+\r
+\r
+Cátedra: Ing. Carlos Fontela\r
+=======\r
+\r
+Grupo: 10\r
+-----\r
+\r
+ALGOWARS - Episodio IV \r
+======================\r
+\r
+Para mayor información visite: http://www.algowars.llucax.hn.org/\r
+\r
+Cambios realizados:\r
+------------------\r
+\r
+05/10/00: Se terminaron de realizar algunos cambios en las clases cNavePropia,\r
+          cEspacio, cNaveEnemiga y cObjetoVolador. Se les agregó, modificó y\r
+          reemplazó algunos métodos (documentado en cada unidad en particular).\r
+          Se empezó a migrar los comentarios del código fuente para hacerlo\r
+          compatible con DelphiDoc (una herramienta similar al JavaDoc pero\r
+          para Delphi que permite generar automáticamente documentación a\r
+          partir de los comentarios en el código fuente).\r
+          Se reestructuró el proyecto en diferentes directorios para simplificar\r
+          el desarrollo. La nueva estructura es la siguiente:\r
+           ---------------\r
+              algowars\                        Directorio con el proyecto entero\r
+              algowars\HISTORIA.TXT            Este documento\r
+              algowars\bin                     Binarios ejecutables compilados\r
+              algowars\dcu                     Unidades compiladas\r
+              algowars\doc                     Documentación del proyecto en gral.\r
+              algowars\doc\uml                 Diagramas UML\r
+              algowars\doc\ref                 Referencia de las clases del proyecto\r
+                                                (y sus métodos) en formato HTML\r
+                                                Generada con DelphiDoc\r
+                                                (http://www.softconsult.se)\r
+              algowars\src                     Código fuente general\r
+              algowars\src\test                Proyectos temporales que fueron\r
+                                                utilizados para probar las unidades\r
+              algowars\src\ov                  Unidad que contiene cObjetoVolador y\r
+                                                sus subclases\r
+              algowars\src\ov\naves            Unidad que contiene cNave y sus\r
+                                                subclases\r
+           ---------------\r
\r
+01/11/00: Se realizaron cambios profundos en el modelo, como el agregado de un\r
+          sistema de coordenadas a todos los objetos voladores.\r
+          También se cambiaron TODOS los métodos mGetXxxx para que devuelvan una\r
+          copia del atributo porque de otra manera se esta violando, en parte,\r
+          el encapsulamiento, ya que al devolver un puntero al atributo, en\r
+          definitiva estamos permitiendo acceso a la estructura interna del\r
+          objeto. Un claro ejemplo de los problemas que traía esa\r
+          implementación es el problema que trajo el cambio de la estructura\r
+          interna de cObjetoVolador, ya que para mantener la "interfaz" intacta,\r
+          se tuvo que simular la existencia de un atributo que no existía mas,\r
+          devolviendo un puntero a un objeto nuevo que luego nunca se liberaba.\r
+10/11/00: Se agrega un condicional para el preprocesador del compilador, para que\r
+          si no se compila como una versión de DEBUG, que no utilice el objeto\r
+          cObjeto y por consiguiente, su método abstracto mGetDebugInfo.\r
+02/12/00: Se terminó de implementar los disparos. Entre los cambios principales\r
+          están los siguientes:\r
+          Se separó la funcionalidad de la cámara en una clase nueva: cFiltro.\r
+          La cámara tiene un atributo cFiltro que se encarga de filtrar los \r
+          objetos que se pueden ver.\r
+          Se reutiliza la clase cFiltro para implementar el sistema de lockeo de\r
+          la cNavePropia. Para hacer esto se hizo una subclase que también filtra\r
+          las armas.\r
+          Se separó la clase auxiliar cLista en su propia unidad.\r
+04/12/00: Se creo una clase abstracta cObjetoPersistente de la cual derivarán\r
+          todas las demás clases que soportan persistencia. Esta clase provee un\r
+          identificador único de la clase y métodos para serializar y deserializar\r
+          las clases. La serialización se realiza representando el objeto en una\r
+          cadena de texto con un formato parecido al XML (con el que cualquier\r
+          persona que conozca XML o incluso HTML se va a sentir familiarizado).\r
+          Para hacer esto se hace un uso muy importante de expresiones regulares,\r
+          utilizando la clase TRegExpr (externa).\r
+08/12/00: Se termina de implementar la persistencia. Para lograr esto, además de\r
+          implementarse los métodos mSerializar y mDesSerializar en todas las\r
+          clases que son ahora persistentes, se agregaron algunos métodos auxiliares\r
+          y una nueva unidad con funciones útiles para el manejo de persistencia\r
+          (SerializacionUtils). Los métodos auxiliares se limitaron a ser métodos\r
+          para acceder y establecer atributos.\r
+          También se implementa el almacenamiento de escenarios (configuración\r
+          inicial del juego) de una forma prácticamente idéntica a la del\r
+          almacenamiento de un juego.\r
+          Se cambian las clases cCamara y cFiltro para que sean abstractas. Las\r
+          clases que se utilizan ahora derivan de estas. Se implementan variantes\r
+          de la cámara y filtro frontal, para crear cámaras que "vean" lateralmente,\r
+          arriba, abajo, etc. Siempre como subclases de cCamara y cFiltro.\r
+          Se cambia la clase cVista para que soporte cámaras múltiples. Para esto\r
+          se agrega un array de cámaras.\r
+09/12/00: Se termina de implementar las vistas, creando dos nuevas clases:\r
+          cCamaraMapa y cFiltroMapa. Además se hacen algunos cambios internos a la\r
+          clase cNavePropia para poder obtener el arma recién disparada sobre la que\r
+          se monta la cámara del Arma.\r
+          Se reorganiza el proyecto en una nueva serie de directorios:\r
+            algowars/src/vista         Tiene las clases que implementan las vistas\r
+            algowars/src/modelo        Tiene las clases que implementan el modelo\r
+            algowars/src/forms         Tiene las clases que implementan los formularios\r
+            algowars/src/auxiliares    Tiene las clases auxiliares\r
+            algowars/src/test          Tiene proyectos utilizados para pruebas del\r
+                                        programa.\r
+            algowars/src/test/cb       Tiene proyectos y clases auxiliares para pruebas\r
+                                        de caja blanca específicamente.\r
+            algowars/src/test/cn       Tiene proyectos y clases auxiliares para pruebas\r
+                                        de caja negra específicamente.\r
diff --git a/doc/LICENCIA_GPL.TXT b/doc/LICENCIA_GPL.TXT
new file mode 100644 (file)
index 0000000..f28a1fe
--- /dev/null
@@ -0,0 +1,277 @@
+\r
+                   Licencia Pública GNU (General Public Licence GPL)\r
+\r
+      Preámbulo\r
+\r
+      Las licencias que cubren la mayor parte del software están diseñadas para \r
+      quitarle a usted la libertad de compartirlo y modificarlo. Por el \r
+      contrario, la Licencia Pública General de GNU pretende garantizarle la \r
+      libertad de compartir y modificar software libre, para asegurar que el \r
+      software es libre para todos sus usuarios. Esta Licencia Pública General \r
+      se aplica a la mayor parte del software del la Free Software Foundation y \r
+      a cualquier otro programa si sus autores se comprometen a utilizarla. \r
+      (Existe otro software de la Free Software Foundation que está cubierto por \r
+      la Licencia Pública General de GNU para Bibliotecas). Si quiere, también \r
+      puede aplicarla a sus propios programas.\r
+       \r
+      Cuando hablamos de software libre, estamos refiriéndonos a libertad, no a \r
+      precio. Nuestras Licencias Públicas Generales están diseñadas para \r
+      asegurarnos de que tenga la libertad de distribuir copias de software \r
+      libre (y cobrar por ese servicio si quiere), de que reciba el código \r
+      fuente o que pueda conseguirlo si lo quiere, de que pueda modificar el \r
+      software o usar fragmentos de él en nuevos programas libres, y de que sepa \r
+      que puede hacer todas estas cosas.\r
+        \r
+      Para proteger sus derechos necesitamos algunas restricciones que prohiban \r
+      a cualquiera negarle a usted estos derechos o pedirle que renuncie a \r
+      ellos. Estas restricciones se traducen en ciertas obligaciones que le \r
+      afectan si distribuye copias del software, o si lo modifica.\r
+       \r
+      Por ejemplo, si distribuye copias de uno de estos programas, sea \r
+      gratuitamente, o a cambio de una contraprestación, debe dar a los \r
+      receptores todos los derechos que tiene. Debe asegurarse de que ellos \r
+      también reciben, o pueden conseguir, el código fuente. Y debe mostrarles \r
+      estas condiciones de forma que conozcan sus derechos.\r
+       \r
+      Protegemos sus derechos con la combinación de dos medidas:\r
+        \r
+\r
+        Ponemos el software bajo copyright \r
+        le ofrecemos esta licencia, que le da permiso legal para copiar, \r
+        distribuir y/o modificar el software. \r
+      También, para la protección de cada autor y la nuestra propia, queremos \r
+      asegurarnos de que todo el mundo comprende que no se proporciona ninguna \r
+      garantía para este software libre. Si el software se modifica por \r
+      cualquiera y éste a su vez lo distribuye, queremos que sus receptores \r
+      sepan que lo que tienen no es el original, de forma que cualquier problema \r
+      introducido por otros no afecte a la reputación de los autores originales.\r
+       \r
+      Por último, cualquier programa libre está constantemente amenazado por \r
+      patentes sobre el software. Queremos evitar el peligro de que los \r
+      redistribuidores de un programa libre obtengan patentes por su cuenta, \r
+      convirtiendo de facto el programa en propietario. Para evitar esto, hemos \r
+      dejado claro que cualquier patente debe ser pedida para el uso libre de \r
+      cualquiera, o no ser pedida.\r
+       \r
+      Los términos exactos y las condiciones para la copia, distribución y \r
+      modificación se exponen a continuación. \r
+      Términos y condiciones para la copia, distribución y modificación\r
+        Esta Licencia se aplica a cualquier programa u otro tipo de trabajo que \r
+        contenga una nota colocada por el tenedor del copyright diciendo que \r
+        puede ser distribuido bajo los términos de esta Licencia Pública \r
+        General. En adelante, «Programa» se referirá a cualquier programa o \r
+        trabajo que cumpla esa condición y «trabajo basado en el Programa» se \r
+        referirá bien al Programa o a cualquier trabajo derivado de él según la \r
+        ley de copyright. Esto es, un trabajo que contenga el programa o una \r
+        proción de él, bien en forma literal o con modificaciones y/o traducido \r
+        en otro lenguaje. Por lo tanto, la traducción está incluida sin \r
+        limitaciones en el término «modificación». Cada concesionario \r
+        (licenciatario) será denominado «usted».\r
+         \r
+        Cualquier otra actividad que no sea la copia, distribución o \r
+        modificación no está cubierta por esta Licencia, está fuera de su \r
+        ámbito. El acto de ejecutar el Programa no está restringido, y los \r
+        resultados del Programa están cubiertos únicamente si sus contenidos \r
+        constituyen un trabajo basado en el Programa, independientemente de \r
+        haberlo producido mediante la ejecución del programa. El que esto se \r
+        cumpla, depende de lo que haga el programa. \r
+        Usted puede copiar y distribuir copias literales del código fuente del \r
+        Programa, según lo has recibido, en cualquier medio, supuesto que de \r
+        forma adecuada y bien visible publique en cada copia un anuncio de \r
+        copyright adecuado y un repudio de garantía, mantenga intactos todos los \r
+        anuncios que se refieran a esta Licencia y a la ausencia de garantía, y \r
+        proporcione a cualquier otro receptor del programa una copia de esta \r
+        Licencia junto con el Programa.\r
+         \r
+        Puede cobrar un precio por el acto físico de transferir una copia, y \r
+        puede, según su libre albedrío, ofrecer garantía a cambio de unos \r
+        honorarios. \r
+        Puede modificar su copia o copias del Programa o de cualquier porción de \r
+        él, formando de esta manera un trabajo basado en el Programa, y copiar y \r
+        distribuir esa modificación o trabajo bajo los términos del apartado 1, \r
+        antedicho, supuesto que además cumpla las siguientes condiciones: \r
+          Debe hacer que los ficheros modificados lleven anuncios prominentes \r
+          indicando que los ha cambiado y la fecha de cualquier cambio. \r
+          Debe hacer que cualquier trabajo que distribuya o publique y que en \r
+          todo o en parte contenga o sea derivado del Programa o de cualquier \r
+          parte de él sea licenciada como un todo, sin carga alguna, a todas las \r
+          terceras partes y bajo los términos de esta Licencia. \r
+          Si el programa modificado lee normalmente órdenes interactivamente \r
+          cuando es ejecutado, debe hacer que, cuando comience su ejecución para \r
+          ese uso interactivo de la forma más habitual, muestre o escriba un \r
+          mensaje que incluya un anuncio de copyright y un anuncio de que no se \r
+          ofrece ninguna garantía (o por el contrario que sí se ofrece garantía) \r
+          y que los usuarios pueden redistribuir el programa bajo estas \r
+          condiciones, e indicando al usuario cómo ver una copia de esta \r
+          licencia. (Excepción: si el propio programa es interactivo pero \r
+          normalmente no muestra ese anuncio, no se requiere que su trabajo \r
+          basado en el Programa muestre ningún anuncio). \r
+        Estos requisitos se aplican al trabajo modificado como un todo. Si \r
+        partes identificables de ese trabajo no son derivadas del Programa, y \r
+        pueden, razonablemente, ser consideradas trabajos independientes y \r
+        separados por ellos mismos, entonces esta Licencia y sus términos no se \r
+        aplican a esas partes cuando sean distribuidas como trabajos separados. \r
+        Pero cuando distribuya esas mismas secciones como partes de un todo que \r
+        es un trabajo basado en el Programa, la distribución del todo debe ser \r
+        según los términos de esta licencia, cuyos permisos para otros \r
+        licenciatarios se extienden al todo completo, y por lo tanto a todas y \r
+        cada una de sus partes, con independencia de quién la escribió.\r
+         \r
+        Por lo tanto, no es la intención de este apartado reclamar derechos o \r
+        desafiar sus derechos sobre trabajos escritos totalmente por usted \r
+        mismo. El intento es ejercer el derecho a controlar la distribución de \r
+        trabajos derivados o colectivos basados en el Programa.\r
+         \r
+        Además, el simple hecho de reunir un trabajo no basado en el Programa \r
+        con el Programa (o con un trabajo basado en el Programa) en un volumen \r
+        de almacenamiento o en un medio de distribución no hace que dicho \r
+        trabajo entre dentro del ámbito cubierto por esta Licencia. \r
+         \r
+\r
+        Puede copiar y distribuir el Programa (o un trabajo basado en él, según \r
+        se especifica en el apartado 2, como código objeto o en formato \r
+        ejecutable según los términos de los apartados 1 y 2, supuesto que \r
+        además cumpla una de las siguientes condiciones: \r
+          Acompañarlo con el código fuente completo correspondiente, en formato \r
+          electrónico, que debe ser distribuido según se especifica en los \r
+          apartados 1 y 2 de esta Licencia en un medio habitualmente utilizado \r
+          para el intercambio de programas, o \r
+          Acompañarlo con una oferta por escrito, válida durante al menos tres \r
+          años, de proporcionar a cualquier tercera parte una copia completa en \r
+          formato electrónico del código fuente correspondiente, a un coste no \r
+          mayor que el de realizar físicamente la distribución del fuente, que \r
+          será distribuido bajo las condiciones descritas en los apartados 1 y 2 \r
+          anteriores, en un medio habitualmente utilizado para el intercambio de \r
+          programas, o \r
+          Acompañarlo con la información que recibiste ofreciendo distribuir el \r
+          código fuente correspondiente. (Esta opción se permite sólo para \r
+          distribución no comercial y sólo si usted recibió el programa como \r
+          código objeto o en formato ejecutable con tal oferta, de acuerdo con \r
+          el apartado b anterior). \r
+        Por código fuente de un trabajo se entiende la forma preferida del \r
+        trabajo cuando se le hacen modificaciones. Para un trabajo ejecutable, \r
+        se entiende por código fuente completo todo el código fuente para todos \r
+        los módulos que contiene, más cualquier fichero asociado de definición \r
+        de interfaces, más los guiones utilizados para controlar la compilación \r
+        e instalación del ejecutable.\r
+         \r
+        Como excepción especial el código fuente distribuido no necesita incluir \r
+        nada que sea distribuido normalmente (bien como fuente, bien en forma \r
+        binaria) con los componentes principales (compilador, kernel y \r
+        similares) del sistema operativo en el cual funciona el ejecutable, a no \r
+        ser que el propio componente acompañe al ejecutable.\r
+         \r
+        Si la distribución del ejecutable o del código objeto se hace mediante \r
+        la oferta acceso para copiarlo de un cierto lugar, entonces se considera \r
+        la oferta de acceso para copiar el código fuente del mismo lugar como \r
+        distribución del código fuente, incluso aunque terceras partes no estén \r
+        forzadas a copiar el fuente junto con el código objeto.\r
+         \r
+        No puede copiar, modificar, sublicenciar o distribuir el Programa \r
+        excepto como prevé expresamente esta Licencia. Cualquier intento de \r
+        copiar, modificar sublicenciar o distribuir el Programa de otra forma es \r
+        inválida, y hará que cesen automáticamente los derechos que te \r
+        proporciona esta Licencia. En cualquier caso, las partes que hayan \r
+        recibido copias o derechos de usted bajo esta Licencia no cesarán en sus \r
+        derechos mientras esas partes continúen cumpliéndola. \r
+        No está obligado a aceptar esta licencia, ya que no la ha firmado. Sin \r
+        embargo, no hay hada más que le proporcione permiso para modificar o \r
+        distribuir el Programa o sus trabajos derivados. Estas acciones están \r
+        prohibidas por la ley si no acepta esta Licencia. Por lo tanto, si \r
+        modifica o distribuye el Programa (o cualquier trabajo basado en el \r
+        Programa), está indicando que acepta esta Licencia para poder hacerlo, y \r
+        todos sus términos y condiciones para copiar, distribuir o modificar el \r
+        Programa o trabajos basados en él. \r
+        Cada vez que redistribuya el Programa (o cualquier trabajo basado en el \r
+        Programa), el receptor recibe automáticamente una licencia del \r
+        licenciatario original para copiar, distribuir o modificar el Programa, \r
+        de forma sujeta a estos términos y condiciones. No puede imponer al \r
+        receptor ninguna restricción más sobre el ejercicio de los derechos aquí \r
+        garantizados. No es usted responsable de hacer cumplir esta licencia por \r
+        terceras partes. \r
+        Si como consecuencia de una resolución judicial o de una alegación de \r
+        infracción de patente o por cualquier otra razón (no limitada a asuntos \r
+        relacionados con patentes) se le imponen condiciones (ya sea por mandato \r
+        judicial, por acuerdo o por cualquier otra causa) que contradigan las \r
+        condiciones de esta Licencia, ello no le exime de cumplir las \r
+        condiciones de esta Licencia. Si no puede realizar distribuciones de \r
+        forma que se satisfagan simultáneamente sus obligaciones bajo esta \r
+        licencia y cualquier otra obligación pertinente entonces, como \r
+        consecuencia, no puede distribuir el Programa de ninguna forma. Por \r
+        ejemplo, si una patente no permite la redistribución libre de derechos \r
+        de autor del Programa por parte de todos aquellos que reciban copias \r
+        directa o indirectamente a través de usted, entonces la única forma en \r
+        que podría satisfacer tanto esa condición como esta Licencia sería \r
+        evitar completamente la distribución del Programa.\r
+         \r
+        Si cualquier porción de este apartado se considera inválida o imposible \r
+        de cumplir bajo cualquier circunstancia particular ha de cumplirse el \r
+        resto y la sección por entero ha de cumplirse en cualquier otra \r
+        circunstancia.\r
+         \r
+        No es el propósito de este apartado inducirle a infringir ninguna \r
+        reivindicación de patente ni de ningún otro derecho deç propiedad o \r
+        impugnar la validez de ninguna de dichas reivindicaciones. Este apartado \r
+        tiene el único propósito de proteger la integridad del sistema de \r
+        distribución de software libre, que se realiza mediante prácticas de \r
+        licencia pública. Mucha gente ha hecho contribuciones generosas a la \r
+        gran variedad de software distribuido mediante ese sistema con la \r
+        confianza de que el sistema se aplicará consistentemente. Será el \r
+        autor/donante quien decida si quiere distribuir software mediante \r
+        cualquier otro sistema y una licencia no puede imponer esa elección.\r
+         \r
+        Este apartado pretende dejar completamente claro lo que se cree que es \r
+        una consecuencia del resto de esta Licencia. \r
+        Si la distribución y/o uso de el Programa está restringida en ciertos \r
+        países, bien por patentes o por interfaces bajo copyright, el tenedor \r
+        del copyright que coloca este Programa bajo esta Licencia puede añadir \r
+        una limitación explícita de distribución geográfica excluyendo esos \r
+        países, de forma que la distribución se permita sólo en o entre los \r
+        países no excluidos de esta manera. En ese caso, esta Licencia \r
+        incorporará la limitación como si estuviese escrita en el cuerpo de esta \r
+        Licencia. \r
+        La Free Software Foundation puede publicar versiones revisadas y/o \r
+        nuevas de la Licencia Pública General de tiempo en tiempo. Dichas nuevas \r
+        versiones serán similares en espíritu a la presente versión, pero pueden \r
+        ser diferentes en detalles para considerar nuevos problemas o \r
+        situaciones.\r
+        &nbps;\r
+        Cada versión recibe un número de versión que la distingue de otras. Si \r
+        el Programa especifica un número de versión de esta Licencia que se \r
+        refiere a ella y a «cualquier versión posterior», tienes la opción de \r
+        seguir los términos y condiciones, bien de esa versión, bien de \r
+        cualquier versión posterior publicada por la Free Software Foundation. \r
+        Si el Programa no especifica un número de versión de esta Licencia, \r
+        puedes escoger cualquier versión publicada por la Free Software \r
+        Foundation. \r
+        Si quiere incorporar partes del Programa en otros programas libres cuyas \r
+        condiciones de distribución son diferentes, escribe al autor para \r
+        pedirle permiso. Si el software tiene copyright de la Free Software \r
+        Foundation, escribe a la Free Software Foundation: algunas veces hacemos \r
+        excepciones en estos casos. Nuestra decisión estará guiada por el doble \r
+        objetivo de de preservar la libertad de todos los derivados de nuestro \r
+        software libre y promover el que se comparta y reutilice el software en \r
+        general. \r
+\r
+      AUSENCIA DE GARANTÍA\r
+        Como el programa se licencia libre de cargas, no se ofrece ninguna \r
+        garantía sobre el programa, en todas la extensión permitida por la \r
+        legislación aplicable. Excepto cuando se indique de otra forma por \r
+        escrito, los tenedores del copyright y/u otras partes proporcionan el \r
+        programa «tal cual», sin garantía de ninguna clase, bien expresa o \r
+        implícita, con inclusión, pero sin limitación a las garantías \r
+        mercantiles implícitas o a la conveniencia para un propósito particular. \r
+        Cualquier riesgo referente a la calidad y prestaciones del programa es \r
+        asumido por usted. Si se probase que el Programa es defectuoso, asume el \r
+        coste de cualquier servicio, reparación o corrección. \r
+        En ningún caso, salvo que lo requiera la legislaciónç aplicable o haya \r
+        sido acordado por escrito, ningún tenedor del copyright ni ninguna otra \r
+        parte que modifique y/o redistribuya el Programa según se permite en \r
+        esta Licencia será responsable ante usted por daños, incluyendo \r
+        cualquier daño general, especial, incidental o resultante producido por \r
+        el uso o la imposibilidad de uso del Programa (con inclusión, pero sin \r
+        limitación a la pérdida de datos o a la generación incorrecta de datos o \r
+        a pérdidas sufridas por usted o por terceras partes o a un fallo del \r
+        Programa al funcionar en combinación con cualquier otro programa), \r
+        incluso si dicho tenedor u otra parte ha sido advertido de la \r
+        posibilidad de dichos daños. \r
diff --git a/doc/Manual.sxw b/doc/Manual.sxw
new file mode 100644 (file)
index 0000000..35c30cb
Binary files /dev/null and b/doc/Manual.sxw differ
diff --git a/doc/README b/doc/README
new file mode 100644 (file)
index 0000000..9b93c0e
--- /dev/null
@@ -0,0 +1,51 @@
+\r
+UNIVERSIDAD DE BUENOS AIRES - Facultad de Ingeniería\r
+~~~~~~~~~~~~~~~~~~~~~~~~~~~   ======================\r
+\r
+  +-------------------------------+\r
+  | ALGORITMOS Y PROGRAMACIÓN III |  2do cuatrimestre de 2000\r
+  +-------------------------------+\r
+\r
+\r
+Cátedra: Ing. Carlos Fontela\r
+=======\r
+\r
+Grupo: 10\r
+-----\r
+\r
+ALGOWARS - Episodio IV \r
+======================\r
+\r
+Para mayor información visite: http://www.algowars.2y.net\r
+\r
+El Proyecto está distribuido en los siguientes directorios:\r
+----------------------------------------------------------\r
+\r
+  algowars\                     Directorio raiz del proyecto\r
+  algowars\README.TXT           Este documento\r
+  algowars\bin                  Binarios ejecutables compilados\r
+  algowars\doc\CHANGES.TXT      Cambios en el proyecto (para usuarios)\r
+  algowars\dcu                  Unidades compiladas\r
+  algowars\doc                  Documentación del proyecto en gral.\r
+  algowars\doc\HISTORIA.TXT     Cambios en el proyecto (para desarrolladores)\r
+  algowars\doc\uml              Diagramas UML\r
+  algowars\doc\ref              Referencia de las clases del proyecto\r
+                                 (y sus métodos) en formato HTML Generada con\r
+                                 DelphiDoc (http://www.softconsult.se)\r
+  algowars\doc\src-html         Código fuente en formato HTML para visualizar\r
+                                 más fácilmente\r
+  algowars\src                  Código fuente general\r
+  algowars\src\vista            Tiene las clases que implementan las vistas\r
+  algowars\src\modelo           Tiene las clases que implementan el modelo\r
+  algowars\src\modelo\ov        Unidad que contiene cObjetoVolador y\r
+                                 sus subclases\r
+  algowars\src\ov\modelo\naves  Unidad que contiene cNave y sus\r
+                                 subclases\r
+  algowars\src\forms            Tiene las clases que implementan los formularios\r
+  algowars\src\auxiliares       Tiene las clases auxiliares\r
+  algowars\src\test             Tiene proyectos utilizados para pruebas del\r
+                                 programa.\r
+  algowars\src\test\cb          Tiene proyectos y clases auxiliares para pruebas\r
+                                 de caja blanca específicamente.\r
+  algowars\src\test\cn          Tiene proyectos y clases auxiliares para pruebas\r
+                                 de caja negra específicamente.\r
diff --git a/doc/consigna.sxw b/doc/consigna.sxw
new file mode 100644 (file)
index 0000000..ddfb583
Binary files /dev/null and b/doc/consigna.sxw differ
diff --git a/doc/ref/Armas.html b/doc/ref/Armas.html
new file mode 100644 (file)
index 0000000..d9ee41e
--- /dev/null
@@ -0,0 +1,50 @@
+<HTML>\r
+<H2>Unit: Armas</H2>\r
+<B>Description:</B><BR>Contiene las armas que pueden ser usadas por las diferentes naves.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    10/11/00: Se agrega el manejo de excepciones para evitar un BUG en cMisilDirigido. Si el objetivo del misil\r
+              dirigido es destruido, la velocidad permanece constante y en mGetDebugInfo se informa que esta destruido.\r
+    27/11/00: Se le agrega el manejo de la velocidad maxima a la clase cArma y se agrega el Alcance del arma, cambiando\r
+              el anterior por la Duracion.\r
+    01/12/00: Se cambiaron las dimensiones de las armas para que los disparos sean mas "jugables".\r
+    </PRE><BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=cArma.html>cArma</A>\r
+: La clase cArma esta pensada como una clase abtracta. En ella se encuentran\r
+      características comunes a todas las armas.<BR>\r
+<A HREF=cLaser.html>cLaser</A>\r
+: El laser es un tipo de arma básica. Es la que menos daño hace pero la que más rápido viaja<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión      0,1       metros (10 cm)\r
+      Potencia:      1         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:       1         Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad:     0,4       metros/milisegundos (1440 km/h)\r
+      Alcance:       3000      milisegundos (3 segundos, 1,2 km)\r
+      </PRE><BR>\r
+<A HREF=cMisil.html>cMisil</A>\r
+: El misil es un tipo de arma básica. Hace un daño considerable y su velocidad también es alta<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión      0,5       metros (50 cm)\r
+      Potencia:      20        Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:       1         Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad:     0,3       metros/milisegundos (1080 km/h)\r
+      Alcance:       5000      milisegundos (5 segundos, 1,5 km)\r
+      </PRE><BR>\r
+<A HREF=cMisilDirigido.html>cMisilDirigido</A>\r
+: El misil dirigido es un tipo de arma avanzada. Persigue a su objetivo hasta que lo alcanza o\r
+      hasta que se le acaba el alcance. Hace un daño alto, su velocidad es mediana y tiene un gran alcance.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión      0,7       metros (70 cm)\r
+      Potencia:      30        Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:       1         Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad:     0,25      metros/milisegundos (900 km/h)\r
+      Alcance:       20000     milisegundos (20 segundos, 5 km)\r
+      Area de Lock:  2000      metros (2 km)\r
+      </PRE><BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/Camara.html b/doc/ref/Camara.html
new file mode 100644 (file)
index 0000000..1748417
--- /dev/null
@@ -0,0 +1,32 @@
+<HTML>\r
+<H2>Unit: Camara</H2>\r
+<B>Description:</B><BR>Implementa una cámara que se encarga de representar los objetos en 2D.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    10/11/00: Se agrega el manejo de excepciones para evitar usar la camara cuando el cameraman fue destruido.\r
+              Para lograr esto se crea una excepcion (ECameramanDestruido) que se lanza cuando hay una excepcion\r
+              de violacion de acceso a memoria. Esta excepcion debe ser manejada por quien meneje la camara y puede\r
+              ser lanzada por mGetDebugInfo o mProyectar.\r
+    01/12/00: Se elimina el atributo aApertura porque era absolutamente inecesario.\r
+              Se cambia la estructura interna para que el filtrado de los objetos los realice un cFiltro.\r
+    07/12/00: Se agregan nuevos métodos (protegidos) para obtener información de la cámara para poder crear subclases,\r
+              para lo cual tambien se hace virtual el método mProyectar.\r
+    08/12/00: Se quita el método para setear el filtro y se agrega un contructor que admite un filtro para reemplazarlo.\r
+              Se cambia esta clase para que sea abstracta. Se deja la implementacion del método mProyectar para las\r
+              subclases exlusivamente ya que ahora es abstracto. La cámara frontal (que antes se implementaba en\r
+              esta unidad), ahora está implementado la unidad Camaras al igual que el resto.\r
+    </PRE><BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=cCamara.html>cCamara</A>\r
+: Implementa una cámara que se encarga de representar los objetos en 2D.<BR>\r
+<A HREF=ECameramanDestruido.html>ECameramanDestruido</A>\r
+: Excepcion producida por la cámara si se utiliza cuando el cameraman fue destruido<BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+<A NAME=listSort></A>\r
+<dt><IMG SRC=functions_big.gif><code> function listSort( item1, item2: pointer ): integer;</code></dt>\r
+<dd>Funcion para ordenar los elementos de la lista que se devuelve\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>item1 </CODE> : Item a comparar (puntero)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>item2 </CODE> : Item a comparar (puntero)</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;<b>1</b> si item1 > item2<br>&nbsp;&nbsp;&nbsp;\r
+                  <b>-1</b> si item1 < item2<br>&nbsp;&nbsp;&nbsp;\r
+                  <b>0</b> si item1 = item2</dd><p>\r
+</dl></HTML>\r
diff --git a/doc/ref/Camaras.html b/doc/ref/Camaras.html
new file mode 100644 (file)
index 0000000..f591e4b
--- /dev/null
@@ -0,0 +1,26 @@
+<HTML>\r
+<H2>Unit: Camaras</H2>\r
+<B>Description:</B><BR>Se implementan varias cámaras en diferentes direcciones.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    09/12/00: Se agrega la clase cCamaraMapa.\r
+    </PRE><BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=cCamaraAbajo.html>cCamaraAbajo</A>\r
+: Implementa una cámara para ver hacia abajo.<BR>\r
+<A HREF=cCamaraArriba.html>cCamaraArriba</A>\r
+: Implementa una cámara para ver hacia arriba.<BR>\r
+<A HREF=cCamaraFrontal.html>cCamaraFrontal</A>\r
+: Implementa una cámara frontal.<BR>\r
+<A HREF=cCamaraLatDer.html>cCamaraLatDer</A>\r
+: Implementa una cámara lateral derecha.<BR>\r
+<A HREF=cCamaraLatIzq.html>cCamaraLatIzq</A>\r
+: Implementa una cámara lateral izquierda.<BR>\r
+<A HREF=cCamaraMapa.html>cCamaraMapa</A>\r
+: Implementa una cámara para ver hacia abajo pero alejado del cameraman.\r
+      Es como si observara al cameraman desde arriba.<BR>\r
+<A HREF=cCamaraTrasera.html>cCamaraTrasera</A>\r
+: Implementa una cámara trasera.<BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/Coordenadas.html b/doc/ref/Coordenadas.html
new file mode 100644 (file)
index 0000000..49a0fd0
--- /dev/null
@@ -0,0 +1,14 @@
+<HTML>\r
+<H2>Unit: Coordenadas</H2>\r
+<B>Description:</B><BR>Implementa un sistema de coordenadas y metodos para rotarlo.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    28/10/00: Se agregaron métodos para modificar el sistema de coordenadas, asignandole a un versor\r
+              particular la direccion de un vector arbitrario (mSetI, mSetJ, mSetK).\r
+    </PRE><BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=cCoordenadas.html>cCoordenadas</A>\r
+: Implementa un sistema de coordenadas y metodos para rotarlo.<BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/Descripcion.html b/doc/ref/Descripcion.html
new file mode 100644 (file)
index 0000000..fabb4ab
--- /dev/null
@@ -0,0 +1,36 @@
+<html>\r
+<title>AlgoWars - Manual de referencia para el programador</title>\r
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\r
+\r
+<body bgcolor="#FFFFFF">\r
+<center>\r
+  <h1><font face="Verdana, Arial, Helvetica, sans-serif" color="#990066">Algoritmos y Programaci&oacute;n III</font></h1>\r
+  <h2><font face="Arial, Helvetica, sans-serif">Trabajo Pr&aacute;ctico</font></h2>\r
+  <h2><font color="#0033CC">AlgoWars - Episodio IV</font></h2>\r
+  <h2>&nbsp;</h2>\r
+  <h3><font face="Arial, Helvetica, sans-serif">Manual de referencia para el programador</font></h3>\r
+  <h3>&nbsp;</h3>\r
+  <h3>Historial de cambios</h3>\r
+  <table width="60%" border="0" cellspacing="0" cellpadding="0">\r
+    <tr>\r
+      <td width="50%">\r
+        <center>\r
+          <p><a href="../CHANGES.TXT">CHANGES.TXT</a>\r
+</p>\r
+          <p>(orientado al usuario)          \r
+        </p>\r
+        </center>\r
+      </td>\r
+      <td width="50%">\r
+        <center>\r
+          <p><a href="../HISTORY.TXT">HISTORY.TXT</a>\r
+</p>\r
+          <p>(orientado al programador)        </p>\r
+        </center>\r
+      </td>\r
+    </tr>\r
+  </table>\r
+  <h3>&nbsp;</h3>\r
+  <h5 align="center"><font face="Arial, Helvetica, sans-serif"><i><font color="#CC0066">Grupo 10</font></i></font></h5>\r
+</center>\r
+</html>\r
diff --git a/doc/ref/ECameramanDestruido.html b/doc/ref/ECameramanDestruido.html
new file mode 100644 (file)
index 0000000..ab135f4
--- /dev/null
@@ -0,0 +1,29 @@
+<html>\r
+<h2>Class: ECameramanDestruido</h2>\r
+<pre> Exception ----+\r
+               |\r
+      ECameramanDestruido\r
+</pre>\r
+<hr>\r
+<b>Description:</b><br>Excepcion producida por la cámara si se utiliza cuando el cameraman fue destruido\r
+<p><b>Unit:</b><br><a href=Camara.html>Camara</a>\r
+<a href=Camara.pas>   <code>(Camara.pas)</code></a><br><br>\r
+<p><b>Constructors:</b><br>\r
+<dl>\r
+<dt>\r
+<img src=public.gif>\r
+<a href="ECameramanDestruido.html#0">constructor create;</a><br>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<hr>\r
+<p><img src=constructors.gif>\r
+<a name="0"></a><p>\r
+<img src=public_big.gif>\r
+<code>constructor create;</code>\r
+<dl>\r
+<dd>Constructor</dd><p>\r
+</dl><hr>\r
+</html>\r
diff --git a/doc/ref/ENavePropiaDestruida.html b/doc/ref/ENavePropiaDestruida.html
new file mode 100644 (file)
index 0000000..451654f
--- /dev/null
@@ -0,0 +1,29 @@
+<html>\r
+<h2>Class: ENavePropiaDestruida</h2>\r
+<pre> Exception ----+\r
+               |\r
+     ENavePropiaDestruida\r
+</pre>\r
+<hr>\r
+<b>Description:</b><br>Excepcion producida por el espacio si la nave propia fue destruido\r
+<p><b>Unit:</b><br><a href=Espacio.html>Espacio</a>\r
+<a href=Espacio.pas>   <code>(Espacio.pas)</code></a><br><br>\r
+<p><b>Constructors:</b><br>\r
+<dl>\r
+<dt>\r
+<img src=public.gif>\r
+<a href="ENavePropiaDestruida.html#0">constructor create;</a><br>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<hr>\r
+<p><img src=constructors.gif>\r
+<a name="0"></a><p>\r
+<img src=public_big.gif>\r
+<code>constructor create;</code>\r
+<dl>\r
+<dd>Constructor</dd><p>\r
+</dl><hr>\r
+</html>\r
diff --git a/doc/ref/EObservadorDestruido.html b/doc/ref/EObservadorDestruido.html
new file mode 100644 (file)
index 0000000..b4188f6
--- /dev/null
@@ -0,0 +1,29 @@
+<html>\r
+<h2>Class: EObservadorDestruido</h2>\r
+<pre> Exception ----+\r
+               |\r
+     EObservadorDestruido\r
+</pre>\r
+<hr>\r
+<b>Description:</b><br>Excepcion producida por el filtro si se utiliza cuando el observador fue destruido\r
+<p><b>Unit:</b><br><a href=Filtro.html>Filtro</a>\r
+<a href=Filtro.pas>   <code>(Filtro.pas)</code></a><br><br>\r
+<p><b>Constructors:</b><br>\r
+<dl>\r
+<dt>\r
+<img src=public.gif>\r
+<a href="EObservadorDestruido.html#0">constructor create;</a><br>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<hr>\r
+<p><img src=constructors.gif>\r
+<a name="0"></a><p>\r
+<img src=public_big.gif>\r
+<code>constructor create;</code>\r
+<dl>\r
+<dd>Constructor</dd><p>\r
+</dl><hr>\r
+</html>\r
diff --git a/doc/ref/ERegExpr.html b/doc/ref/ERegExpr.html
new file mode 100644 (file)
index 0000000..d988a2b
--- /dev/null
@@ -0,0 +1,12 @@
+<html>\r
+<h2>Class: ERegExpr</h2>\r
+<pre> Exception ----+\r
+               |\r
+           ERegExpr\r
+</pre>\r
+<hr>\r
+<b>Description:</b><br>Excepción de expresiones regulares\r
+<p><b>Unit:</b><br><a href=RegExpr.html>RegExpr</a>\r
+<a href=RegExpr.pas>   <code>(RegExpr.pas)</code></a><br><br>\r
+<hr>\r
+</html>\r
diff --git a/doc/ref/ESerializacion.html b/doc/ref/ESerializacion.html
new file mode 100644 (file)
index 0000000..494f2f4
--- /dev/null
@@ -0,0 +1,12 @@
+<html>\r
+<h2>Class: ESerializacion</h2>\r
+<pre> Exception ----+\r
+               |\r
+        ESerializacion\r
+</pre>\r
+<hr>\r
+<b>Description:</b><br>Excepcion producida si hay un error al serializar.\r
+<p><b>Unit:</b><br><a href=ObjetoPersistente.html>ObjetoPersistente</a>\r
+<a href=ObjetoPersistente.pas>   <code>(ObjetoPersistente.pas)</code></a><br><br>\r
+<hr>\r
+</html>\r
diff --git a/doc/ref/Espacio.html b/doc/ref/Espacio.html
new file mode 100644 (file)
index 0000000..5ceb110
--- /dev/null
@@ -0,0 +1,36 @@
+<HTML>\r
+<H2>Unit: Espacio</H2>\r
+<B>Description:</B><BR>Se encarga de controlar la interacción entre\r
+    las naves y el responsable de manejar el tiempo.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    05/10/00: Se corrigió para que utilice los nuevos metodos de cNaveEnemiga y cObjetoVolador\r
+              Se corrigió el método mComunicarPosicion para que solo se comunique la posicion\r
+              a las naves que estan en el campo de radar de la nave espia.\r
+    07/10/00: Se agregaron los métodos mDestruir y mActualizarObjetoVolador. Se modificó el\r
+              método mActualizar (para usar los nuevos) y el método mDetectarColisiones para\r
+              manejar de forma más eficiente y clara la destrucción de objetos sin energía.\r
+    03/11/00: Se sacan los metodos mIniciay y mParar, ya que el control del tiempo y el encargado\r
+              de actualizar el espacio sera el Controlador (Controller).\r
+              Se agregaron métodos para facilitar la manipulación del espacio:\r
+              mQuitarObjeto, mGetObjetos, mSetObjetos y mSetNavePropia\r
+    05/11/00: Se corrigió un BUG que hacia que siempre el espacio se inicialice con una lista vacia\r
+              y una nave propia estandar (en el constructor).\r
+    09/11/00: Se corrigió un BUG que hacía que la nave espia no pueda escapar, ya que se avisaba a si misma.\r
+              Tambien se hace que ignore otras naves espias que esten avisando para evitar problemas similares.\r
+              (en el método mComunicarPosicion).\r
+    10/11/00: Se reemplaza el método mNavePropiaDestruida por una excepción (ENavePropiaDestruida).\r
+              Es lanzada por el método mActualizar y otros metodos privados que utilizan la nave propia.\r
+    27/11/00: Se agrega el control de disparos de las naves enemigas en el método mActualizar\r
+    29/11/00: Se elimina el método temporal mActualizarNavePropia.\r
+    01/12/00: Se modifica el método mActualizar para manejar los disparos de la nave propia.\r
+    </PRE><BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=cEspacio.html>cEspacio</A>\r
+: Se encarga de controlar la interacción entre\r
+      las naves y el responsable de manejar el tiempo.<BR>\r
+<A HREF=ENavePropiaDestruida.html>ENavePropiaDestruida</A>\r
+: Excepcion producida por el espacio si la nave propia fue destruido<BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/Filtro.html b/doc/ref/Filtro.html
new file mode 100644 (file)
index 0000000..787cdab
--- /dev/null
@@ -0,0 +1,19 @@
+<HTML>\r
+<H2>Unit: Filtro</H2>\r
+<B>Description:</B><BR>Es una clase abstracta que representa filtro que recibe una lista de objetos y devuelve otra filtrada.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    06/12/00: Se agregan nuevos métodos (protegidos) para obtener información del filtro para poder crear subclases,\r
+              para lo cual tambien se hace virtual el método mVisible.\r
+    08/12/00: Se cambia esta clase para que sea abstracta. Se deja la implementacion del método mVisible para las\r
+              subclases exlusivamente ya que ahora es abstracto. El filtro frontal (que antes se implementaba en\r
+              esta unidad), ahora está implementado la unidad Filtros al igual que el resto.\r
+    </PRE><BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=cFiltro.html>cFiltro</A>\r
+: Es una clase abstracta que representa un filtro que recibe una lista de objetos y devuelve otra filtrada.<BR>\r
+<A HREF=EObservadorDestruido.html>EObservadorDestruido</A>\r
+: Excepcion producida por el filtro si se utiliza cuando el observador fue destruido<BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/Filtros.html b/doc/ref/Filtros.html
new file mode 100644 (file)
index 0000000..a144d20
--- /dev/null
@@ -0,0 +1,29 @@
+<HTML>\r
+<H2>Unit: Filtros</H2>\r
+<B>Description:</B><BR>Se implementan varios filtro en diferentes direcciones.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    09/12/00: Se agrega la clase cFiltroMapa.\r
+    </PRE><BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=cFiltroAbajo.html>cFiltroAbajo</A>\r
+: Implementa un filtro que "ve" hacia abajo.<BR>\r
+<A HREF=cFiltroArriba.html>cFiltroArriba</A>\r
+: Implementa un filtro que "ve" hacia arriba.<BR>\r
+<A HREF=cFiltroFrontal.html>cFiltroFrontal</A>\r
+: Implementa un filtro que "ve" hacia adelante.<BR>\r
+<A HREF=cFiltroLatDer.html>cFiltroLatDer</A>\r
+: Implementa un filtro que "ve" hacia la derecha.<BR>\r
+<A HREF=cFiltroLatIzq.html>cFiltroLatIzq</A>\r
+: Implementa un filtro que "ve" hacia la izquierda.<BR>\r
+<A HREF=cFiltroLock.html>cFiltroLock</A>\r
+: Implementa un filtro que "ve" hacia adelante y que además sólo puede\r
+      ver objetos del tipo cNave y cMeteorito.<BR>\r
+<A HREF=cFiltroMapa.html>cFiltroMapa</A>\r
+: Implementa un filtro que "ve" hacia abajo pero desde arriba a una cierta distancia\r
+      del observador. Es como si observara al observador mismo.<BR>\r
+<A HREF=cFiltroTrasero.html>cFiltroTrasero</A>\r
+: Implementa un filtro que "ve" hacia atrás.<BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/FormConfig.html b/doc/ref/FormConfig.html
new file mode 100644 (file)
index 0000000..becdfeb
--- /dev/null
@@ -0,0 +1,9 @@
+<HTML>\r
+<H2>Unit: FormConfig</H2>\r
+<B>Description:</B><BR>Formulario para configurar la aplicación<BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=TConfigForm.html>TConfigForm</A>\r
+: Formulario para configurar la aplicación<BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/FormMain.html b/doc/ref/FormMain.html
new file mode 100644 (file)
index 0000000..0749a19
--- /dev/null
@@ -0,0 +1,25 @@
+<HTML>\r
+<H2>Unit: FormMain</H2>\r
+<B>Description:</B><BR>Formulario principal de la aplicación<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    29/11/00: Se agregan algunos controles gráficos con indicadores de energía y velocidad.\r
+              No se incluyen en una clase Vista porque son muy pequeños.\r
+    01/12/00: Se modifica levemente la interfaz.\r
+              Se agregan controles para los disparos y metodos pertinentes.\r
+    06/12/00: Se cambian minimamente los menúes, poniendo la parte del manejo\r
+              de escenarios en un submenú del menú Archivo.\r
+    08/12/00: Se termina de implementar la funcionalidad de los menúes\r
+                Archivo -> Abrir ...\r
+                Archivo -> Guardar ...\r
+                Archivo -> Escenario -> Abrir ...\r
+                Archivo -> Escenario -> Guardar ...\r
+              Se completa el 'destructor', ya que faltaban liberar bastantes\r
+              objetos.\r
+    </PRE><BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=TMainForm.html>TMainForm</A>\r
+: Formulario principal de la aplicación<BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/Lista.html b/doc/ref/Lista.html
new file mode 100644 (file)
index 0000000..9127cc0
--- /dev/null
@@ -0,0 +1,11 @@
+<HTML>\r
+<H2>Unit: Lista</H2>\r
+<B>Description:</B><BR>Lista exactamente igual a TList, solo que el destructor tambien destruye\r
+    todos los objetos que contiene<BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=cLista.html>cLista</A>\r
+: Lista exactamente igual a TList, solo que el destructor tambien destruye todos\r
+      los objetos que contiene<BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/Meteorito.html b/doc/ref/Meteorito.html
new file mode 100644 (file)
index 0000000..f240c3f
--- /dev/null
@@ -0,0 +1,13 @@
+<HTML>\r
+<H2>Unit: Meteorito</H2>\r
+<B>Description:</B><BR>Representa un objeto volador básico. Tiene una velocidad constante.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    01/12/00: Se cambiaron las dimensiones por defecto para que los disparos sean mas "jugables".\r
+    </PRE><BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=cMeteorito.html>cMeteorito</A>\r
+: Representa un objeto volador básico. Tiene una velocidad constante.<BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/Nave.html b/doc/ref/Nave.html
new file mode 100644 (file)
index 0000000..958efdb
--- /dev/null
@@ -0,0 +1,27 @@
+<HTML>\r
+<H2>Unit: Nave</H2>\r
+<B>Description:</B><BR>Contiene una clase abstracta con elementos comunes a todas las naves.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    27/11/00: Se agrega toda la parte del manejo de disparos, agregándose los métodos mPuedeDispararLaser,\r
+              mPuedeDispararMisil, mPuedeDispararMisDir y mDisparar, además de varios atributos para manejar\r
+              los retardos de las armas. El método mDisparar se hace virtual ya que puede ser modificado por\r
+              las subclases para que cambie su mecanismo de disparos.\r
+    29/11/00: Se agregan métodos para obtener la cantidad de armamento que le queda a la nave para poder ser\r
+              mostrados (mGetMisiles y mGetMisilesDirigidos)\r
+    01/12/00: Se modifican levemente los metodos mPuedeDispararXxxx para que permitan disparar si el puntero\r
+              al Objeto Volador objetivo es nil.\r
+              Se Agregan los métodos mRetardarLaser, mRetardarMisil, mRetardarMisDir que resetea el contador\r
+              del retardo, mActualizarRetardos que resta el dT a los retardos, y mCrearLaserDisparado,\r
+              mCrearMisilDisparado y mCrearMisDirDisparado que crea el arma correspondiente (actualizando\r
+              retardos y todo lo que sea necesario) para que las subclases puedan escribir su propio mDisparar.\r
+              Se cambia el orden de los argumentos de mDisparar para aprovechar los argumentos por defecto.\r
+    08/12/00: Se sobreescribieron los métodos para establecer la velocidad y su módulo para evitar que se\r
+              sobrepase el límite de la velocidad máxima.\r
+    </PRE><BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=cNave.html>cNave</A>\r
+: Clase abstracta con elementos comunes a todas las naves.<BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/NaveEnemiga.html b/doc/ref/NaveEnemiga.html
new file mode 100644 (file)
index 0000000..3eea5b1
--- /dev/null
@@ -0,0 +1,17 @@
+<HTML>\r
+<H2>Unit: NaveEnemiga</H2>\r
+<B>Description:</B><BR>La clase cNaveEnemiga esta pensada como una clase abtracta. En ella se encuentran\r
+    características comunes a todas las naves enemigas.<br>\r
+      <i>Cambios:</i>\r
+    <PRE>\r
+    05/10/00: Se cambio el metodo mGetRadar por el metodo mDetectado, que devuelve true\r
+              si un objeto volador esta destro del campo de radar. De esta manera se logra\r
+              una abstracción mayor y un manejo mas intuitivo del radar.\r
+    </PRE><BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=cNaveEnemiga.html>cNaveEnemiga</A>\r
+: La clase cNaveEnemiga esta pensada como una clase abtracta. En ella se encuentran\r
+      características comunes a todas las naves enemigas.<BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/NavePropia.html b/doc/ref/NavePropia.html
new file mode 100644 (file)
index 0000000..f438d8b
--- /dev/null
@@ -0,0 +1,33 @@
+<HTML>\r
+<H2>Unit: NavePropia</H2>\r
+<B>Description:</B><BR>Es la nave que será controlada por el jugador.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    05/10/00: Se corrigió el método mAcelerar porque tenía algunos bugs cuando la velocidad llegaba a cero.\r
+    01/12/00: Se implementan los disparon sobreescribiendo el método mDisparar de cNave y agregando algunos\r
+              atributos (aArmaSelect, aDisparando y aLockeado) y algunos métodos (mIntentarDisparo,\r
+              mSeleccionarArma, mSeleccionarArmaSig, mGetArmaSelect, mSetLockeado, mGetLockeado).\r
+              Se cambiaron las dimensiones de la nave para que los disparos sean mas "jugables".\r
+              Se cambia el orden de los argumentos de mDisparar para aprovechar los argumentos por defecto.\r
+              Se arreglaron un par de BUGs con punteros que apuntaba a objetos destruidos (aLockeado).\r
+    08/12/00: Se arregló una falla en el constructor que permitia crear la nave con una velocidad superior\r
+              a la máxima.\r
+    09/12/00: Se cambia el atributo disparando por un puntero a un arma que se disparara en el proximo turno.\r
+              También se cambia los métodos que lo utilizan y en particular se convierte el método\r
+              mIntentarDisparo en una función que devuelve dicho puntero para implementar la cámara en el arma.\r
+    </PRE><BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=cNavePropia.html>cNavePropia</A>\r
+: Es la nave que será controlada por el jugador.\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            15        metros\r
+      Potencia:             5         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              100       Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,17      metros/milisegundos (612 km/h)\r
+      Misiles:              10\r
+      Misiles Dirigidos:    5\r
+      </PRE><BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/NavesEnemigas.html b/doc/ref/NavesEnemigas.html
new file mode 100644 (file)
index 0000000..70ab76e
--- /dev/null
@@ -0,0 +1,66 @@
+<HTML>\r
+<H2>Unit: NavesEnemigas</H2>\r
+<B>Description:</B><BR>Distintos tipos de Naves Enemigas<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    27/11/00: Se realizan algunos cambios para adaptarse a la nueva implementacion de cNave con disparos.\r
+    01/12/00: Se cambiaron las dimensiones de la nave para que los disparos sean mas "jugables".\r
+              Se cambia el orden de los argumentos de mDisparar para aprovechar los argumentos por defecto.\r
+    </PRE><BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=cNaveEspia.html>cNaveEspia</A>\r
+: Es una nave sin armas que se desplaza por el epacio\r
+      hasta que encuentra una nave propia, en ese momento empieza a huir avisando a\r
+      las demas naves enemigas la ultima posicion de la nave propia.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            10        metros\r
+      Potencia:             1         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              30        Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,2       metros/milisegundos (720 km/h)\r
+      Campo de radar:       2000      metros (2 km)\r
+      Misiles:              0\r
+      Misiles Dirigidos:    0\r
+      </PRE><BR>\r
+<A HREF=cNaveLiviana.html>cNaveLiviana</A>\r
+: Es una nave sin misiles, solo con lasers que\r
+      se desplaza por el epacio hasta que encuentra una nave propia para atacar.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            15        metros\r
+      Potencia:             1         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              60        Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,18      metros/milisegundos (648 km/h)\r
+      Campo de radar:       3000      metros (3 km)\r
+      Misiles:              0\r
+      Misiles Dirigidos:    0\r
+      </PRE><BR>\r
+<A HREF=cNavePesada.html>cNavePesada</A>\r
+: Es una nave con misiles y lasers (igual que la propia)\r
+      que se desplaza por el epacio hasta que encuentra una nave propia para atacar.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            25        metros\r
+      Potencia:             2         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              100       Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,17      metros/milisegundos (612 km/h)\r
+      Campo de radar:       5000      metros (5 km)\r
+      Misiles:              5\r
+      Misiles Dirigidos:    2\r
+      </PRE><BR>\r
+<A HREF=cNaveSuicida.html>cNaveSuicida</A>\r
+: Es una nave sin armas que se desplaza por el epacio\r
+      hasta que encuentra una nave propia y trata de chocarla.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            10        metros\r
+      Potencia:             4         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              30        Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,2       metros/milisegundos (720 km/h)\r
+      Campo de radar:       2500      metros (2,5 km)\r
+      Misiles:              0\r
+      Misiles Dirigidos:    0\r
+      </PRE><BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/Objeto.html b/doc/ref/Objeto.html
new file mode 100644 (file)
index 0000000..b27fcbf
--- /dev/null
@@ -0,0 +1,13 @@
+<HTML>\r
+<H2>Unit: Objeto</H2>\r
+<B>Description:</B><BR>Es una clase abstracta para agregar algunos métodos generales útiles\r
+    para el resto de las clases que implementemos. Podría considerarse una\r
+    extensión a la funcionalidad básica dada por TObject.<BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=cObjeto.html>cObjeto</A>\r
+: Es una clase abstracta para agregar algunos métodos generales útiles\r
+      para el resto de las clases que implementemos. Podría considerarse una\r
+      extensión a la funcionalidad básica dada por TObject.<BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/ObjetoPersistente.html b/doc/ref/ObjetoPersistente.html
new file mode 100644 (file)
index 0000000..cc946f7
--- /dev/null
@@ -0,0 +1,26 @@
+<HTML>\r
+<H2>Unit: ObjetoPersistente</H2>\r
+<B>Description:</B><BR>Es una clase abstracta para hacer persistente un objeto.\r
+    Básicamente provee métodos para serialización.<br>\r
+    <U>NOTA:</U>\r
+    <PRE>\r
+      Es importante que el ID del objeto sea el primer atributo en la\r
+      serialización, de otra manera puede ser malinterpretado al des-\r
+      serializarlo.\r
+      El orden del resto de los atributos deben ser respetados también.\r
+      Aunque es bastante probable que fucione si están en otro órden,\r
+      no está 100% asegurado y si se hace en otro orden los resultados\r
+      pueden ser inesperados o pueden surgir errores.\r
+    <PRE><BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=cObjetoPersistente.html>cObjetoPersistente</A>\r
+: Es una clase abstracta para hacer persistente un objeto.\r
+      Básicamente provee métodos para serialización.\r
+      NOTA: Es importante que el ID del objeto sea el primer atributo en la\r
+            serialización, de otra manera puede ser malinterpretado al des-\r
+            serializarlo.<BR>\r
+<A HREF=ESerializacion.html>ESerializacion</A>\r
+: Excepcion producida si hay un error al serializar.<BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/ObjetoVolador.html b/doc/ref/ObjetoVolador.html
new file mode 100644 (file)
index 0000000..bf3f398
--- /dev/null
@@ -0,0 +1,35 @@
+<HTML>\r
+<H2>Unit: ObjetoVolador</H2>\r
+<B>Description:</B><BR>Clase abstracta, implementa todas las funcionalidades básicas de los objetos voladores.\r
+    De esta van a derivar la mayor parte del resto de las clases.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    05/10/00: Se agregaron los métodos mGetDistancia y mColisiono. De esta manera se deja\r
+              a los objetos voladores manejar las colisiones mas intuitivamente.\r
+    30/10/00: Se agregó un atributo <b>aCoordenadas</b> para que se pueda orientar al objeto volador.\r
+    02/11/00: Se agregaron métodos para cambiar solamente el modulo de la velocidad, para cambiar solo\r
+              la direccion de la velocidad y para extraer directamente copias de los versores i, j, k y\r
+              para rotar el objeto volador en todas direcciones.\r
+              Los nuevos métodos son: mSetVelModulo, mSetVelDir, mGetVelModulo,\r
+                                      mGetI, mGetJ, mGetK, mRotarEnI,\r
+                                      mRotarEnJ, mRotarEnK\r
+    07/11/00: Se agrega un nuevo método (mSetPosicion) y se hace a público otro (mSetVelocidad) para\r
+              que se pueda cambiar la configuración (es temporal, se planea cambiar el sistema de\r
+              configuración del juego para que esto no sea necesario)\r
+    29/11/00: Se arregla un BUG en mSetVelModulo que no modificaba el modulo si la velocidad pasada\r
+              como argumento era menor que cero. En este caso el modulo de la velocidad se setea en 0.\r
+    02/12/00: Se cambio el dato que devuelve el método mDibujar. Ahora devuelve un tipo de dato enumerado\r
+              tObjetosVoladores. Todas sus subclases fueron actualizadas también.\r
+    08/12/00: Se agregan menúes para manejar la nueva vistas con varias camaras. Se agrega la opcion de\r
+              alta calidad en el menú vista. Se carga un escenario por defecto (si existe) al iniciar el\r
+              juego, el nombre de dicho escenario debe ser 'comun.eaw'.\r
+              Se agrega una nueva tecla para cambiar de cámara ('C'), además de las que se provee con las\r
+              teclas de atajo.\r
+    </PRE><BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=cObjetoVolador.html>cObjetoVolador</A>\r
+: Clase abstracta, implementa todas las funcionalidades básicas de los objetos voladores.\r
+      De esta van a derivar la mayor parte del resto de las clases.<BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/RegExpr.html b/doc/ref/RegExpr.html
new file mode 100644 (file)
index 0000000..3516f5a
--- /dev/null
@@ -0,0 +1,48 @@
+<HTML>\r
+<H2>Unit: RegExpr</H2>\r
+<B>Description:</B><BR>Implementación de expresiones regulares para Delphi<BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=ERegExpr.html>ERegExpr</A>\r
+: Excepción de expresiones regulares<BR>\r
+<A HREF=TRegExpr.html>TRegExpr</A>\r
+: Clase auxiliar que implementa expresiones Regulares. Se ultiliza para validar los campos de texto<BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+<A NAME=ExecRegExpr ></A>\r
+<dt><IMG SRC=functions_big.gif><code> function ExecRegExpr (const ARegExpr, AInputStr : RegExprString) : boolean;</code></dt>\r
+<dd>true if string AInputString match regular expression ARegExpr\r
+    ! will raise exeption if syntax errors in ARegExpr</dd><p>\r
+<A NAME=QuoteRegExprMetaChars ></A>\r
+<dt><IMG SRC=functions_big.gif><code> function QuoteRegExprMetaChars (const AStr : RegExprString) : RegExprString;</code></dt>\r
+<dd>Replace all metachars with its safe representation,\r
+    for example 'abc$cd.(' converts into 'abc\$cd\.\('\r
+    This function usefull for r.e. autogeneration from\r
+    user input</dd><p>\r
+<A NAME=ReplaceRegExpr ></A>\r
+<dt><IMG SRC=functions_big.gif><code> function ReplaceRegExpr (const ARegExpr, AInputStr, AReplaceStr : RegExprString) : RegExprString;</code></dt>\r
+<dd>Returns AInputStr with r.e. occurencies replaced by AReplaceStr</dd><p>\r
+<A NAME=SplitRegExpr ></A>\r
+<dt><IMG SRC=functions_big.gif><code> procedure SplitRegExpr (const ARegExpr, AInputStr : RegExprString; APieces : TStrings);</code></dt>\r
+<dd>Split AInputStr into APieces by r.e. ARegExpr occurencies</dd><p>\r
+<A NAME=strcspn ></A>\r
+<dt><IMG SRC=functions_big.gif><code> function strcspn (s1 : PRegExprChar; s2 : PRegExprChar) : integer;</code></dt>\r
+<p>\r
+<A NAME=StrLComp ></A>\r
+<dt><IMG SRC=functions_big.gif><code> function StrLComp (Str1, Str2: PRegExprChar; MaxLen: Cardinal): Integer;</code></dt>\r
+<p>\r
+<A NAME=StrLCopy ></A>\r
+<dt><IMG SRC=functions_big.gif><code> function StrLCopy (Dest, Source: PRegExprChar; MaxLen: Cardinal): PRegExprChar;</code></dt>\r
+<p>\r
+<A NAME=StrLen ></A>\r
+<dt><IMG SRC=functions_big.gif><code> function StrLen (Str: PRegExprChar): Cardinal;</code></dt>\r
+<p>\r
+<A NAME=StrPCopy ></A>\r
+<dt><IMG SRC=functions_big.gif><code> function StrPCopy (Dest: PRegExprChar; const Source: RegExprString): PRegExprChar;</code></dt>\r
+<p>\r
+<A NAME=StrPos ></A>\r
+<dt><IMG SRC=functions_big.gif><code> function StrPos (Str1, Str2: PRegExprChar): PRegExprChar;</code></dt>\r
+<p>\r
+<A NAME=StrScan ></A>\r
+<dt><IMG SRC=functions_big.gif><code> function StrScan (Str: PRegExprChar; Chr: WideChar): PRegExprChar;</code></dt>\r
+<p>\r
+</dl></HTML>\r
diff --git a/doc/ref/SerializacionUtils.html b/doc/ref/SerializacionUtils.html
new file mode 100644 (file)
index 0000000..0a38009
--- /dev/null
@@ -0,0 +1,13 @@
+<HTML>\r
+<H2>Unit: SerializacionUtils</H2>\r
+<B>Description:</B><BR>Funciones útiles para complementar la utilización de la serialización en\r
+    este modelo en particular<BR><BR>\r
+<B>Classes:</B><BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+<A NAME=restaurarObjeto></A>\r
+<dt><IMG SRC=functions_big.gif><code> function restaurarObjeto( clase, str: string ): cObjetoVolador;</code></dt>\r
+<dd>Crea un objeto a partir de un string con el nombre de su clase y otro\r
+    con su representación serializada.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>clase </CODE> : Clase del Objeto</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>str </CODE> :   Representación del objeto serializado</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Puntero al nuevo objeto.</dd><p>\r
+</dl></HTML>\r
diff --git a/doc/ref/TConfigForm.html b/doc/ref/TConfigForm.html
new file mode 100644 (file)
index 0000000..9b883b4
--- /dev/null
@@ -0,0 +1,88 @@
+<html>\r
+<h2>Class: TConfigForm</h2>\r
+<pre> TForm ----+\r
+           |\r
+      TConfigForm\r
+</pre>\r
+<hr>\r
+<b>Description:</b><br>Formulario para configurar la aplicación\r
+<p><b>Unit:</b><br><a href=FormConfig.html>FormConfig</a>\r
+<a href=FormConfig.pas>   <code>(FormConfig.pas)</code></a><br><br>\r
+<p><b>Methods:</b><br>\r
+<dl>\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TConfigForm.html#0">procedure aBtnAceptarClick(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TConfigForm.html#1">procedure aBtnAgregarClick(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TConfigForm.html#2">procedure aBtnCancelarClick(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TConfigForm.html#3">procedure aBtnQuitarClick(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TConfigForm.html#4">procedure FormShow(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TConfigForm.html#5">procedure mValidar(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+</dl>\r
+<hr>\r
+<p><img src=methods.gif>\r
+<a name="0"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure aBtnAceptarClick(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="1"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure aBtnAgregarClick(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="2"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure aBtnCancelarClick(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="3"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure aBtnQuitarClick(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="4"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure FormShow(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="5"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure mValidar(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+</html>\r
diff --git a/doc/ref/TMainForm.html b/doc/ref/TMainForm.html
new file mode 100644 (file)
index 0000000..c99711a
--- /dev/null
@@ -0,0 +1,306 @@
+<html>\r
+<h2>Class: TMainForm</h2>\r
+<pre> TForm ----+\r
+           |\r
+       TMainForm\r
+</pre>\r
+<hr>\r
+<b>Description:</b><br>Formulario principal de la aplicación\r
+<p><b>Unit:</b><br><a href=FormMain.html>FormMain</a>\r
+<a href=FormMain.pas>   <code>(FormMain.pas)</code></a><br><br>\r
+<p><b>Methods:</b><br>\r
+<dl>\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#0">procedure aBtnIniciarClick(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#1">procedure aMenuClick(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#2">procedure aMenuItemAbrirClick(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#3">procedure aMenuItemAbrirEscenarioClick(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#4">procedure aMenuItemCalidadClick(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#5">procedure aMenuItemCambioAutomaticoClick(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#6">procedure aMenuItemConfigurarClick(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#7">procedure aMenuItemGuardarClick(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#8">procedure aMenuItemGuardarEscenarioClick(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#9">procedure aMenuItemNuevoJuegoClick(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#10">procedure aMenuItemSalirClick(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#11">procedure aTimerTimer(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#12">procedure aTimerVistaTimer(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#13">procedure CambiarVistaClick(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#14">procedure DesSerializarEscenario( archivo: string );</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#15">procedure DesSerializarJuego( archivo: string );</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#16">procedure FormCreate(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#17">procedure FormDestroy(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#18">procedure FormHide(Sender: TObject);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#19">procedure FormKeyDown(Sender: TObject; var Key: Word;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#20">function mGetNavePropia: cNavePropia;</a><br>\r
+</dt>\r
+<dd>\r
+Obtiene la nave propia del formulario\r
+</dd>\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#21">function mGetObjetos: TList;</a><br>\r
+</dt>\r
+<dd>\r
+Obtiene la lista de objetos del formulario\r
+</dd>\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#22">procedure SerializarEscenario( archivo: string );</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TMainForm.html#23">procedure SerializarJuego( archivo: string );</a><br>\r
+</dt>\r
+\r
+\r
+</dl>\r
+<hr>\r
+<p><img src=methods.gif>\r
+<a name="0"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure aBtnIniciarClick(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="1"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure aMenuClick(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="2"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure aMenuItemAbrirClick(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="3"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure aMenuItemAbrirEscenarioClick(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="4"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure aMenuItemCalidadClick(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="5"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure aMenuItemCambioAutomaticoClick(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="6"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure aMenuItemConfigurarClick(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="7"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure aMenuItemGuardarClick(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="8"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure aMenuItemGuardarEscenarioClick(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="9"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure aMenuItemNuevoJuegoClick(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="10"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure aMenuItemSalirClick(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="11"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure aTimerTimer(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="12"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure aTimerVistaTimer(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="13"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure CambiarVistaClick(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="14"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure DesSerializarEscenario( archivo: string );</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="15"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure DesSerializarJuego( archivo: string );</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="16"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure FormCreate(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="17"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure FormDestroy(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="18"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure FormHide(Sender: TObject);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="19"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure FormKeyDown(Sender: TObject; var Key: Word;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="20"></a><p>\r
+<img src=public_big.gif>\r
+<code>function mGetNavePropia: cNavePropia;</code>\r
+<dl>\r
+<dd></dd><dd><b>Returns</b></dd><dd>&nbsp;&nbsp;&nbsp;Nave propia que utilizara el espacio</dd><p>\r
+</dl><hr>\r
+<a name="21"></a><p>\r
+<img src=public_big.gif>\r
+<code>function mGetObjetos: TList;</code>\r
+<dl>\r
+<dd></dd><dd><b>Returns</b></dd><dd>&nbsp;&nbsp;&nbsp;Lista de objetos que utilizara el espacio</dd><p>\r
+</dl><hr>\r
+<a name="22"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure SerializarEscenario( archivo: string );</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="23"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure SerializarJuego( archivo: string );</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+</html>\r
diff --git a/doc/ref/TRegExpr.html b/doc/ref/TRegExpr.html
new file mode 100644 (file)
index 0000000..e198c6b
--- /dev/null
@@ -0,0 +1,324 @@
+<html>\r
+<h2>Class: TRegExpr</h2>\r
+<pre> TObject ----+\r
+             |\r
+         TRegExpr\r
+</pre>\r
+<hr>\r
+<b>Description:</b><br>Clase auxiliar que implementa expresiones Regulares. Se ultiliza para validar los campos de texto\r
+<p><b>Unit:</b><br><a href=RegExpr.html>RegExpr</a>\r
+<a href=RegExpr.pas>   <code>(RegExpr.pas)</code></a><br><br>\r
+<p><b>Constructors:</b><br>\r
+<dl>\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#1">constructor Create;</a><br>\r
+</dt>\r
+\r
+\r
+</dl>\r
+<p><b>Properties:</b><br>\r
+<dl>\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#0">property CompilerErrorPos : integer read GetCompilerErrorPos;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#8">property Expression : RegExprString read GetExpression write SetExpression;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#9">property InputString : RegExprString read GetInputString write SetInputString;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#10">property InvertCase : TRegExprInvertCaseFunction read fInvertCase write fInvertCase; //##0.935</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#12">property Match [Idx : integer] : RegExprString read GetMatch;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#13">property MatchLen [Idx : integer] : integer read GetMatchLen;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#14">property MatchPos [Idx : integer] : integer read GetMatchPos;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#15">property ModifierI : boolean index 1 read GetModifier write SetModifier;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#16">property ModifierR : boolean index 2 read GetModifier write SetModifier;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#17">property ModifierS : boolean index 3 read GetModifier write SetModifier;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#18">property ModifierStr : RegExprString read GetModifierStr write SetModifierStr;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#20">property SpaceChars : RegExprString read fSpaceChars write fSpaceChars; //###0.927</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#22">property SubExprMatchCount : integer read GetSubExprMatchCount;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#24">property WordChars : RegExprString read fWordChars write fWordChars; //###0.929</a><br>\r
+</dt>\r
+\r
+\r
+</dl>\r
+<p><b>Methods:</b><br>\r
+<dl>\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#2">destructor Destroy; override;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#3">function Dump : RegExprString;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#4">function ErrorMsg (AErrorID : integer) : RegExprString; virtual;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#5">function Exec (const AInputString : RegExprString) : boolean;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#6">function ExecNext : boolean;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#7">function ExecPos (AOffset: integer {$IFDEF D4_}= 1{$ENDIF}) : boolean;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#11">function LastError : integer;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#19">function Replace (AInputStr : RegExprString; const AReplaceStr : RegExprString) : RegExprString;</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#21">procedure Split (AInputStr : RegExprString; APieces : TStrings);</a><br>\r
+</dt>\r
+\r
+\r
+<dt>\r
+<img src=public.gif>\r
+<a href="TRegExpr.html#23">function Substitute (const ATemplate : RegExprString) : RegExprString;</a><br>\r
+</dt>\r
+\r
+\r
+</dl>\r
+<hr>\r
+<p><img src=constructors.gif>\r
+<a name="1"></a><p>\r
+<img src=public_big.gif>\r
+<code>constructor Create;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<p><img src=property.gif>\r
+<a name="0"></a><p>\r
+<img src=public_big.gif>\r
+<code>property CompilerErrorPos : integer read GetCompilerErrorPos;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="8"></a><p>\r
+<img src=public_big.gif>\r
+<code>property Expression : RegExprString read GetExpression write SetExpression;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="9"></a><p>\r
+<img src=public_big.gif>\r
+<code>property InputString : RegExprString read GetInputString write SetInputString;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="10"></a><p>\r
+<img src=public_big.gif>\r
+<code>property InvertCase : TRegExprInvertCaseFunction read fInvertCase write fInvertCase; //##0.935</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="12"></a><p>\r
+<img src=public_big.gif>\r
+<code>property Match [Idx : integer] : RegExprString read GetMatch;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="13"></a><p>\r
+<img src=public_big.gif>\r
+<code>property MatchLen [Idx : integer] : integer read GetMatchLen;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="14"></a><p>\r
+<img src=public_big.gif>\r
+<code>property MatchPos [Idx : integer] : integer read GetMatchPos;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="15"></a><p>\r
+<img src=public_big.gif>\r
+<code>property ModifierI : boolean index 1 read GetModifier write SetModifier;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="16"></a><p>\r
+<img src=public_big.gif>\r
+<code>property ModifierR : boolean index 2 read GetModifier write SetModifier;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="17"></a><p>\r
+<img src=public_big.gif>\r
+<code>property ModifierS : boolean index 3 read GetModifier write SetModifier;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="18"></a><p>\r
+<img src=public_big.gif>\r
+<code>property ModifierStr : RegExprString read GetModifierStr write SetModifierStr;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="20"></a><p>\r
+<img src=public_big.gif>\r
+<code>property SpaceChars : RegExprString read fSpaceChars write fSpaceChars; //###0.927</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="22"></a><p>\r
+<img src=public_big.gif>\r
+<code>property SubExprMatchCount : integer read GetSubExprMatchCount;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="24"></a><p>\r
+<img src=public_big.gif>\r
+<code>property WordChars : RegExprString read fWordChars write fWordChars; //###0.929</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<p><img src=methods.gif>\r
+<a name="2"></a><p>\r
+<img src=public_big.gif>\r
+<code>destructor Destroy; override;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="3"></a><p>\r
+<img src=public_big.gif>\r
+<code>function Dump : RegExprString;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="4"></a><p>\r
+<img src=public_big.gif>\r
+<code>function ErrorMsg (AErrorID : integer) : RegExprString; virtual;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="5"></a><p>\r
+<img src=public_big.gif>\r
+<code>function Exec (const AInputString : RegExprString) : boolean;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="6"></a><p>\r
+<img src=public_big.gif>\r
+<code>function ExecNext : boolean;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="7"></a><p>\r
+<img src=public_big.gif>\r
+<code>function ExecPos (AOffset: integer {$IFDEF D4_}= 1{$ENDIF}) : boolean;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="11"></a><p>\r
+<img src=public_big.gif>\r
+<code>function LastError : integer;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="19"></a><p>\r
+<img src=public_big.gif>\r
+<code>function Replace (AInputStr : RegExprString; const AReplaceStr : RegExprString) : RegExprString;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="21"></a><p>\r
+<img src=public_big.gif>\r
+<code>procedure Split (AInputStr : RegExprString; APieces : TStrings);</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+<a name="23"></a><p>\r
+<img src=public_big.gif>\r
+<code>function Substitute (const ATemplate : RegExprString) : RegExprString;</code>\r
+<dl>\r
+<p>\r
+</dl><hr>\r
+</html>\r
diff --git a/doc/ref/Tipos.html b/doc/ref/Tipos.html
new file mode 100644 (file)
index 0000000..cd437d6
--- /dev/null
@@ -0,0 +1,9 @@
+<HTML>\r
+<H2>Unit: Tipos</H2>\r
+<B>Description:</B><BR>En esta unidad se definen todos los tipos que usaremos en el proyecto\r
+    Decidimos mantener los tipos por separado por el caso de que sea\r
+    necesario un cambio de implementacion.<BR><BR>\r
+<B>Classes:</B><BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/Vectores.html b/doc/ref/Vectores.html
new file mode 100644 (file)
index 0000000..bd778c8
--- /dev/null
@@ -0,0 +1,21 @@
+<HTML>\r
+<H2>Unit: Vectores</H2>\r
+<B>Description:</B><BR>Es la implementación de un vector físico. Esta clase es el esqueleto de\r
+    la aplicación ya que todas las velocidades y posiciones son del tipo cVector.\r
+    Todos los calculos de movimientos, distancias, etc. se manejan con los metodos de esta clase<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    05/10/00: Se corrigió el método mAddModulo para que al verificar el signo del modulo resultante,\r
+              si es negativo, setee el modulo a cero.\r
+    28/10/00: Se cambiaron todos los metodos en los que se realizan operaciones con el vector para\r
+              que devulvan un puntero a si mismo (para poder hacer asignaciones luego de la operacion).\r
+              Ahora todos los métodos son funciones\r
+    </PRE><BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=cVector.html>cVector</A>\r
+: La clase cVector es la implementación de un vector físico. Esta clase es el esqueleto de\r
+      la aplicación ya que todas las velocidades y posiciones son del tipo cVector.\r
+      Todos los calculos de movimientos, distancias, etc. se manejan con los metodos de esta clase<BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/Vista.html b/doc/ref/Vista.html
new file mode 100644 (file)
index 0000000..5772d31
--- /dev/null
@@ -0,0 +1,29 @@
+<HTML>\r
+<H2>Unit: Vista</H2>\r
+<B>Description:</B><BR>Interpreta y dibuja los datos del modelo en un formulario<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    10/11/00: Se maneja la excepción para evitar usar la camara cuando el cameraman fue destruido (ECameramanDestruido).\r
+              Esta es propagada (por ahora) para que el controlador (formulario) frene el timer\r
+    02/12/00: Se mejoran los graficos usando transparencias en los bitmaps y se da la opcion de presentar\r
+              los graficos con transparencias (alta calidad) o no (a través del atributo aAltaCalidad y\r
+              los métodos mSetAltaCalidad, mSetBajaCalidad y mCambiarCalidad).\r
+              Se mejora la performance gracias a la nueva implementación de mDibujar, ya que los\r
+              bitmas se cargan una sola vez en memoria (en un array aBitmaps) en vez de cargarse\r
+              y liberarse cada vez que se actualiza la pantalla como sucedía anteriormente.\r
+              Se implementa el soporte de visualización de un objeto volador lockeado (utilizando\r
+              otra lista de bitmaps con los gráficos de los objetos lockeados, aBitmapsLockeados).\r
+    08/12/00: Se agregan múltiples cámaras: Derecha, Izquierda, Arriba, Abajo, Atrás, Del Misil. Para hacerlo\r
+              se agragega un array de camaras y un atributo que indica la camara actual. Tambien se agregan\r
+              métodos para cambiar la cámara actual, etc.\r
+              Se arregla el destructor que no liberaba todos los objetos.\r
+    09/12/00: Se reemplaza la vista del misil por una mas general (vista del arma) que permite ver a traves de\r
+              cualquier arma disparada. Se implementa correctamente esta vista.\r
+              Se agrega una vista tipo mapa. \r
+    </PRE><BR><BR>\r
+<B>Classes:</B><BR>\r
+<A HREF=cVista.html>cVista</A>\r
+: Interpreta y dibuja los datos del modelo en un formulario<BR>\r
+<BR><B>Functions:</B>\r
+<dl>\r
+</dl></HTML>\r
diff --git a/doc/ref/algowars.ddp b/doc/ref/algowars.ddp
new file mode 100644 (file)
index 0000000..122ffad
--- /dev/null
@@ -0,0 +1,30 @@
+[SETUP]\r
+OutputDir=D:\develop\delphi\algowars\doc\ref\\r
+DescriptFile=D:\develop\delphi\algowars\doc\ref\Descripcion.html\r
+ParsePrivate=0\r
+\r
+[FILES]\r
+File0=D:\develop\delphi\algowars\src\Vectores.pas\r
+File1=D:\develop\delphi\algowars\src\Coordenadas.pas\r
+File2=D:\develop\delphi\algowars\src\Espacio.pas\r
+File3=D:\develop\delphi\algowars\src\Objeto.pas\r
+File4=D:\develop\delphi\algowars\src\Tipos.pas\r
+File5=D:\develop\delphi\algowars\src\Camara.pas\r
+File6=D:\develop\delphi\algowars\src\ov\ObjetoVolador.pas\r
+File7=D:\develop\delphi\algowars\src\ov\Meteorito.pas\r
+File8=D:\develop\delphi\algowars\src\ov\Armas.pas\r
+File9=D:\develop\delphi\algowars\src\ov\naves\NavesEnemigas.pas\r
+File10=D:\develop\delphi\algowars\src\ov\naves\NaveEnemiga.pas\r
+File11=D:\develop\delphi\algowars\src\ov\naves\NavePropia.pas\r
+File12=D:\develop\delphi\algowars\src\ov\naves\Nave.pas\r
+File13=D:\develop\delphi\algowars\src\RegExpr.pas\r
+File14=D:\develop\delphi\algowars\src\Vista.pas\r
+File15=D:\develop\delphi\algowars\src\forms\FormConfig.pas\r
+File16=D:\develop\delphi\algowars\src\forms\FormMain.pas\r
+File17=D:\develop\delphi\algowars\src\SerializacionUtils.pas\r
+File18=D:\develop\delphi\algowars\src\Lista.pas\r
+File19=D:\develop\delphi\algowars\src\ObjetoPersistente.pas\r
+File20=D:\develop\delphi\algowars\src\Filtro.pas\r
+File21=D:\develop\delphi\algowars\src\Filtros.pas\r
+File22=D:\develop\delphi\algowars\src\Camaras.pas\r
+\r
diff --git a/doc/ref/cArma.html b/doc/ref/cArma.html
new file mode 100644 (file)
index 0000000..5b34146
--- /dev/null
@@ -0,0 +1,157 @@
+<HTML>\r
+<H2>Class: cArma</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                         <A HREF=cObjetoVolador.html>cObjetoVolador</A> ----+\r                                                            |\r                                                          cArma\r</pre><hr>\r
+<B>Description:</B><BR>La clase cArma esta pensada como una clase abtracta. En ella se encuentran\r
+      características comunes a todas las armas.\r
+<p><B>Unit:</B><BR><A HREF=Armas.html>Armas</A>\r
+<code>   <A HREF=Armas.pas>(Armas.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cArma.html#0">constructor create( pos: cVector = nil; vel: cVector = nil; dim: tLongitud = 1;</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cArma.html#1">function mActivo: boolean;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve true si el arma todavia tiene alcance\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cArma.html#2">procedure mActualizarDuracion( dt: tTiempo );</A><BR>\r
+</dt>\r
+<dd>\r
+Actualiza el alcance del arma, que va disminuyendo a medida que pasa el tiempo\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cArma.html#3">procedure mDesSerializar( str: string ); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cArma.html#4">function mGetAlcance: tLongitud;</A><BR>\r
+</dt>\r
+<dd>\r
+Método para obtener el alcance del arma\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cArma.html#5">function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cArma.html#6">function mGetVelMax:  tLongitud;</A><BR>\r
+</dt>\r
+<dd>\r
+Método para obtener el alcance del arma\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cArma.html#7">procedure mMover( dt: tTiempo ); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado, se sobreescribe porque se le agrega alguna funcionalidad\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cArma.html#8">function mSerializar: string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve una cadena de texto con el objeto serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cArma.html#9">procedure mSetAlcance( alc: tLongitud );</A><BR>\r
+</dt>\r
+<dd>\r
+Método para obtener el alcance del arma\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( pos: cVector = nil; vel: cVector = nil; dim: tLongitud = 1;</CODE>\r
+<dl>\r
+<dd>Este constructor es protegido porque solo va a ser utilizado por subclases\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pos </CODE> :     Posicion inicial</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>vel </CODE> :     Velocidad inicial</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>dim </CODE> :     Dimensión del objeto volador (radio, en metros)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pot </CODE> :     Potencia del objeto volador (cantidad de daño que hace por intervalode tiempo)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ene </CODE> :     Energía del objeto volador(cantidad de daño que soporta antes de ser destruido)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>alcance </CODE> : Tiempo que debe pasar para que el arma se destruya si no impactó con ningún objeto volador</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mActivo: boolean;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;<i>true</i> si todavía tiene alcance, <i>false</i> si no</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="2"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mActualizarDuracion( dt: tTiempo );</CODE>\r
+<dl>\r
+<dd>Actualiza el alcance del arma, que va disminuyendo a medida que pasa el tiempo\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>dt </CODE> : Intervalo de tiempo</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="3"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mDesSerializar( str: string ); override;</CODE>\r
+<dl>\r
+<dd>Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>str </CODE> : Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="4"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetAlcance: tLongitud;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Alcance del arma</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="5"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</CODE>\r
+<dl>\r
+<dd>Devuelve el estado del objeto basandose en la cantidad de datos requeridos.\r
+    @return            Cadena de texto con el estado del Objeto.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>debugLevel </CODE> : Cantidad de información requerida</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="6"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetVelMax:  tLongitud;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Velocidad maxima del arma</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="7"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mMover( dt: tTiempo ); override;</CODE>\r
+<dl>\r
+<dd>Mueve el arma basado en su posición y velocidad actual y un intervalo de tiempo\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>dt </CODE> : Intervalo de tiempo</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="8"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSerializar: string; override;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="9"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mSetAlcance( alc: tLongitud );</CODE>\r
+<dl>\r
+<dd>Método para establecer el alcance del arma\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>alc </CODE> : Alcance del arma</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cCamara.html b/doc/ref/cCamara.html
new file mode 100644 (file)
index 0000000..7b38baa
--- /dev/null
@@ -0,0 +1,159 @@
+<HTML>\r
+<H2>Class: cCamara</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                               cCamara\r</pre><hr>\r
+<B>Description:</B><BR>Implementa una cámara que se encarga de representar los objetos en 2D.\r
+<p><B>Unit:</B><BR><A HREF=Camara.html>Camara</A>\r
+<code>   <A HREF=Camara.pas>(Camara.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCamara.html#0">constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 ); overload;</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cCamara.html#1">function mGetCameraman: cObjetoVolador;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve el objeto portador de la cámara\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCamara.html#2">function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cCamara.html#3">function mGetDistPantalla: tLongitud;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve distancia a la pantalla\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cCamara.html#4">function mGetRadioMaximo: tLongitud;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve el radio máximo de detección\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cCamara.html#5">function mGetRadioMinimo: tLongitud;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve el radio mínimo de detección\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCamara.html#6">function mGetRadioPantalla: tLongitud;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene el radio de la pantalla\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCamara.html#7">function mProcesar( l: TList ): cLista;</A><BR>\r
+</dt>\r
+<dd>\r
+Procesa una lista de objetos, devolviendo solo los visibles en una lista de records tProyectado\r
+          ordenada ascendentemente por el tamaño proporcional (es decir, el objeto de tamaño menor está primero en la lista).\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cCamara.html#8">procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); virtual; abstract;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la proyección del objeto volador en X, Y\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cCamara.html#9">procedure mSetCameraman( oOV: cObjetoVOlador );</A><BR>\r
+</dt>\r
+<dd>\r
+Permite asignar un nuevo portador de la cámara\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 ); overload;</CODE>\r
+<dl>\r
+<dd>Contructor\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>cameraman </CODE> : Objeto Volador en el que estará montada la cámara (obligatorio)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>angulo </CODE> :         Angulo de apertura (visión) de la cámara (default = pi/4)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>maximo </CODE> :         Distancia máxima en la que se considera visible a un objeto (default = 5000)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>distPantalla </CODE> :   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default\r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mGetCameraman: cObjetoVolador;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Objeto portador de la cámara</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="2"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</CODE>\r
+<dl>\r
+<dd>Devuelve el estado del objeto basandose en la cantidad de datos requeridos:<br>\r
+    Siempre devuelve los valores de las componentes x, y, z y si debugLevel es mayor que DI_NORMAL,\r
+    también muestra el módulo.\r
+    @return             Cadena de texto con el estado del Objeto.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>debugLevel </CODE> : Cantidad de información requerida</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="3"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mGetDistPantalla: tLongitud;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Distancia a la pantalla</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="4"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mGetRadioMaximo: tLongitud;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Radio mínimo de detección</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="5"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mGetRadioMinimo: tLongitud;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Radio máximo de detección</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="6"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetRadioPantalla: tLongitud;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Radio de la pantalla</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="7"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mProcesar( l: TList ): cLista;</CODE>\r
+<dl>\r
+<dd>Procesa una lista de objetos, devolviendo solo los visibles en una lista de records tProyectado\r
+    ordenada ascendentemente por el tamaño proporcional (es decir, el objeto de tamaño menor está primero en la lista).\r
+    @return  Lista con los objetos visibles y sus posiciones y tamaños, en un registro\r
+             del tipo <i>tProyectado</i>, ordenados de forma ascendente según el tamaño.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>l </CODE> : Lista con los objetos a procesar</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="8"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); virtual; abstract;</CODE>\r
+<dl>\r
+<dd>Obtiene la proyección del objeto volador en X, Y</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="9"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mSetCameraman( oOV: cObjetoVOlador );</CODE>\r
+<dl>\r
+<dd>Permite asignar un nuevo portador de la cámara\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>oOV </CODE> : Objeto volador que será en nuevo portador de la cámara</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cCamaraAbajo.html b/doc/ref/cCamaraAbajo.html
new file mode 100644 (file)
index 0000000..df78954
--- /dev/null
@@ -0,0 +1,46 @@
+<HTML>\r
+<H2>Class: cCamaraAbajo</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                               <A HREF=cCamara.html>cCamara</A> ----+\r                                           |\r                                     cCamaraAbajo\r</pre><hr>\r
+<B>Description:</B><BR>Implementa una cámara para ver hacia abajo.\r
+<p><B>Unit:</B><BR><A HREF=Camaras.html>Camaras</A>\r
+<code>   <A HREF=Camaras.pas>(Camaras.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCamaraAbajo.html#0">constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cCamaraAbajo.html#1">procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la proyección del objeto volador en X, Y\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );</CODE>\r
+<dl>\r
+<dd>Contructor\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>cameraman </CODE> : Objeto Volador en el que estará montada la cámara (obligatorio)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>angulo </CODE> :         Angulo de apertura (visión) de la cámara (default = pi/4)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>maximo </CODE> :         Distancia máxima en la que se considera visible a un objeto (default = 5000)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>distPantalla </CODE> :   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default\r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;</CODE>\r
+<dl>\r
+<dd>Obtiene la proyección del objeto volador en X, Y\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> :  Objeto volador a proyectar.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>x </CODE> :   Valor de la proyección en X.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>x </CODE> :   Valor de la proyección en Y.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>tam </CODE> : Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es).\r
+               Varia entre 0 y 1</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cCamaraArriba.html b/doc/ref/cCamaraArriba.html
new file mode 100644 (file)
index 0000000..bcd2712
--- /dev/null
@@ -0,0 +1,46 @@
+<HTML>\r
+<H2>Class: cCamaraArriba</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                               <A HREF=cCamara.html>cCamara</A> ----+\r                                           |\r                                     cCamaraArriba\r</pre><hr>\r
+<B>Description:</B><BR>Implementa una cámara para ver hacia arriba.\r
+<p><B>Unit:</B><BR><A HREF=Camaras.html>Camaras</A>\r
+<code>   <A HREF=Camaras.pas>(Camaras.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCamaraArriba.html#0">constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cCamaraArriba.html#1">procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la proyección del objeto volador en X, Y\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );</CODE>\r
+<dl>\r
+<dd>Contructor\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>cameraman </CODE> : Objeto Volador en el que estará montada la cámara (obligatorio)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>angulo </CODE> :         Angulo de apertura (visión) de la cámara (default = pi/4)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>maximo </CODE> :         Distancia máxima en la que se considera visible a un objeto (default = 5000)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>distPantalla </CODE> :   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default\r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;</CODE>\r
+<dl>\r
+<dd>Obtiene la proyección del objeto volador en X, Y\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> :  Objeto volador a proyectar.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>x </CODE> :   Valor de la proyección en X.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>x </CODE> :   Valor de la proyección en Y.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>tam </CODE> : Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es).\r
+               Varia entre 0 y 1</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cCamaraFrontal.html b/doc/ref/cCamaraFrontal.html
new file mode 100644 (file)
index 0000000..79e0aa3
--- /dev/null
@@ -0,0 +1,46 @@
+<HTML>\r
+<H2>Class: cCamaraFrontal</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                               <A HREF=cCamara.html>cCamara</A> ----+\r                                           |\r                                    cCamaraFrontal\r</pre><hr>\r
+<B>Description:</B><BR>Implementa una cámara frontal.\r
+<p><B>Unit:</B><BR><A HREF=Camaras.html>Camaras</A>\r
+<code>   <A HREF=Camaras.pas>(Camaras.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCamaraFrontal.html#0">constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cCamaraFrontal.html#1">procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la proyección del objeto volador en X, Y\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );</CODE>\r
+<dl>\r
+<dd>Contructor\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>cameraman </CODE> : Objeto Volador en el que estará montada la cámara (obligatorio)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>angulo </CODE> :         Angulo de apertura (visión) de la cámara (default = pi/4)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>maximo </CODE> :         Distancia máxima en la que se considera visible a un objeto (default = 5000)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>distPantalla </CODE> :   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default\r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;</CODE>\r
+<dl>\r
+<dd>Obtiene la proyección del objeto volador en X, Y\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> :  Objeto volador a proyectar.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>x </CODE> :   Valor de la proyección en X.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>x </CODE> :   Valor de la proyección en Y.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>tam </CODE> : Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es).\r
+               Varia entre 0 y 1</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cCamaraLatDer.html b/doc/ref/cCamaraLatDer.html
new file mode 100644 (file)
index 0000000..952bf97
--- /dev/null
@@ -0,0 +1,46 @@
+<HTML>\r
+<H2>Class: cCamaraLatDer</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                               <A HREF=cCamara.html>cCamara</A> ----+\r                                           |\r                                     cCamaraLatDer\r</pre><hr>\r
+<B>Description:</B><BR>Implementa una cámara lateral derecha.\r
+<p><B>Unit:</B><BR><A HREF=Camaras.html>Camaras</A>\r
+<code>   <A HREF=Camaras.pas>(Camaras.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cCamaraLatDer.html#0">constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cCamaraLatDer.html#1">procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la proyección del objeto volador en X, Y\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );</CODE>\r
+<dl>\r
+<dd>Contructor\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>cameraman </CODE> : Objeto Volador en el que estará montada la cámara (obligatorio)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>angulo </CODE> :         Angulo de apertura (visión) de la cámara (default = pi/4)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>maximo </CODE> :         Distancia máxima en la que se considera visible a un objeto (default = 5000)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>distPantalla </CODE> :   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default\r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;</CODE>\r
+<dl>\r
+<dd>Obtiene la proyección del objeto volador en X, Y\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> :  Objeto volador a proyectar.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>x </CODE> :   Valor de la proyección en X.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>x </CODE> :   Valor de la proyección en Y.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>tam </CODE> : Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es).\r
+               Varia entre 0 y 1</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cCamaraLatIzq.html b/doc/ref/cCamaraLatIzq.html
new file mode 100644 (file)
index 0000000..f3b902a
--- /dev/null
@@ -0,0 +1,46 @@
+<HTML>\r
+<H2>Class: cCamaraLatIzq</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                               <A HREF=cCamara.html>cCamara</A> ----+\r                                           |\r                                     cCamaraLatIzq\r</pre><hr>\r
+<B>Description:</B><BR>Implementa una cámara lateral izquierda.\r
+<p><B>Unit:</B><BR><A HREF=Camaras.html>Camaras</A>\r
+<code>   <A HREF=Camaras.pas>(Camaras.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCamaraLatIzq.html#0">constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cCamaraLatIzq.html#1">procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la proyección del objeto volador en X, Y\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );</CODE>\r
+<dl>\r
+<dd>Contructor\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>cameraman </CODE> : Objeto Volador en el que estará montada la cámara (obligatorio)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>angulo </CODE> :         Angulo de apertura (visión) de la cámara (default = pi/4)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>maximo </CODE> :         Distancia máxima en la que se considera visible a un objeto (default = 5000)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>distPantalla </CODE> :   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default\r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;</CODE>\r
+<dl>\r
+<dd>Obtiene la proyección del objeto volador en X, Y\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> :  Objeto volador a proyectar.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>x </CODE> :   Valor de la proyección en X.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>x </CODE> :   Valor de la proyección en Y.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>tam </CODE> : Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es).\r
+               Varia entre 0 y 1</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cCamaraMapa.html b/doc/ref/cCamaraMapa.html
new file mode 100644 (file)
index 0000000..6821e52
--- /dev/null
@@ -0,0 +1,47 @@
+<HTML>\r
+<H2>Class: cCamaraMapa</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                               <A HREF=cCamara.html>cCamara</A> ----+\r                                           |\r                                      cCamaraMapa\r</pre><hr>\r
+<B>Description:</B><BR>Implementa una cámara para ver hacia abajo pero alejado del cameraman.\r
+      Es como si observara al cameraman desde arriba.\r
+<p><B>Unit:</B><BR><A HREF=Camaras.html>Camaras</A>\r
+<code>   <A HREF=Camaras.pas>(Camaras.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCamaraMapa.html#0">constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cCamaraMapa.html#1">procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la proyección del objeto volador en X, Y\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );</CODE>\r
+<dl>\r
+<dd>Contructor\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>cameraman </CODE> : Objeto Volador en el que estará montada la cámara (obligatorio)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>angulo </CODE> :         Angulo de apertura (visión) de la cámara (default = pi/4)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>maximo </CODE> :         Distancia máxima en la que se considera visible a un objeto (default = 5000)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>distPantalla </CODE> :   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default\r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;</CODE>\r
+<dl>\r
+<dd>Obtiene la proyección del objeto volador en X, Y\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> :  Objeto volador a proyectar.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>x </CODE> :   Valor de la proyección en X.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>x </CODE> :   Valor de la proyección en Y.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>tam </CODE> : Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es).\r
+               Varia entre 0 y 1</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cCamaraTrasera.html b/doc/ref/cCamaraTrasera.html
new file mode 100644 (file)
index 0000000..2908534
--- /dev/null
@@ -0,0 +1,46 @@
+<HTML>\r
+<H2>Class: cCamaraTrasera</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                               <A HREF=cCamara.html>cCamara</A> ----+\r                                           |\r                                    cCamaraTrasera\r</pre><hr>\r
+<B>Description:</B><BR>Implementa una cámara trasera.\r
+<p><B>Unit:</B><BR><A HREF=Camaras.html>Camaras</A>\r
+<code>   <A HREF=Camaras.pas>(Camaras.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCamaraTrasera.html#0">constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cCamaraTrasera.html#1">procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la proyección del objeto volador en X, Y\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );</CODE>\r
+<dl>\r
+<dd>Contructor\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>cameraman </CODE> : Objeto Volador en el que estará montada la cámara (obligatorio)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>angulo </CODE> :         Angulo de apertura (visión) de la cámara (default = pi/4)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>maximo </CODE> :         Distancia máxima en la que se considera visible a un objeto (default = 5000)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>distPantalla </CODE> :   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default\r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;</CODE>\r
+<dl>\r
+<dd>Obtiene la proyección del objeto volador en X, Y\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> :  Objeto volador a proyectar.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>x </CODE> :   Valor de la proyección en X.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>x </CODE> :   Valor de la proyección en Y.</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>tam </CODE> : Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es).\r
+               Varia entre 0 y 1</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cCoordenadas.html b/doc/ref/cCoordenadas.html
new file mode 100644 (file)
index 0000000..4eec13f
--- /dev/null
@@ -0,0 +1,239 @@
+<HTML>\r
+<H2>Class: cCoordenadas</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                          cCoordenadas\r</pre><hr>\r
+<B>Description:</B><BR>Implementa un sistema de coordenadas y metodos para rotarlo.\r
+<p><B>Unit:</B><BR><A HREF=Coordenadas.html>Coordenadas</A>\r
+<code>   <A HREF=Coordenadas.pas>(Coordenadas.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCoordenadas.html#0">constructor create( c: cCoordenadas ); overload;</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor que se basa en otro sistema de coordenadas\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCoordenadas.html#1">constructor create; overload;</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCoordenadas.html#2">destructor destroy; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Destructor\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCoordenadas.html#3">procedure mDesSerializar( str: string ); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCoordenadas.html#4">function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCoordenadas.html#5">function mGetI: cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene el versor i\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCoordenadas.html#6">function mGetJ: cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene el versor j\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCoordenadas.html#7">function mGetK: cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene el versor k\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCoordenadas.html#8">function mRotarEnI( dAngulo: tAngulo ): cCoordenadas;</A><BR>\r
+</dt>\r
+<dd>\r
+Rota el sistema de coordenadas sobre el eje i\r
+          (el sentido positivo es de j a k)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCoordenadas.html#9">function mRotarEnJ( dAngulo: tAngulo ): cCoordenadas;</A><BR>\r
+</dt>\r
+<dd>\r
+Rota el sistema de coordenadas sobre el eje j\r
+          (el sentido positivo es de i a k)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCoordenadas.html#10">function mRotarEnK( dAngulo: tAngulo ): cCoordenadas;</A><BR>\r
+</dt>\r
+<dd>\r
+Rota el sistema de coordenadas sobre el eje k\r
+          (el sentido positivo es de i a j)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCoordenadas.html#11">function mSerializar: string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve una cadena de texto con el objeto serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCoordenadas.html#12">function mSetI( v: cVector ): cCoordenadas;</A><BR>\r
+</dt>\r
+<dd>\r
+Setea la dirección del versor î igual que la del vector v.\r
+          Para lograr esto, rota primero sobre el eje k y luego sobre el eje j\r
+          (no se rota sobre el eje î).\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCoordenadas.html#13">function mSetJ( v: cVector ): cCoordenadas;</A><BR>\r
+</dt>\r
+<dd>\r
+Setea la dirección del versor j igual que la del vector v.\r
+          Para lograr esto, rota primero sobre el eje î y luego sobre el eje k\r
+          (no se rota sobre el eje j).\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cCoordenadas.html#14">function mSetK( v: cVector ): cCoordenadas;</A><BR>\r
+</dt>\r
+<dd>\r
+Setea la dirección del versor k igual que la del vector v.\r
+          Para lograr esto, rota primero sobre el eje j y luego sobre el eje î\r
+          (no se rota sobre el eje k).\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( c: cCoordenadas ); overload;</CODE>\r
+<dl>\r
+<dd>Constructor que se basa en otro sistema de coordenadas\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>c </CODE> : Coordenadas en las que se basa para crear las nuevas</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create; overload;</CODE>\r
+<dl>\r
+<dd>Constructor</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="2"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>destructor destroy; override;</CODE>\r
+<dl>\r
+<dd>Destructor</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="3"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mDesSerializar( str: string ); override;</CODE>\r
+<dl>\r
+<dd>Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>str </CODE> : Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="4"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</CODE>\r
+<dl>\r
+<dd>Devuelve el estado del objeto basandose en la cantidad de datos requeridos.\r
+    @return            Cadena de texto con el estado del Objeto.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>debugLevel </CODE> : Cantidad de información requerida</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="5"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetI: cVector;</CODE>\r
+<dl>\r
+<dd>Obtiene el versor i</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="6"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetJ: cVector;</CODE>\r
+<dl>\r
+<dd>Obtiene el versor j</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="7"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetK: cVector;</CODE>\r
+<dl>\r
+<dd>Obtiene el versor k</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="8"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mRotarEnI( dAngulo: tAngulo ): cCoordenadas;</CODE>\r
+<dl>\r
+<dd>Rota el sistema de coordenadas sobre el eje i\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>angulo </CODE> : Ángulo a rotar</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="9"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mRotarEnJ( dAngulo: tAngulo ): cCoordenadas;</CODE>\r
+<dl>\r
+<dd>Rota el sistema de coordenadas sobre el eje j\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>angulo </CODE> : Ángulo a rotar</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="10"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mRotarEnK( dAngulo: tAngulo ): cCoordenadas;</CODE>\r
+<dl>\r
+<dd>Rota el sistema de coordenadas sobre el eje k\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>angulo </CODE> : Ángulo a rotar</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="11"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSerializar: string; override;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="12"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSetI( v: cVector ): cCoordenadas;</CODE>\r
+<dl>\r
+<dd>Setea la dirección del versor î igual que la del vector v.\r
+    Para lograr esto, rota primero sobre el eje k y luego sobre el eje j\r
+    (no se rota sobre el eje î).\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>v </CODE> : Dirección a asignarle a î (no puede ser nulo!)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="13"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSetJ( v: cVector ): cCoordenadas;</CODE>\r
+<dl>\r
+<dd>Setea la dirección del versor j igual que la del vector v.\r
+    Para lograr esto, rota primero sobre el eje î y luego sobre el eje k\r
+    (no se rota sobre el eje j).\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>v </CODE> : Dirección a asignarle a j (no puede ser nulo!)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="14"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSetK( v: cVector ): cCoordenadas;</CODE>\r
+<dl>\r
+<dd>Setea la dirección del versor k igual que la del vector v.\r
+    Para lograr esto, rota primero sobre el eje j y luego sobre el eje î\r
+    (no se rota sobre el eje k).\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>v </CODE> : Dirección a asignarle a k (no puede ser nulo!)</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cEspacio.html b/doc/ref/cEspacio.html
new file mode 100644 (file)
index 0000000..e4e8055
--- /dev/null
@@ -0,0 +1,272 @@
+<HTML>\r
+<H2>Class: cEspacio</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                            cEspacio\r</pre><hr>\r
+<B>Description:</B><BR>Se encarga de controlar la interacción entre\r
+      las naves y el responsable de manejar el tiempo.\r
+<p><B>Unit:</B><BR><A HREF=Espacio.html>Espacio</A>\r
+<code>   <A HREF=Espacio.pas>(Espacio.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cEspacio.html#0">constructor create( np: cNavePropia = nil; objetos: TList = nil; dt: tTiempo = 25 );</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor. La lista que se pasa NO debe incluir la nave propia\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cEspacio.html#1">destructor destroy; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Destructor\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cEspacio.html#2">procedure mActualizar;</A><BR>\r
+</dt>\r
+<dd>\r
+Actualiza el Espacio. En esto se incluye mover las naves, detectar colisiones y tomar las\r
+          desiciones necesarias según sea el caso.\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cEspacio.html#3">procedure mActualizarObjetoVolador( ov: cObjetoVolador );</A><BR>\r
+</dt>\r
+<dd>\r
+Actualiza el estado de un objeto según sea tu tipo\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cEspacio.html#4">procedure mAgregarObjeto( ov: cObjetoVolador );</A><BR>\r
+</dt>\r
+<dd>\r
+Agrega un Objeto Volador al Espacio\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cEspacio.html#5">function mBuscarDuplicado( ov: cObjetoVolador ): cObjetoVolador;</A><BR>\r
+</dt>\r
+<dd>\r
+Busca el duplicado de un objeto volador\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cEspacio.html#6">procedure mComunicarPosicion( nEsp: cNaveEspia );</A><BR>\r
+</dt>\r
+<dd>\r
+Método que se encarga de avisar al resto de las naves enemigas que estan cerca de una\r
+          espia sobre la ultima posicion de la nave propia.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cEspacio.html#7">procedure mDesSerializar( str: string ); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cEspacio.html#8">procedure mDestruir( ov: cObjetoVolador );</A><BR>\r
+</dt>\r
+<dd>\r
+Destruye un Objeto Volador\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cEspacio.html#9">procedure mDetectarColision;</A><BR>\r
+</dt>\r
+<dd>\r
+Procedimiento que evalua las posiciones de los Objetos Voladores que se encuentran en el espacio,\r
+          verificando 2 a 2 si hay una colisión.\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cEspacio.html#10">procedure mEliminarDuplicados;</A><BR>\r
+</dt>\r
+<dd>\r
+Elimina los objetos duplicados después de recuperarlos de una serialización\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cEspacio.html#11">function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cEspacio.html#12">function mGetNavePropia: cNavePropia;</A><BR>\r
+</dt>\r
+<dd>\r
+Método que obtiene la nave propia del espacio (este método es probable que deje de exstir)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cEspacio.html#13">function mGetObjetos: TList;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la lista de Objetos Voladores del Espacio\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cEspacio.html#14">function mQuitarObjeto( ov: cObjetoVolador ): boolean;</A><BR>\r
+</dt>\r
+<dd>\r
+Quita un Objeto Volador del Espacio. Devuelve true si lo saco y false si no existia\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cEspacio.html#15">function mSerializar: string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve una cadena de texto con el objeto serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cEspacio.html#16">function mSetNavePropia( np: cNavePropia ): cNavePropia;</A><BR>\r
+</dt>\r
+<dd>\r
+Método para cambiar la nave propia. Devuelve un puntero a la nave propia vieja.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cEspacio.html#17">function mSetObjetos( l: TList ): TList;</A><BR>\r
+</dt>\r
+<dd>\r
+Cambia la lista de Objetos Voladores del Espacio, devolviendo un puntero a la lista vieja\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( np: cNavePropia = nil; objetos: TList = nil; dt: tTiempo = 25 );</CODE>\r
+<dl>\r
+<dd>Constructor\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>np </CODE> :      Nave propia a utilizar</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>objetos </CODE> : Lista de objetos voladores (sin incluir la nave propia!)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>dt </CODE> :      Intervalo de tiempo</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>destructor destroy; override;</CODE>\r
+<dl>\r
+<dd>Destructor</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="2"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mActualizar;</CODE>\r
+<dl>\r
+<dd>Actualiza el Espacio. En esto se incluye mover las naves, detectar colisiones y tomar las\r
+          desiciones necesarias según sea el caso.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="3"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mActualizarObjetoVolador( ov: cObjetoVolador );</CODE>\r
+<dl>\r
+<dd>Actualiza el estado de un objeto volador, dependiendo de que tipo de objeto sea.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> : Objeto Volador a actualizar</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="4"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mAgregarObjeto( ov: cObjetoVolador );</CODE>\r
+<dl>\r
+<dd>Agrega un Objeto Volador al Espacio\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> : Objeto volador a agregar</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="5"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mBuscarDuplicado( ov: cObjetoVolador ): cObjetoVolador;</CODE>\r
+<dl>\r
+<dd>Busca el duplicado de un objeto volador\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> : Objeto volador al cual se le quiere encontrar un duplicado</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Objeto Volador duplicado de ov</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="6"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mComunicarPosicion( nEsp: cNaveEspia );</CODE>\r
+<dl>\r
+<dd>Método que se encarga de avisar al resto de las naves enemigas que estan cerca de una\r
+    espia sobre la ultima posicion de la nave propia.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>nEsp </CODE> : Nave espía que está avisando</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="7"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mDesSerializar( str: string ); override;</CODE>\r
+<dl>\r
+<dd>Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>str </CODE> : Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="8"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mDestruir( ov: cObjetoVolador );</CODE>\r
+<dl>\r
+<dd>Destruye un objeto volador, liberando memoria y eliminandolo de la lista\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> : Objeto Volador a destruir</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="9"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mDetectarColision;</CODE>\r
+<dl>\r
+<dd>Procedimiento que evalua las posiciones de los Objetos Voladores que se encuentran en el espacio,\r
+          verificando 2 a 2 si hay una colisión.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="10"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mEliminarDuplicados;</CODE>\r
+<dl>\r
+<dd>Elimina los objetos duplicados después de recuperarlos de una serialización</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="11"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</CODE>\r
+<dl>\r
+<dd>Devuelve el estado del objeto basandose en la cantidad de datos requeridos.\r
+    @return            Cadena de texto con el estado del Objeto.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>debugLevel </CODE> : Cantidad de información requerida</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="12"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetNavePropia: cNavePropia;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Instancia de la nave propia que se encuentra en el espacio (como puntero)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="13"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetObjetos: TList;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Lista de objetos del espacio (como puntero)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="14"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mQuitarObjeto( ov: cObjetoVolador ): boolean;</CODE>\r
+<dl>\r
+<dd>Quita un Objeto Volador del Espacio. Devuelve true si lo saco y false si no existia\r
+    (esto lo quita del espacio, no lo destruye)\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> : Objeto a quitar del espacio</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;<i>true</i> si se quitó, <i>false</i> si no estaba en el espacio</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="15"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSerializar: string; override;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="16"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSetNavePropia( np: cNavePropia ): cNavePropia;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Lista de objetos del espacio (como puntero)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="17"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSetObjetos( l: TList ): TList;</CODE>\r
+<dl>\r
+<dd>Cambia la lista de Objetos Voladores del Espacio, devolviendo un puntero a la lista vieja\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>l </CODE> : Nueva lista de objetos a asignarle al espacio</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Vieja lista de objetos del espacio</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cFiltro.html b/doc/ref/cFiltro.html
new file mode 100644 (file)
index 0000000..84597d7
--- /dev/null
@@ -0,0 +1,173 @@
+<HTML>\r
+<H2>Class: cFiltro</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                             cFiltro\r</pre><hr>\r
+<B>Description:</B><BR>Es una clase abstracta que representa un filtro que recibe una lista de objetos y devuelve otra filtrada.\r
+<p><B>Unit:</B><BR><A HREF=Filtro.html>Filtro</A>\r
+<code>   <A HREF=Filtro.pas>(Filtro.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cFiltro.html#0">constructor create( observador: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; minimo: tLongitud = -1 );</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cFiltro.html#1">procedure mDesSerializar( str: string ); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cFiltro.html#2">function mFiltrar( l: TList ): TList;</A><BR>\r
+</dt>\r
+<dd>\r
+Procesa una lista de objetos, devolviendo solo los visibles en una lista ordenada ascendentemente por la distancia\r
+          (es decir, el objeto más cercano está primero en la lista).\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cFiltro.html#3">function mGetCosApertura: tAngulo;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene el coseno de la apertura\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cFiltro.html#4">function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cFiltro.html#5">function mGetObservador: cObjetoVolador;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene un puntero al observador\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cFiltro.html#6">function mGetRadioMaximo: tLongitud;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene el radio máximo\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cFiltro.html#7">function mGetRadioMinimo: tLongitud;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene el radio mínimo\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cFiltro.html#8">function mSerializar: string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve una cadena de texto con el objeto serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cFiltro.html#9">procedure mSetObservador( ov: cObjetoVolador );</A><BR>\r
+</dt>\r
+<dd>\r
+Establece el observador con un nuevo puntero\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cFiltro.html#10">function mVisible( ov: cObjetoVolador ): boolean; virtual; abstract;</A><BR>\r
+</dt>\r
+<dd>\r
+Verifica que un objeto volador pueda ser visto por la cámara\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( observador: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; minimo: tLongitud = -1 );</CODE>\r
+<dl>\r
+<dd>Contructor\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>observador </CODE> : Objeto Volador en el que estará montado el filtro (obligatorio)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>angulo </CODE> :     Angulo de apertura (visión) del filtro (default = pi/4)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>maximo </CODE> :     Distancia máxima en la que se considera visible a un objeto (default = 5000)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>minimo </CODE> :     Distancia mínima en la que se considera visible a un objeto (default = -1).\r
+                      Si se especifica un valor negativo o cero, se toma la dimension del objeto volador</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mDesSerializar( str: string ); override;</CODE>\r
+<dl>\r
+<dd>Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>str </CODE> : Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="2"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mFiltrar( l: TList ): TList;</CODE>\r
+<dl>\r
+<dd>Filtra una lista de objetos, devolviendo solo los visibles.\r
+    @return  Lista con los objetos visibles.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>l </CODE> : Lista con los objetos a procesar.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="3"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mGetCosApertura: tAngulo;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Coseno de la apertura</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="4"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</CODE>\r
+<dl>\r
+<dd>Devuelve el estado del objeto basandose en la cantidad de datos requeridos:<br>\r
+    Siempre devuelve los valores de las componentes x, y, z y si debugLevel es mayor que DI_NORMAL,\r
+    también muestra el módulo.\r
+    @return             Cadena de texto con el estado del Objeto.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>debugLevel </CODE> : Cantidad de información requerida</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="5"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetObservador: cObjetoVolador;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Puntero al obervador</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="6"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mGetRadioMaximo: tLongitud;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Radio máximo</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="7"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mGetRadioMinimo: tLongitud;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Radio mínimo</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="8"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSerializar: string; override;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="9"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mSetObservador( ov: cObjetoVolador );</CODE>\r
+<dl>\r
+<dd>Establece el observador con un nuevo puntero\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>Puntero </CODE> : al nuevo obervador</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="10"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mVisible( ov: cObjetoVolador ): boolean; virtual; abstract;</CODE>\r
+<dl>\r
+<dd>Verifica que un objeto volador pueda ser visto por la cámara</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cFiltroAbajo.html b/doc/ref/cFiltroAbajo.html
new file mode 100644 (file)
index 0000000..ff72985
--- /dev/null
@@ -0,0 +1,25 @@
+<HTML>\r
+<H2>Class: cFiltroAbajo</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                             <A HREF=cFiltro.html>cFiltro</A> ----+\r                                                         |\r                                                   cFiltroAbajo\r</pre><hr>\r
+<B>Description:</B><BR>Implementa un filtro que "ve" hacia abajo.\r
+<p><B>Unit:</B><BR><A HREF=Filtros.html>Filtros</A>\r
+<code>   <A HREF=Filtros.pas>(Filtros.pas)</code></A><BR><BR>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cFiltroAbajo.html#0">function mVisible( ov: cObjetoVolador ): boolean; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Verifica que un objeto volador pueda ser visto por la cámara\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mVisible( ov: cObjetoVolador ): boolean; override;</CODE>\r
+<dl>\r
+<dd>Verifica que un objeto volador pueda ser visto por la cámara</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cFiltroArriba.html b/doc/ref/cFiltroArriba.html
new file mode 100644 (file)
index 0000000..dda5f2b
--- /dev/null
@@ -0,0 +1,25 @@
+<HTML>\r
+<H2>Class: cFiltroArriba</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                             <A HREF=cFiltro.html>cFiltro</A> ----+\r                                                         |\r                                                   cFiltroArriba\r</pre><hr>\r
+<B>Description:</B><BR>Implementa un filtro que "ve" hacia arriba.\r
+<p><B>Unit:</B><BR><A HREF=Filtros.html>Filtros</A>\r
+<code>   <A HREF=Filtros.pas>(Filtros.pas)</code></A><BR><BR>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cFiltroArriba.html#0">function mVisible( ov: cObjetoVolador ): boolean; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Verifica que un objeto volador pueda ser visto por la cámara\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mVisible( ov: cObjetoVolador ): boolean; override;</CODE>\r
+<dl>\r
+<dd>Verifica que un objeto volador pueda ser visto por la cámara</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cFiltroFrontal.html b/doc/ref/cFiltroFrontal.html
new file mode 100644 (file)
index 0000000..a5a97ed
--- /dev/null
@@ -0,0 +1,26 @@
+<HTML>\r
+<H2>Class: cFiltroFrontal</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                             <A HREF=cFiltro.html>cFiltro</A> ----+\r                                                         |\r                                                  cFiltroFrontal\r</pre><hr>\r
+<B>Description:</B><BR>Implementa un filtro que "ve" hacia adelante.\r
+<p><B>Unit:</B><BR><A HREF=Filtros.html>Filtros</A>\r
+<code>   <A HREF=Filtros.pas>(Filtros.pas)</code></A><BR><BR>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cFiltroFrontal.html#0">function mVisible( ov: cObjetoVolador ): boolean; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Verifica que un objeto volador pueda ser visto por la cámara\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mVisible( ov: cObjetoVolador ): boolean; override;</CODE>\r
+<dl>\r
+<dd>Verifica que un objeto volador pueda ser visto por la cámara\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> : Objeto volador que se quiere verificar si es visto por la cámara.</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;<i>True</i> si lo ve, <i>False</i> si no.</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cFiltroLatDer.html b/doc/ref/cFiltroLatDer.html
new file mode 100644 (file)
index 0000000..2cd0d1d
--- /dev/null
@@ -0,0 +1,25 @@
+<HTML>\r
+<H2>Class: cFiltroLatDer</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                             <A HREF=cFiltro.html>cFiltro</A> ----+\r                                                         |\r                                                   cFiltroLatDer\r</pre><hr>\r
+<B>Description:</B><BR>Implementa un filtro que "ve" hacia la derecha.\r
+<p><B>Unit:</B><BR><A HREF=Filtros.html>Filtros</A>\r
+<code>   <A HREF=Filtros.pas>(Filtros.pas)</code></A><BR><BR>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cFiltroLatDer.html#0">function mVisible( ov: cObjetoVolador ): boolean; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Verifica que un objeto volador pueda ser visto por la cámara\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mVisible( ov: cObjetoVolador ): boolean; override;</CODE>\r
+<dl>\r
+<dd>Verifica que un objeto volador pueda ser visto por la cámara</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cFiltroLatIzq.html b/doc/ref/cFiltroLatIzq.html
new file mode 100644 (file)
index 0000000..35ece18
--- /dev/null
@@ -0,0 +1,26 @@
+<HTML>\r
+<H2>Class: cFiltroLatIzq</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                             <A HREF=cFiltro.html>cFiltro</A> ----+\r                                                         |\r                                                   cFiltroLatIzq\r</pre><hr>\r
+<B>Description:</B><BR>Implementa un filtro que "ve" hacia la izquierda.\r
+<p><B>Unit:</B><BR><A HREF=Filtros.html>Filtros</A>\r
+<code>   <A HREF=Filtros.pas>(Filtros.pas)</code></A><BR><BR>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cFiltroLatIzq.html#0">function mVisible( ov: cObjetoVolador ): boolean; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Verifica que un objeto volador pueda ser visto por la cámara\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mVisible( ov: cObjetoVolador ): boolean; override;</CODE>\r
+<dl>\r
+<dd>Verifica que un objeto volador pueda ser visto por la cámara\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> : Objeto volador que se quiere verificar si es visto por la cámara.</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;<i>True</i> si lo ve, <i>False</i> si no.</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cFiltroLock.html b/doc/ref/cFiltroLock.html
new file mode 100644 (file)
index 0000000..ac9cca3
--- /dev/null
@@ -0,0 +1,26 @@
+<HTML>\r
+<H2>Class: cFiltroLock</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                             <A HREF=cFiltro.html>cFiltro</A> ----+\r                                                         |\r                                                  <A HREF=cFiltroFrontal.html>cFiltroFrontal</A> ----+\r                                                                     |\r                                                                cFiltroLock\r</pre><hr>\r
+<B>Description:</B><BR>Implementa un filtro que "ve" hacia adelante y que además sólo puede\r
+      ver objetos del tipo cNave y cMeteorito.\r
+<p><B>Unit:</B><BR><A HREF=Filtros.html>Filtros</A>\r
+<code>   <A HREF=Filtros.pas>(Filtros.pas)</code></A><BR><BR>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cFiltroLock.html#0">function mVisible( ov: cObjetoVolador ): boolean; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Verifica que un objeto volador pueda ser visto por la cámara\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mVisible( ov: cObjetoVolador ): boolean; override;</CODE>\r
+<dl>\r
+<dd>Verifica que un objeto volador pueda ser visto por la cámara</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cFiltroMapa.html b/doc/ref/cFiltroMapa.html
new file mode 100644 (file)
index 0000000..4c8cf6f
--- /dev/null
@@ -0,0 +1,26 @@
+<HTML>\r
+<H2>Class: cFiltroMapa</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                             <A HREF=cFiltro.html>cFiltro</A> ----+\r                                                         |\r                                                    cFiltroMapa\r</pre><hr>\r
+<B>Description:</B><BR>Implementa un filtro que "ve" hacia abajo pero desde arriba a una cierta distancia\r
+      del observador. Es como si observara al observador mismo.\r
+<p><B>Unit:</B><BR><A HREF=Filtros.html>Filtros</A>\r
+<code>   <A HREF=Filtros.pas>(Filtros.pas)</code></A><BR><BR>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cFiltroMapa.html#0">function mVisible( ov: cObjetoVolador ): boolean; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Verifica que un objeto volador pueda ser visto por la cámara\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mVisible( ov: cObjetoVolador ): boolean; override;</CODE>\r
+<dl>\r
+<dd>Verifica que un objeto volador pueda ser visto por la cámara</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cFiltroTrasero.html b/doc/ref/cFiltroTrasero.html
new file mode 100644 (file)
index 0000000..3e0d0cc
--- /dev/null
@@ -0,0 +1,25 @@
+<HTML>\r
+<H2>Class: cFiltroTrasero</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                             <A HREF=cFiltro.html>cFiltro</A> ----+\r                                                         |\r                                                  cFiltroTrasero\r</pre><hr>\r
+<B>Description:</B><BR>Implementa un filtro que "ve" hacia atrás.\r
+<p><B>Unit:</B><BR><A HREF=Filtros.html>Filtros</A>\r
+<code>   <A HREF=Filtros.pas>(Filtros.pas)</code></A><BR><BR>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cFiltroTrasero.html#0">function mVisible( ov: cObjetoVolador ): boolean; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Verifica que un objeto volador pueda ser visto por la cámara\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mVisible( ov: cObjetoVolador ): boolean; override;</CODE>\r
+<dl>\r
+<dd>Verifica que un objeto volador pueda ser visto por la cámara</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cLaser.html b/doc/ref/cLaser.html
new file mode 100644 (file)
index 0000000..39d10e0
--- /dev/null
@@ -0,0 +1,51 @@
+<HTML>\r
+<H2>Class: cLaser</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                         <A HREF=cObjetoVolador.html>cObjetoVolador</A> ----+\r                                                            |\r                                                          <A HREF=cArma.html>cArma</A> ----+\r                                                                    |\r                                                                 cLaser\r</pre><hr>\r
+<B>Description:</B><BR>El laser es un tipo de arma básica. Es la que menos daño hace pero la que más rápido viaja<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión      0,1       metros (10 cm)\r
+      Potencia:      1         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:       1         Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad:     0,4       metros/milisegundos (1440 km/h)\r
+      Alcance:       3000      milisegundos (3 segundos, 1,2 km)\r
+      </PRE>\r
+<p><B>Unit:</B><BR><A HREF=Armas.html>Armas</A>\r
+<code>   <A HREF=Armas.pas>(Armas.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cLaser.html#0">constructor create( pos: cVector = nil; vel: cVector = nil ); overload;</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cLaser.html#1">function mDibujar: tObjetosVoladores; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado, se sobreescribe porque se dibuja de forma distinta\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( pos: cVector = nil; vel: cVector = nil ); overload;</CODE>\r
+<dl>\r
+<dd>Crea una nueva instancia.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pos </CODE> : Vector posición</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>vel </CODE> : Dirección del vector velocidad</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mDibujar: tObjetosVoladores; override;</CODE>\r
+<dl>\r
+<dd>Método heredado, se sobreescribe porque se dibuja de forma distinta</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cLista.html b/doc/ref/cLista.html
new file mode 100644 (file)
index 0000000..2b8729e
--- /dev/null
@@ -0,0 +1,30 @@
+<html>\r
+<h2>Class: cLista</h2>\r
+<pre> TList ----+\r
+           |\r
+        cLista\r
+</pre>\r
+<hr>\r
+<b>Description:</b><br>Lista exactamente igual a TList, solo que el destructor tambien destruye todos\r
+      los objetos que contiene\r
+<p><b>Unit:</b><br><a href=Lista.html>Lista</a>\r
+<a href=Lista.pas>   <code>(Lista.pas)</code></a><br><br>\r
+<p><b>Methods:</b><br>\r
+<dl>\r
+<dt>\r
+<img src=public.gif>\r
+<a href="cLista.html#0">destructor destroy; override;</a><br>\r
+</dt>\r
+<dd>\r
+Destructor. Destruye la lista y TODOS los objetos que ella contiene\r
+</dd>\r
+</dl>\r
+<hr>\r
+<p><img src=methods.gif>\r
+<a name="0"></a><p>\r
+<img src=public_big.gif>\r
+<code>destructor destroy; override;</code>\r
+<dl>\r
+<dd>Destructor. Destruye la lista y TODOS los objetos que ella contiene</dd><p>\r
+</dl><hr>\r
+</html>\r
diff --git a/doc/ref/cMeteorito.html b/doc/ref/cMeteorito.html
new file mode 100644 (file)
index 0000000..2783a86
--- /dev/null
@@ -0,0 +1,43 @@
+<HTML>\r
+<H2>Class: cMeteorito</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                         <A HREF=cObjetoVolador.html>cObjetoVolador</A> ----+\r                                                            |\r                                                       cMeteorito\r</pre><hr>\r
+<B>Description:</B><BR>Representa un objeto volador básico. Tiene una velocidad constante.\r
+<p><B>Unit:</B><BR><A HREF=Meteorito.html>Meteorito</A>\r
+<code>   <A HREF=Meteorito.pas>(Meteorito.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cMeteorito.html#0">constructor create( pos: cVector = nil; vel: cVector = nil; dim: tLongitud = 5; pot: tEnergia = 5; ene: tEnergia = 20 ); overload;</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cMeteorito.html#1">function mDibujar: tObjetosVoladores; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método para dibujar el meteorito (todavía no implementado)\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( pos: cVector = nil; vel: cVector = nil; dim: tLongitud = 5; pot: tEnergia = 5; ene: tEnergia = 20 ); overload;</CODE>\r
+<dl>\r
+<dd>Constructor\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pos </CODE> : Posicion inicial</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>vel </CODE> : Velocidad inicial</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>dim </CODE> : Dimensión del objeto volador (radio, en metros)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pot </CODE> : Potencia del objeto volador (cantidad de daño que hace por intervalode tiempo)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ene </CODE> : Energía del objeto volador(cantidad de daño que soporta antes de ser destruido)</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mDibujar: tObjetosVoladores; override;</CODE>\r
+<dl>\r
+<dd>Método para dibujar el meteorito (todavía no implementado)</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cMisil.html b/doc/ref/cMisil.html
new file mode 100644 (file)
index 0000000..6eb6bec
--- /dev/null
@@ -0,0 +1,52 @@
+<HTML>\r
+<H2>Class: cMisil</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                         <A HREF=cObjetoVolador.html>cObjetoVolador</A> ----+\r                                                            |\r                                                          <A HREF=cArma.html>cArma</A> ----+\r                                                                    |\r                                                                 cMisil\r</pre><hr>\r
+<B>Description:</B><BR>El misil es un tipo de arma básica. Hace un daño considerable y su velocidad también es alta<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión      0,5       metros (50 cm)\r
+      Potencia:      20        Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:       1         Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad:     0,3       metros/milisegundos (1080 km/h)\r
+      Alcance:       5000      milisegundos (5 segundos, 1,5 km)\r
+      </PRE>\r
+<p><B>Unit:</B><BR><A HREF=Armas.html>Armas</A>\r
+<code>   <A HREF=Armas.pas>(Armas.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cMisil.html#0">constructor create( pos: cVector = nil; vel: cVector = nil ); overload;</A><BR>\r
+</dt>\r
+<dd>\r
+Crea una nueva instancia.\r
+    \r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cMisil.html#1">function mDibujar: tObjetosVoladores; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado, se sobreescribe porque se dibuja de forma distinta\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( pos: cVector = nil; vel: cVector = nil ); overload;</CODE>\r
+<dl>\r
+<dd>Crea una nueva instancia.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pos </CODE> : Vector posición</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>vel </CODE> : Dirección del vector velocidad</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mDibujar: tObjetosVoladores; override;</CODE>\r
+<dl>\r
+<dd>Método heredado, se sobreescribe porque se dibuja de forma distinta</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cMisilDirigido.html b/doc/ref/cMisilDirigido.html
new file mode 100644 (file)
index 0000000..394926d
--- /dev/null
@@ -0,0 +1,152 @@
+<HTML>\r
+<H2>Class: cMisilDirigido</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                         <A HREF=cObjetoVolador.html>cObjetoVolador</A> ----+\r                                                            |\r                                                          <A HREF=cArma.html>cArma</A> ----+\r                                                                    |\r                                                                 <A HREF=cMisil.html>cMisil</A> ----+\r                                                                            |\r                                                                     cMisilDirigido\r</pre><hr>\r
+<B>Description:</B><BR>El misil dirigido es un tipo de arma avanzada. Persigue a su objetivo hasta que lo alcanza o\r
+      hasta que se le acaba el alcance. Hace un daño alto, su velocidad es mediana y tiene un gran alcance.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión      0,7       metros (70 cm)\r
+      Potencia:      30        Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:       1         Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad:     0,25      metros/milisegundos (900 km/h)\r
+      Alcance:       20000     milisegundos (20 segundos, 5 km)\r
+      Area de Lock:  2000      metros (2 km)\r
+      </PRE>\r
+<p><B>Unit:</B><BR><A HREF=Armas.html>Armas</A>\r
+<code>   <A HREF=Armas.pas>(Armas.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cMisilDirigido.html#0">constructor create( obj: cObjetoVolador; pos: cVector = nil ); overload;</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cMisilDirigido.html#1">procedure mDesSerializar( str: string ); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cMisilDirigido.html#2">function mDibujar: tObjetosVoladores; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado, se sobreescribe porque se dibuja de forma distinta\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cMisilDirigido.html#3">function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cMisilDirigido.html#4">function mGetObjetivo: cObjetoVolador;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene el objetivo del misil dirigido\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cMisilDirigido.html#5">procedure mModificarVelocidad;</A><BR>\r
+</dt>\r
+<dd>\r
+Método que calcula la nueva velocidad basandose en al posicion del objetivo\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cMisilDirigido.html#6">procedure mMover( dt: tTiempo ); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado, se sobreescribe porque se le agrega alguna funcionalidad\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cMisilDirigido.html#7">function mSerializar: string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve una cadena de texto con el objeto serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cMisilDirigido.html#8">procedure mSetObjetivo( ov: cObjetoVolador );</A><BR>\r
+</dt>\r
+<dd>\r
+Establece el objetivo del misil dirigido\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( obj: cObjetoVolador; pos: cVector = nil ); overload;</CODE>\r
+<dl>\r
+<dd>Crea una nueva instancia.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>obj </CODE> : Objeto volador al que perseguirá (objetivo)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pos </CODE> : Vector posición</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mDesSerializar( str: string ); override;</CODE>\r
+<dl>\r
+<dd>Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>str </CODE> : Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="2"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mDibujar: tObjetosVoladores; override;</CODE>\r
+<dl>\r
+<dd>Método heredado, se sobreescribe porque se dibuja de forma distinta</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="3"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</CODE>\r
+<dl>\r
+<dd>Devuelve el estado del objeto basandose en la cantidad de datos requeridos.\r
+    @return            Cadena de texto con el estado del Objeto.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>debugLevel </CODE> : Cantidad de información requerida</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="4"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetObjetivo: cObjetoVolador;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Objetivo del misil dirigido.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="5"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mModificarVelocidad;</CODE>\r
+<dl>\r
+<dd>Método que calcula la nueva velocidad basandose en al posicion del objetivo</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="6"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mMover( dt: tTiempo ); override;</CODE>\r
+<dl>\r
+<dd>Mueve el arma basado en su posición y velocidad actual, su objetivo y un intervalo de tiempo\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>dt </CODE> : Intervalo de tiempo</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="7"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSerializar: string; override;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="8"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mSetObjetivo( ov: cObjetoVolador );</CODE>\r
+<dl>\r
+<dd>Establece el objetivo del misil dirigido\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> : Nuevo objetivo</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cNave.html b/doc/ref/cNave.html
new file mode 100644 (file)
index 0000000..c25eac6
--- /dev/null
@@ -0,0 +1,358 @@
+<HTML>\r
+<H2>Class: cNave</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                         <A HREF=cObjetoVolador.html>cObjetoVolador</A> ----+\r                                                            |\r                                                          cNave\r</pre><hr>\r
+<B>Description:</B><BR>Clase abstracta con elementos comunes a todas las naves.\r
+<p><B>Unit:</B><BR><A HREF=Nave.html>Nave</A>\r
+<code>   <A HREF=Nave.pas>(Nave.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNave.html#0">constructor create( pos: cVector = nil; vel: cVector = nil; dim: tLongitud = 5;</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cNave.html#1">procedure mActualizarRetardadores( dT: tTiempo );</A><BR>\r
+</dt>\r
+<dd>\r
+Actualiza los retardadores\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cNave.html#2">function mCrearLaserDisparado: cLaser;</A><BR>\r
+</dt>\r
+<dd>\r
+Crea un laser (actualizando retardos y todo lo que sea necesario)\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cNave.html#3">function mCrearMisDirDisparado( ov : cObjetoVolador ): cMisilDirigido;</A><BR>\r
+</dt>\r
+<dd>\r
+Crea un misil dirigido (actualizando retardos y todo lo que sea necesario)\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cNave.html#4">function mCrearMisilDisparado: cMisil;</A><BR>\r
+</dt>\r
+<dd>\r
+Crea un misil (actualizando retardos y todo lo que sea necesario)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNave.html#5">procedure mDesSerializar( str: string ); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNave.html#6">function mDisparar( dT: tTiempo; ov : cObjetoVolador = nil ): cArma; virtual;</A><BR>\r
+</dt>\r
+<dd>\r
+Hace que se dispare un arma (todavía no está implementado), devolviendo la nueva\r
+          municion disparada\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNave.html#7">function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNave.html#8">function mGetMisiles: tMaxMisil;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la cantidad de Misiles que le quedan a la nave\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNave.html#9">function mGetMisilesDirigidos: tMaxMisilDirigido;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la cantidad de Misiles Dirigidos que le quedan a la nave\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNave.html#10">function mGetVelMax: tLongitud;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la velocidad máxima\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNave.html#11">function mPuedeDispararLaser( ov : cObjetoVolador ): boolean;</A><BR>\r
+</dt>\r
+<dd>\r
+Chequea que el enemigo este a distancia, que tenga municiones, etc.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNave.html#12">function mPuedeDispararMisDir( ov : cObjetoVolador ): boolean;</A><BR>\r
+</dt>\r
+<dd>\r
+Chequea que el enemigo este a distancia, que tenga municiones, etc.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNave.html#13">function mPuedeDispararMisil( ov : cObjetoVolador ): boolean;</A><BR>\r
+</dt>\r
+<dd>\r
+Chequea que el enemigo este a distancia, que tenga municiones, etc.\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cNave.html#14">function mRestarMisil: cNave;</A><BR>\r
+</dt>\r
+<dd>\r
+Resta un misil\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cNave.html#15">function mRestarMisilDirigido: cNave;</A><BR>\r
+</dt>\r
+<dd>\r
+Resta un misil dirigido\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cNave.html#16">procedure mRetardarLaser;</A><BR>\r
+</dt>\r
+<dd>\r
+Resetea el contador del retardo del láser\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cNave.html#17">procedure mRetardarMisDir;</A><BR>\r
+</dt>\r
+<dd>\r
+Resetea el contador del retardo del misil dirigido\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cNave.html#18">procedure mRetardarMisil;</A><BR>\r
+</dt>\r
+<dd>\r
+Resetea el contador del retardo del misil\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNave.html#19">function mSerializar: string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve una cadena de texto con el objeto serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cNave.html#20">function mSetVelMax( velMax: tLongitud ): cNave;</A><BR>\r
+</dt>\r
+<dd>\r
+Setea la velocidad máxima\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNave.html#21">function mSetVelModulo( velocidad: tLongitud ): cObjetoVolador; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método para establecer el modulo de la velocidad\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNave.html#22">function mSetVelocidad( velocidad: cVector ): cObjetoVolador; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método para establecer la velocidad\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cNave.html#23">function mTieneMisil: boolean;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve true si todavía tiene misiles\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cNave.html#24">function mTieneMisilDirigido: boolean;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve true si todavía tiene misiles dirigidos\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( pos: cVector = nil; vel: cVector = nil; dim: tLongitud = 5;</CODE>\r
+<dl>\r
+<dd>Constructor\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pos </CODE> :              Posicion inicial</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>vel </CODE> :              Velocidad inicial</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>dim </CODE> :              Dimensión (radio, en metros)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pot </CODE> :              Potencia (cantidad de daño que hace por intervalode tiempo)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ene </CODE> :              Energía (cantidad de daño que soporta antes de ser destruido)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>misiles </CODE> :          Cantidad de misiles comunes</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>misilesDirigidos </CODE> : Cantidad de misiles dirigidos</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>velMax </CODE> :           Velocidad máxima que puede alcanzar (modulo)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>retardoLaser </CODE> :     Ratardo del arma antes de poder volver a disparar</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>retardoMisil </CODE> :     Ratardo del arma antes de poder volver a disparar</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>retardoMisDir </CODE> :    Ratardo del arma antes de poder volver a disparar</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mActualizarRetardadores( dT: tTiempo );</CODE>\r
+<dl>\r
+<dd>Actualiza los retardadores\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>dT </CODE> : Intervalo de tiempo a restarles</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="2"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mCrearLaserDisparado: cLaser;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Nuevo láser</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="3"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mCrearMisDirDisparado( ov : cObjetoVolador ): cMisilDirigido;</CODE>\r
+<dl>\r
+<dd>Crea un misil dirigido (actualizando retardos y restando un misil dirigido)\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> : Objetivo del misil dirigido</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Nuevo misil dirigido</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="4"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mCrearMisilDisparado: cMisil;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Nuevo misil</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="5"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mDesSerializar( str: string ); override;</CODE>\r
+<dl>\r
+<dd>Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>str </CODE> : Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="6"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mDisparar( dT: tTiempo; ov : cObjetoVolador = nil ): cArma; virtual;</CODE>\r
+<dl>\r
+<dd>Hace que se dispare un arma\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> : Objetivo del disparo</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>dT </CODE> : Intervalo de tiempo</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Arma disparada (o <i>nil</i> si no se puede disparar ningún arma)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="7"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</CODE>\r
+<dl>\r
+<dd>Devuelve el estado del objeto basandose en la cantidad de datos requeridos.\r
+    @return            Cadena de texto con el estado del Objeto.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>debugLevel </CODE> : Cantidad de información requerida</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="8"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetMisiles: tMaxMisil;</CODE>\r
+<dl>\r
+<dd>Obtiene la cantidad de Misiles que le quedan a la nave\r
+    return Cantidad de misiles que le quedan a la nave</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="9"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetMisilesDirigidos: tMaxMisilDirigido;</CODE>\r
+<dl>\r
+<dd>Obtiene la cantidad de Misiles que le quedan a la nave\r
+    return Cantidad de misiles dirigidos que le quedan a la nave</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="10"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetVelMax: tLongitud;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Velocidad máxima (modulo)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="11"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mPuedeDispararLaser( ov : cObjetoVolador ): boolean;</CODE>\r
+<dl>\r
+<dd>Chequea que el enemigo este a distancia, que tenga municiones, etc.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>np </CODE> : Nave Propia a la que quiere disparar</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;<i>True</i> si está todo ok, <i>False</i> si no.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="12"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mPuedeDispararMisDir( ov : cObjetoVolador ): boolean;</CODE>\r
+<dl>\r
+<dd>Chequea que el enemigo este a distancia, que tenga municiones, etc.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>np </CODE> : Nave Propia a la que quiere disparar</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;<i>True</i> si está todo ok, <i>False</i> si no.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="13"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mPuedeDispararMisil( ov : cObjetoVolador ): boolean;</CODE>\r
+<dl>\r
+<dd>Chequea que el enemigo este a distancia, que tenga municiones, etc.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>np </CODE> : Nave Propia a la que quiere disparar</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;<i>True</i> si está todo ok, <i>False</i> si no.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="14"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mRestarMisil: cNave;</CODE>\r
+<dl>\r
+<dd>Resta un misil</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="15"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mRestarMisilDirigido: cNave;</CODE>\r
+<dl>\r
+<dd>Resta un misil dirigido</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="16"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mRetardarLaser;</CODE>\r
+<dl>\r
+<dd>Resetea el contador del retardo del láser</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="17"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mRetardarMisDir;</CODE>\r
+<dl>\r
+<dd>Resetea el contador del retardo del misil dirigido</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="18"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mRetardarMisil;</CODE>\r
+<dl>\r
+<dd>Resetea el contador del retardo del misil</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="19"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSerializar: string; override;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="20"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mSetVelMax( velMax: tLongitud ): cNave;</CODE>\r
+<dl>\r
+<dd>Setea la velocidad máxima\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>velMax </CODE> : Nueva velocidad máxima (modulo)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="21"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSetVelModulo( velocidad: tLongitud ): cObjetoVolador; override;</CODE>\r
+<dl>\r
+<dd>Método para establecer la velocidad</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="22"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSetVelocidad( velocidad: cVector ): cObjetoVolador; override;</CODE>\r
+<dl>\r
+<dd>Método para establecer el modulo de la velocidad</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="23"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mTieneMisil: boolean;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;<i>true</i> si tiene misiles, <i>false</i> si no</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="24"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mTieneMisilDirigido: boolean;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;<i>true</i> si tiene misiles dirigidos, <i>false</i> si no</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cNaveEnemiga.html b/doc/ref/cNaveEnemiga.html
new file mode 100644 (file)
index 0000000..e8e5dfe
--- /dev/null
@@ -0,0 +1,133 @@
+<HTML>\r
+<H2>Class: cNaveEnemiga</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                         <A HREF=cObjetoVolador.html>cObjetoVolador</A> ----+\r                                                            |\r                                                          <A HREF=cNave.html>cNave</A> ----+\r                                                                    |\r                                                              cNaveEnemiga\r</pre><hr>\r
+<B>Description:</B><BR>La clase cNaveEnemiga esta pensada como una clase abtracta. En ella se encuentran\r
+      características comunes a todas las naves enemigas.\r
+<p><B>Unit:</B><BR><A HREF=NaveEnemiga.html>NaveEnemiga</A>\r
+<code>   <A HREF=NaveEnemiga.pas>(NaveEnemiga.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveEnemiga.html#0">constructor create( pos: cVector = nil; vel: cVector = nil; dim: tLongitud = 10;</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveEnemiga.html#1">procedure mDesSerializar( str: string ); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveEnemiga.html#2">function mDetectado( ov: cObjetoVolador ): boolean;</A><BR>\r
+</dt>\r
+<dd>\r
+Indica si ov esta en el campo de radar\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveEnemiga.html#3">function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveEnemiga.html#4">procedure mIrA( pos: cVector );</A><BR>\r
+</dt>\r
+<dd>\r
+Hace que la nave se dirija a una posicion particular\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cNaveEnemiga.html#5">procedure mModificarVelocidad( np: cNavePropia; modulo: tLongitud = -1 ); virtual;</A><BR>\r
+</dt>\r
+<dd>\r
+Modifica la velocidad de la nave en base a la nave propia\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveEnemiga.html#6">procedure mReaccionar( np: cNavePropia ); virtual; abstract;</A><BR>\r
+</dt>\r
+<dd>\r
+Hace reaccionar ante la presencia de la nave propia. Tiene un comportamiento polimófico ya que cada nave\r
+          enemiga reaccionará de forma diferente (método abstracto)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveEnemiga.html#7">function mSerializar: string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve una cadena de texto con el objeto serializado.\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( pos: cVector = nil; vel: cVector = nil; dim: tLongitud = 10;</CODE>\r
+<dl>\r
+<dd>Constructor\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pos </CODE> :              Posicion inicial</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>vel </CODE> :              Velocidad inicial</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>dim </CODE> :              Dimensión (radio, en metros)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pot </CODE> :              Potencia (cantidad de daño que hace por intervalode tiempo)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ene </CODE> :              Energía (cantidad de daño que soporta antes de ser destruido)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>misiles </CODE> :          Cantidad de misiles comunes</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>misilesDirigidos </CODE> : Cantidad de misiles dirigidos</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>velMax </CODE> :           Velocidad máxima que puede alcanzar (modulo)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>radar </CODE> :            Área máxima en la que puede detectar a otras naves (radio, en metros)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>retardoLaser </CODE> :     Ratardo del arma antes de poder volver a disparar</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>retardoMisil </CODE> :     Ratardo del arma antes de poder volver a disparar</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>retardoMisDir </CODE> :    Ratardo del arma antes de poder volver a disparar</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mDesSerializar( str: string ); override;</CODE>\r
+<dl>\r
+<dd>Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>str </CODE> : Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="2"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mDetectado( ov: cObjetoVolador ): boolean;</CODE>\r
+<dl>\r
+<dd>Indica si ov esta en el campo de radar\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> : Objeto volador a chequear si está dentro del alcance del radar</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="3"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</CODE>\r
+<dl>\r
+<dd>Devuelve el estado del objeto basandose en la cantidad de datos requeridos.\r
+    @return            Cadena de texto con el estado del Objeto.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>debugLevel </CODE> : Cantidad de información requerida</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="4"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mIrA( pos: cVector );</CODE>\r
+<dl>\r
+<dd>Hace que la nave se dirija a una posicion particular\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pos </CODE> : Vector posición del punto al cual se dirigirá la nave</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="5"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mModificarVelocidad( np: cNavePropia; modulo: tLongitud = -1 ); virtual;</CODE>\r
+<dl>\r
+<dd>Modifica la velocidad de la nave en base a la nave propia\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>np </CODE> :     Nave propia con la cual se calculará la dirección de la nueva velocidad</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>modulo </CODE> : Nuevo módulo de la velocidad</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="6"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mReaccionar( np: cNavePropia ); virtual; abstract;</CODE>\r
+<dl>\r
+<dd>Hace reaccionar ante la presencia de la nave propia. Tiene un comportamiento polimófico ya que cada nave\r
+          enemiga reaccionará de forma diferente (método abstracto)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="7"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSerializar: string; override;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cNaveEspia.html b/doc/ref/cNaveEspia.html
new file mode 100644 (file)
index 0000000..082f2d9
--- /dev/null
@@ -0,0 +1,170 @@
+<HTML>\r
+<H2>Class: cNaveEspia</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                         <A HREF=cObjetoVolador.html>cObjetoVolador</A> ----+\r                                                            |\r                                                          <A HREF=cNave.html>cNave</A> ----+\r                                                                    |\r                                                              <A HREF=cNaveEnemiga.html>cNaveEnemiga</A> ----+\r                                                                               |\r                                                                          cNaveEspia\r</pre><hr>\r
+<B>Description:</B><BR>Es una nave sin armas que se desplaza por el epacio\r
+      hasta que encuentra una nave propia, en ese momento empieza a huir avisando a\r
+      las demas naves enemigas la ultima posicion de la nave propia.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            10        metros\r
+      Potencia:             1         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              30        Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,2       metros/milisegundos (720 km/h)\r
+      Campo de radar:       2000      metros (2 km)\r
+      Misiles:              0\r
+      Misiles Dirigidos:    0\r
+      </PRE>\r
+<p><B>Unit:</B><BR><A HREF=NavesEnemigas.html>NavesEnemigas</A>\r
+<code>   <A HREF=NavesEnemigas.pas>(NavesEnemigas.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveEspia.html#0">constructor create( pos : cVector = nil; vel : cVector = nil );</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor \r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveEspia.html#1">destructor destroy; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Destructor\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveEspia.html#2">function mAvisando: boolean;</A><BR>\r
+</dt>\r
+<dd>\r
+Método que indica si está avisando \r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveEspia.html#3">procedure mDesSerializar( str: string ); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveEspia.html#4">function mDibujar: tObjetosVoladores; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado, se sobreescribe porque se dibuja de forma distinta\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveEspia.html#5">function mDisparar( dT: tTiempo; ov : cObjetoVolador = nil ): cArma; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado, se sobreescribe porque esta nave en particular no puede disparar\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveEspia.html#6">function mGetPosicionEnemiga: cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Método que devuelve la última posición en dónde vió a la nave propia (si está avisando)\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cNaveEspia.html#7">procedure mModificarVelocidad( np: cNavePropia; modulo: tLongitud = -1 ); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado se modifica porque su forma de modificar la velocidad es diferente al\r
+          resto de las naves enemigas\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveEspia.html#8">procedure mReaccionar( np : cNavePropia );override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado que hace que la nave reaccione ante la presencia\r
+          de la nave propia (en este caso huirá y empezará a avisar al resto de las naves que encuentre\r
+          sobre la última posición de la nave propia)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveEspia.html#9">function mSerializar: string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve una cadena de texto con el objeto serializado.\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( pos : cVector = nil; vel : cVector = nil );</CODE>\r
+<dl>\r
+<dd>Crea una instancia de una nave espía.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pos </CODE> : Vector posición</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>vel </CODE> : Vector velocidad</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>destructor destroy; override;</CODE>\r
+<dl>\r
+<dd>Destructor</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="2"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mAvisando: boolean;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;<i>true</i> si está avisando, <i>false</i> si no lo está</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="3"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mDesSerializar( str: string ); override;</CODE>\r
+<dl>\r
+<dd>Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>str </CODE> : Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="4"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mDibujar: tObjetosVoladores; override;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Última posición donde detectó a la nave propia (<i>nil</i> si no la detecto nunca)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="5"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mDisparar( dT: tTiempo; ov : cObjetoVolador = nil ): cArma; override;</CODE>\r
+<dl>\r
+<dd>Hace que se dispare un arma\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> : Objetivo del disparo</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Arma disparada (o <i>nil</i> si no se puede disparar ningún arma)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="6"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetPosicionEnemiga: cVector;</CODE>\r
+<dl>\r
+<dd>Método que devuelve la última posición en dónde vió a la nave propia (si está avisando)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="7"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mModificarVelocidad( np: cNavePropia; modulo: tLongitud = -1 ); override;</CODE>\r
+<dl>\r
+<dd>Modifica la velocidad de la nave en base a la nave propia.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>np </CODE> :     Nave propia con la cual se calculará la dirección de la nueva velocidad</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>modulo </CODE> : Nuevo módulo de la velocidad</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="8"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mReaccionar( np : cNavePropia );override;</CODE>\r
+<dl>\r
+<dd>Método heredado que hace que la nave reaccione ante la presencia\r
+    de la nave propia (en este caso huirá y empezará a avisar al resto de las naves que encuentre\r
+    sobre la última posición de la nave propia)\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>np </CODE> : Nave Propia con la cual esta reaccionando</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="9"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSerializar: string; override;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cNaveLiviana.html b/doc/ref/cNaveLiviana.html
new file mode 100644 (file)
index 0000000..82a408b
--- /dev/null
@@ -0,0 +1,99 @@
+<HTML>\r
+<H2>Class: cNaveLiviana</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                         <A HREF=cObjetoVolador.html>cObjetoVolador</A> ----+\r                                                            |\r                                                          <A HREF=cNave.html>cNave</A> ----+\r                                                                    |\r                                                              <A HREF=cNaveEnemiga.html>cNaveEnemiga</A> ----+\r                                                                               |\r                                                                         cNaveLiviana\r</pre><hr>\r
+<B>Description:</B><BR>Es una nave sin misiles, solo con lasers que\r
+      se desplaza por el epacio hasta que encuentra una nave propia para atacar.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            15        metros\r
+      Potencia:             1         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              60        Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,18      metros/milisegundos (648 km/h)\r
+      Campo de radar:       3000      metros (3 km)\r
+      Misiles:              0\r
+      Misiles Dirigidos:    0\r
+      </PRE>\r
+<p><B>Unit:</B><BR><A HREF=NavesEnemigas.html>NavesEnemigas</A>\r
+<code>   <A HREF=NavesEnemigas.pas>(NavesEnemigas.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveLiviana.html#0">constructor create( pos : cVector = nil; vel : cVector = nil );</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveLiviana.html#1">procedure mDesSerializar( str: string ); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveLiviana.html#2">function mDibujar: tObjetosVoladores; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado, se sobreescribe porque se dibuja de forma distinta\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveLiviana.html#3">procedure mReaccionar( np : cNavePropia );override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado que hace que la nave reaccione ante la presencia\r
+          de la nave propia (en este caso la atacará con lasers)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveLiviana.html#4">function mSerializar: string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve una cadena de texto con el objeto serializado.\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( pos : cVector = nil; vel : cVector = nil );</CODE>\r
+<dl>\r
+<dd>Crea una instancia de una nave liviana.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pos </CODE> : Vector posición</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>vel </CODE> : Vector velocidad</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mDesSerializar( str: string ); override;</CODE>\r
+<dl>\r
+<dd>Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>str </CODE> : Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="2"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mDibujar: tObjetosVoladores; override;</CODE>\r
+<dl>\r
+<dd>Hace que se dispare un arma (todavía no está implementado)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="3"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mReaccionar( np : cNavePropia );override;</CODE>\r
+<dl>\r
+<dd>Método heredado que hace que la nave reaccione ante la presencia\r
+    de la nave propia (en este caso la atacará con lasers)\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>np </CODE> : Nave Propia con la cual esta reaccionando</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="4"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSerializar: string; override;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cNavePesada.html b/doc/ref/cNavePesada.html
new file mode 100644 (file)
index 0000000..3f562f9
--- /dev/null
@@ -0,0 +1,99 @@
+<HTML>\r
+<H2>Class: cNavePesada</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                         <A HREF=cObjetoVolador.html>cObjetoVolador</A> ----+\r                                                            |\r                                                          <A HREF=cNave.html>cNave</A> ----+\r                                                                    |\r                                                              <A HREF=cNaveEnemiga.html>cNaveEnemiga</A> ----+\r                                                                               |\r                                                                          cNavePesada\r</pre><hr>\r
+<B>Description:</B><BR>Es una nave con misiles y lasers (igual que la propia)\r
+      que se desplaza por el epacio hasta que encuentra una nave propia para atacar.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            25        metros\r
+      Potencia:             2         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              100       Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,17      metros/milisegundos (612 km/h)\r
+      Campo de radar:       5000      metros (5 km)\r
+      Misiles:              5\r
+      Misiles Dirigidos:    2\r
+      </PRE>\r
+<p><B>Unit:</B><BR><A HREF=NavesEnemigas.html>NavesEnemigas</A>\r
+<code>   <A HREF=NavesEnemigas.pas>(NavesEnemigas.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePesada.html#0">constructor create( pos : cVector = nil; vel : cVector = nil );</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePesada.html#1">procedure mDesSerializar( str: string ); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePesada.html#2">function mDibujar: tObjetosVoladores; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado, se sobreescribe porque se dibuja de forma distinta\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePesada.html#3">procedure mReaccionar( np : cNavePropia );override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado que hace que la nave reaccione ante la presencia\r
+          de la nave propia (en este caso la atacará con lasers y misiles)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePesada.html#4">function mSerializar: string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve una cadena de texto con el objeto serializado.\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( pos : cVector = nil; vel : cVector = nil );</CODE>\r
+<dl>\r
+<dd>Crea una instancia de una nave pesada.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pos </CODE> : Vector posición</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>vel </CODE> : Vector velocidad</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mDesSerializar( str: string ); override;</CODE>\r
+<dl>\r
+<dd>Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>str </CODE> : Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="2"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mDibujar: tObjetosVoladores; override;</CODE>\r
+<dl>\r
+<dd>Método heredado, se sobreescribe porque se dibuja de forma distinta</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="3"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mReaccionar( np : cNavePropia );override;</CODE>\r
+<dl>\r
+<dd>Método heredado que hace que la nave reaccione ante la presencia\r
+    de la nave propia cerca (en este caso la atacará con lasers y misiles)\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>np </CODE> : Nave Propia con la cual esta reaccionando</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="4"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSerializar: string; override;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cNavePropia.html b/doc/ref/cNavePropia.html
new file mode 100644 (file)
index 0000000..838260a
--- /dev/null
@@ -0,0 +1,315 @@
+<HTML>\r
+<H2>Class: cNavePropia</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                         <A HREF=cObjetoVolador.html>cObjetoVolador</A> ----+\r                                                            |\r                                                          <A HREF=cNave.html>cNave</A> ----+\r                                                                    |\r                                                               cNavePropia\r</pre><hr>\r
+<B>Description:</B><BR>Es la nave que será controlada por el jugador.\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            15        metros\r
+      Potencia:             5         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              100       Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,17      metros/milisegundos (612 km/h)\r
+      Misiles:              10\r
+      Misiles Dirigidos:    5\r
+      </PRE>\r
+<p><B>Unit:</B><BR><A HREF=NavePropia.html>NavePropia</A>\r
+<code>   <A HREF=NavePropia.pas>(NavePropia.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#0">constructor create( pos: cVector = nil; vel: cVector = nil ); overload;</A><BR>\r
+</dt>\r
+<dd>\r
+Crea una nave controlada por un jugador\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#1">procedure mAcelerar( modulo: tLongitud );</A><BR>\r
+</dt>\r
+<dd>\r
+Aumenta el modulo de la velocidad (sin cambiar su dirección ni\r
+          sentido y sin sobrepasar la velocidad maxima)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#2">procedure mCambiarLockeado( lEnemigos: TList );</A><BR>\r
+</dt>\r
+<dd>\r
+Cambia el objetivo lockeado\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#3">procedure mDesacelerar( modulo: tLongitud );</A><BR>\r
+</dt>\r
+<dd>\r
+Disminuye el modulo de la velocidad (sin cambiar su dirección ni sentido)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#4">procedure mDesSerializar( str: string ); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#5">function mDibujar: tObjetosVoladores; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado, se sobreescribe porque se dibuja de forma distinta\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#6">function mDisparar( dT: tTiempo; ov : cObjetoVolador = nil ): cArma; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Hace que se dispare un arma (todavía no está implementado)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#7">function mGetArmaSelec: tArma;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene el arma seleccionada actualmente\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#8">function mGetLockeado: cObjetoVolador;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene el objetivo lockeado\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#9">function mGetUltimoArmaDisparado: cArma;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene un puntero a la último arma disparada\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#10">procedure mGirarAbajo( angulo: tAngulo );</A><BR>\r
+</dt>\r
+<dd>\r
+Permite a la nave girar hacia abajo (sobre su eje Y)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#11">procedure mGirarArriba( angulo: tAngulo );</A><BR>\r
+</dt>\r
+<dd>\r
+Permite a la nave girar hacia arriba (sobre su eje Y)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#12">procedure mGirarDerecha( angulo: tAngulo );</A><BR>\r
+</dt>\r
+<dd>\r
+Permite a la nave girar hacia la derecha (sobre su eje Z)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#13">procedure mGirarIzquierda( angulo: tAngulo );</A><BR>\r
+</dt>\r
+<dd>\r
+Permite a la nave girar hacia la izquierda (sobre su eje Z)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#14">function mIntentarDisparo: cArma;</A><BR>\r
+</dt>\r
+<dd>\r
+Intenta disparar. Si las condiciones son las correctas, el proximo turno\r
+          saldrá el disparo, si no, no hace nada\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#15">procedure mRotarDerecha( angulo: tAngulo );</A><BR>\r
+</dt>\r
+<dd>\r
+Permite a la nave rotar a la derecha sobre su eje X\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#16">procedure mRotarIzquierda( angulo: tAngulo );</A><BR>\r
+</dt>\r
+<dd>\r
+Permite a la nave rotar a la izquierda sobre su eje X\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#17">procedure mSeleccionarArma( a: tArma );</A><BR>\r
+</dt>\r
+<dd>\r
+Selecciona un arma determinada. Si tiene municiones, la selecciona, si no,\r
+          no hace nada.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#18">procedure mSeleccionarArmaSig;</A><BR>\r
+</dt>\r
+<dd>\r
+Selecciona el proximo arma con municiones\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#19">function mSerializar: string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve una cadena de texto con el objeto serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNavePropia.html#20">procedure mSetLockeado( ov: cObjetoVolador );</A><BR>\r
+</dt>\r
+<dd>\r
+Setea el objetivo lockeado\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( pos: cVector = nil; vel: cVector = nil ); overload;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pos </CODE> : Posición Inicial</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>vel </CODE> : Velocidad Inicial</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mAcelerar( modulo: tLongitud );</CODE>\r
+<dl>\r
+<dd>Hace que aumente el modulo de la velocidad\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>modulo </CODE> : Modulo de la velocidad a sumar</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="2"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mCambiarLockeado( lEnemigos: TList );</CODE>\r
+<dl>\r
+<dd>Cambia el objetivo lockeado</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="3"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mDesacelerar( modulo: tLongitud );</CODE>\r
+<dl>\r
+<dd>Hace que disminuya el modulo de la velocidad\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>modulo </CODE> : Modulo de la velocidad a restar</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="4"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mDesSerializar( str: string ); override;</CODE>\r
+<dl>\r
+<dd>Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>str </CODE> : Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="5"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mDibujar: tObjetosVoladores; override;</CODE>\r
+<dl>\r
+<dd>Método heredado, se sobreescribe porque se dibuja de forma distinta</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="6"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mDisparar( dT: tTiempo; ov : cObjetoVolador = nil ): cArma; override;</CODE>\r
+<dl>\r
+<dd>Hace que se dispare un arma\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> : Objetivo del disparo</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>dT </CODE> : Intervalo de tiempo</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Arma disparada (o <i>nil</i> si no se puede disparar ningún arma)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="7"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetArmaSelec: tArma;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Arma seleccionada</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="8"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetLockeado: cObjetoVolador;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Objeto volador lockeado</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="9"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetUltimoArmaDisparado: cArma;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Último arma disparado</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="10"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mGirarAbajo( angulo: tAngulo );</CODE>\r
+<dl>\r
+<dd>Permite a la nave girar hacia abajo (sobre su eje Y)\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>angulo </CODE> : Ángulo a girar</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="11"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mGirarArriba( angulo: tAngulo );</CODE>\r
+<dl>\r
+<dd>Permite a la nave girar hacia arriba (sobre su eje Y)\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>angulo </CODE> : Ángulo a girar</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="12"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mGirarDerecha( angulo: tAngulo );</CODE>\r
+<dl>\r
+<dd>Permite a la nave girar hacia la derecha (sobre su eje Z)\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>angulo </CODE> : Ángulo a girar</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="13"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mGirarIzquierda( angulo: tAngulo );</CODE>\r
+<dl>\r
+<dd>Permite a la nave girar hacia la izquierda (sobre su eje Z)\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>angulo </CODE> : Ángulo a girar</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="14"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mIntentarDisparo: cArma;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Arma proximamente disparada</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="15"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mRotarDerecha( angulo: tAngulo );</CODE>\r
+<dl>\r
+<dd>Permite a la nave rotar hacia la derecha (sobre su eje I)\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>angulo </CODE> : Ángulo a rotar</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="16"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mRotarIzquierda( angulo: tAngulo );</CODE>\r
+<dl>\r
+<dd>Permite a la nave rotar hacia la izquierda (sobre su eje I)\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>angulo </CODE> : Ángulo a rotar</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="17"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mSeleccionarArma( a: tArma );</CODE>\r
+<dl>\r
+<dd>Selecciona un arma determinada. Si tiene municiones, la selecciona, si no,\r
+    no hace nada.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="18"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mSeleccionarArmaSig;</CODE>\r
+<dl>\r
+<dd>Selecciona el proximo arma con municiones</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="19"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSerializar: string; override;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="20"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mSetLockeado( ov: cObjetoVolador );</CODE>\r
+<dl>\r
+<dd>Setea el objetivo lockeado\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> : Objeto volador lockeado</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cNaveSuicida.html b/doc/ref/cNaveSuicida.html
new file mode 100644 (file)
index 0000000..5c59ea8
--- /dev/null
@@ -0,0 +1,85 @@
+<HTML>\r
+<H2>Class: cNaveSuicida</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                         <A HREF=cObjetoVolador.html>cObjetoVolador</A> ----+\r                                                            |\r                                                          <A HREF=cNave.html>cNave</A> ----+\r                                                                    |\r                                                              <A HREF=cNaveEnemiga.html>cNaveEnemiga</A> ----+\r                                                                               |\r                                                                         cNaveSuicida\r</pre><hr>\r
+<B>Description:</B><BR>Es una nave sin armas que se desplaza por el epacio\r
+      hasta que encuentra una nave propia y trata de chocarla.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            10        metros\r
+      Potencia:             4         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              30        Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,2       metros/milisegundos (720 km/h)\r
+      Campo de radar:       2500      metros (2,5 km)\r
+      Misiles:              0\r
+      Misiles Dirigidos:    0\r
+      </PRE>\r
+<p><B>Unit:</B><BR><A HREF=NavesEnemigas.html>NavesEnemigas</A>\r
+<code>   <A HREF=NavesEnemigas.pas>(NavesEnemigas.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveSuicida.html#0">constructor create( pos : cVector = nil; vel : cVector = nil );</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveSuicida.html#1">function mDibujar: tObjetosVoladores; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado, se sobreescribe porque se dibuja de forma distinta\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveSuicida.html#2">function mDisparar( dT: tTiempo; ov : cObjetoVolador = nil ): cArma; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado, se sobreescribe porque esta nave en particular no puede disparar\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cNaveSuicida.html#3">procedure mReaccionar( np : cNavePropia );override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado que hace que la nave reaccione ante la presencia\r
+          de la nave propia (en este caso tratará de chocarla)\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( pos : cVector = nil; vel : cVector = nil );</CODE>\r
+<dl>\r
+<dd>Crea una instancia de una nave suicida.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pos </CODE> : Vector posición</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>vel </CODE> : Vector velocidad</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mDibujar: tObjetosVoladores; override;</CODE>\r
+<dl>\r
+<dd>Método heredado que hace que la nave reaccione ante la presencia\r
+    de la nave propia (en este caso tratará de chocarla)\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>np </CODE> : Nave Propia con la cual esta reaccionando</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="2"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mDisparar( dT: tTiempo; ov : cObjetoVolador = nil ): cArma; override;</CODE>\r
+<dl>\r
+<dd>Hace que se dispare un arma\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> : Objetivo del disparo</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Arma disparada (o <i>nil</i> si no se puede disparar ningún arma)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="3"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mReaccionar( np : cNavePropia );override;</CODE>\r
+<dl>\r
+<dd>Método heredado que hace que la nave reaccione ante la presencia\r
+          de la nave propia (en este caso tratará de chocarla)</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cObjeto.html b/doc/ref/cObjeto.html
new file mode 100644 (file)
index 0000000..eddcf3b
--- /dev/null
@@ -0,0 +1,33 @@
+<html>\r
+<h2>Class: cObjeto</h2>\r
+<pre> TObject ----+\r
+             |\r
+          cObjeto\r
+</pre>\r
+<hr>\r
+<b>Description:</b><br>Es una clase abstracta para agregar algunos métodos generales útiles\r
+      para el resto de las clases que implementemos. Podría considerarse una\r
+      extensión a la funcionalidad básica dada por TObject.\r
+<p><b>Unit:</b><br><a href=Objeto.html>Objeto</a>\r
+<a href=Objeto.pas>   <code>(Objeto.pas)</code></a><br><br>\r
+<p><b>Methods:</b><br>\r
+<dl>\r
+<dt>\r
+<img src=public.gif>\r
+<a href="cObjeto.html#0">function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; virtual; abstract;</a><br>\r
+</dt>\r
+<dd>\r
+Devuelve una cadena de texto con el estado actual del objeto.\r
+          La cantidad de información devuelta depende del parametro debugLevel\r
+</dd>\r
+</dl>\r
+<hr>\r
+<p><img src=methods.gif>\r
+<a name="0"></a><p>\r
+<img src=public_big.gif>\r
+<code>function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; virtual; abstract;</code>\r
+<dl>\r
+<dd>Devuelve una cadena de texto con el estado actual del objeto.\r
+          La cantidad de información devuelta depende del parametro debugLevel</dd><p>\r
+</dl><hr>\r
+</html>\r
diff --git a/doc/ref/cObjetoPersistente.html b/doc/ref/cObjetoPersistente.html
new file mode 100644 (file)
index 0000000..bf0b0f4
--- /dev/null
@@ -0,0 +1,105 @@
+<HTML>\r
+<H2>Class: cObjetoPersistente</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         cObjetoPersistente\r</pre><hr>\r
+<B>Description:</B><BR>Es una clase abstracta para hacer persistente un objeto.\r
+      Básicamente provee métodos para serialización.\r
+      NOTA: Es importante que el ID del objeto sea el primer atributo en la\r
+            serialización, de otra manera puede ser malinterpretado al des-\r
+            serializarlo.\r
+<p><B>Unit:</B><BR><A HREF=ObjetoPersistente.html>ObjetoPersistente</A>\r
+<code>   <A HREF=ObjetoPersistente.pas>(ObjetoPersistente.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoPersistente.html#0">constructor crearDeSerializado( str: string );</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor que crea el objeto a partir de una cadena de texto con\r
+          el objeto serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoPersistente.html#1">constructor create;</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor. Setea el ID.\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoPersistente.html#2">procedure mDesSerializar( str: string ); virtual;</A><BR>\r
+</dt>\r
+<dd>\r
+Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoPersistente.html#3">function mGetID: string;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la identificacion del objeto\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoPersistente.html#4">function mSerializar: string; virtual;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve una cadena de texto con el objeto serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cObjetoPersistente.html#5">procedure mSetID( id: string );</A><BR>\r
+</dt>\r
+<dd>\r
+Setea la identificacion del objeto\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor crearDeSerializado( str: string );</CODE>\r
+<dl>\r
+<dd>Constructor que crea el objeto a partir de una cadena de texto con\r
+    el objeto serializado.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>str </CODE> : cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create;</CODE>\r
+<dl>\r
+<dd>Constructor. Setea el ID.</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="2"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mDesSerializar( str: string ); virtual;</CODE>\r
+<dl>\r
+<dd>Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>str </CODE> : Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="3"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetID: string;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;ID del objeto.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="4"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSerializar: string; virtual;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="5"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mSetID( id: string );</CODE>\r
+<dl>\r
+<dd>Setea la identificacion del objeto\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>id </CODE> : nuevo ID.</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cObjetoVolador.html b/doc/ref/cObjetoVolador.html
new file mode 100644 (file)
index 0000000..2847921
--- /dev/null
@@ -0,0 +1,420 @@
+<HTML>\r
+<H2>Class: cObjetoVolador</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                         cObjetoVolador\r</pre><hr>\r
+<B>Description:</B><BR>Clase abstracta, implementa todas las funcionalidades básicas de los objetos voladores.\r
+      De esta van a derivar la mayor parte del resto de las clases.\r
+<p><B>Unit:</B><BR><A HREF=ObjetoVolador.html>ObjetoVolador</A>\r
+<code>   <A HREF=ObjetoVolador.pas>(ObjetoVolador.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#0">constructor create( pos: cVector = nil; vel: cVector = nil; dim: tLongitud = 5; pot: tEnergia = 1; ene: tEnergia = 100 ); overload;</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#1">constructor create( ov:  cObjetoVolador ); overload;</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor que copia los atributos de un Objeto volador existente\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#2">destructor destroy; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Destructor\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#3">function mColisiono( ov: cObjetoVolador ): boolean;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve true si colisionaron los objetos voladores\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#4">procedure mDesSerializar( str: string ); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#5">function mDibujar: tObjetosVoladores; virtual; abstract;</A><BR>\r
+</dt>\r
+<dd>\r
+Método abstracto, se sobreescribira en las subclases porque van a ser\r
+          dibujadas de forma diferente\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#6">function mGetCoordenadas: cCoordenadas;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene el sistema de coordenadas de la nave\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#7">function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#8">function mGetDimension: tLongitud;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la Dimension del objeto volador\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#9">function mGetDistancia( ov: cObjetoVolador ): tLongitud;</A><BR>\r
+</dt>\r
+<dd>\r
+Calcula la distancia a otro objeto volador\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#10">function mGetEnergia: tEnergia;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la Energia del objeto volador\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#11">function mGetI: cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene el versor i del sistema de coordenadas de la nave\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#12">function mGetJ: cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene el versor j del sistema de coordenadas de la nave\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#13">function mGetK: cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene el versor k del sistema de coordenadas de la nave\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#14">function mGetPosicion: cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la Posicion del objeto volador\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#15">function mGetPotencia: tEnergia;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la Potencia del objeto volador\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#16">function mGetVelModulo: tLongitud;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene el modulo de la velocidad del objeto volador\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#17">function mGetVelocidad: cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la velocidad del objeto volador\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#18">procedure mMover( dT: tTiempo ); virtual;</A><BR>\r
+</dt>\r
+<dd>\r
+Mueve el objeto volador basandose en su posicion, su velocidad y un intervalo de tiempo\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#19">function mRestarEnergia( ene: tEnergia ): cObjetoVolador;</A><BR>\r
+</dt>\r
+<dd>\r
+Resta energia al objeto volador\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cObjetoVolador.html#20">function mRotarEnI( dAngulo: tAngulo ): cObjetoVolador;</A><BR>\r
+</dt>\r
+<dd>\r
+Rota el objeto volador sobre el eje i\r
+          (el sentido positivo es de j a k)\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cObjetoVolador.html#21">function mRotarEnJ( dAngulo: tAngulo ): cObjetoVolador;</A><BR>\r
+</dt>\r
+<dd>\r
+Rota el objeto volador sobre el eje j\r
+          (el sentido positivo es de i a k)\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cObjetoVolador.html#22">function mRotarEnK( dAngulo: tAngulo ): cObjetoVolador;</A><BR>\r
+</dt>\r
+<dd>\r
+Rota el objeto volador sobre el eje k\r
+          (el sentido positivo es de i a j)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#23">function mSerializar: string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve una cadena de texto con el objeto serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cObjetoVolador.html#24">function mSetEnergia( ene: tEnergia ): cObjetoVolador;</A><BR>\r
+</dt>\r
+<dd>\r
+Método para establecer la energía\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#25">function mSetPosicion( posicion: cVector ): cObjetoVolador;</A><BR>\r
+</dt>\r
+<dd>\r
+Método para establecer la posición\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#26">function mSetVelDir( velocidad: cVector ): cObjetoVolador;</A><BR>\r
+</dt>\r
+<dd>\r
+Método para establecer la direccion de la velocidad\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#27">function mSetVelModulo( velocidad: tLongitud ): cObjetoVolador; virtual;</A><BR>\r
+</dt>\r
+<dd>\r
+Método para establecer el modulo de la velocidad\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cObjetoVolador.html#28">function mSetVelocidad( velocidad: cVector ): cObjetoVolador; virtual;</A><BR>\r
+</dt>\r
+<dd>\r
+Método para establecer la velocidad\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( pos: cVector = nil; vel: cVector = nil; dim: tLongitud = 5; pot: tEnergia = 1; ene: tEnergia = 100 ); overload;</CODE>\r
+<dl>\r
+<dd>Constructor\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pos </CODE> : Posicion inicial</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>vel </CODE> : Velocidad inicial</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>dim </CODE> : Dimensión del objeto volador (radio, en metros)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>pot </CODE> : Potencia del objeto volador (cantidad de daño que hace por intervalode tiempo)</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ene </CODE> : Energía del objeto volador(cantidad de daño que soporta antes de ser destruido)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( ov:  cObjetoVolador ); overload;</CODE>\r
+<dl>\r
+<dd>Constructor que copia los atributos de un Objeto volador existente</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="2"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>destructor destroy; override;</CODE>\r
+<dl>\r
+<dd>Destructor</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="3"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mColisiono( ov: cObjetoVolador ): boolean;</CODE>\r
+<dl>\r
+<dd>Devuelve true si colisionaron los objetos voladores\r
+    @return     <i>true<i> si colisionaron, <i>false</i> si no lo hicieron\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> : Objeto volador con el que se evalua si colisiono</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="4"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mDesSerializar( str: string ); override;</CODE>\r
+<dl>\r
+<dd>Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>str </CODE> : Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="5"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mDibujar: tObjetosVoladores; virtual; abstract;</CODE>\r
+<dl>\r
+<dd>Método abstracto, se sobreescribira en las subclases porque van a ser\r
+          dibujadas de forma diferente</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="6"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetCoordenadas: cCoordenadas;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Sistema de coordenadas de la nave</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="7"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</CODE>\r
+<dl>\r
+<dd>Devuelve el estado del objeto basandose en la cantidad de datos requeridos.\r
+    @return            Cadena de texto con el estado del Objeto.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>debugLevel </CODE> : Cantidad de información requerida</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="8"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetDimension: tLongitud;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Dimensión (radio, en metros)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="9"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetDistancia( ov: cObjetoVolador ): tLongitud;</CODE>\r
+<dl>\r
+<dd>Calcula la distancia a otro objeto volador\r
+    @return     Distancia al otro objeto volador\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> : Objeto volador al que se calcula la distancia</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="10"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetEnergia: tEnergia;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Energía (cantidad de daño que soporta antes de ser destruido)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="11"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetI: cVector;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Versor i, que representa la direccion en la que viaja el objeto</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="12"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetJ: cVector;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Versor j, que representa la direccion en la que está la izquierda del objeto</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="13"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetK: cVector;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Versor k, que representa la direccion en la que está el "techo" del objeto</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="14"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetPosicion: cVector;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Vector posición</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="15"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetPotencia: tEnergia;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Potencia (cantidad de daño que realiza por intervalo de tiempo)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="16"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetVelModulo: tLongitud;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Módulo de la velocidad</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="17"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetVelocidad: cVector;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Vector velocidad</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="18"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mMover( dT: tTiempo ); virtual;</CODE>\r
+<dl>\r
+<dd>Mueve el objeto volador basandose en su posicion, su velocidad y un intervalo de tiempo\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>dT </CODE> : Intervalo de tiempo</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="19"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mRestarEnergia( ene: tEnergia ): cObjetoVolador;</CODE>\r
+<dl>\r
+<dd>Resta energía al objeto volador\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ene </CODE> : Energía a restar</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="20"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mRotarEnI( dAngulo: tAngulo ): cObjetoVolador;</CODE>\r
+<dl>\r
+<dd>Rota el objeto volador sobre el eje i\r
+    (el sentido positivo es de j a k)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="21"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mRotarEnJ( dAngulo: tAngulo ): cObjetoVolador;</CODE>\r
+<dl>\r
+<dd>Rota el objeto volador sobre el eje j\r
+    (el sentido positivo es de i a k)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="22"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mRotarEnK( dAngulo: tAngulo ): cObjetoVolador;</CODE>\r
+<dl>\r
+<dd>Rota el objeto volador sobre el eje k\r
+    (el sentido positivo es de i a j)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="23"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSerializar: string; override;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="24"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mSetEnergia( ene: tEnergia ): cObjetoVolador;</CODE>\r
+<dl>\r
+<dd>Setea la energía del objeto volador a un valor arbitrario\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ene </CODE> : Nueva energía</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="25"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSetPosicion( posicion: cVector ): cObjetoVolador;</CODE>\r
+<dl>\r
+<dd>Método para establecer la posición\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>velocidad </CODE> : Nuevo vector posición</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="26"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSetVelDir( velocidad: cVector ): cObjetoVolador;</CODE>\r
+<dl>\r
+<dd>Método para establecer la direccion de la velocidad\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>velocidad </CODE> : Nueva dirección de la velocidad</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="27"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSetVelModulo( velocidad: tLongitud ): cObjetoVolador; virtual;</CODE>\r
+<dl>\r
+<dd>Método para establecer el modulo de la velocidad\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>velocidad </CODE> : Nuevo módulo de la velocidad</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="28"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSetVelocidad( velocidad: cVector ): cObjetoVolador; virtual;</CODE>\r
+<dl>\r
+<dd>Establece la velocidad del objeto volador\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>velocidad </CODE> : Nuevo vector velocidad</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cVector.html b/doc/ref/cVector.html
new file mode 100644 (file)
index 0000000..ede5dc2
--- /dev/null
@@ -0,0 +1,399 @@
+<HTML>\r
+<H2>Class: cVector</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                         <A HREF=cObjetoPersistente.html>cObjetoPersistente</A> ----+\r                                                |\r                                             cVector\r</pre><hr>\r
+<B>Description:</B><BR>La clase cVector es la implementación de un vector físico. Esta clase es el esqueleto de\r
+      la aplicación ya que todas las velocidades y posiciones son del tipo cVector.\r
+      Todos los calculos de movimientos, distancias, etc. se manejan con los metodos de esta clase\r
+<p><B>Unit:</B><BR><A HREF=Vectores.html>Vectores</A>\r
+<code>   <A HREF=Vectores.pas>(Vectores.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#0">constructor create( v: cVector ); overload;</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor que copia los atributos de un Vector existente\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#1">constructor create( x: tLongitud = 0; y: tLongitud = 0; z: tLongitud = 0 ); overload;</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#2">function mAddModulo( modulo: tLongitud ): cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Aumenta (o disminuye si el argumente es negativo) el modulo del vector\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#3">function mAddX( x: tLongitud ): cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Agrega un valor a la componente X\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#4">function mAddY( y: tLongitud ): cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Agrega un valor a la componente Y\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#5">function mAddZ( z: tLongitud ): cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Agrega un valor a la componente Z\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#6">procedure mDesSerializar( str: string ); override;</A><BR>\r
+</dt>\r
+<dd>\r
+Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#7">function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#8">function mGetDistancia( vec: cVector ): tLongitud;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la distancia al a otro vector\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#9">function mGetModulo: tLongitud;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene el modulo del vector\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#10">function mGetX: tLongitud;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la componente X\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#11">function mGetY: tLongitud;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la componente Y\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#12">function mGetZ: tLongitud;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene la componente Z\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#13">function mHacerVersor: cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Convierte el vector en un versor (norma 1)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#14">function mModificarCon( vel: cVector; dT: tTiempo ): cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Modifica el vector con basandose en otro vector (pensado como velocidad) y un\r
+          intervalo de tiempo siguiendo la formula física X' = X + V * dt\r
+          (este metodo esta pensado basicamente para calcular los movimientos)\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#15">function mMultiplicar( vec: cVector ): cVector; overload;</A><BR>\r
+</dt>\r
+<dd>\r
+Se multiplica vectorialmente a si mismo por el vector vec\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#16">function mMultiplicar( esc: tLongitud ): cVector; overload;</A><BR>\r
+</dt>\r
+<dd>\r
+Se multiplica por un escalar\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#17">function mMultiplicarEsc( vec: cVector ): tLongitud;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene el producto escalar entre si mismo y el vector vec\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#18">function mRestar( vec: cVector ): cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Resta a si mismo el vector vec\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#19">function mSerializar: string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve una cadena de texto con el objeto serializado.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#20">function mSet( x, y, z: tLongitud ): cVector; overload;</A><BR>\r
+</dt>\r
+<dd>\r
+Establece los valores del vector x, y, z\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#21">function mSet( v: cVector ): cVector; overload;</A><BR>\r
+</dt>\r
+<dd>\r
+Modifica las componentes del vector basandose en otro\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#22">function mSetModulo( modulo: tLongitud ): cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Setea el modulo del vector a un valor determinado\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#23">function mSetX( x: tLongitud ): cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Setea la componente X\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#24">function mSetY( y: tLongitud ): cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Setea la componente Y\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#25">function mSetZ( z: tLongitud ): cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Setea la componente Z\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVector.html#26">function mSumar( vec: cVector ): cVector;</A><BR>\r
+</dt>\r
+<dd>\r
+Suma a si mismo el vector vec\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( v: cVector ); overload;</CODE>\r
+<dl>\r
+<dd>Constructor que copia los atributos de un Vector existente</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( x: tLongitud = 0; y: tLongitud = 0; z: tLongitud = 0 ); overload;</CODE>\r
+<dl>\r
+<dd>Crea un nuevo vector basandose en los atributos dados como parámetro.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>x </CODE> : Componente en el eje X</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>y </CODE> : Componente en el eje Y</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>z </CODE> : Componente en el eje Z</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="2"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mAddModulo( modulo: tLongitud ): cVector;</CODE>\r
+<dl>\r
+<dd>Setea el modulo del vector a un valor determinado (sólo tiene sentido si el modulo actual es distinto de cero)\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>modulo </CODE> : Modulo a adherir al verctor</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="3"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mAddX( x: tLongitud ): cVector;</CODE>\r
+<dl>\r
+<dd>Agrega un valor a la componente X\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>x </CODE> : Valor a sumarle a la componente X</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="4"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mAddY( y: tLongitud ): cVector;</CODE>\r
+<dl>\r
+<dd>Agrega un valor a la componente Y\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>y </CODE> : Valor a sumarle a la componente Y</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="5"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mAddZ( z: tLongitud ): cVector;</CODE>\r
+<dl>\r
+<dd>Agrega un valor a la componente Z\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>z </CODE> : Valor a sumarle a la componente Z</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="6"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mDesSerializar( str: string ); override;</CODE>\r
+<dl>\r
+<dd>Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>str </CODE> : Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="7"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</CODE>\r
+<dl>\r
+<dd>Devuelve el estado del objeto basandose en la cantidad de datos requeridos:<br>\r
+    Siempre devuelve los valores de las componentes x, y, z y si debugLevel es mayor que DI_NORMAL,\r
+    también muestra el módulo.\r
+    @return             Cadena de texto con el estado del Objeto.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>debugLevel </CODE> : Cantidad de información requerida</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="8"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetDistancia( vec: cVector ): tLongitud;</CODE>\r
+<dl>\r
+<dd>Obtiene la distancia al a otro vector (en realidad se tratan como puntos)\r
+    @returns     Distancia al otro vector\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>vec </CODE> : Punto al cual se calcula la distancia</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="9"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetModulo: tLongitud;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Modulo (o norma) del vector</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="10"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetX: tLongitud;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Componente X del vector</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="11"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetY: tLongitud;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Componente Y del vector</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="12"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetZ: tLongitud;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Componente Z del vector</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="13"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mHacerVersor: cVector;</CODE>\r
+<dl>\r
+<dd>Convierte el vector en un versor (sólo tiene sentido si el modulo actual es distinto de cero)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="14"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mModificarCon( vel: cVector; dT: tTiempo ): cVector;</CODE>\r
+<dl>\r
+<dd>Modifica el vector con basandose en otro vector (pensado como velocidad) y un\r
+    intervalo de tiempo siguiendo la formula física X' = X + V * dt\r
+    (este metodo esta pensado basicamente para calcular los movimientos)\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>vel </CODE> : Vector velocidad</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>dT </CODE> :  Intervalo de tiempo</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="15"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mMultiplicar( vec: cVector ): cVector; overload;</CODE>\r
+<dl>\r
+<dd>Se multiplica por un escalar\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>esc </CODE> : Escalar por el cual se multiplica</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="16"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mMultiplicar( esc: tLongitud ): cVector; overload;</CODE>\r
+<dl>\r
+<dd>Se multiplica por un escalar</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="17"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mMultiplicarEsc( vec: cVector ): tLongitud;</CODE>\r
+<dl>\r
+<dd>Obtiene el producto escalar entre si mismo y el vector vec\r
+    @return      Producto escalar entre los vectores\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>vec </CODE> : Vector por el cual se multiplica escalarmente</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="18"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mRestar( vec: cVector ): cVector;</CODE>\r
+<dl>\r
+<dd>Resta a si mismo el vector vec\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>vec </CODE> : Vector que se resta</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="19"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSerializar: string; override;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Cadena de texto con el objeto serializado.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="20"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSet( x, y, z: tLongitud ): cVector; overload;</CODE>\r
+<dl>\r
+<dd>Establece las componentes del vector\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>x </CODE> : Nuevo valor de la componente en el eje X</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>y </CODE> : Nuevo valor de la componente en el eje Y</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>z </CODE> : Nuevo valor de la componente en el eje Z</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="21"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSet( v: cVector ): cVector; overload;</CODE>\r
+<dl>\r
+<dd>Modifica las componentes del vector basandose en otro</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="22"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSetModulo( modulo: tLongitud ): cVector;</CODE>\r
+<dl>\r
+<dd>Setea el modulo del vector a un valor determinado\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>modulo </CODE> : Valor del nuevo Módulo</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="23"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSetX( x: tLongitud ): cVector;</CODE>\r
+<dl>\r
+<dd>Setea la componente X\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>x </CODE> : Nuevo valor de la componente en el eje X</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="24"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSetY( y: tLongitud ): cVector;</CODE>\r
+<dl>\r
+<dd>Setea la componente Y\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>y </CODE> : Nuevo valor de la componente en el eje Y</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="25"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSetZ( z: tLongitud ): cVector;</CODE>\r
+<dl>\r
+<dd>Setea la componente Z\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>z </CODE> : Nuevo valor de la componente en el eje Z</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="26"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mSumar( vec: cVector ): cVector;</CODE>\r
+<dl>\r
+<dd>Suma a si mismo el vector vec\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>vec </CODE> : Vector a sumarle</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/cVista.html b/doc/ref/cVista.html
new file mode 100644 (file)
index 0000000..a8e3caf
--- /dev/null
@@ -0,0 +1,328 @@
+<HTML>\r
+<H2>Class: cVista</H2>\r
+<pre> <A HREF=cObjeto.html>cObjeto</A> ----+\r                                  |\r                               cVista\r</pre><hr>\r
+<B>Description:</B><BR>Interpreta y dibuja los datos del modelo en un formulario\r
+<p><B>Unit:</B><BR><A HREF=Vista.html>Vista</A>\r
+<code>   <A HREF=Vista.pas>(Vista.pas)</code></A><BR><BR>\r
+<p><B>Constructors:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVista.html#0">constructor create( formulario: TCustomForm; ov: cObjetoVolador; calidad: boolean = true );</A><BR>\r
+</dt>\r
+<dd>\r
+Constructor\r
+</dd>\r
+</dl>\r
+<p><B>Methods:</B><BR>\r
+<dl>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVista.html#1">destructor destroy; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Destructor\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVista.html#2">procedure mCamaraSiguiente;</A><BR>\r
+</dt>\r
+<dd>\r
+Cambia a la siguiente cámara\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVista.html#3">procedure mCambiarCalidad;</A><BR>\r
+</dt>\r
+<dd>\r
+Invierte la calidad de los gráficos. Es decir, si estaban en baja los pone\r
+          en alta y vice versa.\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVista.html#4">procedure mCambiarCamara( cam: tCamaras );</A><BR>\r
+</dt>\r
+<dd>\r
+Permite realizar el cambio de camara\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cVista.html#5">function mCrearCamara( cam: tCamaras; ov: cObjetoVolador ): cCamara;</A><BR>\r
+</dt>\r
+<dd>\r
+Crea una cámara según el tipo\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVista.html#6">procedure mCrearCamaraDeArma( a: cArma );</A><BR>\r
+</dt>\r
+<dd>\r
+Crea la cámara del arma\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cVista.html#7">procedure mDibujarOV( proy: tPProy );</A><BR>\r
+</dt>\r
+<dd>\r
+Dibuja un ObjetoVolador\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cVista.html#8">procedure mDibujarOVLockeado( proy: tPProy );</A><BR>\r
+</dt>\r
+<dd>\r
+Dibuja el ObjetoVolador lockeado por la nave propia\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVista.html#9">procedure mDibujarVista( oEspacio: cEspacio );</A><BR>\r
+</dt>\r
+<dd>\r
+Dibuja todos los Objetos Voladores que ve la cámara\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cVista.html#10">procedure mGameOver;</A><BR>\r
+</dt>\r
+<dd>\r
+Muestra un mensaje de game over\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVista.html#11">function mGetCamaraStr: string;</A><BR>\r
+</dt>\r
+<dd>\r
+Devuelve que camara esta activa\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVista.html#12">function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</A><BR>\r
+</dt>\r
+<dd>\r
+Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cVista.html#13">function mGetFormLado: integer;</A><BR>\r
+</dt>\r
+<dd>\r
+Obtiene el lado menor del formulario\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cVista.html#14">function mGetTam( proy: tPProy ): integer;</A><BR>\r
+</dt>\r
+<dd>\r
+Convierte el tamaño obtenido de la cámara a uno proporcional en píxeles\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cVista.html#15">function mGetX( proy: tPProy ): integer;</A><BR>\r
+</dt>\r
+<dd>\r
+Convierte la componente en x obtenida de la cámara a una proporcional en píxeles\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cVista.html#16">function mGetY( proy: tPProy ): integer;</A><BR>\r
+</dt>\r
+<dd>\r
+Convierte la componente en y obtenida de la cámara a una proporcional en píxeles\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cVista.html#17">function mObjetoVoladorLockedToFilename( obj: tObjetosVoladores ): string;</A><BR>\r
+</dt>\r
+<dd>\r
+Convierte un tipo tObjetosVoladores al nombre del archivo que guarda su bitmap lockeado\r
+</dd>\r
+<dt>\r
+<IMG SRC=protected.gif>\r
+<A HREF="cVista.html#18">function mObjetoVoladorToFilename( obj: tObjetosVoladores ): string;</A><BR>\r
+</dt>\r
+<dd>\r
+Convierte un tipo tObjetosVoladores al nombre del archivo que guarda su bitmap\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVista.html#19">procedure mSetAltaCalidad;</A><BR>\r
+</dt>\r
+<dd>\r
+Setea gráficos de alta calidad\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVista.html#20">procedure mSetBajaCalidad;</A><BR>\r
+</dt>\r
+<dd>\r
+Setea gráficos de baja calidad\r
+</dd>\r
+<dt>\r
+<IMG SRC=public.gif>\r
+<A HREF="cVista.html#21">procedure mSetForm( oForm: TCustomForm );</A><BR>\r
+</dt>\r
+<dd>\r
+Define el formulario en donde dibujar\r
+</dd>\r
+</dl>\r
+<HR>\r
+<p><IMG SRC=constructors.gif>\r
+<A NAME="0"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>constructor create( formulario: TCustomForm; ov: cObjetoVolador; calidad: boolean = true );</CODE>\r
+<dl>\r
+<dd>Constructor\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>formulario </CODE> : Formulario en donde dibujará la vista</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> :         Objeto Volador en el cual montar la cámara</dd><p>\r
+</dl></dd></dl><HR>\r
+<p><IMG SRC=methods.gif>\r
+<A NAME="1"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>destructor destroy; override;</CODE>\r
+<dl>\r
+<dd>Destructor</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="2"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mCamaraSiguiente;</CODE>\r
+<dl>\r
+<dd>Cambia a la siguiente cámara</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="3"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mCambiarCalidad;</CODE>\r
+<dl>\r
+<dd>Invierte la calidad de los gráficos. Es decir, si estaban en baja los pone\r
+          en alta y vice versa.</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="4"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mCambiarCamara( cam: tCamaras );</CODE>\r
+<dl>\r
+<dd>Permite realizar el cambio de camara</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="5"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mCrearCamara( cam: tCamaras; ov: cObjetoVolador ): cCamara;</CODE>\r
+<dl>\r
+<dd>Crea una cámara según el tipo\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>cam </CODE> : Tipo de Cámara</dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> :  Portador de la cámara</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Nueva cámara creada</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="6"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mCrearCamaraDeArma( a: cArma );</CODE>\r
+<dl>\r
+<dd>Crea la cámara del arma\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>ov </CODE> : Objeto Volador portador de la camara</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="7"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mDibujarOV( proy: tPProy );</CODE>\r
+<dl>\r
+<dd>Dibuja un ObjetoVolador\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>proy </CODE> : Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion\r
+                de un determinado objeto volador (proporcionado por la cámara)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="8"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mDibujarOVLockeado( proy: tPProy );</CODE>\r
+<dl>\r
+<dd>Dibuja el ObjetoVolador lockeado por la nave propia\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>proy </CODE> : Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion\r
+                de un determinado objeto volador (proporcionado por la cámara)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="9"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mDibujarVista( oEspacio: cEspacio );</CODE>\r
+<dl>\r
+<dd>Dibuja todos los Objetos Voladores que ve la cámara\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>oEspacio </CODE> : Espacio del cual obtener la lista de objetos a interpretar por la cámara\r
+                    para dibujarlos</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="10"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>procedure mGameOver;</CODE>\r
+<dl>\r
+<dd>Muestra un mensaje de game over</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="11"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetCamaraStr: string;</CODE>\r
+<dl>\r
+<dd>Devuelve que camara esta activa</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="12"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;</CODE>\r
+<dl>\r
+<dd>Devuelve el estado del objeto basandose en la cantidad de datos requeridos.\r
+    @return            Cadena de texto con el estado del Objeto.\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>debugLevel </CODE> : Cantidad de información requerida</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="13"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mGetFormLado: integer;</CODE>\r
+<dl>\r
+<dd></dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;El alto o el ancho del formulario, dependiendo de cual sea menor</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="14"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mGetTam( proy: tPProy ): integer;</CODE>\r
+<dl>\r
+<dd>Convierte el tamaño obtenido de la cámara a uno proporcional en píxeles\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>proy </CODE> : Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion\r
+                 de un determinado objeto volador (proporcionado por la cámara)</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Tamaño del objeto en píxeles (tamaño del lado del cuadrado que se usará para\r
+                 dibujar el bitmap)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="15"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mGetX( proy: tPProy ): integer;</CODE>\r
+<dl>\r
+<dd>Convierte la componente en x obtenida de la cámara a una proporcional en píxeles\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>proy </CODE> : Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion\r
+                 de un determinado objeto volador (proporcionado por la cámara)</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Componente en X del objeto en píxeles (x de la esquina superior izquierdadel\r
+                 cuadrado que se usará para dibujar el bitmap)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="16"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mGetY( proy: tPProy ): integer;</CODE>\r
+<dl>\r
+<dd>Convierte la componente en y obtenida de la cámara a una proporcional en píxeles\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>proy </CODE> : Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion\r
+                 de un determinado objeto volador (proporcionado por la cámara)</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Componente en Y del objeto en píxeles (y de la esquina superior izquierdadel\r
+                 cuadrado que se usará para dibujar el bitmap)</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="17"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mObjetoVoladorLockedToFilename( obj: tObjetosVoladores ): string;</CODE>\r
+<dl>\r
+<dd>Convierte un tipo tObjetosVoladores al nombre del archivo que guarda su bitmap lockeado\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>obj </CODE> : Tipo de objeto volador</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Nombre del archivo que almacena el bitmap que lo representa</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="18"></A><P>\r
+<IMG SRC=protected_big.gif>\r
+<CODE>function mObjetoVoladorToFilename( obj: tObjetosVoladores ): string;</CODE>\r
+<dl>\r
+<dd>Convierte un tipo tObjetosVoladores al nombre del archivo que guarda su bitmap\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>obj </CODE> : Tipo de objeto volador</dd><dd><B>Returns</B></dd><dd>&nbsp;&nbsp;&nbsp;Nombre del archivo que almacena el bitmap que lo representa</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="19"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mSetAltaCalidad;</CODE>\r
+<dl>\r
+<dd>Setea gráficos de alta calidad</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="20"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mSetBajaCalidad;</CODE>\r
+<dl>\r
+<dd>Setea gráficos de baja calidad</dd><p>\r
+</dl></dd></dl><HR>\r
+<A NAME="21"></A><P>\r
+<IMG SRC=public_big.gif>\r
+<CODE>procedure mSetForm( oForm: TCustomForm );</CODE>\r
+<dl>\r
+<dd>Define el formulario en donde dibujar\r
+    </dd><dd><B>Parameters</B></dd><dd>&nbsp;&nbsp;&nbsp;<CODE>oForm </CODE> : Formulario en el cual dibujará la vista</dd><p>\r
+</dl></dd></dl><HR>\r
+</HTML>\r
diff --git a/doc/ref/constructors.gif b/doc/ref/constructors.gif
new file mode 100644 (file)
index 0000000..d130953
Binary files /dev/null and b/doc/ref/constructors.gif differ
diff --git a/doc/ref/functions.gif b/doc/ref/functions.gif
new file mode 100644 (file)
index 0000000..240968a
Binary files /dev/null and b/doc/ref/functions.gif differ
diff --git a/doc/ref/functions_big.gif b/doc/ref/functions_big.gif
new file mode 100644 (file)
index 0000000..edc29b7
Binary files /dev/null and b/doc/ref/functions_big.gif differ
diff --git a/doc/ref/index-class.html b/doc/ref/index-class.html
new file mode 100644 (file)
index 0000000..5e81a31
--- /dev/null
@@ -0,0 +1,297 @@
+<html>\r
+<h2>Class Index</h2>\r
+<dl>\r
+  <dt>\r
+    <li><a href=cArma.html>cArma</a>\r
+  </dt>\r
+  <dd>La clase cArma esta pensada como una clase abtracta. En ella se encuentran\r
+      características comunes a todas las armas.</dd>\r
+  <dt>\r
+    <li><a href=cCamara.html>cCamara</a>\r
+  </dt>\r
+  <dd>Implementa una cámara que se encarga de representar los objetos en 2D.</dd>\r
+  <dt>\r
+    <li><a href=cCamaraAbajo.html>cCamaraAbajo</a>\r
+  </dt>\r
+  <dd>Implementa una cámara para ver hacia abajo.</dd>\r
+  <dt>\r
+    <li><a href=cCamaraArriba.html>cCamaraArriba</a>\r
+  </dt>\r
+  <dd>Implementa una cámara para ver hacia arriba.</dd>\r
+  <dt>\r
+    <li><a href=cCamaraFrontal.html>cCamaraFrontal</a>\r
+  </dt>\r
+  <dd>Implementa una cámara frontal.</dd>\r
+  <dt>\r
+    <li><a href=cCamaraLatDer.html>cCamaraLatDer</a>\r
+  </dt>\r
+  <dd>Implementa una cámara lateral derecha.</dd>\r
+  <dt>\r
+    <li><a href=cCamaraLatIzq.html>cCamaraLatIzq</a>\r
+  </dt>\r
+  <dd>Implementa una cámara lateral izquierda.</dd>\r
+  <dt>\r
+    <li><a href=cCamaraMapa.html>cCamaraMapa</a>\r
+  </dt>\r
+  <dd>Implementa una cámara para ver hacia abajo pero alejado del cameraman.\r
+      Es como si observara al cameraman desde arriba.</dd>\r
+  <dt>\r
+    <li><a href=cCamaraTrasera.html>cCamaraTrasera</a>\r
+  </dt>\r
+  <dd>Implementa una cámara trasera.</dd>\r
+  <dt>\r
+    <li><a href=cCoordenadas.html>cCoordenadas</a>\r
+  </dt>\r
+  <dd>Implementa un sistema de coordenadas y metodos para rotarlo.</dd>\r
+  <dt>\r
+    <li><a href=cEspacio.html>cEspacio</a>\r
+  </dt>\r
+  <dd>Se encarga de controlar la interacción entre\r
+      las naves y el responsable de manejar el tiempo.</dd>\r
+  <dt>\r
+    <li><a href=cFiltro.html>cFiltro</a>\r
+  </dt>\r
+  <dd>Es una clase abstracta que representa un filtro que recibe una lista de objetos y devuelve otra filtrada.</dd>\r
+  <dt>\r
+    <li><a href=cFiltroAbajo.html>cFiltroAbajo</a>\r
+  </dt>\r
+  <dd>Implementa un filtro que "ve" hacia abajo.</dd>\r
+  <dt>\r
+    <li><a href=cFiltroArriba.html>cFiltroArriba</a>\r
+  </dt>\r
+  <dd>Implementa un filtro que "ve" hacia arriba.</dd>\r
+  <dt>\r
+    <li><a href=cFiltroFrontal.html>cFiltroFrontal</a>\r
+  </dt>\r
+  <dd>Implementa un filtro que "ve" hacia adelante.</dd>\r
+  <dt>\r
+    <li><a href=cFiltroLatDer.html>cFiltroLatDer</a>\r
+  </dt>\r
+  <dd>Implementa un filtro que "ve" hacia la derecha.</dd>\r
+  <dt>\r
+    <li><a href=cFiltroLatIzq.html>cFiltroLatIzq</a>\r
+  </dt>\r
+  <dd>Implementa un filtro que "ve" hacia la izquierda.</dd>\r
+  <dt>\r
+    <li><a href=cFiltroLock.html>cFiltroLock</a>\r
+  </dt>\r
+  <dd>Implementa un filtro que "ve" hacia adelante y que además sólo puede\r
+      ver objetos del tipo cNave y cMeteorito.</dd>\r
+  <dt>\r
+    <li><a href=cFiltroMapa.html>cFiltroMapa</a>\r
+  </dt>\r
+  <dd>Implementa un filtro que "ve" hacia abajo pero desde arriba a una cierta distancia\r
+      del observador. Es como si observara al observador mismo.</dd>\r
+  <dt>\r
+    <li><a href=cFiltroTrasero.html>cFiltroTrasero</a>\r
+  </dt>\r
+  <dd>Implementa un filtro que "ve" hacia atrás.</dd>\r
+  <dt>\r
+    <li><a href=cLaser.html>cLaser</a>\r
+  </dt>\r
+  <dd>El laser es un tipo de arma básica. Es la que menos daño hace pero la que más rápido viaja<br>\r
+      <u>Características:</u>\r
+      \r
+    <pre>\r
+      Dimensión      0,1       metros (10 cm)\r
+      Potencia:      1         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:       1         Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad:     0,4       metros/milisegundos (1440 km/h)\r
+      Alcance:       3000      milisegundos (3 segundos, 1,2 km)\r
+      </pre>\r
+  </dd>\r
+  <dt>\r
+    <li><a href=cLista.html>cLista</a>\r
+  </dt>\r
+  <dd>Lista exactamente igual a TList, solo que el destructor tambien destruye todos\r
+      los objetos que contiene</dd>\r
+  <dt>\r
+    <li><a href=cMeteorito.html>cMeteorito</a>\r
+  </dt>\r
+  <dd>Representa un objeto volador básico. Tiene una velocidad constante.</dd>\r
+  <dt>\r
+    <li><a href=cMisil.html>cMisil</a>\r
+  </dt>\r
+  <dd>El misil es un tipo de arma básica. Hace un daño considerable y su velocidad también es alta<br>\r
+      <u>Características:</u>\r
+      \r
+    <pre>\r
+      Dimensión      0,5       metros (50 cm)\r
+      Potencia:      20        Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:       1         Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad:     0,3       metros/milisegundos (1080 km/h)\r
+      Alcance:       5000      milisegundos (5 segundos, 1,5 km)\r
+      </pre>\r
+  </dd>\r
+  <dt>\r
+    <li><a href=cMisilDirigido.html>cMisilDirigido</a>\r
+  </dt>\r
+  <dd>El misil dirigido es un tipo de arma avanzada. Persigue a su objetivo hasta que lo alcanza o\r
+      hasta que se le acaba el alcance. Hace un daño alto, su velocidad es mediana y tiene un gran alcance.<br>\r
+      <u>Características:</u>\r
+      \r
+    <pre>\r
+      Dimensión      0,7       metros (70 cm)\r
+      Potencia:      30        Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:       1         Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad:     0,25      metros/milisegundos (900 km/h)\r
+      Alcance:       20000     milisegundos (20 segundos, 5 km)\r
+      Area de Lock:  2000      metros (2 km)\r
+      </pre>\r
+  </dd>\r
+  <dt>\r
+    <li><a href=cNave.html>cNave</a>\r
+  </dt>\r
+  <dd>Clase abstracta con elementos comunes a todas las naves.</dd>\r
+  <dt>\r
+    <li><a href=cNaveEnemiga.html>cNaveEnemiga</a>\r
+  </dt>\r
+  <dd>La clase cNaveEnemiga esta pensada como una clase abtracta. En ella se encuentran\r
+      características comunes a todas las naves enemigas.</dd>\r
+  <dt>\r
+    <li><a href=cNaveEspia.html>cNaveEspia</a>\r
+  </dt>\r
+  <dd>Es una nave sin armas que se desplaza por el epacio\r
+      hasta que encuentra una nave propia, en ese momento empieza a huir avisando a\r
+      las demas naves enemigas la ultima posicion de la nave propia.<br>\r
+      <u>Características:</u>\r
+      \r
+    <pre>\r
+      Dimensión:            10        metros\r
+      Potencia:             1         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              30        Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,2       metros/milisegundos (720 km/h)\r
+      Campo de radar:       2000      metros (2 km)\r
+      Misiles:              0\r
+      Misiles Dirigidos:    0\r
+      </pre>\r
+  </dd>\r
+  <dt>\r
+    <li><a href=cNaveLiviana.html>cNaveLiviana</a>\r
+  </dt>\r
+  <dd>Es una nave sin misiles, solo con lasers que\r
+      se desplaza por el epacio hasta que encuentra una nave propia para atacar.<br>\r
+      <u>Características:</u>\r
+      \r
+    <pre>\r
+      Dimensión:            15        metros\r
+      Potencia:             1         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              60        Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,18      metros/milisegundos (648 km/h)\r
+      Campo de radar:       3000      metros (3 km)\r
+      Misiles:              0\r
+      Misiles Dirigidos:    0\r
+      </pre>\r
+  </dd>\r
+  <dt>\r
+    <li><a href=cNavePesada.html>cNavePesada</a>\r
+  </dt>\r
+  <dd>Es una nave con misiles y lasers (igual que la propia)\r
+      que se desplaza por el epacio hasta que encuentra una nave propia para atacar.<br>\r
+      <u>Características:</u>\r
+      \r
+    <pre>\r
+      Dimensión:            25        metros\r
+      Potencia:             2         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              100       Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,17      metros/milisegundos (612 km/h)\r
+      Campo de radar:       5000      metros (5 km)\r
+      Misiles:              5\r
+      Misiles Dirigidos:    2\r
+      </pre>\r
+  </dd>\r
+  <dt>\r
+    <li><a href=cNavePropia.html>cNavePropia</a>\r
+  </dt>\r
+  <dd>Es la nave que será controlada por el jugador.<br>\r
+      <u>Características:</u>\r
+      \r
+    <pre>\r
+      Dimensión:            15        metros\r
+      Potencia:             5         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              100       Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,17      metros/milisegundos (612 km/h)\r
+      Misiles:              10\r
+      Misiles Dirigidos:    5\r
+      </pre>\r
+  </dd>\r
+  <dt>\r
+    <li><a href=cNaveSuicida.html>cNaveSuicida</a>\r
+  </dt>\r
+  <dd>Es una nave sin armas que se desplaza por el epacio\r
+      hasta que encuentra una nave propia y trata de chocarla.<br>\r
+      <u>Características:</u>\r
+      \r
+    <pre>\r
+      Dimensión:            10        metros\r
+      Potencia:             4         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              30        Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,2       metros/milisegundos (720 km/h)\r
+      Campo de radar:       2500      metros (2,5 km)\r
+      Misiles:              0\r
+      Misiles Dirigidos:    0\r
+      </pre>\r
+  </dd>\r
+  <dt>\r
+    <li><a href=cObjeto.html>cObjeto</a>\r
+  </dt>\r
+  <dd>Es una clase abstracta para agregar algunos métodos generales útiles\r
+      para el resto de las clases que implementemos. Podría considerarse una\r
+      extensión a la funcionalidad básica dada por TObject.</dd>\r
+  <dt>\r
+    <li><a href=cObjetoPersistente.html>cObjetoPersistente</a>\r
+  </dt>\r
+  <dd>Es una clase abstracta para hacer persistente un objeto.\r
+      Básicamente provee métodos para serialización.\r
+      NOTA: Es importante que el ID del objeto sea el primer atributo en la\r
+            serialización, de otra manera puede ser malinterpretado al des-\r
+            serializarlo.</dd>\r
+  <dt>\r
+    <li><a href=cObjetoVolador.html>cObjetoVolador</a>\r
+  </dt>\r
+  <dd>Clase abstracta, implementa todas las funcionalidades básicas de los objetos voladores.\r
+      De esta van a derivar la mayor parte del resto de las clases.</dd>\r
+  <dt>\r
+    <li><a href=cVector.html>cVector</a>\r
+  </dt>\r
+  <dd>La clase cVector es la implementación de un vector físico. Esta clase es el esqueleto de\r
+      la aplicación ya que todas las velocidades y posiciones son del tipo cVector.\r
+      Todos los calculos de movimientos, distancias, etc. se manejan con los metodos de esta clase</dd>\r
+  <dt>\r
+    <li><a href=cVista.html>cVista</a>\r
+  </dt>\r
+  <dd>Interpreta y dibuja los datos del modelo en un formulario</dd>\r
+  <dt>\r
+    <li><a href=ECameramanDestruido.html>ECameramanDestruido</a>\r
+  </dt>\r
+  <dd>Excepcion producida por la cámara si se utiliza cuando el cameraman fue destruido</dd>\r
+  <dt>\r
+    <li><a href=ENavePropiaDestruida.html>ENavePropiaDestruida</a>\r
+  </dt>\r
+  <dd>Excepcion producida por el espacio si la nave propia fue destruido</dd>\r
+  <dt>\r
+    <li><a href=EObservadorDestruido.html>EObservadorDestruido</a>\r
+  </dt>\r
+  <dd>Excepcion producida por el filtro si se utiliza cuando el observador fue destruido</dd>\r
+  <dt>\r
+    <li><a href=ERegExpr.html>ERegExpr</a>\r
+  </dt>\r
+  <dd>Excepción de expresiones regulares</dd>\r
+  <dt>\r
+    <li><a href=ESerializacion.html>ESerializacion</a>\r
+  </dt>\r
+  <dd>Excepcion producida si hay un error al serializar.</dd>\r
+  <dt>\r
+    <li><a href=TConfigForm.html>TConfigForm</a>\r
+  </dt>\r
+  <dd>Formulario para configurar la aplicación</dd>\r
+  <dt>\r
+    <li><a href=TMainForm.html>TMainForm</a>\r
+  </dt>\r
+  <dd>Formulario principal de la aplicación</dd>\r
+  <dt>\r
+    <li><a href=TRegExpr.html>TRegExpr</a>\r
+  </dt>\r
+  <dd>Clase auxiliar que implementa expresiones Regulares. Se ultiliza para validar los campos de texto</dd>\r
+</dl>\r
+</html>\r
diff --git a/doc/ref/index-function.html b/doc/ref/index-function.html
new file mode 100644 (file)
index 0000000..ea44fd2
--- /dev/null
@@ -0,0 +1,30 @@
+<HTML>\r
+<H2>Function Index</H2>\r
+<dl>\r
+<dt><li><A HREF=RegExpr.html#ExecRegExpr >ExecRegExpr </A></dt>\r
+<dd>true if string AInputString match regular expression ARegExpr\r
+    ! will raise exeption if syntax errors in ARegExpr</dd>\r
+<dt><li><A HREF=Camara.html#listSort>listSort</A></dt>\r
+<dd>Funcion para ordenar los elementos de la lista que se devuelve\r
+    </dd>\r
+<dt><li><A HREF=RegExpr.html#QuoteRegExprMetaChars >QuoteRegExprMetaChars </A></dt>\r
+<dd>Replace all metachars with its safe representation,\r
+    for example 'abc$cd.(' converts into 'abc\$cd\.\('\r
+    This function usefull for r.e. autogeneration from\r
+    user input</dd>\r
+<dt><li><A HREF=RegExpr.html#ReplaceRegExpr >ReplaceRegExpr </A></dt>\r
+<dd>Returns AInputStr with r.e. occurencies replaced by AReplaceStr</dd>\r
+<dt><li><A HREF=SerializacionUtils.html#restaurarObjeto>restaurarObjeto</A></dt>\r
+<dd>Crea un objeto a partir de un string con el nombre de su clase y otro\r
+    con su representación serializada.\r
+    </dd>\r
+<dt><li><A HREF=RegExpr.html#SplitRegExpr >SplitRegExpr </A></dt>\r
+<dd>Split AInputStr into APieces by r.e. ARegExpr occurencies</dd>\r
+<dt><li><A HREF=RegExpr.html#strcspn >strcspn </A></dt>\r
+<dt><li><A HREF=RegExpr.html#StrLComp >StrLComp </A></dt>\r
+<dt><li><A HREF=RegExpr.html#StrLCopy >StrLCopy </A></dt>\r
+<dt><li><A HREF=RegExpr.html#StrLen >StrLen </A></dt>\r
+<dt><li><A HREF=RegExpr.html#StrPCopy >StrPCopy </A></dt>\r
+<dt><li><A HREF=RegExpr.html#StrPos >StrPos </A></dt>\r
+<dt><li><A HREF=RegExpr.html#StrScan >StrScan </A></dt>\r
+</dl></HTML>\r
diff --git a/doc/ref/index-unit.html b/doc/ref/index-unit.html
new file mode 100644 (file)
index 0000000..cdbfd6f
--- /dev/null
@@ -0,0 +1,256 @@
+<HTML>\r
+<H2>Unit Index</H2>\r
+<dl>\r
+<dt><li><A HREF=Armas.html>Armas</A></dt>\r
+<dd>Contiene las armas que pueden ser usadas por las diferentes naves.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    10/11/00: Se agrega el manejo de excepciones para evitar un BUG en cMisilDirigido. Si el objetivo del misil\r
+              dirigido es destruido, la velocidad permanece constante y en mGetDebugInfo se informa que esta destruido.\r
+    27/11/00: Se le agrega el manejo de la velocidad maxima a la clase cArma y se agrega el Alcance del arma, cambiando\r
+              el anterior por la Duracion.\r
+    01/12/00: Se cambiaron las dimensiones de las armas para que los disparos sean mas "jugables".\r
+    </PRE></dd>\r
+<dt><li><A HREF=Camara.html>Camara</A></dt>\r
+<dd>Implementa una cámara que se encarga de representar los objetos en 2D.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    10/11/00: Se agrega el manejo de excepciones para evitar usar la camara cuando el cameraman fue destruido.\r
+              Para lograr esto se crea una excepcion (ECameramanDestruido) que se lanza cuando hay una excepcion\r
+              de violacion de acceso a memoria. Esta excepcion debe ser manejada por quien meneje la camara y puede\r
+              ser lanzada por mGetDebugInfo o mProyectar.\r
+    01/12/00: Se elimina el atributo aApertura porque era absolutamente inecesario.\r
+              Se cambia la estructura interna para que el filtrado de los objetos los realice un cFiltro.\r
+    07/12/00: Se agregan nuevos métodos (protegidos) para obtener información de la cámara para poder crear subclases,\r
+              para lo cual tambien se hace virtual el método mProyectar.\r
+    08/12/00: Se quita el método para setear el filtro y se agrega un contructor que admite un filtro para reemplazarlo.\r
+              Se cambia esta clase para que sea abstracta. Se deja la implementacion del método mProyectar para las\r
+              subclases exlusivamente ya que ahora es abstracto. La cámara frontal (que antes se implementaba en\r
+              esta unidad), ahora está implementado la unidad Camaras al igual que el resto.\r
+    </PRE></dd>\r
+<dt><li><A HREF=Camaras.html>Camaras</A></dt>\r
+<dd>Se implementan varias cámaras en diferentes direcciones.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    09/12/00: Se agrega la clase cCamaraMapa.\r
+    </PRE></dd>\r
+<dt><li><A HREF=Coordenadas.html>Coordenadas</A></dt>\r
+<dd>Implementa un sistema de coordenadas y metodos para rotarlo.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    28/10/00: Se agregaron métodos para modificar el sistema de coordenadas, asignandole a un versor\r
+              particular la direccion de un vector arbitrario (mSetI, mSetJ, mSetK).\r
+    </PRE></dd>\r
+<dt><li><A HREF=Espacio.html>Espacio</A></dt>\r
+<dd>Se encarga de controlar la interacción entre\r
+    las naves y el responsable de manejar el tiempo.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    05/10/00: Se corrigió para que utilice los nuevos metodos de cNaveEnemiga y cObjetoVolador\r
+              Se corrigió el método mComunicarPosicion para que solo se comunique la posicion\r
+              a las naves que estan en el campo de radar de la nave espia.\r
+    07/10/00: Se agregaron los métodos mDestruir y mActualizarObjetoVolador. Se modificó el\r
+              método mActualizar (para usar los nuevos) y el método mDetectarColisiones para\r
+              manejar de forma más eficiente y clara la destrucción de objetos sin energía.\r
+    03/11/00: Se sacan los metodos mIniciay y mParar, ya que el control del tiempo y el encargado\r
+              de actualizar el espacio sera el Controlador (Controller).\r
+              Se agregaron métodos para facilitar la manipulación del espacio:\r
+              mQuitarObjeto, mGetObjetos, mSetObjetos y mSetNavePropia\r
+    05/11/00: Se corrigió un BUG que hacia que siempre el espacio se inicialice con una lista vacia\r
+              y una nave propia estandar (en el constructor).\r
+    09/11/00: Se corrigió un BUG que hacía que la nave espia no pueda escapar, ya que se avisaba a si misma.\r
+              Tambien se hace que ignore otras naves espias que esten avisando para evitar problemas similares.\r
+              (en el método mComunicarPosicion).\r
+    10/11/00: Se reemplaza el método mNavePropiaDestruida por una excepción (ENavePropiaDestruida).\r
+              Es lanzada por el método mActualizar y otros metodos privados que utilizan la nave propia.\r
+    27/11/00: Se agrega el control de disparos de las naves enemigas en el método mActualizar\r
+    29/11/00: Se elimina el método temporal mActualizarNavePropia.\r
+    01/12/00: Se modifica el método mActualizar para manejar los disparos de la nave propia.\r
+    </PRE></dd>\r
+<dt><li><A HREF=Filtro.html>Filtro</A></dt>\r
+<dd>Es una clase abstracta que representa filtro que recibe una lista de objetos y devuelve otra filtrada.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    06/12/00: Se agregan nuevos métodos (protegidos) para obtener información del filtro para poder crear subclases,\r
+              para lo cual tambien se hace virtual el método mVisible.\r
+    08/12/00: Se cambia esta clase para que sea abstracta. Se deja la implementacion del método mVisible para las\r
+              subclases exlusivamente ya que ahora es abstracto. El filtro frontal (que antes se implementaba en\r
+              esta unidad), ahora está implementado la unidad Filtros al igual que el resto.\r
+    </PRE></dd>\r
+<dt><li><A HREF=Filtros.html>Filtros</A></dt>\r
+<dd>Se implementan varios filtro en diferentes direcciones.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    09/12/00: Se agrega la clase cFiltroMapa.\r
+    </PRE></dd>\r
+<dt><li><A HREF=FormConfig.html>FormConfig</A></dt>\r
+<dd>Formulario para configurar la aplicación</dd>\r
+<dt><li><A HREF=FormMain.html>FormMain</A></dt>\r
+<dd>Formulario principal de la aplicación<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    29/11/00: Se agregan algunos controles gráficos con indicadores de energía y velocidad.\r
+              No se incluyen en una clase Vista porque son muy pequeños.\r
+    01/12/00: Se modifica levemente la interfaz.\r
+              Se agregan controles para los disparos y metodos pertinentes.\r
+    06/12/00: Se cambian minimamente los menúes, poniendo la parte del manejo\r
+              de escenarios en un submenú del menú Archivo.\r
+    08/12/00: Se termina de implementar la funcionalidad de los menúes\r
+                Archivo -> Abrir ...\r
+                Archivo -> Guardar ...\r
+                Archivo -> Escenario -> Abrir ...\r
+                Archivo -> Escenario -> Guardar ...\r
+              Se completa el 'destructor', ya que faltaban liberar bastantes\r
+              objetos.\r
+    </PRE></dd>\r
+<dt><li><A HREF=Lista.html>Lista</A></dt>\r
+<dd>Lista exactamente igual a TList, solo que el destructor tambien destruye\r
+    todos los objetos que contiene</dd>\r
+<dt><li><A HREF=Meteorito.html>Meteorito</A></dt>\r
+<dd>Representa un objeto volador básico. Tiene una velocidad constante.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    01/12/00: Se cambiaron las dimensiones por defecto para que los disparos sean mas "jugables".\r
+    </PRE></dd>\r
+<dt><li><A HREF=Nave.html>Nave</A></dt>\r
+<dd>Contiene una clase abstracta con elementos comunes a todas las naves.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    27/11/00: Se agrega toda la parte del manejo de disparos, agregándose los métodos mPuedeDispararLaser,\r
+              mPuedeDispararMisil, mPuedeDispararMisDir y mDisparar, además de varios atributos para manejar\r
+              los retardos de las armas. El método mDisparar se hace virtual ya que puede ser modificado por\r
+              las subclases para que cambie su mecanismo de disparos.\r
+    29/11/00: Se agregan métodos para obtener la cantidad de armamento que le queda a la nave para poder ser\r
+              mostrados (mGetMisiles y mGetMisilesDirigidos)\r
+    01/12/00: Se modifican levemente los metodos mPuedeDispararXxxx para que permitan disparar si el puntero\r
+              al Objeto Volador objetivo es nil.\r
+              Se Agregan los métodos mRetardarLaser, mRetardarMisil, mRetardarMisDir que resetea el contador\r
+              del retardo, mActualizarRetardos que resta el dT a los retardos, y mCrearLaserDisparado,\r
+              mCrearMisilDisparado y mCrearMisDirDisparado que crea el arma correspondiente (actualizando\r
+              retardos y todo lo que sea necesario) para que las subclases puedan escribir su propio mDisparar.\r
+              Se cambia el orden de los argumentos de mDisparar para aprovechar los argumentos por defecto.\r
+    08/12/00: Se sobreescribieron los métodos para establecer la velocidad y su módulo para evitar que se\r
+              sobrepase el límite de la velocidad máxima.\r
+    </PRE></dd>\r
+<dt><li><A HREF=NaveEnemiga.html>NaveEnemiga</A></dt>\r
+<dd>La clase cNaveEnemiga esta pensada como una clase abtracta. En ella se encuentran\r
+    características comunes a todas las naves enemigas.<br>\r
+      <i>Cambios:</i>\r
+    <PRE>\r
+    05/10/00: Se cambio el metodo mGetRadar por el metodo mDetectado, que devuelve true\r
+              si un objeto volador esta destro del campo de radar. De esta manera se logra\r
+              una abstracción mayor y un manejo mas intuitivo del radar.\r
+    </PRE></dd>\r
+<dt><li><A HREF=NavePropia.html>NavePropia</A></dt>\r
+<dd>Es la nave que será controlada por el jugador.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    05/10/00: Se corrigió el método mAcelerar porque tenía algunos bugs cuando la velocidad llegaba a cero.\r
+    01/12/00: Se implementan los disparon sobreescribiendo el método mDisparar de cNave y agregando algunos\r
+              atributos (aArmaSelect, aDisparando y aLockeado) y algunos métodos (mIntentarDisparo,\r
+              mSeleccionarArma, mSeleccionarArmaSig, mGetArmaSelect, mSetLockeado, mGetLockeado).\r
+              Se cambiaron las dimensiones de la nave para que los disparos sean mas "jugables".\r
+              Se cambia el orden de los argumentos de mDisparar para aprovechar los argumentos por defecto.\r
+              Se arreglaron un par de BUGs con punteros que apuntaba a objetos destruidos (aLockeado).\r
+    08/12/00: Se arregló una falla en el constructor que permitia crear la nave con una velocidad superior\r
+              a la máxima.\r
+    09/12/00: Se cambia el atributo disparando por un puntero a un arma que se disparara en el proximo turno.\r
+              También se cambia los métodos que lo utilizan y en particular se convierte el método\r
+              mIntentarDisparo en una función que devuelve dicho puntero para implementar la cámara en el arma.\r
+    </PRE></dd>\r
+<dt><li><A HREF=NavesEnemigas.html>NavesEnemigas</A></dt>\r
+<dd>Distintos tipos de Naves Enemigas<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    27/11/00: Se realizan algunos cambios para adaptarse a la nueva implementacion de cNave con disparos.\r
+    01/12/00: Se cambiaron las dimensiones de la nave para que los disparos sean mas "jugables".\r
+              Se cambia el orden de los argumentos de mDisparar para aprovechar los argumentos por defecto.\r
+    </PRE></dd>\r
+<dt><li><A HREF=Objeto.html>Objeto</A></dt>\r
+<dd>Es una clase abstracta para agregar algunos métodos generales útiles\r
+    para el resto de las clases que implementemos. Podría considerarse una\r
+    extensión a la funcionalidad básica dada por TObject.</dd>\r
+<dt><li><A HREF=ObjetoPersistente.html>ObjetoPersistente</A></dt>\r
+<dd>Es una clase abstracta para hacer persistente un objeto.\r
+    Básicamente provee métodos para serialización.<br>\r
+    <U>NOTA:</U>\r
+    <PRE>\r
+      Es importante que el ID del objeto sea el primer atributo en la\r
+      serialización, de otra manera puede ser malinterpretado al des-\r
+      serializarlo.\r
+      El orden del resto de los atributos deben ser respetados también.\r
+      Aunque es bastante probable que fucione si están en otro órden,\r
+      no está 100% asegurado y si se hace en otro orden los resultados\r
+      pueden ser inesperados o pueden surgir errores.\r
+    <PRE></dd>\r
+<dt><li><A HREF=ObjetoVolador.html>ObjetoVolador</A></dt>\r
+<dd>Clase abstracta, implementa todas las funcionalidades básicas de los objetos voladores.\r
+    De esta van a derivar la mayor parte del resto de las clases.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    05/10/00: Se agregaron los métodos mGetDistancia y mColisiono. De esta manera se deja\r
+              a los objetos voladores manejar las colisiones mas intuitivamente.\r
+    30/10/00: Se agregó un atributo <b>aCoordenadas</b> para que se pueda orientar al objeto volador.\r
+    02/11/00: Se agregaron métodos para cambiar solamente el modulo de la velocidad, para cambiar solo\r
+              la direccion de la velocidad y para extraer directamente copias de los versores i, j, k y\r
+              para rotar el objeto volador en todas direcciones.\r
+              Los nuevos métodos son: mSetVelModulo, mSetVelDir, mGetVelModulo,\r
+                                      mGetI, mGetJ, mGetK, mRotarEnI,\r
+                                      mRotarEnJ, mRotarEnK\r
+    07/11/00: Se agrega un nuevo método (mSetPosicion) y se hace a público otro (mSetVelocidad) para\r
+              que se pueda cambiar la configuración (es temporal, se planea cambiar el sistema de\r
+              configuración del juego para que esto no sea necesario)\r
+    29/11/00: Se arregla un BUG en mSetVelModulo que no modificaba el modulo si la velocidad pasada\r
+              como argumento era menor que cero. En este caso el modulo de la velocidad se setea en 0.\r
+    02/12/00: Se cambio el dato que devuelve el método mDibujar. Ahora devuelve un tipo de dato enumerado\r
+              tObjetosVoladores. Todas sus subclases fueron actualizadas también.\r
+    08/12/00: Se agregan menúes para manejar la nueva vistas con varias camaras. Se agrega la opcion de\r
+              alta calidad en el menú vista. Se carga un escenario por defecto (si existe) al iniciar el\r
+              juego, el nombre de dicho escenario debe ser 'comun.eaw'.\r
+              Se agrega una nueva tecla para cambiar de cámara ('C'), además de las que se provee con las\r
+              teclas de atajo.\r
+    </PRE></dd>\r
+<dt><li><A HREF=RegExpr.html>RegExpr</A></dt>\r
+<dd>Implementación de expresiones regulares para Delphi</dd>\r
+<dt><li><A HREF=SerializacionUtils.html>SerializacionUtils</A></dt>\r
+<dd>Funciones útiles para complementar la utilización de la serialización en\r
+    este modelo en particular</dd>\r
+<dt><li><A HREF=Tipos.html>Tipos</A></dt>\r
+<dd>En esta unidad se definen todos los tipos que usaremos en el proyecto\r
+    Decidimos mantener los tipos por separado por el caso de que sea\r
+    necesario un cambio de implementacion.</dd>\r
+<dt><li><A HREF=Vectores.html>Vectores</A></dt>\r
+<dd>Es la implementación de un vector físico. Esta clase es el esqueleto de\r
+    la aplicación ya que todas las velocidades y posiciones son del tipo cVector.\r
+    Todos los calculos de movimientos, distancias, etc. se manejan con los metodos de esta clase<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    05/10/00: Se corrigió el método mAddModulo para que al verificar el signo del modulo resultante,\r
+              si es negativo, setee el modulo a cero.\r
+    28/10/00: Se cambiaron todos los metodos en los que se realizan operaciones con el vector para\r
+              que devulvan un puntero a si mismo (para poder hacer asignaciones luego de la operacion).\r
+              Ahora todos los métodos son funciones\r
+    </PRE></dd>\r
+<dt><li><A HREF=Vista.html>Vista</A></dt>\r
+<dd>Interpreta y dibuja los datos del modelo en un formulario<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    10/11/00: Se maneja la excepción para evitar usar la camara cuando el cameraman fue destruido (ECameramanDestruido).\r
+              Esta es propagada (por ahora) para que el controlador (formulario) frene el timer\r
+    02/12/00: Se mejoran los graficos usando transparencias en los bitmaps y se da la opcion de presentar\r
+              los graficos con transparencias (alta calidad) o no (a través del atributo aAltaCalidad y\r
+              los métodos mSetAltaCalidad, mSetBajaCalidad y mCambiarCalidad).\r
+              Se mejora la performance gracias a la nueva implementación de mDibujar, ya que los\r
+              bitmas se cargan una sola vez en memoria (en un array aBitmaps) en vez de cargarse\r
+              y liberarse cada vez que se actualiza la pantalla como sucedía anteriormente.\r
+              Se implementa el soporte de visualización de un objeto volador lockeado (utilizando\r
+              otra lista de bitmaps con los gráficos de los objetos lockeados, aBitmapsLockeados).\r
+    08/12/00: Se agregan múltiples cámaras: Derecha, Izquierda, Arriba, Abajo, Atrás, Del Misil. Para hacerlo\r
+              se agragega un array de camaras y un atributo que indica la camara actual. Tambien se agregan\r
+              métodos para cambiar la cámara actual, etc.\r
+              Se arregla el destructor que no liberaba todos los objetos.\r
+    09/12/00: Se reemplaza la vista del misil por una mas general (vista del arma) que permite ver a traves de\r
+              cualquier arma disparada. Se implementa correctamente esta vista.\r
+              Se agrega una vista tipo mapa. \r
+    </PRE></dd>\r
+</dl></HTML>\r
diff --git a/doc/ref/index.html b/doc/ref/index.html
new file mode 100644 (file)
index 0000000..aca8d22
--- /dev/null
@@ -0,0 +1,13 @@
+<html>\r
+<head>\r
+<title>AlgoWars</title>\r
+</head>\r
+<frameset rows = 35,100% frameborder=1>\r
+<frame src=menue.html scrolling=NO name=menue marginwidth=5 marginheight=6 NORESIZE>\r
+<frame src=Descripcion.html name=main>\r
+</frameset>\r
+<noframes>\r
+<p>Your browser does not seems to support frames. Please upgrade it.\r
+</body>\r
+</noframes>\r
+</html>\r
diff --git a/doc/ref/legend.html b/doc/ref/legend.html
new file mode 100644 (file)
index 0000000..0b1f3cc
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>\r
+<TABLE><TR>\r
+<TD VALIGN=CENTER><IMG SRC=functions.gif></TD>\r
+<TD><FONT FACE="Tahoma,Arial,Helvetica" SIZE="1">Functions</TD><TR>\r
+<TD VALIGN=CENTER><IMG SRC=protected.gif></TD>\r
+<TD><FONT FACE="Tahoma,Arial,Helvetica" SIZE="1">Protected</TD><TR>\r
+<TD VALIGN=CENTER><IMG SRC=public.gif></TD>\r
+<TD><FONT FACE="Tahoma,Arial,Helvetica" SIZE="1">Public</TD><TR>\r
+</TABLE>\r
+</HTML>\r
diff --git a/doc/ref/menue.html b/doc/ref/menue.html
new file mode 100644 (file)
index 0000000..c93e3d9
--- /dev/null
@@ -0,0 +1,28 @@
+<HTML>\r
+<script JavaScript>\r
+function openLegend() {\r
+  Window2=window.open("legend.html","legendWindow","toolbar=no,scrollbars=no,width=100,height=100,resizable=no")\r
+  return;\r
+}\r
+</script>\r
+<BODY BGCOLOR=EFDACC>\r
+<TABLE width=100%>\r
+<tr>\r
+<td align=center colspan=5><font face="Arial" size=2>\r
+<A HREF=index-unit.html TARGET=main>Unit-Index</A>\r
+</td>\r
+<td align=center colspan=5><font face="Arial" size=2>\r
+<A HREF=index-class.html TARGET=main>Class-Index</A>\r
+</td>\r
+<td align=center colspan=5><font face="Arial" size=2>\r
+<A HREF=index-function.html TARGET=main>Function-Index</A>\r
+</td>\r
+<td align=center colspan=5><font face="Arial" size=2>\r
+<A HREF=index.html TARGET=_top>Description</A>\r
+</td>\r
+<td align=center colspan=5><font face="Arial" size=2>\r
+<A HREF="javascript:openLegend()">Legend</A>\r
+</td>\r
+</table>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/ref/methods.gif b/doc/ref/methods.gif
new file mode 100644 (file)
index 0000000..18ad57b
Binary files /dev/null and b/doc/ref/methods.gif differ
diff --git a/doc/ref/private.gif b/doc/ref/private.gif
new file mode 100644 (file)
index 0000000..02a7907
Binary files /dev/null and b/doc/ref/private.gif differ
diff --git a/doc/ref/private_big.gif b/doc/ref/private_big.gif
new file mode 100644 (file)
index 0000000..fa29d8b
Binary files /dev/null and b/doc/ref/private_big.gif differ
diff --git a/doc/ref/property.gif b/doc/ref/property.gif
new file mode 100644 (file)
index 0000000..cc1f0bb
Binary files /dev/null and b/doc/ref/property.gif differ
diff --git a/doc/ref/protected.gif b/doc/ref/protected.gif
new file mode 100644 (file)
index 0000000..4fab629
Binary files /dev/null and b/doc/ref/protected.gif differ
diff --git a/doc/ref/protected_big.gif b/doc/ref/protected_big.gif
new file mode 100644 (file)
index 0000000..2b8c0bb
Binary files /dev/null and b/doc/ref/protected_big.gif differ
diff --git a/doc/ref/public.gif b/doc/ref/public.gif
new file mode 100644 (file)
index 0000000..a1fdf1e
Binary files /dev/null and b/doc/ref/public.gif differ
diff --git a/doc/ref/public_big.gif b/doc/ref/public_big.gif
new file mode 100644 (file)
index 0000000..71e1b2e
Binary files /dev/null and b/doc/ref/public_big.gif differ
diff --git a/doc/src-html/.htaccess b/doc/src-html/.htaccess
new file mode 100644 (file)
index 0000000..0d7a28c
--- /dev/null
@@ -0,0 +1,11 @@
+AddType application/x-httpd-php .pas
+#DirectoryIndex secciones.php
+
+#php directives
+#php_value auto_prepend_file "/www/docs/lucarella.com.ar/phplib/prepend.luca_fotos.php"
+#php_value include_path ".:/www/docs/lucarella.com.ar/phplib:/www/docs/lucarella.com.ar/public_html/leandro/fotos"
+#php_flag register_globals on
+#php_flag magic_quotes_gpc off
+#php_flag magic_quotes_runtime off
+#php_flag magic_quotes_sybase off
+
diff --git a/doc/src-html/AlgoWars.html b/doc/src-html/AlgoWars.html
new file mode 100644 (file)
index 0000000..71180d0
--- /dev/null
@@ -0,0 +1,48 @@
+<HTML><HEAD>\r
+<TITLE>File: AlgoWars.dpr </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=AlgoWars.dpr><CENTER><H3>AlgoWars.dpr</H3></CENTER></A>\r
+<HR>\r
+<PRE>\r
+<B>program</B> AlgoWars; \r
\r
+<B>uses</B> \r
+  Vectores <B>in</B> <A HREF="modelo/Vectores.pas">'modelo/vectores.pas'</A>, \r
+  Coordenadas <B>in</B> <A HREF="modelo/Coordenadas.pas">'modelo/coordenadas.pas'</A>, \r
+  Espacio <B>in</B> <A HREF="modelo/Espacio.pas">'modelo/espacio.pas'</A>, \r
+  ObjetoVolador <B>in</B> <A HREF="modelo/ov/ObjetoVolador.pas">'modelo/ov/objetovolador.pas'</A>, \r
+  Meteorito <B>in</B> <A HREF="modelo/ov/Meteorito.pas">'modelo/ov/meteorito.pas'</A>, \r
+  Armas <B>in</B> <A HREF="modelo/ov/Armas.pas">'modelo/ov/armas.pas'</A>, \r
+  Nave <B>in</B> <A HREF="modelo/ov/naves/Nave.pas">'modelo/ov/naves/nave.pas'</A>, \r
+  NaveEnemiga <B>in</B> <A HREF="modelo/ov/naves/NaveEnemiga.pas">'modelo/ov/naves/naveenemiga.pas'</A>, \r
+  NavePropia <B>in</B> <A HREF="modelo/ov/naves/NavePropia.pas">'modelo/ov/naves/navepropia.pas'</A>, \r
+  NavesEnemigas <B>in</B> <A HREF="modelo/ov/naves/NavesEnemigas.pas">'modelo/ov/naves/navesenemigas.pas'</A>, \r
+  Filtro <B>in</B> <A HREF="vista/Filtro.pas">'vista/filtro.pas'</A>, \r
+  Filtros <B>in</B> <A HREF="vista/Filtros.pas">'vista/filtros.pas'</A>, \r
+  Camara <B>in</B> <A HREF="vista/Camara.pas">'vista/camara.pas'</A>, \r
+  Camaras <B>in</B> <A HREF="vista/Camaras.pas">'vista/camaras.pas'</A>, \r
+  Vista <B>in</B> <A HREF="vista/Vista.pas">'vista/vista.pas'</A>, \r
+  Lista <B>in</B> <A HREF="auxiliares/Lista.pas">'auxiliares/lista.pas'</A>, \r
+  ObjetoPersistente <B>in</B> <A HREF="auxiliares/ObjetoPersistente.pas">'auxiliares/objetopersistente.pas'</A>, \r
+  SerializacionUtils <B>in</B> <A HREF="auxiliares/SerializacionUtils.pas">'auxiliares/serializacionutils.pas'</A>, \r
+  Objeto <B>in</B> <A HREF="auxiliares/Objeto.pas">'auxiliares/objeto.pas'</A>, \r
+  Tipos <B>in</B> <A HREF="auxiliares/Tipos.pas">'auxiliares/tipos.pas'</A>, \r
+  RegExpr <B>in</B> <A HREF="auxiliares/RegExpr.pas">'auxiliares/regexpr.pas'</A>, \r
+  Forms, \r
+  FormMain <B>in</B> <A HREF="forms/FormMain.pas">'forms/formmain.pas'</A> <I><FONT COLOR="Navy">{MainForm}</FONT></I>, \r
+  FormConfig <B>in</B> <A HREF="forms/FormConfig.pas">'forms/formconfig.pas'</A> <I><FONT COLOR="Navy">{ConfigForm}</FONT></I>; \r
\r
+<I><FONT COLOR="Navy">{$R *.RES}</FONT></I> \r
\r
+<B>begin</B> \r
+  Application.Initialize; \r
+  Application.Title := 'AlgoWars - Episodio IV'; \r
+  Application.CreateForm(TMainForm, MainForm); \r
+  Application.CreateForm(TConfigForm, ConfigForm); \r
+  Application.Run; \r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/auxiliares/Lista.pas b/doc/src-html/auxiliares/Lista.pas
new file mode 100644 (file)
index 0000000..f18873f
--- /dev/null
@@ -0,0 +1,49 @@
+<HTML><HEAD>\r
+<TITLE>File: lista.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=lista.pas><CENTER><H3>lista.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Lista exactamente igual a TList, solo que el destructor tambien destruye \r
+    todos los objetos que contiene}</FONT></I> \r
+<B>unit</B> Lista; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  Tipos, \r
+  Classes; \r
\r
+<B>type</B> \r
+  <I><FONT COLOR="Navy">{** Lista exactamente igual a TList, solo que el destructor tambien destruye todos \r
+      los objetos que contiene}</FONT></I> \r
+  cLista = <B>class</B>( TList ) \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Destructor. Destruye la lista y TODOS los objetos que ella contiene}</FONT></I> \r
+      <B>destructor</B> destroy; <B>override</B>; \r
+  <B>end</B>; \r
\r
+<B>implementation</B> \r
\r
+<I><FONT COLOR="Navy">{ cLista }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Destructor. Destruye la lista y TODOS los objetos que ella contiene}</FONT></I> \r
+<B>destructor</B> cLista.destroy; \r
+<B>var</B> \r
+  p: pointer; \r
+<B>begin</B> \r
+  <B>while</B> Count > 0 <B>do</B> <B>begin</B> \r
+    p := First; \r
+    Remove( p ); \r
+    <B>if</B> p <> <B>nil</B> <B>then</B> \r
+        dispose( p ); \r
+  <B>end</B>; \r
+  <B>inherited</B>; \r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/auxiliares/Objeto.pas b/doc/src-html/auxiliares/Objeto.pas
new file mode 100644 (file)
index 0000000..a390d92
--- /dev/null
@@ -0,0 +1,36 @@
+<HTML><HEAD>\r
+<TITLE>File: objeto.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=objeto.pas><CENTER><H3>objeto.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Es una clase abstracta para agregar algunos métodos generales útiles \r
+    para el resto de las clases que implementemos. Podría considerarse una \r
+    extensión a la funcionalidad básica dada por TObject.}</FONT></I> \r
+<B>unit</B> Objeto; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  Tipos; \r
+<I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+<B>type</B> \r
+  <I><FONT COLOR="Navy">{** Es una clase abstracta para agregar algunos métodos generales útiles \r
+      para el resto de las clases que implementemos. Podría considerarse una \r
+      extensión a la funcionalidad básica dada por TObject.}</FONT></I> \r
+  cObjeto = <B>class</B> \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el estado actual del objeto. \r
+          La cantidad de información devuelta depende del parametro debugLevel}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjeto.mGetDebugInfo">mGetDebugInfo</A>( debugLevel: tDebugInfo = DI_MINI ): <B>string</B>; <B>virtual</B>; <B>abstract</B>; \r
+  <B>end</B>; \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<B>implementation</B> \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/auxiliares/ObjetoPersistente.pas b/doc/src-html/auxiliares/ObjetoPersistente.pas
new file mode 100644 (file)
index 0000000..59c0f8b
--- /dev/null
@@ -0,0 +1,132 @@
+<HTML><HEAD>\r
+<TITLE>File: objetopersistente.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=objetopersistente.pas><CENTER><H3>objetopersistente.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Es una clase abstracta para hacer persistente un objeto. \r
+    Básicamente provee métodos para serialización.<br> \r
+    <U>NOTA:</U> \r
+    <PRE> \r
+      Es importante que el ID del objeto sea el primer atributo en la \r
+      serialización, de otra manera puede ser malinterpretado al des- \r
+      serializarlo. \r
+      El orden del resto de los atributos deben ser respetados también. \r
+      Aunque es bastante probable que fucione si están en otro órden, \r
+      no está 100% asegurado y si se hace en otro orden los resultados \r
+      pueden ser inesperados o pueden surgir errores. \r
+    <PRE>}</FONT></I> \r
+<B>unit</B> ObjetoPersistente; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+  Objeto, \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+  Sysutils; \r
\r
+<B>type</B> \r
+  <I><FONT COLOR="Navy">{** Excepcion producida si hay un error al serializar.}</FONT></I> \r
+  ESerializacion = <B>class</B>( Exception ) \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Es una clase abstracta para hacer persistente un objeto. \r
+      Básicamente provee métodos para serialización. \r
+      NOTA: Es importante que el ID del objeto sea el primer atributo en la \r
+            serialización, de otra manera puede ser malinterpretado al des- \r
+            serializarlo.}</FONT></I> \r
+  cObjetoPersistente = <B>class</B><I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I>( cObjeto )<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+    <B>private</B> \r
+      aID: <B>string</B>; <I><FONT COLOR="Navy">// Identificación UNICA de la instancia </FONT></I>\r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Setea la identificacion del objeto}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cObjetoPersistente.mSetID">mSetID</A>( id: <B>string</B> ); \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor. Setea el ID.}</FONT></I> \r
+      <B>constructor</B> create; \r
+      <I><FONT COLOR="Navy">{** Constructor que crea el objeto a partir de una cadena de texto con \r
+          el objeto serializado.}</FONT></I> \r
+      <B>constructor</B> crearDeSerializado( str: <B>string</B> ); \r
+      <I><FONT COLOR="Navy">{** Obtiene la identificacion del objeto}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoPersistente.mGetID">mGetID</A>: <B>string</B>; \r
+      <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoPersistente.mSerializar">mSerializar</A>: <B>string</B>; <B>virtual</B>; \r
+      <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+          serializado.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cObjetoPersistente.mDesSerializar">mDesSerializar</A>( str: <B>string</B> ); <B>virtual</B>; \r
+  <B>end</B>; \r
\r
+<B>implementation</B> \r
\r
+<B>uses</B> \r
+  RegExpr; \r
\r
+<I><FONT COLOR="Navy">{ cObjetoPersistente }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Constructor que crea el objeto a partir de una cadena de texto con \r
+    el objeto serializado. \r
+    @param str cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>constructor</B> cObjetoPersistente.crearDeSerializado(str: <B>string</B>); \r
+<B>begin</B> \r
+  <B>inherited</B> create;      <I><FONT COLOR="Navy">// Llama al create padre </FONT></I>\r
+  mDesSerializar( str ); <I><FONT COLOR="Navy">// Deserializa los datos </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Constructor. Setea el ID.}</FONT></I> \r
+<B>constructor</B> cObjetoPersistente.create; \r
+<B>begin</B> \r
+  <B>inherited</B>; \r
+  aID := IntToHex( integer( self ), 6 ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la identificacion del objeto \r
+    @return ID del objeto.}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoPersistente.mGetID>cObjetoPersistente.mGetID</A>: <B>string</B>; \r
+<B>begin</B> \r
+  result := aID; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Setea la identificacion del objeto \r
+    @param id nuevo ID.}</FONT></I> \r
+<B>procedure</B> <A NAME=cObjetoPersistente.mSetID>cObjetoPersistente.mSetID</A>(id: <B>string</B>); \r
+<B>begin</B> \r
+  aID := id; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado. \r
+    @return Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoPersistente.mSerializar>cObjetoPersistente.mSerializar</A>: <B>string</B>; \r
+<B>begin</B> \r
+  result := '<id>' + aID + '</id>'; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+    serializado. \r
+    @param str Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>procedure</B> <A NAME=cObjetoPersistente.mDesSerializar>cObjetoPersistente.mDesSerializar</A>(str: <B>string</B>); \r
+<B>var</B> \r
+  r: TRegExpr; \r
+<B>begin</B> \r
+  r := TRegExpr.create; \r
+  <B>try</B> <I><FONT COLOR="Navy">// prueba que no haya errores con las expresiones regulares </FONT></I>\r
+    r.Expression := '<id>/s*([ABCDEFabcdef0-9]{6})/s*</id>'; \r
+    <B>if</B> r.Exec ( str ) <B>then</B> \r
+      aID := r.Match[1] \r
+    <B>else</B> \r
+      <B>raise</B> ESerializacion.create( 'No se encontro el ID del Objeto' ); \r
+  <B>except</B> \r
+    on e: ERegExpr <B>do</B> <B>begin</B> \r
+      r.Free; \r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el ID utilizando expresiones regulares: ' + e.<B>Message</B> ); \r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  r.free; \r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/auxiliares/RegExpr.pas b/doc/src-html/auxiliares/RegExpr.pas
new file mode 100644 (file)
index 0000000..e992c02
--- /dev/null
@@ -0,0 +1,3633 @@
+<HTML><HEAD>\r
+<TITLE>File: regexpr.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=regexpr.pas><CENTER><H3>regexpr.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Implementación de expresiones regulares para Delphi}</FONT></I> \r
+<I><FONT COLOR="Navy">{$B-}</FONT></I> \r
+<B>unit</B> RegExpr; \r
\r
+<I><FONT COLOR="Navy">(* \r
\r
+     TRegExpr library \r
+     Regular Expressions for Delphi \r
+     v. 0.938 \r
\r
+Author: \r
+     Andrey V. Sorokin \r
+     St-Petersburg \r
+     Russia \r
+     anso@mail.ru, anso@usa.net \r
+     http://anso.da.ru \r
+     http://anso.virtualave.net \r
\r
+This library is derived from Henry Spencer sources. \r
+I translated the C sources into Object Pascal, \r
+implemented object wrapper and some new features. \r
+Many features suggested or partially implemented \r
+by TRegExpr's users (see Gratitude below). \r
\r
\r
+--------------------------------------------------------------- \r
+     Legal issues \r
+--------------------------------------------------------------- \r
+ Copyright (c) 1999-00 by Andrey V. Sorokin <anso@mail.ru> \r
\r
+ This software is provided as it is, without any kind of warranty \r
+ given. Use it at your own risk. \r
\r
+ You may use this software in any kind of development, including \r
+ comercial, redistribute, and modify it freely, under the \r
+ following restrictions : \r
+ 1. The origin of this software may not be mispresented, you must \r
+    not claim that you wrote the original software. If you use \r
+    this software in any kind of product, it would be appreciated \r
+    that there in a information box, or in the documentation would \r
+    be an acknowledgmnent like this \r
+           Partial Copyright (c) 2000 by Andrey V. Sorokin \r
+ 2. You may not have any income from distributing this source \r
+    to other developers. When you use this product in a comercial \r
+    package, the source may not be charged seperatly. \r
\r
\r
+--------------------------------------------------------------- \r
+     Legal issues for the original C sources: \r
+--------------------------------------------------------------- \r
+ *  Copyright (c) 1986 by University of Toronto. \r
+ *  Written by Henry Spencer.  Not derived from licensed software. \r
+ * \r
+ *  Permission is granted to anyone to use this software for any \r
+ *  purpose on any computer system, and to redistribute it freely, \r
+ *  subject to the following restrictions: \r
+ *  1. The author is not responsible for the consequences of use of \r
+ *      this software, no matter how awful, even if they arise \r
+ *      from defects in it. \r
+ *  2. The origin of this software must not be misrepresented, either \r
+ *      by explicit claim or by omission. \r
+ *  3. Altered versions must be plainly marked as such, and must not \r
+ *      be misrepresented as being the original software. \r
\r
\r
+--------------------------------------------------------------- \r
+     Gratitudes \r
+--------------------------------------------------------------- \r
+  Guido Muehlwitz \r
+    found and fixed ugly bug in big string processing \r
+  Stephan Klimek \r
+    testing in CPPB and suggesting/implementing many features \r
+  Steve Mudford \r
+    implemented Offset parameter \r
+  Martin Baur \r
+    usefull suggetions \r
+  Yury Finkel \r
+    Implemented UniCode support, found and fixed some bugs \r
+  Ralf Junker \r
+    Implemented some features, many optimization suggestions \r
\r
+  And many others - for big work of bug hunting ! \r
\r
+I am still looking for person who can help me to translate \r
+this documentation into other languages (especially German) \r
\r
\r
+--------------------------------------------------------------- \r
+     To do \r
+--------------------------------------------------------------- \r
\r
+-=- VCL-version of TRegExpr - for dummies ;) and TRegExprEdit \r
+(replacement for TMaskEdit). \r
+Actually, I am writing non-VCL aplications (with web-based \r
+interfaces), so I don't need VCL's TRegExpr for myself. \r
+Will it be really usefull ? \r
\r
+-=- full functiona<A HREF="#llity">llity</A> of braces {} \r
\r
+-=- working with pascal-style string. \r
+Now pascal-strings converted into PChar, so \r
+you can't find r.e. in strings with #0 -chars. \r
+(suggested by Pavel O). \r
\r
+-=- non-greedy style (suggested by Martin Baur) \r
\r
+-=- put precalculated lengths into EXACTLY[CI] ! \r
\r
+-=- fInputString as string (suggested by Ralf Junker) \r
\r
+-=- Add regstart optimization for case-insensitive mode ? \r
+ Or complitely remove because FirstCharSet is faster ? \r
\r
+-=- "Russian Ranges" --> National ranges (use property WordChars ? \r
+for ordering letters in ranges by its order in WirdsChars if modifier /r is On) \r
\r
+-=- FirstCharSet as array [#0 .. #255] of REChar ? \r
+(2x faster then set of REChar) \r
\r
+-=- p-code optimization (remove BRANCH-to-EEND, COMMENT, BACK(?) \r
+    merge EXACTLY etc). \r
\r
+I need your suggestions ! \r
+What are more importent in this list ? \r
+Did I forget anything ? \r
\r
\r
+--------------------------------------------------------------- \r
+     History \r
+--------------------------------------------------------------- \r
+Legend: \r
+ (+) added feature \r
+ (-) fixed bug \r
+ (^) upgraded implementation \r
\r
+ v. 0.938 2000.07.23 \r
+ -=- (^) Exeptions now jump to appropriate source line, not \r
+     to Error procedure (I am not quite sure this is safe for \r
+     all compiler versions. You can turn it off - remove \r
+     reRealExceptionAddr definition below). \r
+ -=- (^) Forgotten BSUBEXP[CI] in FillFirstCharSet caused \r
+     exeption 'memory corruption' in case if back reference can \r
+     be first op, like this: (a)*/1 (first subexpression can be \r
+     skipped and we'll start matching with back reference..). \r
\r
+ v. 0.937 2000.06.12 \r
+ -=- (-) Bug in optimization engine (since v.0.934). In some cases \r
+     TRegExpr didn't catch right strings. \r
+     Thanks to Matthias Fichtner \r
\r
+ v. 0.936 2000.04.22 \r
+ -=- (+) Back references, like <font size=(['"]?)(/d+)/1>, see \r
+     manual for details \r
+ -=- (+) Wide hex char support, like '/x{263a}' \r
\r
+ v. 0.935 2000.04.19 (by Yury Finkel) \r
+ -=- (-) fInvertCase now isn't readonly ;) \r
+ -=- (-) UniCode mode compiling errors \r
\r
+ v. 0.934 2000.04.17 \r
+ -=- (^) New ranges implementation (range matching now is very fast \r
+      - uses one(!) CPU instruction) \r
+ -=- (^) Internal p-code structure converted into 32-bits - works \r
+      faster and now there is no 64K limit for compiled r.e. \r
+ -=- (^) '{m,n}' now use 32-bits arguments (up to 2147483646) - specially \r
+      for Dmitry Veprintsev ;) \r
+ -=- (^) Ranges now support metachars: [/n-/x0D] -> #10,#11,#12,#13; \r
+     Changed '-' processing, now it's like in Perl: \r
+     [/d-t] -> '0'..'9','-','t'; []-a] -> ']'..'a' \r
+ -=- (-) Bug with /t and etc macro (they worked only in ranges) \r
+     Thanks to Yury Finkel \r
+ -=- (^) Added new preprocessing optimization (see FirstCharSet). \r
+      Incredible fast (!). But be carefull it isn's properly tested. \r
+      You can switch it Off - remove UseFirstCharSet definition. \r
+ -=- (^) Many other speed optimizations \r
+ -=- (-) Case-insensitive mode now support system-defined national \r
+      charset (due to bug in v.0.90 .. 0.926 supported only english one) \r
+ -=- (^) Case-insensitive mode implemented with InvertCase (param & \r
+      result of REChar type) - works 10 .. 100 times faster. \r
+ -=- (^) Match and ExecNext interfaces optimized, added IsProgrammOk \r
+      by Ralf Junker \r
+ -=- (^) Increased NSUBEXP (now 15) and fixed code for this, now you \r
+      can simply increase NSUBEXP constant by yourself. \r
+      Suggested by Alexander V. Akimov. \r
+ -=- (^+) Substitute adapted for NSUBEXP > 10 and significant (!) \r
+      optimized, improved error checking. \r
+      ATTENTION! Read new Substitute description - syntax was changed ! \r
+ -=- (+) SpaceChars & WordChars property - now you may change chars \r
+      treated as /s & /w. By defauled assigned RegExprSpaceChars/WordChars \r
+ -=- (+) Now /s and /w supported in ranges \r
+ -=- (-) Infinite loop if end of range=#$FF \r
+      Thanks to Andrey Kolegov \r
+ -=- (+) Function QuoteRegExprMetaChars (see description) \r
+ -=- (+) UniCode support - sorry, works VERY slow (remove '.' from \r
+     {.$DEFINE UniCode} after this comment for unicode version). \r
+     Implemented by Yury Finkel \r
\r
+ v. 0.926 2000.02.26 \r
+ -=- (-) Old bug derived from H.Spencer sources - SPSTART was \r
+     set for '?' and '*' instead of '*', '{m,n}' and '+'. \r
+ -=- (-^) Now {m,n} works like Perl's one - error occures only \r
+     if m > n or n > BracesMax (BracesMax = 255 in this version). \r
+     In other cases (no m or nondigit symbols in m or n values, \r
+     or no '}') symbol '{' will be compiled as literal. \r
+     Note: so, you must include m value (use {0,n} instead of {,n}). \r
+     Note: {m,} will be compiled as {m,BracesMax}. \r
+ -=- (-^) CaseInsensitive mode now support ranges \r
+     '(?i)[a]' == '[aA]' \r
+ -=- (^) Roman-number template in TestRExp ;) \r
+ -=- (+^) Beta version of complex-braces - like ((abc){1,2}|d){3} \r
+     By default its turned off. If you want take part in beta-testing, \r
+     please, remove '.' from {.$DEFINE ComplexBraces} below this comments. \r
+ -=- (-^) Removed /b metachar (in Perl it isn't BS as in my implementation, \r
+     but word bound) \r
+ -=- (+) Add /s modifier. Bu I am not sure that it's ok for Windows. \r
+     I implemented it as [^/n] for '.' metachar in non-/s mode. \r
+     But lines separated by /n/r in windows. I need you suggestions ! \r
+ -=- (^) Sorry, but I had to rename Modifiers to ModifierStr \r
+     (ModifierS uses for /s now) \r
\r
+ v. 0.91 2000.02.02 \r
+ -=- (^) some changes in documentation and demo-project. \r
\r
+ v. 0.90 2000.01.31 \r
+ -=- (+) implemented braces repetitions {min,max}. \r
+     Sorry - only simple cases now - like '/d{2,3}' \r
+     or '[a-z1-9]{,7}', but not (abc){2,3} .. \r
+     I still too short in time. \r
+     Wait for future versions of TRegExpr or \r
+     implement it by youself and share with me ;) \r
+ -=- (+) implemented case-insensitive modifier and way \r
+     to work with other modifiers - see properties \r
+     Modifiers, Modifier, ModifierI \r
+     and (?ismx-ismx) Perl extension. \r
+     You may use global variables RegExpr* for assigning \r
+     default modifier values. \r
+ -=- (+) property ExtSyntaxEnabled changed to 'r'-modifier \r
+     (russian extensions - see documentation) \r
+ -=- (+) implemented (?#comment) Perl extension - very hard \r
+     and usefull work ;) \r
+ -=- (^) property MatchCount renamed to SubExprMatchCount. \r
+     Sorry for any inconvenients, but it's because new \r
+     version works slightly different and if you used \r
+     MatchCount in your programms you have to rethink \r
+     it ! (see comments to this property) \r
+ -=- (+) add InputString property - stores input string \r
+     from last Exec call. You may directly assign values \r
+     to this property for using in ExecPos method. \r
+ -=- (+) add ExecPos method - for working with assigned \r
+     to InputString property. You may use it like this \r
+        InputString := AString; \r
+        ExecPos; \r
+     or this \r
+        InputString := AString; \r
+        ExecPos (AOffset); \r
+     Note: ExecPos without parameter works only in \r
+     Delphi 4 or higher. \r
+ -=- (+) add ExecNext method - simple and fast (!) way to finding \r
+     multiple occurences of r.e. in big input string. \r
+ -=- (^) Offset parameter removed from Exec method, if you \r
+     used it in your programs, please replace all \r
+        Exec (AString, AOffset) \r
+     with combination \r
+        InputString := AString; ExecPos (AOffset) \r
+     Sorry for any inconvenients, but old design \r
+     (see v.0.81) was too ugly :( \r
+     In addition, multiple Exec calls with same input \r
+     string produce fool overhead because each Exec \r
+     reallocate input string buffer. \r
+ -=- (^) optimized implementation of Substitution, \r
+     Replace and Split methods \r
+ -=- (-) fixed minor bug - if r.e. compilation raise error \r
+     during second pass (!!! I think it's impossible \r
+     in really practice), TRegExpr stayed in 'compiled' \r
+     state. \r
+ -=- (-) fixed bug - Dump method didn't check program existance \r
+     and raised 'access violation' if previouse Exec \r
+     was finished with error. \r
+ -=- (+) changed error handling (see functions Error, ErrorMsg, \r
+     LastError, property CompilerErrorPos, type ERegExpr). \r
+ -=- (-^) TRegExpr.Replace, Split and ExecNext made a infinite \r
+     loop in case of r.e. match empty-string. \r
+     Now ExecNext moves by MatchLen if MatchLen <> 0 \r
+     and by +1 if MatchLen = 0 \r
+     Thanks to Jon Smith and George Tasker for bugreports. \r
+ -=- (-) While playing with null-matchs I discovered, that \r
+     null-match at tail of input string is never found. \r
+     Well, I fixed this, but I am not sure this is safe \r
+     (MatchPos[0]=length(AInputString)+1, MatchLen = 0). \r
+     Any suggetions are very appreciated. \r
+ -=- (^) Demo project and documentation was upgraded \r
+ -=- (^) Documentation and this version was published on my home page \r
+     http://anso.da.ru \r
\r
\r
+ v. 0.81 1999.12.25 // Merry Christmas ! :) \r
+ -=- added /s (AnySpace) and /S (NotSpace) meta-symbols \r
+     - implemented by Stephan Klimek with minor fixes by AVS \r
+ -=- added /f, /a and /b chars (translates into FF, BEL, BS) \r
+ -=- removed meta-symbols 'ö' & 'Ö' - sorry for any inconvenients \r
+ -=- added Match property (== copy (InputStr, MatchPos [Idx], MatchLen [Idx])) \r
+ -=- added extra parameter Offset to Exec method \r
+     (thanks to Steve Mudford) \r
\r
+ v. 0.7 1999.08.22 \r
+ -=- fixed bug - in some cases the r.e. [^...] \r
+     incorrectly processed (as any symbol) \r
+     (thanks to Jan Korycan) \r
+ -=- Some changes and improvements in TestRExp.dpr \r
\r
+ v. 0.6 1999.08.13 (Friday 13 !) \r
+ -=- changed header of TRegExpr.Substitute \r
+ -=- added Split, Replace & appropriate \r
+     global wrappers (thanks to Stephan Klimek for suggetions) \r
\r
+ v. 0.5 1999.08.12 \r
+ -=- TRegExpr.Substitute routine added \r
+ -=- Some changes and improvements in TestRExp.dpr \r
+ -=- Fixed bug in english version of documentation \r
+     (Thanks to Jon Buckheit) \r
\r
+ v. 0.4 1999.07.20 \r
+ -=- Fixed bug with parsing of strings longer then 255 bytes \r
+     (thanks to Guido Muehlwitz) \r
+ -=- Fixed bug in RegMatch - mathes only first occurence of r.e. \r
+     (thanks to Stephan Klimek) \r
\r
+ v. 0.3 1999.06.13 \r
+ -=- ExecRegExpr function \r
\r
+ v. 0.2 1999.06.10 \r
+ -=- packed into object-pascal class \r
+ -=- code slightly rewriten for pascal \r
+ -=- now macro correct proceeded in ranges \r
+ -=- r.e.ranges syntax extended for russian letters ranges: \r
+     à-ÿ - replaced with all small russian letters (Win1251) \r
+     À-ß - replaced with all capital russian letters (Win1251) \r
+     à-ß - replaced with all russian letters (Win1251) \r
+ -=- added macro '/d' (opcode ANYDIGIT) - match any digit \r
+ -=- added macro '/D' (opcode NOTDIGIT) - match not digit \r
+ -=- added macro '/w' (opcode ANYLETTER) - match any english letter or '_' \r
+ -=- added macro '/W' (opcode NOTLETTER) - match not english letter or '_' \r
+ (all r.e.syntax extensions may be turned off by flag ExtSyntax) \r
\r
+ v. 0.1 1999.06.09 \r
+ first version, with bugs, without help => must die :( \r
\r
+*)</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{$DEFINE DebugRegExpr}</FONT></I> <I><FONT COLOR="Navy">// define for dump/trace enabling </FONT></I>\r
\r
+<I><FONT COLOR="Navy">{$DEFINE reRealExceptionAddr}</FONT></I> <I><FONT COLOR="Navy">// if defined then exceptions will </FONT></I>\r
+<I><FONT COLOR="Navy">// jump to appropriate source line, not to Error procedure </FONT></I>\r
\r
+<I><FONT COLOR="Navy">{.$DEFINE ComplexBraces}</FONT></I> <I><FONT COLOR="Navy">// define for beta-version of braces </FONT></I>\r
+<I><FONT COLOR="Navy">// (in stable version it works only for simple cases) </FONT></I>\r
\r
+<I><FONT COLOR="Navy">{.$DEFINE UniCode}</FONT></I> <I><FONT COLOR="Navy">// define for Unicode support </FONT></I>\r
\r
+<I><FONT COLOR="Navy">{$IFNDEF UniCode}</FONT></I> <I><FONT COLOR="Navy">// optionts applicable only for non-UniCode </FONT></I>\r
+ <I><FONT COLOR="Navy">{$DEFINE UseSetOfChar}</FONT></I> <I><FONT COLOR="Navy">// Significant optimization by using set of char </FONT></I>\r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{$IFDEF UseSetOfChar}</FONT></I> \r
+ <I><FONT COLOR="Navy">{$DEFINE UseFirstCharSet}</FONT></I> <I><FONT COLOR="Navy">// Significant optimization inm some cases </FONT></I>\r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<B>interface</B> \r
\r
+<I><FONT COLOR="Navy">// Determine version (for using 'params by default') </FONT></I>\r
+<I><FONT COLOR="Navy">{$IFNDEF VER80}</FONT></I>         <I><FONT COLOR="Navy">{ Delphi 1.0}</FONT></I> \r
+ <I><FONT COLOR="Navy">{$IFNDEF VER90}</FONT></I>        <I><FONT COLOR="Navy">{ Delphi 2.0}</FONT></I> \r
+  <I><FONT COLOR="Navy">{$IFNDEF VER93}</FONT></I>       <I><FONT COLOR="Navy">{ C++Builder 1.0}</FONT></I> \r
+    <I><FONT COLOR="Navy">{$IFNDEF VER100}</FONT></I>    <I><FONT COLOR="Navy">{ Borland Delphi 3.0}</FONT></I> \r
+        <I><FONT COLOR="Navy">{$DEFINE D4_}</FONT></I>   <I><FONT COLOR="Navy">{ Delphi 4.0 or higher}</FONT></I> \r
+    <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+ <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+<I><FONT COLOR="Navy">{.$IFNDEF VER110}</FONT></I>  <I><FONT COLOR="Navy">{ Borland C++Builder 3.0}</FONT></I> \r
+<I><FONT COLOR="Navy">{.$IFNDEF VER120}</FONT></I>  <I><FONT COLOR="Navy">{Borland Delphi 4.0}</FONT></I> \r
\r
\r
+<B>uses</B> \r
+ Classes, <I><FONT COLOR="Navy">// TStrings in Split method </FONT></I>\r
+ SysUtils; <I><FONT COLOR="Navy">// Exception </FONT></I>\r
\r
\r
+<B>type</B> \r
+ <I><FONT COLOR="Navy">{$IFDEF UniCode}</FONT></I> \r
+ PRegExprChar = PWideChar; \r
+ RegExprString = WideString; \r
+ REChar = WideChar; \r
+ <I><FONT COLOR="Navy">{$ELSE}</FONT></I> \r
+ PRegExprChar = PChar; \r
+ RegExprString = <B>string</B>; \r
+ REChar = Char; \r
+ <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+ TREOp = REChar; <I><FONT COLOR="Navy">// internal p-code type //###0.933 </FONT></I>\r
+ PREOp = ^TREOp; \r
+ TRENextOff = integer; <I><FONT COLOR="Navy">// internal Next "pointer" (offset to current p-code) //###0.933 </FONT></I>\r
+ PRENextOff = ^TRENextOff; <I><FONT COLOR="Navy">// used for extracting Next "pointers" from compiled r.e. //###0.933 </FONT></I>\r
+ TREBracesArg = integer; <I><FONT COLOR="Navy">// type of {m,n} arguments </FONT></I>\r
+ PREBracesArg = ^TREBracesArg; \r
\r
+<B>const</B> \r
+ REOpSz = SizeOf (TREOp) <B>div</B> SizeOf (REChar); <I><FONT COLOR="Navy">// size of p-code in RegExprString units </FONT></I>\r
+ RENextOffSz = SizeOf (TRENextOff) <B>div</B> SizeOf (REChar); <I><FONT COLOR="Navy">// size of Next 'pointer' -"- </FONT></I>\r
+ REBracesArgSz = SizeOf (TREBracesArg) <B>div</B> SizeOf (REChar); <I><FONT COLOR="Navy">// size of BRACES arguments -"- </FONT></I>\r
\r
+<B>type</B> \r
+ TRegExprInvertCaseFunction = <B>function</B> (<B>const</B> Ch : REChar) : REChar \r
+                               <B>of</B> <B>object</B>; \r
\r
+<B>const</B> \r
+  RegExprModifierI : boolean = False; \r
+  <I><FONT COLOR="Navy">// default value for ModifierI </FONT></I>\r
\r
+  RegExprModifierR : boolean = True; \r
+  <I><FONT COLOR="Navy">// default value for ModifierR </FONT></I>\r
\r
+  RegExprModifierS : boolean = True; \r
+  <I><FONT COLOR="Navy">// default value for ModifierS </FONT></I>\r
\r
+  RegExprSpaceChars : RegExprString = <I><FONT COLOR="Navy">// chars for /s & /S </FONT></I>\r
+  ' '#$9#$A#$D#$C; <I><FONT COLOR="Navy">// default for SpaceChars property </FONT></I>\r
\r
+  RegExprWordChars : RegExprString = <I><FONT COLOR="Navy">// chars for /w & /W </FONT></I>\r
+  <I><FONT COLOR="Navy">// Ampliado por Leandro Lucarella (11/00) </FONT></I>\r
+    'abcdefghijklmnopqrstuvwxyzáéíóúýäëïöüÿàèìòùâêîôûñç' \r
+  + 'ABCDEFGHIJKLMNOPQRSTUVWXYZÁÉÍÓÚÝÄËÏÖÜ\9fÀÈÌÒÙÂÊÎÔÛÑÇ_'; <I><FONT COLOR="Navy">// default for WordChars property </FONT></I>\r
\r
\r
+<B>const</B> \r
+ NSUBEXP = 15; <I><FONT COLOR="Navy">// max number of subexpression //###0.929 </FONT></I>\r
+ <I><FONT COLOR="Navy">// Be carefull - don't use values which overflow CLOSE opcode </FONT></I>\r
+ <I><FONT COLOR="Navy">// (in this case you'll get compiler erorr). </FONT></I>\r
+ <I><FONT COLOR="Navy">// Big NSUBEXP will cause more slow work and more stack required </FONT></I>\r
+ MaxBracesArg = $7FFFFFFF - 1; <I><FONT COLOR="Navy">// max value for {n,m} arguments //###0.933 </FONT></I>\r
+ <I><FONT COLOR="Navy">{$IFDEF ComplexBraces}</FONT></I> \r
+ LoopStackMax = 10; <I><FONT COLOR="Navy">// max depth of loops stack //###0.925 </FONT></I>\r
+ <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+ TinySetLen = 3; \r
+ <I><FONT COLOR="Navy">// if range includes more then TinySetLen chars, //###0.934 </FONT></I>\r
+ <I><FONT COLOR="Navy">// then use full (32 bytes) ANYOFFULL instead of ANYOF[BUT]TINYSET </FONT></I>\r
+ <I><FONT COLOR="Navy">// !!! Attension ! If you change TinySetLen, you must </FONT></I>\r
+ <I><FONT COLOR="Navy">// change code marked as "//!!!TinySet" </FONT></I>\r
\r
\r
+<B>type</B> \r
\r
+<I><FONT COLOR="Navy">{$IFDEF UseSetOfChar}</FONT></I> \r
+ PSetOfREChar = ^TSetOfREChar; \r
+ TSetOfREChar = <B>set</B> <B>of</B> REChar; \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+ <I><FONT COLOR="Navy">{** Clase auxiliar que implementa expresiones Regulares. Se ultiliza para validar los campos de texto}</FONT></I> \r
+ TRegExpr = <B>class</B> \r
+   <B>private</B> \r
+    startp : <B>array</B> [0 .. NSUBEXP - 1] <B>of</B> PRegExprChar; <I><FONT COLOR="Navy">// founded expr starting points </FONT></I>\r
+    endp : <B>array</B> [0 .. NSUBEXP - 1] <B>of</B> PRegExprChar; <I><FONT COLOR="Navy">// founded expr end points </FONT></I>\r
\r
+    <I><FONT COLOR="Navy">{$IFDEF ComplexBraces}</FONT></I> \r
+    LoopStack : <B>array</B> [1 .. LoopStackMax] <B>of</B> integer; <I><FONT COLOR="Navy">// state before entering loop </FONT></I>\r
+    LoopStackIdx : integer; <I><FONT COLOR="Navy">// 0 - out of all loops </FONT></I>\r
+    <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+    <I><FONT COLOR="Navy">// The "internal use only" fields to pass info from compile </FONT></I>\r
+    <I><FONT COLOR="Navy">// to execute that permits the execute phase to run lots faster on </FONT></I>\r
+    <I><FONT COLOR="Navy">// simple cases. </FONT></I>\r
+    regstart : REChar; <I><FONT COLOR="Navy">// char that must begin a match; '/0' if none obvious </FONT></I>\r
+    reganch : REChar; <I><FONT COLOR="Navy">// is the match anchored (at beginning-of-line only)? </FONT></I>\r
+    regmust : PRegExprChar; <I><FONT COLOR="Navy">// string (pointer into program) that match must include, or nil </FONT></I>\r
+    regmlen : integer; <I><FONT COLOR="Navy">// length of regmust string </FONT></I>\r
+    <I><FONT COLOR="Navy">// Regstart and reganch permit very fast decisions on suitable starting points </FONT></I>\r
+    <I><FONT COLOR="Navy">// for a match, cutting down the work a lot.  Regmust permits fast rejection </FONT></I>\r
+    <I><FONT COLOR="Navy">// of lines that cannot possibly match.  The regmust tests are costly enough </FONT></I>\r
+    <I><FONT COLOR="Navy">// that regcomp() supplies a regmust only if the r.e. contains something </FONT></I>\r
+    <I><FONT COLOR="Navy">// potentially expensive (at present, the only such thing detected is * or + </FONT></I>\r
+    <I><FONT COLOR="Navy">// at the start of the r.e., which can involve a lot of backup).  Regmlen is </FONT></I>\r
+    <I><FONT COLOR="Navy">// supplied because the test in regexec() needs it and regcomp() is computing </FONT></I>\r
+    <I><FONT COLOR="Navy">// it anyway. </FONT></I>\r
+    <I><FONT COLOR="Navy">{$IFDEF UseFirstCharSet}</FONT></I> <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+    FirstCharSet : TSetOfREChar; \r
+    <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+    <I><FONT COLOR="Navy">// work variables for Exec's routins - save stack in recursion} </FONT></I>\r
+    reginput : PRegExprChar; <I><FONT COLOR="Navy">// String-input pointer. </FONT></I>\r
+    fInputStart : PRegExprChar; <I><FONT COLOR="Navy">// Pointer to first char of input string. </FONT></I>\r
+    fInputEnd : PRegExprChar; <I><FONT COLOR="Navy">// Pointer to char AFTER last char of input string </FONT></I>\r
\r
+    <I><FONT COLOR="Navy">// work variables for compiler's routines </FONT></I>\r
+    regparse : PRegExprChar;  <I><FONT COLOR="Navy">// Input-scan pointer. </FONT></I>\r
+    regnpar : integer; <I><FONT COLOR="Navy">// count. </FONT></I>\r
+    regdummy : char; \r
+    regcode : PRegExprChar;   <I><FONT COLOR="Navy">// Code-emit pointer; @regdummy = don't. </FONT></I>\r
+    regsize : integer; <I><FONT COLOR="Navy">// Code size. </FONT></I>\r
\r
+    regexpbeg : PRegExprChar; <I><FONT COLOR="Navy">// only for error handling. Contains </FONT></I>\r
+    <I><FONT COLOR="Navy">// pointer to beginning of r.e. while compiling </FONT></I>\r
+    fExprIsCompiled : boolean; <I><FONT COLOR="Navy">// true if r.e. successfully compiled </FONT></I>\r
\r
+    <I><FONT COLOR="Navy">// programm is essentially a linear encoding </FONT></I>\r
+    <I><FONT COLOR="Navy">// of a nondeterministic finite-state machine (aka syntax charts or </FONT></I>\r
+    <I><FONT COLOR="Navy">// "railroad normal form" in parsing technology).  Each node is an opcode </FONT></I>\r
+    <I><FONT COLOR="Navy">// plus a "next" pointer, possibly plus an operand.  "Next" pointers of </FONT></I>\r
+    <I><FONT COLOR="Navy">// all nodes except BRANCH implement concatenation; a "next" pointer with </FONT></I>\r
+    <I><FONT COLOR="Navy">// a BRANCH on both ends of it is connecting two alternatives.  (Here we </FONT></I>\r
+    <I><FONT COLOR="Navy">// have one of the subtle syntax dependencies:  an individual BRANCH (as </FONT></I>\r
+    <I><FONT COLOR="Navy">// opposed to a collection of them) is never concatenated with anything </FONT></I>\r
+    <I><FONT COLOR="Navy">// because of operator precedence.)  The operand of some types of node is </FONT></I>\r
+    <I><FONT COLOR="Navy">// a literal string; for others, it is a node leading into a sub-FSM.  In </FONT></I>\r
+    <I><FONT COLOR="Navy">// particular, the operand of a BRANCH node is the first node of the branch. </FONT></I>\r
+    <I><FONT COLOR="Navy">// (NB this is *not* a tree structure:  the tail of the branch connects </FONT></I>\r
+    <I><FONT COLOR="Navy">// to the thing following the set of BRANCHes.)  The opcodes are: </FONT></I>\r
+    programm : PRegExprChar; <I><FONT COLOR="Navy">// Unwarranted chumminess with compiler. </FONT></I>\r
\r
+    fExpression : PRegExprChar; <I><FONT COLOR="Navy">// source of compiled r.e. </FONT></I>\r
+    fInputString : PRegExprChar; <I><FONT COLOR="Navy">// input string </FONT></I>\r
\r
+    fLastError : integer; <I><FONT COLOR="Navy">// see Error, LastError </FONT></I>\r
\r
+    fModifiers : integer; <I><FONT COLOR="Navy">// modifiers </FONT></I>\r
+    fCompModifiers : integer; <I><FONT COLOR="Navy">// compiler's copy of modifiers </FONT></I>\r
+    fProgModifiers : integer; <I><FONT COLOR="Navy">// values modifiers from last programm compilation </FONT></I>\r
\r
+    fSpaceChars : RegExprString; <I><FONT COLOR="Navy">//###0.927 </FONT></I>\r
+    fWordChars : RegExprString; <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+    fInvertCase : TRegExprInvertCaseFunction; <I><FONT COLOR="Navy">//###0.927 </FONT></I>\r
\r
+    <B>function</B> IsProgrammOk : boolean; <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
\r
+    <B>procedure</B> CheckCompModifiers; \r
+    <I><FONT COLOR="Navy">// if modifiers was changed after programm compilation - recompile it ! </FONT></I>\r
\r
+    <B>function</B> GetExpression : RegExprString; \r
+    <B>procedure</B> SetExpression (<B>const</B> s : RegExprString); \r
\r
+    <B>function</B> GetModifierStr : RegExprString; \r
+    <B>function</B> SetModifiersInt (<B>const</B> AModifiers : RegExprString; <B>var</B> AModifiersInt : integer) : boolean; \r
+    <B>procedure</B> SetModifierStr (<B>const</B> AModifiers : RegExprString); \r
\r
+    <B>function</B> GetModifier (AIndex : integer) : boolean; \r
+    <B>procedure</B> SetModifier (AIndex : integer; ASet : boolean); \r
\r
+    <B>procedure</B> Error (AErrorID : integer); <B>virtual</B>; <I><FONT COLOR="Navy">// error handler. </FONT></I>\r
+    <I><FONT COLOR="Navy">// Default handler raise exception ERegExpr with </FONT></I>\r
+    <I><FONT COLOR="Navy">// Message = ErrorMsg (AErrorID), ErrorCode = AErrorID </FONT></I>\r
+    <I><FONT COLOR="Navy">// and CompilerErrorPos = value of property CompilerErrorPos. </FONT></I>\r
\r
\r
+    <I><FONT COLOR="Navy">{==================== Compiler section ===================}</FONT></I> \r
+    <B>function</B> CompileRegExpr (exp : PRegExprChar) : boolean; \r
+    <I><FONT COLOR="Navy">// compile a regular expression into internal code </FONT></I>\r
\r
+    <B>procedure</B> Tail (p : PRegExprChar; val : PRegExprChar); \r
+    <I><FONT COLOR="Navy">// set the next-pointer at the end of a node chain </FONT></I>\r
\r
+    <B>procedure</B> OpTail (p : PRegExprChar; val : PRegExprChar); \r
+    <I><FONT COLOR="Navy">// regoptail - regtail on operand of first argument; nop if operandless </FONT></I>\r
\r
+    <B>function</B> EmitNode (op : TREOp) : PRegExprChar; \r
+    <I><FONT COLOR="Navy">// regnode - emit a node, return location </FONT></I>\r
\r
+    <B>procedure</B> EmitC (b : REChar); \r
+    <I><FONT COLOR="Navy">// emit (if appropriate) a byte of code </FONT></I>\r
\r
+    <B>procedure</B> InsertOperator (op : TREOp; opnd : PRegExprChar; sz : integer); <I><FONT COLOR="Navy">//###0.90 </FONT></I>\r
+    <I><FONT COLOR="Navy">// insert an operator in front of already-emitted operand </FONT></I>\r
+    <I><FONT COLOR="Navy">// Means relocating the operand. </FONT></I>\r
\r
+    <B>function</B> ParseReg (paren : integer; <B>var</B> flagp : integer) : PRegExprChar; \r
+    <I><FONT COLOR="Navy">// regular expression, i.e. main body or parenthesized thing </FONT></I>\r
\r
+    <B>function</B> ParseBranch (<B>var</B> flagp : integer) : PRegExprChar; \r
+    <I><FONT COLOR="Navy">// one alternative of an | operator </FONT></I>\r
\r
+    <B>function</B> ParsePiece (<B>var</B> flagp : integer) : PRegExprChar; \r
+    <I><FONT COLOR="Navy">// something followed by possible [*+?] </FONT></I>\r
\r
+    <B>function</B> ParseAtom (<B>var</B> flagp : integer) : PRegExprChar; \r
+    <I><FONT COLOR="Navy">// the lowest level </FONT></I>\r
\r
+    <B>function</B> GetCompilerErrorPos : integer; \r
+    <I><FONT COLOR="Navy">// current pos in r.e. - for error hanling </FONT></I>\r
\r
+    <I><FONT COLOR="Navy">{$IFDEF UseFirstCharSet}</FONT></I> <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+    <B>procedure</B> FillFirstCharSet (prog : PRegExprChar); \r
+    <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+    <I><FONT COLOR="Navy">{===================== Mathing section ===================}</FONT></I> \r
+    <B>function</B> regrepeat (p : PRegExprChar; AMax : integer) : integer; \r
+    <I><FONT COLOR="Navy">// repeatedly match something simple, report how many </FONT></I>\r
\r
+    <B>function</B> regnext (p : PRegExprChar) : PRegExprChar; \r
+    <I><FONT COLOR="Navy">// dig the "next" pointer out of a node </FONT></I>\r
\r
+    <B>function</B> MatchPrim (prog : PRegExprChar) : boolean; \r
+    <I><FONT COLOR="Navy">// recursively matching routine </FONT></I>\r
\r
+    <B>function</B> RegMatch (str : PRegExprChar) : boolean; \r
+    <I><FONT COLOR="Navy">// try match at specific point, uses MatchPrim for real work </FONT></I>\r
\r
+    <B>function</B> ExecPrim (AOffset: integer) : boolean; \r
+    <I><FONT COLOR="Navy">// Exec for stored InputString </FONT></I>\r
\r
+    <I><FONT COLOR="Navy">{$IFDEF DebugRegExpr}</FONT></I> \r
+    <B>function</B> DumpOp (op : REChar) : RegExprString; \r
+    <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+    <B>function</B> GetSubExprMatchCount : integer; \r
+    <B>function</B> GetMatchPos (Idx : integer) : integer; \r
+    <B>function</B> GetMatchLen (Idx : integer) : integer; \r
+    <B>function</B> GetMatch (Idx : integer) : RegExprString; \r
\r
+    <B>function</B> GetInputString : RegExprString; \r
+    <B>procedure</B> SetInputString (<B>const</B> AInputString : RegExprString); \r
\r
+    <I><FONT COLOR="Navy">{$IFNDEF UseSetOfChar}</FONT></I> \r
+    <B>function</B> StrScanCI (s : PRegExprChar; ch : REChar) : PRegExprChar; <I><FONT COLOR="Navy">//###0.928 </FONT></I>\r
+    <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+   <B>public</B> \r
+    <B>constructor</B> Create; \r
+    <B>destructor</B> Destroy; <B>override</B>; \r
\r
+    <B>property</B> Expression : RegExprString <B>read</B> GetExpression <B>write</B> SetExpression; \r
+    <I><FONT COLOR="Navy">// regular expression </FONT></I>\r
+    <I><FONT COLOR="Navy">// When you assign r.e. to this property, TRegExpr will automatically </FONT></I>\r
+    <I><FONT COLOR="Navy">// compile it and store in internal structures. </FONT></I>\r
+    <I><FONT COLOR="Navy">// In case of compilation error, Error method will be called </FONT></I>\r
+    <I><FONT COLOR="Navy">// (by default Error method raises exception ERegExpr - see below) </FONT></I>\r
\r
+    <B>property</B> ModifierStr : RegExprString <B>read</B> GetModifierStr <B>write</B> SetModifierStr; \r
+    <I><FONT COLOR="Navy">// Set/get default values of r.e.syntax modifiers. Modifiers in </FONT></I>\r
+    <I><FONT COLOR="Navy">// r.e. (?ismx-ismx) will replace this default values. </FONT></I>\r
+    <I><FONT COLOR="Navy">// If you try to set unsupported modifier, Error will be called </FONT></I>\r
+    <I><FONT COLOR="Navy">// (by defaul Error raises exception ERegExpr). </FONT></I>\r
\r
+    <B>property</B> ModifierI : boolean <B>index</B> 1 <B>read</B> GetModifier <B>write</B> SetModifier; \r
+    <I><FONT COLOR="Navy">// Modifier /i - caseinsensitive, false by default </FONT></I>\r
\r
+    <B>property</B> ModifierR : boolean <B>index</B> 2 <B>read</B> GetModifier <B>write</B> SetModifier; \r
+    <I><FONT COLOR="Navy">// Modifier /r - use r.e.syntax extended for russian, true by default </FONT></I>\r
+    <I><FONT COLOR="Navy">// (was property ExtSyntaxEnabled in previous versions) </FONT></I>\r
+    <I><FONT COLOR="Navy">// If true, then à-ÿ  additional include russian letter '¸', </FONT></I>\r
+    <I><FONT COLOR="Navy">// À-ß  additional include '¨', and à-ß include all russian symbols. </FONT></I>\r
+    <I><FONT COLOR="Navy">// You have to turn it off if it may interfere with you national alphabet. </FONT></I>\r
\r
+    <B>property</B> ModifierS : boolean <B>index</B> 3 <B>read</B> GetModifier <B>write</B> SetModifier; \r
+    <I><FONT COLOR="Navy">// Modifier /s - '.' works as any char (else as [^/n]), </FONT></I>\r
+    <I><FONT COLOR="Navy">// true by default </FONT></I>\r
\r
+    <B>function</B> Exec (<B>const</B> AInputString : RegExprString) : boolean; \r
+    <I><FONT COLOR="Navy">// match a programm against a string AInputString </FONT></I>\r
+    <I><FONT COLOR="Navy">// !!! Exec store AInputString into InputString property </FONT></I>\r
\r
+    <B>function</B> ExecNext : boolean; \r
+    <I><FONT COLOR="Navy">// find next match: </FONT></I>\r
+    <I><FONT COLOR="Navy">//    Exec (AString); ExecNext; </FONT></I>\r
+    <I><FONT COLOR="Navy">// works same as </FONT></I>\r
+    <I><FONT COLOR="Navy">//    Exec (AString); </FONT></I>\r
+    <I><FONT COLOR="Navy">//    if MatchLen [0] = 0 then ExecPos (MatchPos [0] + 1) </FONT></I>\r
+    <I><FONT COLOR="Navy">//     else ExecPos (MatchPos [0] + MatchLen [0]); </FONT></I>\r
+    <I><FONT COLOR="Navy">// but it's more simpler ! </FONT></I>\r
\r
+    <B>function</B> ExecPos (AOffset: integer <I><FONT COLOR="Navy">{$IFDEF D4_}</FONT></I>= 1<I><FONT COLOR="Navy">{$ENDIF}</FONT></I>) : boolean; \r
+    <I><FONT COLOR="Navy">// find match for InputString starting from AOffset position </FONT></I>\r
+    <I><FONT COLOR="Navy">// (AOffset=1 - first char of InputString) </FONT></I>\r
\r
+    <B>property</B> InputString : RegExprString <B>read</B> GetInputString <B>write</B> SetInputString; \r
+    <I><FONT COLOR="Navy">// returns current input string (from last Exec call or last assign </FONT></I>\r
+    <I><FONT COLOR="Navy">// to this property). </FONT></I>\r
+    <I><FONT COLOR="Navy">// Any assignment to this property clear Match* properties ! </FONT></I>\r
\r
+    <B>function</B> Substitute (<B>const</B> ATemplate : RegExprString) : RegExprString; \r
+    <I><FONT COLOR="Navy">// Returns ATemplate with '$&' or '$0' replaced by whole r.e. </FONT></I>\r
+    <I><FONT COLOR="Navy">// occurence and '$n' replaced by occurence of subexpression #n. </FONT></I>\r
+    <I><FONT COLOR="Navy">// Since v.0.929 '$' used instead of '/' (for future extensions </FONT></I>\r
+    <I><FONT COLOR="Navy">// and for more Perl-compatibility) and accept more then one digit. </FONT></I>\r
+    <I><FONT COLOR="Navy">// If you want place into template raw '$' or '/', use prefix '/' </FONT></I>\r
+    <I><FONT COLOR="Navy">// Example: '1/$ is $2//rub//' -> '1$ is <Match[2]>/rub/' </FONT></I>\r
+    <I><FONT COLOR="Navy">// If you want to place raw digit after '$n' you must delimit </FONT></I>\r
+    <I><FONT COLOR="Navy">// n with curly braces '{}'. </FONT></I>\r
+    <I><FONT COLOR="Navy">// Example: 'a$12bc' -> 'a<Match[12]>bc' </FONT></I>\r
+    <I><FONT COLOR="Navy">// 'a${1}2bc' -> 'a<Match[1]>2bc'. </FONT></I>\r
\r
+    <B>procedure</B> Split (AInputStr : RegExprString; APieces : TStrings); \r
+    <I><FONT COLOR="Navy">// Split AInputStr into APieces by r.e. occurencies </FONT></I>\r
\r
+    <B>function</B> Replace (AInputStr : RegExprString; <B>const</B> AReplaceStr : RegExprString) : RegExprString; \r
+    <I><FONT COLOR="Navy">// Returns AInputStr with r.e. occurencies replaced by AReplaceStr </FONT></I>\r
\r
+    <B>property</B> SubExprMatchCount : integer <B>read</B> GetSubExprMatchCount; \r
+    <I><FONT COLOR="Navy">// Number of subexpressions has been found in last Exec* call. </FONT></I>\r
+    <I><FONT COLOR="Navy">// If there are no subexpr. but whole expr was found (Exec* returned True), </FONT></I>\r
+    <I><FONT COLOR="Navy">// then SubExprMatchCount=0, if no subexpressions nor whole </FONT></I>\r
+    <I><FONT COLOR="Navy">// r.e. found (Exec* returned false) then SubExprMatchCount=-1. </FONT></I>\r
+    <I><FONT COLOR="Navy">// Note, that some subexpr. may be not found and for such </FONT></I>\r
+    <I><FONT COLOR="Navy">// subexpr. MathPos=MatchLen=-1 and Match=''. </FONT></I>\r
+    <I><FONT COLOR="Navy">// For example: Expression := '(1)?2(3)?'; </FONT></I>\r
+    <I><FONT COLOR="Navy">//  Exec ('123'): SubExprMatchCount=2, Match[0]='123', [1]='1', [2]='3' </FONT></I>\r
+    <I><FONT COLOR="Navy">//  Exec ('12'): SubExprMatchCount=1, Match[0]='23', [1]='1' </FONT></I>\r
+    <I><FONT COLOR="Navy">//  Exec ('23'): SubExprMatchCount=2, Match[0]='23', [1]='', [2]='3' </FONT></I>\r
+    <I><FONT COLOR="Navy">//  Exec ('2'): SubExprMatchCount=0, Match[0]='2' </FONT></I>\r
+    <I><FONT COLOR="Navy">//  Exec ('7') - return False: SubExprMatchCount=-1 </FONT></I>\r
\r
+    <B>property</B> MatchPos [Idx : integer] : integer <B>read</B> GetMatchPos; \r
+    <I><FONT COLOR="Navy">// pos of entrance subexpr. #Idx into tested in last Exec* </FONT></I>\r
+    <I><FONT COLOR="Navy">// string. First subexpr. have Idx=1, last - MatchCount, </FONT></I>\r
+    <I><FONT COLOR="Navy">// whole r.e. have Idx=0. </FONT></I>\r
+    <I><FONT COLOR="Navy">// Returns -1 if in r.e. no such subexpr. or this subexpr. </FONT></I>\r
+    <I><FONT COLOR="Navy">// not found in input string. </FONT></I>\r
\r
+    <B>property</B> MatchLen [Idx : integer] : integer <B>read</B> GetMatchLen; \r
+    <I><FONT COLOR="Navy">// len of entrance subexpr. #Idx r.e. into tested in last Exec* </FONT></I>\r
+    <I><FONT COLOR="Navy">// string. First subexpr. have Idx=1, last - MatchCount, </FONT></I>\r
+    <I><FONT COLOR="Navy">// whole r.e. have Idx=0. </FONT></I>\r
+    <I><FONT COLOR="Navy">// Returns -1 if in r.e. no such subexpr. or this subexpr. </FONT></I>\r
+    <I><FONT COLOR="Navy">// not found in input string. </FONT></I>\r
+    <I><FONT COLOR="Navy">// Remember - MatchLen may be 0 (if r.e. match empty string) ! </FONT></I>\r
\r
+    <B>property</B> Match [Idx : integer] : RegExprString <B>read</B> GetMatch; \r
+    <I><FONT COLOR="Navy">// == copy (InputString, MatchPos [Idx], MatchLen [Idx]) </FONT></I>\r
+    <I><FONT COLOR="Navy">// Returns '' if in r.e. no such subexpr. or this subexpr. </FONT></I>\r
+    <I><FONT COLOR="Navy">// not found in input string. </FONT></I>\r
\r
+    <B>function</B> LastError : integer; \r
+    <I><FONT COLOR="Navy">// Returns ID of last error, 0 if no errors (unusable if </FONT></I>\r
+    <I><FONT COLOR="Navy">// Error method raises exception) and clear internal status </FONT></I>\r
+    <I><FONT COLOR="Navy">// into 0 (no errors). </FONT></I>\r
\r
+    <B>function</B> ErrorMsg (AErrorID : integer) : RegExprString; <B>virtual</B>; \r
+    <I><FONT COLOR="Navy">// Returns Error message for error with ID = AErrorID. </FONT></I>\r
\r
+    <B>property</B> CompilerErrorPos : integer <B>read</B> GetCompilerErrorPos; \r
+    <I><FONT COLOR="Navy">// Returns pos in r.e. there compiler stopped. </FONT></I>\r
+    <I><FONT COLOR="Navy">// Usefull for error diagnostics </FONT></I>\r
\r
+    <B>property</B> SpaceChars : RegExprString <B>read</B> fSpaceChars <B>write</B> fSpaceChars; <I><FONT COLOR="Navy">//###0.927 </FONT></I>\r
+    <I><FONT COLOR="Navy">// Contains chars, treated as /s (initially filled with RegExprSpaceChars </FONT></I>\r
+    <I><FONT COLOR="Navy">// global constant) </FONT></I>\r
\r
+    <B>property</B> WordChars : RegExprString <B>read</B> fWordChars <B>write</B> fWordChars; <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+    <I><FONT COLOR="Navy">// Contains chars, treated as /w (initially filled with RegExprWordChars </FONT></I>\r
+    <I><FONT COLOR="Navy">// global constant) </FONT></I>\r
\r
+    <B>class</B> <B>function</B> InvertCaseFunction  (<B>const</B> Ch : REChar) : REChar; \r
+    <I><FONT COLOR="Navy">// Converts Ch into upper case if it in lower case or in lower </FONT></I>\r
+    <I><FONT COLOR="Navy">// if it in upper (uses current system local setings) </FONT></I>\r
\r
+    <B>property</B> InvertCase : TRegExprInvertCaseFunction <B>read</B> fInvertCase <B>write</B> fInvertCase; <I><FONT COLOR="Navy">//##0.935 </FONT></I>\r
+    <I><FONT COLOR="Navy">// Set this property if you want to override case-insensitive functionality. </FONT></I>\r
+    <I><FONT COLOR="Navy">// Create set it to RegExprInvertCaseFunction (InvertCaseFunction by default) </FONT></I>\r
\r
+    <I><FONT COLOR="Navy">{$IFDEF DebugRegExpr}</FONT></I> \r
+    <B>function</B> Dump : RegExprString; \r
+    <I><FONT COLOR="Navy">// dump a compiled regexp in vaguely comprehensible form </FONT></I>\r
+    <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+  <B>end</B>; \r
\r
+ <I><FONT COLOR="Navy">{** Excepción de expresiones regulares}</FONT></I>  \r
+ ERegExpr = <B>class</B> (Exception) \r
+   <B>public</B> \r
+    ErrorCode : integer; \r
+    CompilerErrorPos : integer; \r
+  <B>end</B>; \r
\r
+<B>const</B> \r
+  RegExprInvertCaseFunction : TRegExprInvertCaseFunction = TRegExpr.InvertCaseFunction; \r
+  <I><FONT COLOR="Navy">// defaul for InvertCase property </FONT></I>\r
\r
+<I><FONT COLOR="Navy">{** true if string AInputString match regular expression ARegExpr \r
+    ! will raise exeption if syntax errors in ARegExpr}</FONT></I> \r
+<B>function</B> ExecRegExpr (<B>const</B> ARegExpr, AInputStr : RegExprString) : boolean; \r
\r
+<I><FONT COLOR="Navy">{** Split AInputStr into APieces by r.e. ARegExpr occurencies}</FONT></I> \r
+<B>procedure</B> SplitRegExpr (<B>const</B> ARegExpr, AInputStr : RegExprString; APieces : TStrings); \r
\r
+<I><FONT COLOR="Navy">{** Returns AInputStr with r.e. occurencies replaced by AReplaceStr}</FONT></I> \r
+<B>function</B> ReplaceRegExpr (<B>const</B> ARegExpr, AInputStr, AReplaceStr : RegExprString) : RegExprString; \r
\r
+<I><FONT COLOR="Navy">{** Replace all metachars with its safe representation, \r
+    for example 'abc$cd.(' converts into 'abc/$cd/./(' \r
+    This function usefull for r.e. autogeneration from \r
+    user input}</FONT></I> \r
+<B>function</B> QuoteRegExprMetaChars (<B>const</B> AStr : RegExprString) : RegExprString; \r
\r
+<B>implementation</B> \r
\r
+<B>uses</B> \r
+ Windows; <I><FONT COLOR="Navy">// CharUpper/Lower </FONT></I>\r
\r
+<B>const</B> \r
+ MaskModI = 1; <I><FONT COLOR="Navy">// modifier /i bit in fModifiers </FONT></I>\r
+ MaskModR = 2; <I><FONT COLOR="Navy">// -"- /r </FONT></I>\r
+ MaskModS = 4; <I><FONT COLOR="Navy">// -"- /s </FONT></I>\r
\r
+<I><FONT COLOR="Navy">{=============================================================}</FONT></I> \r
+<I><FONT COLOR="Navy">{=================== WideString functions ====================}</FONT></I> \r
+<I><FONT COLOR="Navy">{=============================================================}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{$IFDEF UniCode}</FONT></I> \r
\r
+<B>function</B> StrPCopy (Dest: PRegExprChar; <B>const</B> Source: RegExprString): PRegExprChar; \r
+ <B>var</B> \r
+  i, Len : Integer; \r
+ <B>begin</B> \r
+  Len := length (Source); <I><FONT COLOR="Navy">//###0.932 </FONT></I>\r
+  <B>for</B> i := 1 <B>to</B> Len <B>do</B> \r
+   Dest [i - 1] := Source [i]; \r
+  Dest [Len] := #0; \r
+  Result := Dest; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function StrPCopy \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> StrLCopy (Dest, Source: PRegExprChar; MaxLen: Cardinal): PRegExprChar; \r
+ <B>var</B> i: Integer; \r
+ <B>begin</B> \r
+  <B>for</B> i := 0 <B>to</B> MaxLen - 1 <B>do</B> \r
+   Dest [i] := Source [i]; \r
+  Result := Dest; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function StrLCopy \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> StrLen (Str: PRegExprChar): Cardinal; \r
+ <B>begin</B> \r
+  Result:=0; \r
+  <B>while</B> Str [result] <> #0 \r
+   <B>do</B> Inc (Result); \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function StrLen \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> StrPos (Str1, Str2: PRegExprChar): PRegExprChar; \r
+ <B>var</B> n: Integer; \r
+ <B>begin</B> \r
+  Result := <B>nil</B>; \r
+  n := Pos (RegExprString (Str2), RegExprString (Str1)); \r
+  <B>if</B> n = 0 \r
+   <B>then</B> EXIT; \r
+  Result := Str1 + n - 1; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function StrPos \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> StrLComp (Str1, Str2: PRegExprChar; MaxLen: Cardinal): Integer; \r
+ <B>var</B> S1, S2: RegExprString; \r
+ <B>begin</B> \r
+  S1 := Str1; \r
+  S2 := Str2; \r
+  <B>if</B> Copy (S1, 1, MaxLen) > Copy (S2, 1, MaxLen) \r
+   <B>then</B> Result := 1 \r
+   <B>else</B> \r
+    <B>if</B> Copy (S1, 1, MaxLen) < Copy (S2, 1, MaxLen) \r
+     <B>then</B> Result := -1 \r
+     <B>else</B> Result := 0; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ function StrLComp \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> StrScan (Str: PRegExprChar; Chr: WideChar): PRegExprChar; \r
+ <B>begin</B> \r
+  Result := <B>nil</B>; \r
+  <B>while</B> (Str^ <> #0) <B>and</B> (Str^ <> Chr) \r
+   <B>do</B> Inc (Str); \r
+  <B>if</B> (Str^ <> #0) \r
+   <B>then</B> Result := Str; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function StrScan \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{=============================================================}</FONT></I> \r
+<I><FONT COLOR="Navy">{===================== Global functions ======================}</FONT></I> \r
+<I><FONT COLOR="Navy">{=============================================================}</FONT></I> \r
\r
+<B>function</B> ExecRegExpr (<B>const</B> ARegExpr, AInputStr : RegExprString) : boolean; \r
+ <B>var</B> r : TRegExpr; \r
+ <B>begin</B> \r
+  r := TRegExpr.Create; \r
+  <B>try</B> \r
+    r.Expression := ARegExpr; \r
+    Result := r.Exec (AInputStr); \r
+    <B>finally</B> r.Free; \r
+   <B>end</B>; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function ExecRegExpr \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>procedure</B> SplitRegExpr (<B>const</B> ARegExpr, AInputStr : RegExprString; APieces : TStrings); \r
+ <B>var</B> r : TRegExpr; \r
+ <B>begin</B> \r
+  APieces.Clear; \r
+  r := TRegExpr.Create; \r
+  <B>try</B> \r
+    r.Expression := ARegExpr; \r
+    r.Split (AInputStr, APieces); \r
+    <B>finally</B> r.Free; \r
+   <B>end</B>; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of procedure SplitRegExpr \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> ReplaceRegExpr (<B>const</B> ARegExpr, AInputStr, AReplaceStr : RegExprString) : RegExprString; \r
+ <B>var</B> r : TRegExpr; \r
+ <B>begin</B> \r
+  r := TRegExpr.Create; \r
+  <B>try</B> \r
+    r.Expression := ARegExpr; \r
+    Result := r.Replace (AInputStr, AReplaceStr); \r
+    <B>finally</B> r.Free; \r
+   <B>end</B>; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function ReplaceRegExpr \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> QuoteRegExprMetaChars (<B>const</B> AStr : RegExprString) : RegExprString; \r
+ <B>const</B> \r
+  RegExprMetaSet : RegExprString = '^$.[()|?+*/{' \r
+  + ']}'; <I><FONT COLOR="Navy">// - this last are additional to META. </FONT></I>\r
+  <I><FONT COLOR="Navy">// Very similar to META array, but slighly changed. </FONT></I>\r
+  <I><FONT COLOR="Navy">// !Any changes in META array must be synchronized with this set. </FONT></I>\r
+ <B>var</B> \r
+  i, i0, Len : integer; \r
+ <B>begin</B> \r
+  Result := ''; \r
+  Len := length (AStr); \r
+  i := 1; \r
+  i0 := i; \r
+  <B>while</B> i <= Len <B>do</B> <B>begin</B> \r
+    <B>if</B> Pos (AStr [i], RegExprMetaSet) > 0 <B>then</B> <B>begin</B> \r
+      Result := Result + System.Copy (AStr, i0, i - i0) \r
+                 + '/' + AStr [i]; \r
+      i0 := i + 1; \r
+     <B>end</B>; \r
+    inc (i); \r
+   <B>end</B>; \r
+  Result := Result + System.Copy (AStr, i0, MaxInt); <I><FONT COLOR="Navy">// Tail </FONT></I>\r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function QuoteRegExprMetaChars \r
+--------------------------------------------------------------}</FONT></I> \r
\r
\r
\r
+<B>const</B> \r
+ MAGIC       = TREOp (216);<I><FONT COLOR="Navy">// programm signature </FONT></I>\r
\r
+<I><FONT COLOR="Navy">// name            opcode    opnd? meaning </FONT></I>\r
+ EEND        = TREOp (0);  <I><FONT COLOR="Navy">// -    End of program </FONT></I>\r
+ BOL         = TREOp (1);  <I><FONT COLOR="Navy">// -    Match "" at beginning of line </FONT></I>\r
+ EOL         = TREOp (2);  <I><FONT COLOR="Navy">// -    Match "" at end of line </FONT></I>\r
+ ANY         = TREOp (3);  <I><FONT COLOR="Navy">// -    Match any one character </FONT></I>\r
+ ANYOF       = TREOp (4);  <I><FONT COLOR="Navy">// Str  Match any character in string Str </FONT></I>\r
+ ANYBUT      = TREOp (5);  <I><FONT COLOR="Navy">// Str  Match any char. not in string Str </FONT></I>\r
+ BRANCH      = TREOp (6);  <I><FONT COLOR="Navy">// Node Match this alternative, or the next </FONT></I>\r
+ BACK        = TREOp (7);  <I><FONT COLOR="Navy">// -    Jump backward (Next < 0) </FONT></I>\r
+ EXACTLY     = TREOp (8);  <I><FONT COLOR="Navy">// Str  Match string Str </FONT></I>\r
+ NOTHING     = TREOp (9);  <I><FONT COLOR="Navy">// -    Match empty string </FONT></I>\r
+ STAR        = TREOp (10); <I><FONT COLOR="Navy">// Node Match this (simple) thing 0 or more times </FONT></I>\r
+ PLUS        = TREOp (11); <I><FONT COLOR="Navy">// Node Match this (simple) thing 1 or more times </FONT></I>\r
+ ANYDIGIT    = TREOp (12); <I><FONT COLOR="Navy">// -    Match any digit (equiv [0-9]) </FONT></I>\r
+ NOTDIGIT    = TREOp (13); <I><FONT COLOR="Navy">// -    Match not digit (equiv [0-9]) </FONT></I>\r
+ ANYLETTER   = TREOp (14); <I><FONT COLOR="Navy">// -    Match any letter from property WordChars </FONT></I>\r
+ NOTLETTER   = TREOp (15); <I><FONT COLOR="Navy">// -    Match not letter from property WordChars </FONT></I>\r
+ ANYSPACE    = TREOp (16); <I><FONT COLOR="Navy">// -    Match any space char (see property SpaceChars) </FONT></I>\r
+ NOTSPACE    = TREOp (17); <I><FONT COLOR="Navy">// -    Match not space char (see property SpaceChars) </FONT></I>\r
+ BRACES      = TREOp (18); <I><FONT COLOR="Navy">// Node,Min,Max Match this (simple) thing from Min to Max times. </FONT></I>\r
+                           <I><FONT COLOR="Navy">//      Min and Max are TREBracesArg </FONT></I>\r
+ COMMENT     = TREOp (19); <I><FONT COLOR="Navy">// -    Comment ;) </FONT></I>\r
+ EXACTLYCI   = TREOp (20); <I><FONT COLOR="Navy">// Str  Match string Str case insensitive </FONT></I>\r
+ ANYOFCI     = TREOp (21); <I><FONT COLOR="Navy">// Str  Match any character in string Str, case insensitive </FONT></I>\r
+ ANYBUTCI    = TREOp (22); <I><FONT COLOR="Navy">// Str  Match any char. not in string Str, case insensitive </FONT></I>\r
+ LOOPENTRY   = TREOp (23); <I><FONT COLOR="Navy">// Node Start of loop (Node - LOOP for this loop) </FONT></I>\r
+ LOOP        = TREOp (24); <I><FONT COLOR="Navy">// Node,Min,Max,LoopEntryJmp - back jump for LOOPENTRY. </FONT></I>\r
+                           <I><FONT COLOR="Navy">//      Min and Max are TREBracesArg </FONT></I>\r
+                           <I><FONT COLOR="Navy">//      Node - next node in sequence, </FONT></I>\r
+                           <I><FONT COLOR="Navy">//      LoopEntryJmp - associated LOOPENTRY node addr </FONT></I>\r
+ ANYOFTINYSET= TREOp (25); <I><FONT COLOR="Navy">// Chrs Match any one char from Chrs (exactly TinySetLen chars) </FONT></I>\r
+ ANYBUTTINYSET=TREOp (26); <I><FONT COLOR="Navy">// Chrs Match any one char not in Chrs (exactly TinySetLen chars) </FONT></I>\r
+ ANYOFFULLSET= TREOp (27); <I><FONT COLOR="Navy">// Set  Match any one char from set of char </FONT></I>\r
+                           <I><FONT COLOR="Navy">// - very fast (one CPU instruction !) but takes 32 bytes of p-code </FONT></I>\r
+ BSUBEXP     = TREOp (28); <I><FONT COLOR="Navy">// Idx  Match previously matched subexpression #Idx (stored as REChar) //###0.936 </FONT></I>\r
+ BSUBEXPCI   = TREOp (29); <I><FONT COLOR="Navy">// Idx  -"- in case-insensitive mode </FONT></I>\r
\r
\r
+ <I><FONT COLOR="Navy">// !!! Change OPEN value if you add new opcodes !!! </FONT></I>\r
\r
+ OPEN        = TREOp (30); <I><FONT COLOR="Navy">// -    Mark this point in input as start of /n </FONT></I>\r
+                           <I><FONT COLOR="Navy">//      OPEN + 1 is /1, etc. </FONT></I>\r
+ CLOSE       = TREOp (ord (OPEN) + NSUBEXP); \r
+                           <I><FONT COLOR="Navy">// -    Analogous to OPEN. </FONT></I>\r
\r
+ <I><FONT COLOR="Navy">// !!! Don't add new OpCodes after CLOSE !!! </FONT></I>\r
\r
+<I><FONT COLOR="Navy">// We work with p-code thru pointers, compatible with PRegExprChar. </FONT></I>\r
+<I><FONT COLOR="Navy">// Note: all code components (TRENextOff, TREOp, TREBracesArg, etc) </FONT></I>\r
+<I><FONT COLOR="Navy">// must have lengths that can be divided by SizeOf (REChar) ! </FONT></I>\r
+<I><FONT COLOR="Navy">// A node is TREOp of opcode followed Next "pointer" of TRENextOff type. </FONT></I>\r
+<I><FONT COLOR="Navy">// The Next is a offset from the opcode of the node containing it. </FONT></I>\r
+<I><FONT COLOR="Navy">// An operand, if any, simply follows the node. (Note that much of </FONT></I>\r
+<I><FONT COLOR="Navy">// the code generation knows about this implicit relationship!) </FONT></I>\r
+<I><FONT COLOR="Navy">// Using TRENextOff=integer speed up p-code processing. </FONT></I>\r
\r
+<I><FONT COLOR="Navy">// Opcodes description: </FONT></I>\r
+<I><FONT COLOR="Navy">// </FONT></I>\r
+<I><FONT COLOR="Navy">// BRANCH The set of branches constituting a single choice are hooked </FONT></I>\r
+<I><FONT COLOR="Navy">//      together with their "next" pointers, since precedence prevents </FONT></I>\r
+<I><FONT COLOR="Navy">//      anything being concatenated to any individual branch.  The </FONT></I>\r
+<I><FONT COLOR="Navy">//      "next" pointer of the last BRANCH in a choice points to the </FONT></I>\r
+<I><FONT COLOR="Navy">//      thing following the whole choice.  This is also where the </FONT></I>\r
+<I><FONT COLOR="Navy">//      final "next" pointer of each individual branch points; each </FONT></I>\r
+<I><FONT COLOR="Navy">//      branch starts with the operand node of a BRANCH node. </FONT></I>\r
+<I><FONT COLOR="Navy">// BACK Normal "next" pointers all implicitly point forward; BACK </FONT></I>\r
+<I><FONT COLOR="Navy">//      exists to make loop structures possible. </FONT></I>\r
+<I><FONT COLOR="Navy">// STAR,PLUS,BRACES '?', and complex '*' and '+', are implemented as </FONT></I>\r
+<I><FONT COLOR="Navy">//      circular BRANCH structures using BACK. Complex '{min,max}' </FONT></I>\r
+<I><FONT COLOR="Navy">//      - as pair LOOPENTRY-LOOP (see below). Simple cases (one </FONT></I>\r
+<I><FONT COLOR="Navy">//      character per match) are implemented with STAR, PLUS and </FONT></I>\r
+<I><FONT COLOR="Navy">//      BRACES for speed and to minimize recursive plunges. </FONT></I>\r
+<I><FONT COLOR="Navy">// LOOPENTRY,LOOP {min,max} are implemented as special pair </FONT></I>\r
+<I><FONT COLOR="Navy">//      LOOPENTRY-LOOP. Each LOOPENTRY initialize loopstack for </FONT></I>\r
+<I><FONT COLOR="Navy">//      current level. </FONT></I>\r
+<I><FONT COLOR="Navy">// OPEN,CLOSE are numbered at compile time. </FONT></I>\r
\r
\r
+<I><FONT COLOR="Navy">{=============================================================}</FONT></I> \r
+<I><FONT COLOR="Navy">{================== Error handling section ===================}</FONT></I> \r
+<I><FONT COLOR="Navy">{=============================================================}</FONT></I> \r
\r
+<B>const</B> \r
+ reeOk = 0; \r
+ reeCompNullArgument = 100; \r
+ reeCompRegexpTooBig = 101; \r
+ reeCompParseRegTooManyBrackets = 102; \r
+ reeCompParseRegUnmatchedBrackets = 103; \r
+ reeCompParseRegUnmatchedBrackets2 = 104; \r
+ reeCompParseRegJunkOnEnd = 105; \r
+ reePlusStarOperandCouldBeEmpty = 106; \r
+ reeNestedSQP = 107; \r
+ reeBadHexDigit = 108; \r
+ reeInvalidRange = 109; \r
+ reeParseAtomTrailingBackSlash = 110; \r
+ reeNoHexCodeAfterBSlashX = 111; \r
+ reeHexCodeAfterBSlashXTooBig = 112; \r
+ reeUnmatchedSqBrackets = 113; \r
+ reeInternalUrp = 114; \r
+ reeQPSBFollowsNothing = 115; \r
+ reeTrailingBackSlash = 116; \r
+ reeRarseAtomInternalDisaster = 119; \r
+ reeBRACESArgTooBig = 122; \r
+ reeBracesMinParamGreaterMax = 124; \r
+ reeUnclosedComment = 125; \r
+ reeComplexBracesNotImplemented = 126; \r
+ reeUrecognizedModifier = 127; \r
+ reeRegRepeatCalledInappropriately = 1000; \r
+ reeMatchPrimMemoryCorruption = 1001; \r
+ reeMatchPrimCorruptedPointers = 1002; \r
+ reeNoExpression = 1003; \r
+ reeCorruptedProgram = 1004; \r
+ reeNoInpitStringSpecified = 1005; \r
+ reeOffsetMustBeGreaterThen0 = 1006; \r
+ reeExecNextWithoutExec = 1007; \r
+ reeGetInputStringWithoutInputString = 1008; \r
+ reeDumpCorruptedOpcode = 1011; \r
+ reeExecAfterCompErr = 1012; \r
+ reeModifierUnsupported = 1013; \r
+ reeLoopStackExceeded = 1014; \r
+ reeLoopWithoutEntry = 1015; \r
\r
+<B>function</B> TRegExpr.ErrorMsg (AErrorID : integer) : RegExprString; \r
+ <B>begin</B> \r
+  <B>case</B> AErrorID <B>of</B> \r
+    reeOk: Result := 'No errors'; \r
+    reeCompNullArgument: Result := 'TRegExpr(comp): Null Argument'; \r
+    reeCompRegexpTooBig: Result := 'TRegExpr(comp): Regexp Too Big'; \r
+    reeCompParseRegTooManyBrackets: Result := 'TRegExpr(comp): ParseReg Too Many ()'; \r
+    reeCompParseRegUnmatchedBrackets: Result := 'TRegExpr(comp): ParseReg Unmatched ()'; \r
+    reeCompParseRegUnmatchedBrackets2: Result := 'TRegExpr(comp): ParseReg Unmatched ()'; \r
+    reeCompParseRegJunkOnEnd: Result := 'TRegExpr(comp): ParseReg Junk On End'; \r
+    reePlusStarOperandCouldBeEmpty: Result := 'TRegExpr(comp): *+ Operand Could Be Empty'; \r
+    reeNestedSQP: Result := 'TRegExpr(comp): Nested *?+'; \r
+    reeBadHexDigit: Result := 'TRegExpr(comp): Bad Hex Digit'; \r
+    reeInvalidRange: Result := 'TRegExpr(comp): Invalid [] Range'; \r
+    reeParseAtomTrailingBackSlash: Result := 'TRegExpr(comp): Parse Atom Trailing /'; \r
+    reeNoHexCodeAfterBSlashX: Result := 'TRegExpr(comp): No Hex Code After /x'; \r
+    reeHexCodeAfterBSlashXTooBig: Result := 'TRegExpr(comp): Hex Code After /x Is Too Big'; \r
+    reeUnmatchedSqBrackets: Result := 'TRegExpr(comp): Unmatched []'; \r
+    reeInternalUrp: Result := 'TRegExpr(comp): Internal Urp'; \r
+    reeQPSBFollowsNothing: Result := 'TRegExpr(comp): ?+*{ Follows Nothing'; \r
+    reeTrailingBackSlash: Result := 'TRegExpr(comp): Trailing /'; \r
+    reeRarseAtomInternalDisaster: Result := 'TRegExpr(comp): RarseAtom Internal Disaster'; \r
+    reeBRACESArgTooBig: Result := 'TRegExpr(comp): BRACES Argument Too Big'; \r
+    reeBracesMinParamGreaterMax: Result := 'TRegExpr(comp): BRACE Min Param Greater then Max'; \r
+    reeUnclosedComment: Result := 'TRegExpr(comp): Unclosed (?#Comment)'; \r
+    reeComplexBracesNotImplemented: Result := 'TRegExpr(comp): If you want take part in beta-testing BRACES ''{min,max}'' for complex cases - remove ''.'' from {.$DEFINE ComplexBraces}'; \r
+    reeUrecognizedModifier: Result := 'TRegExpr(comp): Urecognized Modifier'; \r
\r
+    reeRegRepeatCalledInappropriately: Result := 'TRegExpr(exec): RegRepeat Called Inappropriately'; \r
+    reeMatchPrimMemoryCorruption: Result := 'TRegExpr(exec): MatchPrim Memory Corruption'; \r
+    reeMatchPrimCorruptedPointers: Result := 'TRegExpr(exec): MatchPrim Corrupted Pointers'; \r
+    reeNoExpression: Result := 'TRegExpr(exec): Not Assigned Expression Property'; \r
+    reeCorruptedProgram: Result := 'TRegExpr(exec): Corrupted Program'; \r
+    reeNoInpitStringSpecified: Result := 'TRegExpr(exec): No Inpit String Specified'; \r
+    reeOffsetMustBeGreaterThen0: Result := 'TRegExpr(exec): Offset Must Be Greater Then 0'; \r
+    reeExecNextWithoutExec: Result := 'TRegExpr(exec): ExecNext Without Exec[Pos]'; \r
+    reeGetInputStringWithoutInputString: Result := 'TRegExpr(exec): GetInputString Without InputString'; \r
+    reeDumpCorruptedOpcode: Result := 'TRegExpr(dump): Corrupted Opcode'; \r
+    reeExecAfterCompErr: Result := 'TRegExpr(exec): Exec After Compilation Error'; \r
+    reeLoopStackExceeded: Result := 'TRegExpr(exec): Loop Stack Exceeded'; \r
+    reeLoopWithoutEntry: Result := 'TRegExpr(exec): Loop Without LoopEntry !'; \r
+    <B>else</B> Result := 'Unknown error'; \r
+   <B>end</B>; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of procedure TRegExpr.Error \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.LastError : integer; \r
+ <B>begin</B> \r
+  Result := fLastError; \r
+  fLastError := reeOk; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.LastError \r
+--------------------------------------------------------------}</FONT></I> \r
\r
\r
+<I><FONT COLOR="Navy">{=============================================================}</FONT></I> \r
+<I><FONT COLOR="Navy">{===================== Common section ========================}</FONT></I> \r
+<I><FONT COLOR="Navy">{=============================================================}</FONT></I> \r
\r
+<B>constructor</B> TRegExpr.Create; \r
+ <B>begin</B> \r
+  <B>inherited</B>; \r
+  programm := <B>nil</B>; \r
+  fExpression := <B>nil</B>; \r
+  fInputString := <B>nil</B>; \r
\r
+  regexpbeg := <B>nil</B>; \r
+  fExprIsCompiled := false; \r
\r
+  ModifierI := RegExprModifierI; \r
+  ModifierR := RegExprModifierR; \r
+  ModifierS := RegExprModifierS; \r
\r
+  SpaceChars := RegExprSpaceChars; <I><FONT COLOR="Navy">//###0.927 </FONT></I>\r
+  WordChars := RegExprWordChars; <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+  fInvertCase := RegExprInvertCaseFunction; <I><FONT COLOR="Navy">//###0.927 </FONT></I>\r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of constructor TRegExpr.Create \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>destructor</B> TRegExpr.Destroy; \r
+ <B>begin</B> \r
+  <B>if</B> programm <> <B>nil</B> \r
+   <B>then</B> FreeMem (programm); \r
+  <B>if</B> fExpression <> <B>nil</B> \r
+   <B>then</B> FreeMem (fExpression); \r
+  <B>if</B> fInputString <> <B>nil</B> \r
+   <B>then</B> FreeMem (fInputString); \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of destructor TRegExpr.Destroy \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>class</B> <B>function</B> TRegExpr.InvertCaseFunction (<B>const</B> Ch : REChar) : REChar; \r
+ <B>begin</B> \r
+  <I><FONT COLOR="Navy">{$IFDEF UniCode}</FONT></I> \r
+  <B>if</B> Ch >= #128 \r
+   <B>then</B> Result := Ch \r
+  <B>else</B> \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+   <B>begin</B> \r
+    Result := REChar (CharUpper (pointer (Ch))); \r
+    <B>if</B> Result = Ch \r
+     <B>then</B> Result := REChar (CharLower (pointer (Ch))); \r
+   <B>end</B>; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.InvertCaseFunction \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.GetExpression : RegExprString; \r
+ <B>begin</B> \r
+  <B>if</B> fExpression <> <B>nil</B> \r
+   <B>then</B> Result := fExpression \r
+   <B>else</B> Result := ''; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.GetExpression \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>procedure</B> TRegExpr.SetExpression (<B>const</B> s : RegExprString); \r
+ <B>begin</B> \r
+  <B>if</B> (s <> fExpression) <B>or</B> <B>not</B> fExprIsCompiled <B>then</B> <B>begin</B> \r
+    fExprIsCompiled := false; \r
+    <B>if</B> fExpression <> <B>nil</B> <B>then</B> <B>begin</B> \r
+      FreeMem (fExpression); \r
+      fExpression := <B>nil</B>; \r
+     <B>end</B>; \r
+    <B>if</B> s <> '' <B>then</B> <B>begin</B> \r
+      GetMem (fExpression, (length (s) + 1) * SizeOf (REChar)); \r
+      CompileRegExpr (StrPCopy (fExpression, s)); \r
+     <B>end</B>; \r
+   <B>end</B>; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of procedure TRegExpr.SetExpression \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.GetSubExprMatchCount : integer; \r
+ <B>begin</B> \r
+  <B>if</B> Assigned (fInputString) <B>then</B> <B>begin</B> \r
+     Result := NSUBEXP - 1; \r
+     <B>while</B> (Result > 0) <B>and</B> ((startp [Result] = <B>nil</B>) \r
+                             <B>or</B> (endp [Result] = <B>nil</B>)) \r
+      <B>do</B> dec (Result); \r
+    <B>end</B> \r
+   <B>else</B> Result := -1; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.GetSubExprMatchCount \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.GetMatchPos (Idx : integer) : integer; \r
+ <B>begin</B> \r
+  <B>if</B> (Idx >= 0) <B>and</B> (Idx < NSUBEXP) <B>and</B> Assigned (fInputString) \r
+     <B>and</B> Assigned (startp [Idx]) <B>and</B> Assigned (endp [Idx]) <B>then</B> <B>begin</B> \r
+     Result := (startp [Idx] - fInputString) + 1; \r
+    <B>end</B> \r
+   <B>else</B> Result := -1; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.GetMatchPos \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.GetMatchLen (Idx : integer) : integer; \r
+ <B>begin</B> \r
+  <B>if</B> (Idx >= 0) <B>and</B> (Idx < NSUBEXP) <B>and</B> Assigned (fInputString) \r
+     <B>and</B> Assigned (startp [Idx]) <B>and</B> Assigned (endp [Idx]) <B>then</B> <B>begin</B> \r
+     Result := endp [Idx] - startp [Idx]; \r
+    <B>end</B> \r
+   <B>else</B> Result := -1; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.GetMatchLen \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.GetMatch (Idx : integer) : RegExprString; \r
+ <B>begin</B> \r
+  <B>if</B> (Idx >= 0) <B>and</B> (Idx < NSUBEXP) <B>and</B> Assigned (fInputString) \r
+     <B>and</B> Assigned (startp [Idx]) <B>and</B> Assigned (endp [Idx]) \r
+   <I><FONT COLOR="Navy">//then Result := copy (fInputString, MatchPos [Idx], MatchLen [Idx]) //###0.929 </FONT></I>\r
+   <B>then</B> SetString (Result, startp [idx], endp [idx] - startp [idx]) \r
+   <B>else</B> Result := ''; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.GetMatch \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.IsProgrammOk : boolean; \r
+ <B>begin</B> \r
+  Result := false; \r
+  <B>if</B> programm = <B>nil</B> <I><FONT COLOR="Navy">// No compiled r.e. present </FONT></I>\r
+   <B>then</B> Error (reeNoExpression) \r
+  <B>else</B> <B>if</B> programm [0] <> MAGIC <I><FONT COLOR="Navy">// Program corrupted. </FONT></I>\r
+   <B>then</B> Error (reeCorruptedProgram) \r
+  <B>else</B> <B>if</B> <B>not</B> fExprIsCompiled <I><FONT COLOR="Navy">// Previous compilation was finished with error </FONT></I>\r
+   <B>then</B> Error (reeExecAfterCompErr) \r
+  <B>else</B> Result := true; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.IsProgrammOk \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>procedure</B> TRegExpr.CheckCompModifiers; \r
+ <B>begin</B> \r
+  <B>if</B> (programm <> <B>nil</B>) <B>and</B> (fExpression <> <B>nil</B>) \r
+     <B>and</B> (fModifiers <> fProgModifiers) \r
+   <B>then</B> CompileRegExpr (fExpression); \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of TRegExpr.CheckCompModifiers \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.GetModifierStr : RegExprString; \r
+ <B>begin</B> \r
+  Result := '-'; \r
\r
+  <B>if</B> ModifierI \r
+   <B>then</B> Result := 'i' + Result \r
+   <B>else</B> Result := Result + 'i'; \r
+  <B>if</B> ModifierR \r
+   <B>then</B> Result := 'r' + Result \r
+   <B>else</B> Result := Result + 'r'; \r
+  <B>if</B> ModifierS \r
+   <B>then</B> Result := 's' + Result \r
+   <B>else</B> Result := Result + 's'; \r
\r
+  <B>if</B> Result [length (Result)] = '-' <I><FONT COLOR="Navy">// remove '-' if all modifiers are 'On' </FONT></I>\r
+   <B>then</B> System.Delete (Result, length (Result), 1); \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.GetModifierStr \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.SetModifiersInt (<B>const</B> AModifiers : RegExprString; <B>var</B> AModifiersInt : integer) : boolean; \r
+ <B>var</B> \r
+  i : integer; \r
+  IsOn : boolean; \r
+  Mask : integer; \r
+ <B>begin</B> \r
+  Result := true; \r
+  IsOn := true; \r
+  Mask := 0; <I><FONT COLOR="Navy">// strange compiler varning </FONT></I>\r
+  <B>for</B> i := 1 <B>to</B> length (AModifiers) <B>do</B> \r
+   <B>if</B> AModifiers [i] = '-' \r
+    <B>then</B> IsOn := false \r
+    <B>else</B> <B>begin</B> \r
+      <B>if</B> Pos (AModifiers [i], 'iI') > 0 \r
+       <B>then</B> Mask := MaskModI \r
+      <B>else</B> <B>if</B> Pos (AModifiers [i], 'rR') > 0 \r
+       <B>then</B> Mask := MaskModR \r
+      <B>else</B> <B>if</B> Pos (AModifiers [i], 'sS') > 0 \r
+       <B>then</B> Mask := MaskModS \r
+      <B>else</B> <B>begin</B> \r
+        Result := false; \r
+        EXIT; \r
+       <B>end</B>; \r
+      <B>if</B> IsOn \r
+       <B>then</B> AModifiersInt := AModifiersInt <B>or</B> Mask \r
+       <B>else</B> AModifiersInt := AModifiersInt <B>and</B> <B>not</B> Mask; \r
+     <B>end</B>; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.SetModifiersInt \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>procedure</B> TRegExpr.SetModifierStr (<B>const</B> AModifiers : RegExprString); \r
+ <B>begin</B> \r
+  <B>if</B> <B>not</B> SetModifiersInt (AModifiers, fModifiers) \r
+   <B>then</B> Error (reeModifierUnsupported); \r
+  CheckCompModifiers; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of procedure TRegExpr.SetModifierStr \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.GetModifier (AIndex : integer) : boolean; \r
+ <B>var</B> \r
+  Mask : integer; \r
+ <B>begin</B> \r
+  Result := false; \r
+  <B>case</B> AIndex <B>of</B> \r
+    1: Mask := MaskModI; \r
+    2: Mask := MaskModR; \r
+    3: Mask := MaskModS; \r
+    <B>else</B> <B>begin</B> \r
+      Error (reeModifierUnsupported); \r
+      EXIT; \r
+     <B>end</B>; \r
+   <B>end</B>; \r
+  Result := (fModifiers <B>and</B> Mask) = Mask; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.GetModifier \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>procedure</B> TRegExpr.SetModifier (AIndex : integer; ASet : boolean); \r
+ <B>var</B> \r
+  Mask : integer; \r
+ <B>begin</B> \r
+  <B>case</B> AIndex <B>of</B> \r
+    1: Mask := MaskModI; \r
+    2: Mask := MaskModR; \r
+    3: Mask := MaskModS; \r
+    <B>else</B> <B>begin</B> \r
+      Error (reeModifierUnsupported); \r
+      EXIT; \r
+     <B>end</B>; \r
+   <B>end</B>; \r
+  <B>if</B> ASet \r
+   <B>then</B> fModifiers := fModifiers <B>or</B> Mask \r
+   <B>else</B> fModifiers := fModifiers <B>and</B> <B>not</B> Mask; \r
+  CheckCompModifiers; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of procedure TRegExpr.SetModifier \r
+--------------------------------------------------------------}</FONT></I> \r
\r
\r
+<I><FONT COLOR="Navy">{=============================================================}</FONT></I> \r
+<I><FONT COLOR="Navy">{==================== Compiler section =======================}</FONT></I> \r
+<I><FONT COLOR="Navy">{=============================================================}</FONT></I> \r
\r
+<B>procedure</B> TRegExpr.Tail (p : PRegExprChar; val : PRegExprChar); \r
+<I><FONT COLOR="Navy">// set the next-pointer at the end of a node chain </FONT></I>\r
+ <B>var</B> \r
+  scan : PRegExprChar; \r
+  temp : PRegExprChar; \r
+ <B>begin</B> \r
+  <B>if</B> p = @regdummy \r
+   <B>then</B> EXIT; \r
+  <I><FONT COLOR="Navy">// Find last node. </FONT></I>\r
+  scan := p; \r
+  <B>REPEAT</B> \r
+   temp := regnext (scan); \r
+   <B>if</B> temp = <B>nil</B> \r
+    <B>then</B> BREAK; \r
+   scan := temp; \r
+  <B>UNTIL</B> false; \r
+  <I><FONT COLOR="Navy">// Set Next 'pointer' </FONT></I>\r
+  PRENextOff (scan + REOpSz)^ := val - scan; <I><FONT COLOR="Navy">//###0.933 </FONT></I>\r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of procedure TRegExpr.Tail \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>procedure</B> TRegExpr.OpTail (p : PRegExprChar; val : PRegExprChar); \r
+<I><FONT COLOR="Navy">// regtail on operand of first argument; nop if operandless </FONT></I>\r
+ <B>begin</B> \r
+  <I><FONT COLOR="Navy">// "Operandless" and "op != BRANCH" are synonymous in practice. </FONT></I>\r
+  <B>if</B> (p = <B>nil</B>) <B>or</B> (p = @regdummy) <B>or</B> (PREOp (p)^ <> BRANCH) \r
+   <B>then</B> EXIT; \r
+  Tail (p + REOpSz + RENextOffSz, val); <I><FONT COLOR="Navy">//###0.933 </FONT></I>\r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of procedure TRegExpr.OpTail \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.EmitNode (op : TREOp) : PRegExprChar; <I><FONT COLOR="Navy">//###0.933 </FONT></I>\r
+<I><FONT COLOR="Navy">// emit a node, return location </FONT></I>\r
+ <B>begin</B> \r
+  Result := regcode; \r
+  <B>if</B> Result <> @regdummy <B>then</B> <B>begin</B> \r
+     PREOp (regcode)^ := op; \r
+     inc (regcode, REOpSz); \r
+     PRENextOff (regcode)^ := 0; <I><FONT COLOR="Navy">// Next "pointer" := nil </FONT></I>\r
+     inc (regcode, RENextOffSz); \r
+    <B>end</B> \r
+   <B>else</B> inc (regsize, REOpSz + RENextOffSz); <I><FONT COLOR="Navy">// compute code size without code generation </FONT></I>\r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.EmitNode \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>procedure</B> TRegExpr.EmitC (b : REChar); \r
+<I><FONT COLOR="Navy">// emit a byte to code </FONT></I>\r
+ <B>begin</B> \r
+  <B>if</B> regcode <> @regdummy <B>then</B> <B>begin</B> \r
+     regcode^ := b; \r
+     inc (regcode); \r
+    <B>end</B> \r
+   <B>else</B> inc (regsize); <I><FONT COLOR="Navy">// Type of p-code pointer always is ^REChar </FONT></I>\r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of procedure TRegExpr.EmitC \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>procedure</B> TRegExpr.InsertOperator (op : TREOp; opnd : PRegExprChar; sz : integer); \r
+<I><FONT COLOR="Navy">// insert an operator in front of already-emitted operand </FONT></I>\r
+<I><FONT COLOR="Navy">// Means relocating the operand. </FONT></I>\r
+ <B>var</B> \r
+  src, dst, place : PRegExprChar; \r
+  i : integer; \r
+ <B>begin</B> \r
+  <B>if</B> regcode = @regdummy <B>then</B> <B>begin</B> \r
+    inc (regsize, sz); \r
+    EXIT; \r
+   <B>end</B>; \r
+  src := regcode; \r
+  inc (regcode, sz); \r
+  dst := regcode; \r
+  <B>while</B> src > opnd <B>do</B> <B>begin</B> \r
+    dec (dst); \r
+    dec (src); \r
+    dst^ := src^; \r
+   <B>end</B>; \r
+  place := opnd; <I><FONT COLOR="Navy">// Op node, where operand used to be. </FONT></I>\r
+  PREOp (place)^ := op; \r
+  inc (place, REOpSz); \r
+  <B>for</B> i := 1 + REOpSz <B>to</B> sz <B>do</B> <B>begin</B> \r
+    place^ := #0; \r
+    inc (place); \r
+   <B>end</B>; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of procedure TRegExpr.InsertOperator \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> strcspn (s1 : PRegExprChar; s2 : PRegExprChar) : integer; \r
+<I><FONT COLOR="Navy">// find length of initial segment of s1 consisting </FONT></I>\r
+<I><FONT COLOR="Navy">// entirely of characters not from s2 </FONT></I>\r
+ <B>var</B> scan1, scan2 : PRegExprChar; \r
+ <B>begin</B> \r
+  Result := 0; \r
+  scan1 := s1; \r
+  <B>while</B> scan1^ <> #0 <B>do</B> <B>begin</B> \r
+    scan2 := s2; \r
+    <B>while</B> scan2^ <> #0 <B>do</B> \r
+     <B>if</B> scan1^ = scan2^ \r
+      <B>then</B> EXIT \r
+      <B>else</B> inc (scan2); \r
+    inc (Result); \r
+    inc (scan1) \r
+   <B>end</B>; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function strcspn \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>const</B> \r
+<I><FONT COLOR="Navy">// Flags to be passed up and down. </FONT></I>\r
+ HASWIDTH =   01; <I><FONT COLOR="Navy">// Known never to match nil string. </FONT></I>\r
+ SIMPLE   =   02; <I><FONT COLOR="Navy">// Simple enough to be STAR/PLUS/BRACES operand. </FONT></I>\r
+ SPSTART  =   04; <I><FONT COLOR="Navy">// Starts with * or +. </FONT></I>\r
+ WORST    =   0;  <I><FONT COLOR="Navy">// Worst case. </FONT></I>\r
+ META : <B>array</B> [0 .. 12] <B>of</B> REChar = ( \r
+  '^', '$', '.', '[', '(', ')', '|', '?', '+', '*', '/', '{', #0); \r
+ <I><FONT COLOR="Navy">// Any modification must be synchronized with QuoteRegExprMetaChars !!! </FONT></I>\r
\r
+<I><FONT COLOR="Navy">{$IFDEF UniCode}</FONT></I> \r
+ RusRangeLo : <B>array</B> [0 .. 33] <B>of</B> REChar = \r
+  (#$430,#$431,#$432,#$433,#$434,#$435,#$451,#$436,#$437, \r
+   #$438,#$439,#$43A,#$43B,#$43C,#$43D,#$43E,#$43F, \r
+   #$440,#$441,#$442,#$443,#$444,#$445,#$446,#$447, \r
+   #$448,#$449,#$44A,#$44B,#$44C,#$44D,#$44E,#$44F,#0); \r
+ RusRangeHi : <B>array</B> [0 .. 33] <B>of</B> REChar = \r
+  (#$410,#$411,#$412,#$413,#$414,#$415,#$401,#$416,#$417, \r
+   #$418,#$419,#$41A,#$41B,#$41C,#$41D,#$41E,#$41F, \r
+   #$420,#$421,#$422,#$423,#$424,#$425,#$426,#$427, \r
+   #$428,#$429,#$42A,#$42B,#$42C,#$42D,#$42E,#$42F,#0); \r
+ RusRangeLoLow = #$430<I><FONT COLOR="Navy">{'à'}</FONT></I>; \r
+ RusRangeLoHigh = #$44F<I><FONT COLOR="Navy">{'ÿ'}</FONT></I>; \r
+ RusRangeHiLow = #$410<I><FONT COLOR="Navy">{'À'}</FONT></I>; \r
+ RusRangeHiHigh = #$42F<I><FONT COLOR="Navy">{'ß'}</FONT></I>; \r
+<I><FONT COLOR="Navy">{$ELSE}</FONT></I> \r
+ RusRangeLo = 'àáâãäå¸æçèéêëìíîïðñòóôõö÷øùúûüýþÿ'; \r
+ RusRangeHi = 'ÀÁÂÃÄŨÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß'; \r
+ RusRangeLoLow = 'à'; \r
+ RusRangeLoHigh = 'ÿ'; \r
+ RusRangeHiLow = 'À'; \r
+ RusRangeHiHigh = 'ß'; \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<B>function</B> TRegExpr.CompileRegExpr (exp : PRegExprChar) : boolean; \r
+<I><FONT COLOR="Navy">// compile a regular expression into internal code </FONT></I>\r
+<I><FONT COLOR="Navy">// We can't allocate space until we know how big the compiled form will be, </FONT></I>\r
+<I><FONT COLOR="Navy">// but we can't compile it (and thus know how big it is) until we've got a </FONT></I>\r
+<I><FONT COLOR="Navy">// place to put the code.  So we cheat:  we compile it twice, once with code </FONT></I>\r
+<I><FONT COLOR="Navy">// generation turned off and size counting turned on, and once "for real". </FONT></I>\r
+<I><FONT COLOR="Navy">// This also means that we don't allocate space until we are sure that the </FONT></I>\r
+<I><FONT COLOR="Navy">// thing really will compile successfully, and we never have to move the </FONT></I>\r
+<I><FONT COLOR="Navy">// code and thus invalidate pointers into it.  (Note that it has to be in </FONT></I>\r
+<I><FONT COLOR="Navy">// one piece because free() must be able to free it all.) </FONT></I>\r
+<I><FONT COLOR="Navy">// Beware that the optimization-preparation code in here knows about some </FONT></I>\r
+<I><FONT COLOR="Navy">// of the structure of the compiled regexp. </FONT></I>\r
+ <B>var</B> \r
+  scan, longest : PRegExprChar; \r
+  len : cardinal; \r
+  flags : integer; \r
+ <B>begin</B> \r
+  Result := false; <I><FONT COLOR="Navy">// life too dark </FONT></I>\r
+  fExprIsCompiled := false; \r
\r
+  regparse := <B>nil</B>; <I><FONT COLOR="Navy">// for correct error handling </FONT></I>\r
+  regexpbeg := exp; \r
+  <B>try</B> <I><FONT COLOR="Navy">// must clear regexpbeg after compilation </FONT></I>\r
\r
+  <B>if</B> programm <> <B>nil</B> <B>then</B> <B>begin</B> \r
+    FreeMem (programm); \r
+    programm := <B>nil</B>; \r
+   <B>end</B>; \r
\r
+  <B>if</B> exp = <B>nil</B> <B>then</B> <B>begin</B> \r
+    Error (reeCompNullArgument); \r
+    EXIT; \r
+   <B>end</B>; \r
\r
+  fProgModifiers := fModifiers; \r
+  <I><FONT COLOR="Navy">// well, may it's paranoia. I'll check it later... !!!!!!!! </FONT></I>\r
\r
+  <I><FONT COLOR="Navy">// First pass: determine size, legality. </FONT></I>\r
+  fCompModifiers := fModifiers; \r
+  regparse := exp; \r
+  regnpar := 1; \r
+  regsize := 0; \r
+  regcode := @regdummy; \r
+  EmitC (MAGIC); \r
+  <B>if</B> ParseReg (0, flags) = <B>nil</B> \r
+   <B>then</B> EXIT; \r
\r
+  <I><FONT COLOR="Navy">// Small enough for 2-bytes programm pointers ? </FONT></I>\r
+  <I><FONT COLOR="Navy">// ###0.933 no real p-code length limits now :))) </FONT></I>\r
+<I><FONT COLOR="Navy">//  if regsize >= 64 * 1024 then begin </FONT></I>\r
+<I><FONT COLOR="Navy">//    Error (reeCompRegexpTooBig); </FONT></I>\r
+<I><FONT COLOR="Navy">//    EXIT; </FONT></I>\r
+<I><FONT COLOR="Navy">//   end; </FONT></I>\r
\r
+  <I><FONT COLOR="Navy">// Allocate space. </FONT></I>\r
+  GetMem (programm, regsize * SizeOf (REChar)); \r
\r
+  <I><FONT COLOR="Navy">// Second pass: emit code. </FONT></I>\r
+  fCompModifiers := fModifiers; \r
+  regparse := exp; \r
+  regnpar := 1; \r
+  regcode := programm; \r
+  EmitC (MAGIC); \r
+  <B>if</B> ParseReg (0, flags) = <B>nil</B> \r
+   <B>then</B> EXIT; \r
\r
+  <I><FONT COLOR="Navy">// Dig out information for optimizations. </FONT></I>\r
+  <I><FONT COLOR="Navy">{$IFDEF UseFirstCharSet}</FONT></I> <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+  FirstCharSet := []; \r
+  FillFirstCharSet (programm + REOpSz); \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+  regstart := #0; <I><FONT COLOR="Navy">// Worst-case defaults. </FONT></I>\r
+  reganch := #0; \r
+  regmust := <B>nil</B>; \r
+  regmlen := 0; \r
+  scan := programm + REOpSz; <I><FONT COLOR="Navy">// First BRANCH. </FONT></I>\r
+  <B>if</B> PREOp (regnext (scan))^ = EEND <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Only one top-level choice. </FONT></I>\r
+    scan := scan + REOpSz + RENextOffSz; \r
\r
+    <I><FONT COLOR="Navy">// Starting-point info. </FONT></I>\r
+    <B>if</B> PREOp (scan)^ = EXACTLY \r
+     <B>then</B> regstart := (scan + REOpSz + RENextOffSz)^ \r
+     <B>else</B> <B>if</B> PREOp (scan)^ = BOL \r
+           <B>then</B> inc (reganch); \r
\r
+    <I><FONT COLOR="Navy">// If there's something expensive in the r.e., find the longest </FONT></I>\r
+    <I><FONT COLOR="Navy">// literal string that must appear and make it the regmust.  Resolve </FONT></I>\r
+    <I><FONT COLOR="Navy">// ties in favor of later strings, since the regstart check works </FONT></I>\r
+    <I><FONT COLOR="Navy">// with the beginning of the r.e. and avoiding duplication </FONT></I>\r
+    <I><FONT COLOR="Navy">// strengthens checking.  Not a strong reason, but sufficient in the </FONT></I>\r
+    <I><FONT COLOR="Navy">// absence of others. </FONT></I>\r
+    <B>if</B> (flags <B>and</B> SPSTART) <> 0 <B>then</B> <B>begin</B> \r
+        longest := <B>nil</B>; \r
+        len := 0; \r
+        <B>while</B> scan <> <B>nil</B> <B>do</B> <B>begin</B> \r
+          <B>if</B> (PREOp (scan)^ = EXACTLY) \r
+             <B>and</B> (strlen (scan + REOpSz + RENextOffSz) >= len) <B>then</B> <B>begin</B> \r
+              longest := scan + REOpSz + RENextOffSz; \r
+              len := strlen (longest); \r
+           <B>end</B>; \r
+          scan := regnext (scan); \r
+         <B>end</B>; \r
+        regmust := longest; \r
+        regmlen := len; \r
+     <B>end</B>; \r
+   <B>end</B>; \r
\r
+  <B>finally</B> regexpbeg := <B>nil</B>; \r
+  <B>end</B>; \r
\r
+  fExprIsCompiled := true; \r
+  Result := true; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.CompileRegExpr \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.ParseReg (paren : integer; <B>var</B> flagp : integer) : PRegExprChar; \r
+<I><FONT COLOR="Navy">// regular expression, i.e. main body or parenthesized thing </FONT></I>\r
+<I><FONT COLOR="Navy">// Caller must absorb opening parenthesis. </FONT></I>\r
+<I><FONT COLOR="Navy">// Combining parenthesis handling with the base level of regular expression </FONT></I>\r
+<I><FONT COLOR="Navy">// is a trifle forced, but the need to tie the tails of the branches to what </FONT></I>\r
+<I><FONT COLOR="Navy">// follows makes it hard to avoid. </FONT></I>\r
+ <B>var</B> \r
+  ret, br, ender : PRegExprChar; \r
+  parno : integer; \r
+  flags : integer; \r
+  SavedModifiers : integer; \r
+ <B>begin</B> \r
+  Result := <B>nil</B>; \r
+  flagp := HASWIDTH; <I><FONT COLOR="Navy">// Tentatively. </FONT></I>\r
+  parno := 0; <I><FONT COLOR="Navy">// eliminate compiler stupid warning </FONT></I>\r
+  SavedModifiers := fCompModifiers; \r
\r
+  <I><FONT COLOR="Navy">// Make an OPEN node, if parenthesized. </FONT></I>\r
+  <B>if</B> paren <> 0 <B>then</B> <B>begin</B> \r
+      <B>if</B> regnpar >= NSUBEXP <B>then</B> <B>begin</B> \r
+        Error (reeCompParseRegTooManyBrackets); \r
+        EXIT; \r
+       <B>end</B>; \r
+      parno := regnpar; \r
+      inc (regnpar); \r
+      ret := EmitNode (TREOp (ord (OPEN) + parno)); \r
+    <B>end</B> \r
+   <B>else</B> ret := <B>nil</B>; \r
\r
+  <I><FONT COLOR="Navy">// Pick up the branches, linking them together. </FONT></I>\r
+  br := ParseBranch (flags); \r
+  <B>if</B> br = <B>nil</B> <B>then</B> <B>begin</B> \r
+    Result := <B>nil</B>; \r
+    EXIT; \r
+   <B>end</B>; \r
+  <B>if</B> ret <> <B>nil</B> \r
+   <B>then</B> Tail (ret, br) <I><FONT COLOR="Navy">// OPEN -> first. </FONT></I>\r
+   <B>else</B> ret := br; \r
+  <B>if</B> (flags <B>and</B> HASWIDTH) = 0 \r
+   <B>then</B> flagp := flagp <B>and</B> <B>not</B> HASWIDTH; \r
+  flagp := flagp <B>or</B> flags <B>and</B> SPSTART; \r
+  <B>while</B> (regparse^ = '|') <B>do</B> <B>begin</B> \r
+    inc (regparse); \r
+    br := ParseBranch (flags); \r
+    <B>if</B> br = <B>nil</B> <B>then</B> <B>begin</B> \r
+       Result := <B>nil</B>; \r
+       EXIT; \r
+      <B>end</B>; \r
+    Tail (ret, br); <I><FONT COLOR="Navy">// BRANCH -> BRANCH. </FONT></I>\r
+    <B>if</B> (flags <B>and</B> HASWIDTH) = 0 \r
+     <B>then</B> flagp := flagp <B>and</B> <B>not</B> HASWIDTH; \r
+    flagp := flagp <B>or</B> flags <B>and</B> SPSTART; \r
+   <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">// Make a closing node, and hook it on the end. </FONT></I>\r
+  <B>if</B> paren <> 0 \r
+   <B>then</B> ender := EmitNode (TREOp (ord (CLOSE) + parno)) \r
+   <B>else</B> ender := EmitNode (EEND); \r
+  Tail (ret, ender); \r
\r
+  <I><FONT COLOR="Navy">// Hook the tails of the branches to the closing node. </FONT></I>\r
+  br := ret; \r
+  <B>while</B> br <> <B>nil</B> <B>do</B> <B>begin</B> \r
+    OpTail (br, ender); \r
+    br := regnext (br); \r
+   <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">// Check for proper termination. </FONT></I>\r
+  <B>if</B> paren <> 0 <B>then</B> \r
+   <B>if</B> regparse^ <> ')' <B>then</B> <B>begin</B> \r
+      Error (reeCompParseRegUnmatchedBrackets); \r
+      EXIT; \r
+     <B>end</B> \r
+    <B>else</B> inc (regparse); <I><FONT COLOR="Navy">// skip trailing ')' </FONT></I>\r
+  <B>if</B> (paren = 0) <B>and</B> (regparse^ <> #0) <B>then</B> <B>begin</B> \r
+      <B>if</B> regparse^ = ')' \r
+       <B>then</B> Error (reeCompParseRegUnmatchedBrackets2) \r
+       <B>else</B> Error (reeCompParseRegJunkOnEnd); \r
+      EXIT; \r
+    <B>end</B>; \r
+  fCompModifiers := SavedModifiers; <I><FONT COLOR="Navy">// restore modifiers of parent </FONT></I>\r
+  Result := ret; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.ParseReg \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.ParseBranch (<B>var</B> flagp : integer) : PRegExprChar; \r
+<I><FONT COLOR="Navy">// one alternative of an | operator </FONT></I>\r
+<I><FONT COLOR="Navy">// Implements the concatenation operator. </FONT></I>\r
+ <B>var</B> \r
+  ret, chain, latest : PRegExprChar; \r
+  flags : integer; \r
+ <B>begin</B> \r
+  flagp := WORST; <I><FONT COLOR="Navy">// Tentatively. </FONT></I>\r
\r
+  ret := EmitNode (BRANCH); \r
+  chain := <B>nil</B>; \r
+  <B>while</B> (regparse^ <> #0) <B>and</B> (regparse^ <> '|') \r
+        <B>and</B> (regparse^ <> ')') <B>do</B> <B>begin</B> \r
+    latest := ParsePiece (flags); \r
+    <B>if</B> latest = <B>nil</B> <B>then</B> <B>begin</B> \r
+      Result := <B>nil</B>; \r
+      EXIT; \r
+     <B>end</B>; \r
+    flagp := flagp <B>or</B> flags <B>and</B> HASWIDTH; \r
+    <B>if</B> chain = <B>nil</B> <I><FONT COLOR="Navy">// First piece. </FONT></I>\r
+     <B>then</B> flagp := flagp <B>or</B> flags <B>and</B> SPSTART \r
+     <B>else</B> Tail (chain, latest); \r
+    chain := latest; \r
+   <B>end</B>; \r
+  <B>if</B> chain = <B>nil</B> <I><FONT COLOR="Navy">// Loop ran zero times. </FONT></I>\r
+   <B>then</B> EmitNode (NOTHING); \r
+  Result := ret; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.ParseBranch \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.ParsePiece (<B>var</B> flagp : integer) : PRegExprChar; \r
+<I><FONT COLOR="Navy">// something followed by possible [*+?{] </FONT></I>\r
+<I><FONT COLOR="Navy">// Note that the branching code sequences used for ? and the general cases </FONT></I>\r
+<I><FONT COLOR="Navy">// of * and + and { are somewhat optimized:  they use the same NOTHING node as </FONT></I>\r
+<I><FONT COLOR="Navy">// both the endmarker for their branch list and the body of the last branch. </FONT></I>\r
+<I><FONT COLOR="Navy">// It might seem that this node could be dispensed with entirely, but the </FONT></I>\r
+<I><FONT COLOR="Navy">// endmarker role is not redundant. </FONT></I>\r
+ <B>function</B> parsenum (AStart, AEnd : PRegExprChar) : TREBracesArg; \r
+  <B>begin</B> \r
+   Result := 0; \r
+   <B>if</B> AEnd - AStart + 1 > 8 <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// prevent stupid scanning </FONT></I>\r
+     Error (reeBRACESArgTooBig); \r
+     EXIT; \r
+    <B>end</B>; \r
+   <B>while</B> AStart <= AEnd <B>do</B> <B>begin</B> \r
+       Result := Result * 10 + (ord (AStart^) - ord ('0')); \r
+       inc (AStart); \r
+      <B>end</B>; \r
+   <B>if</B> (Result > MaxBracesArg) <B>or</B> (Result < 0) <B>then</B> <B>begin</B> \r
+     Error (reeBRACESArgTooBig); \r
+     EXIT; \r
+    <B>end</B>; \r
+  <B>end</B>; \r
+ <B>var</B> \r
+  op : REChar; \r
+  NextNode : PRegExprChar; \r
+  flags : integer; \r
+  BracesMin, Bracesmax : TREBracesArg; \r
+  p, savedparse : PRegExprChar; \r
+  <I><FONT COLOR="Navy">{$IFDEF ComplexBraces}</FONT></I> \r
+  off : integer; \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+ <B>begin</B> \r
+  Result := ParseAtom (flags); \r
+  <B>if</B> Result = <B>nil</B> \r
+   <B>then</B> EXIT; \r
\r
+  op := regparse^; \r
+  <B>if</B> <B>not</B> ((op = '*') <B>or</B> (op = '+') <B>or</B> (op = '?') <B>or</B> (op = '{')) <B>then</B> <B>begin</B> \r
+    flagp := flags; \r
+    EXIT; \r
+   <B>end</B>; \r
+  <B>if</B> ((flags <B>and</B> HASWIDTH) = 0) <B>and</B> (op <> '?') <B>then</B> <B>begin</B> \r
+    Error (reePlusStarOperandCouldBeEmpty); \r
+    EXIT; \r
+   <B>end</B>; \r
\r
+  <B>case</B> op <B>of</B> \r
+    '*': <B>begin</B> \r
+      flagp := WORST <B>or</B> SPSTART; \r
+      <B>if</B> (flags <B>and</B> SIMPLE) = 0 <B>then</B> <B>begin</B> \r
+         <I><FONT COLOR="Navy">// Emit x* as (x&|), where & means "self". </FONT></I>\r
+         InsertOperator (BRANCH, Result, REOpSz + RENextOffSz); <I><FONT COLOR="Navy">// Either x </FONT></I>\r
+         OpTail (Result, EmitNode (BACK)); <I><FONT COLOR="Navy">// and loop </FONT></I>\r
+         OpTail (Result, Result); <I><FONT COLOR="Navy">// back </FONT></I>\r
+         Tail (Result, EmitNode (BRANCH)); <I><FONT COLOR="Navy">// or </FONT></I>\r
+         Tail (Result, EmitNode (NOTHING)); <I><FONT COLOR="Navy">// nil. </FONT></I>\r
+        <B>end</B> \r
+       <B>else</B> InsertOperator (STAR, Result, REOpSz + RENextOffSz); \r
+     <B>end</B>; <I><FONT COLOR="Navy">{ of case '*'}</FONT></I> \r
+    '+': <B>begin</B> \r
+      flagp := WORST <B>or</B> SPSTART <B>or</B> HASWIDTH; \r
+      <B>if</B> (flags <B>and</B> SIMPLE) = 0 <B>then</B> <B>begin</B> \r
+         <I><FONT COLOR="Navy">// Emit x+ as x(&|), where & means "self". </FONT></I>\r
+         NextNode := EmitNode (BRANCH); <I><FONT COLOR="Navy">// Either </FONT></I>\r
+         Tail (Result, NextNode); \r
+         Tail (EmitNode (BACK), Result);    <I><FONT COLOR="Navy">// loop back </FONT></I>\r
+         Tail (NextNode, EmitNode (BRANCH)); <I><FONT COLOR="Navy">// or </FONT></I>\r
+         Tail (Result, EmitNode (NOTHING)); <I><FONT COLOR="Navy">// nil. </FONT></I>\r
+        <B>end</B> \r
+       <B>else</B> InsertOperator (PLUS, Result, REOpSz + RENextOffSz); \r
+     <B>end</B>; <I><FONT COLOR="Navy">{ of case '+'}</FONT></I> \r
+    '?': <B>begin</B> \r
+      flagp := WORST; \r
+      <I><FONT COLOR="Navy">// Emit x? as (x|) </FONT></I>\r
+      InsertOperator (BRANCH, Result, REOpSz + RENextOffSz); <I><FONT COLOR="Navy">// Either x </FONT></I>\r
+      Tail (Result, EmitNode (BRANCH));  <I><FONT COLOR="Navy">// or </FONT></I>\r
+      NextNode := EmitNode (NOTHING); <I><FONT COLOR="Navy">// nil. </FONT></I>\r
+      Tail (Result, NextNode); \r
+      OpTail (Result, NextNode); \r
+     <B>end</B>; <I><FONT COLOR="Navy">{ of case '?'}</FONT></I> \r
+   '{': <B>begin</B> \r
+      savedparse := regparse; \r
+      inc (regparse); \r
+      p := regparse; \r
+      <B>while</B> Pos (regparse^, '0123456789') > 0  <I><FONT COLOR="Navy">// <min> MUST appear </FONT></I>\r
+       <B>do</B> inc (regparse); \r
+      <B>if</B> (regparse^ <> '}') <B>and</B> (regparse^ <> ',') <B>or</B> (p = regparse) <B>then</B> <B>begin</B> \r
+        regparse := savedparse; \r
+        flagp := flags; \r
+        EXIT; \r
+       <B>end</B>; \r
+      BracesMin := parsenum (p, regparse - 1); \r
+      <B>if</B> regparse^ = ',' <B>then</B> <B>begin</B> \r
+         inc (regparse); \r
+         p := regparse; \r
+         <B>while</B> Pos (regparse^, '0123456789') > 0 \r
+          <B>do</B> inc (regparse); \r
+         <B>if</B> regparse^ <> '}' <B>then</B> <B>begin</B> \r
+           regparse := savedparse; \r
+           EXIT; \r
+          <B>end</B>; \r
+         <B>if</B> p = regparse \r
+          <B>then</B> BracesMax := MaxBracesArg \r
+          <B>else</B> BracesMax := parsenum (p, regparse - 1); \r
+        <B>end</B> \r
+       <B>else</B> BracesMax := BracesMin; <I><FONT COLOR="Navy">// {n} == {n,n} </FONT></I>\r
+      <B>if</B> BracesMin > BracesMax <B>then</B> <B>begin</B> \r
+        Error (reeBracesMinParamGreaterMax); \r
+        EXIT; \r
+       <B>end</B>; \r
+      <B>if</B> BracesMin > 0 \r
+       <B>then</B> flagp := WORST; \r
+      <B>if</B> BracesMax > 0 \r
+       <B>then</B> flagp := flagp <B>or</B> HASWIDTH <B>or</B> SPSTART; \r
+      <B>if</B> (flags <B>and</B> SIMPLE) <> 0 <B>then</B> <B>begin</B> \r
+         InsertOperator (BRACES, Result, REOpSz + RENextOffSz + REBracesArgSz * 2); \r
+         <B>if</B> regcode <> @regdummy <B>then</B> <B>begin</B> \r
+           PREBracesArg (Result + REOpSz + RENextOffSz)^ := BracesMin; \r
+           PREBracesArg (Result + REOpSz + RENextOffSz + REBracesArgSz)^ := BracesMax; \r
+          <B>end</B>; \r
+        <B>end</B> \r
+       <B>else</B> <B>begin</B> <I><FONT COLOR="Navy">// Emit complex x{min,max} </FONT></I>\r
+         <I><FONT COLOR="Navy">{$IFNDEF ComplexBraces}</FONT></I> \r
+         Error (reeComplexBracesNotImplemented); \r
+         EXIT; \r
+         <I><FONT COLOR="Navy">{$ELSE}</FONT></I> \r
+         InsertOperator (LOOPENTRY, Result, REOpSz + RENextOffSz); \r
+         NextNode := EmitNode (LOOP); \r
+         <B>if</B> regcode <> @regdummy <B>then</B> <B>begin</B> \r
+            off := (Result + REOpSz + RENextOffSz) \r
+             - (regcode - REOpSz - RENextOffSz); <I><FONT COLOR="Navy">// back to Atom after LOOPENTRY </FONT></I>\r
+            PREBracesArg (regcode)^ := BracesMin; \r
+            inc (regcode, REBracesArgSz); \r
+            PREBracesArg (regcode)^ := BracesMax; \r
+            inc (regcode, REBracesArgSz); \r
+            PRENextOff (regcode)^ := off; \r
+            inc (regcode, RENextOffSz); \r
+           <B>end</B> \r
+          <B>else</B> inc (regsize, REBracesArgSz * 2 + RENextOffSz); \r
+         Tail (Result, NextNode); <I><FONT COLOR="Navy">// LOOPENTRY -> LOOP </FONT></I>\r
+         <B>if</B> regcode <> @regdummy <B>then</B> \r
+          Tail (Result + REOpSz + RENextOffSz, NextNode); <I><FONT COLOR="Navy">// Atom -> LOOP </FONT></I>\r
+         <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+        <B>end</B>; \r
+     <B>end</B>; <I><FONT COLOR="Navy">{ of case '{'}</FONT></I> \r
+<I><FONT COLOR="Navy">//    else // here we can't be </FONT></I>\r
+   <B>end</B>; <I><FONT COLOR="Navy">{ of case op}</FONT></I> \r
\r
+  inc (regparse); \r
+  <B>if</B> (regparse^ = '*') <B>or</B> (regparse^ = '+') <B>or</B> (regparse^ = '?') <B>or</B> (regparse^ = '{') <B>then</B> <B>begin</B> \r
+    Error (reeNestedSQP); \r
+    EXIT; \r
+   <B>end</B>; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.ParsePiece \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.ParseAtom (<B>var</B> flagp : integer) : PRegExprChar; \r
+<I><FONT COLOR="Navy">// the lowest level </FONT></I>\r
+<I><FONT COLOR="Navy">// Optimization:  gobbles an entire sequence of ordinary characters so that </FONT></I>\r
+<I><FONT COLOR="Navy">// it can turn them into a single node, which is smaller to store and </FONT></I>\r
+<I><FONT COLOR="Navy">// faster to run.  Backslashed characters are exceptions, each becoming a </FONT></I>\r
+<I><FONT COLOR="Navy">// separate node; the code is simpler that way and it's not worth fixing. </FONT></I>\r
+ <B>var</B> \r
+  ret : PRegExprChar; \r
+  flags : integer; \r
+  RangeBeg, RangeEnd : REChar; \r
+  CanBeRange : boolean; \r
+  len : integer; \r
+  ender : REChar; \r
+  begmodfs : PRegExprChar; \r
\r
+  <I><FONT COLOR="Navy">{$IFDEF UseSetOfChar}</FONT></I> <I><FONT COLOR="Navy">//###0.930 </FONT></I>\r
+  RangePCodeBeg : PRegExprChar; \r
+  RangePCodeIdx : integer; \r
+  RangeIsCI : boolean; \r
+  RangeSet : TSetOfREChar; \r
+  RangeLen : integer; \r
+  RangeChMin, RangeChMax : REChar; \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+ <B>procedure</B> EmitExactly (ch : REChar); \r
+  <B>begin</B> \r
+   <B>if</B> (fCompModifiers <B>and</B> MaskModI) = MaskModI \r
+    <B>then</B> ret := EmitNode (EXACTLYCI) \r
+    <B>else</B> ret := EmitNode (EXACTLY); \r
+   EmitC (ch); \r
+   EmitC (#0); \r
+   flagp := flagp <B>or</B> HASWIDTH <B>or</B> SIMPLE; \r
+  <B>end</B>; \r
\r
+ <B>procedure</B> EmitStr (<B>const</B> s : RegExprString); \r
+  <B>var</B> i : integer; \r
+  <B>begin</B> \r
+   <B>for</B> i := 1 <B>to</B> length (s) \r
+    <B>do</B> EmitC (s [i]); \r
+  <B>end</B>; \r
\r
+ <B>function</B> HexDig (ch : REChar) : integer; \r
+  <B>begin</B> \r
+   Result := 0; \r
+   <B>if</B> (ch >= 'a') <B>and</B> (ch <= 'f') \r
+    <B>then</B> ch := REChar (ord (ch) - (ord ('a') - ord ('A'))); \r
+   <B>if</B> (ch < '0') <B>or</B> (ch > 'F') <B>or</B> ((ch > '9') <B>and</B> (ch < 'A')) <B>then</B> <B>begin</B> \r
+     Error (reeBadHexDigit); \r
+     EXIT; \r
+    <B>end</B>; \r
+   Result := ord (ch) - ord ('0'); \r
+   <B>if</B> ch >= 'A' \r
+    <B>then</B> Result := Result - (ord ('A') - ord ('9') - 1); \r
+  <B>end</B>; \r
\r
+ <B>function</B> EmitRange (AOpCode : REChar) : PRegExprChar; \r
+  <B>begin</B> \r
+   <I><FONT COLOR="Navy">{$IFDEF UseSetOfChar}</FONT></I> \r
+   <B>case</B> AOpCode <B>of</B> \r
+     ANYBUTCI, ANYBUT: \r
+       Result := EmitNode (ANYBUTTINYSET); \r
+     <B>else</B> <I><FONT COLOR="Navy">// ANYOFCI, ANYOF </FONT></I>\r
+       Result := EmitNode (ANYOFTINYSET); \r
+    <B>end</B>; \r
+   <B>case</B> AOpCode <B>of</B> \r
+     ANYBUTCI, ANYOFCI: \r
+       RangeIsCI := True; \r
+     <B>else</B> <I><FONT COLOR="Navy">// ANYBUT, ANYOF </FONT></I>\r
+       RangeIsCI := False; \r
+    <B>end</B>; \r
+   RangePCodeBeg := regcode; \r
+   RangePCodeIdx := regsize; \r
+   RangeLen := 0; \r
+   RangeSet := []; \r
+   RangeChMin := #255; \r
+   RangeChMax := #0; \r
+   <I><FONT COLOR="Navy">{$ELSE}</FONT></I> \r
+   Result := EmitNode (AOpCode); \r
+   <I><FONT COLOR="Navy">// ToDo: </FONT></I>\r
+   <I><FONT COLOR="Navy">// !!!!!!!!!!!!! Implement ANYOF[BUT]TINYSET generation for UniCode !!!!!!!!!! </FONT></I>\r
+   <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+  <B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{$IFDEF UseSetOfChar}</FONT></I> \r
+ <B>procedure</B> EmitRangeCPrim (b : REChar); <I><FONT COLOR="Navy">//###0.930 </FONT></I>\r
+  <B>begin</B> \r
+   <B>if</B> b <B>in</B> RangeSet \r
+    <B>then</B> EXIT; \r
+   inc (RangeLen); \r
+   <B>if</B> b < RangeChMin \r
+    <B>then</B> RangeChMin := b; \r
+   <B>if</B> b > RangeChMax \r
+    <B>then</B> RangeChMax := b; \r
+   Include (RangeSet, b); \r
+  <B>end</B>; \r
+ <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+ <B>procedure</B> EmitRangeC (b : REChar); \r
+  <I><FONT COLOR="Navy">{$IFDEF UseSetOfChar}</FONT></I> \r
+  <B>var</B> \r
+   Ch : REChar; \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+  <B>begin</B> \r
+   CanBeRange := false; \r
+   <I><FONT COLOR="Navy">{$IFDEF UseSetOfChar}</FONT></I> \r
+    <B>if</B> b <> #0 <B>then</B> <B>begin</B> \r
+       EmitRangeCPrim (b); <I><FONT COLOR="Navy">//###0.930 </FONT></I>\r
+       <B>if</B> RangeIsCI \r
+        <B>then</B> EmitRangeCPrim (InvertCase (b)); <I><FONT COLOR="Navy">//###0.930 </FONT></I>\r
+      <B>end</B> \r
+     <B>else</B> <B>begin</B> \r
+       Assert (RangeLen > 0, 'TRegExpr.ParseAtom(subroutine EmitRangeC): empty range'); <I><FONT COLOR="Navy">// impossible, but who knows.. </FONT></I>\r
+       Assert (RangeChMin <= RangeChMax, 'TRegExpr.ParseAtom(subroutine EmitRangeC): RangeChMin > RangeChMax'); <I><FONT COLOR="Navy">// impossible, but who knows.. </FONT></I>\r
+       <B>if</B> RangeLen <= TinySetLen <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// emit "tiny set" </FONT></I>\r
+          <B>if</B> regcode = @regdummy <B>then</B> <B>begin</B> \r
+            regsize := RangePCodeIdx + TinySetLen; <I><FONT COLOR="Navy">// RangeChMin/Max !!! </FONT></I>\r
+            EXIT; \r
+           <B>end</B>; \r
+          regcode := RangePCodeBeg; \r
+          <B>for</B> Ch := RangeChMin <B>to</B> RangeChMax <B>do</B> <I><FONT COLOR="Navy">//###0.930 </FONT></I>\r
+           <B>if</B> Ch <B>in</B> RangeSet <B>then</B> <B>begin</B> \r
+             regcode^ := Ch; \r
+             inc (regcode); \r
+            <B>end</B>; \r
+          <I><FONT COLOR="Navy">// fill rest: </FONT></I>\r
+          <B>while</B> regcode < RangePCodeBeg + TinySetLen <B>do</B> <B>begin</B> \r
+            regcode^ := RangeChMax; \r
+            inc (regcode); \r
+           <B>end</B>; \r
+         <B>end</B> \r
+        <B>else</B> <B>begin</B> \r
+          <B>if</B> regcode = @regdummy <B>then</B> <B>begin</B> \r
+            regsize := RangePCodeIdx + SizeOf (TSetOfREChar); \r
+            EXIT; \r
+           <B>end</B>; \r
+          <B>if</B> (RangePCodeBeg - REOpSz - RENextOffSz)^ = ANYBUTTINYSET \r
+           <B>then</B> RangeSet := [#0 .. #255] - RangeSet; \r
+          PREOp (RangePCodeBeg - REOpSz - RENextOffSz)^ := ANYOFFULLSET; \r
+          regcode := RangePCodeBeg; \r
+          Move (RangeSet, regcode^, SizeOf (TSetOfREChar)); \r
+          inc (regcode, SizeOf (TSetOfREChar)); \r
+         <B>end</B>; \r
+      <B>end</B>; \r
+   <I><FONT COLOR="Navy">{$ELSE}</FONT></I> \r
+   EmitC (b); \r
+   <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+  <B>end</B>; \r
\r
+ <B>procedure</B> EmitSimpleRangeC (b : REChar); \r
+  <B>begin</B> \r
+   RangeBeg := b; \r
+   EmitRangeC (b); \r
+   CanBeRange := true; \r
+  <B>end</B>; \r
\r
+ <B>procedure</B> EmitRangeStr (<B>const</B> s : RegExprString); \r
+  <B>var</B> i : integer; \r
+  <B>begin</B> \r
+   <B>for</B> i := 1 <B>to</B> length (s) \r
+    <B>do</B> EmitRangeC (s [i]); \r
+  <B>end</B>; \r
\r
+ <B>function</B> UnQuoteChar (<B>var</B> APtr : PRegExprChar) : REChar; <I><FONT COLOR="Navy">//###0.934 </FONT></I>\r
+  <B>begin</B> \r
+   <B>case</B> APtr^ <B>of</B> \r
+     't': Result := #$9;  <I><FONT COLOR="Navy">// tab (HT/TAB) </FONT></I>\r
+     'n': Result := #$a;  <I><FONT COLOR="Navy">// newline (NL) </FONT></I>\r
+     'r': Result := #$d;  <I><FONT COLOR="Navy">// car.return (CR) </FONT></I>\r
+     'f': Result := #$c;  <I><FONT COLOR="Navy">// form feed (FF) </FONT></I>\r
+     'a': Result := #$7;  <I><FONT COLOR="Navy">// alarm (bell) (BEL) </FONT></I>\r
+     'e': Result := #$1b; <I><FONT COLOR="Navy">// escape (ESC) </FONT></I>\r
+     'x': <B>begin</B> <I><FONT COLOR="Navy">// hex char </FONT></I>\r
+       Result := #0; \r
+       inc (APtr); \r
+       <B>if</B> APtr^ = #0 <B>then</B> <B>begin</B> \r
+         Error (reeNoHexCodeAfterBSlashX); \r
+         EXIT; \r
+        <B>end</B>; \r
+       <B>if</B> APtr^ = '{' <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// /x{nnnn} //###0.936 </FONT></I>\r
+          <B>REPEAT</B> \r
+           inc (APtr); \r
+           <B>if</B> APtr^ = #0 <B>then</B> <B>begin</B> \r
+             Error (reeNoHexCodeAfterBSlashX); \r
+             EXIT; \r
+            <B>end</B>; \r
+           <B>if</B> APtr^ <> '}' <B>then</B> <B>begin</B> \r
+              <B>if</B> (Ord (Result) \r
+                  <B>ShR</B> (SizeOf (REChar) * 8 - 4)) <B>and</B> $F <> 0 <B>then</B> <B>begin</B> \r
+                Error (reeHexCodeAfterBSlashXTooBig); \r
+                EXIT; \r
+               <B>end</B>; \r
+              Result := REChar ((Ord (Result) <B>ShL</B> 4) <B>or</B> HexDig (APtr^)); \r
+              <I><FONT COLOR="Navy">// HexDig will cause Error if bad hex digit found </FONT></I>\r
+             <B>end</B> \r
+            <B>else</B> BREAK; \r
+          <B>UNTIL</B> False; \r
+         <B>end</B> \r
+        <B>else</B> <B>begin</B> \r
+          Result := REChar (HexDig (APtr^)); \r
+          <I><FONT COLOR="Navy">// HexDig will cause Error if bad hex digit found </FONT></I>\r
+          inc (APtr); \r
+          <B>if</B> APtr^ = #0 <B>then</B> <B>begin</B> \r
+            Error (reeNoHexCodeAfterBSlashX); \r
+            EXIT; \r
+           <B>end</B>; \r
+          Result := REChar ((Ord (Result) <B>ShL</B> 4) <B>or</B> HexDig (APtr^)); \r
+          <I><FONT COLOR="Navy">// HexDig will cause Error if bad hex digit found </FONT></I>\r
+         <B>end</B>; \r
+      <B>end</B>; \r
+     <B>else</B> Result := APtr^; \r
+    <B>end</B>; \r
+  <B>end</B>; \r
\r
+ <B>begin</B> \r
+  Result := <B>nil</B>; \r
+  flagp := WORST; <I><FONT COLOR="Navy">// Tentatively. </FONT></I>\r
\r
+  inc (regparse); \r
+  <B>case</B> (regparse - 1)^ <B>of</B> \r
+    '^': ret := EmitNode (BOL); \r
+    '$': ret := EmitNode (EOL); \r
+    '.': \r
+       <B>if</B> (fCompModifiers <B>and</B> MaskModS) = MaskModS <B>then</B> <B>begin</B> \r
+          ret := EmitNode (ANY); \r
+          flagp := flagp <B>or</B> HASWIDTH <B>or</B> SIMPLE; \r
+         <B>end</B> \r
+        <B>else</B> <B>begin</B> <I><FONT COLOR="Navy">// not /s, so emit [^/n] </FONT></I>\r
+          ret := EmitRange (ANYBUT); \r
+          EmitRangeStr (#$a); \r
+          EmitRangeC (#0); \r
+          flagp := flagp <B>or</B> HASWIDTH <B>or</B> SIMPLE; \r
+         <B>end</B>; \r
+    '[': <B>begin</B> \r
+        <B>if</B> regparse^ = '^' <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Complement of range. </FONT></I>\r
+           <B>if</B> (fCompModifiers <B>and</B> MaskModI) = MaskModI \r
+            <B>then</B> ret := EmitRange (ANYBUTCI) \r
+            <B>else</B> ret := EmitRange (ANYBUT); \r
+           inc (regparse); \r
+          <B>end</B> \r
+         <B>else</B> \r
+          <B>if</B> (fCompModifiers <B>and</B> MaskModI) = MaskModI \r
+           <B>then</B> ret := EmitRange (ANYOFCI) \r
+           <B>else</B> ret := EmitRange (ANYOF); \r
\r
+        CanBeRange := false; \r
\r
+        <B>if</B> (regparse^ = ']') <B>then</B> <B>begin</B> \r
+          EmitSimpleRangeC (regparse^); <I><FONT COLOR="Navy">// []-a] -> ']' .. 'a' </FONT></I>\r
+          inc (regparse); \r
+         <B>end</B>; \r
\r
+        <B>while</B> (regparse^ <> #0) <B>and</B> (regparse^ <> ']') <B>do</B> <B>begin</B> \r
+          <B>if</B> (regparse^ = '-') \r
+              <B>and</B> ((regparse + 1)^ <> #0) <B>and</B> ((regparse + 1)^ <> ']') \r
+              <B>and</B> CanBeRange <B>then</B> <B>begin</B> \r
+             inc (regparse); \r
+             RangeEnd := regparse^; \r
+             <B>if</B> RangeEnd = '/' <B>then</B> <B>begin</B> \r
+               <I><FONT COLOR="Navy">{$IFDEF UniCode}</FONT></I> <I><FONT COLOR="Navy">//###0.935 </FONT></I>\r
+               <B>if</B> (ord ((regparse + 1)^) < 256) \r
+                  <B>and</B> (char ((regparse + 1)^) \r
+                        <B>in</B> ['d', 'D', 's', 'S', 'w', 'W']) <B>then</B> <B>begin</B> \r
+               <I><FONT COLOR="Navy">{$ELSE}</FONT></I> \r
+               <B>if</B> (regparse + 1)^ <B>in</B> ['d', 'D', 's', 'S', 'w', 'W'] <B>then</B> <B>begin</B> \r
+               <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+                 EmitRangeC ('-'); <I><FONT COLOR="Navy">// or treat as error ?!! </FONT></I>\r
+                 CONTINUE; \r
+                <B>end</B>; \r
+               inc (regparse); \r
+               RangeEnd := UnQuoteChar (regparse); \r
+              <B>end</B>; \r
\r
+             <I><FONT COLOR="Navy">// r.e.ranges extension for russian </FONT></I>\r
+             <B>if</B> ((fCompModifiers <B>and</B> MaskModR) = MaskModR) \r
+                <B>and</B> (RangeBeg = RusRangeLoLow) <B>and</B> (RangeEnd = RusRangeLoHigh) <B>then</B> <B>begin</B> \r
+               EmitRangeStr (RusRangeLo); \r
+              <B>end</B> \r
+             <B>else</B> <B>if</B> ((fCompModifiers <B>and</B> MaskModR) = MaskModR) \r
+                 <B>and</B> (RangeBeg = RusRangeHiLow) <B>and</B> (RangeEnd = RusRangeHiHigh) <B>then</B> <B>begin</B> \r
+               EmitRangeStr (RusRangeHi); \r
+              <B>end</B> \r
+             <B>else</B> <B>if</B> ((fCompModifiers <B>and</B> MaskModR) = MaskModR) \r
+                  <B>and</B> (RangeBeg = RusRangeLoLow) <B>and</B> (RangeEnd = RusRangeHiHigh) <B>then</B> <B>begin</B> \r
+               EmitRangeStr (RusRangeLo); \r
+               EmitRangeStr (RusRangeHi); \r
+              <B>end</B> \r
+             <B>else</B> <B>begin</B> <I><FONT COLOR="Navy">// standard r.e. handling </FONT></I>\r
+               <B>if</B> RangeBeg > RangeEnd <B>then</B> <B>begin</B> \r
+                 Error (reeInvalidRange); \r
+                 EXIT; \r
+                <B>end</B>; \r
+               inc (RangeBeg); \r
+               EmitRangeC (RangeEnd); <I><FONT COLOR="Navy">// prevent infinite loop if RangeEnd=$ff </FONT></I>\r
+               <B>while</B> RangeBeg < RangeEnd <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+                 EmitRangeC (RangeBeg); \r
+                 inc (RangeBeg); \r
+                <B>end</B>; \r
+              <B>end</B>; \r
+             inc (regparse); \r
+            <B>end</B> \r
+           <B>else</B> <B>begin</B> \r
+             <B>if</B> regparse^ = '/' <B>then</B> <B>begin</B> \r
+                inc (regparse); \r
+                <B>if</B> regparse^ = #0 <B>then</B> <B>begin</B> \r
+                  Error (reeParseAtomTrailingBackSlash); \r
+                  EXIT; \r
+                 <B>end</B>; \r
+                <B>case</B> regparse^ <B>of</B> <I><FONT COLOR="Navy">// r.e.extensions </FONT></I>\r
+                  'd': EmitRangeStr ('0123456789'); \r
+                  'w': EmitRangeStr (WordChars); \r
+                  's': EmitRangeStr (SpaceChars); \r
+                  <B>else</B> EmitSimpleRangeC (UnQuoteChar (regparse)); \r
+                 <B>end</B>; <I><FONT COLOR="Navy">{ of case}</FONT></I> \r
+               <B>end</B> \r
+              <B>else</B> EmitSimpleRangeC (regparse^); \r
+             inc (regparse); \r
+            <B>end</B>; \r
+         <B>end</B>; <I><FONT COLOR="Navy">{ of while}</FONT></I> \r
+        EmitRangeC (#0); \r
+        <B>if</B> regparse^ <> ']' <B>then</B> <B>begin</B> \r
+          Error (reeUnmatchedSqBrackets); \r
+          EXIT; \r
+         <B>end</B>; \r
+        inc (regparse); \r
+        flagp := flagp <B>or</B> HASWIDTH <B>or</B> SIMPLE; \r
+      <B>end</B>; \r
+    '(': <B>begin</B> \r
+        <B>if</B> regparse^ = '?' <B>then</B> <B>begin</B> \r
+           <I><FONT COLOR="Navy">// check for extended Perl syntax : (?..) </FONT></I>\r
+           <B>if</B> (regparse + 1)^ = '#' <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// (?#comment) </FONT></I>\r
+              inc (regparse, 2); <I><FONT COLOR="Navy">// find closing ')' </FONT></I>\r
+              <B>while</B> (regparse^ <> #0) <B>and</B> (regparse^ <> ')') \r
+               <B>do</B> inc (regparse); \r
+              <B>if</B> regparse^ <> ')' <B>then</B> <B>begin</B> \r
+                Error (reeUnclosedComment); \r
+                EXIT; \r
+               <B>end</B>; \r
+              inc (regparse); <I><FONT COLOR="Navy">// skip ')' </FONT></I>\r
+              ret := EmitNode (COMMENT); <I><FONT COLOR="Navy">// comment </FONT></I>\r
+             <B>end</B> \r
+           <B>else</B> <B>begin</B> <I><FONT COLOR="Navy">// modifiers ? </FONT></I>\r
+             inc (regparse); <I><FONT COLOR="Navy">// skip '?' </FONT></I>\r
+             begmodfs := regparse; \r
+             <B>while</B> (regparse^ <> #0) <B>and</B> (regparse^ <> ')') \r
+              <B>do</B> inc (regparse); \r
+             <B>if</B> (regparse^ <> ')') \r
+                <B>or</B> <B>not</B> SetModifiersInt (copy (begmodfs, 1, (regparse - begmodfs)), fCompModifiers) <B>then</B> <B>begin</B> \r
+               Error (reeUrecognizedModifier); \r
+               EXIT; \r
+              <B>end</B>; \r
+             inc (regparse); <I><FONT COLOR="Navy">// skip ')' </FONT></I>\r
+             ret := EmitNode (COMMENT); <I><FONT COLOR="Navy">// comment </FONT></I>\r
+<I><FONT COLOR="Navy">//             Error (reeQPSBFollowsNothing); </FONT></I>\r
+<I><FONT COLOR="Navy">//             EXIT; </FONT></I>\r
+            <B>end</B>; \r
+          <B>end</B> \r
+         <B>else</B> <B>begin</B> \r
+           ret := ParseReg (1, flags); \r
+           <B>if</B> ret = <B>nil</B> <B>then</B> <B>begin</B> \r
+             Result := <B>nil</B>; \r
+             EXIT; \r
+            <B>end</B>; \r
+           flagp := flagp <B>or</B> flags <B>and</B> (HASWIDTH <B>or</B> SPSTART); \r
+          <B>end</B>; \r
+      <B>end</B>; \r
+    #0, '|', ')': <B>begin</B> <I><FONT COLOR="Navy">// Supposed to be caught earlier. </FONT></I>\r
+       Error (reeInternalUrp); \r
+       EXIT; \r
+      <B>end</B>; \r
+    '?', '+', '*': <B>begin</B> \r
+       Error (reeQPSBFollowsNothing); \r
+       EXIT; \r
+      <B>end</B>; \r
+    '/': <B>begin</B> \r
+        <B>if</B> regparse^ = #0 <B>then</B> <B>begin</B> \r
+          Error (reeTrailingBackSlash); \r
+          EXIT; \r
+         <B>end</B>; \r
+        <B>case</B> regparse^ <B>of</B> <I><FONT COLOR="Navy">// r.e.extensions </FONT></I>\r
+          'd': <B>begin</B> <I><FONT COLOR="Navy">// r.e.extension - any digit ('0' .. '9') </FONT></I>\r
+             ret := EmitNode (ANYDIGIT); \r
+             flagp := flagp <B>or</B> HASWIDTH <B>or</B> SIMPLE; \r
+            <B>end</B>; \r
+          'D': <B>begin</B> <I><FONT COLOR="Navy">// r.e.extension - not digit ('0' .. '9') </FONT></I>\r
+             ret := EmitNode (NOTDIGIT); \r
+             flagp := flagp <B>or</B> HASWIDTH <B>or</B> SIMPLE; \r
+            <B>end</B>; \r
+          's': <B>begin</B> <I><FONT COLOR="Navy">// r.e.extension - any space char </FONT></I>\r
+             <I><FONT COLOR="Navy">{$IFDEF UseSetOfChar}</FONT></I> \r
+             ret := EmitRange (ANYOF); \r
+             EmitRangeStr (SpaceChars); \r
+             EmitRangeC (#0); \r
+             <I><FONT COLOR="Navy">{$ELSE}</FONT></I> \r
+             ret := EmitNode (ANYSPACE); \r
+             <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+             flagp := flagp <B>or</B> HASWIDTH <B>or</B> SIMPLE; \r
+            <B>end</B>; \r
+          'S': <B>begin</B> <I><FONT COLOR="Navy">// r.e.extension - not space char </FONT></I>\r
+             <I><FONT COLOR="Navy">{$IFDEF UseSetOfChar}</FONT></I> \r
+             ret := EmitRange (ANYBUT); \r
+             EmitRangeStr (SpaceChars); \r
+             EmitRangeC (#0); \r
+             <I><FONT COLOR="Navy">{$ELSE}</FONT></I> \r
+             ret := EmitNode (NOTSPACE); \r
+             <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+             flagp := flagp <B>or</B> HASWIDTH <B>or</B> SIMPLE; \r
+            <B>end</B>; \r
+          'w': <B>begin</B> <I><FONT COLOR="Navy">// r.e.extension - any english char or '_' </FONT></I>\r
+             <I><FONT COLOR="Navy">{$IFDEF UseSetOfChar}</FONT></I> \r
+             ret := EmitRange (ANYOF); \r
+             EmitRangeStr (WordChars); \r
+             EmitRangeC (#0); \r
+             <I><FONT COLOR="Navy">{$ELSE}</FONT></I> \r
+             ret := EmitNode (ANYLETTER); \r
+             <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+             flagp := flagp <B>or</B> HASWIDTH <B>or</B> SIMPLE; \r
+            <B>end</B>; \r
+          'W': <B>begin</B> <I><FONT COLOR="Navy">// r.e.extension - not english char or '_' </FONT></I>\r
+             <I><FONT COLOR="Navy">{$IFDEF UseSetOfChar}</FONT></I> \r
+             ret := EmitRange (ANYBUT); \r
+             EmitRangeStr (WordChars); \r
+             EmitRangeC (#0); \r
+             <I><FONT COLOR="Navy">{$ELSE}</FONT></I> \r
+             ret := EmitNode (NOTLETTER); \r
+             <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+             flagp := flagp <B>or</B> HASWIDTH <B>or</B> SIMPLE; \r
+            <B>end</B>; \r
+           '1' .. '9': <B>begin</B> <I><FONT COLOR="Navy">//###0.936 </FONT></I>\r
+             <B>if</B> (fCompModifiers <B>and</B> MaskModI) = MaskModI \r
+              <B>then</B> ret := EmitNode (BSUBEXPCI) \r
+              <B>else</B> ret := EmitNode (BSUBEXP); \r
+             EmitC (REChar (ord (regparse^) - ord ('0'))); \r
+             flagp := flagp <B>or</B> HASWIDTH <B>or</B> SIMPLE; \r
+            <B>end</B>; \r
+          <B>else</B> EmitExactly (UnQuoteChar (regparse)); \r
+         <B>end</B>; <I><FONT COLOR="Navy">{ of case}</FONT></I> \r
+        inc (regparse); \r
+      <B>end</B>; \r
+    <B>else</B> <B>begin</B> \r
+        dec (regparse); \r
+        len := strcspn (regparse, META); \r
+        <B>if</B> len <= 0 <B>then</B> \r
+         <B>if</B> regparse^ <> '{' <B>then</B> <B>begin</B> \r
+            Error (reeRarseAtomInternalDisaster); \r
+            EXIT; \r
+           <B>end</B> \r
+          <B>else</B> len := strcspn (regparse + 1, META) + 1; <I><FONT COLOR="Navy">// bad {n,m} - compile as EXATLY </FONT></I>\r
+        ender := (regparse + len)^; \r
+        <B>if</B> (len > 1) \r
+           <B>and</B> ((ender = '*') <B>or</B> (ender = '+') <B>or</B> (ender = '?') <B>or</B> (ender = '{')) \r
+         <B>then</B> dec (len); <I><FONT COLOR="Navy">// Back off clear of ?+*{ operand. </FONT></I>\r
+        flagp := flagp <B>or</B> HASWIDTH; \r
+        <B>if</B> len = 1 \r
+         <B>then</B> flagp := flagp <B>or</B> SIMPLE; \r
+        <B>if</B> (fCompModifiers <B>and</B> MaskModI) = MaskModI \r
+         <B>then</B> ret := EmitNode (EXACTLYCI) \r
+         <B>else</B> ret := EmitNode (EXACTLY); \r
+        <B>while</B> len > 0 <B>do</B> <B>begin</B> \r
+          EmitC (regparse^); \r
+          inc (regparse); \r
+          dec (len); \r
+         <B>end</B>; \r
+        EmitC (#0); \r
+      <B>end</B>; <I><FONT COLOR="Navy">{ of case else}</FONT></I> \r
+   <B>end</B>; <I><FONT COLOR="Navy">{ of case}</FONT></I> \r
\r
+  Result := ret; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.ParseAtom \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.GetCompilerErrorPos : integer; \r
+ <B>begin</B> \r
+  Result := 0; \r
+  <B>if</B> (regexpbeg = <B>nil</B>) <B>or</B> (regparse = <B>nil</B>) \r
+   <B>then</B> EXIT; <I><FONT COLOR="Navy">// not in compiling mode ? </FONT></I>\r
+  Result := regparse - regexpbeg; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.GetCompilerErrorPos \r
+--------------------------------------------------------------}</FONT></I> \r
\r
\r
+<I><FONT COLOR="Navy">{=============================================================}</FONT></I> \r
+<I><FONT COLOR="Navy">{===================== Matching section ======================}</FONT></I> \r
+<I><FONT COLOR="Navy">{=============================================================}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{$IFNDEF UseSetOfChar}</FONT></I> \r
+<B>function</B> TRegExpr.StrScanCI (s : PRegExprChar; ch : REChar) : PRegExprChar; <I><FONT COLOR="Navy">//###0.928 - now method of TRegExpr </FONT></I>\r
+ <B>begin</B> \r
+  <B>while</B> (s^ <> #0) <B>and</B> (s^ <> ch) <B>and</B> (s^ <> InvertCase (ch)) \r
+   <B>do</B> inc (s); \r
+  <B>if</B> s^ <> #0 \r
+   <B>then</B> Result := s \r
+   <B>else</B> Result := <B>nil</B>; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.StrScanCI \r
+--------------------------------------------------------------}</FONT></I> \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<B>function</B> TRegExpr.regrepeat (p : PRegExprChar; AMax : integer) : integer; \r
+<I><FONT COLOR="Navy">// repeatedly match something simple, report how many </FONT></I>\r
+ <B>var</B> \r
+  scan : PRegExprChar; \r
+  opnd : PRegExprChar; \r
+  TheMax : integer; \r
+  <I><FONT COLOR="Navy">{Ch,}</FONT></I> InvCh : REChar; <I><FONT COLOR="Navy">//###0.931 </FONT></I>\r
+  sestart, seend : PRegExprChar; <I><FONT COLOR="Navy">//###0.936 </FONT></I>\r
+ <B>begin</B> \r
+  Result := 0; \r
+  scan := reginput; \r
+  opnd := p + REOpSz + RENextOffSz; <I><FONT COLOR="Navy">//OPERAND </FONT></I>\r
+  TheMax := fInputEnd - scan; \r
+  <B>if</B> TheMax > AMax \r
+   <B>then</B> TheMax := AMax; \r
+  <B>case</B> PREOp (p)^ <B>of</B> \r
+    ANY: <B>begin</B> \r
+      Result := TheMax; \r
+      inc (scan, Result); \r
+     <B>end</B>; \r
+    EXACTLY: <B>begin</B> <I><FONT COLOR="Navy">// in opnd can be only ONE char !!! </FONT></I>\r
+<I><FONT COLOR="Navy">//      Ch := opnd^; // store in register //###0.931 </FONT></I>\r
+      <B>while</B> (Result < TheMax) <B>and</B> (opnd^ = scan^) <B>do</B> <B>begin</B> \r
+        inc (Result); \r
+        inc (scan); \r
+       <B>end</B>; \r
+     <B>end</B>; \r
+    EXACTLYCI: <B>begin</B> <I><FONT COLOR="Navy">// in opnd can be only ONE char !!! </FONT></I>\r
+<I><FONT COLOR="Navy">//      Ch := opnd^; // store in register //###0.931 </FONT></I>\r
+      <B>while</B> (Result < TheMax) <B>and</B> (opnd^ = scan^) <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// prevent unneeded InvertCase //###0.931 </FONT></I>\r
+        inc (Result); \r
+        inc (scan); \r
+       <B>end</B>; \r
+      <B>if</B> Result < TheMax <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">//###0.931 </FONT></I>\r
+        InvCh := InvertCase (opnd^); <I><FONT COLOR="Navy">// store in register </FONT></I>\r
+        <B>while</B> (Result < TheMax) <B>and</B> \r
+              ((opnd^ = scan^) <B>or</B> (InvCh = scan^)) <B>do</B> <B>begin</B> \r
+          inc (Result); \r
+          inc (scan); \r
+         <B>end</B>; \r
+       <B>end</B>; \r
+     <B>end</B>; \r
+    BSUBEXP: <B>begin</B> <I><FONT COLOR="Navy">//###0.936 </FONT></I>\r
+      sestart := startp [ord (opnd^)]; \r
+      <B>if</B> sestart = <B>nil</B> \r
+       <B>then</B> EXIT; \r
+      seend := endp [ord (opnd^)]; \r
+      <B>if</B> seend = <B>nil</B> \r
+       <B>then</B> EXIT; \r
+      <B>REPEAT</B> \r
+        opnd := sestart; \r
+        <B>while</B> opnd < seend <B>do</B> <B>begin</B> \r
+          <B>if</B> (scan >= fInputEnd) <B>or</B> (scan^ <> opnd^) \r
+           <B>then</B> EXIT; \r
+          inc (scan); \r
+          inc (opnd); \r
+         <B>end</B>; \r
+        inc (Result); \r
+        reginput := scan; \r
+      <B>UNTIL</B> Result >= AMax; \r
+     <B>end</B>; \r
+    BSUBEXPCI: <B>begin</B> <I><FONT COLOR="Navy">//###0.936 </FONT></I>\r
+      sestart := startp [ord (opnd^)]; \r
+      <B>if</B> sestart = <B>nil</B> \r
+       <B>then</B> EXIT; \r
+      seend := endp [ord (opnd^)]; \r
+      <B>if</B> seend = <B>nil</B> \r
+       <B>then</B> EXIT; \r
+      <B>REPEAT</B> \r
+        opnd := sestart; \r
+        <B>while</B> opnd < seend <B>do</B> <B>begin</B> \r
+          <B>if</B> (scan >= fInputEnd) <B>or</B> \r
+             ((scan^ <> opnd^) <B>and</B> (scan^ <> InvertCase (opnd^))) \r
+           <B>then</B> EXIT; \r
+          inc (scan); \r
+          inc (opnd); \r
+         <B>end</B>; \r
+        inc (Result); \r
+        reginput := scan; \r
+      <B>UNTIL</B> Result >= AMax; \r
+     <B>end</B>; \r
+    ANYDIGIT: \r
+      <B>while</B> (Result < TheMax) <B>and</B> \r
+         (scan^ >= '0') <B>and</B> (scan^ <= '9') <B>do</B> <B>begin</B> \r
+        inc (Result); \r
+        inc (scan); \r
+       <B>end</B>; \r
+    NOTDIGIT: \r
+      <B>while</B> (Result < TheMax) <B>and</B> \r
+         ((scan^ < '0') <B>or</B> (scan^ > '9')) <B>do</B> <B>begin</B> \r
+        inc (Result); \r
+        inc (scan); \r
+       <B>end</B>; \r
+    <I><FONT COLOR="Navy">{$IFNDEF UseSetOfChar}</FONT></I> <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+    ANYLETTER: \r
+      <B>while</B> (Result < TheMax) <B>and</B> \r
+       <I><FONT COLOR="Navy">// !!!!!?????? if length (fWordChars) <> 0 </FONT></I>\r
+       <I><FONT COLOR="Navy">// then Pos (scan^, fWordChars) </FONT></I>\r
+       <I><FONT COLOR="Navy">// else </FONT></I>\r
+       ((scan^ >= 'a') <B>and</B> (scan^ <= 'z') \r
+       <B>or</B> (scan^ >= 'A') <B>and</B> (scan^ <= 'Z') <B>or</B> (scan^ = '_')) <B>do</B> <B>begin</B> \r
+        inc (Result); \r
+        inc (scan); \r
+       <B>end</B>; \r
+    NOTLETTER: \r
+      <B>while</B> (Result < TheMax) <B>and</B> \r
+       <I><FONT COLOR="Navy">// !!!!!?????? if length (fWordChars) <> 0 </FONT></I>\r
+       <I><FONT COLOR="Navy">// then Pos (scan^, fWordChars) </FONT></I>\r
+       <I><FONT COLOR="Navy">// else </FONT></I>\r
+        <B>not</B> ((scan^ >= 'a') <B>and</B> (scan^ <= 'z') \r
+         <B>or</B> (scan^ >= 'A') <B>and</B> (scan^ <= 'Z') \r
+         <B>or</B> (scan^ = '_')) <B>do</B> <B>begin</B> \r
+        inc (Result); \r
+        inc (scan); \r
+       <B>end</B>; \r
+    ANYSPACE: \r
+      <B>while</B> (Result < TheMax) <B>and</B> \r
+         (Pos (scan^, fSpaceChars) > 0) <B>do</B> <B>begin</B> \r
+        inc (Result); \r
+        inc (scan); \r
+       <B>end</B>; \r
+    NOTSPACE: \r
+      <B>while</B> (Result < TheMax) <B>and</B> \r
+         (Pos (scan^, fSpaceChars) <= 0) <B>do</B> <B>begin</B> \r
+        inc (Result); \r
+        inc (scan); \r
+       <B>end</B>; \r
+    <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+    ANYOFTINYSET: <B>begin</B> \r
+      <B>while</B> (Result < TheMax) <B>and</B> <I><FONT COLOR="Navy">//!!!TinySet </FONT></I>\r
+       ((scan^ = opnd^) <B>or</B> (scan^ = (opnd + 1)^) \r
+        <B>or</B> (scan^ = (opnd + 2)^)) <B>do</B> <B>begin</B> \r
+        inc (Result); \r
+        inc (scan); \r
+       <B>end</B>; \r
+     <B>end</B>; \r
+    ANYBUTTINYSET: <B>begin</B> \r
+      <B>while</B> (Result < TheMax) <B>and</B> <I><FONT COLOR="Navy">//!!!TinySet </FONT></I>\r
+       (scan^ <> opnd^) <B>and</B> (scan^ <> (opnd + 1)^) \r
+        <B>and</B> (scan^ <> (opnd + 2)^) <B>do</B> <B>begin</B> \r
+        inc (Result); \r
+        inc (scan); \r
+       <B>end</B>; \r
+     <B>end</B>; \r
+    <I><FONT COLOR="Navy">{$IFDEF UseSetOfChar}</FONT></I> <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+    ANYOFFULLSET: <B>begin</B> \r
+      <B>while</B> (Result < TheMax) <B>and</B> \r
+       (scan^ <B>in</B> PSetOfREChar (opnd)^) <B>do</B> <B>begin</B> \r
+        inc (Result); \r
+        inc (scan); \r
+       <B>end</B>; \r
+     <B>end</B>; \r
+    <I><FONT COLOR="Navy">{$ELSE}</FONT></I> \r
+    ANYOF: \r
+      <B>while</B> (Result < TheMax) <B>and</B> \r
+         (StrScan (opnd, scan^) <> <B>nil</B>) <B>do</B> <B>begin</B> \r
+        inc (Result); \r
+        inc (scan); \r
+       <B>end</B>; \r
+    ANYBUT: \r
+      <B>while</B> (Result < TheMax) <B>and</B> \r
+         (StrScan (opnd, scan^) = <B>nil</B>) <B>do</B> <B>begin</B> \r
+        inc (Result); \r
+        inc (scan); \r
+       <B>end</B>; \r
+    ANYOFCI: \r
+      <B>while</B> (Result < TheMax) <B>and</B> (StrScanCI (opnd, scan^) <> <B>nil</B>) <B>do</B> <B>begin</B> \r
+        inc (Result); \r
+        inc (scan); \r
+       <B>end</B>; \r
+    ANYBUTCI: \r
+      <B>while</B> (Result < TheMax) <B>and</B> (StrScanCI (opnd, scan^) = <B>nil</B>) <B>do</B> <B>begin</B> \r
+        inc (Result); \r
+        inc (scan); \r
+       <B>end</B>; \r
+    <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+    <B>else</B> <B>begin</B> <I><FONT COLOR="Navy">// Oh dear. Called inappropriately. </FONT></I>\r
+      Result := 0; <I><FONT COLOR="Navy">// Best compromise. </FONT></I>\r
+      Error (reeRegRepeatCalledInappropriately); \r
+      EXIT; \r
+     <B>end</B>; \r
+   <B>end</B>; <I><FONT COLOR="Navy">{ of case}</FONT></I> \r
+  reginput := scan; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.regrepeat \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.regnext (p : PRegExprChar) : PRegExprChar; \r
+<I><FONT COLOR="Navy">// dig the "next" pointer out of a node </FONT></I>\r
+ <B>var</B> offset : TRENextOff; \r
+ <B>begin</B> \r
+  <B>if</B> p = @regdummy <B>then</B> <B>begin</B> \r
+    Result := <B>nil</B>; \r
+    EXIT; \r
+   <B>end</B>; \r
+  offset := PRENextOff (p + REOpSz)^; <I><FONT COLOR="Navy">//###0.933 inlined NEXT </FONT></I>\r
+  <B>if</B> offset = 0 \r
+   <B>then</B> Result := <B>nil</B> \r
+   <B>else</B> Result := p + offset; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.regnext \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.MatchPrim (prog : PRegExprChar) : boolean; \r
+<I><FONT COLOR="Navy">// recursively matching routine </FONT></I>\r
+<I><FONT COLOR="Navy">// Conceptually the strategy is simple:  check to see whether the current </FONT></I>\r
+<I><FONT COLOR="Navy">// node matches, call self recursively to see whether the rest matches, </FONT></I>\r
+<I><FONT COLOR="Navy">// and then act accordingly.  In practice we make some effort to avoid </FONT></I>\r
+<I><FONT COLOR="Navy">// recursion, in particular by going through "ordinary" nodes (that don't </FONT></I>\r
+<I><FONT COLOR="Navy">// need to know whether the rest of the match failed) by a loop instead of </FONT></I>\r
+<I><FONT COLOR="Navy">// by recursion. </FONT></I>\r
+ <B>var</B> \r
+  scan : PRegExprChar; <I><FONT COLOR="Navy">// Current node. </FONT></I>\r
+  next : PRegExprChar; <I><FONT COLOR="Navy">// Next node. </FONT></I>\r
+  len : integer; \r
+  opnd : PRegExprChar; \r
+  no : integer; \r
+  save : PRegExprChar; \r
+  nextch : REChar; \r
+  BracesMin, BracesMax : integer; <I><FONT COLOR="Navy">// we use integer instead of TREBracesArg for better support */+ </FONT></I>\r
+  <I><FONT COLOR="Navy">{$IFDEF ComplexBraces}</FONT></I> \r
+  SavedLoopStack : <B>array</B> [1 .. LoopStackMax] <B>of</B> integer; <I><FONT COLOR="Navy">// :(( very bad for recursion </FONT></I>\r
+  SavedLoopStackIdx : integer; <I><FONT COLOR="Navy">//###0.925 </FONT></I>\r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+ <B>begin</B> \r
+  Result := false; \r
+  scan := prog; \r
\r
+  <B>while</B> scan <> <B>nil</B> <B>do</B> <B>begin</B> \r
+     len := PRENextOff (scan + 1)^; <I><FONT COLOR="Navy">//###0.932 inlined regnext </FONT></I>\r
+     <B>if</B> len = 0 \r
+      <B>then</B> next := <B>nil</B> \r
+      <B>else</B> next := scan + len; \r
\r
+     <B>case</B> scan^ <B>of</B> \r
+         BOL: <B>if</B> reginput <> fInputStart \r
+               <B>then</B> EXIT; \r
+         EOL: <B>if</B> reginput^ <> #0 \r
+               <B>then</B> EXIT; \r
+         ANY: <B>begin</B> \r
+            <B>if</B> reginput^ = #0 \r
+             <B>then</B> EXIT; \r
+            inc (reginput); \r
+           <B>end</B>; \r
+         ANYDIGIT: <B>begin</B> \r
+            <B>if</B> (reginput^ = #0) <B>or</B> (reginput^ < '0') <B>or</B> (reginput^ > '9') \r
+             <B>then</B> EXIT; \r
+            inc (reginput); \r
+           <B>end</B>; \r
+         NOTDIGIT: <B>begin</B> \r
+            <B>if</B> (reginput^ = #0) <B>or</B> ((reginput^ >= '0') <B>and</B> (reginput^ <= '9')) \r
+             <B>then</B> EXIT; \r
+            inc (reginput); \r
+           <B>end</B>; \r
+         <I><FONT COLOR="Navy">{$IFNDEF UseSetOfChar}</FONT></I> <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+         ANYLETTER: <B>begin</B> \r
+            <B>if</B> (reginput^ = #0) <B>or</B> \r
+             <I><FONT COLOR="Navy">// !!!!!?????? Pos (scan^, fWordChars) </FONT></I>\r
+             <B>not</B> ((reginput^ >= 'a') <B>and</B> (reginput^ <= 'z') \r
+                 <B>or</B> (reginput^ >= 'A') <B>and</B> (reginput^ <= 'Z') \r
+                 <B>or</B> (reginput^ = '_')) \r
+             <B>then</B> EXIT; \r
+            inc (reginput); \r
+           <B>end</B>; \r
+         NOTLETTER: <B>begin</B> \r
+            <B>if</B> (reginput^ = #0) <B>or</B> \r
+             <I><FONT COLOR="Navy">// !!!!!?????? Pos (scan^, fWordChars) </FONT></I>\r
+               (reginput^ >= 'a') <B>and</B> (reginput^ <= 'z') \r
+                 <B>or</B> (reginput^ >= 'A') <B>and</B> (reginput^ <= 'Z') \r
+                 <B>or</B> (reginput^ = '_') \r
+             <B>then</B> EXIT; \r
+            inc (reginput); \r
+           <B>end</B>; \r
+         ANYSPACE: <B>begin</B> \r
+            <B>if</B> (reginput^ = #0) <B>or</B> <B>not</B> (Pos (scan^, fSpaceChars) > 0) \r
+             <B>then</B> EXIT; \r
+            inc (reginput); \r
+           <B>end</B>; \r
+         NOTSPACE: <B>begin</B> \r
+            <B>if</B> (reginput^ = #0) <B>or</B> (Pos (scan^, fSpaceChars) > 0) \r
+             <B>then</B> EXIT; \r
+            inc (reginput); \r
+           <B>end</B>; \r
+         <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+         EXACTLYCI: <B>begin</B> \r
+            opnd := scan + REOpSz + RENextOffSz; <I><FONT COLOR="Navy">// OPERAND </FONT></I>\r
+            <I><FONT COLOR="Navy">// Inline the first character, for speed. </FONT></I>\r
+            <B>if</B> (opnd^ <> reginput^) \r
+               <B>and</B> (InvertCase (opnd^) <> reginput^) \r
+             <B>then</B> EXIT; \r
+            len := strlen (opnd); \r
+            <I><FONT COLOR="Navy">//###0.929 begin </FONT></I>\r
+            no := len; \r
+            save := reginput; \r
+            <B>while</B> no > 1 <B>do</B> <B>begin</B> \r
+              inc (save); \r
+              inc (opnd); \r
+              <B>if</B> (opnd^ <> save^) \r
+                 <B>and</B> (InvertCase (opnd^) <> save^) \r
+               <B>then</B> EXIT; \r
+              dec (no); \r
+             <B>end</B>; \r
+            <I><FONT COLOR="Navy">//###0.929 end </FONT></I>\r
+            inc (reginput, len); \r
+           <B>end</B>; \r
+         EXACTLY: <B>begin</B> \r
+            opnd := scan + REOpSz + RENextOffSz; <I><FONT COLOR="Navy">// OPERAND </FONT></I>\r
+            <I><FONT COLOR="Navy">// Inline the first character, for speed. </FONT></I>\r
+            <B>if</B> opnd^ <> reginput^ \r
+             <B>then</B> EXIT; \r
+            len := strlen (opnd); \r
+            <I><FONT COLOR="Navy">//###0.929 begin </FONT></I>\r
+            no := len; \r
+            save := reginput; \r
+            <B>while</B> no > 1 <B>do</B> <B>begin</B> \r
+              inc (save); \r
+              inc (opnd); \r
+              <B>if</B> opnd^ <> save^ \r
+               <B>then</B> EXIT; \r
+              dec (no); \r
+             <B>end</B>; \r
+            <I><FONT COLOR="Navy">//###0.929 end </FONT></I>\r
+            inc (reginput, len); \r
+           <B>end</B>; \r
+         BSUBEXP: <B>begin</B> <I><FONT COLOR="Navy">//###0.936 </FONT></I>\r
+           no := ord ((scan + REOpSz + RENextOffSz)^); \r
+           <B>if</B> startp [no] = <B>nil</B> \r
+            <B>then</B> EXIT; \r
+           <B>if</B> endp [no] = <B>nil</B> \r
+            <B>then</B> EXIT; \r
+           save := reginput; \r
+           opnd := startp [no]; \r
+           <B>while</B> opnd < endp [no] <B>do</B> <B>begin</B> \r
+             <B>if</B> (save >= fInputEnd) <B>or</B> (save^ <> opnd^) \r
+              <B>then</B> EXIT; \r
+             inc (save); \r
+             inc (opnd); \r
+            <B>end</B>; \r
+           reginput := save; \r
+          <B>end</B>; \r
+         BSUBEXPCI: <B>begin</B> <I><FONT COLOR="Navy">//###0.936 </FONT></I>\r
+           no := ord ((scan + REOpSz + RENextOffSz)^); \r
+           <B>if</B> startp [no] = <B>nil</B> \r
+            <B>then</B> EXIT; \r
+           <B>if</B> endp [no] = <B>nil</B> \r
+            <B>then</B> EXIT; \r
+           save := reginput; \r
+           opnd := startp [no]; \r
+           <B>while</B> opnd < endp [no] <B>do</B> <B>begin</B> \r
+             <B>if</B> (save >= fInputEnd) <B>or</B> \r
+                ((save^ <> opnd^) <B>and</B> (save^ <> InvertCase (opnd^))) \r
+              <B>then</B> EXIT; \r
+             inc (save); \r
+             inc (opnd); \r
+            <B>end</B>; \r
+           reginput := save; \r
+          <B>end</B>; \r
+         ANYOFTINYSET: <B>begin</B> \r
+           <B>if</B> (reginput^ = #0) <B>or</B> <I><FONT COLOR="Navy">//!!!TinySet </FONT></I>\r
+             ((reginput^ <> (scan + REOpSz + RENextOffSz)^) \r
+             <B>and</B> (reginput^ <> (scan + REOpSz + RENextOffSz + 1)^) \r
+             <B>and</B> (reginput^ <> (scan + REOpSz + RENextOffSz + 2)^)) \r
+            <B>then</B> EXIT; \r
+           inc (reginput); \r
+          <B>end</B>; \r
+         ANYBUTTINYSET: <B>begin</B> \r
+           <B>if</B> (reginput^ = #0) <B>or</B> <I><FONT COLOR="Navy">//!!!TinySet </FONT></I>\r
+             (reginput^ = (scan + REOpSz + RENextOffSz)^) \r
+             <B>or</B> (reginput^ = (scan + REOpSz + RENextOffSz + 1)^) \r
+             <B>or</B> (reginput^ = (scan + REOpSz + RENextOffSz + 2)^) \r
+            <B>then</B> EXIT; \r
+           inc (reginput); \r
+          <B>end</B>; \r
+         <I><FONT COLOR="Navy">{$IFDEF UseSetOfChar}</FONT></I> <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+         ANYOFFULLSET: <B>begin</B> \r
+           <B>if</B> (reginput^ = #0) \r
+              <B>or</B> <B>not</B> (reginput^ <B>in</B> PSetOfREChar (scan + REOpSz + RENextOffSz)^) \r
+            <B>then</B> EXIT; \r
+           inc (reginput); \r
+          <B>end</B>; \r
+         <I><FONT COLOR="Navy">{$ELSE}</FONT></I> \r
+         ANYOF: <B>begin</B> \r
+            <B>if</B> (reginput^ = #0) <B>or</B> (StrScan (scan + REOpSz + RENextOffSz, reginput^) = <B>nil</B>) \r
+             <B>then</B> EXIT; \r
+            inc (reginput); \r
+           <B>end</B>; \r
+         ANYBUT: <B>begin</B> \r
+            <B>if</B> (reginput^ = #0) <B>or</B> (StrScan (scan + REOpSz + RENextOffSz, reginput^) <> <B>nil</B>) \r
+             <B>then</B> EXIT; \r
+            inc (reginput); \r
+           <B>end</B>; \r
+         ANYOFCI: <B>begin</B> \r
+            <B>if</B> (reginput^ = #0) <B>or</B> (StrScanCI (scan + REOpSz + RENextOffSz, reginput^) = <B>nil</B>) \r
+             <B>then</B> EXIT; \r
+            inc (reginput); \r
+           <B>end</B>; \r
+         ANYBUTCI: <B>begin</B> \r
+            <B>if</B> (reginput^ = #0) <B>or</B> (StrScanCI (scan + REOpSz + RENextOffSz, reginput^) <> <B>nil</B>) \r
+             <B>then</B> EXIT; \r
+            inc (reginput); \r
+           <B>end</B>; \r
+         <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+         NOTHING: ; \r
+         COMMENT: ; \r
+         BACK: ; \r
+         Succ (OPEN) .. TREOp (Ord (OPEN) + NSUBEXP - 1) : <B>begin</B> <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+            no := ord (scan^) - ord (OPEN); \r
+<I><FONT COLOR="Navy">//            save := reginput; </FONT></I>\r
+            save := startp [no]; <I><FONT COLOR="Navy">//###0.936 </FONT></I>\r
+            startp [no] := reginput; <I><FONT COLOR="Navy">//###0.936 </FONT></I>\r
+            Result := MatchPrim (next); \r
+            <B>if</B> <B>not</B> Result <I><FONT COLOR="Navy">//###0.936 </FONT></I>\r
+             <B>then</B> startp [no] := save; \r
+<I><FONT COLOR="Navy">//            if Result and (startp [no] = nil) </FONT></I>\r
+<I><FONT COLOR="Navy">//             then startp [no] := save; </FONT></I>\r
+             <I><FONT COLOR="Navy">// Don't set startp if some later invocation of the same </FONT></I>\r
+             <I><FONT COLOR="Navy">// parentheses already has. </FONT></I>\r
+            EXIT; \r
+           <B>end</B>; \r
+         Succ (CLOSE) .. TREOp (Ord (CLOSE) + NSUBEXP - 1): <B>begin</B> <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+            no := ord (scan^) - ord (CLOSE); \r
+<I><FONT COLOR="Navy">//            save := reginput; </FONT></I>\r
+            save := endp [no]; <I><FONT COLOR="Navy">//###0.936 </FONT></I>\r
+            endp [no] := reginput; <I><FONT COLOR="Navy">//###0.936 </FONT></I>\r
+            Result := MatchPrim (next); \r
+            <B>if</B> <B>not</B> Result <I><FONT COLOR="Navy">//###0.936 </FONT></I>\r
+             <B>then</B> endp [no] := save; \r
+<I><FONT COLOR="Navy">//            if Result and (endp [no] = nil) </FONT></I>\r
+<I><FONT COLOR="Navy">//             then endp [no] := save; </FONT></I>\r
+             <I><FONT COLOR="Navy">// Don't set endp if some later invocation of the same </FONT></I>\r
+             <I><FONT COLOR="Navy">// parentheses already has. </FONT></I>\r
+            EXIT; \r
+           <B>end</B>; \r
+         BRANCH: <B>begin</B> \r
+            <B>if</B> (next^ <> BRANCH) <I><FONT COLOR="Navy">// No choice. </FONT></I>\r
+             <B>then</B> next := scan + REOpSz + RENextOffSz <I><FONT COLOR="Navy">// Avoid recursion </FONT></I>\r
+             <B>else</B> <B>begin</B> \r
+               <B>REPEAT</B> \r
+                save := reginput; \r
+                Result := MatchPrim (scan + REOpSz + RENextOffSz); \r
+                <B>if</B> Result \r
+                 <B>then</B> EXIT; \r
+                reginput := save; \r
+                scan := regnext (scan); \r
+               <B>UNTIL</B> (scan = <B>nil</B>) <B>or</B> (scan^ <> BRANCH); \r
+               EXIT; \r
+              <B>end</B>; \r
+           <B>end</B>; \r
+         <I><FONT COLOR="Navy">{$IFDEF ComplexBraces}</FONT></I> \r
+         LOOPENTRY: <B>begin</B> <I><FONT COLOR="Navy">//###0.925 </FONT></I>\r
+           no := LoopStackIdx; \r
+           inc (LoopStackIdx); \r
+           <B>if</B> LoopStackIdx > LoopStackMax <B>then</B> <B>begin</B> \r
+             Error (reeLoopStackExceeded); \r
+             EXIT; \r
+            <B>end</B>; \r
+           save := reginput; \r
+           LoopStack [LoopStackIdx] := 0; <I><FONT COLOR="Navy">// init loop counter </FONT></I>\r
+           Result := MatchPrim (next); <I><FONT COLOR="Navy">// execute LOOP </FONT></I>\r
+           LoopStackIdx := no; <I><FONT COLOR="Navy">// cleanup </FONT></I>\r
+           <B>if</B> Result \r
+            <B>then</B> EXIT; \r
+           reginput := save; \r
+           EXIT; \r
+          <B>end</B>; \r
+         LOOP: <B>begin</B> <I><FONT COLOR="Navy">//###0.925 </FONT></I>\r
+           <B>if</B> LoopStackIdx <= 0 <B>then</B> <B>begin</B> \r
+             Error (reeLoopWithoutEntry); \r
+             EXIT; \r
+            <B>end</B>; \r
+           opnd := scan + PRENextOff (scan + REOpSz + RENextOffSz + 2 * REBracesArgSz)^; \r
+           BracesMin := PREBracesArg (scan + REOpSz + RENextOffSz)^; \r
+           BracesMax := PREBracesArg (scan + REOpSz + RENextOffSz + REBracesArgSz)^; \r
+           save := reginput; \r
+           <B>if</B> LoopStack [LoopStackIdx] >= BracesMin <B>then</B> <B>begin</B> \r
+              <I><FONT COLOR="Navy">// greedy way ;) </FONT></I>\r
+              <B>if</B> LoopStack [LoopStackIdx] < BracesMax <B>then</B> <B>begin</B> \r
+                inc (LoopStack [LoopStackIdx]); \r
+                no := LoopStackIdx; \r
+                Result := MatchPrim (opnd); \r
+                LoopStackIdx := no; \r
+                <B>if</B> Result \r
+                 <B>then</B> EXIT; \r
+                reginput := save; \r
+               <B>end</B>; \r
+              dec (LoopStackIdx); \r
+              Result := MatchPrim (next); \r
+              <B>if</B> <B>not</B> Result \r
+               <B>then</B> reginput := save; \r
+              EXIT; \r
+             <B>end</B> \r
+            <B>else</B> <B>begin</B> <I><FONT COLOR="Navy">// first match a min_cnt times </FONT></I>\r
+              inc (LoopStack [LoopStackIdx]); \r
+              no := LoopStackIdx; \r
+              Result := MatchPrim (opnd); \r
+              LoopStackIdx := no; \r
+              <B>if</B> Result \r
+               <B>then</B> EXIT; \r
+              dec (LoopStack [LoopStackIdx]); \r
+              reginput := save; \r
+              EXIT; \r
+             <B>end</B>; \r
+          <B>end</B>; \r
+         <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+         STAR, PLUS, BRACES: <B>begin</B> \r
+                <I><FONT COLOR="Navy">// Lookahead to avoid useless match attempts when we know </FONT></I>\r
+                <I><FONT COLOR="Navy">// what character comes next. </FONT></I>\r
+                nextch := #0; \r
+                <B>if</B> next^ = EXACTLY \r
+                 <B>then</B> nextch := (next + REOpSz + RENextOffSz)^; \r
+                BracesMax := MaxInt; <I><FONT COLOR="Navy">// infinite loop for * and + //###0.92 </FONT></I>\r
+                <B>if</B> scan^ = STAR \r
+                 <B>then</B> BracesMin := 0  <I><FONT COLOR="Navy">// STAR </FONT></I>\r
+                 <B>else</B> <B>if</B> scan^ = PLUS \r
+                  <B>then</B> BracesMin := 1 <I><FONT COLOR="Navy">// PLUS </FONT></I>\r
+                  <B>else</B> <B>begin</B> <I><FONT COLOR="Navy">// BRACES </FONT></I>\r
+                    BracesMin := PREBracesArg (scan + REOpSz + RENextOffSz)^; \r
+                    BracesMax := PREBracesArg (scan + REOpSz + RENextOffSz + REBracesArgSz)^; \r
+                   <B>end</B>; \r
+                save := reginput; \r
+                opnd := scan + REOpSz + RENextOffSz; \r
+                <B>if</B> scan^ = BRACES \r
+                 <B>then</B> inc (opnd, 2 * REBracesArgSz); \r
+                no := regrepeat (opnd, BracesMax); <I><FONT COLOR="Navy">// don't repeat more than max_cnt </FONT></I>\r
+                <B>while</B> no >= BracesMin <B>do</B> <B>begin</B> \r
+                  <I><FONT COLOR="Navy">// If it could work, try it. </FONT></I>\r
+                  <B>if</B> (nextch = #0) <B>or</B> (reginput^ = nextch) <B>then</B> <B>begin</B> \r
+                    <I><FONT COLOR="Navy">{$IFDEF ComplexBraces}</FONT></I> \r
+                    System.Move (LoopStack, SavedLoopStack, SizeOf (LoopStack)); <I><FONT COLOR="Navy">//###0.925 </FONT></I>\r
+                    SavedLoopStackIdx := LoopStackIdx; \r
+                    <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+                    <B>if</B> MatchPrim (next) <B>then</B> <B>begin</B> \r
+                      Result := true; \r
+                      EXIT; \r
+                     <B>end</B>; \r
+                    <I><FONT COLOR="Navy">{$IFDEF ComplexBraces}</FONT></I> \r
+                    System.Move (SavedLoopStack, LoopStack, SizeOf (LoopStack)); \r
+                    LoopStackIdx := SavedLoopStackIdx; \r
+                    <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+                   <B>end</B>; \r
+                  dec (no); <I><FONT COLOR="Navy">// Couldn't or didn't - back up. </FONT></I>\r
+                  reginput := save + no; \r
+                 <B>end</B>; <I><FONT COLOR="Navy">{ of while}</FONT></I> \r
+                EXIT; \r
+           <B>end</B>; \r
+         EEND: <B>begin</B> \r
+            Result := true;  <I><FONT COLOR="Navy">// Success! </FONT></I>\r
+            EXIT; \r
+           <B>end</B>; \r
+        <B>else</B> <B>begin</B> \r
+            Error (reeMatchPrimMemoryCorruption); \r
+            EXIT; \r
+          <B>end</B>; \r
+        <B>end</B>; <I><FONT COLOR="Navy">{ of case scan^}</FONT></I> \r
+        scan := next; \r
+    <B>end</B>; <I><FONT COLOR="Navy">{ of while scan <> nil}</FONT></I> \r
\r
+  <I><FONT COLOR="Navy">// We get here only if there's trouble -- normally "case EEND" is the </FONT></I>\r
+  <I><FONT COLOR="Navy">// terminating point. </FONT></I>\r
+  Error (reeMatchPrimCorruptedPointers); \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.MatchPrim \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{$IFDEF UseFirstCharSet}</FONT></I> <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+<B>procedure</B> TRegExpr.FillFirstCharSet (prog : PRegExprChar); \r
+ <B>var</B> \r
+  scan : PRegExprChar; <I><FONT COLOR="Navy">// Current node. </FONT></I>\r
+  next : PRegExprChar; <I><FONT COLOR="Navy">// Next node. </FONT></I>\r
+  opnd : PRegExprChar; \r
+  min_cnt : integer; \r
+ <B>begin</B> \r
+  scan := prog; \r
+  <B>while</B> scan <> <B>nil</B> <B>do</B> <B>begin</B> \r
+     next := regnext (scan); \r
+     <B>case</B> PREOp (scan)^ <B>of</B> \r
+         BSUBEXP, BSUBEXPCI: <B>begin</B> <I><FONT COLOR="Navy">//###0.938 </FONT></I>\r
+           FirstCharSet := [#0 .. #255]; <I><FONT COLOR="Navy">// :((( we cannot </FONT></I>\r
+           <I><FONT COLOR="Navy">// optimize r.e. if it starts with back reference </FONT></I>\r
+           EXIT; \r
+          <B>end</B>; \r
+         BOL: ; <I><FONT COLOR="Navy">// EXIT; //###0.937 </FONT></I>\r
+         EOL: ; <I><FONT COLOR="Navy">// EXIT; //###0.937 </FONT></I>\r
+         ANY: <B>begin</B> \r
+           FirstCharSet := [#0 .. #255]; <I><FONT COLOR="Navy">//###0.930 </FONT></I>\r
+           EXIT; \r
+          <B>end</B>; \r
+         ANYDIGIT: <B>begin</B> \r
+           FirstCharSet := FirstCharSet + ['0' .. '9']; \r
+           EXIT; \r
+          <B>end</B>; \r
+         NOTDIGIT: <B>begin</B> \r
+           FirstCharSet := [#0 .. #255] - ['0' .. '9']; \r
+           EXIT; \r
+          <B>end</B>; \r
+         EXACTLYCI: <B>begin</B> \r
+           Include (FirstCharSet, (scan + REOpSz + RENextOffSz)^); \r
+           Include (FirstCharSet, InvertCase ((scan + REOpSz + RENextOffSz)^)); \r
+           EXIT; \r
+          <B>end</B>; \r
+         EXACTLY: <B>begin</B> \r
+           Include (FirstCharSet, (scan + REOpSz + RENextOffSz)^); \r
+           EXIT; \r
+          <B>end</B>; \r
+         ANYOFFULLSET: <B>begin</B> \r
+           FirstCharSet := FirstCharSet + PSetOfREChar (scan + REOpSz + RENextOffSz)^; \r
+           EXIT; \r
+          <B>end</B>; \r
+         ANYOFTINYSET: <B>begin</B> \r
+           <I><FONT COLOR="Navy">//!!!TinySet </FONT></I>\r
+           Include (FirstCharSet, (scan + REOpSz + RENextOffSz)^); \r
+           Include (FirstCharSet, (scan + REOpSz + RENextOffSz + 1)^); \r
+           Include (FirstCharSet, (scan + REOpSz + RENextOffSz + 2)^); \r
+           <I><FONT COLOR="Navy">// ...                                                      // up to TinySetLen </FONT></I>\r
+           EXIT; \r
+          <B>end</B>; \r
+         ANYBUTTINYSET: <B>begin</B> \r
+           <I><FONT COLOR="Navy">//!!!TinySet </FONT></I>\r
+           FirstCharSet := [#0 .. #255]; \r
+           Exclude (FirstCharSet, (scan + REOpSz + RENextOffSz)^); \r
+           Exclude (FirstCharSet, (scan + REOpSz + RENextOffSz + 1)^); \r
+           Exclude (FirstCharSet, (scan + REOpSz + RENextOffSz + 2)^); \r
+           <I><FONT COLOR="Navy">// ...                                                      // up to TinySetLen </FONT></I>\r
+           EXIT; \r
+          <B>end</B>; \r
+         NOTHING: ; \r
+         COMMENT: ; \r
+         BACK: ; \r
+         Succ (OPEN) .. TREOp (Ord (OPEN) + NSUBEXP - 1) : <B>begin</B> <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+            FillFirstCharSet (next); \r
+            EXIT; \r
+           <B>end</B>; \r
+         Succ (CLOSE) .. TREOp (Ord (CLOSE) + NSUBEXP - 1): <B>begin</B> <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+            FillFirstCharSet (next); \r
+            EXIT; \r
+           <B>end</B>; \r
+         BRANCH: <B>begin</B> \r
+            <B>if</B> (PREOp (next)^ <> BRANCH) <I><FONT COLOR="Navy">// No choice. </FONT></I>\r
+             <B>then</B> next := scan + REOpSz + RENextOffSz <I><FONT COLOR="Navy">// Avoid recursion. </FONT></I>\r
+             <B>else</B> <B>begin</B> \r
+               <B>REPEAT</B> \r
+                FillFirstCharSet (scan + REOpSz + RENextOffSz); \r
+                scan := regnext (scan); \r
+               <B>UNTIL</B> (scan = <B>nil</B>) <B>or</B> (PREOp (scan)^ <> BRANCH); \r
+               EXIT; \r
+              <B>end</B>; \r
+           <B>end</B>; \r
+         <I><FONT COLOR="Navy">{$IFDEF ComplexBraces}</FONT></I> \r
+         LOOPENTRY: <B>begin</B> <I><FONT COLOR="Navy">//###0.925 </FONT></I>\r
+           LoopStack [LoopStackIdx] := 0; <I><FONT COLOR="Navy">// init loop counter </FONT></I>\r
+           FillFirstCharSet (next); <I><FONT COLOR="Navy">// execute LOOP </FONT></I>\r
+           EXIT; \r
+          <B>end</B>; \r
+         LOOP: <B>begin</B> <I><FONT COLOR="Navy">//###0.925 </FONT></I>\r
+           opnd := scan + PRENextOff (scan + REOpSz + RENextOffSz + REBracesArgSz * 2)^; \r
+           min_cnt := PREBracesArg (scan + REOpSz + RENextOffSz)^; \r
+           FillFirstCharSet (opnd); \r
+           <B>if</B> min_cnt = 0 \r
+            <B>then</B> FillFirstCharSet (next); \r
+           EXIT; \r
+          <B>end</B>; \r
+         <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+         STAR: \r
+           FillFirstCharSet (scan + REOpSz + RENextOffSz); \r
+         PLUS: <B>begin</B> \r
+           FillFirstCharSet (scan + REOpSz + RENextOffSz); \r
+           EXIT; \r
+          <B>end</B>; \r
+         BRACES: <B>begin</B> \r
+           opnd := scan + REOpSz + RENextOffSz + REBracesArgSz * 2; \r
+           min_cnt := PREBracesArg (scan + REOpSz + RENextOffSz)^; <I><FONT COLOR="Navy">// BRACES </FONT></I>\r
+           FillFirstCharSet (opnd); \r
+           <B>if</B> min_cnt > 0 \r
+            <B>then</B> EXIT; \r
+          <B>end</B>; \r
+         EEND: <B>begin</B> \r
+            EXIT; \r
+           <B>end</B>; \r
+        <B>else</B> <B>begin</B> \r
+            Error (reeMatchPrimMemoryCorruption); \r
+            EXIT; \r
+          <B>end</B>; \r
+        <B>end</B>; <I><FONT COLOR="Navy">{ of case scan^}</FONT></I> \r
+        scan := next; \r
+    <B>end</B>; <I><FONT COLOR="Navy">{ of while scan <> nil}</FONT></I> \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of procedure FillFirstCharSet; \r
+--------------------------------------------------------------}</FONT></I> \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<B>function</B> TRegExpr.RegMatch (str : PRegExprChar) : boolean; \r
+<I><FONT COLOR="Navy">// try match at specific point </FONT></I>\r
+ <B>var</B> i : integer; \r
+ <B>begin</B> \r
+  <B>for</B> i := 0 <B>to</B> NSUBEXP - 1 <B>do</B> <B>begin</B> \r
+    startp [i] := <B>nil</B>; \r
+    endp [i] := <B>nil</B>; \r
+   <B>end</B>; \r
+  reginput := str; \r
+  Result := MatchPrim (programm + REOpSz); \r
+  <B>if</B> Result <B>then</B> <B>begin</B> \r
+    startp [0] := str; \r
+    endp [0] := reginput; \r
+   <B>end</B>; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.RegMatch \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.Exec (<B>const</B> AInputString : RegExprString) : boolean; \r
+ <B>begin</B> \r
+  InputString := AInputString; \r
+  Result := ExecPrim (1); \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.Exec \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.ExecPrim (AOffset: integer) : boolean; \r
+ <B>var</B> \r
+  s : PRegExprChar; \r
+  StartPtr: PRegExprChar; \r
+  InputLen : integer; \r
+ <B>begin</B> \r
+  Result := false; <I><FONT COLOR="Navy">// Be paranoid... </FONT></I>\r
\r
+  <B>if</B> <B>not</B> IsProgrammOk <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+   <B>then</B> EXIT; \r
\r
+  <I><FONT COLOR="Navy">// Check InputString presence </FONT></I>\r
+  <B>if</B> <B>not</B> Assigned (fInputString) <B>then</B> <B>begin</B> \r
+    Error (reeNoInpitStringSpecified); \r
+    EXIT; \r
+   <B>end</B>; \r
\r
+  InputLen := length (fInputString); \r
\r
+  <I><FONT COLOR="Navy">//Check that the start position is not negative </FONT></I>\r
+  <B>if</B> AOffset < 1 <B>then</B> <B>begin</B> \r
+    Error (reeOffsetMustBeGreaterThen0); \r
+    EXIT; \r
+   <B>end</B>; \r
+  <I><FONT COLOR="Navy">// Check that the start position is not longer than the line </FONT></I>\r
+  <I><FONT COLOR="Navy">// If so then exit with nothing found </FONT></I>\r
+  <B>if</B> AOffset > (InputLen + 1) <I><FONT COLOR="Navy">// for matching empty string after last char. </FONT></I>\r
+   <B>then</B> EXIT; \r
\r
+  StartPtr := fInputString + AOffset - 1; \r
\r
+  <I><FONT COLOR="Navy">// If there is a "must appear" string, look for it. </FONT></I>\r
+  <B>if</B> regmust <> <B>nil</B> <B>then</B> <B>begin</B> \r
+    s := StartPtr; \r
+    <B>REPEAT</B> \r
+     s := StrScan (s, regmust [0]); \r
+     <B>if</B> s <> <B>nil</B> <B>then</B> <B>begin</B> \r
+       <B>if</B> StrLComp (s, regmust, regmlen) = 0 \r
+        <B>then</B> BREAK; <I><FONT COLOR="Navy">// Found it. </FONT></I>\r
+       inc (s); \r
+      <B>end</B>; \r
+    <B>UNTIL</B> s = <B>nil</B>; \r
+    <B>if</B> s = <B>nil</B> <I><FONT COLOR="Navy">// Not present. </FONT></I>\r
+     <B>then</B> EXIT; \r
+   <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">// Mark beginning of line for ^ . </FONT></I>\r
+  fInputStart := fInputString; \r
\r
+  <I><FONT COLOR="Navy">// Pointer to end of input stream - for </FONT></I>\r
+  <I><FONT COLOR="Navy">// pascal-style string processing (may include #0) </FONT></I>\r
+  fInputEnd := fInputString + InputLen; \r
\r
+  <I><FONT COLOR="Navy">{$IFDEF ComplexBraces}</FONT></I> \r
+  <I><FONT COLOR="Navy">// no loops started </FONT></I>\r
+  LoopStackIdx := 0; <I><FONT COLOR="Navy">//###0.925 </FONT></I>\r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+  <I><FONT COLOR="Navy">// Simplest case:  anchored match need be tried only once. </FONT></I>\r
+  <B>if</B> reganch <> #0 <B>then</B> <B>begin</B> \r
+    Result := RegMatch (StartPtr); \r
+    EXIT; \r
+   <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">// Messy cases:  unanchored match. </FONT></I>\r
+  s := StartPtr; \r
+  <B>if</B> regstart <> #0 <B>then</B> <I><FONT COLOR="Navy">// We know what char it must start with. </FONT></I>\r
+    <B>REPEAT</B> \r
+     s := StrScan (s, regstart); \r
+     <B>if</B> s <> <B>nil</B> <B>then</B> <B>begin</B> \r
+       Result := RegMatch (s); \r
+       <B>if</B> Result \r
+        <B>then</B> EXIT; \r
+       inc (s); \r
+      <B>end</B>; \r
+    <B>UNTIL</B> s = <B>nil</B> \r
+   <B>else</B> <B>begin</B> <I><FONT COLOR="Navy">// We don't - general case. </FONT></I>\r
+     <I><FONT COLOR="Navy">{$IFDEF UseFirstCharSet}</FONT></I> <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+     <B>while</B> s^ <> #0 <B>do</B> <B>begin</B> \r
+       <B>if</B> s^ <B>in</B> FirstCharSet \r
+        <B>then</B> Result := RegMatch (s); \r
+       <B>if</B> Result \r
+        <B>then</B> EXIT; \r
+       inc (s); \r
+      <B>end</B>; \r
+     <I><FONT COLOR="Navy">{$ELSE}</FONT></I> \r
+     <B>REPEAT</B> \r
+      Result := RegMatch (s); \r
+      <B>if</B> Result \r
+       <B>then</B> EXIT; \r
+      inc (s); \r
+     <B>UNTIL</B> s^ = #0; \r
+     <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+    <B>end</B>; \r
+  <I><FONT COLOR="Navy">// Failure </FONT></I>\r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.ExecPrim \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.ExecNext : boolean; \r
+ <B>var</B> offset : integer; \r
+ <B>begin</B> \r
+  Result := false; \r
+  <B>if</B> <B>not</B> Assigned (startp[0]) <B>or</B> <B>not</B> Assigned (endp[0]) <B>then</B> <B>begin</B> \r
+    Error (reeExecNextWithoutExec); \r
+    EXIT; \r
+   <B>end</B>; \r
+<I><FONT COLOR="Navy">//  Offset := MatchPos [0] + MatchLen [0]; </FONT></I>\r
+<I><FONT COLOR="Navy">//  if MatchLen [0] = 0 </FONT></I>\r
+  Offset := endp [0] - fInputString + 1; <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+  <B>if</B> endp [0] = startp [0] <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+   <B>then</B> inc (Offset); <I><FONT COLOR="Navy">// prevent infinite looping if empty string match r.e. </FONT></I>\r
+  Result := ExecPrim (Offset); \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.ExecNext \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.ExecPos (AOffset: integer <I><FONT COLOR="Navy">{$IFDEF D4_}</FONT></I>= 1<I><FONT COLOR="Navy">{$ENDIF}</FONT></I>) : boolean; \r
+ <B>begin</B> \r
+  Result := ExecPrim (AOffset); \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.ExecPos \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.GetInputString : RegExprString; \r
+ <B>begin</B> \r
+  <B>if</B> <B>not</B> Assigned (fInputString) <B>then</B> <B>begin</B> \r
+    Error (reeGetInputStringWithoutInputString); \r
+    EXIT; \r
+   <B>end</B>; \r
+  Result := fInputString; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.GetInputString \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>procedure</B> TRegExpr.SetInputString (<B>const</B> AInputString : RegExprString); \r
+ <B>var</B> \r
+  Len : integer; \r
+  i : integer; \r
+ <B>begin</B> \r
+  <I><FONT COLOR="Navy">// clear Match* - before next Exec* call it's undefined </FONT></I>\r
+  <B>for</B> i := 0 <B>to</B> NSUBEXP - 1 <B>do</B> <B>begin</B> \r
+    startp [i] := <B>nil</B>; \r
+    endp [i] := <B>nil</B>; \r
+   <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">// need reallocation of input string buffer ? </FONT></I>\r
+  Len := length (AInputString); \r
+  <B>if</B> Assigned (fInputString) <B>and</B> (Length (fInputString) <> Len) <B>then</B> <B>begin</B> \r
+    FreeMem (fInputString); \r
+    fInputString := <B>nil</B>; \r
+   <B>end</B>; \r
+  <I><FONT COLOR="Navy">// buffer [re]allocation </FONT></I>\r
+  <B>if</B> <B>not</B> Assigned (fInputString) \r
+   <B>then</B> GetMem (fInputString, (Len + 1) * SizeOf (REChar)); \r
\r
+  <I><FONT COLOR="Navy">// copy input string into buffer </FONT></I>\r
+  <I><FONT COLOR="Navy">{$IFDEF UniCode}</FONT></I> \r
+  StrPCopy (fInputString, Copy (AInputString, 1, Len)); <I><FONT COLOR="Navy">//###0.927 </FONT></I>\r
+  <I><FONT COLOR="Navy">{$ELSE}</FONT></I> \r
+  StrLCopy (fInputString, PRegExprChar (AInputString), Len); \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+  <I><FONT COLOR="Navy">{ \r
+  fInputString : string; \r
+  fInputStart, fInputEnd : PRegExprChar; \r
\r
+  SetInputString: \r
+  fInputString := AInputString; \r
+  UniqueString (fInputString); \r
+  fInputStart := PChar (fInputString); \r
+  Len := length (fInputString); \r
+  fInputEnd := PRegExprChar (integer (fInputStart) + Len); ?? \r
+  !! startp/endp âñå ðàâíî áóäåò îïàñíî èñïîëüçîâàòü ? \r
+  }</FONT></I> \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of procedure TRegExpr.SetInputString \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.Substitute (<B>const</B> ATemplate : RegExprString) : RegExprString; \r
+<I><FONT COLOR="Navy">// perform substitutions after a regexp match </FONT></I>\r
+<I><FONT COLOR="Navy">// completely rewritten in 0.929 </FONT></I>\r
+ <B>var</B> \r
+  TemplateLen : integer; \r
+  TemplateBeg, TemplateEnd : PRegExprChar; \r
+  p, p0, ResultPtr : PRegExprChar; \r
+  ResultLen : integer; \r
+  n : integer; \r
+  Ch : REChar; \r
+ <B>function</B> ParseVarName (<B>var</B> APtr : PRegExprChar) : integer; \r
+  <I><FONT COLOR="Navy">// extract name of variable (digits, may be enclosed with </FONT></I>\r
+  <I><FONT COLOR="Navy">// curly braces) from APtr^, uses TemplateEnd !!! </FONT></I>\r
+  <B>const</B> \r
+   Digits = ['0' .. '9']; \r
+  <B>var</B> \r
+   p : PRegExprChar; \r
+   Delimited : boolean; \r
+  <B>begin</B> \r
+   Result := 0; \r
+   p := APtr; \r
+   Delimited := (p < TemplateEnd) <B>and</B> (p^ = '{'); \r
+   <B>if</B> Delimited \r
+    <B>then</B> inc (p); <I><FONT COLOR="Navy">// skip left curly brace </FONT></I>\r
+   <B>if</B> (p < TemplateEnd) <B>and</B> (p^ = '&') \r
+    <B>then</B> inc (p) <I><FONT COLOR="Navy">// this is '$&' or '${&}' </FONT></I>\r
+    <B>else</B> \r
+     <B>while</B> (p < TemplateEnd) <B>and</B> \r
+      <I><FONT COLOR="Navy">{$IFDEF UniCode}</FONT></I> <I><FONT COLOR="Navy">//###0.935 </FONT></I>\r
+      (ord (p^) < 256) <B>and</B> (char (p^) <B>in</B> Digits) \r
+      <I><FONT COLOR="Navy">{$ELSE}</FONT></I> \r
+      (p^ <B>in</B> Digits) \r
+      <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+       <B>do</B> <B>begin</B> \r
+       inc (Result, ord (p^) - ord ('0')); \r
+       inc (p); \r
+      <B>end</B>; \r
+   <B>if</B> Delimited <B>then</B> \r
+    <B>if</B> (p < TemplateEnd) <B>and</B> (p^ = '}') \r
+     <B>then</B> inc (p) <I><FONT COLOR="Navy">// skip right curly brace </FONT></I>\r
+     <B>else</B> p := APtr; <I><FONT COLOR="Navy">// isn't properly terminated </FONT></I>\r
+   <B>if</B> p = APtr \r
+    <B>then</B> Result := -1; <I><FONT COLOR="Navy">// no valid digits found or no right curly brace </FONT></I>\r
+   APtr := p; \r
+  <B>end</B>; \r
+ <B>begin</B> \r
+  <I><FONT COLOR="Navy">// Check programm and input string </FONT></I>\r
+  <B>if</B> <B>not</B> IsProgrammOk \r
+   <B>then</B> EXIT; \r
+  <B>if</B> <B>not</B> Assigned (fInputString) <B>then</B> <B>begin</B> \r
+    Error (reeNoInpitStringSpecified); \r
+    EXIT; \r
+   <B>end</B>; \r
+  <I><FONT COLOR="Navy">// Prepare for working </FONT></I>\r
+  TemplateLen := length (ATemplate); \r
+  <B>if</B> TemplateLen = 0 <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// prevent nil pointers </FONT></I>\r
+    Result := ''; \r
+    EXIT; \r
+   <B>end</B>; \r
+  TemplateBeg := pointer (ATemplate); \r
+  TemplateEnd := TemplateBeg + TemplateLen; \r
+  <I><FONT COLOR="Navy">// Count result length for speed optimization. </FONT></I>\r
+  ResultLen := 0; \r
+  p := TemplateBeg; \r
+  <B>while</B> p < TemplateEnd <B>do</B> <B>begin</B> \r
+    Ch := p^; \r
+    inc (p); \r
+    <B>if</B> Ch = '$' \r
+     <B>then</B> n := ParseVarName (p) \r
+     <B>else</B> n := -1; \r
+    <B>if</B> n >= 0 <B>then</B> <B>begin</B> \r
+       <B>if</B> (n < NSUBEXP) <B>and</B> Assigned (startp [n]) <B>and</B> Assigned (endp [n]) \r
+        <B>then</B> inc (ResultLen, endp [n] - startp [n]); \r
+      <B>end</B> \r
+     <B>else</B> <B>begin</B> \r
+       <B>if</B> (Ch = '/') <B>and</B> (p < TemplateEnd) \r
+        <B>then</B> inc (p); <I><FONT COLOR="Navy">// quoted or special char followed </FONT></I>\r
+       inc (ResultLen); \r
+      <B>end</B>; \r
+   <B>end</B>; \r
+  <I><FONT COLOR="Navy">// Get memory. We do it once and it significant speed up work ! </FONT></I>\r
+  <B>if</B> ResultLen = 0 <B>then</B> <B>begin</B> \r
+    Result := ''; \r
+    EXIT; \r
+   <B>end</B>; \r
+  SetString (Result, <B>nil</B>, ResultLen); \r
+  <I><FONT COLOR="Navy">// Fill Result </FONT></I>\r
+  ResultPtr := pointer (Result); \r
+  p := TemplateBeg; \r
+  <B>while</B> p < TemplateEnd <B>do</B> <B>begin</B> \r
+    Ch := p^; \r
+    inc (p); \r
+    <B>if</B> Ch = '$' \r
+     <B>then</B> n := ParseVarName (p) \r
+     <B>else</B> n := -1; \r
+    <B>if</B> n >= 0 <B>then</B> <B>begin</B> \r
+       p0 := startp [n]; \r
+       <B>if</B> (n < NSUBEXP) <B>and</B> Assigned (p0) <B>and</B> Assigned (endp [n]) <B>then</B> \r
+        <B>while</B> p0 < endp [n] <B>do</B> <B>begin</B> \r
+          ResultPtr^ := p0^; \r
+          inc (ResultPtr); \r
+          inc (p0); \r
+         <B>end</B>; \r
+      <B>end</B> \r
+     <B>else</B> <B>begin</B> \r
+       <B>if</B> (Ch = '/') <B>and</B> (p < TemplateEnd) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// quoted or special char followed </FONT></I>\r
+         Ch := p^; \r
+         inc (p); \r
+        <B>end</B>; \r
+       ResultPtr^ := Ch; \r
+       inc (ResultPtr); \r
+      <B>end</B>; \r
+   <B>end</B>; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.Substitute \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">(* \r
+function TRegExpr.Substitute (const ATemplate : RegExprString) : RegExprString; \r
+// perform substitutions after a regexp match \r
+ var \r
+  src : integer; // PRegExprChar; //###0.927 \r
+  c, c2 : REChar; \r
+  no : integer; \r
+ begin \r
+  Result := ''; \r
\r
+  if not IsProgrammOk //###0.929 \r
+   then EXIT; \r
\r
+  src := 1; // PRegExprChar (ATemplate); //###0.927 \r
+  while src <= Length (ATemplate) { ^ <> #0} do begin //###0.927 \r
+    c := ATemplate [src]; // src^; //###0.927 \r
+    inc (src); \r
+    c2 := ATemplate [src]; //###0.927 \r
+    if c = '&' \r
+     then no := 0 \r
+     else if (c = '/') and ('0' <= c2) and (c2 <= '9') \r
+          then begin \r
+              no := ord (c2) - ord ('0'); \r
+              inc (src); \r
+             end \r
+          else no := -1; \r
\r
+    if no < 0 then begin // Ordinary character. \r
+       if (c = '/') and ((c2 = '/') or (c2 = '&')) then begin \r
+         c := c2; // src^; \r
+         inc (src); \r
+        end; \r
+       Result := Result + c; \r
+      end \r
+     else Result := Result + Match [no]; //###0.90 \r
+   end; \r
+ end; { of function TRegExpr.Substitute \r
+--------------------------------------------------------------} \r
+*)</FONT></I> \r
\r
+<B>procedure</B> TRegExpr.Split (AInputStr : RegExprString; APieces : TStrings); \r
+ <B>var</B> PrevPos : integer; \r
+ <B>begin</B> \r
+  PrevPos := 1; \r
+  <B>if</B> Exec (AInputStr) <B>then</B> \r
+   <B>REPEAT</B> \r
+    APieces.Add (System.Copy (AInputStr, PrevPos, MatchPos [0] - PrevPos)); \r
+    PrevPos := MatchPos [0] + MatchLen [0]; \r
+   <B>UNTIL</B> <B>not</B> ExecNext; \r
+  APieces.Add (System.Copy (AInputStr, PrevPos, MaxInt)); <I><FONT COLOR="Navy">// Tail </FONT></I>\r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of procedure TRegExpr.Split \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.Replace (AInputStr : RegExprString; <B>const</B> AReplaceStr : RegExprString) : RegExprString; \r
+ <B>var</B> PrevPos : integer; \r
+ <B>begin</B> \r
+  Result := ''; \r
+  PrevPos := 1; \r
+  <B>if</B> Exec (AInputStr) <B>then</B> \r
+   <B>REPEAT</B> \r
+    Result := Result + System.Copy (AInputStr, PrevPos, \r
+      MatchPos [0] - PrevPos) + AReplaceStr; \r
+    PrevPos := MatchPos [0] + MatchLen [0]; \r
+   <B>UNTIL</B> <B>not</B> ExecNext; \r
+  Result := Result + System.Copy (AInputStr, PrevPos, MaxInt); <I><FONT COLOR="Navy">// Tail </FONT></I>\r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.Replace \r
+--------------------------------------------------------------}</FONT></I> \r
\r
\r
+<I><FONT COLOR="Navy">{=============================================================}</FONT></I> \r
+<I><FONT COLOR="Navy">{====================== Debug section ========================}</FONT></I> \r
+<I><FONT COLOR="Navy">{=============================================================}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{$IFDEF DebugRegExpr}</FONT></I> \r
+<B>function</B> TRegExpr.DumpOp (op : TREOp) : RegExprString; \r
+<I><FONT COLOR="Navy">// printable representation of opcode </FONT></I>\r
+ <B>begin</B> \r
+  <B>case</B> op <B>of</B> \r
+    BOL:          Result := 'BOL'; \r
+    EOL:          Result := 'EOL'; \r
+    ANY:          Result := 'ANY'; \r
+    ANYLETTER:    Result := 'ANYLETTER'; \r
+    NOTLETTER:    Result := 'NOTLETTER'; \r
+    ANYDIGIT:     Result := 'ANYDIGIT'; \r
+    NOTDIGIT:     Result := 'NOTDIGIT'; \r
+    ANYSPACE:     Result := 'ANYSPACE'; \r
+    NOTSPACE:     Result := 'NOTSPACE'; \r
+    ANYOF:        Result := 'ANYOF'; \r
+    ANYBUT:       Result := 'ANYBUT'; \r
+    ANYOFCI:      Result := 'ANYOF/CI'; \r
+    ANYBUTCI:     Result := 'ANYBUT/CI'; \r
+    BRANCH:       Result := 'BRANCH'; \r
+    EXACTLY:      Result := 'EXACTLY'; \r
+    EXACTLYCI:    Result := 'EXACTLY/CI'; \r
+    NOTHING:      Result := 'NOTHING'; \r
+    COMMENT:      Result := 'COMMENT'; \r
+    BACK:         Result := 'BACK'; \r
+    EEND:         Result := 'END'; \r
+    BSUBEXP:      Result := 'BSUBEXP'; \r
+    BSUBEXPCI:    Result := 'BSUBEXP/CI'; \r
+    Succ (OPEN) .. TREOp (Ord (OPEN) + NSUBEXP - 1): <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+                  Result := Format ('OPEN[%d]', [ord (op) - ord (OPEN)]); \r
+    Succ (CLOSE) .. TREOp (Ord (CLOSE) + NSUBEXP - 1): <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+                  Result := Format ('CLOSE[%d]', [ord (op) - ord (CLOSE)]); \r
+    STAR:         Result := 'STAR'; \r
+    PLUS:         Result := 'PLUS'; \r
+    BRACES:       Result := 'BRACES'; \r
+    <I><FONT COLOR="Navy">{$IFDEF ComplexBraces}</FONT></I> \r
+    LOOPENTRY:    Result := 'LOOPENTRY'; <I><FONT COLOR="Navy">//###0.925 </FONT></I>\r
+    LOOP:         Result := 'LOOP'; <I><FONT COLOR="Navy">//###0.925 </FONT></I>\r
+    <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+    ANYOFTINYSET: Result:= 'ANYOFTINYSET'; \r
+    ANYBUTTINYSET:Result:= 'ANYBUTTINYSET'; \r
+    <I><FONT COLOR="Navy">{$IFDEF UseSetOfChar}</FONT></I> <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+    ANYOFFULLSET: Result:= 'ANYOFFULLSET'; \r
+    <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+    <B>else</B> Error (reeDumpCorruptedOpcode); \r
+   <B>end</B>; <I><FONT COLOR="Navy">{of case op}</FONT></I> \r
+  Result := ':' + Result; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.DumpOp \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<B>function</B> TRegExpr.Dump : RegExprString; \r
+<I><FONT COLOR="Navy">// dump a regexp in vaguely comprehensible form </FONT></I>\r
+ <B>var</B> \r
+  s : PRegExprChar; \r
+  op : TREOp; <I><FONT COLOR="Navy">// Arbitrary non-END op. </FONT></I>\r
+  next : PRegExprChar; \r
+  i : integer; \r
+<I><FONT COLOR="Navy">{$IFDEF UseSetOfChar}</FONT></I> <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+  Ch : REChar; \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+ <B>begin</B> \r
+  <B>if</B> <B>not</B> IsProgrammOk <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+   <B>then</B> EXIT; \r
\r
+  op := EXACTLY; \r
+  Result := ''; \r
+  s := programm + REOpSz; \r
+  <B>while</B> op <> EEND <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// While that wasn't END last time... </FONT></I>\r
+     op := s^; \r
+     Result := Result + Format ('%2d%s', [s - programm, DumpOp (s^)]); <I><FONT COLOR="Navy">// Where, what. </FONT></I>\r
+     next := regnext (s); \r
+     <B>if</B> next = <B>nil</B> <I><FONT COLOR="Navy">// Next ptr. </FONT></I>\r
+      <B>then</B> Result := Result + ' (0)' \r
+      <B>else</B> Result := Result + Format (' (%d) ', [(s - programm) + (next - s)]); \r
+     inc (s, REOpSz + RENextOffSz); \r
+     <B>if</B> (op = ANYOF) <B>or</B> (op = ANYOFCI) <B>or</B> (op = ANYBUT) <B>or</B> (op = ANYBUTCI) \r
+        <B>or</B> (op = EXACTLY) <B>or</B> (op = EXACTLYCI) <B>then</B> <B>begin</B> \r
+         <I><FONT COLOR="Navy">// Literal string, where present. </FONT></I>\r
+         <B>while</B> s^ <> #0 <B>do</B> <B>begin</B> \r
+           Result := Result + s^; \r
+           inc (s); \r
+          <B>end</B>; \r
+         inc (s); \r
+      <B>end</B>; \r
+     <B>if</B> (op = ANYOFTINYSET) <B>or</B> (op = ANYBUTTINYSET) <B>then</B> <B>begin</B> \r
+       <B>for</B> i := 1 <B>to</B> TinySetLen <B>do</B> <B>begin</B> \r
+         Result := Result + s^; \r
+         inc (s); \r
+        <B>end</B>; \r
+      <B>end</B>; \r
+     <B>if</B> (op = BSUBEXP) <B>or</B> (op = BSUBEXPCI) <B>then</B> <B>begin</B> \r
+       Result := Result + ' /' + IntToStr (Ord (s^)); \r
+       inc (s); \r
+      <B>end</B>; \r
+     <I><FONT COLOR="Navy">{$IFDEF UseSetOfChar}</FONT></I> <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+     <B>if</B> op = ANYOFFULLSET <B>then</B> <B>begin</B> \r
+       <B>for</B> Ch := #0 <B>to</B> #255 <B>do</B> \r
+        <B>if</B> Ch <B>in</B> PSetOfREChar (s)^ <B>then</B> \r
+         <B>if</B> Ch < ' ' \r
+          <B>then</B> Result := Result + '#' + IntToStr (Ord (Ch)) <I><FONT COLOR="Navy">//###0.936 </FONT></I>\r
+          <B>else</B> Result := Result + Ch; \r
+       inc (s, SizeOf (TSetOfREChar)); \r
+      <B>end</B>; \r
+     <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+     <B>if</B> (op = BRACES) <B>then</B> <B>begin</B> \r
+       <I><FONT COLOR="Navy">// show min/max argument of BRACES operator </FONT></I>\r
+       Result := Result + Format ('{%d,%d}', [PREBracesArg (s)^, PREBracesArg (s + REBracesArgSz)^]); \r
+       inc (s, REBracesArgSz * 2); \r
+      <B>end</B>; \r
+     <I><FONT COLOR="Navy">{$IFDEF ComplexBraces}</FONT></I> \r
+     <B>if</B> op = LOOP <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">//###0.925 </FONT></I>\r
+       Result := Result + Format (' -> (%d) {%d,%d}', [ \r
+        (s - programm - (REOpSz + RENextOffSz)) + PRENextOff (s + 2 * REBracesArgSz)^, \r
+        PREBracesArg (s)^, PREBracesArg (s + REBracesArgSz)^]); \r
+       inc (s, 2 * REBracesArgSz + RENextOffSz); \r
+      <B>end</B>; \r
+     <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+     Result := Result + #$d#$a; \r
+   <B>end</B>; <I><FONT COLOR="Navy">{ of while}</FONT></I> \r
\r
+  <I><FONT COLOR="Navy">// Header fields of interest. </FONT></I>\r
\r
+  <B>if</B> regstart <> #0 \r
+   <B>then</B> Result := Result + 'start ' + regstart; \r
+  <B>if</B> reganch <> #0 \r
+   <B>then</B> Result := Result + 'anchored '; \r
+  <B>if</B> regmust <> <B>nil</B> \r
+   <B>then</B> Result := Result + 'must have ' + regmust; \r
+  <I><FONT COLOR="Navy">{$IFDEF UseFirstCharSet}</FONT></I> <I><FONT COLOR="Navy">//###0.929 </FONT></I>\r
+  Result := Result + #$d#$a'FirstCharSet:'; \r
+  <B>for</B> Ch := #0 <B>to</B> #255 <B>do</B> \r
+   <B>if</B> Ch <B>in</B> FirstCharSet \r
+    <B>then</B> Result := Result + Ch; \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+  Result := Result + #$d#$a; \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of function TRegExpr.Dump \r
+--------------------------------------------------------------}</FONT></I> \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{$IFDEF reRealExceptionAddr}</FONT></I> \r
+<I><FONT COLOR="Navy">{$OPTIMIZATION ON}</FONT></I> \r
+<I><FONT COLOR="Navy">// ReturnAddr works correctly only if compiler optimization is ON </FONT></I>\r
+<I><FONT COLOR="Navy">// I placed this method at very end of unit because there are no </FONT></I>\r
+<I><FONT COLOR="Navy">// way to restore compiler optimization flag ... </FONT></I>\r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+<B>procedure</B> TRegExpr.Error (AErrorID : integer); \r
+<I><FONT COLOR="Navy">{$IFDEF reRealExceptionAddr}</FONT></I> \r
+ <B>function</B> ReturnAddr : pointer; <I><FONT COLOR="Navy">//###0.938 </FONT></I>\r
+  <B>asm</B> \r
+   mov  eax,[ebp+4] \r
+  <B>end</B>; \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+ <B>var</B> \r
+  e : ERegExpr; \r
+ <B>begin</B> \r
+  fLastError := AErrorID; <I><FONT COLOR="Navy">// dummy stub - useless because will raise exception </FONT></I>\r
+  <B>if</B> AErrorID < 1000 <I><FONT COLOR="Navy">// compilation error ? </FONT></I>\r
+   <B>then</B> e := ERegExpr.Create (ErrorMsg (AErrorID) <I><FONT COLOR="Navy">// yes - show error pos </FONT></I>\r
+             + ' (pos ' + IntToStr (CompilerErrorPos) + ')') \r
+   <B>else</B> e := ERegExpr.Create (ErrorMsg (AErrorID)); \r
+  e.ErrorCode := AErrorID; \r
+  e.CompilerErrorPos := CompilerErrorPos; \r
+  <B>raise</B> e \r
+   <I><FONT COLOR="Navy">{$IFDEF reRealExceptionAddr}</FONT></I> \r
+   At ReturnAddr; <I><FONT COLOR="Navy">//###0.938 </FONT></I>\r
+   <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+ <B>end</B>; <I><FONT COLOR="Navy">{ of procedure TRegExpr.Error \r
+--------------------------------------------------------------}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">// be carefull - placed here code will be always compiled with </FONT></I>\r
+<I><FONT COLOR="Navy">// compiler optimization flag </FONT></I>\r
\r
+<B>end</B>. \r
\r
\r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/auxiliares/SerializacionUtils.pas b/doc/src-html/auxiliares/SerializacionUtils.pas
new file mode 100644 (file)
index 0000000..c0a64df
--- /dev/null
@@ -0,0 +1,64 @@
+<HTML><HEAD>\r
+<TITLE>File: serializacionutils.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=serializacionutils.pas><CENTER><H3>serializacionutils.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Funciones útiles para complementar la utilización de la serialización en \r
+    este modelo en particular}</FONT></I> \r
+<B>unit</B> SerializacionUtils; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  ObjetoVolador; \r
\r
+  <I><FONT COLOR="Navy">{** Crea un objeto a partir de un string con el nombre de su clase y otro \r
+      con su representación serializada.}</FONT></I> \r
+  <B>function</B> <A HREF="#restaurarObjeto">restaurarObjeto</A>( clase, str: <B>string</B> ): cObjetoVolador; \r
\r
+<B>implementation</B> \r
\r
+<B>uses</B> \r
+  ObjetoPersistente, \r
+  Armas, \r
+  NavesEnemigas, \r
+  NavePropia, \r
+  Meteorito; \r
\r
+<I><FONT COLOR="Navy">{** Crea un objeto a partir de un string con el nombre de su clase y otro \r
+    con su representación serializada. \r
+    @param  clase Clase del Objeto \r
+    @param  str   Representación del objeto serializado \r
+    @return Puntero al nuevo objeto.}</FONT></I> \r
+<B>function</B> <A NAME=restaurarObjeto>restaurarObjeto</A>( clase, str: <B>string</B> ): cObjetoVolador; \r
+<B>begin</B> \r
+  <B>if</B> clase = 'cMeteorito' <B>then</B> \r
+    result := cMeteorito.crearDeSerializado( str ) \r
+  <B>else</B> <B>if</B> clase = 'cLaser' <B>then</B> \r
+    result := cLaser.crearDeSerializado( str ) \r
+  <B>else</B> <B>if</B> clase = 'cMisil' <B>then</B> \r
+    result := cMisil.crearDeSerializado( str ) \r
+  <B>else</B> <B>if</B> clase = 'cMisilDirigido' <B>then</B> \r
+    result := cMisilDirigido.crearDeSerializado( str ) \r
+  <B>else</B> <B>if</B> clase = 'cNavePropia' <B>then</B> \r
+    result := cNavePropia.crearDeSerializado( str ) \r
+  <B>else</B> <B>if</B> clase = 'cNavePesada' <B>then</B> \r
+    result := cNavePesada.crearDeSerializado( str ) \r
+  <B>else</B> <B>if</B> clase = 'cNaveLiviana' <B>then</B> \r
+    result := cNaveLiviana.crearDeSerializado( str ) \r
+  <B>else</B> <B>if</B> clase = 'cNaveEspia' <B>then</B> \r
+    result := cNaveEspia.crearDeSerializado( str ) \r
+  <B>else</B> <B>if</B> clase = 'cNaveSuicida' <B>then</B> \r
+    result := cNaveSuicida.crearDeSerializado( str ) \r
+  <B>else</B> \r
+    <B>raise</B> ESerializacion.create( 'No se puede crear un objeto de la clase "' + \r
+                                 clase + '". Clase Desconocida!' ); \r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/auxiliares/Tipos.pas b/doc/src-html/auxiliares/Tipos.pas
new file mode 100644 (file)
index 0000000..a9f159e
--- /dev/null
@@ -0,0 +1,40 @@
+<HTML><HEAD>\r
+<TITLE>File: tipos.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=tipos.pas><CENTER><H3>tipos.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** En esta unidad se definen todos los tipos que usaremos en el proyecto \r
+    Decidimos mantener los tipos por separado por el caso de que sea \r
+    necesario un cambio de implementacion.}</FONT></I> \r
+<B>unit</B> Tipos; \r
\r
+<B>interface</B> \r
\r
+<B>type</B> \r
+  tLongitud = extended;  <I><FONT COLOR="Navy">// en metros </FONT></I>\r
+  tTiempo   = extended;  <I><FONT COLOR="Navy">// en milisegundos </FONT></I>\r
+  tEnergia  = integer; \r
+  tAngulo   = extended;  <I><FONT COLOR="Navy">// en radianes </FONT></I>\r
+  tMaxMisil = 0..10; \r
+  tMaxMisilDirigido = 0..5; \r
+  <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+  tDebugInfo = ( DI_MINI, DI_NORMAL, DI_MAXI ); <I><FONT COLOR="Navy">// Cantidad de Informacion a presentar </FONT></I>\r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+  <I><FONT COLOR="Navy">// Tipos de objetos voladores </FONT></I>\r
+  tObjetosVoladores = ( OV_NAVEPESADA, OV_NAVELIVIANA, OV_NAVEESPIA, OV_NAVESUICIDA, \r
+                        OV_METEORITO, OV_NAVEPROPIA, OV_LASER, OV_MISIL, OV_MISDIR ); \r
+  <I><FONT COLOR="Navy">// Tipos de armas </FONT></I>\r
+  tArma = OV_LASER..OV_MISDIR; <I><FONT COLOR="Navy">// Tipo de arma Seleccionada (subrango de tObjetosVoladores) </FONT></I>\r
+  <I><FONT COLOR="Navy">//Tipos de camaras </FONT></I>\r
+  tCamaras = ( CAMARA_FRONTAL, CAMARA_LATDER, CAMARA_LATIZQ, CAMARA_TRASERA, \r
+               CAMARA_ARRIBA, CAMARA_ABAJO, CAMARA_MAPA, CAMARA_ARMA ); \r
\r
+<B>implementation</B> \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/forms/FormConfig.pas b/doc/src-html/forms/FormConfig.pas
new file mode 100644 (file)
index 0000000..1ec820b
--- /dev/null
@@ -0,0 +1,380 @@
+<HTML><HEAD>\r
+<TITLE>File: formconfig.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=formconfig.pas><CENTER><H3>formconfig.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Formulario para configurar la aplicación}</FONT></I> \r
+<B>unit</B> FormConfig; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, \r
+  StdCtrls, ExtCtrls, \r
+  ObjetoVolador; \r
\r
+<B>type</B> \r
+  <I><FONT COLOR="Navy">{** Formulario para configurar la aplicación}</FONT></I> \r
+  TConfigForm = <B>class</B>(TForm) \r
+    aGrpBoxNavePropia: TGroupBox; \r
+    aLblPosicionNP: TLabel; \r
+    aLblVelocidadNP: TLabel; \r
+    aGrpBoxNuevoOV: TGroupBox; \r
+    aLblPosicionOV: TLabel; \r
+    aLblVelocidadOV: TLabel; \r
+    aLblZ: TLabel; \r
+    aLblY: TLabel; \r
+    aLblX: TLabel; \r
+    aRdGrpTipoOV: TRadioGroup; \r
+    aEditOVPosX: TEdit; \r
+    aEditOVPosY: TEdit; \r
+    aEditOVPosZ: TEdit; \r
+    aEditOVVelX: TEdit; \r
+    aEditOVVelY: TEdit; \r
+    aEditOVVelZ: TEdit; \r
+    aBtnAgregar: TButton; \r
+    aEditNPVelX: TEdit; \r
+    aEditNPVelY: TEdit; \r
+    aEditNPVelZ: TEdit; \r
+    aEditNPPosX: TEdit; \r
+    aEditNPPosY: TEdit; \r
+    aEditNPPosZ: TEdit; \r
+    aGrpBoxListaOV: TGroupBox; \r
+    aListBoxObjetos: TListBox; \r
+    aBtnQuitar: TButton; \r
+    aBtnAceptar: TButton; \r
+    aBtnCancelar: TButton; \r
+    <B>procedure</B> <A HREF="#TConfigForm.aBtnAgregarClick">aBtnAgregarClick</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TConfigForm.aBtnCancelarClick">aBtnCancelarClick</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TConfigForm.aBtnAceptarClick">aBtnAceptarClick</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TConfigForm.aBtnQuitarClick">aBtnQuitarClick</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TConfigForm.mValidar">mValidar</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TConfigForm.FormShow">FormShow</A>(Sender: TObject); \r
+  <B>private</B> \r
+    <I><FONT COLOR="Navy">{ Private declarations }</FONT></I> \r
+    <I><FONT COLOR="Navy">{** Crea un objeto volador dependiendo del tipo que se eligió en los radio buttons}</FONT></I> \r
+    <B>function</B> <A HREF="#TConfigForm.mCrearOV">mCrearOV</A>(indice: integer): cObjetoVolador; \r
+    <I><FONT COLOR="Navy">{** Obtiene una cadena compatible con los radio buttons dependiendo de la clase del objeto}</FONT></I> \r
+    <B>function</B> <A HREF="#mClassToStr">mClassToStr</A>( oOV: cObjetoVolador ): <B>string</B>; \r
+    <I><FONT COLOR="Navy">{** Obtiene el indice compatible con los radio buttons dependiendo de la clase del objeto}</FONT></I> \r
+    <B>function</B> <A HREF="#mClassToIndex">mClassToIndex</A>(oOV: cObjetoVolador): integer; \r
+  <B>public</B> \r
+    <I><FONT COLOR="Navy">{ Public declarations }</FONT></I> \r
+  <B>end</B>; \r
\r
+<B>var</B> \r
+  ConfigForm: TConfigForm; \r
\r
+<B>implementation</B> \r
\r
+<I><FONT COLOR="Navy">{$R *.DFM}</FONT></I> \r
\r
+<B>uses</B> \r
+  FormMain, \r
+  RegExpr, \r
+  Vectores, \r
+  NavesEnemigas, \r
+  Meteorito, \r
+  Armas, \r
+  NavePropia; \r
\r
+<B>procedure</B> <A NAME=TConfigForm.aBtnAgregarClick>TConfigForm.aBtnAgregarClick</A>(Sender: TObject); \r
+<B>var</B> \r
+  oOV: cObjetoVolador; \r
+  oPos, \r
+  oVel: cVector; \r
+<B>begin</B> \r
+  <B>if</B> aRdGrpTipoOV.ItemIndex > -1 <B>then</B> <B>begin</B> \r
+    oOV := mCrearOV( aRdGrpTipoOV.ItemIndex ); \r
+    oPos := oOV.mGetPosicion; \r
+    oVel := oOV.mGetVelocidad; \r
+    aListBoxObjetos.Items.AddObject( aRdGrpTipoOV.Items[aRdGrpTipoOV.ItemIndex] + \r
+                               '; (' + FloatToStrF( oPos.mGetX, ffGeneral, 5, 5 ) + \r
+                               ';' + FloatToStrF( oPos.mGetY, ffGeneral, 5, 5 ) + \r
+                               ';' + FloatToStrF( oPos.mGetZ, ffGeneral, 5, 5 ) + ')' + \r
+                               '; (' + FloatToStrF( oVel.mGetX, ffGeneral, 5, 5 ) + \r
+                               ';' + FloatToStrF( oVel.mGetY, ffGeneral, 5, 5 ) + \r
+                               ';' + FloatToStrF( oVel.mGetZ, ffGeneral, 5, 5 ) + ')', \r
+                               oOV ); \r
+    oPos.free; \r
+    oVel.free; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TConfigForm.aBtnCancelarClick>TConfigForm.aBtnCancelarClick</A>(Sender: TObject); \r
+<B>var</B> \r
+  oOV: cObjetoVolador; \r
+  i:   integer; \r
+  oObjetos: TList; \r
+<B>begin</B> \r
+  oObjetos := MainForm.mGetObjetos; \r
+  i := 0; \r
+  <B>while</B> i < aListBoxObjetos.Items.Count <B>do</B> <B>begin</B> \r
+    aListBoxObjetos.ItemIndex := i; \r
+    oOV := cObjetoVolador( aListBoxObjetos.Items.Objects[i] ); \r
+    <B>if</B> oObjetos.IndexOf( oOV ) = -1 <B>then</B> \r
+      aBtnQuitarClick( Sender ) \r
+    <B>else</B> \r
+      i := i + 1; \r
+  <B>end</B>; \r
+  Close; \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TConfigForm.aBtnAceptarClick>TConfigForm.aBtnAceptarClick</A>(Sender: TObject); \r
+<B>var</B> \r
+  oOV: cObjetoVolador; \r
+  i:   integer; \r
+  oObjetos: TList; \r
+  oPos, \r
+  oVel: cVector; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Se modifican los valores de la nave propia </FONT></I>\r
+  oPos := cVector.create( StrToFloat( aEditNPPosX.Text ), StrToFloat( aEditNPPosY.Text ), StrToFloat( aEditNPPosZ.Text ) ); \r
+  oVel := cVector.create( StrToFloat( aEditNPVelX.Text ), StrToFloat( aEditNPVelY.Text ), StrToFloat( aEditNPVelZ.Text ) ); \r
+  MainForm.mGetNavePropia.mSetPosicion( oPos ); \r
+  MainForm.mGetNavePropia.mSetVelocidad( oVel ); \r
+  oPos.free; \r
+  oVel.free; \r
+  <I><FONT COLOR="Navy">// Se sincronizan las listas de objetos (la del formulario con la de la list box) </FONT></I>\r
+  oObjetos := MainForm.mGetObjetos; \r
+  i := 0; \r
+  <B>while</B> i < oObjetos.Count <B>do</B> <B>begin</B> \r
+    oOV := cObjetoVolador( oObjetos.Items[i] ); \r
+    <B>if</B> aListBoxObjetos.Items.IndexOfObject( oOV ) = -1 <B>then</B> <B>begin</B> \r
+      oObjetos.Delete( i ); \r
+      oOV.free; \r
+    <B>end</B> <B>else</B> \r
+      i := i + 1; \r
+  <B>end</B>; \r
+  <B>for</B> i := 0 <B>to</B> aListBoxObjetos.Items.Count - 1 <B>do</B> <B>begin</B> \r
+    aListBoxObjetos.ItemIndex := i; \r
+    oOV := cObjetoVolador( aListBoxObjetos.Items.Objects[i] ); \r
+    <B>if</B> oObjetos.IndexOf( oOV ) = -1 <B>then</B> \r
+      oObjetos.Add( oOV ); \r
+  <B>end</B>; \r
+  Close; \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TConfigForm.aBtnQuitarClick>TConfigForm.aBtnQuitarClick</A>(Sender: TObject); \r
+<B>var</B> \r
+  oObjetos: TList; \r
+  oOV:      cObjetoVolador; \r
+  oPos, \r
+  oVel:     cVector; \r
+<B>begin</B> \r
+  oObjetos := MainForm.mGetObjetos; \r
+  <B>if</B> (aListBoxObjetos.ItemIndex > -1) <B>and</B> (aListBoxObjetos.Items.Count > 0 ) <B>then</B> <B>begin</B> \r
+    oOV := cObjetoVolador( aListBoxObjetos.Items.Objects[aListBoxObjetos.ItemIndex] ); \r
+    oPos := oOV.mGetPosicion; \r
+    oVel := oOV.mGetVelocidad; \r
+    aEditOVPosX.Text := FloatToStrF( oPos.mGetX, ffGeneral, 5, 5 ); \r
+    aEditOVPosY.Text := FloatToStrF( oPos.mGetY, ffGeneral, 5, 5 ); \r
+    aEditOVPosZ.Text := FloatToStrF( oPos.mGetZ, ffGeneral, 5, 5 ); \r
+    aEditOVVelX.Text := FloatToStrF( oVel.mGetX, ffGeneral, 5, 5 ); \r
+    aEditOVVelY.Text := FloatToStrF( oVel.mGetY, ffGeneral, 5, 5 ); \r
+    aEditOVVelZ.Text := FloatToStrF( oVel.mGetZ, ffGeneral, 5, 5 ); \r
+    aListBoxObjetos.Items.Delete( aListBoxObjetos.ItemIndex ); \r
+    aRdGrpTipoOV.ItemIndex := mClassToIndex( oOV ); \r
+    <B>if</B> oObjetos.IndexOf( oOV ) = -1 <B>then</B> \r
+      oOV.free; \r
+    oPos.free; \r
+    oVel.free; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Crea un objeto volador dependiendo del tipo que se eligió en los radio buttons \r
+    @param  indice Indice del radio button \r
+    @return Objeto Volador de la clase apropiada}</FONT></I> \r
+<B>function</B> <A NAME=TConfigForm.mCrearOV>TConfigForm.mCrearOV</A>( indice: integer ): cObjetoVolador; \r
+<B>var</B> \r
+  oOV: cObjetoVolador; \r
+  oPos: cVector; \r
+  oVel: cVector; \r
+<B>begin</B> \r
+    <B>case</B> indice <B>of</B> \r
+      0: <B>begin</B> \r
+        oPos := cVector.create( StrToFloat( aEditOVPosX.Text ), StrToFloat( aEditOVPosY.Text ), StrToFloat( aEditOVPosZ.Text ) ); \r
+        oVel := cVector.create( StrToFloat( aEditOVVelX.Text ), StrToFloat( aEditOVVelY.Text ), StrToFloat( aEditOVVelZ.Text ) ); \r
+        oOV := cNavePesada.create( oPos, oVel ); \r
+        oPos.free; \r
+        oVel.free; \r
+      <B>end</B>; \r
+      1: <B>begin</B> \r
+        oPos := cVector.create( StrToFloat( aEditOVPosX.Text ), StrToFloat( aEditOVPosY.Text ), StrToFloat( aEditOVPosZ.Text ) ); \r
+        oVel := cVector.create( StrToFloat( aEditOVVelX.Text ), StrToFloat( aEditOVVelY.Text ), StrToFloat( aEditOVVelZ.Text ) ); \r
+        oOV := cNaveLiviana.create( oPos, oVel ); \r
+        oPos.free; \r
+        oVel.free; \r
+      <B>end</B>; \r
+      2: <B>begin</B> \r
+        oPos := cVector.create( StrToFloat( aEditOVPosX.Text ), StrToFloat( aEditOVPosY.Text ), StrToFloat( aEditOVPosZ.Text ) ); \r
+        oVel := cVector.create( StrToFloat( aEditOVVelX.Text ), StrToFloat( aEditOVVelY.Text ), StrToFloat( aEditOVVelZ.Text ) ); \r
+        oOV := cNaveSuicida.create( oPos, oVel ); \r
+        oPos.free; \r
+        oVel.free; \r
+      <B>end</B>; \r
+      3: <B>begin</B> \r
+        oPos := cVector.create( StrToFloat( aEditOVPosX.Text ), StrToFloat( aEditOVPosY.Text ), StrToFloat( aEditOVPosZ.Text ) ); \r
+        oVel := cVector.create( StrToFloat( aEditOVVelX.Text ), StrToFloat( aEditOVVelY.Text ), StrToFloat( aEditOVVelZ.Text ) ); \r
+        oOV := cNaveEspia.create( oPos, oVel ); \r
+        oPos.free; \r
+        oVel.free; \r
+      <B>end</B>; \r
+      4: <B>begin</B> \r
+        oPos := cVector.create( StrToFloat( aEditOVPosX.Text ), StrToFloat( aEditOVPosY.Text ), StrToFloat( aEditOVPosZ.Text ) ); \r
+        oVel := cVector.create( StrToFloat( aEditOVVelX.Text ), StrToFloat( aEditOVVelY.Text ), StrToFloat( aEditOVVelZ.Text ) ); \r
+        oOV := cMeteorito.create( oPos, oVel ); \r
+        oPos.free; \r
+        oVel.free; \r
+      <B>end</B>; \r
+      5: <B>begin</B> \r
+        oPos := cVector.create( StrToFloat( aEditOVPosX.Text ), StrToFloat( aEditOVPosY.Text ), StrToFloat( aEditOVPosZ.Text ) ); \r
+        oVel := cVector.create( StrToFloat( aEditOVVelX.Text ), StrToFloat( aEditOVVelY.Text ), StrToFloat( aEditOVVelZ.Text ) ); \r
+        oOV := cLaser.create( oPos, oVel ); \r
+        oPos.free; \r
+        oVel.free; \r
+      <B>end</B>; \r
+      6: <B>begin</B> \r
+        oPos := cVector.create( StrToFloat( aEditOVPosX.Text ), StrToFloat( aEditOVPosY.Text ), StrToFloat( aEditOVPosZ.Text ) ); \r
+        oVel := cVector.create( StrToFloat( aEditOVVelX.Text ), StrToFloat( aEditOVVelY.Text ), StrToFloat( aEditOVVelZ.Text ) ); \r
+        oOV := cMisil.create( oPos, oVel ); \r
+        oPos.free; \r
+        oVel.free; \r
+      <B>end</B>; \r
+      7: <B>begin</B> \r
+        oPos := cVector.create( StrToFloat( aEditOVPosX.Text ), StrToFloat( aEditOVPosY.Text ), StrToFloat( aEditOVPosZ.Text ) ); \r
+        oOV := cMisilDirigido.create( MainForm.mGetNavePropia, oPos ); \r
+        oPos.free; \r
+      <B>end</B>; \r
+    <B>end</B>; \r
+    result := oOV; \r
+<B>end</B>; \r
+<B>procedure</B> <A NAME=TConfigForm.mValidar>TConfigForm.mValidar</A>(Sender: TObject); \r
+<B>const</B> \r
+  <I><FONT COLOR="Navy">// Expresion regular para hallar número un real </FONT></I>\r
+  PATTERN = '^[+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?$'; \r
+<B>var</B> \r
+  r :  TRegExpr; \r
+<B>begin</B> \r
+  <B>with</B> Sender <B>as</B> TEdit <B>do</B> <B>begin</B> \r
+    r := TRegExpr.Create; <I><FONT COLOR="Navy">// Create object </FONT></I>\r
+    <B>try</B> <I><FONT COLOR="Navy">// ensure memory release </FONT></I>\r
+      r.Expression := PATTERN; \r
+      <B>if</B> <B>not</B> r.Exec( Text ) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si no es un real </FONT></I>\r
+        ShowMessage( 'El valor "' + Text + '" no es válido. ' + \r
+                     'Por favor ingrese un valor real expresado con "," para separar los decimales ' + \r
+                     'o expresado en forma científica (con exponente). Ejemplos:' + #13 + #10 + \r
+                     '  10,5'   + #13 + #10 + \r
+                     '  -4,1'   + #13 + #10 + \r
+                     '  10e5'   + #13 + #10 + \r
+                     '  -23e-5' + #13 + #10 + \r
+                     '  98e-5'  + #13 + #10 ); \r
+        Text := '0'; \r
+        SetFocus; \r
+      <B>end</B>; \r
+    <B>finally</B> \r
+      r.Free; \r
+    <B>end</B>; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TConfigForm.FormShow>TConfigForm.FormShow</A>(Sender: TObject); \r
+<B>var</B> \r
+  oOV:      cObjetoVolador; \r
+  i:        integer; \r
+  oObjetos: TList; \r
+  oPos, \r
+  oVel:     cVector; \r
+  tipo:     <B>string</B>; \r
+<B>begin</B> \r
+  aListBoxObjetos.Clear; \r
+  oObjetos := MainForm.mGetObjetos; \r
+  <B>for</B> i := 0 <B>to</B> oObjetos.Count - 1 <B>do</B> <B>begin</B> \r
+    oOV := cObjetoVolador( oObjetos.Items[i] ); \r
+    tipo := mClassToStr( oOV ); \r
+    oPos := oOV.mGetPosicion; \r
+    oVel := oOV.mGetVelocidad; \r
+    aListBoxObjetos.Items.AddObject( tipo + \r
+                                     '; (' + FloatToStrF( oPos.mGetX, ffGeneral, 5, 5 ) + \r
+                                     ';' + FloatToStrF( oPos.mGetY, ffGeneral, 5, 5 ) + \r
+                                     ';' + FloatToStrF( oPos.mGetZ, ffGeneral, 5, 5 ) + ')' + \r
+                                     '; (' + FloatToStrF( oVel.mGetX, ffGeneral, 5, 5 ) + \r
+                                     ';' + FloatToStrF( oVel.mGetY, ffGeneral, 5, 5 ) + \r
+                                     ';' + FloatToStrF( oVel.mGetZ, ffGeneral, 5, 5 ) + ')', \r
+                                     oOV ); \r
+    oPos.free; \r
+    oVel.free; \r
+    oPos := MainForm.mGetNavePropia.mGetPosicion; \r
+    oVel := MainForm.mGetNavePropia.mGetVelocidad; \r
+    aEditNPPosX.Text := FloatToStrF( oPos.mGetX, ffGeneral, 5, 5 ); \r
+    aEditNPPosY.Text := FloatToStrF( oPos.mGetY, ffGeneral, 5, 5 ); \r
+    aEditNPPosZ.Text := FloatToStrF( oPos.mGetZ, ffGeneral, 5, 5 ); \r
+    aEditNPVelX.Text := FloatToStrF( oVel.mGetX, ffGeneral, 5, 5 ); \r
+    aEditNPVelY.Text := FloatToStrF( oVel.mGetY, ffGeneral, 5, 5 ); \r
+    aEditNPVelZ.Text := FloatToStrF( oVel.mGetZ, ffGeneral, 5, 5 ); \r
+    oPos.free; \r
+    oVel.free; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene una cadena compatible con los radio buttons dependiendo de la clase del objeto \r
+    @param  oOV Objeto Volador de la clase apropiada \r
+    @return     Cadena compatible con el titulo del Radio Button}</FONT></I> \r
+<B>function</B> TConfigForm.mClassToStr(oOV: cObjetoVolador): <B>string</B>; \r
+<B>var</B> \r
+  clase: <B>string</B>; \r
+<B>begin</B> \r
+    clase := oOV.ClassName; \r
+    result := 'Desconocido'; \r
+    <B>if</B> clase = 'cNavePesada' <B>then</B> \r
+      result := 'Nave Pesada'; \r
+    <B>if</B> clase = 'cNaveLiviana' <B>then</B> \r
+      result := 'Nave Liviana'; \r
+    <B>if</B> clase = 'cNaveSuicida' <B>then</B> \r
+      result := 'Nave Suicida'; \r
+    <B>if</B> clase = 'cNaveEspia' <B>then</B> \r
+      result := 'Nave Espia'; \r
+    <B>if</B> clase = 'cMeteorito' <B>then</B> \r
+      result := 'Meteorito'; \r
+    <B>if</B> clase = 'cLaser' <B>then</B> \r
+      result := 'Laser'; \r
+    <B>if</B> clase = 'cMisil' <B>then</B> \r
+      result := 'Misil'; \r
+    <B>if</B> clase = 'cMisilDirigido' <B>then</B> \r
+      result := 'Misil Dirigido'; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el indice compatible con los radio buttons dependiendo de la clase del objeto \r
+    @param  oOV Objeto Volador de la clase apropiada \r
+    @return     Indice del Radio Button}</FONT></I> \r
+<B>function</B> TConfigForm.mClassToIndex(oOV: cObjetoVolador): integer; \r
+<B>var</B> \r
+  clase: <B>string</B>; \r
+<B>begin</B> \r
+    clase := oOV.ClassName; \r
+    result := -1; \r
+    <B>if</B> clase = 'cNavePesada' <B>then</B> \r
+      result := 0; \r
+    <B>if</B> clase = 'cNaveLiviana' <B>then</B> \r
+      result := 1; \r
+    <B>if</B> clase = 'cNaveSuicida' <B>then</B> \r
+      result := 2; \r
+    <B>if</B> clase = 'cNaveEspia' <B>then</B> \r
+      result := 3; \r
+    <B>if</B> clase = 'cMeteorito' <B>then</B> \r
+      result := 4; \r
+    <B>if</B> clase = 'cLaser' <B>then</B> \r
+      result := 5; \r
+    <B>if</B> clase = 'cMisil' <B>then</B> \r
+      result := 6; \r
+    <B>if</B> clase = 'cMisilDirigido' <B>then</B> \r
+      result := 7; \r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/forms/FormMain.pas b/doc/src-html/forms/FormMain.pas
new file mode 100644 (file)
index 0000000..8bbaa97
--- /dev/null
@@ -0,0 +1,729 @@
+<HTML><HEAD>\r
+<TITLE>File: formmain.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=formmain.pas><CENTER><H3>formmain.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Formulario principal de la aplicación<br> \r
+    <i>Cambios:</i> \r
+    <PRE> \r
+    29/11/00: Se agregan algunos controles gráficos con indicadores de energía y velocidad. \r
+              No se incluyen en una clase Vista porque son muy pequeños. \r
+    01/12/00: Se modifica levemente la interfaz. \r
+              Se agregan controles para los disparos y metodos pertinentes. \r
+    06/12/00: Se cambian minimamente los menúes, poniendo la parte del manejo \r
+              de escenarios en un submenú del menú Archivo. \r
+    08/12/00: Se termina de implementar la funcionalidad de los menúes \r
+                Archivo -> Abrir ... \r
+                Archivo -> Guardar ... \r
+                Archivo -> Escenario -> Abrir ... \r
+                Archivo -> Escenario -> Guardar ... \r
+              Se completa el 'destructor', ya que faltaban liberar bastantes \r
+              objetos. \r
+    </PRE>}</FONT></I> \r
+<B>unit</B> FormMain; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, \r
+  ExtCtrls, Menus, StdCtrls, \r
+  Espacio, \r
+  NavePropia, \r
+  NavesEnemigas, \r
+  Meteorito, \r
+  Armas, \r
+  Vectores, \r
+  Vista, \r
+  Tipos; \r
\r
+<B>type</B> \r
+  <I><FONT COLOR="Navy">{** Formulario principal de la aplicación}</FONT></I> \r
+  TMainForm = <B>class</B>(TForm) \r
+    aBtnIniciar: TButton; \r
+    aMainMenu: TMainMenu; \r
+    aTimer: TTimer; \r
+    aMenuJuego: TMenuItem; \r
+    aMenuItemConfigurar: TMenuItem; \r
+    aMenuItemSalir: TMenuItem; \r
+    aTimerVista: TTimer; \r
+    aEditEnergia: TEdit; \r
+    aLblEnergia: TLabel; \r
+    N1: TMenuItem; \r
+    aMenuItemNuevoJuego: TMenuItem; \r
+    aMenuItemGuardar: TMenuItem; \r
+    aMenuItemAbrir: TMenuItem; \r
+    aMenuItemAbrirEscenario: TMenuItem; \r
+    aMenuItemGuardarEscenario: TMenuItem; \r
+    N3: TMenuItem; \r
+    aLblVelocidad: TLabel; \r
+    aEditVelocidad: TEdit; \r
+    aLblKMH: TLabel; \r
+    aLblMisiles: TLabel; \r
+    aEditMisiles: TEdit; \r
+    aLblMisilesDir: TLabel; \r
+    aEditMisilesDirigidos: TEdit; \r
+    aLblArma: TLabel; \r
+    aEditArma: TEdit; \r
+    aMenuEscenario: TMenuItem; \r
+    aSaveJuego: TSaveDialog; \r
+    aOpenJuego: TOpenDialog; \r
+    aSaveEscenario: TSaveDialog; \r
+    aOpenEscenario: TOpenDialog; \r
+    aMenuVista: TMenuItem; \r
+    aMenuItemFrontal: TMenuItem; \r
+    aMenuItemDerecha: TMenuItem; \r
+    aMenuItemIzquierda: TMenuItem; \r
+    aMenuItemTrasera: TMenuItem; \r
+    aMenuItemSuperior: TMenuItem; \r
+    aMenuItemInferior: TMenuItem; \r
+    aMenuItemDelArma: TMenuItem; \r
+    N2: TMenuItem; \r
+    aMenuItemCalidad: TMenuItem; \r
+    aMenuItemCambioAutomatico: TMenuItem; \r
+    aMenuItemMapa: TMenuItem; \r
+    <B>procedure</B> <A HREF="#TMainForm.aBtnIniciarClick">aBtnIniciarClick</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TMainForm.aTimerTimer">aTimerTimer</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TMainForm.aMenuItemConfigurarClick">aMenuItemConfigurarClick</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TMainForm.FormCreate">FormCreate</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TMainForm.aMenuItemSalirClick">aMenuItemSalirClick</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TMainForm.FormDestroy">FormDestroy</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TMainForm.FormKeyDown">FormKeyDown</A>(Sender: TObject; <B>var</B> Key: Word; \r
+      Shift: TShiftState); \r
+    <B>procedure</B> <A HREF="#TMainForm.FormHide">FormHide</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TMainForm.aTimerVistaTimer">aTimerVistaTimer</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TMainForm.aMenuItemGuardarClick">aMenuItemGuardarClick</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TMainForm.aMenuClick">aMenuClick</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TMainForm.aMenuItemAbrirClick">aMenuItemAbrirClick</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TMainForm.aMenuItemNuevoJuegoClick">aMenuItemNuevoJuegoClick</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TMainForm.aMenuItemGuardarEscenarioClick">aMenuItemGuardarEscenarioClick</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TMainForm.aMenuItemAbrirEscenarioClick">aMenuItemAbrirEscenarioClick</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TMainForm.CambiarVistaClick">CambiarVistaClick</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TMainForm.aMenuItemCalidadClick">aMenuItemCalidadClick</A>(Sender: TObject); \r
+    <B>procedure</B> <A HREF="#TMainForm.DesSerializarEscenario">DesSerializarEscenario</A>( archivo: <B>string</B> ); \r
+    <B>procedure</B> <A HREF="#TMainForm.SerializarEscenario">SerializarEscenario</A>( archivo: <B>string</B> ); \r
+    <B>procedure</B> <A HREF="#TMainForm.DesSerializarJuego">DesSerializarJuego</A>( archivo: <B>string</B> ); \r
+    <B>procedure</B> <A HREF="#TMainForm.SerializarJuego">SerializarJuego</A>( archivo: <B>string</B> ); \r
+    <B>procedure</B> <A HREF="#TMainForm.aMenuItemCambioAutomaticoClick">aMenuItemCambioAutomaticoClick</A>(Sender: TObject); \r
+  <B>private</B> \r
+    <I><FONT COLOR="Navy">{ Private declarations }</FONT></I> \r
+    aObjetos:    TList;       <I><FONT COLOR="Navy">// Lista de objetos a utlizar con el espacio </FONT></I>\r
+    aEspacio:    cEspacio;    <I><FONT COLOR="Navy">// Espacio a utilizar </FONT></I>\r
+    aNavePropia: cNavePropia; <I><FONT COLOR="Navy">// Nave propia a utilizar con el espacio </FONT></I>\r
+    aVista:      cVista;      <I><FONT COLOR="Navy">// Vista utilizada para dibujar el modelo en el formulario </FONT></I>\r
+    <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+    aDebugFile:  Text;        <I><FONT COLOR="Navy">// Archivo para guardar información de debug </FONT></I>\r
+    <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+  <B>public</B> \r
+    <I><FONT COLOR="Navy">{ Public declarations }</FONT></I> \r
+    <I><FONT COLOR="Navy">{** Obtiene la lista de objetos del formulario}</FONT></I> \r
+    <B>function</B> <A HREF="#TMainForm.mGetObjetos">mGetObjetos</A>: TList; \r
+    <I><FONT COLOR="Navy">{** Obtiene la nave propia del formulario}</FONT></I> \r
+    <B>function</B> <A HREF="#TMainForm.mGetNavePropia">mGetNavePropia</A>: cNavePropia; \r
+  <B>end</B>; \r
\r
+<B>var</B> \r
+  MainForm:    TMainForm; \r
\r
+<B>implementation</B> \r
\r
+<B>uses</B> \r
+  FormConfig, \r
+  ObjetoPersistente, \r
+  SerializacionUtils, \r
+  RegExpr, \r
+  ObjetoVolador, \r
+  Camara; \r
\r
+<I><FONT COLOR="Navy">{$R *.DFM}</FONT></I> \r
\r
+<B>const</B> \r
+  DEBUGING: boolean = true; <I><FONT COLOR="Navy">// Constante para indicar si se genera el archivo de debug </FONT></I>\r
\r
+<B>procedure</B> <A NAME=TMainForm.aBtnIniciarClick>TMainForm.aBtnIniciarClick</A>(Sender: TObject); \r
+<B>begin</B> \r
+  <B>if</B> aEspacio = <B>nil</B> <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Todavía no se inicio el juego </FONT></I>\r
+    aEspacio := cEspacio.create( aNavePropia, aObjetos, 50 ); \r
+    aVista := cVista.create( self, aNavePropia ); \r
+    aMenuItemConfigurar.Enabled := false; \r
+    aMenuItemGuardar.Enabled := true; \r
+    aMenuEscenario.Enabled := false; \r
+    aMenuVista.Enabled := true; \r
+  <B>end</B>; \r
+  <B>if</B> aTimer.Enabled = false <B>then</B> <B>begin</B> \r
+    aTimer.enabled := true; \r
+    aTimerVista.enabled := true; \r
+    aBtnIniciar.caption := 'Pausa'; \r
+  <B>end</B> <B>else</B> <B>begin</B> \r
+    aTimer.enabled := false; \r
+    aTimerVista.enabled := false; \r
+    aBtnIniciar.caption := 'Continuar'; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.aTimerTimer>TMainForm.aTimerTimer</A>(Sender: TObject); \r
+<B>begin</B> \r
+  <B>try</B> <I><FONT COLOR="Navy">// Prueba el codigo </FONT></I>\r
+    aEspacio.mActualizar; \r
+  <B>except</B> \r
+    on e: ENavePropiaDestruida <B>do</B> <B>begin</B>         <I><FONT COLOR="Navy">// Si cae en una excepcion de nave propia destruida </FONT></I>\r
+      aBtnIniciarClick( self );                 <I><FONT COLOR="Navy">// Detiene la ejecucion </FONT></I>\r
+      aBtnIniciar.Enabled := false;             <I><FONT COLOR="Navy">// No permite que se reinicie </FONT></I>\r
+      aMenuItemGuardar.Enabled := false;        <I><FONT COLOR="Navy">// No permite guardar el juego </FONT></I>\r
+      aMenuVista.Enabled := false;              <I><FONT COLOR="Navy">// No permite manipular la vista </FONT></I>\r
+      <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+      writeln( aDebugFile, 'GAME OVER!!!! (' +  <I><FONT COLOR="Navy">// Escribe el archivo de LOG de ser necesario </FONT></I>\r
+                           e.<B>Message</B> + ')' ); \r
+      <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+      ShowMessage( 'GAME OVER!!!' ); <I><FONT COLOR="Navy">// Muestra un mensaje </FONT></I>\r
+    <B>end</B>; \r
+    on e: Exception <B>do</B> <B>begin</B>                       <I><FONT COLOR="Navy">// Si cae en una excepcion desconocida </FONT></I>\r
+      aBtnIniciarClick( self );                    <I><FONT COLOR="Navy">// Detiene la ejecucion </FONT></I>\r
+      aBtnIniciar.Enabled := false;                <I><FONT COLOR="Navy">// No permite que se reinicie </FONT></I>\r
+      aMenuItemGuardar.Enabled := false;           <I><FONT COLOR="Navy">// No permite guardar el juego </FONT></I>\r
+      aMenuVista.Enabled := false;                 <I><FONT COLOR="Navy">// No permite manipular la vista </FONT></I>\r
+      <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+      writeln( aDebugFile, 'ERROR: ' + e.<B>Message</B>); <I><FONT COLOR="Navy">// Escribe el archivo de LOG de ser necesario </FONT></I>\r
+      <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+      ShowMessage( 'ERROR: ' + e.<B>Message</B> );    <I><FONT COLOR="Navy">// Muestra un mensaje </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.aTimerVistaTimer>TMainForm.aTimerVistaTimer</A>(Sender: TObject); \r
+<B>const</B> \r
+  i: int64 = 0; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+  i := i + 1; \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+  <I><FONT COLOR="Navy">// Muestra la energía de la nave </FONT></I>\r
+  aEditEnergia.Text := IntToStr( aNavePropia.mGetEnergia ); \r
+  <I><FONT COLOR="Navy">// La velocidad esta en las unidades 1m/ms. Sabiendo que 1m = 0,001 km y </FONT></I>\r
+  <I><FONT COLOR="Navy">// 1 h = 60 . 60 . 1000 ms, entonces 1 ms = 1 / 3600000 h </FONT></I>\r
+  <I><FONT COLOR="Navy">// Entonces velocidad * 0,001 * 3600000 = velocidad * 3600 = km/h </FONT></I>\r
+  aEditVelocidad.Text := FloatToStr( aNavePropia.mGetVelModulo * 3600 ); \r
+  <I><FONT COLOR="Navy">// Muestra la cantidad de misiles que le quedan a la nave </FONT></I>\r
+  aEditMisiles.Text := IntToStr( aNavePropia.mGetMisiles ); \r
+  <I><FONT COLOR="Navy">// Muestra la cantidad de misiles dirigidos que le quedan a la nave </FONT></I>\r
+  aEditMisilesDirigidos.Text := IntToStr( aNavePropia.mGetMisilesDirigidos ); \r
+  <I><FONT COLOR="Navy">// Muestra en el título la cámara actualmente en uso </FONT></I>\r
+  Caption := Application.Title + ' @ ' + aVista.mGetCamaraStr; \r
+  <I><FONT COLOR="Navy">// Muestra el arma seleccionada </FONT></I>\r
+  <B>case</B> aNavePropia.mGetArmaSelec <B>of</B> \r
+    OV_LASER: <B>begin</B> \r
+      aEditArma.Text := 'Láser'; \r
+      <B>if</B> aNavePropia.mPuedeDispararLaser( <B>nil</B> ) <B>then</B> \r
+        aEditArma.Font.Color := clLime \r
+      <B>else</B> \r
+        aEditArma.Font.Color := clRed; \r
+    <B>end</B>; \r
+    OV_MISIL: <B>begin</B> \r
+      aEditArma.Text := 'Misil'; \r
+      <B>if</B> aNavePropia.mPuedeDispararMisil( <B>nil</B> ) <B>then</B> \r
+        aEditArma.Font.Color := clLime \r
+      <B>else</B> \r
+        aEditArma.Font.Color := clRed; \r
+    <B>end</B>; \r
+    OV_MISDIR: <B>begin</B> \r
+      aEditArma.Text := 'Misil Dirigido'; \r
+      <B>if</B> aNavePropia.mPuedeDispararMisDir( <B>nil</B> ) <B>then</B> \r
+        aEditArma.Font.Color := clLime \r
+      <B>else</B> \r
+        aEditArma.Font.Color := clRed; \r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <B>try</B> <I><FONT COLOR="Navy">// Prueba el codigo </FONT></I>\r
+    aVista.mDibujarVista( aEspacio ); \r
+    <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+    <I><FONT COLOR="Navy">// Imprime la informacion del estado del espacio en este instante </FONT></I>\r
+    writeln( aDebugFile, aEspacio.mGetDebugInfo( DI_NORMAL ) ); \r
+    <I><FONT COLOR="Navy">// Imprime la data de la vista </FONT></I>\r
+    writeln( aDebugFile, aVista.mGetDebugInfo( DI_MAXI ) ); \r
+    writeln( aDebugFile, #13 + #10 + '====================>  ' + IntToStr( i ) + '  <======================' ); \r
+    <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+  <B>except</B> \r
+    on e: ECameramanDestruido <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si cae en una excepcion de camara destruida </FONT></I>\r
+      aBtnIniciarClick( self );        <I><FONT COLOR="Navy">// Detiene la ejecucion </FONT></I>\r
+      aBtnIniciar.Enabled := false;    <I><FONT COLOR="Navy">// No permite que se reinicie </FONT></I>\r
+      <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+      writeln( aDebugFile, 'ERROR!!!! (' +  <I><FONT COLOR="Navy">// Escribe el archivo de LOG de ser necesario </FONT></I>\r
+                           e.<B>Message</B> + ')' ); \r
+      <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+      ShowMessage( 'ERROR!!!! (' + e.<B>Message</B> + ')' ); <I><FONT COLOR="Navy">// Muestra un mensaje </FONT></I>\r
+    <B>end</B>; \r
+    on e: ENavePropiaDestruida <B>do</B> <B>begin</B>         <I><FONT COLOR="Navy">// Si cae en una excepcion de nave propia destruida </FONT></I>\r
+      aBtnIniciarClick( self );                 <I><FONT COLOR="Navy">// Detiene la ejecucion </FONT></I>\r
+      aBtnIniciar.Enabled := false;             <I><FONT COLOR="Navy">// No permite que se reinicie </FONT></I>\r
+      <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+      writeln( aDebugFile, 'GAME OVER!!!! (' +  <I><FONT COLOR="Navy">// Escribe el archivo de LOG de ser necesario </FONT></I>\r
+                           e.<B>Message</B> + ')' ); \r
+      <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+      ShowMessage( 'GAME OVER!!!' ); <I><FONT COLOR="Navy">// Muestra un mensaje </FONT></I>\r
+    <B>end</B>; \r
+    on e: Exception <B>do</B> <B>begin</B>                      <I><FONT COLOR="Navy">// Si cae en una excepcion desconocida </FONT></I>\r
+      aBtnIniciarClick( self );                    <I><FONT COLOR="Navy">// Detiene la ejecucion </FONT></I>\r
+      aBtnIniciar.Enabled := false;                <I><FONT COLOR="Navy">// No permite que se reinicie </FONT></I>\r
+      <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+      writeln( aDebugFile, 'ERROR: ' + e.<B>Message</B>); <I><FONT COLOR="Navy">// Escribe el archivo de LOG de ser necesario </FONT></I>\r
+      <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+      ShowMessage( 'ERROR: ' + e.<B>Message</B> );    <I><FONT COLOR="Navy">// Muestra un mensaje </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.aMenuItemConfigurarClick>TMainForm.aMenuItemConfigurarClick</A>(Sender: TObject); \r
+<B>begin</B> \r
+  ConfigForm.ShowModal; \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.FormCreate>TMainForm.FormCreate</A>(Sender: TObject); \r
+<B>begin</B> \r
+  aEspacio := <B>nil</B>; \r
+  aObjetos := TList.create; \r
+  aNavePropia := cNavePropia.create; \r
+  <I><FONT COLOR="Navy">// Pausa si se minimiza </FONT></I>\r
+  Application.OnMinimize := FormHide; \r
\r
+  <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+  <I><FONT COLOR="Navy">// Inicializa el archivo de texto para DEBUG </FONT></I>\r
+  assignFile( aDebugFile, 'debug.txt' ); \r
+  rewrite( aDebugFile ); \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+  <I><FONT COLOR="Navy">// Cargamos Algunos datos de ejemplo al principio si existe el archivo </FONT></I>\r
+  <B>if</B> FileExists( 'comun.eaw' ) <B>then</B> \r
+    <B>try</B> <I><FONT COLOR="Navy">// Prueba que no haya errores </FONT></I>\r
+      DesSerializarEscenario( 'comun.eaw' ); \r
+    <B>except</B> \r
+      on e: ESerializacion <B>do</B> <B>begin</B> \r
+        ShowMessage( 'Hubo un error al recuperar el escenario por defecto "comun.eaw": ' + e.<B>Message</B> );    <I><FONT COLOR="Navy">// Muestra un mensaje </FONT></I>\r
+        <I><FONT COLOR="Navy">// Resetea todos los valores ... </FONT></I>\r
+        aEspacio.free; \r
+        aObjetos.free; \r
+        aNavePropia.free; \r
+        aEspacio := <B>nil</B>; \r
+        aObjetos := TList.create; \r
+        aNavePropia := cNavePropia.create; \r
+      <B>end</B>; \r
+    <B>end</B>; \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.aMenuItemSalirClick>TMainForm.aMenuItemSalirClick</A>(Sender: TObject); \r
+<B>begin</B> \r
+  Close; \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.FormDestroy>TMainForm.FormDestroy</A>(Sender: TObject); \r
+<B>var</B> \r
+  ov: cObjetoVolador; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Si el espacio no esta creado, liberamos la nave propia y los objetos </FONT></I>\r
+  <B>if</B> aEspacio = <B>nil</B> <B>then</B> <B>begin</B> \r
+    aNavePropia.free; \r
+    <B>while</B> aObjetos.Count > 0 <B>do</B> <B>begin</B> \r
+      ov := aObjetos.First; \r
+      aObjetos.Remove( ov ); \r
+      ov.free; \r
+    <B>end</B>; \r
+    aObjetos.free; \r
+  <B>end</B> <B>else</B> <I><FONT COLOR="Navy">// Si el espacio esta creado ... </FONT></I>\r
+    <I><FONT COLOR="Navy">// aObjetos y aNavePropia se liberan cuando se libera el aEspacio </FONT></I>\r
+    aEspacio.free; \r
+  aVista.free; \r
+  <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+  <I><FONT COLOR="Navy">// Cierra el archivo para DEBUG </FONT></I>\r
+  closeFile( aDebugFile ); \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la lista de objetos del formulario \r
+    @return Lista de objetos que utilizara el espacio}</FONT></I> \r
+<B>function</B> <A NAME=TMainForm.mGetObjetos>TMainForm.mGetObjetos</A>: TList; \r
+<B>begin</B> \r
+  result := aObjetos; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la nave propia del formulario \r
+    @return Nave propia que utilizara el espacio}</FONT></I> \r
+<B>function</B> <A NAME=TMainForm.mGetNavePropia>TMainForm.mGetNavePropia</A>: cNavePropia; \r
+<B>begin</B> \r
+  result := aNavePropia; \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.FormKeyDown>TMainForm.FormKeyDown</A>(Sender: TObject; <B>var</B> Key: Word; \r
+  Shift: TShiftState); \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+  writeln( aDebugFile, 'Presiono la letra: ', Key ); \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+  <B>if</B> aTimer.Enabled <B>then</B> \r
+    <B>case</B> Key <B>of</B> \r
+      <I><FONT COLOR="Navy">// 8.7e-3 es 0,5 grados </FONT></I>\r
+      73<I><FONT COLOR="Navy">{I}</FONT></I>: aNavePropia.mGirarArriba( 8.7e-3 ); \r
+      75<I><FONT COLOR="Navy">{K}</FONT></I>: aNavePropia.mGirarAbajo( 8.7e-3 ); \r
+      74<I><FONT COLOR="Navy">{J}</FONT></I>: aNavePropia.mGirarIzquierda( 8.7e-3 ); \r
+      76<I><FONT COLOR="Navy">{L}</FONT></I>: aNavePropia.mGirarDerecha( 8.7e-3 ); \r
+      85<I><FONT COLOR="Navy">{U}</FONT></I>: aNavePropia.mRotarDerecha( 8.7e-3 ); \r
+      79<I><FONT COLOR="Navy">{O}</FONT></I>: aNavePropia.mRotarIzquierda( 8.7e-3 ); \r
+      <I><FONT COLOR="Navy">// 0.005 es 18 km/h </FONT></I>\r
+      81<I><FONT COLOR="Navy">{Q}</FONT></I>: aNavePropia.mAcelerar( 0.005 ); \r
+      65<I><FONT COLOR="Navy">{A}</FONT></I>: aNavePropia.mDesacelerar( 0.005 ); \r
+      <I><FONT COLOR="Navy">// Disparos </FONT></I>\r
+      83<I><FONT COLOR="Navy">{S}</FONT></I>: <B>begin</B> <I><FONT COLOR="Navy">// Dispara creando la nueva camara del arma si hubo un disparo </FONT></I>\r
+               aVista.mCrearCamaraDeArma( aNavePropia.mIntentarDisparo ); \r
+               <B>if</B> aMenuItemCambioAutomatico.Checked <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si está activado el cambio automatico... </FONT></I>\r
+                 CambiarVistaClick( aMenuItemDelArma ); <I><FONT COLOR="Navy">// Cambia la camara </FONT></I>\r
+               <B>end</B>; \r
+             <B>end</B>; \r
+      87<I><FONT COLOR="Navy">{W}</FONT></I>: aNavePropia.mSeleccionarArmaSig; \r
+      84<I><FONT COLOR="Navy">{T}</FONT></I>: aNavePropia.mCambiarLockeado( aEspacio.mGetObjetos ); \r
+      <I><FONT COLOR="Navy">// Vista </FONT></I>\r
+      67<I><FONT COLOR="Navy">{C}</FONT></I>: aVista.mCamaraSiguiente; \r
+    <B>end</B>; \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.FormHide>TMainForm.FormHide</A>(Sender: TObject); \r
+<B>begin</B> \r
+  <B>if</B> aBtnIniciar.caption = 'Pausa' <B>then</B> <I><FONT COLOR="Navy">// Esta jugando </FONT></I>\r
+    aBtnIniciarClick( self ); <I><FONT COLOR="Navy">// Pausa el juego </FONT></I>\r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.aMenuItemGuardarClick>TMainForm.aMenuItemGuardarClick</A>(Sender: TObject); \r
+<B>begin</B> \r
+  Repaint; \r
+  <B>if</B> aTimer.Enabled = true <B>then</B> <I><FONT COLOR="Navy">// Si esta funcinando, </FONT></I>\r
+    aBtnIniciarClick( self );   <I><FONT COLOR="Navy">// lo interrumpe... </FONT></I>\r
+  <B>if</B> aSaveJuego.Execute <B>then</B> <I><FONT COLOR="Navy">// Si eligio un archivo... </FONT></I>\r
+    SerializarJuego( aSaveJuego.Filename ); \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.aMenuClick>TMainForm.aMenuClick</A>(Sender: TObject); \r
+<B>begin</B> \r
+  <B>if</B> aTimer.Enabled = true <B>then</B> <I><FONT COLOR="Navy">// Si esta funcinando, </FONT></I>\r
+    aBtnIniciarClick( self );   <I><FONT COLOR="Navy">// lo interrumpe... </FONT></I>\r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.aMenuItemAbrirClick>TMainForm.aMenuItemAbrirClick</A>(Sender: TObject); \r
+<B>begin</B> \r
+  Repaint; \r
+  <B>if</B> aTimer.Enabled = true <B>then</B> <I><FONT COLOR="Navy">// Si esta funcinando, </FONT></I>\r
+    aBtnIniciarClick( self );   <I><FONT COLOR="Navy">// lo interrumpe... </FONT></I>\r
+  <B>if</B> aOpenJuego.Execute <B>then</B> <I><FONT COLOR="Navy">// Si eligio un archivo... </FONT></I>\r
+    DesSerializarJuego( aOpenJuego.Filename ); \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.aMenuItemNuevoJuegoClick>TMainForm.aMenuItemNuevoJuegoClick</A>(Sender: TObject); \r
+<B>var</B> \r
+  ov: cObjetoVolador; \r
+<B>begin</B> \r
+  Repaint; \r
+  <B>if</B> aTimer.Enabled = true <B>then</B> <I><FONT COLOR="Navy">// Si esta funcinando, </FONT></I>\r
+    aBtnIniciarClick( self );   <I><FONT COLOR="Navy">// lo interrumpe... </FONT></I>\r
+  <B>if</B> MessageDlg( 'Se perderán todos los datos del juego actual ¿Está seguro que desea empezar un juego nuevo?', \r
+                 mtConfirmation, [mbYes, mbNo], 0) = mrYes <B>then</B> <B>begin</B> \r
+  <I><FONT COLOR="Navy">// Si el espacio no esta creado, liberamos la nave propia y los objetos </FONT></I>\r
+    <B>if</B> aEspacio = <B>nil</B> <B>then</B> <B>begin</B> \r
+      aNavePropia.free; \r
+      <B>while</B> aObjetos.Count > 0 <B>do</B> <B>begin</B> \r
+        ov := aObjetos.First; \r
+        aObjetos.Remove( ov ); \r
+        ov.free; \r
+      <B>end</B>; \r
+      aObjetos.free; \r
+    <B>end</B> <B>else</B> <I><FONT COLOR="Navy">// Si el espacio esta creado ... </FONT></I>\r
+      <I><FONT COLOR="Navy">// aObjetos y aNavePropia se liberan cuando se libera el aEspacio </FONT></I>\r
+      aEspacio.free; \r
+    aVista.free; \r
+    aEspacio := <B>nil</B>; \r
+    aVista := <B>nil</B>; \r
+    aObjetos := TList.create; \r
+    aNavePropia := cNavePropia.create; \r
+    aBtnIniciar.caption := 'Iniciar'; \r
+    aMenuItemConfigurar.Enabled := true; \r
+    aMenuItemGuardar.Enabled := false; \r
+    aMenuEscenario.Enabled := true; \r
+    aBtnIniciar.Enabled := true;         <I><FONT COLOR="Navy">// Se puede iniciar el juego </FONT></I>\r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.aMenuItemGuardarEscenarioClick>TMainForm.aMenuItemGuardarEscenarioClick</A>(Sender: TObject); \r
+<B>begin</B> \r
+  Repaint; \r
+  <B>if</B> aTimer.Enabled = true <B>then</B> <I><FONT COLOR="Navy">// Si esta funcinando, </FONT></I>\r
+    aBtnIniciarClick( self );   <I><FONT COLOR="Navy">// lo interrumpe... </FONT></I>\r
+  <B>if</B> aSaveEscenario.Execute <B>then</B> <I><FONT COLOR="Navy">// Si eligio un archivo... </FONT></I>\r
+    SerializarEscenario( aSaveEscenario.Filename ); \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.aMenuItemAbrirEscenarioClick>TMainForm.aMenuItemAbrirEscenarioClick</A>(Sender: TObject); \r
+<B>begin</B> \r
+  Repaint; \r
+  <B>if</B> aTimer.Enabled = true <B>then</B> <I><FONT COLOR="Navy">// Si esta funcinando, </FONT></I>\r
+    aBtnIniciarClick( self );   <I><FONT COLOR="Navy">// lo interrumpe... </FONT></I>\r
+  <B>if</B> aOpenEscenario.Execute <B>then</B> <I><FONT COLOR="Navy">// Si eligio un archivo... </FONT></I>\r
+    DesSerializarEscenario( aOpenEscenario.Filename ); <I><FONT COLOR="Navy">// Deserializa el archivo </FONT></I>\r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.CambiarVistaClick>TMainForm.CambiarVistaClick</A>(Sender: TObject); \r
+<B>begin</B> \r
+  <B>if</B> Sender = aMenuItemFrontal <B>then</B> \r
+    aVista.mCambiarCamara( CAMARA_FRONTAL ) \r
+  <B>else</B> <B>if</B> Sender = aMenuItemDerecha <B>then</B> \r
+    aVista.mCambiarCamara( CAMARA_LATDER ) \r
+  <B>else</B> <B>if</B> Sender = aMenuItemIzquierda <B>then</B> \r
+    aVista.mCambiarCamara( CAMARA_LATIZQ ) \r
+  <B>else</B> <B>if</B> Sender = aMenuItemTrasera <B>then</B> \r
+    aVista.mCambiarCamara( CAMARA_TRASERA ) \r
+  <B>else</B> <B>if</B> Sender = aMenuItemSuperior <B>then</B> \r
+    aVista.mCambiarCamara( CAMARA_ARRIBA ) \r
+  <B>else</B> <B>if</B> Sender = aMenuItemInferior <B>then</B> \r
+    aVista.mCambiarCamara( CAMARA_ABAJO ) \r
+  <B>else</B> <B>if</B> Sender = aMenuItemDelArma <B>then</B> \r
+    aVista.mCambiarCamara( CAMARA_ARMA ) \r
+  <B>else</B> <B>if</B> Sender = aMenuItemMapa <B>then</B> \r
+    aVista.mCambiarCamara( CAMARA_MAPA ) \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.aMenuItemCalidadClick>TMainForm.aMenuItemCalidadClick</A>(Sender: TObject); \r
+<B>begin</B> \r
+  aVista.mCambiarCalidad; \r
+  aMenuItemCalidad.Checked := <B>not</B> aMenuItemCalidad.Checked; \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.DesSerializarEscenario>TMainForm.DesSerializarEscenario</A>( archivo: <B>string</B> ); \r
+<B>var</B> \r
+  recuperado, \r
+  str:         <B>string</B>; \r
+  i, \r
+  total:       integer; \r
+  ov:          cObjetoVolador; \r
+  c:           char; \r
+  f:           TextFile; \r
+  r:           TRegExpr; \r
+<B>begin</B> \r
+    <B>try</B> \r
+      assignFile( f, archivo );   <I><FONT COLOR="Navy">// Asigna el archivo </FONT></I>\r
+      reset( f );                             <I><FONT COLOR="Navy">// Abre el archivo </FONT></I>\r
+      recuperado := ''; \r
+      <B>while</B> <B>not</B> eof( f ) <B>do</B> <B>begin</B>     <I><FONT COLOR="Navy">// Lee el archivo </FONT></I>\r
+        <B>read</B>( f, c );                 <I><FONT COLOR="Navy">// caracter por caracter </FONT></I>\r
+        recuperado := recuperado + c; <I><FONT COLOR="Navy">// Almacenandolo en un string </FONT></I>\r
+      <B>end</B>; \r
+      closeFile( f );                 <I><FONT COLOR="Navy">// Cierra el archivo </FONT></I>\r
+    <B>except</B>  <I><FONT COLOR="Navy">// Si hay algun error </FONT></I>\r
+      on e: Exception <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Muestra un mensaje </FONT></I>\r
+        ShowMessage( 'Hubo un error al leer el archivo "' + \r
+                     archivo + '": ' + #13 + #10 + \r
+                     e.<B>Message</B> + #13 + #10 + \r
+                     'Por favor lea la Sección de Errores del Manual del ' + \r
+                     'Usuario para más información'  ); <I><FONT COLOR="Navy">// Muestra un mensaje </FONT></I>\r
+      <B>end</B>; \r
+    <B>end</B>; \r
+    r := TRegExpr.create; \r
+    <B>try</B> <I><FONT COLOR="Navy">// ensure memory release </FONT></I>\r
+      r.Expression := '<eaw/s+version=(/d+[/./d+]*)/s*>/s*(.+)/s*</eaw>'; \r
+      <B>if</B> r.Exec ( recuperado ) <B>then</B> \r
+        <B>if</B> r.Match[1] = '1.0' <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si el archivo es version 1.0 </FONT></I>\r
+          str := r.Match[2]; \r
+          <B>try</B> <I><FONT COLOR="Navy">// ensure memory release </FONT></I>\r
+            r.Expression := '<navepropia>/s*(.+)/s*</navepropia>'; \r
+            <B>if</B> r.Exec ( str ) <B>then</B> <B>begin</B> \r
+              aNavePropia.free; <I><FONT COLOR="Navy">// Libera la vieja nave propia </FONT></I>\r
+              <I><FONT COLOR="Navy">// Obtiene la nueva navepropia de la serializacion </FONT></I>\r
+              aNavePropia := cNavePropia.crearDeSerializado( r.Match[1] ); \r
+              <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+                r.Expression := '<objetos/s+total=(/d+)/s*>/s*(.+)/s*</objetos>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+                <B>if</B> r.Exec ( str ) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+                  total := StrToInt( r.Match[1] ); \r
+                  str := r.Match[2]; \r
+                  <I><FONT COLOR="Navy">// libera los objetos viejos </FONT></I>\r
+                  <B>while</B> aObjetos.Count > 0 <B>do</B> <B>begin</B> \r
+                    ov := aObjetos.First; \r
+                    aObjetos.Remove( ov ); \r
+                    ov.free; \r
+                  <B>end</B>; \r
+                  <B>for</B> i := 0 <B>to</B> total - 1 <B>do</B> <B>begin</B> \r
+                    <I><FONT COLOR="Navy">// OBJETO N </FONT></I>\r
+                    <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+                      r.Expression := '<objeto' + IntToStr( i ) + '/s+class=([/w/d]+)/s*>/s*(.+)/s*</objeto' + IntToStr( i ) + '>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+                      <B>if</B> r.Exec ( str ) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+                        <I><FONT COLOR="Navy">// lo crea segun su clase y lo agrega a la lista </FONT></I>\r
+                        ov := restaurarObjeto( r.Match[1], r.Match[2] ); \r
+                        aObjetos.Add( ov ); \r
+                        <I><FONT COLOR="Navy">// Elimina duplicados </FONT></I>\r
+                        <B>if</B> ov <B>is</B> cMisilDirigido <B>then</B> <B>begin</B> \r
+                          (ov <B>as</B> cMisilDirigido).mGetObjetivo.free; <I><FONT COLOR="Navy">// libera el objetivo duplicado </FONT></I>\r
+                          (ov <B>as</B> cMisilDirigido).mSetObjetivo( aNavePropia ); <I><FONT COLOR="Navy">// le asigna como objetivo a la nave propia </FONT></I>\r
+                        <B>end</B>; \r
+                      <B>end</B> <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+                        ShowMessage( 'No se encontro el objeto ' + IntToStr( i ) ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+                    <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+                      on e: ESerializacion <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si fueron de serializacion... </FONT></I>\r
+                        r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+                        ShowMessage( 'Error al deserializar el objeto ' \r
+                                     + IntToStr( i ) + ': ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// muestra mensaje </FONT></I>\r
+                      <B>end</B>; \r
+                      on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+                         r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+                         ShowMessage( 'Error al extraer el objeto ' + IntToStr( i ) + ' utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+                      <B>end</B>; \r
+                    <B>end</B>; \r
+                  <B>end</B>; \r
+                <B>end</B> <B>else</B> <I><FONT COLOR="Navy">// si no encontro el tag <objetos total=n> </FONT></I>\r
+                  ShowMessage( 'No se encontro la cantidad total de objetos' ); <I><FONT COLOR="Navy">// muestra mensaje </FONT></I>\r
+              <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores en el tag <objetos total=n> </FONT></I>\r
+                on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+                  r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+                  ShowMessage( 'Error al extraer la cantidad total de objetos utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+                <B>end</B>; \r
+              <B>end</B>; \r
+            <B>end</B> <B>else</B> <I><FONT COLOR="Navy">// si no encontro el tag <navepropia> </FONT></I>\r
+                  ShowMessage( 'No se encontro la nave propia' ); <I><FONT COLOR="Navy">// muestra mensaje </FONT></I>\r
+          <B>except</B> <I><FONT COLOR="Navy">// si hubieron errores en el tag <navepropia> </FONT></I>\r
+            on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+              r.Free; \r
+              ShowMessage( 'Error al recuperar la nave propia utilizando expresiones regulares: ' + e.<B>Message</B> ); \r
+            <B>end</B>; \r
+            on e: ESerializacion <B>do</B> <B>begin</B> \r
+              r.Free; \r
+              ShowMessage( 'Error al recuperar la nave propia: ' + e.<B>Message</B> ); \r
+            <B>end</B>; \r
+          <B>end</B> \r
+        <B>end</B> <B>else</B> <I><FONT COLOR="Navy">// if r.Match[1] = '1.0' then begin - chequeo de version fallido </FONT></I>\r
+          ShowMessage( 'El escenario almacenado es de una versión incorrecta (' + \r
+                       r.Match[1] + ').' ) \r
+      <B>else</B> <I><FONT COLOR="Navy">// if r.Exec ( recuperado ) then - si no se encontró un escenario almacenado </FONT></I>\r
+        ShowMessage( 'No se encontró un escenario almacenado en el archivo "' + \r
+                     archivo + '".' ); \r
+    <B>except</B> <I><FONT COLOR="Navy">// error en el tag <eaw version=n> </FONT></I>\r
+      on e: ERegExpr <B>do</B> <B>begin</B> \r
+        r.Free; \r
+        ShowMessage( 'Error al recuperar el escenario utilizando expresiones regulares: ' + e.<B>Message</B> ); \r
+      <B>end</B>; \r
+    <B>end</B>; <I><FONT COLOR="Navy">// try - except </FONT></I>\r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.SerializarEscenario>TMainForm.SerializarEscenario</A>( archivo: <B>string</B> ); \r
+<B>var</B> \r
+  serializado: <B>string</B>; \r
+  f:           TextFile; \r
+  ov:          cObjetoVolador; \r
+  i:           integer; \r
+<B>begin</B> \r
+    <B>try</B> \r
+      assignFile( f, archivo ); <I><FONT COLOR="Navy">// Asigna el archivo </FONT></I>\r
+      rewrite( f );                         <I><FONT COLOR="Navy">// Sobreescribe el archivo </FONT></I>\r
+      <I><FONT COLOR="Navy">// Serializa la nave propia agregando alguna información sobre el archivo y la versión </FONT></I>\r
+      serializado := '<eaw version=1.0><navepropia>' + aNavePropia.mSerializar + '</navepropia>' + \r
+                     '<objetos total=' + IntToStr( aObjetos.Count ) + '>'; \r
+      <I><FONT COLOR="Navy">// Serializa los objetos </FONT></I>\r
+      <B>for</B> i := 0 <B>to</B> aObjetos.Count - 1 <B>do</B> <B>begin</B>  <I><FONT COLOR="Navy">// recorre la lista </FONT></I>\r
+        ov := aObjetos.Items[i]; <I><FONT COLOR="Navy">// obteniendo el primer objeto volador </FONT></I>\r
+          <I><FONT COLOR="Navy">// Serializa el objeto actual </FONT></I>\r
+          serializado := serializado + '<objeto' + IntToStr( i ) + ' class=' + \r
+                         ov.ClassName + '>' + ov.mSerializar + '</objeto' + \r
+                         IntToStr( i ) + '>'; \r
+      <B>end</B>; \r
+      serializado := serializado + '</objetos></eaw>'; \r
+      <B>write</B>( f, serializado );              <I><FONT COLOR="Navy">// Escribe en el archivo </FONT></I>\r
+      closeFile( f );                       <I><FONT COLOR="Navy">// Cierra el archivo </FONT></I>\r
+    <B>except</B>  <I><FONT COLOR="Navy">// Si hay algun error </FONT></I>\r
+      on e: Exception <B>do</B> <I><FONT COLOR="Navy">// Muestra un mensaje </FONT></I>\r
+        ShowMessage( 'Hubo un error al grabar el archivo "' + \r
+                     archivo + '": ' + #13 + #10 + \r
+                     e.<B>Message</B> + #13 + #10 + \r
+                     'Por favor lea la Sección de Errores del Manual del ' + \r
+                     'Usuario para más información'  ); <I><FONT COLOR="Navy">// Muestra un mensaje </FONT></I>\r
+    <B>end</B>; \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.DesSerializarJuego>TMainForm.DesSerializarJuego</A>( archivo: <B>string</B> ); \r
+<B>var</B> \r
+  recuperado:  <B>string</B>; \r
+  c:           char; \r
+  f:           TextFile; \r
+  r:           TRegExpr; \r
+<B>begin</B> \r
+    <B>try</B> \r
+      assignFile( f, archivo );   <I><FONT COLOR="Navy">// Asigna el archivo </FONT></I>\r
+      reset( f );                             <I><FONT COLOR="Navy">// Abre el archivo </FONT></I>\r
+      recuperado := ''; \r
+      <B>while</B> <B>not</B> eof( f ) <B>do</B> <B>begin</B>     <I><FONT COLOR="Navy">// Lee el archivo </FONT></I>\r
+        <B>read</B>( f, c );                 <I><FONT COLOR="Navy">// caracter por caracter </FONT></I>\r
+        recuperado := recuperado + c; <I><FONT COLOR="Navy">// Almacenandolo en un string </FONT></I>\r
+      <B>end</B>; \r
+    <B>except</B>  <I><FONT COLOR="Navy">// Si hay algun error </FONT></I>\r
+      on e: Exception <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Muestra un mensaje </FONT></I>\r
+        ShowMessage( 'Hubo un error al leer el archivo "' + \r
+                     archivo + '": ' + #13 + #10 + \r
+                     e.<B>Message</B> + #13 + #10 + \r
+                     'Por favor lea la Sección de Errores del Manual del ' + \r
+                     'Usuario para más información'  ); <I><FONT COLOR="Navy">// Muestra un mensaje </FONT></I>\r
+      <B>end</B>; \r
+    <B>end</B>; \r
+    r := TRegExpr.create; \r
+    <B>try</B> <I><FONT COLOR="Navy">// ensure memory release </FONT></I>\r
+      r.Expression := '<jaw/s+version=(/d+[/./d+]*)/s*>/s*(.+)/s*</jaw>'; \r
+      <B>if</B> r.Exec ( recuperado ) <B>then</B> \r
+        <B>if</B> r.Match[1] = '1.0' <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si el archivo es version 1.0 </FONT></I>\r
+          aEspacio.free; <I><FONT COLOR="Navy">// Libera el espacio existente de existir </FONT></I>\r
+          aEspacio := <B>nil</B>; \r
+          aEspacio := cEspacio.crearDeSerializado( r.Match[2] );    <I><FONT COLOR="Navy">// Crea el nuevo a partir del guardado </FONT></I>\r
+          aNavePropia := aEspacio.mGetNavePropia;       <I><FONT COLOR="Navy">// Asigna la nueva nave propia </FONT></I>\r
+          aVista.free;                                  <I><FONT COLOR="Navy">// Libera la vieja vista </FONT></I>\r
+          aVista := <B>nil</B>; \r
+          aVista := cVista.create( self, aNavePropia ); <I><FONT COLOR="Navy">// Crea la nueva vista </FONT></I>\r
+          aBtnIniciar.Enabled := true;                  <I><FONT COLOR="Navy">// Se puede iniciar el juego </FONT></I>\r
+        <B>end</B> <B>else</B> \r
+          ShowMessage( 'El juego almacenado es de una versión incorrecta (' + \r
+                       r.Match[1] + ').' ) \r
+      <B>else</B> \r
+        ShowMessage( 'No se encontró un juego almacenado en el archivo "' + \r
+                     archivo + '".' ); \r
+    <B>except</B> \r
+      on e: ERegExpr <B>do</B> <B>begin</B> \r
+        r.Free; \r
+        ShowMessage( 'Error al recuperar el juego utilizando expresiones regulares: ' + e.<B>Message</B> ); \r
+      <B>end</B>; \r
+      on e: ESerializacion <B>do</B> <B>begin</B> \r
+        r.Free; \r
+        ShowMessage( 'Error al recuperar el juego: ' + e.<B>Message</B> ); \r
+      <B>end</B>; \r
+    <B>end</B>; \r
+    closeFile( f );                         <I><FONT COLOR="Navy">// Cierra el archivo </FONT></I>\r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.SerializarJuego>TMainForm.SerializarJuego</A>( archivo: <B>string</B> ); \r
+<B>var</B> \r
+  serializado: <B>string</B>; \r
+  f:           TextFile; \r
+<B>begin</B> \r
+    <B>try</B> \r
+      assignFile( f, archivo ); <I><FONT COLOR="Navy">// Asigna el archivo </FONT></I>\r
+      rewrite( f );                         <I><FONT COLOR="Navy">// Sobreescribe el archivo </FONT></I>\r
+      <I><FONT COLOR="Navy">// Serializa agregando alguna información sobre el archivo y la versión </FONT></I>\r
+      serializado := '<jaw version=1.0>' + aEspacio.mSerializar + '</jaw>'; \r
+      <B>write</B>( f, serializado );              <I><FONT COLOR="Navy">// Escribe en el archivo </FONT></I>\r
+      closeFile( f );                       <I><FONT COLOR="Navy">// Cierra el archivo </FONT></I>\r
+    <B>except</B>  <I><FONT COLOR="Navy">// Si hay algun error </FONT></I>\r
+      on e: Exception <B>do</B> <I><FONT COLOR="Navy">// Muestra un mensaje </FONT></I>\r
+        ShowMessage( 'Hubo un error al grabar el archivo "' + \r
+                     archivo + '": ' + #13 + #10 + \r
+                     e.<B>Message</B> + #13 + #10 + \r
+                     'Por favor lea la Sección de Errores del Manual del ' + \r
+                     'Usuario para más información'  ); <I><FONT COLOR="Navy">// Muestra un mensaje </FONT></I>\r
+    <B>end</B>; \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=TMainForm.aMenuItemCambioAutomaticoClick>TMainForm.aMenuItemCambioAutomaticoClick</A>(Sender: TObject); \r
+<B>begin</B> \r
+  aMenuItemCambioAutomatico.Checked := <B>not</B> aMenuItemCambioAutomatico.Checked;  \r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/modelo/Coordenadas.pas b/doc/src-html/modelo/Coordenadas.pas
new file mode 100644 (file)
index 0000000..47636cf
--- /dev/null
@@ -0,0 +1,561 @@
+<HTML><HEAD>\r
+<TITLE>File: coordenadas.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=coordenadas.pas><CENTER><H3>coordenadas.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Implementa un sistema de coordenadas y metodos para rotarlo.<br> \r
+    <i>Cambios:</i> \r
+    <PRE> \r
+    28/10/00: Se agregaron métodos para modificar el sistema de coordenadas, asignandole a un versor \r
+              particular la direccion de un vector arbitrario (mSetI, mSetJ, mSetK). \r
+    </PRE>}</FONT></I> \r
+<B>unit</B> Coordenadas; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  Tipos, \r
+  ObjetoPersistente, \r
+  Vectores; \r
\r
+<B>type</B> \r
+  <I><FONT COLOR="Navy">{** Implementa un sistema de coordenadas y metodos para rotarlo.}</FONT></I> \r
+  cCoordenadas = <B>class</B>( cObjetoPersistente ) \r
+    <B>private</B> \r
+      aI,          <I><FONT COLOR="Navy">// Versor i </FONT></I>\r
+      aJ,          <I><FONT COLOR="Navy">// Versor j </FONT></I>\r
+      aK: cVector; <I><FONT COLOR="Navy">// Versor k </FONT></I>\r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create; overload; \r
+      <I><FONT COLOR="Navy">{** Constructor que se basa en otro sistema de coordenadas}</FONT></I> \r
+      <B>constructor</B> create( c: cCoordenadas ); overload; \r
+      <I><FONT COLOR="Navy">{** Rota el sistema de coordenadas sobre el eje i \r
+          (el sentido positivo es de j a k)}</FONT></I> \r
+      <B>function</B> <A HREF="#cCoordenadas.mRotarEnI">mRotarEnI</A>( dAngulo: tAngulo ): cCoordenadas; \r
+      <I><FONT COLOR="Navy">{** Rota el sistema de coordenadas sobre el eje j \r
+          (el sentido positivo es de i a k)}</FONT></I> \r
+      <B>function</B> <A HREF="#cCoordenadas.mRotarEnJ">mRotarEnJ</A>( dAngulo: tAngulo ): cCoordenadas; \r
+      <I><FONT COLOR="Navy">{** Rota el sistema de coordenadas sobre el eje k \r
+          (el sentido positivo es de i a j)}</FONT></I> \r
+      <B>function</B> <A HREF="#cCoordenadas.mRotarEnK">mRotarEnK</A>( dAngulo: tAngulo ): cCoordenadas; \r
+      <I><FONT COLOR="Navy">{** Obtiene el versor i}</FONT></I> \r
+      <B>function</B> <A HREF="#cCoordenadas.mGetI">mGetI</A>: cVector; \r
+      <I><FONT COLOR="Navy">{** Obtiene el versor j}</FONT></I> \r
+      <B>function</B> <A HREF="#cCoordenadas.mGetJ">mGetJ</A>: cVector; \r
+      <I><FONT COLOR="Navy">{** Obtiene el versor k}</FONT></I> \r
+      <B>function</B> <A HREF="#cCoordenadas.mGetK">mGetK</A>: cVector; \r
+      <I><FONT COLOR="Navy">{** Setea la dirección del versor î igual que la del vector v. \r
+          Para lograr esto, rota primero sobre el eje k y luego sobre el eje j \r
+          (no se rota sobre el eje î).}</FONT></I> \r
+      <B>function</B> <A HREF="#cCoordenadas.mSetI">mSetI</A>( v: cVector ): cCoordenadas; \r
+      <I><FONT COLOR="Navy">{** Setea la dirección del versor j igual que la del vector v. \r
+          Para lograr esto, rota primero sobre el eje î y luego sobre el eje k \r
+          (no se rota sobre el eje j).}</FONT></I> \r
+      <B>function</B> <A HREF="#cCoordenadas.mSetJ">mSetJ</A>( v: cVector ): cCoordenadas; \r
+      <I><FONT COLOR="Navy">{** Setea la dirección del versor k igual que la del vector v. \r
+          Para lograr esto, rota primero sobre el eje j y luego sobre el eje î \r
+          (no se rota sobre el eje k).}</FONT></I> \r
+      <B>function</B> <A HREF="#cCoordenadas.mSetK">mSetK</A>( v: cVector ): cCoordenadas; \r
+      <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar \r
+          y la información entregada depende del parámetro tDebugInfo.}</FONT></I> \r
+      <B>function</B> <A HREF="#cCoordenadas.mGetDebugInfo">mGetDebugInfo</A>( debugLevel: tDebugInfo = DI_MINI ): <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Destructor}</FONT></I> \r
+      <B>destructor</B> destroy; <B>override</B>; \r
+      <I><FONT COLOR="Navy">// SERIALIZACION </FONT></I>\r
+      <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.}</FONT></I> \r
+      <B>function</B> <A HREF="#cCoordenadas.mSerializar">mSerializar</A>: <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+          serializado.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cCoordenadas.mDesSerializar">mDesSerializar</A>( str: <B>string</B> ); <B>override</B>; \r
+  <B>end</B>; \r
\r
+<B>implementation</B> \r
\r
+<B>uses</B> \r
+  RegExpr, \r
+  Math; \r
\r
+<I><FONT COLOR="Navy">{ cCoordenadas }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+<B>constructor</B> cCoordenadas.create; \r
+<B>begin</B> \r
+  <B>inherited</B>; \r
+  aI := cVector.create( 1, 0, 0 ); \r
+  aJ := cVector.create( 0, 1, 0 ); \r
+  aK := cVector.create( 0, 0, 1 ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Constructor que se basa en otro sistema de coordenadas \r
+    @param c Coordenadas en las que se basa para crear las nuevas}</FONT></I> \r
+<B>constructor</B> cCoordenadas.create(c: cCoordenadas); \r
+<B>var</B> \r
+  v: cVector; \r
+<B>begin</B> \r
+  <B>inherited</B> create; \r
+  v := c.mGetI; \r
+  aI := cVector.create( v ); \r
+  v.free; \r
+  v := c.mGetJ; \r
+  aJ := cVector.create( v ); \r
+  v.free; \r
+  v := c.mGetK; \r
+  aK := cVector.create( v ); \r
+  v.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Destructor}</FONT></I> \r
+<B>destructor</B> cCoordenadas.destroy; \r
+<B>begin</B> \r
+  aI.free; \r
+  aJ.free; \r
+  aK.free; \r
+  <B>inherited</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+<I><FONT COLOR="Navy">{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos. \r
+    @return            Cadena de texto con el estado del Objeto. \r
+    @param   debugLevel Cantidad de información requerida}</FONT></I> \r
+<B>function</B> <A NAME=cCoordenadas.mGetDebugInfo>cCoordenadas.mGetDebugInfo</A>(debugLevel: tDebugInfo): <B>string</B>; \r
+<B>begin</B> \r
+  result := 'Versor i: ' + aI.mGetDebugInfo( debugLevel ) + #13 + #10 + \r
+            'Versor j: ' + aJ.mGetDebugInfo( debugLevel ) + #13 + #10 + \r
+            'Versor k: ' + aK.mGetDebugInfo( debugLevel ); \r
+<B>end</B>; \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el versor i}</FONT></I> \r
+<B>function</B> <A NAME=cCoordenadas.mGetI>cCoordenadas.mGetI</A>: cVector; \r
+<B>begin</B> \r
+  result := cVector.create( aI ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el versor j}</FONT></I> \r
+<B>function</B> <A NAME=cCoordenadas.mGetJ>cCoordenadas.mGetJ</A>: cVector; \r
+<B>begin</B> \r
+  result := cVector.create( aJ ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el versor k}</FONT></I> \r
+<B>function</B> <A NAME=cCoordenadas.mGetK>cCoordenadas.mGetK</A>: cVector; \r
+<B>begin</B> \r
+  result := cVector.create( aK ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Rota el sistema de coordenadas sobre el eje i \r
+    @param angulo Ángulo a rotar}</FONT></I> \r
+<B>function</B> <A NAME=cCoordenadas.mRotarEnI>cCoordenadas.mRotarEnI</A>(dAngulo: tAngulo): cCoordenadas; \r
+<B>var</B> \r
+  oJ,               <I><FONT COLOR="Navy">// componente en j </FONT></I>\r
+  oK,               <I><FONT COLOR="Navy">// componente en k </FONT></I>\r
+  oNuevoJ,          <I><FONT COLOR="Navy">// nueva coordenada j </FONT></I>\r
+  oNuevoK: cVector; <I><FONT COLOR="Navy">// nueva coordenada k </FONT></I>\r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Primero se calcula el nuevo versor i utilizando la </FONT></I>\r
+  <I><FONT COLOR="Navy">//  transformacion lineal: j' = j * cos tAngulo + k * sin tAngulo </FONT></I>\r
+  oJ := cVector.create( aJ ).mMultiplicar( cos( dAngulo ) ); \r
+  oK := cVector.create( aK ).mMultiplicar( sin( dAngulo ) ); \r
+  oNuevoJ := cVector.create( oJ ).mSumar( oK ); \r
+  oJ.free; \r
+  oK.free; \r
+  <I><FONT COLOR="Navy">// Ahora se calcula el nuevo versor k utilizando la </FONT></I>\r
+  <I><FONT COLOR="Navy">//  transformacion lineal: k' = k * cos tAngulo - j * sin tAngulo </FONT></I>\r
+  oJ := cVector.create( aJ ).mMultiplicar( sin( dAngulo ) ); \r
+  oK := cVector.create( aK ).mMultiplicar( cos( dAngulo ) ); \r
+  oNuevoK := cVector.create( oK ).mRestar( oJ ); \r
+  oJ.free; \r
+  oK.free; \r
+  <I><FONT COLOR="Navy">// Se reemplazan los viejos versores por los nuevos </FONT></I>\r
+  aJ.mSet( oNuevoJ ); \r
+  aK.mSet( oNuevoK ); \r
+  oNuevoJ.free; \r
+  oNuevoK.free; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Rota el sistema de coordenadas sobre el eje j \r
+    @param angulo Ángulo a rotar}</FONT></I> \r
+<B>function</B> <A NAME=cCoordenadas.mRotarEnJ>cCoordenadas.mRotarEnJ</A>(dAngulo: tAngulo): cCoordenadas; \r
+<B>var</B> \r
+  oI,               <I><FONT COLOR="Navy">// componente en i </FONT></I>\r
+  oK,               <I><FONT COLOR="Navy">// componente en k </FONT></I>\r
+  oNuevoI,          <I><FONT COLOR="Navy">// nueva coordenada i </FONT></I>\r
+  oNuevoK: cVector; <I><FONT COLOR="Navy">// nueva coordenada k </FONT></I>\r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Primero se calcula el nuevo versor i utilizando la </FONT></I>\r
+  <I><FONT COLOR="Navy">//  transformacion lineal: i' = i * cos tAngulo + k * sin tAngulo </FONT></I>\r
+  oI := cVector.create( aI ).mMultiplicar( cos( dAngulo ) ); \r
+  oK := cVector.create( aK ).mMultiplicar( sin( dAngulo ) ); \r
+  oNuevoI := cVector.create( oI ).mSumar( oK ); \r
+  oI.free; \r
+  oK.free; \r
+  <I><FONT COLOR="Navy">// Ahora se calcula el nuevo versor k utilizando la </FONT></I>\r
+  <I><FONT COLOR="Navy">//  transformacion lineal: k' = k * cos tAngulo - i * sin tAngulo </FONT></I>\r
+  oI := cVector.create( aI ).mMultiplicar( sin( dAngulo ) ); \r
+  oK := cVector.create( aK ).mMultiplicar( cos( dAngulo ) ); \r
+  oNuevoK := cVector.create( oK ).mRestar( oI ); \r
+  oI.free; \r
+  oK.free; \r
+  <I><FONT COLOR="Navy">// Se reemplazan los viejos versores por los nuevos </FONT></I>\r
+  aI.mSet( oNuevoI ); \r
+  aK.mSet( oNuevoK ); \r
+  oNuevoI.free; \r
+  oNuevoK.free; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Rota el sistema de coordenadas sobre el eje k \r
+    @param angulo Ángulo a rotar}</FONT></I> \r
+<B>function</B> <A NAME=cCoordenadas.mRotarEnK>cCoordenadas.mRotarEnK</A>(dAngulo: tAngulo): cCoordenadas; \r
+<B>var</B> \r
+  oI,               <I><FONT COLOR="Navy">// componente en i </FONT></I>\r
+  oJ,               <I><FONT COLOR="Navy">// componente en j </FONT></I>\r
+  oNuevoI,          <I><FONT COLOR="Navy">// nueva coordenada i </FONT></I>\r
+  oNuevoJ: cVector; <I><FONT COLOR="Navy">// nueva coordenada j </FONT></I>\r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Primero se calcula el nuevo versor i utilizando la </FONT></I>\r
+  <I><FONT COLOR="Navy">//  transformacion lineal: i' = i * cos tAngulo + j * sin tAngulo </FONT></I>\r
+  oI := cVector.create( aI ).mMultiplicar( cos( dAngulo ) ); \r
+  oJ := cVector.create( aJ ).mMultiplicar( sin( dAngulo ) ); \r
+  oNuevoI := cVector.create( oI ).mSumar( oJ ); \r
+  oI.free; \r
+  oJ.free; \r
+  <I><FONT COLOR="Navy">// Ahora se calcula el nuevo versor j utilizando la </FONT></I>\r
+  <I><FONT COLOR="Navy">//  transformacion lineal: j' = j * cos tAngulo - i * sin tAngulo </FONT></I>\r
+  oI := cVector.create( aI ).mMultiplicar( sin( dAngulo ) ); \r
+  oJ := cVector.create( aJ ).mMultiplicar( cos( dAngulo ) ); \r
+  oNuevoJ := cVector.create( oJ ).mRestar( oI ); \r
+  oI.free; \r
+  oJ.free; \r
+  <I><FONT COLOR="Navy">// Se reemplazan los viejos versores por los nuevos </FONT></I>\r
+  aI.mSet( oNuevoI ); \r
+  aJ.mSet( oNuevoJ ); \r
+  oNuevoI.free; \r
+  oNuevoJ.free; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Setea la dirección del versor î igual que la del vector v. \r
+    Para lograr esto, rota primero sobre el eje k y luego sobre el eje j \r
+    (no se rota sobre el eje î). \r
+    @param v Dirección a asignarle a î (no puede ser nulo!)}</FONT></I> \r
+<B>function</B> <A NAME=cCoordenadas.mSetI>cCoordenadas.mSetI</A>(v: cVector): cCoordenadas; \r
+<B>var</B> \r
+  vProy,              <I><FONT COLOR="Navy">// Proyección de v sobre el plano ij </FONT></I>\r
+  vi,                 <I><FONT COLOR="Navy">// ip.i (vector proyeccion de v en i) </FONT></I>\r
+  vj: cVector;        <I><FONT COLOR="Navy">// jp.j (vector proyeccion de v en j) </FONT></I>\r
+  ip,                 <I><FONT COLOR="Navy">// v.i  (proyeccion de v en i) </FONT></I>\r
+  jp,                 <I><FONT COLOR="Navy">// v.j  (proyeccion de v en j) </FONT></I>\r
+  kp,                 <I><FONT COLOR="Navy">// v.k  (proyeccion de v en k) </FONT></I>\r
+  modulo: tLongitud;  <I><FONT COLOR="Navy">// Módulo de vProy </FONT></I>\r
+  alfa,               <I><FONT COLOR="Navy">// Angulo formado entre i y vProy </FONT></I>\r
+  beta: tAngulo;      <I><FONT COLOR="Navy">// Angulo formado entre i' (i rotado sobre k) y v </FONT></I>\r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Se calcula la proyeccion de v sobre el plano formado por î y j. </FONT></I>\r
+  <I><FONT COLOR="Navy">// Para hacer esto, se utiliza la farmula de proyeccion a partir de una base ortonormal </FONT></I>\r
+  <I><FONT COLOR="Navy">//  del subespacio en donde proyectar (en este caso el subespacio es el plano formado </FONT></I>\r
+  <I><FONT COLOR="Navy">//  por îj y los versores de la BON son î y j: </FONT></I>\r
+  <I><FONT COLOR="Navy">//    Proy ij (v) = (v.i).i + (v.j).j </FONT></I>\r
+  <I><FONT COLOR="Navy">// Se crea en base a i y se multiplica por el producto escalar entre v y î </FONT></I>\r
+  ip := v.mMultiplicarEsc( aI ); \r
+  vi := cVector.create( aI ).mMultiplicar( ip ); \r
+  <I><FONT COLOR="Navy">// Se crea en base a j y se multiplica por el producto escalar entre v y j </FONT></I>\r
+  jp := v.mMultiplicarEsc( aJ ); \r
+  vj := cVector.create( aJ ).mMultiplicar( jp ); \r
+  <I><FONT COLOR="Navy">// Ahora se calcula la proyección sumando vi y vj </FONT></I>\r
+  vProy := cVector.create( vi ).mSumar( vj ); \r
+  <I><FONT COLOR="Navy">// Con esta proyección podemos calcular en ángulo que debemos rotar las coordenadas </FONT></I>\r
+  <I><FONT COLOR="Navy">//  sobre el eje k de la siguiente forma (se toman las proyecciones para que, dependiendo </FONT></I>\r
+  <I><FONT COLOR="Navy">//  del signo, se pueda establecer el ángulo correcto): </FONT></I>\r
+  <I><FONT COLOR="Navy">//    tg alfa = jp / ip  ==> alfa = arctg( jp / ip ) </FONT></I>\r
+  <I><FONT COLOR="Navy">//  si ip = 0  ==>  v no tiene componentes en i  ==>  se sabe que el angulo es recto, </FONT></I>\r
+  <I><FONT COLOR="Navy">//   para saber si es PI/2 o -PI/2, verificamos si (vProy.j)/|vProy| = cos vProyj = 1, </FONT></I>\r
+  <I><FONT COLOR="Navy">//   entonces alfa = PI/2. Si (vProy.j)/|vProy| = cos vProyj = -1  ==>  alfa = -PI/2 </FONT></I>\r
+  modulo := vProy.mGetModulo; \r
+  <B>if</B> modulo > 0 <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// solo hace falta rotarlo si la proyeccion no es nula </FONT></I>\r
+    alfa := arctan2( jp, ip ); \r
+    <B>if</B> alfa <> 0 <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si el angulo es distinto de cero, hay que rotarlo </FONT></I>\r
+      <B>if</B> alfa = PI/2 <B>then</B> <I><FONT COLOR="Navy">// Si es PI/2 hay que verificar que no sea en realidad -PI/2 </FONT></I>\r
+        <I><FONT COLOR="Navy">// Se compara tomando en cuenta si es menor que cero porque ya sabemos que </FONT></I>\r
+        <I><FONT COLOR="Navy">//  solo puede ser 1 o -1. </FONT></I>\r
+        <B>if</B> jp / modulo < 0 <B>then</B> <I><FONT COLOR="Navy">// cos vProyj = vProy . j / |vProy| = jp . |vProy| </FONT></I>\r
+          alfa := -alfa; <I><FONT COLOR="Navy">// alfa = -PI/2 </FONT></I>\r
+      mRotarEnK( alfa ); <I><FONT COLOR="Navy">// rotamos sobre el eje k ese angulo </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// Ahora tenemos que hallar beta, para esto se calculan las proyecciones sobre i y k </FONT></I>\r
+  <I><FONT COLOR="Navy">// Se calcula la proyeccion, para eso se multiplica por el producto escalar entre v y î </FONT></I>\r
+  ip := v.mMultiplicarEsc( aI ); \r
+  <I><FONT COLOR="Navy">// Se calcula la proyeccion, para eso se multiplica por el producto escalar entre v y k </FONT></I>\r
+  kp := v.mMultiplicarEsc( aK ); \r
+  <I><FONT COLOR="Navy">// Con estas proyecciones podemos calcular en ángulo que debemos rotar las coordenadas </FONT></I>\r
+  <I><FONT COLOR="Navy">//  sobre el eje k de la siguiente forma (se toman las proyecciones para que, dependiendo </FONT></I>\r
+  <I><FONT COLOR="Navy">//  del signo, se pueda establecer el ángulo correcto): </FONT></I>\r
+  <I><FONT COLOR="Navy">//    tg beta = kp / ip  ==> beta = arctg( kp / ip ) </FONT></I>\r
+  <I><FONT COLOR="Navy">//  si ip = 0  ==>  v no tiene componentes en i  ==>  se sabe que el angulo es recto, </FONT></I>\r
+  <I><FONT COLOR="Navy">//   para saber si es PI/2 o -PI/2, verificamos si (v.k)/|v| = cos vk = 1, </FONT></I>\r
+  <I><FONT COLOR="Navy">//   entonces beta = PI/2. Si (v.k)/|v| = cos vk = -1  ==>  beta = -PI/2 </FONT></I>\r
+  modulo := v.mGetModulo; \r
+  <B>if</B> modulo > 0 <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// solo hace falta rotarlo si la proyeccion no es nula </FONT></I>\r
+    beta := arctan2( kp, ip ); \r
+    <B>if</B> beta <> 0 <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si el angulo es distinto de cero, hay que rotarlo </FONT></I>\r
+      <B>if</B> beta = PI/2 <B>then</B> <I><FONT COLOR="Navy">// Si es PI/2 hay que verificar que no sea en realidad -PI/2 </FONT></I>\r
+        <I><FONT COLOR="Navy">// Se compara tomando en cuenta si es menor que cero porque ya sabemos que </FONT></I>\r
+        <I><FONT COLOR="Navy">//  solo puede ser 1 o -1. </FONT></I>\r
+        <B>if</B> kp / modulo < 0 <B>then</B> <I><FONT COLOR="Navy">// cos vk = v . k / |v| = kp . |v| </FONT></I>\r
+          beta := -beta; <I><FONT COLOR="Navy">// beta = -PI/2 </FONT></I>\r
+      mRotarEnJ( beta ); <I><FONT COLOR="Navy">// rotamos sobre el eje j ese angulo </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// Aca termina, ya que no se realiza ninguna rotacion sobre el eje i </FONT></I>\r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Setea la dirección del versor j igual que la del vector v. \r
+    Para lograr esto, rota primero sobre el eje î y luego sobre el eje k \r
+    (no se rota sobre el eje j). \r
+    @param v Dirección a asignarle a j (no puede ser nulo!)}</FONT></I> \r
+<B>function</B> <A NAME=cCoordenadas.mSetJ>cCoordenadas.mSetJ</A>(v: cVector): cCoordenadas; \r
+<B>var</B> \r
+  vProy,              <I><FONT COLOR="Navy">// Proyección de v sobre el plano jk </FONT></I>\r
+  vj,                 <I><FONT COLOR="Navy">// jp.j (vector proyeccion de v en j) </FONT></I>\r
+  vk: cVector;        <I><FONT COLOR="Navy">// kp.k (vector proyeccion de v en k) </FONT></I>\r
+  ip,                 <I><FONT COLOR="Navy">// v.i  (proyeccion de v en i) </FONT></I>\r
+  jp,                 <I><FONT COLOR="Navy">// v.j  (proyeccion de v en j) </FONT></I>\r
+  kp,                 <I><FONT COLOR="Navy">// v.k  (proyeccion de v en k) </FONT></I>\r
+  modulo: tLongitud;  <I><FONT COLOR="Navy">// Módulo de vProy </FONT></I>\r
+  alfa,               <I><FONT COLOR="Navy">// Angulo formado entre j y vProy </FONT></I>\r
+  beta: tAngulo;      <I><FONT COLOR="Navy">// Angulo formado entre j' (j rotado sobre i) y v </FONT></I>\r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Se calcula la proyeccion de v sobre el plano formado por j y k. </FONT></I>\r
+  <I><FONT COLOR="Navy">// Para hacer esto, se utiliza la farmula de proyeccion a partir de una base ortonormal </FONT></I>\r
+  <I><FONT COLOR="Navy">//  del subespacio en donde proyectar (en este caso el subespacio es el plano formado </FONT></I>\r
+  <I><FONT COLOR="Navy">//  por jk y los versores de la BON son j y k: </FONT></I>\r
+  <I><FONT COLOR="Navy">//    Proy jk (v) = (v.j).j + (v.k).k </FONT></I>\r
+  <I><FONT COLOR="Navy">// Se crea en base a j y se multiplica por el producto escalar entre v y j </FONT></I>\r
+  jp := v.mMultiplicarEsc( aJ ); \r
+  vj := cVector.create( aJ ).mMultiplicar( jp ); \r
+  <I><FONT COLOR="Navy">// Se crea en base a k y se multiplica por el producto escalar entre v y k </FONT></I>\r
+  kp := v.mMultiplicarEsc( aK ); \r
+  vk := cVector.create( aK ).mMultiplicar( kp ); \r
+  <I><FONT COLOR="Navy">// Ahora se calcula la proyección sumando vj y vk </FONT></I>\r
+  vProy := cVector.create( vj ).mSumar( vk ); \r
+  <I><FONT COLOR="Navy">// Con esta proyección podemos calcular en ángulo que debemos rotar las coordenadas </FONT></I>\r
+  <I><FONT COLOR="Navy">//  sobre el eje i de la siguiente forma (se toman las proyecciones para que, dependiendo </FONT></I>\r
+  <I><FONT COLOR="Navy">//  del signo, se pueda establecer el ángulo correcto): </FONT></I>\r
+  <I><FONT COLOR="Navy">//    tg alfa = kp / jp  ==> alfa = arctg( kp / jp ) </FONT></I>\r
+  <I><FONT COLOR="Navy">//  si jp = 0  ==>  v no tiene componentes en j  ==>  se sabe que el angulo es recto, </FONT></I>\r
+  <I><FONT COLOR="Navy">//   para saber si es PI/2 o -PI/2, verificamos si (vProy.k)/|vProy| = cos vProyk = 1, </FONT></I>\r
+  <I><FONT COLOR="Navy">//   entonces alfa = PI/2. Si (vProy.k)/|vProy| = cos vProyk = -1  ==>  alfa = -PI/2 </FONT></I>\r
+  modulo := vProy.mGetModulo; \r
+  <B>if</B> modulo > 0 <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// solo hace falta rotarlo si la proyeccion no es nula </FONT></I>\r
+    alfa := arctan2( kp, jp ); \r
+    <B>if</B> alfa <> 0 <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si el angulo es distinto de cero, hay que rotarlo </FONT></I>\r
+      <B>if</B> alfa = PI/2 <B>then</B> <I><FONT COLOR="Navy">// Si es PI/2 hay que verificar que no sea en realidad -PI/2 </FONT></I>\r
+        <I><FONT COLOR="Navy">// Se compara tomando en cuenta si es menor que cero porque ya sabemos que </FONT></I>\r
+        <I><FONT COLOR="Navy">//  solo puede ser 1 o -1. </FONT></I>\r
+        <B>if</B> kp / modulo < 0 <B>then</B> <I><FONT COLOR="Navy">// cos vProyk = vProy . k / |vProy| = kp . |vProy| </FONT></I>\r
+          alfa := -alfa; <I><FONT COLOR="Navy">// alfa = -PI/2 </FONT></I>\r
+      mRotarEnI( alfa ); <I><FONT COLOR="Navy">// rotamos sobre el eje i ese angulo </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// Ahora tenemos que hallar beta, para esto se calculan las proyecciones sobre j y i </FONT></I>\r
+  <I><FONT COLOR="Navy">// Se calcula la proyeccion, para eso se multiplica por el producto escalar entre v y j </FONT></I>\r
+  jp := v.mMultiplicarEsc( aJ ); \r
+  <I><FONT COLOR="Navy">// Se calcula la proyeccion, para eso se multiplica por el producto escalar entre v y i </FONT></I>\r
+  ip := v.mMultiplicarEsc( aI ); \r
+  <I><FONT COLOR="Navy">// Con estas proyecciones podemos calcular en ángulo que debemos rotar las coordenadas </FONT></I>\r
+  <I><FONT COLOR="Navy">//  sobre el eje k de la siguiente forma (se toman las proyecciones para que, dependiendo </FONT></I>\r
+  <I><FONT COLOR="Navy">//  del signo, se pueda establecer el ángulo correcto): </FONT></I>\r
+  <I><FONT COLOR="Navy">//    tg beta = ip / jp  ==> beta = arctg( ip / jp ) </FONT></I>\r
+  <I><FONT COLOR="Navy">//  si jp = 0  ==>  v no tiene componentes en j  ==>  se sabe que el angulo es recto, </FONT></I>\r
+  <I><FONT COLOR="Navy">//   para saber si es PI/2 o -PI/2, verificamos si (v.i)/|v| = cos vi = 1, </FONT></I>\r
+  <I><FONT COLOR="Navy">//   entonces beta = PI/2. Si (v.i)/|v| = cos vi = -1  ==>  beta = -PI/2 </FONT></I>\r
+  modulo := v.mGetModulo; \r
+  <B>if</B> modulo > 0 <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// solo hace falta rotarlo si la proyeccion no es nula </FONT></I>\r
+    beta := arctan2( ip, jp ); \r
+    <B>if</B> beta <> 0 <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si el angulo es distinto de cero, hay que rotarlo </FONT></I>\r
+      <B>if</B> beta = PI/2 <B>then</B> <I><FONT COLOR="Navy">// Si es PI/2 hay que verificar que no sea en realidad -PI/2 </FONT></I>\r
+        <I><FONT COLOR="Navy">// Se compara tomando en cuenta si es menor que cero porque ya sabemos que </FONT></I>\r
+        <I><FONT COLOR="Navy">//  solo puede ser 1 o -1. </FONT></I>\r
+        <B>if</B> ip / modulo < 0 <B>then</B> <I><FONT COLOR="Navy">// cos vi = v . i / |v| = ip . |v| </FONT></I>\r
+          beta := -beta; <I><FONT COLOR="Navy">// beta = -PI/2 </FONT></I>\r
+      mRotarEnK( -beta ); <I><FONT COLOR="Navy">// rotamos sobre el eje k ese angulo (el signo negativo es porque </FONT></I>\r
+                          <I><FONT COLOR="Navy">//  estamos rotando en sentido opuesto, de j a i) </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// Aca termina, ya que no se realiza ninguna rotacion sobre el eje j </FONT></I>\r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Setea la dirección del versor k igual que la del vector v. \r
+    Para lograr esto, rota primero sobre el eje j y luego sobre el eje î \r
+    (no se rota sobre el eje k). \r
+    @param v Dirección a asignarle a k (no puede ser nulo!)}</FONT></I> \r
+<B>function</B> <A NAME=cCoordenadas.mSetK>cCoordenadas.mSetK</A>(v: cVector): cCoordenadas; \r
+<B>var</B> \r
+  vProy,              <I><FONT COLOR="Navy">// Proyección de v sobre el plano jk </FONT></I>\r
+  vi,                 <I><FONT COLOR="Navy">// ip.i (vector proyeccion de v en i) </FONT></I>\r
+  vk: cVector;        <I><FONT COLOR="Navy">// kp.k (vector proyeccion de v en k) </FONT></I>\r
+  ip,                 <I><FONT COLOR="Navy">// v.i  (proyeccion de v en i) </FONT></I>\r
+  jp,                 <I><FONT COLOR="Navy">// v.j  (proyeccion de v en j) </FONT></I>\r
+  kp,                 <I><FONT COLOR="Navy">// v.k  (proyeccion de v en k) </FONT></I>\r
+  modulo: tLongitud;  <I><FONT COLOR="Navy">// Módulo de vProy </FONT></I>\r
+  alfa,               <I><FONT COLOR="Navy">// Angulo formado entre j y vProy </FONT></I>\r
+  beta: tAngulo;      <I><FONT COLOR="Navy">// Angulo formado entre j' (j rotado sobre i) y v </FONT></I>\r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Se calcula la proyeccion de v sobre el plano formado por k y i. </FONT></I>\r
+  <I><FONT COLOR="Navy">// Para hacer esto, se utiliza la farmula de proyeccion a partir de una base ortonormal </FONT></I>\r
+  <I><FONT COLOR="Navy">//  del subespacio en donde proyectar (en este caso el subespacio es el plano formado </FONT></I>\r
+  <I><FONT COLOR="Navy">//  por ki y los versores de la BON son k y i: </FONT></I>\r
+  <I><FONT COLOR="Navy">//    Proy ki (v) = (v.k).k + (v.i).i </FONT></I>\r
+  <I><FONT COLOR="Navy">// Se crea en base a k y se multiplica por el producto escalar entre v y k </FONT></I>\r
+  kp := v.mMultiplicarEsc( aK ); \r
+  vk := cVector.create( aK ).mMultiplicar( kp ); \r
+  <I><FONT COLOR="Navy">// Se crea en base a k y se multiplica por el producto escalar entre v y k </FONT></I>\r
+  ip := v.mMultiplicarEsc( aI ); \r
+  vi := cVector.create( aI ).mMultiplicar( ip ); \r
+  <I><FONT COLOR="Navy">// Ahora se calcula la proyección sumando vk y vi </FONT></I>\r
+  vProy := cVector.create( vk ).mSumar( vi ); \r
+  <I><FONT COLOR="Navy">// Con esta proyección podemos calcular en ángulo que debemos rotar las coordenadas </FONT></I>\r
+  <I><FONT COLOR="Navy">//  sobre el eje j de la siguiente forma (se toman las proyecciones para que, dependiendo </FONT></I>\r
+  <I><FONT COLOR="Navy">//  del signo, se pueda establecer el ángulo correcto): </FONT></I>\r
+  <I><FONT COLOR="Navy">//    tg alfa = ip / kp  ==> alfa = arctg( ip / kp ) </FONT></I>\r
+  <I><FONT COLOR="Navy">//  si kp = 0  ==>  v no tiene componentes en j  ==>  se sabe que el angulo es recto, </FONT></I>\r
+  <I><FONT COLOR="Navy">//   para saber si es PI/2 o -PI/2, verificamos si (vProy.i)/|vProy| = cos vProyi = 1, </FONT></I>\r
+  <I><FONT COLOR="Navy">//   entonces alfa = PI/2. Si (vProy.i)/|vProy| = cos vProyi = -1  ==>  alfa = -PI/2 </FONT></I>\r
+  modulo := vProy.mGetModulo; \r
+  <B>if</B> modulo > 0 <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// solo hace falta rotarlo si la proyeccion no es nula </FONT></I>\r
+    alfa := arctan2( ip, kp ); \r
+    <B>if</B> alfa <> 0 <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si el angulo es distinto de cero, hay que rotarlo </FONT></I>\r
+      <B>if</B> alfa = PI/2 <B>then</B> <I><FONT COLOR="Navy">// Si es PI/2 hay que verificar que no sea en realidad -PI/2 </FONT></I>\r
+        <I><FONT COLOR="Navy">// Se compara tomando en cuenta si es menor que cero porque ya sabemos que </FONT></I>\r
+        <I><FONT COLOR="Navy">//  solo puede ser 1 o -1. </FONT></I>\r
+        <B>if</B> ip / modulo < 0 <B>then</B> <I><FONT COLOR="Navy">// cos vProyi = vProy . i / |vProy| = ip . |vProy| </FONT></I>\r
+          alfa := -alfa; <I><FONT COLOR="Navy">// alfa = -PI/2 </FONT></I>\r
+      mRotarEnJ( -alfa ); <I><FONT COLOR="Navy">// rotamos sobre el eje j ese angulo (el signo negativo es porque </FONT></I>\r
+                          <I><FONT COLOR="Navy">//  estamos rotando en sentido opuesto, de k a i) </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// Ahora tenemos que hallar beta, para esto se calculan las proyecciones sobre k y j </FONT></I>\r
+  <I><FONT COLOR="Navy">// Se calcula la proyeccion, para eso se multiplica por el producto escalar entre v y k </FONT></I>\r
+  kp := v.mMultiplicarEsc( aK ); \r
+  <I><FONT COLOR="Navy">// Se calcula la proyeccion, para eso se multiplica por el producto escalar entre v y j </FONT></I>\r
+  jp := v.mMultiplicarEsc( aJ ); \r
+  <I><FONT COLOR="Navy">// Con estas proyecciones podemos calcular en ángulo que debemos rotar las coordenadas </FONT></I>\r
+  <I><FONT COLOR="Navy">//  sobre el eje i de la siguiente forma (se toman las proyecciones para que, dependiendo </FONT></I>\r
+  <I><FONT COLOR="Navy">//  del signo, se pueda establecer el ángulo correcto): </FONT></I>\r
+  <I><FONT COLOR="Navy">//    tg beta = jp / kp  ==> beta = arctg( jp / kp ) </FONT></I>\r
+  <I><FONT COLOR="Navy">//  si kp = 0  ==>  v no tiene componentes en k  ==>  se sabe que el angulo es recto, </FONT></I>\r
+  <I><FONT COLOR="Navy">//   para saber si es PI/2 o -PI/2, verificamos si (v.j)/|v| = cos vj = 1, </FONT></I>\r
+  <I><FONT COLOR="Navy">//   entonces beta = PI/2. Si (v.j)/|v| = cos vj = -1  ==>  beta = -PI/2 </FONT></I>\r
+  modulo := v.mGetModulo; \r
+  <B>if</B> modulo > 0 <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// solo hace falta rotarlo si la proyeccion no es nula </FONT></I>\r
+    beta := arctan2( jp, kp ); \r
+    <B>if</B> beta <> 0 <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si el angulo es distinto de cero, hay que rotarlo </FONT></I>\r
+      <B>if</B> beta = PI/2 <B>then</B> <I><FONT COLOR="Navy">// Si es PI/2 hay que verificar que no sea en realidad -PI/2 </FONT></I>\r
+        <I><FONT COLOR="Navy">// Se compara tomando en cuenta si es menor que cero porque ya sabemos que </FONT></I>\r
+        <I><FONT COLOR="Navy">//  solo puede ser 1 o -1. </FONT></I>\r
+        <B>if</B> ip / modulo < 0 <B>then</B> <I><FONT COLOR="Navy">// cos vj = v . j / |v| = jp . |v| </FONT></I>\r
+          beta := -beta; <I><FONT COLOR="Navy">// beta = -PI/2 </FONT></I>\r
+      mRotarEnI( -beta ); <I><FONT COLOR="Navy">// rotamos sobre el eje i ese angulo (el signo negativo es porque </FONT></I>\r
+                          <I><FONT COLOR="Navy">//  estamos rotando en sentido opuesto, de k a j) </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// Aca termina, ya que no se realiza ninguna rotacion sobre el eje k </FONT></I>\r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+    serializado. \r
+    @param str Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>procedure</B> <A NAME=cCoordenadas.mDesSerializar>cCoordenadas.mDesSerializar</A>(str: <B>string</B>); \r
+<B>var</B> \r
+  r: TRegExpr; \r
+<B>begin</B> \r
+  <B>inherited</B> mDesSerializar( str ); <I><FONT COLOR="Navy">// SIEMPRE el ID debe ser el PRIMER atributo </FONT></I>\r
+  r := TRegExpr.create; \r
+  <I><FONT COLOR="Navy">// VERSOR I </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<i>/s*(.+)/s*</i>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      <B>if</B> aI <> <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no es nulo </FONT></I>\r
+        aI.mDesSerializar( r.Match[1] ) <I><FONT COLOR="Navy">// Lo deserializa </FONT></I>\r
+      <B>else</B> <I><FONT COLOR="Navy">// si es nulo </FONT></I>\r
+        aI := cVector.crearDeSerializado( r.Match[1] ) <I><FONT COLOR="Navy">// lo crea </FONT></I>\r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el versor i' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ESerializacion <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si fueron de serializacion... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al deserializar el versor i: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el versor i utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// VERSOR J </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<j>/s*(.+)/s*</j>'; \r
+    <B>if</B> r.Exec ( str ) <B>then</B> \r
+      <B>if</B> aJ <> <B>nil</B> <B>then</B> \r
+        aJ.mDesSerializar( r.Match[1] ) \r
+      <B>else</B> \r
+        aJ := cVector.crearDeSerializado( r.Match[1] ) \r
+    <B>else</B> \r
+      <B>raise</B> ESerializacion.create( 'No se encontro el versor j' ); \r
+  <B>except</B> \r
+    on e: ESerializacion <B>do</B> <B>begin</B> \r
+      r.Free; \r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al deserializar el versor j: ' + e.<B>Message</B> ); \r
+    <B>end</B>; \r
+    on e: ERegExpr <B>do</B> <B>begin</B> \r
+      r.Free; \r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el versor j utilizando expresiones regulares: ' + e.<B>Message</B> ); \r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// VERSOR K </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<k>/s*(.+)/s*</k>'; \r
+    <B>if</B> r.Exec ( str ) <B>then</B> \r
+      <B>if</B> aK <> <B>nil</B> <B>then</B> \r
+        aK.mDesSerializar( r.Match[1] ) \r
+      <B>else</B> \r
+        aK := cVector.crearDeSerializado( r.Match[1] ) \r
+    <B>else</B> \r
+      <B>raise</B> ESerializacion.create( 'No se encontro el versor k' ); \r
+  <B>except</B> \r
+    on e: ESerializacion <B>do</B> <B>begin</B> \r
+      r.Free; \r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al deserializar el versor k: ' + e.<B>Message</B> ); \r
+    <B>end</B>; \r
+    on e: ERegExpr <B>do</B> <B>begin</B> \r
+      r.Free; \r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el versor k utilizando expresiones regulares: ' + e.<B>Message</B> ); \r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  r.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado. \r
+    @return Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>function</B> <A NAME=cCoordenadas.mSerializar>cCoordenadas.mSerializar</A>: <B>string</B>; \r
+<B>begin</B> \r
+  result := <B>inherited</B> mSerializar + \r
+            '<i>' + aI.mSerializar + '</i>' + \r
+            '<j>' + aJ.mSerializar + '</j>' + \r
+            '<k>' + aK.mSerializar + '</k>'; \r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/modelo/Espacio.pas b/doc/src-html/modelo/Espacio.pas
new file mode 100644 (file)
index 0000000..db5f5f3
--- /dev/null
@@ -0,0 +1,504 @@
+<HTML><HEAD>\r
+<TITLE>File: espacio.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=espacio.pas><CENTER><H3>espacio.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Se encarga de controlar la interacción entre \r
+    las naves y el responsable de manejar el tiempo.<br> \r
+    <i>Cambios:</i> \r
+    <PRE> \r
+    05/10/00: Se corrigió para que utilice los nuevos metodos de cNaveEnemiga y cObjetoVolador \r
+              Se corrigió el método mComunicarPosicion para que solo se comunique la posicion \r
+              a las naves que estan en el campo de radar de la nave espia. \r
+    07/10/00: Se agregaron los métodos mDestruir y mActualizarObjetoVolador. Se modificó el \r
+              método mActualizar (para usar los nuevos) y el método mDetectarColisiones para \r
+              manejar de forma más eficiente y clara la destrucción de objetos sin energía. \r
+    03/11/00: Se sacan los metodos mIniciay y mParar, ya que el control del tiempo y el encargado \r
+              de actualizar el espacio sera el Controlador (Controller). \r
+              Se agregaron métodos para facilitar la manipulación del espacio: \r
+              mQuitarObjeto, mGetObjetos, mSetObjetos y mSetNavePropia \r
+    05/11/00: Se corrigió un BUG que hacia que siempre el espacio se inicialice con una lista vacia \r
+              y una nave propia estandar (en el constructor). \r
+    09/11/00: Se corrigió un BUG que hacía que la nave espia no pueda escapar, ya que se avisaba a si misma. \r
+              Tambien se hace que ignore otras naves espias que esten avisando para evitar problemas similares. \r
+              (en el método mComunicarPosicion). \r
+    10/11/00: Se reemplaza el método mNavePropiaDestruida por una excepción (ENavePropiaDestruida). \r
+              Es lanzada por el método mActualizar y otros metodos privados que utilizan la nave propia. \r
+    27/11/00: Se agrega el control de disparos de las naves enemigas en el método mActualizar \r
+    29/11/00: Se elimina el método temporal mActualizarNavePropia. \r
+    01/12/00: Se modifica el método mActualizar para manejar los disparos de la nave propia. \r
+    </PRE>}</FONT></I> \r
+<B>unit</B> Espacio; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  Tipos, \r
+  ObjetoPersistente, \r
+  ObjetoVolador, \r
+  Nave, \r
+  Vectores, \r
+  Armas, \r
+  NaveEnemiga, \r
+  NavesEnemigas, \r
+  NavePropia, \r
+  Classes, \r
+  Sysutils, \r
+  Meteorito; \r
\r
+<B>type</B> \r
+  <I><FONT COLOR="Navy">{** Excepcion producida por el espacio si la nave propia fue destruido}</FONT></I> \r
+  ENavePropiaDestruida = <B>class</B>( Exception ) \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create; \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Se encarga de controlar la interacción entre \r
+      las naves y el responsable de manejar el tiempo.}</FONT></I> \r
+  cEspacio = <B>class</B>( cObjetoPersistente ) \r
+    <B>private</B> \r
+      aDeltaT:  tTiempo;        <I><FONT COLOR="Navy">// Intervalo de tiempo (en milisegundos) que pasa entre ciclo y ciclo </FONT></I>\r
+      aNavePropia: cNavePropia; <I><FONT COLOR="Navy">// Nave del jugador, tambien esta en la lista, pero se lo </FONT></I>\r
+                                <I><FONT COLOR="Navy">//  pone a parte para poder ser referenciado más fácilmente </FONT></I>\r
+      aObjetos: TList;          <I><FONT COLOR="Navy">// Lista con los objetos presentes en el espacio </FONT></I>\r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Procedimiento que evalua las posiciones de los Objetos Voladores que se encuentran en el espacio, \r
+          verificando 2 a 2 si hay una colisión.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cEspacio.mDetectarColision">mDetectarColision</A>; \r
+      <I><FONT COLOR="Navy">{** Método que se encarga de avisar al resto de las naves enemigas que estan cerca de una \r
+          espia sobre la ultima posicion de la nave propia.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cEspacio.mComunicarPosicion">mComunicarPosicion</A>( nEsp: cNaveEspia ); \r
+      <I><FONT COLOR="Navy">{** Destruye un Objeto Volador}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cEspacio.mDestruir">mDestruir</A>( ov: cObjetoVolador ); \r
+      <I><FONT COLOR="Navy">{** Actualiza el estado de un objeto según sea tu tipo}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cEspacio.mActualizarObjetoVolador">mActualizarObjetoVolador</A>( ov: cObjetoVolador ); \r
+      <I><FONT COLOR="Navy">{** Elimina los objetos duplicados después de recuperarlos de una serialización}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cEspacio.mEliminarDuplicados">mEliminarDuplicados</A>; \r
+      <I><FONT COLOR="Navy">{** Busca el duplicado de un objeto volador}</FONT></I> \r
+      <B>function</B> <A HREF="#cEspacio.mBuscarDuplicado">mBuscarDuplicado</A>( ov: cObjetoVolador ): cObjetoVolador; \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor. La lista que se pasa NO debe incluir la nave propia}</FONT></I> \r
+      <B>constructor</B> create( np: cNavePropia = <B>nil</B>; objetos: TList = <B>nil</B>; dt: tTiempo = 25 ); \r
+      <I><FONT COLOR="Navy">{** Actualiza el Espacio. En esto se incluye mover las naves, detectar colisiones y tomar las \r
+          desiciones necesarias según sea el caso.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cEspacio.mActualizar">mActualizar</A>; \r
+      <I><FONT COLOR="Navy">{** Agrega un Objeto Volador al Espacio}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cEspacio.mAgregarObjeto">mAgregarObjeto</A>( ov: cObjetoVolador ); \r
+      <I><FONT COLOR="Navy">{** Quita un Objeto Volador del Espacio. Devuelve true si lo saco y false si no existia}</FONT></I> \r
+      <B>function</B> <A HREF="#cEspacio.mQuitarObjeto">mQuitarObjeto</A>( ov: cObjetoVolador ): boolean; \r
+      <I><FONT COLOR="Navy">{** Obtiene la lista de Objetos Voladores del Espacio}</FONT></I> \r
+      <B>function</B> <A HREF="#cEspacio.mGetObjetos">mGetObjetos</A>: TList; \r
+      <I><FONT COLOR="Navy">{** Cambia la lista de Objetos Voladores del Espacio, devolviendo un puntero a la lista vieja}</FONT></I> \r
+      <B>function</B> <A HREF="#cEspacio.mSetObjetos">mSetObjetos</A>( l: TList ): TList; \r
+      <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar \r
+          y la información entregada depende del parámetro tDebugInfo.}</FONT></I> \r
+      <B>function</B> <A HREF="#cEspacio.mGetDebugInfo">mGetDebugInfo</A>( debugLevel: tDebugInfo = DI_MINI ): <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Método que obtiene la nave propia del espacio (este método es probable que deje de exstir)}</FONT></I> \r
+      <B>function</B> <A HREF="#cEspacio.mGetNavePropia">mGetNavePropia</A>: cNavePropia; \r
+      <I><FONT COLOR="Navy">{** Método para cambiar la nave propia. Devuelve un puntero a la nave propia vieja.}</FONT></I> \r
+      <B>function</B> <A HREF="#cEspacio.mSetNavePropia">mSetNavePropia</A>( np: cNavePropia ): cNavePropia; \r
+      <I><FONT COLOR="Navy">{** Destructor}</FONT></I> \r
+      <B>destructor</B> destroy; <B>override</B>; \r
+      <I><FONT COLOR="Navy">// SERIALIZACION </FONT></I>\r
+      <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.}</FONT></I> \r
+      <B>function</B> <A HREF="#cEspacio.mSerializar">mSerializar</A>: <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+          serializado.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cEspacio.mDesSerializar">mDesSerializar</A>( str: <B>string</B> ); <B>override</B>; \r
+    <B>end</B>; \r
\r
+<B>implementation</B> \r
\r
+<B>uses</B> \r
+  RegExpr, \r
+  SerializacionUtils; \r
\r
+<I><FONT COLOR="Navy">{ cEspacio }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Constructor \r
+    @param np      Nave propia a utilizar \r
+    @param objetos Lista de objetos voladores (sin incluir la nave propia!) \r
+    @param dt      Intervalo de tiempo}</FONT></I> \r
+<B>constructor</B> cEspacio.create(np: cNavePropia; objetos: TList; dt: tTiempo); \r
+<B>begin</B> \r
+  <B>inherited</B> create; \r
+  <B>if</B> objetos <> <B>nil</B> <B>then</B> \r
+    aObjetos := objetos \r
+  <B>else</B> <I><FONT COLOR="Navy">// Si no se pasó nada como argumento, crea una nueva lista. </FONT></I>\r
+    aObjetos := TList.create; \r
+  <I><FONT COLOR="Navy">// inicializa la nave propia y la inserta en la lista. </FONT></I>\r
+  <B>if</B> np <> <B>nil</B> <B>then</B> \r
+    aNavePropia := np \r
+  <B>else</B> <I><FONT COLOR="Navy">// Si no se pasó nada como argumento, crea una nueva nave propia. </FONT></I>\r
+    aNavePropia := cNavePropia.create; \r
+  aObjetos.Add( aNavePropia ); \r
+  <I><FONT COLOR="Navy">// Define el intervalo de tiempo </FONT></I>\r
+  aDeltaT := dt; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Destructor}</FONT></I> \r
+<B>destructor</B> cEspacio.destroy; \r
+<B>var</B> \r
+  oOV: cObjetoVolador; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Recorre la lista, liberando los Objetos Voladores en ella </FONT></I>\r
+  <B>while</B> aObjetos.Count > 0 <B>do</B> <B>begin</B> \r
+    oOV := aObjetos.First; \r
+    aObjetos.Remove( oOV ); \r
+    oOV.free; \r
+  <B>end</B>; \r
+  aObjetos.free; <I><FONT COLOR="Navy">// Libera la memoria de la lista </FONT></I>\r
+  <B>inherited</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Actualiza el Espacio. En esto se incluye mover las naves, detectar colisiones y tomar las \r
+    desiciones necesarias según sea el caso.}</FONT></I> \r
+<B>procedure</B> <A NAME=cEspacio.mActualizar>cEspacio.mActualizar</A>; \r
+<B>var</B> \r
+  i:     integer;        <I><FONT COLOR="Navy">// contador para el bucle </FONT></I>\r
+  oOV:   cObjetoVolador; <I><FONT COLOR="Navy">// objeto volador para apuntar al de la lista </FONT></I>\r
+  oArma: cArma;          <I><FONT COLOR="Navy">// Arma disparada </FONT></I>\r
+<B>begin</B> \r
+  <B>for</B> i:=0 <B>to</B> aObjetos.count -1 <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// recorre la lista de objetos </FONT></I>\r
+    oOV:= aObjetos.items[i]; <I><FONT COLOR="Navy">// obtiene el ObjetoVolador actual </FONT></I>\r
+    mActualizarObjetoVolador( oOV ); <I><FONT COLOR="Navy">// Actualiza el estado del objeto segun su tipo </FONT></I>\r
+    oOV.mMover( aDeltaT );  <I><FONT COLOR="Navy">// Se mueve la objeto volador actual sin importar de que clase sea </FONT></I>\r
+    <B>if</B> oOV <B>is</B> cNave <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si es una nave, maneja los disparos </FONT></I>\r
+      <B>with</B> oOV <B>as</B> cNave <B>do</B> <B>begin</B>  <I><FONT COLOR="Navy">// Convierte el puntero a cNave </FONT></I>\r
+        <B>if</B> oOV <B>is</B> cNaveEnemiga <B>then</B>                   <I><FONT COLOR="Navy">// Si es una nave enemiga </FONT></I>\r
+          oArma := mDisparar( aDeltaT, aNavePropia )  <I><FONT COLOR="Navy">// Dispara con la NavePropia como objetivo </FONT></I>\r
+        <B>else</B>                                   <I><FONT COLOR="Navy">// Si es otra nave (inclusive la nave propia) </FONT></I>\r
+          oArma := mDisparar( aDeltaT )   <I><FONT COLOR="Navy">// dispara con nil como objetivo (el objetivo es </FONT></I>\r
+      <B>end</B>;                                     <I><FONT COLOR="Navy">// manejado por la propia nave) </FONT></I>\r
+      <B>if</B> oArma <> <B>nil</B> <B>then</B>        <I><FONT COLOR="Navy">// Si efectivamente se disparo un arma </FONT></I>\r
+        mAgregarObjeto( oArma );  <I><FONT COLOR="Navy">// Se la agrega a la lista </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  mDetectarColision; <I><FONT COLOR="Navy">// Se detectan las colisiones </FONT></I>\r
+  <B>if</B> aNavePropia = <B>nil</B> <B>then</B> \r
+    <B>raise</B> ENavePropiaDestruida.create; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Actualiza el estado de un objeto volador, dependiendo de que tipo de objeto sea. \r
+    @param ov Objeto Volador a actualizar}</FONT></I> \r
+<B>procedure</B> <A NAME=cEspacio.mActualizarObjetoVolador>cEspacio.mActualizarObjetoVolador</A>(ov: cObjetoVolador); \r
+<B>begin</B> \r
+  <B>if</B> ov <B>is</B> cNaveEnemiga <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// si es una nave enemiga... </FONT></I>\r
+    <B>with</B> ov <B>as</B> cNaveEnemiga <B>do</B> <I><FONT COLOR="Navy">// "Transforma el puntero" a uno de clase NaveEnemiga </FONT></I>\r
+    <B>if</B> aNavePropia = <B>nil</B> <B>then</B> \r
+      <B>raise</B> ENavePropiaDestruida.create \r
+    <B>else</B> \r
+      <B>if</B> mDetectado( aNavePropia ) <B>then</B> <I><FONT COLOR="Navy">// si la nave propia esta en el campo de radar de la nave enemiga... </FONT></I>\r
+        mReaccionar( aNavePropia );  <I><FONT COLOR="Navy">// se manda un mensaje a la nave enemiga de atacar a la propia </FONT></I>\r
+      <I><FONT COLOR="Navy">// Si es una nave espia, nos fijamos si esta avisando </FONT></I>\r
+      <B>if</B> ov <B>is</B> cNaveEspia <B>then</B> <B>begin</B> \r
+        <B>with</B> ov <B>as</B> cNaveEspia <B>do</B> <I><FONT COLOR="Navy">// "Transforma el puntero" a uno de clase NaveEspia </FONT></I>\r
+        <B>if</B> mAvisando <B>then</B> \r
+          mComunicarPosicion( ov <B>as</B> cNaveEspia ); \r
+      <B>end</B>; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Agrega un Objeto Volador al Espacio \r
+    @param ov Objeto volador a agregar}</FONT></I> \r
+<B>procedure</B> <A NAME=cEspacio.mAgregarObjeto>cEspacio.mAgregarObjeto</A>(ov: cObjetoVolador); \r
+<B>begin</B> \r
+  aObjetos.Add( ov ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método que se encarga de avisar al resto de las naves enemigas que estan cerca de una \r
+    espia sobre la ultima posicion de la nave propia. \r
+    @param nEsp Nave espía que está avisando}</FONT></I> \r
+<B>procedure</B> <A NAME=cEspacio.mComunicarPosicion>cEspacio.mComunicarPosicion</A>(nEsp: cNaveEspia); \r
+<B>var</B> \r
+  i:   integer;        <I><FONT COLOR="Navy">// contador para el bucle </FONT></I>\r
+  oOV: cObjetoVolador; <I><FONT COLOR="Navy">// objeto volador para apuntar al de la lista </FONT></I>\r
+<B>begin</B> \r
+  <B>for</B> i := 0 <B>to</B> aObjetos.Count - 1 <B>do</B> <B>begin</B>  <I><FONT COLOR="Navy">// recorre la lista </FONT></I>\r
+    oOV := aObjetos.Items[i]; <I><FONT COLOR="Navy">// obteniendo el primer objeto volador </FONT></I>\r
+    <B>if</B> oOV = nEsp <B>then</B> <I><FONT COLOR="Navy">// Si es la misma nave propia... </FONT></I>\r
+      continue;        <I><FONT COLOR="Navy">//  la pasa por alto </FONT></I>\r
+    <B>if</B> oOV <B>is</B> cNaveEnemiga <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// si es una nave enemiga... </FONT></I>\r
+      <B>if</B> oOV <B>is</B> cNaveEspia <B>then</B>    <I><FONT COLOR="Navy">// Si es una nave espia, se fija si esta avisando </FONT></I>\r
+        <B>with</B> oOV <B>as</B> cNaveEspia <B>do</B> \r
+          <B>if</B> mAvisando <B>then</B>        <I><FONT COLOR="Navy">// Si esta avisando: </FONT></I>\r
+            continue;              <I><FONT COLOR="Navy">// la pasa por alto </FONT></I>\r
+      <B>if</B> nEsp.mDetectado( oOV ) <B>then</B> <I><FONT COLOR="Navy">// Si esta dentro del radar de la nave espia... </FONT></I>\r
+        <B>with</B> oOV <B>as</B> cNaveEnemiga <B>do</B> \r
+          mIrA( nEsp.mGetPosicionEnemiga );   <I><FONT COLOR="Navy">// Le indica que vaya a la ultima posicion </FONT></I>\r
+                                              <I><FONT COLOR="Navy">//  en donde vio a la nave propia </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Destruye un objeto volador, liberando memoria y eliminandolo de la lista \r
+    @param ov Objeto Volador a destruir}</FONT></I> \r
+<B>procedure</B> <A NAME=cEspacio.mDestruir>cEspacio.mDestruir</A>(ov: cObjetoVolador); \r
+<B>begin</B> \r
+  aObjetos.Remove( ov ); \r
+  <B>if</B> ov <B>is</B> cNavePropia <B>then</B> \r
+    aNavePropia := <B>nil</B>; \r
+  ov.Free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Procedimiento que evalua las posiciones de los Objetos Voladores que se encuentran en el espacio, \r
+    verificando si hay una colisión.}</FONT></I> \r
+<B>procedure</B> <A NAME=cEspacio.mDetectarColision>cEspacio.mDetectarColision</A>; \r
+<B>var</B> \r
+  i,                    <I><FONT COLOR="Navy">// contador </FONT></I>\r
+  j: integer;           <I><FONT COLOR="Navy">// contador </FONT></I>\r
+  oOV1,                 <I><FONT COLOR="Navy">// variables para apuntar a los dos objetos voladores </FONT></I>\r
+  oOV2: cObjetoVolador; <I><FONT COLOR="Navy">//  que queremos evaluar si colisionaron </FONT></I>\r
+  oRotos: TList;        <I><FONT COLOR="Navy">// lista que contiene todos los objetos voladores destruidos </FONT></I>\r
\r
+<B>begin</B> \r
+  oRotos := TList.create; \r
+  <B>for</B> i := 0 <B>to</B> aObjetos.Count - 1 <B>do</B> <B>begin</B>  <I><FONT COLOR="Navy">// recorre la lista </FONT></I>\r
+    oOV1 := aObjetos.Items[i]; <I><FONT COLOR="Navy">// obteniendo el primer objeto volador </FONT></I>\r
+    <B>for</B> j := i + 1 <B>to</B> aObjetos.Count - 1 <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// recorre la lista a partir del objeto volador anterior (excluyentemente) </FONT></I>\r
+      oOV2 := aObjetos.Items[j]; <I><FONT COLOR="Navy">// obteniendo el segundo objeto volador </FONT></I>\r
+      <B>if</B> oOV1.mColisiono( oOV2 ) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si colisionaron los Objetos Voladores... </FONT></I>\r
+        oOV1.mRestarEnergia( oOV2.mGetPotencia ); <I><FONT COLOR="Navy">// Le resta la energia al primer objeto volador </FONT></I>\r
+        oOV2.mRestarEnergia( oOV1.mGetPotencia ); <I><FONT COLOR="Navy">// Le resta la energia al segundo objeto volador </FONT></I>\r
+      <B>end</B>; \r
+    <B>end</B>; \r
+    <I><FONT COLOR="Navy">// Una vez que termina de restarle toda la energia por choques, verifica si esta destruido </FONT></I>\r
+    <B>if</B> oOV1.mGetEnergia <= 0 <B>then</B> <I><FONT COLOR="Navy">// Si quedo con energia negativa, </FONT></I>\r
+      oRotos.Add( oOV1 );         <I><FONT COLOR="Navy">//  lo agrega a la lista de objetos rotos </FONT></I>\r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// Destruye todos los objetos voladores rotos </FONT></I>\r
+  <B>while</B> oRotos.Count > 0 <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Extra un objeto volador destruido de la lista (mientras que haya alguno) </FONT></I>\r
+    oOV1 := oRotos.First; \r
+    oRotos.Remove( oOV1 ); <I><FONT COLOR="Navy">// Elimina el objeto de la lista de objetos rotos </FONT></I>\r
+    mDestruir( oOV1 ); <I><FONT COLOR="Navy">// Destruye el objeto volador </FONT></I>\r
+  <B>end</B>; \r
+  oRotos.free; <I><FONT COLOR="Navy">// Libera la memoria de la lista </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+<I><FONT COLOR="Navy">{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos. \r
+    @return            Cadena de texto con el estado del Objeto. \r
+    @param   debugLevel Cantidad de información requerida}</FONT></I> \r
+<B>function</B> <A NAME=cEspacio.mGetDebugInfo>cEspacio.mGetDebugInfo</A>( debugLevel: tDebugInfo ): <B>string</B>; \r
+<B>var</B> \r
+  i:  integer;         <I><FONT COLOR="Navy">// contador </FONT></I>\r
+  oOV: cObjetoVolador; <I><FONT COLOR="Navy">// variable temporal para obtener info del OV </FONT></I>\r
+<B>begin</B> \r
+  result := ''; \r
+  <I><FONT COLOR="Navy">// Genera el string con el estado del Espacio </FONT></I>\r
+  <B>if</B> debugLevel > DI_NORMAL <B>then</B> \r
+    result := result + 'Delta de T = ' + FloatToStrF( aDeltaT, ffNumber, 10, 0 ) + #13 + #10; \r
+  <I><FONT COLOR="Navy">// Genera el string con el estado de los objetos dentro del Espacio </FONT></I>\r
+  <B>for</B> i := 0 <B>to</B> aObjetos.Count - 1 <B>do</B> <B>begin</B> \r
+    oOV := aObjetos.Items[i]; \r
+    result := result + #13 + #10 + \r
+              'ObjetoVolador' + IntToStr( i ) + ' (' + oOV.ClassName + '): ' + #13 + #10 + \r
+              oOV.mGetDebugInfo( debugLevel ) + #13 + #10 \r
+              + '----'; \r
+  <B>end</B>; \r
+<B>end</B>; \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Método que obtiene la nave propia del espacio (este método es probable que deje de exstir) \r
+    @return Instancia de la nave propia que se encuentra en el espacio (como puntero)}</FONT></I> \r
+<B>function</B> <A NAME=cEspacio.mGetNavePropia>cEspacio.mGetNavePropia</A>: cNavePropia; \r
+<B>begin</B> \r
+  result := aNavePropia; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Quita un Objeto Volador del Espacio. Devuelve true si lo saco y false si no existia \r
+    (esto lo quita del espacio, no lo destruye) \r
+    @param  ov Objeto a quitar del espacio \r
+    @return    <i>true</i> si se quitó, <i>false</i> si no estaba en el espacio}</FONT></I> \r
+<B>function</B> <A NAME=cEspacio.mQuitarObjeto>cEspacio.mQuitarObjeto</A>( ov: cObjetoVolador ): boolean; \r
+<B>var</B> \r
+  <B>index</B>: integer; \r
+<B>begin</B> \r
+  result := false; \r
+  <B>index</B> := aObjetos.IndexOf( ov ); \r
+  <B>if</B> <B>index</B> >= 0 <B>then</B> <B>begin</B> \r
+    aObjetos.Delete( <B>index</B> ); \r
+    result := true; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la lista de Objetos Voladores del Espacio \r
+    @return Lista de objetos del espacio (como puntero)}</FONT></I> \r
+<B>function</B> <A NAME=cEspacio.mGetObjetos>cEspacio.mGetObjetos</A>: TList; \r
+<B>begin</B> \r
+  result := aObjetos; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Cambia la lista de Objetos Voladores del Espacio, devolviendo un puntero a la lista vieja \r
+    @param  l Nueva lista de objetos a asignarle al espacio \r
+    @return   Vieja lista de objetos del espacio}</FONT></I> \r
+<B>function</B> <A NAME=cEspacio.mSetObjetos>cEspacio.mSetObjetos</A>( l: TList ): TList; \r
+<B>begin</B> \r
+  result := aObjetos; \r
+  aObjetos := l; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método para cambiar la nave propia. Devuelve un puntero a la nave propia vieja. \r
+    @return Lista de objetos del espacio (como puntero)}</FONT></I> \r
+<B>function</B> <A NAME=cEspacio.mSetNavePropia>cEspacio.mSetNavePropia</A>( np: cNavePropia ): cNavePropia; \r
+<B>begin</B> \r
+  result := aNavePropia; \r
+  aNavePropia := np; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+    serializado. \r
+    @param str Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>procedure</B> <A NAME=cEspacio.mDesSerializar>cEspacio.mDesSerializar</A>(str: <B>string</B>); \r
+<B>var</B> \r
+  total, \r
+  i:       integer; \r
+  objetos: <B>string</B>; \r
+  r:       TRegExpr; \r
+  ov:      cObjetoVolador; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Crea la lista de ser necesario </FONT></I>\r
+  <B>if</B> aObjetos = <B>nil</B> <B>then</B> \r
+    aObjetos := TList.create; \r
+  <I><FONT COLOR="Navy">// Libera la lista los objetos existentes... </FONT></I>\r
+  <B>while</B> aObjetos.Count > 0 <B>do</B> <B>begin</B> \r
+    ov := aObjetos.First; \r
+    aObjetos.Remove( ov ); \r
+    ov.free; \r
+  <B>end</B>; \r
+  aNavePropia := <B>nil</B>; \r
+  <B>inherited</B> mDesSerializar( str ); <I><FONT COLOR="Navy">// SIEMPRE el ID debe ser el PRIMER atributo </FONT></I>\r
+  r := TRegExpr.create; \r
+  <I><FONT COLOR="Navy">// DELTAT </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<deltat>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</deltat>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aDeltaT := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el intervalo de actualizacion' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el intervalo de actualizacion utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// OBJETOS </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<objetos/s+total=(/d+)/s*>/s*(.+)/s*</objetos>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      total := StrToInt( r.Match[1] ); \r
+      objetos := r.Match[2]; \r
+      <B>for</B> i := 0 <B>to</B> total - 1 <B>do</B> <B>begin</B> \r
+        <I><FONT COLOR="Navy">// OBJETO N </FONT></I>\r
+        <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+          r.Expression := '<objeto' + IntToStr( i ) + '/s+class=([/w/d]+)/s*>/s*(.+)/s*</objeto' + IntToStr( i ) + '>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+          <B>if</B> r.Exec ( objetos ) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+            <I><FONT COLOR="Navy">// lo crea segun su clase y lo agrega a la lista </FONT></I>\r
+            ov := restaurarObjeto( r.Match[1], r.Match[2] ); \r
+            aObjetos.Add( ov ); \r
+            <B>if</B> ov <B>is</B> cNavePropia <B>then</B> <I><FONT COLOR="Navy">// Si es la nave propia </FONT></I>\r
+              aNavePropia := ov <B>as</B> cNavePropia; <I><FONT COLOR="Navy">// Asigna el atributo NavePropia </FONT></I>\r
+          <B>end</B> <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+            <B>raise</B> ESerializacion.create( 'No se encontro el objeto ' + IntToStr( i ) ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+        <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+          on e: ESerializacion <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si fueron de serializacion... </FONT></I>\r
+            r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+            <B>raise</B> ESerializacion.create( ClassName + ': Error al deserializar el objeto ' \r
+                                         + IntToStr( i ) + ': ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+          <B>end</B>; \r
+          on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+            r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+            <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el objeto ' + IntToStr( i ) + ' utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+          <B>end</B>; \r
+        <B>end</B>; \r
+      <B>end</B>; \r
+    <B>end</B> <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro la potencia' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer la potencia utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  mEliminarDuplicados; \r
+  <B>if</B> aNavePropia = <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no se deserializo una nave propia ... </FONT></I>\r
+    <B>raise</B> ESerializacion.create( ClassName + ': No se encontro la nave propia' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  r.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado. \r
+    @return Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>function</B> <A NAME=cEspacio.mSerializar>cEspacio.mSerializar</A>: <B>string</B>; \r
+<B>var</B> \r
+  i:  integer; \r
+  ov: cObjetoVOlador; \r
+<B>begin</B> \r
+  result := <B>inherited</B> mSerializar + \r
+            '<deltat>' + FloatToStrF( aDeltaT, ffGeneral, 18, 0 ) + '</deltat>' + \r
+            '<objetos total=' + IntToStr( aObjetos.Count ) + '>'; \r
+  <B>for</B> i := 0 <B>to</B> aObjetos.Count - 1 <B>do</B> <B>begin</B>  <I><FONT COLOR="Navy">// recorre la lista </FONT></I>\r
+    ov := aObjetos.Items[i]; <I><FONT COLOR="Navy">// obteniendo el primer objeto volador </FONT></I>\r
+      <I><FONT COLOR="Navy">// Serializa el objeto actual </FONT></I>\r
+      result := result + '<objeto' + IntToStr( i ) + ' class=' + ov.ClassName + '>' + ov.mSerializar + '</objeto' + IntToStr( i ) + '>'; \r
+  <B>end</B>; \r
+  result := result + '</objetos>'; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Elimina los objetos duplicados después de recuperarlos de una serialización}</FONT></I> \r
+<B>procedure</B> <A NAME=cEspacio.mEliminarDuplicados>cEspacio.mEliminarDuplicados</A>; \r
+<B>var</B> \r
+  i:    integer; \r
+  oOV, \r
+  oAux: cObjetoVolador; \r
+<B>begin</B> \r
+  <B>for</B> i := 0 <B>to</B> aObjetos.Count - 1 <B>do</B> <B>begin</B> \r
+    oOV  := aObjetos.Items[i]; \r
+    <B>if</B> oOV <B>is</B> cNavePropia <B>then</B> <B>begin</B> \r
+      <I><FONT COLOR="Navy">// Busca el duplicado del objetivo </FONT></I>\r
+      oAux := mBuscarDuplicado( (oOV <B>as</B> cNavePropia).mGetLockeado ); \r
+      (oOV <B>as</B> cNavePropia).mGetLockeado.free; <I><FONT COLOR="Navy">// Libera la copia que tiene como objetivo </FONT></I>\r
+      (oOV <B>as</B> cNavePropia).mSetLockeado( oAux ); <I><FONT COLOR="Navy">// Setea como nuevo objetivo al objeto de la lista </FONT></I>\r
+    <B>end</B>; \r
+    <B>if</B> oOV <B>is</B> cMisilDirigido <B>then</B> <B>begin</B> \r
+      <I><FONT COLOR="Navy">// Busca el duplicado del objetivo </FONT></I>\r
+      oAux := mBuscarDuplicado( (oOV <B>as</B> cMisilDirigido).mGetObjetivo ); \r
+      (oOV <B>as</B> cMisilDirigido).mGetObjetivo.free; <I><FONT COLOR="Navy">// Libera la copia que tiene como objetivo </FONT></I>\r
+      (oOV <B>as</B> cMisilDirigido).mSetObjetivo( oAux ); <I><FONT COLOR="Navy">// Setea como nuevo objetivo al objeto de la lista </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Busca el duplicado de un objeto volador \r
+    @param  ov Objeto volador al cual se le quiere encontrar un duplicado \r
+    @return Objeto Volador duplicado de ov}</FONT></I> \r
+<B>function</B> <A NAME=cEspacio.mBuscarDuplicado>cEspacio.mBuscarDuplicado</A>(ov: cObjetoVolador): cObjetoVolador; \r
+<B>var</B> \r
+  i:   integer; \r
+  oOV: cObjetoVolador; \r
+<B>begin</B> \r
+  result := <B>nil</B>; \r
+  <B>if</B> ov <> <B>nil</B> <B>then</B> \r
+    <B>for</B> i := 0 <B>to</B> aObjetos.Count - 1 <B>do</B> <B>begin</B> \r
+      oOV  := aObjetos.Items[i]; \r
+      <B>if</B> oOV.mGetID = ov.mGetID <B>then</B> <I><FONT COLOR="Navy">// Si tienen el mismo ID... </FONT></I>\r
+        result := oOV; <I><FONT COLOR="Navy">// Devulve el duplicado </FONT></I>\r
+    <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ ENavePropiaDestruida }</FONT></I> \r
\r
+<B>constructor</B> ENavePropiaDestruida.create; \r
+<B>begin</B> \r
+  <B>inherited</B> create( 'La Nave Propia fue destruida.' ); \r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/modelo/Vectores.pas b/doc/src-html/modelo/Vectores.pas
new file mode 100644 (file)
index 0000000..389eae1
--- /dev/null
@@ -0,0 +1,417 @@
+<HTML><HEAD>\r
+<TITLE>File: vectores.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=vectores.pas><CENTER><H3>vectores.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Es la implementación de un vector físico. Esta clase es el esqueleto de \r
+    la aplicación ya que todas las velocidades y posiciones son del tipo cVector. \r
+    Todos los calculos de movimientos, distancias, etc. se manejan con los metodos de esta clase<br> \r
+    <i>Cambios:</i> \r
+    <PRE> \r
+    05/10/00: Se corrigió el método mAddModulo para que al verificar el signo del modulo resultante, \r
+              si es negativo, setee el modulo a cero. \r
+    28/10/00: Se cambiaron todos los metodos en los que se realizan operaciones con el vector para \r
+              que devulvan un puntero a si mismo (para poder hacer asignaciones luego de la operacion). \r
+              Ahora todos los métodos son funciones \r
+    </PRE>}</FONT></I> \r
+<B>unit</B> Vectores; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  ObjetoPersistente, \r
+  Tipos; \r
\r
+<B>type</B> \r
+  <I><FONT COLOR="Navy">{** La clase cVector es la implementación de un vector físico. Esta clase es el esqueleto de \r
+      la aplicación ya que todas las velocidades y posiciones son del tipo cVector. \r
+      Todos los calculos de movimientos, distancias, etc. se manejan con los metodos de esta clase}</FONT></I> \r
+  cVector = <B>class</B>( cObjetoPersistente ) \r
+    <B>private</B> \r
+      aX: tLongitud; <I><FONT COLOR="Navy">// Componente del vector en X </FONT></I>\r
+      aY: tLongitud; <I><FONT COLOR="Navy">// Componente del vector en Y </FONT></I>\r
+      aZ: tLongitud; <I><FONT COLOR="Navy">// Componente del vector en Z </FONT></I>\r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( x: tLongitud = 0; y: tLongitud = 0; z: tLongitud = 0 ); overload; \r
+      <I><FONT COLOR="Navy">{** Constructor que copia los atributos de un Vector existente}</FONT></I> \r
+      <B>constructor</B> create( v: cVector ); overload; \r
+      <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar \r
+          y la información entregada depende del parámetro tDebugInfo.}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mGetDebugInfo">mGetDebugInfo</A>( debugLevel: tDebugInfo = DI_MINI ): <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Convierte el vector en un versor (norma 1)}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mHacerVersor">mHacerVersor</A>: cVector; \r
+      <I><FONT COLOR="Navy">{** Establece los valores del vector x, y, z}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mSet">mSet</A>( x, y, z: tLongitud ): cVector; overload; \r
+      <I><FONT COLOR="Navy">{** Modifica las componentes del vector basandose en otro}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mSet">mSet</A>( v: cVector ): cVector; overload; \r
+      <I><FONT COLOR="Navy">{** Setea la componente X}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mSetX">mSetX</A>( x: tLongitud ): cVector; \r
+      <I><FONT COLOR="Navy">{** Setea la componente Y}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mSetY">mSetY</A>( y: tLongitud ): cVector; \r
+      <I><FONT COLOR="Navy">{** Setea la componente Z}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mSetZ">mSetZ</A>( z: tLongitud ): cVector; \r
+      <I><FONT COLOR="Navy">{** Agrega un valor a la componente X}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mAddX">mAddX</A>( x: tLongitud ): cVector; \r
+      <I><FONT COLOR="Navy">{** Agrega un valor a la componente Y}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mAddY">mAddY</A>( y: tLongitud ): cVector; \r
+      <I><FONT COLOR="Navy">{** Agrega un valor a la componente Z}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mAddZ">mAddZ</A>( z: tLongitud ): cVector; \r
+      <I><FONT COLOR="Navy">{** Setea el modulo del vector a un valor determinado}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mSetModulo">mSetModulo</A>( modulo: tLongitud ): cVector; \r
+      <I><FONT COLOR="Navy">{** Aumenta (o disminuye si el argumente es negativo) el modulo del vector}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mAddModulo">mAddModulo</A>( modulo: tLongitud ): cVector; \r
+      <I><FONT COLOR="Navy">{** Obtiene la componente X}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mGetX">mGetX</A>: tLongitud; \r
+      <I><FONT COLOR="Navy">{** Obtiene la componente Y}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mGetY">mGetY</A>: tLongitud; \r
+      <I><FONT COLOR="Navy">{** Obtiene la componente Z}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mGetZ">mGetZ</A>: tLongitud; \r
+      <I><FONT COLOR="Navy">{** Obtiene el modulo del vector}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mGetModulo">mGetModulo</A>: tLongitud; \r
+      <I><FONT COLOR="Navy">{** Suma a si mismo el vector vec}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mSumar">mSumar</A>( vec: cVector ): cVector; \r
+      <I><FONT COLOR="Navy">{** Resta a si mismo el vector vec}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mRestar">mRestar</A>( vec: cVector ): cVector; \r
+      <I><FONT COLOR="Navy">{** Se multiplica vectorialmente a si mismo por el vector vec}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mMultiplicar">mMultiplicar</A>( vec: cVector ): cVector; overload; \r
+      <I><FONT COLOR="Navy">{** Se multiplica por un escalar}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mMultiplicar">mMultiplicar</A>( esc: tLongitud ): cVector; overload; \r
+      <I><FONT COLOR="Navy">{** Obtiene el producto escalar entre si mismo y el vector vec}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mMultiplicarEsc">mMultiplicarEsc</A>( vec: cVector ): tLongitud; \r
+      <I><FONT COLOR="Navy">{** Obtiene la distancia al a otro vector}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mGetDistancia">mGetDistancia</A>( vec: cVector ): tLongitud; \r
+      <I><FONT COLOR="Navy">{** Modifica el vector con basandose en otro vector (pensado como velocidad) y un \r
+          intervalo de tiempo siguiendo la formula física X' = X + V * dt \r
+          (este metodo esta pensado basicamente para calcular los movimientos)}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mModificarCon">mModificarCon</A>( vel: cVector; dT: tTiempo ): cVector; \r
+      <I><FONT COLOR="Navy">// SERIALIZACION </FONT></I>\r
+      <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.}</FONT></I> \r
+      <B>function</B> <A HREF="#cVector.mSerializar">mSerializar</A>: <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+          serializado.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cVector.mDesSerializar">mDesSerializar</A>( str: <B>string</B> ); <B>override</B>; \r
+  <B>end</B>; \r
\r
+<B>implementation</B> \r
\r
+<B>uses</B> \r
+  Sysutils, \r
+  RegExpr, \r
+  Math; \r
\r
+<I><FONT COLOR="Navy">{ cVector }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Crea un nuevo vector basandose en los atributos de uno existente. \r
+    @param v Vector a copiar}</FONT></I> \r
+<B>constructor</B> cVector.create(v: cVector); \r
+<B>begin</B> \r
+  <B>inherited</B> create; \r
+  <I><FONT COLOR="Navy">// Usa el metodo mSet para establecer los valores </FONT></I>\r
+  mSet( v ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Crea un nuevo vector basandose en los atributos dados como parámetro. \r
+    @param x Componente en el eje X \r
+    @param y Componente en el eje Y \r
+    @param z Componente en el eje Z}</FONT></I> \r
+<B>constructor</B> cVector.create(x, y, z: tLongitud); \r
+<B>begin</B> \r
+  <B>inherited</B> create; \r
+  <I><FONT COLOR="Navy">// Usa el metodo mSet para establecer los valores </FONT></I>\r
+  mSet( x, y, z ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Setea el modulo del vector a un valor determinado (sólo tiene sentido si el modulo actual es distinto de cero) \r
+    @param modulo Modulo a adherir al verctor}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mAddModulo>cVector.mAddModulo</A>(modulo: tLongitud): cVector; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Disminuye el módulo sólo si el resultante no es negativo </FONT></I>\r
+  <B>if</B> (mGetModulo + modulo) <= 0 <B>then</B> <I><FONT COLOR="Navy">// Si el modulo resultante es negativo o cero </FONT></I>\r
+    mSetModulo( 0 ) <I><FONT COLOR="Navy">// Setea el modulo en 0 </FONT></I>\r
+  <B>else</B> <I><FONT COLOR="Navy">// Si el modulo resultante es positivo </FONT></I>\r
+    mSetModulo( mGetModulo + modulo ); \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Agrega un valor a la componente X \r
+    @param x Valor a sumarle a la componente X}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mAddX>cVector.mAddX</A>(x: tLongitud): cVector; \r
+<B>begin</B> \r
+  aX := aX + x; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Agrega un valor a la componente Y \r
+    @param y Valor a sumarle a la componente Y}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mAddY>cVector.mAddY</A>(y: tLongitud): cVector; \r
+<B>begin</B> \r
+  aY := aY + y; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Agrega un valor a la componente Z \r
+    @param z Valor a sumarle a la componente Z}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mAddZ>cVector.mAddZ</A>(z: tLongitud): cVector; \r
+<B>begin</B> \r
+  aZ := aZ + z; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el modulo del vector \r
+    @return Modulo (o norma) del vector}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mGetModulo>cVector.mGetModulo</A>: tLongitud; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Devuelve la raiz cuadrada de la suma de los cuadrados de las componentes </FONT></I>\r
+  result := sqrt( sqr( aX ) + sqr( aY ) + sqr( aZ ) ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la componente X \r
+    @return Componente X del vector}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mGetX>cVector.mGetX</A>: tLongitud; \r
+<B>begin</B> \r
+  result := aX; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la componente Y \r
+    @return Componente Y del vector}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mGetY>cVector.mGetY</A>: tLongitud; \r
+<B>begin</B> \r
+  result := aY; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la componente Z \r
+    @return Componente Z del vector}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mGetZ>cVector.mGetZ</A>: tLongitud; \r
+<B>begin</B> \r
+  result := aZ; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Se multiplica vectorialmente a si mismo por el vector vec \r
+    @param vec Vector por el cual se multiplica vectorialmente}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mMultiplicar>cVector.mMultiplicar</A>(vec: cVector): cVector; \r
+<B>var</B> \r
+  x, \r
+  y, \r
+  z: tLongitud; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Obtiene el resultado siguiendo la formula de producto vectorial </FONT></I>\r
+  x  := aY * vec.mGetZ - aZ * vec.mGetY; \r
+  y  := aX * vec.mGetZ - aZ * vec.mGetX; \r
+  z  := aX * vec.mGetY - aY * vec.mGetX; \r
+  aX := x; \r
+  aY := y; \r
+  aZ := z; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Se multiplica por un escalar \r
+    @param esc Escalar por el cual se multiplica}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mMultiplicar>cVector.mMultiplicar</A>(esc: tLongitud): cVector; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Multiplica cada componente por el escalar </FONT></I>\r
+  aX := aX * esc; \r
+  aY := aY * esc; \r
+  aZ := aZ * esc; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el producto escalar entre si mismo y el vector vec \r
+    @return      Producto escalar entre los vectores \r
+    @param   vec Vector por el cual se multiplica escalarmente}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mMultiplicarEsc>cVector.mMultiplicarEsc</A>(vec: cVector): tLongitud; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Realiza el producto escalar (suma el producto componente a componente) </FONT></I>\r
+  result := aX * vec.mGetX + aY * vec.mGetY + aZ * vec.mGetZ; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Resta a si mismo el vector vec \r
+    @param vec Vector que se resta}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mRestar>cVector.mRestar</A>(vec: cVector): cVector; \r
+<B>begin</B> \r
+  aX := aX - vec.mGetX; \r
+  aY := aY - vec.mGetY; \r
+  aZ := aZ - vec.mGetZ; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Setea el modulo del vector a un valor determinado \r
+    @param modulo Valor del nuevo Módulo}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mSetModulo>cVector.mSetModulo</A>(modulo: tLongitud): cVector; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Primero lo convertimos en un versor </FONT></I>\r
+  mHacerVersor; \r
+  <I><FONT COLOR="Navy">// Ahora multiplicamos el versor por la modulo deseada </FONT></I>\r
+  mMultiplicar( modulo ); \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Modifica las componentes del vector basandose en otro \r
+    @param v Vector del cual se obtendran los nuevos atributos}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mSet>cVector.mSet</A>(v: cVector): cVector; \r
+<B>begin</B> \r
+  aX := v.mGetX; \r
+  aY := v.mGetY; \r
+  aZ := v.mGetZ; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Establece las componentes del vector \r
+    @param x Nuevo valor de la componente en el eje X \r
+    @param y Nuevo valor de la componente en el eje Y \r
+    @param z Nuevo valor de la componente en el eje Z}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mSet>cVector.mSet</A>(x, y, z: tLongitud): cVector; \r
+<B>begin</B> \r
+  aX := x; \r
+  aY := y; \r
+  aZ := z; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Setea la componente X \r
+    @param x Nuevo valor de la componente en el eje X}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mSetX>cVector.mSetX</A>(x: tLongitud): cVector; \r
+<B>begin</B> \r
+  aX := x; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Setea la componente Y \r
+    @param y Nuevo valor de la componente en el eje Y}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mSetY>cVector.mSetY</A>(y: tLongitud): cVector; \r
+<B>begin</B> \r
+  aY := y; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Setea la componente Z \r
+    @param z Nuevo valor de la componente en el eje Z}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mSetZ>cVector.mSetZ</A>(z: tLongitud): cVector; \r
+<B>begin</B> \r
+  aZ := z; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Suma a si mismo el vector vec \r
+    @param vec Vector a sumarle}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mSumar>cVector.mSumar</A>(vec: cVector): cVector; \r
+<B>begin</B> \r
+  aX := aX + vec.mGetX; \r
+  aY := aY + vec.mGetY; \r
+  aZ := aZ + vec.mGetZ; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+<I><FONT COLOR="Navy">{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos:<br> \r
+    Siempre devuelve los valores de las componentes x, y, z y si debugLevel es mayor que DI_NORMAL, \r
+    también muestra el módulo. \r
+    @return             Cadena de texto con el estado del Objeto. \r
+    @param   debugLevel Cantidad de información requerida}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mGetDebugInfo>cVector.mGetDebugInfo</A>( debugLevel: tDebugInfo ): <B>string</B>; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Construye la cadena dependiendo de la cantidad de informacion que se quiera obtener </FONT></I>\r
+  result := 'X: ' + FloatToStrF( mGetX, ffNumber, 5, 5 ) + \r
+            ' | Y: ' + FloatToStrF( mGetY, ffNumber, 5, 5 ) + \r
+            ' | Z: ' + FloatToStrF( mGetZ, ffNumber, 5, 5 ); \r
+  <B>if</B> debugLevel > DI_NORMAL <B>then</B> \r
+    result := result + ' | Modulo: ' + FloatToStrF( mGetModulo, ffNumber, 5, 5 ); \r
+<B>end</B>; \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la distancia al a otro vector (en realidad se tratan como puntos) \r
+    @returns     Distancia al otro vector \r
+    @param   vec Punto al cual se calcula la distancia}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mGetDistancia>cVector.mGetDistancia</A>( vec: cVector ): tLongitud; \r
+<B>var</B> \r
+  v: cVector; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Crea un nuevo vector basado en vec y le resta el vector actual </FONT></I>\r
+  v := cVector.create( vec ).mRestar( self ); \r
+  <I><FONT COLOR="Navy">// devuelve el modulo </FONT></I>\r
+  result := v.mGetModulo; \r
+  <I><FONT COLOR="Navy">// Libera el vector temporal </FONT></I>\r
+  v.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Modifica el vector con basandose en otro vector (pensado como velocidad) y un \r
+    intervalo de tiempo siguiendo la formula física X' = X + V * dt \r
+    (este metodo esta pensado basicamente para calcular los movimientos) \r
+    @param vel Vector velocidad \r
+    @param dT  Intervalo de tiempo}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mModificarCon>cVector.mModificarCon</A>(vel: cVector; dT: tTiempo): cVector; \r
+<B>var</B> \r
+  v: cVector; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// formula de MRU: SELF = SELF + VELOCIDAD * TIEMPO </FONT></I>\r
+  v := cVector.create( vel ).mMultiplicar( dT ); \r
+  mSumar( v ); \r
+  v.free; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Convierte el vector en un versor (sólo tiene sentido si el modulo actual es distinto de cero)}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mHacerVersor>cVector.mHacerVersor</A>: cVector; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Si el modulo es mayor que cero... </FONT></I>\r
+  <B>if</B> mGetModulo > 0 <B>then</B> \r
+    mMultiplicar( 1 / mGetModulo ); \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+    serializado. \r
+    @param str Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>procedure</B> <A NAME=cVector.mDesSerializar>cVector.mDesSerializar</A>(str: <B>string</B>); \r
+<B>var</B> \r
+  r: TRegExpr; \r
+<B>begin</B> \r
+  <B>inherited</B> mDesSerializar( str ); <I><FONT COLOR="Navy">// SIEMPRE el ID debe ser el PRIMER atributo </FONT></I>\r
+  r := TRegExpr.create; \r
+  <B>try</B> <I><FONT COLOR="Navy">// ensure memory release </FONT></I>\r
+    <I><FONT COLOR="Navy">// X </FONT></I>\r
+    r.Expression := '<X>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</X>'; \r
+    <B>if</B> r.Exec ( str ) <B>then</B> \r
+      aX := StrToFloat( r.Match[1] ) \r
+    <B>else</B> \r
+      <B>raise</B> ESerializacion.create( 'No se encontro la componente en X' ); \r
+    <I><FONT COLOR="Navy">// Y </FONT></I>\r
+    r.Expression := '<Y>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</Y>'; \r
+    <B>if</B> r.Exec ( str ) <B>then</B> \r
+      aY := StrToFloat( r.Match[1] ) \r
+    <B>else</B> \r
+      <B>raise</B> ESerializacion.create( 'No se encontro la componente en Y' ); \r
+    <I><FONT COLOR="Navy">// Z </FONT></I>\r
+    r.Expression := '<Z>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</Z>'; \r
+    <B>if</B> r.Exec ( str ) <B>then</B> \r
+      aZ := StrToFloat( r.Match[1] ) \r
+    <B>else</B> \r
+      <B>raise</B> ESerializacion.create( 'No se encontro la componente en Z' ); \r
+  <B>except</B> \r
+    on e: ERegExpr <B>do</B> <B>begin</B> \r
+      r.Free; \r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error utilizando expresiones regulares: ' + e.<B>Message</B> ); \r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  r.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado. \r
+    @return Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>function</B> <A NAME=cVector.mSerializar>cVector.mSerializar</A>: <B>string</B>; \r
+<B>begin</B> \r
+  result := <B>inherited</B> mSerializar + \r
+            '<X>' + FloatToStrF( aX, ffGeneral, 18, 0 ) + '</X>' + \r
+            '<Y>' + FloatToStrF( aY, ffGeneral, 18, 0 ) + '</Y>' + \r
+            '<Z>' + FloatToStrF( aZ, ffGeneral, 18, 0 ) + '</Z>'; \r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/modelo/ov/Armas.pas b/doc/src-html/modelo/ov/Armas.pas
new file mode 100644 (file)
index 0000000..43bb746
--- /dev/null
@@ -0,0 +1,522 @@
+<HTML><HEAD>\r
+<TITLE>File: armas.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=armas.pas><CENTER><H3>armas.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Contiene las armas que pueden ser usadas por las diferentes naves.<br> \r
+    <i>Cambios:</i> \r
+    <PRE> \r
+    10/11/00: Se agrega el manejo de excepciones para evitar un BUG en cMisilDirigido. Si el objetivo del misil \r
+              dirigido es destruido, la velocidad permanece constante y en mGetDebugInfo se informa que esta destruido. \r
+    27/11/00: Se le agrega el manejo de la velocidad maxima a la clase cArma y se agrega el Alcance del arma, cambiando \r
+              el anterior por la Duracion. \r
+    01/12/00: Se cambiaron las dimensiones de las armas para que los disparos sean mas "jugables". \r
+    </PRE>}</FONT></I> \r
+<B>unit</B> Armas; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  Tipos, \r
+  Vectores, \r
+  ObjetoVolador; \r
\r
+<B>type</B> \r
+  <I><FONT COLOR="Navy">{** La clase cArma esta pensada como una clase abtracta. En ella se encuentran \r
+      características comunes a todas las armas.}</FONT></I> \r
+  cArma = <B>class</B>( cObjetoVolador ) \r
+    <B>private</B> \r
+      aDuracion:  tTiempo;   <I><FONT COLOR="Navy">// Este alcance determina cuanto tiempo tiene que pasar </FONT></I>\r
+                             <I><FONT COLOR="Navy">//  para que el arma se autodestruya. </FONT></I>\r
+      aAlcance:   tLongitud; <I><FONT COLOR="Navy">// Alcance en metros del arma </FONT></I>\r
+      aVelMaxima: tLongitud; <I><FONT COLOR="Navy">// Velocidad máxima del arma </FONT></I>\r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Actualiza el alcance del arma, que va disminuyendo a medida que pasa el tiempo}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cArma.mActualizarDuracion">mActualizarDuracion</A>( dt: tTiempo ); \r
+      <I><FONT COLOR="Navy">{** Devuelve true si el arma todavia tiene alcance}</FONT></I> \r
+      <B>function</B> <A HREF="#cArma.mActivo">mActivo</A>: boolean; \r
+      <I><FONT COLOR="Navy">{** Método para obtener el alcance del arma}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cArma.mSetAlcance">mSetAlcance</A>( alc: tLongitud ); \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( pos: cVector = <B>nil</B>; vel: cVector = <B>nil</B>; dim: tLongitud = 1; \r
+                          pot: tEnergia = 1; ene: tEnergia = 1; duracion: tTiempo = 2500; \r
+                          velMax: tLongitud = 0.25 ); overload; \r
+      <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar \r
+          y la información entregada depende del parámetro tDebugInfo.}</FONT></I> \r
+      <B>function</B> <A HREF="#cArma.mGetDebugInfo">mGetDebugInfo</A>( debugLevel: tDebugInfo = DI_MINI ): <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Método para obtener el alcance del arma}</FONT></I> \r
+      <B>function</B> <A HREF="#cArma.mGetAlcance">mGetAlcance</A>: tLongitud; \r
+      <I><FONT COLOR="Navy">{** Método para obtener el alcance del arma}</FONT></I> \r
+      <B>function</B> <A HREF="#cArma.mGetVelMax">mGetVelMax</A>:  tLongitud; \r
+      <I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se le agrega alguna funcionalidad}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cArma.mMover">mMover</A>( dt: tTiempo ); <B>override</B>; \r
+      <I><FONT COLOR="Navy">// SERIALIZACION </FONT></I>\r
+      <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.}</FONT></I> \r
+      <B>function</B> <A HREF="#cArma.mSerializar">mSerializar</A>: <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+          serializado.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cArma.mDesSerializar">mDesSerializar</A>( str: <B>string</B> ); <B>override</B>; \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** El laser es un tipo de arma básica. Es la que menos daño hace pero la que más rápido viaja<br> \r
+      <u>Características:</u> \r
+      <PRE> \r
+      Dimensión      0,1       metros (10 cm) \r
+      Potencia:      1         Cantidad de daño que hace por intervalo de tiempo \r
+      Energía:       1         Cantidad de daño que soporta antes de ser destruída \r
+      Velocidad:     0,4       metros/milisegundos (1440 km/h) \r
+      Alcance:       3000      milisegundos (3 segundos, 1,2 km) \r
+      </PRE>}</FONT></I> \r
+  cLaser = <B>class</B>( cArma ) \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( pos: cVector = <B>nil</B>; vel: cVector = <B>nil</B> ); overload; \r
+      <I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se dibuja de forma distinta}</FONT></I> \r
+      <B>function</B> <A HREF="#cLaser.mDibujar">mDibujar</A>: tObjetosVoladores; <B>override</B>; \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** El misil es un tipo de arma básica. Hace un daño considerable y su velocidad también es alta<br> \r
+      <u>Características:</u> \r
+      <PRE> \r
+      Dimensión      0,5       metros (50 cm) \r
+      Potencia:      20        Cantidad de daño que hace por intervalo de tiempo \r
+      Energía:       1         Cantidad de daño que soporta antes de ser destruída \r
+      Velocidad:     0,3       metros/milisegundos (1080 km/h) \r
+      Alcance:       5000      milisegundos (5 segundos, 1,5 km) \r
+      </PRE>}</FONT></I> \r
+  cMisil = <B>class</B>( cArma ) \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">// Constructor </FONT></I>\r
+      <B>constructor</B> create( pos: cVector = <B>nil</B>; vel: cVector = <B>nil</B> ); overload; \r
+      <I><FONT COLOR="Navy">// Método heredado, se sobreescribe porque se dibuja de forma distinta </FONT></I>\r
+      <B>function</B> <A HREF="#cMisil.mDibujar">mDibujar</A>: tObjetosVoladores; <B>override</B>; \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** El misil dirigido es un tipo de arma avanzada. Persigue a su objetivo hasta que lo alcanza o \r
+      hasta que se le acaba el alcance. Hace un daño alto, su velocidad es mediana y tiene un gran alcance.<br> \r
+      <u>Características:</u> \r
+      <PRE> \r
+      Dimensión      0,7       metros (70 cm) \r
+      Potencia:      30        Cantidad de daño que hace por intervalo de tiempo \r
+      Energía:       1         Cantidad de daño que soporta antes de ser destruída \r
+      Velocidad:     0,25      metros/milisegundos (900 km/h) \r
+      Alcance:       20000     milisegundos (20 segundos, 5 km) \r
+      Area de Lock:  2000      metros (2 km) \r
+      </PRE>}</FONT></I> \r
+  cMisilDirigido = <B>class</B>( cMisil ) \r
+    <B>private</B> \r
+      aObjetivo:  cObjetoVolador;      <I><FONT COLOR="Navy">// Objetivo del misil </FONT></I>\r
+      aLockArea:  tLongitud;           <I><FONT COLOR="Navy">// Maxima distancia a la que se debe encontrar </FONT></I>\r
+                                       <I><FONT COLOR="Navy">//  el objetivo para poder ser disparado </FONT></I>\r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Método que calcula la nueva velocidad basandose en al posicion del objetivo}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cMisilDirigido.mModificarVelocidad">mModificarVelocidad</A>; \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( obj: cObjetoVolador; pos: cVector = <B>nil</B> ); overload; \r
+      <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar \r
+          y la información entregada depende del parámetro tDebugInfo.}</FONT></I> \r
+      <B>function</B> <A HREF="#cMisilDirigido.mGetDebugInfo">mGetDebugInfo</A>( debugLevel: tDebugInfo = DI_MINI ): <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se le agrega alguna funcionalidad}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cMisilDirigido.mMover">mMover</A>( dt: tTiempo ); <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Obtiene el objetivo del misil dirigido}</FONT></I> \r
+      <B>function</B> <A HREF="#cMisilDirigido.mGetObjetivo">mGetObjetivo</A>: cObjetoVolador; \r
+      <I><FONT COLOR="Navy">{** Establece el objetivo del misil dirigido}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cMisilDirigido.mSetObjetivo">mSetObjetivo</A>( ov: cObjetoVolador ); \r
+      <I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se dibuja de forma distinta}</FONT></I> \r
+      <B>function</B> <A HREF="#cMisilDirigido.mDibujar">mDibujar</A>: tObjetosVoladores; <B>override</B>; \r
+      <I><FONT COLOR="Navy">// SERIALIZACION </FONT></I>\r
+      <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.}</FONT></I> \r
+      <B>function</B> <A HREF="#cMisilDirigido.mSerializar">mSerializar</A>: <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+          serializado.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cMisilDirigido.mDesSerializar">mDesSerializar</A>( str: <B>string</B> ); <B>override</B>; \r
+  <B>end</B>; \r
\r
+<B>implementation</B> \r
\r
+<B>uses</B> \r
+  RegExpr, \r
+  ObjetoPersistente, \r
+  SerializacionUtils, \r
+  Sysutils; \r
\r
+<I><FONT COLOR="Navy">{ cArma }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Este constructor es protegido porque solo va a ser utilizado por subclases \r
+    @param pos     Posicion inicial \r
+    @param vel     Velocidad inicial \r
+    @param dim     Dimensión del objeto volador (radio, en metros) \r
+    @param pot     Potencia del objeto volador (cantidad de daño que hace por intervalode tiempo) \r
+    @param ene     Energía del objeto volador(cantidad de daño que soporta antes de ser destruido) \r
+    @param alcance Tiempo que debe pasar para que el arma se destruya si no impactó con ningún objeto volador}</FONT></I> \r
+<B>constructor</B> cArma.create(pos: cVector; vel: cVector; dim: tLongitud; \r
+  pot, ene: tEnergia; duracion: tTiempo; velMax: tLongitud); \r
+<B>var</B> \r
+  v: cVector; \r
+<B>begin</B> \r
+  <B>inherited</B> create( pos, vel, dim, pot, ene ); \r
+  aDuracion  := duracion; \r
+  aVelMaxima := velMax; \r
+  aAlcance   := aDuracion * aVelMaxima; \r
+  <I><FONT COLOR="Navy">// Setea el modulo de la velocidad a la maxima </FONT></I>\r
+  v := mGetVelocidad.mSetModulo( aVelMaxima ); \r
+  mSetVelocidad( v ); \r
+  v.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Chequea si el arma todavia tiene alcance \r
+    @return <i>true</i> si todavía tiene alcance, <i>false</i> si no}</FONT></I> \r
+<B>function</B> <A NAME=cArma.mActivo>cArma.mActivo</A>: boolean; \r
+<B>begin</B> \r
+  result := ( aDuracion > 0 ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método para obtener el alcance del arma \r
+    @return Alcance del arma}</FONT></I> \r
+<B>function</B> <A NAME=cArma.mGetAlcance>cArma.mGetAlcance</A>: tLongitud; \r
+<B>begin</B> \r
+  result := aAlcance; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método para establecer el alcance del arma \r
+    @param alc Alcance del arma}</FONT></I> \r
+<B>procedure</B> <A NAME=cArma.mSetAlcance>cArma.mSetAlcance</A>(alc: tLongitud); \r
+<B>begin</B> \r
+  aAlcance := alc; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método para obtener la velocidad maxima del arma \r
+    @return Velocidad maxima del arma}</FONT></I> \r
+<B>function</B> <A NAME=cArma.mGetVelMax>cArma.mGetVelMax</A>: tLongitud; \r
+<B>begin</B> \r
+  result := aVelMaxima; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Actualiza el alcance del arma, que va disminuyendo a medida que pasa el tiempo \r
+    @param dt Intervalo de tiempo}</FONT></I> \r
+<B>procedure</B> <A NAME=cArma.mActualizarDuracion>cArma.mActualizarDuracion</A>(dt: tTiempo); \r
+<B>begin</B> \r
+  aDuracion := aDuracion - dt; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+<I><FONT COLOR="Navy">{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos. \r
+    @return            Cadena de texto con el estado del Objeto. \r
+    @param   debugLevel Cantidad de información requerida}</FONT></I> \r
+<B>function</B> <A NAME=cArma.mGetDebugInfo>cArma.mGetDebugInfo</A>(debugLevel: tDebugInfo): <B>string</B>; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Genera el string con el estado del Arma </FONT></I>\r
+  result := <B>inherited</B> mGetDebugInfo( debugLevel ); \r
+  <B>if</B> debugLevel > DI_MINI <B>then</B> \r
+    result := result + ' | Alcance: ' + FloatToStr( aDuracion ); \r
+<B>end</B>; \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Mueve el arma basado en su posición y velocidad actual y un intervalo de tiempo \r
+    @param dt Intervalo de tiempo}</FONT></I> \r
+<B>procedure</B> <A NAME=cArma.mMover>cArma.mMover</A>(dt: tTiempo); \r
+<B>begin</B> \r
+  <B>inherited</B> mMover( dt );  <I><FONT COLOR="Navy">// Mueve el arma de la forma convencional </FONT></I>\r
+  mActualizarDuracion( dt ); <I><FONT COLOR="Navy">// Actualiza el alcance </FONT></I>\r
+  <B>if</B> <B>not</B> mActivo <B>then</B> <I><FONT COLOR="Navy">// Si se quedó sin alcance... </FONT></I>\r
+    mSetEnergia( -1 ); <I><FONT COLOR="Navy">// pone energia en negativo, lo que significa que se destruyó... </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+    serializado. \r
+    @param str Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>procedure</B> <A NAME=cArma.mDesSerializar>cArma.mDesSerializar</A>(str: <B>string</B>); \r
+<B>var</B> \r
+  r: TRegExpr; \r
+<B>begin</B> \r
+  <B>inherited</B> mDesSerializar( str ); <I><FONT COLOR="Navy">// SIEMPRE el ID debe ser el PRIMER atributo </FONT></I>\r
+  r := TRegExpr.create; \r
+  <I><FONT COLOR="Navy">// DURACION </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<duracion>/s*([+-]?/d+)/s*</duracion>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aDuracion := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro la duracion' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer la duracion utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// ALCANCE </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<alcance>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</alcance>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aAlcance := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el alcance' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el alcance utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// VELMAXIMA </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<velmaxima>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</velmaxima>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aVelMaxima := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro la velocidad maxima' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer la velocidad maxima utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  r.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado. \r
+    @return Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>function</B> <A NAME=cArma.mSerializar>cArma.mSerializar</A>: <B>string</B>; \r
+<B>begin</B> \r
+  result := <B>inherited</B> mSerializar + \r
+            '<duracion>' + FloatToStrF( aDuracion, ffGeneral, 18, 0 ) + '</duracion>' + \r
+            '<alcance>' + FloatToStrF( aAlcance, ffGeneral, 18, 0 ) + '</alcance>' + \r
+            '<velmaxima>' + FloatToStrF( aVelMaxima, ffGeneral, 18, 0 ) + '</velmaxima>'; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cLaser }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Crea una nueva instancia. \r
+    @param pos Vector posición \r
+    @param vel Dirección del vector velocidad}</FONT></I> \r
+<B>constructor</B> cLaser.create(pos: cVector = <B>nil</B>; vel: cVector = <B>nil</B>); \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// El laser tiene 10 cm de radio, 1 punto de potencia, 1 punto de energia y 3 seg de alcance (1,2 km) </FONT></I>\r
+  <I><FONT COLOR="Navy">// Setea el modulo de la velocidad a 0,4 m/mseg (1440 km/h) </FONT></I>\r
+  <B>inherited</B> create( pos, vel, 0.1 <I><FONT COLOR="Navy">{dim}</FONT></I>, 1 <I><FONT COLOR="Navy">{pot}</FONT></I>, 1 <I><FONT COLOR="Navy">{ene}</FONT></I>, 3000 <I><FONT COLOR="Navy">{dur}</FONT></I>, 0.4 <I><FONT COLOR="Navy">{velmax}</FONT></I> ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se dibuja de forma distinta}</FONT></I> \r
+<B>function</B> <A NAME=cLaser.mDibujar>cLaser.mDibujar</A>: tObjetosVoladores; \r
+<B>begin</B> \r
+  result := OV_LASER; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cMisil }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Crea una nueva instancia. \r
+    @param pos Vector posición \r
+    @param vel Dirección del vector velocidad}</FONT></I> \r
+<B>constructor</B> cMisil.create(pos: cVector = <B>nil</B>; vel: cVector = <B>nil</B>); \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// El misil tiene 50 cm de radio, 20 puntos de potencia, 1 punto de energia y 5 seg de alcance (1,5 km) </FONT></I>\r
+  <I><FONT COLOR="Navy">// Setea el modulo de la velocidad a 0,3 m/mseg (1080 km/h) </FONT></I>\r
+  <B>inherited</B> create( pos, vel, 0.5 <I><FONT COLOR="Navy">{dim}</FONT></I>, 20 <I><FONT COLOR="Navy">{pot}</FONT></I>, 1 <I><FONT COLOR="Navy">{ene}</FONT></I>, 5000 <I><FONT COLOR="Navy">{dur}</FONT></I>, 0.3 <I><FONT COLOR="Navy">{velmax}</FONT></I> ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se dibuja de forma distinta}</FONT></I> \r
+<B>function</B> <A NAME=cMisil.mDibujar>cMisil.mDibujar</A>: tObjetosVoladores; \r
+<B>begin</B> \r
+  result := OV_MISIL; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cMisilDirigido }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Crea una nueva instancia. \r
+    @param obj Objeto volador al que perseguirá (objetivo) \r
+    @param pos Vector posición}</FONT></I> \r
+<B>constructor</B> cMisilDirigido.create( obj: cObjetoVolador; pos: cVector = <B>nil</B> ); \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// El misil dirigido tiene 70 m de radio, 30 puntos de potencia, 1 punto de energia y 20 seg de alcance (5 km) </FONT></I>\r
+  <B>inherited</B> create( pos, cVector.create, 0.7 <I><FONT COLOR="Navy">{dim}</FONT></I>, 30 <I><FONT COLOR="Navy">{pot}</FONT></I>, 1 <I><FONT COLOR="Navy">{ene}</FONT></I>, 20000 <I><FONT COLOR="Navy">{dur}</FONT></I>, 0.25 <I><FONT COLOR="Navy">{velmax}</FONT></I> ); \r
+  aObjetivo := obj; \r
+  aLockArea := 2000;   <I><FONT COLOR="Navy">// 2 km </FONT></I>\r
+  mSetAlcance( aLockArea ); <I><FONT COLOR="Navy">// Setea como alcance al area de lockeo. </FONT></I>\r
+  mModificarVelocidad; <I><FONT COLOR="Navy">// Modifica la velocidad de forma tal que apunte al objetivo </FONT></I>\r
+                       <I><FONT COLOR="Navy">//  y tenga un modulo constante </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método que calcula la nueva velocidad basandose en al posicion del objetivo}</FONT></I> \r
+<B>procedure</B> <A NAME=cMisilDirigido.mModificarVelocidad>cMisilDirigido.mModificarVelocidad</A>; \r
+<B>var</B> \r
+  pos,           <I><FONT COLOR="Navy">// Vector temporal para hacer calculos </FONT></I>\r
+  vel: cVector;  <I><FONT COLOR="Navy">// Vector temporal para hacer calculos </FONT></I>\r
+<B>begin</B> \r
+  vel := <B>nil</B>; \r
+  pos := <B>nil</B>; \r
+  <B>if</B> aObjetivo <> <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no es nulo ... </FONT></I>\r
+    <B>try</B> <I><FONT COLOR="Navy">// Probamos que el objetivo no este destruido </FONT></I>\r
+      <I><FONT COLOR="Navy">// Le resta la posicion propia a la del objetivo, obteniendo la nueva direccion de la velocidad </FONT></I>\r
+      pos := mGetPosicion; \r
+      vel := aObjetivo.mGetPosicion.mRestar( pos ); \r
+      vel.mSetModulo( mGetVelMax ); <I><FONT COLOR="Navy">// Setea el modulo al de la velocidad maxima: 0,25 m/mseg (900 km/h) </FONT></I>\r
+      mSetVelocidad( vel ); <I><FONT COLOR="Navy">// Modifica la velocidad basado en el vector v </FONT></I>\r
+    <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido queda la velocidad constante y libera los vectores </FONT></I>\r
+      on e: EAccessViolation <B>do</B> <B>begin</B> \r
+        mSetVelModulo( mGetVelMax ); <I><FONT COLOR="Navy">// Setea el modulo de la velocidad como la maxima </FONT></I>\r
+                                     <I><FONT COLOR="Navy">// (no cambia su direccion ni sentido) </FONT></I>\r
+        aObjetivo := <B>nil</B>; <I><FONT COLOR="Navy">// Lo seteamos a nil </FONT></I>\r
+        vel.free; <I><FONT COLOR="Navy">// libera la memoria del vector temporal </FONT></I>\r
+        pos.free; <I><FONT COLOR="Navy">// libera la memoria del vector temporal </FONT></I>\r
+      <B>end</B>; \r
+    <B>end</B>; \r
+  <I><FONT COLOR="Navy">// Si es nulo no modifica la velocidad ... </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Mueve el arma basado en su posición y velocidad actual, su objetivo y un intervalo de tiempo \r
+    @param dt Intervalo de tiempo}</FONT></I> \r
+<B>procedure</B> <A NAME=cMisilDirigido.mMover>cMisilDirigido.mMover</A>(dt: tTiempo); \r
+<B>begin</B> \r
+  mModificarVelocidad;    <I><FONT COLOR="Navy">// Modifica la velocidad segun su objetivo </FONT></I>\r
+  <B>inherited</B> mMover( dt ); <I><FONT COLOR="Navy">// Se mueve al igual que el resto de las armas </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+<I><FONT COLOR="Navy">{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos. \r
+    @return            Cadena de texto con el estado del Objeto. \r
+    @param   debugLevel Cantidad de información requerida}</FONT></I> \r
+<B>function</B> <A NAME=cMisilDirigido.mGetDebugInfo>cMisilDirigido.mGetDebugInfo</A>(debugLevel: tDebugInfo): <B>string</B>; \r
+<B>var</B> \r
+  objInfo: <B>string</B>; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Genera el string con el estado del Misil Dirigido </FONT></I>\r
+  result := <B>inherited</B> mGetDebugInfo( debugLevel ); \r
+  <B>if</B> debugLevel > DI_MINI <B>then</B> \r
+    result := result + ' | LockArea: ' + FloatToStr( aLockArea ); \r
+  <B>if</B> aObjetivo <> <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no es nulo ... </FONT></I>\r
+    <B>try</B> <I><FONT COLOR="Navy">// Probamos que el objetivo no este destruido </FONT></I>\r
+      objInfo := aObjetivo.mGetDebugInfo( DI_MINI ); \r
+    <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cambia la cadena de texto </FONT></I>\r
+      on e: EAccessViolation <B>do</B> <B>begin</B> \r
+        objInfo := 'DESTRUIDO'; \r
+        aObjetivo := <B>nil</B>; \r
+      <B>end</B>; \r
+    <B>end</B> \r
+  <B>else</B> <I><FONT COLOR="Navy">// Si es nulo ... </FONT></I>\r
+    objInfo := 'DESTRUIDO'; \r
+  <B>if</B> debugLevel > DI_NORMAL <B>then</B> \r
+    result := result + #13 + #10 + 'Objetivo: ' + objInfo; \r
+<B>end</B>; \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el objetivo del misil dirigido. \r
+    @return Objetivo del misil dirigido.}</FONT></I> \r
+<B>function</B> <A NAME=cMisilDirigido.mGetObjetivo>cMisilDirigido.mGetObjetivo</A>: cObjetoVolador; \r
+<B>begin</B> \r
+  result := aObjetivo; \r
+  <B>if</B> aObjetivo <> <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no es nil... </FONT></I>\r
+    <B>try</B> <I><FONT COLOR="Navy">// Primero se fija que no esté destruido </FONT></I>\r
+      aObjetivo.mGetID; \r
+    <B>except</B> \r
+      on e: EAccessViolation <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si lo está... </FONT></I>\r
+        aObjetivo := <B>nil</B>; <I><FONT COLOR="Navy">// Lo setea a nil </FONT></I>\r
+        result := aObjetivo; \r
+      <B>end</B>; \r
+    <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Establece el objetivo del misil dirigido \r
+    @param ov Nuevo objetivo}</FONT></I> \r
+<B>procedure</B> <A NAME=cMisilDirigido.mSetObjetivo>cMisilDirigido.mSetObjetivo</A>( ov: cObjetoVolador ); \r
+<B>begin</B> \r
+  aObjetivo := ov; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se dibuja de forma distinta}</FONT></I> \r
+<B>function</B> <A NAME=cMisilDirigido.mDibujar>cMisilDirigido.mDibujar</A>: tObjetosVoladores; \r
+<B>begin</B> \r
+    result := OV_MISDIR; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+    serializado. \r
+    @param str Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>procedure</B> <A NAME=cMisilDirigido.mDesSerializar>cMisilDirigido.mDesSerializar</A>(str: <B>string</B>); \r
+<B>var</B> \r
+  r: TRegExpr; \r
+<B>begin</B> \r
+  <B>inherited</B> mDesSerializar( str ); <I><FONT COLOR="Navy">// SIEMPRE el ID debe ser el PRIMER atributo </FONT></I>\r
+  r := TRegExpr.create; \r
+  <I><FONT COLOR="Navy">// OBJETIVO </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<objetivo/s+class=([/w/d]+)/s*>/s*(.+)/s*</objetivo>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      <B>if</B> r.Match[1] <> '0' <B>then</B> <I><FONT COLOR="Navy">// Si tiene una clase determinada... </FONT></I>\r
+        <B>if</B> aObjetivo <> <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no es nulo </FONT></I>\r
+          <I><FONT COLOR="Navy">// Puede caer en una EAccessViolation si esta destruido </FONT></I>\r
+          aObjetivo.mDesSerializar( r.Match[2] ) <I><FONT COLOR="Navy">// Lo deserializa </FONT></I>\r
+        <B>else</B> <I><FONT COLOR="Navy">// si es nulo </FONT></I>\r
+          aObjetivo := restaurarObjeto( r.Match[1], r.Match[2] ) <I><FONT COLOR="Navy">// lo crea segun su clase </FONT></I>\r
+      <B>else</B> <I><FONT COLOR="Navy">// Si no tiene una clase determinada, entonces se lo pone en nil </FONT></I>\r
+        aObjetivo := <B>nil</B> \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el objetivo' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ESerializacion <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si fueron de serializacion... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al deserializar el objetivo: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el objetivo utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+    on e: EAccessViolation <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si el Objetivo fue destruido... </FONT></I>\r
+      aObjetivo := restaurarObjeto( r.Match[1], r.Match[2] ) <I><FONT COLOR="Navy">// lo crea segun su clase </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// LOCKAREA </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<lockarea>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</lockarea>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aLockArea := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el area de lockeo' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el area de lockeo utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  r.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado. \r
+    @return Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>function</B> <A NAME=cMisilDirigido.mSerializar>cMisilDirigido.mSerializar</A>: <B>string</B>; \r
+<B>var</B> \r
+  clase, \r
+  objetivo: <B>string</B>; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Si el objetivo es nil o está destruido, se setea el atributo class del </FONT></I>\r
+  <I><FONT COLOR="Navy">// TAG objetivo como '0' y entre el TAG se indica que es nil. Si no se </FONT></I>\r
+  <I><FONT COLOR="Navy">// setea como el nombre de la clase y su expresion serializada respectivamente </FONT></I>\r
+  objetivo := 'nil'; \r
+  clase    := '0'; \r
+  <B>if</B> aObjetivo <> <B>nil</B> <B>then</B> \r
+    <B>try</B> \r
+      objetivo := aObjetivo.mSerializar; \r
+      clase    := aObjetivo.ClassName; \r
+    <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cambia la cadena de texto </FONT></I>\r
+      on e: EAccessViolation <B>do</B> <B>begin</B> \r
+        objetivo := 'nil'; \r
+        clase    := '0'; \r
+        aObjetivo := <B>nil</B>; \r
+      <B>end</B>; \r
+    <B>end</B>; \r
+  result := <B>inherited</B> mSerializar + \r
+            '<objetivo class=' + clase + '>' + objetivo + '</objetivo>' + \r
+            '<lockarea>' + FloatToStrF( aLockArea, ffGeneral, 18, 0 ) + '</lockarea>'; \r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/modelo/ov/Meteorito.pas b/doc/src-html/modelo/ov/Meteorito.pas
new file mode 100644 (file)
index 0000000..e460062
--- /dev/null
@@ -0,0 +1,58 @@
+<HTML><HEAD>\r
+<TITLE>File: meteorito.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=meteorito.pas><CENTER><H3>meteorito.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Representa un objeto volador básico. Tiene una velocidad constante.<br> \r
+    <i>Cambios:</i> \r
+    <PRE> \r
+    01/12/00: Se cambiaron las dimensiones por defecto para que los disparos sean mas "jugables". \r
+    </PRE>}</FONT></I> \r
+<B>unit</B> Meteorito; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  ObjetoVolador, \r
+  Tipos, \r
+  Vectores; \r
\r
+<B>type</B> \r
+  <I><FONT COLOR="Navy">{** Representa un objeto volador básico. Tiene una velocidad constante.}</FONT></I> \r
+  cMeteorito = <B>class</B>( cObjetoVolador ) \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( pos: cVector = <B>nil</B>; vel: cVector = <B>nil</B>; dim: tLongitud = 5; pot: tEnergia = 5; ene: tEnergia = 20 ); overload; \r
+      <I><FONT COLOR="Navy">{** Método para dibujar el meteorito (todavía no implementado)}</FONT></I> \r
+      <B>function</B> <A HREF="#cMeteorito.mDibujar">mDibujar</A>: tObjetosVoladores; <B>override</B>; \r
+  <B>end</B>; \r
\r
+<B>implementation</B> \r
\r
+<I><FONT COLOR="Navy">{ cMeteorito }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Constructor \r
+    @param pos Posicion inicial \r
+    @param vel Velocidad inicial \r
+    @param dim Dimensión del objeto volador (radio, en metros) \r
+    @param pot Potencia del objeto volador (cantidad de daño que hace por intervalode tiempo) \r
+    @param ene Energía del objeto volador(cantidad de daño que soporta antes de ser destruido)}</FONT></I> \r
+<B>constructor</B> cMeteorito.create(pos, vel: cVector; dim: tLongitud; pot, \r
+  ene: tEnergia); \r
+<B>begin</B> \r
+  <B>inherited</B> create( pos, vel, dim, pot, ene ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método para dibujar el meteorito (todavía no implementado)}</FONT></I> \r
+<B>function</B> <A NAME=cMeteorito.mDibujar>cMeteorito.mDibujar</A>: tObjetosVoladores; \r
+<B>begin</B> \r
+  result := OV_METEORITO; \r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/modelo/ov/ObjetoVolador.pas b/doc/src-html/modelo/ov/ObjetoVolador.pas
new file mode 100644 (file)
index 0000000..399144b
--- /dev/null
@@ -0,0 +1,510 @@
+<HTML><HEAD>\r
+<TITLE>File: objetovolador.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=objetovolador.pas><CENTER><H3>objetovolador.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Clase abstracta, implementa todas las funcionalidades básicas de los objetos voladores. \r
+    De esta van a derivar la mayor parte del resto de las clases.<br> \r
+    <i>Cambios:</i> \r
+    <PRE> \r
+    05/10/00: Se agregaron los métodos mGetDistancia y mColisiono. De esta manera se deja \r
+              a los objetos voladores manejar las colisiones mas intuitivamente. \r
+    30/10/00: Se agregó un atributo <b>aCoordenadas</b> para que se pueda orientar al objeto volador. \r
+    02/11/00: Se agregaron métodos para cambiar solamente el modulo de la velocidad, para cambiar solo \r
+              la direccion de la velocidad y para extraer directamente copias de los versores i, j, k y \r
+              para rotar el objeto volador en todas direcciones. \r
+              Los nuevos métodos son: mSetVelModulo, mSetVelDir, mGetVelModulo, \r
+                                      mGetI, mGetJ, mGetK, mRotarEnI, \r
+                                      mRotarEnJ, mRotarEnK \r
+    07/11/00: Se agrega un nuevo método (mSetPosicion) y se hace a público otro (mSetVelocidad) para \r
+              que se pueda cambiar la configuración (es temporal, se planea cambiar el sistema de \r
+              configuración del juego para que esto no sea necesario) \r
+    29/11/00: Se arregla un BUG en mSetVelModulo que no modificaba el modulo si la velocidad pasada \r
+              como argumento era menor que cero. En este caso el modulo de la velocidad se setea en 0. \r
+    02/12/00: Se cambio el dato que devuelve el método mDibujar. Ahora devuelve un tipo de dato enumerado \r
+              tObjetosVoladores. Todas sus subclases fueron actualizadas también. \r
+    08/12/00: Se agregan menúes para manejar la nueva vistas con varias camaras. Se agrega la opcion de \r
+              alta calidad en el menú vista. Se carga un escenario por defecto (si existe) al iniciar el \r
+              juego, el nombre de dicho escenario debe ser 'comun.eaw'. \r
+              Se agrega una nueva tecla para cambiar de cámara ('C'), además de las que se provee con las \r
+              teclas de atajo. \r
+    </PRE>}</FONT></I> \r
+<B>unit</B> ObjetoVolador; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  Tipos, \r
+  ObjetoPersistente, \r
+  Coordenadas, \r
+  Vectores; \r
\r
+<B>type</B> \r
+  <I><FONT COLOR="Navy">{** Clase abstracta, implementa todas las funcionalidades básicas de los objetos voladores. \r
+      De esta van a derivar la mayor parte del resto de las clases.}</FONT></I> \r
+  cObjetoVolador = <B>class</B>( cObjetoPersistente ) \r
+    <B>private</B> \r
+      aPosicion:    cVector;      <I><FONT COLOR="Navy">// Posicion del objeto volador en el espacio </FONT></I>\r
+      aVelocidad:   tLongitud;    <I><FONT COLOR="Navy">// Velocidad del objeto volador (en modulo) </FONT></I>\r
+      aPotencia:    tEnergia;     <I><FONT COLOR="Navy">// Potencia del objeto volador (la cantidad de daño que hace por impacto) </FONT></I>\r
+      aEnergia:     tEnergia;     <I><FONT COLOR="Navy">// Energía del objeto volador (la cantidad de daño que soporta antes de ser destruido) </FONT></I>\r
+      aDimension:   tLongitud;    <I><FONT COLOR="Navy">// La dimesión del objeto volador (es el radio de una esfera) </FONT></I>\r
+      <I><FONT COLOR="Navy">// Agregado 30/10/00 </FONT></I>\r
+      aCoordenadas: cCoordenadas; <I><FONT COLOR="Navy">// Sistema de coordenadas del objeto volador (para tener nocion de la orientación) </FONT></I>\r
+                                  <I><FONT COLOR="Navy">//  El versor i es la direccion de la velocidad </FONT></I>\r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Método para establecer la energía}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mSetEnergia">mSetEnergia</A>( ene: tEnergia ): cObjetoVolador; \r
+      <I><FONT COLOR="Navy">{** Rota el objeto volador sobre el eje i \r
+          (el sentido positivo es de j a k)}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mRotarEnI">mRotarEnI</A>( dAngulo: tAngulo ): cObjetoVolador; \r
+      <I><FONT COLOR="Navy">{** Rota el objeto volador sobre el eje j \r
+          (el sentido positivo es de i a k)}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mRotarEnJ">mRotarEnJ</A>( dAngulo: tAngulo ): cObjetoVolador; \r
+      <I><FONT COLOR="Navy">{** Rota el objeto volador sobre el eje k \r
+          (el sentido positivo es de i a j)}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mRotarEnK">mRotarEnK</A>( dAngulo: tAngulo ): cObjetoVolador; \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( pos: cVector = <B>nil</B>; vel: cVector = <B>nil</B>; dim: tLongitud = 5; pot: tEnergia = 1; ene: tEnergia = 100 ); overload; \r
+      <I><FONT COLOR="Navy">{** Constructor que copia los atributos de un Objeto volador existente}</FONT></I> \r
+      <B>constructor</B> create( ov:  cObjetoVolador ); overload; \r
+      <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar \r
+          y la información entregada depende del parámetro tDebugInfo.}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mGetDebugInfo">mGetDebugInfo</A>( debugLevel: tDebugInfo = DI_MINI ): <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Mueve el objeto volador basandose en su posicion, su velocidad y un intervalo de tiempo}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cObjetoVolador.mMover">mMover</A>( dT: tTiempo ); <B>virtual</B>; \r
+      <I><FONT COLOR="Navy">{** Calcula la distancia a otro objeto volador}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mGetDistancia">mGetDistancia</A>( ov: cObjetoVolador ): tLongitud; \r
+      <I><FONT COLOR="Navy">{** Devuelve true si colisionaron los objetos voladores}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mColisiono">mColisiono</A>( ov: cObjetoVolador ): boolean; \r
+      <I><FONT COLOR="Navy">{** Obtiene la velocidad del objeto volador}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mGetVelocidad">mGetVelocidad</A>: cVector; \r
+      <I><FONT COLOR="Navy">{** Obtiene el modulo de la velocidad del objeto volador}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mGetVelModulo">mGetVelModulo</A>: tLongitud; \r
+      <I><FONT COLOR="Navy">{** Obtiene la Posicion del objeto volador}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mGetPosicion">mGetPosicion</A>: cVector; \r
+      <I><FONT COLOR="Navy">{** Obtiene la Potencia del objeto volador}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mGetPotencia">mGetPotencia</A>: tEnergia; \r
+      <I><FONT COLOR="Navy">{** Obtiene la Energia del objeto volador}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mGetEnergia">mGetEnergia</A>: tEnergia; \r
+      <I><FONT COLOR="Navy">{** Obtiene la Dimension del objeto volador}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mGetDimension">mGetDimension</A>: tLongitud; \r
+      <I><FONT COLOR="Navy">{** Obtiene el sistema de coordenadas de la nave}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mGetCoordenadas">mGetCoordenadas</A>: cCoordenadas; \r
+      <I><FONT COLOR="Navy">{** Obtiene el versor i del sistema de coordenadas de la nave}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mGetI">mGetI</A>: cVector; \r
+      <I><FONT COLOR="Navy">{** Obtiene el versor j del sistema de coordenadas de la nave}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mGetJ">mGetJ</A>: cVector; \r
+      <I><FONT COLOR="Navy">{** Obtiene el versor k del sistema de coordenadas de la nave}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mGetK">mGetK</A>: cVector; \r
+      <I><FONT COLOR="Navy">{** Método para establecer la posición}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mSetPosicion">mSetPosicion</A>( posicion: cVector ): cObjetoVolador; \r
+      <I><FONT COLOR="Navy">{** Método para establecer la velocidad}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mSetVelocidad">mSetVelocidad</A>( velocidad: cVector ): cObjetoVolador; <B>virtual</B>; \r
+      <I><FONT COLOR="Navy">{** Método para establecer el modulo de la velocidad}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mSetVelModulo">mSetVelModulo</A>( velocidad: tLongitud ): cObjetoVolador; <B>virtual</B>; \r
+      <I><FONT COLOR="Navy">{** Método para establecer la direccion de la velocidad}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mSetVelDir">mSetVelDir</A>( velocidad: cVector ): cObjetoVolador; \r
+      <I><FONT COLOR="Navy">{** Resta energia al objeto volador}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mRestarEnergia">mRestarEnergia</A>( ene: tEnergia ): cObjetoVolador; \r
+      <I><FONT COLOR="Navy">{** Método abstracto, se sobreescribira en las subclases porque van a ser \r
+          dibujadas de forma diferente}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mDibujar">mDibujar</A>: tObjetosVoladores; <B>virtual</B>; <B>abstract</B>; \r
+      <I><FONT COLOR="Navy">{** Destructor}</FONT></I> \r
+      <B>destructor</B> destroy; <B>override</B>; \r
+      <I><FONT COLOR="Navy">// SERIALIZACION </FONT></I>\r
+      <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.}</FONT></I> \r
+      <B>function</B> <A HREF="#cObjetoVolador.mSerializar">mSerializar</A>: <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+          serializado.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cObjetoVolador.mDesSerializar">mDesSerializar</A>( str: <B>string</B> ); <B>override</B>; \r
+  <B>end</B>; \r
\r
+<B>implementation</B> \r
\r
+<B>uses</B> \r
+  RegExpr, \r
+  Sysutils; \r
\r
+<I><FONT COLOR="Navy">{ cObjetoVolador }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Constructor \r
+    @param ov Objeto volador del cual extraer los datos para inicializar en actual}</FONT></I> \r
+<B>constructor</B> cObjetoVolador.create( ov: cObjetoVolador ); \r
+<B>var</B> \r
+  vel: cVector; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Crea el objeto basandose en los atributos del parametro </FONT></I>\r
+  <B>inherited</B> create; \r
+  aPosicion := ov.mGetPosicion; \r
+  vel := ov.mGetVelocidad; \r
+  aVelocidad := vel.mGetModulo; \r
+  vel.free; \r
+  aDimension := ov.mGetDimension; \r
+  aPotencia  := ov.mGetPotencia; \r
+  aEnergia   := ov.mGetEnergia; \r
+  aCoordenadas := ov.mGetCoordenadas; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Constructor \r
+    @param pos Posicion inicial \r
+    @param vel Velocidad inicial \r
+    @param dim Dimensión del objeto volador (radio, en metros) \r
+    @param pot Potencia del objeto volador (cantidad de daño que hace por intervalode tiempo) \r
+    @param ene Energía del objeto volador(cantidad de daño que soporta antes de ser destruido)}</FONT></I> \r
+<B>constructor</B> cObjetoVolador.create(pos: cVector = <B>nil</B>; vel: cVector = <B>nil</B>; \r
+  dim: tLongitud = 5; pot: tEnergia = 1; ene: tEnergia = 100); \r
+<B>begin</B> \r
+  <B>inherited</B> create; \r
+  aDimension := dim; \r
+  aPotencia  := pot; \r
+  aEnergia   := ene; \r
+  aCoordenadas := cCoordenadas.create; \r
+  <I><FONT COLOR="Navy">// Si la posicion es nula crea una nueva </FONT></I>\r
+  <B>if</B> pos = <B>nil</B> <B>then</B> \r
+    aPosicion := cVector.create( 0, 0, 0 ) \r
+  <B>else</B> \r
+    aPosicion := cVector.create( pos ); \r
+  <I><FONT COLOR="Navy">// Si la velocidad es nula crea una nueva </FONT></I>\r
+  <B>if</B> vel = <B>nil</B> <B>then</B> \r
+    aVelocidad := 0 \r
+  <B>else</B> <B>begin</B> \r
+    aVelocidad := vel.mGetModulo; \r
+    aCoordenadas.mSetI( vel ); \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Mueve el objeto volador basandose en su posicion, su velocidad y un intervalo de tiempo \r
+    @param dT Intervalo de tiempo}</FONT></I> \r
+<B>procedure</B> <A NAME=cObjetoVolador.mMover>cObjetoVolador.mMover</A>( dT: tTiempo ); \r
+<B>var</B> \r
+  v: cVector; \r
+<B>begin</B> \r
+  v := cVector.create( mGetVelocidad ); \r
+  aPosicion.mModificarCon( v, dT ); \r
+  v.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Establece la velocidad del objeto volador \r
+    @param velocidad Nuevo vector velocidad}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mSetVelocidad>cObjetoVolador.mSetVelocidad</A>( velocidad: cVector ): cObjetoVolador; \r
+<B>begin</B> \r
+  aVelocidad := velocidad.mGetModulo; \r
+  <I><FONT COLOR="Navy">// Agregado 30/10/00 para que mantenga las coordenadas </FONT></I>\r
+  aCoordenadas.mSetI( velocidad ); \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la velocidad del objeto volador \r
+    @return Vector velocidad}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mGetVelocidad>cObjetoVolador.mGetVelocidad</A>: cVector; \r
+<B>begin</B> \r
+  result := aCoordenadas.mGetI.mMultiplicar( aVelocidad ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la posición del objeto volador \r
+    @return Vector posición}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mGetPosicion>cObjetoVolador.mGetPosicion</A>: cVector; \r
+<B>begin</B> \r
+  result := cVector.create( aPosicion ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la dimensión del objeto volador \r
+    @return Dimensión (radio, en metros)}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mGetDimension>cObjetoVolador.mGetDimension</A>: tLongitud; \r
+<B>begin</B> \r
+  result := aDimension; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Destructor}</FONT></I> \r
+<B>destructor</B> cObjetoVolador.destroy; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Libera los atributo objeto </FONT></I>\r
+  aPosicion.free; \r
+  aCoordenadas.free; \r
+  <B>inherited</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la potencia del objeto volador \r
+    @return Potencia (cantidad de daño que realiza por intervalo de tiempo)}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mGetPotencia>cObjetoVolador.mGetPotencia</A>: tEnergia; \r
+<B>begin</B> \r
+ result := aPotencia; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la e del objeto volador \r
+    @return Energía (cantidad de daño que soporta antes de ser destruido)}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mGetEnergia>cObjetoVolador.mGetEnergia</A>: tEnergia; \r
+<B>begin</B> \r
+ result := aEnergia; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+<I><FONT COLOR="Navy">{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos. \r
+    @return            Cadena de texto con el estado del Objeto. \r
+    @param   debugLevel Cantidad de información requerida}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mGetDebugInfo>cObjetoVolador.mGetDebugInfo</A>( debugLevel: tDebugInfo = DI_MINI ): <B>string</B>; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Construye la cadena dependiendo de la cantidad de informacion que se quiera obtener </FONT></I>\r
+  result := 'Posición: ' + aPosicion.mGetDebugInfo( debugLevel ); \r
+  <B>if</B> debugLevel > DI_MINI <B>then</B> \r
+    result := result + #13 + #10 + \r
+              'Energia: ' + FloatToStrF( aEnergia, ffNumber, 5, 5 ); \r
+  <B>if</B> debugLevel > DI_NORMAL <B>then</B> \r
+    result := result + ' | Potencia: ' + FloatToStrF( aPotencia, ffNumber, 5, 5 ) + \r
+                       ' | Dimension: ' + FloatToStrF( aDimension, ffNumber, 5, 5 ) + #13 + #10 + \r
+                       'Velocidad: ' + mGetVelocidad.mGetDebugInfo( debugLevel ) + #13 + #10 + \r
+                       'Coordenadas: ' + #13 + #10 + aCoordenadas.mGetDebugInfo; \r
+<B>end</B>; \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Resta energía al objeto volador \r
+    @param ene Energía a restar}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mRestarEnergia>cObjetoVolador.mRestarEnergia</A>(ene: tEnergia): cObjetoVolador; \r
+<B>begin</B> \r
+  aEnergia := aEnergia - ene; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Setea la energía del objeto volador a un valor arbitrario \r
+    @param ene Nueva energía}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mSetEnergia>cObjetoVolador.mSetEnergia</A>(ene: tEnergia): cObjetoVolador; \r
+<B>begin</B> \r
+  aEnergia := ene; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Calcula la distancia a otro objeto volador \r
+    @return     Distancia al otro objeto volador \r
+    @param   ov Objeto volador al que se calcula la distancia}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mGetDistancia>cObjetoVolador.mGetDistancia</A>(ov: cObjetoVolador): tLongitud; \r
+<B>var</B> \r
+  v: cVector; <I><FONT COLOR="Navy">// Vector temporal </FONT></I>\r
+<B>begin</B> \r
+  v := ov.mGetPosicion; <I><FONT COLOR="Navy">// obtiene la posicion de ov </FONT></I>\r
+  result := v.mGetDistancia( aPosicion ); <I><FONT COLOR="Navy">// obtiene la distancia </FONT></I>\r
+  v.free; <I><FONT COLOR="Navy">// Libera al vector temporal </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve true si colisionaron los objetos voladores \r
+    @return     <i>true<i> si colisionaron, <i>false</i> si no lo hicieron \r
+    @param   ov Objeto volador con el que se evalua si colisiono}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mColisiono>cObjetoVolador.mColisiono</A>(ov: cObjetoVolador): boolean; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// true si la distancia es menor a la suma de las dimensiones </FONT></I>\r
+  result := ( mGetDistancia( ov ) <= ( aDimension + ov.mGetDimension ) ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el sistema de coordenadas de la nave \r
+    @return Sistema de coordenadas de la nave}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mGetCoordenadas>cObjetoVolador.mGetCoordenadas</A>: cCoordenadas; \r
+<B>begin</B> \r
+  result := cCoordenadas.create( aCoordenadas ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método para establecer el modulo de la velocidad \r
+    @param velocidad Nuevo módulo de la velocidad}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mSetVelModulo>cObjetoVolador.mSetVelModulo</A>( velocidad: tLongitud ): cObjetoVolador; \r
+<B>begin</B> \r
+  <B>if</B> velocidad > 0 <B>then</B> \r
+    aVelocidad := velocidad \r
+  <B>else</B> \r
+    aVelocidad := 0; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método para establecer la direccion de la velocidad \r
+    @param velocidad Nueva dirección de la velocidad}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mSetVelDir>cObjetoVolador.mSetVelDir</A>( velocidad: cVector ): cObjetoVolador; \r
+<B>begin</B> \r
+  aCoordenadas.mSetI( velocidad ); \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el modulo de la velocidad del objeto volador \r
+    @return Módulo de la velocidad}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mGetVelModulo>cObjetoVolador.mGetVelModulo</A>: tLongitud; \r
+<B>begin</B> \r
+  result := aVelocidad; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el versor i del sistema de coordenadas de la nave \r
+    @return Versor i, que representa la direccion en la que viaja el objeto}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mGetI>cObjetoVolador.mGetI</A>: cVector; \r
+<B>begin</B> \r
+  result := aCoordenadas.mGetI; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el versor j del sistema de coordenadas de la nave \r
+    @return Versor j, que representa la direccion en la que está la izquierda del objeto}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mGetJ>cObjetoVolador.mGetJ</A>: cVector; \r
+<B>begin</B> \r
+  result := aCoordenadas.mGetJ; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el versor k del sistema de coordenadas de la nave \r
+    @return Versor k, que representa la direccion en la que está el "techo" del objeto}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mGetK>cObjetoVolador.mGetK</A>: cVector; \r
+<B>begin</B> \r
+  result := aCoordenadas.mGetK; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Rota el objeto volador sobre el eje i \r
+    (el sentido positivo es de j a k)}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mRotarEnI>cObjetoVolador.mRotarEnI</A>( dAngulo: tAngulo ): cObjetoVolador; \r
+<B>begin</B> \r
+  aCoordenadas.mRotarEnI( dAngulo ); \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Rota el objeto volador sobre el eje j \r
+    (el sentido positivo es de i a k)}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mRotarEnJ>cObjetoVolador.mRotarEnJ</A>( dAngulo: tAngulo ): cObjetoVolador; \r
+<B>begin</B> \r
+  aCoordenadas.mRotarEnJ( dAngulo ); \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Rota el objeto volador sobre el eje k \r
+    (el sentido positivo es de i a j)}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mRotarEnK>cObjetoVolador.mRotarEnK</A>( dAngulo: tAngulo ): cObjetoVolador; \r
+<B>begin</B> \r
+  aCoordenadas.mRotarEnK( dAngulo ); \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método para establecer la posición \r
+    @param velocidad Nuevo vector posición}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mSetPosicion>cObjetoVolador.mSetPosicion</A>(posicion: cVector): cObjetoVolador; \r
+<B>begin</B> \r
+  aPosicion := cVector.create( posicion ); \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+    serializado. \r
+    @param str Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>procedure</B> <A NAME=cObjetoVolador.mDesSerializar>cObjetoVolador.mDesSerializar</A>(str: <B>string</B>); \r
+<B>var</B> \r
+  r: TRegExpr; \r
+<B>begin</B> \r
+  <B>inherited</B> mDesSerializar( str ); <I><FONT COLOR="Navy">// SIEMPRE el ID debe ser el PRIMER atributo </FONT></I>\r
+  r := TRegExpr.create; \r
+  <I><FONT COLOR="Navy">// POSICION </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<posicion>/s*(.+)/s*</posicion>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      <B>if</B> aPosicion <> <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no es nulo </FONT></I>\r
+        aPosicion.mDesSerializar( r.Match[1] ) <I><FONT COLOR="Navy">// Lo deserializa </FONT></I>\r
+      <B>else</B> <I><FONT COLOR="Navy">// si es nulo </FONT></I>\r
+        aPosicion := cVector.crearDeSerializado( r.Match[1] ) <I><FONT COLOR="Navy">// lo crea </FONT></I>\r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro la posicion' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ESerializacion <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si fueron de serializacion... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al deserializar la posicion: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer la posicion utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// VELOCIDAD </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<velocidad>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</velocidad>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aVelocidad := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro la velocidad' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer la velocidad utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// POTENCIA </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<potencia>/s*([+/-]?/d+)/s*</potencia>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aPotencia := StrToInt( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro la potencia' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer la potencia utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// ENERGIA </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<energia>/s*([+/-]?/d+)/s*</energia>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aEnergia := StrToInt( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro la energia' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer la energia utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// DIMENSION </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<dimension>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</dimension>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aDimension := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro la dimension' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer la dimension utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// COORDENADAS </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<coordenadas>/s*(.+)/s*</coordenadas>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      <B>if</B> aCoordenadas <> <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no es nulo </FONT></I>\r
+        aCoordenadas.mDesSerializar( r.Match[1] ) <I><FONT COLOR="Navy">// Lo deserializa </FONT></I>\r
+      <B>else</B> <I><FONT COLOR="Navy">// si es nulo </FONT></I>\r
+        aCoordenadas := cCoordenadas.crearDeSerializado( r.Match[1] ) <I><FONT COLOR="Navy">// lo crea </FONT></I>\r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': No se pudieron extraer las coordenadas' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ESerializacion <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si fueron de serializacion... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al deserializar las coordenadas: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer las coordenadas utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  r.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado. \r
+    @return Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>function</B> <A NAME=cObjetoVolador.mSerializar>cObjetoVolador.mSerializar</A>: <B>string</B>; \r
+<B>begin</B> \r
+  result := <B>inherited</B> mSerializar + \r
+            '<posicion>' + aPosicion.mSerializar + '</posicion>' + \r
+            '<velocidad>' + FloatToStrF( aVelocidad, ffGeneral, 18, 0 ) + '</velocidad>' + \r
+            '<potencia>' + FloatToStrF( aPotencia, ffGeneral, 18, 0 ) + '</potencia>' + \r
+            '<energia>' + FloatToStrF( aEnergia, ffGeneral, 18, 0 ) + '</energia>' + \r
+            '<dimension>' + FloatToStrF( aDimension, ffGeneral, 18, 0 ) + '</dimension>' + \r
+            '<coordenadas>' + aCoordenadas.mSerializar + '</coordenadas>'; \r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/modelo/ov/naves/Nave.pas b/doc/src-html/modelo/ov/naves/Nave.pas
new file mode 100644 (file)
index 0000000..e905185
--- /dev/null
@@ -0,0 +1,553 @@
+<HTML><HEAD>\r
+<TITLE>File: nave.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=nave.pas><CENTER><H3>nave.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Contiene una clase abstracta con elementos comunes a todas las naves.<br> \r
+    <i>Cambios:</i> \r
+    <PRE> \r
+    27/11/00: Se agrega toda la parte del manejo de disparos, agregándose los métodos mPuedeDispararLaser, \r
+              mPuedeDispararMisil, mPuedeDispararMisDir y mDisparar, además de varios atributos para manejar \r
+              los retardos de las armas. El método mDisparar se hace virtual ya que puede ser modificado por \r
+              las subclases para que cambie su mecanismo de disparos. \r
+    29/11/00: Se agregan métodos para obtener la cantidad de armamento que le queda a la nave para poder ser \r
+              mostrados (mGetMisiles y mGetMisilesDirigidos) \r
+    01/12/00: Se modifican levemente los metodos mPuedeDispararXxxx para que permitan disparar si el puntero \r
+              al Objeto Volador objetivo es nil. \r
+              Se Agregan los métodos mRetardarLaser, mRetardarMisil, mRetardarMisDir que resetea el contador \r
+              del retardo, mActualizarRetardos que resta el dT a los retardos, y mCrearLaserDisparado, \r
+              mCrearMisilDisparado y mCrearMisDirDisparado que crea el arma correspondiente (actualizando \r
+              retardos y todo lo que sea necesario) para que las subclases puedan escribir su propio mDisparar. \r
+              Se cambia el orden de los argumentos de mDisparar para aprovechar los argumentos por defecto. \r
+    08/12/00: Se sobreescribieron los métodos para establecer la velocidad y su módulo para evitar que se \r
+              sobrepase el límite de la velocidad máxima. \r
+    </PRE>}</FONT></I> \r
+<B>unit</B> Nave; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  ObjetoVolador, \r
+  Tipos, \r
+  Vectores, \r
+  Armas; \r
\r
+<B>type</B> \r
+  <I><FONT COLOR="Navy">{** Clase abstracta con elementos comunes a todas las naves.}</FONT></I> \r
+  cNave = <B>class</B>( cObjetoVolador ) \r
+    <B>private</B> \r
+      aMisiles:           tMaxMisil;         <I><FONT COLOR="Navy">// Cantidad de misilies comunes </FONT></I>\r
+      aMisilesDirigidos:  tMaxMisilDirigido; <I><FONT COLOR="Navy">// Cantidad de misiles dirigidos </FONT></I>\r
+      aVelMaxima:         tLongitud;        <I><FONT COLOR="Navy">// Velocidad máxima de la nave </FONT></I>\r
+      aRetardoLaser:      tTiempo;          <I><FONT COLOR="Navy">// Ratardo del arma antes de poder volver a disparar </FONT></I>\r
+      aRetardoMisil:      tTiempo;          <I><FONT COLOR="Navy">// Ratardo del arma antes de poder volver a disparar </FONT></I>\r
+      aRetardoMisDir:     tTiempo;          <I><FONT COLOR="Navy">// Ratardo del arma antes de poder volver a disparar </FONT></I>\r
+      aRetardoLaserCont:  tTiempo;          <I><FONT COLOR="Navy">// Ratardo del arma antes de poder volver a disparar (contador) </FONT></I>\r
+      aRetardoMisilCont:  tTiempo;          <I><FONT COLOR="Navy">// Ratardo del arma antes de poder volver a disparar (contador) </FONT></I>\r
+      aRetardoMisDirCont: tTiempo;          <I><FONT COLOR="Navy">// Ratardo del arma antes de poder volver a disparar (contador) </FONT></I>\r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Setea la velocidad máxima}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mSetVelMax">mSetVelMax</A>( velMax: tLongitud ): cNave; \r
+      <I><FONT COLOR="Navy">{** Resta un misil}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mRestarMisil">mRestarMisil</A>: cNave; \r
+      <I><FONT COLOR="Navy">{** Resta un misil dirigido}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mRestarMisilDirigido">mRestarMisilDirigido</A>: cNave; \r
+      <I><FONT COLOR="Navy">{** Devuelve true si todavía tiene misiles}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mTieneMisil">mTieneMisil</A>: boolean; \r
+      <I><FONT COLOR="Navy">{** Devuelve true si todavía tiene misiles dirigidos}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mTieneMisilDirigido">mTieneMisilDirigido</A>: boolean; \r
+      <I><FONT COLOR="Navy">{** Resetea el contador del retardo del láser}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNave.mRetardarLaser">mRetardarLaser</A>; \r
+      <I><FONT COLOR="Navy">{** Resetea el contador del retardo del misil}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNave.mRetardarMisil">mRetardarMisil</A>; \r
+      <I><FONT COLOR="Navy">{** Resetea el contador del retardo del misil dirigido}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNave.mRetardarMisDir">mRetardarMisDir</A>; \r
+      <I><FONT COLOR="Navy">{** Actualiza los retardadores}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNave.mActualizarRetardadores">mActualizarRetardadores</A>( dT: tTiempo ); \r
+      <I><FONT COLOR="Navy">{** Crea un laser (actualizando retardos y todo lo que sea necesario)}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mCrearLaserDisparado">mCrearLaserDisparado</A>: cLaser; \r
+      <I><FONT COLOR="Navy">{** Crea un misil (actualizando retardos y todo lo que sea necesario)}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mCrearMisilDisparado">mCrearMisilDisparado</A>: cMisil; \r
+      <I><FONT COLOR="Navy">{** Crea un misil dirigido (actualizando retardos y todo lo que sea necesario)}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mCrearMisDirDisparado">mCrearMisDirDisparado</A>( ov : cObjetoVolador ): cMisilDirigido; \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( pos: cVector = <B>nil</B>; vel: cVector = <B>nil</B>; dim: tLongitud = 5; \r
+                          pot: tEnergia = 1; ene: tEnergia = 100; misiles: tMaxMisil = 0; \r
+                          misilesDirigidos: tMaxMisilDirigido = 0; velMax: tLongitud = 0.2; \r
+                          retardoLaser:   tTiempo = 1000;  <I><FONT COLOR="Navy">{1 segundo}</FONT></I> \r
+                          retardoMisil:  tTiempo = 60000; <I><FONT COLOR="Navy">{1 minuto}</FONT></I> \r
+                          retardoMisDir: tTiempo = 180000 <I><FONT COLOR="Navy">{3 minutos}</FONT></I>); overload; \r
+      <I><FONT COLOR="Navy">{** Hace que se dispare un arma (todavía no está implementado), devolviendo la nueva \r
+          municion disparada}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mDisparar">mDisparar</A>( dT: tTiempo; ov : cObjetoVolador = <B>nil</B> ): cArma; <B>virtual</B>; \r
+      <I><FONT COLOR="Navy">{** Obtiene la cantidad de Misiles que le quedan a la nave}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mGetMisiles">mGetMisiles</A>: tMaxMisil; \r
+      <I><FONT COLOR="Navy">{** Obtiene la cantidad de Misiles Dirigidos que le quedan a la nave}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mGetMisilesDirigidos">mGetMisilesDirigidos</A>: tMaxMisilDirigido; \r
+      <I><FONT COLOR="Navy">{** Obtiene la velocidad máxima}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mGetVelMax">mGetVelMax</A>: tLongitud; \r
+      <I><FONT COLOR="Navy">{** Método para establecer la velocidad}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mSetVelocidad">mSetVelocidad</A>( velocidad: cVector ): cObjetoVolador; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Método para establecer el modulo de la velocidad}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mSetVelModulo">mSetVelModulo</A>( velocidad: tLongitud ): cObjetoVolador; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Chequea que el enemigo este a distancia, que tenga municiones, etc.}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mPuedeDispararLaser">mPuedeDispararLaser</A>( ov : cObjetoVolador ): boolean; \r
+      <I><FONT COLOR="Navy">{** Chequea que el enemigo este a distancia, que tenga municiones, etc.}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mPuedeDispararMisil">mPuedeDispararMisil</A>( ov : cObjetoVolador ): boolean; \r
+      <I><FONT COLOR="Navy">{** Chequea que el enemigo este a distancia, que tenga municiones, etc.}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mPuedeDispararMisDir">mPuedeDispararMisDir</A>( ov : cObjetoVolador ): boolean; \r
+      <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar \r
+          y la información entregada depende del parámetro tDebugInfo.}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mGetDebugInfo">mGetDebugInfo</A>( debugLevel: tDebugInfo = DI_MINI ): <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+      <I><FONT COLOR="Navy">// SERIALIZACION </FONT></I>\r
+      <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.}</FONT></I> \r
+      <B>function</B> <A HREF="#cNave.mSerializar">mSerializar</A>: <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+          serializado.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNave.mDesSerializar">mDesSerializar</A>( str: <B>string</B> ); <B>override</B>; \r
+  <B>end</B>; \r
\r
+<B>implementation</B> \r
\r
+<B>uses</B> \r
+  RegExpr, \r
+  ObjetoPersistente, \r
+  Sysutils; \r
\r
+<I><FONT COLOR="Navy">{ cNave }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Constructor \r
+    @param pos              Posicion inicial \r
+    @param vel              Velocidad inicial \r
+    @param dim              Dimensión (radio, en metros) \r
+    @param pot              Potencia (cantidad de daño que hace por intervalode tiempo) \r
+    @param ene              Energía (cantidad de daño que soporta antes de ser destruido) \r
+    @param misiles          Cantidad de misiles comunes \r
+    @param misilesDirigidos Cantidad de misiles dirigidos \r
+    @param velMax           Velocidad máxima que puede alcanzar (modulo) \r
+    @param retardoLaser     Ratardo del arma antes de poder volver a disparar \r
+    @param retardoMisil     Ratardo del arma antes de poder volver a disparar \r
+    @param retardoMisDir    Ratardo del arma antes de poder volver a disparar}</FONT></I> \r
+<B>constructor</B> cNave.create(pos, vel: cVector; dim: tLongitud; pot, \r
+  ene: tEnergia; misiles: tMaxMisil; misilesDirigidos: tMaxMisilDirigido; \r
+  velMax: tLongitud; retardoLaser: tTiempo; retardoMisil: tTiempo; \r
+  retardoMisDir: tTiempo); \r
+<B>begin</B> \r
+  <B>if</B> vel <> <B>nil</B> <B>then</B> \r
+    <B>if</B> vel.mGetModulo > velMax <B>then</B> \r
+      vel.mSetModulo( velMax ); \r
+  <B>inherited</B> create( pos, vel, dim, pot, ene ); \r
+  aMisiles := misiles; \r
+  aMisilesDirigidos := misilesDirigidos; \r
+  aVelMaxima := velMax; \r
+  aRetardoLaser  := retardoLaser; \r
+  aRetardoMisil  := retardoMisil; \r
+  aRetardoMisDir := retardoMisDir; \r
+  aRetardoLaserCont  := 0; <I><FONT COLOR="Navy">// lista para disparar </FONT></I>\r
+  aRetardoMisilCont  := 0; <I><FONT COLOR="Navy">// lista para disparar </FONT></I>\r
+  aRetardoMisDirCont := 0; <I><FONT COLOR="Navy">// lista para disparar </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+<I><FONT COLOR="Navy">{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos. \r
+    @return            Cadena de texto con el estado del Objeto. \r
+    @param   debugLevel Cantidad de información requerida}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mGetDebugInfo>cNave.mGetDebugInfo</A>(debugLevel: tDebugInfo): <B>string</B>; \r
+<B>begin</B> \r
+  result := <B>inherited</B> mGetDebugInfo( debugLevel ); \r
+  <B>if</B> debugLevel > DI_MINI <B>then</B> \r
+    result := result + ' | Misiles: ' + IntToStr( aMisiles ) + \r
+              ' | Misiles Dirigidos: ' + IntToStr( aMisilesDirigidos ); \r
+<B>end</B>; \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Devuelve la velocidad máxima \r
+    @return Velocidad máxima (modulo)}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mGetVelMax>cNave.mGetVelMax</A>: tLongitud; \r
+<B>begin</B> \r
+  result := aVelMaxima; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Resta un misil}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mRestarMisil>cNave.mRestarMisil</A>: cNave; \r
+<B>begin</B> \r
+  aMisiles := aMisiles - 1; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Resta un misil dirigido}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mRestarMisilDirigido>cNave.mRestarMisilDirigido</A>: cNave; \r
+<B>begin</B> \r
+  aMisilesDirigidos := aMisilesDirigidos - 1; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Setea la velocidad máxima \r
+    @param velMax Nueva velocidad máxima (modulo)}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mSetVelMax>cNave.mSetVelMax</A>(velMax: tLongitud): cNave; \r
+<B>begin</B> \r
+  aVelMaxima := velMax; \r
+  result := self; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Chequea si todavía tiene misiles \r
+    @return <i>true</i> si tiene misiles, <i>false</i> si no}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mTieneMisil>cNave.mTieneMisil</A>: boolean; \r
+<B>begin</B> \r
+  result := ( aMisiles > 0 ); <I><FONT COLOR="Navy">// Devuelve true si aMisiles es mayor que cero </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Chequea si todavía tiene misiles dirigidos \r
+    @return <i>true</i> si tiene misiles dirigidos, <i>false</i> si no}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mTieneMisilDirigido>cNave.mTieneMisilDirigido</A>: boolean; \r
+<B>begin</B> \r
+  result := ( aMisilesDirigidos > 0 ); <I><FONT COLOR="Navy">// Devuelve true si aMisilesDirigidos es mayor que cero </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Chequea que el enemigo este a distancia, que tenga municiones, etc. \r
+    @param  np Nave Propia a la que quiere disparar \r
+    @return <i>True</i> si está todo ok, <i>False</i> si no.}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mPuedeDispararLaser>cNave.mPuedeDispararLaser</A>( ov : cObjetoVolador ): boolean; \r
+<B>begin</B> \r
+  result := false; \r
+  <B>if</B> aRetardoLaserCont <= 0 <B>then</B> <I><FONT COLOR="Navy">// Primero se fija que ya esté recargada el arma </FONT></I>\r
+    <I><FONT COLOR="Navy">// 1200 es el alcance del laser. </FONT></I>\r
+    <B>if</B> ov <> <B>nil</B> <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si el ov es nil puede disparar, ni no lo es, chequea la distancia </FONT></I>\r
+      <B>if</B> mGetDistancia( ov ) < 1200 <B>then</B><I><FONT COLOR="Navy">// Si la distancia a la np es menor que el alcance </FONT></I>\r
+        result := true; \r
+    <B>end</B> <B>else</B> \r
+      result := true; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Chequea que el enemigo este a distancia, que tenga municiones, etc. \r
+    @param  np Nave Propia a la que quiere disparar \r
+    @return <i>True</i> si está todo ok, <i>False</i> si no.}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mPuedeDispararMisil>cNave.mPuedeDispararMisil</A>( ov : cObjetoVolador ): boolean; \r
+<B>begin</B> \r
+  result := false; \r
+  <I><FONT COLOR="Navy">// Primero se fija que ya esté recargada el arma y que todavia tenga municiones </FONT></I>\r
+  <B>if</B> mTieneMisil <B>and</B> ( aRetardoMisilCont <= 0 ) <B>then</B> \r
+    <I><FONT COLOR="Navy">// 1500 es el alcance del misil. </FONT></I>\r
+    <B>if</B> ov <> <B>nil</B> <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si el ov es nil puede disparar, ni no lo es, chequea la distancia </FONT></I>\r
+      <B>if</B> mGetDistancia( ov ) < 1500 <B>then</B><I><FONT COLOR="Navy">// Si la distancia a la np es menor que el alcance </FONT></I>\r
+        result := true; \r
+    <B>end</B> <B>else</B> \r
+      result := true; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Chequea que el enemigo este a distancia, que tenga municiones, etc. \r
+    @param  np Nave Propia a la que quiere disparar \r
+    @return <i>True</i> si está todo ok, <i>False</i> si no.}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mPuedeDispararMisDir>cNave.mPuedeDispararMisDir</A>( ov : cObjetoVolador ): boolean; \r
+<B>begin</B> \r
+  result := false; \r
+  <I><FONT COLOR="Navy">// Primero se fija que ya esté recargada el arma y que todavia tenga municiones </FONT></I>\r
+  <B>if</B> mTieneMisilDirigido <B>and</B> ( aRetardoMisDirCont <= 0 ) <B>then</B> \r
+    <I><FONT COLOR="Navy">// 2000 es el alcance del misil dirigido. </FONT></I>\r
+    <B>if</B> ov <> <B>nil</B> <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si el ov es nil puede disparar, ni no lo es, chequea la distancia </FONT></I>\r
+      <B>if</B> mGetDistancia( ov ) < 2000 <B>then</B><I><FONT COLOR="Navy">// Si la distancia a la np es menor que el alcance </FONT></I>\r
+        result := true; \r
+    <B>end</B> <B>else</B> \r
+      result := true; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Hace que se dispare un arma \r
+    @param  ov Objetivo del disparo \r
+    @param  dT Intervalo de tiempo \r
+    @return Arma disparada (o <i>nil</i> si no se puede disparar ningún arma)}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mDisparar>cNave.mDisparar</A>( dT: tTiempo; ov : cObjetoVolador ): cArma; \r
+<B>begin</B> \r
+  result := <B>nil</B>; <I><FONT COLOR="Navy">// devuelve nil por defecto </FONT></I>\r
+  mActualizarRetardadores( dT ); \r
+  <B>if</B> mPuedeDispararMisDir( ov ) <B>then</B> \r
+    result := mCrearMisDirDisparado( ov ) \r
+  <B>else</B> <B>if</B> mPuedeDispararMisil( ov ) <B>then</B> \r
+    result := mCrearMisilDisparado \r
+  <B>else</B> <B>if</B> mPuedeDispararLaser( ov ) <B>then</B> \r
+    result := mCrearLaserDisparado; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la cantidad de Misiles que le quedan a la nave \r
+    return Cantidad de misiles que le quedan a la nave}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mGetMisiles>cNave.mGetMisiles</A>: tMaxMisil; \r
+<B>begin</B> \r
+  result := aMisiles; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la cantidad de Misiles que le quedan a la nave \r
+    return Cantidad de misiles dirigidos que le quedan a la nave}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mGetMisilesDirigidos>cNave.mGetMisilesDirigidos</A>: tMaxMisilDirigido; \r
+<B>begin</B> \r
+  result := aMisilesDirigidos; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Resetea el contador del retardo del láser}</FONT></I> \r
+<B>procedure</B> <A NAME=cNave.mRetardarLaser>cNave.mRetardarLaser</A>; \r
+<B>begin</B> \r
+  aRetardoLaserCont := aRetardoLaser; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Resetea el contador del retardo del misil dirigido}</FONT></I> \r
+<B>procedure</B> <A NAME=cNave.mRetardarMisDir>cNave.mRetardarMisDir</A>; \r
+<B>begin</B> \r
+  aRetardoMisDirCont := aRetardoMisDir; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Resetea el contador del retardo del misil}</FONT></I> \r
+<B>procedure</B> <A NAME=cNave.mRetardarMisil>cNave.mRetardarMisil</A>; \r
+<B>begin</B> \r
+  aRetardoMisilCont := aRetardoMisil; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Actualiza los retardadores \r
+    @param dT Intervalo de tiempo a restarles}</FONT></I> \r
+<B>procedure</B> <A NAME=cNave.mActualizarRetardadores>cNave.mActualizarRetardadores</A>(dT: tTiempo); \r
+<B>begin</B> \r
+  <B>if</B> aRetardoMisDirCont > 0 <B>then</B> \r
+    aRetardoMisDirCont := aRetardoMisDirCont - dT; \r
+  <B>if</B> aRetardoMisilCont > 0 <B>then</B> \r
+    aRetardoMisilCont := aRetardoMisilCont - dT; \r
+  <B>if</B> aRetardoLaserCont > 0 <B>then</B> \r
+    aRetardoLaserCont := aRetardoLaserCont - dT; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Crea un láser (actualizando retardos) \r
+    @return Nuevo láser}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mCrearLaserDisparado>cNave.mCrearLaserDisparado</A>: cLaser; \r
+<B>var</B> \r
+  pos, \r
+  vel, \r
+  vec: cVector; \r
+<B>begin</B> \r
+    mRetardarLaser; <I><FONT COLOR="Navy">// Resetea el retardo </FONT></I>\r
+    <I><FONT COLOR="Navy">// Se calcula la posicion a partir de la posicion de la nave propia y sumandole el 150% de </FONT></I>\r
+    <I><FONT COLOR="Navy">// su tamaño en la direccion de i (para que no colisione con quien dispara). </FONT></I>\r
+    vec := mGetI.mMultiplicar( mGetDimension * 1.5 ); \r
+    pos := mGetPosicion.mSumar( vec ); \r
+    <I><FONT COLOR="Navy">// vec tambien me va a servir como la dirección de la velocidad porque tiene la direccion de i </FONT></I>\r
+    vel := vec; \r
+    <I><FONT COLOR="Navy">// devuelve el arma disparada </FONT></I>\r
+    result := cLaser.create( pos, vel ); \r
+    <I><FONT COLOR="Navy">// Libera memoria </FONT></I>\r
+    pos.free; \r
+    vec.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Crea un misil dirigido (actualizando retardos y restando un misil dirigido) \r
+    @param  ov Objetivo del misil dirigido \r
+    @return Nuevo misil dirigido}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mCrearMisDirDisparado>cNave.mCrearMisDirDisparado</A>( ov : cObjetoVolador ): cMisilDirigido; \r
+<B>var</B> \r
+  pos, \r
+  vec: cVector; \r
+<B>begin</B> \r
+    mRestarMisilDirigido; \r
+    mRetardarMisDir; <I><FONT COLOR="Navy">// Resetea el retardo </FONT></I>\r
+    <I><FONT COLOR="Navy">// Se calcula la posicion a partir de la posicion de la nave propia y sumandole el 150% de </FONT></I>\r
+    <I><FONT COLOR="Navy">// su tamaño en la direccion de i (para que no colisione con quien dispara) </FONT></I>\r
+    vec := mGetI.mMultiplicar( mGetDimension * 1.5 ); \r
+    pos := mGetPosicion.mSumar( vec ); \r
+    <I><FONT COLOR="Navy">// devuelve el arma disparada </FONT></I>\r
+    result := cMisilDirigido.create( ov, pos ); \r
+    <I><FONT COLOR="Navy">// Libera memoria </FONT></I>\r
+    pos.free; \r
+    vec.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Crea un misil dirigido (actualizando retardos y restando un misil) \r
+    @return Nuevo misil}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mCrearMisilDisparado>cNave.mCrearMisilDisparado</A>: cMisil; \r
+<B>var</B> \r
+  pos, \r
+  vel, \r
+  vec: cVector; \r
+<B>begin</B> \r
+    mRestarMisil;   <I><FONT COLOR="Navy">// Resta un misil </FONT></I>\r
+    mRetardarMisil; <I><FONT COLOR="Navy">// Resetea el retardo </FONT></I>\r
+    <I><FONT COLOR="Navy">// Se calcula la posicion a partir de la posicion de la nave propia y sumandole el 150% de </FONT></I>\r
+    <I><FONT COLOR="Navy">// su tamaño en la direccion de i (para que no colisione con quien dispara) </FONT></I>\r
+    vec := mGetI.mMultiplicar( mGetDimension * 1.5 ); \r
+    pos := mGetPosicion.mSumar( vec ); \r
+    <I><FONT COLOR="Navy">// vec tambien me va a servir como la dirección de la velocidad porque tiene la direccion de i </FONT></I>\r
+    vel := vec; \r
+    <I><FONT COLOR="Navy">// devuelve el arma disparada </FONT></I>\r
+    result := cMisil.create( pos, vel ); \r
+    <I><FONT COLOR="Navy">// Libera memoria </FONT></I>\r
+    pos.free; \r
+    vec.free \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+    serializado. \r
+    @param str Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>procedure</B> <A NAME=cNave.mDesSerializar>cNave.mDesSerializar</A>(str: <B>string</B>); \r
+<B>var</B> \r
+  r: TRegExpr; \r
+<B>begin</B> \r
+  <B>inherited</B> mDesSerializar( str ); <I><FONT COLOR="Navy">// SIEMPRE el ID debe ser el PRIMER atributo </FONT></I>\r
+  r := TRegExpr.create; \r
+  <I><FONT COLOR="Navy">// MISILES </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<misiles>/s*(/d+)/s*</misiles>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aMisiles := StrToInt( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro la cantidad de misiles' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer la cantidad de misiles utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// MISILESDIRIGIDOS </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<misilesdirigidos>/s*(/d+)/s*</misilesdirigidos>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aMisilesDirigidos := StrToInt( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro la cantidad de misiles dirigidos' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer la cantidad de misiles dirigidos utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// VELMAXIMA </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<velmaxima>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</velmaxima>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aVelMaxima := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro la velocidad maxima' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer la velocidad maxima utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// RETARDOLASER </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<retardolaser>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</retardolaser>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aRetardoLaser := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el retardo del laser' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el retardo del laser utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// RETARDOMISIL </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<retardomisil>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</retardomisil>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aRetardoMisil := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el retardo del misil' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el retardo del misil utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// RETARDOMISDIR </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<retardomisdir>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</retardomisdir>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aRetardoMisDir := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el retardo del misil dirigido' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el retardo del misil dirigido utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// RETARDOLASERCONT </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<retardolasercont>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</retardolasercont>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aRetardoLaserCont := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el contador del retardo del laser' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el contador del retardo del laser utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// RETARDOMISIL </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<retardomisilcont>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</retardomisilcont>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aRetardoMisilCont := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el contador del retardo del misil' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el contador del retardo del misil utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// RETARDOMISDIR </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<retardomisdircont>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</retardomisdircont>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aRetardoMisDirCont := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el contador del retardo del misil dirigido' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el contador del retardo del misil dirigido utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  r.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado. \r
+    @return Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mSerializar>cNave.mSerializar</A>: <B>string</B>; \r
+<B>begin</B> \r
+  result := <B>inherited</B> mSerializar + \r
+            '<misiles>' + IntToStr( aMisiles ) + '</misiles>' + \r
+            '<misilesdirigidos>' + IntToStr( aMisilesDirigidos ) + '</misilesdirigidos>' + \r
+            '<velmaxima>' + FloatToStrF( aVelMaxima, ffGeneral, 18, 0 ) + '</velmaxima>' + \r
+            '<retardolaser>' + FloatToStrF( aRetardoLaser, ffGeneral, 18, 0 ) + '</retardolaser>' + \r
+            '<retardomisil>' + FloatToStrF( aRetardoMisil, ffGeneral, 18, 0 ) + '</retardomisil>' + \r
+            '<retardomisdir>' + FloatToStrF( aRetardoMisDir, ffGeneral, 18, 0 ) + '</retardomisdir>' + \r
+            '<retardolasercont>' + FloatToStrF( aRetardoLaserCont, ffGeneral, 18, 0 ) + '</retardolasercont>' + \r
+            '<retardomisilcont>' + FloatToStrF( aRetardoMisilCont, ffGeneral, 18, 0 ) + '</retardomisilcont>' + \r
+            '<retardomisdircont>' + FloatToStrF( aRetardoMisDirCont, ffGeneral, 18, 0 ) + '</retardomisdircont>'; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método para establecer la velocidad}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mSetVelModulo>cNave.mSetVelModulo</A>(velocidad: tLongitud): cObjetoVolador; \r
+<B>begin</B> \r
+  <B>if</B> velocidad > aVelMaxima <B>then</B> \r
+    velocidad := aVelMaxima; \r
+  result := <B>inherited</B> mSetVelModulo( velocidad ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método para establecer el modulo de la velocidad}</FONT></I> \r
+<B>function</B> <A NAME=cNave.mSetVelocidad>cNave.mSetVelocidad</A>(velocidad: cVector): cObjetoVolador; \r
+<B>begin</B> \r
+  <B>if</B> velocidad.mGetModulo > aVelMaxima <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si sobrepasa el limite ... </FONT></I>\r
+    mSetVelModulo( aVelMaxima ); <I><FONT COLOR="Navy">// Se le asigna el modulo como limite </FONT></I>\r
+    mSetVelDir( velocidad );     <I><FONT COLOR="Navy">// Se le asigna la direccion </FONT></I>\r
+    result := self; \r
+  <B>end</B> <B>else</B> <I><FONT COLOR="Navy">// Si no sobrepasa el limite ... </FONT></I>\r
+    result := <B>inherited</B> mSetVelocidad( velocidad ); <I><FONT COLOR="Navy">// Se asigna la nueva vel </FONT></I>\r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/modelo/ov/naves/NaveEnemiga.pas b/doc/src-html/modelo/ov/naves/NaveEnemiga.pas
new file mode 100644 (file)
index 0000000..ea2ccec
--- /dev/null
@@ -0,0 +1,195 @@
+<HTML><HEAD>\r
+<TITLE>File: naveenemiga.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=naveenemiga.pas><CENTER><H3>naveenemiga.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** La clase cNaveEnemiga esta pensada como una clase abtracta. En ella se encuentran \r
+    características comunes a todas las naves enemigas.<br> \r
+      <i>Cambios:</i> \r
+    <PRE> \r
+    05/10/00: Se cambio el metodo mGetRadar por el metodo mDetectado, que devuelve true \r
+              si un objeto volador esta destro del campo de radar. De esta manera se logra \r
+              una abstracción mayor y un manejo mas intuitivo del radar. \r
+    </PRE>}</FONT></I> \r
+<B>unit</B> NaveEnemiga; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  Tipos, \r
+  Vectores, \r
+  Nave, \r
+  NavePropia, \r
+  ObjetoVolador, \r
+  Armas; \r
\r
+<B>type</B> \r
+  <I><FONT COLOR="Navy">{** La clase cNaveEnemiga esta pensada como una clase abtracta. En ella se encuentran \r
+      características comunes a todas las naves enemigas.}</FONT></I> \r
+  cNaveEnemiga = <B>class</B>( cNave ) \r
+    <B>private</B> \r
+      aCampoRadar: tLongitud; <I><FONT COLOR="Navy">// Area en la que detecta a la nave propia </FONT></I>\r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Modifica la velocidad de la nave en base a la nave propia}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNaveEnemiga.mModificarVelocidad">mModificarVelocidad</A>( np: cNavePropia; modulo: tLongitud = -1 ); <B>virtual</B>; \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( pos: cVector = <B>nil</B>; vel: cVector = <B>nil</B>; dim: tLongitud = 10; \r
+                          pot: tEnergia = 100; ene: tEnergia = 100; misiles: tMaxMisil = 0; \r
+                          misilesDirigidos: tMaxMisilDirigido = 0; velMax: tLongitud = 0.2; \r
+                          radar : tLongitud = 2500; \r
+                          retardoLaser:   tTiempo = 1000;   <I><FONT COLOR="Navy">{1 segundo}</FONT></I> \r
+                          retardoMisil:  tTiempo = 60000;  <I><FONT COLOR="Navy">{1 minuto}</FONT></I> \r
+                          retardoMisDir: tTiempo = 180000 <I><FONT COLOR="Navy">{3 minutos}</FONT></I>); overload; \r
+      <I><FONT COLOR="Navy">{** Hace reaccionar ante la presencia de la nave propia. Tiene un comportamiento polimófico ya que cada nave \r
+          enemiga reaccionará de forma diferente (método abstracto)}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNaveEnemiga.mReaccionar">mReaccionar</A>( np: cNavePropia ); <B>virtual</B>; <B>abstract</B>; \r
+      <I><FONT COLOR="Navy">{** Indica si ov esta en el campo de radar}</FONT></I> \r
+      <B>function</B> <A HREF="#cNaveEnemiga.mDetectado">mDetectado</A>( ov: cObjetoVolador ): boolean; \r
+      <I><FONT COLOR="Navy">{** Hace que la nave se dirija a una posicion particular}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNaveEnemiga.mIrA">mIrA</A>( pos: cVector ); \r
+      <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar \r
+          y la información entregada depende del parámetro tDebugInfo.}</FONT></I> \r
+      <B>function</B> <A HREF="#cNaveEnemiga.mGetDebugInfo">mGetDebugInfo</A>( debugLevel: tDebugInfo = DI_MINI ): <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+      <I><FONT COLOR="Navy">// SERIALIZACION </FONT></I>\r
+      <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.}</FONT></I> \r
+      <B>function</B> <A HREF="#cNaveEnemiga.mSerializar">mSerializar</A>: <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+          serializado.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNaveEnemiga.mDesSerializar">mDesSerializar</A>( str: <B>string</B> ); <B>override</B>; \r
+  <B>end</B>; \r
\r
+<B>implementation</B> \r
\r
+<B>uses</B> \r
+  RegExpr, \r
+  ObjetoPersistente, \r
+  Sysutils; \r
\r
+<I><FONT COLOR="Navy">{ cNaveEnemiga }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Constructor \r
+    @param pos              Posicion inicial \r
+    @param vel              Velocidad inicial \r
+    @param dim              Dimensión (radio, en metros) \r
+    @param pot              Potencia (cantidad de daño que hace por intervalode tiempo) \r
+    @param ene              Energía (cantidad de daño que soporta antes de ser destruido) \r
+    @param misiles          Cantidad de misiles comunes \r
+    @param misilesDirigidos Cantidad de misiles dirigidos \r
+    @param velMax           Velocidad máxima que puede alcanzar (modulo) \r
+    @param radar            Área máxima en la que puede detectar a otras naves (radio, en metros) \r
+    @param retardoLaser     Ratardo del arma antes de poder volver a disparar \r
+    @param retardoMisil     Ratardo del arma antes de poder volver a disparar \r
+    @param retardoMisDir    Ratardo del arma antes de poder volver a disparar}</FONT></I> \r
+<B>constructor</B> cNaveEnemiga.create(pos, vel: cVector; dim: tLongitud; pot, \r
+  ene: tEnergia; misiles: tMaxMisil; misilesDirigidos: tMaxMisilDirigido; \r
+  velMax: tLongitud; radar: tLongitud; retardoLaser, retardoMisil, \r
+  retardoMisDir: tTiempo); \r
+<B>begin</B> \r
+  <B>inherited</B> create( pos , vel , dim , pot , ene , misiles, misilesDirigidos, \r
+                    velMax, retardoLaser, retardoMisil, retardoMisDir ); \r
+  aCampoRadar := radar; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Modifica la velocidad de la nave en base a la nave propia \r
+    @param np     Nave propia con la cual se calculará la dirección de la nueva velocidad \r
+    @param modulo Nuevo módulo de la velocidad}</FONT></I> \r
+<B>procedure</B> <A NAME=cNaveEnemiga.mModificarVelocidad>cNaveEnemiga.mModificarVelocidad</A>( np: cNavePropia; modulo: tLongitud ); \r
+<B>var</B> \r
+  vel,        <I><FONT COLOR="Navy">// Vector temporal para hacer calculos </FONT></I>\r
+  pos: cVector; <I><FONT COLOR="Navy">// Vector temporal para hacer calculos </FONT></I>\r
+<B>begin</B> \r
+  <B>if</B> (modulo < 0) <B>or</B> (modulo > mGetVelMax) <B>then</B> \r
+    modulo := mGetVelMax; \r
+  pos := mGetPosicion; \r
+  <I><FONT COLOR="Navy">// Crea un nuevo verctor basado en la posicion del objetivo, </FONT></I>\r
+  <I><FONT COLOR="Navy">//  Le resta la posicion propia, obteniendo la nueva direccion de la velocidad </FONT></I>\r
+  <I><FONT COLOR="Navy">//  y luego setea el modulo </FONT></I>\r
+  vel := np.mGetPosicion.mRestar( pos ); \r
+  <I><FONT COLOR="Navy">// Modifica la velocidad basado en el vector v </FONT></I>\r
+  mSetVelDir( vel ); \r
+  mSetVelModulo( modulo ); \r
+  vel.free; <I><FONT COLOR="Navy">// libera la memoria del vector temporal </FONT></I>\r
+  pos.free; <I><FONT COLOR="Navy">// libera la memoria del vector temporal </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Indica si ov esta en el campo de radar \r
+    @param ov Objeto volador a chequear si está dentro del alcance del radar}</FONT></I> \r
+<B>function</B> <A NAME=cNaveEnemiga.mDetectado>cNaveEnemiga.mDetectado</A>( ov: cObjetoVolador ): boolean; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// true si la distancia es menor que el campo de radar </FONT></I>\r
+  result := ( mGetDistancia( ov ) <= aCampoRadar ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Hace que la nave se dirija a una posicion particular \r
+    @param pos Vector posición del punto al cual se dirigirá la nave}</FONT></I> \r
+<B>procedure</B> <A NAME=cNaveEnemiga.mIrA>cNaveEnemiga.mIrA</A>(pos: cVector); \r
+<B>var</B> \r
+  v: cVector;        <I><FONT COLOR="Navy">// Vector temporal para hacer calculos </FONT></I>\r
+  modulo: tLongitud; <I><FONT COLOR="Navy">// Modulo actual de la velocidad </FONT></I>\r
+<B>begin</B> \r
+  v := mGetVelocidad; \r
+  modulo := v.mGetModulo; <I><FONT COLOR="Navy">// Obtiene el modulo actual de la velocidad </FONT></I>\r
+  v.free; \r
+  <I><FONT COLOR="Navy">// Crea un nuevo verctor basado en la posicion y e resta la posicion propia, </FONT></I>\r
+  <I><FONT COLOR="Navy">//  obteniendo la nueva direccion de la velocidad. </FONT></I>\r
+  v := cVector.create( pos ).mRestar( mGetPosicion ); \r
+  mSetVelDir( v ); <I><FONT COLOR="Navy">// Modifica la direccion de la velocidad basado en el vector v </FONT></I>\r
+  mSetVelModulo( modulo ); <I><FONT COLOR="Navy">// Setea el modulo igual que el de la velocidad original </FONT></I>\r
+  v.free; <I><FONT COLOR="Navy">// libera la memoria del vector temporal </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+<I><FONT COLOR="Navy">{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos. \r
+    @return            Cadena de texto con el estado del Objeto. \r
+    @param   debugLevel Cantidad de información requerida}</FONT></I> \r
+<B>function</B> <A NAME=cNaveEnemiga.mGetDebugInfo>cNaveEnemiga.mGetDebugInfo</A>(debugLevel: tDebugInfo): <B>string</B>; \r
+<B>begin</B> \r
+  result := <B>inherited</B> mGetDebugInfo( debugLevel ); \r
+  <B>if</B> debugLevel > DI_NORMAL <B>then</B> \r
+    result := result + ' | Campo de Radar: ' + FloatToStrF( aCampoRadar, ffNumber, 5, 5 ); \r
+<B>end</B>; \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+    serializado. \r
+    @param str Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>procedure</B> <A NAME=cNaveEnemiga.mDesSerializar>cNaveEnemiga.mDesSerializar</A>(str: <B>string</B>); \r
+<B>var</B> \r
+  r: TRegExpr; \r
+<B>begin</B> \r
+  <B>inherited</B> mDesSerializar( str ); <I><FONT COLOR="Navy">// SIEMPRE el ID debe ser el PRIMER atributo </FONT></I>\r
+  r := TRegExpr.create; \r
+  <I><FONT COLOR="Navy">// CAMPORADAR </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<camporadar>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</camporadar>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aCampoRadar := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el campo de radar' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el campo de radar utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  r.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado. \r
+    @return Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>function</B> <A NAME=cNaveEnemiga.mSerializar>cNaveEnemiga.mSerializar</A>: <B>string</B>; \r
+<B>begin</B> \r
+  result := <B>inherited</B> mSerializar + \r
+            '<camporadar>' + FloatToStrF( aCampoRadar, ffGeneral, 18, 0 ) + '</camporadar>'; \r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/modelo/ov/naves/NavePropia.pas b/doc/src-html/modelo/ov/naves/NavePropia.pas
new file mode 100644 (file)
index 0000000..d7b2104
--- /dev/null
@@ -0,0 +1,477 @@
+<HTML><HEAD>\r
+<TITLE>File: navepropia.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=navepropia.pas><CENTER><H3>navepropia.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Es la nave que será controlada por el jugador.<br> \r
+    <i>Cambios:</i> \r
+    <PRE> \r
+    05/10/00: Se corrigió el método mAcelerar porque tenía algunos bugs cuando la velocidad llegaba a cero. \r
+    01/12/00: Se implementan los disparon sobreescribiendo el método mDisparar de cNave y agregando algunos \r
+              atributos (aArmaSelect, aDisparando y aLockeado) y algunos métodos (mIntentarDisparo, \r
+              mSeleccionarArma, mSeleccionarArmaSig, mGetArmaSelect, mSetLockeado, mGetLockeado). \r
+              Se cambiaron las dimensiones de la nave para que los disparos sean mas "jugables". \r
+              Se cambia el orden de los argumentos de mDisparar para aprovechar los argumentos por defecto. \r
+              Se arreglaron un par de BUGs con punteros que apuntaba a objetos destruidos (aLockeado). \r
+    08/12/00: Se arregló una falla en el constructor que permitia crear la nave con una velocidad superior \r
+              a la máxima. \r
+    09/12/00: Se cambia el atributo disparando por un puntero a un arma que se disparara en el proximo turno. \r
+              También se cambia los métodos que lo utilizan y en particular se convierte el método \r
+              mIntentarDisparo en una función que devuelve dicho puntero para implementar la cámara en el arma. \r
+    </PRE>}</FONT></I> \r
+<B>unit</B> NavePropia; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  Tipos, \r
+  Vectores, \r
+  Nave, \r
+  ObjetoVolador, \r
+  Meteorito, \r
+  Coordenadas, \r
+  Classes, \r
+  Filtros, \r
+  Armas; \r
\r
+<B>type</B> \r
+  <I><FONT COLOR="Navy">{** Es la nave que será controlada por el jugador. \r
+      <u>Características:</u> \r
+      <PRE> \r
+      Dimensión:            15        metros \r
+      Potencia:             5         Cantidad de daño que hace por intervalo de tiempo \r
+      Energía:              100       Cantidad de daño que soporta antes de ser destruída \r
+      Velocidad máxima:     0,17      metros/milisegundos (612 km/h) \r
+      Misiles:              10 \r
+      Misiles Dirigidos:    5 \r
+      </PRE>}</FONT></I> \r
+  cNavePropia = <B>class</B>( cNave ) \r
+    <B>private</B> \r
+      aLockeado:   cObjetoVolador; <I><FONT COLOR="Navy">// Objeto Volador Lockeado </FONT></I>\r
+      aArmaSelec:  tArma;          <I><FONT COLOR="Navy">// Arma seleccionada por el usuario </FONT></I>\r
+      aDisparando: cArma;          <I><FONT COLOR="Navy">// Indica si en este momento se esta disparando o no </FONT></I>\r
+      aLockFiltro: cFiltroLock;    <I><FONT COLOR="Navy">// Filtro para saber que objetos voladores se puede lockear </FONT></I>\r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Crea una nave controlada por un jugador}</FONT></I> \r
+      <B>constructor</B> create( pos: cVector = <B>nil</B>; vel: cVector = <B>nil</B> ); overload; \r
+      <I><FONT COLOR="Navy">{** Hace que se dispare un arma (todavía no está implementado)}</FONT></I> \r
+      <B>function</B> <A HREF="#cNavePropia.mDisparar">mDisparar</A>( dT: tTiempo; ov : cObjetoVolador = <B>nil</B> ): cArma; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Obtiene el objetivo lockeado}</FONT></I> \r
+      <B>function</B> <A HREF="#cNavePropia.mGetLockeado">mGetLockeado</A>: cObjetoVolador; \r
+      <I><FONT COLOR="Navy">{** Setea el objetivo lockeado}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNavePropia.mSetLockeado">mSetLockeado</A>( ov: cObjetoVolador ); \r
+      <I><FONT COLOR="Navy">{** Cambia el objetivo lockeado}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNavePropia.mCambiarLockeado">mCambiarLockeado</A>( lEnemigos: TList ); \r
+      <I><FONT COLOR="Navy">{** Permite a la nave rotar a la izquierda sobre su eje X}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNavePropia.mRotarIzquierda">mRotarIzquierda</A>( angulo: tAngulo ); \r
+      <I><FONT COLOR="Navy">{** Permite a la nave rotar a la derecha sobre su eje X}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNavePropia.mRotarDerecha">mRotarDerecha</A>( angulo: tAngulo ); \r
+      <I><FONT COLOR="Navy">{** Permite a la nave girar hacia la izquierda (sobre su eje Z)}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNavePropia.mGirarIzquierda">mGirarIzquierda</A>( angulo: tAngulo ); \r
+      <I><FONT COLOR="Navy">{** Permite a la nave girar hacia la derecha (sobre su eje Z)}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNavePropia.mGirarDerecha">mGirarDerecha</A>( angulo: tAngulo ); \r
+      <I><FONT COLOR="Navy">{** Permite a la nave girar hacia arriba (sobre su eje Y)}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNavePropia.mGirarArriba">mGirarArriba</A>( angulo: tAngulo ); \r
+      <I><FONT COLOR="Navy">{** Permite a la nave girar hacia abajo (sobre su eje Y)}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNavePropia.mGirarAbajo">mGirarAbajo</A>( angulo: tAngulo ); \r
+      <I><FONT COLOR="Navy">{** Aumenta el modulo de la velocidad (sin cambiar su dirección ni \r
+          sentido y sin sobrepasar la velocidad maxima)}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNavePropia.mAcelerar">mAcelerar</A>( modulo: tLongitud ); \r
+      <I><FONT COLOR="Navy">{** Disminuye el modulo de la velocidad (sin cambiar su dirección ni sentido)}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNavePropia.mDesacelerar">mDesacelerar</A>( modulo: tLongitud ); \r
+      <I><FONT COLOR="Navy">{** Intenta disparar. Si las condiciones son las correctas, el proximo turno \r
+          saldrá el disparo, si no, no hace nada}</FONT></I> \r
+      <B>function</B> <A HREF="#cNavePropia.mIntentarDisparo">mIntentarDisparo</A>: cArma; \r
+      <I><FONT COLOR="Navy">{** Selecciona un arma determinada. Si tiene municiones, la selecciona, si no, \r
+          no hace nada.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNavePropia.mSeleccionarArma">mSeleccionarArma</A>( a: tArma ); \r
+      <I><FONT COLOR="Navy">{** Selecciona el proximo arma con municiones}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNavePropia.mSeleccionarArmaSig">mSeleccionarArmaSig</A>; \r
+      <I><FONT COLOR="Navy">{** Obtiene el arma seleccionada actualmente}</FONT></I> \r
+      <B>function</B> <A HREF="#cNavePropia.mGetArmaSelec">mGetArmaSelec</A>: tArma; \r
+      <I><FONT COLOR="Navy">{** Obtiene un puntero a la último arma disparada}</FONT></I> \r
+      <B>function</B> <A HREF="#cNavePropia.mGetUltimoArmaDisparado">mGetUltimoArmaDisparado</A>: cArma; \r
+      <I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se dibuja de forma distinta}</FONT></I> \r
+      <B>function</B> <A HREF="#cNavePropia.mDibujar">mDibujar</A>: tObjetosVoladores; <B>override</B>; \r
+      <I><FONT COLOR="Navy">// SERIALIZACION </FONT></I>\r
+      <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.}</FONT></I> \r
+      <B>function</B> <A HREF="#cNavePropia.mSerializar">mSerializar</A>: <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+          serializado.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNavePropia.mDesSerializar">mDesSerializar</A>( str: <B>string</B> ); <B>override</B>; \r
+  <B>end</B>; \r
\r
+<B>implementation</B> \r
\r
+<B>uses</B> \r
+  RegExpr, \r
+  ObjetoPersistente, \r
+  SerializacionUtils, \r
+  Sysutils; \r
\r
+<I><FONT COLOR="Navy">{ cNavePropia }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** @param pos Posición Inicial \r
+    @param vel Velocidad Inicial}</FONT></I> \r
+<B>constructor</B> cNavePropia.create(pos: cVector; vel: cVector); \r
+<B>begin</B> \r
+  <B>if</B> vel <> <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no es nula la velocidad ... </FONT></I>\r
+    vel.mSetModulo( 0.17 ); <I><FONT COLOR="Navy">// Setea la velocidad como la máxima </FONT></I>\r
+  <I><FONT COLOR="Navy">// La dimensión es 15 m de radio, la potencia 5, la energía 100, tiene 10 misiles comunes, </FONT></I>\r
+  <I><FONT COLOR="Navy">//  5 dirigidos y su velocidad maxima es 0,17 m/mseg (612 km/h) </FONT></I>\r
+  <I><FONT COLOR="Navy">// El retardo del laser es de .5 segundos. </FONT></I>\r
+  <B>inherited</B> create( pos, vel, 15 <I><FONT COLOR="Navy">{dim}</FONT></I>, 5 <I><FONT COLOR="Navy">{pot}</FONT></I>, 100 <I><FONT COLOR="Navy">{ene}</FONT></I>, 10 <I><FONT COLOR="Navy">{mis}</FONT></I>, 5 <I><FONT COLOR="Navy">{misdir}</FONT></I>, \r
+                    0.17 <I><FONT COLOR="Navy">{velmax}</FONT></I>, 50 <I><FONT COLOR="Navy">{retlas}</FONT></I>, 1000 <I><FONT COLOR="Navy">{retmis}</FONT></I>, 2500 <I><FONT COLOR="Navy">{retmisdir}</FONT></I> ); \r
+  aArmaSelec  := OV_LASER; \r
+  aDisparando := <B>nil</B>; \r
+  aLockeado   := <B>nil</B>; \r
+  aLockFiltro := cFiltroLock.create( self <I><FONT COLOR="Navy">{observador}</FONT></I>, 0.8 <I><FONT COLOR="Navy">{angulo}</FONT></I>, 2000 <I><FONT COLOR="Navy">{maximo}</FONT></I> ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Hace que aumente el modulo de la velocidad \r
+    @param modulo Modulo de la velocidad a sumar}</FONT></I> \r
+<B>procedure</B> <A NAME=cNavePropia.mAcelerar>cNavePropia.mAcelerar</A>(modulo: tLongitud); \r
+<B>begin</B> \r
+  modulo := mGetVelModulo + modulo; \r
+  <B>if</B> modulo <= mGetVelMax <B>then</B> \r
+    mSetVelModulo( modulo ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Hace que disminuya el modulo de la velocidad \r
+    @param modulo Modulo de la velocidad a restar}</FONT></I> \r
+<B>procedure</B> <A NAME=cNavePropia.mDesacelerar>cNavePropia.mDesacelerar</A>(modulo: tLongitud); \r
+<B>begin</B> \r
+  modulo := mGetVelModulo - modulo; \r
+  mSetVelModulo( modulo ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se dibuja de forma distinta}</FONT></I> \r
+<B>function</B> <A NAME=cNavePropia.mDibujar>cNavePropia.mDibujar</A>: tObjetosVoladores; \r
+<B>begin</B> \r
+  result := OV_NAVEPROPIA; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Hace que se dispare un arma \r
+    @param  ov Objetivo del disparo \r
+    @param  dT Intervalo de tiempo \r
+    @return Arma disparada (o <i>nil</i> si no se puede disparar ningún arma)}</FONT></I> \r
+<B>function</B> <A NAME=cNavePropia.mDisparar>cNavePropia.mDisparar</A>( dT: tTiempo; ov : cObjetoVolador ): cArma; \r
+<B>begin</B> \r
+  result := <B>nil</B>; \r
+  mActualizarRetardadores( dT ); \r
+  <B>if</B> aDisparando <> <B>nil</B> <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si esta disparando ... </FONT></I>\r
+    result := aDisparando; <I><FONT COLOR="Navy">// Se devuleve el arma disparada </FONT></I>\r
+    aDisparando := <B>nil</B>;    <I><FONT COLOR="Navy">// Deja de disparar </FONT></I>\r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Permite a la nave girar hacia abajo (sobre su eje Y) \r
+    @param angulo Ángulo a girar}</FONT></I> \r
+<B>procedure</B> <A NAME=cNavePropia.mGirarAbajo>cNavePropia.mGirarAbajo</A>(angulo: tAngulo); \r
+<B>begin</B> \r
+  mRotarEnJ( - angulo ); <I><FONT COLOR="Navy">// Rota el sistema de coordenadas </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Permite a la nave girar hacia arriba (sobre su eje Y) \r
+    @param angulo Ángulo a girar}</FONT></I> \r
+<B>procedure</B> <A NAME=cNavePropia.mGirarArriba>cNavePropia.mGirarArriba</A>(angulo: tAngulo); \r
+<B>begin</B> \r
+  mRotarEnJ( angulo ); <I><FONT COLOR="Navy">// Rota el sistema de coordenadas </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Permite a la nave girar hacia la derecha (sobre su eje Z) \r
+    @param angulo Ángulo a girar}</FONT></I> \r
+<B>procedure</B> <A NAME=cNavePropia.mGirarDerecha>cNavePropia.mGirarDerecha</A>(angulo: tAngulo); \r
+<B>begin</B> \r
+  mRotarEnK( - angulo ); <I><FONT COLOR="Navy">// Rota el sistema de coordenadas </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Permite a la nave girar hacia la izquierda (sobre su eje Z) \r
+    @param angulo Ángulo a girar}</FONT></I> \r
+<B>procedure</B> <A NAME=cNavePropia.mGirarIzquierda>cNavePropia.mGirarIzquierda</A>(angulo: tAngulo); \r
+<B>begin</B> \r
+  mRotarEnK( angulo ); <I><FONT COLOR="Navy">// Rota el sistema de coordenadas </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Permite a la nave rotar hacia la derecha (sobre su eje I) \r
+    @param angulo Ángulo a rotar}</FONT></I> \r
+<B>procedure</B> <A NAME=cNavePropia.mRotarDerecha>cNavePropia.mRotarDerecha</A>(angulo: tAngulo); \r
+<B>begin</B> \r
+  mRotarEnI( angulo ); <I><FONT COLOR="Navy">// Rota el sistema de coordenadas </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Permite a la nave rotar hacia la izquierda (sobre su eje I) \r
+    @param angulo Ángulo a rotar}</FONT></I> \r
+<B>procedure</B> <A NAME=cNavePropia.mRotarIzquierda>cNavePropia.mRotarIzquierda</A>(angulo: tAngulo); \r
+<B>begin</B> \r
+  mRotarEnI( - angulo ); <I><FONT COLOR="Navy">// Rota el sistema de coordenadas </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Intenta disparar. Si las condiciones son las correctas, el proximo turno \r
+    saldrá el disparo, si no, no hace nada \r
+    @return Arma proximamente disparada}</FONT></I> \r
+<B>function</B> <A NAME=cNavePropia.mIntentarDisparo>cNavePropia.mIntentarDisparo</A>: cArma; \r
+<B>var</B> \r
+  vel:     cVector; \r
+  ok:      boolean; \r
+<B>begin</B> \r
+  result := <B>nil</B>; \r
+  <B>if</B> aDisparando = <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no esta disparando se fija si puede hacerlo </FONT></I>\r
+    <B>case</B> aArmaSelec <B>of</B> \r
+      OV_LASER: <B>if</B> mPuedeDispararLaser( <B>nil</B> ) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// si puede disparar... </FONT></I>\r
+                  aDisparando := mCrearLaserDisparado; \r
+                  result := aDisparando; \r
+                <B>end</B>; \r
+      OV_MISIL: <B>if</B> mPuedeDispararMisil( <B>nil</B> ) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// si puede disparar... </FONT></I>\r
+                  aDisparando := mCrearMisilDisparado; \r
+                  result := aDisparando; \r
+                <B>end</B>; \r
+      OV_MISDIR: <B>begin</B> \r
+                  <B>try</B> <I><FONT COLOR="Navy">// Prueba si aLockeado no fue destruido... </FONT></I>\r
+                    ok := mPuedeDispararMisDir( aLockeado ); \r
+                  <B>except</B> \r
+                    on e: EAccessViolation <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si el objetivo lockeado esta destruido... </FONT></I>\r
+                      aLockeado := <B>nil</B>;                        <I><FONT COLOR="Navy">// Lo setea a nil </FONT></I>\r
+                      ok := mPuedeDispararMisDir( aLockeado ); <I><FONT COLOR="Navy">// Se fija de nuevo si puede disparar </FONT></I>\r
+                    <B>end</B>; \r
+                  <B>end</B>; \r
+                  <B>if</B> ok <B>then</B> <B>begin</B>  <I><FONT COLOR="Navy">// Si puede disparar ... </FONT></I>\r
+                    aDisparando := mCrearMisDirDisparado( aLockeado ); <I><FONT COLOR="Navy">// Utiliza como objetivo a aLockeado </FONT></I>\r
+                    <B>if</B> aLockeado = <B>nil</B> <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si no hay ninguno lockeado se setea la direccion </FONT></I>\r
+                      vel := mGetI;               <I><FONT COLOR="Navy">//  de la velocidad igual que la de la nave propia. </FONT></I>\r
+                      aDisparando.mSetVelDir( vel ); \r
+                      vel.free; \r
+                    <B>end</B>; \r
+                    result := aDisparando; \r
+                  <B>end</B>; \r
+                 <B>end</B>; \r
+    <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Selecciona un arma determinada. Si tiene municiones, la selecciona, si no, \r
+    no hace nada.}</FONT></I> \r
+<B>procedure</B> <A NAME=cNavePropia.mSeleccionarArma>cNavePropia.mSeleccionarArma</A>(a: tArma); \r
+<B>begin</B> \r
+  <B>case</B> a <B>of</B> \r
+    OV_LASER: \r
+      aArmaSelec := a; \r
+    OV_MISIL: \r
+      <B>if</B> mTieneMisil <B>then</B> \r
+        aArmaSelec := a; \r
+    OV_MISDIR: \r
+      <B>if</B> mTieneMisilDirigido <B>then</B> \r
+        aArmaSelec := a; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Selecciona el proximo arma con municiones}</FONT></I> \r
+<B>procedure</B> <A NAME=cNavePropia.mSeleccionarArmaSig>cNavePropia.mSeleccionarArmaSig</A>; \r
+<B>begin</B> \r
+  <B>case</B> aArmaSelec <B>of</B> \r
+    OV_LASER: \r
+      <B>if</B> mTieneMisil <B>then</B> \r
+        aArmaSelec := OV_MISIL \r
+      <B>else</B> <B>if</B> mTieneMisilDirigido <B>then</B> \r
+        aArmaSelec := OV_MISDIR; \r
+    OV_MISIL: \r
+      <B>if</B> mTieneMisilDirigido <B>then</B> \r
+        aArmaSelec := OV_MISDIR \r
+      <B>else</B> \r
+        aArmaSelec := OV_LASER; \r
+    OV_MISDIR: \r
+      aArmaSelec := OV_LASER; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el arma seleccionada actualmente \r
+    @return Arma seleccionada}</FONT></I> \r
+<B>function</B> <A NAME=cNavePropia.mGetArmaSelec>cNavePropia.mGetArmaSelec</A>: tArma; \r
+<B>begin</B> \r
+  result := aArmaSelec; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el objetivo lockeado \r
+    @return Objeto volador lockeado}</FONT></I> \r
+<B>function</B> <A NAME=cNavePropia.mGetLockeado>cNavePropia.mGetLockeado</A>: cObjetoVolador; \r
+<B>begin</B> \r
+  result := aLockeado; \r
+  <B>if</B> aLockeado <> <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no es nil... </FONT></I>\r
+    <B>try</B> <I><FONT COLOR="Navy">// Primero se fija que no esté destruido </FONT></I>\r
+      aLockeado.mGetID; \r
+    <B>except</B> \r
+      on e: EAccessViolation <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si lo está... </FONT></I>\r
+        aLockeado := <B>nil</B>; <I><FONT COLOR="Navy">// Lo setea a nil </FONT></I>\r
+        result := aLockeado; \r
+      <B>end</B>; \r
+    <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Setea el objetivo lockeado \r
+    @param ov Objeto volador lockeado}</FONT></I> \r
+<B>procedure</B> <A NAME=cNavePropia.mSetLockeado>cNavePropia.mSetLockeado</A>(ov: cObjetoVolador); \r
+<B>begin</B> \r
+  aLockeado := ov; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Cambia el objetivo lockeado}</FONT></I> \r
+<B>procedure</B> <A NAME=cNavePropia.mCambiarLockeado>cNavePropia.mCambiarLockeado</A>(lEnemigos: TList); \r
+<B>var</B> \r
+  lFiltrados: TList; \r
+  i: integer; \r
+<B>begin</B> \r
+  lFiltrados := aLockFiltro.mFiltrar( lEnemigos ); \r
+  <B>if</B> lFiltrados.Count = 0 <B>then</B> \r
+    aLockeado := <B>nil</B> \r
+  <B>else</B> \r
+    <B>if</B> aLockeado = <B>nil</B> <B>then</B> \r
+      aLockeado := lFiltrados.First <I><FONT COLOR="Navy">// Asigna el primero </FONT></I>\r
+    <B>else</B> <B>begin</B> \r
+      i := lFiltrados.IndexOf( aLockeado ); \r
+      <B>if</B> i < 0 <B>then</B> <I><FONT COLOR="Navy">// No esta en la lista </FONT></I>\r
+        aLockeado := lFiltrados.First <I><FONT COLOR="Navy">// Asigna el primero </FONT></I>\r
+      <B>else</B> \r
+        <B>if</B> i = (lFiltrados.Count - 1) <B>then</B> <I><FONT COLOR="Navy">// Es el ultimo objeto de la lista </FONT></I>\r
+          aLockeado := lFiltrados.First <I><FONT COLOR="Navy">// Asigna el primero </FONT></I>\r
+        <B>else</B> \r
+          aLockeado := lFiltrados.Items[i+1]; <I><FONT COLOR="Navy">// Asigna el proximo </FONT></I>\r
+    <B>end</B>; \r
+  lFiltrados.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+    serializado. \r
+    @param str Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>procedure</B> <A NAME=cNavePropia.mDesSerializar>cNavePropia.mDesSerializar</A>(str: <B>string</B>); \r
+<B>var</B> \r
+  r: TRegExpr; \r
+<B>begin</B> \r
+  <B>inherited</B> mDesSerializar( str ); <I><FONT COLOR="Navy">// SIEMPRE el ID debe ser el PRIMER atributo </FONT></I>\r
+  r := TRegExpr.create; \r
+  <I><FONT COLOR="Navy">// LOCKEADO </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<lockeado/s+class=([/w/d]+)/s*>/s*(.+)/s*</lockeado>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      <B>if</B> r.Match[1] <> '0' <B>then</B> <I><FONT COLOR="Navy">// Si tiene una clase determinada... </FONT></I>\r
+        <B>if</B> aLockeado <> <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no es nulo </FONT></I>\r
+          <I><FONT COLOR="Navy">// Puede caer en una EAccessViolation si esta destruido </FONT></I>\r
+          aLockeado.mDesSerializar( r.Match[2] ) <I><FONT COLOR="Navy">// Lo deserializa </FONT></I>\r
+        <B>else</B> <I><FONT COLOR="Navy">// si es nulo </FONT></I>\r
+          aLockeado := restaurarObjeto( r.Match[1], r.Match[2] ) <I><FONT COLOR="Navy">// lo crea segun su clase </FONT></I>\r
+      <B>else</B> <I><FONT COLOR="Navy">// Si no tiene una clase determinada, entonces se lo pone en nil </FONT></I>\r
+        aLockeado := <B>nil</B> \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el objetivo lockeado' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ESerializacion <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si fueron de serializacion... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al deserializar el objetivo lockeado: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el objetivo lockeado utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+    on e: EAccessViolation <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si el Objetivo fue destruido... </FONT></I>\r
+      aLockeado := restaurarObjeto( r.Match[1], r.Match[2] ) <I><FONT COLOR="Navy">// lo crea segun su clase </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// ARMASELEC </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<armaselec>/s*(/d+)/s*</armaselec>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aArmaSelec := tArma( StrToInt( r.Match[1] ) ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el arma seleccionada' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el arma seleccionada utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// LOCKFILTRO </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<lockfiltro>/s*(.+)/s*</lockfiltro>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      <B>if</B> aLockFiltro <> <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no es nulo </FONT></I>\r
+        aLockFiltro.mDesSerializar( r.Match[1] ) <I><FONT COLOR="Navy">// Lo deserializa </FONT></I>\r
+      <B>else</B> <I><FONT COLOR="Navy">// si es nulo </FONT></I>\r
+        aLockFiltro := cFiltroLock.crearDeSerializado( r.Match[1] ) <I><FONT COLOR="Navy">// lo crea </FONT></I>\r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': No se pudieron extraer el filtro de lockeo' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ESerializacion <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si fueron de serializacion... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al deserializar el filtro de lockeo: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el filtro de lockeo utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// El observador del filtro va a ser siempre la nave propia, es por esto </FONT></I>\r
+  <I><FONT COLOR="Navy">//  que debemos eliminar la copia del observador que se creo y asignarle self </FONT></I>\r
+  aLockFiltro.mGetObservador.free; \r
+  aLockFiltro.mSetObservador( self ); \r
+  r.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado. \r
+    @return Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>function</B> <A NAME=cNavePropia.mSerializar>cNavePropia.mSerializar</A>: <B>string</B>; \r
+<B>var</B> \r
+  clase, \r
+  lockeado:  <B>string</B>; \r
+  meteorito: cMeteorito; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Si el objetivo es nil o está destruido, se setea el atributo class del </FONT></I>\r
+  <I><FONT COLOR="Navy">// TAG objetivo como '0' y entre el TAG se indica que es nil. Si no se </FONT></I>\r
+  <I><FONT COLOR="Navy">// setea como el nombre de la clase y su expresion serializada respectivamente </FONT></I>\r
+  lockeado := 'nil'; \r
+  clase    := '0'; \r
+  <B>if</B> aLockeado <> <B>nil</B> <B>then</B> \r
+    <B>try</B> \r
+      lockeado := aLockeado.mSerializar; \r
+      clase    := aLockeado.ClassName; \r
+    <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cambia la cadena de texto </FONT></I>\r
+      on e: EAccessViolation <B>do</B> <B>begin</B> \r
+        lockeado := 'nil'; \r
+        clase    := '0'; \r
+      <B>end</B>; \r
+    <B>end</B>; \r
+  <I><FONT COLOR="Navy">// Hoy que modificar el observador del filtro porque de otra forma esta funcion </FONT></I>\r
+  <I><FONT COLOR="Navy">//  se volveria infinitamente recursiva, ya que cuando quiere serializar el </FONT></I>\r
+  <I><FONT COLOR="Navy">//  filtro, necesita serializar el observador quien necesita serializar el </FONT></I>\r
+  <I><FONT COLOR="Navy">//  filtro y asi ad infinitum. </FONT></I>\r
+  meteorito := cMeteorito.create; \r
+  aLockFiltro.mSetObservador( meteorito ); \r
+  result := <B>inherited</B> mSerializar + \r
+            '<lockeado class=' + clase  + '>' + lockeado + '</lockeado>' + \r
+            '<armaselec>' + IntToStr( ord( aArmaSelec ) ) + '</armaselec>' + \r
+            '<lockfiltro>' + aLockFiltro.mSerializar + '</lockfiltro>'; \r
+  <I><FONT COLOR="Navy">// Se vuelve a establecer como observador a la nave propia. </FONT></I>\r
+  aLockFiltro.mSetObservador( self ); \r
+  meteorito.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene un puntero a la último arma disparada \r
+    @return Último arma disparado}</FONT></I> \r
+<B>function</B> <A NAME=cNavePropia.mGetUltimoArmaDisparado>cNavePropia.mGetUltimoArmaDisparado</A>: cArma; \r
+<B>begin</B> \r
+  result := aDisparando; \r
+  <B>if</B> aDisparando <> <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no es nil... </FONT></I>\r
+    <B>try</B> <I><FONT COLOR="Navy">// Primero se fija que no esté destruido </FONT></I>\r
+      aDisparando.mGetID; \r
+    <B>except</B> \r
+      on e: EAccessViolation <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si lo está... </FONT></I>\r
+        aDisparando := <B>nil</B>; <I><FONT COLOR="Navy">// Lo setea a nil </FONT></I>\r
+        result := aDisparando; \r
+      <B>end</B>; \r
+    <B>end</B>; \r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/modelo/ov/naves/NavesEnemigas.pas b/doc/src-html/modelo/ov/naves/NavesEnemigas.pas
new file mode 100644 (file)
index 0000000..61ed755
--- /dev/null
@@ -0,0 +1,472 @@
+<HTML><HEAD>\r
+<TITLE>File: navesenemigas.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=navesenemigas.pas><CENTER><H3>navesenemigas.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Distintos tipos de Naves Enemigas<br> \r
+    <i>Cambios:</i> \r
+    <PRE> \r
+    27/11/00: Se realizan algunos cambios para adaptarse a la nueva implementacion de cNave con disparos. \r
+    01/12/00: Se cambiaron las dimensiones de la nave para que los disparos sean mas "jugables". \r
+              Se cambia el orden de los argumentos de mDisparar para aprovechar los argumentos por defecto. \r
+    </PRE>}</FONT></I> \r
+<B>unit</B> NavesEnemigas; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  Tipos, \r
+  Vectores, \r
+  Nave, \r
+  NaveEnemiga, \r
+  NavePropia, \r
+  ObjetoVolador, \r
+  Armas; \r
\r
+<B>type</B> \r
+  <I><FONT COLOR="Navy">{** Es una nave con misiles y lasers (igual que la propia) \r
+      que se desplaza por el epacio hasta que encuentra una nave propia para atacar.<br> \r
+      <u>Características:</u> \r
+      <PRE> \r
+      Dimensión:            25        metros \r
+      Potencia:             2         Cantidad de daño que hace por intervalo de tiempo \r
+      Energía:              100       Cantidad de daño que soporta antes de ser destruída \r
+      Velocidad máxima:     0,17      metros/milisegundos (612 km/h) \r
+      Campo de radar:       5000      metros (5 km) \r
+      Misiles:              5 \r
+      Misiles Dirigidos:    2 \r
+      </PRE>}</FONT></I> \r
+  cNavePesada = <B>class</B>( cNaveEnemiga ) \r
+    <B>private</B> \r
+      aCampoMinimo: tLongitud; <I><FONT COLOR="Navy">// Distancia minima a la nave propia </FONT></I>\r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( pos : cVector = <B>nil</B>; vel : cVector = <B>nil</B> ); \r
+      <I><FONT COLOR="Navy">{** Método heredado que hace que la nave reaccione ante la presencia \r
+          de la nave propia (en este caso la atacará con lasers y misiles)}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNavePesada.mReaccionar">mReaccionar</A>( np : cNavePropia );<B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se dibuja de forma distinta}</FONT></I> \r
+      <B>function</B> <A HREF="#cNavePesada.mDibujar">mDibujar</A>: tObjetosVoladores; <B>override</B>; \r
+      <I><FONT COLOR="Navy">// SERIALIZACION </FONT></I>\r
+      <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.}</FONT></I> \r
+      <B>function</B> <A HREF="#cNavePesada.mSerializar">mSerializar</A>: <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+          serializado.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNavePesada.mDesSerializar">mDesSerializar</A>( str: <B>string</B> ); <B>override</B>; \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Es una nave sin misiles, solo con lasers que \r
+      se desplaza por el epacio hasta que encuentra una nave propia para atacar.<br> \r
+      <u>Características:</u> \r
+      <PRE> \r
+      Dimensión:            15        metros \r
+      Potencia:             1         Cantidad de daño que hace por intervalo de tiempo \r
+      Energía:              60        Cantidad de daño que soporta antes de ser destruída \r
+      Velocidad máxima:     0,18      metros/milisegundos (648 km/h) \r
+      Campo de radar:       3000      metros (3 km) \r
+      Misiles:              0 \r
+      Misiles Dirigidos:    0 \r
+      </PRE>}</FONT></I> \r
+  cNaveLiviana = <B>class</B>( cNaveEnemiga ) \r
+    <B>private</B> \r
+      aCampoMinimo: tLongitud; <I><FONT COLOR="Navy">// Distancia minima a la nave propia </FONT></I>\r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( pos : cVector = <B>nil</B>; vel : cVector = <B>nil</B> ); \r
+      <I><FONT COLOR="Navy">{** Método heredado que hace que la nave reaccione ante la presencia \r
+          de la nave propia (en este caso la atacará con lasers)}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNaveLiviana.mReaccionar">mReaccionar</A>( np : cNavePropia );<B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se dibuja de forma distinta}</FONT></I> \r
+      <B>function</B> <A HREF="#cNaveLiviana.mDibujar">mDibujar</A>: tObjetosVoladores; <B>override</B>; \r
+      <I><FONT COLOR="Navy">// SERIALIZACION </FONT></I>\r
+      <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.}</FONT></I> \r
+      <B>function</B> <A HREF="#cNaveLiviana.mSerializar">mSerializar</A>: <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+          serializado.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNaveLiviana.mDesSerializar">mDesSerializar</A>( str: <B>string</B> ); <B>override</B>; \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Es una nave sin armas que se desplaza por el epacio \r
+      hasta que encuentra una nave propia, en ese momento empieza a huir avisando a \r
+      las demas naves enemigas la ultima posicion de la nave propia.<br> \r
+      <u>Características:</u> \r
+      <PRE> \r
+      Dimensión:            10        metros \r
+      Potencia:             1         Cantidad de daño que hace por intervalo de tiempo \r
+      Energía:              30        Cantidad de daño que soporta antes de ser destruída \r
+      Velocidad máxima:     0,2       metros/milisegundos (720 km/h) \r
+      Campo de radar:       2000      metros (2 km) \r
+      Misiles:              0 \r
+      Misiles Dirigidos:    0 \r
+      </PRE>}</FONT></I> \r
+  cNaveEspia = <B>class</B>( cNaveEnemiga ) \r
+    <B>private</B> \r
+      aPosicionEnemiga: cVector; <I><FONT COLOR="Navy">// Indica la posicion de la nave propia. Si todavía no </FONT></I>\r
+                                 <I><FONT COLOR="Navy">//  la encontró, su valor es nil </FONT></I>\r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Método heredado se modifica porque su forma de modificar la velocidad es diferente al \r
+          resto de las naves enemigas}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNaveEspia.mModificarVelocidad">mModificarVelocidad</A>( np: cNavePropia; modulo: tLongitud = -1 ); <B>override</B>; \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor }</FONT></I> \r
+      <B>constructor</B> create( pos : cVector = <B>nil</B>; vel : cVector = <B>nil</B> ); \r
+      <I><FONT COLOR="Navy">{** Método que indica si está avisando }</FONT></I> \r
+      <B>function</B> <A HREF="#cNaveEspia.mAvisando">mAvisando</A>: boolean; \r
+      <I><FONT COLOR="Navy">{** Método que devuelve la última posición en dónde vió a la nave propia (si está avisando)}</FONT></I> \r
+      <B>function</B> <A HREF="#cNaveEspia.mGetPosicionEnemiga">mGetPosicionEnemiga</A>: cVector; \r
+      <I><FONT COLOR="Navy">{** Método heredado que hace que la nave reaccione ante la presencia \r
+          de la nave propia (en este caso huirá y empezará a avisar al resto de las naves que encuentre \r
+          sobre la última posición de la nave propia)}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNaveEspia.mReaccionar">mReaccionar</A>( np : cNavePropia );<B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Destructor}</FONT></I> \r
+      <B>destructor</B> destroy; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque esta nave en particular no puede disparar}</FONT></I> \r
+      <B>function</B> <A HREF="#cNaveEspia.mDisparar">mDisparar</A>( dT: tTiempo; ov : cObjetoVolador = <B>nil</B> ): cArma; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se dibuja de forma distinta}</FONT></I> \r
+      <B>function</B> <A HREF="#cNaveEspia.mDibujar">mDibujar</A>: tObjetosVoladores; <B>override</B>; \r
+      <I><FONT COLOR="Navy">// SERIALIZACION </FONT></I>\r
+      <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.}</FONT></I> \r
+      <B>function</B> <A HREF="#cNaveEspia.mSerializar">mSerializar</A>: <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+          serializado.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNaveEspia.mDesSerializar">mDesSerializar</A>( str: <B>string</B> ); <B>override</B>; \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Es una nave sin armas que se desplaza por el epacio \r
+      hasta que encuentra una nave propia y trata de chocarla.<br> \r
+      <u>Características:</u> \r
+      <PRE> \r
+      Dimensión:            10        metros \r
+      Potencia:             4         Cantidad de daño que hace por intervalo de tiempo \r
+      Energía:              30        Cantidad de daño que soporta antes de ser destruída \r
+      Velocidad máxima:     0,2       metros/milisegundos (720 km/h) \r
+      Campo de radar:       2500      metros (2,5 km) \r
+      Misiles:              0 \r
+      Misiles Dirigidos:    0 \r
+      </PRE>}</FONT></I> \r
+  cNaveSuicida = <B>class</B>( cNaveEnemiga ) \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( pos : cVector = <B>nil</B>; vel : cVector = <B>nil</B> ); \r
+      <I><FONT COLOR="Navy">{** Método heredado que hace que la nave reaccione ante la presencia \r
+          de la nave propia (en este caso tratará de chocarla)}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cNaveSuicida.mReaccionar">mReaccionar</A>( np : cNavePropia );<B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque esta nave en particular no puede disparar}</FONT></I> \r
+      <B>function</B> <A HREF="#cNaveSuicida.mDisparar">mDisparar</A>( dT: tTiempo; ov : cObjetoVolador = <B>nil</B> ): cArma; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Método heredado, se sobreescribe porque se dibuja de forma distinta}</FONT></I> \r
+      <B>function</B> <A HREF="#cNaveSuicida.mDibujar">mDibujar</A>: tObjetosVoladores; <B>override</B>; \r
+  <B>end</B>; \r
\r
+<B>implementation</B> \r
\r
+<B>uses</B> \r
+  RegExpr, \r
+  ObjetoPersistente, \r
+  Sysutils; \r
\r
+<I><FONT COLOR="Navy">{ cNavePesada }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Crea una instancia de una nave pesada. \r
+    @param pos Vector posición \r
+    @param vel Vector velocidad}</FONT></I> \r
+<B>constructor</B> cNavePesada.create(pos, vel: cVector); \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// La dimensión es 5 m de radio, la potencia 2, la energía 100, tiene 5 misiles comunes, </FONT></I>\r
+  <I><FONT COLOR="Navy">//  2 dirigidos, su velocidad maxima es 0,17 m/mseg (612 km/h) y su Campo de radar 5 km </FONT></I>\r
+  <B>inherited</B> create( pos, vel, 25 <I><FONT COLOR="Navy">{dim}</FONT></I>, 2 <I><FONT COLOR="Navy">{pot}</FONT></I>, 100 <I><FONT COLOR="Navy">{ene}</FONT></I>, 5 <I><FONT COLOR="Navy">{mis}</FONT></I>, 2 <I><FONT COLOR="Navy">{misdir}</FONT></I>, \r
+                    0.17 <I><FONT COLOR="Navy">{velmax}</FONT></I>, 5000 <I><FONT COLOR="Navy">{rad}</FONT></I>); \r
+  aCampoMinimo := 500; \r
+<B>end</B>; \r
\r
+<B>function</B> <A NAME=cNavePesada.mDibujar>cNavePesada.mDibujar</A>: tObjetosVoladores; \r
+<B>begin</B> \r
+  result := OV_NAVEPESADA; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método heredado que hace que la nave reaccione ante la presencia \r
+    de la nave propia cerca (en este caso la atacará con lasers y misiles) \r
+    @param np Nave Propia con la cual esta reaccionando}</FONT></I> \r
+<B>procedure</B> <A NAME=cNavePesada.mReaccionar>cNavePesada.mReaccionar</A>(np: cNavePropia); \r
+<B>var</B> \r
+  modulo: tLongitud; \r
+<B>begin</B> \r
+  modulo := mGetVelMax; <I><FONT COLOR="Navy">// nuevo modulo de la velocidad igual a la velocidad maxima </FONT></I>\r
+  <B>if</B> mGetDistancia( np ) < aCampoMinimo <B>then</B> <I><FONT COLOR="Navy">// si esta cerca de la nave propia... </FONT></I>\r
+    <B>if</B> np.mGetVelModulo < mGetVelMax <B>then</B> <I><FONT COLOR="Navy">// si la vel de la nave propia es menor a la maxima </FONT></I>\r
+      modulo := np.mGetVelModulo; <I><FONT COLOR="Navy">// nuevo modulo de la velocidad igual al de la nave propia </FONT></I>\r
+  mModificarVelocidad( np, modulo ); <I><FONT COLOR="Navy">// cambiar la velocidad segun la nave propia y el nuevo modulo </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+    serializado. \r
+    @param str Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>procedure</B> <A NAME=cNavePesada.mDesSerializar>cNavePesada.mDesSerializar</A>(str: <B>string</B>); \r
+<B>var</B> \r
+  r: TRegExpr; \r
+<B>begin</B> \r
+  <B>inherited</B> mDesSerializar( str ); <I><FONT COLOR="Navy">// SIEMPRE el ID debe ser el PRIMER atributo </FONT></I>\r
+  r := TRegExpr.create; \r
+  <I><FONT COLOR="Navy">// CAMPORADAR </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<campominimo>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</campominimo>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aCampoMinimo := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el campo minimo' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el campo minimo utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  r.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado. \r
+    @return Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>function</B> <A NAME=cNavePesada.mSerializar>cNavePesada.mSerializar</A>: <B>string</B>; \r
+<B>begin</B> \r
+  result := <B>inherited</B> mSerializar + \r
+            '<campominimo>' + FloatToStrF( aCampoMinimo, ffGeneral, 18, 0 ) + '</campominimo>'; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cNaveLiviana }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Crea una instancia de una nave liviana. \r
+    @param pos Vector posición \r
+    @param vel Vector velocidad}</FONT></I> \r
+<B>constructor</B> cNaveLiviana.create(pos, vel: cVector); \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// La dimensión es 3 m de radio, la potencia 1, la energía 60, no tiene misiles comunes </FONT></I>\r
+  <I><FONT COLOR="Navy">//  ni dirigidos, su velocidad maxima es 0,18 m/mseg (648 km/h) y su Campo de radar 3 km </FONT></I>\r
+  <I><FONT COLOR="Navy">// El retardo del laser es de .5 segundos, el del misil de 2 segundos y el del misil </FONT></I>\r
+  <I><FONT COLOR="Navy">//  dirigido de 5 segundos. </FONT></I>\r
+  <B>inherited</B> create( pos, vel, 15 <I><FONT COLOR="Navy">{dim}</FONT></I>, 1 <I><FONT COLOR="Navy">{pot}</FONT></I>, 60 <I><FONT COLOR="Navy">{ene}</FONT></I>, 0 <I><FONT COLOR="Navy">{mis}</FONT></I>, 0 <I><FONT COLOR="Navy">{misdir}</FONT></I>, \r
+                    0.18 <I><FONT COLOR="Navy">{velmax}</FONT></I>, 3000 <I><FONT COLOR="Navy">{rad}</FONT></I>, 500 <I><FONT COLOR="Navy">{retlaser}</FONT></I>); \r
+  aCampoMinimo := 250; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Hace que se dispare un arma (todavía no está implementado)}</FONT></I> \r
+<B>function</B> <A NAME=cNaveLiviana.mDibujar>cNaveLiviana.mDibujar</A>: tObjetosVoladores; \r
+<B>begin</B> \r
+  result := OV_NAVELIVIANA; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método heredado que hace que la nave reaccione ante la presencia \r
+    de la nave propia (en este caso la atacará con lasers) \r
+    @param np Nave Propia con la cual esta reaccionando}</FONT></I> \r
+<B>procedure</B> <A NAME=cNaveLiviana.mReaccionar>cNaveLiviana.mReaccionar</A>(np: cNavePropia); \r
+<B>var</B> \r
+  modulo: tLongitud; \r
+<B>begin</B> \r
+  modulo := mGetVelMax; <I><FONT COLOR="Navy">// nuevo modulo de la velocidad igual a la velocidad maxima </FONT></I>\r
+  <B>if</B> mGetDistancia( np ) < aCampoMinimo <B>then</B> <I><FONT COLOR="Navy">// si esta cerca de la nave propia... </FONT></I>\r
+    <B>if</B> np.mGetVelModulo < mGetVelMax <B>then</B> <I><FONT COLOR="Navy">// si la vel de la nave propia es menor a la maxima </FONT></I>\r
+      modulo := np.mGetVelModulo; <I><FONT COLOR="Navy">// nuevo modulo de la velocidad igual al de la nave propia </FONT></I>\r
+  mModificarVelocidad( np, modulo ); <I><FONT COLOR="Navy">// cambiar la velocidad segun la nave propia y el nuevo modulo </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+    serializado. \r
+    @param str Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>procedure</B> <A NAME=cNaveLiviana.mDesSerializar>cNaveLiviana.mDesSerializar</A>(str: <B>string</B>); \r
+<B>var</B> \r
+  r: TRegExpr; \r
+<B>begin</B> \r
+  <B>inherited</B> mDesSerializar( str ); <I><FONT COLOR="Navy">// SIEMPRE el ID debe ser el PRIMER atributo </FONT></I>\r
+  r := TRegExpr.create; \r
+  <I><FONT COLOR="Navy">// CAMPORADAR </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<campominimo>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</campominimo>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aCampoMinimo := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el campo minimo' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el campo minimo utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  r.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado. \r
+    @return Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>function</B> <A NAME=cNaveLiviana.mSerializar>cNaveLiviana.mSerializar</A>: <B>string</B>; \r
+<B>begin</B> \r
+  result := <B>inherited</B> mSerializar + \r
+            '<campominimo>' + FloatToStrF( aCampoMinimo, ffGeneral, 18, 0 ) + '</campominimo>'; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cNaveEspia }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Crea una instancia de una nave espía. \r
+    @param pos Vector posición \r
+    @param vel Vector velocidad}</FONT></I> \r
+<B>constructor</B> cNaveEspia.create(pos, vel: cVector); \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// La dimensión es 2 m de radio, la potencia 1, la energía 30, no tiene misiles comunes </FONT></I>\r
+  <I><FONT COLOR="Navy">//  ni dirigidos, su velocidad maxima es 0,2 m/mseg (720 km/h) y su Campo de radar 3 km </FONT></I>\r
+  <B>inherited</B> create( pos, vel, 10 <I><FONT COLOR="Navy">{dim}</FONT></I>, 1 <I><FONT COLOR="Navy">{pot}</FONT></I>, 30 <I><FONT COLOR="Navy">{ene}</FONT></I>, 0 <I><FONT COLOR="Navy">{mis}</FONT></I>, 0 <I><FONT COLOR="Navy">{misdir}</FONT></I>, \r
+                    0.2 <I><FONT COLOR="Navy">{velmax}</FONT></I>, 2000 <I><FONT COLOR="Navy">{rad}</FONT></I> ); \r
+  aPosicionEnemiga := <B>nil</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Destructor}</FONT></I> \r
+<B>destructor</B> cNaveEspia.destroy; \r
+<B>begin</B> \r
+  aPosicionEnemiga.free; \r
+  <B>inherited</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Hace que se dispare un arma \r
+    @param  ov Objetivo del disparo \r
+    @return Arma disparada (o <i>nil</i> si no se puede disparar ningún arma)}</FONT></I> \r
+<B>function</B> <A NAME=cNaveEspia.mDisparar>cNaveEspia.mDisparar</A>( dT: tTiempo; ov : cObjetoVolador ): cArma; \r
+<B>begin</B> \r
+  result := <B>nil</B>; <I><FONT COLOR="Navy">// No puede disparar nada (nunca!) </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método que indica si está avisando \r
+    @return <i>true</i> si está avisando, <i>false</i> si no lo está}</FONT></I> \r
+<B>function</B> <A NAME=cNaveEspia.mAvisando>cNaveEspia.mAvisando</A>: boolean; \r
+<B>begin</B> \r
+  result := ( aPosicionEnemiga <> <B>nil</B> ); <I><FONT COLOR="Navy">// True si la posicion no es nil </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método que devuelve la última posición en dónde vió a la nave propia (si está avisando) \r
+    @return Última posición donde detectó a la nave propia (<i>nil</i> si no la detecto nunca)}</FONT></I> \r
+<B>function</B> <A NAME=cNaveEspia.mDibujar>cNaveEspia.mDibujar</A>: tObjetosVoladores; \r
+<B>begin</B> \r
+  result := OV_NAVEESPIA; \r
+<B>end</B>; \r
\r
+<B>function</B> <A NAME=cNaveEspia.mGetPosicionEnemiga>cNaveEspia.mGetPosicionEnemiga</A>: cVector; \r
+<B>begin</B> \r
+  result := cVector.create( aPosicionEnemiga ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Modifica la velocidad de la nave en base a la nave propia. \r
+    @param np     Nave propia con la cual se calculará la dirección de la nueva velocidad \r
+    @param modulo Nuevo módulo de la velocidad}</FONT></I> \r
+<B>procedure</B> <A NAME=cNaveEspia.mModificarVelocidad>cNaveEspia.mModificarVelocidad</A>(np: cNavePropia; modulo: tLongitud); \r
+<B>var</B> \r
+  pos,          <I><FONT COLOR="Navy">// Vector temporal </FONT></I>\r
+  vel: cVector; <I><FONT COLOR="Navy">// Vector temporal </FONT></I>\r
+<B>begin</B> \r
+  pos := np.mGetPosicion; \r
+  vel := mGetPosicion.mRestar( pos ); <I><FONT COLOR="Navy">// Crea un vector igual a su posicion </FONT></I>\r
+                                      <I><FONT COLOR="Navy">// Le resta la posicion de la nave propia </FONT></I>\r
+  mSetVelModulo( mGetVelMax );        <I><FONT COLOR="Navy">// Setea el modulo al maximo </FONT></I>\r
+  mSetVelDir( vel );                  <I><FONT COLOR="Navy">// Copia el vector a su velocidad </FONT></I>\r
+  vel.free;                           <I><FONT COLOR="Navy">// Libera el vector temporal </FONT></I>\r
+  pos.free;                           <I><FONT COLOR="Navy">// Libera el vector temporal </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método heredado que hace que la nave reaccione ante la presencia \r
+    de la nave propia (en este caso huirá y empezará a avisar al resto de las naves que encuentre \r
+    sobre la última posición de la nave propia) \r
+    @param np Nave Propia con la cual esta reaccionando}</FONT></I> \r
+<B>procedure</B> <A NAME=cNaveEspia.mReaccionar>cNaveEspia.mReaccionar</A>(np: cNavePropia); \r
+<B>begin</B> \r
+  mModificarVelocidad( np ); \r
+  <I><FONT COLOR="Navy">// Si ya tiene una posición, la modifica, si no crea una nueva </FONT></I>\r
+  <B>if</B> aPosicionEnemiga <> <B>nil</B> <B>then</B> \r
+    aPosicionEnemiga.free; \r
+  aPosicionEnemiga := np.mGetPosicion; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+    serializado. \r
+    @param str Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>procedure</B> <A NAME=cNaveEspia.mDesSerializar>cNaveEspia.mDesSerializar</A>(str: <B>string</B>); \r
+<B>var</B> \r
+  r: TRegExpr; \r
+<B>begin</B> \r
+  <B>inherited</B> mDesSerializar( str ); <I><FONT COLOR="Navy">// SIEMPRE el ID debe ser el PRIMER atributo </FONT></I>\r
+  r := TRegExpr.create; \r
+  <I><FONT COLOR="Navy">// POSICIONENEMIGA </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<posicionenemiga>/s*(.+)/s*</posicionenemiga>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      <B>if</B> r.Match[1] = 'nil' <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si la posicion enemiga recuperada es nil... </FONT></I>\r
+        aPosicionEnemiga.free;   <I><FONT COLOR="Navy">// Libera la posicion actual </FONT></I>\r
+        aPosicionEnemiga := <B>nil</B>; <I><FONT COLOR="Navy">// y la pone en nil </FONT></I>\r
+      <B>end</B> <B>else</B> <I><FONT COLOR="Navy">// si es otra cosa, la interpreta </FONT></I>\r
+        <B>if</B> aPosicionEnemiga <> <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no es nulo </FONT></I>\r
+          aPosicionEnemiga.mDesSerializar( r.Match[1] ) <I><FONT COLOR="Navy">// Lo deserializa </FONT></I>\r
+        <B>else</B> <I><FONT COLOR="Navy">// si es nulo </FONT></I>\r
+          aPosicionEnemiga := cVector.crearDeSerializado( r.Match[1] ) <I><FONT COLOR="Navy">// lo crea </FONT></I>\r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro la posicion enemiga' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ESerializacion <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si fueron de serializacion... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al deserializar la posicion enemiga: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer la posicion enemiga utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  r.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado. \r
+    @return Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>function</B> <A NAME=cNaveEspia.mSerializar>cNaveEspia.mSerializar</A>: <B>string</B>; \r
+<B>var</B> \r
+  posene: <B>string</B>; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Si el objetivo es nil o está destruido, se setea el atributo class del </FONT></I>\r
+  <I><FONT COLOR="Navy">// TAG objetivo como '0' y entre el TAG se indica que es nil. Si no se </FONT></I>\r
+  <I><FONT COLOR="Navy">// setea como el nombre de la clase y su expresion serializada respectivamente </FONT></I>\r
+  posene := 'nil'; \r
+  <B>if</B> aPosicionEnemiga <> <B>nil</B> <B>then</B> \r
+    posene := aPosicionEnemiga.mSerializar; \r
+  result := <B>inherited</B> mSerializar + \r
+            '<posicionenemiga>' + posene + '</posicionenemiga>'; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cNaveSuicida }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Crea una instancia de una nave suicida. \r
+    @param pos Vector posición \r
+    @param vel Vector velocidad}</FONT></I> \r
+<B>constructor</B> cNaveSuicida.create(pos, vel: cVector); \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// La dimensión es 2 m de radio, la potencia 4, la energía 30, no tiene misiles comunes </FONT></I>\r
+  <I><FONT COLOR="Navy">//  ni dirigidos, su velocidad maxima es 0,2 m/mseg (720 km/h) y su Campo de radar 1 km </FONT></I>\r
+  <B>inherited</B> create( pos, vel, 10 <I><FONT COLOR="Navy">{dim}</FONT></I>, 4 <I><FONT COLOR="Navy">{pot}</FONT></I>, 30 <I><FONT COLOR="Navy">{ene}</FONT></I>, 0 <I><FONT COLOR="Navy">{mis}</FONT></I>, 0 <I><FONT COLOR="Navy">{misdir}</FONT></I>, \r
+                    0.2 <I><FONT COLOR="Navy">{velmax}</FONT></I>, 2500 <I><FONT COLOR="Navy">{rad}</FONT></I>); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Método heredado que hace que la nave reaccione ante la presencia \r
+    de la nave propia (en este caso tratará de chocarla) \r
+    @param np Nave Propia con la cual esta reaccionando}</FONT></I> \r
+<B>function</B> <A NAME=cNaveSuicida.mDibujar>cNaveSuicida.mDibujar</A>: tObjetosVoladores; \r
+<B>begin</B> \r
+  result := OV_NAVESUICIDA; \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=cNaveSuicida.mReaccionar>cNaveSuicida.mReaccionar</A>(np: cNavePropia); \r
+<B>begin</B> \r
+  mModificarVelocidad( np ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Hace que se dispare un arma \r
+    @param  ov Objetivo del disparo \r
+    @return Arma disparada (o <i>nil</i> si no se puede disparar ningún arma)}</FONT></I> \r
+<B>function</B> <A NAME=cNaveSuicida.mDisparar>cNaveSuicida.mDisparar</A>( dT: tTiempo; ov : cObjetoVolador ): cArma; \r
+<B>begin</B> \r
+  result := <B>nil</B>; <I><FONT COLOR="Navy">// No puede disparar nada (nunca!) </FONT></I>\r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/vista/Camara.pas b/doc/src-html/vista/Camara.pas
new file mode 100644 (file)
index 0000000..b580034
--- /dev/null
@@ -0,0 +1,298 @@
+<HTML><HEAD>\r
+<TITLE>File: camara.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=camara.pas><CENTER><H3>camara.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Implementa una cámara que se encarga de representar los objetos en 2D.<br> \r
+    <i>Cambios:</i> \r
+    <PRE> \r
+    10/11/00: Se agrega el manejo de excepciones para evitar usar la camara cuando el cameraman fue destruido. \r
+              Para lograr esto se crea una excepcion (ECameramanDestruido) que se lanza cuando hay una excepcion \r
+              de violacion de acceso a memoria. Esta excepcion debe ser manejada por quien meneje la camara y puede \r
+              ser lanzada por mGetDebugInfo o mProyectar. \r
+    01/12/00: Se elimina el atributo aApertura porque era absolutamente inecesario. \r
+              Se cambia la estructura interna para que el filtrado de los objetos los realice un cFiltro. \r
+    07/12/00: Se agregan nuevos métodos (protegidos) para obtener información de la cámara para poder crear subclases, \r
+              para lo cual tambien se hace virtual el método mProyectar. \r
+    08/12/00: Se quita el método para setear el filtro y se agrega un contructor que admite un filtro para reemplazarlo. \r
+              Se cambia esta clase para que sea abstracta. Se deja la implementacion del método mProyectar para las \r
+              subclases exlusivamente ya que ahora es abstracto. La cámara frontal (que antes se implementaba en \r
+              esta unidad), ahora está implementado la unidad Camaras al igual que el resto. \r
+    </PRE>}</FONT></I> \r
+<B>unit</B> Camara; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+  Objeto, \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+  Tipos, \r
+  Coordenadas, \r
+  Vectores, \r
+  ObjetoVolador, \r
+  NavePropia, \r
+  Espacio, \r
+  Classes, \r
+  Sysutils, \r
+  Filtro, \r
+  Lista; \r
\r
+<B>type</B> \r
+  <I><FONT COLOR="Navy">{** Datos de un Objeto Volador procesado por una cámara }</FONT></I> \r
+  tProyectado = <B>record</B> \r
+    oOV:  cObjetoVolador; \r
+    x:    tLongitud; \r
+    y:    tLongitud; \r
+    tam:  tLongitud; \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Puntero a tProyectado}</FONT></I> \r
+  tPProy = ^tProyectado; \r
\r
+  <I><FONT COLOR="Navy">{** Excepcion producida por la cámara si se utiliza cuando el cameraman fue destruido}</FONT></I> \r
+  ECameramanDestruido = <B>class</B>( Exception ) \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create; \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Implementa una cámara que se encarga de representar los objetos en 2D.}</FONT></I> \r
+  cCamara = <B>class</B><I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I>( cObjeto )<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+    <B>private</B> \r
+      aCameraman:     cObjetoVolador; <I><FONT COLOR="Navy">// Objeto volador que porta la camara </FONT></I>\r
+      aRadioMaximo:   tLongitud;      <I><FONT COLOR="Navy">// Alcance maximo de la camara (los </FONT></I>\r
+                                      <I><FONT COLOR="Navy">//  objetos mas lejanos no se veran) </FONT></I>\r
+      aRadioMinimo:   tLongitud;      <I><FONT COLOR="Navy">// Alcance minimo de la camara (los </FONT></I>\r
+                                      <I><FONT COLOR="Navy">//  objetos mas cercanos no se veran) </FONT></I>\r
+      <I><FONT COLOR="Navy">// Estos 3 ultimos atributos están ligados entre si (y son en parte redundantes) </FONT></I>\r
+      aRadioPantalla: tLongitud;      <I><FONT COLOR="Navy">// Radio de la pantalla. </FONT></I>\r
+      aDistPantalla:  tLongitud;      <I><FONT COLOR="Navy">// Distancia (mínima) hasta la pantalla </FONT></I>\r
+      aCosApertura:   tAngulo;        <I><FONT COLOR="Navy">// Coseno del Angulo de vision de la camara, </FONT></I>\r
+                                      <I><FONT COLOR="Navy">//   se almacena sólo el coseno porque el </FONT></I>\r
+                                      <I><FONT COLOR="Navy">//   ángulo en sí no se usa. </FONT></I>\r
+      aFiltro:        cFiltro;        <I><FONT COLOR="Navy">// Filtro que utiliza la cámara para evaluar </FONT></I>\r
+                                      <I><FONT COLOR="Navy">//  cuales objetos están visibles y cuales no. </FONT></I>\r
\r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Obtiene la proyección del objeto volador en X, Y}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cCamara.mProyectar">mProyectar</A>(ov: cObjetoVolador; <B>var</B> x, y, tam: tLongitud); <B>virtual</B>; <B>abstract</B>; \r
+      <I><FONT COLOR="Navy">{** Devuelve el objeto portador de la cámara}</FONT></I> \r
+      <B>function</B> <A HREF="#cCamara.mGetCameraman">mGetCameraman</A>: cObjetoVolador; \r
+      <I><FONT COLOR="Navy">{** Permite asignar un nuevo portador de la cámara}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cCamara.mSetCameraman">mSetCameraman</A>( oOV: cObjetoVOlador ); \r
+      <I><FONT COLOR="Navy">{** Devuelve distancia a la pantalla}</FONT></I> \r
+      <B>function</B> <A HREF="#cCamara.mGetDistPantalla">mGetDistPantalla</A>: tLongitud; \r
+      <I><FONT COLOR="Navy">{** Devuelve el radio mínimo de detección}</FONT></I> \r
+      <B>function</B> <A HREF="#cCamara.mGetRadioMinimo">mGetRadioMinimo</A>: tLongitud; \r
+      <I><FONT COLOR="Navy">{** Devuelve el radio máximo de detección}</FONT></I> \r
+      <B>function</B> <A HREF="#cCamara.mGetRadioMaximo">mGetRadioMaximo</A>: tLongitud; \r
+      <I><FONT COLOR="Navy">{** Asigna un nuevo filtro}</FONT></I> \r
+      <B>Procedure</B> <A HREF="#cCamara.mSetFiltro">mSetFiltro</A>( filtro: cFiltro ); \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 ); overload; \r
+      <I><FONT COLOR="Navy">{** Procesa una lista de objetos, devolviendo solo los visibles en una lista de records tProyectado \r
+          ordenada ascendentemente por el tamaño proporcional (es decir, el objeto de tamaño menor está primero en la lista).}</FONT></I> \r
+      <B>function</B> <A HREF="#cCamara.mProcesar">mProcesar</A>( l: TList ): cLista; \r
+      <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar \r
+          y la información entregada depende del parámetro tDebugInfo.}</FONT></I> \r
+      <B>function</B> <A HREF="#cCamara.mGetDebugInfo">mGetDebugInfo</A>( debugLevel: tDebugInfo = DI_MINI ): <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Obtiene el radio de la pantalla}</FONT></I> \r
+      <B>function</B> <A HREF="#cCamara.mGetRadioPantalla">mGetRadioPantalla</A>: tLongitud; \r
+  <B>end</B>; \r
\r
\r
+<B>implementation</B> \r
\r
+<B>uses</B> \r
+  Filtros, \r
+  Math; \r
\r
+<I><FONT COLOR="Navy">{** Funcion para ordenar los elementos de la lista que se devuelve \r
+    @param  item1 Item a comparar (puntero) \r
+    @param  item2 Item a comparar (puntero) \r
+    @return       <b>1</b> si item1 > item2<br>&nbsp;&nbsp;&nbsp; \r
+                  <b>-1</b> si item1 < item2<br>&nbsp;&nbsp;&nbsp; \r
+                  <b>0</b> si item1 = item2}</FONT></I> \r
+<B>function</B> listSort( item1, item2: pointer ): integer; \r
+<B>var</B> \r
+  p1, \r
+  p2: tPProy; \r
+<B>begin</B> \r
+  p1 := tPProy( item1 ); \r
+  p2 := tPProy( item2 ); \r
+  result := 0; \r
+  <B>if</B> p1^.tam > p2^.tam <B>then</B> \r
+    result := 1 \r
+  <B>else</B> \r
+    <B>if</B> p1^.tam < p2^.tam <B>then</B> \r
+      result := -1 \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cCamara }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Contructor \r
+    @param cameraman Objeto Volador en el que estará montada la cámara (obligatorio) \r
+    @param angulo         Angulo de apertura (visión) de la cámara (default = pi/4) \r
+    @param maximo         Distancia máxima en la que se considera visible a un objeto (default = 5000) \r
+    @param distPantalla   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default \r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador}</FONT></I> \r
+<B>constructor</B> cCamara.create(cameraman: cObjetoVolador; \r
+  angulo: tAngulo; maximo: tLongitud; \r
+  distPantalla: tLongitud ); \r
+<B>begin</B> \r
+  <B>inherited</B> create; \r
+  aCameraman    := cameraman; \r
+  aRadioMaximo  := maximo; \r
+  aCosApertura  := cos( angulo ); \r
+  <B>if</B> distPantalla > 0 <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Si la distancia es positiva, se la asigna y calcula el radio minimo </FONT></I>\r
+    aDistPantalla := distPantalla; \r
+    <I><FONT COLOR="Navy">// El radio minimo se calcula basado en la formula sen(a) = adyacente / HIPOTENUSA </FONT></I>\r
+    aRadioMinimo  := aDistPantalla / sin( angulo ); \r
+  <B>end</B> <B>else</B> <B>begin</B> <I><FONT COLOR="Navy">// Si es negativo o cero (se paso como default o mal), lo extrae del objeto volador </FONT></I>\r
+    aRadioMinimo  := aCameraman.mGetDimension; \r
+    <I><FONT COLOR="Navy">// La distancia a la pantalla se calcula basado en la formula sen(a) = ADYACENTE / hipotenusa </FONT></I>\r
+    aDistPantalla := sin( angulo ) * aRadioMinimo; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// El radio de la pantalla se calcula basado en la formula cos(a) = OPUESTO / hipotenusa </FONT></I>\r
+  aRadioPantalla := aCosApertura * aRadioMinimo; \r
+  <I><FONT COLOR="Navy">// Crea un filtro frontal </FONT></I>\r
+  aFiltro := cFiltroFrontal.create( aCameraman, angulo, aRadioMaximo, aRadioMinimo ) \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Procesa una lista de objetos, devolviendo solo los visibles en una lista de records tProyectado \r
+    ordenada ascendentemente por el tamaño proporcional (es decir, el objeto de tamaño menor está primero en la lista). \r
+    @return  Lista con los objetos visibles y sus posiciones y tamaños, en un registro \r
+             del tipo <i>tProyectado</i>, ordenados de forma ascendente según el tamaño. \r
+    @param l Lista con los objetos a procesar}</FONT></I> \r
+<B>function</B> <A NAME=cCamara.mProcesar>cCamara.mProcesar</A>( l: TList ): cLista; \r
+<B>var</B> \r
+  lFiltrada:  TList; \r
+  lProcesada: cLista; \r
+  proy: tPProy; \r
+  oOV: cObjetoVolador; \r
+  i: integer; \r
+  x, \r
+  y, \r
+  tam: tLongitud; \r
+  sort: TListSortCompare; \r
\r
+<B>begin</B> \r
+  lProcesada := cLista.create; \r
+  <B>try</B> \r
+    lFiltrada  := aFiltro.mFiltrar( l ); \r
+  <B>except</B> \r
+    on e: EObservadorDestruido <B>do</B> \r
+      <B>raise</B> ECameramanDestruido.create; \r
+  <B>end</B>; \r
+  <B>for</B> i:=0 <B>to</B> lFiltrada.count - 1 <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// recorre la lista de objetos </FONT></I>\r
+    oOV := lFiltrada.items[i]; <I><FONT COLOR="Navy">// obtiene el ObjetoVolador actual </FONT></I>\r
+    new( proy ); \r
+    mProyectar( oOV, x, y, tam ); \r
+    proy^.oOV := oOV; \r
+    proy^.x := x; \r
+    proy^.y := y; \r
+    proy^.tam := tam; \r
+    lProcesada.Add( proy ); \r
+  <B>end</B>; \r
+  sort := listSort; \r
+  lProcesada.Sort( sort ); \r
+  result := lProcesada; \r
+  lFiltrada.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+<I><FONT COLOR="Navy">{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos:<br> \r
+    Siempre devuelve los valores de las componentes x, y, z y si debugLevel es mayor que DI_NORMAL, \r
+    también muestra el módulo. \r
+    @return             Cadena de texto con el estado del Objeto. \r
+    @param   debugLevel Cantidad de información requerida}</FONT></I> \r
+<B>function</B> <A NAME=cCamara.mGetDebugInfo>cCamara.mGetDebugInfo</A>( debugLevel: tDebugInfo ): <B>string</B>; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Construye la cadena dependiendo de la cantidad de informacion que se quiera obtener </FONT></I>\r
+  result := 'Radio Máximo: ' + FloatToStrF( aRadioMaximo, ffNumber, 5, 5 ) + \r
+            ' | Radio Mínimo: ' + FloatToStrF( aRadioMinimo, ffNumber, 5, 5 ) + \r
+            ' | Radio de Pantalla: ' + FloatToStrF( aRadioPantalla, ffNumber, 5, 5 ) + \r
+            ' | Distancia de Pantalla: ' + FloatToStrF( aDistPantalla, ffNumber, 5, 5 ); \r
+  <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
+    <B>if</B> debugLevel = DI_NORMAL <B>then</B> \r
+      result := result + #13 + #10 + \r
+                'Cameraman: ' + aCameraman.mGetDebugInfo; \r
+    <B>if</B> debugLevel = DI_MAXI <B>then</B> \r
+      result := result + #13 + #10 + \r
+                'Cameraman: ' + aCameraman.mGetDebugInfo( debugLevel ); <I><FONT COLOR="Navy">// + #13 + #10 + </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
+    on e: EAccessViolation <B>do</B> \r
+      <B>raise</B> ECameramanDestruido.create; <I><FONT COLOR="Navy">// Creamos una nueva excepcion especial </FONT></I>\r
+  <B>end</B>; \r
+<B>end</B>; \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el radio de la pantalla \r
+    @return Radio de la pantalla}</FONT></I> \r
+<B>function</B> <A NAME=cCamara.mGetRadioPantalla>cCamara.mGetRadioPantalla</A>: tLongitud; \r
+<B>begin</B> \r
+  result := aRadioPantalla; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve el objeto portador de la cámara \r
+    @return Objeto portador de la cámara}</FONT></I> \r
+<B>function</B> <A NAME=cCamara.mGetCameraman>cCamara.mGetCameraman</A>: cObjetoVolador; \r
+<B>begin</B> \r
+  result := aCameraman; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Permite asignar un nuevo portador de la cámara \r
+    @param oOV Objeto volador que será en nuevo portador de la cámara}</FONT></I> \r
+<B>procedure</B> <A NAME=cCamara.mSetCameraman>cCamara.mSetCameraman</A>(oOV: cObjetoVOlador); \r
+<B>begin</B> \r
+  aCameraman := oOV; \r
+  aFiltro.mSetObservador( oOV ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve distancia a la pantalla \r
+    @return Distancia a la pantalla}</FONT></I> \r
+<B>function</B> <A NAME=cCamara.mGetDistPantalla>cCamara.mGetDistPantalla</A>: tLongitud; \r
+<B>begin</B> \r
+  result:=aDistPantalla; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve el radio mínimo de detección \r
+    @return Radio mínimo de detección}</FONT></I> \r
+<B>function</B> <A NAME=cCamara.mGetRadioMaximo>cCamara.mGetRadioMaximo</A>: tLongitud; \r
+<B>begin</B> \r
+  result:=aRadioMaximo; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve el radio máximo de detección \r
+    @return Radio máximo de detección}</FONT></I> \r
+<B>function</B> <A NAME=cCamara.mGetRadioMinimo>cCamara.mGetRadioMinimo</A>: tLongitud; \r
+<B>begin</B> \r
+  result:=aRadioMinimo; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Asigna un nuevo filtro}</FONT></I> \r
+<B>procedure</B> <A NAME=cCamara.mSetFiltro>cCamara.mSetFiltro</A>(filtro: cFiltro); \r
+<B>begin</B> \r
+  aFiltro.free; \r
+  aFiltro := filtro; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ ECameramanDestruido }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+<B>constructor</B> ECameramanDestruido.create; \r
+<B>begin</B> \r
+  <B>inherited</B> create( 'El Cameraman fue destruido.' ); \r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/vista/Camaras.pas b/doc/src-html/vista/Camaras.pas
new file mode 100644 (file)
index 0000000..c947afa
--- /dev/null
@@ -0,0 +1,640 @@
+<HTML><HEAD>\r
+<TITLE>File: camaras.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=camaras.pas><CENTER><H3>camaras.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Se implementan varias cámaras en diferentes direcciones.<br> \r
+    <i>Cambios:</i> \r
+    <PRE> \r
+    09/12/00: Se agrega la clase cCamaraMapa. \r
+    </PRE>}</FONT></I> \r
+<B>unit</B> Camaras; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  SysUtils, \r
+  Camara, \r
+  Tipos, \r
+  Vectores, \r
+  ObjetoVolador, \r
+  Lista; \r
\r
+<B>type</B> \r
+  <I><FONT COLOR="Navy">{** Implementa una cámara frontal.}</FONT></I> \r
+  cCamaraFrontal = <B>class</B>( cCamara ) \r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Obtiene la proyección del objeto volador en X, Y}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cCamaraFrontal.mProyectar">mProyectar</A>(ov: cObjetoVolador; <B>var</B> x, y, tam: tLongitud); <B>override</B>; \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 ); \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Implementa una cámara lateral derecha.}</FONT></I> \r
+  cCamaraLatDer = <B>class</B>( cCamara ) \r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Obtiene la proyección del objeto volador en X, Y}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cCamaraLatDer.mProyectar">mProyectar</A>(ov: cObjetoVolador; <B>var</B> x, y, tam: tLongitud); <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 ); \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Implementa una cámara lateral izquierda.}</FONT></I> \r
+  cCamaraLatIzq = <B>class</B>( cCamara ) \r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Obtiene la proyección del objeto volador en X, Y}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cCamaraLatIzq.mProyectar">mProyectar</A>(ov: cObjetoVolador; <B>var</B> x, y, tam: tLongitud); <B>override</B>; \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 ); \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Implementa una cámara trasera.}</FONT></I> \r
+  cCamaraTrasera = <B>class</B>( cCamara ) \r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Obtiene la proyección del objeto volador en X, Y}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cCamaraTrasera.mProyectar">mProyectar</A>(ov: cObjetoVolador; <B>var</B> x, y, tam: tLongitud); <B>override</B>; \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 ); \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Implementa una cámara para ver hacia arriba.}</FONT></I> \r
+  cCamaraArriba = <B>class</B>( cCamara ) \r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Obtiene la proyección del objeto volador en X, Y}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cCamaraArriba.mProyectar">mProyectar</A>(ov: cObjetoVolador; <B>var</B> x, y, tam: tLongitud); <B>override</B>; \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 ); \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Implementa una cámara para ver hacia abajo.}</FONT></I> \r
+  cCamaraAbajo = <B>class</B>( cCamara ) \r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Obtiene la proyección del objeto volador en X, Y}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cCamaraAbajo.mProyectar">mProyectar</A>(ov: cObjetoVolador; <B>var</B> x, y, tam: tLongitud); <B>override</B>; \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 ); \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Implementa una cámara para ver hacia abajo pero alejado del cameraman. \r
+      Es como si observara al cameraman desde arriba.}</FONT></I> \r
+  cCamaraMapa = <B>class</B>( cCamara ) \r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Obtiene la proyección del objeto volador en X, Y}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cCamaraMapa.mProyectar">mProyectar</A>(ov: cObjetoVolador; <B>var</B> x, y, tam: tLongitud); <B>override</B>; \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 ); \r
+  <B>end</B>; \r
\r
+<B>implementation</B> \r
\r
+<B>uses</B> \r
+  Filtros; \r
\r
+<I><FONT COLOR="Navy">{ cCamaraFrontal }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Contructor \r
+    @param cameraman Objeto Volador en el que estará montada la cámara (obligatorio) \r
+    @param angulo         Angulo de apertura (visión) de la cámara (default = pi/4) \r
+    @param maximo         Distancia máxima en la que se considera visible a un objeto (default = 5000) \r
+    @param distPantalla   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default \r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador}</FONT></I> \r
+<B>constructor</B> cCamaraFrontal.create(cameraman: cObjetoVolador; angulo: tAngulo; maximo: tLongitud; distPantalla: tLongitud); \r
+<B>begin</B> \r
+  <B>inherited</B> create(cameraman, angulo, maximo, distPantalla ); \r
+  mSetFiltro( cFiltroFrontal.create( Cameraman, angulo, maximo, mGetRadioMinimo ) ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la proyección del objeto volador en X, Y \r
+    @param ov  Objeto volador a proyectar. \r
+    @param x   Valor de la proyección en X. \r
+    @param x   Valor de la proyección en Y. \r
+    @param tam Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es). \r
+               Varia entre 0 y 1}</FONT></I> \r
+<B>procedure</B> <A NAME=cCamaraFrontal.mProyectar>cCamaraFrontal.mProyectar</A>(ov: cObjetoVolador; <B>var</B> x, y, tam: tLongitud); \r
+<B>var</B> \r
+  posCam, \r
+  i, \r
+  vX, \r
+  vY, \r
+  v, \r
+  O, \r
+  OI: cVector; \r
+  distMax, \r
+  tmp: tLongitud; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Lo primero que hay que hacer es hallar OI, para eso utilizaremos la siguiente formula: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  OI = O.(d/D.O) </FONT></I>\r
+  <I><FONT COLOR="Navy">// En nuetro caso seria: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  OI =   O . aDistPantalla </FONT></I>\r
+  <I><FONT COLOR="Navy">//        aCameraman.mGetI . 0 </FONT></I>\r
+  <I><FONT COLOR="Navy">// Donde O = ov.mGetPosicion - aCameraman.mGetPosicion </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
+    posCam := mGetCameraman.mGetPosicion; \r
+  <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
+    on e: EAccessViolation <B>do</B> <B>raise</B> ECameramanDestruido.create; <I><FONT COLOR="Navy">// Creamos una nueva excepcion especial </FONT></I>\r
+  <B>end</B>; \r
+  i := mGetCameraman.mGetI; \r
+  O := ov.mGetPosicion.mRestar( posCam ); \r
+  OI := cVector.create( O ).mMultiplicar( mGetDistPantalla / i.mMultiplicarEsc( O ) ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos el vector v que pertenece a la pantalla, que nos dara las nuevas coordenadas respecto de ella. </FONT></I>\r
+  <I><FONT COLOR="Navy">//  v = OI - d.D </FONT></I>\r
+  <I><FONT COLOR="Navy">// En nuestro caso: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  v = OI - ( aCameraman.mGetCoordenadas.mGetI . aDistPantalla ) </FONT></I>\r
+  v := cVector.create( OI ).mRestar( i.mMultiplicar( mGetDistPantalla ) ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos su proyeccion en el versor -j (que sera nuestro X de la pantalla) </FONT></I>\r
+  <I><FONT COLOR="Navy">//  Es -j porque tomaremos positivo hacia la derecha. </FONT></I>\r
+  vX := mGetCameraman.mGetJ.mMultiplicar( -1 ); \r
+  x := v.mMultiplicarEsc( vX ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos su proyeccion en el versor k (que sera nuestro Y de la pantalla) </FONT></I>\r
+  vY := mGetCameraman.mGetK; \r
+  y := v.mMultiplicarEsc( vY ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos el tamaño proporcional (un numero entre 0 y 1, donde 0 es </FONT></I>\r
+  <I><FONT COLOR="Navy">//  lo mas lejano y 1 lo mas cercano). Se calcula de la siguiente forma: </FONT></I>\r
+  <I><FONT COLOR="Navy">// tam = 1  -      |O| - aRadioMinimo </FONT></I>\r
+  <I><FONT COLOR="Navy">//              aRadioMaximo - aRadioMinimo </FONT></I>\r
+  <I><FONT COLOR="Navy">// Donde O es el vector posicion respecto de la camara, y el " 1 - xxx ", es porque cuanto mas </FONT></I>\r
+  <I><FONT COLOR="Navy">//  lejos, menor tiene que ser el tamaño </FONT></I>\r
+  tmp := O.mGetModulo - mGetRadioMinimo; \r
+  distMax := mGetRadioMaximo - mGetRadioMinimo; \r
+  tam := 1 - (tmp / distMax); \r
+  i.free; \r
+  posCam.free; \r
+  v.free; \r
+  vX.free; \r
+  vY.free; \r
+  OI.free; \r
+  O.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cCamaraLatIzq }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Contructor \r
+    @param cameraman Objeto Volador en el que estará montada la cámara (obligatorio) \r
+    @param angulo         Angulo de apertura (visión) de la cámara (default = pi/4) \r
+    @param maximo         Distancia máxima en la que se considera visible a un objeto (default = 5000) \r
+    @param distPantalla   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default \r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador}</FONT></I> \r
+<B>constructor</B> cCamaraLatIzq.create(cameraman: cObjetoVolador; angulo: tAngulo; maximo: tLongitud; distPantalla: tLongitud); \r
+<B>begin</B> \r
+  <B>inherited</B> create(cameraman, angulo, maximo, distPantalla ); \r
+  mSetFiltro( cFiltroLatIzq.create( Cameraman, angulo, maximo, mGetRadioMinimo ) ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la proyección del objeto volador en X, Y \r
+    @param ov  Objeto volador a proyectar. \r
+    @param x   Valor de la proyección en X. \r
+    @param x   Valor de la proyección en Y. \r
+    @param tam Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es). \r
+               Varia entre 0 y 1}</FONT></I> \r
+<B>procedure</B> <A NAME=cCamaraLatIzq.mProyectar>cCamaraLatIzq.mProyectar</A>(ov: cObjetoVolador; <B>var</B> x, y, tam: tLongitud); \r
+<B>var</B> \r
+  posCam, \r
+  i, \r
+  vX, \r
+  vY, \r
+  v, \r
+  O, \r
+  OI: cVector; \r
+  distMax, \r
+  tmp: tLongitud; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Lo primero que hay que hacer es hallar OI, para eso utilizaremos la siguiente formula: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  OI = O.(d/D.O) </FONT></I>\r
+  <I><FONT COLOR="Navy">// En nuetro caso seria: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  OI =   O . aDistPantalla </FONT></I>\r
+  <I><FONT COLOR="Navy">//        aCameraman.mGetI . 0 </FONT></I>\r
+  <I><FONT COLOR="Navy">// Donde O = ov.mGetPosicion - mGetCameraman.mGetPosicion </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
+    posCam := mGetCameraman.mGetPosicion; \r
+  <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
+    on e: EAccessViolation <B>do</B> <B>raise</B> ECameramanDestruido.create; <I><FONT COLOR="Navy">// Creamos una nueva excepcion especial </FONT></I>\r
+  <B>end</B>; \r
+  i := mGetCameraman.mGetJ; \r
+  O := ov.mGetPosicion.mRestar( posCam ); \r
+  OI := cVector.create( O ).mMultiplicar( mGetDistPantalla / i.mMultiplicarEsc( O ) ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos el vector v que pertenece a la pantalla, que nos dara las nuevas coordenadas respecto de ella. </FONT></I>\r
+  <I><FONT COLOR="Navy">//  v = OI - d.D </FONT></I>\r
+  <I><FONT COLOR="Navy">// En nuestro caso: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  v = OI - ( aCameraman.mGetCoordenadas.mGetI . aDistPantalla ) </FONT></I>\r
+  v := cVector.create( OI ).mRestar( i.mMultiplicar( mGetDistPantalla ) ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos su proyeccion en el versor -j (que sera nuestro X de la pantalla) </FONT></I>\r
+  <I><FONT COLOR="Navy">//  Es -j porque tomaremos positivo hacia la derecha. </FONT></I>\r
+  vX := mGetCameraman.mGetI; \r
+  x := v.mMultiplicarEsc( vX ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos su proyeccion en el versor k (que sera nuestro Y de la pantalla) </FONT></I>\r
+  vY := mGetCameraman.mGetK; \r
+  y := v.mMultiplicarEsc( vY ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos el tamaño proporcional (un numero entre 0 y 1, donde 0 es </FONT></I>\r
+  <I><FONT COLOR="Navy">//  lo mas lejano y 1 lo mas cercano). Se calcula de la siguiente forma: </FONT></I>\r
+  <I><FONT COLOR="Navy">// tam = 1  -      |O| - aRadioMinimo </FONT></I>\r
+  <I><FONT COLOR="Navy">//              aRadioMaximo - aRadioMinimo </FONT></I>\r
+  <I><FONT COLOR="Navy">// Donde O es el vector posicion respecto de la camara, y el " 1 - xxx ", es porque cuanto mas </FONT></I>\r
+  <I><FONT COLOR="Navy">//  lejos, menor tiene que ser el tamaño </FONT></I>\r
+  tmp := O.mGetModulo - mGetRadioMinimo; \r
+  distMax := mGetRadioMaximo - mGetRadioMinimo; \r
+  tam := 1 - (tmp / distMax); \r
+  i.free; \r
+  posCam.free; \r
+  v.free; \r
+  vX.free; \r
+  vY.free; \r
+  OI.free; \r
+  O.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cCamaraLatDer }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Contructor \r
+    @param cameraman Objeto Volador en el que estará montada la cámara (obligatorio) \r
+    @param angulo         Angulo de apertura (visión) de la cámara (default = pi/4) \r
+    @param maximo         Distancia máxima en la que se considera visible a un objeto (default = 5000) \r
+    @param distPantalla   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default \r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador}</FONT></I> \r
+<B>constructor</B> cCamaraLatDer.create(cameraman: cObjetoVolador; angulo: tAngulo; maximo: tLongitud; distPantalla: tLongitud); \r
+<B>begin</B> \r
+  <B>inherited</B> create(cameraman, angulo, maximo, distPantalla ); \r
+  mSetFiltro( cFiltroLatDer.create( Cameraman, angulo, maximo, mGetRadioMinimo ) ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la proyección del objeto volador en X, Y \r
+    @param ov  Objeto volador a proyectar. \r
+    @param x   Valor de la proyección en X. \r
+    @param x   Valor de la proyección en Y. \r
+    @param tam Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es). \r
+               Varia entre 0 y 1}</FONT></I> \r
+<B>procedure</B> <A NAME=cCamaraLatDer.mProyectar>cCamaraLatDer.mProyectar</A>(ov: cObjetoVolador; <B>var</B> x, y, tam: tLongitud); \r
+<B>var</B> \r
+  posCam, \r
+  i, \r
+  vX, \r
+  vY, \r
+  v, \r
+  O, \r
+  OI: cVector; \r
+  distMax, \r
+  tmp: tLongitud; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Lo primero que hay que hacer es hallar OI, para eso utilizaremos la siguiente formula: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  OI = O.(d/D.O) </FONT></I>\r
+  <I><FONT COLOR="Navy">// En nuetro caso seria: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  OI =   O . aDistPantalla </FONT></I>\r
+  <I><FONT COLOR="Navy">//        aCameraman.mGetI . 0 </FONT></I>\r
+  <I><FONT COLOR="Navy">// Donde O = ov.mGetPosicion - mGetCameraman.mGetPosicion </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
+    posCam := mGetCameraman.mGetPosicion; \r
+  <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
+    on e: EAccessViolation <B>do</B> <B>raise</B> ECameramanDestruido.create; <I><FONT COLOR="Navy">// Creamos una nueva excepcion especial </FONT></I>\r
+  <B>end</B>; \r
+  i := mGetCameraman.mGetJ.mMultiplicar(-1); \r
+  O := ov.mGetPosicion.mRestar( posCam ); \r
+  OI := cVector.create( O ).mMultiplicar( mGetDistPantalla / i.mMultiplicarEsc( O ) ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos el vector v que pertenece a la pantalla, que nos dara las nuevas coordenadas respecto de ella. </FONT></I>\r
+  <I><FONT COLOR="Navy">//  v = OI - d.D </FONT></I>\r
+  <I><FONT COLOR="Navy">// En nuestro caso: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  v = OI - ( aCameraman.mGetCoordenadas.mGetI . aDistPantalla ) </FONT></I>\r
+  v := cVector.create( OI ).mRestar( i.mMultiplicar( mGetDistPantalla ) ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos su proyeccion en el versor -j (que sera nuestro X de la pantalla) </FONT></I>\r
+  <I><FONT COLOR="Navy">//  Es -j porque tomaremos positivo hacia la derecha. </FONT></I>\r
+  vX := mGetCameraman.mGetI.mMultiplicar(-1); \r
+  x := v.mMultiplicarEsc( vX ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos su proyeccion en el versor k (que sera nuestro Y de la pantalla) </FONT></I>\r
+  vY := mGetCameraman.mGetK; \r
+  y := v.mMultiplicarEsc( vY ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos el tamaño proporcional (un numero entre 0 y 1, donde 0 es </FONT></I>\r
+  <I><FONT COLOR="Navy">//  lo mas lejano y 1 lo mas cercano). Se calcula de la siguiente forma: </FONT></I>\r
+  <I><FONT COLOR="Navy">// tam = 1  -      |O| - aRadioMinimo </FONT></I>\r
+  <I><FONT COLOR="Navy">//              aRadioMaximo - aRadioMinimo </FONT></I>\r
+  <I><FONT COLOR="Navy">// Donde O es el vector posicion respecto de la camara, y el " 1 - xxx ", es porque cuanto mas </FONT></I>\r
+  <I><FONT COLOR="Navy">//  lejos, menor tiene que ser el tamaño </FONT></I>\r
+  tmp := O.mGetModulo - mGetRadioMinimo; \r
+  distMax := mGetRadioMaximo - mGetRadioMinimo; \r
+  tam := 1 - (tmp / distMax); \r
+  i.free; \r
+  posCam.free; \r
+  v.free; \r
+  vX.free; \r
+  vY.free; \r
+  OI.free; \r
+  O.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cCamaraTrasera }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Contructor \r
+    @param cameraman Objeto Volador en el que estará montada la cámara (obligatorio) \r
+    @param angulo         Angulo de apertura (visión) de la cámara (default = pi/4) \r
+    @param maximo         Distancia máxima en la que se considera visible a un objeto (default = 5000) \r
+    @param distPantalla   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default \r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador}</FONT></I> \r
+<B>constructor</B> cCamaraTrasera.create(cameraman: cObjetoVolador; angulo: tAngulo; maximo: tLongitud; distPantalla: tLongitud); \r
+<B>begin</B> \r
+  <B>inherited</B> create(cameraman, angulo, maximo, distPantalla ); \r
+  mSetFiltro( cFiltroTrasero.create( Cameraman, angulo, maximo, mGetRadioMinimo ) ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la proyección del objeto volador en X, Y \r
+    @param ov  Objeto volador a proyectar. \r
+    @param x   Valor de la proyección en X. \r
+    @param x   Valor de la proyección en Y. \r
+    @param tam Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es). \r
+               Varia entre 0 y 1}</FONT></I> \r
+<B>procedure</B> <A NAME=cCamaraTrasera.mProyectar>cCamaraTrasera.mProyectar</A>(ov: cObjetoVolador; <B>var</B> x, y, tam: tLongitud); \r
+<B>var</B> \r
+  posCam, \r
+  i, \r
+  vX, \r
+  vY, \r
+  v, \r
+  O, \r
+  OI: cVector; \r
+  distMax, \r
+  tmp: tLongitud; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Lo primero que hay que hacer es hallar OI, para eso utilizaremos la siguiente formula: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  OI = O.(d/D.O) </FONT></I>\r
+  <I><FONT COLOR="Navy">// En nuetro caso seria: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  OI =   O . aDistPantalla </FONT></I>\r
+  <I><FONT COLOR="Navy">//        aCameraman.mGetI . 0 </FONT></I>\r
+  <I><FONT COLOR="Navy">// Donde O = ov.mGetPosicion - mGetCameraman.mGetPosicion </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
+    posCam := mGetCameraman.mGetPosicion; \r
+  <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
+    on e: EAccessViolation <B>do</B> <B>raise</B> ECameramanDestruido.create; <I><FONT COLOR="Navy">// Creamos una nueva excepcion especial </FONT></I>\r
+  <B>end</B>; \r
+  i := mGetCameraman.mGetI.mMultiplicar(-1); \r
+  O := ov.mGetPosicion.mRestar( posCam ); \r
+  OI := cVector.create( O ).mMultiplicar( mGetDistPantalla / i.mMultiplicarEsc( O ) ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos el vector v que pertenece a la pantalla, que nos dara las nuevas coordenadas respecto de ella. </FONT></I>\r
+  <I><FONT COLOR="Navy">//  v = OI - d.D </FONT></I>\r
+  <I><FONT COLOR="Navy">// En nuestro caso: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  v = OI - ( aCameraman.mGetCoordenadas.mGetI . aDistPantalla ) </FONT></I>\r
+  v := cVector.create( OI ).mRestar( i.mMultiplicar( mGetDistPantalla ) ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos su proyeccion en el versor -j (que sera nuestro X de la pantalla) </FONT></I>\r
+  <I><FONT COLOR="Navy">//  Es -j porque tomaremos positivo hacia la derecha. </FONT></I>\r
+  vX := mGetCameraman.mGetJ; \r
+  x := v.mMultiplicarEsc( vX ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos su proyeccion en el versor k (que sera nuestro Y de la pantalla) </FONT></I>\r
+  vY := mGetCameraman.mGetK; \r
+  y := v.mMultiplicarEsc( vY ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos el tamaño proporcional (un numero entre 0 y 1, donde 0 es </FONT></I>\r
+  <I><FONT COLOR="Navy">//  lo mas lejano y 1 lo mas cercano). Se calcula de la siguiente forma: </FONT></I>\r
+  <I><FONT COLOR="Navy">// tam = 1  -      |O| - aRadioMinimo </FONT></I>\r
+  <I><FONT COLOR="Navy">//              aRadioMaximo - aRadioMinimo </FONT></I>\r
+  <I><FONT COLOR="Navy">// Donde O es el vector posicion respecto de la camara, y el " 1 - xxx ", es porque cuanto mas </FONT></I>\r
+  <I><FONT COLOR="Navy">//  lejos, menor tiene que ser el tamaño </FONT></I>\r
+  tmp := O.mGetModulo - mGetRadioMinimo; \r
+  distMax := mGetRadioMaximo - mGetRadioMinimo; \r
+  tam := 1 - (tmp / distMax); \r
+  i.free; \r
+  posCam.free; \r
+  v.free; \r
+  vX.free; \r
+  vY.free; \r
+  OI.free; \r
+  O.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cCamaraArriba }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Contructor \r
+    @param cameraman Objeto Volador en el que estará montada la cámara (obligatorio) \r
+    @param angulo         Angulo de apertura (visión) de la cámara (default = pi/4) \r
+    @param maximo         Distancia máxima en la que se considera visible a un objeto (default = 5000) \r
+    @param distPantalla   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default \r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador}</FONT></I> \r
+<B>constructor</B> cCamaraArriba.create(cameraman: cObjetoVolador; angulo: tAngulo; maximo: tLongitud; distPantalla: tLongitud); \r
+<B>begin</B> \r
+  <B>inherited</B> create(cameraman, angulo, maximo, distPantalla ); \r
+  mSetFiltro( cFiltroArriba.create( Cameraman, angulo, maximo, mGetRadioMinimo ) ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la proyección del objeto volador en X, Y \r
+    @param ov  Objeto volador a proyectar. \r
+    @param x   Valor de la proyección en X. \r
+    @param x   Valor de la proyección en Y. \r
+    @param tam Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es). \r
+               Varia entre 0 y 1}</FONT></I> \r
+<B>procedure</B> <A NAME=cCamaraArriba.mProyectar>cCamaraArriba.mProyectar</A>(ov: cObjetoVolador; <B>var</B> x, y, tam: tLongitud); \r
+<B>var</B> \r
+  posCam, \r
+  i, \r
+  vX, \r
+  vY, \r
+  v, \r
+  O, \r
+  OI: cVector; \r
+  distMax, \r
+  tmp: tLongitud; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Lo primero que hay que hacer es hallar OI, para eso utilizaremos la siguiente formula: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  OI = O.(d/D.O) </FONT></I>\r
+  <I><FONT COLOR="Navy">// En nuetro caso seria: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  OI =   O . aDistPantalla </FONT></I>\r
+  <I><FONT COLOR="Navy">//        aCameraman.mGetI . 0 </FONT></I>\r
+  <I><FONT COLOR="Navy">// Donde O = ov.mGetPosicion - mGetCameraman.mGetPosicion </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
+    posCam := mGetCameraman.mGetPosicion; \r
+  <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
+    on e: EAccessViolation <B>do</B> <B>raise</B> ECameramanDestruido.create; <I><FONT COLOR="Navy">// Creamos una nueva excepcion especial </FONT></I>\r
+  <B>end</B>; \r
+  i := mGetCameraman.mGetk; \r
+  O := ov.mGetPosicion.mRestar( posCam ); \r
+  OI := cVector.create( O ).mMultiplicar( mGetDistPantalla / i.mMultiplicarEsc( O ) ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos el vector v que pertenece a la pantalla, que nos dara las nuevas coordenadas respecto de ella. </FONT></I>\r
+  <I><FONT COLOR="Navy">//  v = OI - d.D </FONT></I>\r
+  <I><FONT COLOR="Navy">// En nuestro caso: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  v = OI - ( aCameraman.mGetCoordenadas.mGetI . aDistPantalla ) </FONT></I>\r
+  v := cVector.create( OI ).mRestar( i.mMultiplicar( mGetDistPantalla ) ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos su proyeccion en el versor -j (que sera nuestro X de la pantalla) </FONT></I>\r
+  <I><FONT COLOR="Navy">//  Es -j porque tomaremos positivo hacia la derecha. </FONT></I>\r
+  vX := mGetCameraman.mGetJ; \r
+  x := v.mMultiplicarEsc( vX ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos su proyeccion en el versor k (que sera nuestro Y de la pantalla) </FONT></I>\r
+  vY := mGetCameraman.mGetI.mMultiplicar(-1); \r
+  y := v.mMultiplicarEsc( vY ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos el tamaño proporcional (un numero entre 0 y 1, donde 0 es </FONT></I>\r
+  <I><FONT COLOR="Navy">//  lo mas lejano y 1 lo mas cercano). Se calcula de la siguiente forma: </FONT></I>\r
+  <I><FONT COLOR="Navy">// tam = 1  -      |O| - aRadioMinimo </FONT></I>\r
+  <I><FONT COLOR="Navy">//              aRadioMaximo - aRadioMinimo </FONT></I>\r
+  <I><FONT COLOR="Navy">// Donde O es el vector posicion respecto de la camara, y el " 1 - xxx ", es porque cuanto mas </FONT></I>\r
+  <I><FONT COLOR="Navy">//  lejos, menor tiene que ser el tamaño </FONT></I>\r
+  tmp := O.mGetModulo - mGetRadioMinimo; \r
+  distMax := mGetRadioMaximo - mGetRadioMinimo; \r
+  tam := 1 - (tmp / distMax); \r
+  i.free; \r
+  posCam.free; \r
+  v.free; \r
+  vX.free; \r
+  vY.free; \r
+  OI.free; \r
+  O.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cCamaraLatAbajo }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Contructor \r
+    @param cameraman Objeto Volador en el que estará montada la cámara (obligatorio) \r
+    @param angulo         Angulo de apertura (visión) de la cámara (default = pi/4) \r
+    @param maximo         Distancia máxima en la que se considera visible a un objeto (default = 5000) \r
+    @param distPantalla   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default \r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador}</FONT></I> \r
+<B>constructor</B> cCamaraAbajo.create(cameraman: cObjetoVolador; angulo: tAngulo; maximo: tLongitud; distPantalla: tLongitud); \r
+<B>begin</B> \r
+  <B>inherited</B> create(cameraman, angulo, maximo, distPantalla ); \r
+  mSetFiltro( cFiltroAbajo.create( Cameraman, angulo, maximo, mGetRadioMinimo ) ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la proyección del objeto volador en X, Y \r
+    @param ov  Objeto volador a proyectar. \r
+    @param x   Valor de la proyección en X. \r
+    @param x   Valor de la proyección en Y. \r
+    @param tam Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es). \r
+               Varia entre 0 y 1}</FONT></I> \r
+<B>procedure</B> <A NAME=cCamaraAbajo.mProyectar>cCamaraAbajo.mProyectar</A>(ov: cObjetoVolador; <B>var</B> x, y, tam: tLongitud); \r
+<B>var</B> \r
+  posCam, \r
+  i, \r
+  vX, \r
+  vY, \r
+  v, \r
+  O, \r
+  OI: cVector; \r
+  distMax, \r
+  tmp: tLongitud; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Lo primero que hay que hacer es hallar OI, para eso utilizaremos la siguiente formula: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  OI = O.(d/D.O) </FONT></I>\r
+  <I><FONT COLOR="Navy">// En nuetro caso seria: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  OI =   O . aDistPantalla </FONT></I>\r
+  <I><FONT COLOR="Navy">//        aCameraman.mGetI . 0 </FONT></I>\r
+  <I><FONT COLOR="Navy">// Donde O = ov.mGetPosicion - mGetCameraman.mGetPosicion </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
+    posCam := mGetCameraman.mGetPosicion; \r
+  <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
+    on e: EAccessViolation <B>do</B> <B>raise</B> ECameramanDestruido.create; <I><FONT COLOR="Navy">// Creamos una nueva excepcion especial </FONT></I>\r
+  <B>end</B>; \r
+  i := mGetCameraman.mGetk.mMultiplicar(-1); \r
+  O := ov.mGetPosicion.mRestar( posCam ); \r
+  OI := cVector.create( O ).mMultiplicar( mGetDistPantalla / i.mMultiplicarEsc( O ) ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos el vector v que pertenece a la pantalla, que nos dara las nuevas coordenadas respecto de ella. </FONT></I>\r
+  <I><FONT COLOR="Navy">//  v = OI - d.D </FONT></I>\r
+  <I><FONT COLOR="Navy">// En nuestro caso: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  v = OI - ( aCameraman.mGetCoordenadas.mGetI . aDistPantalla ) </FONT></I>\r
+  v := cVector.create( OI ).mRestar( i.mMultiplicar( mGetDistPantalla ) ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos su proyeccion en el versor -j (que sera nuestro X de la pantalla) </FONT></I>\r
+  <I><FONT COLOR="Navy">//  Es -j porque tomaremos positivo hacia la derecha. </FONT></I>\r
+  vX := mGetCameraman.mGetj.mMultiplicar(-1); \r
+  x := v.mMultiplicarEsc( vX ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos su proyeccion en el versor k (que sera nuestro Y de la pantalla) </FONT></I>\r
+  vY := mGetCameraman.mGetI; \r
+  y := v.mMultiplicarEsc( vY ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos el tamaño proporcional (un numero entre 0 y 1, donde 0 es </FONT></I>\r
+  <I><FONT COLOR="Navy">//  lo mas lejano y 1 lo mas cercano). Se calcula de la siguiente forma: </FONT></I>\r
+  <I><FONT COLOR="Navy">// tam = 1  -      |O| - aRadioMinimo </FONT></I>\r
+  <I><FONT COLOR="Navy">//              aRadioMaximo - aRadioMinimo </FONT></I>\r
+  <I><FONT COLOR="Navy">// Donde O es el vector posicion respecto de la camara, y el " 1 - xxx ", es porque cuanto mas </FONT></I>\r
+  <I><FONT COLOR="Navy">//  lejos, menor tiene que ser el tamaño </FONT></I>\r
+  tmp := O.mGetModulo - mGetRadioMinimo; \r
+  distMax := mGetRadioMaximo - mGetRadioMinimo; \r
+  tam := 1 - (tmp / distMax); \r
+  i.free; \r
+  posCam.free; \r
+  v.free; \r
+  vX.free; \r
+  vY.free; \r
+  OI.free; \r
+  O.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cCamaraMapa }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Contructor \r
+    @param cameraman Objeto Volador en el que estará montada la cámara (obligatorio) \r
+    @param angulo         Angulo de apertura (visión) de la cámara (default = pi/4) \r
+    @param maximo         Distancia máxima en la que se considera visible a un objeto (default = 5000) \r
+    @param distPantalla   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default \r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador}</FONT></I> \r
+<B>constructor</B> cCamaraMapa.create(cameraman: cObjetoVolador; angulo: tAngulo; maximo: tLongitud; distPantalla: tLongitud); \r
+<B>begin</B> \r
+  <B>inherited</B> create(cameraman, angulo, 5000<I><FONT COLOR="Navy">{max}</FONT></I>, 1000<I><FONT COLOR="Navy">{min}</FONT></I> ); \r
+  mSetFiltro( cFiltroMapa.create( Cameraman, angulo, 5000<I><FONT COLOR="Navy">{max}</FONT></I>, mGetRadioMinimo ) ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene la proyección del objeto volador en X, Y \r
+    @param ov  Objeto volador a proyectar. \r
+    @param x   Valor de la proyección en X. \r
+    @param x   Valor de la proyección en Y. \r
+    @param tam Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es). \r
+               Varia entre 0 y 1}</FONT></I> \r
+<B>procedure</B> <A NAME=cCamaraMapa.mProyectar>cCamaraMapa.mProyectar</A>(ov: cObjetoVolador; <B>var</B> x, y, tam: tLongitud); \r
+<B>var</B> \r
+  desplazamiento, \r
+  posCam, \r
+  i, \r
+  vX, \r
+  vY, \r
+  v, \r
+  O, \r
+  OI: cVector; \r
+  distMax, \r
+  tmp: tLongitud; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Lo primero que hay que hacer es hallar OI, para eso utilizaremos la siguiente formula: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  OI = O.(d/D.O) </FONT></I>\r
+  <I><FONT COLOR="Navy">// En nuetro caso seria: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  OI =   O . aDistPantalla </FONT></I>\r
+  <I><FONT COLOR="Navy">//        aCameraman.mGetI . 0 </FONT></I>\r
+  <I><FONT COLOR="Navy">// Donde O = ov.mGetPosicion - mGetCameraman.mGetPosicion </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
+    desplazamiento := mGetCameraman.mGetk.mSetModulo( 3000 ); <I><FONT COLOR="Navy">// Esta 3000 metros alejado del cameraman </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
+    on e: EAccessViolation <B>do</B> <B>raise</B> ECameramanDestruido.create; <I><FONT COLOR="Navy">// Creamos una nueva excepcion especial </FONT></I>\r
+  <B>end</B>; \r
+  posCam := mGetCameraman.mGetPosicion.mSumar( desplazamiento ); \r
+  desplazamiento.free; \r
+  i := mGetCameraman.mGetk.mMultiplicar(-1); \r
+  O := ov.mGetPosicion.mRestar( posCam ); \r
+  OI := cVector.create( O ).mMultiplicar( mGetDistPantalla / i.mMultiplicarEsc( O ) ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos el vector v que pertenece a la pantalla, que nos dara las nuevas coordenadas respecto de ella. </FONT></I>\r
+  <I><FONT COLOR="Navy">//  v = OI - d.D </FONT></I>\r
+  <I><FONT COLOR="Navy">// En nuestro caso: </FONT></I>\r
+  <I><FONT COLOR="Navy">//  v = OI - ( aCameraman.mGetCoordenadas.mGetI . aDistPantalla ) </FONT></I>\r
+  v := cVector.create( OI ).mRestar( i.mMultiplicar( mGetDistPantalla ) ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos su proyeccion en el versor -j (que sera nuestro X de la pantalla) </FONT></I>\r
+  <I><FONT COLOR="Navy">//  Es -j porque tomaremos positivo hacia la derecha. </FONT></I>\r
+  vX := mGetCameraman.mGetj.mMultiplicar(-1); \r
+  x := v.mMultiplicarEsc( vX ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos su proyeccion en el versor k (que sera nuestro Y de la pantalla) </FONT></I>\r
+  vY := mGetCameraman.mGetI; \r
+  y := v.mMultiplicarEsc( vY ); \r
+  <I><FONT COLOR="Navy">// Ahora hallamos el tamaño proporcional (un numero entre 0 y 1, donde 0 es </FONT></I>\r
+  <I><FONT COLOR="Navy">//  lo mas lejano y 1 lo mas cercano). Se calcula de la siguiente forma: </FONT></I>\r
+  <I><FONT COLOR="Navy">// tam = 1  -      |O| - aRadioMinimo </FONT></I>\r
+  <I><FONT COLOR="Navy">//              aRadioMaximo - aRadioMinimo </FONT></I>\r
+  <I><FONT COLOR="Navy">// Donde O es el vector posicion respecto de la camara, y el " 1 - xxx ", es porque cuanto mas </FONT></I>\r
+  <I><FONT COLOR="Navy">//  lejos, menor tiene que ser el tamaño </FONT></I>\r
+  tmp := O.mGetModulo - mGetRadioMinimo; \r
+  distMax := mGetRadioMaximo - mGetRadioMinimo; \r
+  tam := 1 - (tmp / distMax); \r
+  i.free; \r
+  posCam.free; \r
+  v.free; \r
+  vX.free; \r
+  vY.free; \r
+  OI.free; \r
+  O.free; \r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/vista/Filtro.pas b/doc/src-html/vista/Filtro.pas
new file mode 100644 (file)
index 0000000..b6fae8f
--- /dev/null
@@ -0,0 +1,305 @@
+<HTML><HEAD>\r
+<TITLE>File: filtro.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=filtro.pas><CENTER><H3>filtro.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Es una clase abstracta que representa filtro que recibe una lista de objetos y devuelve otra filtrada.<br> \r
+    <i>Cambios:</i> \r
+    <PRE> \r
+    06/12/00: Se agregan nuevos métodos (protegidos) para obtener información del filtro para poder crear subclases, \r
+              para lo cual tambien se hace virtual el método mVisible. \r
+    08/12/00: Se cambia esta clase para que sea abstracta. Se deja la implementacion del método mVisible para las \r
+              subclases exlusivamente ya que ahora es abstracto. El filtro frontal (que antes se implementaba en \r
+              esta unidad), ahora está implementado la unidad Filtros al igual que el resto. \r
+    </PRE>}</FONT></I> \r
+<B>unit</B> Filtro; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  Tipos, \r
+  ObjetoPersistente, \r
+  Vectores, \r
+  ObjetoVolador, \r
+  Classes, \r
+  Sysutils; \r
\r
+<B>type</B> \r
+  <I><FONT COLOR="Navy">{** Excepcion producida por el filtro si se utiliza cuando el observador fue destruido}</FONT></I> \r
+  EObservadorDestruido = <B>class</B>( Exception ) \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create; \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Es una clase abstracta que representa un filtro que recibe una lista de objetos y devuelve otra filtrada.}</FONT></I> \r
+  cFiltro = <B>class</B>( cObjetoPersistente ) \r
+    <B>private</B> \r
+      aObservador:    cObjetoVolador; <I><FONT COLOR="Navy">// Objeto volador que observa a traves del filtro </FONT></I>\r
+      aRadioMaximo:   tLongitud;      <I><FONT COLOR="Navy">// Alcance maximo del filtro (los </FONT></I>\r
+                                      <I><FONT COLOR="Navy">//  objetos mas lejanos no se veran) </FONT></I>\r
+      aRadioMinimo:   tLongitud;      <I><FONT COLOR="Navy">// Alcance minimo del filtro (los </FONT></I>\r
+                                      <I><FONT COLOR="Navy">//  objetos mas cercanos no se veran) </FONT></I>\r
+      aCosApertura:   tAngulo;        <I><FONT COLOR="Navy">// Coseno del Angulo de captación del filtro, </FONT></I>\r
+                                      <I><FONT COLOR="Navy">//   se almacena sólo el coseno porque el </FONT></I>\r
+                                      <I><FONT COLOR="Navy">//   ángulo en sí no se usa. </FONT></I>\r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Verifica que un objeto volador pueda ser visto por la cámara}</FONT></I> \r
+      <B>function</B> <A HREF="#cFiltro.mVisible">mVisible</A>( ov: cObjetoVolador ): boolean; <B>virtual</B>; <B>abstract</B>; \r
+      <I><FONT COLOR="Navy">{** Obtiene el radio mínimo}</FONT></I> \r
+      <B>function</B> <A HREF="#cFiltro.mGetRadioMinimo">mGetRadioMinimo</A>: tLongitud; \r
+      <I><FONT COLOR="Navy">{** Obtiene el radio máximo}</FONT></I> \r
+      <B>function</B> <A HREF="#cFiltro.mGetRadioMaximo">mGetRadioMaximo</A>: tLongitud; \r
+      <I><FONT COLOR="Navy">{** Obtiene el coseno de la apertura}</FONT></I> \r
+      <B>function</B> <A HREF="#cFiltro.mGetCosApertura">mGetCosApertura</A>: tAngulo; \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( observador: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; minimo: tLongitud = -1 ); \r
+      <I><FONT COLOR="Navy">{** Procesa una lista de objetos, devolviendo solo los visibles en una lista ordenada ascendentemente por la distancia \r
+          (es decir, el objeto más cercano está primero en la lista).}</FONT></I> \r
+      <B>function</B> <A HREF="#cFiltro.mFiltrar">mFiltrar</A>( l: TList ): TList; \r
+      <I><FONT COLOR="Navy">{** Obtiene un puntero al observador}</FONT></I> \r
+      <B>function</B> <A HREF="#cFiltro.mGetObservador">mGetObservador</A>: cObjetoVolador; \r
+      <I><FONT COLOR="Navy">{** Establece el observador con un nuevo puntero}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cFiltro.mSetObservador">mSetObservador</A>( ov: cObjetoVolador ); \r
+      <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar \r
+          y la información entregada depende del parámetro tDebugInfo.}</FONT></I> \r
+      <B>function</B> <A HREF="#cFiltro.mGetDebugInfo">mGetDebugInfo</A>( debugLevel: tDebugInfo = DI_MINI ): <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+      <I><FONT COLOR="Navy">// SERIALIZACION </FONT></I>\r
+      <I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado.}</FONT></I> \r
+      <B>function</B> <A HREF="#cFiltro.mSerializar">mSerializar</A>: <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+          serializado.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cFiltro.mDesSerializar">mDesSerializar</A>( str: <B>string</B> ); <B>override</B>; \r
+  <B>end</B>; \r
\r
+<B>implementation</B> \r
\r
+<B>uses</B> \r
+  RegExpr, \r
+  SerializacionUtils, \r
+  Math; \r
\r
+<I><FONT COLOR="Navy">{ cFiltro }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Contructor \r
+    @param observador Objeto Volador en el que estará montado el filtro (obligatorio) \r
+    @param angulo     Angulo de apertura (visión) del filtro (default = pi/4) \r
+    @param maximo     Distancia máxima en la que se considera visible a un objeto (default = 5000) \r
+    @param minimo     Distancia mínima en la que se considera visible a un objeto (default = -1). \r
+                      Si se especifica un valor negativo o cero, se toma la dimension del objeto volador}</FONT></I> \r
+<B>constructor</B> cFiltro.create(observador: cObjetoVolador; angulo: tAngulo; \r
+  maximo: tLongitud; minimo: tLongitud); \r
+<B>begin</B> \r
+  <B>inherited</B> create; \r
+  aObservador  := observador; \r
+  aRadioMaximo  := maximo; \r
+  aCosApertura  := cos( angulo ); \r
+  <B>if</B> minimo > 0 <B>then</B> <I><FONT COLOR="Navy">// Si el radio minimo es positiva se lo asigna </FONT></I>\r
+    aRadioMinimo  := minimo \r
+  <B>else</B> <I><FONT COLOR="Navy">// Si es negativo o cero (se paso como default o mal), lo extrae del objeto volador </FONT></I>\r
+    aRadioMinimo  := aObservador.mGetDimension; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Filtra una lista de objetos, devolviendo solo los visibles. \r
+    @return  Lista con los objetos visibles. \r
+    @param l Lista con los objetos a procesar.}</FONT></I> \r
+<B>function</B> <A NAME=cFiltro.mFiltrar>cFiltro.mFiltrar</A>( l: TList ): TList; \r
+<B>var</B> \r
+  lProcesada: TList; \r
+  oOV: cObjetoVolador; \r
+  i: word; \r
+<B>begin</B> \r
+  lProcesada := TList.create; \r
+  <B>for</B> i:=0 <B>to</B> l.count - 1 <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// recorre la lista de objetos </FONT></I>\r
+    oOV := l.items[i]; <I><FONT COLOR="Navy">// obtiene el ObjetoVolador actual </FONT></I>\r
+    <B>if</B> mVisible( oOV ) <B>then</B> \r
+      lProcesada.Add( oOV ); \r
+  <B>end</B>; \r
+  result := lProcesada; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+<I><FONT COLOR="Navy">{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos:<br> \r
+    Siempre devuelve los valores de las componentes x, y, z y si debugLevel es mayor que DI_NORMAL, \r
+    también muestra el módulo. \r
+    @return             Cadena de texto con el estado del Objeto. \r
+    @param   debugLevel Cantidad de información requerida}</FONT></I> \r
+<B>function</B> <A NAME=cFiltro.mGetDebugInfo>cFiltro.mGetDebugInfo</A>( debugLevel: tDebugInfo ): <B>string</B>; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Construye la cadena dependiendo de la cantidad de informacion que se quiera obtener </FONT></I>\r
+  result := 'Radio Máximo: ' + FloatToStrF( aRadioMaximo, ffNumber, 5, 5 ) + \r
+            ' | Radio Mínimo: ' + FloatToStrF( aRadioMinimo, ffNumber, 5, 5 ); \r
+  <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
+    <B>if</B> debugLevel = DI_NORMAL <B>then</B> \r
+      result := result + #13 + #10 + \r
+                'Cameraman: ' + aObservador.mGetDebugInfo; \r
+    <B>if</B> debugLevel = DI_MAXI <B>then</B> \r
+      result := result + #13 + #10 + \r
+                'Cameraman: ' + aObservador.mGetDebugInfo( debugLevel ); <I><FONT COLOR="Navy">// + #13 + #10 + </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
+    on e: EAccessViolation <B>do</B> \r
+      <B>raise</B> EObservadorDestruido.create; <I><FONT COLOR="Navy">// Creamos una nueva excepcion especial </FONT></I>\r
+  <B>end</B>; \r
+<B>end</B>; \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Obtiene un puntero al observador \r
+    @return Puntero al obervador}</FONT></I> \r
+<B>function</B> <A NAME=cFiltro.mGetObservador>cFiltro.mGetObservador</A>: cObjetoVolador; \r
+<B>begin</B> \r
+  result := aObservador; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Establece el observador con un nuevo puntero \r
+    @param Puntero al nuevo obervador}</FONT></I> \r
+<B>procedure</B> <A NAME=cFiltro.mSetObservador>cFiltro.mSetObservador</A>(ov: cObjetoVolador); \r
+<B>begin</B> \r
+  aObservador := ov; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Recrea el objeto a partir de una cadena de texto con el objeto \r
+    serializado. \r
+    @param str Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>procedure</B> <A NAME=cFiltro.mDesSerializar>cFiltro.mDesSerializar</A>(str: <B>string</B>); \r
+<B>var</B> \r
+  r: TRegExpr; \r
+<B>begin</B> \r
+  <B>inherited</B> mDesSerializar( str ); <I><FONT COLOR="Navy">// SIEMPRE el ID debe ser el PRIMER atributo </FONT></I>\r
+  r := TRegExpr.create; \r
+  <I><FONT COLOR="Navy">// OBSERVADOR </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<observador/s+class=([/w/d]+)/s*>/s*(.+)/s*</observador>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      <B>if</B> r.Match[1] <> '0' <B>then</B> <I><FONT COLOR="Navy">// Si tiene una clase determinada... </FONT></I>\r
+        <B>if</B> aObservador <> <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no es nulo </FONT></I>\r
+          <I><FONT COLOR="Navy">// Puede caer en una EAccessViolation si esta destruido </FONT></I>\r
+          aObservador.mDesSerializar( r.Match[2] ) <I><FONT COLOR="Navy">// Lo deserializa </FONT></I>\r
+        <B>else</B> <I><FONT COLOR="Navy">// si es nulo </FONT></I>\r
+          aObservador := restaurarObjeto( r.Match[1], r.Match[2] ) <I><FONT COLOR="Navy">// lo crea segun su clase </FONT></I>\r
+      <B>else</B> <I><FONT COLOR="Navy">// Si no tiene una clase determinada, entonces se lo pone en nil </FONT></I>\r
+        aObservador := <B>nil</B> \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el objetivo' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ESerializacion <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si fueron de serializacion... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al deserializar la posicion: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer la posicion utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+    on e: EAccessViolation <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si el Objetivo fue destruido... </FONT></I>\r
+      aObservador := restaurarObjeto( r.Match[1], r.Match[2] ) <I><FONT COLOR="Navy">// lo crea segun su clase </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// RADIOMAXIMO </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<radiomaximo>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</radiomaximo>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aRadioMaximo := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el radio maximo' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el radio maximo utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// RADIOMINIMO </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<radiominimo>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</radiominimo>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aRadioMinimo := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el radio minimo' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el radio minimo utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// COSAPERTURA </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// se fija si hay errores al extraer los datos </FONT></I>\r
+    r.Expression := '<cosapertura>/s*([+/-]?/d+(/,/d+)?([eE][+/-]?/d+)?)/s*</cosapertura>'; <I><FONT COLOR="Navy">// contruye la expresion regular a buscar </FONT></I>\r
+    <B>if</B> r.Exec ( str ) <B>then</B> <I><FONT COLOR="Navy">// Ejecuta la expresion. Si la encuentra... </FONT></I>\r
+      aCosApertura := StrToFloat( r.Match[1] ) \r
+    <B>else</B> <I><FONT COLOR="Navy">// si no encontro la experesion... </FONT></I>\r
+      <B>raise</B> ESerializacion.create( 'No se encontro el coseno de la apertura' ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si hubieron errores ... </FONT></I>\r
+    on e: ERegExpr <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// si fueron de expresiones regulares... </FONT></I>\r
+      r.Free; <I><FONT COLOR="Navy">// libera memoria </FONT></I>\r
+      <B>raise</B> ESerializacion.create( ClassName + ': Error al extraer el coseno de la apertura utilizando expresiones regulares: ' + e.<B>Message</B> ); <I><FONT COLOR="Navy">// cae en una excepcion </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+  r.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Devuelve una cadena de texto con el objeto serializado. \r
+    @return Cadena de texto con el objeto serializado.}</FONT></I> \r
+<B>function</B> <A NAME=cFiltro.mSerializar>cFiltro.mSerializar</A>: <B>string</B>; \r
+<B>var</B> \r
+  clase, \r
+  observador: <B>string</B>; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Si el observador es nil o está destruido, se setea el atributo class del </FONT></I>\r
+  <I><FONT COLOR="Navy">// TAG objetivo como '0' y entre el TAG se indica que es nil. Si no se </FONT></I>\r
+  <I><FONT COLOR="Navy">// setea como el nombre de la clase y su expresion serializada respectivamente </FONT></I>\r
+  observador := 'nil'; \r
+  clase    := '0'; \r
+  <B>if</B> aObservador <> <B>nil</B> <B>then</B> \r
+    <B>try</B> \r
+      observador := aObservador.mSerializar; \r
+      clase      := aObservador.ClassName; \r
+    <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cambia la cadena de texto </FONT></I>\r
+      on e: EAccessViolation <B>do</B> <B>begin</B> \r
+        observador := 'nil'; \r
+        clase      := '0'; \r
+      <B>end</B>; \r
+    <B>end</B>; \r
+  result := <B>inherited</B> mSerializar + \r
+            '<observador class=' + clase + '>' + observador + '</observador>' + \r
+            '<radiomaximo>' + FloatToStrF( aRadioMaximo, ffGeneral, 18, 0 ) + '</radiomaximo>' + \r
+            '<radiominimo>' + FloatToStrF( aRadioMinimo, ffGeneral, 18, 0 ) + '</radiominimo>' + \r
+            '<cosapertura>' + FloatToStrF( aCosApertura, ffGeneral, 18, 0 ) + '</cosapertura>'; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el radio máximo \r
+    @return Radio máximo}</FONT></I> \r
+<B>function</B> <A NAME=cFiltro.mGetRadioMaximo>cFiltro.mGetRadioMaximo</A>: tLongitud; \r
+<B>begin</B> \r
+  result := aRadioMaximo; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el radio mínimo \r
+    @return Radio mínimo}</FONT></I> \r
+<B>function</B> <A NAME=cFiltro.mGetRadioMinimo>cFiltro.mGetRadioMinimo</A>: tLongitud; \r
+<B>begin</B> \r
+  result := aRadioMinimo; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el coseno de la apertura \r
+    @return Coseno de la apertura}</FONT></I> \r
+<B>function</B> <A NAME=cFiltro.mGetCosApertura>cFiltro.mGetCosApertura</A>: tAngulo; \r
+<B>begin</B> \r
+  result := aCosApertura; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ EObservadorDestruido }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+<B>constructor</B> EObservadorDestruido.create; \r
+<B>begin</B> \r
+  <B>inherited</B> create( 'El Observador fue destruido.' ); \r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/vista/Filtros.pas b/doc/src-html/vista/Filtros.pas
new file mode 100644 (file)
index 0000000..a9dda91
--- /dev/null
@@ -0,0 +1,361 @@
+<HTML><HEAD>\r
+<TITLE>File: filtros.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=filtros.pas><CENTER><H3>filtros.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Se implementan varios filtro en diferentes direcciones.<br> \r
+    <i>Cambios:</i> \r
+    <PRE> \r
+    09/12/00: Se agrega la clase cFiltroMapa. \r
+    </PRE>}</FONT></I> \r
+<B>unit</B> Filtros; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  Tipos, \r
+  Vectores, \r
+  ObjetoVolador, \r
+  Sysutils, \r
+  Filtro; \r
\r
+<B>type</B> \r
\r
+  <I><FONT COLOR="Navy">{** Implementa un filtro que "ve" hacia adelante.}</FONT></I> \r
+  cFiltroFrontal = <B>class</B>( cFiltro ) \r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Verifica que un objeto volador pueda ser visto por la cámara}</FONT></I> \r
+      <B>function</B> <A HREF="#cFiltroFrontal.mVisible">mVisible</A>( ov: cObjetoVolador ): boolean; <B>override</B>; \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Implementa un filtro que "ve" hacia la izquierda.}</FONT></I> \r
+  cFiltroLatIzq = <B>class</B>( cFiltro ) \r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Verifica que un objeto volador pueda ser visto por la cámara}</FONT></I> \r
+      <B>function</B> <A HREF="#cFiltroLatIzq.mVisible">mVisible</A>( ov: cObjetoVolador ): boolean; <B>override</B>; \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Implementa un filtro que "ve" hacia la derecha.}</FONT></I> \r
+  cFiltroLatDer = <B>class</B>( cFiltro ) \r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Verifica que un objeto volador pueda ser visto por la cámara}</FONT></I> \r
+      <B>function</B> <A HREF="#cFiltroLatDer.mVisible">mVisible</A>( ov: cObjetoVolador ): boolean; <B>override</B>; \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Implementa un filtro que "ve" hacia atrás.}</FONT></I> \r
+  cFiltroTrasero = <B>class</B>( cFiltro ) \r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Verifica que un objeto volador pueda ser visto por la cámara}</FONT></I> \r
+      <B>function</B> <A HREF="#cFiltroTrasero.mVisible">mVisible</A>( ov: cObjetoVolador ): boolean; <B>override</B>; \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Implementa un filtro que "ve" hacia arriba.}</FONT></I> \r
+  cFiltroArriba = <B>class</B>( cFiltro ) \r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Verifica que un objeto volador pueda ser visto por la cámara}</FONT></I> \r
+      <B>function</B> <A HREF="#cFiltroArriba.mVisible">mVisible</A>( ov: cObjetoVolador ): boolean; <B>override</B>; \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Implementa un filtro que "ve" hacia abajo.}</FONT></I> \r
+  cFiltroAbajo = <B>class</B>( cFiltro ) \r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Verifica que un objeto volador pueda ser visto por la cámara}</FONT></I> \r
+      <B>function</B> <A HREF="#cFiltroAbajo.mVisible">mVisible</A>( ov: cObjetoVolador ): boolean; <B>override</B>; \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Implementa un filtro que "ve" hacia abajo pero desde arriba a una cierta distancia \r
+      del observador. Es como si observara al observador mismo.}</FONT></I> \r
+  cFiltroMapa = <B>class</B>( cFiltro ) \r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Verifica que un objeto volador pueda ser visto por la cámara}</FONT></I> \r
+      <B>function</B> <A HREF="#cFiltroMapa.mVisible">mVisible</A>( ov: cObjetoVolador ): boolean; <B>override</B>; \r
+  <B>end</B>; \r
\r
+  <I><FONT COLOR="Navy">{** Implementa un filtro que "ve" hacia adelante y que además sólo puede \r
+      ver objetos del tipo cNave y cMeteorito.}</FONT></I> \r
+  cFiltroLock = <B>class</B>( cFiltroFrontal ) \r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Verifica que un objeto volador pueda ser visto por la cámara}</FONT></I> \r
+      <B>function</B> <A HREF="#cFiltroLock.mVisible">mVisible</A>( ov: cObjetoVolador ): boolean; <B>override</B>; \r
+  <B>end</B>; \r
\r
+<B>implementation</B> \r
\r
+<B>uses</B> \r
+  Nave, \r
+  Meteorito; \r
\r
+<I><FONT COLOR="Navy">{ cFiltroFrontal }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Verifica que un objeto volador pueda ser visto por la cámara \r
+    @param  ov Objeto volador que se quiere verificar si es visto por la cámara. \r
+    @return    <i>True</i> si lo ve, <i>False</i> si no.}</FONT></I> \r
+<B>function</B> <A NAME=cFiltroFrontal.mVisible>cFiltroFrontal.mVisible</A>(ov: cObjetoVolador): boolean; \r
+<B>var</B> \r
+  posRel,             <I><FONT COLOR="Navy">// vector posicion del objeto volador relativo a la camara </FONT></I>\r
+  posCam,             <I><FONT COLOR="Navy">// Posision del cameraman </FONT></I>\r
+  dirCam:  cVector;   <I><FONT COLOR="Navy">// vector con la direccion en la que apunta la camara </FONT></I>\r
+  dist:    tLongitud; <I><FONT COLOR="Navy">// Distancia entre la camara y el objeto </FONT></I>\r
+  cosAlfa: tAngulo;   <I><FONT COLOR="Navy">// Coseno del angulo que forman la dir de la camara y la pos del objeto </FONT></I>\r
+<B>begin</B> \r
+  result := false; \r
+  <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
+    dist := mGetObservador.mGetDistancia( ov ); \r
+  <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
+    on e: EAccessViolation <B>do</B> \r
+      <B>raise</B> EObservadorDestruido.create; <I><FONT COLOR="Navy">// Creamos una nueva excepcion especial </FONT></I>\r
+  <B>end</B>; \r
+  <B>if</B> ( dist > mGetRadioMinimo ) <B>and</B> \r
+     ( dist < mGetRadioMaximo ) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Esta dentro de la distancia minima y maxima </FONT></I>\r
+    <I><FONT COLOR="Navy">// posRel es el vector posicion del objeto volador relativo a la camara: posRel = posOV - posCam </FONT></I>\r
+    posRel := ov.mGetPosicion; \r
+    posCam := mGetObservador.mGetPosicion; \r
+    posRel.mRestar( posCam ); \r
+    dirCam := mGetObservador.mGetI; \r
+    <I><FONT COLOR="Navy">// Calcula el angulo entre las 2 posiciones ( A . B / |A| . |B| ) </FONT></I>\r
+    cosAlfa := posRel.mMultiplicarEsc( dirCam ) / ( posRel.mGetModulo * dirCam.mGetModulo); \r
+    <I><FONT COLOR="Navy">// Ahora se comparan los cosenos, ya que es una funcion decreciente entre 0 y PI </FONT></I>\r
+    <B>if</B> cosAlfa > mGetCosApertura <B>then</B> <I><FONT COLOR="Navy">// Esta dentro del angulo de vision </FONT></I>\r
+      result := true; \r
+    posRel.free; \r
+    posCam.free; \r
+    dirCam.free; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cFiltroLatIzq }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Verifica que un objeto volador pueda ser visto por la cámara \r
+    @param  ov Objeto volador que se quiere verificar si es visto por la cámara. \r
+    @return    <i>True</i> si lo ve, <i>False</i> si no.}</FONT></I> \r
+<B>function</B> <A NAME=cFiltroLatIzq.mVisible>cFiltroLatIzq.mVisible</A>(ov: cObjetoVolador): boolean; \r
+<B>var</B> \r
+  posRel,             <I><FONT COLOR="Navy">// vector posicion del objeto volador relativo a la camara </FONT></I>\r
+  posCam,             <I><FONT COLOR="Navy">// Posision del cameraman </FONT></I>\r
+  dirCam:  cVector;   <I><FONT COLOR="Navy">// vector con la direccion en la que apunta la camara </FONT></I>\r
+  dist:    tLongitud; <I><FONT COLOR="Navy">// Distancia entre la camara y el objeto </FONT></I>\r
+  cosAlfa: tAngulo;   <I><FONT COLOR="Navy">// Coseno del angulo que forman la dir de la camara y la pos del objeto </FONT></I>\r
+<B>begin</B> \r
+  result := false; \r
+  <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
+    dist := mGetObservador.mGetDistancia( ov ); \r
+  <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
+    on e: EAccessViolation <B>do</B> \r
+      <B>raise</B> EObservadorDestruido.create; <I><FONT COLOR="Navy">// Creamos una nueva excepcion especial </FONT></I>\r
+  <B>end</B>; \r
+  <B>if</B> ( dist > mGetRadioMinimo ) <B>and</B> \r
+     ( dist < mGetRadioMaximo ) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Esta dentro de la distancia minima y maxima </FONT></I>\r
+    <I><FONT COLOR="Navy">// posRel es el vector posicion del objeto volador relativo a la camara: posRel = posOV - posCam </FONT></I>\r
+    posRel := ov.mGetPosicion; \r
+    posCam := mGetObservador.mGetPosicion; \r
+    posRel.mRestar( posCam ); \r
+    dirCam := mGetObservador.mGetJ; \r
+    <I><FONT COLOR="Navy">// Calcula el angulo entre las 2 posiciones ( A . B / |A| . |B| ) </FONT></I>\r
+    cosAlfa := posRel.mMultiplicarEsc( dirCam ) / ( posRel.mGetModulo * dirCam.mGetModulo); \r
+    <I><FONT COLOR="Navy">// Ahora se comparan los cosenos, ya que es una funcion decreciente entre 0 y PI </FONT></I>\r
+    <B>if</B> cosAlfa > mGetCosApertura <B>then</B> <I><FONT COLOR="Navy">// Esta dentro del angulo de vision </FONT></I>\r
+      result := true; \r
+    posRel.free; \r
+    posCam.free; \r
+    dirCam.free; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cFiltroLatDer }</FONT></I> \r
\r
+<B>function</B> <A NAME=cFiltroLatDer.mVisible>cFiltroLatDer.mVisible</A>(ov: cObjetoVolador): boolean; \r
+<B>var</B> \r
+  posRel,             <I><FONT COLOR="Navy">// vector posicion del objeto volador relativo a la camara </FONT></I>\r
+  posCam,             <I><FONT COLOR="Navy">// Posision del cameraman </FONT></I>\r
+  dirCam:  cVector;   <I><FONT COLOR="Navy">// vector con la direccion en la que apunta la camara </FONT></I>\r
+  dist:    tLongitud; <I><FONT COLOR="Navy">// Distancia entre la camara y el objeto </FONT></I>\r
+  cosAlfa: tAngulo;   <I><FONT COLOR="Navy">// Coseno del angulo que forman la dir de la camara y la pos del objeto </FONT></I>\r
+<B>begin</B> \r
+  result := false; \r
+  <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
+    dist := mGetObservador.mGetDistancia( ov ); \r
+  <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
+    on e: EAccessViolation <B>do</B> \r
+      <B>raise</B> EObservadorDestruido.create; <I><FONT COLOR="Navy">// Creamos una nueva excepcion especial </FONT></I>\r
+  <B>end</B>; \r
+  <B>if</B> ( dist > mGetRadioMinimo ) <B>and</B> \r
+     ( dist < mGetRadioMaximo ) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Esta dentro de la distancia minima y maxima </FONT></I>\r
+    <I><FONT COLOR="Navy">// posRel es el vector posicion del objeto volador relativo a la camara: posRel = posOV - posCam </FONT></I>\r
+    posRel := ov.mGetPosicion; \r
+    posCam := mGetObservador.mGetPosicion; \r
+    posRel.mRestar( posCam ); \r
+    dirCam := mGetObservador.mGetJ.mMultiplicar(-1); \r
+    <I><FONT COLOR="Navy">// Calcula el angulo entre las 2 posiciones ( A . B / |A| . |B| ) </FONT></I>\r
+    cosAlfa := posRel.mMultiplicarEsc( dirCam ) / ( posRel.mGetModulo * dirCam.mGetModulo); \r
+    <I><FONT COLOR="Navy">// Ahora se comparan los cosenos, ya que es una funcion decreciente entre 0 y PI </FONT></I>\r
+    <B>if</B> cosAlfa > mGetCosApertura <B>then</B> <I><FONT COLOR="Navy">// Esta dentro del angulo de vision </FONT></I>\r
+      result := true; \r
+    posRel.free; \r
+    posCam.free; \r
+    dirCam.free; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cFiltroTrasero }</FONT></I> \r
\r
+<B>function</B> <A NAME=cFiltroTrasero.mVisible>cFiltroTrasero.mVisible</A>(ov: cObjetoVolador): boolean; \r
+<B>var</B> \r
+  posRel,             <I><FONT COLOR="Navy">// vector posicion del objeto volador relativo a la camara </FONT></I>\r
+  posCam,             <I><FONT COLOR="Navy">// Posision del cameraman </FONT></I>\r
+  dirCam:  cVector;   <I><FONT COLOR="Navy">// vector con la direccion en la que apunta la camara </FONT></I>\r
+  dist:    tLongitud; <I><FONT COLOR="Navy">// Distancia entre la camara y el objeto </FONT></I>\r
+  cosAlfa: tAngulo;   <I><FONT COLOR="Navy">// Coseno del angulo que forman la dir de la camara y la pos del objeto </FONT></I>\r
+<B>begin</B> \r
+  result := false; \r
+  <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
+    dist := mGetObservador.mGetDistancia( ov ); \r
+  <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
+    on e: EAccessViolation <B>do</B> \r
+      <B>raise</B> EObservadorDestruido.create; <I><FONT COLOR="Navy">// Creamos una nueva excepcion especial </FONT></I>\r
+  <B>end</B>; \r
+  <B>if</B> ( dist > mGetRadioMinimo ) <B>and</B> \r
+     ( dist < mGetRadioMaximo ) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Esta dentro de la distancia minima y maxima </FONT></I>\r
+    <I><FONT COLOR="Navy">// posRel es el vector posicion del objeto volador relativo a la camara: posRel = posOV - posCam </FONT></I>\r
+    posRel := ov.mGetPosicion; \r
+    posCam := mGetObservador.mGetPosicion; \r
+    posRel.mRestar( posCam ); \r
+    dirCam := mGetObservador.mGetI.mMultiplicar(-1); \r
+    <I><FONT COLOR="Navy">// Calcula el angulo entre las 2 posiciones ( A . B / |A| . |B| ) </FONT></I>\r
+    cosAlfa := posRel.mMultiplicarEsc( dirCam ) / ( posRel.mGetModulo * dirCam.mGetModulo); \r
+    <I><FONT COLOR="Navy">// Ahora se comparan los cosenos, ya que es una funcion decreciente entre 0 y PI </FONT></I>\r
+    <B>if</B> cosAlfa > mGetCosApertura <B>then</B> <I><FONT COLOR="Navy">// Esta dentro del angulo de vision </FONT></I>\r
+      result := true; \r
+    posRel.free; \r
+    posCam.free; \r
+    dirCam.free; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cFiltroArriba }</FONT></I> \r
\r
+<B>function</B> <A NAME=cFiltroArriba.mVisible>cFiltroArriba.mVisible</A>(ov: cObjetoVolador): boolean; \r
+<B>var</B> \r
+  posRel,             <I><FONT COLOR="Navy">// vector posicion del objeto volador relativo a la camara </FONT></I>\r
+  posCam,             <I><FONT COLOR="Navy">// Posision del cameraman </FONT></I>\r
+  dirCam:  cVector;   <I><FONT COLOR="Navy">// vector con la direccion en la que apunta la camara </FONT></I>\r
+  dist:    tLongitud; <I><FONT COLOR="Navy">// Distancia entre la camara y el objeto </FONT></I>\r
+  cosAlfa: tAngulo;   <I><FONT COLOR="Navy">// Coseno del angulo que forman la dir de la camara y la pos del objeto </FONT></I>\r
+<B>begin</B> \r
+  result := false; \r
+  <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
+    dist := mGetObservador.mGetDistancia( ov ); \r
+  <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
+    on e: EAccessViolation <B>do</B> \r
+      <B>raise</B> EObservadorDestruido.create; <I><FONT COLOR="Navy">// Creamos una nueva excepcion especial </FONT></I>\r
+  <B>end</B>; \r
+  <B>if</B> ( dist > mGetRadioMinimo ) <B>and</B> \r
+     ( dist < mGetRadioMaximo ) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Esta dentro de la distancia minima y maxima </FONT></I>\r
+    <I><FONT COLOR="Navy">// posRel es el vector posicion del objeto volador relativo a la camara: posRel = posOV - posCam </FONT></I>\r
+    posRel := ov.mGetPosicion; \r
+    posCam := mGetObservador.mGetPosicion; \r
+    posRel.mRestar( posCam ); \r
+    dirCam := mGetObservador.mGetK; \r
+    <I><FONT COLOR="Navy">// Calcula el angulo entre las 2 posiciones ( A . B / |A| . |B| ) </FONT></I>\r
+    cosAlfa := posRel.mMultiplicarEsc( dirCam ) / ( posRel.mGetModulo * dirCam.mGetModulo); \r
+    <I><FONT COLOR="Navy">// Ahora se comparan los cosenos, ya que es una funcion decreciente entre 0 y PI </FONT></I>\r
+    <B>if</B> cosAlfa > mGetCosApertura <B>then</B> <I><FONT COLOR="Navy">// Esta dentro del angulo de vision </FONT></I>\r
+      result := true; \r
+    posRel.free; \r
+    posCam.free; \r
+    dirCam.free; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cFiltroAbajo }</FONT></I> \r
\r
+<B>function</B> <A NAME=cFiltroAbajo.mVisible>cFiltroAbajo.mVisible</A>(ov: cObjetoVolador): boolean; \r
+<B>var</B> \r
+  posRel,             <I><FONT COLOR="Navy">// vector posicion del objeto volador relativo a la camara </FONT></I>\r
+  posCam,             <I><FONT COLOR="Navy">// Posision del cameraman </FONT></I>\r
+  dirCam:  cVector;   <I><FONT COLOR="Navy">// vector con la direccion en la que apunta la camara </FONT></I>\r
+  dist:    tLongitud; <I><FONT COLOR="Navy">// Distancia entre la camara y el objeto </FONT></I>\r
+  cosAlfa: tAngulo;   <I><FONT COLOR="Navy">// Coseno del angulo que forman la dir de la camara y la pos del objeto </FONT></I>\r
+<B>begin</B> \r
+  result := false; \r
+  <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
+    dist := mGetObservador.mGetDistancia( ov ); \r
+  <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
+    on e: EAccessViolation <B>do</B> \r
+      <B>raise</B> EObservadorDestruido.create; <I><FONT COLOR="Navy">// Creamos una nueva excepcion especial </FONT></I>\r
+  <B>end</B>; \r
+  <B>if</B> ( dist > mGetRadioMinimo ) <B>and</B> \r
+     ( dist < mGetRadioMaximo ) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Esta dentro de la distancia minima y maxima </FONT></I>\r
+    <I><FONT COLOR="Navy">// posRel es el vector posicion del objeto volador relativo a la camara: posRel = posOV - posCam </FONT></I>\r
+    posRel := ov.mGetPosicion; \r
+    posCam := mGetObservador.mGetPosicion; \r
+    posRel.mRestar( posCam ); \r
+    dirCam := mGetObservador.mGetK.mMultiplicar(-1); \r
+    <I><FONT COLOR="Navy">// Calcula el angulo entre las 2 posiciones ( A . B / |A| . |B| ) </FONT></I>\r
+    cosAlfa := posRel.mMultiplicarEsc( dirCam ) / ( posRel.mGetModulo * dirCam.mGetModulo); \r
+    <I><FONT COLOR="Navy">// Ahora se comparan los cosenos, ya que es una funcion decreciente entre 0 y PI </FONT></I>\r
+    <B>if</B> cosAlfa > mGetCosApertura <B>then</B> <I><FONT COLOR="Navy">// Esta dentro del angulo de vision </FONT></I>\r
+      result := true; \r
+    posRel.free; \r
+    posCam.free; \r
+    dirCam.free; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cFiltroMapa }</FONT></I> \r
\r
+<B>function</B> <A NAME=cFiltroMapa.mVisible>cFiltroMapa.mVisible</A>(ov: cObjetoVolador): boolean; \r
+<B>var</B> \r
+  desplazamiento,     <I><FONT COLOR="Navy">// desplazamiento del filtro respecto del observador </FONT></I>\r
+  posTmp,             <I><FONT COLOR="Navy">// Vector posicion temporal </FONT></I>\r
+  posRel,             <I><FONT COLOR="Navy">// vector posicion del objeto volador relativo a la camara </FONT></I>\r
+  posCam,             <I><FONT COLOR="Navy">// Posision del cameraman </FONT></I>\r
+  dirCam:  cVector;   <I><FONT COLOR="Navy">// vector con la direccion en la que apunta la camara </FONT></I>\r
+  dist:    tLongitud; <I><FONT COLOR="Navy">// Distancia entre la camara y el objeto </FONT></I>\r
+  cosAlfa: tAngulo;   <I><FONT COLOR="Navy">// Coseno del angulo que forman la dir de la camara y la pos del objeto </FONT></I>\r
+<B>begin</B> \r
+  result := false; \r
+  <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
+    desplazamiento := mGetObservador.mGetk.mSetModulo( 3000 ); <I><FONT COLOR="Navy">// Esta 3000 metros alejado del observador </FONT></I>\r
+  <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
+    on e: EAccessViolation <B>do</B> \r
+      <B>raise</B> EObservadorDestruido.create; <I><FONT COLOR="Navy">// Creamos una nueva excepcion especial </FONT></I>\r
+  <B>end</B>; \r
+  posCam := mGetObservador.mGetPosicion.mSumar( desplazamiento ); \r
+  desplazamiento.free; \r
+  posTmp := ov.mGetPosicion; \r
+  dist := posCam.mGetDistancia( posTmp ); \r
+  posTmp.free; \r
+  <B>if</B> ( dist > mGetRadioMinimo ) <B>and</B> \r
+     ( dist < mGetRadioMaximo ) <B>then</B> <B>begin</B> <I><FONT COLOR="Navy">// Esta dentro de la distancia minima y maxima </FONT></I>\r
+    <I><FONT COLOR="Navy">// posRel es el vector posicion del objeto volador relativo a la camara: posRel = posOV - posCam </FONT></I>\r
+    posRel := ov.mGetPosicion; \r
+    posRel.mRestar( posCam ); \r
+    dirCam := mGetObservador.mGetK.mMultiplicar(-1); \r
+    <I><FONT COLOR="Navy">// Calcula el angulo entre las 2 posiciones ( A . B / |A| . |B| ) </FONT></I>\r
+    cosAlfa := posRel.mMultiplicarEsc( dirCam ) / ( posRel.mGetModulo * dirCam.mGetModulo); \r
+    <I><FONT COLOR="Navy">// Ahora se comparan los cosenos, ya que es una funcion decreciente entre 0 y PI </FONT></I>\r
+    <B>if</B> cosAlfa > mGetCosApertura <B>then</B> <I><FONT COLOR="Navy">// Esta dentro del angulo de vision </FONT></I>\r
+      result := true; \r
+    posRel.free; \r
+    dirCam.free; \r
+  <B>end</B>; \r
+  posCam.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{ cFiltroLock }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Verifica que un objeto volador pueda ser visto por la cámara}</FONT></I> \r
+<B>function</B> <A NAME=cFiltroLock.mVisible>cFiltroLock.mVisible</A>(ov: cObjetoVolador): boolean; \r
+<B>begin</B> \r
+  result := false; \r
+  <B>if</B> (ov <B>is</B> cNave) <B>or</B> (ov <B>is</B> cMeteorito) <B>then</B> \r
+    result := <B>inherited</B> mVisible( ov ); \r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/src-html/vista/Vista.pas b/doc/src-html/vista/Vista.pas
new file mode 100644 (file)
index 0000000..a3a5af0
--- /dev/null
@@ -0,0 +1,522 @@
+<HTML><HEAD>\r
+<TITLE>File: vista.pas </TITLE>\r
+<META NAME="GENERATOR" CONTENT="PasToHTML(Bystricky Vladimir)">\r
+</HEAD>\r
+<BODY BGCOLOR="#FFFFFF">\r
+<A NAME=vista.pas><CENTER><H3>vista.pas</H3></A><I> from <A HREF=/proyecto/doc/src-html/AlgoWars.html> Project: AlgoWars.dpr</A></I></CENTER>\r
+<HR>\r
+<PRE>\r
+<I><FONT COLOR="Navy">{** Interpreta y dibuja los datos del modelo en un formulario<br> \r
+    <i>Cambios:</i> \r
+    <PRE> \r
+    10/11/00: Se maneja la excepción para evitar usar la camara cuando el cameraman fue destruido (ECameramanDestruido). \r
+              Esta es propagada (por ahora) para que el controlador (formulario) frene el timer \r
+    02/12/00: Se mejoran los graficos usando transparencias en los bitmaps y se da la opcion de presentar \r
+              los graficos con transparencias (alta calidad) o no (a través del atributo aAltaCalidad y \r
+              los métodos mSetAltaCalidad, mSetBajaCalidad y mCambiarCalidad). \r
+              Se mejora la performance gracias a la nueva implementación de mDibujar, ya que los \r
+              bitmas se cargan una sola vez en memoria (en un array aBitmaps) en vez de cargarse \r
+              y liberarse cada vez que se actualiza la pantalla como sucedía anteriormente. \r
+              Se implementa el soporte de visualización de un objeto volador lockeado (utilizando \r
+              otra lista de bitmaps con los gráficos de los objetos lockeados, aBitmapsLockeados). \r
+    08/12/00: Se agregan múltiples cámaras: Derecha, Izquierda, Arriba, Abajo, Atrás, Del Misil. Para hacerlo \r
+              se agragega un array de camaras y un atributo que indica la camara actual. Tambien se agregan \r
+              métodos para cambiar la cámara actual, etc. \r
+              Se arregla el destructor que no liberaba todos los objetos. \r
+    09/12/00: Se reemplaza la vista del misil por una mas general (vista del arma) que permite ver a traves de \r
+              cualquier arma disparada. Se implementa correctamente esta vista. \r
+              Se agrega una vista tipo mapa.  \r
+    </PRE>}</FONT></I> \r
+<B>unit</B> Vista; \r
\r
+<B>interface</B> \r
\r
+<B>uses</B> \r
+  <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+  Objeto, \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+  Windows, \r
+  SysUtils, \r
+  Graphics, \r
+  Forms, \r
+  Camara, \r
+  Tipos, \r
+  ObjetoVolador, \r
+  Espacio, \r
+  Armas, \r
+  Lista; \r
\r
+<B>type</B> \r
+  tArrayBitmaps = <B>array</B> [OV_NAVEPESADA..OV_MISDIR] <B>of</B> TBitmap; \r
+  tArrayCamaras = <B>array</B> [CAMARA_FRONTAL..CAMARA_ARMA] <B>of</B> cCamara; \r
\r
+  <I><FONT COLOR="Navy">{** Interpreta y dibuja los datos del modelo en un formulario}</FONT></I> \r
+  cVista = <B>class</B><I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I>( cObjeto )<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+    <B>private</B> \r
+      aFormulario:    TCustomForm;   <I><FONT COLOR="Navy">// Formulario en el cual dibuja </FONT></I>\r
+      aRegion:        HRgn;          <I><FONT COLOR="Navy">// Región del formulario en la que dibuja </FONT></I>\r
+      aCamara:        tCamaras;      <I><FONT COLOR="Navy">// Cámara seleccionada actualmente </FONT></I>\r
+      aCamaras:       tArrayCamaras; <I><FONT COLOR="Navy">// Multiples cámaras </FONT></I>\r
+      aBitmaps:       tArrayBitmaps; <I><FONT COLOR="Navy">// Lista con los bitmaps </FONT></I>\r
+      aBitmapsLocked: tArrayBitmaps; <I><FONT COLOR="Navy">// Lista con los bitmaps </FONT></I>\r
+      aAltaCalidad:   boolean;       <I><FONT COLOR="Navy">// Indica si las imagenes se ven con transparencias. </FONT></I>\r
+      <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+      aListaProy:     cLista;   <I><FONT COLOR="Navy">// Lista de objetos proyectados (se guarda para poder </FONT></I>\r
+                                <I><FONT COLOR="Navy">//  implementar el método mGetDebugInfo </FONT></I>\r
+      <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+    <B>protected</B> \r
+      <I><FONT COLOR="Navy">{** Obtiene el lado menor del formulario}</FONT></I> \r
+      <B>function</B> <A HREF="#cVista.mGetFormLado">mGetFormLado</A>: integer; \r
+      <I><FONT COLOR="Navy">{** Convierte el tamaño obtenido de la cámara a uno proporcional en píxeles}</FONT></I> \r
+      <B>function</B> <A HREF="#cVista.mGetTam">mGetTam</A>( proy: tPProy ): integer; \r
+      <I><FONT COLOR="Navy">{** Convierte la componente en x obtenida de la cámara a una proporcional en píxeles}</FONT></I> \r
+      <B>function</B> <A HREF="#cVista.mGetX">mGetX</A>( proy: tPProy ): integer; \r
+      <I><FONT COLOR="Navy">{** Convierte la componente en y obtenida de la cámara a una proporcional en píxeles}</FONT></I> \r
+      <B>function</B> <A HREF="#cVista.mGetY">mGetY</A>( proy: tPProy ): integer; \r
+      <I><FONT COLOR="Navy">{** Dibuja un ObjetoVolador}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cVista.mDibujarOV">mDibujarOV</A>( proy: tPProy ); \r
+      <I><FONT COLOR="Navy">{** Dibuja el ObjetoVolador lockeado por la nave propia}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cVista.mDibujarOVLockeado">mDibujarOVLockeado</A>( proy: tPProy ); \r
+      <I><FONT COLOR="Navy">{** Muestra un mensaje de game over}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cVista.mGameOver">mGameOver</A>; \r
+      <I><FONT COLOR="Navy">{** Convierte un tipo tObjetosVoladores al nombre del archivo que guarda su bitmap}</FONT></I> \r
+      <B>function</B> <A HREF="#cVista.mObjetoVoladorToFilename">mObjetoVoladorToFilename</A>( obj: tObjetosVoladores ): <B>string</B>; \r
+      <I><FONT COLOR="Navy">{** Convierte un tipo tObjetosVoladores al nombre del archivo que guarda su bitmap lockeado}</FONT></I> \r
+      <B>function</B> <A HREF="#cVista.mObjetoVoladorLockedToFilename">mObjetoVoladorLockedToFilename</A>( obj: tObjetosVoladores ): <B>string</B>; \r
+      <I><FONT COLOR="Navy">{** Crea una cámara según el tipo}</FONT></I> \r
+      <B>function</B> <A HREF="#cVista.mCrearCamara">mCrearCamara</A>( cam: tCamaras; ov: cObjetoVolador ): cCamara; \r
+    <B>public</B> \r
+      <I><FONT COLOR="Navy">{** Constructor}</FONT></I> \r
+      <B>constructor</B> create( formulario: TCustomForm; ov: cObjetoVolador; calidad: boolean = true ); \r
+      <I><FONT COLOR="Navy">{** Dibuja todos los Objetos Voladores que ve la cámara}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cVista.mDibujarVista">mDibujarVista</A>( oEspacio: cEspacio ); \r
+      <I><FONT COLOR="Navy">{** Define el formulario en donde dibujar}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cVista.mSetForm">mSetForm</A>( oForm: TCustomForm ); \r
+      <I><FONT COLOR="Navy">{** Setea gráficos de alta calidad}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cVista.mSetAltaCalidad">mSetAltaCalidad</A>; \r
+      <I><FONT COLOR="Navy">{** Setea gráficos de baja calidad}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cVista.mSetBajaCalidad">mSetBajaCalidad</A>; \r
+      <I><FONT COLOR="Navy">{** Invierte la calidad de los gráficos. Es decir, si estaban en baja los pone \r
+          en alta y vice versa.}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cVista.mCambiarCalidad">mCambiarCalidad</A>; \r
+      <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar \r
+          y la información entregada depende del parámetro tDebugInfo.}</FONT></I> \r
+      <B>function</B> <A HREF="#cVista.mGetDebugInfo">mGetDebugInfo</A>( debugLevel: tDebugInfo = DI_MINI ): <B>string</B>; <B>override</B>; \r
+      <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+      <I><FONT COLOR="Navy">{** Permite realizar el cambio de camara}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cVista.mCambiarCamara">mCambiarCamara</A>( cam: tCamaras ); \r
+      <I><FONT COLOR="Navy">{** Cambia a la siguiente cámara}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cVista.mCamaraSiguiente">mCamaraSiguiente</A>; \r
+      <I><FONT COLOR="Navy">{** Devuelve que camara esta activa}</FONT></I> \r
+      <B>function</B> <A HREF="#cVista.mGetCamaraStr">mGetCamaraStr</A>: <B>string</B>; \r
+      <I><FONT COLOR="Navy">{** Crea la cámara del arma}</FONT></I> \r
+      <B>procedure</B> <A HREF="#cVista.mCrearCamaraDeArma">mCrearCamaraDeArma</A>( a: cArma ); \r
+      <I><FONT COLOR="Navy">{** Destructor}</FONT></I> \r
+      <B>destructor</B> destroy; <B>override</B>; \r
+  <B>end</B>; \r
\r
\r
+<B>implementation</B> \r
\r
+<B>uses</B> \r
+  Camaras; \r
\r
+<I><FONT COLOR="Navy">{ cVista }</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Constructor \r
+    @param formulario Formulario en donde dibujará la vista \r
+    @param ov         Objeto Volador en el cual montar la cámara}</FONT></I> \r
+<B>constructor</B> cVista.create(formulario: TCustomForm; ov: cObjetoVolador; calidad: boolean); \r
+<B>var</B> \r
+  obj:    tObjetosVoladores; \r
+  cam:    tCamaras; \r
+  bitmap: TBitmap; \r
+<B>begin</B> \r
+  <B>inherited</B> create; \r
+  <B>for</B> cam := CAMARA_FRONTAL <B>to</B> pred( CAMARA_ARMA ) <B>do</B> \r
+    aCamaras[cam] := mCrearCamara( cam, ov ); \r
+  aCamaras[CAMARA_ARMA] := <B>nil</B>; \r
+  aCamara := CAMARA_FRONTAL; \r
+  aAltaCalidad := calidad; \r
+  <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+  aListaProy := <B>nil</B>; \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+  mSetForm( formulario ); \r
+  <I><FONT COLOR="Navy">// Carga gráficos Comunes </FONT></I>\r
+  <B>for</B> obj := OV_NAVEPESADA <B>to</B> OV_MISDIR <B>do</B> <B>begin</B> \r
+    bitmap := TBitmap.create; \r
+    <B>with</B> bitmap <B>do</B> <B>begin</B> \r
+      LoadFromFile( mObjetoVoladorToFilename( obj ) ); \r
+      TransparentColor := clBlack; \r
+      TransparentMode  := tmFixed; \r
+      Transparent      := aAltaCalidad; \r
+    <B>end</B>; \r
+    aBitmaps[obj] := bitmap; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">// Carga gráficos Lockeados </FONT></I>\r
+  <B>for</B> obj := OV_NAVEPESADA <B>to</B> OV_NAVEPROPIA <B>do</B> <B>begin</B> \r
+    bitmap := TBitmap.create; \r
+    <B>with</B> bitmap <B>do</B> <B>begin</B> \r
+      LoadFromFile( mObjetoVoladorLockedToFilename( obj ) ); \r
+      TransparentColor := clBlack; \r
+      TransparentMode  := tmFixed; \r
+      Transparent      := aAltaCalidad; \r
+    <B>end</B>; \r
+    aBitmapsLocked[obj] := bitmap; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Destructor}</FONT></I> \r
+<B>destructor</B> cVista.destroy; \r
+<B>var</B> \r
+  obj: tObjetosVoladores; \r
+  cam: tCamaras; \r
+<B>begin</B> \r
+  <B>for</B> cam := CAMARA_FRONTAL <B>to</B> CAMARA_ARMA <B>do</B> \r
+    aCamaras[cam].free; \r
+  <B>for</B> obj := OV_NAVEPESADA <B>to</B> OV_MISDIR <B>do</B> <B>begin</B> \r
+    aBitmaps[obj].free; \r
+    aBitmapsLocked[obj].free; \r
+  <B>end</B>; \r
+  <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+  aListaProy.free; \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Dibuja un ObjetoVolador \r
+    @param proy Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion \r
+                de un determinado objeto volador (proporcionado por la cámara)}</FONT></I> \r
+<B>procedure</B> <A NAME=cVista.mDibujarOV>cVista.mDibujarOV</A>(proy: tPProy); \r
+<B>var</B> \r
+  rect:   TRect; \r
+  tam:    integer; \r
+<B>begin</B> \r
+  tam := mGetTam(proy); \r
+  rect.Left   := mGetX(proy); \r
+  rect.top    := mGetY(proy); \r
+  rect.right  := rect.left + tam; \r
+  rect.bottom := rect.top  + tam; \r
+  <I><FONT COLOR="Navy">// crea una region de dibujo //solo bmp </FONT></I>\r
+  <I><FONT COLOR="Navy">// asigna la region anterior </FONT></I>\r
+  SelectClipRgn( aFormulario.canvas.handle, aRegion ); \r
+  <I><FONT COLOR="Navy">// dibuja el bmp entero entre los puntos de rect o rect1 </FONT></I>\r
+  aFormulario.canvas.StretchDraw( rect, aBitmaps[proy^.oOV.mDibujar] ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Dibuja el ObjetoVolador lockeado por la nave propia \r
+    @param proy Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion \r
+                de un determinado objeto volador (proporcionado por la cámara)}</FONT></I> \r
+<B>procedure</B> <A NAME=cVista.mDibujarOVLockeado>cVista.mDibujarOVLockeado</A>(proy: tPProy); \r
+<B>var</B> \r
+  rect:    TRect; \r
+  tam:     integer; \r
+<B>begin</B> \r
+  tam := mGetTam(proy); \r
+  rect.Left   := mGetX(proy); \r
+  rect.top    := mGetY(proy); \r
+  rect.right  := rect.left + tam; \r
+  rect.bottom := rect.top  + tam; \r
+  <I><FONT COLOR="Navy">// crea una region de dibujo //solo bmp </FONT></I>\r
+  <I><FONT COLOR="Navy">// asigna la region anterior </FONT></I>\r
+  SelectClipRgn( aFormulario.canvas.handle, aRegion ); \r
+  <I><FONT COLOR="Navy">// dibuja el bmp entero entre los puntos de rect </FONT></I>\r
+  aFormulario.canvas.StretchDraw( rect, aBitmapsLocked[proy^.oOV.mDibujar] ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Dibuja todos los Objetos Voladores que ve la cámara \r
+    @param oEspacio Espacio del cual obtener la lista de objetos a interpretar por la cámara \r
+                    para dibujarlos}</FONT></I> \r
+<B>procedure</B> <A NAME=cVista.mDibujarVista>cVista.mDibujarVista</A>( oEspacio: cEspacio ); \r
+<B>var</B> \r
+  i:  integer; \r
+  pProy: tPProy; \r
+  <I><FONT COLOR="Navy">{$IFNDEF DebugAlgoWars}</FONT></I> \r
+  aListaProy: cLista; \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+  <I><FONT COLOR="Navy">// Libera la lista vieja </FONT></I>\r
+  aListaProy.free; \r
+  aListaProy := <B>nil</B>; \r
+  <I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
+  <I><FONT COLOR="Navy">//mantiene el circulo negro </FONT></I>\r
+  aFormulario.canvas.brush.Color := clblack; \r
+  aFormulario.canvas.ellipse( 0, 0, mGetFormLado, mGetFormLado ); \r
+  <B>if</B> aCamaras[aCamara] = <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si es la camara es nil </FONT></I>\r
+    mCamaraSiguiente; <I><FONT COLOR="Navy">// Selecciona la camara siguiente </FONT></I>\r
+  <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
+    aListaProy := aCamaras[aCamara].mProcesar( oEspacio.mGetObjetos ); \r
+    <B>for</B> i := 0 <B>to</B> aListaProy.Count - 1 <B>do</B> <B>begin</B> \r
+      pProy := aListaProy.items[i]; \r
+      <I><FONT COLOR="Navy">// Si el objeto volador lockeado por la nave propia es el actual... </FONT></I>\r
+      <B>if</B> oEspacio.mGetNavePropia.mGetLockeado = pProy^.oOV <B>then</B> \r
+        mDibujarOVLockeado( aListaProy.items[i] ) <I><FONT COLOR="Navy">// lo dibuja de una forma distinta </FONT></I>\r
+      <B>else</B>                                   <I><FONT COLOR="Navy">// si no... </FONT></I>\r
+        mDibujarOV( aListaProy.items[i] );        <I><FONT COLOR="Navy">// lo dibuja de la forma normal </FONT></I>\r
+    <B>end</B>; \r
+  <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
+    on e: ENavePropiaDestruida <B>do</B> <B>begin</B> \r
+      mGameOver; <I><FONT COLOR="Navy">// Muestra el mensaje de GAME OVER </FONT></I>\r
+      <B>raise</B>; <I><FONT COLOR="Navy">// Propaga la excepcion </FONT></I>\r
+    <B>end</B>; \r
+    on e: ECameramanDestruido <B>do</B> <B>begin</B> <I><FONT COLOR="Navy">// Si fue destruido el cameraman </FONT></I>\r
+      mCamaraSiguiente; <I><FONT COLOR="Navy">// pasa a la siguiente </FONT></I>\r
+    <B>end</B>; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Obtiene el lado menor del formulario \r
+    @return El alto o el ancho del formulario, dependiendo de cual sea menor}</FONT></I> \r
+<B>function</B> <A NAME=cVista.mGetFormLado>cVista.mGetFormLado</A>: integer; \r
+<B>begin</B> \r
+ <B>if</B> aFormulario.ClientWidth > aFormulario.ClientHeight <B>then</B> \r
+    result := aFormulario.ClientHeight \r
+  <B>else</B> \r
+    result := aFormulario.ClientWidth; \r
+    <I><FONT COLOR="Navy">//result:=409; </FONT></I>\r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Convierte el tamaño obtenido de la cámara a uno proporcional en píxeles \r
+    @param  proy Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion \r
+                 de un determinado objeto volador (proporcionado por la cámara) \r
+    @return      Tamaño del objeto en píxeles (tamaño del lado del cuadrado que se usará para \r
+                 dibujar el bitmap)}</FONT></I> \r
+<B>function</B> <A NAME=cVista.mGetTam>cVista.mGetTam</A>(proy: tPProy): integer; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Se calcula tomando un valor de la supuesta cabina de 1/2 metro, a partir de ahi es una </FONT></I>\r
+  <I><FONT COLOR="Navy">//  regla de 3 simple. </FONT></I>\r
+  <I><FONT COLOR="Navy">// NOTA: como los objetos quedan demasiado grandes, en vez de tomarse 1/2 metro, se toma mas pequeña </FONT></I>\r
+  <I><FONT COLOR="Navy">// La dimension se multiplica por 2 porque es el radio de la nave </FONT></I>\r
+  <I><FONT COLOR="Navy">//  TAM = tam * (dim * 2) * (lado / 2) / 25 (metros) = tam * dim * lado / 25 </FONT></I>\r
+  result := round( proy^.tam * proy^.oOV.mGetDimension * mGetFormLado / 25 ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Convierte la componente en x obtenida de la cámara a una proporcional en píxeles \r
+    @param  proy Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion \r
+                 de un determinado objeto volador (proporcionado por la cámara) \r
+    @return      Componente en X del objeto en píxeles (x de la esquina superior izquierdadel \r
+                 cuadrado que se usará para dibujar el bitmap)}</FONT></I> \r
+<B>function</B> <A NAME=cVista.mGetX>cVista.mGetX</A>(proy: tPProy): integer; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Se calcula por medio de una regla de 3 simple teniendo en cuenta los tamaños maximos y se le </FONT></I>\r
+  <I><FONT COLOR="Navy">//  resta la mitad del tamaño porque se dibuja a partir de la esquina superior izquierda, no a </FONT></I>\r
+  <I><FONT COLOR="Navy">//  partir del centro como es en el modelo. </FONT></I>\r
+  result := round( proy^.x * (mGetFormLado / 2) / aCamaras[aCamara].mGetRadioPantalla + mGetFormLado / 2 ) - \r
+            mGetTam( proy ) <B>div</B> 2; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Convierte la componente en y obtenida de la cámara a una proporcional en píxeles \r
+    @param  proy Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion \r
+                 de un determinado objeto volador (proporcionado por la cámara) \r
+    @return      Componente en Y del objeto en píxeles (y de la esquina superior izquierdadel \r
+                 cuadrado que se usará para dibujar el bitmap)}</FONT></I> \r
+<B>function</B> <A NAME=cVista.mGetY>cVista.mGetY</A>(proy: tPProy): integer; \r
+<B>begin</B> \r
+  <I><FONT COLOR="Navy">// Se calcula por medio de una regla de 3 simple teniendo en cuenta los tamaños maximos y se le </FONT></I>\r
+  <I><FONT COLOR="Navy">//  resta la mitad del tamaño porque se dibuja a partir de la esquina superior izquierda, no a </FONT></I>\r
+  <I><FONT COLOR="Navy">//  partir del centro como es en el modelo. </FONT></I>\r
+  result := round( proy^.y * (mGetFormLado / 2) / aCamaras[aCamara].mGetRadioPantalla + mGetFormLado / 2 ) - \r
+            mGetTam( proy ) <B>div</B> 2; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Define el formulario en donde dibujar \r
+    @param oForm Formulario en el cual dibujará la vista}</FONT></I> \r
+<B>procedure</B> <A NAME=cVista.mSetForm>cVista.mSetForm</A>(oForm: TCustomForm); \r
+<B>begin</B> \r
+  aFormulario := oForm; \r
+  aRegion := CreateEllipticRgn( 0, 0, mGetFormLado, mGetFormLado ); \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{$IFDEF DebugAlgoWars}</FONT></I> \r
+<I><FONT COLOR="Navy">{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos. \r
+    @return            Cadena de texto con el estado del Objeto. \r
+    @param   debugLevel Cantidad de información requerida}</FONT></I> \r
+<B>function</B> <A NAME=cVista.mGetDebugInfo>cVista.mGetDebugInfo</A>( debugLevel: tDebugInfo ): <B>string</B>; \r
+<B>var</B> \r
+  i:    integer;  <I><FONT COLOR="Navy">// contador </FONT></I>\r
+  proy: tPProy;   <I><FONT COLOR="Navy">// variable temporal para obtener info de la proyeccion </FONT></I>\r
+  camInfo: <B>string</B>; \r
+<B>begin</B> \r
+  result := 'Cámara: ' + #13 + #10; \r
+  <B>try</B> <I><FONT COLOR="Navy">// Probamos que el cameraman no este destruido </FONT></I>\r
+    camInfo := aCamaras[aCamara].mGetDebugInfo( debugLevel ); \r
+  <B>except</B> <I><FONT COLOR="Navy">// Si esta destruido cae en una excepcion </FONT></I>\r
+    on e: ECameramanDestruido <B>do</B> \r
+      camInfo := e.<B>Message</B>; \r
+  <B>end</B>; \r
+  result := result + camInfo; \r
+  <I><FONT COLOR="Navy">// Genera el string con el estado del Espacio </FONT></I>\r
+  <B>if</B> aListaProy <> <B>nil</B> <B>then</B> <B>begin</B> \r
+    <B>for</B> i := 0 <B>to</B> aListaProy.Count - 1 <B>do</B> <B>begin</B> \r
+      proy := aListaProy.Items[i]; \r
+      result := result + #13 + #10 + \r
+                'ObjetoVolador Proyectado ' + IntToStr( i ) + ': ' + proy^.oOV.ClassName + \r
+                ' | X: ' + IntToStr( mGetX( proy ) ) + \r
+                ' | Y: ' + IntToStr( mGetY( proy ) ) + \r
+                ' | Tam: ' + IntToStr( mGetTam( proy ) ); \r
+      <B>if</B> debugLevel > DI_NORMAL <B>then</B> \r
+        result := result + #13 + #10 + \r
+                  'X (cámara): ' + FloatToStrF( proy^.x, ffNumber, 5, 5 ) + \r
+                  ' | Y (cámara): ' + FloatToStrF( proy^.y, ffNumber, 5, 5 ) + \r
+                  ' | Tam (cámara): ' + FloatToStrF( proy^.tam, ffNumber, 5, 5 ); \r
+    <B>end</B>; \r
+  <B>end</B>; \r
+<B>end</B>; \r
+<I><FONT COLOR="Navy">{$ENDIF}</FONT></I> \r
\r
+<I><FONT COLOR="Navy">{** Muestra un mensaje de game over}</FONT></I> \r
+<B>procedure</B> <A NAME=cVista.mGameOver>cVista.mGameOver</A>; \r
+<B>var</B> \r
+  rect: TRect; \r
+  bitm: TBitMap; \r
+<B>begin</B> \r
+  rect.Left   := 100; \r
+  rect.top    := 150; \r
+  rect.right  := 300; \r
+  rect.bottom := 250; \r
+  <I><FONT COLOR="Navy">// crea una region de dibujo //solo bmp </FONT></I>\r
+  <I><FONT COLOR="Navy">// asigna la region anterior </FONT></I>\r
+  SelectClipRgn( aFormulario.canvas.handle, aRegion ); \r
+  <I><FONT COLOR="Navy">// dibuja el bmp entero entre los puntos de rect o rect1 </FONT></I>\r
+  bitm := TBitMap.create; \r
+  bitm.LoadFromFile( 'bitmaps/gameover.bmp' ); \r
+  aFormulario.canvas.StretchDraw( rect, bitm ); \r
+  <I><FONT COLOR="Navy">// canvas.stretchdraw(rect1,bitm); </FONT></I>\r
+  bitm.free; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Convierte un tipo tObjetosVoladores al nombre del archivo que guarda su bitmap \r
+    @param obj Tipo de objeto volador \r
+    @return Nombre del archivo que almacena el bitmap que lo representa}</FONT></I> \r
+<B>function</B> <A NAME=cVista.mObjetoVoladorToFilename>cVista.mObjetoVoladorToFilename</A>(obj: tObjetosVoladores): <B>string</B>; \r
+<B>begin</B> \r
+  <B>case</B> obj <B>of</B> \r
+    OV_METEORITO:   result := 'bitmaps/meteorito.bmp'; \r
+    OV_LASER:       result := 'bitmaps/laser.bmp'; \r
+    OV_MISIL:       result := 'bitmaps/misil.bmp'; \r
+    OV_MISDIR:      result := 'bitmaps/misildirigido.bmp'; \r
+    OV_NAVEPROPIA:  result := 'bitmaps/navepropia.bmp'; \r
+    OV_NAVEPESADA:  result := 'bitmaps/navepesada.bmp'; \r
+    OV_NAVELIVIANA: result := 'bitmaps/naveliviana.bmp'; \r
+    OV_NAVEESPIA:   result := 'bitmaps/naveespia.bmp'; \r
+    OV_NAVESUICIDA: result := 'bitmaps/navesuicida.bmp'; \r
+    <B>else</B>            result := 'bitmaps/desconocido.bmp'; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Convierte un tipo tObjetosVoladores al nombre del archivo que guarda su bitmap lockeado \r
+    @param obj Tipo de objeto volador \r
+    @return Nombre del archivo que almacena el bitmap que lo representa}</FONT></I> \r
+<B>function</B> <A NAME=cVista.mObjetoVoladorLockedToFilename>cVista.mObjetoVoladorLockedToFilename</A>( \r
+  obj: tObjetosVoladores): <B>string</B>; \r
+<B>begin</B> \r
+  <B>case</B> obj <B>of</B> \r
+    OV_METEORITO:   result := 'bitmaps/meteorito_l.bmp'; \r
+    OV_NAVEPROPIA:  result := 'bitmaps/navepropia_l.bmp'; \r
+    OV_NAVEPESADA:  result := 'bitmaps/navepesada_l.bmp'; \r
+    OV_NAVELIVIANA: result := 'bitmaps/naveliviana_l.bmp'; \r
+    OV_NAVEESPIA:   result := 'bitmaps/naveespia_l.bmp'; \r
+    OV_NAVESUICIDA: result := 'bitmaps/navesuicida_l.bmp'; \r
+    <B>else</B>            result := 'bitmaps/desconocido_l.bmp'; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Setea gráficos de alta calidad}</FONT></I> \r
+<B>procedure</B> <A NAME=cVista.mSetAltaCalidad>cVista.mSetAltaCalidad</A>; \r
+<B>begin</B> \r
+  <B>if</B> <B>not</B> aAltaCalidad <B>then</B> <I><FONT COLOR="Navy">// Si no estan seteados como de alta calidad... </FONT></I>\r
+  mCambiarCalidad; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Setea gráficos de baja calidad}</FONT></I> \r
+<B>procedure</B> <A NAME=cVista.mSetBajaCalidad>cVista.mSetBajaCalidad</A>; \r
+<B>begin</B> \r
+  <B>if</B> aAltaCalidad <B>then</B> <I><FONT COLOR="Navy">// Si no estan seteados como de alta calidad... </FONT></I>\r
+  mCambiarCalidad; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Invierte la calidad de los gráficos. Es decir, si estaban en baja los pone \r
+    en alta y vice versa.}</FONT></I> \r
+<B>procedure</B> <A NAME=cVista.mCambiarCalidad>cVista.mCambiarCalidad</A>; \r
+<B>var</B> \r
+  obj: tObjetosVoladores; \r
+<B>begin</B> \r
+  aAltaCalidad := <B>not</B> aAltaCalidad; \r
+  <B>for</B> obj := OV_NAVEPESADA <B>to</B> OV_MISDIR <B>do</B> \r
+    aBitmaps[obj].Transparent := aAltaCalidad; \r
+  <B>for</B> obj := OV_NAVEPESADA <B>to</B> OV_NAVEPROPIA <B>do</B> \r
+    aBitmapsLocked[obj].Transparent := aAltaCalidad; \r
+<B>end</B>; \r
\r
+<B>procedure</B> <A NAME=cVista.mCambiarCamara>cVista.mCambiarCamara</A>(cam : tCamaras); \r
+<B>begin</B> \r
+  <B>if</B> aCamaras[cam] <>  <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si esta creada es camara, la cambia </FONT></I>\r
+    aCamara := cam; \r
+<B>end</B>; \r
\r
+<B>function</B> <A NAME=cVista.mGetCamaraStr>cVista.mGetCamaraStr</A>: <B>string</B>; \r
+<B>begin</B> \r
+  <B>case</B> aCamara <B>of</B> \r
+    CAMARA_FRONTAL: result := 'Cámara Frontal'; \r
+    CAMARA_LATDER:  result := 'Cámara Lateral Derecha'; \r
+    CAMARA_LATIZQ:  result := 'Cámara Lateral Izquierda'; \r
+    CAMARA_TRASERA: result := 'Cámara Trasera'; \r
+    CAMARA_ARRIBA:  result := 'Cámara Superior'; \r
+    CAMARA_ABAJO:   result := 'Cámara Inferior'; \r
+    CAMARA_MAPA:    result := 'Mapa del Escenario'; \r
+    CAMARA_ARMA:    result := 'Cámara en el Arma'; \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Crea una cámara según el tipo \r
+    @param  cam Tipo de Cámara \r
+    @param  ov  Portador de la cámara \r
+    @return Nueva cámara creada}</FONT></I> \r
+<B>function</B> <A NAME=cVista.mCrearCamara>cVista.mCrearCamara</A>(cam: tCamaras; ov: cObjetoVolador): cCamara; \r
+<B>begin</B> \r
+  <B>case</B> cam <B>of</B> \r
+    CAMARA_FRONTAL: result := cCamaraFrontal.create( ov, 1 ); <I><FONT COLOR="Navy">// Se la crea con un poco mas de angulo que el comun </FONT></I>\r
+    CAMARA_LATDER:  result := cCamaraLatDer.create( ov, 1 );  <I><FONT COLOR="Navy">// Se la crea con un poco mas de angulo que el comun </FONT></I>\r
+    CAMARA_LATIZQ:  result := cCamaraLatIzq.create( ov, 1 );  <I><FONT COLOR="Navy">// Se la crea con un poco mas de angulo que el comun </FONT></I>\r
+    CAMARA_TRASERA: result := cCamaraTrasera.create( ov, 1 ); <I><FONT COLOR="Navy">// Se la crea con un poco mas de angulo que el comun </FONT></I>\r
+    CAMARA_ARRIBA:  result := cCamaraArriba.create( ov, 1 );  <I><FONT COLOR="Navy">// Se la crea con un poco mas de angulo que el comun </FONT></I>\r
+    CAMARA_ABAJO:   result := cCamaraAbajo.create( ov, 1 );   <I><FONT COLOR="Navy">// Se la crea con un poco mas de angulo que el comun </FONT></I>\r
+    CAMARA_MAPA:    result := cCamaraMapa.create( ov, 1 );    <I><FONT COLOR="Navy">// Se la crea con un poco mas de angulo que el comun </FONT></I>\r
+    CAMARA_ARMA:    result := cCamaraFrontal.create( ov, 1 ); <I><FONT COLOR="Navy">// Se la crea con un poco mas de angulo que el comun </FONT></I>\r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Cambia a la siguiente cámara}</FONT></I> \r
+<B>procedure</B> <A NAME=cVista.mCamaraSiguiente>cVista.mCamaraSiguiente</A>; \r
+<B>var</B> \r
+  cam: tCamaras; \r
+<B>begin</B> \r
+  cam := succ( aCamara ); <I><FONT COLOR="Navy">// Pasa a la próxima </FONT></I>\r
+  <B>if</B> cam > CAMARA_ARMA <B>then</B> <I><FONT COLOR="Navy">// Si se paso del ultimo ... </FONT></I>\r
+    aCamara := CAMARA_FRONTAL <I><FONT COLOR="Navy">// Vuelve a la primera </FONT></I>\r
+  <B>else</B> \r
+    <B>if</B> cam = CAMARA_ARMA <B>then</B> <I><FONT COLOR="Navy">// Si es la camara del misil... </FONT></I>\r
+      <B>if</B> aCamaras[aCamara] = <B>nil</B> <B>then</B> <I><FONT COLOR="Navy">// Si no esta activa... </FONT></I>\r
+        aCamara := CAMARA_FRONTAL <I><FONT COLOR="Navy">// Vuelve a la camara frontal </FONT></I>\r
+      <B>else</B> <I><FONT COLOR="Navy">// si esta todo normal... </FONT></I>\r
+        aCamara := cam \r
+    <B>else</B> <I><FONT COLOR="Navy">// si esta todo normal... </FONT></I>\r
+        aCamara := cam \r
+<B>end</B>; \r
\r
+<I><FONT COLOR="Navy">{** Crea la cámara del arma \r
+    @param ov Objeto Volador portador de la camara}</FONT></I> \r
+<B>procedure</B> <A NAME=cVista.mCrearCamaraDeArma>cVista.mCrearCamaraDeArma</A>(a: cArma); \r
+<B>begin</B> \r
+  <B>if</B> a <> <B>nil</B> <B>then</B> <B>begin</B> \r
+    <B>if</B> aCamaras[CAMARA_ARMA] <> <B>nil</B> <B>then</B> \r
+      aCamaras[CAMARA_ARMA].free; \r
+    aCamaras[CAMARA_ARMA] := mCrearCamara( CAMARA_ARMA, a ); \r
+  <B>end</B>; \r
+<B>end</B>; \r
\r
+<B>end</B>. \r
+</PRE>\r
+</BODY>\r
+</HTML>\r
diff --git a/doc/uml/diagrama.dia b/doc/uml/diagrama.dia
new file mode 100644 (file)
index 0000000..ab81c0c
--- /dev/null
@@ -0,0 +1,660 @@
+<?xml version="1.0"?>\r
+<diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">\r
+  <diagramdata>\r
+    <attribute name="background">\r
+      <color val="#ffffff"/>\r
+    </attribute>\r
+    <attribute name="paper">\r
+      <composite type="paper">\r
+        <attribute name="name">\r
+          <string>#A4#</string>\r
+        </attribute>\r
+        <attribute name="tmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="bmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="lmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="rmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="is_portrait">\r
+          <boolean val="true"/>\r
+        </attribute>\r
+        <attribute name="scaling">\r
+          <real val="1"/>\r
+        </attribute>\r
+        <attribute name="fitto">\r
+          <boolean val="false"/>\r
+        </attribute>\r
+      </composite>\r
+    </attribute>\r
+  </diagramdata>\r
+  <layer name="Background" visible="true">\r
+    <object type="UML - Class" version="0" id="O0">\r
+      <attribute name="obj_pos">\r
+        <point val="28,14"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="27.95,13.95;35.3746,15.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="28,14"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="7.3246"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="1.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cObjetoVolador#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations"/>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O1">\r
+      <attribute name="obj_pos">\r
+        <point val="21,7"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="20.95,6.95;25.688,8.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="21,7"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="4.638"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="1.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cEspacio#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations"/>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O2">\r
+      <attribute name="obj_pos">\r
+        <point val="24,23"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="23.95,22.95;32.9946,24.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="24,23"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="8.94464"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="1.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cArma#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="attributes">\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aAlcance#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tTiempo#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="operations"/>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O3">\r
+      <attribute name="obj_pos">\r
+        <point val="17,19"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="16.95,18.95;20.4255,20.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="17,19"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="3.3755"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="1.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cNave#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations"/>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O4">\r
+      <attribute name="obj_pos">\r
+        <point val="36,21"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="35.95,20.95;42.5969,22.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="36,21"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="6.5469"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="1.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cMisilDirigido#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations"/>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O5">\r
+      <attribute name="obj_pos">\r
+        <point val="11,14"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="10.95,13.95;17.1525,15.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="11,14"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="6.1025"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="1.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cNavePropia#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations"/>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O6">\r
+      <attribute name="obj_pos">\r
+        <point val="2,21"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="1.95,20.95;9.0716,22.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="2,21"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="7.0216"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="1.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cNaveEnemiga#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations"/>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Association" version="0" id="O7">\r
+      <attribute name="obj_pos">\r
+        <point val="22.419,8.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="12.6013,6.95;23.869,15.45"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="22.419,8.4"/>\r
+        <point val="22.419,11"/>\r
+        <point val="14.0513,11"/>\r
+        <point val="14.0513,14"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#juega en#</string>\r
+      </attribute>\r
+      <attribute name="direction">\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="ends">\r
+        <composite>\r
+          <attribute name="role">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="multiplicity">\r
+            <string># 1#</string>\r
+          </attribute>\r
+          <attribute name="arrow">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="aggregate">\r
+            <enum val="1"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite>\r
+          <attribute name="role">\r
+            <string># juegador#</string>\r
+          </attribute>\r
+          <attribute name="multiplicity">\r
+            <string># 0..1#</string>\r
+          </attribute>\r
+          <attribute name="arrow">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="aggregate">\r
+            <enum val="0"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="1" to="O5" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Association" version="0" id="O8">\r
+      <attribute name="obj_pos">\r
+        <point val="24.3466,8.41467"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="22.8966,6.96467;33.1123,15.45"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="24.3466,8.41467"/>\r
+        <point val="24.3466,11"/>\r
+        <point val="31.6623,11"/>\r
+        <point val="31.6623,14"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#vuela en#</string>\r
+      </attribute>\r
+      <attribute name="direction">\r
+        <enum val="2"/>\r
+      </attribute>\r
+      <attribute name="ends">\r
+        <composite>\r
+          <attribute name="role">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="multiplicity">\r
+            <string># 1#</string>\r
+          </attribute>\r
+          <attribute name="arrow">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="aggregate">\r
+            <enum val="1"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite>\r
+          <attribute name="role">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="multiplicity">\r
+            <string># *#</string>\r
+          </attribute>\r
+          <attribute name="arrow">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="aggregate">\r
+            <enum val="0"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="1" to="O0" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Association" version="0" id="O9">\r
+      <attribute name="obj_pos">\r
+        <point val="31.6623,15.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="30.2123,13.95;43.5458,22.45"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="31.6623,15.4"/>\r
+        <point val="31.6623,18"/>\r
+        <point val="39.2734,18"/>\r
+        <point val="39.2734,21"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#Persigue a#</string>\r
+      </attribute>\r
+      <attribute name="direction">\r
+        <enum val="2"/>\r
+      </attribute>\r
+      <attribute name="ends">\r
+        <composite>\r
+          <attribute name="role">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="multiplicity">\r
+            <string># 1#</string>\r
+          </attribute>\r
+          <attribute name="arrow">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="aggregate">\r
+            <enum val="0"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite>\r
+          <attribute name="role">\r
+            <string># objetivo#</string>\r
+          </attribute>\r
+          <attribute name="multiplicity">\r
+            <string># 0..1#</string>\r
+          </attribute>\r
+          <attribute name="arrow">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="aggregate">\r
+            <enum val="0"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O0" connection="6"/>\r
+        <connection handle="1" to="O4" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Association" version="0" id="O10">\r
+      <attribute name="obj_pos">\r
+        <point val="18.6878,20.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="17.2378,18.95;29.9223,24.45"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="18.6878,20.4"/>\r
+        <point val="18.6878,22"/>\r
+        <point val="28.4723,22"/>\r
+        <point val="28.4723,23"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#puede disparar#</string>\r
+      </attribute>\r
+      <attribute name="direction">\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="ends">\r
+        <composite>\r
+          <attribute name="role">\r
+            <string># 1#</string>\r
+          </attribute>\r
+          <attribute name="multiplicity">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="arrow">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="aggregate">\r
+            <enum val="0"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite>\r
+          <attribute name="role">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="multiplicity">\r
+            <string># *#</string>\r
+          </attribute>\r
+          <attribute name="arrow">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="aggregate">\r
+            <enum val="0"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O3" connection="6"/>\r
+        <connection handle="1" to="O2" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Association" version="0" id="O11">\r
+      <attribute name="obj_pos">\r
+        <point val="5.5108,21"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="4.0608,13.95;15.5012,22.6"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="5.5108,21"/>\r
+        <point val="5.5108,18"/>\r
+        <point val="14.0513,18"/>\r
+        <point val="14.0513,15.4"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#reacciona con#</string>\r
+      </attribute>\r
+      <attribute name="direction">\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="ends">\r
+        <composite>\r
+          <attribute name="role">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="multiplicity">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="arrow">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="aggregate">\r
+            <enum val="0"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite>\r
+          <attribute name="role">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="multiplicity">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="arrow">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="aggregate">\r
+            <enum val="0"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O6" connection="1"/>\r
+        <connection handle="1" to="O5" connection="6"/>\r
+      </connections>\r
+    </object>\r
+  </layer>\r
+</diagram>\r
diff --git a/doc/uml/diagrama.png b/doc/uml/diagrama.png
new file mode 100644 (file)
index 0000000..ac98207
Binary files /dev/null and b/doc/uml/diagrama.png differ
diff --git a/doc/uml/estado.png b/doc/uml/estado.png
new file mode 100644 (file)
index 0000000..e5ad73e
Binary files /dev/null and b/doc/uml/estado.png differ
diff --git a/doc/uml/jerarquia.dia b/doc/uml/jerarquia.dia
new file mode 100644 (file)
index 0000000..3b8db7d
--- /dev/null
@@ -0,0 +1,4415 @@
+<?xml version="1.0"?>\r
+<diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">\r
+  <diagramdata>\r
+    <attribute name="background">\r
+      <color val="#ffffff"/>\r
+    </attribute>\r
+    <attribute name="paper">\r
+      <composite type="paper">\r
+        <attribute name="name">\r
+          <string>#A4#</string>\r
+        </attribute>\r
+        <attribute name="tmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="bmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="lmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="rmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="is_portrait">\r
+          <boolean val="true"/>\r
+        </attribute>\r
+        <attribute name="scaling">\r
+          <real val="1"/>\r
+        </attribute>\r
+        <attribute name="fitto">\r
+          <boolean val="false"/>\r
+        </attribute>\r
+      </composite>\r
+    </attribute>\r
+  </diagramdata>\r
+  <layer name="Background" visible="true">\r
+    <object type="UML - Class" version="0" id="O0">\r
+      <attribute name="obj_pos">\r
+        <point val="30,2"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="29.95,1.95;54.8314,19.05"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="30,2"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="24.7814"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="17"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cVector#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes">\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aX#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aY#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aZ#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mHacerVersor#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mSet#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#x#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#y#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#z#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>##</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>##</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mSet#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#v#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mAddX#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#x#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mAddY#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#y#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mAddZ#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#z#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mSetModulo#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#modulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mAddModulo#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#modulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mGetModulo#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mSumar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#vec#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mRestar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#vec#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mMultiplicar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#vec#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mMultiplicar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#esc#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mMultiplicarEsc#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#vec#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mGetDistancia#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#vec#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mModificarCon#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#vel#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dT#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tTiempo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O1">\r
+      <attribute name="obj_pos">\r
+        <point val="30,23"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="29.95,22.95;44.8769,32.05"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="30,23"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="14.8269"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="9"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cCoordenadas#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes">\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aI#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aJ#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aK#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mRotarEnI#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dAngulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tAngulo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mRotatEnJ#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dAngulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tAngulo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mRotarEnK#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dAngulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tAngulo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mSetI#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cCoordenadas#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#v#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mSetJ#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cCoordenadas#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#v#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mSetK#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cCoordenadas#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#v#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O2">\r
+      <attribute name="obj_pos">\r
+        <point val="-15.95,2.05"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-16,2;4.80912,12.7"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="-15.95,2.05"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="20.7091"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="10.6"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cObjetoVolador#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes">\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aPosicion#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aVelocidad#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aPotencia#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tEnergia#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aEnergia#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tEnergia#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aDimension#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aCoordenadas#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cCoordenadas#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mMover#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dT#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tTiempo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mGetDistancia#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#ov#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cObjetoVolador#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mColisiono#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#boolean#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#ov#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cObjetoVolador#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mRestarEnergia#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#ene#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tEnergia#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDibujar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tObjetosVoladores#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="true"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O3">\r
+      <attribute name="obj_pos">\r
+        <point val="-54,2"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-54.05,1.95;-33.2409,9.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="-54,2"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="20.7091"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="7.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cEspacio#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes">\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aDeltaT#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tTiempo#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aObjetos#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#TList#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aNavePropia#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cNavePropia#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDetectarColision#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mActualizar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mComunicarPosicion#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#sEsp#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cNaveEspia#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mActualizarObjetoVolador#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#ov#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cObjetoVolador#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O4">\r
+      <attribute name="obj_pos">\r
+        <point val="1.3,20"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="1.25,19.95;16.6294,26.65"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="1.3,20"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="15.2794"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="6.6"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cArma#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes">\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aAlcance#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aDuracion#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tTiempo#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aVelMaxima#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mActualizarDuracion#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dt#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tTiempo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mActivo#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#boolean#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mMover#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dt#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tTiempo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O5">\r
+      <attribute name="obj_pos">\r
+        <point val="-10.3,20.05"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-10.35,20;4.1244,22.9"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="-10.3,20.05"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="14.3744"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="2.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cMeteorito#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDibujar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tObjetosVoladores#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O6">\r
+      <attribute name="obj_pos">\r
+        <point val="-5.59544,12.65"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-6.44544,11.8;-2.2628,20.9"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="-5.59544,12.65"/>\r
+        <point val="-5.59544,18"/>\r
+        <point val="-3.1128,18"/>\r
+        <point val="-3.1128,20.05"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O2" connection="6"/>\r
+        <connection handle="1" to="O5" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O7">\r
+      <attribute name="obj_pos">\r
+        <point val="-5.59544,12.65"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-6.44544,11.8;9.78968,20.85"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="-5.59544,12.65"/>\r
+        <point val="-5.59544,18"/>\r
+        <point val="8.93968,18"/>\r
+        <point val="8.93968,20"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O2" connection="6"/>\r
+        <connection handle="1" to="O4" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O8">\r
+      <attribute name="obj_pos">\r
+        <point val="-42.2,20"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-42.25,19.95;-14.2012,41.05"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="-42.2,20"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="27.9488"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="21"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cNave#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes">\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aMisiles#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tMaxMisil#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aMisilesDirigidos#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tMaxMisilDirigido#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aVelMaxima#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aRetardoLaser#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tTiempo#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aRetardoMisil#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tTiempo#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aRetardoMisDir#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tTiempo#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aRetardoLaserCont#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tTiempo#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aRetardoMisilCont#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tTiempo#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aRetardoMisDirCont#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tTiempo#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mRestarMisil#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mRestarMisilDirigido#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mTieneMisil#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#boolean#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mTieneMisilDirigido#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#boolean#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mRetardarLaser#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mRetardarMisil#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mRetardarMisDir#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mActualizarRetardadores#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dT#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tTiempo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mCrearLaserDisparado#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cLaser#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mCrearMisilDisparado#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cMisil#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mCrearMisDirDisparado#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cMisilDirigido#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#ov#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cObjetoVolador#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDisparar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cArma#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dT#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tTiempo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#ov#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cObjetoVolador#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string>#nil#</string>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mPuedeDispararLaser#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#boolean#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#ov#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cObjetoVolador#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mPuedeDispararMisil#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#boolean#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dT#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tTiempo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#ov#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cObjetoVolador#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mPuedeDispararMisDir#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#boolean#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dT#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tTiempo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#ov#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cObjetoVolador#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O9">\r
+      <attribute name="obj_pos">\r
+        <point val="-5.59544,12.65"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-29.0756,11.8;-4.74544,20.85"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="-5.59544,12.65"/>\r
+        <point val="-5.59544,18"/>\r
+        <point val="-28.2256,18"/>\r
+        <point val="-28.2256,20"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O2" connection="6"/>\r
+        <connection handle="1" to="O8" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O10">\r
+      <attribute name="obj_pos">\r
+        <point val="0.15,31.05"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="0.1,31;14.5744,33.9"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="0.15,31.05"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="14.3744"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="2.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cLaser#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDibujar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tObjetosVoladores#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O11">\r
+      <attribute name="obj_pos">\r
+        <point val="16,31"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="15.95,30.95;30.4244,33.85"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="16,31"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="14.3744"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="2.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cMisil#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDibujar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tObjetosVoladores#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O12">\r
+      <attribute name="obj_pos">\r
+        <point val="8.93968,26.6"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="6.4872,25.75;9.78968,31.9"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="8.93968,26.6"/>\r
+        <point val="8.93968,28"/>\r
+        <point val="7.3372,28"/>\r
+        <point val="7.3372,31.05"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O4" connection="6"/>\r
+        <connection handle="1" to="O10" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O13">\r
+      <attribute name="obj_pos">\r
+        <point val="8.93968,26.6"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="8.08968,25.75;24.0372,31.85"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="8.93968,26.6"/>\r
+        <point val="8.93968,28"/>\r
+        <point val="23.1872,28"/>\r
+        <point val="23.1872,31"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O4" connection="6"/>\r
+        <connection handle="1" to="O11" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O14">\r
+      <attribute name="obj_pos">\r
+        <point val="14.4,36.75"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="14.35,36.7;28.8244,42.6"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="14.4,36.75"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="14.3744"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="5.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cMisilDirigido#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes">\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aObjetivo#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cObjetoVolador#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aLockArea#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mModificarVelocidad#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mMover#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dt#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tTiempo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDibujar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tObjetosVoladores#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O15">\r
+      <attribute name="obj_pos">\r
+        <point val="23.1872,33.8"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="20.7372,32.95;24.0372,37.6"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="23.1872,33.8"/>\r
+        <point val="23.1872,35.4928"/>\r
+        <point val="21.5872,35.4928"/>\r
+        <point val="21.5872,36.75"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O11" connection="6"/>\r
+        <connection handle="1" to="O14" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O16">\r
+      <attribute name="obj_pos">\r
+        <point val="-53.25,45.2"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-53.3,45.15;-29.3235,61.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="-53.25,45.2"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="23.8765"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="16.2"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cNavePropia#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes">\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aLockeado#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cObjetoVolador#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aArmaSelec#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tArma#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aDisparando#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cArma#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aLockFiltro#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cFiltroLock#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDisparar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cArma#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dT#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tTiempo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#ov#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cObjetoVolador#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string>#nil#</string>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mRotarIzquierda#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#angulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tAngulo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mRotarDerecha#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#angulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tAngulo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mGirarIzquierda#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#angulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tAngulo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mGirarDerecha#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#angulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tAngulo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mGirarArriba#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#angulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tAngulo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mGirarAbajo#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#angulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tAngulo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mAcelerar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#modulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDesacelerar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#modulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDibujar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tObjetosVoladores#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mCambiarLockeado#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#lEnemigos#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#TList#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mIntentarDisparo#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cArma#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mSeleccionarArma#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#a#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tArma#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mSeleccionarArmaSig#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O17">\r
+      <attribute name="obj_pos">\r
+        <point val="-22.75,45.3"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-22.8,45.25;3.43888,51.15"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="-22.75,45.3"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="26.1389"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="5.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cNaveEnemiga#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes">\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aCampoRadar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mModificarVelocidad#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#np#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cNavePropia#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#modulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string>#-1#</string>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mReaccionar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="true"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#np#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cNavePropia#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDetectado#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#boolean#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#ov#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cObjetoVolador#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mIrA#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#pos#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O18">\r
+      <attribute name="obj_pos">\r
+        <point val="-28.2256,41"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-42.1618,40.15;-27.3756,46.05"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="-28.2256,41"/>\r
+        <point val="-28.2256,42.4628"/>\r
+        <point val="-41.3118,42.4628"/>\r
+        <point val="-41.3118,45.2"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O8" connection="6"/>\r
+        <connection handle="1" to="O16" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O19">\r
+      <attribute name="obj_pos">\r
+        <point val="-28.2256,41"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-29.0756,40.15;-8.83056,46.15"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="-28.2256,41"/>\r
+        <point val="-28.2256,42.4628"/>\r
+        <point val="-9.68056,42.4628"/>\r
+        <point val="-9.68056,45.3"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O8" connection="6"/>\r
+        <connection handle="1" to="O17" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O20">\r
+      <attribute name="obj_pos">\r
+        <point val="-48.6,69.45"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-48.65,69.4;-34.1756,73.7"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="-48.6,69.45"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="14.3744"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="4.2"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cNavePesada#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes">\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aRadioMinimo#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mReaccionar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#np#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cNavePropia#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDibujar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tObjetosVoladores#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O21">\r
+      <attribute name="obj_pos">\r
+        <point val="-24.975,69.6"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-25.025,69.55;-10.5506,73.85"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="-24.975,69.6"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="14.3744"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="4.2"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cNaveLiviana#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes">\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aRadioMinimo#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mReaccionar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#np#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cNavePropia#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDibujar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tObjetosVoladores#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O22">\r
+      <attribute name="obj_pos">\r
+        <point val="-9.68056,51.1"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-42.2628,50.25;-8.83056,70.3"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="-9.68056,51.1"/>\r
+        <point val="-9.68056,67.764"/>\r
+        <point val="-41.4128,67.764"/>\r
+        <point val="-41.4128,69.45"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O17" connection="6"/>\r
+        <connection handle="1" to="O20" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O23">\r
+      <attribute name="obj_pos">\r
+        <point val="-9.68056,51.1"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-18.6378,50.25;-8.83056,70.45"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="-9.68056,51.1"/>\r
+        <point val="-9.68056,67.814"/>\r
+        <point val="-17.7878,67.814"/>\r
+        <point val="-17.7878,69.6"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O17" connection="6"/>\r
+        <connection handle="1" to="O21" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O24">\r
+      <attribute name="obj_pos">\r
+        <point val="0.2,69"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="0.15,68.95;24.1265,76.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="0.2,69"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="23.8765"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="7.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cNaveEspia#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes">\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aPosicionEnemiga#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mModificarVelocidad#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#np#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cNavePropia#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mAvisando#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#boolean#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mGetPosicionEnemiga#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mReaccionar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#np#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cNavePropia#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDibujar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tObjetosVoladores#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDisparar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cArma#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dT#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tTiempo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#ov#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cObjetoVolador#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string>#nil#</string>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O25">\r
+      <attribute name="obj_pos">\r
+        <point val="29.8,69.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="29.75,69.35;53.7265,73.85"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="29.8,69.4"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="23.8765"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="4.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cNaveSuicida#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mReaccionar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#np#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cNavePropia#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDibujar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#string#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDisparar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cArma#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dT#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tTiempo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#ov#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cObjetoVolador#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string>#nil#</string>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O26">\r
+      <attribute name="obj_pos">\r
+        <point val="-9.68056,51.1"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-10.5306,50.25;42.5882,70.25"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="-9.68056,51.1"/>\r
+        <point val="-9.68056,67.714"/>\r
+        <point val="41.7382,67.714"/>\r
+        <point val="41.7382,69.4"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O17" connection="6"/>\r
+        <connection handle="1" to="O25" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O27">\r
+      <attribute name="obj_pos">\r
+        <point val="-9.68056,51.1"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-10.5306,50.25;12.9882,69.85"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="-9.68056,51.1"/>\r
+        <point val="-9.68056,67.764"/>\r
+        <point val="12.1382,67.764"/>\r
+        <point val="12.1382,69"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O17" connection="6"/>\r
+        <connection handle="1" to="O24" connection="1"/>\r
+      </connections>\r
+    </object>\r
+  </layer>\r
+</diagram>\r
diff --git a/doc/uml/jerarquia.png b/doc/uml/jerarquia.png
new file mode 100644 (file)
index 0000000..c4cb55a
Binary files /dev/null and b/doc/uml/jerarquia.png differ
diff --git a/doc/uml/secuencia_actualizar.dia b/doc/uml/secuencia_actualizar.dia
new file mode 100644 (file)
index 0000000..3201b1f
--- /dev/null
@@ -0,0 +1,860 @@
+<?xml version="1.0"?>\r
+<diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">\r
+  <diagramdata>\r
+    <attribute name="background">\r
+      <color val="#ffffff"/>\r
+    </attribute>\r
+    <attribute name="paper">\r
+      <composite type="paper">\r
+        <attribute name="name">\r
+          <string>#A4#</string>\r
+        </attribute>\r
+        <attribute name="tmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="bmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="lmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="rmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="is_portrait">\r
+          <boolean val="true"/>\r
+        </attribute>\r
+        <attribute name="scaling">\r
+          <real val="1"/>\r
+        </attribute>\r
+        <attribute name="fitto">\r
+          <boolean val="false"/>\r
+        </attribute>\r
+      </composite>\r
+    </attribute>\r
+  </diagramdata>\r
+  <layer name="Background" visible="true">\r
+    <object type="UML - Class" version="0" id="O0">\r
+      <attribute name="obj_pos">\r
+        <point val="4,8"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="3.95,7.95;13.1219,9.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="4,8"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="9.0719"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="1.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#oEspacio: cEspacio#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations"/>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O1">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,24.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="8.53595,24.4;8.53595,41"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,24.4"/>\r
+        <point val="8.53595,41"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="2.6"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O2" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O2">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,9.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="8.53595,9.4;8.53595,25"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,9.4"/>\r
+        <point val="8.53595,25"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="1"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O0" connection="6"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O3">\r
+      <attribute name="obj_pos">\r
+        <point val="16,8"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="15.95,7.95;23.2736,9.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="16,8"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="7.2236"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="1.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#oObjetos: TList#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations"/>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O4">\r
+      <attribute name="obj_pos">\r
+        <point val="19.6118,24.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="19.6118,24.4;19.6118,41"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="19.6118,24.4"/>\r
+        <point val="19.6118,41"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="2.6"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O5" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O5">\r
+      <attribute name="obj_pos">\r
+        <point val="19.6118,9.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="19.6118,9.4;19.6118,25"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="19.6118,9.4"/>\r
+        <point val="19.6118,25"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="1"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O3" connection="6"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O6">\r
+      <attribute name="obj_pos">\r
+        <point val="26,8"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="25.95,7.95;35.7279,9.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="26,8"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="9.6779"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="1.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#oOV: cObjetoVolador#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations"/>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O7">\r
+      <attribute name="obj_pos">\r
+        <point val="30.839,24.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="30.839,24.4;30.839,41"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="30.839,24.4"/>\r
+        <point val="30.839,41"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="2.6"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O8" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O8">\r
+      <attribute name="obj_pos">\r
+        <point val="30.839,9.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="30.839,9.4;30.839,25"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="30.839,9.4"/>\r
+        <point val="30.839,25"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="1"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O6" connection="6"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Message" version="0" id="O9">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,13.2"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.68595,11.4272;20.4618,14.05"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,13.2"/>\r
+        <point val="19.6118,13.2"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <string>#oOV := pedirObjeto#</string>\r
+      </attribute>\r
+      <attribute name="text_pos">\r
+        <point val="11.9252,12.9172"/>\r
+      </attribute>\r
+      <attribute name="type">\r
+        <int val="0"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O2" connection="1"/>\r
+        <connection handle="1" to="O5" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Message" version="0" id="O10">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,34.44"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.68595,32.6697;31.689,35.29"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,34.44"/>\r
+        <point val="30.839,34.44"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <string>#mover#</string>\r
+      </attribute>\r
+      <attribute name="text_pos">\r
+        <point val="9.90183,34.1597"/>\r
+      </attribute>\r
+      <attribute name="type">\r
+        <int val="0"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O1" connection="3"/>\r
+        <connection handle="1" to="O7" connection="3"/>\r
+      </connections>\r
+    </object>\r
+    <object type="Standard - Text" version="0" id="O11">\r
+      <attribute name="obj_pos">\r
+        <point val="12.1252,10.4672"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="8.2074,9.90659;16.043,11.4066"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <composite type="text">\r
+          <attribute name="string">\r
+            <string>#*[Para cada objeto\r
+en oObjetos]#</string>\r
+          </attribute>\r
+          <attribute name="font">\r
+            <font name="Courier"/>\r
+          </attribute>\r
+          <attribute name="height">\r
+            <real val="0.75"/>\r
+          </attribute>\r
+          <attribute name="pos">\r
+            <point val="12.1252,10.4672"/>\r
+          </attribute>\r
+          <attribute name="color">\r
+            <color val="#000000"/>\r
+          </attribute>\r
+          <attribute name="alignment">\r
+            <enum val="1"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+    </object>\r
+    <object type="Standard - PolyLine" version="0" id="O12">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,10.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="5.96248,10.35;8.58595,10.467"/>\r
+      </attribute>\r
+      <attribute name="poly_points">\r
+        <point val="8.53595,10.4"/>\r
+        <point val="6.01248,10.417"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O2" connection="0"/>\r
+      </connections>\r
+    </object>\r
+    <object type="Standard - PolyLine" version="0" id="O13">\r
+      <attribute name="obj_pos">\r
+        <point val="6.01248,10.467"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="5.96248,10.417;6.06248,35.8679"/>\r
+      </attribute>\r
+      <attribute name="poly_points">\r
+        <point val="6.01248,10.467"/>\r
+        <point val="6.01248,35.8179"/>\r
+      </attribute>\r
+    </object>\r
+    <object type="Standard - PolyLine" version="0" id="O14">\r
+      <attribute name="obj_pos">\r
+        <point val="6.01248,35.8179"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="5.96248,35.76;8.56914,35.8679"/>\r
+      </attribute>\r
+      <attribute name="poly_points">\r
+        <point val="6.01248,35.8179"/>\r
+        <point val="8.51914,35.81"/>\r
+      </attribute>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O15">\r
+      <attribute name="obj_pos">\r
+        <point val="39,8"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="38.95,7.95;42.9709,9.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="39,8"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="3.9209"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="1.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#: cNave#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations"/>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O16">\r
+      <attribute name="obj_pos">\r
+        <point val="40.9605,24.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="40.9605,24.4;40.9605,41"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="40.9605,24.4"/>\r
+        <point val="40.9605,41"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="2.6"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O17" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O17">\r
+      <attribute name="obj_pos">\r
+        <point val="40.9605,9.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="40.9605,9.4;40.9605,25"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="40.9605,9.4"/>\r
+        <point val="40.9605,25"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="1"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O15" connection="6"/>\r
+      </connections>\r
+    </object>\r
+    <group>\r
+      <object type="Standard - PolyLine" version="0" id="O18">\r
+        <attribute name="obj_pos">\r
+          <point val="16.9325,38.3271"/>\r
+        </attribute>\r
+        <attribute name="obj_bb">\r
+          <rectangle val="7.73248,37.4271;17.7825,39.1771"/>\r
+        </attribute>\r
+        <attribute name="poly_points">\r
+          <point val="16.9325,38.3271"/>\r
+          <point val="8.58248,38.2771"/>\r
+        </attribute>\r
+        <attribute name="end_arrow">\r
+          <enum val="3"/>\r
+        </attribute>\r
+        <attribute name="end_arrow_length">\r
+          <real val="0.8"/>\r
+        </attribute>\r
+        <attribute name="end_arrow_width">\r
+          <real val="0.5"/>\r
+        </attribute>\r
+      </object>\r
+      <object type="Standard - Text" version="0" id="O19">\r
+        <attribute name="obj_pos">\r
+          <point val="12.1825,36.6271"/>\r
+        </attribute>\r
+        <attribute name="obj_bb">\r
+          <rectangle val="8.2647,36.0665;16.1003,36.8165"/>\r
+        </attribute>\r
+        <attribute name="text">\r
+          <composite type="text">\r
+            <attribute name="string">\r
+              <string>#detectarColisiones#</string>\r
+            </attribute>\r
+            <attribute name="font">\r
+              <font name="Courier"/>\r
+            </attribute>\r
+            <attribute name="height">\r
+              <real val="0.75"/>\r
+            </attribute>\r
+            <attribute name="pos">\r
+              <point val="12.1825,36.6271"/>\r
+            </attribute>\r
+            <attribute name="color">\r
+              <color val="#000000"/>\r
+            </attribute>\r
+            <attribute name="alignment">\r
+              <enum val="1"/>\r
+            </attribute>\r
+          </composite>\r
+        </attribute>\r
+      </object>\r
+      <object type="Standard - PolyLine" version="0" id="O20">\r
+        <attribute name="obj_pos">\r
+          <point val="17.0125,36.9685"/>\r
+        </attribute>\r
+        <attribute name="obj_bb">\r
+          <rectangle val="8.48595,36.87;17.0625,37.0185"/>\r
+        </attribute>\r
+        <attribute name="poly_points">\r
+          <point val="17.0125,36.9685"/>\r
+          <point val="8.53595,36.92"/>\r
+        </attribute>\r
+      </object>\r
+      <object type="Standard - PolyLine" version="0" id="O21">\r
+        <attribute name="obj_pos">\r
+          <point val="17.0325,36.9771"/>\r
+        </attribute>\r
+        <attribute name="obj_bb">\r
+          <rectangle val="16.9825,36.9271;17.0825,38.3771"/>\r
+        </attribute>\r
+        <attribute name="poly_points">\r
+          <point val="17.0325,36.9771"/>\r
+          <point val="17.0325,38.3271"/>\r
+        </attribute>\r
+      </object>\r
+    </group>\r
+    <object type="Standard - Text" version="0" id="O22">\r
+      <attribute name="obj_pos">\r
+        <point val="13.7002,15.7294"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.8735,15.1688;19.5269,15.9188"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <composite type="text">\r
+          <attribute name="string">\r
+            <string>#actualizarObjVolador( oOV )#</string>\r
+          </attribute>\r
+          <attribute name="font">\r
+            <font name="Courier"/>\r
+          </attribute>\r
+          <attribute name="height">\r
+            <real val="0.75"/>\r
+          </attribute>\r
+          <attribute name="pos">\r
+            <point val="13.7002,15.7294"/>\r
+          </attribute>\r
+          <attribute name="color">\r
+            <color val="#000000"/>\r
+          </attribute>\r
+          <attribute name="alignment">\r
+            <enum val="1"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+    </object>\r
+    <object type="Standard - PolyLine" version="0" id="O23">\r
+      <attribute name="obj_pos">\r
+        <point val="18.6218,16.0355"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="8.48595,15.95;18.6718,16.0855"/>\r
+      </attribute>\r
+      <attribute name="poly_points">\r
+        <point val="18.6218,16.0355"/>\r
+        <point val="8.53595,16"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="1" to="O2" connection="2"/>\r
+      </connections>\r
+    </object>\r
+    <object type="Standard - PolyLine" version="0" id="O24">\r
+      <attribute name="obj_pos">\r
+        <point val="18.6502,16.0794"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="18.6002,16.0294;18.7218,18.8855"/>\r
+      </attribute>\r
+      <attribute name="poly_points">\r
+        <point val="18.6502,16.0794"/>\r
+        <point val="18.6718,18.8355"/>\r
+      </attribute>\r
+    </object>\r
+    <object type="Standard - PolyLine" version="0" id="O25">\r
+      <attribute name="obj_pos">\r
+        <point val="18.5718,18.8355"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.68595,17.95;19.4218,19.6855"/>\r
+      </attribute>\r
+      <attribute name="poly_points">\r
+        <point val="18.5718,18.8355"/>\r
+        <point val="8.53595,18.8"/>\r
+      </attribute>\r
+      <attribute name="end_arrow">\r
+        <enum val="3"/>\r
+      </attribute>\r
+      <attribute name="end_arrow_length">\r
+        <real val="0.8"/>\r
+      </attribute>\r
+      <attribute name="end_arrow_width">\r
+        <real val="0.5"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="1" to="O2" connection="3"/>\r
+      </connections>\r
+    </object>\r
+    <object type="Standard - Text" version="0" id="O26">\r
+      <attribute name="obj_pos">\r
+        <point val="11.4718,21.7855"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="8.40237,21.2249;14.5412,21.9749"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <composite type="text">\r
+          <attribute name="string">\r
+            <string>#[oOV es cNave]#</string>\r
+          </attribute>\r
+          <attribute name="font">\r
+            <font name="Courier"/>\r
+          </attribute>\r
+          <attribute name="height">\r
+            <real val="0.75"/>\r
+          </attribute>\r
+          <attribute name="pos">\r
+            <point val="11.4718,21.7855"/>\r
+          </attribute>\r
+          <attribute name="color">\r
+            <color val="#000000"/>\r
+          </attribute>\r
+          <attribute name="alignment">\r
+            <enum val="1"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+    </object>\r
+    <object type="UML - Message" version="0" id="O27">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,24.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.68595,22.6955;41.8105,25.25"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,24.4"/>\r
+        <point val="40.9605,24.4"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <string>#oArma := mDisparar#</string>\r
+      </attribute>\r
+      <attribute name="text_pos">\r
+        <point val="11.9718,24.1855"/>\r
+      </attribute>\r
+      <attribute name="type">\r
+        <int val="0"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O2" connection="5"/>\r
+        <connection handle="1" to="O17" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="Standard - Text" version="0" id="O28">\r
+      <attribute name="obj_pos">\r
+        <point val="11.9596,27.1911"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="8.25387,26.6305;15.6653,27.3805"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <composite type="text">\r
+          <attribute name="string">\r
+            <string>#[oArma no es nil]#</string>\r
+          </attribute>\r
+          <attribute name="font">\r
+            <font name="Courier"/>\r
+          </attribute>\r
+          <attribute name="height">\r
+            <real val="0.75"/>\r
+          </attribute>\r
+          <attribute name="pos">\r
+            <point val="11.9596,27.1911"/>\r
+          </attribute>\r
+          <attribute name="color">\r
+            <color val="#000000"/>\r
+          </attribute>\r
+          <attribute name="alignment">\r
+            <enum val="1"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+    </object>\r
+    <object type="UML - Message" version="0" id="O29">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,29.48"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.68595,27.7255;20.4618,30.33"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,29.48"/>\r
+        <point val="19.6118,29.48"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <string>#Agregar( oArma )#</string>\r
+      </attribute>\r
+      <attribute name="text_pos">\r
+        <point val="11.5718,29.2155"/>\r
+      </attribute>\r
+      <attribute name="type">\r
+        <int val="0"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O1" connection="1"/>\r
+        <connection handle="1" to="O4" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="Standard - PolyLine" version="0" id="O30">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,21.6"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.07177,21.55;8.58595,21.6855"/>\r
+      </attribute>\r
+      <attribute name="poly_points">\r
+        <point val="8.53595,21.6"/>\r
+        <point val="7.12177,21.6355"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O2" connection="4"/>\r
+      </connections>\r
+    </object>\r
+    <object type="Standard - PolyLine" version="0" id="O31">\r
+      <attribute name="obj_pos">\r
+        <point val="7.12177,21.6355"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.07177,21.5855;7.17177,32.0355"/>\r
+      </attribute>\r
+      <attribute name="poly_points">\r
+        <point val="7.12177,21.6355"/>\r
+        <point val="7.12177,31.9855"/>\r
+      </attribute>\r
+    </object>\r
+    <object type="Standard - PolyLine" version="0" id="O32">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,31.96"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.09177,31.91;8.58595,32.016"/>\r
+      </attribute>\r
+      <attribute name="poly_points">\r
+        <point val="8.53595,31.96"/>\r
+        <point val="7.14177,31.966"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O1" connection="2"/>\r
+      </connections>\r
+    </object>\r
+  </layer>\r
+</diagram>\r
diff --git a/doc/uml/secuencia_actualizar.png b/doc/uml/secuencia_actualizar.png
new file mode 100644 (file)
index 0000000..e394e69
Binary files /dev/null and b/doc/uml/secuencia_actualizar.png differ
diff --git a/doc/uml/secuencia_colisiones.dia b/doc/uml/secuencia_colisiones.dia
new file mode 100644 (file)
index 0000000..fe28a6e
--- /dev/null
@@ -0,0 +1,1413 @@
+<?xml version="1.0"?>\r
+<diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">\r
+  <diagramdata>\r
+    <attribute name="background">\r
+      <color val="#ffffff"/>\r
+    </attribute>\r
+    <attribute name="paper">\r
+      <composite type="paper">\r
+        <attribute name="name">\r
+          <string>#A4#</string>\r
+        </attribute>\r
+        <attribute name="tmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="bmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="lmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="rmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="is_portrait">\r
+          <boolean val="true"/>\r
+        </attribute>\r
+        <attribute name="scaling">\r
+          <real val="1"/>\r
+        </attribute>\r
+        <attribute name="fitto">\r
+          <boolean val="false"/>\r
+        </attribute>\r
+      </composite>\r
+    </attribute>\r
+  </diagramdata>\r
+  <layer name="Background" visible="true">\r
+    <object type="UML - Class" version="0" id="O0">\r
+      <attribute name="obj_pos">\r
+        <point val="4,8"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="3.95,7.95;13.1219,9.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="4,8"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="9.0719"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="1.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#oEspacio: cEspacio#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations"/>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O1">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,24.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="8.53595,24.4;8.53595,41"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,24.4"/>\r
+        <point val="8.53595,41"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="2.6"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O3" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O2">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,39.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="8.53595,39.4;8.53595,56"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,39.4"/>\r
+        <point val="8.53595,56"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="2.6"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O1" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O3">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,9.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="8.53595,9.4;8.53595,25"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,9.4"/>\r
+        <point val="8.53595,25"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="1"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O0" connection="6"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O4">\r
+      <attribute name="obj_pos">\r
+        <point val="25,8"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="24.95,7.95;32.2736,9.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="25,8"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="7.2236"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="1.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#oObjetos: TList#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations"/>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O5">\r
+      <attribute name="obj_pos">\r
+        <point val="28.6118,24.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="28.6118,24.4;28.6118,41"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="28.6118,24.4"/>\r
+        <point val="28.6118,41"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="2.6"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O7" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O6">\r
+      <attribute name="obj_pos">\r
+        <point val="28.6118,39.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="28.6118,39.4;28.6118,56"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="28.6118,39.4"/>\r
+        <point val="28.6118,56"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="2.6"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O5" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O7">\r
+      <attribute name="obj_pos">\r
+        <point val="28.6118,9.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="28.6118,9.4;28.6118,25"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="28.6118,9.4"/>\r
+        <point val="28.6118,25"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="1"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O4" connection="6"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O8">\r
+      <attribute name="obj_pos">\r
+        <point val="35,8"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="34.95,7.95;45.2127,9.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="35,8"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="10.1627"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="1.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#oOV1: cObjetoVolador#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations"/>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O9">\r
+      <attribute name="obj_pos">\r
+        <point val="40.0814,24.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="40.0814,24.4;40.0814,41"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="40.0814,24.4"/>\r
+        <point val="40.0814,41"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="2.6"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O11" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O10">\r
+      <attribute name="obj_pos">\r
+        <point val="40.0814,39.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="40.0814,39.4;40.0814,56"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="40.0814,39.4"/>\r
+        <point val="40.0814,56"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="2.6"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O9" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O11">\r
+      <attribute name="obj_pos">\r
+        <point val="40.0814,9.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="40.0814,9.4;40.0814,25"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="40.0814,9.4"/>\r
+        <point val="40.0814,25"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="1"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O8" connection="6"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O12">\r
+      <attribute name="obj_pos">\r
+        <point val="48,8"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="47.95,7.95;58.2127,9.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="48,8"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="10.1627"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="1.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#oOV2: cObjetoVolador#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations"/>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O13">\r
+      <attribute name="obj_pos">\r
+        <point val="53.0814,24.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="53.0814,24.4;53.0814,41"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="53.0814,24.4"/>\r
+        <point val="53.0814,41"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="2.6"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O15" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O14">\r
+      <attribute name="obj_pos">\r
+        <point val="53.0814,39.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="53.0814,39.4;53.0814,56"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="53.0814,39.4"/>\r
+        <point val="53.0814,56"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="2.6"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O13" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O15">\r
+      <attribute name="obj_pos">\r
+        <point val="53.0814,9.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="53.0814,9.4;53.0814,25"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="53.0814,9.4"/>\r
+        <point val="53.0814,25"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="1"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O12" connection="6"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O16">\r
+      <attribute name="obj_pos">\r
+        <point val="16,9.7"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="15.95,9.65;22.4959,11.15"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="16,9.7"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="6.4459"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="1.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#oRotos: TList#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations"/>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O17">\r
+      <attribute name="obj_pos">\r
+        <point val="19.223,26.1"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="19.223,26.1;19.223,42.7"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="19.223,26.1"/>\r
+        <point val="19.223,42.7"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="2.6"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O19" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O18">\r
+      <attribute name="obj_pos">\r
+        <point val="19.2255,41.7834"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="18.4255,41.7834;20.0255,55.1834"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="19.2255,41.7834"/>\r
+        <point val="19.2255,54.3834"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="2"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="12.6"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="1" to="O18" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O19">\r
+      <attribute name="obj_pos">\r
+        <point val="19.223,11.1"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="19.223,11.1;19.223,26.7"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="19.223,11.1"/>\r
+        <point val="19.223,26.7"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="2.09697"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O16" connection="6"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O20">\r
+      <attribute name="obj_pos">\r
+        <point val="61,8"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="60.95,7.95;72.7277,9.45"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="61,8"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="11.6777"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="1.4"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#oOVRoto: cObjetoVolador#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations"/>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O21">\r
+      <attribute name="obj_pos">\r
+        <point val="66.8388,24.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="66.8388,24.4;66.8388,41"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="66.8388,24.4"/>\r
+        <point val="66.8388,41"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="2.6"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O23" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O22">\r
+      <attribute name="obj_pos">\r
+        <point val="66.8388,39.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="66.0388,39.4;67.6388,52.7834"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="66.8388,39.4"/>\r
+        <point val="66.8388,51.9834"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="2.6"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="12.5834"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O21" connection="5"/>\r
+        <connection handle="1" to="O22" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Lifeline" version="0" id="O23">\r
+      <attribute name="obj_pos">\r
+        <point val="66.8388,9.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="66.8388,9.4;66.8388,25"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="66.8388,9.4"/>\r
+        <point val="66.8388,25"/>\r
+      </attribute>\r
+      <attribute name="rtop">\r
+        <real val="1"/>\r
+      </attribute>\r
+      <attribute name="rbot">\r
+        <real val="15"/>\r
+      </attribute>\r
+      <attribute name="draw_focus">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="draw_cross">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O20" connection="6"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Message" version="0" id="O24">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,10.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.68595,8.70697;16.85,11.25"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,10.4"/>\r
+        <point val="16,10.4"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <string>#crear#</string>\r
+      </attribute>\r
+      <attribute name="text_pos">\r
+        <point val="9.46475,10.197"/>\r
+      </attribute>\r
+      <attribute name="type">\r
+        <int val="0"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O3" connection="0"/>\r
+        <connection handle="1" to="O16" connection="3"/>\r
+      </connections>\r
+    </object>\r
+    <object type="Standard - Text" version="0" id="O25">\r
+      <attribute name="obj_pos">\r
+        <point val="10.6507,12.4404"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="8.21758,11.8798;13.0838,14.1298"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <composite type="text">\r
+          <attribute name="string">\r
+            <string>#*[Para cada\r
+objeto de\r
+oObjetos]#</string>\r
+          </attribute>\r
+          <attribute name="font">\r
+            <font name="Courier"/>\r
+          </attribute>\r
+          <attribute name="height">\r
+            <real val="0.75"/>\r
+          </attribute>\r
+          <attribute name="pos">\r
+            <point val="10.6507,12.4404"/>\r
+          </attribute>\r
+          <attribute name="color">\r
+            <color val="#000000"/>\r
+          </attribute>\r
+          <attribute name="alignment">\r
+            <enum val="1"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+    </object>\r
+    <object type="UML - Message" version="0" id="O26">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,16"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.68595,14.2585;29.4618,16.85"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,16"/>\r
+        <point val="28.6118,16"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <string>#oOV1 := pedirObjeto#</string>\r
+      </attribute>\r
+      <attribute name="text_pos">\r
+        <point val="11.6133,15.7485"/>\r
+      </attribute>\r
+      <attribute name="type">\r
+        <int val="0"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O3" connection="2"/>\r
+        <connection handle="1" to="O7" connection="2"/>\r
+      </connections>\r
+    </object>\r
+    <object type="Standard - Text" version="0" id="O27">\r
+      <attribute name="obj_pos">\r
+        <point val="12.2647,18.747"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.92275,18.1864;16.6067,19.6864"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <composite type="text">\r
+          <attribute name="string">\r
+            <string>#*[Para cada objeto a\r
+partir del anterior]#</string>\r
+          </attribute>\r
+          <attribute name="font">\r
+            <font name="Courier"/>\r
+          </attribute>\r
+          <attribute name="height">\r
+            <real val="0.75"/>\r
+          </attribute>\r
+          <attribute name="pos">\r
+            <point val="12.2647,18.747"/>\r
+          </attribute>\r
+          <attribute name="color">\r
+            <color val="#000000"/>\r
+          </attribute>\r
+          <attribute name="alignment">\r
+            <enum val="1"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+    </object>\r
+    <object type="UML - Message" version="0" id="O28">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,21.6"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.68595,19.8585;29.4618,22.45"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,21.6"/>\r
+        <point val="28.6118,21.6"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <string>#oOV2 := pedirObjeto#</string>\r
+      </attribute>\r
+      <attribute name="text_pos">\r
+        <point val="11.6133,21.3485"/>\r
+      </attribute>\r
+      <attribute name="type">\r
+        <int val="0"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O3" connection="4"/>\r
+        <connection handle="1" to="O7" connection="4"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Message" version="0" id="O29">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,24.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.68595,22.6767;40.9314,25.25"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,24.4"/>\r
+        <point val="40.0814,24.4"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <string>#choco := ColisionoCon( oOV2 )#</string>\r
+      </attribute>\r
+      <attribute name="text_pos">\r
+        <point val="13.2647,24.1667"/>\r
+      </attribute>\r
+      <attribute name="type">\r
+        <int val="0"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O3" connection="5"/>\r
+        <connection handle="1" to="O11" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="Standard - Text" version="0" id="O30">\r
+      <attribute name="obj_pos">\r
+        <point val="9.89648,25.4397"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="8.31178,24.8791;11.4812,25.6291"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <composite type="text">\r
+          <attribute name="string">\r
+            <string>#[choco]#</string>\r
+          </attribute>\r
+          <attribute name="font">\r
+            <font name="Courier"/>\r
+          </attribute>\r
+          <attribute name="height">\r
+            <real val="0.75"/>\r
+          </attribute>\r
+          <attribute name="pos">\r
+            <point val="9.89648,25.4397"/>\r
+          </attribute>\r
+          <attribute name="color">\r
+            <color val="#000000"/>\r
+          </attribute>\r
+          <attribute name="alignment">\r
+            <enum val="1"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+    </object>\r
+    <object type="UML - Message" version="0" id="O31">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,27"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.68595,25.2767;40.9314,27.85"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,27"/>\r
+        <point val="40.0814,27"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <string>#restarEnergia#</string>\r
+      </attribute>\r
+      <attribute name="text_pos">\r
+        <point val="10.6965,26.7667"/>\r
+      </attribute>\r
+      <attribute name="type">\r
+        <int val="0"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O1" connection="0"/>\r
+        <connection handle="1" to="O9" connection="0"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Message" version="0" id="O32">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,29.48"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.68595,27.7523;53.9314,30.33"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,29.48"/>\r
+        <point val="53.0814,29.48"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <string>#restarEnergia#</string>\r
+      </attribute>\r
+      <attribute name="text_pos">\r
+        <point val="10.6981,29.2423"/>\r
+      </attribute>\r
+      <attribute name="type">\r
+        <int val="0"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O1" connection="1"/>\r
+        <connection handle="1" to="O13" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="Standard - Text" version="0" id="O33">\r
+      <attribute name="obj_pos">\r
+        <point val="11.8965,30.9897"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.97868,30.4291;15.8143,33.4291"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <composite type="text">\r
+          <attribute name="string">\r
+            <string>#[oOV1 no tiene mas\r
+energia AND oOV1\r
+no esta en oRotos]\r
+#</string>\r
+          </attribute>\r
+          <attribute name="font">\r
+            <font name="Courier"/>\r
+          </attribute>\r
+          <attribute name="height">\r
+            <real val="0.75"/>\r
+          </attribute>\r
+          <attribute name="pos">\r
+            <point val="11.8965,30.9897"/>\r
+          </attribute>\r
+          <attribute name="color">\r
+            <color val="#000000"/>\r
+          </attribute>\r
+          <attribute name="alignment">\r
+            <enum val="1"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+    </object>\r
+    <object type="UML - Message" version="0" id="O34">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,34.44"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.68595,32.6685;20.0449,35.29"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,34.44"/>\r
+        <point val="19.1949,34.4272"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <string>#agregar( oOV1 )#</string>\r
+      </attribute>\r
+      <attribute name="text_pos">\r
+        <point val="10.9707,34.1585"/>\r
+      </attribute>\r
+      <attribute name="type">\r
+        <int val="0"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O1" connection="3"/>\r
+      </connections>\r
+    </object>\r
+    <object type="Standard - Text" version="0" id="O35">\r
+      <attribute name="obj_pos">\r
+        <point val="11.8965,35.9897"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.97868,35.4291;15.8143,38.4291"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <composite type="text">\r
+          <attribute name="string">\r
+            <string>#[oOV2 no tiene mas\r
+energia AND oOV2\r
+no esta en oRotos]\r
+#</string>\r
+          </attribute>\r
+          <attribute name="font">\r
+            <font name="Courier"/>\r
+          </attribute>\r
+          <attribute name="height">\r
+            <real val="0.75"/>\r
+          </attribute>\r
+          <attribute name="pos">\r
+            <point val="11.8965,35.9897"/>\r
+          </attribute>\r
+          <attribute name="color">\r
+            <color val="#000000"/>\r
+          </attribute>\r
+          <attribute name="alignment">\r
+            <enum val="1"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+    </object>\r
+    <object type="UML - Message" version="0" id="O36">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,39.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.68595,37.6529;20.0507,40.2861"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,39.4"/>\r
+        <point val="19.2007,39.4361"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <string>#agregar( oOV2 )#</string>\r
+      </attribute>\r
+      <attribute name="text_pos">\r
+        <point val="10.9736,39.1429"/>\r
+      </attribute>\r
+      <attribute name="type">\r
+        <int val="0"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O1" connection="5"/>\r
+      </connections>\r
+    </object>\r
+    <object type="Standard - PolyLine" version="0" id="O37">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,12.25"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="6.06343,12.2;8.58595,12.314"/>\r
+      </attribute>\r
+      <attribute name="poly_points">\r
+        <point val="8.53595,12.25"/>\r
+        <point val="6.11343,12.264"/>\r
+      </attribute>\r
+    </object>\r
+    <object type="Standard - PolyLine" version="0" id="O38">\r
+      <attribute name="obj_pos">\r
+        <point val="6.11343,12.3347"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="6.06343,12.2847;6.16343,41.0225"/>\r
+      </attribute>\r
+      <attribute name="poly_points">\r
+        <point val="6.11343,12.3347"/>\r
+        <point val="6.11343,40.9725"/>\r
+      </attribute>\r
+    </object>\r
+    <object type="Standard - PolyLine" version="0" id="O39">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,41.05"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="6.06343,40.9933;8.58595,41.1"/>\r
+      </attribute>\r
+      <attribute name="poly_points">\r
+        <point val="8.53595,41.05"/>\r
+        <point val="6.11343,41.0433"/>\r
+      </attribute>\r
+    </object>\r
+    <object type="Standard - PolyLine" version="0" id="O40">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,18.8"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.20068,18.75;8.58595,18.9058"/>\r
+      </attribute>\r
+      <attribute name="poly_points">\r
+        <point val="8.53595,18.8"/>\r
+        <point val="7.25068,18.8558"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O3" connection="3"/>\r
+      </connections>\r
+    </object>\r
+    <object type="Standard - PolyLine" version="0" id="O41">\r
+      <attribute name="obj_pos">\r
+        <point val="7.15068,18.8558"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.10068,18.8058;7.20068,40.3373"/>\r
+      </attribute>\r
+      <attribute name="poly_points">\r
+        <point val="7.15068,18.8558"/>\r
+        <point val="7.15068,40.2873"/>\r
+      </attribute>\r
+    </object>\r
+    <object type="Standard - PolyLine" version="0" id="O42">\r
+      <attribute name="obj_pos">\r
+        <point val="8.55068,40.3121"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.10068,40.2121;8.60068,40.3621"/>\r
+      </attribute>\r
+      <attribute name="poly_points">\r
+        <point val="8.55068,40.3121"/>\r
+        <point val="7.15068,40.2621"/>\r
+      </attribute>\r
+    </object>\r
+    <object type="Standard - Text" version="0" id="O43">\r
+      <attribute name="obj_pos">\r
+        <point val="11.8507,41.9125"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.93288,41.3519;15.7685,42.8519"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <composite type="text">\r
+          <attribute name="string">\r
+            <string>#*[Para cada objeto\r
+de oRotos]#</string>\r
+          </attribute>\r
+          <attribute name="font">\r
+            <font name="Courier"/>\r
+          </attribute>\r
+          <attribute name="height">\r
+            <real val="0.75"/>\r
+          </attribute>\r
+          <attribute name="pos">\r
+            <point val="11.8507,41.9125"/>\r
+          </attribute>\r
+          <attribute name="color">\r
+            <color val="#000000"/>\r
+          </attribute>\r
+          <attribute name="alignment">\r
+            <enum val="1"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+    </object>\r
+    <object type="UML - Message" version="0" id="O44">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,44.48"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.68595,42.7461;20.0507,45.33"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,44.48"/>\r
+        <point val="19.2007,44.4625"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <string>#oOVRoto := obtener#</string>\r
+      </attribute>\r
+      <attribute name="text_pos">\r
+        <point val="11.5507,44.2361"/>\r
+      </attribute>\r
+      <attribute name="type">\r
+        <int val="0"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O2" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Message" version="0" id="O45">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,46.96"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.68595,45.1461;20.0007,47.81"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,46.96"/>\r
+        <point val="19.1507,46.9361"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <string>#borrar( oOVRoto )#</string>\r
+      </attribute>\r
+      <attribute name="text_pos">\r
+        <point val="11.2007,46.6361"/>\r
+      </attribute>\r
+      <attribute name="type">\r
+        <int val="0"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O2" connection="2"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Message" version="0" id="O46">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,49.44"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.68595,47.6211;29.4618,50.29"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,49.44"/>\r
+        <point val="28.6118,49.44"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <string>#borrar( oOVRoto )#</string>\r
+      </attribute>\r
+      <attribute name="text_pos">\r
+        <point val="11.2007,49.1111"/>\r
+      </attribute>\r
+      <attribute name="type">\r
+        <int val="0"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O2" connection="3"/>\r
+        <connection handle="1" to="O6" connection="3"/>\r
+      </connections>\r
+    </object>\r
+    <object type="Standard - PolyLine" version="0" id="O47">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,42"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.25068,41.95;8.58595,42.0591"/>\r
+      </attribute>\r
+      <attribute name="poly_points">\r
+        <point val="8.53595,42"/>\r
+        <point val="7.30068,42.0091"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O2" connection="0"/>\r
+      </connections>\r
+    </object>\r
+    <object type="Standard - PolyLine" version="0" id="O48">\r
+      <attribute name="obj_pos">\r
+        <point val="7.30068,42.0591"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.25068,42.0091;7.35068,52.9091"/>\r
+      </attribute>\r
+      <attribute name="poly_points">\r
+        <point val="7.30068,42.0591"/>\r
+        <point val="7.30068,52.8591"/>\r
+      </attribute>\r
+    </object>\r
+    <object type="Standard - PolyLine" version="0" id="O49">\r
+      <attribute name="obj_pos">\r
+        <point val="7.35068,52.8591"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.30068,52.8091;8.56914,52.91"/>\r
+      </attribute>\r
+      <attribute name="poly_points">\r
+        <point val="7.35068,52.8591"/>\r
+        <point val="8.51914,52.86"/>\r
+      </attribute>\r
+    </object>\r
+    <object type="UML - Message" version="0" id="O50">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,51.92"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.68595,50.2267;67.7126,52.7834"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,51.92"/>\r
+        <point val="66.8626,51.9334"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <string>#destruir#</string>\r
+      </attribute>\r
+      <attribute name="text_pos">\r
+        <point val="9.72453,51.7167"/>\r
+      </attribute>\r
+      <attribute name="type">\r
+        <int val="0"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O2" connection="4"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Message" version="0" id="O51">\r
+      <attribute name="obj_pos">\r
+        <point val="8.53595,54.4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="7.68595,52.6934;20.0755,55.25"/>\r
+      </attribute>\r
+      <attribute name="conn_endpoints">\r
+        <point val="8.53595,54.4"/>\r
+        <point val="19.2255,54.3834"/>\r
+      </attribute>\r
+      <attribute name="text">\r
+        <string>#destruir#</string>\r
+      </attribute>\r
+      <attribute name="text_pos">\r
+        <point val="9.67547,54.1834"/>\r
+      </attribute>\r
+      <attribute name="type">\r
+        <int val="0"/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O2" connection="5"/>\r
+        <connection handle="1" to="O18" connection="5"/>\r
+      </connections>\r
+    </object>\r
+  </layer>\r
+</diagram>\r
diff --git a/doc/uml/secuencia_colisiones.png b/doc/uml/secuencia_colisiones.png
new file mode 100644 (file)
index 0000000..7741512
Binary files /dev/null and b/doc/uml/secuencia_colisiones.png differ
diff --git a/doc/uml/vista.dia b/doc/uml/vista.dia
new file mode 100644 (file)
index 0000000..05c4c5c
--- /dev/null
@@ -0,0 +1,3435 @@
+<?xml version="1.0"?>\r
+<diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">\r
+  <diagramdata>\r
+    <attribute name="background">\r
+      <color val="#ffffff"/>\r
+    </attribute>\r
+    <attribute name="paper">\r
+      <composite type="paper">\r
+        <attribute name="name">\r
+          <string>#A4#</string>\r
+        </attribute>\r
+        <attribute name="tmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="bmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="lmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="rmargin">\r
+          <real val="2.82"/>\r
+        </attribute>\r
+        <attribute name="is_portrait">\r
+          <boolean val="true"/>\r
+        </attribute>\r
+        <attribute name="scaling">\r
+          <real val="1"/>\r
+        </attribute>\r
+        <attribute name="fitto">\r
+          <boolean val="false"/>\r
+        </attribute>\r
+      </composite>\r
+    </attribute>\r
+  </diagramdata>\r
+  <layer name="Background" visible="true">\r
+    <object type="UML - Class" version="0" id="O0">\r
+      <attribute name="obj_pos">\r
+        <point val="-1,32"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-1.05,31.95;28.9703,41.05"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="-1,32"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="29.9203"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="9"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cCamara#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes">\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aCameraman#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cObjetoVolador#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aRadioMaximo#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aRadioMinimo#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aRadioPantalla#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aDistPantalla#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aCosApertura#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tAngulo#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aFiltro#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cFiltro#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mProyectar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="true"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#ov#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cObjetoVolador#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#x#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#y#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#tam#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mProcesar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cLista#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#l#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#TList#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O1">\r
+      <attribute name="obj_pos">\r
+        <point val="-22,7"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-22.05,6.95;-0.7884,17.65"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="-22,7"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="21.1616"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="10.6"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cVista#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes">\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aFormulario#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#TCustomForm#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aRegion#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#HRgn#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aCamara#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cCamara#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aProy#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cLista#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mGetFormLado#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#integer#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mGetTam#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#integer#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#proy#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tPPoy#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mGetX#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#integer#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#proy#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tPProy#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mGetY#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#integer#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#proy#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tPProy#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDibujarOV#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#proy#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tPProy#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mDibujarVista#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#oEspacio#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cEspacio#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mGetDebugInfo#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#string#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#debugLevel#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tDebugInfo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O2">\r
+      <attribute name="obj_pos">\r
+        <point val="30,4"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="29.95,3.95;54.8314,21.05"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="30,4"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="24.7814"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="17"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cVector#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes">\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aX#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aY#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aZ#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mHacerVersor#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mSet#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#x#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#y#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#z#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>##</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>##</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mSet#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#v#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mAddX#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#x#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mAddY#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#y#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mAddZ#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#z#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mSetModulo#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#modulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mAddModulo#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#modulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mGetModulo#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters"/>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mSumar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#vec#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mRestar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#vec#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mMultiplicar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#vec#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mMultiplicar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#esc#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tLongitud#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mMultiplicarEsc#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#vec#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mGetDistancia#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#vec#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mModificarCon#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#vel#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dT#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tTiempo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O3">\r
+      <attribute name="obj_pos">\r
+        <point val="7,3"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="6.95,2.95;21.8769,12.05"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="7,3"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="14.8269"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="9"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cCoordenadas#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes">\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aI#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aJ#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aK#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cVector#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mRotarEnI#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dAngulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tAngulo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mRotatEnJ#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dAngulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tAngulo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mRotarEnK#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#dAngulo#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#tAngulo#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mSetI#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cCoordenadas#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#v#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mSetJ#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cCoordenadas#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#v#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mSetK#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cCoordenadas#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#v#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cVector#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O4">\r
+      <attribute name="obj_pos">\r
+        <point val="6,15"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="5.95,14.95;22.6949,21.65"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="6,15"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="16.6449"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="6.6"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cFiltro#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes">\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aObservador#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#cObjetoVolador#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aRadioMaximo#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aRadioMinimo#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tLongitud#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umlattribute">\r
+          <attribute name="name">\r
+            <string>#aCosApertura#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#tAngulo#</string>\r
+          </attribute>\r
+          <attribute name="value">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="1"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mVisible#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#boolean#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="2"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="true"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#ov#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#cObjetoVolador#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mFiltrar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#TLista#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="0"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#l#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#TList#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O5">\r
+      <attribute name="obj_pos">\r
+        <point val="-25.7,45.45"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-25.75,45.4;-15.8004,48.3"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="-25.7,45.45"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="9.8496"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="2.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cCamaraFrontal#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mProyectar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O6">\r
+      <attribute name="obj_pos">\r
+        <point val="-14.1469,45.2345"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-14.1969,45.1845;-4.24729,48.0845"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="-14.1469,45.2345"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="9.8496"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="2.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cCamaraTrasera#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mProyectar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O7">\r
+      <attribute name="obj_pos">\r
+        <point val="-2,45"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-2.05,44.95;7.8996,47.85"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="-2,45"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="9.8496"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="2.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cCamaraLatDer#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mProyectar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O8">\r
+      <attribute name="obj_pos">\r
+        <point val="10,45"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="9.95,44.95;19.8996,47.85"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="10,45"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="9.8496"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="2.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cCamaraLatIzq#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mProyectar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O9">\r
+      <attribute name="obj_pos">\r
+        <point val="22,45"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="21.95,44.95;31.8996,47.85"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="22,45"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="9.8496"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="2.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cCamaraArriba#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mProyectar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O10">\r
+      <attribute name="obj_pos">\r
+        <point val="34,45"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="33.95,44.95;43.8996,47.85"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="34,45"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="9.8496"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="2.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cCamaraAbajo#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mProyectar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O11">\r
+      <attribute name="obj_pos">\r
+        <point val="46,45"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="45.95,44.95;55.8996,47.85"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="46,45"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="9.8496"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="2.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cCamaraMapa#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mProyectar#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string/>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O12">\r
+      <attribute name="obj_pos">\r
+        <point val="-26,25"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-26.05,24.95;-16.1004,27.85"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="-26,25"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="9.8496"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="2.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cFiltroFrontal#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mVisible#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#...#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>##</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O13">\r
+      <attribute name="obj_pos">\r
+        <point val="34,25"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="33.95,24.95;43.8996,27.85"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="34,25"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="9.8496"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="2.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cFiltroAbajo#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mVisible#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#...#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>##</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O14">\r
+      <attribute name="obj_pos">\r
+        <point val="22,25"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="21.95,24.95;31.8996,27.85"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="22,25"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="9.8496"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="2.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cFiltroArriba#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mVisible#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#...#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>##</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O15">\r
+      <attribute name="obj_pos">\r
+        <point val="10,25"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="9.95,24.95;19.8996,27.85"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="10,25"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="9.8496"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="2.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cFiltroLatIzq#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mVisible#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#...#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>##</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O16">\r
+      <attribute name="obj_pos">\r
+        <point val="-2,25"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-2.05,24.95;7.8996,27.85"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="-2,25"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="9.8496"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="2.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cFiltroLatDer#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mVisible#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#...#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>##</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O17">\r
+      <attribute name="obj_pos">\r
+        <point val="-14,25"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-14.05,24.95;-4.1004,27.85"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="-14,25"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="9.8496"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="2.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cFiltroTrasero#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mVisible#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#...#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>##</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O18">\r
+      <attribute name="obj_pos">\r
+        <point val="46,25"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="45.95,24.95;55.8996,27.85"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="46,25"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="9.8496"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="2.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cFiltroMapa#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mVisible#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#...#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>##</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Class" version="0" id="O19">\r
+      <attribute name="obj_pos">\r
+        <point val="-26,31"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-26.05,30.95;-16.1004,33.85"/>\r
+      </attribute>\r
+      <attribute name="elem_corner">\r
+        <point val="-26,31"/>\r
+      </attribute>\r
+      <attribute name="elem_width">\r
+        <real val="9.8496"/>\r
+      </attribute>\r
+      <attribute name="elem_height">\r
+        <real val="2.8"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string>#cFiltroLock#</string>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="abstract">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_attributes">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="suppress_operations">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="visible_attributes">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="visible_operations">\r
+        <boolean val="true"/>\r
+      </attribute>\r
+      <attribute name="attributes"/>\r
+      <attribute name="operations">\r
+        <composite type="umloperation">\r
+          <attribute name="name">\r
+            <string>#mVisible#</string>\r
+          </attribute>\r
+          <attribute name="type">\r
+            <string>#...#</string>\r
+          </attribute>\r
+          <attribute name="visibility">\r
+            <enum val="3"/>\r
+          </attribute>\r
+          <attribute name="abstract">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="class_scope">\r
+            <boolean val="false"/>\r
+          </attribute>\r
+          <attribute name="parameters">\r
+            <composite type="umlparameter">\r
+              <attribute name="name">\r
+                <string>#...#</string>\r
+              </attribute>\r
+              <attribute name="type">\r
+                <string>##</string>\r
+              </attribute>\r
+              <attribute name="value">\r
+                <string/>\r
+              </attribute>\r
+              <attribute name="kind">\r
+                <enum val="0"/>\r
+              </attribute>\r
+            </composite>\r
+          </attribute>\r
+        </composite>\r
+      </attribute>\r
+      <attribute name="template">\r
+        <boolean val="false"/>\r
+      </attribute>\r
+      <attribute name="templates"/>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O20">\r
+      <attribute name="obj_pos">\r
+        <point val="14.3224,21.6"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-21.9252,20.75;15.1724,25.85"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="14.3224,21.6"/>\r
+        <point val="14.3224,23"/>\r
+        <point val="-21.0752,23"/>\r
+        <point val="-21.0752,25"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O4" connection="6"/>\r
+        <connection handle="1" to="O12" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O21">\r
+      <attribute name="obj_pos">\r
+        <point val="14.3224,21.6"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-9.9252,20.75;15.1724,25.85"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="14.3224,21.6"/>\r
+        <point val="14.3224,23"/>\r
+        <point val="-9.0752,23"/>\r
+        <point val="-9.0752,25"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O4" connection="6"/>\r
+        <connection handle="1" to="O17" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O22">\r
+      <attribute name="obj_pos">\r
+        <point val="14.3224,21.6"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="2.0748,20.75;15.1724,25.85"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="14.3224,21.6"/>\r
+        <point val="14.3224,23"/>\r
+        <point val="2.9248,23"/>\r
+        <point val="2.9248,25"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O4" connection="6"/>\r
+        <connection handle="1" to="O16" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O23">\r
+      <attribute name="obj_pos">\r
+        <point val="14.3224,21.6"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="13.4724,20.75;15.7748,25.85"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="14.3224,21.6"/>\r
+        <point val="14.3224,23"/>\r
+        <point val="14.9248,23"/>\r
+        <point val="14.9248,25"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O4" connection="6"/>\r
+        <connection handle="1" to="O15" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O24">\r
+      <attribute name="obj_pos">\r
+        <point val="14.3224,21.6"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="13.4724,20.75;27.7748,25.85"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="14.3224,21.6"/>\r
+        <point val="14.3224,23"/>\r
+        <point val="26.9248,23"/>\r
+        <point val="26.9248,25"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O4" connection="6"/>\r
+        <connection handle="1" to="O14" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O25">\r
+      <attribute name="obj_pos">\r
+        <point val="14.3224,21.6"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="13.4724,20.75;39.7748,25.85"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="14.3224,21.6"/>\r
+        <point val="14.3224,23"/>\r
+        <point val="38.9248,23"/>\r
+        <point val="38.9248,25"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O4" connection="6"/>\r
+        <connection handle="1" to="O13" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O26">\r
+      <attribute name="obj_pos">\r
+        <point val="14.3224,21.6"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="13.4724,20.75;51.7748,25.85"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="14.3224,21.6"/>\r
+        <point val="14.3224,23"/>\r
+        <point val="50.9248,23"/>\r
+        <point val="50.9248,25"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O4" connection="6"/>\r
+        <connection handle="1" to="O18" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O27">\r
+      <attribute name="obj_pos">\r
+        <point val="-21.0752,27.8"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-21.9252,26.95;-20.2252,31.85"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="-21.0752,27.8"/>\r
+        <point val="-21.0752,29"/>\r
+        <point val="-21.0752,29"/>\r
+        <point val="-21.0752,31"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O12" connection="6"/>\r
+        <connection handle="1" to="O19" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O28">\r
+      <attribute name="obj_pos">\r
+        <point val="13.9602,41"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-21.6252,40.15;14.8102,46.3"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="13.9602,41"/>\r
+        <point val="13.9602,43"/>\r
+        <point val="-20.7752,43"/>\r
+        <point val="-20.7752,45.45"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O0" connection="6"/>\r
+        <connection handle="1" to="O5" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O29">\r
+      <attribute name="obj_pos">\r
+        <point val="13.9602,41"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="-10.0721,40.15;14.8102,46.0845"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="13.9602,41"/>\r
+        <point val="13.9602,43"/>\r
+        <point val="-9.22209,43"/>\r
+        <point val="-9.22209,45.2345"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O0" connection="6"/>\r
+        <connection handle="1" to="O6" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O30">\r
+      <attribute name="obj_pos">\r
+        <point val="13.9602,41"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="13.1102,40.15;15.7748,45.85"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="13.9602,41"/>\r
+        <point val="13.9602,43"/>\r
+        <point val="14.9248,43"/>\r
+        <point val="14.9248,45"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O0" connection="6"/>\r
+        <connection handle="1" to="O8" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O31">\r
+      <attribute name="obj_pos">\r
+        <point val="13.9602,41"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="2.0748,40.15;14.8102,45.85"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="13.9602,41"/>\r
+        <point val="13.9602,43"/>\r
+        <point val="2.9248,43"/>\r
+        <point val="2.9248,45"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O0" connection="6"/>\r
+        <connection handle="1" to="O7" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O32">\r
+      <attribute name="obj_pos">\r
+        <point val="13.9602,41"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="13.1102,40.15;27.7748,45.85"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="13.9602,41"/>\r
+        <point val="13.9602,43"/>\r
+        <point val="26.9248,43"/>\r
+        <point val="26.9248,45"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O0" connection="6"/>\r
+        <connection handle="1" to="O9" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O33">\r
+      <attribute name="obj_pos">\r
+        <point val="13.9602,41"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="13.1102,40.15;39.7748,45.85"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="13.9602,41"/>\r
+        <point val="13.9602,43"/>\r
+        <point val="38.9248,43"/>\r
+        <point val="38.9248,45"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O0" connection="6"/>\r
+        <connection handle="1" to="O10" connection="1"/>\r
+      </connections>\r
+    </object>\r
+    <object type="UML - Generalization" version="0" id="O34">\r
+      <attribute name="obj_pos">\r
+        <point val="13.9602,41"/>\r
+      </attribute>\r
+      <attribute name="obj_bb">\r
+        <rectangle val="13.1102,40.15;51.7748,45.85"/>\r
+      </attribute>\r
+      <attribute name="orth_points">\r
+        <point val="13.9602,41"/>\r
+        <point val="13.9602,43"/>\r
+        <point val="50.9248,43"/>\r
+        <point val="50.9248,45"/>\r
+      </attribute>\r
+      <attribute name="orth_orient">\r
+        <enum val="1"/>\r
+        <enum val="0"/>\r
+        <enum val="1"/>\r
+      </attribute>\r
+      <attribute name="name">\r
+        <string/>\r
+      </attribute>\r
+      <attribute name="stereotype">\r
+        <string/>\r
+      </attribute>\r
+      <connections>\r
+        <connection handle="0" to="O0" connection="6"/>\r
+        <connection handle="1" to="O11" connection="1"/>\r
+      </connections>\r
+    </object>\r
+  </layer>\r
+</diagram>\r
diff --git a/doc/uml/vista.png b/doc/uml/vista.png
new file mode 100644 (file)
index 0000000..2cdb545
Binary files /dev/null and b/doc/uml/vista.png differ
diff --git a/download/algowars0.4.4_src.zip b/download/algowars0.4.4_src.zip
new file mode 100644 (file)
index 0000000..dc35a60
Binary files /dev/null and b/download/algowars0.4.4_src.zip differ
diff --git a/download/algowars0.5.5_src.zip b/download/algowars0.5.5_src.zip
new file mode 100644 (file)
index 0000000..3f437b1
Binary files /dev/null and b/download/algowars0.5.5_src.zip differ
diff --git a/download/algowars0.6.0_src.zip b/download/algowars0.6.0_src.zip
new file mode 100644 (file)
index 0000000..e5dba6c
Binary files /dev/null and b/download/algowars0.6.0_src.zip differ
diff --git a/download/algowars0.8.0_src.zip b/download/algowars0.8.0_src.zip
new file mode 100644 (file)
index 0000000..940ceb4
Binary files /dev/null and b/download/algowars0.8.0_src.zip differ
diff --git a/download/algowars0.8.2_src.zip b/download/algowars0.8.2_src.zip
new file mode 100644 (file)
index 0000000..79ae0ca
Binary files /dev/null and b/download/algowars0.8.2_src.zip differ
diff --git a/download/algowars0.9.8_src.zip b/download/algowars0.9.8_src.zip
new file mode 100644 (file)
index 0000000..56efe30
Binary files /dev/null and b/download/algowars0.9.8_src.zip differ
diff --git a/download/algowars0.9.9.1_src.zip b/download/algowars0.9.9.1_src.zip
new file mode 100644 (file)
index 0000000..ba840fc
Binary files /dev/null and b/download/algowars0.9.9.1_src.zip differ
diff --git a/download/algowars_src.zip b/download/algowars_src.zip
new file mode 100644 (file)
index 0000000..d76cde8
Binary files /dev/null and b/download/algowars_src.zip differ
diff --git a/download/escenarios/meteoritos.eaw b/download/escenarios/meteoritos.eaw
new file mode 100644 (file)
index 0000000..ef563e0
--- /dev/null
@@ -0,0 +1 @@
+<eaw version=1.0><navepropia><id>BD604C</id><posicion><id>BD6E44</id><X>5000</X><Y>0</Y><Z>0</Z></posicion><velocidad>0,17</velocidad><potencia>5</potencia><energia>100</energia><dimension>25</dimension><coordenadas><id>BD8AD8</id><i><id>BD60FC</id><X>-1</X><Y>5,42098688187657737E-20</Y><Z>0</Z></i><j><id>BD8BD8</id><X>-5,42098688187657737E-20</X><Y>-1</Y><Z>0</Z></j><k><id>BD8C18</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas><misiles>10</misiles><misilesdirigidos>5</misilesdirigidos><velmaxima>0,17</velmaxima><retardolaser>50</retardolaser><retardomisil>1000</retardomisil><retardomisdir>2500</retardomisdir><retardolasercont>0</retardolasercont><retardomisilcont>0</retardomisilcont><retardomisdircont>0</retardomisdircont><lockeado class=0>nil</lockeado><armaselec>6</armaselec><lockfiltro><id>BD8C98</id><observador class=cMeteorito><id>BDA3F4</id><posicion><id>BDE12C</id><X>0</X><Y>0</Y><Z>0</Z></posicion><velocidad>0</velocidad><potencia>5</potencia><energia>20</energia><dimension>5</dimension><coordenadas><id>BD8AB0</id><i><id>BE5B9C</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BE66DC</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BE6D9C</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas></observador><radiomaximo>2000</radiomaximo><radiominimo>25</radiominimo><cosapertura>0,696706709347165421</cosapertura></lockfiltro></navepropia><objetos total=11><objeto0 class=cMeteorito><id>BD11F8</id><posicion><id>BE6A94</id><X>3000</X><Y>3300</Y><Z>300</Z></posicion><velocidad>0,170002612332869756</velocidad><potencia>5</potencia><energia>20</energia><dimension>5</dimension><coordenadas><id>BE7224</id><i><id>BE67B4</id><X>-0,707106781186547524</X><Y>-0,707106781186547524</Y><Z>0</Z></i><j><id>BD6064</id><X>0,707106781186547524</X><Y>-0,707106781186547524</Y><Z>0</Z></j><k><id>BE5CC8</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas></objeto0><objeto1 class=cMeteorito><id>BD4134</id><posicion><id>BE65DC</id><X>4000</X><Y>-500</Y><Z>-1000</Z></posicion><velocidad>0,180000753748421843</velocidad><potencia>5</potencia><energia>20</energia><dimension>5</dimension><coordenadas><id>BD73C4</id><i><id>BD73DC</id><X>-0,816496580927726033</X><Y>0,408248290463863016</Y><Z>0,408248290463863016</Z></i><j><id>BE7E68</id><X>-0,447213595499957939</X><Y>-0,894427190999915879</Y><Z>0</Z></j><k><id>BE7E94</id><X>0,365148371670110742</X><Y>-0,182574185835055371</Y><Z>0,912870929175276856</Z></k></coordenadas></objeto1><objeto2 class=cMeteorito><id>BE6708</id><posicion><id>BDEC30</id><X>1000</X><Y>600</Y><Z>600</Z></posicion><velocidad>0,200000837498246492</velocidad><potencia>5</potencia><energia>20</energia><dimension>5</dimension><coordenadas><id>BE6AC0</id><i><id>BE6750</id><X>-0,816496580927726033</X><Y>0,408248290463863016</Y><Z>-0,408248290463863016</Z></i><j><id>BDEBB0</id><X>-0,447213595499957939</X><Y>-0,894427190999915879</Y><Z>0</Z></j><k><id>BDEBF0</id><X>-0,365148371670110742</X><Y>0,182574185835055371</Y><Z>0,912870929175276856</Z></k></coordenadas></objeto2><objeto3 class=cMeteorito><id>BDE2D8</id><posicion><id>BDEB10</id><X>3000</X><Y>-500</Y><Z>-500</Z></posicion><velocidad>0,2</velocidad><potencia>5</potencia><energia>20</energia><dimension>5</dimension><coordenadas><id>BDE30C</id><i><id>BDE338</id><X>-1</X><Y>5,42101086242752217E-20</Y><Z>0</Z></i><j><id>BDEA90</id><X>-5,42101086242752217E-20</X><Y>-1</Y><Z>0</Z></j><k><id>BDEAD0</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas></objeto3><objeto4 class=cMeteorito><id>BE7100</id><posicion><id>BE6EF4</id><X>2000</X><Y>1000</Y><Z>1000</Z></posicion><velocidad>0</velocidad><potencia>5</potencia><energia>20</energia><dimension>5</dimension><coordenadas><id>BE7148</id><i><id>BE7174</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BE6E74</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BE6EB4</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas></objeto4><objeto5 class=cMeteorito><id>BDE754</id><posicion><id>BDE888</id><X>-2000</X><Y>1000</Y><Z>1000</Z></posicion><velocidad>0</velocidad><potencia>5</potencia><energia>20</energia><dimension>5</dimension><coordenadas><id>BDE79C</id><i><id>BDE7C8</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BDE808</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BDE848</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas></objeto5><objeto6 class=cMeteorito><id>BD6328</id><posicion><id>BD645C</id><X>-2000</X><Y>-1000</Y><Z>1000</Z></posicion><velocidad>0</velocidad><potencia>5</potencia><energia>20</energia><dimension>5</dimension><coordenadas><id>BD6370</id><i><id>BD639C</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BD63DC</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BD641C</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas></objeto6><objeto7 class=cMeteorito><id>BD655C</id><posicion><id>BD6690</id><X>-2000</X><Y>-1000</Y><Z>-1000</Z></posicion><velocidad>0</velocidad><potencia>5</potencia><energia>20</energia><dimension>5</dimension><coordenadas><id>BD65A4</id><i><id>BD65D0</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BD6610</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BD6650</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas></objeto7><objeto8 class=cMeteorito><id>BD6790</id><posicion><id>BD68C4</id><X>-2000</X><Y>1000</Y><Z>-1000</Z></posicion><velocidad>0</velocidad><potencia>5</potencia><energia>20</energia><dimension>5</dimension><coordenadas><id>BD67D8</id><i><id>BD6804</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BD6844</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BD6884</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas></objeto8><objeto9 class=cMeteorito><id>BD69C4</id><posicion><id>BD6AF8</id><X>2000</X><Y>1000</Y><Z>-1000</Z></posicion><velocidad>0</velocidad><potencia>5</potencia><energia>20</energia><dimension>5</dimension><coordenadas><id>BD6A0C</id><i><id>BD6A38</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BD6A78</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BD6AB8</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas></objeto9><objeto10 class=cMeteorito><id>BD6C10</id><posicion><id>BD6D44</id><X>2000</X><Y>1000</Y><Z>-1000</Z></posicion><velocidad>0,24999692531709265</velocidad><potencia>5</potencia><energia>20</energia><dimension>5</dimension><coordenadas><id>BD6C58</id><i><id>BD6C84</id><X>0,904531124585551717</X><Y>-0,301515708260777948</Y><Z>0,301515708260777948</Z></i><j><id>BD6CC4</id><X>0,316232800364058715</X><Y>0,948681619919931508</Y><Z>0</Z></j><k><id>BD6D04</id><X>-0,286042410544140298</X><Y>0,0953491567770583619</Y><Z>0,95346120931687695</Z></k></coordenadas></objeto10></objetos></eaw>
\ No newline at end of file
diff --git a/download/escenarios/naves.eaw b/download/escenarios/naves.eaw
new file mode 100644 (file)
index 0000000..717d19e
--- /dev/null
@@ -0,0 +1 @@
+<eaw version=1.0><navepropia><id>BD604C</id><posicion><id>BDE158</id><X>5000</X><Y>0</Y><Z>0</Z></posicion><velocidad>0,17</velocidad><potencia>5</potencia><energia>100</energia><dimension>25</dimension><coordenadas><id>BD8AD8</id><i><id>BD60FC</id><X>-2,71052941176470588E-20</X><Y>1</Y><Z>0</Z></i><j><id>BD8BD8</id><X>-1</X><Y>-2,71052941176470588E-20</Y><Z>0</Z></j><k><id>BD8C18</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas><misiles>10</misiles><misilesdirigidos>5</misilesdirigidos><velmaxima>0,17</velmaxima><retardolaser>50</retardolaser><retardomisil>1000</retardomisil><retardomisdir>2500</retardomisdir><retardolasercont>0</retardolasercont><retardomisilcont>0</retardomisilcont><retardomisdircont>0</retardomisdircont><lockeado class=0>nil</lockeado><armaselec>6</armaselec><lockfiltro><id>BD8C98</id><observador class=cMeteorito><id>BD11F8</id><posicion><id>BD6064</id><X>0</X><Y>0</Y><Z>0</Z></posicion><velocidad>0</velocidad><potencia>5</potencia><energia>20</energia><dimension>5</dimension><coordenadas><id>BE7224</id><i><id>BE67B4</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BE6D38</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BD9B30</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas></observador><radiomaximo>2000</radiomaximo><radiominimo>25</radiominimo><cosapertura>0,696706709347165421</cosapertura></lockfiltro></navepropia><objetos total=11><objeto0 class=cNavePesada><id>BD8D5C</id><posicion><id>BD8ED8</id><X>3000</X><Y>3300</Y><Z>300</Z></posicion><velocidad>0,17</velocidad><potencia>2</potencia><energia>100</energia><dimension>25</dimension><coordenadas><id>BD893C</id><i><id>BD8E18</id><X>-0,707106781186547524</X><Y>-0,707106781186547524</Y><Z>0</Z></i><j><id>BD8E58</id><X>0,707106781186547524</X><Y>-0,707106781186547524</Y><Z>0</Z></j><k><id>BD8E98</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas><misiles>5</misiles><misilesdirigidos>2</misilesdirigidos><velmaxima>0,17</velmaxima><retardolaser>1000</retardolaser><retardomisil>60000</retardomisil><retardomisdir>180000</retardomisdir><retardolasercont>0</retardolasercont><retardomisilcont>0</retardomisilcont><retardomisdircont>0</retardomisdircont><camporadar>5000</camporadar><campominimo>500</campominimo></objeto0><objeto1 class=cNaveLiviana><id>BD906C</id><posicion><id>BD91E8</id><X>4000</X><Y>-500</Y><Z>-1000</Z></posicion><velocidad>0,18</velocidad><potencia>1</potencia><energia>60</energia><dimension>15</dimension><coordenadas><id>BD85C0</id><i><id>BD9128</id><X>-0,816496580927726033</X><Y>0,408248290463863016</Y><Z>0,408248290463863016</Z></i><j><id>BD9168</id><X>-0,447213595499957939</X><Y>-0,894427190999915879</Y><Z>0</Z></j><k><id>BD91A8</id><X>0,365148371670110742</X><Y>-0,182574185835055371</Y><Z>0,912870929175276856</Z></k></coordenadas><misiles>0</misiles><misilesdirigidos>0</misilesdirigidos><velmaxima>0,18</velmaxima><retardolaser>500</retardolaser><retardomisil>60000</retardomisil><retardomisdir>180000</retardomisdir><retardolasercont>0</retardolasercont><retardomisilcont>0</retardomisilcont><retardomisdircont>0</retardomisdircont><camporadar>3000</camporadar><campominimo>250</campominimo></objeto1><objeto2 class=cNaveSuicida><id>BD9368</id><posicion><id>BD94F0</id><X>1000</X><Y>600</Y><Z>600</Z></posicion><velocidad>0,2</velocidad><potencia>4</potencia><energia>30</energia><dimension>10</dimension><coordenadas><id>BD9404</id><i><id>BD9430</id><X>-0,816496580927726033</X><Y>0,408248290463863016</Y><Z>-0,408248290463863016</Z></i><j><id>BD9470</id><X>-0,447213595499957939</X><Y>-0,894427190999915879</Y><Z>0</Z></j><k><id>BD94B0</id><X>-0,365148371670110742</X><Y>0,182574185835055371</Y><Z>0,912870929175276856</Z></k></coordenadas><misiles>0</misiles><misilesdirigidos>0</misilesdirigidos><velmaxima>0,2</velmaxima><retardolaser>1000</retardolaser><retardomisil>60000</retardomisil><retardomisdir>180000</retardomisdir><retardolasercont>0</retardolasercont><retardomisilcont>0</retardomisilcont><retardomisdircont>0</retardomisdircont><camporadar>2500</camporadar></objeto2><objeto3 class=cNaveEspia><id>BD9670</id><posicion><id>BD97FC</id><X>3000</X><Y>-500</Y><Z>-500</Z></posicion><velocidad>0,2</velocidad><potencia>1</potencia><energia>30</energia><dimension>10</dimension><coordenadas><id>BD9710</id><i><id>BD973C</id><X>-1</X><Y>-5,42101086242752217E-20</Y><Z>0</Z></i><j><id>BD977C</id><X>5,42101086242752217E-20</X><Y>-1</Y><Z>0</Z></j><k><id>BD97BC</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas><misiles>0</misiles><misilesdirigidos>0</misilesdirigidos><velmaxima>0,2</velmaxima><retardolaser>1000</retardolaser><retardomisil>60000</retardomisil><retardomisdir>180000</retardomisdir><retardolasercont>0</retardolasercont><retardomisilcont>0</retardomisilcont><retardomisdircont>0</retardomisdircont><camporadar>2000</camporadar><posicionenemiga>nil</posicionenemiga></objeto3><objeto4 class=cNaveLiviana><id>BD9870</id><posicion><id>BD9A04</id><X>2000</X><Y>1000</Y><Z>1000</Z></posicion><velocidad>0</velocidad><potencia>1</potencia><energia>60</energia><dimension>15</dimension><coordenadas><id>BD9918</id><i><id>BD9944</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BD9984</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BD99C4</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas><misiles>0</misiles><misilesdirigidos>0</misilesdirigidos><velmaxima>0,18</velmaxima><retardolaser>500</retardolaser><retardomisil>60000</retardomisil><retardomisdir>180000</retardomisdir><retardolasercont>0</retardolasercont><retardomisilcont>0</retardomisilcont><retardomisdircont>0</retardomisdircont><camporadar>3000</camporadar><campominimo>250</campominimo></objeto4><objeto5 class=cNaveLiviana><id>BD9B5C</id><posicion><id>BD9CF0</id><X>-2000</X><Y>1000</Y><Z>1000</Z></posicion><velocidad>0</velocidad><potencia>1</potencia><energia>60</energia><dimension>15</dimension><coordenadas><id>BD9C04</id><i><id>BD9C30</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BD9C70</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BD9CB0</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas><misiles>0</misiles><misilesdirigidos>0</misilesdirigidos><velmaxima>0,18</velmaxima><retardolaser>500</retardolaser><retardomisil>60000</retardomisil><retardomisdir>180000</retardomisdir><retardolasercont>0</retardolasercont><retardomisilcont>0</retardomisilcont><retardomisdircont>0</retardomisdircont><camporadar>3000</camporadar><campominimo>250</campominimo></objeto5><objeto6 class=cNaveLiviana><id>BD9E48</id><posicion><id>BD9FDC</id><X>-2000</X><Y>-1000</Y><Z>1000</Z></posicion><velocidad>0</velocidad><potencia>1</potencia><energia>60</energia><dimension>15</dimension><coordenadas><id>BD9EF0</id><i><id>BD9F1C</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BD9F5C</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BD9F9C</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas><misiles>0</misiles><misilesdirigidos>0</misilesdirigidos><velmaxima>0,18</velmaxima><retardolaser>500</retardolaser><retardomisil>60000</retardomisil><retardomisdir>180000</retardomisdir><retardolasercont>0</retardolasercont><retardomisilcont>0</retardomisilcont><retardomisdircont>0</retardomisdircont><camporadar>3000</camporadar><campominimo>250</campominimo></objeto6><objeto7 class=cNavePesada><id>BDA134</id><posicion><id>BDA2C8</id><X>-2000</X><Y>-1000</Y><Z>-1000</Z></posicion><velocidad>0</velocidad><potencia>2</potencia><energia>100</energia><dimension>25</dimension><coordenadas><id>BDA1DC</id><i><id>BDA208</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BDA248</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BDA288</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas><misiles>5</misiles><misilesdirigidos>2</misilesdirigidos><velmaxima>0,17</velmaxima><retardolaser>1000</retardolaser><retardomisil>60000</retardomisil><retardomisdir>180000</retardomisdir><retardolasercont>0</retardolasercont><retardomisilcont>0</retardomisilcont><retardomisdircont>0</retardomisdircont><camporadar>5000</camporadar><campominimo>500</campominimo></objeto7><objeto8 class=cNavePesada><id>BDA420</id><posicion><id>BD9728</id><X>-2000</X><Y>1000</Y><Z>-1000</Z></posicion><velocidad>0</velocidad><potencia>2</potencia><energia>100</energia><dimension>25</dimension><coordenadas><id>BDA4C8</id><i><id>BDA4F4</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BE63A0</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BD96FC</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas><misiles>5</misiles><misilesdirigidos>2</misilesdirigidos><velmaxima>0,17</velmaxima><retardolaser>1000</retardolaser><retardomisil>60000</retardomisil><retardomisdir>180000</retardomisdir><retardolasercont>0</retardolasercont><retardomisilcont>0</retardomisilcont><retardomisdircont>0</retardomisdircont><camporadar>5000</camporadar><campominimo>500</campominimo></objeto8><objeto9 class=cNaveEspia><id>BE2C78</id><posicion><id>BDE5EC</id><X>2000</X><Y>1000</Y><Z>-1000</Z></posicion><velocidad>0</velocidad><potencia>1</potencia><energia>30</energia><dimension>10</dimension><coordenadas><id>BDA408</id><i><id>BD9E04</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BDA0DC</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BDE5C0</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas><misiles>0</misiles><misilesdirigidos>0</misilesdirigidos><velmaxima>0,2</velmaxima><retardolaser>1000</retardolaser><retardomisil>60000</retardomisil><retardomisdir>180000</retardomisdir><retardolasercont>0</retardolasercont><retardomisilcont>0</retardomisilcont><retardomisdircont>0</retardomisdircont><camporadar>2000</camporadar><posicionenemiga>nil</posicionenemiga></objeto9><objeto10 class=cMisilDirigido><id>BDDCB4</id><posicion><id>BDDE2C</id><X>2000</X><Y>1000</Y><Z>-1000</Z></posicion><velocidad>0,25</velocidad><potencia>30</potencia><energia>1</energia><dimension>0,7</dimension><coordenadas><id>BDDD40</id><i><id>BDDD6C</id><X>0,904534033733290868</X><Y>-0,301511344577763623</Y><Z>0,301511344577763623</Z></i><j><id>BDDDAC</id><X>0,316227766016837933</X><Y>0,9486832980505138</Y><Z>0</Z></j><k><id>BDDDEC</id><X>-0,286038776773677695</X><Y>0,0953462589245592316</Y><Z>0,953462589245592315</Z></k></coordenadas><duracion>20000</duracion><alcance>2000</alcance><velmaxima>0,25</velmaxima><objetivo class=cNavePropia><id>BD604C</id><posicion><id>BDE158</id><X>5000</X><Y>0</Y><Z>0</Z></posicion><velocidad>0,17</velocidad><potencia>5</potencia><energia>100</energia><dimension>25</dimension><coordenadas><id>BD8AD8</id><i><id>BD60FC</id><X>-2,71052941176470588E-20</X><Y>1</Y><Z>0</Z></i><j><id>BD8BD8</id><X>-1</X><Y>-2,71052941176470588E-20</Y><Z>0</Z></j><k><id>BD8C18</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas><misiles>10</misiles><misilesdirigidos>5</misilesdirigidos><velmaxima>0,17</velmaxima><retardolaser>50</retardolaser><retardomisil>1000</retardomisil><retardomisdir>2500</retardomisdir><retardolasercont>0</retardolasercont><retardomisilcont>0</retardomisilcont><retardomisdircont>0</retardomisdircont><lockeado class=0>nil</lockeado><armaselec>6</armaselec><lockfiltro><id>BD8C98</id><observador class=cMeteorito><id>BEF430</id><posicion><id>BEF464</id><X>0</X><Y>0</Y><Z>0</Z></posicion><velocidad>0</velocidad><potencia>5</potencia><energia>20</energia><dimension>5</dimension><coordenadas><id>BE7224</id><i><id>BE6D38</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BD9B30</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BE67B4</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas></observador><radiomaximo>2000</radiomaximo><radiominimo>25</radiominimo><cosapertura>0,696706709347165421</cosapertura></lockfiltro></objetivo><lockarea>2000</lockarea></objeto10></objetos></eaw>
\ No newline at end of file
diff --git a/download/instalar.exe b/download/instalar.exe
new file mode 100644 (file)
index 0000000..c33a838
Binary files /dev/null and b/download/instalar.exe differ
diff --git a/download/skins/alfa.zip b/download/skins/alfa.zip
new file mode 100644 (file)
index 0000000..73a67d1
Binary files /dev/null and b/download/skins/alfa.zip differ
diff --git a/download/skins/alfa/laser.bmp b/download/skins/alfa/laser.bmp
new file mode 100644 (file)
index 0000000..7cce48b
Binary files /dev/null and b/download/skins/alfa/laser.bmp differ
diff --git a/download/skins/alfa/meteorito.bmp b/download/skins/alfa/meteorito.bmp
new file mode 100644 (file)
index 0000000..4486ab9
Binary files /dev/null and b/download/skins/alfa/meteorito.bmp differ
diff --git a/download/skins/alfa/meteorito_l.bmp b/download/skins/alfa/meteorito_l.bmp
new file mode 100644 (file)
index 0000000..8c08ec1
Binary files /dev/null and b/download/skins/alfa/meteorito_l.bmp differ
diff --git a/download/skins/alfa/misil.bmp b/download/skins/alfa/misil.bmp
new file mode 100644 (file)
index 0000000..087be16
Binary files /dev/null and b/download/skins/alfa/misil.bmp differ
diff --git a/download/skins/alfa/misildirigido.bmp b/download/skins/alfa/misildirigido.bmp
new file mode 100644 (file)
index 0000000..428e7a4
Binary files /dev/null and b/download/skins/alfa/misildirigido.bmp differ
diff --git a/download/skins/alfa/naveespia.bmp b/download/skins/alfa/naveespia.bmp
new file mode 100644 (file)
index 0000000..90981ca
Binary files /dev/null and b/download/skins/alfa/naveespia.bmp differ
diff --git a/download/skins/alfa/naveespia_l.bmp b/download/skins/alfa/naveespia_l.bmp
new file mode 100644 (file)
index 0000000..73c48db
Binary files /dev/null and b/download/skins/alfa/naveespia_l.bmp differ
diff --git a/download/skins/alfa/naveliviana.bmp b/download/skins/alfa/naveliviana.bmp
new file mode 100644 (file)
index 0000000..d9320dc
Binary files /dev/null and b/download/skins/alfa/naveliviana.bmp differ
diff --git a/download/skins/alfa/naveliviana_l.bmp b/download/skins/alfa/naveliviana_l.bmp
new file mode 100644 (file)
index 0000000..317553b
Binary files /dev/null and b/download/skins/alfa/naveliviana_l.bmp differ
diff --git a/download/skins/alfa/navepesada.bmp b/download/skins/alfa/navepesada.bmp
new file mode 100644 (file)
index 0000000..04b92b5
Binary files /dev/null and b/download/skins/alfa/navepesada.bmp differ
diff --git a/download/skins/alfa/navepesada_l.bmp b/download/skins/alfa/navepesada_l.bmp
new file mode 100644 (file)
index 0000000..037b09d
Binary files /dev/null and b/download/skins/alfa/navepesada_l.bmp differ
diff --git a/download/skins/alfa/navepropia.bmp b/download/skins/alfa/navepropia.bmp
new file mode 100644 (file)
index 0000000..fba71a6
Binary files /dev/null and b/download/skins/alfa/navepropia.bmp differ
diff --git a/download/skins/alfa/navesuicida.bmp b/download/skins/alfa/navesuicida.bmp
new file mode 100644 (file)
index 0000000..0fd222f
Binary files /dev/null and b/download/skins/alfa/navesuicida.bmp differ
diff --git a/download/skins/alfa/navesuicida_l.bmp b/download/skins/alfa/navesuicida_l.bmp
new file mode 100644 (file)
index 0000000..9bebdcc
Binary files /dev/null and b/download/skins/alfa/navesuicida_l.bmp differ
diff --git a/download/skins/default.zip b/download/skins/default.zip
new file mode 100644 (file)
index 0000000..56071d3
Binary files /dev/null and b/download/skins/default.zip differ
diff --git a/download/skins/default/laser.jpg b/download/skins/default/laser.jpg
new file mode 100644 (file)
index 0000000..fee3619
Binary files /dev/null and b/download/skins/default/laser.jpg differ
diff --git a/download/skins/default/meteorito.jpg b/download/skins/default/meteorito.jpg
new file mode 100644 (file)
index 0000000..02013bb
Binary files /dev/null and b/download/skins/default/meteorito.jpg differ
diff --git a/download/skins/default/misil.jpg b/download/skins/default/misil.jpg
new file mode 100644 (file)
index 0000000..faea9f1
Binary files /dev/null and b/download/skins/default/misil.jpg differ
diff --git a/download/skins/default/misildirigido.jpg b/download/skins/default/misildirigido.jpg
new file mode 100644 (file)
index 0000000..e685762
Binary files /dev/null and b/download/skins/default/misildirigido.jpg differ
diff --git a/download/skins/default/naveespia.jpg b/download/skins/default/naveespia.jpg
new file mode 100644 (file)
index 0000000..4343bfa
Binary files /dev/null and b/download/skins/default/naveespia.jpg differ
diff --git a/download/skins/default/naveliviana.jpg b/download/skins/default/naveliviana.jpg
new file mode 100644 (file)
index 0000000..f356ef8
Binary files /dev/null and b/download/skins/default/naveliviana.jpg differ
diff --git a/download/skins/default/navepesada.jpg b/download/skins/default/navepesada.jpg
new file mode 100644 (file)
index 0000000..2ddef83
Binary files /dev/null and b/download/skins/default/navepesada.jpg differ
diff --git a/download/skins/default/navepropia.jpg b/download/skins/default/navepropia.jpg
new file mode 100644 (file)
index 0000000..e20c873
Binary files /dev/null and b/download/skins/default/navepropia.jpg differ
diff --git a/download/skins/default/navesuicida.jpg b/download/skins/default/navesuicida.jpg
new file mode 100644 (file)
index 0000000..88de66e
Binary files /dev/null and b/download/skins/default/navesuicida.jpg differ
diff --git a/download/skins/maxx/naveliviana.bmp b/download/skins/maxx/naveliviana.bmp
new file mode 100644 (file)
index 0000000..9a0a31f
Binary files /dev/null and b/download/skins/maxx/naveliviana.bmp differ
diff --git a/download/skins/maxx/navepesada.bmp b/download/skins/maxx/navepesada.bmp
new file mode 100644 (file)
index 0000000..6ae6cc8
Binary files /dev/null and b/download/skins/maxx/navepesada.bmp differ
diff --git a/download/skins/maxx/navepropia.bmp b/download/skins/maxx/navepropia.bmp
new file mode 100644 (file)
index 0000000..9ab385f
Binary files /dev/null and b/download/skins/maxx/navepropia.bmp differ
diff --git a/download/skins/maxx/navesuicida.bmp b/download/skins/maxx/navesuicida.bmp
new file mode 100644 (file)
index 0000000..9b67cb3
Binary files /dev/null and b/download/skins/maxx/navesuicida.bmp differ
diff --git a/src/AlgoWars.am2 b/src/AlgoWars.am2
new file mode 100644 (file)
index 0000000..e6ba173
Binary files /dev/null and b/src/AlgoWars.am2 differ
diff --git a/src/AlgoWars.bpg b/src/AlgoWars.bpg
new file mode 100644 (file)
index 0000000..21fd5c4
--- /dev/null
@@ -0,0 +1,20 @@
+#------------------------------------------------------------------------------\r
+VERSION = BWS.01\r
+#------------------------------------------------------------------------------\r
+!ifndef ROOT\r
+ROOT = $(MAKEDIR)\..\r
+!endif\r
+#------------------------------------------------------------------------------\r
+MAKE = $(ROOT)\bin\make.exe -$(MAKEFLAGS) -f$**\r
+DCC = $(ROOT)\bin\dcc32.exe $**\r
+BRCC = $(ROOT)\bin\brcc32.exe $**\r
+#------------------------------------------------------------------------------\r
+PROJECTS = AlgoWars.exe\r
+#------------------------------------------------------------------------------\r
+default: $(PROJECTS)\r
+#------------------------------------------------------------------------------\r
+\r
+AlgoWars.exe: AlgoWars.dpr\r
+  $(DCC)\r
+\r
+\r
diff --git a/src/AlgoWars.cfg b/src/AlgoWars.cfg
new file mode 100644 (file)
index 0000000..0654f75
--- /dev/null
@@ -0,0 +1,41 @@
+-$A+\r
+-$B-\r
+-$C-\r
+-$D-\r
+-$E-\r
+-$F-\r
+-$G+\r
+-$H+\r
+-$I+\r
+-$J+\r
+-$K-\r
+-$L-\r
+-$M-\r
+-$N+\r
+-$O+\r
+-$P+\r
+-$Q-\r
+-$R-\r
+-$S-\r
+-$T-\r
+-$U-\r
+-$V+\r
+-$W-\r
+-$X+\r
+-$Y-\r
+-$Z1\r
+-cg\r
+-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;\r
+-H+\r
+-W+\r
+-M\r
+-$M16384,1048576\r
+-K$00400000\r
+-E..\bin\r
+-N..\dcu\r
+-LE..\bin\r
+-LN..\dcu\r
+-U..\src\r
+-O..\src\r
+-I..\src\r
+-R..\src\r
diff --git a/src/AlgoWars.dof b/src/AlgoWars.dof
new file mode 100644 (file)
index 0000000..fbd722e
--- /dev/null
@@ -0,0 +1,117 @@
+[Compiler]\r
+A=1\r
+B=0\r
+C=0\r
+D=0\r
+E=0\r
+F=0\r
+G=1\r
+H=1\r
+I=1\r
+J=1\r
+K=0\r
+L=0\r
+M=0\r
+N=1\r
+O=1\r
+P=1\r
+Q=0\r
+R=0\r
+S=0\r
+T=0\r
+U=0\r
+V=1\r
+W=0\r
+X=1\r
+Y=0\r
+Z=1\r
+ShowHints=1\r
+ShowWarnings=1\r
+UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;\r
+\r
+[Linker]\r
+MapFile=0\r
+OutputObjs=0\r
+ConsoleApp=1\r
+DebugInfo=0\r
+RemoteSymbols=0\r
+MinStackSize=16384\r
+MaxStackSize=1048576\r
+ImageBase=4194304\r
+ExeDescription=\r
+\r
+[Directories]\r
+OutputDir=..\bin\r
+UnitOutputDir=..\dcu\r
+PackageDLLOutputDir=..\bin\r
+PackageDCPOutputDir=..\dcu\r
+SearchPath=..\src\r
+Packages=VCL40;VCLX40;VCLDB40;VCLDBX40;VCLSMP40;QRPT40;TEEUI40;TEEDB40;TEE40;DSS40;ibevnt40;VCLMID40;NMFAST40;INETDB40;INET40\r
+Conditionals=\r
+DebugSourceDirs=\r
+UsePackages=0\r
+\r
+[Parameters]\r
+RunParams=\r
+HostApplication=\r
+\r
+[Version Info]\r
+IncludeVerInfo=1\r
+AutoIncBuild=0\r
+MajorVer=1\r
+MinorVer=0\r
+Release=1\r
+Build=3\r
+Debug=0\r
+PreRelease=0\r
+Special=0\r
+Private=0\r
+DLL=0\r
+Locale=11274\r
+CodePage=1252\r
+\r
+[Version Info Keys]\r
+CompanyName=Grupo 10\r
+FileDescription=AlgoWars - Episodio IV\r
+FileVersion=1.0.1.3\r
+InternalName=\r
+LegalCopyright=Copyleft - GPL\r
+LegalTrademarks=\r
+OriginalFilename=AlgoWars.exe\r
+ProductName=AlgoWars\r
+ProductVersion=1.0.0.0\r
+Comments=Trabajo Práctico de Algoritmos y Programación III. Universidad de Buenos Aires - Facultad de Ingeniería\r
+\r
+[HistoryLists\hlConditionals]\r
+Count=1\r
+Item0=DebugAlgoWars\r
+\r
+[HistoryLists\hlUnitAliases]\r
+Count=1\r
+Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;\r
+\r
+[HistoryLists\hlSearchPath]\r
+Count=2\r
+Item0=..\src\r
+Item1=d:\develop\delphi\algowars\src\r
+\r
+[HistoryLists\hlUnitOutputDirectory]\r
+Count=5\r
+Item0=..\dcu\r
+Item1=d:\develop\delphi\algowars\dcu\r
+Item2=..\..\dcu\r
+Item3=..\..\..\dcu\r
+Item4=../../dcu\r
+\r
+[HistoryLists\hlOutputDirectorry]\r
+Count=2\r
+Item0=..\bin\r
+Item1=d:\develop\delphi\algowars\bin\r
+\r
+[HistoryLists\hlBPLOutput]\r
+Count=1\r
+Item0=..\bin\r
+\r
+[HistoryLists\hlDCPOutput]\r
+Count=1\r
+Item0=..\dcu\r
diff --git a/src/AlgoWars.dpr b/src/AlgoWars.dpr
new file mode 100644 (file)
index 0000000..bdfa124
--- /dev/null
@@ -0,0 +1,37 @@
+program AlgoWars;\r
+\r
+uses\r
+  Vectores in 'modelo\Vectores.pas',\r
+  Coordenadas in 'modelo\Coordenadas.pas',\r
+  Espacio in 'modelo\Espacio.pas',\r
+  ObjetoVolador in 'modelo\ov\ObjetoVolador.pas',\r
+  Meteorito in 'modelo\ov\Meteorito.pas',\r
+  Armas in 'modelo\ov\Armas.pas',\r
+  Nave in 'modelo\ov\naves\Nave.pas',\r
+  NaveEnemiga in 'modelo\ov\naves\NaveEnemiga.pas',\r
+  NavePropia in 'modelo\ov\naves\NavePropia.pas',\r
+  NavesEnemigas in 'modelo\ov\naves\NavesEnemigas.pas',\r
+  Filtro in 'vista\Filtro.pas',\r
+  Filtros in 'vista\Filtros.pas',\r
+  Camara in 'vista\Camara.pas',\r
+  Camaras in 'vista\Camaras.pas',\r
+  Vista in 'vista\Vista.pas',\r
+  Lista in 'auxiliares\Lista.pas',\r
+  ObjetoPersistente in 'auxiliares\ObjetoPersistente.pas',\r
+  SerializacionUtils in 'auxiliares\SerializacionUtils.pas',\r
+  Objeto in 'auxiliares\Objeto.pas',\r
+  Tipos in 'auxiliares\Tipos.pas',\r
+  RegExpr in 'auxiliares\RegExpr.pas',\r
+  Forms,\r
+  FormMain in 'forms\FormMain.pas' {MainForm},\r
+  FormConfig in 'forms\FormConfig.pas' {ConfigForm};\r
+\r
+{$R *.RES}\r
+\r
+begin\r
+  Application.Initialize;\r
+  Application.Title := 'AlgoWars - Episodio IV';\r
+  Application.CreateForm(TMainForm, MainForm);\r
+  Application.CreateForm(TConfigForm, ConfigForm);\r
+  Application.Run;\r
+end.\r
diff --git a/src/AlgoWars.drc b/src/AlgoWars.drc
new file mode 100644 (file)
index 0000000..aba52ef
--- /dev/null
@@ -0,0 +1,358 @@
+#define Consts_SDockZoneHasNoCtl 65344\r
+#define Consts_SmkcLeft 65360\r
+#define Consts_SmkcUp 65361\r
+#define Consts_SmkcRight 65362\r
+#define Consts_SmkcDown 65363\r
+#define Consts_SmkcIns 65364\r
+#define Consts_SmkcDel 65365\r
+#define Consts_SmkcShift 65366\r
+#define Consts_SmkcCtrl 65367\r
+#define Consts_SmkcAlt 65368\r
+#define Consts_SInsertLineError 65369\r
+#define Consts_SIconToClipboard 65370\r
+#define Consts_SBitsIndexError 65371\r
+#define Consts_SDuplicateMenus 65372\r
+#define Consts_SDockedCtlNeedsName 65373\r
+#define Consts_SDockTreeRemoveError 65374\r
+#define Consts_SDockZoneNotFound 65375\r
+#define Consts_SMsgDlgHelp 65376\r
+#define Consts_SMsgDlgAbort 65377\r
+#define Consts_SMsgDlgRetry 65378\r
+#define Consts_SMsgDlgIgnore 65379\r
+#define Consts_SMsgDlgAll 65380\r
+#define Consts_SMsgDlgNoToAll 65381\r
+#define Consts_SMsgDlgYesToAll 65382\r
+#define Consts_SmkcBkSp 65383\r
+#define Consts_SmkcTab 65384\r
+#define Consts_SmkcEsc 65385\r
+#define Consts_SmkcEnter 65386\r
+#define Consts_SmkcSpace 65387\r
+#define Consts_SmkcPgUp 65388\r
+#define Consts_SmkcPgDn 65389\r
+#define Consts_SmkcEnd 65390\r
+#define Consts_SmkcHome 65391\r
+#define Consts_SGroupIndexTooLow 65392\r
+#define Consts_SNoMDIForm 65393\r
+#define Consts_SControlParentSetToSelf 65394\r
+#define Consts_SCannotDragForm 65395\r
+#define Consts_SVMetafiles 65396\r
+#define Consts_SVEnhMetafiles 65397\r
+#define Consts_SVIcons 65398\r
+#define Consts_SVBitmaps 65399\r
+#define Consts_SMsgDlgWarning 65400\r
+#define Consts_SMsgDlgError 65401\r
+#define Consts_SMsgDlgInformation 65402\r
+#define Consts_SMsgDlgConfirm 65403\r
+#define Consts_SMsgDlgYes 65404\r
+#define Consts_SMsgDlgNo 65405\r
+#define Consts_SMsgDlgOK 65406\r
+#define Consts_SMsgDlgCancel 65407\r
+#define Consts_SNoCanvasHandle 65408\r
+#define Consts_SInvalidImageSize 65409\r
+#define Consts_SInvalidImageList 65410\r
+#define Consts_SImageIndexError 65411\r
+#define Consts_SImageReadFail 65412\r
+#define Consts_SWindowDCError 65413\r
+#define Consts_SWindowClass 65414\r
+#define Consts_SCannotFocus 65415\r
+#define Consts_SParentRequired 65416\r
+#define Consts_SMDIChildNotVisible 65417\r
+#define Consts_SVisibleChanged 65418\r
+#define Consts_SCannotShowModal 65419\r
+#define Consts_SMenuIndexError 65420\r
+#define Consts_SMenuReinserted 65421\r
+#define Consts_SMenuNotFound 65422\r
+#define Consts_SNoTimers 65423\r
+#define Consts_SDuplicateString 65424\r
+#define Consts_SDuplicateName 65425\r
+#define Consts_SInvalidName 65426\r
+#define Consts_SDuplicateClass 65427\r
+#define Consts_SInvalidPropertyValue 65428\r
+#define Consts_SInvalidPropertyPath 65429\r
+#define Consts_SUnknownProperty 65430\r
+#define Consts_SReadOnlyProperty 65431\r
+#define Consts_SPropertyException 65432\r
+#define Consts_SAncestorNotFound 65433\r
+#define Consts_SInvalidBitmap 65434\r
+#define Consts_SInvalidIcon 65435\r
+#define Consts_SInvalidMetafile 65436\r
+#define Consts_SChangeIconSize 65437\r
+#define Consts_SUnknownClipboardFormat 65438\r
+#define Consts_SOutOfResources 65439\r
+#define SysConst_SLongDayNameFri 65440\r
+#define SysConst_SLongDayNameSat 65441\r
+#define Consts_SAssignError 65442\r
+#define Consts_SFCreateError 65443\r
+#define Consts_SFOpenError 65444\r
+#define Consts_SReadError 65445\r
+#define Consts_SWriteError 65446\r
+#define Consts_SMemoryStreamError 65447\r
+#define Consts_SCantWriteResourceStreamError 65448\r
+#define Consts_SClassNotFound 65449\r
+#define Consts_SInvalidImage 65450\r
+#define Consts_SResNotFound 65451\r
+#define Consts_SListIndexError 65452\r
+#define Consts_SListCapacityError 65453\r
+#define Consts_SListCountError 65454\r
+#define Consts_SSortedListError 65455\r
+#define SysConst_SLongMonthNameSep 65456\r
+#define SysConst_SLongMonthNameOct 65457\r
+#define SysConst_SLongMonthNameNov 65458\r
+#define SysConst_SLongMonthNameDec 65459\r
+#define SysConst_SShortDayNameSun 65460\r
+#define SysConst_SShortDayNameMon 65461\r
+#define SysConst_SShortDayNameTue 65462\r
+#define SysConst_SShortDayNameWed 65463\r
+#define SysConst_SShortDayNameThu 65464\r
+#define SysConst_SShortDayNameFri 65465\r
+#define SysConst_SShortDayNameSat 65466\r
+#define SysConst_SLongDayNameSun 65467\r
+#define SysConst_SLongDayNameMon 65468\r
+#define SysConst_SLongDayNameTue 65469\r
+#define SysConst_SLongDayNameWed 65470\r
+#define SysConst_SLongDayNameThu 65471\r
+#define SysConst_SShortMonthNameMay 65472\r
+#define SysConst_SShortMonthNameJun 65473\r
+#define SysConst_SShortMonthNameJul 65474\r
+#define SysConst_SShortMonthNameAug 65475\r
+#define SysConst_SShortMonthNameSep 65476\r
+#define SysConst_SShortMonthNameOct 65477\r
+#define SysConst_SShortMonthNameNov 65478\r
+#define SysConst_SShortMonthNameDec 65479\r
+#define SysConst_SLongMonthNameJan 65480\r
+#define SysConst_SLongMonthNameFeb 65481\r
+#define SysConst_SLongMonthNameMar 65482\r
+#define SysConst_SLongMonthNameApr 65483\r
+#define SysConst_SLongMonthNameMay 65484\r
+#define SysConst_SLongMonthNameJun 65485\r
+#define SysConst_SLongMonthNameJul 65486\r
+#define SysConst_SLongMonthNameAug 65487\r
+#define SysConst_SWriteAccess 65488\r
+#define SysConst_SVarArrayCreate 65489\r
+#define SysConst_SVarNotArray 65490\r
+#define SysConst_SVarArrayBounds 65491\r
+#define SysConst_SExternalException 65492\r
+#define SysConst_SAssertionFailed 65493\r
+#define SysConst_SIntfCastError 65494\r
+#define SysConst_SAssertError 65495\r
+#define SysConst_SAbstractError 65496\r
+#define SysConst_SModuleAccessViolation 65497\r
+#define SysConst_SWin32Error 65498\r
+#define SysConst_SUnkWin32Error 65499\r
+#define SysConst_SShortMonthNameJan 65500\r
+#define SysConst_SShortMonthNameFeb 65501\r
+#define SysConst_SShortMonthNameMar 65502\r
+#define SysConst_SShortMonthNameApr 65503\r
+#define SysConst_SOverflow 65504\r
+#define SysConst_SUnderflow 65505\r
+#define SysConst_SInvalidPointer 65506\r
+#define SysConst_SInvalidCast 65507\r
+#define SysConst_SAccessViolation 65508\r
+#define SysConst_SStackOverflow 65509\r
+#define SysConst_SControlC 65510\r
+#define SysConst_SPrivilege 65511\r
+#define SysConst_SException 65512\r
+#define SysConst_SExceptTitle 65513\r
+#define SysConst_SInvalidFormat 65514\r
+#define SysConst_SArgumentMissing 65515\r
+#define SysConst_SInvalidVarCast 65516\r
+#define SysConst_SInvalidVarOp 65517\r
+#define SysConst_SDispatchError 65518\r
+#define SysConst_SReadAccess 65519\r
+#define SysConst_SInvalidInteger 65520\r
+#define SysConst_SInvalidFloat 65521\r
+#define SysConst_SOutOfMemory 65522\r
+#define SysConst_SInOutError 65523\r
+#define SysConst_SFileNotFound 65524\r
+#define SysConst_SInvalidFilename 65525\r
+#define SysConst_STooManyOpenFiles 65526\r
+#define SysConst_SAccessDenied 65527\r
+#define SysConst_SEndOfFile 65528\r
+#define SysConst_SDiskFull 65529\r
+#define SysConst_SInvalidInput 65530\r
+#define SysConst_SDivByZero 65531\r
+#define SysConst_SRangeError 65532\r
+#define SysConst_SIntOverflow 65533\r
+#define SysConst_SInvalidOp 65534\r
+#define SysConst_SZeroDivide 65535\r
+STRINGTABLE\r
+BEGIN\r
+       Consts_SDockZoneHasNoCtl,       " - Dock zone has no control"\r
+       Consts_SmkcLeft,        "Left"\r
+       Consts_SmkcUp,  "Up"\r
+       Consts_SmkcRight,       "Right"\r
+       Consts_SmkcDown,        "Down"\r
+       Consts_SmkcIns, "Ins"\r
+       Consts_SmkcDel, "Del"\r
+       Consts_SmkcShift,       "Shift+"\r
+       Consts_SmkcCtrl,        "Ctrl+"\r
+       Consts_SmkcAlt, "Alt+"\r
+       Consts_SInsertLineError,        "Unable to insert a line"\r
+       Consts_SIconToClipboard,        "Clipboard does not support Icons"\r
+       Consts_SBitsIndexError, "Bits index out of range"\r
+       Consts_SDuplicateMenus, "Menu '%s' is already being used by another form"\r
+       Consts_SDockedCtlNeedsName,     "Docked control must have a name"\r
+       Consts_SDockTreeRemoveError,    "Error removing control from dock tree"\r
+       Consts_SDockZoneNotFound,       " - Dock zone not found"\r
+       Consts_SMsgDlgHelp,     "&Help"\r
+       Consts_SMsgDlgAbort,    "&Abort"\r
+       Consts_SMsgDlgRetry,    "&Retry"\r
+       Consts_SMsgDlgIgnore,   "&Ignore"\r
+       Consts_SMsgDlgAll,      "&All"\r
+       Consts_SMsgDlgNoToAll,  "N&o to All"\r
+       Consts_SMsgDlgYesToAll, "Yes to &All"\r
+       Consts_SmkcBkSp,        "BkSp"\r
+       Consts_SmkcTab, "Tab"\r
+       Consts_SmkcEsc, "Esc"\r
+       Consts_SmkcEnter,       "Enter"\r
+       Consts_SmkcSpace,       "Space"\r
+       Consts_SmkcPgUp,        "PgUp"\r
+       Consts_SmkcPgDn,        "PgDn"\r
+       Consts_SmkcEnd, "End"\r
+       Consts_SmkcHome,        "Home"\r
+       Consts_SGroupIndexTooLow,       "GroupIndex cannot be less than a previous menu item's GroupIndex"\r
+       Consts_SNoMDIForm,      "Cannot create form. No MDI forms are currently active"\r
+       Consts_SControlParentSetToSelf, "A control cannot have itself as its parent"\r
+       Consts_SCannotDragForm, "Cannot drag a form"\r
+       Consts_SVMetafiles,     "Metafiles"\r
+       Consts_SVEnhMetafiles,  "Enhanced Metafiles"\r
+       Consts_SVIcons, "Icons"\r
+       Consts_SVBitmaps,       "Bitmaps"\r
+       Consts_SMsgDlgWarning,  "Warning"\r
+       Consts_SMsgDlgError,    "Error"\r
+       Consts_SMsgDlgInformation,      "Information"\r
+       Consts_SMsgDlgConfirm,  "Confirm"\r
+       Consts_SMsgDlgYes,      "&Yes"\r
+       Consts_SMsgDlgNo,       "&No"\r
+       Consts_SMsgDlgOK,       "OK"\r
+       Consts_SMsgDlgCancel,   "Cancel"\r
+       Consts_SNoCanvasHandle, "Canvas does not allow drawing"\r
+       Consts_SInvalidImageSize,       "Invalid image size"\r
+       Consts_SInvalidImageList,       "Invalid ImageList"\r
+       Consts_SImageIndexError,        "Invalid ImageList Index"\r
+       Consts_SImageReadFail,  "Failed to read ImageList data from stream"\r
+       Consts_SWindowDCError,  "Error creating window device context"\r
+       Consts_SWindowClass,    "Error creating window class"\r
+       Consts_SCannotFocus,    "Cannot focus a disabled or invisible window"\r
+       Consts_SParentRequired, "Control '%s' has no parent window"\r
+       Consts_SMDIChildNotVisible,     "Cannot hide an MDI Child Form"\r
+       Consts_SVisibleChanged, "Cannot change Visible in OnShow or OnHide"\r
+       Consts_SCannotShowModal,        "Cannot make a visible window modal"\r
+       Consts_SMenuIndexError, "Menu index out of range"\r
+       Consts_SMenuReinserted, "Menu inserted twice"\r
+       Consts_SMenuNotFound,   "Sub-menu is not in menu"\r
+       Consts_SNoTimers,       "Not enough timers available"\r
+       Consts_SDuplicateString,        "String list does not allow duplicates"\r
+       Consts_SDuplicateName,  "A component named %s already exists"\r
+       Consts_SInvalidName,    "''%s'' is not a valid component name"\r
+       Consts_SDuplicateClass, "A class named %s already exists"\r
+       Consts_SInvalidPropertyValue,   "Invalid property value"\r
+       Consts_SInvalidPropertyPath,    "Invalid property path"\r
+       Consts_SUnknownProperty,        "Property does not exist"\r
+       Consts_SReadOnlyProperty,       "Property is read-only"\r
+       Consts_SPropertyException,      "Error reading %s%s%s: %s"\r
+       Consts_SAncestorNotFound,       "Ancestor for '%s' not found"\r
+       Consts_SInvalidBitmap,  "Bitmap image is not valid"\r
+       Consts_SInvalidIcon,    "Icon image is not valid"\r
+       Consts_SInvalidMetafile,        "Metafile is not valid"\r
+       Consts_SChangeIconSize, "Cannot change the size of an icon"\r
+       Consts_SUnknownClipboardFormat, "Unsupported clipboard format"\r
+       Consts_SOutOfResources, "Out of system resources"\r
+       SysConst_SLongDayNameFri,       "Friday"\r
+       SysConst_SLongDayNameSat,       "Saturday"\r
+       Consts_SAssignError,    "Cannot assign a %s to a %s"\r
+       Consts_SFCreateError,   "Cannot create file %s"\r
+       Consts_SFOpenError,     "Cannot open file %s"\r
+       Consts_SReadError,      "Stream read error"\r
+       Consts_SWriteError,     "Stream write error"\r
+       Consts_SMemoryStreamError,      "Out of memory while expanding memory stream"\r
+       Consts_SCantWriteResourceStreamError,   "Can't write to a read-only resource stream"\r
+       Consts_SClassNotFound,  "Class %s not found"\r
+       Consts_SInvalidImage,   "Invalid stream format"\r
+       Consts_SResNotFound,    "Resource %s not found"\r
+       Consts_SListIndexError, "List index out of bounds (%d)"\r
+       Consts_SListCapacityError,      "List capacity out of bounds (%d)"\r
+       Consts_SListCountError, "List count out of bounds (%d)"\r
+       Consts_SSortedListError,        "Operation not allowed on sorted string list"\r
+       SysConst_SLongMonthNameSep,     "September"\r
+       SysConst_SLongMonthNameOct,     "October"\r
+       SysConst_SLongMonthNameNov,     "November"\r
+       SysConst_SLongMonthNameDec,     "December"\r
+       SysConst_SShortDayNameSun,      "Sun"\r
+       SysConst_SShortDayNameMon,      "Mon"\r
+       SysConst_SShortDayNameTue,      "Tue"\r
+       SysConst_SShortDayNameWed,      "Wed"\r
+       SysConst_SShortDayNameThu,      "Thu"\r
+       SysConst_SShortDayNameFri,      "Fri"\r
+       SysConst_SShortDayNameSat,      "Sat"\r
+       SysConst_SLongDayNameSun,       "Sunday"\r
+       SysConst_SLongDayNameMon,       "Monday"\r
+       SysConst_SLongDayNameTue,       "Tuesday"\r
+       SysConst_SLongDayNameWed,       "Wednesday"\r
+       SysConst_SLongDayNameThu,       "Thursday"\r
+       SysConst_SShortMonthNameMay,    "May"\r
+       SysConst_SShortMonthNameJun,    "Jun"\r
+       SysConst_SShortMonthNameJul,    "Jul"\r
+       SysConst_SShortMonthNameAug,    "Aug"\r
+       SysConst_SShortMonthNameSep,    "Sep"\r
+       SysConst_SShortMonthNameOct,    "Oct"\r
+       SysConst_SShortMonthNameNov,    "Nov"\r
+       SysConst_SShortMonthNameDec,    "Dec"\r
+       SysConst_SLongMonthNameJan,     "January"\r
+       SysConst_SLongMonthNameFeb,     "February"\r
+       SysConst_SLongMonthNameMar,     "March"\r
+       SysConst_SLongMonthNameApr,     "April"\r
+       SysConst_SLongMonthNameMay,     "May"\r
+       SysConst_SLongMonthNameJun,     "June"\r
+       SysConst_SLongMonthNameJul,     "July"\r
+       SysConst_SLongMonthNameAug,     "August"\r
+       SysConst_SWriteAccess,  "Write"\r
+       SysConst_SVarArrayCreate,       "Error creating variant array"\r
+       SysConst_SVarNotArray,  "Variant is not an array"\r
+       SysConst_SVarArrayBounds,       "Variant array index out of bounds"\r
+       SysConst_SExternalException,    "External exception %x"\r
+       SysConst_SAssertionFailed,      "Assertion failed"\r
+       SysConst_SIntfCastError,        "Interface not supported"\r
+       SysConst_SAssertError,  "%s (%s, line %d)"\r
+       SysConst_SAbstractError,        "Abstract Error"\r
+       SysConst_SModuleAccessViolation,        "Access violation at address %p in module '%s'. %s of address %p"\r
+       SysConst_SWin32Error,   "Win32 Error.  Code: %d.\n%s"\r
+       SysConst_SUnkWin32Error,        "A Win32 API function failed"\r
+       SysConst_SShortMonthNameJan,    "Jan"\r
+       SysConst_SShortMonthNameFeb,    "Feb"\r
+       SysConst_SShortMonthNameMar,    "Mar"\r
+       SysConst_SShortMonthNameApr,    "Apr"\r
+       SysConst_SOverflow,     "Floating point overflow"\r
+       SysConst_SUnderflow,    "Floating point underflow"\r
+       SysConst_SInvalidPointer,       "Invalid pointer operation"\r
+       SysConst_SInvalidCast,  "Invalid class typecast"\r
+       SysConst_SAccessViolation,      "Access violation at address %p. %s of address %p"\r
+       SysConst_SStackOverflow,        "Stack overflow"\r
+       SysConst_SControlC,     "Control-C hit"\r
+       SysConst_SPrivilege,    "Privileged instruction"\r
+       SysConst_SException,    "Exception %s in module %s at %p.\n%s%s"\r
+       SysConst_SExceptTitle,  "Application Error"\r
+       SysConst_SInvalidFormat,        "Format '%s' invalid or incompatible with argument"\r
+       SysConst_SArgumentMissing,      "No argument for format '%s'"\r
+       SysConst_SInvalidVarCast,       "Invalid variant type conversion"\r
+       SysConst_SInvalidVarOp, "Invalid variant operation"\r
+       SysConst_SDispatchError,        "Variant method calls not supported"\r
+       SysConst_SReadAccess,   "Read"\r
+       SysConst_SInvalidInteger,       "'%s' is not a valid integer value"\r
+       SysConst_SInvalidFloat, "'%s' is not a valid floating point value"\r
+       SysConst_SOutOfMemory,  "Out of memory"\r
+       SysConst_SInOutError,   "I/O error %d"\r
+       SysConst_SFileNotFound, "File not found"\r
+       SysConst_SInvalidFilename,      "Invalid filename"\r
+       SysConst_STooManyOpenFiles,     "Too many open files"\r
+       SysConst_SAccessDenied, "File access denied"\r
+       SysConst_SEndOfFile,    "Read beyond end of file"\r
+       SysConst_SDiskFull,     "Disk full"\r
+       SysConst_SInvalidInput, "Invalid numeric input"\r
+       SysConst_SDivByZero,    "Division by zero"\r
+       SysConst_SRangeError,   "Range check error"\r
+       SysConst_SIntOverflow,  "Integer overflow"\r
+       SysConst_SInvalidOp,    "Invalid floating point operation"\r
+       SysConst_SZeroDivide,   "Floating point division by zero"\r
+END\r
+\r
diff --git a/src/AlgoWars.dsk b/src/AlgoWars.dsk
new file mode 100644 (file)
index 0000000..55c957a
--- /dev/null
@@ -0,0 +1,177 @@
+[Main Window]\r
+Create=1\r
+Visible=1\r
+State=2\r
+Left=0\r
+Top=0\r
+Width=1024\r
+Height=105\r
+MaxLeft=-1\r
+MaxTop=-1\r
+MaxWidth=1032\r
+MaxHeight=105\r
+ClientWidth=1024\r
+ClientHeight=78\r
+\r
+[PropertyInspector]\r
+Create=1\r
+Visible=1\r
+State=0\r
+Left=0\r
+Top=107\r
+Width=190\r
+Height=494\r
+MaxLeft=-1\r
+MaxTop=-1\r
+ClientWidth=180\r
+ClientHeight=468\r
+TBDockHeight=494\r
+LRDockWidth=190\r
+SplitPos=85\r
+\r
+[ProjectManager]\r
+Create=1\r
+Visible=1\r
+State=0\r
+Left=0\r
+Top=11\r
+Width=187\r
+Height=363\r
+MaxLeft=-1\r
+MaxTop=-1\r
+ClientWidth=187\r
+ClientHeight=363\r
+TBDockHeight=303\r
+LRDockWidth=187\r
+\r
+[Modules]\r
+Module0=D:\develop\delphi\algowars\src\forms\FormMain.pas\r
+Module1=D:\develop\delphi\algowars\src\AlgoWars.dpr\r
+Count=2\r
+EditWindowCount=1\r
+\r
+[D:\develop\delphi\algowars\src\forms\FormMain.pas]\r
+ModuleType=SourceModule\r
+FormState=1\r
+FormOnTop=0\r
+\r
+[D:\develop\delphi\algowars\src\AlgoWars.dpr]\r
+ModuleType=SourceModule\r
+FormState=0\r
+FormOnTop=0\r
+\r
+[\\BURNS\www\algowars\proyecto\src\AlgoWars.bpg]\r
+FormState=0\r
+FormOnTop=0\r
+\r
+[\\BURNS\www\algowars\proyecto\src\AlgoWars.dpr]\r
+FormState=0\r
+FormOnTop=0\r
+\r
+[EditWindow0]\r
+CodeExplorer=CodeExplorer@EditWindow0\r
+MessageView=MessageView@EditWindow0\r
+Create=1\r
+Visible=1\r
+State=2\r
+Left=200\r
+Top=122\r
+Width=696\r
+Height=482\r
+MaxLeft=-4\r
+MaxTop=97\r
+MaxWidth=1032\r
+MaxHeight=647\r
+ClientWidth=1024\r
+ClientHeight=620\r
+LeftPanelSize=187\r
+LeftPanelClients=ProjectManager,CodeExplorer@EditWindow0\r
+LeftPanelData=0000040000000000F20100000000000001BB0000000000000001000000007A0100001200000050726F6A6563744D616E61676572466F726D0100000000F20100000C000000436F64654578706C6F726572FFFFFFFF\r
+RightPanelSize=0\r
+BottomPanelSize=101\r
+BottomPanelClients=MessageView@EditWindow0\r
+BottomPanelData=000004000000000000000000000000000000000000000000000100000000000000000B0000004D65737361676556696577FFFFFFFF\r
+ViewCount=2\r
+CurrentView=1\r
+View0=0\r
+View1=1\r
+\r
+[CodeExplorer@EditWindow0]\r
+Create=1\r
+Visible=1\r
+State=0\r
+Left=0\r
+Top=389\r
+Width=187\r
+Height=109\r
+MaxLeft=-1\r
+MaxTop=-1\r
+ClientWidth=187\r
+ClientHeight=109\r
+TBDockHeight=305\r
+LRDockWidth=187\r
+\r
+[MessageView@EditWindow0]\r
+Create=1\r
+Visible=1\r
+State=0\r
+Left=11\r
+Top=0\r
+Width=1013\r
+Height=101\r
+MaxLeft=-1\r
+MaxTop=-1\r
+ClientWidth=1013\r
+ClientHeight=101\r
+TBDockHeight=101\r
+LRDockWidth=443\r
+\r
+[View0]\r
+Module=D:\develop\delphi\algowars\src\AlgoWars.dpr\r
+CursorX=1\r
+CursorY=1\r
+TopLine=1\r
+LeftCol=1\r
+\r
+[View1]\r
+Module=D:\develop\delphi\algowars\src\forms\FormMain.pas\r
+CursorX=10\r
+CursorY=473\r
+TopLine=466\r
+LeftCol=1\r
+\r
+[DockHosts]\r
+DockHostCount=0\r
+\r
+[Watches]\r
+Count=1\r
+Watch0='i',256,0,18,1\r
+\r
+[Breakpoints]\r
+Count=0\r
+\r
+[AddressBreakpoints]\r
+Count=0\r
+\r
+[PVCS Browser]\r
+Left=236\r
+Top=105\r
+Width=625\r
+Height=393\r
+State=0\r
+Visible=0\r
+\r
+[PVCS VDiff]\r
+Left=257\r
+Top=160\r
+Width=591\r
+Height=608\r
+Layout=1\r
+Orientation=1\r
+State=0\r
+Visible=0\r
+File1Color=16711680\r
+File2Color=255\r
+SpaceColor=16776960\r
+TextColor=0\r
+\r
diff --git a/src/AlgoWars.iss b/src/AlgoWars.iss
new file mode 100644 (file)
index 0000000..824a8e4
--- /dev/null
@@ -0,0 +1,67 @@
+; Script created by ISS Creator v1.1.0\r
+; © 2000 Jason Hanford-Smith\r
+; http://www.verinet.com/~jhanford\r
+; -- AlgoWars.iss --\r
+; Programa de instalación de AlgoWars - Episodio IV versión 1.0.\r
+; Copyleft 2000. Este programa está bajo licencia GPL.\r
+\r
+[Setup]\r
+AppName=AlgoWars - Episodio IV\r
+AppVerName=AlgoWars - Episodio IV versión 1.0\r
+AppCopyright=Copyleft. GPL 2000. Grupo 10. Facultad de Ingeniería. UBA. Algoritmos y Programación III.\r
+DefaultDirName={pf}\AlgoWars\r
+DefaultGroupName=AlgoWars - Episodio IV\r
+AllowNoIcons=1\r
+InfoAfterFile=..\doc\CHANGES.TXT\r
+LicenseFile=..\doc\LICENCIA_GPL.TXT\r
+DisableStartupPrompt=1\r
+AlwaysCreateUninstallIcon=1\r
+UninstallDisplayIcon={app}\AlgoWars.exe\r
+WizardImageFile=compiler:WizImg15.bmp\r
+BackColor=clBlack\r
+BackColor2=clNavy\r
+OutputBaseFilename=instalar\r
+OutputDir=..\download\r
+SourceDir=..\bin\r
+MessagesFile=compiler:InoSetup-Spanish-2-1.3.14.isl\r
+; MinVersion=4,3.51\r
+CompressLevel=9\r
+\r
+[Files]\r
+Source: "AlgoWars.exe"; DestDir: "{app}"\r
+Source: "comun.eaw"; DestDir: "{app}"\r
+Source: "CHANGES.TXT"; DestDir: "{app}"\r
+Source: "bitmaps\desconocido.bmp"; DestDir: "{app}\bitmaps"\r
+Source: "bitmaps\desconocido_l.bmp"; DestDir: "{app}\bitmaps"\r
+Source: "bitmaps\gameover.bmp"; DestDir: "{app}\bitmaps"\r
+Source: "bitmaps\laser.bmp"; DestDir: "{app}\bitmaps"\r
+Source: "bitmaps\meteorito.bmp"; DestDir: "{app}\bitmaps"\r
+Source: "bitmaps\meteorito_l.bmp"; DestDir: "{app}\bitmaps"\r
+Source: "bitmaps\misil.bmp"; DestDir: "{app}\bitmaps"\r
+Source: "bitmaps\misildirigido.bmp"; DestDir: "{app}\bitmaps"\r
+Source: "bitmaps\naveespia.bmp"; DestDir: "{app}\bitmaps"\r
+Source: "bitmaps\naveespia_l.bmp"; DestDir: "{app}\bitmaps"\r
+Source: "bitmaps\naveliviana.bmp"; DestDir: "{app}\bitmaps"\r
+Source: "bitmaps\naveliviana_l.bmp"; DestDir: "{app}\bitmaps"\r
+Source: "bitmaps\navepesada.bmp"; DestDir: "{app}\bitmaps"\r
+Source: "bitmaps\navepesada_l.bmp"; DestDir: "{app}\bitmaps"\r
+Source: "bitmaps\navepropia.bmp"; DestDir: "{app}\bitmaps"\r
+Source: "bitmaps\navepropia_l.bmp"; DestDir: "{app}\bitmaps"\r
+Source: "bitmaps\navesuicida.bmp"; DestDir: "{app}\bitmaps"\r
+Source: "bitmaps\navesuicida_l.bmp"; DestDir: "{app}\bitmaps"\r
+\r
+[Icons]\r
+Name: "{group}\AlgoWars - Episodio IV"; Filename: "{app}\AlgoWars.exe"\r
+Name: "{group}\Cambios"; Filename: "{app}\CHANGES.TXT"\r
+Name: "{userdesktop}\AlgoWars - Episodio IV"; Filename: "{app}\AlgoWars.exe"\r
+\r
+[Registry]\r
+Root: HKLM; Subkey: "Software\AlgoWars\"; ValueType: string; ValueName: "Directorio"; ValueData: "{app}"; Flags: createvalueifdoesntexist uninsdeletekey\r
+\r
+[UninstallDelete]\r
+Type: dirifempty; Name: "{app}\bitmaps"\r
+Type: dirifempty; Name: "{app}"\r
+\r
+[Messages]\r
+FinishedLabel=El programa terminó la instalación de [name] en su computadora. Puede ejecutar la aplicación seleccionando el icono instalado.%nRecuerde que para obtener una versión más reciente o nuevas imágenes o nuevos escenarios puede visitar el sitio web http://www.algowars.2y.net\r
+WelcomeLabel=Bienvenido a la instalación de [name]. Este programa instalará [name/ver] en su computadora.%n%nSe recomienda ampliamente que, antes de continuar, cierre todas las otras aplicaciones que esté ejecutando. Esto ayudará a prevenir conflictos durante el proceso de instalación.%nRecuerde que para obtener una versión más reciente o nuevas imágenes o nuevos escenarios puede visitar el sitio web http://www.algowars.2y.net\r
diff --git a/src/AlgoWars.res b/src/AlgoWars.res
new file mode 100644 (file)
index 0000000..d4623e9
Binary files /dev/null and b/src/AlgoWars.res differ
diff --git a/src/AlgoWars.todo b/src/AlgoWars.todo
new file mode 100644 (file)
index 0000000..654268b
--- /dev/null
@@ -0,0 +1 @@
+{TODO 5 -oLuca -ccEspacio : Cambiar TODOS los metodos para que usen el nuevo "esquema de punteros"}{TODO 2 -oLuca -ccEspacio : Cambiar constructor del espacio para que pueda especificarse una NavePropia}{DONE 2 -oLuca -ccObjetoVolador : Implementar metodos que cambien solo la direccion  y solo el modulo de la velocidad.}{TODO 1 -oLuca -ccObjetoVolador : Implementar mGetDebugInfo para los objetos voladores que tienen atributos nuevos.}\r
diff --git a/src/algowars.ico b/src/algowars.ico
new file mode 100644 (file)
index 0000000..b569399
Binary files /dev/null and b/src/algowars.ico differ
diff --git a/src/auxiliares/Lista.pas b/src/auxiliares/Lista.pas
new file mode 100644 (file)
index 0000000..2739e55
--- /dev/null
@@ -0,0 +1,38 @@
+{** Lista exactamente igual a TList, solo que el destructor tambien destruye\r
+    todos los objetos que contiene}\r
+unit Lista;\r
+\r
+interface\r
+\r
+uses\r
+  Tipos,\r
+  Classes;\r
+\r
+type\r
+  {** Lista exactamente igual a TList, solo que el destructor tambien destruye todos\r
+      los objetos que contiene}\r
+  cLista = class( TList )\r
+    public\r
+      {** Destructor. Destruye la lista y TODOS los objetos que ella contiene}\r
+      destructor destroy; override;\r
+  end;\r
+\r
+implementation\r
+\r
+{ cLista }\r
+\r
+{** Destructor. Destruye la lista y TODOS los objetos que ella contiene}\r
+destructor cLista.destroy;\r
+var\r
+  p: pointer;\r
+begin\r
+  while Count > 0 do begin\r
+    p := First;\r
+    Remove( p );\r
+    if p <> nil then\r
+        dispose( p );\r
+  end;\r
+  inherited;\r
+end;\r
+\r
+end.\r
diff --git a/src/auxiliares/Objeto.pas b/src/auxiliares/Objeto.pas
new file mode 100644 (file)
index 0000000..fcda35d
--- /dev/null
@@ -0,0 +1,25 @@
+{** Es una clase abstracta para agregar algunos métodos generales útiles\r
+    para el resto de las clases que implementemos. Podría considerarse una\r
+    extensión a la funcionalidad básica dada por TObject.}\r
+unit Objeto;\r
+\r
+interface\r
+\r
+uses\r
+  Tipos;\r
+{$IFDEF DebugAlgoWars}\r
+type\r
+  {** Es una clase abstracta para agregar algunos métodos generales útiles\r
+      para el resto de las clases que implementemos. Podría considerarse una\r
+      extensión a la funcionalidad básica dada por TObject.}\r
+  cObjeto = class\r
+    public\r
+      {** Devuelve una cadena de texto con el estado actual del objeto.\r
+          La cantidad de información devuelta depende del parametro debugLevel}\r
+      function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; virtual; abstract;\r
+  end;\r
+{$ENDIF}\r
+\r
+implementation\r
+\r
+end.\r
diff --git a/src/auxiliares/ObjetoPersistente.pas b/src/auxiliares/ObjetoPersistente.pas
new file mode 100644 (file)
index 0000000..a225370
--- /dev/null
@@ -0,0 +1,121 @@
+{** Es una clase abstracta para hacer persistente un objeto.\r
+    Básicamente provee métodos para serialización.<br>\r
+    <U>NOTA:</U>\r
+    <PRE>\r
+      Es importante que el ID del objeto sea el primer atributo en la\r
+      serialización, de otra manera puede ser malinterpretado al des-\r
+      serializarlo.\r
+      El orden del resto de los atributos deben ser respetados también.\r
+      Aunque es bastante probable que fucione si están en otro órden,\r
+      no está 100% asegurado y si se hace en otro orden los resultados\r
+      pueden ser inesperados o pueden surgir errores.\r
+    <PRE>}\r
+unit ObjetoPersistente;\r
+\r
+interface\r
+\r
+uses\r
+  {$IFDEF DebugAlgoWars}\r
+  Objeto,\r
+  {$ENDIF}\r
+  Sysutils;\r
+\r
+type\r
+  {** Excepcion producida si hay un error al serializar.}\r
+  ESerializacion = class( Exception )\r
+  end;\r
+\r
+  {** Es una clase abstracta para hacer persistente un objeto.\r
+      Básicamente provee métodos para serialización.\r
+      NOTA: Es importante que el ID del objeto sea el primer atributo en la\r
+            serialización, de otra manera puede ser malinterpretado al des-\r
+            serializarlo.}\r
+  cObjetoPersistente = class{$IFDEF DebugAlgoWars}( cObjeto ){$ENDIF}\r
+    private\r
+      aID: string; // Identificación UNICA de la instancia\r
+    protected\r
+      {** Setea la identificacion del objeto}\r
+      procedure mSetID( id: string );\r
+    public\r
+      {** Constructor. Setea el ID.}\r
+      constructor create;\r
+      {** Constructor que crea el objeto a partir de una cadena de texto con\r
+          el objeto serializado.}\r
+      constructor crearDeSerializado( str: string );\r
+      {** Obtiene la identificacion del objeto}\r
+      function mGetID: string;\r
+      {** Devuelve una cadena de texto con el objeto serializado.}\r
+      function mSerializar: string; virtual;\r
+      {** Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.}\r
+      procedure mDesSerializar( str: string ); virtual;\r
+  end;\r
+\r
+implementation\r
+\r
+uses\r
+  RegExpr;\r
+\r
+{ cObjetoPersistente }\r
+\r
+{** Constructor que crea el objeto a partir de una cadena de texto con\r
+    el objeto serializado.\r
+    @param str cadena de texto con el objeto serializado.}\r
+constructor cObjetoPersistente.crearDeSerializado(str: string);\r
+begin\r
+  inherited create;      // Llama al create padre\r
+  mDesSerializar( str ); // Deserializa los datos\r
+end;\r
+\r
+{** Constructor. Setea el ID.}\r
+constructor cObjetoPersistente.create;\r
+begin\r
+  inherited;\r
+  aID := IntToHex( integer( self ), 6 );\r
+end;\r
+\r
+{** Obtiene la identificacion del objeto\r
+    @return ID del objeto.}\r
+function cObjetoPersistente.mGetID: string;\r
+begin\r
+  result := aID;\r
+end;\r
+\r
+{** Setea la identificacion del objeto\r
+    @param id nuevo ID.}\r
+procedure cObjetoPersistente.mSetID(id: string);\r
+begin\r
+  aID := id;\r
+end;\r
+\r
+{** Devuelve una cadena de texto con el objeto serializado.\r
+    @return Cadena de texto con el objeto serializado.}\r
+function cObjetoPersistente.mSerializar: string;\r
+begin\r
+  result := '<id>' + aID + '</id>';\r
+end;\r
+\r
+{** Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    @param str Cadena de texto con el objeto serializado.}\r
+procedure cObjetoPersistente.mDesSerializar(str: string);\r
+var\r
+  r: TRegExpr;\r
+begin\r
+  r := TRegExpr.create;\r
+  try // prueba que no haya errores con las expresiones regulares\r
+    r.Expression := '<id>\s*([ABCDEFabcdef0-9]{6})\s*</id>';\r
+    if r.Exec ( str ) then\r
+      aID := r.Match[1]\r
+    else\r
+      raise ESerializacion.create( 'No se encontro el ID del Objeto' );\r
+  except\r
+    on e: ERegExpr do begin\r
+      r.Free;\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el ID utilizando expresiones regulares: ' + e.Message );\r
+    end;\r
+  end;\r
+  r.free;\r
+end;\r
+\r
+end.\r
diff --git a/src/auxiliares/RegExpr.pas b/src/auxiliares/RegExpr.pas
new file mode 100644 (file)
index 0000000..a57d7c6
--- /dev/null
@@ -0,0 +1,3622 @@
+{** Implementación de expresiones regulares para Delphi}\r
+{$B-}\r
+unit RegExpr;\r
+\r
+(*\r
+\r
+     TRegExpr library\r
+     Regular Expressions for Delphi\r
+     v. 0.938\r
+\r
+Author:\r
+     Andrey V. Sorokin\r
+     St-Petersburg\r
+     Russia\r
+     anso@mail.ru, anso@usa.net\r
+     http://anso.da.ru\r
+     http://anso.virtualave.net\r
+\r
+This library is derived from Henry Spencer sources.\r
+I translated the C sources into Object Pascal,\r
+implemented object wrapper and some new features.\r
+Many features suggested or partially implemented\r
+by TRegExpr's users (see Gratitude below).\r
+\r
+\r
+---------------------------------------------------------------\r
+     Legal issues\r
+---------------------------------------------------------------\r
+ Copyright (c) 1999-00 by Andrey V. Sorokin <anso@mail.ru>\r
+\r
+ This software is provided as it is, without any kind of warranty\r
+ given. Use it at your own risk.\r
+\r
+ You may use this software in any kind of development, including\r
+ comercial, redistribute, and modify it freely, under the\r
+ following restrictions :\r
+ 1. The origin of this software may not be mispresented, you must\r
+    not claim that you wrote the original software. If you use\r
+    this software in any kind of product, it would be appreciated\r
+    that there in a information box, or in the documentation would\r
+    be an acknowledgmnent like this\r
+           Partial Copyright (c) 2000 by Andrey V. Sorokin\r
+ 2. You may not have any income from distributing this source\r
+    to other developers. When you use this product in a comercial\r
+    package, the source may not be charged seperatly.\r
+\r
+\r
+---------------------------------------------------------------\r
+     Legal issues for the original C sources:\r
+---------------------------------------------------------------\r
+ *  Copyright (c) 1986 by University of Toronto.\r
+ *  Written by Henry Spencer.  Not derived from licensed software.\r
+ *\r
+ *  Permission is granted to anyone to use this software for any\r
+ *  purpose on any computer system, and to redistribute it freely,\r
+ *  subject to the following restrictions:\r
+ *  1. The author is not responsible for the consequences of use of\r
+ *      this software, no matter how awful, even if they arise\r
+ *      from defects in it.\r
+ *  2. The origin of this software must not be misrepresented, either\r
+ *      by explicit claim or by omission.\r
+ *  3. Altered versions must be plainly marked as such, and must not\r
+ *      be misrepresented as being the original software.\r
+\r
+\r
+---------------------------------------------------------------\r
+     Gratitudes\r
+---------------------------------------------------------------\r
+  Guido Muehlwitz\r
+    found and fixed ugly bug in big string processing\r
+  Stephan Klimek\r
+    testing in CPPB and suggesting/implementing many features\r
+  Steve Mudford\r
+    implemented Offset parameter\r
+  Martin Baur\r
+    usefull suggetions\r
+  Yury Finkel\r
+    Implemented UniCode support, found and fixed some bugs\r
+  Ralf Junker\r
+    Implemented some features, many optimization suggestions\r
+\r
+  And many others - for big work of bug hunting !\r
+\r
+I am still looking for person who can help me to translate\r
+this documentation into other languages (especially German)\r
+\r
+\r
+---------------------------------------------------------------\r
+     To do\r
+---------------------------------------------------------------\r
+\r
+-=- VCL-version of TRegExpr - for dummies ;) and TRegExprEdit\r
+(replacement for TMaskEdit).\r
+Actually, I am writing non-VCL aplications (with web-based\r
+interfaces), so I don't need VCL's TRegExpr for myself.\r
+Will it be really usefull ?\r
+\r
+-=- full functionallity of braces {}\r
+\r
+-=- working with pascal-style string.\r
+Now pascal-strings converted into PChar, so\r
+you can't find r.e. in strings with #0 -chars.\r
+(suggested by Pavel O).\r
+\r
+-=- non-greedy style (suggested by Martin Baur)\r
+\r
+-=- put precalculated lengths into EXACTLY[CI] !\r
+\r
+-=- fInputString as string (suggested by Ralf Junker)\r
+\r
+-=- Add regstart optimization for case-insensitive mode ?\r
+ Or complitely remove because FirstCharSet is faster ?\r
+\r
+-=- "Russian Ranges" --> National ranges (use property WordChars ?\r
+for ordering letters in ranges by its order in WirdsChars if modifier /r is On)\r
+\r
+-=- FirstCharSet as array [#0 .. #255] of REChar ?\r
+(2x faster then set of REChar)\r
+\r
+-=- p-code optimization (remove BRANCH-to-EEND, COMMENT, BACK(?)\r
+    merge EXACTLY etc).\r
+\r
+I need your suggestions !\r
+What are more importent in this list ?\r
+Did I forget anything ?\r
+\r
+\r
+---------------------------------------------------------------\r
+     History\r
+---------------------------------------------------------------\r
+Legend:\r
+ (+) added feature\r
+ (-) fixed bug\r
+ (^) upgraded implementation\r
+\r
+ v. 0.938 2000.07.23\r
+ -=- (^) Exeptions now jump to appropriate source line, not\r
+     to Error procedure (I am not quite sure this is safe for\r
+     all compiler versions. You can turn it off - remove\r
+     reRealExceptionAddr definition below).\r
+ -=- (^) Forgotten BSUBEXP[CI] in FillFirstCharSet caused\r
+     exeption 'memory corruption' in case if back reference can\r
+     be first op, like this: (a)*\1 (first subexpression can be\r
+     skipped and we'll start matching with back reference..).\r
+\r
+ v. 0.937 2000.06.12\r
+ -=- (-) Bug in optimization engine (since v.0.934). In some cases\r
+     TRegExpr didn't catch right strings.\r
+     Thanks to Matthias Fichtner\r
+\r
+ v. 0.936 2000.04.22\r
+ -=- (+) Back references, like <font size=(['"]?)(\d+)\1>, see\r
+     manual for details\r
+ -=- (+) Wide hex char support, like '\x{263a}'\r
+\r
+ v. 0.935 2000.04.19 (by Yury Finkel)\r
+ -=- (-) fInvertCase now isn't readonly ;)\r
+ -=- (-) UniCode mode compiling errors\r
+\r
+ v. 0.934 2000.04.17\r
+ -=- (^) New ranges implementation (range matching now is very fast\r
+      - uses one(!) CPU instruction)\r
+ -=- (^) Internal p-code structure converted into 32-bits - works\r
+      faster and now there is no 64K limit for compiled r.e.\r
+ -=- (^) '{m,n}' now use 32-bits arguments (up to 2147483646) - specially\r
+      for Dmitry Veprintsev ;)\r
+ -=- (^) Ranges now support metachars: [\n-\x0D] -> #10,#11,#12,#13;\r
+     Changed '-' processing, now it's like in Perl:\r
+     [\d-t] -> '0'..'9','-','t'; []-a] -> ']'..'a'\r
+ -=- (-) Bug with \t and etc macro (they worked only in ranges)\r
+     Thanks to Yury Finkel\r
+ -=- (^) Added new preprocessing optimization (see FirstCharSet).\r
+      Incredible fast (!). But be carefull it isn's properly tested.\r
+      You can switch it Off - remove UseFirstCharSet definition.\r
+ -=- (^) Many other speed optimizations\r
+ -=- (-) Case-insensitive mode now support system-defined national\r
+      charset (due to bug in v.0.90 .. 0.926 supported only english one)\r
+ -=- (^) Case-insensitive mode implemented with InvertCase (param &\r
+      result of REChar type) - works 10 .. 100 times faster.\r
+ -=- (^) Match and ExecNext interfaces optimized, added IsProgrammOk\r
+      by Ralf Junker\r
+ -=- (^) Increased NSUBEXP (now 15) and fixed code for this, now you\r
+      can simply increase NSUBEXP constant by yourself.\r
+      Suggested by Alexander V. Akimov.\r
+ -=- (^+) Substitute adapted for NSUBEXP > 10 and significant (!)\r
+      optimized, improved error checking.\r
+      ATTENTION! Read new Substitute description - syntax was changed !\r
+ -=- (+) SpaceChars & WordChars property - now you may change chars\r
+      treated as \s & \w. By defauled assigned RegExprSpaceChars/WordChars\r
+ -=- (+) Now \s and \w supported in ranges\r
+ -=- (-) Infinite loop if end of range=#$FF\r
+      Thanks to Andrey Kolegov\r
+ -=- (+) Function QuoteRegExprMetaChars (see description)\r
+ -=- (+) UniCode support - sorry, works VERY slow (remove '.' from\r
+     {.$DEFINE UniCode} after this comment for unicode version).\r
+     Implemented by Yury Finkel\r
+\r
+ v. 0.926 2000.02.26\r
+ -=- (-) Old bug derived from H.Spencer sources - SPSTART was\r
+     set for '?' and '*' instead of '*', '{m,n}' and '+'.\r
+ -=- (-^) Now {m,n} works like Perl's one - error occures only\r
+     if m > n or n > BracesMax (BracesMax = 255 in this version).\r
+     In other cases (no m or nondigit symbols in m or n values,\r
+     or no '}') symbol '{' will be compiled as literal.\r
+     Note: so, you must include m value (use {0,n} instead of {,n}).\r
+     Note: {m,} will be compiled as {m,BracesMax}.\r
+ -=- (-^) CaseInsensitive mode now support ranges\r
+     '(?i)[a]' == '[aA]'\r
+ -=- (^) Roman-number template in TestRExp ;)\r
+ -=- (+^) Beta version of complex-braces - like ((abc){1,2}|d){3}\r
+     By default its turned off. If you want take part in beta-testing,\r
+     please, remove '.' from {.$DEFINE ComplexBraces} below this comments.\r
+ -=- (-^) Removed \b metachar (in Perl it isn't BS as in my implementation,\r
+     but word bound)\r
+ -=- (+) Add /s modifier. Bu I am not sure that it's ok for Windows.\r
+     I implemented it as [^\n] for '.' metachar in non-/s mode.\r
+     But lines separated by \n\r in windows. I need you suggestions !\r
+ -=- (^) Sorry, but I had to rename Modifiers to ModifierStr\r
+     (ModifierS uses for /s now)\r
+\r
+ v. 0.91 2000.02.02\r
+ -=- (^) some changes in documentation and demo-project.\r
+\r
+ v. 0.90 2000.01.31\r
+ -=- (+) implemented braces repetitions {min,max}.\r
+     Sorry - only simple cases now - like '\d{2,3}'\r
+     or '[a-z1-9]{,7}', but not (abc){2,3} ..\r
+     I still too short in time.\r
+     Wait for future versions of TRegExpr or\r
+     implement it by youself and share with me ;)\r
+ -=- (+) implemented case-insensitive modifier and way\r
+     to work with other modifiers - see properties\r
+     Modifiers, Modifier, ModifierI\r
+     and (?ismx-ismx) Perl extension.\r
+     You may use global variables RegExpr* for assigning\r
+     default modifier values.\r
+ -=- (+) property ExtSyntaxEnabled changed to 'r'-modifier\r
+     (russian extensions - see documentation)\r
+ -=- (+) implemented (?#comment) Perl extension - very hard\r
+     and usefull work ;)\r
+ -=- (^) property MatchCount renamed to SubExprMatchCount.\r
+     Sorry for any inconvenients, but it's because new\r
+     version works slightly different and if you used\r
+     MatchCount in your programms you have to rethink\r
+     it ! (see comments to this property)\r
+ -=- (+) add InputString property - stores input string\r
+     from last Exec call. You may directly assign values\r
+     to this property for using in ExecPos method.\r
+ -=- (+) add ExecPos method - for working with assigned\r
+     to InputString property. You may use it like this\r
+        InputString := AString;\r
+        ExecPos;\r
+     or this\r
+        InputString := AString;\r
+        ExecPos (AOffset);\r
+     Note: ExecPos without parameter works only in\r
+     Delphi 4 or higher.\r
+ -=- (+) add ExecNext method - simple and fast (!) way to finding\r
+     multiple occurences of r.e. in big input string.\r
+ -=- (^) Offset parameter removed from Exec method, if you\r
+     used it in your programs, please replace all\r
+        Exec (AString, AOffset)\r
+     with combination\r
+        InputString := AString; ExecPos (AOffset)\r
+     Sorry for any inconvenients, but old design\r
+     (see v.0.81) was too ugly :(\r
+     In addition, multiple Exec calls with same input\r
+     string produce fool overhead because each Exec\r
+     reallocate input string buffer.\r
+ -=- (^) optimized implementation of Substitution,\r
+     Replace and Split methods\r
+ -=- (-) fixed minor bug - if r.e. compilation raise error\r
+     during second pass (!!! I think it's impossible\r
+     in really practice), TRegExpr stayed in 'compiled'\r
+     state.\r
+ -=- (-) fixed bug - Dump method didn't check program existance\r
+     and raised 'access violation' if previouse Exec\r
+     was finished with error.\r
+ -=- (+) changed error handling (see functions Error, ErrorMsg,\r
+     LastError, property CompilerErrorPos, type ERegExpr).\r
+ -=- (-^) TRegExpr.Replace, Split and ExecNext made a infinite\r
+     loop in case of r.e. match empty-string.\r
+     Now ExecNext moves by MatchLen if MatchLen <> 0\r
+     and by +1 if MatchLen = 0\r
+     Thanks to Jon Smith and George Tasker for bugreports.\r
+ -=- (-) While playing with null-matchs I discovered, that\r
+     null-match at tail of input string is never found.\r
+     Well, I fixed this, but I am not sure this is safe\r
+     (MatchPos[0]=length(AInputString)+1, MatchLen = 0).\r
+     Any suggetions are very appreciated.\r
+ -=- (^) Demo project and documentation was upgraded\r
+ -=- (^) Documentation and this version was published on my home page\r
+     http://anso.da.ru\r
+\r
+\r
+ v. 0.81 1999.12.25 // Merry Christmas ! :)\r
+ -=- added \s (AnySpace) and \S (NotSpace) meta-symbols\r
+     - implemented by Stephan Klimek with minor fixes by AVS\r
+ -=- added \f, \a and \b chars (translates into FF, BEL, BS)\r
+ -=- removed meta-symbols 'ö' & 'Ö' - sorry for any inconvenients\r
+ -=- added Match property (== copy (InputStr, MatchPos [Idx], MatchLen [Idx]))\r
+ -=- added extra parameter Offset to Exec method\r
+     (thanks to Steve Mudford)\r
+\r
+ v. 0.7 1999.08.22\r
+ -=- fixed bug - in some cases the r.e. [^...]\r
+     incorrectly processed (as any symbol)\r
+     (thanks to Jan Korycan)\r
+ -=- Some changes and improvements in TestRExp.dpr\r
+\r
+ v. 0.6 1999.08.13 (Friday 13 !)\r
+ -=- changed header of TRegExpr.Substitute\r
+ -=- added Split, Replace & appropriate\r
+     global wrappers (thanks to Stephan Klimek for suggetions)\r
+\r
+ v. 0.5 1999.08.12\r
+ -=- TRegExpr.Substitute routine added\r
+ -=- Some changes and improvements in TestRExp.dpr\r
+ -=- Fixed bug in english version of documentation\r
+     (Thanks to Jon Buckheit)\r
+\r
+ v. 0.4 1999.07.20\r
+ -=- Fixed bug with parsing of strings longer then 255 bytes\r
+     (thanks to Guido Muehlwitz)\r
+ -=- Fixed bug in RegMatch - mathes only first occurence of r.e.\r
+     (thanks to Stephan Klimek)\r
+\r
+ v. 0.3 1999.06.13\r
+ -=- ExecRegExpr function\r
+\r
+ v. 0.2 1999.06.10\r
+ -=- packed into object-pascal class\r
+ -=- code slightly rewriten for pascal\r
+ -=- now macro correct proceeded in ranges\r
+ -=- r.e.ranges syntax extended for russian letters ranges:\r
+     à-ÿ - replaced with all small russian letters (Win1251)\r
+     À-ß - replaced with all capital russian letters (Win1251)\r
+     à-ß - replaced with all russian letters (Win1251)\r
+ -=- added macro '\d' (opcode ANYDIGIT) - match any digit\r
+ -=- added macro '\D' (opcode NOTDIGIT) - match not digit\r
+ -=- added macro '\w' (opcode ANYLETTER) - match any english letter or '_'\r
+ -=- added macro '\W' (opcode NOTLETTER) - match not english letter or '_'\r
+ (all r.e.syntax extensions may be turned off by flag ExtSyntax)\r
+\r
+ v. 0.1 1999.06.09\r
+ first version, with bugs, without help => must die :(\r
+\r
+*)\r
+\r
+{$DEFINE DebugRegExpr} // define for dump/trace enabling\r
+\r
+{$DEFINE reRealExceptionAddr} // if defined then exceptions will\r
+// jump to appropriate source line, not to Error procedure\r
+\r
+{.$DEFINE ComplexBraces} // define for beta-version of braces\r
+// (in stable version it works only for simple cases)\r
+\r
+{.$DEFINE UniCode} // define for Unicode support\r
+\r
+{$IFNDEF UniCode} // optionts applicable only for non-UniCode\r
+ {$DEFINE UseSetOfChar} // Significant optimization by using set of char\r
+{$ENDIF}\r
+\r
+{$IFDEF UseSetOfChar}\r
+ {$DEFINE UseFirstCharSet} // Significant optimization inm some cases\r
+{$ENDIF}\r
+\r
+interface\r
+\r
+// Determine version (for using 'params by default')\r
+{$IFNDEF VER80}         { Delphi 1.0}\r
+ {$IFNDEF VER90}        { Delphi 2.0}\r
+  {$IFNDEF VER93}       { C++Builder 1.0}\r
+    {$IFNDEF VER100}    { Borland Delphi 3.0}\r
+        {$DEFINE D4_}   { Delphi 4.0 or higher}\r
+    {$ENDIF}\r
+  {$ENDIF}\r
+ {$ENDIF}\r
+{$ENDIF}\r
+{.$IFNDEF VER110}  { Borland C++Builder 3.0}\r
+{.$IFNDEF VER120}  {Borland Delphi 4.0}\r
+\r
+\r
+uses\r
+ Classes, // TStrings in Split method\r
+ SysUtils; // Exception\r
+\r
+\r
+type\r
+ {$IFDEF UniCode}\r
+ PRegExprChar = PWideChar;\r
+ RegExprString = WideString;\r
+ REChar = WideChar;\r
+ {$ELSE}\r
+ PRegExprChar = PChar;\r
+ RegExprString = string;\r
+ REChar = Char;\r
+ {$ENDIF}\r
+ TREOp = REChar; // internal p-code type //###0.933\r
+ PREOp = ^TREOp;\r
+ TRENextOff = integer; // internal Next "pointer" (offset to current p-code) //###0.933\r
+ PRENextOff = ^TRENextOff; // used for extracting Next "pointers" from compiled r.e. //###0.933\r
+ TREBracesArg = integer; // type of {m,n} arguments\r
+ PREBracesArg = ^TREBracesArg;\r
+\r
+const\r
+ REOpSz = SizeOf (TREOp) div SizeOf (REChar); // size of p-code in RegExprString units\r
+ RENextOffSz = SizeOf (TRENextOff) div SizeOf (REChar); // size of Next 'pointer' -"-\r
+ REBracesArgSz = SizeOf (TREBracesArg) div SizeOf (REChar); // size of BRACES arguments -"-\r
+\r
+type\r
+ TRegExprInvertCaseFunction = function (const Ch : REChar) : REChar\r
+                               of object;\r
+\r
+const\r
+  RegExprModifierI : boolean = False;\r
+  // default value for ModifierI\r
+\r
+  RegExprModifierR : boolean = True;\r
+  // default value for ModifierR\r
+\r
+  RegExprModifierS : boolean = True;\r
+  // default value for ModifierS\r
+\r
+  RegExprSpaceChars : RegExprString = // chars for /s & /S\r
+  ' '#$9#$A#$D#$C; // default for SpaceChars property\r
+\r
+  RegExprWordChars : RegExprString = // chars for /w & /W\r
+  // Ampliado por Leandro Lucarella (11/00)\r
+    'abcdefghijklmnopqrstuvwxyzáéíóúýäëïöüÿàèìòùâêîôûñç'\r
+  + 'ABCDEFGHIJKLMNOPQRSTUVWXYZÁÉÍÓÚÝÄËÏÖÜ\9fÀÈÌÒÙÂÊÎÔÛÑÇ_'; // default for WordChars property\r
+\r
+\r
+const\r
+ NSUBEXP = 15; // max number of subexpression //###0.929\r
+ // Be carefull - don't use values which overflow CLOSE opcode\r
+ // (in this case you'll get compiler erorr).\r
+ // Big NSUBEXP will cause more slow work and more stack required\r
+ MaxBracesArg = $7FFFFFFF - 1; // max value for {n,m} arguments //###0.933\r
+ {$IFDEF ComplexBraces}\r
+ LoopStackMax = 10; // max depth of loops stack //###0.925\r
+ {$ENDIF}\r
+ TinySetLen = 3;\r
+ // if range includes more then TinySetLen chars, //###0.934\r
+ // then use full (32 bytes) ANYOFFULL instead of ANYOF[BUT]TINYSET\r
+ // !!! Attension ! If you change TinySetLen, you must\r
+ // change code marked as "//!!!TinySet"\r
+\r
+\r
+type\r
+\r
+{$IFDEF UseSetOfChar}\r
+ PSetOfREChar = ^TSetOfREChar;\r
+ TSetOfREChar = set of REChar;\r
+{$ENDIF}\r
+\r
+ {** Clase auxiliar que implementa expresiones Regulares. Se ultiliza para validar los campos de texto}\r
+ TRegExpr = class\r
+   private\r
+    startp : array [0 .. NSUBEXP - 1] of PRegExprChar; // founded expr starting points\r
+    endp : array [0 .. NSUBEXP - 1] of PRegExprChar; // founded expr end points\r
+\r
+    {$IFDEF ComplexBraces}\r
+    LoopStack : array [1 .. LoopStackMax] of integer; // state before entering loop\r
+    LoopStackIdx : integer; // 0 - out of all loops\r
+    {$ENDIF}\r
+\r
+    // The "internal use only" fields to pass info from compile\r
+    // to execute that permits the execute phase to run lots faster on\r
+    // simple cases.\r
+    regstart : REChar; // char that must begin a match; '\0' if none obvious\r
+    reganch : REChar; // is the match anchored (at beginning-of-line only)?\r
+    regmust : PRegExprChar; // string (pointer into program) that match must include, or nil\r
+    regmlen : integer; // length of regmust string\r
+    // Regstart and reganch permit very fast decisions on suitable starting points\r
+    // for a match, cutting down the work a lot.  Regmust permits fast rejection\r
+    // of lines that cannot possibly match.  The regmust tests are costly enough\r
+    // that regcomp() supplies a regmust only if the r.e. contains something\r
+    // potentially expensive (at present, the only such thing detected is * or +\r
+    // at the start of the r.e., which can involve a lot of backup).  Regmlen is\r
+    // supplied because the test in regexec() needs it and regcomp() is computing\r
+    // it anyway.\r
+    {$IFDEF UseFirstCharSet} //###0.929\r
+    FirstCharSet : TSetOfREChar;\r
+    {$ENDIF}\r
+\r
+    // work variables for Exec's routins - save stack in recursion}\r
+    reginput : PRegExprChar; // String-input pointer.\r
+    fInputStart : PRegExprChar; // Pointer to first char of input string.\r
+    fInputEnd : PRegExprChar; // Pointer to char AFTER last char of input string\r
+\r
+    // work variables for compiler's routines\r
+    regparse : PRegExprChar;  // Input-scan pointer.\r
+    regnpar : integer; // count.\r
+    regdummy : char;\r
+    regcode : PRegExprChar;   // Code-emit pointer; @regdummy = don't.\r
+    regsize : integer; // Code size.\r
+\r
+    regexpbeg : PRegExprChar; // only for error handling. Contains\r
+    // pointer to beginning of r.e. while compiling\r
+    fExprIsCompiled : boolean; // true if r.e. successfully compiled\r
+\r
+    // programm is essentially a linear encoding\r
+    // of a nondeterministic finite-state machine (aka syntax charts or\r
+    // "railroad normal form" in parsing technology).  Each node is an opcode\r
+    // plus a "next" pointer, possibly plus an operand.  "Next" pointers of\r
+    // all nodes except BRANCH implement concatenation; a "next" pointer with\r
+    // a BRANCH on both ends of it is connecting two alternatives.  (Here we\r
+    // have one of the subtle syntax dependencies:  an individual BRANCH (as\r
+    // opposed to a collection of them) is never concatenated with anything\r
+    // because of operator precedence.)  The operand of some types of node is\r
+    // a literal string; for others, it is a node leading into a sub-FSM.  In\r
+    // particular, the operand of a BRANCH node is the first node of the branch.\r
+    // (NB this is *not* a tree structure:  the tail of the branch connects\r
+    // to the thing following the set of BRANCHes.)  The opcodes are:\r
+    programm : PRegExprChar; // Unwarranted chumminess with compiler.\r
+\r
+    fExpression : PRegExprChar; // source of compiled r.e.\r
+    fInputString : PRegExprChar; // input string\r
+\r
+    fLastError : integer; // see Error, LastError\r
+\r
+    fModifiers : integer; // modifiers\r
+    fCompModifiers : integer; // compiler's copy of modifiers\r
+    fProgModifiers : integer; // values modifiers from last programm compilation\r
+\r
+    fSpaceChars : RegExprString; //###0.927\r
+    fWordChars : RegExprString; //###0.929\r
+    fInvertCase : TRegExprInvertCaseFunction; //###0.927\r
+\r
+    function IsProgrammOk : boolean; //###0.929\r
+\r
+    procedure CheckCompModifiers;\r
+    // if modifiers was changed after programm compilation - recompile it !\r
+\r
+    function GetExpression : RegExprString;\r
+    procedure SetExpression (const s : RegExprString);\r
+\r
+    function GetModifierStr : RegExprString;\r
+    function SetModifiersInt (const AModifiers : RegExprString; var AModifiersInt : integer) : boolean;\r
+    procedure SetModifierStr (const AModifiers : RegExprString);\r
+\r
+    function GetModifier (AIndex : integer) : boolean;\r
+    procedure SetModifier (AIndex : integer; ASet : boolean);\r
+\r
+    procedure Error (AErrorID : integer); virtual; // error handler.\r
+    // Default handler raise exception ERegExpr with\r
+    // Message = ErrorMsg (AErrorID), ErrorCode = AErrorID\r
+    // and CompilerErrorPos = value of property CompilerErrorPos.\r
+\r
+\r
+    {==================== Compiler section ===================}\r
+    function CompileRegExpr (exp : PRegExprChar) : boolean;\r
+    // compile a regular expression into internal code\r
+\r
+    procedure Tail (p : PRegExprChar; val : PRegExprChar);\r
+    // set the next-pointer at the end of a node chain\r
+\r
+    procedure OpTail (p : PRegExprChar; val : PRegExprChar);\r
+    // regoptail - regtail on operand of first argument; nop if operandless\r
+\r
+    function EmitNode (op : TREOp) : PRegExprChar;\r
+    // regnode - emit a node, return location\r
+\r
+    procedure EmitC (b : REChar);\r
+    // emit (if appropriate) a byte of code\r
+\r
+    procedure InsertOperator (op : TREOp; opnd : PRegExprChar; sz : integer); //###0.90\r
+    // insert an operator in front of already-emitted operand\r
+    // Means relocating the operand.\r
+\r
+    function ParseReg (paren : integer; var flagp : integer) : PRegExprChar;\r
+    // regular expression, i.e. main body or parenthesized thing\r
+\r
+    function ParseBranch (var flagp : integer) : PRegExprChar;\r
+    // one alternative of an | operator\r
+\r
+    function ParsePiece (var flagp : integer) : PRegExprChar;\r
+    // something followed by possible [*+?]\r
+\r
+    function ParseAtom (var flagp : integer) : PRegExprChar;\r
+    // the lowest level\r
+\r
+    function GetCompilerErrorPos : integer;\r
+    // current pos in r.e. - for error hanling\r
+\r
+    {$IFDEF UseFirstCharSet} //###0.929\r
+    procedure FillFirstCharSet (prog : PRegExprChar);\r
+    {$ENDIF}\r
+\r
+    {===================== Mathing section ===================}\r
+    function regrepeat (p : PRegExprChar; AMax : integer) : integer;\r
+    // repeatedly match something simple, report how many\r
+\r
+    function regnext (p : PRegExprChar) : PRegExprChar;\r
+    // dig the "next" pointer out of a node\r
+\r
+    function MatchPrim (prog : PRegExprChar) : boolean;\r
+    // recursively matching routine\r
+\r
+    function RegMatch (str : PRegExprChar) : boolean;\r
+    // try match at specific point, uses MatchPrim for real work\r
+\r
+    function ExecPrim (AOffset: integer) : boolean;\r
+    // Exec for stored InputString\r
+\r
+    {$IFDEF DebugRegExpr}\r
+    function DumpOp (op : REChar) : RegExprString;\r
+    {$ENDIF}\r
+\r
+    function GetSubExprMatchCount : integer;\r
+    function GetMatchPos (Idx : integer) : integer;\r
+    function GetMatchLen (Idx : integer) : integer;\r
+    function GetMatch (Idx : integer) : RegExprString;\r
+\r
+    function GetInputString : RegExprString;\r
+    procedure SetInputString (const AInputString : RegExprString);\r
+\r
+    {$IFNDEF UseSetOfChar}\r
+    function StrScanCI (s : PRegExprChar; ch : REChar) : PRegExprChar; //###0.928\r
+    {$ENDIF}\r
+\r
+   public\r
+    constructor Create;\r
+    destructor Destroy; override;\r
+\r
+    property Expression : RegExprString read GetExpression write SetExpression;\r
+    // regular expression\r
+    // When you assign r.e. to this property, TRegExpr will automatically\r
+    // compile it and store in internal structures.\r
+    // In case of compilation error, Error method will be called\r
+    // (by default Error method raises exception ERegExpr - see below)\r
+\r
+    property ModifierStr : RegExprString read GetModifierStr write SetModifierStr;\r
+    // Set/get default values of r.e.syntax modifiers. Modifiers in\r
+    // r.e. (?ismx-ismx) will replace this default values.\r
+    // If you try to set unsupported modifier, Error will be called\r
+    // (by defaul Error raises exception ERegExpr).\r
+\r
+    property ModifierI : boolean index 1 read GetModifier write SetModifier;\r
+    // Modifier /i - caseinsensitive, false by default\r
+\r
+    property ModifierR : boolean index 2 read GetModifier write SetModifier;\r
+    // Modifier /r - use r.e.syntax extended for russian, true by default\r
+    // (was property ExtSyntaxEnabled in previous versions)\r
+    // If true, then à-ÿ  additional include russian letter '¸',\r
+    // À-ß  additional include '¨', and à-ß include all russian symbols.\r
+    // You have to turn it off if it may interfere with you national alphabet.\r
+\r
+    property ModifierS : boolean index 3 read GetModifier write SetModifier;\r
+    // Modifier /s - '.' works as any char (else as [^\n]),\r
+    // true by default\r
+\r
+    function Exec (const AInputString : RegExprString) : boolean;\r
+    // match a programm against a string AInputString\r
+    // !!! Exec store AInputString into InputString property\r
+\r
+    function ExecNext : boolean;\r
+    // find next match:\r
+    //    Exec (AString); ExecNext;\r
+    // works same as\r
+    //    Exec (AString);\r
+    //    if MatchLen [0] = 0 then ExecPos (MatchPos [0] + 1)\r
+    //     else ExecPos (MatchPos [0] + MatchLen [0]);\r
+    // but it's more simpler !\r
+\r
+    function ExecPos (AOffset: integer {$IFDEF D4_}= 1{$ENDIF}) : boolean;\r
+    // find match for InputString starting from AOffset position\r
+    // (AOffset=1 - first char of InputString)\r
+\r
+    property InputString : RegExprString read GetInputString write SetInputString;\r
+    // returns current input string (from last Exec call or last assign\r
+    // to this property).\r
+    // Any assignment to this property clear Match* properties !\r
+\r
+    function Substitute (const ATemplate : RegExprString) : RegExprString;\r
+    // Returns ATemplate with '$&' or '$0' replaced by whole r.e.\r
+    // occurence and '$n' replaced by occurence of subexpression #n.\r
+    // Since v.0.929 '$' used instead of '\' (for future extensions\r
+    // and for more Perl-compatibility) and accept more then one digit.\r
+    // If you want place into template raw '$' or '\', use prefix '\'\r
+    // Example: '1\$ is $2\\rub\\' -> '1$ is <Match[2]>\rub\'\r
+    // If you want to place raw digit after '$n' you must delimit\r
+    // n with curly braces '{}'.\r
+    // Example: 'a$12bc' -> 'a<Match[12]>bc'\r
+    // 'a${1}2bc' -> 'a<Match[1]>2bc'.\r
+\r
+    procedure Split (AInputStr : RegExprString; APieces : TStrings);\r
+    // Split AInputStr into APieces by r.e. occurencies\r
+\r
+    function Replace (AInputStr : RegExprString; const AReplaceStr : RegExprString) : RegExprString;\r
+    // Returns AInputStr with r.e. occurencies replaced by AReplaceStr\r
+\r
+    property SubExprMatchCount : integer read GetSubExprMatchCount;\r
+    // Number of subexpressions has been found in last Exec* call.\r
+    // If there are no subexpr. but whole expr was found (Exec* returned True),\r
+    // then SubExprMatchCount=0, if no subexpressions nor whole\r
+    // r.e. found (Exec* returned false) then SubExprMatchCount=-1.\r
+    // Note, that some subexpr. may be not found and for such\r
+    // subexpr. MathPos=MatchLen=-1 and Match=''.\r
+    // For example: Expression := '(1)?2(3)?';\r
+    //  Exec ('123'): SubExprMatchCount=2, Match[0]='123', [1]='1', [2]='3'\r
+    //  Exec ('12'): SubExprMatchCount=1, Match[0]='23', [1]='1'\r
+    //  Exec ('23'): SubExprMatchCount=2, Match[0]='23', [1]='', [2]='3'\r
+    //  Exec ('2'): SubExprMatchCount=0, Match[0]='2'\r
+    //  Exec ('7') - return False: SubExprMatchCount=-1\r
+\r
+    property MatchPos [Idx : integer] : integer read GetMatchPos;\r
+    // pos of entrance subexpr. #Idx into tested in last Exec*\r
+    // string. First subexpr. have Idx=1, last - MatchCount,\r
+    // whole r.e. have Idx=0.\r
+    // Returns -1 if in r.e. no such subexpr. or this subexpr.\r
+    // not found in input string.\r
+\r
+    property MatchLen [Idx : integer] : integer read GetMatchLen;\r
+    // len of entrance subexpr. #Idx r.e. into tested in last Exec*\r
+    // string. First subexpr. have Idx=1, last - MatchCount,\r
+    // whole r.e. have Idx=0.\r
+    // Returns -1 if in r.e. no such subexpr. or this subexpr.\r
+    // not found in input string.\r
+    // Remember - MatchLen may be 0 (if r.e. match empty string) !\r
+\r
+    property Match [Idx : integer] : RegExprString read GetMatch;\r
+    // == copy (InputString, MatchPos [Idx], MatchLen [Idx])\r
+    // Returns '' if in r.e. no such subexpr. or this subexpr.\r
+    // not found in input string.\r
+\r
+    function LastError : integer;\r
+    // Returns ID of last error, 0 if no errors (unusable if\r
+    // Error method raises exception) and clear internal status\r
+    // into 0 (no errors).\r
+\r
+    function ErrorMsg (AErrorID : integer) : RegExprString; virtual;\r
+    // Returns Error message for error with ID = AErrorID.\r
+\r
+    property CompilerErrorPos : integer read GetCompilerErrorPos;\r
+    // Returns pos in r.e. there compiler stopped.\r
+    // Usefull for error diagnostics\r
+\r
+    property SpaceChars : RegExprString read fSpaceChars write fSpaceChars; //###0.927\r
+    // Contains chars, treated as /s (initially filled with RegExprSpaceChars\r
+    // global constant)\r
+\r
+    property WordChars : RegExprString read fWordChars write fWordChars; //###0.929\r
+    // Contains chars, treated as /w (initially filled with RegExprWordChars\r
+    // global constant)\r
+\r
+    class function InvertCaseFunction  (const Ch : REChar) : REChar;\r
+    // Converts Ch into upper case if it in lower case or in lower\r
+    // if it in upper (uses current system local setings)\r
+\r
+    property InvertCase : TRegExprInvertCaseFunction read fInvertCase write fInvertCase; //##0.935\r
+    // Set this property if you want to override case-insensitive functionality.\r
+    // Create set it to RegExprInvertCaseFunction (InvertCaseFunction by default)\r
+\r
+    {$IFDEF DebugRegExpr}\r
+    function Dump : RegExprString;\r
+    // dump a compiled regexp in vaguely comprehensible form\r
+    {$ENDIF}\r
+  end;\r
+\r
+ {** Excepción de expresiones regulares} \r
+ ERegExpr = class (Exception)\r
+   public\r
+    ErrorCode : integer;\r
+    CompilerErrorPos : integer;\r
+  end;\r
+\r
+const\r
+  RegExprInvertCaseFunction : TRegExprInvertCaseFunction = TRegExpr.InvertCaseFunction;\r
+  // defaul for InvertCase property\r
+\r
+{** true if string AInputString match regular expression ARegExpr\r
+    ! will raise exeption if syntax errors in ARegExpr}\r
+function ExecRegExpr (const ARegExpr, AInputStr : RegExprString) : boolean;\r
+\r
+{** Split AInputStr into APieces by r.e. ARegExpr occurencies}\r
+procedure SplitRegExpr (const ARegExpr, AInputStr : RegExprString; APieces : TStrings);\r
+\r
+{** Returns AInputStr with r.e. occurencies replaced by AReplaceStr}\r
+function ReplaceRegExpr (const ARegExpr, AInputStr, AReplaceStr : RegExprString) : RegExprString;\r
+\r
+{** Replace all metachars with its safe representation,\r
+    for example 'abc$cd.(' converts into 'abc\$cd\.\('\r
+    This function usefull for r.e. autogeneration from\r
+    user input}\r
+function QuoteRegExprMetaChars (const AStr : RegExprString) : RegExprString;\r
+\r
+implementation\r
+\r
+uses\r
+ Windows; // CharUpper/Lower\r
+\r
+const\r
+ MaskModI = 1; // modifier /i bit in fModifiers\r
+ MaskModR = 2; // -"- /r\r
+ MaskModS = 4; // -"- /s\r
+\r
+{=============================================================}\r
+{=================== WideString functions ====================}\r
+{=============================================================}\r
+\r
+{$IFDEF UniCode}\r
+\r
+function StrPCopy (Dest: PRegExprChar; const Source: RegExprString): PRegExprChar;\r
+ var\r
+  i, Len : Integer;\r
+ begin\r
+  Len := length (Source); //###0.932\r
+  for i := 1 to Len do\r
+   Dest [i - 1] := Source [i];\r
+  Dest [Len] := #0;\r
+  Result := Dest;\r
+ end; { of function StrPCopy\r
+--------------------------------------------------------------}\r
+\r
+function StrLCopy (Dest, Source: PRegExprChar; MaxLen: Cardinal): PRegExprChar;\r
+ var i: Integer;\r
+ begin\r
+  for i := 0 to MaxLen - 1 do\r
+   Dest [i] := Source [i];\r
+  Result := Dest;\r
+ end; { of function StrLCopy\r
+--------------------------------------------------------------}\r
+\r
+function StrLen (Str: PRegExprChar): Cardinal;\r
+ begin\r
+  Result:=0;\r
+  while Str [result] <> #0\r
+   do Inc (Result);\r
+ end; { of function StrLen\r
+--------------------------------------------------------------}\r
+\r
+function StrPos (Str1, Str2: PRegExprChar): PRegExprChar;\r
+ var n: Integer;\r
+ begin\r
+  Result := nil;\r
+  n := Pos (RegExprString (Str2), RegExprString (Str1));\r
+  if n = 0\r
+   then EXIT;\r
+  Result := Str1 + n - 1;\r
+ end; { of function StrPos\r
+--------------------------------------------------------------}\r
+\r
+function StrLComp (Str1, Str2: PRegExprChar; MaxLen: Cardinal): Integer;\r
+ var S1, S2: RegExprString;\r
+ begin\r
+  S1 := Str1;\r
+  S2 := Str2;\r
+  if Copy (S1, 1, MaxLen) > Copy (S2, 1, MaxLen)\r
+   then Result := 1\r
+   else\r
+    if Copy (S1, 1, MaxLen) < Copy (S2, 1, MaxLen)\r
+     then Result := -1\r
+     else Result := 0;\r
+ end; { function StrLComp\r
+--------------------------------------------------------------}\r
+\r
+function StrScan (Str: PRegExprChar; Chr: WideChar): PRegExprChar;\r
+ begin\r
+  Result := nil;\r
+  while (Str^ <> #0) and (Str^ <> Chr)\r
+   do Inc (Str);\r
+  if (Str^ <> #0)\r
+   then Result := Str;\r
+ end; { of function StrScan\r
+--------------------------------------------------------------}\r
+\r
+{$ENDIF}\r
+\r
+{=============================================================}\r
+{===================== Global functions ======================}\r
+{=============================================================}\r
+\r
+function ExecRegExpr (const ARegExpr, AInputStr : RegExprString) : boolean;\r
+ var r : TRegExpr;\r
+ begin\r
+  r := TRegExpr.Create;\r
+  try\r
+    r.Expression := ARegExpr;\r
+    Result := r.Exec (AInputStr);\r
+    finally r.Free;\r
+   end;\r
+ end; { of function ExecRegExpr\r
+--------------------------------------------------------------}\r
+\r
+procedure SplitRegExpr (const ARegExpr, AInputStr : RegExprString; APieces : TStrings);\r
+ var r : TRegExpr;\r
+ begin\r
+  APieces.Clear;\r
+  r := TRegExpr.Create;\r
+  try\r
+    r.Expression := ARegExpr;\r
+    r.Split (AInputStr, APieces);\r
+    finally r.Free;\r
+   end;\r
+ end; { of procedure SplitRegExpr\r
+--------------------------------------------------------------}\r
+\r
+function ReplaceRegExpr (const ARegExpr, AInputStr, AReplaceStr : RegExprString) : RegExprString;\r
+ var r : TRegExpr;\r
+ begin\r
+  r := TRegExpr.Create;\r
+  try\r
+    r.Expression := ARegExpr;\r
+    Result := r.Replace (AInputStr, AReplaceStr);\r
+    finally r.Free;\r
+   end;\r
+ end; { of function ReplaceRegExpr\r
+--------------------------------------------------------------}\r
+\r
+function QuoteRegExprMetaChars (const AStr : RegExprString) : RegExprString;\r
+ const\r
+  RegExprMetaSet : RegExprString = '^$.[()|?+*\{'\r
+  + ']}'; // - this last are additional to META.\r
+  // Very similar to META array, but slighly changed.\r
+  // !Any changes in META array must be synchronized with this set.\r
+ var\r
+  i, i0, Len : integer;\r
+ begin\r
+  Result := '';\r
+  Len := length (AStr);\r
+  i := 1;\r
+  i0 := i;\r
+  while i <= Len do begin\r
+    if Pos (AStr [i], RegExprMetaSet) > 0 then begin\r
+      Result := Result + System.Copy (AStr, i0, i - i0)\r
+                 + '\' + AStr [i];\r
+      i0 := i + 1;\r
+     end;\r
+    inc (i);\r
+   end;\r
+  Result := Result + System.Copy (AStr, i0, MaxInt); // Tail\r
+ end; { of function QuoteRegExprMetaChars\r
+--------------------------------------------------------------}\r
+\r
+\r
+\r
+const\r
+ MAGIC       = TREOp (216);// programm signature\r
+\r
+// name            opcode    opnd? meaning\r
+ EEND        = TREOp (0);  // -    End of program\r
+ BOL         = TREOp (1);  // -    Match "" at beginning of line\r
+ EOL         = TREOp (2);  // -    Match "" at end of line\r
+ ANY         = TREOp (3);  // -    Match any one character\r
+ ANYOF       = TREOp (4);  // Str  Match any character in string Str\r
+ ANYBUT      = TREOp (5);  // Str  Match any char. not in string Str\r
+ BRANCH      = TREOp (6);  // Node Match this alternative, or the next\r
+ BACK        = TREOp (7);  // -    Jump backward (Next < 0)\r
+ EXACTLY     = TREOp (8);  // Str  Match string Str\r
+ NOTHING     = TREOp (9);  // -    Match empty string\r
+ STAR        = TREOp (10); // Node Match this (simple) thing 0 or more times\r
+ PLUS        = TREOp (11); // Node Match this (simple) thing 1 or more times\r
+ ANYDIGIT    = TREOp (12); // -    Match any digit (equiv [0-9])\r
+ NOTDIGIT    = TREOp (13); // -    Match not digit (equiv [0-9])\r
+ ANYLETTER   = TREOp (14); // -    Match any letter from property WordChars\r
+ NOTLETTER   = TREOp (15); // -    Match not letter from property WordChars\r
+ ANYSPACE    = TREOp (16); // -    Match any space char (see property SpaceChars)\r
+ NOTSPACE    = TREOp (17); // -    Match not space char (see property SpaceChars)\r
+ BRACES      = TREOp (18); // Node,Min,Max Match this (simple) thing from Min to Max times.\r
+                           //      Min and Max are TREBracesArg\r
+ COMMENT     = TREOp (19); // -    Comment ;)\r
+ EXACTLYCI   = TREOp (20); // Str  Match string Str case insensitive\r
+ ANYOFCI     = TREOp (21); // Str  Match any character in string Str, case insensitive\r
+ ANYBUTCI    = TREOp (22); // Str  Match any char. not in string Str, case insensitive\r
+ LOOPENTRY   = TREOp (23); // Node Start of loop (Node - LOOP for this loop)\r
+ LOOP        = TREOp (24); // Node,Min,Max,LoopEntryJmp - back jump for LOOPENTRY.\r
+                           //      Min and Max are TREBracesArg\r
+                           //      Node - next node in sequence,\r
+                           //      LoopEntryJmp - associated LOOPENTRY node addr\r
+ ANYOFTINYSET= TREOp (25); // Chrs Match any one char from Chrs (exactly TinySetLen chars)\r
+ ANYBUTTINYSET=TREOp (26); // Chrs Match any one char not in Chrs (exactly TinySetLen chars)\r
+ ANYOFFULLSET= TREOp (27); // Set  Match any one char from set of char\r
+                           // - very fast (one CPU instruction !) but takes 32 bytes of p-code\r
+ BSUBEXP     = TREOp (28); // Idx  Match previously matched subexpression #Idx (stored as REChar) //###0.936\r
+ BSUBEXPCI   = TREOp (29); // Idx  -"- in case-insensitive mode\r
+\r
+\r
+ // !!! Change OPEN value if you add new opcodes !!!\r
+\r
+ OPEN        = TREOp (30); // -    Mark this point in input as start of \n\r
+                           //      OPEN + 1 is \1, etc.\r
+ CLOSE       = TREOp (ord (OPEN) + NSUBEXP);\r
+                           // -    Analogous to OPEN.\r
+\r
+ // !!! Don't add new OpCodes after CLOSE !!!\r
+\r
+// We work with p-code thru pointers, compatible with PRegExprChar.\r
+// Note: all code components (TRENextOff, TREOp, TREBracesArg, etc)\r
+// must have lengths that can be divided by SizeOf (REChar) !\r
+// A node is TREOp of opcode followed Next "pointer" of TRENextOff type.\r
+// The Next is a offset from the opcode of the node containing it.\r
+// An operand, if any, simply follows the node. (Note that much of\r
+// the code generation knows about this implicit relationship!)\r
+// Using TRENextOff=integer speed up p-code processing.\r
+\r
+// Opcodes description:\r
+//\r
+// BRANCH The set of branches constituting a single choice are hooked\r
+//      together with their "next" pointers, since precedence prevents\r
+//      anything being concatenated to any individual branch.  The\r
+//      "next" pointer of the last BRANCH in a choice points to the\r
+//      thing following the whole choice.  This is also where the\r
+//      final "next" pointer of each individual branch points; each\r
+//      branch starts with the operand node of a BRANCH node.\r
+// BACK Normal "next" pointers all implicitly point forward; BACK\r
+//      exists to make loop structures possible.\r
+// STAR,PLUS,BRACES '?', and complex '*' and '+', are implemented as\r
+//      circular BRANCH structures using BACK. Complex '{min,max}'\r
+//      - as pair LOOPENTRY-LOOP (see below). Simple cases (one\r
+//      character per match) are implemented with STAR, PLUS and\r
+//      BRACES for speed and to minimize recursive plunges.\r
+// LOOPENTRY,LOOP {min,max} are implemented as special pair\r
+//      LOOPENTRY-LOOP. Each LOOPENTRY initialize loopstack for\r
+//      current level.\r
+// OPEN,CLOSE are numbered at compile time.\r
+\r
+\r
+{=============================================================}\r
+{================== Error handling section ===================}\r
+{=============================================================}\r
+\r
+const\r
+ reeOk = 0;\r
+ reeCompNullArgument = 100;\r
+ reeCompRegexpTooBig = 101;\r
+ reeCompParseRegTooManyBrackets = 102;\r
+ reeCompParseRegUnmatchedBrackets = 103;\r
+ reeCompParseRegUnmatchedBrackets2 = 104;\r
+ reeCompParseRegJunkOnEnd = 105;\r
+ reePlusStarOperandCouldBeEmpty = 106;\r
+ reeNestedSQP = 107;\r
+ reeBadHexDigit = 108;\r
+ reeInvalidRange = 109;\r
+ reeParseAtomTrailingBackSlash = 110;\r
+ reeNoHexCodeAfterBSlashX = 111;\r
+ reeHexCodeAfterBSlashXTooBig = 112;\r
+ reeUnmatchedSqBrackets = 113;\r
+ reeInternalUrp = 114;\r
+ reeQPSBFollowsNothing = 115;\r
+ reeTrailingBackSlash = 116;\r
+ reeRarseAtomInternalDisaster = 119;\r
+ reeBRACESArgTooBig = 122;\r
+ reeBracesMinParamGreaterMax = 124;\r
+ reeUnclosedComment = 125;\r
+ reeComplexBracesNotImplemented = 126;\r
+ reeUrecognizedModifier = 127;\r
+ reeRegRepeatCalledInappropriately = 1000;\r
+ reeMatchPrimMemoryCorruption = 1001;\r
+ reeMatchPrimCorruptedPointers = 1002;\r
+ reeNoExpression = 1003;\r
+ reeCorruptedProgram = 1004;\r
+ reeNoInpitStringSpecified = 1005;\r
+ reeOffsetMustBeGreaterThen0 = 1006;\r
+ reeExecNextWithoutExec = 1007;\r
+ reeGetInputStringWithoutInputString = 1008;\r
+ reeDumpCorruptedOpcode = 1011;\r
+ reeExecAfterCompErr = 1012;\r
+ reeModifierUnsupported = 1013;\r
+ reeLoopStackExceeded = 1014;\r
+ reeLoopWithoutEntry = 1015;\r
+\r
+function TRegExpr.ErrorMsg (AErrorID : integer) : RegExprString;\r
+ begin\r
+  case AErrorID of\r
+    reeOk: Result := 'No errors';\r
+    reeCompNullArgument: Result := 'TRegExpr(comp): Null Argument';\r
+    reeCompRegexpTooBig: Result := 'TRegExpr(comp): Regexp Too Big';\r
+    reeCompParseRegTooManyBrackets: Result := 'TRegExpr(comp): ParseReg Too Many ()';\r
+    reeCompParseRegUnmatchedBrackets: Result := 'TRegExpr(comp): ParseReg Unmatched ()';\r
+    reeCompParseRegUnmatchedBrackets2: Result := 'TRegExpr(comp): ParseReg Unmatched ()';\r
+    reeCompParseRegJunkOnEnd: Result := 'TRegExpr(comp): ParseReg Junk On End';\r
+    reePlusStarOperandCouldBeEmpty: Result := 'TRegExpr(comp): *+ Operand Could Be Empty';\r
+    reeNestedSQP: Result := 'TRegExpr(comp): Nested *?+';\r
+    reeBadHexDigit: Result := 'TRegExpr(comp): Bad Hex Digit';\r
+    reeInvalidRange: Result := 'TRegExpr(comp): Invalid [] Range';\r
+    reeParseAtomTrailingBackSlash: Result := 'TRegExpr(comp): Parse Atom Trailing \';\r
+    reeNoHexCodeAfterBSlashX: Result := 'TRegExpr(comp): No Hex Code After \x';\r
+    reeHexCodeAfterBSlashXTooBig: Result := 'TRegExpr(comp): Hex Code After \x Is Too Big';\r
+    reeUnmatchedSqBrackets: Result := 'TRegExpr(comp): Unmatched []';\r
+    reeInternalUrp: Result := 'TRegExpr(comp): Internal Urp';\r
+    reeQPSBFollowsNothing: Result := 'TRegExpr(comp): ?+*{ Follows Nothing';\r
+    reeTrailingBackSlash: Result := 'TRegExpr(comp): Trailing \';\r
+    reeRarseAtomInternalDisaster: Result := 'TRegExpr(comp): RarseAtom Internal Disaster';\r
+    reeBRACESArgTooBig: Result := 'TRegExpr(comp): BRACES Argument Too Big';\r
+    reeBracesMinParamGreaterMax: Result := 'TRegExpr(comp): BRACE Min Param Greater then Max';\r
+    reeUnclosedComment: Result := 'TRegExpr(comp): Unclosed (?#Comment)';\r
+    reeComplexBracesNotImplemented: Result := 'TRegExpr(comp): If you want take part in beta-testing BRACES ''{min,max}'' for complex cases - remove ''.'' from {.$DEFINE ComplexBraces}';\r
+    reeUrecognizedModifier: Result := 'TRegExpr(comp): Urecognized Modifier';\r
+\r
+    reeRegRepeatCalledInappropriately: Result := 'TRegExpr(exec): RegRepeat Called Inappropriately';\r
+    reeMatchPrimMemoryCorruption: Result := 'TRegExpr(exec): MatchPrim Memory Corruption';\r
+    reeMatchPrimCorruptedPointers: Result := 'TRegExpr(exec): MatchPrim Corrupted Pointers';\r
+    reeNoExpression: Result := 'TRegExpr(exec): Not Assigned Expression Property';\r
+    reeCorruptedProgram: Result := 'TRegExpr(exec): Corrupted Program';\r
+    reeNoInpitStringSpecified: Result := 'TRegExpr(exec): No Inpit String Specified';\r
+    reeOffsetMustBeGreaterThen0: Result := 'TRegExpr(exec): Offset Must Be Greater Then 0';\r
+    reeExecNextWithoutExec: Result := 'TRegExpr(exec): ExecNext Without Exec[Pos]';\r
+    reeGetInputStringWithoutInputString: Result := 'TRegExpr(exec): GetInputString Without InputString';\r
+    reeDumpCorruptedOpcode: Result := 'TRegExpr(dump): Corrupted Opcode';\r
+    reeExecAfterCompErr: Result := 'TRegExpr(exec): Exec After Compilation Error';\r
+    reeLoopStackExceeded: Result := 'TRegExpr(exec): Loop Stack Exceeded';\r
+    reeLoopWithoutEntry: Result := 'TRegExpr(exec): Loop Without LoopEntry !';\r
+    else Result := 'Unknown error';\r
+   end;\r
+ end; { of procedure TRegExpr.Error\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.LastError : integer;\r
+ begin\r
+  Result := fLastError;\r
+  fLastError := reeOk;\r
+ end; { of function TRegExpr.LastError\r
+--------------------------------------------------------------}\r
+\r
+\r
+{=============================================================}\r
+{===================== Common section ========================}\r
+{=============================================================}\r
+\r
+constructor TRegExpr.Create;\r
+ begin\r
+  inherited;\r
+  programm := nil;\r
+  fExpression := nil;\r
+  fInputString := nil;\r
+\r
+  regexpbeg := nil;\r
+  fExprIsCompiled := false;\r
+\r
+  ModifierI := RegExprModifierI;\r
+  ModifierR := RegExprModifierR;\r
+  ModifierS := RegExprModifierS;\r
+\r
+  SpaceChars := RegExprSpaceChars; //###0.927\r
+  WordChars := RegExprWordChars; //###0.929\r
+  fInvertCase := RegExprInvertCaseFunction; //###0.927\r
+ end; { of constructor TRegExpr.Create\r
+--------------------------------------------------------------}\r
+\r
+destructor TRegExpr.Destroy;\r
+ begin\r
+  if programm <> nil\r
+   then FreeMem (programm);\r
+  if fExpression <> nil\r
+   then FreeMem (fExpression);\r
+  if fInputString <> nil\r
+   then FreeMem (fInputString);\r
+ end; { of destructor TRegExpr.Destroy\r
+--------------------------------------------------------------}\r
+\r
+class function TRegExpr.InvertCaseFunction (const Ch : REChar) : REChar;\r
+ begin\r
+  {$IFDEF UniCode}\r
+  if Ch >= #128\r
+   then Result := Ch\r
+  else\r
+  {$ENDIF}\r
+   begin\r
+    Result := REChar (CharUpper (pointer (Ch)));\r
+    if Result = Ch\r
+     then Result := REChar (CharLower (pointer (Ch)));\r
+   end;\r
+ end; { of function TRegExpr.InvertCaseFunction\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.GetExpression : RegExprString;\r
+ begin\r
+  if fExpression <> nil\r
+   then Result := fExpression\r
+   else Result := '';\r
+ end; { of function TRegExpr.GetExpression\r
+--------------------------------------------------------------}\r
+\r
+procedure TRegExpr.SetExpression (const s : RegExprString);\r
+ begin\r
+  if (s <> fExpression) or not fExprIsCompiled then begin\r
+    fExprIsCompiled := false;\r
+    if fExpression <> nil then begin\r
+      FreeMem (fExpression);\r
+      fExpression := nil;\r
+     end;\r
+    if s <> '' then begin\r
+      GetMem (fExpression, (length (s) + 1) * SizeOf (REChar));\r
+      CompileRegExpr (StrPCopy (fExpression, s));\r
+     end;\r
+   end;\r
+ end; { of procedure TRegExpr.SetExpression\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.GetSubExprMatchCount : integer;\r
+ begin\r
+  if Assigned (fInputString) then begin\r
+     Result := NSUBEXP - 1;\r
+     while (Result > 0) and ((startp [Result] = nil)\r
+                             or (endp [Result] = nil))\r
+      do dec (Result);\r
+    end\r
+   else Result := -1;\r
+ end; { of function TRegExpr.GetSubExprMatchCount\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.GetMatchPos (Idx : integer) : integer;\r
+ begin\r
+  if (Idx >= 0) and (Idx < NSUBEXP) and Assigned (fInputString)\r
+     and Assigned (startp [Idx]) and Assigned (endp [Idx]) then begin\r
+     Result := (startp [Idx] - fInputString) + 1;\r
+    end\r
+   else Result := -1;\r
+ end; { of function TRegExpr.GetMatchPos\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.GetMatchLen (Idx : integer) : integer;\r
+ begin\r
+  if (Idx >= 0) and (Idx < NSUBEXP) and Assigned (fInputString)\r
+     and Assigned (startp [Idx]) and Assigned (endp [Idx]) then begin\r
+     Result := endp [Idx] - startp [Idx];\r
+    end\r
+   else Result := -1;\r
+ end; { of function TRegExpr.GetMatchLen\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.GetMatch (Idx : integer) : RegExprString;\r
+ begin\r
+  if (Idx >= 0) and (Idx < NSUBEXP) and Assigned (fInputString)\r
+     and Assigned (startp [Idx]) and Assigned (endp [Idx])\r
+   //then Result := copy (fInputString, MatchPos [Idx], MatchLen [Idx]) //###0.929\r
+   then SetString (Result, startp [idx], endp [idx] - startp [idx])\r
+   else Result := '';\r
+ end; { of function TRegExpr.GetMatch\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.IsProgrammOk : boolean;\r
+ begin\r
+  Result := false;\r
+  if programm = nil // No compiled r.e. present\r
+   then Error (reeNoExpression)\r
+  else if programm [0] <> MAGIC // Program corrupted.\r
+   then Error (reeCorruptedProgram)\r
+  else if not fExprIsCompiled // Previous compilation was finished with error\r
+   then Error (reeExecAfterCompErr)\r
+  else Result := true;\r
+ end; { of function TRegExpr.IsProgrammOk\r
+--------------------------------------------------------------}\r
+\r
+procedure TRegExpr.CheckCompModifiers;\r
+ begin\r
+  if (programm <> nil) and (fExpression <> nil)\r
+     and (fModifiers <> fProgModifiers)\r
+   then CompileRegExpr (fExpression);\r
+ end; { of TRegExpr.CheckCompModifiers\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.GetModifierStr : RegExprString;\r
+ begin\r
+  Result := '-';\r
+\r
+  if ModifierI\r
+   then Result := 'i' + Result\r
+   else Result := Result + 'i';\r
+  if ModifierR\r
+   then Result := 'r' + Result\r
+   else Result := Result + 'r';\r
+  if ModifierS\r
+   then Result := 's' + Result\r
+   else Result := Result + 's';\r
+\r
+  if Result [length (Result)] = '-' // remove '-' if all modifiers are 'On'\r
+   then System.Delete (Result, length (Result), 1);\r
+ end; { of function TRegExpr.GetModifierStr\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.SetModifiersInt (const AModifiers : RegExprString; var AModifiersInt : integer) : boolean;\r
+ var\r
+  i : integer;\r
+  IsOn : boolean;\r
+  Mask : integer;\r
+ begin\r
+  Result := true;\r
+  IsOn := true;\r
+  Mask := 0; // strange compiler varning\r
+  for i := 1 to length (AModifiers) do\r
+   if AModifiers [i] = '-'\r
+    then IsOn := false\r
+    else begin\r
+      if Pos (AModifiers [i], 'iI') > 0\r
+       then Mask := MaskModI\r
+      else if Pos (AModifiers [i], 'rR') > 0\r
+       then Mask := MaskModR\r
+      else if Pos (AModifiers [i], 'sS') > 0\r
+       then Mask := MaskModS\r
+      else begin\r
+        Result := false;\r
+        EXIT;\r
+       end;\r
+      if IsOn\r
+       then AModifiersInt := AModifiersInt or Mask\r
+       else AModifiersInt := AModifiersInt and not Mask;\r
+     end;\r
+ end; { of function TRegExpr.SetModifiersInt\r
+--------------------------------------------------------------}\r
+\r
+procedure TRegExpr.SetModifierStr (const AModifiers : RegExprString);\r
+ begin\r
+  if not SetModifiersInt (AModifiers, fModifiers)\r
+   then Error (reeModifierUnsupported);\r
+  CheckCompModifiers;\r
+ end; { of procedure TRegExpr.SetModifierStr\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.GetModifier (AIndex : integer) : boolean;\r
+ var\r
+  Mask : integer;\r
+ begin\r
+  Result := false;\r
+  case AIndex of\r
+    1: Mask := MaskModI;\r
+    2: Mask := MaskModR;\r
+    3: Mask := MaskModS;\r
+    else begin\r
+      Error (reeModifierUnsupported);\r
+      EXIT;\r
+     end;\r
+   end;\r
+  Result := (fModifiers and Mask) = Mask;\r
+ end; { of function TRegExpr.GetModifier\r
+--------------------------------------------------------------}\r
+\r
+procedure TRegExpr.SetModifier (AIndex : integer; ASet : boolean);\r
+ var\r
+  Mask : integer;\r
+ begin\r
+  case AIndex of\r
+    1: Mask := MaskModI;\r
+    2: Mask := MaskModR;\r
+    3: Mask := MaskModS;\r
+    else begin\r
+      Error (reeModifierUnsupported);\r
+      EXIT;\r
+     end;\r
+   end;\r
+  if ASet\r
+   then fModifiers := fModifiers or Mask\r
+   else fModifiers := fModifiers and not Mask;\r
+  CheckCompModifiers;\r
+ end; { of procedure TRegExpr.SetModifier\r
+--------------------------------------------------------------}\r
+\r
+\r
+{=============================================================}\r
+{==================== Compiler section =======================}\r
+{=============================================================}\r
+\r
+procedure TRegExpr.Tail (p : PRegExprChar; val : PRegExprChar);\r
+// set the next-pointer at the end of a node chain\r
+ var\r
+  scan : PRegExprChar;\r
+  temp : PRegExprChar;\r
+ begin\r
+  if p = @regdummy\r
+   then EXIT;\r
+  // Find last node.\r
+  scan := p;\r
+  REPEAT\r
+   temp := regnext (scan);\r
+   if temp = nil\r
+    then BREAK;\r
+   scan := temp;\r
+  UNTIL false;\r
+  // Set Next 'pointer'\r
+  PRENextOff (scan + REOpSz)^ := val - scan; //###0.933\r
+ end; { of procedure TRegExpr.Tail\r
+--------------------------------------------------------------}\r
+\r
+procedure TRegExpr.OpTail (p : PRegExprChar; val : PRegExprChar);\r
+// regtail on operand of first argument; nop if operandless\r
+ begin\r
+  // "Operandless" and "op != BRANCH" are synonymous in practice.\r
+  if (p = nil) or (p = @regdummy) or (PREOp (p)^ <> BRANCH)\r
+   then EXIT;\r
+  Tail (p + REOpSz + RENextOffSz, val); //###0.933\r
+ end; { of procedure TRegExpr.OpTail\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.EmitNode (op : TREOp) : PRegExprChar; //###0.933\r
+// emit a node, return location\r
+ begin\r
+  Result := regcode;\r
+  if Result <> @regdummy then begin\r
+     PREOp (regcode)^ := op;\r
+     inc (regcode, REOpSz);\r
+     PRENextOff (regcode)^ := 0; // Next "pointer" := nil\r
+     inc (regcode, RENextOffSz);\r
+    end\r
+   else inc (regsize, REOpSz + RENextOffSz); // compute code size without code generation\r
+ end; { of function TRegExpr.EmitNode\r
+--------------------------------------------------------------}\r
+\r
+procedure TRegExpr.EmitC (b : REChar);\r
+// emit a byte to code\r
+ begin\r
+  if regcode <> @regdummy then begin\r
+     regcode^ := b;\r
+     inc (regcode);\r
+    end\r
+   else inc (regsize); // Type of p-code pointer always is ^REChar\r
+ end; { of procedure TRegExpr.EmitC\r
+--------------------------------------------------------------}\r
+\r
+procedure TRegExpr.InsertOperator (op : TREOp; opnd : PRegExprChar; sz : integer);\r
+// insert an operator in front of already-emitted operand\r
+// Means relocating the operand.\r
+ var\r
+  src, dst, place : PRegExprChar;\r
+  i : integer;\r
+ begin\r
+  if regcode = @regdummy then begin\r
+    inc (regsize, sz);\r
+    EXIT;\r
+   end;\r
+  src := regcode;\r
+  inc (regcode, sz);\r
+  dst := regcode;\r
+  while src > opnd do begin\r
+    dec (dst);\r
+    dec (src);\r
+    dst^ := src^;\r
+   end;\r
+  place := opnd; // Op node, where operand used to be.\r
+  PREOp (place)^ := op;\r
+  inc (place, REOpSz);\r
+  for i := 1 + REOpSz to sz do begin\r
+    place^ := #0;\r
+    inc (place);\r
+   end;\r
+ end; { of procedure TRegExpr.InsertOperator\r
+--------------------------------------------------------------}\r
+\r
+function strcspn (s1 : PRegExprChar; s2 : PRegExprChar) : integer;\r
+// find length of initial segment of s1 consisting\r
+// entirely of characters not from s2\r
+ var scan1, scan2 : PRegExprChar;\r
+ begin\r
+  Result := 0;\r
+  scan1 := s1;\r
+  while scan1^ <> #0 do begin\r
+    scan2 := s2;\r
+    while scan2^ <> #0 do\r
+     if scan1^ = scan2^\r
+      then EXIT\r
+      else inc (scan2);\r
+    inc (Result);\r
+    inc (scan1)\r
+   end;\r
+ end; { of function strcspn\r
+--------------------------------------------------------------}\r
+\r
+const\r
+// Flags to be passed up and down.\r
+ HASWIDTH =   01; // Known never to match nil string.\r
+ SIMPLE   =   02; // Simple enough to be STAR/PLUS/BRACES operand.\r
+ SPSTART  =   04; // Starts with * or +.\r
+ WORST    =   0;  // Worst case.\r
+ META : array [0 .. 12] of REChar = (\r
+  '^', '$', '.', '[', '(', ')', '|', '?', '+', '*', '\', '{', #0);\r
+ // Any modification must be synchronized with QuoteRegExprMetaChars !!!\r
+\r
+{$IFDEF UniCode}\r
+ RusRangeLo : array [0 .. 33] of REChar =\r
+  (#$430,#$431,#$432,#$433,#$434,#$435,#$451,#$436,#$437,\r
+   #$438,#$439,#$43A,#$43B,#$43C,#$43D,#$43E,#$43F,\r
+   #$440,#$441,#$442,#$443,#$444,#$445,#$446,#$447,\r
+   #$448,#$449,#$44A,#$44B,#$44C,#$44D,#$44E,#$44F,#0);\r
+ RusRangeHi : array [0 .. 33] of REChar =\r
+  (#$410,#$411,#$412,#$413,#$414,#$415,#$401,#$416,#$417,\r
+   #$418,#$419,#$41A,#$41B,#$41C,#$41D,#$41E,#$41F,\r
+   #$420,#$421,#$422,#$423,#$424,#$425,#$426,#$427,\r
+   #$428,#$429,#$42A,#$42B,#$42C,#$42D,#$42E,#$42F,#0);\r
+ RusRangeLoLow = #$430{'à'};\r
+ RusRangeLoHigh = #$44F{'ÿ'};\r
+ RusRangeHiLow = #$410{'À'};\r
+ RusRangeHiHigh = #$42F{'ß'};\r
+{$ELSE}\r
+ RusRangeLo = 'àáâãäå¸æçèéêëìíîïðñòóôõö÷øùúûüýþÿ';\r
+ RusRangeHi = 'ÀÁÂÃÄŨÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß';\r
+ RusRangeLoLow = 'à';\r
+ RusRangeLoHigh = 'ÿ';\r
+ RusRangeHiLow = 'À';\r
+ RusRangeHiHigh = 'ß';\r
+{$ENDIF}\r
+\r
+function TRegExpr.CompileRegExpr (exp : PRegExprChar) : boolean;\r
+// compile a regular expression into internal code\r
+// We can't allocate space until we know how big the compiled form will be,\r
+// but we can't compile it (and thus know how big it is) until we've got a\r
+// place to put the code.  So we cheat:  we compile it twice, once with code\r
+// generation turned off and size counting turned on, and once "for real".\r
+// This also means that we don't allocate space until we are sure that the\r
+// thing really will compile successfully, and we never have to move the\r
+// code and thus invalidate pointers into it.  (Note that it has to be in\r
+// one piece because free() must be able to free it all.)\r
+// Beware that the optimization-preparation code in here knows about some\r
+// of the structure of the compiled regexp.\r
+ var\r
+  scan, longest : PRegExprChar;\r
+  len : cardinal;\r
+  flags : integer;\r
+ begin\r
+  Result := false; // life too dark\r
+  fExprIsCompiled := false;\r
+\r
+  regparse := nil; // for correct error handling\r
+  regexpbeg := exp;\r
+  try // must clear regexpbeg after compilation\r
+\r
+  if programm <> nil then begin\r
+    FreeMem (programm);\r
+    programm := nil;\r
+   end;\r
+\r
+  if exp = nil then begin\r
+    Error (reeCompNullArgument);\r
+    EXIT;\r
+   end;\r
+\r
+  fProgModifiers := fModifiers;\r
+  // well, may it's paranoia. I'll check it later... !!!!!!!!\r
+\r
+  // First pass: determine size, legality.\r
+  fCompModifiers := fModifiers;\r
+  regparse := exp;\r
+  regnpar := 1;\r
+  regsize := 0;\r
+  regcode := @regdummy;\r
+  EmitC (MAGIC);\r
+  if ParseReg (0, flags) = nil\r
+   then EXIT;\r
+\r
+  // Small enough for 2-bytes programm pointers ?\r
+  // ###0.933 no real p-code length limits now :)))\r
+//  if regsize >= 64 * 1024 then begin\r
+//    Error (reeCompRegexpTooBig);\r
+//    EXIT;\r
+//   end;\r
+\r
+  // Allocate space.\r
+  GetMem (programm, regsize * SizeOf (REChar));\r
+\r
+  // Second pass: emit code.\r
+  fCompModifiers := fModifiers;\r
+  regparse := exp;\r
+  regnpar := 1;\r
+  regcode := programm;\r
+  EmitC (MAGIC);\r
+  if ParseReg (0, flags) = nil\r
+   then EXIT;\r
+\r
+  // Dig out information for optimizations.\r
+  {$IFDEF UseFirstCharSet} //###0.929\r
+  FirstCharSet := [];\r
+  FillFirstCharSet (programm + REOpSz);\r
+  {$ENDIF}\r
+  regstart := #0; // Worst-case defaults.\r
+  reganch := #0;\r
+  regmust := nil;\r
+  regmlen := 0;\r
+  scan := programm + REOpSz; // First BRANCH.\r
+  if PREOp (regnext (scan))^ = EEND then begin // Only one top-level choice.\r
+    scan := scan + REOpSz + RENextOffSz;\r
+\r
+    // Starting-point info.\r
+    if PREOp (scan)^ = EXACTLY\r
+     then regstart := (scan + REOpSz + RENextOffSz)^\r
+     else if PREOp (scan)^ = BOL\r
+           then inc (reganch);\r
+\r
+    // If there's something expensive in the r.e., find the longest\r
+    // literal string that must appear and make it the regmust.  Resolve\r
+    // ties in favor of later strings, since the regstart check works\r
+    // with the beginning of the r.e. and avoiding duplication\r
+    // strengthens checking.  Not a strong reason, but sufficient in the\r
+    // absence of others.\r
+    if (flags and SPSTART) <> 0 then begin\r
+        longest := nil;\r
+        len := 0;\r
+        while scan <> nil do begin\r
+          if (PREOp (scan)^ = EXACTLY)\r
+             and (strlen (scan + REOpSz + RENextOffSz) >= len) then begin\r
+              longest := scan + REOpSz + RENextOffSz;\r
+              len := strlen (longest);\r
+           end;\r
+          scan := regnext (scan);\r
+         end;\r
+        regmust := longest;\r
+        regmlen := len;\r
+     end;\r
+   end;\r
+\r
+  finally regexpbeg := nil;\r
+  end;\r
+\r
+  fExprIsCompiled := true;\r
+  Result := true;\r
+ end; { of function TRegExpr.CompileRegExpr\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.ParseReg (paren : integer; var flagp : integer) : PRegExprChar;\r
+// regular expression, i.e. main body or parenthesized thing\r
+// Caller must absorb opening parenthesis.\r
+// Combining parenthesis handling with the base level of regular expression\r
+// is a trifle forced, but the need to tie the tails of the branches to what\r
+// follows makes it hard to avoid.\r
+ var\r
+  ret, br, ender : PRegExprChar;\r
+  parno : integer;\r
+  flags : integer;\r
+  SavedModifiers : integer;\r
+ begin\r
+  Result := nil;\r
+  flagp := HASWIDTH; // Tentatively.\r
+  parno := 0; // eliminate compiler stupid warning\r
+  SavedModifiers := fCompModifiers;\r
+\r
+  // Make an OPEN node, if parenthesized.\r
+  if paren <> 0 then begin\r
+      if regnpar >= NSUBEXP then begin\r
+        Error (reeCompParseRegTooManyBrackets);\r
+        EXIT;\r
+       end;\r
+      parno := regnpar;\r
+      inc (regnpar);\r
+      ret := EmitNode (TREOp (ord (OPEN) + parno));\r
+    end\r
+   else ret := nil;\r
+\r
+  // Pick up the branches, linking them together.\r
+  br := ParseBranch (flags);\r
+  if br = nil then begin\r
+    Result := nil;\r
+    EXIT;\r
+   end;\r
+  if ret <> nil\r
+   then Tail (ret, br) // OPEN -> first.\r
+   else ret := br;\r
+  if (flags and HASWIDTH) = 0\r
+   then flagp := flagp and not HASWIDTH;\r
+  flagp := flagp or flags and SPSTART;\r
+  while (regparse^ = '|') do begin\r
+    inc (regparse);\r
+    br := ParseBranch (flags);\r
+    if br = nil then begin\r
+       Result := nil;\r
+       EXIT;\r
+      end;\r
+    Tail (ret, br); // BRANCH -> BRANCH.\r
+    if (flags and HASWIDTH) = 0\r
+     then flagp := flagp and not HASWIDTH;\r
+    flagp := flagp or flags and SPSTART;\r
+   end;\r
+\r
+  // Make a closing node, and hook it on the end.\r
+  if paren <> 0\r
+   then ender := EmitNode (TREOp (ord (CLOSE) + parno))\r
+   else ender := EmitNode (EEND);\r
+  Tail (ret, ender);\r
+\r
+  // Hook the tails of the branches to the closing node.\r
+  br := ret;\r
+  while br <> nil do begin\r
+    OpTail (br, ender);\r
+    br := regnext (br);\r
+   end;\r
+\r
+  // Check for proper termination.\r
+  if paren <> 0 then\r
+   if regparse^ <> ')' then begin\r
+      Error (reeCompParseRegUnmatchedBrackets);\r
+      EXIT;\r
+     end\r
+    else inc (regparse); // skip trailing ')'\r
+  if (paren = 0) and (regparse^ <> #0) then begin\r
+      if regparse^ = ')'\r
+       then Error (reeCompParseRegUnmatchedBrackets2)\r
+       else Error (reeCompParseRegJunkOnEnd);\r
+      EXIT;\r
+    end;\r
+  fCompModifiers := SavedModifiers; // restore modifiers of parent\r
+  Result := ret;\r
+ end; { of function TRegExpr.ParseReg\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.ParseBranch (var flagp : integer) : PRegExprChar;\r
+// one alternative of an | operator\r
+// Implements the concatenation operator.\r
+ var\r
+  ret, chain, latest : PRegExprChar;\r
+  flags : integer;\r
+ begin\r
+  flagp := WORST; // Tentatively.\r
+\r
+  ret := EmitNode (BRANCH);\r
+  chain := nil;\r
+  while (regparse^ <> #0) and (regparse^ <> '|')\r
+        and (regparse^ <> ')') do begin\r
+    latest := ParsePiece (flags);\r
+    if latest = nil then begin\r
+      Result := nil;\r
+      EXIT;\r
+     end;\r
+    flagp := flagp or flags and HASWIDTH;\r
+    if chain = nil // First piece.\r
+     then flagp := flagp or flags and SPSTART\r
+     else Tail (chain, latest);\r
+    chain := latest;\r
+   end;\r
+  if chain = nil // Loop ran zero times.\r
+   then EmitNode (NOTHING);\r
+  Result := ret;\r
+ end; { of function TRegExpr.ParseBranch\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.ParsePiece (var flagp : integer) : PRegExprChar;\r
+// something followed by possible [*+?{]\r
+// Note that the branching code sequences used for ? and the general cases\r
+// of * and + and { are somewhat optimized:  they use the same NOTHING node as\r
+// both the endmarker for their branch list and the body of the last branch.\r
+// It might seem that this node could be dispensed with entirely, but the\r
+// endmarker role is not redundant.\r
+ function parsenum (AStart, AEnd : PRegExprChar) : TREBracesArg;\r
+  begin\r
+   Result := 0;\r
+   if AEnd - AStart + 1 > 8 then begin // prevent stupid scanning\r
+     Error (reeBRACESArgTooBig);\r
+     EXIT;\r
+    end;\r
+   while AStart <= AEnd do begin\r
+       Result := Result * 10 + (ord (AStart^) - ord ('0'));\r
+       inc (AStart);\r
+      end;\r
+   if (Result > MaxBracesArg) or (Result < 0) then begin\r
+     Error (reeBRACESArgTooBig);\r
+     EXIT;\r
+    end;\r
+  end;\r
+ var\r
+  op : REChar;\r
+  NextNode : PRegExprChar;\r
+  flags : integer;\r
+  BracesMin, Bracesmax : TREBracesArg;\r
+  p, savedparse : PRegExprChar;\r
+  {$IFDEF ComplexBraces}\r
+  off : integer;\r
+  {$ENDIF}\r
+ begin\r
+  Result := ParseAtom (flags);\r
+  if Result = nil\r
+   then EXIT;\r
+\r
+  op := regparse^;\r
+  if not ((op = '*') or (op = '+') or (op = '?') or (op = '{')) then begin\r
+    flagp := flags;\r
+    EXIT;\r
+   end;\r
+  if ((flags and HASWIDTH) = 0) and (op <> '?') then begin\r
+    Error (reePlusStarOperandCouldBeEmpty);\r
+    EXIT;\r
+   end;\r
+\r
+  case op of\r
+    '*': begin\r
+      flagp := WORST or SPSTART;\r
+      if (flags and SIMPLE) = 0 then begin\r
+         // Emit x* as (x&|), where & means "self".\r
+         InsertOperator (BRANCH, Result, REOpSz + RENextOffSz); // Either x\r
+         OpTail (Result, EmitNode (BACK)); // and loop\r
+         OpTail (Result, Result); // back\r
+         Tail (Result, EmitNode (BRANCH)); // or\r
+         Tail (Result, EmitNode (NOTHING)); // nil.\r
+        end\r
+       else InsertOperator (STAR, Result, REOpSz + RENextOffSz);\r
+     end; { of case '*'}\r
+    '+': begin\r
+      flagp := WORST or SPSTART or HASWIDTH;\r
+      if (flags and SIMPLE) = 0 then begin\r
+         // Emit x+ as x(&|), where & means "self".\r
+         NextNode := EmitNode (BRANCH); // Either\r
+         Tail (Result, NextNode);\r
+         Tail (EmitNode (BACK), Result);    // loop back\r
+         Tail (NextNode, EmitNode (BRANCH)); // or\r
+         Tail (Result, EmitNode (NOTHING)); // nil.\r
+        end\r
+       else InsertOperator (PLUS, Result, REOpSz + RENextOffSz);\r
+     end; { of case '+'}\r
+    '?': begin\r
+      flagp := WORST;\r
+      // Emit x? as (x|)\r
+      InsertOperator (BRANCH, Result, REOpSz + RENextOffSz); // Either x\r
+      Tail (Result, EmitNode (BRANCH));  // or\r
+      NextNode := EmitNode (NOTHING); // nil.\r
+      Tail (Result, NextNode);\r
+      OpTail (Result, NextNode);\r
+     end; { of case '?'}\r
+   '{': begin\r
+      savedparse := regparse;\r
+      inc (regparse);\r
+      p := regparse;\r
+      while Pos (regparse^, '0123456789') > 0  // <min> MUST appear\r
+       do inc (regparse);\r
+      if (regparse^ <> '}') and (regparse^ <> ',') or (p = regparse) then begin\r
+        regparse := savedparse;\r
+        flagp := flags;\r
+        EXIT;\r
+       end;\r
+      BracesMin := parsenum (p, regparse - 1);\r
+      if regparse^ = ',' then begin\r
+         inc (regparse);\r
+         p := regparse;\r
+         while Pos (regparse^, '0123456789') > 0\r
+          do inc (regparse);\r
+         if regparse^ <> '}' then begin\r
+           regparse := savedparse;\r
+           EXIT;\r
+          end;\r
+         if p = regparse\r
+          then BracesMax := MaxBracesArg\r
+          else BracesMax := parsenum (p, regparse - 1);\r
+        end\r
+       else BracesMax := BracesMin; // {n} == {n,n}\r
+      if BracesMin > BracesMax then begin\r
+        Error (reeBracesMinParamGreaterMax);\r
+        EXIT;\r
+       end;\r
+      if BracesMin > 0\r
+       then flagp := WORST;\r
+      if BracesMax > 0\r
+       then flagp := flagp or HASWIDTH or SPSTART;\r
+      if (flags and SIMPLE) <> 0 then begin\r
+         InsertOperator (BRACES, Result, REOpSz + RENextOffSz + REBracesArgSz * 2);\r
+         if regcode <> @regdummy then begin\r
+           PREBracesArg (Result + REOpSz + RENextOffSz)^ := BracesMin;\r
+           PREBracesArg (Result + REOpSz + RENextOffSz + REBracesArgSz)^ := BracesMax;\r
+          end;\r
+        end\r
+       else begin // Emit complex x{min,max}\r
+         {$IFNDEF ComplexBraces}\r
+         Error (reeComplexBracesNotImplemented);\r
+         EXIT;\r
+         {$ELSE}\r
+         InsertOperator (LOOPENTRY, Result, REOpSz + RENextOffSz);\r
+         NextNode := EmitNode (LOOP);\r
+         if regcode <> @regdummy then begin\r
+            off := (Result + REOpSz + RENextOffSz)\r
+             - (regcode - REOpSz - RENextOffSz); // back to Atom after LOOPENTRY\r
+            PREBracesArg (regcode)^ := BracesMin;\r
+            inc (regcode, REBracesArgSz);\r
+            PREBracesArg (regcode)^ := BracesMax;\r
+            inc (regcode, REBracesArgSz);\r
+            PRENextOff (regcode)^ := off;\r
+            inc (regcode, RENextOffSz);\r
+           end\r
+          else inc (regsize, REBracesArgSz * 2 + RENextOffSz);\r
+         Tail (Result, NextNode); // LOOPENTRY -> LOOP\r
+         if regcode <> @regdummy then\r
+          Tail (Result + REOpSz + RENextOffSz, NextNode); // Atom -> LOOP\r
+         {$ENDIF}\r
+        end;\r
+     end; { of case '{'}\r
+//    else // here we can't be\r
+   end; { of case op}\r
+\r
+  inc (regparse);\r
+  if (regparse^ = '*') or (regparse^ = '+') or (regparse^ = '?') or (regparse^ = '{') then begin\r
+    Error (reeNestedSQP);\r
+    EXIT;\r
+   end;\r
+ end; { of function TRegExpr.ParsePiece\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.ParseAtom (var flagp : integer) : PRegExprChar;\r
+// the lowest level\r
+// Optimization:  gobbles an entire sequence of ordinary characters so that\r
+// it can turn them into a single node, which is smaller to store and\r
+// faster to run.  Backslashed characters are exceptions, each becoming a\r
+// separate node; the code is simpler that way and it's not worth fixing.\r
+ var\r
+  ret : PRegExprChar;\r
+  flags : integer;\r
+  RangeBeg, RangeEnd : REChar;\r
+  CanBeRange : boolean;\r
+  len : integer;\r
+  ender : REChar;\r
+  begmodfs : PRegExprChar;\r
+\r
+  {$IFDEF UseSetOfChar} //###0.930\r
+  RangePCodeBeg : PRegExprChar;\r
+  RangePCodeIdx : integer;\r
+  RangeIsCI : boolean;\r
+  RangeSet : TSetOfREChar;\r
+  RangeLen : integer;\r
+  RangeChMin, RangeChMax : REChar;\r
+  {$ENDIF}\r
+\r
+ procedure EmitExactly (ch : REChar);\r
+  begin\r
+   if (fCompModifiers and MaskModI) = MaskModI\r
+    then ret := EmitNode (EXACTLYCI)\r
+    else ret := EmitNode (EXACTLY);\r
+   EmitC (ch);\r
+   EmitC (#0);\r
+   flagp := flagp or HASWIDTH or SIMPLE;\r
+  end;\r
+\r
+ procedure EmitStr (const s : RegExprString);\r
+  var i : integer;\r
+  begin\r
+   for i := 1 to length (s)\r
+    do EmitC (s [i]);\r
+  end;\r
+\r
+ function HexDig (ch : REChar) : integer;\r
+  begin\r
+   Result := 0;\r
+   if (ch >= 'a') and (ch <= 'f')\r
+    then ch := REChar (ord (ch) - (ord ('a') - ord ('A')));\r
+   if (ch < '0') or (ch > 'F') or ((ch > '9') and (ch < 'A')) then begin\r
+     Error (reeBadHexDigit);\r
+     EXIT;\r
+    end;\r
+   Result := ord (ch) - ord ('0');\r
+   if ch >= 'A'\r
+    then Result := Result - (ord ('A') - ord ('9') - 1);\r
+  end;\r
+\r
+ function EmitRange (AOpCode : REChar) : PRegExprChar;\r
+  begin\r
+   {$IFDEF UseSetOfChar}\r
+   case AOpCode of\r
+     ANYBUTCI, ANYBUT:\r
+       Result := EmitNode (ANYBUTTINYSET);\r
+     else // ANYOFCI, ANYOF\r
+       Result := EmitNode (ANYOFTINYSET);\r
+    end;\r
+   case AOpCode of\r
+     ANYBUTCI, ANYOFCI:\r
+       RangeIsCI := True;\r
+     else // ANYBUT, ANYOF\r
+       RangeIsCI := False;\r
+    end;\r
+   RangePCodeBeg := regcode;\r
+   RangePCodeIdx := regsize;\r
+   RangeLen := 0;\r
+   RangeSet := [];\r
+   RangeChMin := #255;\r
+   RangeChMax := #0;\r
+   {$ELSE}\r
+   Result := EmitNode (AOpCode);\r
+   // ToDo:\r
+   // !!!!!!!!!!!!! Implement ANYOF[BUT]TINYSET generation for UniCode !!!!!!!!!!\r
+   {$ENDIF}\r
+  end;\r
+\r
+{$IFDEF UseSetOfChar}\r
+ procedure EmitRangeCPrim (b : REChar); //###0.930\r
+  begin\r
+   if b in RangeSet\r
+    then EXIT;\r
+   inc (RangeLen);\r
+   if b < RangeChMin\r
+    then RangeChMin := b;\r
+   if b > RangeChMax\r
+    then RangeChMax := b;\r
+   Include (RangeSet, b);\r
+  end;\r
+ {$ENDIF}\r
+\r
+ procedure EmitRangeC (b : REChar);\r
+  {$IFDEF UseSetOfChar}\r
+  var\r
+   Ch : REChar;\r
+  {$ENDIF}\r
+  begin\r
+   CanBeRange := false;\r
+   {$IFDEF UseSetOfChar}\r
+    if b <> #0 then begin\r
+       EmitRangeCPrim (b); //###0.930\r
+       if RangeIsCI\r
+        then EmitRangeCPrim (InvertCase (b)); //###0.930\r
+      end\r
+     else begin\r
+       Assert (RangeLen > 0, 'TRegExpr.ParseAtom(subroutine EmitRangeC): empty range'); // impossible, but who knows..\r
+       Assert (RangeChMin <= RangeChMax, 'TRegExpr.ParseAtom(subroutine EmitRangeC): RangeChMin > RangeChMax'); // impossible, but who knows..\r
+       if RangeLen <= TinySetLen then begin // emit "tiny set"\r
+          if regcode = @regdummy then begin\r
+            regsize := RangePCodeIdx + TinySetLen; // RangeChMin/Max !!!\r
+            EXIT;\r
+           end;\r
+          regcode := RangePCodeBeg;\r
+          for Ch := RangeChMin to RangeChMax do //###0.930\r
+           if Ch in RangeSet then begin\r
+             regcode^ := Ch;\r
+             inc (regcode);\r
+            end;\r
+          // fill rest:\r
+          while regcode < RangePCodeBeg + TinySetLen do begin\r
+            regcode^ := RangeChMax;\r
+            inc (regcode);\r
+           end;\r
+         end\r
+        else begin\r
+          if regcode = @regdummy then begin\r
+            regsize := RangePCodeIdx + SizeOf (TSetOfREChar);\r
+            EXIT;\r
+           end;\r
+          if (RangePCodeBeg - REOpSz - RENextOffSz)^ = ANYBUTTINYSET\r
+           then RangeSet := [#0 .. #255] - RangeSet;\r
+          PREOp (RangePCodeBeg - REOpSz - RENextOffSz)^ := ANYOFFULLSET;\r
+          regcode := RangePCodeBeg;\r
+          Move (RangeSet, regcode^, SizeOf (TSetOfREChar));\r
+          inc (regcode, SizeOf (TSetOfREChar));\r
+         end;\r
+      end;\r
+   {$ELSE}\r
+   EmitC (b);\r
+   {$ENDIF}\r
+  end;\r
+\r
+ procedure EmitSimpleRangeC (b : REChar);\r
+  begin\r
+   RangeBeg := b;\r
+   EmitRangeC (b);\r
+   CanBeRange := true;\r
+  end;\r
+\r
+ procedure EmitRangeStr (const s : RegExprString);\r
+  var i : integer;\r
+  begin\r
+   for i := 1 to length (s)\r
+    do EmitRangeC (s [i]);\r
+  end;\r
+\r
+ function UnQuoteChar (var APtr : PRegExprChar) : REChar; //###0.934\r
+  begin\r
+   case APtr^ of\r
+     't': Result := #$9;  // tab (HT/TAB)\r
+     'n': Result := #$a;  // newline (NL)\r
+     'r': Result := #$d;  // car.return (CR)\r
+     'f': Result := #$c;  // form feed (FF)\r
+     'a': Result := #$7;  // alarm (bell) (BEL)\r
+     'e': Result := #$1b; // escape (ESC)\r
+     'x': begin // hex char\r
+       Result := #0;\r
+       inc (APtr);\r
+       if APtr^ = #0 then begin\r
+         Error (reeNoHexCodeAfterBSlashX);\r
+         EXIT;\r
+        end;\r
+       if APtr^ = '{' then begin // \x{nnnn} //###0.936\r
+          REPEAT\r
+           inc (APtr);\r
+           if APtr^ = #0 then begin\r
+             Error (reeNoHexCodeAfterBSlashX);\r
+             EXIT;\r
+            end;\r
+           if APtr^ <> '}' then begin\r
+              if (Ord (Result)\r
+                  ShR (SizeOf (REChar) * 8 - 4)) and $F <> 0 then begin\r
+                Error (reeHexCodeAfterBSlashXTooBig);\r
+                EXIT;\r
+               end;\r
+              Result := REChar ((Ord (Result) ShL 4) or HexDig (APtr^));\r
+              // HexDig will cause Error if bad hex digit found\r
+             end\r
+            else BREAK;\r
+          UNTIL False;\r
+         end\r
+        else begin\r
+          Result := REChar (HexDig (APtr^));\r
+          // HexDig will cause Error if bad hex digit found\r
+          inc (APtr);\r
+          if APtr^ = #0 then begin\r
+            Error (reeNoHexCodeAfterBSlashX);\r
+            EXIT;\r
+           end;\r
+          Result := REChar ((Ord (Result) ShL 4) or HexDig (APtr^));\r
+          // HexDig will cause Error if bad hex digit found\r
+         end;\r
+      end;\r
+     else Result := APtr^;\r
+    end;\r
+  end;\r
+\r
+ begin\r
+  Result := nil;\r
+  flagp := WORST; // Tentatively.\r
+\r
+  inc (regparse);\r
+  case (regparse - 1)^ of\r
+    '^': ret := EmitNode (BOL);\r
+    '$': ret := EmitNode (EOL);\r
+    '.':\r
+       if (fCompModifiers and MaskModS) = MaskModS then begin\r
+          ret := EmitNode (ANY);\r
+          flagp := flagp or HASWIDTH or SIMPLE;\r
+         end\r
+        else begin // not /s, so emit [^\n]\r
+          ret := EmitRange (ANYBUT);\r
+          EmitRangeStr (#$a);\r
+          EmitRangeC (#0);\r
+          flagp := flagp or HASWIDTH or SIMPLE;\r
+         end;\r
+    '[': begin\r
+        if regparse^ = '^' then begin // Complement of range.\r
+           if (fCompModifiers and MaskModI) = MaskModI\r
+            then ret := EmitRange (ANYBUTCI)\r
+            else ret := EmitRange (ANYBUT);\r
+           inc (regparse);\r
+          end\r
+         else\r
+          if (fCompModifiers and MaskModI) = MaskModI\r
+           then ret := EmitRange (ANYOFCI)\r
+           else ret := EmitRange (ANYOF);\r
+\r
+        CanBeRange := false;\r
+\r
+        if (regparse^ = ']') then begin\r
+          EmitSimpleRangeC (regparse^); // []-a] -> ']' .. 'a'\r
+          inc (regparse);\r
+         end;\r
+\r
+        while (regparse^ <> #0) and (regparse^ <> ']') do begin\r
+          if (regparse^ = '-')\r
+              and ((regparse + 1)^ <> #0) and ((regparse + 1)^ <> ']')\r
+              and CanBeRange then begin\r
+             inc (regparse);\r
+             RangeEnd := regparse^;\r
+             if RangeEnd = '\' then begin\r
+               {$IFDEF UniCode} //###0.935\r
+               if (ord ((regparse + 1)^) < 256)\r
+                  and (char ((regparse + 1)^)\r
+                        in ['d', 'D', 's', 'S', 'w', 'W']) then begin\r
+               {$ELSE}\r
+               if (regparse + 1)^ in ['d', 'D', 's', 'S', 'w', 'W'] then begin\r
+               {$ENDIF}\r
+                 EmitRangeC ('-'); // or treat as error ?!!\r
+                 CONTINUE;\r
+                end;\r
+               inc (regparse);\r
+               RangeEnd := UnQuoteChar (regparse);\r
+              end;\r
+\r
+             // r.e.ranges extension for russian\r
+             if ((fCompModifiers and MaskModR) = MaskModR)\r
+                and (RangeBeg = RusRangeLoLow) and (RangeEnd = RusRangeLoHigh) then begin\r
+               EmitRangeStr (RusRangeLo);\r
+              end\r
+             else if ((fCompModifiers and MaskModR) = MaskModR)\r
+                 and (RangeBeg = RusRangeHiLow) and (RangeEnd = RusRangeHiHigh) then begin\r
+               EmitRangeStr (RusRangeHi);\r
+              end\r
+             else if ((fCompModifiers and MaskModR) = MaskModR)\r
+                  and (RangeBeg = RusRangeLoLow) and (RangeEnd = RusRangeHiHigh) then begin\r
+               EmitRangeStr (RusRangeLo);\r
+               EmitRangeStr (RusRangeHi);\r
+              end\r
+             else begin // standard r.e. handling\r
+               if RangeBeg > RangeEnd then begin\r
+                 Error (reeInvalidRange);\r
+                 EXIT;\r
+                end;\r
+               inc (RangeBeg);\r
+               EmitRangeC (RangeEnd); // prevent infinite loop if RangeEnd=$ff\r
+               while RangeBeg < RangeEnd do begin //###0.929\r
+                 EmitRangeC (RangeBeg);\r
+                 inc (RangeBeg);\r
+                end;\r
+              end;\r
+             inc (regparse);\r
+            end\r
+           else begin\r
+             if regparse^ = '\' then begin\r
+                inc (regparse);\r
+                if regparse^ = #0 then begin\r
+                  Error (reeParseAtomTrailingBackSlash);\r
+                  EXIT;\r
+                 end;\r
+                case regparse^ of // r.e.extensions\r
+                  'd': EmitRangeStr ('0123456789');\r
+                  'w': EmitRangeStr (WordChars);\r
+                  's': EmitRangeStr (SpaceChars);\r
+                  else EmitSimpleRangeC (UnQuoteChar (regparse));\r
+                 end; { of case}\r
+               end\r
+              else EmitSimpleRangeC (regparse^);\r
+             inc (regparse);\r
+            end;\r
+         end; { of while}\r
+        EmitRangeC (#0);\r
+        if regparse^ <> ']' then begin\r
+          Error (reeUnmatchedSqBrackets);\r
+          EXIT;\r
+         end;\r
+        inc (regparse);\r
+        flagp := flagp or HASWIDTH or SIMPLE;\r
+      end;\r
+    '(': begin\r
+        if regparse^ = '?' then begin\r
+           // check for extended Perl syntax : (?..)\r
+           if (regparse + 1)^ = '#' then begin // (?#comment)\r
+              inc (regparse, 2); // find closing ')'\r
+              while (regparse^ <> #0) and (regparse^ <> ')')\r
+               do inc (regparse);\r
+              if regparse^ <> ')' then begin\r
+                Error (reeUnclosedComment);\r
+                EXIT;\r
+               end;\r
+              inc (regparse); // skip ')'\r
+              ret := EmitNode (COMMENT); // comment\r
+             end\r
+           else begin // modifiers ?\r
+             inc (regparse); // skip '?'\r
+             begmodfs := regparse;\r
+             while (regparse^ <> #0) and (regparse^ <> ')')\r
+              do inc (regparse);\r
+             if (regparse^ <> ')')\r
+                or not SetModifiersInt (copy (begmodfs, 1, (regparse - begmodfs)), fCompModifiers) then begin\r
+               Error (reeUrecognizedModifier);\r
+               EXIT;\r
+              end;\r
+             inc (regparse); // skip ')'\r
+             ret := EmitNode (COMMENT); // comment\r
+//             Error (reeQPSBFollowsNothing);\r
+//             EXIT;\r
+            end;\r
+          end\r
+         else begin\r
+           ret := ParseReg (1, flags);\r
+           if ret = nil then begin\r
+             Result := nil;\r
+             EXIT;\r
+            end;\r
+           flagp := flagp or flags and (HASWIDTH or SPSTART);\r
+          end;\r
+      end;\r
+    #0, '|', ')': begin // Supposed to be caught earlier.\r
+       Error (reeInternalUrp);\r
+       EXIT;\r
+      end;\r
+    '?', '+', '*': begin\r
+       Error (reeQPSBFollowsNothing);\r
+       EXIT;\r
+      end;\r
+    '\': begin\r
+        if regparse^ = #0 then begin\r
+          Error (reeTrailingBackSlash);\r
+          EXIT;\r
+         end;\r
+        case regparse^ of // r.e.extensions\r
+          'd': begin // r.e.extension - any digit ('0' .. '9')\r
+             ret := EmitNode (ANYDIGIT);\r
+             flagp := flagp or HASWIDTH or SIMPLE;\r
+            end;\r
+          'D': begin // r.e.extension - not digit ('0' .. '9')\r
+             ret := EmitNode (NOTDIGIT);\r
+             flagp := flagp or HASWIDTH or SIMPLE;\r
+            end;\r
+          's': begin // r.e.extension - any space char\r
+             {$IFDEF UseSetOfChar}\r
+             ret := EmitRange (ANYOF);\r
+             EmitRangeStr (SpaceChars);\r
+             EmitRangeC (#0);\r
+             {$ELSE}\r
+             ret := EmitNode (ANYSPACE);\r
+             {$ENDIF}\r
+             flagp := flagp or HASWIDTH or SIMPLE;\r
+            end;\r
+          'S': begin // r.e.extension - not space char\r
+             {$IFDEF UseSetOfChar}\r
+             ret := EmitRange (ANYBUT);\r
+             EmitRangeStr (SpaceChars);\r
+             EmitRangeC (#0);\r
+             {$ELSE}\r
+             ret := EmitNode (NOTSPACE);\r
+             {$ENDIF}\r
+             flagp := flagp or HASWIDTH or SIMPLE;\r
+            end;\r
+          'w': begin // r.e.extension - any english char or '_'\r
+             {$IFDEF UseSetOfChar}\r
+             ret := EmitRange (ANYOF);\r
+             EmitRangeStr (WordChars);\r
+             EmitRangeC (#0);\r
+             {$ELSE}\r
+             ret := EmitNode (ANYLETTER);\r
+             {$ENDIF}\r
+             flagp := flagp or HASWIDTH or SIMPLE;\r
+            end;\r
+          'W': begin // r.e.extension - not english char or '_'\r
+             {$IFDEF UseSetOfChar}\r
+             ret := EmitRange (ANYBUT);\r
+             EmitRangeStr (WordChars);\r
+             EmitRangeC (#0);\r
+             {$ELSE}\r
+             ret := EmitNode (NOTLETTER);\r
+             {$ENDIF}\r
+             flagp := flagp or HASWIDTH or SIMPLE;\r
+            end;\r
+           '1' .. '9': begin //###0.936\r
+             if (fCompModifiers and MaskModI) = MaskModI\r
+              then ret := EmitNode (BSUBEXPCI)\r
+              else ret := EmitNode (BSUBEXP);\r
+             EmitC (REChar (ord (regparse^) - ord ('0')));\r
+             flagp := flagp or HASWIDTH or SIMPLE;\r
+            end;\r
+          else EmitExactly (UnQuoteChar (regparse));\r
+         end; { of case}\r
+        inc (regparse);\r
+      end;\r
+    else begin\r
+        dec (regparse);\r
+        len := strcspn (regparse, META);\r
+        if len <= 0 then\r
+         if regparse^ <> '{' then begin\r
+            Error (reeRarseAtomInternalDisaster);\r
+            EXIT;\r
+           end\r
+          else len := strcspn (regparse + 1, META) + 1; // bad {n,m} - compile as EXATLY\r
+        ender := (regparse + len)^;\r
+        if (len > 1)\r
+           and ((ender = '*') or (ender = '+') or (ender = '?') or (ender = '{'))\r
+         then dec (len); // Back off clear of ?+*{ operand.\r
+        flagp := flagp or HASWIDTH;\r
+        if len = 1\r
+         then flagp := flagp or SIMPLE;\r
+        if (fCompModifiers and MaskModI) = MaskModI\r
+         then ret := EmitNode (EXACTLYCI)\r
+         else ret := EmitNode (EXACTLY);\r
+        while len > 0 do begin\r
+          EmitC (regparse^);\r
+          inc (regparse);\r
+          dec (len);\r
+         end;\r
+        EmitC (#0);\r
+      end; { of case else}\r
+   end; { of case}\r
+\r
+  Result := ret;\r
+ end; { of function TRegExpr.ParseAtom\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.GetCompilerErrorPos : integer;\r
+ begin\r
+  Result := 0;\r
+  if (regexpbeg = nil) or (regparse = nil)\r
+   then EXIT; // not in compiling mode ?\r
+  Result := regparse - regexpbeg;\r
+ end; { of function TRegExpr.GetCompilerErrorPos\r
+--------------------------------------------------------------}\r
+\r
+\r
+{=============================================================}\r
+{===================== Matching section ======================}\r
+{=============================================================}\r
+\r
+{$IFNDEF UseSetOfChar}\r
+function TRegExpr.StrScanCI (s : PRegExprChar; ch : REChar) : PRegExprChar; //###0.928 - now method of TRegExpr\r
+ begin\r
+  while (s^ <> #0) and (s^ <> ch) and (s^ <> InvertCase (ch))\r
+   do inc (s);\r
+  if s^ <> #0\r
+   then Result := s\r
+   else Result := nil;\r
+ end; { of function TRegExpr.StrScanCI\r
+--------------------------------------------------------------}\r
+{$ENDIF}\r
+\r
+function TRegExpr.regrepeat (p : PRegExprChar; AMax : integer) : integer;\r
+// repeatedly match something simple, report how many\r
+ var\r
+  scan : PRegExprChar;\r
+  opnd : PRegExprChar;\r
+  TheMax : integer;\r
+  {Ch,} InvCh : REChar; //###0.931\r
+  sestart, seend : PRegExprChar; //###0.936\r
+ begin\r
+  Result := 0;\r
+  scan := reginput;\r
+  opnd := p + REOpSz + RENextOffSz; //OPERAND\r
+  TheMax := fInputEnd - scan;\r
+  if TheMax > AMax\r
+   then TheMax := AMax;\r
+  case PREOp (p)^ of\r
+    ANY: begin\r
+      Result := TheMax;\r
+      inc (scan, Result);\r
+     end;\r
+    EXACTLY: begin // in opnd can be only ONE char !!!\r
+//      Ch := opnd^; // store in register //###0.931\r
+      while (Result < TheMax) and (opnd^ = scan^) do begin\r
+        inc (Result);\r
+        inc (scan);\r
+       end;\r
+     end;\r
+    EXACTLYCI: begin // in opnd can be only ONE char !!!\r
+//      Ch := opnd^; // store in register //###0.931\r
+      while (Result < TheMax) and (opnd^ = scan^) do begin // prevent unneeded InvertCase //###0.931\r
+        inc (Result);\r
+        inc (scan);\r
+       end;\r
+      if Result < TheMax then begin //###0.931\r
+        InvCh := InvertCase (opnd^); // store in register\r
+        while (Result < TheMax) and\r
+              ((opnd^ = scan^) or (InvCh = scan^)) do begin\r
+          inc (Result);\r
+          inc (scan);\r
+         end;\r
+       end;\r
+     end;\r
+    BSUBEXP: begin //###0.936\r
+      sestart := startp [ord (opnd^)];\r
+      if sestart = nil\r
+       then EXIT;\r
+      seend := endp [ord (opnd^)];\r
+      if seend = nil\r
+       then EXIT;\r
+      REPEAT\r
+        opnd := sestart;\r
+        while opnd < seend do begin\r
+          if (scan >= fInputEnd) or (scan^ <> opnd^)\r
+           then EXIT;\r
+          inc (scan);\r
+          inc (opnd);\r
+         end;\r
+        inc (Result);\r
+        reginput := scan;\r
+      UNTIL Result >= AMax;\r
+     end;\r
+    BSUBEXPCI: begin //###0.936\r
+      sestart := startp [ord (opnd^)];\r
+      if sestart = nil\r
+       then EXIT;\r
+      seend := endp [ord (opnd^)];\r
+      if seend = nil\r
+       then EXIT;\r
+      REPEAT\r
+        opnd := sestart;\r
+        while opnd < seend do begin\r
+          if (scan >= fInputEnd) or\r
+             ((scan^ <> opnd^) and (scan^ <> InvertCase (opnd^)))\r
+           then EXIT;\r
+          inc (scan);\r
+          inc (opnd);\r
+         end;\r
+        inc (Result);\r
+        reginput := scan;\r
+      UNTIL Result >= AMax;\r
+     end;\r
+    ANYDIGIT:\r
+      while (Result < TheMax) and\r
+         (scan^ >= '0') and (scan^ <= '9') do begin\r
+        inc (Result);\r
+        inc (scan);\r
+       end;\r
+    NOTDIGIT:\r
+      while (Result < TheMax) and\r
+         ((scan^ < '0') or (scan^ > '9')) do begin\r
+        inc (Result);\r
+        inc (scan);\r
+       end;\r
+    {$IFNDEF UseSetOfChar} //###0.929\r
+    ANYLETTER:\r
+      while (Result < TheMax) and\r
+       // !!!!!?????? if length (fWordChars) <> 0\r
+       // then Pos (scan^, fWordChars)\r
+       // else\r
+       ((scan^ >= 'a') and (scan^ <= 'z')\r
+       or (scan^ >= 'A') and (scan^ <= 'Z') or (scan^ = '_')) do begin\r
+        inc (Result);\r
+        inc (scan);\r
+       end;\r
+    NOTLETTER:\r
+      while (Result < TheMax) and\r
+       // !!!!!?????? if length (fWordChars) <> 0\r
+       // then Pos (scan^, fWordChars)\r
+       // else\r
+        not ((scan^ >= 'a') and (scan^ <= 'z')\r
+         or (scan^ >= 'A') and (scan^ <= 'Z')\r
+         or (scan^ = '_')) do begin\r
+        inc (Result);\r
+        inc (scan);\r
+       end;\r
+    ANYSPACE:\r
+      while (Result < TheMax) and\r
+         (Pos (scan^, fSpaceChars) > 0) do begin\r
+        inc (Result);\r
+        inc (scan);\r
+       end;\r
+    NOTSPACE:\r
+      while (Result < TheMax) and\r
+         (Pos (scan^, fSpaceChars) <= 0) do begin\r
+        inc (Result);\r
+        inc (scan);\r
+       end;\r
+    {$ENDIF}\r
+    ANYOFTINYSET: begin\r
+      while (Result < TheMax) and //!!!TinySet\r
+       ((scan^ = opnd^) or (scan^ = (opnd + 1)^)\r
+        or (scan^ = (opnd + 2)^)) do begin\r
+        inc (Result);\r
+        inc (scan);\r
+       end;\r
+     end;\r
+    ANYBUTTINYSET: begin\r
+      while (Result < TheMax) and //!!!TinySet\r
+       (scan^ <> opnd^) and (scan^ <> (opnd + 1)^)\r
+        and (scan^ <> (opnd + 2)^) do begin\r
+        inc (Result);\r
+        inc (scan);\r
+       end;\r
+     end;\r
+    {$IFDEF UseSetOfChar} //###0.929\r
+    ANYOFFULLSET: begin\r
+      while (Result < TheMax) and\r
+       (scan^ in PSetOfREChar (opnd)^) do begin\r
+        inc (Result);\r
+        inc (scan);\r
+       end;\r
+     end;\r
+    {$ELSE}\r
+    ANYOF:\r
+      while (Result < TheMax) and\r
+         (StrScan (opnd, scan^) <> nil) do begin\r
+        inc (Result);\r
+        inc (scan);\r
+       end;\r
+    ANYBUT:\r
+      while (Result < TheMax) and\r
+         (StrScan (opnd, scan^) = nil) do begin\r
+        inc (Result);\r
+        inc (scan);\r
+       end;\r
+    ANYOFCI:\r
+      while (Result < TheMax) and (StrScanCI (opnd, scan^) <> nil) do begin\r
+        inc (Result);\r
+        inc (scan);\r
+       end;\r
+    ANYBUTCI:\r
+      while (Result < TheMax) and (StrScanCI (opnd, scan^) = nil) do begin\r
+        inc (Result);\r
+        inc (scan);\r
+       end;\r
+    {$ENDIF}\r
+    else begin // Oh dear. Called inappropriately.\r
+      Result := 0; // Best compromise.\r
+      Error (reeRegRepeatCalledInappropriately);\r
+      EXIT;\r
+     end;\r
+   end; { of case}\r
+  reginput := scan;\r
+ end; { of function TRegExpr.regrepeat\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.regnext (p : PRegExprChar) : PRegExprChar;\r
+// dig the "next" pointer out of a node\r
+ var offset : TRENextOff;\r
+ begin\r
+  if p = @regdummy then begin\r
+    Result := nil;\r
+    EXIT;\r
+   end;\r
+  offset := PRENextOff (p + REOpSz)^; //###0.933 inlined NEXT\r
+  if offset = 0\r
+   then Result := nil\r
+   else Result := p + offset;\r
+ end; { of function TRegExpr.regnext\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.MatchPrim (prog : PRegExprChar) : boolean;\r
+// recursively matching routine\r
+// Conceptually the strategy is simple:  check to see whether the current\r
+// node matches, call self recursively to see whether the rest matches,\r
+// and then act accordingly.  In practice we make some effort to avoid\r
+// recursion, in particular by going through "ordinary" nodes (that don't\r
+// need to know whether the rest of the match failed) by a loop instead of\r
+// by recursion.\r
+ var\r
+  scan : PRegExprChar; // Current node.\r
+  next : PRegExprChar; // Next node.\r
+  len : integer;\r
+  opnd : PRegExprChar;\r
+  no : integer;\r
+  save : PRegExprChar;\r
+  nextch : REChar;\r
+  BracesMin, BracesMax : integer; // we use integer instead of TREBracesArg for better support */+\r
+  {$IFDEF ComplexBraces}\r
+  SavedLoopStack : array [1 .. LoopStackMax] of integer; // :(( very bad for recursion\r
+  SavedLoopStackIdx : integer; //###0.925\r
+  {$ENDIF}\r
+ begin\r
+  Result := false;\r
+  scan := prog;\r
+\r
+  while scan <> nil do begin\r
+     len := PRENextOff (scan + 1)^; //###0.932 inlined regnext\r
+     if len = 0\r
+      then next := nil\r
+      else next := scan + len;\r
+\r
+     case scan^ of\r
+         BOL: if reginput <> fInputStart\r
+               then EXIT;\r
+         EOL: if reginput^ <> #0\r
+               then EXIT;\r
+         ANY: begin\r
+            if reginput^ = #0\r
+             then EXIT;\r
+            inc (reginput);\r
+           end;\r
+         ANYDIGIT: begin\r
+            if (reginput^ = #0) or (reginput^ < '0') or (reginput^ > '9')\r
+             then EXIT;\r
+            inc (reginput);\r
+           end;\r
+         NOTDIGIT: begin\r
+            if (reginput^ = #0) or ((reginput^ >= '0') and (reginput^ <= '9'))\r
+             then EXIT;\r
+            inc (reginput);\r
+           end;\r
+         {$IFNDEF UseSetOfChar} //###0.929\r
+         ANYLETTER: begin\r
+            if (reginput^ = #0) or\r
+             // !!!!!?????? Pos (scan^, fWordChars)\r
+             not ((reginput^ >= 'a') and (reginput^ <= 'z')\r
+                 or (reginput^ >= 'A') and (reginput^ <= 'Z')\r
+                 or (reginput^ = '_'))\r
+             then EXIT;\r
+            inc (reginput);\r
+           end;\r
+         NOTLETTER: begin\r
+            if (reginput^ = #0) or\r
+             // !!!!!?????? Pos (scan^, fWordChars)\r
+               (reginput^ >= 'a') and (reginput^ <= 'z')\r
+                 or (reginput^ >= 'A') and (reginput^ <= 'Z')\r
+                 or (reginput^ = '_')\r
+             then EXIT;\r
+            inc (reginput);\r
+           end;\r
+         ANYSPACE: begin\r
+            if (reginput^ = #0) or not (Pos (scan^, fSpaceChars) > 0)\r
+             then EXIT;\r
+            inc (reginput);\r
+           end;\r
+         NOTSPACE: begin\r
+            if (reginput^ = #0) or (Pos (scan^, fSpaceChars) > 0)\r
+             then EXIT;\r
+            inc (reginput);\r
+           end;\r
+         {$ENDIF}\r
+         EXACTLYCI: begin\r
+            opnd := scan + REOpSz + RENextOffSz; // OPERAND\r
+            // Inline the first character, for speed.\r
+            if (opnd^ <> reginput^)\r
+               and (InvertCase (opnd^) <> reginput^)\r
+             then EXIT;\r
+            len := strlen (opnd);\r
+            //###0.929 begin\r
+            no := len;\r
+            save := reginput;\r
+            while no > 1 do begin\r
+              inc (save);\r
+              inc (opnd);\r
+              if (opnd^ <> save^)\r
+                 and (InvertCase (opnd^) <> save^)\r
+               then EXIT;\r
+              dec (no);\r
+             end;\r
+            //###0.929 end\r
+            inc (reginput, len);\r
+           end;\r
+         EXACTLY: begin\r
+            opnd := scan + REOpSz + RENextOffSz; // OPERAND\r
+            // Inline the first character, for speed.\r
+            if opnd^ <> reginput^\r
+             then EXIT;\r
+            len := strlen (opnd);\r
+            //###0.929 begin\r
+            no := len;\r
+            save := reginput;\r
+            while no > 1 do begin\r
+              inc (save);\r
+              inc (opnd);\r
+              if opnd^ <> save^\r
+               then EXIT;\r
+              dec (no);\r
+             end;\r
+            //###0.929 end\r
+            inc (reginput, len);\r
+           end;\r
+         BSUBEXP: begin //###0.936\r
+           no := ord ((scan + REOpSz + RENextOffSz)^);\r
+           if startp [no] = nil\r
+            then EXIT;\r
+           if endp [no] = nil\r
+            then EXIT;\r
+           save := reginput;\r
+           opnd := startp [no];\r
+           while opnd < endp [no] do begin\r
+             if (save >= fInputEnd) or (save^ <> opnd^)\r
+              then EXIT;\r
+             inc (save);\r
+             inc (opnd);\r
+            end;\r
+           reginput := save;\r
+          end;\r
+         BSUBEXPCI: begin //###0.936\r
+           no := ord ((scan + REOpSz + RENextOffSz)^);\r
+           if startp [no] = nil\r
+            then EXIT;\r
+           if endp [no] = nil\r
+            then EXIT;\r
+           save := reginput;\r
+           opnd := startp [no];\r
+           while opnd < endp [no] do begin\r
+             if (save >= fInputEnd) or\r
+                ((save^ <> opnd^) and (save^ <> InvertCase (opnd^)))\r
+              then EXIT;\r
+             inc (save);\r
+             inc (opnd);\r
+            end;\r
+           reginput := save;\r
+          end;\r
+         ANYOFTINYSET: begin\r
+           if (reginput^ = #0) or //!!!TinySet\r
+             ((reginput^ <> (scan + REOpSz + RENextOffSz)^)\r
+             and (reginput^ <> (scan + REOpSz + RENextOffSz + 1)^)\r
+             and (reginput^ <> (scan + REOpSz + RENextOffSz + 2)^))\r
+            then EXIT;\r
+           inc (reginput);\r
+          end;\r
+         ANYBUTTINYSET: begin\r
+           if (reginput^ = #0) or //!!!TinySet\r
+             (reginput^ = (scan + REOpSz + RENextOffSz)^)\r
+             or (reginput^ = (scan + REOpSz + RENextOffSz + 1)^)\r
+             or (reginput^ = (scan + REOpSz + RENextOffSz + 2)^)\r
+            then EXIT;\r
+           inc (reginput);\r
+          end;\r
+         {$IFDEF UseSetOfChar} //###0.929\r
+         ANYOFFULLSET: begin\r
+           if (reginput^ = #0)\r
+              or not (reginput^ in PSetOfREChar (scan + REOpSz + RENextOffSz)^)\r
+            then EXIT;\r
+           inc (reginput);\r
+          end;\r
+         {$ELSE}\r
+         ANYOF: begin\r
+            if (reginput^ = #0) or (StrScan (scan + REOpSz + RENextOffSz, reginput^) = nil)\r
+             then EXIT;\r
+            inc (reginput);\r
+           end;\r
+         ANYBUT: begin\r
+            if (reginput^ = #0) or (StrScan (scan + REOpSz + RENextOffSz, reginput^) <> nil)\r
+             then EXIT;\r
+            inc (reginput);\r
+           end;\r
+         ANYOFCI: begin\r
+            if (reginput^ = #0) or (StrScanCI (scan + REOpSz + RENextOffSz, reginput^) = nil)\r
+             then EXIT;\r
+            inc (reginput);\r
+           end;\r
+         ANYBUTCI: begin\r
+            if (reginput^ = #0) or (StrScanCI (scan + REOpSz + RENextOffSz, reginput^) <> nil)\r
+             then EXIT;\r
+            inc (reginput);\r
+           end;\r
+         {$ENDIF}\r
+         NOTHING: ;\r
+         COMMENT: ;\r
+         BACK: ;\r
+         Succ (OPEN) .. TREOp (Ord (OPEN) + NSUBEXP - 1) : begin //###0.929\r
+            no := ord (scan^) - ord (OPEN);\r
+//            save := reginput;\r
+            save := startp [no]; //###0.936\r
+            startp [no] := reginput; //###0.936\r
+            Result := MatchPrim (next);\r
+            if not Result //###0.936\r
+             then startp [no] := save;\r
+//            if Result and (startp [no] = nil)\r
+//             then startp [no] := save;\r
+             // Don't set startp if some later invocation of the same\r
+             // parentheses already has.\r
+            EXIT;\r
+           end;\r
+         Succ (CLOSE) .. TREOp (Ord (CLOSE) + NSUBEXP - 1): begin //###0.929\r
+            no := ord (scan^) - ord (CLOSE);\r
+//            save := reginput;\r
+            save := endp [no]; //###0.936\r
+            endp [no] := reginput; //###0.936\r
+            Result := MatchPrim (next);\r
+            if not Result //###0.936\r
+             then endp [no] := save;\r
+//            if Result and (endp [no] = nil)\r
+//             then endp [no] := save;\r
+             // Don't set endp if some later invocation of the same\r
+             // parentheses already has.\r
+            EXIT;\r
+           end;\r
+         BRANCH: begin\r
+            if (next^ <> BRANCH) // No choice.\r
+             then next := scan + REOpSz + RENextOffSz // Avoid recursion\r
+             else begin\r
+               REPEAT\r
+                save := reginput;\r
+                Result := MatchPrim (scan + REOpSz + RENextOffSz);\r
+                if Result\r
+                 then EXIT;\r
+                reginput := save;\r
+                scan := regnext (scan);\r
+               UNTIL (scan = nil) or (scan^ <> BRANCH);\r
+               EXIT;\r
+              end;\r
+           end;\r
+         {$IFDEF ComplexBraces}\r
+         LOOPENTRY: begin //###0.925\r
+           no := LoopStackIdx;\r
+           inc (LoopStackIdx);\r
+           if LoopStackIdx > LoopStackMax then begin\r
+             Error (reeLoopStackExceeded);\r
+             EXIT;\r
+            end;\r
+           save := reginput;\r
+           LoopStack [LoopStackIdx] := 0; // init loop counter\r
+           Result := MatchPrim (next); // execute LOOP\r
+           LoopStackIdx := no; // cleanup\r
+           if Result\r
+            then EXIT;\r
+           reginput := save;\r
+           EXIT;\r
+          end;\r
+         LOOP: begin //###0.925\r
+           if LoopStackIdx <= 0 then begin\r
+             Error (reeLoopWithoutEntry);\r
+             EXIT;\r
+            end;\r
+           opnd := scan + PRENextOff (scan + REOpSz + RENextOffSz + 2 * REBracesArgSz)^;\r
+           BracesMin := PREBracesArg (scan + REOpSz + RENextOffSz)^;\r
+           BracesMax := PREBracesArg (scan + REOpSz + RENextOffSz + REBracesArgSz)^;\r
+           save := reginput;\r
+           if LoopStack [LoopStackIdx] >= BracesMin then begin\r
+              // greedy way ;)\r
+              if LoopStack [LoopStackIdx] < BracesMax then begin\r
+                inc (LoopStack [LoopStackIdx]);\r
+                no := LoopStackIdx;\r
+                Result := MatchPrim (opnd);\r
+                LoopStackIdx := no;\r
+                if Result\r
+                 then EXIT;\r
+                reginput := save;\r
+               end;\r
+              dec (LoopStackIdx);\r
+              Result := MatchPrim (next);\r
+              if not Result\r
+               then reginput := save;\r
+              EXIT;\r
+             end\r
+            else begin // first match a min_cnt times\r
+              inc (LoopStack [LoopStackIdx]);\r
+              no := LoopStackIdx;\r
+              Result := MatchPrim (opnd);\r
+              LoopStackIdx := no;\r
+              if Result\r
+               then EXIT;\r
+              dec (LoopStack [LoopStackIdx]);\r
+              reginput := save;\r
+              EXIT;\r
+             end;\r
+          end;\r
+         {$ENDIF}\r
+         STAR, PLUS, BRACES: begin\r
+                // Lookahead to avoid useless match attempts when we know\r
+                // what character comes next.\r
+                nextch := #0;\r
+                if next^ = EXACTLY\r
+                 then nextch := (next + REOpSz + RENextOffSz)^;\r
+                BracesMax := MaxInt; // infinite loop for * and + //###0.92\r
+                if scan^ = STAR\r
+                 then BracesMin := 0  // STAR\r
+                 else if scan^ = PLUS\r
+                  then BracesMin := 1 // PLUS\r
+                  else begin // BRACES\r
+                    BracesMin := PREBracesArg (scan + REOpSz + RENextOffSz)^;\r
+                    BracesMax := PREBracesArg (scan + REOpSz + RENextOffSz + REBracesArgSz)^;\r
+                   end;\r
+                save := reginput;\r
+                opnd := scan + REOpSz + RENextOffSz;\r
+                if scan^ = BRACES\r
+                 then inc (opnd, 2 * REBracesArgSz);\r
+                no := regrepeat (opnd, BracesMax); // don't repeat more than max_cnt\r
+                while no >= BracesMin do begin\r
+                  // If it could work, try it.\r
+                  if (nextch = #0) or (reginput^ = nextch) then begin\r
+                    {$IFDEF ComplexBraces}\r
+                    System.Move (LoopStack, SavedLoopStack, SizeOf (LoopStack)); //###0.925\r
+                    SavedLoopStackIdx := LoopStackIdx;\r
+                    {$ENDIF}\r
+                    if MatchPrim (next) then begin\r
+                      Result := true;\r
+                      EXIT;\r
+                     end;\r
+                    {$IFDEF ComplexBraces}\r
+                    System.Move (SavedLoopStack, LoopStack, SizeOf (LoopStack));\r
+                    LoopStackIdx := SavedLoopStackIdx;\r
+                    {$ENDIF}\r
+                   end;\r
+                  dec (no); // Couldn't or didn't - back up.\r
+                  reginput := save + no;\r
+                 end; { of while}\r
+                EXIT;\r
+           end;\r
+         EEND: begin\r
+            Result := true;  // Success!\r
+            EXIT;\r
+           end;\r
+        else begin\r
+            Error (reeMatchPrimMemoryCorruption);\r
+            EXIT;\r
+          end;\r
+        end; { of case scan^}\r
+        scan := next;\r
+    end; { of while scan <> nil}\r
+\r
+  // We get here only if there's trouble -- normally "case EEND" is the\r
+  // terminating point.\r
+  Error (reeMatchPrimCorruptedPointers);\r
+ end; { of function TRegExpr.MatchPrim\r
+--------------------------------------------------------------}\r
+\r
+{$IFDEF UseFirstCharSet} //###0.929\r
+procedure TRegExpr.FillFirstCharSet (prog : PRegExprChar);\r
+ var\r
+  scan : PRegExprChar; // Current node.\r
+  next : PRegExprChar; // Next node.\r
+  opnd : PRegExprChar;\r
+  min_cnt : integer;\r
+ begin\r
+  scan := prog;\r
+  while scan <> nil do begin\r
+     next := regnext (scan);\r
+     case PREOp (scan)^ of\r
+         BSUBEXP, BSUBEXPCI: begin //###0.938\r
+           FirstCharSet := [#0 .. #255]; // :((( we cannot\r
+           // optimize r.e. if it starts with back reference\r
+           EXIT;\r
+          end;\r
+         BOL: ; // EXIT; //###0.937\r
+         EOL: ; // EXIT; //###0.937\r
+         ANY: begin\r
+           FirstCharSet := [#0 .. #255]; //###0.930\r
+           EXIT;\r
+          end;\r
+         ANYDIGIT: begin\r
+           FirstCharSet := FirstCharSet + ['0' .. '9'];\r
+           EXIT;\r
+          end;\r
+         NOTDIGIT: begin\r
+           FirstCharSet := [#0 .. #255] - ['0' .. '9'];\r
+           EXIT;\r
+          end;\r
+         EXACTLYCI: begin\r
+           Include (FirstCharSet, (scan + REOpSz + RENextOffSz)^);\r
+           Include (FirstCharSet, InvertCase ((scan + REOpSz + RENextOffSz)^));\r
+           EXIT;\r
+          end;\r
+         EXACTLY: begin\r
+           Include (FirstCharSet, (scan + REOpSz + RENextOffSz)^);\r
+           EXIT;\r
+          end;\r
+         ANYOFFULLSET: begin\r
+           FirstCharSet := FirstCharSet + PSetOfREChar (scan + REOpSz + RENextOffSz)^;\r
+           EXIT;\r
+          end;\r
+         ANYOFTINYSET: begin\r
+           //!!!TinySet\r
+           Include (FirstCharSet, (scan + REOpSz + RENextOffSz)^);\r
+           Include (FirstCharSet, (scan + REOpSz + RENextOffSz + 1)^);\r
+           Include (FirstCharSet, (scan + REOpSz + RENextOffSz + 2)^);\r
+           // ...                                                      // up to TinySetLen\r
+           EXIT;\r
+          end;\r
+         ANYBUTTINYSET: begin\r
+           //!!!TinySet\r
+           FirstCharSet := [#0 .. #255];\r
+           Exclude (FirstCharSet, (scan + REOpSz + RENextOffSz)^);\r
+           Exclude (FirstCharSet, (scan + REOpSz + RENextOffSz + 1)^);\r
+           Exclude (FirstCharSet, (scan + REOpSz + RENextOffSz + 2)^);\r
+           // ...                                                      // up to TinySetLen\r
+           EXIT;\r
+          end;\r
+         NOTHING: ;\r
+         COMMENT: ;\r
+         BACK: ;\r
+         Succ (OPEN) .. TREOp (Ord (OPEN) + NSUBEXP - 1) : begin //###0.929\r
+            FillFirstCharSet (next);\r
+            EXIT;\r
+           end;\r
+         Succ (CLOSE) .. TREOp (Ord (CLOSE) + NSUBEXP - 1): begin //###0.929\r
+            FillFirstCharSet (next);\r
+            EXIT;\r
+           end;\r
+         BRANCH: begin\r
+            if (PREOp (next)^ <> BRANCH) // No choice.\r
+             then next := scan + REOpSz + RENextOffSz // Avoid recursion.\r
+             else begin\r
+               REPEAT\r
+                FillFirstCharSet (scan + REOpSz + RENextOffSz);\r
+                scan := regnext (scan);\r
+               UNTIL (scan = nil) or (PREOp (scan)^ <> BRANCH);\r
+               EXIT;\r
+              end;\r
+           end;\r
+         {$IFDEF ComplexBraces}\r
+         LOOPENTRY: begin //###0.925\r
+           LoopStack [LoopStackIdx] := 0; // init loop counter\r
+           FillFirstCharSet (next); // execute LOOP\r
+           EXIT;\r
+          end;\r
+         LOOP: begin //###0.925\r
+           opnd := scan + PRENextOff (scan + REOpSz + RENextOffSz + REBracesArgSz * 2)^;\r
+           min_cnt := PREBracesArg (scan + REOpSz + RENextOffSz)^;\r
+           FillFirstCharSet (opnd);\r
+           if min_cnt = 0\r
+            then FillFirstCharSet (next);\r
+           EXIT;\r
+          end;\r
+         {$ENDIF}\r
+         STAR:\r
+           FillFirstCharSet (scan + REOpSz + RENextOffSz);\r
+         PLUS: begin\r
+           FillFirstCharSet (scan + REOpSz + RENextOffSz);\r
+           EXIT;\r
+          end;\r
+         BRACES: begin\r
+           opnd := scan + REOpSz + RENextOffSz + REBracesArgSz * 2;\r
+           min_cnt := PREBracesArg (scan + REOpSz + RENextOffSz)^; // BRACES\r
+           FillFirstCharSet (opnd);\r
+           if min_cnt > 0\r
+            then EXIT;\r
+          end;\r
+         EEND: begin\r
+            EXIT;\r
+           end;\r
+        else begin\r
+            Error (reeMatchPrimMemoryCorruption);\r
+            EXIT;\r
+          end;\r
+        end; { of case scan^}\r
+        scan := next;\r
+    end; { of while scan <> nil}\r
+ end; { of procedure FillFirstCharSet;\r
+--------------------------------------------------------------}\r
+{$ENDIF}\r
+\r
+function TRegExpr.RegMatch (str : PRegExprChar) : boolean;\r
+// try match at specific point\r
+ var i : integer;\r
+ begin\r
+  for i := 0 to NSUBEXP - 1 do begin\r
+    startp [i] := nil;\r
+    endp [i] := nil;\r
+   end;\r
+  reginput := str;\r
+  Result := MatchPrim (programm + REOpSz);\r
+  if Result then begin\r
+    startp [0] := str;\r
+    endp [0] := reginput;\r
+   end;\r
+ end; { of function TRegExpr.RegMatch\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.Exec (const AInputString : RegExprString) : boolean;\r
+ begin\r
+  InputString := AInputString;\r
+  Result := ExecPrim (1);\r
+ end; { of function TRegExpr.Exec\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.ExecPrim (AOffset: integer) : boolean;\r
+ var\r
+  s : PRegExprChar;\r
+  StartPtr: PRegExprChar;\r
+  InputLen : integer;\r
+ begin\r
+  Result := false; // Be paranoid...\r
+\r
+  if not IsProgrammOk //###0.929\r
+   then EXIT;\r
+\r
+  // Check InputString presence\r
+  if not Assigned (fInputString) then begin\r
+    Error (reeNoInpitStringSpecified);\r
+    EXIT;\r
+   end;\r
+\r
+  InputLen := length (fInputString);\r
+\r
+  //Check that the start position is not negative\r
+  if AOffset < 1 then begin\r
+    Error (reeOffsetMustBeGreaterThen0);\r
+    EXIT;\r
+   end;\r
+  // Check that the start position is not longer than the line\r
+  // If so then exit with nothing found\r
+  if AOffset > (InputLen + 1) // for matching empty string after last char.\r
+   then EXIT;\r
+\r
+  StartPtr := fInputString + AOffset - 1;\r
+\r
+  // If there is a "must appear" string, look for it.\r
+  if regmust <> nil then begin\r
+    s := StartPtr;\r
+    REPEAT\r
+     s := StrScan (s, regmust [0]);\r
+     if s <> nil then begin\r
+       if StrLComp (s, regmust, regmlen) = 0\r
+        then BREAK; // Found it.\r
+       inc (s);\r
+      end;\r
+    UNTIL s = nil;\r
+    if s = nil // Not present.\r
+     then EXIT;\r
+   end;\r
+\r
+  // Mark beginning of line for ^ .\r
+  fInputStart := fInputString;\r
+\r
+  // Pointer to end of input stream - for\r
+  // pascal-style string processing (may include #0)\r
+  fInputEnd := fInputString + InputLen;\r
+\r
+  {$IFDEF ComplexBraces}\r
+  // no loops started\r
+  LoopStackIdx := 0; //###0.925\r
+  {$ENDIF}\r
+\r
+  // Simplest case:  anchored match need be tried only once.\r
+  if reganch <> #0 then begin\r
+    Result := RegMatch (StartPtr);\r
+    EXIT;\r
+   end;\r
+\r
+  // Messy cases:  unanchored match.\r
+  s := StartPtr;\r
+  if regstart <> #0 then // We know what char it must start with.\r
+    REPEAT\r
+     s := StrScan (s, regstart);\r
+     if s <> nil then begin\r
+       Result := RegMatch (s);\r
+       if Result\r
+        then EXIT;\r
+       inc (s);\r
+      end;\r
+    UNTIL s = nil\r
+   else begin // We don't - general case.\r
+     {$IFDEF UseFirstCharSet} //###0.929\r
+     while s^ <> #0 do begin\r
+       if s^ in FirstCharSet\r
+        then Result := RegMatch (s);\r
+       if Result\r
+        then EXIT;\r
+       inc (s);\r
+      end;\r
+     {$ELSE}\r
+     REPEAT\r
+      Result := RegMatch (s);\r
+      if Result\r
+       then EXIT;\r
+      inc (s);\r
+     UNTIL s^ = #0;\r
+     {$ENDIF}\r
+    end;\r
+  // Failure\r
+ end; { of function TRegExpr.ExecPrim\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.ExecNext : boolean;\r
+ var offset : integer;\r
+ begin\r
+  Result := false;\r
+  if not Assigned (startp[0]) or not Assigned (endp[0]) then begin\r
+    Error (reeExecNextWithoutExec);\r
+    EXIT;\r
+   end;\r
+//  Offset := MatchPos [0] + MatchLen [0];\r
+//  if MatchLen [0] = 0\r
+  Offset := endp [0] - fInputString + 1; //###0.929\r
+  if endp [0] = startp [0] //###0.929\r
+   then inc (Offset); // prevent infinite looping if empty string match r.e.\r
+  Result := ExecPrim (Offset);\r
+ end; { of function TRegExpr.ExecNext\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.ExecPos (AOffset: integer {$IFDEF D4_}= 1{$ENDIF}) : boolean;\r
+ begin\r
+  Result := ExecPrim (AOffset);\r
+ end; { of function TRegExpr.ExecPos\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.GetInputString : RegExprString;\r
+ begin\r
+  if not Assigned (fInputString) then begin\r
+    Error (reeGetInputStringWithoutInputString);\r
+    EXIT;\r
+   end;\r
+  Result := fInputString;\r
+ end; { of function TRegExpr.GetInputString\r
+--------------------------------------------------------------}\r
+\r
+procedure TRegExpr.SetInputString (const AInputString : RegExprString);\r
+ var\r
+  Len : integer;\r
+  i : integer;\r
+ begin\r
+  // clear Match* - before next Exec* call it's undefined\r
+  for i := 0 to NSUBEXP - 1 do begin\r
+    startp [i] := nil;\r
+    endp [i] := nil;\r
+   end;\r
+\r
+  // need reallocation of input string buffer ?\r
+  Len := length (AInputString);\r
+  if Assigned (fInputString) and (Length (fInputString) <> Len) then begin\r
+    FreeMem (fInputString);\r
+    fInputString := nil;\r
+   end;\r
+  // buffer [re]allocation\r
+  if not Assigned (fInputString)\r
+   then GetMem (fInputString, (Len + 1) * SizeOf (REChar));\r
+\r
+  // copy input string into buffer\r
+  {$IFDEF UniCode}\r
+  StrPCopy (fInputString, Copy (AInputString, 1, Len)); //###0.927\r
+  {$ELSE}\r
+  StrLCopy (fInputString, PRegExprChar (AInputString), Len);\r
+  {$ENDIF}\r
+\r
+  {\r
+  fInputString : string;\r
+  fInputStart, fInputEnd : PRegExprChar;\r
+\r
+  SetInputString:\r
+  fInputString := AInputString;\r
+  UniqueString (fInputString);\r
+  fInputStart := PChar (fInputString);\r
+  Len := length (fInputString);\r
+  fInputEnd := PRegExprChar (integer (fInputStart) + Len); ??\r
+  !! startp/endp âñå ðàâíî áóäåò îïàñíî èñïîëüçîâàòü ?\r
+  }\r
+ end; { of procedure TRegExpr.SetInputString\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.Substitute (const ATemplate : RegExprString) : RegExprString;\r
+// perform substitutions after a regexp match\r
+// completely rewritten in 0.929\r
+ var\r
+  TemplateLen : integer;\r
+  TemplateBeg, TemplateEnd : PRegExprChar;\r
+  p, p0, ResultPtr : PRegExprChar;\r
+  ResultLen : integer;\r
+  n : integer;\r
+  Ch : REChar;\r
+ function ParseVarName (var APtr : PRegExprChar) : integer;\r
+  // extract name of variable (digits, may be enclosed with\r
+  // curly braces) from APtr^, uses TemplateEnd !!!\r
+  const\r
+   Digits = ['0' .. '9'];\r
+  var\r
+   p : PRegExprChar;\r
+   Delimited : boolean;\r
+  begin\r
+   Result := 0;\r
+   p := APtr;\r
+   Delimited := (p < TemplateEnd) and (p^ = '{');\r
+   if Delimited\r
+    then inc (p); // skip left curly brace\r
+   if (p < TemplateEnd) and (p^ = '&')\r
+    then inc (p) // this is '$&' or '${&}'\r
+    else\r
+     while (p < TemplateEnd) and\r
+      {$IFDEF UniCode} //###0.935\r
+      (ord (p^) < 256) and (char (p^) in Digits)\r
+      {$ELSE}\r
+      (p^ in Digits)\r
+      {$ENDIF}\r
+       do begin\r
+       inc (Result, ord (p^) - ord ('0'));\r
+       inc (p);\r
+      end;\r
+   if Delimited then\r
+    if (p < TemplateEnd) and (p^ = '}')\r
+     then inc (p) // skip right curly brace\r
+     else p := APtr; // isn't properly terminated\r
+   if p = APtr\r
+    then Result := -1; // no valid digits found or no right curly brace\r
+   APtr := p;\r
+  end;\r
+ begin\r
+  // Check programm and input string\r
+  if not IsProgrammOk\r
+   then EXIT;\r
+  if not Assigned (fInputString) then begin\r
+    Error (reeNoInpitStringSpecified);\r
+    EXIT;\r
+   end;\r
+  // Prepare for working\r
+  TemplateLen := length (ATemplate);\r
+  if TemplateLen = 0 then begin // prevent nil pointers\r
+    Result := '';\r
+    EXIT;\r
+   end;\r
+  TemplateBeg := pointer (ATemplate);\r
+  TemplateEnd := TemplateBeg + TemplateLen;\r
+  // Count result length for speed optimization.\r
+  ResultLen := 0;\r
+  p := TemplateBeg;\r
+  while p < TemplateEnd do begin\r
+    Ch := p^;\r
+    inc (p);\r
+    if Ch = '$'\r
+     then n := ParseVarName (p)\r
+     else n := -1;\r
+    if n >= 0 then begin\r
+       if (n < NSUBEXP) and Assigned (startp [n]) and Assigned (endp [n])\r
+        then inc (ResultLen, endp [n] - startp [n]);\r
+      end\r
+     else begin\r
+       if (Ch = '\') and (p < TemplateEnd)\r
+        then inc (p); // quoted or special char followed\r
+       inc (ResultLen);\r
+      end;\r
+   end;\r
+  // Get memory. We do it once and it significant speed up work !\r
+  if ResultLen = 0 then begin\r
+    Result := '';\r
+    EXIT;\r
+   end;\r
+  SetString (Result, nil, ResultLen);\r
+  // Fill Result\r
+  ResultPtr := pointer (Result);\r
+  p := TemplateBeg;\r
+  while p < TemplateEnd do begin\r
+    Ch := p^;\r
+    inc (p);\r
+    if Ch = '$'\r
+     then n := ParseVarName (p)\r
+     else n := -1;\r
+    if n >= 0 then begin\r
+       p0 := startp [n];\r
+       if (n < NSUBEXP) and Assigned (p0) and Assigned (endp [n]) then\r
+        while p0 < endp [n] do begin\r
+          ResultPtr^ := p0^;\r
+          inc (ResultPtr);\r
+          inc (p0);\r
+         end;\r
+      end\r
+     else begin\r
+       if (Ch = '\') and (p < TemplateEnd) then begin // quoted or special char followed\r
+         Ch := p^;\r
+         inc (p);\r
+        end;\r
+       ResultPtr^ := Ch;\r
+       inc (ResultPtr);\r
+      end;\r
+   end;\r
+ end; { of function TRegExpr.Substitute\r
+--------------------------------------------------------------}\r
+\r
+(*\r
+function TRegExpr.Substitute (const ATemplate : RegExprString) : RegExprString;\r
+// perform substitutions after a regexp match\r
+ var\r
+  src : integer; // PRegExprChar; //###0.927\r
+  c, c2 : REChar;\r
+  no : integer;\r
+ begin\r
+  Result := '';\r
+\r
+  if not IsProgrammOk //###0.929\r
+   then EXIT;\r
+\r
+  src := 1; // PRegExprChar (ATemplate); //###0.927\r
+  while src <= Length (ATemplate) { ^ <> #0} do begin //###0.927\r
+    c := ATemplate [src]; // src^; //###0.927\r
+    inc (src);\r
+    c2 := ATemplate [src]; //###0.927\r
+    if c = '&'\r
+     then no := 0\r
+     else if (c = '\') and ('0' <= c2) and (c2 <= '9')\r
+          then begin\r
+              no := ord (c2) - ord ('0');\r
+              inc (src);\r
+             end\r
+          else no := -1;\r
+\r
+    if no < 0 then begin // Ordinary character.\r
+       if (c = '\') and ((c2 = '\') or (c2 = '&')) then begin\r
+         c := c2; // src^;\r
+         inc (src);\r
+        end;\r
+       Result := Result + c;\r
+      end\r
+     else Result := Result + Match [no]; //###0.90\r
+   end;\r
+ end; { of function TRegExpr.Substitute\r
+--------------------------------------------------------------}\r
+*)\r
+\r
+procedure TRegExpr.Split (AInputStr : RegExprString; APieces : TStrings);\r
+ var PrevPos : integer;\r
+ begin\r
+  PrevPos := 1;\r
+  if Exec (AInputStr) then\r
+   REPEAT\r
+    APieces.Add (System.Copy (AInputStr, PrevPos, MatchPos [0] - PrevPos));\r
+    PrevPos := MatchPos [0] + MatchLen [0];\r
+   UNTIL not ExecNext;\r
+  APieces.Add (System.Copy (AInputStr, PrevPos, MaxInt)); // Tail\r
+ end; { of procedure TRegExpr.Split\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.Replace (AInputStr : RegExprString; const AReplaceStr : RegExprString) : RegExprString;\r
+ var PrevPos : integer;\r
+ begin\r
+  Result := '';\r
+  PrevPos := 1;\r
+  if Exec (AInputStr) then\r
+   REPEAT\r
+    Result := Result + System.Copy (AInputStr, PrevPos,\r
+      MatchPos [0] - PrevPos) + AReplaceStr;\r
+    PrevPos := MatchPos [0] + MatchLen [0];\r
+   UNTIL not ExecNext;\r
+  Result := Result + System.Copy (AInputStr, PrevPos, MaxInt); // Tail\r
+ end; { of function TRegExpr.Replace\r
+--------------------------------------------------------------}\r
+\r
+\r
+{=============================================================}\r
+{====================== Debug section ========================}\r
+{=============================================================}\r
+\r
+{$IFDEF DebugRegExpr}\r
+function TRegExpr.DumpOp (op : TREOp) : RegExprString;\r
+// printable representation of opcode\r
+ begin\r
+  case op of\r
+    BOL:          Result := 'BOL';\r
+    EOL:          Result := 'EOL';\r
+    ANY:          Result := 'ANY';\r
+    ANYLETTER:    Result := 'ANYLETTER';\r
+    NOTLETTER:    Result := 'NOTLETTER';\r
+    ANYDIGIT:     Result := 'ANYDIGIT';\r
+    NOTDIGIT:     Result := 'NOTDIGIT';\r
+    ANYSPACE:     Result := 'ANYSPACE';\r
+    NOTSPACE:     Result := 'NOTSPACE';\r
+    ANYOF:        Result := 'ANYOF';\r
+    ANYBUT:       Result := 'ANYBUT';\r
+    ANYOFCI:      Result := 'ANYOF/CI';\r
+    ANYBUTCI:     Result := 'ANYBUT/CI';\r
+    BRANCH:       Result := 'BRANCH';\r
+    EXACTLY:      Result := 'EXACTLY';\r
+    EXACTLYCI:    Result := 'EXACTLY/CI';\r
+    NOTHING:      Result := 'NOTHING';\r
+    COMMENT:      Result := 'COMMENT';\r
+    BACK:         Result := 'BACK';\r
+    EEND:         Result := 'END';\r
+    BSUBEXP:      Result := 'BSUBEXP';\r
+    BSUBEXPCI:    Result := 'BSUBEXP/CI';\r
+    Succ (OPEN) .. TREOp (Ord (OPEN) + NSUBEXP - 1): //###0.929\r
+                  Result := Format ('OPEN[%d]', [ord (op) - ord (OPEN)]);\r
+    Succ (CLOSE) .. TREOp (Ord (CLOSE) + NSUBEXP - 1): //###0.929\r
+                  Result := Format ('CLOSE[%d]', [ord (op) - ord (CLOSE)]);\r
+    STAR:         Result := 'STAR';\r
+    PLUS:         Result := 'PLUS';\r
+    BRACES:       Result := 'BRACES';\r
+    {$IFDEF ComplexBraces}\r
+    LOOPENTRY:    Result := 'LOOPENTRY'; //###0.925\r
+    LOOP:         Result := 'LOOP'; //###0.925\r
+    {$ENDIF}\r
+    ANYOFTINYSET: Result:= 'ANYOFTINYSET';\r
+    ANYBUTTINYSET:Result:= 'ANYBUTTINYSET';\r
+    {$IFDEF UseSetOfChar} //###0.929\r
+    ANYOFFULLSET: Result:= 'ANYOFFULLSET';\r
+    {$ENDIF}\r
+    else Error (reeDumpCorruptedOpcode);\r
+   end; {of case op}\r
+  Result := ':' + Result;\r
+ end; { of function TRegExpr.DumpOp\r
+--------------------------------------------------------------}\r
+\r
+function TRegExpr.Dump : RegExprString;\r
+// dump a regexp in vaguely comprehensible form\r
+ var\r
+  s : PRegExprChar;\r
+  op : TREOp; // Arbitrary non-END op.\r
+  next : PRegExprChar;\r
+  i : integer;\r
+{$IFDEF UseSetOfChar} //###0.929\r
+  Ch : REChar;\r
+{$ENDIF}\r
+ begin\r
+  if not IsProgrammOk //###0.929\r
+   then EXIT;\r
+\r
+  op := EXACTLY;\r
+  Result := '';\r
+  s := programm + REOpSz;\r
+  while op <> EEND do begin // While that wasn't END last time...\r
+     op := s^;\r
+     Result := Result + Format ('%2d%s', [s - programm, DumpOp (s^)]); // Where, what.\r
+     next := regnext (s);\r
+     if next = nil // Next ptr.\r
+      then Result := Result + ' (0)'\r
+      else Result := Result + Format (' (%d) ', [(s - programm) + (next - s)]);\r
+     inc (s, REOpSz + RENextOffSz);\r
+     if (op = ANYOF) or (op = ANYOFCI) or (op = ANYBUT) or (op = ANYBUTCI)\r
+        or (op = EXACTLY) or (op = EXACTLYCI) then begin\r
+         // Literal string, where present.\r
+         while s^ <> #0 do begin\r
+           Result := Result + s^;\r
+           inc (s);\r
+          end;\r
+         inc (s);\r
+      end;\r
+     if (op = ANYOFTINYSET) or (op = ANYBUTTINYSET) then begin\r
+       for i := 1 to TinySetLen do begin\r
+         Result := Result + s^;\r
+         inc (s);\r
+        end;\r
+      end;\r
+     if (op = BSUBEXP) or (op = BSUBEXPCI) then begin\r
+       Result := Result + ' \' + IntToStr (Ord (s^));\r
+       inc (s);\r
+      end;\r
+     {$IFDEF UseSetOfChar} //###0.929\r
+     if op = ANYOFFULLSET then begin\r
+       for Ch := #0 to #255 do\r
+        if Ch in PSetOfREChar (s)^ then\r
+         if Ch < ' '\r
+          then Result := Result + '#' + IntToStr (Ord (Ch)) //###0.936\r
+          else Result := Result + Ch;\r
+       inc (s, SizeOf (TSetOfREChar));\r
+      end;\r
+     {$ENDIF}\r
+     if (op = BRACES) then begin\r
+       // show min/max argument of BRACES operator\r
+       Result := Result + Format ('{%d,%d}', [PREBracesArg (s)^, PREBracesArg (s + REBracesArgSz)^]);\r
+       inc (s, REBracesArgSz * 2);\r
+      end;\r
+     {$IFDEF ComplexBraces}\r
+     if op = LOOP then begin //###0.925\r
+       Result := Result + Format (' -> (%d) {%d,%d}', [\r
+        (s - programm - (REOpSz + RENextOffSz)) + PRENextOff (s + 2 * REBracesArgSz)^,\r
+        PREBracesArg (s)^, PREBracesArg (s + REBracesArgSz)^]);\r
+       inc (s, 2 * REBracesArgSz + RENextOffSz);\r
+      end;\r
+     {$ENDIF}\r
+     Result := Result + #$d#$a;\r
+   end; { of while}\r
+\r
+  // Header fields of interest.\r
+\r
+  if regstart <> #0\r
+   then Result := Result + 'start ' + regstart;\r
+  if reganch <> #0\r
+   then Result := Result + 'anchored ';\r
+  if regmust <> nil\r
+   then Result := Result + 'must have ' + regmust;\r
+  {$IFDEF UseFirstCharSet} //###0.929\r
+  Result := Result + #$d#$a'FirstCharSet:';\r
+  for Ch := #0 to #255 do\r
+   if Ch in FirstCharSet\r
+    then Result := Result + Ch;\r
+  {$ENDIF}\r
+  Result := Result + #$d#$a;\r
+ end; { of function TRegExpr.Dump\r
+--------------------------------------------------------------}\r
+{$ENDIF}\r
+\r
+{$IFDEF reRealExceptionAddr}\r
+{$OPTIMIZATION ON}\r
+// ReturnAddr works correctly only if compiler optimization is ON\r
+// I placed this method at very end of unit because there are no\r
+// way to restore compiler optimization flag ...\r
+{$ENDIF}\r
+procedure TRegExpr.Error (AErrorID : integer);\r
+{$IFDEF reRealExceptionAddr}\r
+ function ReturnAddr : pointer; //###0.938\r
+  asm\r
+   mov  eax,[ebp+4]\r
+  end;\r
+{$ENDIF}\r
+ var\r
+  e : ERegExpr;\r
+ begin\r
+  fLastError := AErrorID; // dummy stub - useless because will raise exception\r
+  if AErrorID < 1000 // compilation error ?\r
+   then e := ERegExpr.Create (ErrorMsg (AErrorID) // yes - show error pos\r
+             + ' (pos ' + IntToStr (CompilerErrorPos) + ')')\r
+   else e := ERegExpr.Create (ErrorMsg (AErrorID));\r
+  e.ErrorCode := AErrorID;\r
+  e.CompilerErrorPos := CompilerErrorPos;\r
+  raise e\r
+   {$IFDEF reRealExceptionAddr}\r
+   At ReturnAddr; //###0.938\r
+   {$ENDIF}\r
+ end; { of procedure TRegExpr.Error\r
+--------------------------------------------------------------}\r
+\r
+// be carefull - placed here code will be always compiled with\r
+// compiler optimization flag\r
+\r
+end.\r
+\r
+\r
diff --git a/src/auxiliares/SerializacionUtils.pas b/src/auxiliares/SerializacionUtils.pas
new file mode 100644 (file)
index 0000000..ce4a1a9
--- /dev/null
@@ -0,0 +1,53 @@
+{** Funciones útiles para complementar la utilización de la serialización en\r
+    este modelo en particular}\r
+unit SerializacionUtils;\r
+\r
+interface\r
+\r
+uses\r
+  ObjetoVolador;\r
+\r
+  {** Crea un objeto a partir de un string con el nombre de su clase y otro\r
+      con su representación serializada.}\r
+  function restaurarObjeto( clase, str: string ): cObjetoVolador;\r
+\r
+implementation\r
+\r
+uses\r
+  ObjetoPersistente,\r
+  Armas,\r
+  NavesEnemigas,\r
+  NavePropia,\r
+  Meteorito;\r
+\r
+{** Crea un objeto a partir de un string con el nombre de su clase y otro\r
+    con su representación serializada.\r
+    @param  clase Clase del Objeto\r
+    @param  str   Representación del objeto serializado\r
+    @return Puntero al nuevo objeto.}\r
+function restaurarObjeto( clase, str: string ): cObjetoVolador;\r
+begin\r
+  if clase = 'cMeteorito' then\r
+    result := cMeteorito.crearDeSerializado( str )\r
+  else if clase = 'cLaser' then\r
+    result := cLaser.crearDeSerializado( str )\r
+  else if clase = 'cMisil' then\r
+    result := cMisil.crearDeSerializado( str )\r
+  else if clase = 'cMisilDirigido' then\r
+    result := cMisilDirigido.crearDeSerializado( str )\r
+  else if clase = 'cNavePropia' then\r
+    result := cNavePropia.crearDeSerializado( str )\r
+  else if clase = 'cNavePesada' then\r
+    result := cNavePesada.crearDeSerializado( str )\r
+  else if clase = 'cNaveLiviana' then\r
+    result := cNaveLiviana.crearDeSerializado( str )\r
+  else if clase = 'cNaveEspia' then\r
+    result := cNaveEspia.crearDeSerializado( str )\r
+  else if clase = 'cNaveSuicida' then\r
+    result := cNaveSuicida.crearDeSerializado( str )\r
+  else\r
+    raise ESerializacion.create( 'No se puede crear un objeto de la clase "' +\r
+                                 clase + '". Clase Desconocida!' );\r
+end;\r
+\r
+end.\r
diff --git a/src/auxiliares/Tipos.pas b/src/auxiliares/Tipos.pas
new file mode 100644 (file)
index 0000000..ca38f72
--- /dev/null
@@ -0,0 +1,29 @@
+{** En esta unidad se definen todos los tipos que usaremos en el proyecto\r
+    Decidimos mantener los tipos por separado por el caso de que sea\r
+    necesario un cambio de implementacion.}\r
+unit Tipos;\r
+\r
+interface\r
+\r
+type\r
+  tLongitud = extended;  // en metros\r
+  tTiempo   = extended;  // en milisegundos\r
+  tEnergia  = integer;\r
+  tAngulo   = extended;  // en radianes\r
+  tMaxMisil = 0..10;\r
+  tMaxMisilDirigido = 0..5;\r
+  {$IFDEF DebugAlgoWars}\r
+  tDebugInfo = ( DI_MINI, DI_NORMAL, DI_MAXI ); // Cantidad de Informacion a presentar\r
+  {$ENDIF}\r
+  // Tipos de objetos voladores\r
+  tObjetosVoladores = ( OV_NAVEPESADA, OV_NAVELIVIANA, OV_NAVEESPIA, OV_NAVESUICIDA,\r
+                        OV_METEORITO, OV_NAVEPROPIA, OV_LASER, OV_MISIL, OV_MISDIR );\r
+  // Tipos de armas\r
+  tArma = OV_LASER..OV_MISDIR; // Tipo de arma Seleccionada (subrango de tObjetosVoladores)\r
+  //Tipos de camaras\r
+  tCamaras = ( CAMARA_FRONTAL, CAMARA_LATDER, CAMARA_LATIZQ, CAMARA_TRASERA,\r
+               CAMARA_ARRIBA, CAMARA_ABAJO, CAMARA_MAPA, CAMARA_ARMA );\r
+\r
+implementation\r
+\r
+end.\r
diff --git a/src/forms/FormConfig.dfm b/src/forms/FormConfig.dfm
new file mode 100644 (file)
index 0000000..7a2307e
Binary files /dev/null and b/src/forms/FormConfig.dfm differ
diff --git a/src/forms/FormConfig.pas b/src/forms/FormConfig.pas
new file mode 100644 (file)
index 0000000..5c19606
--- /dev/null
@@ -0,0 +1,369 @@
+{** Formulario para configurar la aplicación}\r
+unit FormConfig;\r
+\r
+interface\r
+\r
+uses\r
+  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\r
+  StdCtrls, ExtCtrls,\r
+  ObjetoVolador;\r
+\r
+type\r
+  {** Formulario para configurar la aplicación}\r
+  TConfigForm = class(TForm)\r
+    aGrpBoxNavePropia: TGroupBox;\r
+    aLblPosicionNP: TLabel;\r
+    aLblVelocidadNP: TLabel;\r
+    aGrpBoxNuevoOV: TGroupBox;\r
+    aLblPosicionOV: TLabel;\r
+    aLblVelocidadOV: TLabel;\r
+    aLblZ: TLabel;\r
+    aLblY: TLabel;\r
+    aLblX: TLabel;\r
+    aRdGrpTipoOV: TRadioGroup;\r
+    aEditOVPosX: TEdit;\r
+    aEditOVPosY: TEdit;\r
+    aEditOVPosZ: TEdit;\r
+    aEditOVVelX: TEdit;\r
+    aEditOVVelY: TEdit;\r
+    aEditOVVelZ: TEdit;\r
+    aBtnAgregar: TButton;\r
+    aEditNPVelX: TEdit;\r
+    aEditNPVelY: TEdit;\r
+    aEditNPVelZ: TEdit;\r
+    aEditNPPosX: TEdit;\r
+    aEditNPPosY: TEdit;\r
+    aEditNPPosZ: TEdit;\r
+    aGrpBoxListaOV: TGroupBox;\r
+    aListBoxObjetos: TListBox;\r
+    aBtnQuitar: TButton;\r
+    aBtnAceptar: TButton;\r
+    aBtnCancelar: TButton;\r
+    procedure aBtnAgregarClick(Sender: TObject);\r
+    procedure aBtnCancelarClick(Sender: TObject);\r
+    procedure aBtnAceptarClick(Sender: TObject);\r
+    procedure aBtnQuitarClick(Sender: TObject);\r
+    procedure mValidar(Sender: TObject);\r
+    procedure FormShow(Sender: TObject);\r
+  private\r
+    { Private declarations }\r
+    {** Crea un objeto volador dependiendo del tipo que se eligió en los radio buttons}\r
+    function mCrearOV(indice: integer): cObjetoVolador;\r
+    {** Obtiene una cadena compatible con los radio buttons dependiendo de la clase del objeto}\r
+    function mClassToStr( oOV: cObjetoVolador ): string;\r
+    {** Obtiene el indice compatible con los radio buttons dependiendo de la clase del objeto}\r
+    function mClassToIndex(oOV: cObjetoVolador): integer;\r
+  public\r
+    { Public declarations }\r
+  end;\r
+\r
+var\r
+  ConfigForm: TConfigForm;\r
+\r
+implementation\r
+\r
+{$R *.DFM}\r
+\r
+uses\r
+  FormMain,\r
+  RegExpr,\r
+  Vectores,\r
+  NavesEnemigas,\r
+  Meteorito,\r
+  Armas,\r
+  NavePropia;\r
+\r
+procedure TConfigForm.aBtnAgregarClick(Sender: TObject);\r
+var\r
+  oOV: cObjetoVolador;\r
+  oPos,\r
+  oVel: cVector;\r
+begin\r
+  if aRdGrpTipoOV.ItemIndex > -1 then begin\r
+    oOV := mCrearOV( aRdGrpTipoOV.ItemIndex );\r
+    oPos := oOV.mGetPosicion;\r
+    oVel := oOV.mGetVelocidad;\r
+    aListBoxObjetos.Items.AddObject( aRdGrpTipoOV.Items[aRdGrpTipoOV.ItemIndex] +\r
+                               '; (' + FloatToStrF( oPos.mGetX, ffGeneral, 5, 5 ) +\r
+                               ';' + FloatToStrF( oPos.mGetY, ffGeneral, 5, 5 ) +\r
+                               ';' + FloatToStrF( oPos.mGetZ, ffGeneral, 5, 5 ) + ')' +\r
+                               '; (' + FloatToStrF( oVel.mGetX, ffGeneral, 5, 5 ) +\r
+                               ';' + FloatToStrF( oVel.mGetY, ffGeneral, 5, 5 ) +\r
+                               ';' + FloatToStrF( oVel.mGetZ, ffGeneral, 5, 5 ) + ')',\r
+                               oOV );\r
+    oPos.free;\r
+    oVel.free;\r
+  end;\r
+end;\r
+\r
+procedure TConfigForm.aBtnCancelarClick(Sender: TObject);\r
+var\r
+  oOV: cObjetoVolador;\r
+  i:   integer;\r
+  oObjetos: TList;\r
+begin\r
+  oObjetos := MainForm.mGetObjetos;\r
+  i := 0;\r
+  while i < aListBoxObjetos.Items.Count do begin\r
+    aListBoxObjetos.ItemIndex := i;\r
+    oOV := cObjetoVolador( aListBoxObjetos.Items.Objects[i] );\r
+    if oObjetos.IndexOf( oOV ) = -1 then\r
+      aBtnQuitarClick( Sender )\r
+    else\r
+      i := i + 1;\r
+  end;\r
+  Close;\r
+end;\r
+\r
+procedure TConfigForm.aBtnAceptarClick(Sender: TObject);\r
+var\r
+  oOV: cObjetoVolador;\r
+  i:   integer;\r
+  oObjetos: TList;\r
+  oPos,\r
+  oVel: cVector;\r
+begin\r
+  // Se modifican los valores de la nave propia\r
+  oPos := cVector.create( StrToFloat( aEditNPPosX.Text ), StrToFloat( aEditNPPosY.Text ), StrToFloat( aEditNPPosZ.Text ) );\r
+  oVel := cVector.create( StrToFloat( aEditNPVelX.Text ), StrToFloat( aEditNPVelY.Text ), StrToFloat( aEditNPVelZ.Text ) );\r
+  MainForm.mGetNavePropia.mSetPosicion( oPos );\r
+  MainForm.mGetNavePropia.mSetVelocidad( oVel );\r
+  oPos.free;\r
+  oVel.free;\r
+  // Se sincronizan las listas de objetos (la del formulario con la de la list box)\r
+  oObjetos := MainForm.mGetObjetos;\r
+  i := 0;\r
+  while i < oObjetos.Count do begin\r
+    oOV := cObjetoVolador( oObjetos.Items[i] );\r
+    if aListBoxObjetos.Items.IndexOfObject( oOV ) = -1 then begin\r
+      oObjetos.Delete( i );\r
+      oOV.free;\r
+    end else\r
+      i := i + 1;\r
+  end;\r
+  for i := 0 to aListBoxObjetos.Items.Count - 1 do begin\r
+    aListBoxObjetos.ItemIndex := i;\r
+    oOV := cObjetoVolador( aListBoxObjetos.Items.Objects[i] );\r
+    if oObjetos.IndexOf( oOV ) = -1 then\r
+      oObjetos.Add( oOV );\r
+  end;\r
+  Close;\r
+end;\r
+\r
+procedure TConfigForm.aBtnQuitarClick(Sender: TObject);\r
+var\r
+  oObjetos: TList;\r
+  oOV:      cObjetoVolador;\r
+  oPos,\r
+  oVel:     cVector;\r
+begin\r
+  oObjetos := MainForm.mGetObjetos;\r
+  if (aListBoxObjetos.ItemIndex > -1) and (aListBoxObjetos.Items.Count > 0 ) then begin\r
+    oOV := cObjetoVolador( aListBoxObjetos.Items.Objects[aListBoxObjetos.ItemIndex] );\r
+    oPos := oOV.mGetPosicion;\r
+    oVel := oOV.mGetVelocidad;\r
+    aEditOVPosX.Text := FloatToStrF( oPos.mGetX, ffGeneral, 5, 5 );\r
+    aEditOVPosY.Text := FloatToStrF( oPos.mGetY, ffGeneral, 5, 5 );\r
+    aEditOVPosZ.Text := FloatToStrF( oPos.mGetZ, ffGeneral, 5, 5 );\r
+    aEditOVVelX.Text := FloatToStrF( oVel.mGetX, ffGeneral, 5, 5 );\r
+    aEditOVVelY.Text := FloatToStrF( oVel.mGetY, ffGeneral, 5, 5 );\r
+    aEditOVVelZ.Text := FloatToStrF( oVel.mGetZ, ffGeneral, 5, 5 );\r
+    aListBoxObjetos.Items.Delete( aListBoxObjetos.ItemIndex );\r
+    aRdGrpTipoOV.ItemIndex := mClassToIndex( oOV );\r
+    if oObjetos.IndexOf( oOV ) = -1 then\r
+      oOV.free;\r
+    oPos.free;\r
+    oVel.free;\r
+  end;\r
+end;\r
+\r
+{** Crea un objeto volador dependiendo del tipo que se eligió en los radio buttons\r
+    @param  indice Indice del radio button\r
+    @return Objeto Volador de la clase apropiada}\r
+function TConfigForm.mCrearOV( indice: integer ): cObjetoVolador;\r
+var\r
+  oOV: cObjetoVolador;\r
+  oPos: cVector;\r
+  oVel: cVector;\r
+begin\r
+    case indice of\r
+      0: begin\r
+        oPos := cVector.create( StrToFloat( aEditOVPosX.Text ), StrToFloat( aEditOVPosY.Text ), StrToFloat( aEditOVPosZ.Text ) );\r
+        oVel := cVector.create( StrToFloat( aEditOVVelX.Text ), StrToFloat( aEditOVVelY.Text ), StrToFloat( aEditOVVelZ.Text ) );\r
+        oOV := cNavePesada.create( oPos, oVel );\r
+        oPos.free;\r
+        oVel.free;\r
+      end;\r
+      1: begin\r
+        oPos := cVector.create( StrToFloat( aEditOVPosX.Text ), StrToFloat( aEditOVPosY.Text ), StrToFloat( aEditOVPosZ.Text ) );\r
+        oVel := cVector.create( StrToFloat( aEditOVVelX.Text ), StrToFloat( aEditOVVelY.Text ), StrToFloat( aEditOVVelZ.Text ) );\r
+        oOV := cNaveLiviana.create( oPos, oVel );\r
+        oPos.free;\r
+        oVel.free;\r
+      end;\r
+      2: begin\r
+        oPos := cVector.create( StrToFloat( aEditOVPosX.Text ), StrToFloat( aEditOVPosY.Text ), StrToFloat( aEditOVPosZ.Text ) );\r
+        oVel := cVector.create( StrToFloat( aEditOVVelX.Text ), StrToFloat( aEditOVVelY.Text ), StrToFloat( aEditOVVelZ.Text ) );\r
+        oOV := cNaveSuicida.create( oPos, oVel );\r
+        oPos.free;\r
+        oVel.free;\r
+      end;\r
+      3: begin\r
+        oPos := cVector.create( StrToFloat( aEditOVPosX.Text ), StrToFloat( aEditOVPosY.Text ), StrToFloat( aEditOVPosZ.Text ) );\r
+        oVel := cVector.create( StrToFloat( aEditOVVelX.Text ), StrToFloat( aEditOVVelY.Text ), StrToFloat( aEditOVVelZ.Text ) );\r
+        oOV := cNaveEspia.create( oPos, oVel );\r
+        oPos.free;\r
+        oVel.free;\r
+      end;\r
+      4: begin\r
+        oPos := cVector.create( StrToFloat( aEditOVPosX.Text ), StrToFloat( aEditOVPosY.Text ), StrToFloat( aEditOVPosZ.Text ) );\r
+        oVel := cVector.create( StrToFloat( aEditOVVelX.Text ), StrToFloat( aEditOVVelY.Text ), StrToFloat( aEditOVVelZ.Text ) );\r
+        oOV := cMeteorito.create( oPos, oVel );\r
+        oPos.free;\r
+        oVel.free;\r
+      end;\r
+      5: begin\r
+        oPos := cVector.create( StrToFloat( aEditOVPosX.Text ), StrToFloat( aEditOVPosY.Text ), StrToFloat( aEditOVPosZ.Text ) );\r
+        oVel := cVector.create( StrToFloat( aEditOVVelX.Text ), StrToFloat( aEditOVVelY.Text ), StrToFloat( aEditOVVelZ.Text ) );\r
+        oOV := cLaser.create( oPos, oVel );\r
+        oPos.free;\r
+        oVel.free;\r
+      end;\r
+      6: begin\r
+        oPos := cVector.create( StrToFloat( aEditOVPosX.Text ), StrToFloat( aEditOVPosY.Text ), StrToFloat( aEditOVPosZ.Text ) );\r
+        oVel := cVector.create( StrToFloat( aEditOVVelX.Text ), StrToFloat( aEditOVVelY.Text ), StrToFloat( aEditOVVelZ.Text ) );\r
+        oOV := cMisil.create( oPos, oVel );\r
+        oPos.free;\r
+        oVel.free;\r
+      end;\r
+      7: begin\r
+        oPos := cVector.create( StrToFloat( aEditOVPosX.Text ), StrToFloat( aEditOVPosY.Text ), StrToFloat( aEditOVPosZ.Text ) );\r
+        oOV := cMisilDirigido.create( MainForm.mGetNavePropia, oPos );\r
+        oPos.free;\r
+      end;\r
+    end;\r
+    result := oOV;\r
+end;\r
+procedure TConfigForm.mValidar(Sender: TObject);\r
+const\r
+  // Expresion regular para hallar número un real\r
+  PATTERN = '^[+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?$';\r
+var\r
+  r :  TRegExpr;\r
+begin\r
+  with Sender as TEdit do begin\r
+    r := TRegExpr.Create; // Create object\r
+    try // ensure memory release\r
+      r.Expression := PATTERN;\r
+      if not r.Exec( Text ) then begin // Si no es un real\r
+        ShowMessage( 'El valor "' + Text + '" no es válido. ' +\r
+                     'Por favor ingrese un valor real expresado con "," para separar los decimales ' +\r
+                     'o expresado en forma científica (con exponente). Ejemplos:' + #13 + #10 +\r
+                     '  10,5'   + #13 + #10 +\r
+                     '  -4,1'   + #13 + #10 +\r
+                     '  10e5'   + #13 + #10 +\r
+                     '  -23e-5' + #13 + #10 +\r
+                     '  98e-5'  + #13 + #10 );\r
+        Text := '0';\r
+        SetFocus;\r
+      end;\r
+    finally\r
+      r.Free;\r
+    end;\r
+  end;\r
+end;\r
+\r
+procedure TConfigForm.FormShow(Sender: TObject);\r
+var\r
+  oOV:      cObjetoVolador;\r
+  i:        integer;\r
+  oObjetos: TList;\r
+  oPos,\r
+  oVel:     cVector;\r
+  tipo:     string;\r
+begin\r
+  aListBoxObjetos.Clear;\r
+  oObjetos := MainForm.mGetObjetos;\r
+  for i := 0 to oObjetos.Count - 1 do begin\r
+    oOV := cObjetoVolador( oObjetos.Items[i] );\r
+    tipo := mClassToStr( oOV );\r
+    oPos := oOV.mGetPosicion;\r
+    oVel := oOV.mGetVelocidad;\r
+    aListBoxObjetos.Items.AddObject( tipo +\r
+                                     '; (' + FloatToStrF( oPos.mGetX, ffGeneral, 5, 5 ) +\r
+                                     ';' + FloatToStrF( oPos.mGetY, ffGeneral, 5, 5 ) +\r
+                                     ';' + FloatToStrF( oPos.mGetZ, ffGeneral, 5, 5 ) + ')' +\r
+                                     '; (' + FloatToStrF( oVel.mGetX, ffGeneral, 5, 5 ) +\r
+                                     ';' + FloatToStrF( oVel.mGetY, ffGeneral, 5, 5 ) +\r
+                                     ';' + FloatToStrF( oVel.mGetZ, ffGeneral, 5, 5 ) + ')',\r
+                                     oOV );\r
+    oPos.free;\r
+    oVel.free;\r
+    oPos := MainForm.mGetNavePropia.mGetPosicion;\r
+    oVel := MainForm.mGetNavePropia.mGetVelocidad;\r
+    aEditNPPosX.Text := FloatToStrF( oPos.mGetX, ffGeneral, 5, 5 );\r
+    aEditNPPosY.Text := FloatToStrF( oPos.mGetY, ffGeneral, 5, 5 );\r
+    aEditNPPosZ.Text := FloatToStrF( oPos.mGetZ, ffGeneral, 5, 5 );\r
+    aEditNPVelX.Text := FloatToStrF( oVel.mGetX, ffGeneral, 5, 5 );\r
+    aEditNPVelY.Text := FloatToStrF( oVel.mGetY, ffGeneral, 5, 5 );\r
+    aEditNPVelZ.Text := FloatToStrF( oVel.mGetZ, ffGeneral, 5, 5 );\r
+    oPos.free;\r
+    oVel.free;\r
+  end;\r
+end;\r
+\r
+{** Obtiene una cadena compatible con los radio buttons dependiendo de la clase del objeto\r
+    @param  oOV Objeto Volador de la clase apropiada\r
+    @return     Cadena compatible con el titulo del Radio Button}\r
+function TConfigForm.mClassToStr(oOV: cObjetoVolador): string;\r
+var\r
+  clase: string;\r
+begin\r
+    clase := oOV.ClassName;\r
+    result := 'Desconocido';\r
+    if clase = 'cNavePesada' then\r
+      result := 'Nave Pesada';\r
+    if clase = 'cNaveLiviana' then\r
+      result := 'Nave Liviana';\r
+    if clase = 'cNaveSuicida' then\r
+      result := 'Nave Suicida';\r
+    if clase = 'cNaveEspia' then\r
+      result := 'Nave Espia';\r
+    if clase = 'cMeteorito' then\r
+      result := 'Meteorito';\r
+    if clase = 'cLaser' then\r
+      result := 'Laser';\r
+    if clase = 'cMisil' then\r
+      result := 'Misil';\r
+    if clase = 'cMisilDirigido' then\r
+      result := 'Misil Dirigido';\r
+end;\r
+\r
+{** Obtiene el indice compatible con los radio buttons dependiendo de la clase del objeto\r
+    @param  oOV Objeto Volador de la clase apropiada\r
+    @return     Indice del Radio Button}\r
+function TConfigForm.mClassToIndex(oOV: cObjetoVolador): integer;\r
+var\r
+  clase: string;\r
+begin\r
+    clase := oOV.ClassName;\r
+    result := -1;\r
+    if clase = 'cNavePesada' then\r
+      result := 0;\r
+    if clase = 'cNaveLiviana' then\r
+      result := 1;\r
+    if clase = 'cNaveSuicida' then\r
+      result := 2;\r
+    if clase = 'cNaveEspia' then\r
+      result := 3;\r
+    if clase = 'cMeteorito' then\r
+      result := 4;\r
+    if clase = 'cLaser' then\r
+      result := 5;\r
+    if clase = 'cMisil' then\r
+      result := 6;\r
+    if clase = 'cMisilDirigido' then\r
+      result := 7;\r
+end;\r
+\r
+end.\r
diff --git a/src/forms/FormMain.dfm b/src/forms/FormMain.dfm
new file mode 100644 (file)
index 0000000..95b8175
Binary files /dev/null and b/src/forms/FormMain.dfm differ
diff --git a/src/forms/FormMain.pas b/src/forms/FormMain.pas
new file mode 100644 (file)
index 0000000..bb2c522
--- /dev/null
@@ -0,0 +1,725 @@
+{** Formulario principal de la aplicación<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    29/11/00: Se agregan algunos controles gráficos con indicadores de energía y velocidad.\r
+              No se incluyen en una clase Vista porque son muy pequeños.\r
+    01/12/00: Se modifica levemente la interfaz.\r
+              Se agregan controles para los disparos y metodos pertinentes.\r
+    06/12/00: Se cambian minimamente los menúes, poniendo la parte del manejo\r
+              de escenarios en un submenú del menú Archivo.\r
+    08/12/00: Se termina de implementar la funcionalidad de los menúes\r
+                Archivo -> Abrir ...\r
+                Archivo -> Guardar ...\r
+                Archivo -> Escenario -> Abrir ...\r
+                Archivo -> Escenario -> Guardar ...\r
+              Se completa el 'destructor', ya que faltaban liberar bastantes\r
+              objetos.\r
+    18/12/00: Se corrige un bug que hacía que en ciertas circunstancias no se\r
+              encuentren el escenario por defecto, agregando la ruta completa.\r
+    </PRE>}\r
+unit FormMain;\r
+\r
+interface\r
+\r
+uses\r
+  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\r
+  ExtCtrls, Menus, StdCtrls,\r
+  Espacio,\r
+  NavePropia,\r
+  NavesEnemigas,\r
+  Meteorito,\r
+  Armas,\r
+  Vectores,\r
+  Vista,\r
+  Tipos;\r
+\r
+type\r
+  {** Formulario principal de la aplicación}\r
+  TMainForm = class(TForm)\r
+    aBtnIniciar: TButton;\r
+    aMainMenu: TMainMenu;\r
+    aTimer: TTimer;\r
+    aMenuJuego: TMenuItem;\r
+    aMenuItemConfigurar: TMenuItem;\r
+    aMenuItemSalir: TMenuItem;\r
+    aTimerVista: TTimer;\r
+    aEditEnergia: TEdit;\r
+    aLblEnergia: TLabel;\r
+    N1: TMenuItem;\r
+    aMenuItemNuevoJuego: TMenuItem;\r
+    aMenuItemGuardar: TMenuItem;\r
+    aMenuItemAbrir: TMenuItem;\r
+    aMenuItemAbrirEscenario: TMenuItem;\r
+    aMenuItemGuardarEscenario: TMenuItem;\r
+    N3: TMenuItem;\r
+    aLblVelocidad: TLabel;\r
+    aEditVelocidad: TEdit;\r
+    aLblKMH: TLabel;\r
+    aLblMisiles: TLabel;\r
+    aEditMisiles: TEdit;\r
+    aLblMisilesDir: TLabel;\r
+    aEditMisilesDirigidos: TEdit;\r
+    aLblArma: TLabel;\r
+    aEditArma: TEdit;\r
+    aMenuEscenario: TMenuItem;\r
+    aSaveJuego: TSaveDialog;\r
+    aOpenJuego: TOpenDialog;\r
+    aSaveEscenario: TSaveDialog;\r
+    aOpenEscenario: TOpenDialog;\r
+    aMenuVista: TMenuItem;\r
+    aMenuItemFrontal: TMenuItem;\r
+    aMenuItemDerecha: TMenuItem;\r
+    aMenuItemIzquierda: TMenuItem;\r
+    aMenuItemTrasera: TMenuItem;\r
+    aMenuItemSuperior: TMenuItem;\r
+    aMenuItemInferior: TMenuItem;\r
+    aMenuItemDelArma: TMenuItem;\r
+    N2: TMenuItem;\r
+    aMenuItemCalidad: TMenuItem;\r
+    aMenuItemCambioAutomatico: TMenuItem;\r
+    aMenuItemMapa: TMenuItem;\r
+    procedure aBtnIniciarClick(Sender: TObject);\r
+    procedure aTimerTimer(Sender: TObject);\r
+    procedure aMenuItemConfigurarClick(Sender: TObject);\r
+    procedure FormCreate(Sender: TObject);\r
+    procedure aMenuItemSalirClick(Sender: TObject);\r
+    procedure FormDestroy(Sender: TObject);\r
+    procedure FormKeyDown(Sender: TObject; var Key: Word;\r
+      Shift: TShiftState);\r
+    procedure FormHide(Sender: TObject);\r
+    procedure aTimerVistaTimer(Sender: TObject);\r
+    procedure aMenuItemGuardarClick(Sender: TObject);\r
+    procedure aMenuClick(Sender: TObject);\r
+    procedure aMenuItemAbrirClick(Sender: TObject);\r
+    procedure aMenuItemNuevoJuegoClick(Sender: TObject);\r
+    procedure aMenuItemGuardarEscenarioClick(Sender: TObject);\r
+    procedure aMenuItemAbrirEscenarioClick(Sender: TObject);\r
+    procedure CambiarVistaClick(Sender: TObject);\r
+    procedure aMenuItemCalidadClick(Sender: TObject);\r
+    procedure DesSerializarEscenario( archivo: string );\r
+    procedure SerializarEscenario( archivo: string );\r
+    procedure DesSerializarJuego( archivo: string );\r
+    procedure SerializarJuego( archivo: string );\r
+    procedure aMenuItemCambioAutomaticoClick(Sender: TObject);\r
+  private\r
+    { Private declarations }\r
+    aObjetos:    TList;       // Lista de objetos a utlizar con el espacio\r
+    aEspacio:    cEspacio;    // Espacio a utilizar\r
+    aNavePropia: cNavePropia; // Nave propia a utilizar con el espacio\r
+    aVista:      cVista;      // Vista utilizada para dibujar el modelo en el formulario\r
+    {$IFDEF DebugAlgoWars}\r
+    aDebugFile:  Text;        // Archivo para guardar información de debug\r
+    {$ENDIF}\r
+  public\r
+    { Public declarations }\r
+    {** Obtiene la lista de objetos del formulario}\r
+    function mGetObjetos: TList;\r
+    {** Obtiene la nave propia del formulario}\r
+    function mGetNavePropia: cNavePropia;\r
+  end;\r
+\r
+var\r
+  MainForm:    TMainForm;\r
+\r
+implementation\r
+\r
+uses\r
+  FormConfig,\r
+  ObjetoPersistente,\r
+  SerializacionUtils,\r
+  RegExpr,\r
+  ObjetoVolador,\r
+  Camara;\r
+\r
+{$R *.DFM}\r
+\r
+const\r
+  DEBUGING: boolean = true; // Constante para indicar si se genera el archivo de debug\r
+\r
+procedure TMainForm.aBtnIniciarClick(Sender: TObject);\r
+begin\r
+  if aEspacio = nil then begin // Todavía no se inicio el juego\r
+    aEspacio := cEspacio.create( aNavePropia, aObjetos, 50 );\r
+    aVista := cVista.create( self, aNavePropia );\r
+    aMenuItemConfigurar.Enabled := false;\r
+    aMenuItemGuardar.Enabled := true;\r
+    aMenuEscenario.Enabled := false;\r
+    aMenuVista.Enabled := true;\r
+  end;\r
+  if aTimer.Enabled = false then begin\r
+    aTimer.enabled := true;\r
+    aTimerVista.enabled := true;\r
+    aBtnIniciar.caption := 'Pausa';\r
+  end else begin\r
+    aTimer.enabled := false;\r
+    aTimerVista.enabled := false;\r
+    aBtnIniciar.caption := 'Continuar';\r
+  end;\r
+end;\r
+\r
+procedure TMainForm.aTimerTimer(Sender: TObject);\r
+begin\r
+  try // Prueba el codigo\r
+    aEspacio.mActualizar;\r
+  except\r
+    on e: ENavePropiaDestruida do begin         // Si cae en una excepcion de nave propia destruida\r
+      aBtnIniciarClick( self );                 // Detiene la ejecucion\r
+      aBtnIniciar.Enabled := false;             // No permite que se reinicie\r
+      aMenuItemGuardar.Enabled := false;        // No permite guardar el juego\r
+      aMenuVista.Enabled := false;              // No permite manipular la vista\r
+      {$IFDEF DebugAlgoWars}\r
+      writeln( aDebugFile, 'GAME OVER!!!! (' +  // Escribe el archivo de LOG de ser necesario\r
+                           e.Message + ')' );\r
+      {$ENDIF}\r
+      ShowMessage( 'GAME OVER!!!' ); // Muestra un mensaje\r
+    end;\r
+    on e: Exception do begin                       // Si cae en una excepcion desconocida\r
+      aBtnIniciarClick( self );                    // Detiene la ejecucion\r
+      aBtnIniciar.Enabled := false;                // No permite que se reinicie\r
+      aMenuItemGuardar.Enabled := false;           // No permite guardar el juego\r
+      aMenuVista.Enabled := false;                 // No permite manipular la vista\r
+      {$IFDEF DebugAlgoWars}\r
+      writeln( aDebugFile, 'ERROR: ' + e.Message); // Escribe el archivo de LOG de ser necesario\r
+      {$ENDIF}\r
+      ShowMessage( 'ERROR: ' + e.Message );    // Muestra un mensaje\r
+    end;\r
+  end;\r
+end;\r
+\r
+procedure TMainForm.aTimerVistaTimer(Sender: TObject);\r
+const\r
+  i: int64 = 0;\r
+begin\r
+  {$IFDEF DebugAlgoWars}\r
+  i := i + 1;\r
+  {$ENDIF}\r
+  // Muestra la energía de la nave\r
+  aEditEnergia.Text := IntToStr( aNavePropia.mGetEnergia );\r
+  // La velocidad esta en las unidades 1m/ms. Sabiendo que 1m = 0,001 km y\r
+  // 1 h = 60 . 60 . 1000 ms, entonces 1 ms = 1 / 3600000 h\r
+  // Entonces velocidad * 0,001 * 3600000 = velocidad * 3600 = km/h\r
+  aEditVelocidad.Text := FloatToStr( aNavePropia.mGetVelModulo * 3600 );\r
+  // Muestra la cantidad de misiles que le quedan a la nave\r
+  aEditMisiles.Text := IntToStr( aNavePropia.mGetMisiles );\r
+  // Muestra la cantidad de misiles dirigidos que le quedan a la nave\r
+  aEditMisilesDirigidos.Text := IntToStr( aNavePropia.mGetMisilesDirigidos );\r
+  // Muestra en el título la cámara actualmente en uso\r
+  Caption := Application.Title + ' @ ' + aVista.mGetCamaraStr;\r
+  // Muestra el arma seleccionada\r
+  case aNavePropia.mGetArmaSelec of\r
+    OV_LASER: begin\r
+      aEditArma.Text := 'Láser';\r
+      if aNavePropia.mPuedeDispararLaser( nil ) then\r
+        aEditArma.Font.Color := clLime\r
+      else\r
+        aEditArma.Font.Color := clRed;\r
+    end;\r
+    OV_MISIL: begin\r
+      aEditArma.Text := 'Misil';\r
+      if aNavePropia.mPuedeDispararMisil( nil ) then\r
+        aEditArma.Font.Color := clLime\r
+      else\r
+        aEditArma.Font.Color := clRed;\r
+    end;\r
+    OV_MISDIR: begin\r
+      aEditArma.Text := 'Misil Dirigido';\r
+      if aNavePropia.mPuedeDispararMisDir( nil ) then\r
+        aEditArma.Font.Color := clLime\r
+      else\r
+        aEditArma.Font.Color := clRed;\r
+    end;\r
+  end;\r
+  try // Prueba el codigo\r
+    aVista.mDibujarVista( aEspacio );\r
+    {$IFDEF DebugAlgoWars}\r
+    // Imprime la informacion del estado del espacio en este instante\r
+    writeln( aDebugFile, aEspacio.mGetDebugInfo( DI_NORMAL ) );\r
+    // Imprime la data de la vista\r
+    writeln( aDebugFile, aVista.mGetDebugInfo( DI_MAXI ) );\r
+    writeln( aDebugFile, #13 + #10 + '====================>  ' + IntToStr( i ) + '  <======================' );\r
+    {$ENDIF}\r
+  except\r
+    on e: ECameramanDestruido do begin // Si cae en una excepcion de camara destruida\r
+      aBtnIniciarClick( self );        // Detiene la ejecucion\r
+      aBtnIniciar.Enabled := false;    // No permite que se reinicie\r
+      {$IFDEF DebugAlgoWars}\r
+      writeln( aDebugFile, 'ERROR!!!! (' +  // Escribe el archivo de LOG de ser necesario\r
+                           e.Message + ')' );\r
+      {$ENDIF}\r
+      ShowMessage( 'ERROR!!!! (' + e.Message + ')' ); // Muestra un mensaje\r
+    end;\r
+    on e: ENavePropiaDestruida do begin         // Si cae en una excepcion de nave propia destruida\r
+      aBtnIniciarClick( self );                 // Detiene la ejecucion\r
+      aBtnIniciar.Enabled := false;             // No permite que se reinicie\r
+      {$IFDEF DebugAlgoWars}\r
+      writeln( aDebugFile, 'GAME OVER!!!! (' +  // Escribe el archivo de LOG de ser necesario\r
+                           e.Message + ')' );\r
+      {$ENDIF}\r
+      ShowMessage( 'GAME OVER!!!' ); // Muestra un mensaje\r
+    end;\r
+    on e: Exception do begin                      // Si cae en una excepcion desconocida\r
+      aBtnIniciarClick( self );                    // Detiene la ejecucion\r
+      aBtnIniciar.Enabled := false;                // No permite que se reinicie\r
+      {$IFDEF DebugAlgoWars}\r
+      writeln( aDebugFile, 'ERROR: ' + e.Message); // Escribe el archivo de LOG de ser necesario\r
+      {$ENDIF}\r
+      ShowMessage( 'ERROR: ' + e.Message );    // Muestra un mensaje\r
+    end;\r
+  end;\r
+end;\r
+\r
+procedure TMainForm.aMenuItemConfigurarClick(Sender: TObject);\r
+begin\r
+  ConfigForm.ShowModal;\r
+end;\r
+\r
+procedure TMainForm.FormCreate(Sender: TObject);\r
+var\r
+  fName: string;\r
+begin\r
+  aEspacio := nil;\r
+  aObjetos := TList.create;\r
+  aNavePropia := cNavePropia.create;\r
+  // Pausa si se minimiza\r
+  Application.OnMinimize := FormHide;\r
+\r
+  {$IFDEF DebugAlgoWars}\r
+  // Inicializa el archivo de texto para DEBUG\r
+  assignFile( aDebugFile, 'debug.txt' );\r
+  rewrite( aDebugFile );\r
+  {$ENDIF}\r
+\r
+  // Establecemos el nombre del archivo con la ruta completa\r
+  fName := ExtractFileDir( ParamStr( 0 ) ) + '\comun.eaw';\r
+\r
+  // Cargamos Algunos datos de ejemplo al principio si existe el archivo\r
+  if FileExists( fName ) then\r
+    try // Prueba que no haya errores\r
+      DesSerializarEscenario( fName );\r
+    except\r
+      on e: ESerializacion do begin\r
+        ShowMessage( 'Hubo un error al recuperar el escenario por defecto "comun.eaw": ' + e.Message );    // Muestra un mensaje\r
+        // Resetea todos los valores ...\r
+        aEspacio.free;\r
+        aObjetos.free;\r
+        aNavePropia.free;\r
+        aEspacio := nil;\r
+        aObjetos := TList.create;\r
+        aNavePropia := cNavePropia.create;\r
+      end;\r
+    end;\r
+end;\r
+\r
+procedure TMainForm.aMenuItemSalirClick(Sender: TObject);\r
+begin\r
+  Close;\r
+end;\r
+\r
+procedure TMainForm.FormDestroy(Sender: TObject);\r
+var\r
+  ov: cObjetoVolador;\r
+begin\r
+  // Si el espacio no esta creado, liberamos la nave propia y los objetos\r
+  if aEspacio = nil then begin\r
+    aNavePropia.free;\r
+    while aObjetos.Count > 0 do begin\r
+      ov := aObjetos.First;\r
+      aObjetos.Remove( ov );\r
+      ov.free;\r
+    end;\r
+    aObjetos.free;\r
+  end else // Si el espacio esta creado ...\r
+    // aObjetos y aNavePropia se liberan cuando se libera el aEspacio\r
+    aEspacio.free;\r
+  aVista.free;\r
+  {$IFDEF DebugAlgoWars}\r
+  // Cierra el archivo para DEBUG\r
+  closeFile( aDebugFile );\r
+  {$ENDIF}\r
+end;\r
+\r
+{** Obtiene la lista de objetos del formulario\r
+    @return Lista de objetos que utilizara el espacio}\r
+function TMainForm.mGetObjetos: TList;\r
+begin\r
+  result := aObjetos;\r
+end;\r
+\r
+{** Obtiene la nave propia del formulario\r
+    @return Nave propia que utilizara el espacio}\r
+function TMainForm.mGetNavePropia: cNavePropia;\r
+begin\r
+  result := aNavePropia;\r
+end;\r
+\r
+procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;\r
+  Shift: TShiftState);\r
+begin\r
+  {$IFDEF DebugAlgoWars}\r
+  writeln( aDebugFile, 'Presiono la letra: ', Key );\r
+  {$ENDIF}\r
+  if aTimer.Enabled then\r
+    case Key of\r
+      // 8.7e-3 es 0,5 grados\r
+      73{I}: aNavePropia.mGirarArriba( 8.7e-3 );\r
+      75{K}: aNavePropia.mGirarAbajo( 8.7e-3 );\r
+      74{J}: aNavePropia.mGirarIzquierda( 8.7e-3 );\r
+      76{L}: aNavePropia.mGirarDerecha( 8.7e-3 );\r
+      85{U}: aNavePropia.mRotarDerecha( 8.7e-3 );\r
+      79{O}: aNavePropia.mRotarIzquierda( 8.7e-3 );\r
+      // 0.005 es 18 km/h\r
+      81{Q}: aNavePropia.mAcelerar( 0.005 );\r
+      65{A}: aNavePropia.mDesacelerar( 0.005 );\r
+      // Disparos\r
+      83{S}: begin // Dispara creando la nueva camara del arma si hubo un disparo\r
+               aVista.mCrearCamaraDeArma( aNavePropia.mIntentarDisparo );\r
+               if aMenuItemCambioAutomatico.Checked then begin // Si está activado el cambio automatico...\r
+                 CambiarVistaClick( aMenuItemDelArma ); // Cambia la camara\r
+               end;\r
+             end;\r
+      87{W}: aNavePropia.mSeleccionarArmaSig;\r
+      84{T}: aNavePropia.mCambiarLockeado( aEspacio.mGetObjetos );\r
+      // Vista\r
+      67{C}: aVista.mCamaraSiguiente;\r
+    end;\r
+end;\r
+\r
+procedure TMainForm.FormHide(Sender: TObject);\r
+begin\r
+  if aBtnIniciar.caption = 'Pausa' then // Esta jugando\r
+    aBtnIniciarClick( self ); // Pausa el juego\r
+end;\r
+\r
+procedure TMainForm.aMenuItemGuardarClick(Sender: TObject);\r
+begin\r
+  Repaint;\r
+  if aTimer.Enabled = true then // Si esta funcinando,\r
+    aBtnIniciarClick( self );   // lo interrumpe...\r
+  if aSaveJuego.Execute then // Si eligio un archivo...\r
+    SerializarJuego( aSaveJuego.Filename );\r
+end;\r
+\r
+procedure TMainForm.aMenuClick(Sender: TObject);\r
+begin\r
+  if aTimer.Enabled = true then // Si esta funcinando,\r
+    aBtnIniciarClick( self );   // lo interrumpe...\r
+end;\r
+\r
+procedure TMainForm.aMenuItemAbrirClick(Sender: TObject);\r
+begin\r
+  Repaint;\r
+  if aTimer.Enabled = true then // Si esta funcinando,\r
+    aBtnIniciarClick( self );   // lo interrumpe...\r
+  if aOpenJuego.Execute then // Si eligio un archivo...\r
+    DesSerializarJuego( aOpenJuego.Filename );\r
+end;\r
+\r
+procedure TMainForm.aMenuItemNuevoJuegoClick(Sender: TObject);\r
+var\r
+  ov: cObjetoVolador;\r
+begin\r
+  Repaint;\r
+  if aTimer.Enabled = true then // Si esta funcinando,\r
+    aBtnIniciarClick( self );   // lo interrumpe...\r
+  if MessageDlg( 'Se perderán todos los datos del juego actual ¿Está seguro que desea empezar un juego nuevo?',\r
+                 mtConfirmation, [mbYes, mbNo], 0) = mrYes then begin\r
+  // Si el espacio no esta creado, liberamos la nave propia y los objetos\r
+    if aEspacio = nil then begin\r
+      aNavePropia.free;\r
+      while aObjetos.Count > 0 do begin\r
+        ov := aObjetos.First;\r
+        aObjetos.Remove( ov );\r
+        ov.free;\r
+      end;\r
+      aObjetos.free;\r
+    end else // Si el espacio esta creado ...\r
+      // aObjetos y aNavePropia se liberan cuando se libera el aEspacio\r
+      aEspacio.free;\r
+    aVista.free;\r
+    aEspacio := nil;\r
+    aVista := nil;\r
+    aObjetos := TList.create;\r
+    aNavePropia := cNavePropia.create;\r
+    aBtnIniciar.caption := 'Iniciar';\r
+    aMenuItemConfigurar.Enabled := true;\r
+    aMenuItemGuardar.Enabled := false;\r
+    aMenuEscenario.Enabled := true;\r
+    aBtnIniciar.Enabled := true;         // Se puede iniciar el juego\r
+  end;\r
+end;\r
+\r
+procedure TMainForm.aMenuItemGuardarEscenarioClick(Sender: TObject);\r
+begin\r
+  Repaint;\r
+  if aTimer.Enabled = true then // Si esta funcinando,\r
+    aBtnIniciarClick( self );   // lo interrumpe...\r
+  if aSaveEscenario.Execute then // Si eligio un archivo...\r
+    SerializarEscenario( aSaveEscenario.Filename );\r
+end;\r
+\r
+procedure TMainForm.aMenuItemAbrirEscenarioClick(Sender: TObject);\r
+begin\r
+  Repaint;\r
+  if aTimer.Enabled = true then // Si esta funcinando,\r
+    aBtnIniciarClick( self );   // lo interrumpe...\r
+  if aOpenEscenario.Execute then // Si eligio un archivo...\r
+    DesSerializarEscenario( aOpenEscenario.Filename ); // Deserializa el archivo\r
+end;\r
+\r
+procedure TMainForm.CambiarVistaClick(Sender: TObject);\r
+begin\r
+  if Sender = aMenuItemFrontal then\r
+    aVista.mCambiarCamara( CAMARA_FRONTAL )\r
+  else if Sender = aMenuItemDerecha then\r
+    aVista.mCambiarCamara( CAMARA_LATDER )\r
+  else if Sender = aMenuItemIzquierda then\r
+    aVista.mCambiarCamara( CAMARA_LATIZQ )\r
+  else if Sender = aMenuItemTrasera then\r
+    aVista.mCambiarCamara( CAMARA_TRASERA )\r
+  else if Sender = aMenuItemSuperior then\r
+    aVista.mCambiarCamara( CAMARA_ARRIBA )\r
+  else if Sender = aMenuItemInferior then\r
+    aVista.mCambiarCamara( CAMARA_ABAJO )\r
+  else if Sender = aMenuItemDelArma then\r
+    aVista.mCambiarCamara( CAMARA_ARMA )\r
+  else if Sender = aMenuItemMapa then\r
+    aVista.mCambiarCamara( CAMARA_MAPA )\r
+end;\r
+\r
+procedure TMainForm.aMenuItemCalidadClick(Sender: TObject);\r
+begin\r
+  aVista.mCambiarCalidad;\r
+  aMenuItemCalidad.Checked := not aMenuItemCalidad.Checked;\r
+end;\r
+\r
+procedure TMainForm.DesSerializarEscenario( archivo: string );\r
+var\r
+  recuperado,\r
+  str:         string;\r
+  i,\r
+  total:       integer;\r
+  ov:          cObjetoVolador;\r
+  c:           char;\r
+  f:           TextFile;\r
+  r:           TRegExpr;\r
+begin\r
+    try\r
+      assignFile( f, archivo );   // Asigna el archivo\r
+      reset( f );                             // Abre el archivo\r
+      recuperado := '';\r
+      while not eof( f ) do begin     // Lee el archivo\r
+        read( f, c );                 // caracter por caracter\r
+        recuperado := recuperado + c; // Almacenandolo en un string\r
+      end;\r
+      closeFile( f );                 // Cierra el archivo\r
+    except  // Si hay algun error\r
+      on e: Exception do begin // Muestra un mensaje\r
+        ShowMessage( 'Hubo un error al leer el archivo "' +\r
+                     archivo + '": ' + #13 + #10 +\r
+                     e.Message + #13 + #10 +\r
+                     'Por favor lea la Sección de Errores del Manual del ' +\r
+                     'Usuario para más información'  ); // Muestra un mensaje\r
+      end;\r
+    end;\r
+    r := TRegExpr.create;\r
+    try // ensure memory release\r
+      r.Expression := '<eaw\s+version=(\d+[\.\d+]*)\s*>\s*(.+)\s*</eaw>';\r
+      if r.Exec ( recuperado ) then\r
+        if r.Match[1] = '1.0' then begin // Si el archivo es version 1.0\r
+          str := r.Match[2];\r
+          try // ensure memory release\r
+            r.Expression := '<navepropia>\s*(.+)\s*</navepropia>';\r
+            if r.Exec ( str ) then begin\r
+              aNavePropia.free; // Libera la vieja nave propia\r
+              // Obtiene la nueva navepropia de la serializacion\r
+              aNavePropia := cNavePropia.crearDeSerializado( r.Match[1] );\r
+              try // se fija si hay errores al extraer los datos\r
+                r.Expression := '<objetos\s+total=(\d+)\s*>\s*(.+)\s*</objetos>'; // contruye la expresion regular a buscar\r
+                if r.Exec ( str ) then begin // Ejecuta la expresion. Si la encuentra...\r
+                  total := StrToInt( r.Match[1] );\r
+                  str := r.Match[2];\r
+                  // libera los objetos viejos\r
+                  while aObjetos.Count > 0 do begin\r
+                    ov := aObjetos.First;\r
+                    aObjetos.Remove( ov );\r
+                    ov.free;\r
+                  end;\r
+                  for i := 0 to total - 1 do begin\r
+                    // OBJETO N\r
+                    try // se fija si hay errores al extraer los datos\r
+                      r.Expression := '<objeto' + IntToStr( i ) + '\s+class=([\w\d]+)\s*>\s*(.+)\s*</objeto' + IntToStr( i ) + '>'; // contruye la expresion regular a buscar\r
+                      if r.Exec ( str ) then begin // Ejecuta la expresion. Si la encuentra...\r
+                        // lo crea segun su clase y lo agrega a la lista\r
+                        ov := restaurarObjeto( r.Match[1], r.Match[2] );\r
+                        aObjetos.Add( ov );\r
+                        // Elimina duplicados\r
+                        if ov is cMisilDirigido then begin\r
+                          (ov as cMisilDirigido).mGetObjetivo.free; // libera el objetivo duplicado\r
+                          (ov as cMisilDirigido).mSetObjetivo( aNavePropia ); // le asigna como objetivo a la nave propia\r
+                        end;\r
+                      end else // si no encontro la experesion...\r
+                        ShowMessage( 'No se encontro el objeto ' + IntToStr( i ) ); // cae en una excepcion\r
+                    except // Si hubieron errores ...\r
+                      on e: ESerializacion do begin // Si fueron de serializacion...\r
+                        r.Free; // libera memoria\r
+                        ShowMessage( 'Error al deserializar el objeto '\r
+                                     + IntToStr( i ) + ': ' + e.Message ); // muestra mensaje\r
+                      end;\r
+                      on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+                         r.Free; // libera memoria\r
+                         ShowMessage( 'Error al extraer el objeto ' + IntToStr( i ) + ' utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+                      end;\r
+                    end;\r
+                  end;\r
+                end else // si no encontro el tag <objetos total=n>\r
+                  ShowMessage( 'No se encontro la cantidad total de objetos' ); // muestra mensaje\r
+              except // Si hubieron errores en el tag <objetos total=n>\r
+                on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+                  r.Free; // libera memoria\r
+                  ShowMessage( 'Error al extraer la cantidad total de objetos utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+                end;\r
+              end;\r
+            end else // si no encontro el tag <navepropia>\r
+                  ShowMessage( 'No se encontro la nave propia' ); // muestra mensaje\r
+          except // si hubieron errores en el tag <navepropia>\r
+            on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+              r.Free;\r
+              ShowMessage( 'Error al recuperar la nave propia utilizando expresiones regulares: ' + e.Message );\r
+            end;\r
+            on e: ESerializacion do begin\r
+              r.Free;\r
+              ShowMessage( 'Error al recuperar la nave propia: ' + e.Message );\r
+            end;\r
+          end\r
+        end else // if r.Match[1] = '1.0' then begin - chequeo de version fallido\r
+          ShowMessage( 'El escenario almacenado es de una versión incorrecta (' +\r
+                       r.Match[1] + ').' )\r
+      else // if r.Exec ( recuperado ) then - si no se encontró un escenario almacenado\r
+        ShowMessage( 'No se encontró un escenario almacenado en el archivo "' +\r
+                     archivo + '".' );\r
+    except // error en el tag <eaw version=n>\r
+      on e: ERegExpr do begin\r
+        r.Free;\r
+        ShowMessage( 'Error al recuperar el escenario utilizando expresiones regulares: ' + e.Message );\r
+      end;\r
+    end; // try - except\r
+end;\r
+\r
+procedure TMainForm.SerializarEscenario( archivo: string );\r
+var\r
+  serializado: string;\r
+  f:           TextFile;\r
+  ov:          cObjetoVolador;\r
+  i:           integer;\r
+begin\r
+    try\r
+      assignFile( f, archivo ); // Asigna el archivo\r
+      rewrite( f );                         // Sobreescribe el archivo\r
+      // Serializa la nave propia agregando alguna información sobre el archivo y la versión\r
+      serializado := '<eaw version=1.0><navepropia>' + aNavePropia.mSerializar + '</navepropia>' +\r
+                     '<objetos total=' + IntToStr( aObjetos.Count ) + '>';\r
+      // Serializa los objetos\r
+      for i := 0 to aObjetos.Count - 1 do begin  // recorre la lista\r
+        ov := aObjetos.Items[i]; // obteniendo el primer objeto volador\r
+          // Serializa el objeto actual\r
+          serializado := serializado + '<objeto' + IntToStr( i ) + ' class=' +\r
+                         ov.ClassName + '>' + ov.mSerializar + '</objeto' +\r
+                         IntToStr( i ) + '>';\r
+      end;\r
+      serializado := serializado + '</objetos></eaw>';\r
+      write( f, serializado );              // Escribe en el archivo\r
+      closeFile( f );                       // Cierra el archivo\r
+    except  // Si hay algun error\r
+      on e: Exception do // Muestra un mensaje\r
+        ShowMessage( 'Hubo un error al grabar el archivo "' +\r
+                     archivo + '": ' + #13 + #10 +\r
+                     e.Message + #13 + #10 +\r
+                     'Por favor lea la Sección de Errores del Manual del ' +\r
+                     'Usuario para más información'  ); // Muestra un mensaje\r
+    end;\r
+end;\r
+\r
+procedure TMainForm.DesSerializarJuego( archivo: string );\r
+var\r
+  recuperado:  string;\r
+  c:           char;\r
+  f:           TextFile;\r
+  r:           TRegExpr;\r
+begin\r
+    try\r
+      assignFile( f, archivo );   // Asigna el archivo\r
+      reset( f );                             // Abre el archivo\r
+      recuperado := '';\r
+      while not eof( f ) do begin     // Lee el archivo\r
+        read( f, c );                 // caracter por caracter\r
+        recuperado := recuperado + c; // Almacenandolo en un string\r
+      end;\r
+    except  // Si hay algun error\r
+      on e: Exception do begin // Muestra un mensaje\r
+        ShowMessage( 'Hubo un error al leer el archivo "' +\r
+                     archivo + '": ' + #13 + #10 +\r
+                     e.Message + #13 + #10 +\r
+                     'Por favor lea la Sección de Errores del Manual del ' +\r
+                     'Usuario para más información'  ); // Muestra un mensaje\r
+      end;\r
+    end;\r
+    r := TRegExpr.create;\r
+    try // ensure memory release\r
+      r.Expression := '<jaw\s+version=(\d+[\.\d+]*)\s*>\s*(.+)\s*</jaw>';\r
+      if r.Exec ( recuperado ) then\r
+        if r.Match[1] = '1.0' then begin // Si el archivo es version 1.0\r
+          aEspacio.free; // Libera el espacio existente de existir\r
+          aEspacio := nil;\r
+          aEspacio := cEspacio.crearDeSerializado( r.Match[2] );    // Crea el nuevo a partir del guardado\r
+          aNavePropia := aEspacio.mGetNavePropia;       // Asigna la nueva nave propia\r
+          aVista.free;                                  // Libera la vieja vista\r
+          aVista := nil;\r
+          aVista := cVista.create( self, aNavePropia ); // Crea la nueva vista\r
+          aBtnIniciar.Enabled := true;                  // Se puede iniciar el juego\r
+        end else\r
+          ShowMessage( 'El juego almacenado es de una versión incorrecta (' +\r
+                       r.Match[1] + ').' )\r
+      else\r
+        ShowMessage( 'No se encontró un juego almacenado en el archivo "' +\r
+                     archivo + '".' );\r
+    except\r
+      on e: ERegExpr do begin\r
+        r.Free;\r
+        ShowMessage( 'Error al recuperar el juego utilizando expresiones regulares: ' + e.Message );\r
+      end;\r
+      on e: ESerializacion do begin\r
+        r.Free;\r
+        ShowMessage( 'Error al recuperar el juego: ' + e.Message );\r
+      end;\r
+    end;\r
+    closeFile( f );                         // Cierra el archivo\r
+end;\r
+\r
+procedure TMainForm.SerializarJuego( archivo: string );\r
+var\r
+  serializado: string;\r
+  f:           TextFile;\r
+begin\r
+    try\r
+      assignFile( f, archivo ); // Asigna el archivo\r
+      rewrite( f );                         // Sobreescribe el archivo\r
+      // Serializa agregando alguna información sobre el archivo y la versión\r
+      serializado := '<jaw version=1.0>' + aEspacio.mSerializar + '</jaw>';\r
+      write( f, serializado );              // Escribe en el archivo\r
+      closeFile( f );                       // Cierra el archivo\r
+    except  // Si hay algun error\r
+      on e: Exception do // Muestra un mensaje\r
+        ShowMessage( 'Hubo un error al grabar el archivo "' +\r
+                     archivo + '": ' + #13 + #10 +\r
+                     e.Message + #13 + #10 +\r
+                     'Por favor lea la Sección de Errores del Manual del ' +\r
+                     'Usuario para más información'  ); // Muestra un mensaje\r
+    end;\r
+end;\r
+\r
+procedure TMainForm.aMenuItemCambioAutomaticoClick(Sender: TObject);\r
+begin\r
+  aMenuItemCambioAutomatico.Checked := not aMenuItemCambioAutomatico.Checked; \r
+end;\r
+\r
+end.\r
diff --git a/src/modelo/Coordenadas.pas b/src/modelo/Coordenadas.pas
new file mode 100644 (file)
index 0000000..2752bc2
--- /dev/null
@@ -0,0 +1,550 @@
+{** Implementa un sistema de coordenadas y metodos para rotarlo.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    28/10/00: Se agregaron métodos para modificar el sistema de coordenadas, asignandole a un versor\r
+              particular la direccion de un vector arbitrario (mSetI, mSetJ, mSetK).\r
+    </PRE>}\r
+unit Coordenadas;\r
+\r
+interface\r
+\r
+uses\r
+  Tipos,\r
+  ObjetoPersistente,\r
+  Vectores;\r
+\r
+type\r
+  {** Implementa un sistema de coordenadas y metodos para rotarlo.}\r
+  cCoordenadas = class( cObjetoPersistente )\r
+    private\r
+      aI,          // Versor i\r
+      aJ,          // Versor j\r
+      aK: cVector; // Versor k\r
+    public\r
+      {** Constructor}\r
+      constructor create; overload;\r
+      {** Constructor que se basa en otro sistema de coordenadas}\r
+      constructor create( c: cCoordenadas ); overload;\r
+      {** Rota el sistema de coordenadas sobre el eje i\r
+          (el sentido positivo es de j a k)}\r
+      function mRotarEnI( dAngulo: tAngulo ): cCoordenadas;\r
+      {** Rota el sistema de coordenadas sobre el eje j\r
+          (el sentido positivo es de i a k)}\r
+      function mRotarEnJ( dAngulo: tAngulo ): cCoordenadas;\r
+      {** Rota el sistema de coordenadas sobre el eje k\r
+          (el sentido positivo es de i a j)}\r
+      function mRotarEnK( dAngulo: tAngulo ): cCoordenadas;\r
+      {** Obtiene el versor i}\r
+      function mGetI: cVector;\r
+      {** Obtiene el versor j}\r
+      function mGetJ: cVector;\r
+      {** Obtiene el versor k}\r
+      function mGetK: cVector;\r
+      {** Setea la dirección del versor î igual que la del vector v.\r
+          Para lograr esto, rota primero sobre el eje k y luego sobre el eje j\r
+          (no se rota sobre el eje î).}\r
+      function mSetI( v: cVector ): cCoordenadas;\r
+      {** Setea la dirección del versor j igual que la del vector v.\r
+          Para lograr esto, rota primero sobre el eje î y luego sobre el eje k\r
+          (no se rota sobre el eje j).}\r
+      function mSetJ( v: cVector ): cCoordenadas;\r
+      {** Setea la dirección del versor k igual que la del vector v.\r
+          Para lograr esto, rota primero sobre el eje j y luego sobre el eje î\r
+          (no se rota sobre el eje k).}\r
+      function mSetK( v: cVector ): cCoordenadas;\r
+      {$IFDEF DebugAlgoWars}\r
+      {** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.}\r
+      function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;\r
+      {$ENDIF}\r
+      {** Destructor}\r
+      destructor destroy; override;\r
+      // SERIALIZACION\r
+      {** Devuelve una cadena de texto con el objeto serializado.}\r
+      function mSerializar: string; override;\r
+      {** Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.}\r
+      procedure mDesSerializar( str: string ); override;\r
+  end;\r
+\r
+implementation\r
+\r
+uses\r
+  RegExpr,\r
+  Math;\r
+\r
+{ cCoordenadas }\r
+\r
+{** Constructor}\r
+constructor cCoordenadas.create;\r
+begin\r
+  inherited;\r
+  aI := cVector.create( 1, 0, 0 );\r
+  aJ := cVector.create( 0, 1, 0 );\r
+  aK := cVector.create( 0, 0, 1 );\r
+end;\r
+\r
+{** Constructor que se basa en otro sistema de coordenadas\r
+    @param c Coordenadas en las que se basa para crear las nuevas}\r
+constructor cCoordenadas.create(c: cCoordenadas);\r
+var\r
+  v: cVector;\r
+begin\r
+  inherited create;\r
+  v := c.mGetI;\r
+  aI := cVector.create( v );\r
+  v.free;\r
+  v := c.mGetJ;\r
+  aJ := cVector.create( v );\r
+  v.free;\r
+  v := c.mGetK;\r
+  aK := cVector.create( v );\r
+  v.free;\r
+end;\r
+\r
+{** Destructor}\r
+destructor cCoordenadas.destroy;\r
+begin\r
+  aI.free;\r
+  aJ.free;\r
+  aK.free;\r
+  inherited;\r
+end;\r
+\r
+{$IFDEF DebugAlgoWars}\r
+{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos.\r
+    @return            Cadena de texto con el estado del Objeto.\r
+    @param   debugLevel Cantidad de información requerida}\r
+function cCoordenadas.mGetDebugInfo(debugLevel: tDebugInfo): string;\r
+begin\r
+  result := 'Versor i: ' + aI.mGetDebugInfo( debugLevel ) + #13 + #10 +\r
+            'Versor j: ' + aJ.mGetDebugInfo( debugLevel ) + #13 + #10 +\r
+            'Versor k: ' + aK.mGetDebugInfo( debugLevel );\r
+end;\r
+{$ENDIF}\r
+\r
+{** Obtiene el versor i}\r
+function cCoordenadas.mGetI: cVector;\r
+begin\r
+  result := cVector.create( aI );\r
+end;\r
+\r
+{** Obtiene el versor j}\r
+function cCoordenadas.mGetJ: cVector;\r
+begin\r
+  result := cVector.create( aJ );\r
+end;\r
+\r
+{** Obtiene el versor k}\r
+function cCoordenadas.mGetK: cVector;\r
+begin\r
+  result := cVector.create( aK );\r
+end;\r
+\r
+{** Rota el sistema de coordenadas sobre el eje i\r
+    @param angulo Ángulo a rotar}\r
+function cCoordenadas.mRotarEnI(dAngulo: tAngulo): cCoordenadas;\r
+var\r
+  oJ,               // componente en j\r
+  oK,               // componente en k\r
+  oNuevoJ,          // nueva coordenada j\r
+  oNuevoK: cVector; // nueva coordenada k\r
+begin\r
+  // Primero se calcula el nuevo versor i utilizando la\r
+  //  transformacion lineal: j' = j * cos tAngulo + k * sin tAngulo\r
+  oJ := cVector.create( aJ ).mMultiplicar( cos( dAngulo ) );\r
+  oK := cVector.create( aK ).mMultiplicar( sin( dAngulo ) );\r
+  oNuevoJ := cVector.create( oJ ).mSumar( oK );\r
+  oJ.free;\r
+  oK.free;\r
+  // Ahora se calcula el nuevo versor k utilizando la\r
+  //  transformacion lineal: k' = k * cos tAngulo - j * sin tAngulo\r
+  oJ := cVector.create( aJ ).mMultiplicar( sin( dAngulo ) );\r
+  oK := cVector.create( aK ).mMultiplicar( cos( dAngulo ) );\r
+  oNuevoK := cVector.create( oK ).mRestar( oJ );\r
+  oJ.free;\r
+  oK.free;\r
+  // Se reemplazan los viejos versores por los nuevos\r
+  aJ.mSet( oNuevoJ );\r
+  aK.mSet( oNuevoK );\r
+  oNuevoJ.free;\r
+  oNuevoK.free;\r
+  result := self;\r
+end;\r
+\r
+{** Rota el sistema de coordenadas sobre el eje j\r
+    @param angulo Ángulo a rotar}\r
+function cCoordenadas.mRotarEnJ(dAngulo: tAngulo): cCoordenadas;\r
+var\r
+  oI,               // componente en i\r
+  oK,               // componente en k\r
+  oNuevoI,          // nueva coordenada i\r
+  oNuevoK: cVector; // nueva coordenada k\r
+begin\r
+  // Primero se calcula el nuevo versor i utilizando la\r
+  //  transformacion lineal: i' = i * cos tAngulo + k * sin tAngulo\r
+  oI := cVector.create( aI ).mMultiplicar( cos( dAngulo ) );\r
+  oK := cVector.create( aK ).mMultiplicar( sin( dAngulo ) );\r
+  oNuevoI := cVector.create( oI ).mSumar( oK );\r
+  oI.free;\r
+  oK.free;\r
+  // Ahora se calcula el nuevo versor k utilizando la\r
+  //  transformacion lineal: k' = k * cos tAngulo - i * sin tAngulo\r
+  oI := cVector.create( aI ).mMultiplicar( sin( dAngulo ) );\r
+  oK := cVector.create( aK ).mMultiplicar( cos( dAngulo ) );\r
+  oNuevoK := cVector.create( oK ).mRestar( oI );\r
+  oI.free;\r
+  oK.free;\r
+  // Se reemplazan los viejos versores por los nuevos\r
+  aI.mSet( oNuevoI );\r
+  aK.mSet( oNuevoK );\r
+  oNuevoI.free;\r
+  oNuevoK.free;\r
+  result := self;\r
+end;\r
+\r
+{** Rota el sistema de coordenadas sobre el eje k\r
+    @param angulo Ángulo a rotar}\r
+function cCoordenadas.mRotarEnK(dAngulo: tAngulo): cCoordenadas;\r
+var\r
+  oI,               // componente en i\r
+  oJ,               // componente en j\r
+  oNuevoI,          // nueva coordenada i\r
+  oNuevoJ: cVector; // nueva coordenada j\r
+begin\r
+  // Primero se calcula el nuevo versor i utilizando la\r
+  //  transformacion lineal: i' = i * cos tAngulo + j * sin tAngulo\r
+  oI := cVector.create( aI ).mMultiplicar( cos( dAngulo ) );\r
+  oJ := cVector.create( aJ ).mMultiplicar( sin( dAngulo ) );\r
+  oNuevoI := cVector.create( oI ).mSumar( oJ );\r
+  oI.free;\r
+  oJ.free;\r
+  // Ahora se calcula el nuevo versor j utilizando la\r
+  //  transformacion lineal: j' = j * cos tAngulo - i * sin tAngulo\r
+  oI := cVector.create( aI ).mMultiplicar( sin( dAngulo ) );\r
+  oJ := cVector.create( aJ ).mMultiplicar( cos( dAngulo ) );\r
+  oNuevoJ := cVector.create( oJ ).mRestar( oI );\r
+  oI.free;\r
+  oJ.free;\r
+  // Se reemplazan los viejos versores por los nuevos\r
+  aI.mSet( oNuevoI );\r
+  aJ.mSet( oNuevoJ );\r
+  oNuevoI.free;\r
+  oNuevoJ.free;\r
+  result := self;\r
+end;\r
+\r
+{** Setea la dirección del versor î igual que la del vector v.\r
+    Para lograr esto, rota primero sobre el eje k y luego sobre el eje j\r
+    (no se rota sobre el eje î).\r
+    @param v Dirección a asignarle a î (no puede ser nulo!)}\r
+function cCoordenadas.mSetI(v: cVector): cCoordenadas;\r
+var\r
+  vProy,              // Proyección de v sobre el plano ij\r
+  vi,                 // ip.i (vector proyeccion de v en i)\r
+  vj: cVector;        // jp.j (vector proyeccion de v en j)\r
+  ip,                 // v.i  (proyeccion de v en i)\r
+  jp,                 // v.j  (proyeccion de v en j)\r
+  kp,                 // v.k  (proyeccion de v en k)\r
+  modulo: tLongitud;  // Módulo de vProy\r
+  alfa,               // Angulo formado entre i y vProy\r
+  beta: tAngulo;      // Angulo formado entre i' (i rotado sobre k) y v\r
+begin\r
+  // Se calcula la proyeccion de v sobre el plano formado por î y j.\r
+  // Para hacer esto, se utiliza la farmula de proyeccion a partir de una base ortonormal\r
+  //  del subespacio en donde proyectar (en este caso el subespacio es el plano formado\r
+  //  por îj y los versores de la BON son î y j:\r
+  //    Proy ij (v) = (v.i).i + (v.j).j\r
+  // Se crea en base a i y se multiplica por el producto escalar entre v y î\r
+  ip := v.mMultiplicarEsc( aI );\r
+  vi := cVector.create( aI ).mMultiplicar( ip );\r
+  // Se crea en base a j y se multiplica por el producto escalar entre v y j\r
+  jp := v.mMultiplicarEsc( aJ );\r
+  vj := cVector.create( aJ ).mMultiplicar( jp );\r
+  // Ahora se calcula la proyección sumando vi y vj\r
+  vProy := cVector.create( vi ).mSumar( vj );\r
+  // Con esta proyección podemos calcular en ángulo que debemos rotar las coordenadas\r
+  //  sobre el eje k de la siguiente forma (se toman las proyecciones para que, dependiendo\r
+  //  del signo, se pueda establecer el ángulo correcto):\r
+  //    tg alfa = jp / ip  ==> alfa = arctg( jp / ip )\r
+  //  si ip = 0  ==>  v no tiene componentes en i  ==>  se sabe que el angulo es recto,\r
+  //   para saber si es PI/2 o -PI/2, verificamos si (vProy.j)/|vProy| = cos vProyj = 1,\r
+  //   entonces alfa = PI/2. Si (vProy.j)/|vProy| = cos vProyj = -1  ==>  alfa = -PI/2\r
+  modulo := vProy.mGetModulo;\r
+  if modulo > 0 then begin // solo hace falta rotarlo si la proyeccion no es nula\r
+    alfa := arctan2( jp, ip );\r
+    if alfa <> 0 then begin // Si el angulo es distinto de cero, hay que rotarlo\r
+      if alfa = PI/2 then // Si es PI/2 hay que verificar que no sea en realidad -PI/2\r
+        // Se compara tomando en cuenta si es menor que cero porque ya sabemos que\r
+        //  solo puede ser 1 o -1.\r
+        if jp / modulo < 0 then // cos vProyj = vProy . j / |vProy| = jp . |vProy|\r
+          alfa := -alfa; // alfa = -PI/2\r
+      mRotarEnK( alfa ); // rotamos sobre el eje k ese angulo\r
+    end;\r
+  end;\r
+  // Ahora tenemos que hallar beta, para esto se calculan las proyecciones sobre i y k\r
+  // Se calcula la proyeccion, para eso se multiplica por el producto escalar entre v y î\r
+  ip := v.mMultiplicarEsc( aI );\r
+  // Se calcula la proyeccion, para eso se multiplica por el producto escalar entre v y k\r
+  kp := v.mMultiplicarEsc( aK );\r
+  // Con estas proyecciones podemos calcular en ángulo que debemos rotar las coordenadas\r
+  //  sobre el eje k de la siguiente forma (se toman las proyecciones para que, dependiendo\r
+  //  del signo, se pueda establecer el ángulo correcto):\r
+  //    tg beta = kp / ip  ==> beta = arctg( kp / ip )\r
+  //  si ip = 0  ==>  v no tiene componentes en i  ==>  se sabe que el angulo es recto,\r
+  //   para saber si es PI/2 o -PI/2, verificamos si (v.k)/|v| = cos vk = 1,\r
+  //   entonces beta = PI/2. Si (v.k)/|v| = cos vk = -1  ==>  beta = -PI/2\r
+  modulo := v.mGetModulo;\r
+  if modulo > 0 then begin // solo hace falta rotarlo si la proyeccion no es nula\r
+    beta := arctan2( kp, ip );\r
+    if beta <> 0 then begin // Si el angulo es distinto de cero, hay que rotarlo\r
+      if beta = PI/2 then // Si es PI/2 hay que verificar que no sea en realidad -PI/2\r
+        // Se compara tomando en cuenta si es menor que cero porque ya sabemos que\r
+        //  solo puede ser 1 o -1.\r
+        if kp / modulo < 0 then // cos vk = v . k / |v| = kp . |v|\r
+          beta := -beta; // beta = -PI/2\r
+      mRotarEnJ( beta ); // rotamos sobre el eje j ese angulo\r
+    end;\r
+  end;\r
+  // Aca termina, ya que no se realiza ninguna rotacion sobre el eje i\r
+  result := self;\r
+end;\r
+\r
+{** Setea la dirección del versor j igual que la del vector v.\r
+    Para lograr esto, rota primero sobre el eje î y luego sobre el eje k\r
+    (no se rota sobre el eje j).\r
+    @param v Dirección a asignarle a j (no puede ser nulo!)}\r
+function cCoordenadas.mSetJ(v: cVector): cCoordenadas;\r
+var\r
+  vProy,              // Proyección de v sobre el plano jk\r
+  vj,                 // jp.j (vector proyeccion de v en j)\r
+  vk: cVector;        // kp.k (vector proyeccion de v en k)\r
+  ip,                 // v.i  (proyeccion de v en i)\r
+  jp,                 // v.j  (proyeccion de v en j)\r
+  kp,                 // v.k  (proyeccion de v en k)\r
+  modulo: tLongitud;  // Módulo de vProy\r
+  alfa,               // Angulo formado entre j y vProy\r
+  beta: tAngulo;      // Angulo formado entre j' (j rotado sobre i) y v\r
+begin\r
+  // Se calcula la proyeccion de v sobre el plano formado por j y k.\r
+  // Para hacer esto, se utiliza la farmula de proyeccion a partir de una base ortonormal\r
+  //  del subespacio en donde proyectar (en este caso el subespacio es el plano formado\r
+  //  por jk y los versores de la BON son j y k:\r
+  //    Proy jk (v) = (v.j).j + (v.k).k\r
+  // Se crea en base a j y se multiplica por el producto escalar entre v y j\r
+  jp := v.mMultiplicarEsc( aJ );\r
+  vj := cVector.create( aJ ).mMultiplicar( jp );\r
+  // Se crea en base a k y se multiplica por el producto escalar entre v y k\r
+  kp := v.mMultiplicarEsc( aK );\r
+  vk := cVector.create( aK ).mMultiplicar( kp );\r
+  // Ahora se calcula la proyección sumando vj y vk\r
+  vProy := cVector.create( vj ).mSumar( vk );\r
+  // Con esta proyección podemos calcular en ángulo que debemos rotar las coordenadas\r
+  //  sobre el eje i de la siguiente forma (se toman las proyecciones para que, dependiendo\r
+  //  del signo, se pueda establecer el ángulo correcto):\r
+  //    tg alfa = kp / jp  ==> alfa = arctg( kp / jp )\r
+  //  si jp = 0  ==>  v no tiene componentes en j  ==>  se sabe que el angulo es recto,\r
+  //   para saber si es PI/2 o -PI/2, verificamos si (vProy.k)/|vProy| = cos vProyk = 1,\r
+  //   entonces alfa = PI/2. Si (vProy.k)/|vProy| = cos vProyk = -1  ==>  alfa = -PI/2\r
+  modulo := vProy.mGetModulo;\r
+  if modulo > 0 then begin // solo hace falta rotarlo si la proyeccion no es nula\r
+    alfa := arctan2( kp, jp );\r
+    if alfa <> 0 then begin // Si el angulo es distinto de cero, hay que rotarlo\r
+      if alfa = PI/2 then // Si es PI/2 hay que verificar que no sea en realidad -PI/2\r
+        // Se compara tomando en cuenta si es menor que cero porque ya sabemos que\r
+        //  solo puede ser 1 o -1.\r
+        if kp / modulo < 0 then // cos vProyk = vProy . k / |vProy| = kp . |vProy|\r
+          alfa := -alfa; // alfa = -PI/2\r
+      mRotarEnI( alfa ); // rotamos sobre el eje i ese angulo\r
+    end;\r
+  end;\r
+  // Ahora tenemos que hallar beta, para esto se calculan las proyecciones sobre j y i\r
+  // Se calcula la proyeccion, para eso se multiplica por el producto escalar entre v y j\r
+  jp := v.mMultiplicarEsc( aJ );\r
+  // Se calcula la proyeccion, para eso se multiplica por el producto escalar entre v y i\r
+  ip := v.mMultiplicarEsc( aI );\r
+  // Con estas proyecciones podemos calcular en ángulo que debemos rotar las coordenadas\r
+  //  sobre el eje k de la siguiente forma (se toman las proyecciones para que, dependiendo\r
+  //  del signo, se pueda establecer el ángulo correcto):\r
+  //    tg beta = ip / jp  ==> beta = arctg( ip / jp )\r
+  //  si jp = 0  ==>  v no tiene componentes en j  ==>  se sabe que el angulo es recto,\r
+  //   para saber si es PI/2 o -PI/2, verificamos si (v.i)/|v| = cos vi = 1,\r
+  //   entonces beta = PI/2. Si (v.i)/|v| = cos vi = -1  ==>  beta = -PI/2\r
+  modulo := v.mGetModulo;\r
+  if modulo > 0 then begin // solo hace falta rotarlo si la proyeccion no es nula\r
+    beta := arctan2( ip, jp );\r
+    if beta <> 0 then begin // Si el angulo es distinto de cero, hay que rotarlo\r
+      if beta = PI/2 then // Si es PI/2 hay que verificar que no sea en realidad -PI/2\r
+        // Se compara tomando en cuenta si es menor que cero porque ya sabemos que\r
+        //  solo puede ser 1 o -1.\r
+        if ip / modulo < 0 then // cos vi = v . i / |v| = ip . |v|\r
+          beta := -beta; // beta = -PI/2\r
+      mRotarEnK( -beta ); // rotamos sobre el eje k ese angulo (el signo negativo es porque\r
+                          //  estamos rotando en sentido opuesto, de j a i)\r
+    end;\r
+  end;\r
+  // Aca termina, ya que no se realiza ninguna rotacion sobre el eje j\r
+  result := self;\r
+end;\r
+\r
+{** Setea la dirección del versor k igual que la del vector v.\r
+    Para lograr esto, rota primero sobre el eje j y luego sobre el eje î\r
+    (no se rota sobre el eje k).\r
+    @param v Dirección a asignarle a k (no puede ser nulo!)}\r
+function cCoordenadas.mSetK(v: cVector): cCoordenadas;\r
+var\r
+  vProy,              // Proyección de v sobre el plano jk\r
+  vi,                 // ip.i (vector proyeccion de v en i)\r
+  vk: cVector;        // kp.k (vector proyeccion de v en k)\r
+  ip,                 // v.i  (proyeccion de v en i)\r
+  jp,                 // v.j  (proyeccion de v en j)\r
+  kp,                 // v.k  (proyeccion de v en k)\r
+  modulo: tLongitud;  // Módulo de vProy\r
+  alfa,               // Angulo formado entre j y vProy\r
+  beta: tAngulo;      // Angulo formado entre j' (j rotado sobre i) y v\r
+begin\r
+  // Se calcula la proyeccion de v sobre el plano formado por k y i.\r
+  // Para hacer esto, se utiliza la farmula de proyeccion a partir de una base ortonormal\r
+  //  del subespacio en donde proyectar (en este caso el subespacio es el plano formado\r
+  //  por ki y los versores de la BON son k y i:\r
+  //    Proy ki (v) = (v.k).k + (v.i).i\r
+  // Se crea en base a k y se multiplica por el producto escalar entre v y k\r
+  kp := v.mMultiplicarEsc( aK );\r
+  vk := cVector.create( aK ).mMultiplicar( kp );\r
+  // Se crea en base a k y se multiplica por el producto escalar entre v y k\r
+  ip := v.mMultiplicarEsc( aI );\r
+  vi := cVector.create( aI ).mMultiplicar( ip );\r
+  // Ahora se calcula la proyección sumando vk y vi\r
+  vProy := cVector.create( vk ).mSumar( vi );\r
+  // Con esta proyección podemos calcular en ángulo que debemos rotar las coordenadas\r
+  //  sobre el eje j de la siguiente forma (se toman las proyecciones para que, dependiendo\r
+  //  del signo, se pueda establecer el ángulo correcto):\r
+  //    tg alfa = ip / kp  ==> alfa = arctg( ip / kp )\r
+  //  si kp = 0  ==>  v no tiene componentes en j  ==>  se sabe que el angulo es recto,\r
+  //   para saber si es PI/2 o -PI/2, verificamos si (vProy.i)/|vProy| = cos vProyi = 1,\r
+  //   entonces alfa = PI/2. Si (vProy.i)/|vProy| = cos vProyi = -1  ==>  alfa = -PI/2\r
+  modulo := vProy.mGetModulo;\r
+  if modulo > 0 then begin // solo hace falta rotarlo si la proyeccion no es nula\r
+    alfa := arctan2( ip, kp );\r
+    if alfa <> 0 then begin // Si el angulo es distinto de cero, hay que rotarlo\r
+      if alfa = PI/2 then // Si es PI/2 hay que verificar que no sea en realidad -PI/2\r
+        // Se compara tomando en cuenta si es menor que cero porque ya sabemos que\r
+        //  solo puede ser 1 o -1.\r
+        if ip / modulo < 0 then // cos vProyi = vProy . i / |vProy| = ip . |vProy|\r
+          alfa := -alfa; // alfa = -PI/2\r
+      mRotarEnJ( -alfa ); // rotamos sobre el eje j ese angulo (el signo negativo es porque\r
+                          //  estamos rotando en sentido opuesto, de k a i)\r
+    end;\r
+  end;\r
+  // Ahora tenemos que hallar beta, para esto se calculan las proyecciones sobre k y j\r
+  // Se calcula la proyeccion, para eso se multiplica por el producto escalar entre v y k\r
+  kp := v.mMultiplicarEsc( aK );\r
+  // Se calcula la proyeccion, para eso se multiplica por el producto escalar entre v y j\r
+  jp := v.mMultiplicarEsc( aJ );\r
+  // Con estas proyecciones podemos calcular en ángulo que debemos rotar las coordenadas\r
+  //  sobre el eje i de la siguiente forma (se toman las proyecciones para que, dependiendo\r
+  //  del signo, se pueda establecer el ángulo correcto):\r
+  //    tg beta = jp / kp  ==> beta = arctg( jp / kp )\r
+  //  si kp = 0  ==>  v no tiene componentes en k  ==>  se sabe que el angulo es recto,\r
+  //   para saber si es PI/2 o -PI/2, verificamos si (v.j)/|v| = cos vj = 1,\r
+  //   entonces beta = PI/2. Si (v.j)/|v| = cos vj = -1  ==>  beta = -PI/2\r
+  modulo := v.mGetModulo;\r
+  if modulo > 0 then begin // solo hace falta rotarlo si la proyeccion no es nula\r
+    beta := arctan2( jp, kp );\r
+    if beta <> 0 then begin // Si el angulo es distinto de cero, hay que rotarlo\r
+      if beta = PI/2 then // Si es PI/2 hay que verificar que no sea en realidad -PI/2\r
+        // Se compara tomando en cuenta si es menor que cero porque ya sabemos que\r
+        //  solo puede ser 1 o -1.\r
+        if ip / modulo < 0 then // cos vj = v . j / |v| = jp . |v|\r
+          beta := -beta; // beta = -PI/2\r
+      mRotarEnI( -beta ); // rotamos sobre el eje i ese angulo (el signo negativo es porque\r
+                          //  estamos rotando en sentido opuesto, de k a j)\r
+    end;\r
+  end;\r
+  // Aca termina, ya que no se realiza ninguna rotacion sobre el eje k\r
+  result := self;\r
+end;\r
+\r
+{** Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    @param str Cadena de texto con el objeto serializado.}\r
+procedure cCoordenadas.mDesSerializar(str: string);\r
+var\r
+  r: TRegExpr;\r
+begin\r
+  inherited mDesSerializar( str ); // SIEMPRE el ID debe ser el PRIMER atributo\r
+  r := TRegExpr.create;\r
+  // VERSOR I\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<i>\s*(.+)\s*</i>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      if aI <> nil then // Si no es nulo\r
+        aI.mDesSerializar( r.Match[1] ) // Lo deserializa\r
+      else // si es nulo\r
+        aI := cVector.crearDeSerializado( r.Match[1] ) // lo crea\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el versor i' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ESerializacion do begin // Si fueron de serializacion...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al deserializar el versor i: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el versor i utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // VERSOR J\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<j>\s*(.+)\s*</j>';\r
+    if r.Exec ( str ) then\r
+      if aJ <> nil then\r
+        aJ.mDesSerializar( r.Match[1] )\r
+      else\r
+        aJ := cVector.crearDeSerializado( r.Match[1] )\r
+    else\r
+      raise ESerializacion.create( 'No se encontro el versor j' );\r
+  except\r
+    on e: ESerializacion do begin\r
+      r.Free;\r
+      raise ESerializacion.create( ClassName + ': Error al deserializar el versor j: ' + e.Message );\r
+    end;\r
+    on e: ERegExpr do begin\r
+      r.Free;\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el versor j utilizando expresiones regulares: ' + e.Message );\r
+    end;\r
+  end;\r
+  // VERSOR K\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<k>\s*(.+)\s*</k>';\r
+    if r.Exec ( str ) then\r
+      if aK <> nil then\r
+        aK.mDesSerializar( r.Match[1] )\r
+      else\r
+        aK := cVector.crearDeSerializado( r.Match[1] )\r
+    else\r
+      raise ESerializacion.create( 'No se encontro el versor k' );\r
+  except\r
+    on e: ESerializacion do begin\r
+      r.Free;\r
+      raise ESerializacion.create( ClassName + ': Error al deserializar el versor k: ' + e.Message );\r
+    end;\r
+    on e: ERegExpr do begin\r
+      r.Free;\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el versor k utilizando expresiones regulares: ' + e.Message );\r
+    end;\r
+  end;\r
+  r.free;\r
+end;\r
+\r
+{** Devuelve una cadena de texto con el objeto serializado.\r
+    @return Cadena de texto con el objeto serializado.}\r
+function cCoordenadas.mSerializar: string;\r
+begin\r
+  result := inherited mSerializar +\r
+            '<i>' + aI.mSerializar + '</i>' +\r
+            '<j>' + aJ.mSerializar + '</j>' +\r
+            '<k>' + aK.mSerializar + '</k>';\r
+end;\r
+\r
+end.\r
diff --git a/src/modelo/Espacio.pas b/src/modelo/Espacio.pas
new file mode 100644 (file)
index 0000000..1652e6e
--- /dev/null
@@ -0,0 +1,493 @@
+{** Se encarga de controlar la interacción entre\r
+    las naves y el responsable de manejar el tiempo.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    05/10/00: Se corrigió para que utilice los nuevos metodos de cNaveEnemiga y cObjetoVolador\r
+              Se corrigió el método mComunicarPosicion para que solo se comunique la posicion\r
+              a las naves que estan en el campo de radar de la nave espia.\r
+    07/10/00: Se agregaron los métodos mDestruir y mActualizarObjetoVolador. Se modificó el\r
+              método mActualizar (para usar los nuevos) y el método mDetectarColisiones para\r
+              manejar de forma más eficiente y clara la destrucción de objetos sin energía.\r
+    03/11/00: Se sacan los metodos mIniciay y mParar, ya que el control del tiempo y el encargado\r
+              de actualizar el espacio sera el Controlador (Controller).\r
+              Se agregaron métodos para facilitar la manipulación del espacio:\r
+              mQuitarObjeto, mGetObjetos, mSetObjetos y mSetNavePropia\r
+    05/11/00: Se corrigió un BUG que hacia que siempre el espacio se inicialice con una lista vacia\r
+              y una nave propia estandar (en el constructor).\r
+    09/11/00: Se corrigió un BUG que hacía que la nave espia no pueda escapar, ya que se avisaba a si misma.\r
+              Tambien se hace que ignore otras naves espias que esten avisando para evitar problemas similares.\r
+              (en el método mComunicarPosicion).\r
+    10/11/00: Se reemplaza el método mNavePropiaDestruida por una excepción (ENavePropiaDestruida).\r
+              Es lanzada por el método mActualizar y otros metodos privados que utilizan la nave propia.\r
+    27/11/00: Se agrega el control de disparos de las naves enemigas en el método mActualizar\r
+    29/11/00: Se elimina el método temporal mActualizarNavePropia.\r
+    01/12/00: Se modifica el método mActualizar para manejar los disparos de la nave propia.\r
+    </PRE>}\r
+unit Espacio;\r
+\r
+interface\r
+\r
+uses\r
+  Tipos,\r
+  ObjetoPersistente,\r
+  ObjetoVolador,\r
+  Nave,\r
+  Vectores,\r
+  Armas,\r
+  NaveEnemiga,\r
+  NavesEnemigas,\r
+  NavePropia,\r
+  Classes,\r
+  Sysutils,\r
+  Meteorito;\r
+\r
+type\r
+  {** Excepcion producida por el espacio si la nave propia fue destruido}\r
+  ENavePropiaDestruida = class( Exception )\r
+    public\r
+      {** Constructor}\r
+      constructor create;\r
+  end;\r
+\r
+  {** Se encarga de controlar la interacción entre\r
+      las naves y el responsable de manejar el tiempo.}\r
+  cEspacio = class( cObjetoPersistente )\r
+    private\r
+      aDeltaT:  tTiempo;        // Intervalo de tiempo (en milisegundos) que pasa entre ciclo y ciclo\r
+      aNavePropia: cNavePropia; // Nave del jugador, tambien esta en la lista, pero se lo\r
+                                //  pone a parte para poder ser referenciado más fácilmente\r
+      aObjetos: TList;          // Lista con los objetos presentes en el espacio\r
+    protected\r
+      {** Procedimiento que evalua las posiciones de los Objetos Voladores que se encuentran en el espacio,\r
+          verificando 2 a 2 si hay una colisión.}\r
+      procedure mDetectarColision;\r
+      {** Método que se encarga de avisar al resto de las naves enemigas que estan cerca de una\r
+          espia sobre la ultima posicion de la nave propia.}\r
+      procedure mComunicarPosicion( nEsp: cNaveEspia );\r
+      {** Destruye un Objeto Volador}\r
+      procedure mDestruir( ov: cObjetoVolador );\r
+      {** Actualiza el estado de un objeto según sea tu tipo}\r
+      procedure mActualizarObjetoVolador( ov: cObjetoVolador );\r
+      {** Elimina los objetos duplicados después de recuperarlos de una serialización}\r
+      procedure mEliminarDuplicados;\r
+      {** Busca el duplicado de un objeto volador}\r
+      function mBuscarDuplicado( ov: cObjetoVolador ): cObjetoVolador;\r
+    public\r
+      {** Constructor. La lista que se pasa NO debe incluir la nave propia}\r
+      constructor create( np: cNavePropia = nil; objetos: TList = nil; dt: tTiempo = 25 );\r
+      {** Actualiza el Espacio. En esto se incluye mover las naves, detectar colisiones y tomar las\r
+          desiciones necesarias según sea el caso.}\r
+      procedure mActualizar;\r
+      {** Agrega un Objeto Volador al Espacio}\r
+      procedure mAgregarObjeto( ov: cObjetoVolador );\r
+      {** Quita un Objeto Volador del Espacio. Devuelve true si lo saco y false si no existia}\r
+      function mQuitarObjeto( ov: cObjetoVolador ): boolean;\r
+      {** Obtiene la lista de Objetos Voladores del Espacio}\r
+      function mGetObjetos: TList;\r
+      {** Cambia la lista de Objetos Voladores del Espacio, devolviendo un puntero a la lista vieja}\r
+      function mSetObjetos( l: TList ): TList;\r
+      {$IFDEF DebugAlgoWars}\r
+      {** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.}\r
+      function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;\r
+      {$ENDIF}\r
+      {** Método que obtiene la nave propia del espacio (este método es probable que deje de exstir)}\r
+      function mGetNavePropia: cNavePropia;\r
+      {** Método para cambiar la nave propia. Devuelve un puntero a la nave propia vieja.}\r
+      function mSetNavePropia( np: cNavePropia ): cNavePropia;\r
+      {** Destructor}\r
+      destructor destroy; override;\r
+      // SERIALIZACION\r
+      {** Devuelve una cadena de texto con el objeto serializado.}\r
+      function mSerializar: string; override;\r
+      {** Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.}\r
+      procedure mDesSerializar( str: string ); override;\r
+    end;\r
+\r
+implementation\r
+\r
+uses\r
+  RegExpr,\r
+  SerializacionUtils;\r
+\r
+{ cEspacio }\r
+\r
+{** Constructor\r
+    @param np      Nave propia a utilizar\r
+    @param objetos Lista de objetos voladores (sin incluir la nave propia!)\r
+    @param dt      Intervalo de tiempo}\r
+constructor cEspacio.create(np: cNavePropia; objetos: TList; dt: tTiempo);\r
+begin\r
+  inherited create;\r
+  if objetos <> nil then\r
+    aObjetos := objetos\r
+  else // Si no se pasó nada como argumento, crea una nueva lista.\r
+    aObjetos := TList.create;\r
+  // inicializa la nave propia y la inserta en la lista.\r
+  if np <> nil then\r
+    aNavePropia := np\r
+  else // Si no se pasó nada como argumento, crea una nueva nave propia.\r
+    aNavePropia := cNavePropia.create;\r
+  aObjetos.Add( aNavePropia );\r
+  // Define el intervalo de tiempo\r
+  aDeltaT := dt;\r
+end;\r
+\r
+{** Destructor}\r
+destructor cEspacio.destroy;\r
+var\r
+  oOV: cObjetoVolador;\r
+begin\r
+  // Recorre la lista, liberando los Objetos Voladores en ella\r
+  while aObjetos.Count > 0 do begin\r
+    oOV := aObjetos.First;\r
+    aObjetos.Remove( oOV );\r
+    oOV.free;\r
+  end;\r
+  aObjetos.free; // Libera la memoria de la lista\r
+  inherited;\r
+end;\r
+\r
+{** Actualiza el Espacio. En esto se incluye mover las naves, detectar colisiones y tomar las\r
+    desiciones necesarias según sea el caso.}\r
+procedure cEspacio.mActualizar;\r
+var\r
+  i:     integer;        // contador para el bucle\r
+  oOV:   cObjetoVolador; // objeto volador para apuntar al de la lista\r
+  oArma: cArma;          // Arma disparada\r
+begin\r
+  for i:=0 to aObjetos.count -1 do begin // recorre la lista de objetos\r
+    oOV:= aObjetos.items[i]; // obtiene el ObjetoVolador actual\r
+    mActualizarObjetoVolador( oOV ); // Actualiza el estado del objeto segun su tipo\r
+    oOV.mMover( aDeltaT );  // Se mueve la objeto volador actual sin importar de que clase sea\r
+    if oOV is cNave then begin // Si es una nave, maneja los disparos\r
+      with oOV as cNave do begin  // Convierte el puntero a cNave\r
+        if oOV is cNaveEnemiga then                   // Si es una nave enemiga\r
+          oArma := mDisparar( aDeltaT, aNavePropia )  // Dispara con la NavePropia como objetivo\r
+        else                                   // Si es otra nave (inclusive la nave propia)\r
+          oArma := mDisparar( aDeltaT )   // dispara con nil como objetivo (el objetivo es\r
+      end;                                     // manejado por la propia nave)\r
+      if oArma <> nil then        // Si efectivamente se disparo un arma\r
+        mAgregarObjeto( oArma );  // Se la agrega a la lista\r
+    end;\r
+  end;\r
+  mDetectarColision; // Se detectan las colisiones\r
+  if aNavePropia = nil then\r
+    raise ENavePropiaDestruida.create;\r
+end;\r
+\r
+{** Actualiza el estado de un objeto volador, dependiendo de que tipo de objeto sea.\r
+    @param ov Objeto Volador a actualizar}\r
+procedure cEspacio.mActualizarObjetoVolador(ov: cObjetoVolador);\r
+begin\r
+  if ov is cNaveEnemiga then begin // si es una nave enemiga...\r
+    with ov as cNaveEnemiga do // "Transforma el puntero" a uno de clase NaveEnemiga\r
+    if aNavePropia = nil then\r
+      raise ENavePropiaDestruida.create\r
+    else\r
+      if mDetectado( aNavePropia ) then // si la nave propia esta en el campo de radar de la nave enemiga...\r
+        mReaccionar( aNavePropia );  // se manda un mensaje a la nave enemiga de atacar a la propia\r
+      // Si es una nave espia, nos fijamos si esta avisando\r
+      if ov is cNaveEspia then begin\r
+        with ov as cNaveEspia do // "Transforma el puntero" a uno de clase NaveEspia\r
+        if mAvisando then\r
+          mComunicarPosicion( ov as cNaveEspia );\r
+      end;\r
+  end;\r
+end;\r
+\r
+{** Agrega un Objeto Volador al Espacio\r
+    @param ov Objeto volador a agregar}\r
+procedure cEspacio.mAgregarObjeto(ov: cObjetoVolador);\r
+begin\r
+  aObjetos.Add( ov );\r
+end;\r
+\r
+{** Método que se encarga de avisar al resto de las naves enemigas que estan cerca de una\r
+    espia sobre la ultima posicion de la nave propia.\r
+    @param nEsp Nave espía que está avisando}\r
+procedure cEspacio.mComunicarPosicion(nEsp: cNaveEspia);\r
+var\r
+  i:   integer;        // contador para el bucle\r
+  oOV: cObjetoVolador; // objeto volador para apuntar al de la lista\r
+begin\r
+  for i := 0 to aObjetos.Count - 1 do begin  // recorre la lista\r
+    oOV := aObjetos.Items[i]; // obteniendo el primer objeto volador\r
+    if oOV = nEsp then // Si es la misma nave propia...\r
+      continue;        //  la pasa por alto\r
+    if oOV is cNaveEnemiga then begin // si es una nave enemiga...\r
+      if oOV is cNaveEspia then    // Si es una nave espia, se fija si esta avisando\r
+        with oOV as cNaveEspia do\r
+          if mAvisando then        // Si esta avisando:\r
+            continue;              // la pasa por alto\r
+      if nEsp.mDetectado( oOV ) then // Si esta dentro del radar de la nave espia...\r
+        with oOV as cNaveEnemiga do\r
+          mIrA( nEsp.mGetPosicionEnemiga );   // Le indica que vaya a la ultima posicion\r
+                                              //  en donde vio a la nave propia\r
+    end;\r
+  end;\r
+end;\r
+\r
+{** Destruye un objeto volador, liberando memoria y eliminandolo de la lista\r
+    @param ov Objeto Volador a destruir}\r
+procedure cEspacio.mDestruir(ov: cObjetoVolador);\r
+begin\r
+  aObjetos.Remove( ov );\r
+  if ov is cNavePropia then\r
+    aNavePropia := nil;\r
+  ov.Free;\r
+end;\r
+\r
+{** Procedimiento que evalua las posiciones de los Objetos Voladores que se encuentran en el espacio,\r
+    verificando si hay una colisión.}\r
+procedure cEspacio.mDetectarColision;\r
+var\r
+  i,                    // contador\r
+  j: integer;           // contador\r
+  oOV1,                 // variables para apuntar a los dos objetos voladores\r
+  oOV2: cObjetoVolador; //  que queremos evaluar si colisionaron\r
+  oRotos: TList;        // lista que contiene todos los objetos voladores destruidos\r
+\r
+begin\r
+  oRotos := TList.create;\r
+  for i := 0 to aObjetos.Count - 1 do begin  // recorre la lista\r
+    oOV1 := aObjetos.Items[i]; // obteniendo el primer objeto volador\r
+    for j := i + 1 to aObjetos.Count - 1 do begin // recorre la lista a partir del objeto volador anterior (excluyentemente)\r
+      oOV2 := aObjetos.Items[j]; // obteniendo el segundo objeto volador\r
+      if oOV1.mColisiono( oOV2 ) then begin // Si colisionaron los Objetos Voladores...\r
+        oOV1.mRestarEnergia( oOV2.mGetPotencia ); // Le resta la energia al primer objeto volador\r
+        oOV2.mRestarEnergia( oOV1.mGetPotencia ); // Le resta la energia al segundo objeto volador\r
+      end;\r
+    end;\r
+    // Una vez que termina de restarle toda la energia por choques, verifica si esta destruido\r
+    if oOV1.mGetEnergia <= 0 then // Si quedo con energia negativa,\r
+      oRotos.Add( oOV1 );         //  lo agrega a la lista de objetos rotos\r
+  end;\r
+  // Destruye todos los objetos voladores rotos\r
+  while oRotos.Count > 0 do begin // Extra un objeto volador destruido de la lista (mientras que haya alguno)\r
+    oOV1 := oRotos.First;\r
+    oRotos.Remove( oOV1 ); // Elimina el objeto de la lista de objetos rotos\r
+    mDestruir( oOV1 ); // Destruye el objeto volador\r
+  end;\r
+  oRotos.free; // Libera la memoria de la lista\r
+end;\r
+\r
+{$IFDEF DebugAlgoWars}\r
+{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos.\r
+    @return            Cadena de texto con el estado del Objeto.\r
+    @param   debugLevel Cantidad de información requerida}\r
+function cEspacio.mGetDebugInfo( debugLevel: tDebugInfo ): string;\r
+var\r
+  i:  integer;         // contador\r
+  oOV: cObjetoVolador; // variable temporal para obtener info del OV\r
+begin\r
+  result := '';\r
+  // Genera el string con el estado del Espacio\r
+  if debugLevel > DI_NORMAL then\r
+    result := result + 'Delta de T = ' + FloatToStrF( aDeltaT, ffNumber, 10, 0 ) + #13 + #10;\r
+  // Genera el string con el estado de los objetos dentro del Espacio\r
+  for i := 0 to aObjetos.Count - 1 do begin\r
+    oOV := aObjetos.Items[i];\r
+    result := result + #13 + #10 +\r
+              'ObjetoVolador' + IntToStr( i ) + ' (' + oOV.ClassName + '): ' + #13 + #10 +\r
+              oOV.mGetDebugInfo( debugLevel ) + #13 + #10\r
+              + '----';\r
+  end;\r
+end;\r
+{$ENDIF}\r
+\r
+{** Método que obtiene la nave propia del espacio (este método es probable que deje de exstir)\r
+    @return Instancia de la nave propia que se encuentra en el espacio (como puntero)}\r
+function cEspacio.mGetNavePropia: cNavePropia;\r
+begin\r
+  result := aNavePropia;\r
+end;\r
+\r
+{** Quita un Objeto Volador del Espacio. Devuelve true si lo saco y false si no existia\r
+    (esto lo quita del espacio, no lo destruye)\r
+    @param  ov Objeto a quitar del espacio\r
+    @return    <i>true</i> si se quitó, <i>false</i> si no estaba en el espacio}\r
+function cEspacio.mQuitarObjeto( ov: cObjetoVolador ): boolean;\r
+var\r
+  index: integer;\r
+begin\r
+  result := false;\r
+  index := aObjetos.IndexOf( ov );\r
+  if index >= 0 then begin\r
+    aObjetos.Delete( index );\r
+    result := true;\r
+  end;\r
+end;\r
+\r
+{** Obtiene la lista de Objetos Voladores del Espacio\r
+    @return Lista de objetos del espacio (como puntero)}\r
+function cEspacio.mGetObjetos: TList;\r
+begin\r
+  result := aObjetos;\r
+end;\r
+\r
+{** Cambia la lista de Objetos Voladores del Espacio, devolviendo un puntero a la lista vieja\r
+    @param  l Nueva lista de objetos a asignarle al espacio\r
+    @return   Vieja lista de objetos del espacio}\r
+function cEspacio.mSetObjetos( l: TList ): TList;\r
+begin\r
+  result := aObjetos;\r
+  aObjetos := l;\r
+end;\r
+\r
+{** Método para cambiar la nave propia. Devuelve un puntero a la nave propia vieja.\r
+    @return Lista de objetos del espacio (como puntero)}\r
+function cEspacio.mSetNavePropia( np: cNavePropia ): cNavePropia;\r
+begin\r
+  result := aNavePropia;\r
+  aNavePropia := np;\r
+end;\r
+\r
+{** Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    @param str Cadena de texto con el objeto serializado.}\r
+procedure cEspacio.mDesSerializar(str: string);\r
+var\r
+  total,\r
+  i:       integer;\r
+  objetos: string;\r
+  r:       TRegExpr;\r
+  ov:      cObjetoVolador;\r
+begin\r
+  // Crea la lista de ser necesario\r
+  if aObjetos = nil then\r
+    aObjetos := TList.create;\r
+  // Libera la lista los objetos existentes...\r
+  while aObjetos.Count > 0 do begin\r
+    ov := aObjetos.First;\r
+    aObjetos.Remove( ov );\r
+    ov.free;\r
+  end;\r
+  aNavePropia := nil;\r
+  inherited mDesSerializar( str ); // SIEMPRE el ID debe ser el PRIMER atributo\r
+  r := TRegExpr.create;\r
+  // DELTAT\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<deltat>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</deltat>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aDeltaT := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el intervalo de actualizacion' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el intervalo de actualizacion utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // OBJETOS\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<objetos\s+total=(\d+)\s*>\s*(.+)\s*</objetos>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then begin // Ejecuta la expresion. Si la encuentra...\r
+      total := StrToInt( r.Match[1] );\r
+      objetos := r.Match[2];\r
+      for i := 0 to total - 1 do begin\r
+        // OBJETO N\r
+        try // se fija si hay errores al extraer los datos\r
+          r.Expression := '<objeto' + IntToStr( i ) + '\s+class=([\w\d]+)\s*>\s*(.+)\s*</objeto' + IntToStr( i ) + '>'; // contruye la expresion regular a buscar\r
+          if r.Exec ( objetos ) then begin // Ejecuta la expresion. Si la encuentra...\r
+            // lo crea segun su clase y lo agrega a la lista\r
+            ov := restaurarObjeto( r.Match[1], r.Match[2] );\r
+            aObjetos.Add( ov );\r
+            if ov is cNavePropia then // Si es la nave propia\r
+              aNavePropia := ov as cNavePropia; // Asigna el atributo NavePropia\r
+          end else // si no encontro la experesion...\r
+            raise ESerializacion.create( 'No se encontro el objeto ' + IntToStr( i ) ); // cae en una excepcion\r
+        except // Si hubieron errores ...\r
+          on e: ESerializacion do begin // Si fueron de serializacion...\r
+            r.Free; // libera memoria\r
+            raise ESerializacion.create( ClassName + ': Error al deserializar el objeto '\r
+                                         + IntToStr( i ) + ': ' + e.Message ); // cae en una excepcion\r
+          end;\r
+          on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+            r.Free; // libera memoria\r
+            raise ESerializacion.create( ClassName + ': Error al extraer el objeto ' + IntToStr( i ) + ' utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+          end;\r
+        end;\r
+      end;\r
+    end else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro la potencia' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer la potencia utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  mEliminarDuplicados;\r
+  if aNavePropia = nil then // Si no se deserializo una nave propia ...\r
+    raise ESerializacion.create( ClassName + ': No se encontro la nave propia' ); // cae en una excepcion\r
+  r.free;\r
+end;\r
+\r
+{** Devuelve una cadena de texto con el objeto serializado.\r
+    @return Cadena de texto con el objeto serializado.}\r
+function cEspacio.mSerializar: string;\r
+var\r
+  i:  integer;\r
+  ov: cObjetoVOlador;\r
+begin\r
+  result := inherited mSerializar +\r
+            '<deltat>' + FloatToStrF( aDeltaT, ffGeneral, 18, 0 ) + '</deltat>' +\r
+            '<objetos total=' + IntToStr( aObjetos.Count ) + '>';\r
+  for i := 0 to aObjetos.Count - 1 do begin  // recorre la lista\r
+    ov := aObjetos.Items[i]; // obteniendo el primer objeto volador\r
+      // Serializa el objeto actual\r
+      result := result + '<objeto' + IntToStr( i ) + ' class=' + ov.ClassName + '>' + ov.mSerializar + '</objeto' + IntToStr( i ) + '>';\r
+  end;\r
+  result := result + '</objetos>';\r
+end;\r
+\r
+{** Elimina los objetos duplicados después de recuperarlos de una serialización}\r
+procedure cEspacio.mEliminarDuplicados;\r
+var\r
+  i:    integer;\r
+  oOV,\r
+  oAux: cObjetoVolador;\r
+begin\r
+  for i := 0 to aObjetos.Count - 1 do begin\r
+    oOV  := aObjetos.Items[i];\r
+    if oOV is cNavePropia then begin\r
+      // Busca el duplicado del objetivo\r
+      oAux := mBuscarDuplicado( (oOV as cNavePropia).mGetLockeado );\r
+      (oOV as cNavePropia).mGetLockeado.free; // Libera la copia que tiene como objetivo\r
+      (oOV as cNavePropia).mSetLockeado( oAux ); // Setea como nuevo objetivo al objeto de la lista\r
+    end;\r
+    if oOV is cMisilDirigido then begin\r
+      // Busca el duplicado del objetivo\r
+      oAux := mBuscarDuplicado( (oOV as cMisilDirigido).mGetObjetivo );\r
+      (oOV as cMisilDirigido).mGetObjetivo.free; // Libera la copia que tiene como objetivo\r
+      (oOV as cMisilDirigido).mSetObjetivo( oAux ); // Setea como nuevo objetivo al objeto de la lista\r
+    end;\r
+  end;\r
+end;\r
+\r
+{** Busca el duplicado de un objeto volador\r
+    @param  ov Objeto volador al cual se le quiere encontrar un duplicado\r
+    @return Objeto Volador duplicado de ov}\r
+function cEspacio.mBuscarDuplicado(ov: cObjetoVolador): cObjetoVolador;\r
+var\r
+  i:   integer;\r
+  oOV: cObjetoVolador;\r
+begin\r
+  result := nil;\r
+  if ov <> nil then\r
+    for i := 0 to aObjetos.Count - 1 do begin\r
+      oOV  := aObjetos.Items[i];\r
+      if oOV.mGetID = ov.mGetID then // Si tienen el mismo ID...\r
+        result := oOV; // Devulve el duplicado\r
+    end;\r
+end;\r
+\r
+{ ENavePropiaDestruida }\r
+\r
+constructor ENavePropiaDestruida.create;\r
+begin\r
+  inherited create( 'La Nave Propia fue destruida.' );\r
+end;\r
+\r
+end.\r
diff --git a/src/modelo/Vectores.pas b/src/modelo/Vectores.pas
new file mode 100644 (file)
index 0000000..b4cd806
--- /dev/null
@@ -0,0 +1,406 @@
+{** Es la implementación de un vector físico. Esta clase es el esqueleto de\r
+    la aplicación ya que todas las velocidades y posiciones son del tipo cVector.\r
+    Todos los calculos de movimientos, distancias, etc. se manejan con los metodos de esta clase<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    05/10/00: Se corrigió el método mAddModulo para que al verificar el signo del modulo resultante,\r
+              si es negativo, setee el modulo a cero.\r
+    28/10/00: Se cambiaron todos los metodos en los que se realizan operaciones con el vector para\r
+              que devulvan un puntero a si mismo (para poder hacer asignaciones luego de la operacion).\r
+              Ahora todos los métodos son funciones\r
+    </PRE>}\r
+unit Vectores;\r
+\r
+interface\r
+\r
+uses\r
+  ObjetoPersistente,\r
+  Tipos;\r
+\r
+type\r
+  {** La clase cVector es la implementación de un vector físico. Esta clase es el esqueleto de\r
+      la aplicación ya que todas las velocidades y posiciones son del tipo cVector.\r
+      Todos los calculos de movimientos, distancias, etc. se manejan con los metodos de esta clase}\r
+  cVector = class( cObjetoPersistente )\r
+    private\r
+      aX: tLongitud; // Componente del vector en X\r
+      aY: tLongitud; // Componente del vector en Y\r
+      aZ: tLongitud; // Componente del vector en Z\r
+    public\r
+      {** Constructor}\r
+      constructor create( x: tLongitud = 0; y: tLongitud = 0; z: tLongitud = 0 ); overload;\r
+      {** Constructor que copia los atributos de un Vector existente}\r
+      constructor create( v: cVector ); overload;\r
+      {$IFDEF DebugAlgoWars}\r
+      {** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.}\r
+      function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;\r
+      {$ENDIF}\r
+      {** Convierte el vector en un versor (norma 1)}\r
+      function mHacerVersor: cVector;\r
+      {** Establece los valores del vector x, y, z}\r
+      function mSet( x, y, z: tLongitud ): cVector; overload;\r
+      {** Modifica las componentes del vector basandose en otro}\r
+      function mSet( v: cVector ): cVector; overload;\r
+      {** Setea la componente X}\r
+      function mSetX( x: tLongitud ): cVector;\r
+      {** Setea la componente Y}\r
+      function mSetY( y: tLongitud ): cVector;\r
+      {** Setea la componente Z}\r
+      function mSetZ( z: tLongitud ): cVector;\r
+      {** Agrega un valor a la componente X}\r
+      function mAddX( x: tLongitud ): cVector;\r
+      {** Agrega un valor a la componente Y}\r
+      function mAddY( y: tLongitud ): cVector;\r
+      {** Agrega un valor a la componente Z}\r
+      function mAddZ( z: tLongitud ): cVector;\r
+      {** Setea el modulo del vector a un valor determinado}\r
+      function mSetModulo( modulo: tLongitud ): cVector;\r
+      {** Aumenta (o disminuye si el argumente es negativo) el modulo del vector}\r
+      function mAddModulo( modulo: tLongitud ): cVector;\r
+      {** Obtiene la componente X}\r
+      function mGetX: tLongitud;\r
+      {** Obtiene la componente Y}\r
+      function mGetY: tLongitud;\r
+      {** Obtiene la componente Z}\r
+      function mGetZ: tLongitud;\r
+      {** Obtiene el modulo del vector}\r
+      function mGetModulo: tLongitud;\r
+      {** Suma a si mismo el vector vec}\r
+      function mSumar( vec: cVector ): cVector;\r
+      {** Resta a si mismo el vector vec}\r
+      function mRestar( vec: cVector ): cVector;\r
+      {** Se multiplica vectorialmente a si mismo por el vector vec}\r
+      function mMultiplicar( vec: cVector ): cVector; overload;\r
+      {** Se multiplica por un escalar}\r
+      function mMultiplicar( esc: tLongitud ): cVector; overload;\r
+      {** Obtiene el producto escalar entre si mismo y el vector vec}\r
+      function mMultiplicarEsc( vec: cVector ): tLongitud;\r
+      {** Obtiene la distancia al a otro vector}\r
+      function mGetDistancia( vec: cVector ): tLongitud;\r
+      {** Modifica el vector con basandose en otro vector (pensado como velocidad) y un\r
+          intervalo de tiempo siguiendo la formula física X' = X + V * dt\r
+          (este metodo esta pensado basicamente para calcular los movimientos)}\r
+      function mModificarCon( vel: cVector; dT: tTiempo ): cVector;\r
+      // SERIALIZACION\r
+      {** Devuelve una cadena de texto con el objeto serializado.}\r
+      function mSerializar: string; override;\r
+      {** Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.}\r
+      procedure mDesSerializar( str: string ); override;\r
+  end;\r
+\r
+implementation\r
+\r
+uses\r
+  Sysutils,\r
+  RegExpr,\r
+  Math;\r
+\r
+{ cVector }\r
+\r
+{** Crea un nuevo vector basandose en los atributos de uno existente.\r
+    @param v Vector a copiar}\r
+constructor cVector.create(v: cVector);\r
+begin\r
+  inherited create;\r
+  // Usa el metodo mSet para establecer los valores\r
+  mSet( v );\r
+end;\r
+\r
+{** Crea un nuevo vector basandose en los atributos dados como parámetro.\r
+    @param x Componente en el eje X\r
+    @param y Componente en el eje Y\r
+    @param z Componente en el eje Z}\r
+constructor cVector.create(x, y, z: tLongitud);\r
+begin\r
+  inherited create;\r
+  // Usa el metodo mSet para establecer los valores\r
+  mSet( x, y, z );\r
+end;\r
+\r
+{** Setea el modulo del vector a un valor determinado (sólo tiene sentido si el modulo actual es distinto de cero)\r
+    @param modulo Modulo a adherir al verctor}\r
+function cVector.mAddModulo(modulo: tLongitud): cVector;\r
+begin\r
+  // Disminuye el módulo sólo si el resultante no es negativo\r
+  if (mGetModulo + modulo) <= 0 then // Si el modulo resultante es negativo o cero\r
+    mSetModulo( 0 ) // Setea el modulo en 0\r
+  else // Si el modulo resultante es positivo\r
+    mSetModulo( mGetModulo + modulo );\r
+  result := self;\r
+end;\r
+\r
+{** Agrega un valor a la componente X\r
+    @param x Valor a sumarle a la componente X}\r
+function cVector.mAddX(x: tLongitud): cVector;\r
+begin\r
+  aX := aX + x;\r
+  result := self;\r
+end;\r
+\r
+{** Agrega un valor a la componente Y\r
+    @param y Valor a sumarle a la componente Y}\r
+function cVector.mAddY(y: tLongitud): cVector;\r
+begin\r
+  aY := aY + y;\r
+  result := self;\r
+end;\r
+\r
+{** Agrega un valor a la componente Z\r
+    @param z Valor a sumarle a la componente Z}\r
+function cVector.mAddZ(z: tLongitud): cVector;\r
+begin\r
+  aZ := aZ + z;\r
+  result := self;\r
+end;\r
+\r
+{** Obtiene el modulo del vector\r
+    @return Modulo (o norma) del vector}\r
+function cVector.mGetModulo: tLongitud;\r
+begin\r
+  // Devuelve la raiz cuadrada de la suma de los cuadrados de las componentes\r
+  result := sqrt( sqr( aX ) + sqr( aY ) + sqr( aZ ) );\r
+end;\r
+\r
+{** Obtiene la componente X\r
+    @return Componente X del vector}\r
+function cVector.mGetX: tLongitud;\r
+begin\r
+  result := aX;\r
+end;\r
+\r
+{** Obtiene la componente Y\r
+    @return Componente Y del vector}\r
+function cVector.mGetY: tLongitud;\r
+begin\r
+  result := aY;\r
+end;\r
+\r
+{** Obtiene la componente Z\r
+    @return Componente Z del vector}\r
+function cVector.mGetZ: tLongitud;\r
+begin\r
+  result := aZ;\r
+end;\r
+\r
+{** Se multiplica vectorialmente a si mismo por el vector vec\r
+    @param vec Vector por el cual se multiplica vectorialmente}\r
+function cVector.mMultiplicar(vec: cVector): cVector;\r
+var\r
+  x,\r
+  y,\r
+  z: tLongitud;\r
+begin\r
+  // Obtiene el resultado siguiendo la formula de producto vectorial\r
+  x  := aY * vec.mGetZ - aZ * vec.mGetY;\r
+  y  := aX * vec.mGetZ - aZ * vec.mGetX;\r
+  z  := aX * vec.mGetY - aY * vec.mGetX;\r
+  aX := x;\r
+  aY := y;\r
+  aZ := z;\r
+  result := self;\r
+end;\r
+\r
+{** Se multiplica por un escalar\r
+    @param esc Escalar por el cual se multiplica}\r
+function cVector.mMultiplicar(esc: tLongitud): cVector;\r
+begin\r
+  // Multiplica cada componente por el escalar\r
+  aX := aX * esc;\r
+  aY := aY * esc;\r
+  aZ := aZ * esc;\r
+  result := self;\r
+end;\r
+\r
+{** Obtiene el producto escalar entre si mismo y el vector vec\r
+    @return      Producto escalar entre los vectores\r
+    @param   vec Vector por el cual se multiplica escalarmente}\r
+function cVector.mMultiplicarEsc(vec: cVector): tLongitud;\r
+begin\r
+  // Realiza el producto escalar (suma el producto componente a componente)\r
+  result := aX * vec.mGetX + aY * vec.mGetY + aZ * vec.mGetZ;\r
+end;\r
+\r
+{** Resta a si mismo el vector vec\r
+    @param vec Vector que se resta}\r
+function cVector.mRestar(vec: cVector): cVector;\r
+begin\r
+  aX := aX - vec.mGetX;\r
+  aY := aY - vec.mGetY;\r
+  aZ := aZ - vec.mGetZ;\r
+  result := self;\r
+end;\r
+\r
+{** Setea el modulo del vector a un valor determinado\r
+    @param modulo Valor del nuevo Módulo}\r
+function cVector.mSetModulo(modulo: tLongitud): cVector;\r
+begin\r
+  // Primero lo convertimos en un versor\r
+  mHacerVersor;\r
+  // Ahora multiplicamos el versor por la modulo deseada\r
+  mMultiplicar( modulo );\r
+  result := self;\r
+end;\r
+\r
+{** Modifica las componentes del vector basandose en otro\r
+    @param v Vector del cual se obtendran los nuevos atributos}\r
+function cVector.mSet(v: cVector): cVector;\r
+begin\r
+  aX := v.mGetX;\r
+  aY := v.mGetY;\r
+  aZ := v.mGetZ;\r
+  result := self;\r
+end;\r
+\r
+{** Establece las componentes del vector\r
+    @param x Nuevo valor de la componente en el eje X\r
+    @param y Nuevo valor de la componente en el eje Y\r
+    @param z Nuevo valor de la componente en el eje Z}\r
+function cVector.mSet(x, y, z: tLongitud): cVector;\r
+begin\r
+  aX := x;\r
+  aY := y;\r
+  aZ := z;\r
+  result := self;\r
+end;\r
+\r
+{** Setea la componente X\r
+    @param x Nuevo valor de la componente en el eje X}\r
+function cVector.mSetX(x: tLongitud): cVector;\r
+begin\r
+  aX := x;\r
+  result := self;\r
+end;\r
+\r
+{** Setea la componente Y\r
+    @param y Nuevo valor de la componente en el eje Y}\r
+function cVector.mSetY(y: tLongitud): cVector;\r
+begin\r
+  aY := y;\r
+  result := self;\r
+end;\r
+\r
+{** Setea la componente Z\r
+    @param z Nuevo valor de la componente en el eje Z}\r
+function cVector.mSetZ(z: tLongitud): cVector;\r
+begin\r
+  aZ := z;\r
+  result := self;\r
+end;\r
+\r
+{** Suma a si mismo el vector vec\r
+    @param vec Vector a sumarle}\r
+function cVector.mSumar(vec: cVector): cVector;\r
+begin\r
+  aX := aX + vec.mGetX;\r
+  aY := aY + vec.mGetY;\r
+  aZ := aZ + vec.mGetZ;\r
+  result := self;\r
+end;\r
+\r
+{$IFDEF DebugAlgoWars}\r
+{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos:<br>\r
+    Siempre devuelve los valores de las componentes x, y, z y si debugLevel es mayor que DI_NORMAL,\r
+    también muestra el módulo.\r
+    @return             Cadena de texto con el estado del Objeto.\r
+    @param   debugLevel Cantidad de información requerida}\r
+function cVector.mGetDebugInfo( debugLevel: tDebugInfo ): string;\r
+begin\r
+  // Construye la cadena dependiendo de la cantidad de informacion que se quiera obtener\r
+  result := 'X: ' + FloatToStrF( mGetX, ffNumber, 5, 5 ) +\r
+            ' | Y: ' + FloatToStrF( mGetY, ffNumber, 5, 5 ) +\r
+            ' | Z: ' + FloatToStrF( mGetZ, ffNumber, 5, 5 );\r
+  if debugLevel > DI_NORMAL then\r
+    result := result + ' | Modulo: ' + FloatToStrF( mGetModulo, ffNumber, 5, 5 );\r
+end;\r
+{$ENDIF}\r
+\r
+{** Obtiene la distancia al a otro vector (en realidad se tratan como puntos)\r
+    @returns     Distancia al otro vector\r
+    @param   vec Punto al cual se calcula la distancia}\r
+function cVector.mGetDistancia( vec: cVector ): tLongitud;\r
+var\r
+  v: cVector;\r
+begin\r
+  // Crea un nuevo vector basado en vec y le resta el vector actual\r
+  v := cVector.create( vec ).mRestar( self );\r
+  // devuelve el modulo\r
+  result := v.mGetModulo;\r
+  // Libera el vector temporal\r
+  v.free;\r
+end;\r
+\r
+{** Modifica el vector con basandose en otro vector (pensado como velocidad) y un\r
+    intervalo de tiempo siguiendo la formula física X' = X + V * dt\r
+    (este metodo esta pensado basicamente para calcular los movimientos)\r
+    @param vel Vector velocidad\r
+    @param dT  Intervalo de tiempo}\r
+function cVector.mModificarCon(vel: cVector; dT: tTiempo): cVector;\r
+var\r
+  v: cVector;\r
+begin\r
+  // formula de MRU: SELF = SELF + VELOCIDAD * TIEMPO\r
+  v := cVector.create( vel ).mMultiplicar( dT );\r
+  mSumar( v );\r
+  v.free;\r
+  result := self;\r
+end;\r
+\r
+{** Convierte el vector en un versor (sólo tiene sentido si el modulo actual es distinto de cero)}\r
+function cVector.mHacerVersor: cVector;\r
+begin\r
+  // Si el modulo es mayor que cero...\r
+  if mGetModulo > 0 then\r
+    mMultiplicar( 1 / mGetModulo );\r
+  result := self;\r
+end;\r
+\r
+{** Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    @param str Cadena de texto con el objeto serializado.}\r
+procedure cVector.mDesSerializar(str: string);\r
+var\r
+  r: TRegExpr;\r
+begin\r
+  inherited mDesSerializar( str ); // SIEMPRE el ID debe ser el PRIMER atributo\r
+  r := TRegExpr.create;\r
+  try // ensure memory release\r
+    // X\r
+    r.Expression := '<X>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</X>';\r
+    if r.Exec ( str ) then\r
+      aX := StrToFloat( r.Match[1] )\r
+    else\r
+      raise ESerializacion.create( 'No se encontro la componente en X' );\r
+    // Y\r
+    r.Expression := '<Y>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</Y>';\r
+    if r.Exec ( str ) then\r
+      aY := StrToFloat( r.Match[1] )\r
+    else\r
+      raise ESerializacion.create( 'No se encontro la componente en Y' );\r
+    // Z\r
+    r.Expression := '<Z>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</Z>';\r
+    if r.Exec ( str ) then\r
+      aZ := StrToFloat( r.Match[1] )\r
+    else\r
+      raise ESerializacion.create( 'No se encontro la componente en Z' );\r
+  except\r
+    on e: ERegExpr do begin\r
+      r.Free;\r
+      raise ESerializacion.create( ClassName + ': Error utilizando expresiones regulares: ' + e.Message );\r
+    end;\r
+  end;\r
+  r.free;\r
+end;\r
+\r
+{** Devuelve una cadena de texto con el objeto serializado.\r
+    @return Cadena de texto con el objeto serializado.}\r
+function cVector.mSerializar: string;\r
+begin\r
+  result := inherited mSerializar +\r
+            '<X>' + FloatToStrF( aX, ffGeneral, 18, 0 ) + '</X>' +\r
+            '<Y>' + FloatToStrF( aY, ffGeneral, 18, 0 ) + '</Y>' +\r
+            '<Z>' + FloatToStrF( aZ, ffGeneral, 18, 0 ) + '</Z>';\r
+end;\r
+\r
+end.\r
diff --git a/src/modelo/ov/Armas.pas b/src/modelo/ov/Armas.pas
new file mode 100644 (file)
index 0000000..d661f7f
--- /dev/null
@@ -0,0 +1,511 @@
+{** Contiene las armas que pueden ser usadas por las diferentes naves.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    10/11/00: Se agrega el manejo de excepciones para evitar un BUG en cMisilDirigido. Si el objetivo del misil\r
+              dirigido es destruido, la velocidad permanece constante y en mGetDebugInfo se informa que esta destruido.\r
+    27/11/00: Se le agrega el manejo de la velocidad maxima a la clase cArma y se agrega el Alcance del arma, cambiando\r
+              el anterior por la Duracion.\r
+    01/12/00: Se cambiaron las dimensiones de las armas para que los disparos sean mas "jugables".\r
+    </PRE>}\r
+unit Armas;\r
+\r
+interface\r
+\r
+uses\r
+  Tipos,\r
+  Vectores,\r
+  ObjetoVolador;\r
+\r
+type\r
+  {** La clase cArma esta pensada como una clase abtracta. En ella se encuentran\r
+      características comunes a todas las armas.}\r
+  cArma = class( cObjetoVolador )\r
+    private\r
+      aDuracion:  tTiempo;   // Este alcance determina cuanto tiempo tiene que pasar\r
+                             //  para que el arma se autodestruya.\r
+      aAlcance:   tLongitud; // Alcance en metros del arma\r
+      aVelMaxima: tLongitud; // Velocidad máxima del arma\r
+    protected\r
+      {** Actualiza el alcance del arma, que va disminuyendo a medida que pasa el tiempo}\r
+      procedure mActualizarDuracion( dt: tTiempo );\r
+      {** Devuelve true si el arma todavia tiene alcance}\r
+      function mActivo: boolean;\r
+      {** Método para obtener el alcance del arma}\r
+      procedure mSetAlcance( alc: tLongitud );\r
+    public\r
+      {** Constructor}\r
+      constructor create( pos: cVector = nil; vel: cVector = nil; dim: tLongitud = 1;\r
+                          pot: tEnergia = 1; ene: tEnergia = 1; duracion: tTiempo = 2500;\r
+                          velMax: tLongitud = 0.25 ); overload;\r
+      {$IFDEF DebugAlgoWars}\r
+      {** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.}\r
+      function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;\r
+      {$ENDIF}\r
+      {** Método para obtener el alcance del arma}\r
+      function mGetAlcance: tLongitud;\r
+      {** Método para obtener el alcance del arma}\r
+      function mGetVelMax:  tLongitud;\r
+      {** Método heredado, se sobreescribe porque se le agrega alguna funcionalidad}\r
+      procedure mMover( dt: tTiempo ); override;\r
+      // SERIALIZACION\r
+      {** Devuelve una cadena de texto con el objeto serializado.}\r
+      function mSerializar: string; override;\r
+      {** Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.}\r
+      procedure mDesSerializar( str: string ); override;\r
+  end;\r
+\r
+  {** El laser es un tipo de arma básica. Es la que menos daño hace pero la que más rápido viaja<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión      0,1       metros (10 cm)\r
+      Potencia:      1         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:       1         Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad:     0,4       metros/milisegundos (1440 km/h)\r
+      Alcance:       3000      milisegundos (3 segundos, 1,2 km)\r
+      </PRE>}\r
+  cLaser = class( cArma )\r
+    public\r
+      {** Constructor}\r
+      constructor create( pos: cVector = nil; vel: cVector = nil ); overload;\r
+      {** Método heredado, se sobreescribe porque se dibuja de forma distinta}\r
+      function mDibujar: tObjetosVoladores; override;\r
+  end;\r
+\r
+  {** El misil es un tipo de arma básica. Hace un daño considerable y su velocidad también es alta<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión      0,5       metros (50 cm)\r
+      Potencia:      20        Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:       1         Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad:     0,3       metros/milisegundos (1080 km/h)\r
+      Alcance:       5000      milisegundos (5 segundos, 1,5 km)\r
+      </PRE>}\r
+  cMisil = class( cArma )\r
+    public\r
+      // Constructor\r
+      constructor create( pos: cVector = nil; vel: cVector = nil ); overload;\r
+      // Método heredado, se sobreescribe porque se dibuja de forma distinta\r
+      function mDibujar: tObjetosVoladores; override;\r
+  end;\r
+\r
+  {** El misil dirigido es un tipo de arma avanzada. Persigue a su objetivo hasta que lo alcanza o\r
+      hasta que se le acaba el alcance. Hace un daño alto, su velocidad es mediana y tiene un gran alcance.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión      0,7       metros (70 cm)\r
+      Potencia:      30        Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:       1         Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad:     0,25      metros/milisegundos (900 km/h)\r
+      Alcance:       20000     milisegundos (20 segundos, 5 km)\r
+      Area de Lock:  2000      metros (2 km)\r
+      </PRE>}\r
+  cMisilDirigido = class( cMisil )\r
+    private\r
+      aObjetivo:  cObjetoVolador;      // Objetivo del misil\r
+      aLockArea:  tLongitud;           // Maxima distancia a la que se debe encontrar\r
+                                       //  el objetivo para poder ser disparado\r
+    protected\r
+      {** Método que calcula la nueva velocidad basandose en al posicion del objetivo}\r
+      procedure mModificarVelocidad;\r
+    public\r
+      {** Constructor}\r
+      constructor create( obj: cObjetoVolador; pos: cVector = nil ); overload;\r
+      {$IFDEF DebugAlgoWars}\r
+      {** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.}\r
+      function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;\r
+      {$ENDIF}\r
+      {** Método heredado, se sobreescribe porque se le agrega alguna funcionalidad}\r
+      procedure mMover( dt: tTiempo ); override;\r
+      {** Obtiene el objetivo del misil dirigido}\r
+      function mGetObjetivo: cObjetoVolador;\r
+      {** Establece el objetivo del misil dirigido}\r
+      procedure mSetObjetivo( ov: cObjetoVolador );\r
+      {** Método heredado, se sobreescribe porque se dibuja de forma distinta}\r
+      function mDibujar: tObjetosVoladores; override;\r
+      // SERIALIZACION\r
+      {** Devuelve una cadena de texto con el objeto serializado.}\r
+      function mSerializar: string; override;\r
+      {** Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.}\r
+      procedure mDesSerializar( str: string ); override;\r
+  end;\r
+\r
+implementation\r
+\r
+uses\r
+  RegExpr,\r
+  ObjetoPersistente,\r
+  SerializacionUtils,\r
+  Sysutils;\r
+\r
+{ cArma }\r
+\r
+{** Este constructor es protegido porque solo va a ser utilizado por subclases\r
+    @param pos     Posicion inicial\r
+    @param vel     Velocidad inicial\r
+    @param dim     Dimensión del objeto volador (radio, en metros)\r
+    @param pot     Potencia del objeto volador (cantidad de daño que hace por intervalode tiempo)\r
+    @param ene     Energía del objeto volador(cantidad de daño que soporta antes de ser destruido)\r
+    @param alcance Tiempo que debe pasar para que el arma se destruya si no impactó con ningún objeto volador}\r
+constructor cArma.create(pos: cVector; vel: cVector; dim: tLongitud;\r
+  pot, ene: tEnergia; duracion: tTiempo; velMax: tLongitud);\r
+var\r
+  v: cVector;\r
+begin\r
+  inherited create( pos, vel, dim, pot, ene );\r
+  aDuracion  := duracion;\r
+  aVelMaxima := velMax;\r
+  aAlcance   := aDuracion * aVelMaxima;\r
+  // Setea el modulo de la velocidad a la maxima\r
+  v := mGetVelocidad.mSetModulo( aVelMaxima );\r
+  mSetVelocidad( v );\r
+  v.free;\r
+end;\r
+\r
+{** Chequea si el arma todavia tiene alcance\r
+    @return <i>true</i> si todavía tiene alcance, <i>false</i> si no}\r
+function cArma.mActivo: boolean;\r
+begin\r
+  result := ( aDuracion > 0 );\r
+end;\r
+\r
+{** Método para obtener el alcance del arma\r
+    @return Alcance del arma}\r
+function cArma.mGetAlcance: tLongitud;\r
+begin\r
+  result := aAlcance;\r
+end;\r
+\r
+{** Método para establecer el alcance del arma\r
+    @param alc Alcance del arma}\r
+procedure cArma.mSetAlcance(alc: tLongitud);\r
+begin\r
+  aAlcance := alc;\r
+end;\r
+\r
+{** Método para obtener la velocidad maxima del arma\r
+    @return Velocidad maxima del arma}\r
+function cArma.mGetVelMax: tLongitud;\r
+begin\r
+  result := aVelMaxima;\r
+end;\r
+\r
+{** Actualiza el alcance del arma, que va disminuyendo a medida que pasa el tiempo\r
+    @param dt Intervalo de tiempo}\r
+procedure cArma.mActualizarDuracion(dt: tTiempo);\r
+begin\r
+  aDuracion := aDuracion - dt;\r
+end;\r
+\r
+{$IFDEF DebugAlgoWars}\r
+{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos.\r
+    @return            Cadena de texto con el estado del Objeto.\r
+    @param   debugLevel Cantidad de información requerida}\r
+function cArma.mGetDebugInfo(debugLevel: tDebugInfo): string;\r
+begin\r
+  // Genera el string con el estado del Arma\r
+  result := inherited mGetDebugInfo( debugLevel );\r
+  if debugLevel > DI_MINI then\r
+    result := result + ' | Alcance: ' + FloatToStr( aDuracion );\r
+end;\r
+{$ENDIF}\r
+\r
+{** Mueve el arma basado en su posición y velocidad actual y un intervalo de tiempo\r
+    @param dt Intervalo de tiempo}\r
+procedure cArma.mMover(dt: tTiempo);\r
+begin\r
+  inherited mMover( dt );  // Mueve el arma de la forma convencional\r
+  mActualizarDuracion( dt ); // Actualiza el alcance\r
+  if not mActivo then // Si se quedó sin alcance...\r
+    mSetEnergia( -1 ); // pone energia en negativo, lo que significa que se destruyó...\r
+end;\r
+\r
+{** Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    @param str Cadena de texto con el objeto serializado.}\r
+procedure cArma.mDesSerializar(str: string);\r
+var\r
+  r: TRegExpr;\r
+begin\r
+  inherited mDesSerializar( str ); // SIEMPRE el ID debe ser el PRIMER atributo\r
+  r := TRegExpr.create;\r
+  // DURACION\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<duracion>\s*([+-]?\d+)\s*</duracion>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aDuracion := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro la duracion' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer la duracion utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // ALCANCE\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<alcance>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</alcance>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aAlcance := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el alcance' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el alcance utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // VELMAXIMA\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<velmaxima>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</velmaxima>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aVelMaxima := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro la velocidad maxima' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer la velocidad maxima utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  r.free;\r
+end;\r
+\r
+{** Devuelve una cadena de texto con el objeto serializado.\r
+    @return Cadena de texto con el objeto serializado.}\r
+function cArma.mSerializar: string;\r
+begin\r
+  result := inherited mSerializar +\r
+            '<duracion>' + FloatToStrF( aDuracion, ffGeneral, 18, 0 ) + '</duracion>' +\r
+            '<alcance>' + FloatToStrF( aAlcance, ffGeneral, 18, 0 ) + '</alcance>' +\r
+            '<velmaxima>' + FloatToStrF( aVelMaxima, ffGeneral, 18, 0 ) + '</velmaxima>';\r
+end;\r
+\r
+{ cLaser }\r
+\r
+{** Crea una nueva instancia.\r
+    @param pos Vector posición\r
+    @param vel Dirección del vector velocidad}\r
+constructor cLaser.create(pos: cVector = nil; vel: cVector = nil);\r
+begin\r
+  // El laser tiene 10 cm de radio, 1 punto de potencia, 1 punto de energia y 3 seg de alcance (1,2 km)\r
+  // Setea el modulo de la velocidad a 0,4 m/mseg (1440 km/h)\r
+  inherited create( pos, vel, 0.1 {dim}, 1 {pot}, 1 {ene}, 3000 {dur}, 0.4 {velmax} );\r
+end;\r
+\r
+{** Método heredado, se sobreescribe porque se dibuja de forma distinta}\r
+function cLaser.mDibujar: tObjetosVoladores;\r
+begin\r
+  result := OV_LASER;\r
+end;\r
+\r
+{ cMisil }\r
+\r
+{** Crea una nueva instancia.\r
+    @param pos Vector posición\r
+    @param vel Dirección del vector velocidad}\r
+constructor cMisil.create(pos: cVector = nil; vel: cVector = nil);\r
+begin\r
+  // El misil tiene 50 cm de radio, 20 puntos de potencia, 1 punto de energia y 5 seg de alcance (1,5 km)\r
+  // Setea el modulo de la velocidad a 0,3 m/mseg (1080 km/h)\r
+  inherited create( pos, vel, 0.5 {dim}, 20 {pot}, 1 {ene}, 5000 {dur}, 0.3 {velmax} );\r
+end;\r
+\r
+{** Método heredado, se sobreescribe porque se dibuja de forma distinta}\r
+function cMisil.mDibujar: tObjetosVoladores;\r
+begin\r
+  result := OV_MISIL;\r
+end;\r
+\r
+{ cMisilDirigido }\r
+\r
+{** Crea una nueva instancia.\r
+    @param obj Objeto volador al que perseguirá (objetivo)\r
+    @param pos Vector posición}\r
+constructor cMisilDirigido.create( obj: cObjetoVolador; pos: cVector = nil );\r
+begin\r
+  // El misil dirigido tiene 70 m de radio, 30 puntos de potencia, 1 punto de energia y 20 seg de alcance (5 km)\r
+  inherited create( pos, cVector.create, 0.7 {dim}, 30 {pot}, 1 {ene}, 20000 {dur}, 0.25 {velmax} );\r
+  aObjetivo := obj;\r
+  aLockArea := 2000;   // 2 km\r
+  mSetAlcance( aLockArea ); // Setea como alcance al area de lockeo.\r
+  mModificarVelocidad; // Modifica la velocidad de forma tal que apunte al objetivo\r
+                       //  y tenga un modulo constante\r
+end;\r
+\r
+{** Método que calcula la nueva velocidad basandose en al posicion del objetivo}\r
+procedure cMisilDirigido.mModificarVelocidad;\r
+var\r
+  pos,           // Vector temporal para hacer calculos\r
+  vel: cVector;  // Vector temporal para hacer calculos\r
+begin\r
+  vel := nil;\r
+  pos := nil;\r
+  if aObjetivo <> nil then // Si no es nulo ...\r
+    try // Probamos que el objetivo no este destruido\r
+      // Le resta la posicion propia a la del objetivo, obteniendo la nueva direccion de la velocidad\r
+      pos := mGetPosicion;\r
+      vel := aObjetivo.mGetPosicion.mRestar( pos );\r
+      vel.mSetModulo( mGetVelMax ); // Setea el modulo al de la velocidad maxima: 0,25 m/mseg (900 km/h)\r
+      mSetVelocidad( vel ); // Modifica la velocidad basado en el vector v\r
+    except // Si esta destruido queda la velocidad constante y libera los vectores\r
+      on e: EAccessViolation do begin\r
+        mSetVelModulo( mGetVelMax ); // Setea el modulo de la velocidad como la maxima\r
+                                     // (no cambia su direccion ni sentido)\r
+        aObjetivo := nil; // Lo seteamos a nil\r
+        vel.free; // libera la memoria del vector temporal\r
+        pos.free; // libera la memoria del vector temporal\r
+      end;\r
+    end;\r
+  // Si es nulo no modifica la velocidad ...\r
+end;\r
+\r
+{** Mueve el arma basado en su posición y velocidad actual, su objetivo y un intervalo de tiempo\r
+    @param dt Intervalo de tiempo}\r
+procedure cMisilDirigido.mMover(dt: tTiempo);\r
+begin\r
+  mModificarVelocidad;    // Modifica la velocidad segun su objetivo\r
+  inherited mMover( dt ); // Se mueve al igual que el resto de las armas\r
+end;\r
+\r
+{$IFDEF DebugAlgoWars}\r
+{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos.\r
+    @return            Cadena de texto con el estado del Objeto.\r
+    @param   debugLevel Cantidad de información requerida}\r
+function cMisilDirigido.mGetDebugInfo(debugLevel: tDebugInfo): string;\r
+var\r
+  objInfo: string;\r
+begin\r
+  // Genera el string con el estado del Misil Dirigido\r
+  result := inherited mGetDebugInfo( debugLevel );\r
+  if debugLevel > DI_MINI then\r
+    result := result + ' | LockArea: ' + FloatToStr( aLockArea );\r
+  if aObjetivo <> nil then // Si no es nulo ...\r
+    try // Probamos que el objetivo no este destruido\r
+      objInfo := aObjetivo.mGetDebugInfo( DI_MINI );\r
+    except // Si esta destruido cambia la cadena de texto\r
+      on e: EAccessViolation do begin\r
+        objInfo := 'DESTRUIDO';\r
+        aObjetivo := nil;\r
+      end;\r
+    end\r
+  else // Si es nulo ...\r
+    objInfo := 'DESTRUIDO';\r
+  if debugLevel > DI_NORMAL then\r
+    result := result + #13 + #10 + 'Objetivo: ' + objInfo;\r
+end;\r
+{$ENDIF}\r
+\r
+{** Obtiene el objetivo del misil dirigido.\r
+    @return Objetivo del misil dirigido.}\r
+function cMisilDirigido.mGetObjetivo: cObjetoVolador;\r
+begin\r
+  result := aObjetivo;\r
+  if aObjetivo <> nil then // Si no es nil...\r
+    try // Primero se fija que no esté destruido\r
+      aObjetivo.mGetID;\r
+    except\r
+      on e: EAccessViolation do begin // Si lo está...\r
+        aObjetivo := nil; // Lo setea a nil\r
+        result := aObjetivo;\r
+      end;\r
+    end;\r
+end;\r
+\r
+{** Establece el objetivo del misil dirigido\r
+    @param ov Nuevo objetivo}\r
+procedure cMisilDirigido.mSetObjetivo( ov: cObjetoVolador );\r
+begin\r
+  aObjetivo := ov;\r
+end;\r
+\r
+{** Método heredado, se sobreescribe porque se dibuja de forma distinta}\r
+function cMisilDirigido.mDibujar: tObjetosVoladores;\r
+begin\r
+    result := OV_MISDIR;\r
+end;\r
+\r
+{** Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    @param str Cadena de texto con el objeto serializado.}\r
+procedure cMisilDirigido.mDesSerializar(str: string);\r
+var\r
+  r: TRegExpr;\r
+begin\r
+  inherited mDesSerializar( str ); // SIEMPRE el ID debe ser el PRIMER atributo\r
+  r := TRegExpr.create;\r
+  // OBJETIVO\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<objetivo\s+class=([\w\d]+)\s*>\s*(.+)\s*</objetivo>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      if r.Match[1] <> '0' then // Si tiene una clase determinada...\r
+        if aObjetivo <> nil then // Si no es nulo\r
+          // Puede caer en una EAccessViolation si esta destruido\r
+          aObjetivo.mDesSerializar( r.Match[2] ) // Lo deserializa\r
+        else // si es nulo\r
+          aObjetivo := restaurarObjeto( r.Match[1], r.Match[2] ) // lo crea segun su clase\r
+      else // Si no tiene una clase determinada, entonces se lo pone en nil\r
+        aObjetivo := nil\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el objetivo' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ESerializacion do begin // Si fueron de serializacion...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al deserializar el objetivo: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el objetivo utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+    on e: EAccessViolation do begin // si el Objetivo fue destruido...\r
+      aObjetivo := restaurarObjeto( r.Match[1], r.Match[2] ) // lo crea segun su clase\r
+    end;\r
+  end;\r
+  // LOCKAREA\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<lockarea>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</lockarea>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aLockArea := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el area de lockeo' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el area de lockeo utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  r.free;\r
+end;\r
+\r
+{** Devuelve una cadena de texto con el objeto serializado.\r
+    @return Cadena de texto con el objeto serializado.}\r
+function cMisilDirigido.mSerializar: string;\r
+var\r
+  clase,\r
+  objetivo: string;\r
+begin\r
+  // Si el objetivo es nil o está destruido, se setea el atributo class del\r
+  // TAG objetivo como '0' y entre el TAG se indica que es nil. Si no se\r
+  // setea como el nombre de la clase y su expresion serializada respectivamente\r
+  objetivo := 'nil';\r
+  clase    := '0';\r
+  if aObjetivo <> nil then\r
+    try\r
+      objetivo := aObjetivo.mSerializar;\r
+      clase    := aObjetivo.ClassName;\r
+    except // Si esta destruido cambia la cadena de texto\r
+      on e: EAccessViolation do begin\r
+        objetivo := 'nil';\r
+        clase    := '0';\r
+        aObjetivo := nil;\r
+      end;\r
+    end;\r
+  result := inherited mSerializar +\r
+            '<objetivo class=' + clase + '>' + objetivo + '</objetivo>' +\r
+            '<lockarea>' + FloatToStrF( aLockArea, ffGeneral, 18, 0 ) + '</lockarea>';\r
+end;\r
+\r
+end.\r
diff --git a/src/modelo/ov/Meteorito.pas b/src/modelo/ov/Meteorito.pas
new file mode 100644 (file)
index 0000000..08525f1
--- /dev/null
@@ -0,0 +1,47 @@
+{** Representa un objeto volador básico. Tiene una velocidad constante.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    01/12/00: Se cambiaron las dimensiones por defecto para que los disparos sean mas "jugables".\r
+    </PRE>}\r
+unit Meteorito;\r
+\r
+interface\r
+\r
+uses\r
+  ObjetoVolador,\r
+  Tipos,\r
+  Vectores;\r
+\r
+type\r
+  {** Representa un objeto volador básico. Tiene una velocidad constante.}\r
+  cMeteorito = class( cObjetoVolador )\r
+    public\r
+      {** Constructor}\r
+      constructor create( pos: cVector = nil; vel: cVector = nil; dim: tLongitud = 5; pot: tEnergia = 5; ene: tEnergia = 20 ); overload;\r
+      {** Método para dibujar el meteorito (todavía no implementado)}\r
+      function mDibujar: tObjetosVoladores; override;\r
+  end;\r
+\r
+implementation\r
+\r
+{ cMeteorito }\r
+\r
+{** Constructor\r
+    @param pos Posicion inicial\r
+    @param vel Velocidad inicial\r
+    @param dim Dimensión del objeto volador (radio, en metros)\r
+    @param pot Potencia del objeto volador (cantidad de daño que hace por intervalode tiempo)\r
+    @param ene Energía del objeto volador(cantidad de daño que soporta antes de ser destruido)}\r
+constructor cMeteorito.create(pos, vel: cVector; dim: tLongitud; pot,\r
+  ene: tEnergia);\r
+begin\r
+  inherited create( pos, vel, dim, pot, ene );\r
+end;\r
+\r
+{** Método para dibujar el meteorito (todavía no implementado)}\r
+function cMeteorito.mDibujar: tObjetosVoladores;\r
+begin\r
+  result := OV_METEORITO;\r
+end;\r
+\r
+end.\r
diff --git a/src/modelo/ov/ObjetoVolador.pas b/src/modelo/ov/ObjetoVolador.pas
new file mode 100644 (file)
index 0000000..c3c3cbd
--- /dev/null
@@ -0,0 +1,499 @@
+{** Clase abstracta, implementa todas las funcionalidades básicas de los objetos voladores.\r
+    De esta van a derivar la mayor parte del resto de las clases.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    05/10/00: Se agregaron los métodos mGetDistancia y mColisiono. De esta manera se deja\r
+              a los objetos voladores manejar las colisiones mas intuitivamente.\r
+    30/10/00: Se agregó un atributo <b>aCoordenadas</b> para que se pueda orientar al objeto volador.\r
+    02/11/00: Se agregaron métodos para cambiar solamente el modulo de la velocidad, para cambiar solo\r
+              la direccion de la velocidad y para extraer directamente copias de los versores i, j, k y\r
+              para rotar el objeto volador en todas direcciones.\r
+              Los nuevos métodos son: mSetVelModulo, mSetVelDir, mGetVelModulo,\r
+                                      mGetI, mGetJ, mGetK, mRotarEnI,\r
+                                      mRotarEnJ, mRotarEnK\r
+    07/11/00: Se agrega un nuevo método (mSetPosicion) y se hace a público otro (mSetVelocidad) para\r
+              que se pueda cambiar la configuración (es temporal, se planea cambiar el sistema de\r
+              configuración del juego para que esto no sea necesario)\r
+    29/11/00: Se arregla un BUG en mSetVelModulo que no modificaba el modulo si la velocidad pasada\r
+              como argumento era menor que cero. En este caso el modulo de la velocidad se setea en 0.\r
+    02/12/00: Se cambio el dato que devuelve el método mDibujar. Ahora devuelve un tipo de dato enumerado\r
+              tObjetosVoladores. Todas sus subclases fueron actualizadas también.\r
+    08/12/00: Se agregan menúes para manejar la nueva vistas con varias camaras. Se agrega la opcion de\r
+              alta calidad en el menú vista. Se carga un escenario por defecto (si existe) al iniciar el\r
+              juego, el nombre de dicho escenario debe ser 'comun.eaw'.\r
+              Se agrega una nueva tecla para cambiar de cámara ('C'), además de las que se provee con las\r
+              teclas de atajo.\r
+    </PRE>}\r
+unit ObjetoVolador;\r
+\r
+interface\r
+\r
+uses\r
+  Tipos,\r
+  ObjetoPersistente,\r
+  Coordenadas,\r
+  Vectores;\r
+\r
+type\r
+  {** Clase abstracta, implementa todas las funcionalidades básicas de los objetos voladores.\r
+      De esta van a derivar la mayor parte del resto de las clases.}\r
+  cObjetoVolador = class( cObjetoPersistente )\r
+    private\r
+      aPosicion:    cVector;      // Posicion del objeto volador en el espacio\r
+      aVelocidad:   tLongitud;    // Velocidad del objeto volador (en modulo)\r
+      aPotencia:    tEnergia;     // Potencia del objeto volador (la cantidad de daño que hace por impacto)\r
+      aEnergia:     tEnergia;     // Energía del objeto volador (la cantidad de daño que soporta antes de ser destruido)\r
+      aDimension:   tLongitud;    // La dimesión del objeto volador (es el radio de una esfera)\r
+      // Agregado 30/10/00\r
+      aCoordenadas: cCoordenadas; // Sistema de coordenadas del objeto volador (para tener nocion de la orientación)\r
+                                  //  El versor i es la direccion de la velocidad\r
+    protected\r
+      {** Método para establecer la energía}\r
+      function mSetEnergia( ene: tEnergia ): cObjetoVolador;\r
+      {** Rota el objeto volador sobre el eje i\r
+          (el sentido positivo es de j a k)}\r
+      function mRotarEnI( dAngulo: tAngulo ): cObjetoVolador;\r
+      {** Rota el objeto volador sobre el eje j\r
+          (el sentido positivo es de i a k)}\r
+      function mRotarEnJ( dAngulo: tAngulo ): cObjetoVolador;\r
+      {** Rota el objeto volador sobre el eje k\r
+          (el sentido positivo es de i a j)}\r
+      function mRotarEnK( dAngulo: tAngulo ): cObjetoVolador;\r
+    public\r
+      {** Constructor}\r
+      constructor create( pos: cVector = nil; vel: cVector = nil; dim: tLongitud = 5; pot: tEnergia = 1; ene: tEnergia = 100 ); overload;\r
+      {** Constructor que copia los atributos de un Objeto volador existente}\r
+      constructor create( ov:  cObjetoVolador ); overload;\r
+      {$IFDEF DebugAlgoWars}\r
+      {** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.}\r
+      function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;\r
+      {$ENDIF}\r
+      {** Mueve el objeto volador basandose en su posicion, su velocidad y un intervalo de tiempo}\r
+      procedure mMover( dT: tTiempo ); virtual;\r
+      {** Calcula la distancia a otro objeto volador}\r
+      function mGetDistancia( ov: cObjetoVolador ): tLongitud;\r
+      {** Devuelve true si colisionaron los objetos voladores}\r
+      function mColisiono( ov: cObjetoVolador ): boolean;\r
+      {** Obtiene la velocidad del objeto volador}\r
+      function mGetVelocidad: cVector;\r
+      {** Obtiene el modulo de la velocidad del objeto volador}\r
+      function mGetVelModulo: tLongitud;\r
+      {** Obtiene la Posicion del objeto volador}\r
+      function mGetPosicion: cVector;\r
+      {** Obtiene la Potencia del objeto volador}\r
+      function mGetPotencia: tEnergia;\r
+      {** Obtiene la Energia del objeto volador}\r
+      function mGetEnergia: tEnergia;\r
+      {** Obtiene la Dimension del objeto volador}\r
+      function mGetDimension: tLongitud;\r
+      {** Obtiene el sistema de coordenadas de la nave}\r
+      function mGetCoordenadas: cCoordenadas;\r
+      {** Obtiene el versor i del sistema de coordenadas de la nave}\r
+      function mGetI: cVector;\r
+      {** Obtiene el versor j del sistema de coordenadas de la nave}\r
+      function mGetJ: cVector;\r
+      {** Obtiene el versor k del sistema de coordenadas de la nave}\r
+      function mGetK: cVector;\r
+      {** Método para establecer la posición}\r
+      function mSetPosicion( posicion: cVector ): cObjetoVolador;\r
+      {** Método para establecer la velocidad}\r
+      function mSetVelocidad( velocidad: cVector ): cObjetoVolador; virtual;\r
+      {** Método para establecer el modulo de la velocidad}\r
+      function mSetVelModulo( velocidad: tLongitud ): cObjetoVolador; virtual;\r
+      {** Método para establecer la direccion de la velocidad}\r
+      function mSetVelDir( velocidad: cVector ): cObjetoVolador;\r
+      {** Resta energia al objeto volador}\r
+      function mRestarEnergia( ene: tEnergia ): cObjetoVolador;\r
+      {** Método abstracto, se sobreescribira en las subclases porque van a ser\r
+          dibujadas de forma diferente}\r
+      function mDibujar: tObjetosVoladores; virtual; abstract;\r
+      {** Destructor}\r
+      destructor destroy; override;\r
+      // SERIALIZACION\r
+      {** Devuelve una cadena de texto con el objeto serializado.}\r
+      function mSerializar: string; override;\r
+      {** Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.}\r
+      procedure mDesSerializar( str: string ); override;\r
+  end;\r
+\r
+implementation\r
+\r
+uses\r
+  RegExpr,\r
+  Sysutils;\r
+\r
+{ cObjetoVolador }\r
+\r
+{** Constructor\r
+    @param ov Objeto volador del cual extraer los datos para inicializar en actual}\r
+constructor cObjetoVolador.create( ov: cObjetoVolador );\r
+var\r
+  vel: cVector;\r
+begin\r
+  // Crea el objeto basandose en los atributos del parametro\r
+  inherited create;\r
+  aPosicion := ov.mGetPosicion;\r
+  vel := ov.mGetVelocidad;\r
+  aVelocidad := vel.mGetModulo;\r
+  vel.free;\r
+  aDimension := ov.mGetDimension;\r
+  aPotencia  := ov.mGetPotencia;\r
+  aEnergia   := ov.mGetEnergia;\r
+  aCoordenadas := ov.mGetCoordenadas;\r
+end;\r
+\r
+{** Constructor\r
+    @param pos Posicion inicial\r
+    @param vel Velocidad inicial\r
+    @param dim Dimensión del objeto volador (radio, en metros)\r
+    @param pot Potencia del objeto volador (cantidad de daño que hace por intervalode tiempo)\r
+    @param ene Energía del objeto volador(cantidad de daño que soporta antes de ser destruido)}\r
+constructor cObjetoVolador.create(pos: cVector = nil; vel: cVector = nil;\r
+  dim: tLongitud = 5; pot: tEnergia = 1; ene: tEnergia = 100);\r
+begin\r
+  inherited create;\r
+  aDimension := dim;\r
+  aPotencia  := pot;\r
+  aEnergia   := ene;\r
+  aCoordenadas := cCoordenadas.create;\r
+  // Si la posicion es nula crea una nueva\r
+  if pos = nil then\r
+    aPosicion := cVector.create( 0, 0, 0 )\r
+  else\r
+    aPosicion := cVector.create( pos );\r
+  // Si la velocidad es nula crea una nueva\r
+  if vel = nil then\r
+    aVelocidad := 0\r
+  else begin\r
+    aVelocidad := vel.mGetModulo;\r
+    aCoordenadas.mSetI( vel );\r
+  end;\r
+end;\r
+\r
+{** Mueve el objeto volador basandose en su posicion, su velocidad y un intervalo de tiempo\r
+    @param dT Intervalo de tiempo}\r
+procedure cObjetoVolador.mMover( dT: tTiempo );\r
+var\r
+  v: cVector;\r
+begin\r
+  v := cVector.create( mGetVelocidad );\r
+  aPosicion.mModificarCon( v, dT );\r
+  v.free;\r
+end;\r
+\r
+{** Establece la velocidad del objeto volador\r
+    @param velocidad Nuevo vector velocidad}\r
+function cObjetoVolador.mSetVelocidad( velocidad: cVector ): cObjetoVolador;\r
+begin\r
+  aVelocidad := velocidad.mGetModulo;\r
+  // Agregado 30/10/00 para que mantenga las coordenadas\r
+  aCoordenadas.mSetI( velocidad );\r
+  result := self;\r
+end;\r
+\r
+{** Obtiene la velocidad del objeto volador\r
+    @return Vector velocidad}\r
+function cObjetoVolador.mGetVelocidad: cVector;\r
+begin\r
+  result := aCoordenadas.mGetI.mMultiplicar( aVelocidad );\r
+end;\r
+\r
+{** Obtiene la posición del objeto volador\r
+    @return Vector posición}\r
+function cObjetoVolador.mGetPosicion: cVector;\r
+begin\r
+  result := cVector.create( aPosicion );\r
+end;\r
+\r
+{** Obtiene la dimensión del objeto volador\r
+    @return Dimensión (radio, en metros)}\r
+function cObjetoVolador.mGetDimension: tLongitud;\r
+begin\r
+  result := aDimension;\r
+end;\r
+\r
+{** Destructor}\r
+destructor cObjetoVolador.destroy;\r
+begin\r
+  // Libera los atributo objeto\r
+  aPosicion.free;\r
+  aCoordenadas.free;\r
+  inherited;\r
+end;\r
+\r
+{** Obtiene la potencia del objeto volador\r
+    @return Potencia (cantidad de daño que realiza por intervalo de tiempo)}\r
+function cObjetoVolador.mGetPotencia: tEnergia;\r
+begin\r
+ result := aPotencia;\r
+end;\r
+\r
+{** Obtiene la e del objeto volador\r
+    @return Energía (cantidad de daño que soporta antes de ser destruido)}\r
+function cObjetoVolador.mGetEnergia: tEnergia;\r
+begin\r
+ result := aEnergia;\r
+end;\r
+\r
+{$IFDEF DebugAlgoWars}\r
+{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos.\r
+    @return            Cadena de texto con el estado del Objeto.\r
+    @param   debugLevel Cantidad de información requerida}\r
+function cObjetoVolador.mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string;\r
+begin\r
+  // Construye la cadena dependiendo de la cantidad de informacion que se quiera obtener\r
+  result := 'Posición: ' + aPosicion.mGetDebugInfo( debugLevel );\r
+  if debugLevel > DI_MINI then\r
+    result := result + #13 + #10 +\r
+              'Energia: ' + FloatToStrF( aEnergia, ffNumber, 5, 5 );\r
+  if debugLevel > DI_NORMAL then\r
+    result := result + ' | Potencia: ' + FloatToStrF( aPotencia, ffNumber, 5, 5 ) +\r
+                       ' | Dimension: ' + FloatToStrF( aDimension, ffNumber, 5, 5 ) + #13 + #10 +\r
+                       'Velocidad: ' + mGetVelocidad.mGetDebugInfo( debugLevel ) + #13 + #10 +\r
+                       'Coordenadas: ' + #13 + #10 + aCoordenadas.mGetDebugInfo;\r
+end;\r
+{$ENDIF}\r
+\r
+{** Resta energía al objeto volador\r
+    @param ene Energía a restar}\r
+function cObjetoVolador.mRestarEnergia(ene: tEnergia): cObjetoVolador;\r
+begin\r
+  aEnergia := aEnergia - ene;\r
+  result := self;\r
+end;\r
+\r
+{** Setea la energía del objeto volador a un valor arbitrario\r
+    @param ene Nueva energía}\r
+function cObjetoVolador.mSetEnergia(ene: tEnergia): cObjetoVolador;\r
+begin\r
+  aEnergia := ene;\r
+  result := self;\r
+end;\r
+\r
+{** Calcula la distancia a otro objeto volador\r
+    @return     Distancia al otro objeto volador\r
+    @param   ov Objeto volador al que se calcula la distancia}\r
+function cObjetoVolador.mGetDistancia(ov: cObjetoVolador): tLongitud;\r
+var\r
+  v: cVector; // Vector temporal\r
+begin\r
+  v := ov.mGetPosicion; // obtiene la posicion de ov\r
+  result := v.mGetDistancia( aPosicion ); // obtiene la distancia\r
+  v.free; // Libera al vector temporal\r
+end;\r
+\r
+{** Devuelve true si colisionaron los objetos voladores\r
+    @return     <i>true<i> si colisionaron, <i>false</i> si no lo hicieron\r
+    @param   ov Objeto volador con el que se evalua si colisiono}\r
+function cObjetoVolador.mColisiono(ov: cObjetoVolador): boolean;\r
+begin\r
+  // true si la distancia es menor a la suma de las dimensiones\r
+  result := ( mGetDistancia( ov ) <= ( aDimension + ov.mGetDimension ) );\r
+end;\r
+\r
+{** Obtiene el sistema de coordenadas de la nave\r
+    @return Sistema de coordenadas de la nave}\r
+function cObjetoVolador.mGetCoordenadas: cCoordenadas;\r
+begin\r
+  result := cCoordenadas.create( aCoordenadas );\r
+end;\r
+\r
+{** Método para establecer el modulo de la velocidad\r
+    @param velocidad Nuevo módulo de la velocidad}\r
+function cObjetoVolador.mSetVelModulo( velocidad: tLongitud ): cObjetoVolador;\r
+begin\r
+  if velocidad > 0 then\r
+    aVelocidad := velocidad\r
+  else\r
+    aVelocidad := 0;\r
+  result := self;\r
+end;\r
+\r
+{** Método para establecer la direccion de la velocidad\r
+    @param velocidad Nueva dirección de la velocidad}\r
+function cObjetoVolador.mSetVelDir( velocidad: cVector ): cObjetoVolador;\r
+begin\r
+  aCoordenadas.mSetI( velocidad );\r
+  result := self;\r
+end;\r
+\r
+{** Obtiene el modulo de la velocidad del objeto volador\r
+    @return Módulo de la velocidad}\r
+function cObjetoVolador.mGetVelModulo: tLongitud;\r
+begin\r
+  result := aVelocidad;\r
+end;\r
+\r
+{** Obtiene el versor i del sistema de coordenadas de la nave\r
+    @return Versor i, que representa la direccion en la que viaja el objeto}\r
+function cObjetoVolador.mGetI: cVector;\r
+begin\r
+  result := aCoordenadas.mGetI;\r
+end;\r
+\r
+{** Obtiene el versor j del sistema de coordenadas de la nave\r
+    @return Versor j, que representa la direccion en la que está la izquierda del objeto}\r
+function cObjetoVolador.mGetJ: cVector;\r
+begin\r
+  result := aCoordenadas.mGetJ;\r
+end;\r
+\r
+{** Obtiene el versor k del sistema de coordenadas de la nave\r
+    @return Versor k, que representa la direccion en la que está el "techo" del objeto}\r
+function cObjetoVolador.mGetK: cVector;\r
+begin\r
+  result := aCoordenadas.mGetK;\r
+end;\r
+\r
+{** Rota el objeto volador sobre el eje i\r
+    (el sentido positivo es de j a k)}\r
+function cObjetoVolador.mRotarEnI( dAngulo: tAngulo ): cObjetoVolador;\r
+begin\r
+  aCoordenadas.mRotarEnI( dAngulo );\r
+  result := self;\r
+end;\r
+\r
+{** Rota el objeto volador sobre el eje j\r
+    (el sentido positivo es de i a k)}\r
+function cObjetoVolador.mRotarEnJ( dAngulo: tAngulo ): cObjetoVolador;\r
+begin\r
+  aCoordenadas.mRotarEnJ( dAngulo );\r
+  result := self;\r
+end;\r
+\r
+{** Rota el objeto volador sobre el eje k\r
+    (el sentido positivo es de i a j)}\r
+function cObjetoVolador.mRotarEnK( dAngulo: tAngulo ): cObjetoVolador;\r
+begin\r
+  aCoordenadas.mRotarEnK( dAngulo );\r
+  result := self;\r
+end;\r
+\r
+{** Método para establecer la posición\r
+    @param velocidad Nuevo vector posición}\r
+function cObjetoVolador.mSetPosicion(posicion: cVector): cObjetoVolador;\r
+begin\r
+  aPosicion := cVector.create( posicion );\r
+  result := self;\r
+end;\r
+\r
+{** Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    @param str Cadena de texto con el objeto serializado.}\r
+procedure cObjetoVolador.mDesSerializar(str: string);\r
+var\r
+  r: TRegExpr;\r
+begin\r
+  inherited mDesSerializar( str ); // SIEMPRE el ID debe ser el PRIMER atributo\r
+  r := TRegExpr.create;\r
+  // POSICION\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<posicion>\s*(.+)\s*</posicion>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      if aPosicion <> nil then // Si no es nulo\r
+        aPosicion.mDesSerializar( r.Match[1] ) // Lo deserializa\r
+      else // si es nulo\r
+        aPosicion := cVector.crearDeSerializado( r.Match[1] ) // lo crea\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro la posicion' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ESerializacion do begin // Si fueron de serializacion...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al deserializar la posicion: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer la posicion utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // VELOCIDAD\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<velocidad>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</velocidad>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aVelocidad := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro la velocidad' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer la velocidad utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // POTENCIA\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<potencia>\s*([+\-]?\d+)\s*</potencia>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aPotencia := StrToInt( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro la potencia' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer la potencia utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // ENERGIA\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<energia>\s*([+\-]?\d+)\s*</energia>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aEnergia := StrToInt( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro la energia' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer la energia utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // DIMENSION\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<dimension>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</dimension>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aDimension := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro la dimension' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer la dimension utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // COORDENADAS\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<coordenadas>\s*(.+)\s*</coordenadas>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      if aCoordenadas <> nil then // Si no es nulo\r
+        aCoordenadas.mDesSerializar( r.Match[1] ) // Lo deserializa\r
+      else // si es nulo\r
+        aCoordenadas := cCoordenadas.crearDeSerializado( r.Match[1] ) // lo crea\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( ClassName + ': No se pudieron extraer las coordenadas' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ESerializacion do begin // Si fueron de serializacion...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al deserializar las coordenadas: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer las coordenadas utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  r.free;\r
+end;\r
+\r
+{** Devuelve una cadena de texto con el objeto serializado.\r
+    @return Cadena de texto con el objeto serializado.}\r
+function cObjetoVolador.mSerializar: string;\r
+begin\r
+  result := inherited mSerializar +\r
+            '<posicion>' + aPosicion.mSerializar + '</posicion>' +\r
+            '<velocidad>' + FloatToStrF( aVelocidad, ffGeneral, 18, 0 ) + '</velocidad>' +\r
+            '<potencia>' + FloatToStrF( aPotencia, ffGeneral, 18, 0 ) + '</potencia>' +\r
+            '<energia>' + FloatToStrF( aEnergia, ffGeneral, 18, 0 ) + '</energia>' +\r
+            '<dimension>' + FloatToStrF( aDimension, ffGeneral, 18, 0 ) + '</dimension>' +\r
+            '<coordenadas>' + aCoordenadas.mSerializar + '</coordenadas>';\r
+end;\r
+\r
+end.\r
diff --git a/src/modelo/ov/naves/Nave.pas b/src/modelo/ov/naves/Nave.pas
new file mode 100644 (file)
index 0000000..8b66f56
--- /dev/null
@@ -0,0 +1,542 @@
+{** Contiene una clase abstracta con elementos comunes a todas las naves.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    27/11/00: Se agrega toda la parte del manejo de disparos, agregándose los métodos mPuedeDispararLaser,\r
+              mPuedeDispararMisil, mPuedeDispararMisDir y mDisparar, además de varios atributos para manejar\r
+              los retardos de las armas. El método mDisparar se hace virtual ya que puede ser modificado por\r
+              las subclases para que cambie su mecanismo de disparos.\r
+    29/11/00: Se agregan métodos para obtener la cantidad de armamento que le queda a la nave para poder ser\r
+              mostrados (mGetMisiles y mGetMisilesDirigidos)\r
+    01/12/00: Se modifican levemente los metodos mPuedeDispararXxxx para que permitan disparar si el puntero\r
+              al Objeto Volador objetivo es nil.\r
+              Se Agregan los métodos mRetardarLaser, mRetardarMisil, mRetardarMisDir que resetea el contador\r
+              del retardo, mActualizarRetardos que resta el dT a los retardos, y mCrearLaserDisparado,\r
+              mCrearMisilDisparado y mCrearMisDirDisparado que crea el arma correspondiente (actualizando\r
+              retardos y todo lo que sea necesario) para que las subclases puedan escribir su propio mDisparar.\r
+              Se cambia el orden de los argumentos de mDisparar para aprovechar los argumentos por defecto.\r
+    08/12/00: Se sobreescribieron los métodos para establecer la velocidad y su módulo para evitar que se\r
+              sobrepase el límite de la velocidad máxima.\r
+    </PRE>}\r
+unit Nave;\r
+\r
+interface\r
+\r
+uses\r
+  ObjetoVolador,\r
+  Tipos,\r
+  Vectores,\r
+  Armas;\r
+\r
+type\r
+  {** Clase abstracta con elementos comunes a todas las naves.}\r
+  cNave = class( cObjetoVolador )\r
+    private\r
+      aMisiles:           tMaxMisil;         // Cantidad de misilies comunes\r
+      aMisilesDirigidos:  tMaxMisilDirigido; // Cantidad de misiles dirigidos\r
+      aVelMaxima:         tLongitud;        // Velocidad máxima de la nave\r
+      aRetardoLaser:      tTiempo;          // Ratardo del arma antes de poder volver a disparar\r
+      aRetardoMisil:      tTiempo;          // Ratardo del arma antes de poder volver a disparar\r
+      aRetardoMisDir:     tTiempo;          // Ratardo del arma antes de poder volver a disparar\r
+      aRetardoLaserCont:  tTiempo;          // Ratardo del arma antes de poder volver a disparar (contador)\r
+      aRetardoMisilCont:  tTiempo;          // Ratardo del arma antes de poder volver a disparar (contador)\r
+      aRetardoMisDirCont: tTiempo;          // Ratardo del arma antes de poder volver a disparar (contador)\r
+    protected\r
+      {** Setea la velocidad máxima}\r
+      function mSetVelMax( velMax: tLongitud ): cNave;\r
+      {** Resta un misil}\r
+      function mRestarMisil: cNave;\r
+      {** Resta un misil dirigido}\r
+      function mRestarMisilDirigido: cNave;\r
+      {** Devuelve true si todavía tiene misiles}\r
+      function mTieneMisil: boolean;\r
+      {** Devuelve true si todavía tiene misiles dirigidos}\r
+      function mTieneMisilDirigido: boolean;\r
+      {** Resetea el contador del retardo del láser}\r
+      procedure mRetardarLaser;\r
+      {** Resetea el contador del retardo del misil}\r
+      procedure mRetardarMisil;\r
+      {** Resetea el contador del retardo del misil dirigido}\r
+      procedure mRetardarMisDir;\r
+      {** Actualiza los retardadores}\r
+      procedure mActualizarRetardadores( dT: tTiempo );\r
+      {** Crea un laser (actualizando retardos y todo lo que sea necesario)}\r
+      function mCrearLaserDisparado: cLaser;\r
+      {** Crea un misil (actualizando retardos y todo lo que sea necesario)}\r
+      function mCrearMisilDisparado: cMisil;\r
+      {** Crea un misil dirigido (actualizando retardos y todo lo que sea necesario)}\r
+      function mCrearMisDirDisparado( ov : cObjetoVolador ): cMisilDirigido;\r
+    public\r
+      {** Constructor}\r
+      constructor create( pos: cVector = nil; vel: cVector = nil; dim: tLongitud = 5;\r
+                          pot: tEnergia = 1; ene: tEnergia = 100; misiles: tMaxMisil = 0;\r
+                          misilesDirigidos: tMaxMisilDirigido = 0; velMax: tLongitud = 0.2;\r
+                          retardoLaser:   tTiempo = 1000;  {1 segundo}\r
+                          retardoMisil:  tTiempo = 60000; {1 minuto}\r
+                          retardoMisDir: tTiempo = 180000 {3 minutos}); overload;\r
+      {** Hace que se dispare un arma (todavía no está implementado), devolviendo la nueva\r
+          municion disparada}\r
+      function mDisparar( dT: tTiempo; ov : cObjetoVolador = nil ): cArma; virtual;\r
+      {** Obtiene la cantidad de Misiles que le quedan a la nave}\r
+      function mGetMisiles: tMaxMisil;\r
+      {** Obtiene la cantidad de Misiles Dirigidos que le quedan a la nave}\r
+      function mGetMisilesDirigidos: tMaxMisilDirigido;\r
+      {** Obtiene la velocidad máxima}\r
+      function mGetVelMax: tLongitud;\r
+      {** Método para establecer la velocidad}\r
+      function mSetVelocidad( velocidad: cVector ): cObjetoVolador; override;\r
+      {** Método para establecer el modulo de la velocidad}\r
+      function mSetVelModulo( velocidad: tLongitud ): cObjetoVolador; override;\r
+      {** Chequea que el enemigo este a distancia, que tenga municiones, etc.}\r
+      function mPuedeDispararLaser( ov : cObjetoVolador ): boolean;\r
+      {** Chequea que el enemigo este a distancia, que tenga municiones, etc.}\r
+      function mPuedeDispararMisil( ov : cObjetoVolador ): boolean;\r
+      {** Chequea que el enemigo este a distancia, que tenga municiones, etc.}\r
+      function mPuedeDispararMisDir( ov : cObjetoVolador ): boolean;\r
+      {$IFDEF DebugAlgoWars}\r
+      {** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.}\r
+      function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;\r
+      {$ENDIF}\r
+      // SERIALIZACION\r
+      {** Devuelve una cadena de texto con el objeto serializado.}\r
+      function mSerializar: string; override;\r
+      {** Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.}\r
+      procedure mDesSerializar( str: string ); override;\r
+  end;\r
+\r
+implementation\r
+\r
+uses\r
+  RegExpr,\r
+  ObjetoPersistente,\r
+  Sysutils;\r
+\r
+{ cNave }\r
+\r
+{** Constructor\r
+    @param pos              Posicion inicial\r
+    @param vel              Velocidad inicial\r
+    @param dim              Dimensión (radio, en metros)\r
+    @param pot              Potencia (cantidad de daño que hace por intervalode tiempo)\r
+    @param ene              Energía (cantidad de daño que soporta antes de ser destruido)\r
+    @param misiles          Cantidad de misiles comunes\r
+    @param misilesDirigidos Cantidad de misiles dirigidos\r
+    @param velMax           Velocidad máxima que puede alcanzar (modulo)\r
+    @param retardoLaser     Ratardo del arma antes de poder volver a disparar\r
+    @param retardoMisil     Ratardo del arma antes de poder volver a disparar\r
+    @param retardoMisDir    Ratardo del arma antes de poder volver a disparar}\r
+constructor cNave.create(pos, vel: cVector; dim: tLongitud; pot,\r
+  ene: tEnergia; misiles: tMaxMisil; misilesDirigidos: tMaxMisilDirigido;\r
+  velMax: tLongitud; retardoLaser: tTiempo; retardoMisil: tTiempo;\r
+  retardoMisDir: tTiempo);\r
+begin\r
+  if vel <> nil then\r
+    if vel.mGetModulo > velMax then\r
+      vel.mSetModulo( velMax );\r
+  inherited create( pos, vel, dim, pot, ene );\r
+  aMisiles := misiles;\r
+  aMisilesDirigidos := misilesDirigidos;\r
+  aVelMaxima := velMax;\r
+  aRetardoLaser  := retardoLaser;\r
+  aRetardoMisil  := retardoMisil;\r
+  aRetardoMisDir := retardoMisDir;\r
+  aRetardoLaserCont  := 0; // lista para disparar\r
+  aRetardoMisilCont  := 0; // lista para disparar\r
+  aRetardoMisDirCont := 0; // lista para disparar\r
+end;\r
+\r
+{$IFDEF DebugAlgoWars}\r
+{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos.\r
+    @return            Cadena de texto con el estado del Objeto.\r
+    @param   debugLevel Cantidad de información requerida}\r
+function cNave.mGetDebugInfo(debugLevel: tDebugInfo): string;\r
+begin\r
+  result := inherited mGetDebugInfo( debugLevel );\r
+  if debugLevel > DI_MINI then\r
+    result := result + ' | Misiles: ' + IntToStr( aMisiles ) +\r
+              ' | Misiles Dirigidos: ' + IntToStr( aMisilesDirigidos );\r
+end;\r
+{$ENDIF}\r
+\r
+{** Devuelve la velocidad máxima\r
+    @return Velocidad máxima (modulo)}\r
+function cNave.mGetVelMax: tLongitud;\r
+begin\r
+  result := aVelMaxima;\r
+end;\r
+\r
+{** Resta un misil}\r
+function cNave.mRestarMisil: cNave;\r
+begin\r
+  aMisiles := aMisiles - 1;\r
+  result := self;\r
+end;\r
+\r
+{** Resta un misil dirigido}\r
+function cNave.mRestarMisilDirigido: cNave;\r
+begin\r
+  aMisilesDirigidos := aMisilesDirigidos - 1;\r
+  result := self;\r
+end;\r
+\r
+{** Setea la velocidad máxima\r
+    @param velMax Nueva velocidad máxima (modulo)}\r
+function cNave.mSetVelMax(velMax: tLongitud): cNave;\r
+begin\r
+  aVelMaxima := velMax;\r
+  result := self;\r
+end;\r
+\r
+{** Chequea si todavía tiene misiles\r
+    @return <i>true</i> si tiene misiles, <i>false</i> si no}\r
+function cNave.mTieneMisil: boolean;\r
+begin\r
+  result := ( aMisiles > 0 ); // Devuelve true si aMisiles es mayor que cero\r
+end;\r
+\r
+{** Chequea si todavía tiene misiles dirigidos\r
+    @return <i>true</i> si tiene misiles dirigidos, <i>false</i> si no}\r
+function cNave.mTieneMisilDirigido: boolean;\r
+begin\r
+  result := ( aMisilesDirigidos > 0 ); // Devuelve true si aMisilesDirigidos es mayor que cero\r
+end;\r
+\r
+{** Chequea que el enemigo este a distancia, que tenga municiones, etc.\r
+    @param  np Nave Propia a la que quiere disparar\r
+    @return <i>True</i> si está todo ok, <i>False</i> si no.}\r
+function cNave.mPuedeDispararLaser( ov : cObjetoVolador ): boolean;\r
+begin\r
+  result := false;\r
+  if aRetardoLaserCont <= 0 then // Primero se fija que ya esté recargada el arma\r
+    // 1200 es el alcance del laser.\r
+    if ov <> nil then begin // Si el ov es nil puede disparar, ni no lo es, chequea la distancia\r
+      if mGetDistancia( ov ) < 1200 then// Si la distancia a la np es menor que el alcance\r
+        result := true;\r
+    end else\r
+      result := true;\r
+end;\r
+\r
+{** Chequea que el enemigo este a distancia, que tenga municiones, etc.\r
+    @param  np Nave Propia a la que quiere disparar\r
+    @return <i>True</i> si está todo ok, <i>False</i> si no.}\r
+function cNave.mPuedeDispararMisil( ov : cObjetoVolador ): boolean;\r
+begin\r
+  result := false;\r
+  // Primero se fija que ya esté recargada el arma y que todavia tenga municiones\r
+  if mTieneMisil and ( aRetardoMisilCont <= 0 ) then\r
+    // 1500 es el alcance del misil.\r
+    if ov <> nil then begin // Si el ov es nil puede disparar, ni no lo es, chequea la distancia\r
+      if mGetDistancia( ov ) < 1500 then// Si la distancia a la np es menor que el alcance\r
+        result := true;\r
+    end else\r
+      result := true;\r
+end;\r
+\r
+{** Chequea que el enemigo este a distancia, que tenga municiones, etc.\r
+    @param  np Nave Propia a la que quiere disparar\r
+    @return <i>True</i> si está todo ok, <i>False</i> si no.}\r
+function cNave.mPuedeDispararMisDir( ov : cObjetoVolador ): boolean;\r
+begin\r
+  result := false;\r
+  // Primero se fija que ya esté recargada el arma y que todavia tenga municiones\r
+  if mTieneMisilDirigido and ( aRetardoMisDirCont <= 0 ) then\r
+    // 2000 es el alcance del misil dirigido.\r
+    if ov <> nil then begin // Si el ov es nil puede disparar, ni no lo es, chequea la distancia\r
+      if mGetDistancia( ov ) < 2000 then// Si la distancia a la np es menor que el alcance\r
+        result := true;\r
+    end else\r
+      result := true;\r
+end;\r
+\r
+{** Hace que se dispare un arma\r
+    @param  ov Objetivo del disparo\r
+    @param  dT Intervalo de tiempo\r
+    @return Arma disparada (o <i>nil</i> si no se puede disparar ningún arma)}\r
+function cNave.mDisparar( dT: tTiempo; ov : cObjetoVolador ): cArma;\r
+begin\r
+  result := nil; // devuelve nil por defecto\r
+  mActualizarRetardadores( dT );\r
+  if mPuedeDispararMisDir( ov ) then\r
+    result := mCrearMisDirDisparado( ov )\r
+  else if mPuedeDispararMisil( ov ) then\r
+    result := mCrearMisilDisparado\r
+  else if mPuedeDispararLaser( ov ) then\r
+    result := mCrearLaserDisparado;\r
+end;\r
+\r
+{** Obtiene la cantidad de Misiles que le quedan a la nave\r
+    return Cantidad de misiles que le quedan a la nave}\r
+function cNave.mGetMisiles: tMaxMisil;\r
+begin\r
+  result := aMisiles;\r
+end;\r
+\r
+{** Obtiene la cantidad de Misiles que le quedan a la nave\r
+    return Cantidad de misiles dirigidos que le quedan a la nave}\r
+function cNave.mGetMisilesDirigidos: tMaxMisilDirigido;\r
+begin\r
+  result := aMisilesDirigidos;\r
+end;\r
+\r
+{** Resetea el contador del retardo del láser}\r
+procedure cNave.mRetardarLaser;\r
+begin\r
+  aRetardoLaserCont := aRetardoLaser;\r
+end;\r
+\r
+{** Resetea el contador del retardo del misil dirigido}\r
+procedure cNave.mRetardarMisDir;\r
+begin\r
+  aRetardoMisDirCont := aRetardoMisDir;\r
+end;\r
+\r
+{** Resetea el contador del retardo del misil}\r
+procedure cNave.mRetardarMisil;\r
+begin\r
+  aRetardoMisilCont := aRetardoMisil;\r
+end;\r
+\r
+{** Actualiza los retardadores\r
+    @param dT Intervalo de tiempo a restarles}\r
+procedure cNave.mActualizarRetardadores(dT: tTiempo);\r
+begin\r
+  if aRetardoMisDirCont > 0 then\r
+    aRetardoMisDirCont := aRetardoMisDirCont - dT;\r
+  if aRetardoMisilCont > 0 then\r
+    aRetardoMisilCont := aRetardoMisilCont - dT;\r
+  if aRetardoLaserCont > 0 then\r
+    aRetardoLaserCont := aRetardoLaserCont - dT;\r
+end;\r
+\r
+{** Crea un láser (actualizando retardos)\r
+    @return Nuevo láser}\r
+function cNave.mCrearLaserDisparado: cLaser;\r
+var\r
+  pos,\r
+  vel,\r
+  vec: cVector;\r
+begin\r
+    mRetardarLaser; // Resetea el retardo\r
+    // Se calcula la posicion a partir de la posicion de la nave propia y sumandole el 150% de\r
+    // su tamaño en la direccion de i (para que no colisione con quien dispara).\r
+    vec := mGetI.mMultiplicar( mGetDimension * 1.5 );\r
+    pos := mGetPosicion.mSumar( vec );\r
+    // vec tambien me va a servir como la dirección de la velocidad porque tiene la direccion de i\r
+    vel := vec;\r
+    // devuelve el arma disparada\r
+    result := cLaser.create( pos, vel );\r
+    // Libera memoria\r
+    pos.free;\r
+    vec.free;\r
+end;\r
+\r
+{** Crea un misil dirigido (actualizando retardos y restando un misil dirigido)\r
+    @param  ov Objetivo del misil dirigido\r
+    @return Nuevo misil dirigido}\r
+function cNave.mCrearMisDirDisparado( ov : cObjetoVolador ): cMisilDirigido;\r
+var\r
+  pos,\r
+  vec: cVector;\r
+begin\r
+    mRestarMisilDirigido;\r
+    mRetardarMisDir; // Resetea el retardo\r
+    // Se calcula la posicion a partir de la posicion de la nave propia y sumandole el 150% de\r
+    // su tamaño en la direccion de i (para que no colisione con quien dispara)\r
+    vec := mGetI.mMultiplicar( mGetDimension * 1.5 );\r
+    pos := mGetPosicion.mSumar( vec );\r
+    // devuelve el arma disparada\r
+    result := cMisilDirigido.create( ov, pos );\r
+    // Libera memoria\r
+    pos.free;\r
+    vec.free;\r
+end;\r
+\r
+{** Crea un misil dirigido (actualizando retardos y restando un misil)\r
+    @return Nuevo misil}\r
+function cNave.mCrearMisilDisparado: cMisil;\r
+var\r
+  pos,\r
+  vel,\r
+  vec: cVector;\r
+begin\r
+    mRestarMisil;   // Resta un misil\r
+    mRetardarMisil; // Resetea el retardo\r
+    // Se calcula la posicion a partir de la posicion de la nave propia y sumandole el 150% de\r
+    // su tamaño en la direccion de i (para que no colisione con quien dispara)\r
+    vec := mGetI.mMultiplicar( mGetDimension * 1.5 );\r
+    pos := mGetPosicion.mSumar( vec );\r
+    // vec tambien me va a servir como la dirección de la velocidad porque tiene la direccion de i\r
+    vel := vec;\r
+    // devuelve el arma disparada\r
+    result := cMisil.create( pos, vel );\r
+    // Libera memoria\r
+    pos.free;\r
+    vec.free\r
+end;\r
+\r
+{** Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    @param str Cadena de texto con el objeto serializado.}\r
+procedure cNave.mDesSerializar(str: string);\r
+var\r
+  r: TRegExpr;\r
+begin\r
+  inherited mDesSerializar( str ); // SIEMPRE el ID debe ser el PRIMER atributo\r
+  r := TRegExpr.create;\r
+  // MISILES\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<misiles>\s*(\d+)\s*</misiles>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aMisiles := StrToInt( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro la cantidad de misiles' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer la cantidad de misiles utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // MISILESDIRIGIDOS\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<misilesdirigidos>\s*(\d+)\s*</misilesdirigidos>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aMisilesDirigidos := StrToInt( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro la cantidad de misiles dirigidos' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer la cantidad de misiles dirigidos utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // VELMAXIMA\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<velmaxima>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</velmaxima>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aVelMaxima := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro la velocidad maxima' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer la velocidad maxima utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // RETARDOLASER\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<retardolaser>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</retardolaser>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aRetardoLaser := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el retardo del laser' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el retardo del laser utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // RETARDOMISIL\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<retardomisil>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</retardomisil>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aRetardoMisil := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el retardo del misil' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el retardo del misil utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // RETARDOMISDIR\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<retardomisdir>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</retardomisdir>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aRetardoMisDir := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el retardo del misil dirigido' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el retardo del misil dirigido utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // RETARDOLASERCONT\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<retardolasercont>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</retardolasercont>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aRetardoLaserCont := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el contador del retardo del laser' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el contador del retardo del laser utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // RETARDOMISIL\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<retardomisilcont>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</retardomisilcont>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aRetardoMisilCont := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el contador del retardo del misil' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el contador del retardo del misil utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // RETARDOMISDIR\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<retardomisdircont>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</retardomisdircont>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aRetardoMisDirCont := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el contador del retardo del misil dirigido' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el contador del retardo del misil dirigido utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  r.free;\r
+end;\r
+\r
+{** Devuelve una cadena de texto con el objeto serializado.\r
+    @return Cadena de texto con el objeto serializado.}\r
+function cNave.mSerializar: string;\r
+begin\r
+  result := inherited mSerializar +\r
+            '<misiles>' + IntToStr( aMisiles ) + '</misiles>' +\r
+            '<misilesdirigidos>' + IntToStr( aMisilesDirigidos ) + '</misilesdirigidos>' +\r
+            '<velmaxima>' + FloatToStrF( aVelMaxima, ffGeneral, 18, 0 ) + '</velmaxima>' +\r
+            '<retardolaser>' + FloatToStrF( aRetardoLaser, ffGeneral, 18, 0 ) + '</retardolaser>' +\r
+            '<retardomisil>' + FloatToStrF( aRetardoMisil, ffGeneral, 18, 0 ) + '</retardomisil>' +\r
+            '<retardomisdir>' + FloatToStrF( aRetardoMisDir, ffGeneral, 18, 0 ) + '</retardomisdir>' +\r
+            '<retardolasercont>' + FloatToStrF( aRetardoLaserCont, ffGeneral, 18, 0 ) + '</retardolasercont>' +\r
+            '<retardomisilcont>' + FloatToStrF( aRetardoMisilCont, ffGeneral, 18, 0 ) + '</retardomisilcont>' +\r
+            '<retardomisdircont>' + FloatToStrF( aRetardoMisDirCont, ffGeneral, 18, 0 ) + '</retardomisdircont>';\r
+end;\r
+\r
+{** Método para establecer la velocidad}\r
+function cNave.mSetVelModulo(velocidad: tLongitud): cObjetoVolador;\r
+begin\r
+  if velocidad > aVelMaxima then\r
+    velocidad := aVelMaxima;\r
+  result := inherited mSetVelModulo( velocidad );\r
+end;\r
+\r
+{** Método para establecer el modulo de la velocidad}\r
+function cNave.mSetVelocidad(velocidad: cVector): cObjetoVolador;\r
+begin\r
+  if velocidad.mGetModulo > aVelMaxima then begin // Si sobrepasa el limite ...\r
+    mSetVelModulo( aVelMaxima ); // Se le asigna el modulo como limite\r
+    mSetVelDir( velocidad );     // Se le asigna la direccion\r
+    result := self;\r
+  end else // Si no sobrepasa el limite ...\r
+    result := inherited mSetVelocidad( velocidad ); // Se asigna la nueva vel\r
+end;\r
+\r
+end.\r
diff --git a/src/modelo/ov/naves/NaveEnemiga.pas b/src/modelo/ov/naves/NaveEnemiga.pas
new file mode 100644 (file)
index 0000000..42305a0
--- /dev/null
@@ -0,0 +1,184 @@
+{** La clase cNaveEnemiga esta pensada como una clase abtracta. En ella se encuentran\r
+    características comunes a todas las naves enemigas.<br>\r
+      <i>Cambios:</i>\r
+    <PRE>\r
+    05/10/00: Se cambio el metodo mGetRadar por el metodo mDetectado, que devuelve true\r
+              si un objeto volador esta destro del campo de radar. De esta manera se logra\r
+              una abstracción mayor y un manejo mas intuitivo del radar.\r
+    </PRE>}\r
+unit NaveEnemiga;\r
+\r
+interface\r
+\r
+uses\r
+  Tipos,\r
+  Vectores,\r
+  Nave,\r
+  NavePropia,\r
+  ObjetoVolador,\r
+  Armas;\r
+\r
+type\r
+  {** La clase cNaveEnemiga esta pensada como una clase abtracta. En ella se encuentran\r
+      características comunes a todas las naves enemigas.}\r
+  cNaveEnemiga = class( cNave )\r
+    private\r
+      aCampoRadar: tLongitud; // Area en la que detecta a la nave propia\r
+    protected\r
+      {** Modifica la velocidad de la nave en base a la nave propia}\r
+      procedure mModificarVelocidad( np: cNavePropia; modulo: tLongitud = -1 ); virtual;\r
+    public\r
+      {** Constructor}\r
+      constructor create( pos: cVector = nil; vel: cVector = nil; dim: tLongitud = 10;\r
+                          pot: tEnergia = 100; ene: tEnergia = 100; misiles: tMaxMisil = 0;\r
+                          misilesDirigidos: tMaxMisilDirigido = 0; velMax: tLongitud = 0.2;\r
+                          radar : tLongitud = 2500;\r
+                          retardoLaser:   tTiempo = 1000;   {1 segundo}\r
+                          retardoMisil:  tTiempo = 60000;  {1 minuto}\r
+                          retardoMisDir: tTiempo = 180000 {3 minutos}); overload;\r
+      {** Hace reaccionar ante la presencia de la nave propia. Tiene un comportamiento polimófico ya que cada nave\r
+          enemiga reaccionará de forma diferente (método abstracto)}\r
+      procedure mReaccionar( np: cNavePropia ); virtual; abstract;\r
+      {** Indica si ov esta en el campo de radar}\r
+      function mDetectado( ov: cObjetoVolador ): boolean;\r
+      {** Hace que la nave se dirija a una posicion particular}\r
+      procedure mIrA( pos: cVector );\r
+      {$IFDEF DebugAlgoWars}\r
+      {** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.}\r
+      function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;\r
+      {$ENDIF}\r
+      // SERIALIZACION\r
+      {** Devuelve una cadena de texto con el objeto serializado.}\r
+      function mSerializar: string; override;\r
+      {** Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.}\r
+      procedure mDesSerializar( str: string ); override;\r
+  end;\r
+\r
+implementation\r
+\r
+uses\r
+  RegExpr,\r
+  ObjetoPersistente,\r
+  Sysutils;\r
+\r
+{ cNaveEnemiga }\r
+\r
+{** Constructor\r
+    @param pos              Posicion inicial\r
+    @param vel              Velocidad inicial\r
+    @param dim              Dimensión (radio, en metros)\r
+    @param pot              Potencia (cantidad de daño que hace por intervalode tiempo)\r
+    @param ene              Energía (cantidad de daño que soporta antes de ser destruido)\r
+    @param misiles          Cantidad de misiles comunes\r
+    @param misilesDirigidos Cantidad de misiles dirigidos\r
+    @param velMax           Velocidad máxima que puede alcanzar (modulo)\r
+    @param radar            Área máxima en la que puede detectar a otras naves (radio, en metros)\r
+    @param retardoLaser     Ratardo del arma antes de poder volver a disparar\r
+    @param retardoMisil     Ratardo del arma antes de poder volver a disparar\r
+    @param retardoMisDir    Ratardo del arma antes de poder volver a disparar}\r
+constructor cNaveEnemiga.create(pos, vel: cVector; dim: tLongitud; pot,\r
+  ene: tEnergia; misiles: tMaxMisil; misilesDirigidos: tMaxMisilDirigido;\r
+  velMax: tLongitud; radar: tLongitud; retardoLaser, retardoMisil,\r
+  retardoMisDir: tTiempo);\r
+begin\r
+  inherited create( pos , vel , dim , pot , ene , misiles, misilesDirigidos,\r
+                    velMax, retardoLaser, retardoMisil, retardoMisDir );\r
+  aCampoRadar := radar;\r
+end;\r
+\r
+{** Modifica la velocidad de la nave en base a la nave propia\r
+    @param np     Nave propia con la cual se calculará la dirección de la nueva velocidad\r
+    @param modulo Nuevo módulo de la velocidad}\r
+procedure cNaveEnemiga.mModificarVelocidad( np: cNavePropia; modulo: tLongitud );\r
+var\r
+  vel,        // Vector temporal para hacer calculos\r
+  pos: cVector; // Vector temporal para hacer calculos\r
+begin\r
+  if (modulo < 0) or (modulo > mGetVelMax) then\r
+    modulo := mGetVelMax;\r
+  pos := mGetPosicion;\r
+  // Crea un nuevo verctor basado en la posicion del objetivo,\r
+  //  Le resta la posicion propia, obteniendo la nueva direccion de la velocidad\r
+  //  y luego setea el modulo\r
+  vel := np.mGetPosicion.mRestar( pos );\r
+  // Modifica la velocidad basado en el vector v\r
+  mSetVelDir( vel );\r
+  mSetVelModulo( modulo );\r
+  vel.free; // libera la memoria del vector temporal\r
+  pos.free; // libera la memoria del vector temporal\r
+end;\r
+\r
+{** Indica si ov esta en el campo de radar\r
+    @param ov Objeto volador a chequear si está dentro del alcance del radar}\r
+function cNaveEnemiga.mDetectado( ov: cObjetoVolador ): boolean;\r
+begin\r
+  // true si la distancia es menor que el campo de radar\r
+  result := ( mGetDistancia( ov ) <= aCampoRadar );\r
+end;\r
+\r
+{** Hace que la nave se dirija a una posicion particular\r
+    @param pos Vector posición del punto al cual se dirigirá la nave}\r
+procedure cNaveEnemiga.mIrA(pos: cVector);\r
+var\r
+  v: cVector;        // Vector temporal para hacer calculos\r
+  modulo: tLongitud; // Modulo actual de la velocidad\r
+begin\r
+  v := mGetVelocidad;\r
+  modulo := v.mGetModulo; // Obtiene el modulo actual de la velocidad\r
+  v.free;\r
+  // Crea un nuevo verctor basado en la posicion y e resta la posicion propia,\r
+  //  obteniendo la nueva direccion de la velocidad.\r
+  v := cVector.create( pos ).mRestar( mGetPosicion );\r
+  mSetVelDir( v ); // Modifica la direccion de la velocidad basado en el vector v\r
+  mSetVelModulo( modulo ); // Setea el modulo igual que el de la velocidad original\r
+  v.free; // libera la memoria del vector temporal\r
+end;\r
+\r
+{$IFDEF DebugAlgoWars}\r
+{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos.\r
+    @return            Cadena de texto con el estado del Objeto.\r
+    @param   debugLevel Cantidad de información requerida}\r
+function cNaveEnemiga.mGetDebugInfo(debugLevel: tDebugInfo): string;\r
+begin\r
+  result := inherited mGetDebugInfo( debugLevel );\r
+  if debugLevel > DI_NORMAL then\r
+    result := result + ' | Campo de Radar: ' + FloatToStrF( aCampoRadar, ffNumber, 5, 5 );\r
+end;\r
+{$ENDIF}\r
+\r
+{** Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    @param str Cadena de texto con el objeto serializado.}\r
+procedure cNaveEnemiga.mDesSerializar(str: string);\r
+var\r
+  r: TRegExpr;\r
+begin\r
+  inherited mDesSerializar( str ); // SIEMPRE el ID debe ser el PRIMER atributo\r
+  r := TRegExpr.create;\r
+  // CAMPORADAR\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<camporadar>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</camporadar>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aCampoRadar := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el campo de radar' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el campo de radar utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  r.free;\r
+end;\r
+\r
+{** Devuelve una cadena de texto con el objeto serializado.\r
+    @return Cadena de texto con el objeto serializado.}\r
+function cNaveEnemiga.mSerializar: string;\r
+begin\r
+  result := inherited mSerializar +\r
+            '<camporadar>' + FloatToStrF( aCampoRadar, ffGeneral, 18, 0 ) + '</camporadar>';\r
+end;\r
+\r
+end.\r
diff --git a/src/modelo/ov/naves/NavePropia.pas b/src/modelo/ov/naves/NavePropia.pas
new file mode 100644 (file)
index 0000000..c2383cd
--- /dev/null
@@ -0,0 +1,466 @@
+{** Es la nave que será controlada por el jugador.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    05/10/00: Se corrigió el método mAcelerar porque tenía algunos bugs cuando la velocidad llegaba a cero.\r
+    01/12/00: Se implementan los disparon sobreescribiendo el método mDisparar de cNave y agregando algunos\r
+              atributos (aArmaSelect, aDisparando y aLockeado) y algunos métodos (mIntentarDisparo,\r
+              mSeleccionarArma, mSeleccionarArmaSig, mGetArmaSelect, mSetLockeado, mGetLockeado).\r
+              Se cambiaron las dimensiones de la nave para que los disparos sean mas "jugables".\r
+              Se cambia el orden de los argumentos de mDisparar para aprovechar los argumentos por defecto.\r
+              Se arreglaron un par de BUGs con punteros que apuntaba a objetos destruidos (aLockeado).\r
+    08/12/00: Se arregló una falla en el constructor que permitia crear la nave con una velocidad superior\r
+              a la máxima.\r
+    09/12/00: Se cambia el atributo disparando por un puntero a un arma que se disparara en el proximo turno.\r
+              También se cambia los métodos que lo utilizan y en particular se convierte el método\r
+              mIntentarDisparo en una función que devuelve dicho puntero para implementar la cámara en el arma.\r
+    </PRE>}\r
+unit NavePropia;\r
+\r
+interface\r
+\r
+uses\r
+  Tipos,\r
+  Vectores,\r
+  Nave,\r
+  ObjetoVolador,\r
+  Meteorito,\r
+  Coordenadas,\r
+  Classes,\r
+  Filtros,\r
+  Armas;\r
+\r
+type\r
+  {** Es la nave que será controlada por el jugador.\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            15        metros\r
+      Potencia:             5         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              100       Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,17      metros/milisegundos (612 km/h)\r
+      Misiles:              10\r
+      Misiles Dirigidos:    5\r
+      </PRE>}\r
+  cNavePropia = class( cNave )\r
+    private\r
+      aLockeado:   cObjetoVolador; // Objeto Volador Lockeado\r
+      aArmaSelec:  tArma;          // Arma seleccionada por el usuario\r
+      aDisparando: cArma;          // Indica si en este momento se esta disparando o no\r
+      aLockFiltro: cFiltroLock;    // Filtro para saber que objetos voladores se puede lockear\r
+    public\r
+      {** Crea una nave controlada por un jugador}\r
+      constructor create( pos: cVector = nil; vel: cVector = nil ); overload;\r
+      {** Hace que se dispare un arma (todavía no está implementado)}\r
+      function mDisparar( dT: tTiempo; ov : cObjetoVolador = nil ): cArma; override;\r
+      {** Obtiene el objetivo lockeado}\r
+      function mGetLockeado: cObjetoVolador;\r
+      {** Setea el objetivo lockeado}\r
+      procedure mSetLockeado( ov: cObjetoVolador );\r
+      {** Cambia el objetivo lockeado}\r
+      procedure mCambiarLockeado( lEnemigos: TList );\r
+      {** Permite a la nave rotar a la izquierda sobre su eje X}\r
+      procedure mRotarIzquierda( angulo: tAngulo );\r
+      {** Permite a la nave rotar a la derecha sobre su eje X}\r
+      procedure mRotarDerecha( angulo: tAngulo );\r
+      {** Permite a la nave girar hacia la izquierda (sobre su eje Z)}\r
+      procedure mGirarIzquierda( angulo: tAngulo );\r
+      {** Permite a la nave girar hacia la derecha (sobre su eje Z)}\r
+      procedure mGirarDerecha( angulo: tAngulo );\r
+      {** Permite a la nave girar hacia arriba (sobre su eje Y)}\r
+      procedure mGirarArriba( angulo: tAngulo );\r
+      {** Permite a la nave girar hacia abajo (sobre su eje Y)}\r
+      procedure mGirarAbajo( angulo: tAngulo );\r
+      {** Aumenta el modulo de la velocidad (sin cambiar su dirección ni\r
+          sentido y sin sobrepasar la velocidad maxima)}\r
+      procedure mAcelerar( modulo: tLongitud );\r
+      {** Disminuye el modulo de la velocidad (sin cambiar su dirección ni sentido)}\r
+      procedure mDesacelerar( modulo: tLongitud );\r
+      {** Intenta disparar. Si las condiciones son las correctas, el proximo turno\r
+          saldrá el disparo, si no, no hace nada}\r
+      function mIntentarDisparo: cArma;\r
+      {** Selecciona un arma determinada. Si tiene municiones, la selecciona, si no,\r
+          no hace nada.}\r
+      procedure mSeleccionarArma( a: tArma );\r
+      {** Selecciona el proximo arma con municiones}\r
+      procedure mSeleccionarArmaSig;\r
+      {** Obtiene el arma seleccionada actualmente}\r
+      function mGetArmaSelec: tArma;\r
+      {** Obtiene un puntero a la último arma disparada}\r
+      function mGetUltimoArmaDisparado: cArma;\r
+      {** Método heredado, se sobreescribe porque se dibuja de forma distinta}\r
+      function mDibujar: tObjetosVoladores; override;\r
+      // SERIALIZACION\r
+      {** Devuelve una cadena de texto con el objeto serializado.}\r
+      function mSerializar: string; override;\r
+      {** Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.}\r
+      procedure mDesSerializar( str: string ); override;\r
+  end;\r
+\r
+implementation\r
+\r
+uses\r
+  RegExpr,\r
+  ObjetoPersistente,\r
+  SerializacionUtils,\r
+  Sysutils;\r
+\r
+{ cNavePropia }\r
+\r
+{** @param pos Posición Inicial\r
+    @param vel Velocidad Inicial}\r
+constructor cNavePropia.create(pos: cVector; vel: cVector);\r
+begin\r
+  if vel <> nil then // Si no es nula la velocidad ...\r
+    vel.mSetModulo( 0.17 ); // Setea la velocidad como la máxima\r
+  // La dimensión es 15 m de radio, la potencia 5, la energía 100, tiene 10 misiles comunes,\r
+  //  5 dirigidos y su velocidad maxima es 0,17 m/mseg (612 km/h)\r
+  // El retardo del laser es de .5 segundos.\r
+  inherited create( pos, vel, 15 {dim}, 5 {pot}, 100 {ene}, 10 {mis}, 5 {misdir},\r
+                    0.17 {velmax}, 50 {retlas}, 1000 {retmis}, 2500 {retmisdir} );\r
+  aArmaSelec  := OV_LASER;\r
+  aDisparando := nil;\r
+  aLockeado   := nil;\r
+  aLockFiltro := cFiltroLock.create( self {observador}, 0.8 {angulo}, 2000 {maximo} );\r
+end;\r
+\r
+{** Hace que aumente el modulo de la velocidad\r
+    @param modulo Modulo de la velocidad a sumar}\r
+procedure cNavePropia.mAcelerar(modulo: tLongitud);\r
+begin\r
+  modulo := mGetVelModulo + modulo;\r
+  if modulo <= mGetVelMax then\r
+    mSetVelModulo( modulo );\r
+end;\r
+\r
+{** Hace que disminuya el modulo de la velocidad\r
+    @param modulo Modulo de la velocidad a restar}\r
+procedure cNavePropia.mDesacelerar(modulo: tLongitud);\r
+begin\r
+  modulo := mGetVelModulo - modulo;\r
+  mSetVelModulo( modulo );\r
+end;\r
+\r
+{** Método heredado, se sobreescribe porque se dibuja de forma distinta}\r
+function cNavePropia.mDibujar: tObjetosVoladores;\r
+begin\r
+  result := OV_NAVEPROPIA;\r
+end;\r
+\r
+{** Hace que se dispare un arma\r
+    @param  ov Objetivo del disparo\r
+    @param  dT Intervalo de tiempo\r
+    @return Arma disparada (o <i>nil</i> si no se puede disparar ningún arma)}\r
+function cNavePropia.mDisparar( dT: tTiempo; ov : cObjetoVolador ): cArma;\r
+begin\r
+  result := nil;\r
+  mActualizarRetardadores( dT );\r
+  if aDisparando <> nil then begin // Si esta disparando ...\r
+    result := aDisparando; // Se devuleve el arma disparada\r
+    aDisparando := nil;    // Deja de disparar\r
+  end;\r
+end;\r
+\r
+{** Permite a la nave girar hacia abajo (sobre su eje Y)\r
+    @param angulo Ángulo a girar}\r
+procedure cNavePropia.mGirarAbajo(angulo: tAngulo);\r
+begin\r
+  mRotarEnJ( - angulo ); // Rota el sistema de coordenadas\r
+end;\r
+\r
+{** Permite a la nave girar hacia arriba (sobre su eje Y)\r
+    @param angulo Ángulo a girar}\r
+procedure cNavePropia.mGirarArriba(angulo: tAngulo);\r
+begin\r
+  mRotarEnJ( angulo ); // Rota el sistema de coordenadas\r
+end;\r
+\r
+{** Permite a la nave girar hacia la derecha (sobre su eje Z)\r
+    @param angulo Ángulo a girar}\r
+procedure cNavePropia.mGirarDerecha(angulo: tAngulo);\r
+begin\r
+  mRotarEnK( - angulo ); // Rota el sistema de coordenadas\r
+end;\r
+\r
+{** Permite a la nave girar hacia la izquierda (sobre su eje Z)\r
+    @param angulo Ángulo a girar}\r
+procedure cNavePropia.mGirarIzquierda(angulo: tAngulo);\r
+begin\r
+  mRotarEnK( angulo ); // Rota el sistema de coordenadas\r
+end;\r
+\r
+{** Permite a la nave rotar hacia la derecha (sobre su eje I)\r
+    @param angulo Ángulo a rotar}\r
+procedure cNavePropia.mRotarDerecha(angulo: tAngulo);\r
+begin\r
+  mRotarEnI( angulo ); // Rota el sistema de coordenadas\r
+end;\r
+\r
+{** Permite a la nave rotar hacia la izquierda (sobre su eje I)\r
+    @param angulo Ángulo a rotar}\r
+procedure cNavePropia.mRotarIzquierda(angulo: tAngulo);\r
+begin\r
+  mRotarEnI( - angulo ); // Rota el sistema de coordenadas\r
+end;\r
+\r
+{** Intenta disparar. Si las condiciones son las correctas, el proximo turno\r
+    saldrá el disparo, si no, no hace nada\r
+    @return Arma proximamente disparada}\r
+function cNavePropia.mIntentarDisparo: cArma;\r
+var\r
+  vel:     cVector;\r
+  ok:      boolean;\r
+begin\r
+  result := nil;\r
+  if aDisparando = nil then // Si no esta disparando se fija si puede hacerlo\r
+    case aArmaSelec of\r
+      OV_LASER: if mPuedeDispararLaser( nil ) then begin // si puede disparar...\r
+                  aDisparando := mCrearLaserDisparado;\r
+                  result := aDisparando;\r
+                end;\r
+      OV_MISIL: if mPuedeDispararMisil( nil ) then begin // si puede disparar...\r
+                  aDisparando := mCrearMisilDisparado;\r
+                  result := aDisparando;\r
+                end;\r
+      OV_MISDIR: begin\r
+                  try // Prueba si aLockeado no fue destruido...\r
+                    ok := mPuedeDispararMisDir( aLockeado );\r
+                  except\r
+                    on e: EAccessViolation do begin // Si el objetivo lockeado esta destruido...\r
+                      aLockeado := nil;                        // Lo setea a nil\r
+                      ok := mPuedeDispararMisDir( aLockeado ); // Se fija de nuevo si puede disparar\r
+                    end;\r
+                  end;\r
+                  if ok then begin  // Si puede disparar ...\r
+                    aDisparando := mCrearMisDirDisparado( aLockeado ); // Utiliza como objetivo a aLockeado\r
+                    if aLockeado = nil then begin // Si no hay ninguno lockeado se setea la direccion\r
+                      vel := mGetI;               //  de la velocidad igual que la de la nave propia.\r
+                      aDisparando.mSetVelDir( vel );\r
+                      vel.free;\r
+                    end;\r
+                    result := aDisparando;\r
+                  end;\r
+                 end;\r
+    end;\r
+end;\r
+\r
+{** Selecciona un arma determinada. Si tiene municiones, la selecciona, si no,\r
+    no hace nada.}\r
+procedure cNavePropia.mSeleccionarArma(a: tArma);\r
+begin\r
+  case a of\r
+    OV_LASER:\r
+      aArmaSelec := a;\r
+    OV_MISIL:\r
+      if mTieneMisil then\r
+        aArmaSelec := a;\r
+    OV_MISDIR:\r
+      if mTieneMisilDirigido then\r
+        aArmaSelec := a;\r
+  end;\r
+end;\r
+\r
+{** Selecciona el proximo arma con municiones}\r
+procedure cNavePropia.mSeleccionarArmaSig;\r
+begin\r
+  case aArmaSelec of\r
+    OV_LASER:\r
+      if mTieneMisil then\r
+        aArmaSelec := OV_MISIL\r
+      else if mTieneMisilDirigido then\r
+        aArmaSelec := OV_MISDIR;\r
+    OV_MISIL:\r
+      if mTieneMisilDirigido then\r
+        aArmaSelec := OV_MISDIR\r
+      else\r
+        aArmaSelec := OV_LASER;\r
+    OV_MISDIR:\r
+      aArmaSelec := OV_LASER;\r
+  end;\r
+end;\r
+\r
+{** Obtiene el arma seleccionada actualmente\r
+    @return Arma seleccionada}\r
+function cNavePropia.mGetArmaSelec: tArma;\r
+begin\r
+  result := aArmaSelec;\r
+end;\r
+\r
+{** Obtiene el objetivo lockeado\r
+    @return Objeto volador lockeado}\r
+function cNavePropia.mGetLockeado: cObjetoVolador;\r
+begin\r
+  result := aLockeado;\r
+  if aLockeado <> nil then // Si no es nil...\r
+    try // Primero se fija que no esté destruido\r
+      aLockeado.mGetID;\r
+    except\r
+      on e: EAccessViolation do begin // Si lo está...\r
+        aLockeado := nil; // Lo setea a nil\r
+        result := aLockeado;\r
+      end;\r
+    end;\r
+end;\r
+\r
+{** Setea el objetivo lockeado\r
+    @param ov Objeto volador lockeado}\r
+procedure cNavePropia.mSetLockeado(ov: cObjetoVolador);\r
+begin\r
+  aLockeado := ov;\r
+end;\r
+\r
+{** Cambia el objetivo lockeado}\r
+procedure cNavePropia.mCambiarLockeado(lEnemigos: TList);\r
+var\r
+  lFiltrados: TList;\r
+  i: integer;\r
+begin\r
+  lFiltrados := aLockFiltro.mFiltrar( lEnemigos );\r
+  if lFiltrados.Count = 0 then\r
+    aLockeado := nil\r
+  else\r
+    if aLockeado = nil then\r
+      aLockeado := lFiltrados.First // Asigna el primero\r
+    else begin\r
+      i := lFiltrados.IndexOf( aLockeado );\r
+      if i < 0 then // No esta en la lista\r
+        aLockeado := lFiltrados.First // Asigna el primero\r
+      else\r
+        if i = (lFiltrados.Count - 1) then // Es el ultimo objeto de la lista\r
+          aLockeado := lFiltrados.First // Asigna el primero\r
+        else\r
+          aLockeado := lFiltrados.Items[i+1]; // Asigna el proximo\r
+    end;\r
+  lFiltrados.free;\r
+end;\r
+\r
+{** Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    @param str Cadena de texto con el objeto serializado.}\r
+procedure cNavePropia.mDesSerializar(str: string);\r
+var\r
+  r: TRegExpr;\r
+begin\r
+  inherited mDesSerializar( str ); // SIEMPRE el ID debe ser el PRIMER atributo\r
+  r := TRegExpr.create;\r
+  // LOCKEADO\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<lockeado\s+class=([\w\d]+)\s*>\s*(.+)\s*</lockeado>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      if r.Match[1] <> '0' then // Si tiene una clase determinada...\r
+        if aLockeado <> nil then // Si no es nulo\r
+          // Puede caer en una EAccessViolation si esta destruido\r
+          aLockeado.mDesSerializar( r.Match[2] ) // Lo deserializa\r
+        else // si es nulo\r
+          aLockeado := restaurarObjeto( r.Match[1], r.Match[2] ) // lo crea segun su clase\r
+      else // Si no tiene una clase determinada, entonces se lo pone en nil\r
+        aLockeado := nil\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el objetivo lockeado' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ESerializacion do begin // Si fueron de serializacion...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al deserializar el objetivo lockeado: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el objetivo lockeado utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+    on e: EAccessViolation do begin // si el Objetivo fue destruido...\r
+      aLockeado := restaurarObjeto( r.Match[1], r.Match[2] ) // lo crea segun su clase\r
+    end;\r
+  end;\r
+  // ARMASELEC\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<armaselec>\s*(\d+)\s*</armaselec>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aArmaSelec := tArma( StrToInt( r.Match[1] ) )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el arma seleccionada' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el arma seleccionada utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // LOCKFILTRO\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<lockfiltro>\s*(.+)\s*</lockfiltro>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      if aLockFiltro <> nil then // Si no es nulo\r
+        aLockFiltro.mDesSerializar( r.Match[1] ) // Lo deserializa\r
+      else // si es nulo\r
+        aLockFiltro := cFiltroLock.crearDeSerializado( r.Match[1] ) // lo crea\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( ClassName + ': No se pudieron extraer el filtro de lockeo' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ESerializacion do begin // Si fueron de serializacion...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al deserializar el filtro de lockeo: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el filtro de lockeo utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // El observador del filtro va a ser siempre la nave propia, es por esto\r
+  //  que debemos eliminar la copia del observador que se creo y asignarle self\r
+  aLockFiltro.mGetObservador.free;\r
+  aLockFiltro.mSetObservador( self );\r
+  r.free;\r
+end;\r
+\r
+{** Devuelve una cadena de texto con el objeto serializado.\r
+    @return Cadena de texto con el objeto serializado.}\r
+function cNavePropia.mSerializar: string;\r
+var\r
+  clase,\r
+  lockeado:  string;\r
+  meteorito: cMeteorito;\r
+begin\r
+  // Si el objetivo es nil o está destruido, se setea el atributo class del\r
+  // TAG objetivo como '0' y entre el TAG se indica que es nil. Si no se\r
+  // setea como el nombre de la clase y su expresion serializada respectivamente\r
+  lockeado := 'nil';\r
+  clase    := '0';\r
+  if aLockeado <> nil then\r
+    try\r
+      lockeado := aLockeado.mSerializar;\r
+      clase    := aLockeado.ClassName;\r
+    except // Si esta destruido cambia la cadena de texto\r
+      on e: EAccessViolation do begin\r
+        lockeado := 'nil';\r
+        clase    := '0';\r
+      end;\r
+    end;\r
+  // Hoy que modificar el observador del filtro porque de otra forma esta funcion\r
+  //  se volveria infinitamente recursiva, ya que cuando quiere serializar el\r
+  //  filtro, necesita serializar el observador quien necesita serializar el\r
+  //  filtro y asi ad infinitum.\r
+  meteorito := cMeteorito.create;\r
+  aLockFiltro.mSetObservador( meteorito );\r
+  result := inherited mSerializar +\r
+            '<lockeado class=' + clase  + '>' + lockeado + '</lockeado>' +\r
+            '<armaselec>' + IntToStr( ord( aArmaSelec ) ) + '</armaselec>' +\r
+            '<lockfiltro>' + aLockFiltro.mSerializar + '</lockfiltro>';\r
+  // Se vuelve a establecer como observador a la nave propia.\r
+  aLockFiltro.mSetObservador( self );\r
+  meteorito.free;\r
+end;\r
+\r
+{** Obtiene un puntero a la último arma disparada\r
+    @return Último arma disparado}\r
+function cNavePropia.mGetUltimoArmaDisparado: cArma;\r
+begin\r
+  result := aDisparando;\r
+  if aDisparando <> nil then // Si no es nil...\r
+    try // Primero se fija que no esté destruido\r
+      aDisparando.mGetID;\r
+    except\r
+      on e: EAccessViolation do begin // Si lo está...\r
+        aDisparando := nil; // Lo setea a nil\r
+        result := aDisparando;\r
+      end;\r
+    end;\r
+end;\r
+\r
+end.\r
diff --git a/src/modelo/ov/naves/NavesEnemigas.pas b/src/modelo/ov/naves/NavesEnemigas.pas
new file mode 100644 (file)
index 0000000..6bb9b0b
--- /dev/null
@@ -0,0 +1,461 @@
+{** Distintos tipos de Naves Enemigas<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    27/11/00: Se realizan algunos cambios para adaptarse a la nueva implementacion de cNave con disparos.\r
+    01/12/00: Se cambiaron las dimensiones de la nave para que los disparos sean mas "jugables".\r
+              Se cambia el orden de los argumentos de mDisparar para aprovechar los argumentos por defecto.\r
+    </PRE>}\r
+unit NavesEnemigas;\r
+\r
+interface\r
+\r
+uses\r
+  Tipos,\r
+  Vectores,\r
+  Nave,\r
+  NaveEnemiga,\r
+  NavePropia,\r
+  ObjetoVolador,\r
+  Armas;\r
+\r
+type\r
+  {** Es una nave con misiles y lasers (igual que la propia)\r
+      que se desplaza por el epacio hasta que encuentra una nave propia para atacar.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            25        metros\r
+      Potencia:             2         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              100       Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,17      metros/milisegundos (612 km/h)\r
+      Campo de radar:       5000      metros (5 km)\r
+      Misiles:              5\r
+      Misiles Dirigidos:    2\r
+      </PRE>}\r
+  cNavePesada = class( cNaveEnemiga )\r
+    private\r
+      aCampoMinimo: tLongitud; // Distancia minima a la nave propia\r
+    public\r
+      {** Constructor}\r
+      constructor create( pos : cVector = nil; vel : cVector = nil );\r
+      {** Método heredado que hace que la nave reaccione ante la presencia\r
+          de la nave propia (en este caso la atacará con lasers y misiles)}\r
+      procedure mReaccionar( np : cNavePropia );override;\r
+      {** Método heredado, se sobreescribe porque se dibuja de forma distinta}\r
+      function mDibujar: tObjetosVoladores; override;\r
+      // SERIALIZACION\r
+      {** Devuelve una cadena de texto con el objeto serializado.}\r
+      function mSerializar: string; override;\r
+      {** Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.}\r
+      procedure mDesSerializar( str: string ); override;\r
+  end;\r
+\r
+  {** Es una nave sin misiles, solo con lasers que\r
+      se desplaza por el epacio hasta que encuentra una nave propia para atacar.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            15        metros\r
+      Potencia:             1         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              60        Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,18      metros/milisegundos (648 km/h)\r
+      Campo de radar:       3000      metros (3 km)\r
+      Misiles:              0\r
+      Misiles Dirigidos:    0\r
+      </PRE>}\r
+  cNaveLiviana = class( cNaveEnemiga )\r
+    private\r
+      aCampoMinimo: tLongitud; // Distancia minima a la nave propia\r
+    public\r
+      {** Constructor}\r
+      constructor create( pos : cVector = nil; vel : cVector = nil );\r
+      {** Método heredado que hace que la nave reaccione ante la presencia\r
+          de la nave propia (en este caso la atacará con lasers)}\r
+      procedure mReaccionar( np : cNavePropia );override;\r
+      {** Método heredado, se sobreescribe porque se dibuja de forma distinta}\r
+      function mDibujar: tObjetosVoladores; override;\r
+      // SERIALIZACION\r
+      {** Devuelve una cadena de texto con el objeto serializado.}\r
+      function mSerializar: string; override;\r
+      {** Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.}\r
+      procedure mDesSerializar( str: string ); override;\r
+  end;\r
+\r
+  {** Es una nave sin armas que se desplaza por el epacio\r
+      hasta que encuentra una nave propia, en ese momento empieza a huir avisando a\r
+      las demas naves enemigas la ultima posicion de la nave propia.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            10        metros\r
+      Potencia:             1         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              30        Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,2       metros/milisegundos (720 km/h)\r
+      Campo de radar:       2000      metros (2 km)\r
+      Misiles:              0\r
+      Misiles Dirigidos:    0\r
+      </PRE>}\r
+  cNaveEspia = class( cNaveEnemiga )\r
+    private\r
+      aPosicionEnemiga: cVector; // Indica la posicion de la nave propia. Si todavía no\r
+                                 //  la encontró, su valor es nil\r
+    protected\r
+      {** Método heredado se modifica porque su forma de modificar la velocidad es diferente al\r
+          resto de las naves enemigas}\r
+      procedure mModificarVelocidad( np: cNavePropia; modulo: tLongitud = -1 ); override;\r
+    public\r
+      {** Constructor }\r
+      constructor create( pos : cVector = nil; vel : cVector = nil );\r
+      {** Método que indica si está avisando }\r
+      function mAvisando: boolean;\r
+      {** Método que devuelve la última posición en dónde vió a la nave propia (si está avisando)}\r
+      function mGetPosicionEnemiga: cVector;\r
+      {** Método heredado que hace que la nave reaccione ante la presencia\r
+          de la nave propia (en este caso huirá y empezará a avisar al resto de las naves que encuentre\r
+          sobre la última posición de la nave propia)}\r
+      procedure mReaccionar( np : cNavePropia );override;\r
+      {** Destructor}\r
+      destructor destroy; override;\r
+      {** Método heredado, se sobreescribe porque esta nave en particular no puede disparar}\r
+      function mDisparar( dT: tTiempo; ov : cObjetoVolador = nil ): cArma; override;\r
+      {** Método heredado, se sobreescribe porque se dibuja de forma distinta}\r
+      function mDibujar: tObjetosVoladores; override;\r
+      // SERIALIZACION\r
+      {** Devuelve una cadena de texto con el objeto serializado.}\r
+      function mSerializar: string; override;\r
+      {** Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.}\r
+      procedure mDesSerializar( str: string ); override;\r
+  end;\r
+\r
+  {** Es una nave sin armas que se desplaza por el epacio\r
+      hasta que encuentra una nave propia y trata de chocarla.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            10        metros\r
+      Potencia:             4         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              30        Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,2       metros/milisegundos (720 km/h)\r
+      Campo de radar:       2500      metros (2,5 km)\r
+      Misiles:              0\r
+      Misiles Dirigidos:    0\r
+      </PRE>}\r
+  cNaveSuicida = class( cNaveEnemiga )\r
+    public\r
+      {** Constructor}\r
+      constructor create( pos : cVector = nil; vel : cVector = nil );\r
+      {** Método heredado que hace que la nave reaccione ante la presencia\r
+          de la nave propia (en este caso tratará de chocarla)}\r
+      procedure mReaccionar( np : cNavePropia );override;\r
+      {** Método heredado, se sobreescribe porque esta nave en particular no puede disparar}\r
+      function mDisparar( dT: tTiempo; ov : cObjetoVolador = nil ): cArma; override;\r
+      {** Método heredado, se sobreescribe porque se dibuja de forma distinta}\r
+      function mDibujar: tObjetosVoladores; override;\r
+  end;\r
+\r
+implementation\r
+\r
+uses\r
+  RegExpr,\r
+  ObjetoPersistente,\r
+  Sysutils;\r
+\r
+{ cNavePesada }\r
+\r
+{** Crea una instancia de una nave pesada.\r
+    @param pos Vector posición\r
+    @param vel Vector velocidad}\r
+constructor cNavePesada.create(pos, vel: cVector);\r
+begin\r
+  // La dimensión es 5 m de radio, la potencia 2, la energía 100, tiene 5 misiles comunes,\r
+  //  2 dirigidos, su velocidad maxima es 0,17 m/mseg (612 km/h) y su Campo de radar 5 km\r
+  inherited create( pos, vel, 25 {dim}, 2 {pot}, 100 {ene}, 5 {mis}, 2 {misdir},\r
+                    0.17 {velmax}, 5000 {rad});\r
+  aCampoMinimo := 500;\r
+end;\r
+\r
+function cNavePesada.mDibujar: tObjetosVoladores;\r
+begin\r
+  result := OV_NAVEPESADA;\r
+end;\r
+\r
+{** Método heredado que hace que la nave reaccione ante la presencia\r
+    de la nave propia cerca (en este caso la atacará con lasers y misiles)\r
+    @param np Nave Propia con la cual esta reaccionando}\r
+procedure cNavePesada.mReaccionar(np: cNavePropia);\r
+var\r
+  modulo: tLongitud;\r
+begin\r
+  modulo := mGetVelMax; // nuevo modulo de la velocidad igual a la velocidad maxima\r
+  if mGetDistancia( np ) < aCampoMinimo then // si esta cerca de la nave propia...\r
+    if np.mGetVelModulo < mGetVelMax then // si la vel de la nave propia es menor a la maxima\r
+      modulo := np.mGetVelModulo; // nuevo modulo de la velocidad igual al de la nave propia\r
+  mModificarVelocidad( np, modulo ); // cambiar la velocidad segun la nave propia y el nuevo modulo\r
+end;\r
+\r
+{** Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    @param str Cadena de texto con el objeto serializado.}\r
+procedure cNavePesada.mDesSerializar(str: string);\r
+var\r
+  r: TRegExpr;\r
+begin\r
+  inherited mDesSerializar( str ); // SIEMPRE el ID debe ser el PRIMER atributo\r
+  r := TRegExpr.create;\r
+  // CAMPORADAR\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<campominimo>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</campominimo>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aCampoMinimo := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el campo minimo' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el campo minimo utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  r.free;\r
+end;\r
+\r
+{** Devuelve una cadena de texto con el objeto serializado.\r
+    @return Cadena de texto con el objeto serializado.}\r
+function cNavePesada.mSerializar: string;\r
+begin\r
+  result := inherited mSerializar +\r
+            '<campominimo>' + FloatToStrF( aCampoMinimo, ffGeneral, 18, 0 ) + '</campominimo>';\r
+end;\r
+\r
+{ cNaveLiviana }\r
+\r
+{** Crea una instancia de una nave liviana.\r
+    @param pos Vector posición\r
+    @param vel Vector velocidad}\r
+constructor cNaveLiviana.create(pos, vel: cVector);\r
+begin\r
+  // La dimensión es 3 m de radio, la potencia 1, la energía 60, no tiene misiles comunes\r
+  //  ni dirigidos, su velocidad maxima es 0,18 m/mseg (648 km/h) y su Campo de radar 3 km\r
+  // El retardo del laser es de .5 segundos, el del misil de 2 segundos y el del misil\r
+  //  dirigido de 5 segundos.\r
+  inherited create( pos, vel, 15 {dim}, 1 {pot}, 60 {ene}, 0 {mis}, 0 {misdir},\r
+                    0.18 {velmax}, 3000 {rad}, 500 {retlaser});\r
+  aCampoMinimo := 250;\r
+end;\r
+\r
+{** Hace que se dispare un arma (todavía no está implementado)}\r
+function cNaveLiviana.mDibujar: tObjetosVoladores;\r
+begin\r
+  result := OV_NAVELIVIANA;\r
+end;\r
+\r
+{** Método heredado que hace que la nave reaccione ante la presencia\r
+    de la nave propia (en este caso la atacará con lasers)\r
+    @param np Nave Propia con la cual esta reaccionando}\r
+procedure cNaveLiviana.mReaccionar(np: cNavePropia);\r
+var\r
+  modulo: tLongitud;\r
+begin\r
+  modulo := mGetVelMax; // nuevo modulo de la velocidad igual a la velocidad maxima\r
+  if mGetDistancia( np ) < aCampoMinimo then // si esta cerca de la nave propia...\r
+    if np.mGetVelModulo < mGetVelMax then // si la vel de la nave propia es menor a la maxima\r
+      modulo := np.mGetVelModulo; // nuevo modulo de la velocidad igual al de la nave propia\r
+  mModificarVelocidad( np, modulo ); // cambiar la velocidad segun la nave propia y el nuevo modulo\r
+end;\r
+\r
+{** Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    @param str Cadena de texto con el objeto serializado.}\r
+procedure cNaveLiviana.mDesSerializar(str: string);\r
+var\r
+  r: TRegExpr;\r
+begin\r
+  inherited mDesSerializar( str ); // SIEMPRE el ID debe ser el PRIMER atributo\r
+  r := TRegExpr.create;\r
+  // CAMPORADAR\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<campominimo>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</campominimo>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aCampoMinimo := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el campo minimo' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el campo minimo utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  r.free;\r
+end;\r
+\r
+{** Devuelve una cadena de texto con el objeto serializado.\r
+    @return Cadena de texto con el objeto serializado.}\r
+function cNaveLiviana.mSerializar: string;\r
+begin\r
+  result := inherited mSerializar +\r
+            '<campominimo>' + FloatToStrF( aCampoMinimo, ffGeneral, 18, 0 ) + '</campominimo>';\r
+end;\r
+\r
+{ cNaveEspia }\r
+\r
+{** Crea una instancia de una nave espía.\r
+    @param pos Vector posición\r
+    @param vel Vector velocidad}\r
+constructor cNaveEspia.create(pos, vel: cVector);\r
+begin\r
+  // La dimensión es 2 m de radio, la potencia 1, la energía 30, no tiene misiles comunes\r
+  //  ni dirigidos, su velocidad maxima es 0,2 m/mseg (720 km/h) y su Campo de radar 3 km\r
+  inherited create( pos, vel, 10 {dim}, 1 {pot}, 30 {ene}, 0 {mis}, 0 {misdir},\r
+                    0.2 {velmax}, 2000 {rad} );\r
+  aPosicionEnemiga := nil;\r
+end;\r
+\r
+{** Destructor}\r
+destructor cNaveEspia.destroy;\r
+begin\r
+  aPosicionEnemiga.free;\r
+  inherited;\r
+end;\r
+\r
+{** Hace que se dispare un arma\r
+    @param  ov Objetivo del disparo\r
+    @return Arma disparada (o <i>nil</i> si no se puede disparar ningún arma)}\r
+function cNaveEspia.mDisparar( dT: tTiempo; ov : cObjetoVolador ): cArma;\r
+begin\r
+  result := nil; // No puede disparar nada (nunca!)\r
+end;\r
+\r
+{** Método que indica si está avisando\r
+    @return <i>true</i> si está avisando, <i>false</i> si no lo está}\r
+function cNaveEspia.mAvisando: boolean;\r
+begin\r
+  result := ( aPosicionEnemiga <> nil ); // True si la posicion no es nil\r
+end;\r
+\r
+{** Método que devuelve la última posición en dónde vió a la nave propia (si está avisando)\r
+    @return Última posición donde detectó a la nave propia (<i>nil</i> si no la detecto nunca)}\r
+function cNaveEspia.mDibujar: tObjetosVoladores;\r
+begin\r
+  result := OV_NAVEESPIA;\r
+end;\r
+\r
+function cNaveEspia.mGetPosicionEnemiga: cVector;\r
+begin\r
+  result := cVector.create( aPosicionEnemiga );\r
+end;\r
+\r
+{** Modifica la velocidad de la nave en base a la nave propia.\r
+    @param np     Nave propia con la cual se calculará la dirección de la nueva velocidad\r
+    @param modulo Nuevo módulo de la velocidad}\r
+procedure cNaveEspia.mModificarVelocidad(np: cNavePropia; modulo: tLongitud);\r
+var\r
+  pos,          // Vector temporal\r
+  vel: cVector; // Vector temporal\r
+begin\r
+  pos := np.mGetPosicion;\r
+  vel := mGetPosicion.mRestar( pos ); // Crea un vector igual a su posicion\r
+                                      // Le resta la posicion de la nave propia\r
+  mSetVelModulo( mGetVelMax );        // Setea el modulo al maximo\r
+  mSetVelDir( vel );                  // Copia el vector a su velocidad\r
+  vel.free;                           // Libera el vector temporal\r
+  pos.free;                           // Libera el vector temporal\r
+end;\r
+\r
+{** Método heredado que hace que la nave reaccione ante la presencia\r
+    de la nave propia (en este caso huirá y empezará a avisar al resto de las naves que encuentre\r
+    sobre la última posición de la nave propia)\r
+    @param np Nave Propia con la cual esta reaccionando}\r
+procedure cNaveEspia.mReaccionar(np: cNavePropia);\r
+begin\r
+  mModificarVelocidad( np );\r
+  // Si ya tiene una posición, la modifica, si no crea una nueva\r
+  if aPosicionEnemiga <> nil then\r
+    aPosicionEnemiga.free;\r
+  aPosicionEnemiga := np.mGetPosicion;\r
+end;\r
+\r
+{** Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    @param str Cadena de texto con el objeto serializado.}\r
+procedure cNaveEspia.mDesSerializar(str: string);\r
+var\r
+  r: TRegExpr;\r
+begin\r
+  inherited mDesSerializar( str ); // SIEMPRE el ID debe ser el PRIMER atributo\r
+  r := TRegExpr.create;\r
+  // POSICIONENEMIGA\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<posicionenemiga>\s*(.+)\s*</posicionenemiga>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      if r.Match[1] = 'nil' then begin // Si la posicion enemiga recuperada es nil...\r
+        aPosicionEnemiga.free;   // Libera la posicion actual\r
+        aPosicionEnemiga := nil; // y la pone en nil\r
+      end else // si es otra cosa, la interpreta\r
+        if aPosicionEnemiga <> nil then // Si no es nulo\r
+          aPosicionEnemiga.mDesSerializar( r.Match[1] ) // Lo deserializa\r
+        else // si es nulo\r
+          aPosicionEnemiga := cVector.crearDeSerializado( r.Match[1] ) // lo crea\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro la posicion enemiga' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ESerializacion do begin // Si fueron de serializacion...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al deserializar la posicion enemiga: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer la posicion enemiga utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  r.free;\r
+end;\r
+\r
+{** Devuelve una cadena de texto con el objeto serializado.\r
+    @return Cadena de texto con el objeto serializado.}\r
+function cNaveEspia.mSerializar: string;\r
+var\r
+  posene: string;\r
+begin\r
+  // Si el objetivo es nil o está destruido, se setea el atributo class del\r
+  // TAG objetivo como '0' y entre el TAG se indica que es nil. Si no se\r
+  // setea como el nombre de la clase y su expresion serializada respectivamente\r
+  posene := 'nil';\r
+  if aPosicionEnemiga <> nil then\r
+    posene := aPosicionEnemiga.mSerializar;\r
+  result := inherited mSerializar +\r
+            '<posicionenemiga>' + posene + '</posicionenemiga>';\r
+end;\r
+\r
+{ cNaveSuicida }\r
+\r
+{** Crea una instancia de una nave suicida.\r
+    @param pos Vector posición\r
+    @param vel Vector velocidad}\r
+constructor cNaveSuicida.create(pos, vel: cVector);\r
+begin\r
+  // La dimensión es 2 m de radio, la potencia 4, la energía 30, no tiene misiles comunes\r
+  //  ni dirigidos, su velocidad maxima es 0,2 m/mseg (720 km/h) y su Campo de radar 1 km\r
+  inherited create( pos, vel, 10 {dim}, 4 {pot}, 30 {ene}, 0 {mis}, 0 {misdir},\r
+                    0.2 {velmax}, 2500 {rad});\r
+end;\r
+\r
+{** Método heredado que hace que la nave reaccione ante la presencia\r
+    de la nave propia (en este caso tratará de chocarla)\r
+    @param np Nave Propia con la cual esta reaccionando}\r
+function cNaveSuicida.mDibujar: tObjetosVoladores;\r
+begin\r
+  result := OV_NAVESUICIDA;\r
+end;\r
+\r
+procedure cNaveSuicida.mReaccionar(np: cNavePropia);\r
+begin\r
+  mModificarVelocidad( np );\r
+end;\r
+\r
+{** Hace que se dispare un arma\r
+    @param  ov Objetivo del disparo\r
+    @return Arma disparada (o <i>nil</i> si no se puede disparar ningún arma)}\r
+function cNaveSuicida.mDisparar( dT: tTiempo; ov : cObjetoVolador ): cArma;\r
+begin\r
+  result := nil; // No puede disparar nada (nunca!)\r
+end;\r
+\r
+end.\r
diff --git a/src/test/AlgoWars.test_camara+espacio+form.dpr b/src/test/AlgoWars.test_camara+espacio+form.dpr
new file mode 100644 (file)
index 0000000..ea82ec4
--- /dev/null
@@ -0,0 +1,33 @@
+program AlgoWars;\r
+\r
+uses\r
+  Forms,\r
+  Vectores in 'Vectores.pas',\r
+  Coordenadas in 'Coordenadas.pas',\r
+  Espacio in 'Espacio.pas',\r
+  Objeto in 'Objeto.pas',\r
+  Tipos in 'Tipos.pas',\r
+  Camara in 'Camara.pas',\r
+  FormMain in 'forms\FormMain.pas' {MainForm},\r
+  FormConfig in 'forms\FormConfig.pas' {ConfigForm},\r
+  ObjetoVolador in 'ov\ObjetoVolador.pas',\r
+  Meteorito in 'ov\Meteorito.pas',\r
+  Armas in 'ov\Armas.pas',\r
+  Nave in 'ov\naves\Nave.pas',\r
+  NaveEnemiga in 'ov\naves\NaveEnemiga.pas',\r
+  NavePropia in 'ov\naves\NavePropia.pas',\r
+  NavesEnemigas in 'ov\naves\NavesEnemigas.pas',\r
+  RegExpr in 'RegExpr.pas',\r
+  vista in 'vista.pas';\r
+\r
+{$R *.RES}\r
+\r
+begin\r
+  randomize; // Cambia la semilla del generador de numeros aleatorios\r
+\r
+  Application.Initialize;\r
+  Application.Title := 'AlgoWars - Episodio IV';\r
+  Application.CreateForm(TMainForm, MainForm);\r
+  Application.CreateForm(TConfigForm, ConfigForm);\r
+  Application.Run;\r
+end.\r
diff --git a/src/test/AlgoWars.test_camara+espacio.dpr b/src/test/AlgoWars.test_camara+espacio.dpr
new file mode 100644 (file)
index 0000000..e00ad05
--- /dev/null
@@ -0,0 +1,88 @@
+program AlgoWars;\r
+{$APPTYPE CONSOLE}\r
+{%ToDo 'AlgoWars.todo'}\r
+\r
+uses\r
+  SysUtils,\r
+  Vectores in 'Vectores.pas',\r
+  Objeto in 'Objeto.pas',\r
+  Tipos in 'Tipos.pas',\r
+  Espacio in 'Espacio.pas',\r
+  Coordenadas in 'Coordenadas.pas',\r
+  Meteorito in 'ov\Meteorito.pas',\r
+  ObjetoVolador in 'ov\ObjetoVolador.pas',\r
+  Armas in 'ov\Armas.pas',\r
+  Nave in 'ov\naves\Nave.pas',\r
+  NavePropia in 'ov\naves\NavePropia.pas',\r
+  NaveEnemiga in 'ov\naves\NaveEnemiga.pas',\r
+  NavesEnemigas in 'ov\naves\NavesEnemigas.pas',\r
+  Camara in 'Camara.pas';\r
+\r
+var\r
+  oEspacio:    cEspacio;\r
+  oNavePropia: cNavePropia;\r
+  oCamNP,\r
+  oCamM,\r
+  oCamMD:     cCamara;\r
+  oL:          cLaser;\r
+  oM:           cMisil;\r
+  oMD:          cMisilDirigido;\r
+  oLista:       cLista;\r
+  proy:         tPProy;\r
+  i,\r
+  j: integer; // Contador\r
+  f: text; // Archivo de texto en el que se almacena la informacion.\r
+\r
+begin\r
+  randomize; // Cambia la semilla del generador de numeros aleatorios\r
+\r
+  oEspacio := cEspacio.create;\r
+  oNavePropia := oEspacio.mGetNavePropia;\r
+  oMD := cMisilDirigido.create( oNavePropia, cVector.create( 30, -15, -50 ) );\r
+  oM  := cMisil.create( cVector.create( 170, 0, 0 ), cVector.create( -1, 0, 0 ) );\r
+  oL := cLaser.create( cVector.create( 30, 0, 0 ), cVector.create( -1, 0, 0 ) );\r
+  oCamM := cCamara.create( oM );\r
+  oCamMD := cCamara.create( oMD );\r
+  oCamNP := cCamara.create( oNavePropia );\r
+\r
+  oEspacio.mAgregarObjeto( oMD );\r
+  oEspacio.mAgregarObjeto( cMisilDirigido.create( oNavePropia, cVector.create( -15, 40, 50 ) ) );\r
+  oEspacio.mAgregarObjeto( oL );\r
+  oEspacio.mAgregarObjeto( cLaser.create( cVector.create( 50, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cLaser.create( cVector.create( 100, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cLaser.create( cVector.create( 130, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cLaser.create( cVector.create( 160, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cMisil.create( cVector.create( 40, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( oM );\r
+\r
+  // Inicializa el archivo de texto\r
+  assignFile( f, 'dump.txt' );\r
+  rewrite( f );\r
+  // Imprime la informacion del estado del espacio en este instante\r
+  write( f, oEspacio.mGetDebugInfo( DI_MAXI ) );\r
+  write( f,  #13 + #10 + '====================>  0  <======================' + #13 + #10 );\r
+  // Hace que corra el tiempo en el espacio 100 * aDeltaT segundos.\r
+  for i := 1 to 100 do begin\r
+    oEspacio.mActualizar;  // Actualiza el Espacio\r
+    // Verifica que la nave propia siga viva\r
+    if oEspacio.mNavePropiaDestruida then begin // No esta en la lista...\r
+      writeln( f, 'GAME OVER!!!!' );\r
+      break; // Si se quita este break se continua con el vuleco de informacion de los instantes posteriores a la\r
+             //  destruccion de la nave propia\r
+    end;\r
+    // Imprime la informacion del estado del espacio en este instante\r
+    writeln( f, oEspacio.mGetDebugInfo( DI_NORMAL ) );\r
+    // Imprime la data de la camara\r
+    oLista := oCamNP.mProcesar( oEspacio.mGetObjetos );\r
+    for j := 0 to oLista.Count - 1 do begin  // recorre la lista\r
+      proy := tPProy( oLista.Items[j] ); // Castea el puntero\r
+      writeln( f, proy^.oOV.ClassName, ': ', proy^.oOV.mGetDebugInfo + ', ',\r
+                  proy^.x:10:4, ', ', proy^.y:10:4, ', ', proy^.tam:10:4 );\r
+    end;\r
+    oLista.free;\r
+    write( f,  #13 + #10 + '====================>  ' + IntToStr( i ) + '  <======================' + #13 + #10 );\r
+  end;\r
+  // Cierra el archivo\r
+  close( f );\r
+\r
+end.\r
diff --git a/src/test/AlgoWars.test_camara.dpr b/src/test/AlgoWars.test_camara.dpr
new file mode 100644 (file)
index 0000000..b352d95
--- /dev/null
@@ -0,0 +1,44 @@
+program AlgoWars;\r
+{$APPTYPE CONSOLE}\r
+{%ToDo 'AlgoWars.todo'}\r
+\r
+uses\r
+  SysUtils,\r
+  Vectores in 'Vectores.pas',\r
+  Objeto in 'Objeto.pas',\r
+  Tipos in 'Tipos.pas',\r
+  Espacio in 'Espacio.pas',\r
+  Coordenadas in 'Coordenadas.pas',\r
+  Meteorito in 'ov\Meteorito.pas',\r
+  ObjetoVolador in 'ov\ObjetoVolador.pas',\r
+  Armas in 'ov\Armas.pas',\r
+  Nave in 'ov\naves\Nave.pas',\r
+  NavePropia in 'ov\naves\NavePropia.pas',\r
+  NaveEnemiga in 'ov\naves\NaveEnemiga.pas',\r
+  NavesEnemigas in 'ov\naves\NavesEnemigas.pas',\r
+  Camara in 'Camara.pas';\r
+\r
+var\r
+  oCamara:     cCamara;\r
+  oLaser:      cLaser;\r
+  oOV:         cObjetoVolador;\r
+  x,\r
+  y,\r
+  dist:        tLongitud;\r
+\r
+begin\r
+  oOV := cObjetoVolador.create;\r
+  // Se cambio a un objeto volador cualquier en vez de la nave propia\r
+  oCamara := cCamara.create( oOV );\r
+  oLaser := cLaser.create( cVector.create( 3000, 5, 5 ), cVector.create( -1, 1, 0 ) );\r
+  // El problema que tenia es que usaba de cameraman a la NavePropia y cuando termina de ejecutarse\r
+  //  oEspacio.mIniciar, la nave propia esta destruida por lo que da un error de ejecucion.\r
+  writeln( 'Camara: ' + oCamara.mGetDebugInfo( DI_MAXI ) );\r
+  writeln( 'Laser: ' + oLaser.mGetDebugInfo );\r
+  if oCamara.mVisible( oLaser ) then\r
+    writeln( 'visible' )\r
+  else\r
+    writeln( 'invisible' );\r
+  oCamara.mProyectar( oLaser, x, y, dist );\r
+  writeln( 'x: ', x: 10: 5, ' | y: ', y: 10: 5, ' | dist: ', dist: 10: 5 );\r
+end.\r
diff --git a/src/test/AlgoWars.test_coordenadas.dpr b/src/test/AlgoWars.test_coordenadas.dpr
new file mode 100644 (file)
index 0000000..6f72084
--- /dev/null
@@ -0,0 +1,60 @@
+program AlgoWars;\r
+{$APPTYPE CONSOLE}\r
+{%ToDo 'AlgoWars.todo'}\r
+\r
+uses\r
+  SysUtils,\r
+  ObjetoVolador in 'ObjetoVolador.pas',\r
+  Vectores in 'Vectores.pas',\r
+  Objeto in 'Objeto.pas',\r
+  Tipos in 'Tipos.pas',\r
+  Meteorito in 'Meteorito.pas',\r
+  Armas in 'Armas.pas',\r
+  Nave in 'Nave.pas',\r
+  Espacio in 'Espacio.pas',\r
+  NaveEnemiga in 'NaveEnemiga.pas',\r
+  NavePropia in 'NavePropia.pas',\r
+  Coordenadas in 'Coordenadas.pas';\r
+\r
+var\r
+  c: cCoordenadas;\r
+  i,\r
+  j,\r
+  k: cVector;\r
+  fo:  text;\r
+\r
+begin\r
+  assignFile( fo, 'log.txt' );\r
+  rewrite( fo );\r
+  c := cCoordenadas.create;\r
+  writeln( fo, c.mGetDebugInfo( DI_MAXI ) );\r
+  c.mRotarEnI( pi/4 );\r
+  writeln( fo, 'Rotado PI/4 en i:' + #13 + #10 + c.mGetDebugInfo( DI_MAXI ) + #13 + #10  );\r
+  c.free;\r
+  c := cCoordenadas.create;\r
+  c.mRotarEnJ( -pi/4 );\r
+  writeln( fo, 'Rotado -PI/4 en j:' + #13 + #10 + c.mGetDebugInfo( DI_MAXI ) + #13 + #10  );\r
+  c.free;\r
+  c := cCoordenadas.create;\r
+  c.mRotarEnK( pi/8 );\r
+  writeln( fo, 'Rotado PI/8 en k:' + #13 + #10 + c.mGetDebugInfo( DI_MAXI ) + #13 + #10  );\r
+  c.mRotarEnI( pi/4 );\r
+  writeln( fo, ' - Rotado PI/4 en i:' + #13 + #10 + c.mGetDebugInfo( DI_MAXI ) + #13 + #10  );\r
+  c.mRotarEnJ( -pi/4 );\r
+  writeln( fo, ' - Rotado -PI/4 en j:' + #13 + #10 + c.mGetDebugInfo( DI_MAXI ) + #13 + #10  );\r
+{\r
+  writeln( fo, 'Producto Escalar entre i y j: ', c.aI.mMultiplicarEsc( c.aJ ) );\r
+  writeln( fo, 'Producto Escalar entre j y k: ', c.aJ.mMultiplicarEsc( c.aK ) );\r
+  writeln( fo, 'Producto Escalar entre k y i: ', c.aK.mMultiplicarEsc( c.aI ) );\r
+}\r
+  // Se vuelve al principio por otro camino\r
+  c.mRotarEnJ( pi/4 );\r
+  writeln( fo, ' - Rotado PI/4 en j:' + #13 + #10 + c.mGetDebugInfo( DI_MAXI ) + #13 + #10  );\r
+  c.mRotarEnI( -pi/4 );\r
+  writeln( fo, ' - Rotado -PI/4 en i:' + #13 + #10 + c.mGetDebugInfo( DI_MAXI ) + #13 + #10  );\r
+  c.mRotarEnK( -pi/8 );\r
+  writeln( fo, ' - Rotado -PI/8 en k:' + #13 + #10 + c.mGetDebugInfo( DI_MAXI ) + #13 + #10  );\r
+\r
+  c.free;\r
+  close( fo );\r
+end.\r
diff --git a/src/test/AlgoWars.test_coordenadas2.dpr b/src/test/AlgoWars.test_coordenadas2.dpr
new file mode 100644 (file)
index 0000000..fab4fd0
--- /dev/null
@@ -0,0 +1,154 @@
+program AlgoWars;\r
+{$APPTYPE CONSOLE}\r
+{%ToDo 'AlgoWars.todo'}\r
+\r
+uses\r
+  SysUtils,\r
+  Vectores in 'Vectores.pas',\r
+  Objeto in 'Objeto.pas',\r
+  Tipos in 'Tipos.pas',\r
+  Espacio in 'Espacio.pas',\r
+  Coordenadas in 'Coordenadas.pas',\r
+  Meteorito in 'ov\Meteorito.pas',\r
+  ObjetoVolador in 'ov\ObjetoVolador.pas',\r
+  Armas in 'ov\Armas.pas',\r
+  Nave in 'ov\naves\Nave.pas',\r
+  NavePropia in 'ov\naves\NavePropia.pas',\r
+  NaveEnemiga in 'ov\naves\NaveEnemiga.pas',\r
+  NavesEnemigas in 'ov\naves\NavesEnemigas.pas',\r
+  Camara in 'Camara.pas';\r
+\r
+var\r
+  oCoord: cCoordenadas;\r
+  v:      cVector;\r
+\r
+begin\r
+  oCoord := cCoordenadas.create;\r
+  v := cVector.create( 0, 1, 0 );\r
+  oCoord.mSetI( v );\r
+  writeln( 'Nuevo i: ' );\r
+  writeln( v.mGetDebugInfo );\r
+  v.free;\r
+  writeln( 'Coordenadas: ' );\r
+  writeln( oCoord.mGetDebugInfo );\r
+  //////////////////////////////////\r
+  v := cVector.create( 1, 1, 1 );\r
+  oCoord.mSetI( v );\r
+  writeln( 'Nuevo i: ' );\r
+  writeln( v.mGetDebugInfo );\r
+  v.free;\r
+  writeln( 'Coordenadas: ' );\r
+  writeln( oCoord.mGetDebugInfo );\r
+  //////////////////////////////////\r
+  v := cVector.create( 0, 1, 1 );\r
+  oCoord.mSetI( v );\r
+  writeln( 'Nuevo i: ' );\r
+  writeln( v.mGetDebugInfo );\r
+  v.free;\r
+  writeln( 'Coordenadas: ' );\r
+  writeln( oCoord.mGetDebugInfo );\r
+  //////////////////////////////////\r
+  v := cVector.create( 0, 5, 1 );\r
+  oCoord.mSetI( v );\r
+  writeln( 'Nuevo i: ' );\r
+  writeln( v.mGetDebugInfo );\r
+  v.free;\r
+  writeln( 'Coordenadas: ' );\r
+  writeln( oCoord.mGetDebugInfo );\r
+  //////////////////////////////////\r
+  v := cVector.create( -1, 1, -1 );\r
+  oCoord.mSetI( v );\r
+  writeln( 'Nuevo i: ' );\r
+  writeln( v.mGetDebugInfo );\r
+  v.free;\r
+  writeln( 'Coordenadas: ' );\r
+  writeln( oCoord.mGetDebugInfo );\r
+  //////////////////////////////////\r
+  v := cVector.create( 1, 0, 0 );\r
+  oCoord.mSetI( v );\r
+  writeln( 'Nuevo i: ' );\r
+  writeln( v.mGetDebugInfo );\r
+  v.free;\r
+  writeln( 'Coordenadas: ' );\r
+  writeln( oCoord.mGetDebugInfo );\r
+  //////////////////////////////////\r
+  v := cVector.create( 0, 1, 0 );\r
+  oCoord.mSetJ( v );\r
+  writeln( 'Nuevo j: ' );\r
+  writeln( v.mGetDebugInfo );\r
+  v.free;\r
+  writeln( 'Coordenadas: ' );\r
+  writeln( oCoord.mGetDebugInfo );\r
+  //////////////////////////////////\r
+  v := cVector.create( -1, -1, 1 );\r
+  oCoord.mSetJ( v );\r
+  writeln( 'Nuevo j: ' );\r
+  writeln( v.mGetDebugInfo );\r
+  v.free;\r
+  writeln( 'Coordenadas: ' );\r
+  writeln( oCoord.mGetDebugInfo );\r
+  //////////////////////////////////\r
+  v := cVector.create( 1, 1, 2 );\r
+  oCoord.mSetJ( v );\r
+  writeln( 'Nuevo j: ' );\r
+  writeln( v.mGetDebugInfo );\r
+  v.free;\r
+  writeln( 'Coordenadas: ' );\r
+  writeln( oCoord.mGetDebugInfo );\r
+  //////////////////////////////////\r
+  v := cVector.create( 0, 1, 0 );\r
+  oCoord.mSetJ( v );\r
+  writeln( 'Nuevo j: ' );\r
+  writeln( v.mGetDebugInfo );\r
+  v.free;\r
+  writeln( 'Coordenadas: ' );\r
+  writeln( oCoord.mGetDebugInfo );\r
+  //////////////////////////////////\r
+  v := cVector.create( 0, 0, 1 );\r
+  oCoord.mSetK( v );\r
+  writeln( 'Nuevo k: ' );\r
+  writeln( v.mGetDebugInfo );\r
+  v.free;\r
+  writeln( 'Coordenadas: ' );\r
+  writeln( oCoord.mGetDebugInfo );\r
+  //////////////////////////////////\r
+  v := cVector.create( 1, 2, 0 );\r
+  oCoord.mSetK( v );\r
+  writeln( 'Nuevo k: ' );\r
+  writeln( v.mGetDebugInfo );\r
+  v.free;\r
+  writeln( 'Coordenadas: ' );\r
+  writeln( oCoord.mGetDebugInfo );\r
+  //////////////////////////////////\r
+  v := cVector.create( 2, -2, -1 );\r
+  oCoord.mSetK( v );\r
+  writeln( 'Nuevo k: ' );\r
+  writeln( v.mGetDebugInfo );\r
+  v.free;\r
+  writeln( 'Coordenadas: ' );\r
+  writeln( oCoord.mGetDebugInfo );\r
+  //////////////////////////////////\r
+  v := cVector.create( -1, 2, 1 );\r
+  oCoord.mSetK( v );\r
+  writeln( 'Nuevo k: ' );\r
+  writeln( v.mGetDebugInfo );\r
+  v.free;\r
+  writeln( 'Coordenadas: ' );\r
+  writeln( oCoord.mGetDebugInfo );\r
+  //////////////////////////////////\r
+  v := cVector.create( 0, 0, 1 );\r
+  oCoord.mSetK( v );\r
+  writeln( 'Nuevo k: ' );\r
+  writeln( v.mGetDebugInfo );\r
+  v.free;\r
+  writeln( 'Coordenadas: ' );\r
+  writeln( oCoord.mGetDebugInfo );\r
+  //////////////////////////////////\r
+  v := cVector.create( 1, 0, 0 );\r
+  oCoord.mSetI( v );\r
+  writeln( 'Nuevo i: ' );\r
+  writeln( v.mGetDebugInfo );\r
+  v.free;\r
+  writeln( 'Coordenadas: ' );\r
+  writeln( oCoord.mGetDebugInfo );\r
+end.\r
diff --git a/src/test/AlgoWars.test_espacio.dpr b/src/test/AlgoWars.test_espacio.dpr
new file mode 100644 (file)
index 0000000..5d7df17
--- /dev/null
@@ -0,0 +1,36 @@
+program AlgoWars;\r
+{$APPTYPE CONSOLE}\r
+{%ToDo 'AlgoWars.todo'}\r
+\r
+uses\r
+  SysUtils,\r
+  ObjetoVolador in 'ObjetoVolador.pas',\r
+  Vectores in 'Vectores.pas',\r
+  Objeto in 'Objeto.pas',\r
+  Tipos in 'Tipos.pas',\r
+  Meteorito in 'Meteorito.pas',\r
+  Armas in 'Armas.pas',\r
+  Nave in 'Nave.pas',\r
+  Espacio in 'Espacio.pas',\r
+  NaveEnemiga in 'NaveEnemiga.pas',\r
+  NavePropia in 'NavePropia.pas',\r
+  Coordenadas in 'Coordenadas.pas';\r
+\r
+var\r
+  oEspacio:    cEspacio;\r
+  oNavePropia: cNavePropia;\r
+\r
+begin\r
+  oEspacio := cEspacio.create;\r
+  oNavePropia := oEspacio.mGetNavePropia;\r
+  oEspacio.mAgregarObjeto( cMisilDirigido.create( oNavePropia, cVector.create( 30, -15, -50 ) ) );\r
+  oEspacio.mAgregarObjeto( cMisilDirigido.create( oNavePropia, cVector.create( -15, 40, 50 ) ) );\r
+  oEspacio.mAgregarObjeto( cLaser.create( cVector.create( 30, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cLaser.create( cVector.create( 50, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cLaser.create( cVector.create( 100, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cLaser.create( cVector.create( 130, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cLaser.create( cVector.create( 160, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cMisil.create( cVector.create( 40, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cMisil.create( cVector.create( 170, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mIniciar;\r
+end.\r
diff --git a/src/test/AlgoWars.test_objeto_volador.dpr b/src/test/AlgoWars.test_objeto_volador.dpr
new file mode 100644 (file)
index 0000000..299ee47
--- /dev/null
@@ -0,0 +1,52 @@
+program AlgoWars;\r
+{$APPTYPE CONSOLE}\r
+{%ToDo 'AlgoWars.todo'}\r
+\r
+uses\r
+  SysUtils,\r
+  ObjetoVolador in 'ObjetoVolador.pas',\r
+  Vectores in 'Vectores.pas',\r
+  Objeto in 'Objeto.pas',\r
+  Tipos in 'Tipos.pas',\r
+  Meteorito in 'Meteorito.pas',\r
+  Armas in 'Armas.pas';\r
+\r
+const\r
+  MAX = 7;\r
+\r
+var\r
+  o:   array [1..MAX] of cObjetoVolador;\r
+  i:   byte;\r
+//  tmp: string;\r
+  fo:  text;\r
+\r
+begin\r
+  assignFile( fo, 'log.txt' );\r
+  rewrite( fo );\r
+  o[1] := cObjetoVolador.create;\r
+  o[2] := cObjetoVolador.create( cVector.createXYZ( 3, 3, 3 ) );\r
+  o[3] := cObjetoVolador.create( cVector.createXYZ( 4, -3, 1 ),\r
+                                 cVector.create( 2, pi / 2, 0 ) );\r
+  o[4] := cObjetoVolador.create( cVector.createXYZ( 4, -3, 1 ),\r
+                                 cVector.create( 2, 3 * pi / 2, 10 ),\r
+                                 30 );\r
+  o[5] := cObjetoVolador.create( cVector.createXYZ( 4,-3,1 ),\r
+                                 cVector.create( 2, 3 * pi / 2, 10 ),\r
+                                 30,\r
+                                 500 );\r
+  o[6] := cObjetoVolador.create( cVector.createXYZ( -15, -3, 91 ),\r
+                                 cVector.createXYZ( 2, 3, 10 ),\r
+                                 30,\r
+                                 50,\r
+                                 10 );\r
+  o[7] := cObjetoVolador.create( o[6] );\r
+  o[7].mMover( 10 );\r
+  o[7].mRestarEnergia( 20 );\r
+  writeln ( fo, o[7].mGetPosicion.mGetDistanciaA( o[6].mGetPosicion ): 8: 2 );\r
+  for i := 1 to MAX do begin\r
+    writeln( fo, 'OBJETO ' + IntToStr( i ) + ': ' + #13 + #10 +\r
+                 o[i].mGetDebugInfo + #13 + #10 );\r
+    o[i].free;\r
+    end;\r
+  closeFile( fo );\r
+end.\r
diff --git a/src/test/AlgoWars.test_persecusion.dpr b/src/test/AlgoWars.test_persecusion.dpr
new file mode 100644 (file)
index 0000000..ed05f06
--- /dev/null
@@ -0,0 +1,63 @@
+program AlgoWars;\r
+{$APPTYPE CONSOLE}\r
+{%ToDo 'AlgoWars.todo'}\r
+\r
+uses\r
+  SysUtils,\r
+  ObjetoVolador in 'ObjetoVolador.pas',\r
+  Vectores in 'Vectores.pas',\r
+  Objeto in 'Objeto.pas',\r
+  Tipos in 'Tipos.pas',\r
+  Meteorito in 'Meteorito.pas',\r
+  Armas in 'Armas.pas',\r
+  Nave in 'Nave.pas',\r
+  Espacio in 'Espacio.pas',\r
+  NaveEnemiga in 'NaveEnemiga.pas',\r
+  NavePropia in 'NavePropia.pas';\r
+\r
+const\r
+  MAX = 3;\r
+\r
+var\r
+//  l:   array [1..MAX] of cLaser;\r
+  i:   byte;\r
+  n:   cNave;\r
+  m:  cMisilDirigido;\r
+//  tmp: string;\r
+  fo:  text;\r
+\r
+begin\r
+  assignFile( fo, 'log.txt' );\r
+  rewrite( fo );\r
+//  l[1] := cLaser.create;\r
+//  l[2] := cLaser.create( cVector.createXYZ( 3, 3, 3 ) );\r
+//  l[3] := cLaser.create( cVector.createXYZ( 1, 0, 0 ),\r
+//                         cVector.createXYZ( 1, 1, 1 ) );\r
+  n := cNave.create( cVector.create( 0, 0, 0 ),\r
+                     cVector.create( 0.25, 0, 0 ) );\r
+  m := cMisilDirigido.create( n, cVector.create( -5, 10, 10 ) );\r
+  writeln( fo, 'NAVE: ' + #13 + #10 +\r
+               n.mGetDebugInfo( DI_MAXI ) + #13 + #10 );\r
+  writeln( fo, 'MISIL: ' + #13 + #10 +\r
+               m.mGetDebugInfo( DI_MAXI ) + #13 + #10 );\r
+  for i := 1 to 50 do begin\r
+    m.mMover( 500 );\r
+    n.mMover( 500 );\r
+    writeln( fo, i, '-------------------------------------' );\r
+    writeln( fo, 'NAVE: ' + #13 + #10 +\r
+                 n.mGetDebugInfo( DI_MAXI ) + #13 + #10 );\r
+    writeln( fo, 'MISIL: ' + #13 + #10 +\r
+                 m.mGetDebugInfo( DI_MAXI ) + #13 + #10 );\r
+{    if not m.mActivo then begin\r
+      writeln( fo, 'Murio el misil!!!!' );\r
+      m.free;\r
+      break;\r
+    end;}\r
+  end;\r
+//  for i := 1 to MAX do begin\r
+//    writeln( fo, 'OBJETO ' + IntToStr( i ) + ': ' + #13 + #10 +\r
+//                 o[i].mGetDebugInfo + #13 + #10 );\r
+//    o[i].free;\r
+//    end;\r
+  closeFile( fo );\r
+end.\r
diff --git a/src/test/AlgoWars.test_vectores.dpr b/src/test/AlgoWars.test_vectores.dpr
new file mode 100644 (file)
index 0000000..f65982a
--- /dev/null
@@ -0,0 +1,54 @@
+program AlgoWars;\r
+{$APPTYPE CONSOLE}\r
+{%ToDo 'AlgoWars.todo'}\r
+{%ToDo 'AlgoWars.test_vectores.todo'}\r
+\r
+uses\r
+  SysUtils,\r
+  ObjetosVoladores in 'ObjetosVoladores.pas',\r
+  Vectores in 'Vectores.pas',\r
+  Objeto in 'Objeto.pas',\r
+  Tipos in 'Tipos.pas';\r
+\r
+const\r
+  MAX = 14;\r
+\r
+var\r
+  v:   array [1..MAX] of cVector;\r
+  i:   byte;\r
+//  tmp: string;\r
+  fo:  text;\r
+\r
+begin\r
+  assignFile( fo, 'log.txt' );\r
+  rewrite( fo );\r
+  v[1] := cVector.Create;                 // O\r
+  v[2] := cVector.Create( 1, pi / 2, 0 ); // j\r
+  v[3] := cVector.Create( v[2] );         // j\r
+  v[4] := cVector.Create( 0, 1, 0 );   // j\r
+  v[5] := cVector.Create( -3473, 67100, 12249 );\r
+  v[6] := cVector.Create( -3473, 67100, 12249 );\r
+  v[6].mHacerVersor;\r
+  v[7] := cVector.Create( -3473, 67100, 12249 );\r
+  v[7].mMultiplicar( v[4] );      // k\r
+  v[8] := cVector.Create( v[5] );\r
+  v[8].mAddModulo( 10 );\r
+  v[9] := cVector.Create( v[8] );\r
+  v[9].mSetModulo( 10 );\r
+  v[10] := cVector.Create( v[9] );\r
+  v[10].mMultiplicarPor( 0.1 );\r
+  v[11] := cVector.Create( v[10] );\r
+  v[11].mAddX( 1.5 );\r
+  v[12] := cVector.Create( v[9] );\r
+  v[12].mMultiplicar( 1.5 );\r
+  v[13] := cVector.Create( v[9] );\r
+  v[13].mSumar( v[4] );\r
+  v[14] := cVector.create( -1, 1, 0 );\r
+  writeln( fo, 'v[5].v[5]: ' + floatToStr( v[5].mMultiplicarEsc( v[5] ) ) );\r
+  writeln( fo, 'v[3].v[4]: ' + floatToStr( v[3].mMultiplicarEsc( v[4] ) ) );\r
+  for i := 1 to MAX do begin\r
+    writeln( fo, 'VECTOR ' + IntToStr( i ) + ': ' + #13 + #10 + v[i].mGetDebugInfo + #13 + #10 );\r
+    v[i].free;\r
+    end;\r
+  closeFile( fo );\r
+end.\r
diff --git a/src/test/AlgoWars_test_espacio2.dpr b/src/test/AlgoWars_test_espacio2.dpr
new file mode 100644 (file)
index 0000000..a908a49
--- /dev/null
@@ -0,0 +1,58 @@
+program AlgoWars;\r
+{$APPTYPE CONSOLE}\r
+{%ToDo 'AlgoWars.todo'}\r
+\r
+uses\r
+  SysUtils,\r
+  Vectores in 'Vectores.pas',\r
+  Objeto in 'Objeto.pas',\r
+  Tipos in 'Tipos.pas',\r
+  Espacio in 'Espacio.pas',\r
+  Coordenadas in 'Coordenadas.pas',\r
+  Meteorito in 'ov\Meteorito.pas',\r
+  ObjetoVolador in 'ov\ObjetoVolador.pas',\r
+  Armas in 'ov\Armas.pas',\r
+  Nave in 'ov\naves\Nave.pas',\r
+  NavePropia in 'ov\naves\NavePropia.pas',\r
+  NaveEnemiga in 'ov\naves\NaveEnemiga.pas',\r
+  NavesEnemigas in 'ov\naves\NavesEnemigas.pas',\r
+  Camara in 'Camara.pas';\r
+\r
+var\r
+  oEspacio:    cEspacio;\r
+  oNavePropia: cNavePropia;\r
+\r
+begin\r
+  randomize; // Cambia la semilla del generador de numeros aleatorios\r
+  \r
+  // Creamos un objeto espacio y obtenemos la nave que el crea para pasarla como objetivo a los misiles\r
+  //  dirigidos (en el futuro no va a ser posible obtener la nave propia...)\r
+  oEspacio := cEspacio.create;\r
+  oNavePropia := oEspacio.mGetNavePropia;\r
+\r
+  // Creamos varios ejemplos de objetos voladores para agregar al espacio\r
+\r
+  // Ejemplo 1\r
+{  oEspacio.mAgregarObjeto( cNaveSuicida.create( cVector.create( 30, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cNaveEspia.create( cVector.create( 50, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cNaveLiviana.create( cVector.create( 100, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cNavePesada.create( cVector.create( 130, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  // Ejemplo 2\r
+  oEspacio.mAgregarObjeto( cNaveSuicida.create( cVector.create( 1010, 5, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cNaveEspia.create( cVector.create( 1510, 0, 5 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cNaveLiviana.create( cVector.create( 2010, -5, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cNavePesada.create( cVector.create( 2510, 0, -5 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cMeteorito.create( cVector.create( 2500, 0, -5 ), cVector.create( -0.05, 0, 0 ) ) );\r
+}  // Ejemplo 3\r
+  oEspacio.mAgregarObjeto( cMisilDirigido.create( oNavePropia, cVector.create( 30, -15, -50 ) ) );\r
+  oEspacio.mAgregarObjeto( cMisilDirigido.create( oNavePropia, cVector.create( -15, 40, 50 ) ) );\r
+  oEspacio.mAgregarObjeto( cLaser.create( cVector.create( 30, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cLaser.create( cVector.create( 50, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cLaser.create( cVector.create( 100, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cLaser.create( cVector.create( 130, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cLaser.create( cVector.create( 160, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cMisil.create( cVector.create( 40, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+  oEspacio.mAgregarObjeto( cMisil.create( cVector.create( 170, 0, 0 ), cVector.create( -1, 0, 0 ) ) );\r
+\r
+  oEspacio.mIniciar;\r
+end.\r
diff --git a/src/test/AlgoWars_test_serializacion.cfg b/src/test/AlgoWars_test_serializacion.cfg
new file mode 100644 (file)
index 0000000..6e4aedc
--- /dev/null
@@ -0,0 +1,35 @@
+-$A+\r
+-$B-\r
+-$C+\r
+-$D+\r
+-$E-\r
+-$F-\r
+-$G+\r
+-$H+\r
+-$I+\r
+-$J+\r
+-$K-\r
+-$L+\r
+-$M-\r
+-$N+\r
+-$O+\r
+-$P+\r
+-$Q-\r
+-$R-\r
+-$S-\r
+-$T-\r
+-$U-\r
+-$V+\r
+-$W-\r
+-$X+\r
+-$YD\r
+-$Z1\r
+-cg\r
+-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;\r
+-H+\r
+-W+\r
+-M\r
+-$M16384,1048576\r
+-K$00400000\r
+-N..\..\dcu\r
+-DDebugAlgoWars\r
diff --git a/src/test/AlgoWars_test_serializacion.dfm b/src/test/AlgoWars_test_serializacion.dfm
new file mode 100644 (file)
index 0000000..56d44bb
Binary files /dev/null and b/src/test/AlgoWars_test_serializacion.dfm differ
diff --git a/src/test/AlgoWars_test_serializacion.dof b/src/test/AlgoWars_test_serializacion.dof
new file mode 100644 (file)
index 0000000..b4b26e9
--- /dev/null
@@ -0,0 +1,97 @@
+[Compiler]\r
+A=1\r
+B=0\r
+C=1\r
+D=1\r
+E=0\r
+F=0\r
+G=1\r
+H=1\r
+I=1\r
+J=1\r
+K=0\r
+L=1\r
+M=0\r
+N=1\r
+O=1\r
+P=1\r
+Q=0\r
+R=0\r
+S=0\r
+T=0\r
+U=0\r
+V=1\r
+W=0\r
+X=1\r
+Y=1\r
+Z=1\r
+ShowHints=1\r
+ShowWarnings=1\r
+UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;\r
+\r
+[Linker]\r
+MapFile=0\r
+OutputObjs=0\r
+ConsoleApp=1\r
+DebugInfo=0\r
+RemoteSymbols=0\r
+MinStackSize=16384\r
+MaxStackSize=1048576\r
+ImageBase=4194304\r
+ExeDescription=\r
+\r
+[Directories]\r
+OutputDir=\r
+UnitOutputDir=..\..\dcu\r
+PackageDLLOutputDir=\r
+PackageDCPOutputDir=\r
+SearchPath=\r
+Packages=VCL40;VCLX40;VCLDB40;VCLDBX40;VCLSMP40;QRPT40;TEEUI40;TEEDB40;TEE40;DSS40;ibevnt40;VCLMID40;NMFAST40;INETDB40;INET40\r
+Conditionals=DebugAlgoWars\r
+DebugSourceDirs=\r
+UsePackages=0\r
+\r
+[Parameters]\r
+RunParams=\r
+HostApplication=\r
+\r
+[Version Info]\r
+IncludeVerInfo=0\r
+AutoIncBuild=0\r
+MajorVer=1\r
+MinorVer=0\r
+Release=0\r
+Build=0\r
+Debug=0\r
+PreRelease=0\r
+Special=0\r
+Private=0\r
+DLL=0\r
+Locale=11274\r
+CodePage=1252\r
+\r
+[Version Info Keys]\r
+CompanyName=\r
+FileDescription=\r
+FileVersion=1.0.0.0\r
+InternalName=\r
+LegalCopyright=\r
+LegalTrademarks=\r
+OriginalFilename=\r
+ProductName=\r
+ProductVersion=1.0.0.0\r
+Comments=\r
+\r
+[HistoryLists\hlConditionals]\r
+Count=1\r
+Item0=DebugAlgoWars\r
+\r
+[HistoryLists\hlUnitAliases]\r
+Count=1\r
+Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;\r
+\r
+[HistoryLists\hlUnitOutputDirectory]\r
+Count=3\r
+Item0=..\..\dcu\r
+Item1=..\..\..\dcu\r
+Item2=../../dcu\r
diff --git a/src/test/AlgoWars_test_serializacion.dpr b/src/test/AlgoWars_test_serializacion.dpr
new file mode 100644 (file)
index 0000000..084cfe9
--- /dev/null
@@ -0,0 +1,33 @@
+program AlgoWars_test_serializacion;\r
+\r
+uses\r
+  Vectores in '..\Vectores.pas',\r
+  Coordenadas in '..\Coordenadas.pas',\r
+  Espacio in '..\Espacio.pas',\r
+  Objeto in '..\Objeto.pas',\r
+  Tipos in '..\Tipos.pas',\r
+  Camara in '..\Camara.pas',\r
+  ObjetoVolador in '..\ov\ObjetoVolador.pas',\r
+  Meteorito in '..\ov\Meteorito.pas',\r
+  Armas in '..\ov\Armas.pas',\r
+  Nave in '..\ov\naves\Nave.pas',\r
+  NaveEnemiga in '..\ov\naves\NaveEnemiga.pas',\r
+  NavePropia in '..\ov\naves\NavePropia.pas',\r
+  NavesEnemigas in '..\ov\naves\NavesEnemigas.pas',\r
+  RegExpr in '..\RegExpr.pas',\r
+  Vista in '..\Vista.pas',\r
+  Filtro in '..\Filtro.pas',\r
+  Lista in '..\Lista.pas',\r
+  FiltroLock in '..\FiltroLock.pas',\r
+  ObjetoPersistente in '..\ObjetoPersistente.pas',\r
+  Forms,\r
+  Serializacion in 'Serializacion.pas' {Form1},\r
+  SerializacionUtils in '..\SerializacionUtils.pas';\r
+\r
+{$R *.RES}\r
+\r
+begin\r
+  Application.Initialize;\r
+  Application.CreateForm(TForm1, Form1);\r
+  Application.Run;\r
+end.\r
diff --git a/src/test/AlgoWars_test_serializacion.dsk b/src/test/AlgoWars_test_serializacion.dsk
new file mode 100644 (file)
index 0000000..31646da
--- /dev/null
@@ -0,0 +1,21 @@
+[PVCS Browser]\r
+Left=236\r
+Top=105\r
+Width=625\r
+Height=393\r
+State=0\r
+Visible=0\r
+\r
+[PVCS VDiff]\r
+Left=257\r
+Top=160\r
+Width=591\r
+Height=608\r
+Layout=1\r
+Orientation=1\r
+State=0\r
+Visible=0\r
+File1Color=16711680\r
+File2Color=255\r
+SpaceColor=16776960\r
+TextColor=0\r
diff --git a/src/test/AlgoWars_test_serializacion.res b/src/test/AlgoWars_test_serializacion.res
new file mode 100644 (file)
index 0000000..8deee64
Binary files /dev/null and b/src/test/AlgoWars_test_serializacion.res differ
diff --git a/src/test/AlgoWars_test_serializacion.salida b/src/test/AlgoWars_test_serializacion.salida
new file mode 100644 (file)
index 0000000..c863a33
--- /dev/null
@@ -0,0 +1,8 @@
+ -- Serializando. --\r
+<vector><id>ABCDEF</id><X>0</X><Y>1</Y><Z>-1</Z></vector>\r
+<coordenadas><id>000001</id><i><id>000002</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>000003</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>000004</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas>\r
+<ObjetoVolador><id>BC60F8</id><posicion><id>BC5FA4</id><X>1</X><Y>2</Y><Z>-1</Z></posicion><velocidad>0</velocidad><potencia>1</potencia><energia>100</energia><dimension>5</dimension><coordenadas><id>BC5FD8</id><i><id>BC6004</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BC6078</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BC60B8</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas></ObjetoVolador>\r
+<laser><id>BC2DA0</id><posicion><id>BC6E44</id><X>4563</X><Y>1345</Y><Z>3545</Z></posicion><velocidad>0,2</velocidad><potencia>10</potencia><energia>120</energia><dimension>1</dimension><coordenadas><id>BC2E08</id><i><id>BC2E34</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BC6DD8</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BC6E04</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas><duracion>3000</duracion><alcance>1200</alcance><velmaxima>0,4</velmaxima></laser>\r
+<misil><id>BC3208</id><posicion><id>BC331C</id><X>0</X><Y>0</Y><Z>0</Z></posicion><velocidad>0</velocidad><potencia>20</potencia><energia>1</energia><dimension>0,5</dimension><coordenadas><id>BC6E98</id><i><id>BC325C</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BC329C</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BC32DC</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas><duracion>5000</duracion><alcance>1500</alcance><velmaxima>0,3</velmaxima></misil>\r
+<misildirigido><id>BC345C</id><posicion><id>BC35C0</id><X>0</X><Y>0</Y><Z>0</Z></posicion><velocidad>0,25</velocidad><potencia>30</potencia><energia>1</energia><dimension>0,7</dimension><coordenadas><id>BC34D4</id><i><id>BC3500</id><X>0,408248290463863016</X><Y>0,816496580927726033</Y><Z>-0,408248290463863016</Z></i><j><id>BC3540</id><X>-0,894427190999915879</X><Y>0,447213595499957939</Y><Z>0</Z></j><k><id>BC3580</id><X>0,182574185835055371</X><Y>0,365148371670110742</Y><Z>0,912870929175276856</Z></k></coordenadas><duracion>20000</duracion><alcance>2000</alcance><velmaxima>0,25</velmaxima><objetivo class=cObjetoVolador><id>BC60F8</id><posicion><id>BC5FA4</id><X>1</X><Y>2</Y><Z>-1</Z></posicion><velocidad>0</velocidad><potencia>1</potencia><energia>100</energia><dimension>5</dimension><coordenadas><id>BC5FD8</id><i><id>BC6004</id><X>1</X><Y>0</Y><Z>0</Z></i><j><id>BC6078</id><X>0</X><Y>1</Y><Z>0</Z></j><k><id>BC60B8</id><X>0</X><Y>0</Y><Z>1</Z></k></coordenadas></objetivo><lockarea>2000</lockarea></misildirigido>\r
+ -- Terminado. --
\ No newline at end of file
diff --git a/src/test/Serializacion.dfm b/src/test/Serializacion.dfm
new file mode 100644 (file)
index 0000000..209af75
Binary files /dev/null and b/src/test/Serializacion.dfm differ
diff --git a/src/test/Serializacion.pas b/src/test/Serializacion.pas
new file mode 100644 (file)
index 0000000..3952544
--- /dev/null
@@ -0,0 +1,166 @@
+unit Serializacion;\r
+\r
+interface\r
+\r
+uses\r
+  Espacio,\r
+  Nave,\r
+  NaveEnemiga,\r
+  NavePropia,\r
+  NavesEnemigas,\r
+  Meteorito,\r
+  Armas,\r
+  Vectores,\r
+  Vista,\r
+  Tipos,\r
+  Coordenadas,\r
+  Filtro,\r
+  ObjetoVolador,\r
+\r
+  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\r
+  StdCtrls;\r
+\r
+type\r
+  TForm1 = class(TForm)\r
+    gbSalida: TGroupBox;\r
+    mmSalida: TMemo;\r
+    Button1: TButton;\r
+    procedure FormCreate(Sender: TObject);\r
+  private\r
+    { Private declarations }\r
+  public\r
+    { Public declarations }\r
+  end;\r
+\r
+var\r
+  Form1: TForm1;\r
+\r
+implementation\r
+\r
+uses\r
+  RegExpr;\r
+\r
+{$R *.DFM}\r
+\r
+procedure TForm1.FormCreate(Sender: TObject);\r
+var\r
+  v:  cVector;\r
+  c:  cCoordenadas;\r
+  ov: cObjetoVolador;\r
+  l:  cLaser;\r
+  m:  cMisil;\r
+  md: cMisilDirigido;\r
+  f:  cFiltro;\r
+  n:  cNave;\r
+  ne: cNaveEnemiga;\r
+  np: cNavePesada;\r
+  nl: cNaveLiviana;\r
+  ni: cNaveEspia;\r
+  nr: cNavePropia;\r
+  r:  TRegExpr;\r
+begin\r
+  r := TRegExpr.create;\r
+  mmSalida.Lines.LoadFromFile( 'serializado.eaw' );\r
+  mmSalida.Lines.Insert( 0, ' -- Cargando Archivo: "serializado.eaw"... --' );\r
+  mmSalida.Lines.Append( ' -- Archivo Cargado. --' );\r
+  mmSalida.Lines.Append( ' -- Deserializando... --' );\r
+  r.Expression := '<vector>\s*(.+)\s*</vector>';\r
+  if r.Exec( mmSalida.Lines.Text ) then\r
+    v  := cVector.crearDeSerializado( r.Match[1] );\r
+  r.Expression := '<coordenadas>\s*(.+)\s*</coordenadas>';\r
+  if r.Exec( mmSalida.Lines.Text ) then\r
+    c  := cCoordenadas.crearDeSerializado( r.Match[1] );\r
+  r.Expression := '<ObjetoVolador>\s*(.+)\s*</ObjetoVolador>';\r
+  if r.Exec( mmSalida.Lines.Text ) then\r
+    ov := cObjetoVolador.crearDeSerializado( r.Match[1] );\r
+  r.Expression := '<laser>\s*(.+)\s*</laser>';\r
+  if r.Exec( mmSalida.Lines.Text ) then\r
+    l  := cLaser.crearDeSerializado( r.Match[1] );\r
+  r.Expression := '<misil>\s*(.+)\s*</misil>';\r
+  if r.Exec( mmSalida.Lines.Text ) then\r
+    m  := cMisil.crearDeSerializado( r.Match[1] );\r
+  r.Expression := '<misildirigido>\s*(.+)\s*</misildirigido>';\r
+  if r.Exec( mmSalida.Lines.Text ) then\r
+    md := cMisilDirigido.crearDeSerializado( r.Match[1] );\r
+  r.Expression := '<filtro>\s*(.+)\s*</filtro>';\r
+  if r.Exec( mmSalida.Lines.Text ) then\r
+    f := cFiltro.crearDeSerializado( r.Match[1] );\r
+  r.Expression := '<nave>\s*(.+)\s*</nave>';\r
+  if r.Exec( mmSalida.Lines.Text ) then\r
+    n := cNave.crearDeSerializado( r.Match[1] );\r
+  r.Expression := '<naveenemiga>\s*(.+)\s*</naveenemiga>';\r
+  if r.Exec( mmSalida.Lines.Text ) then\r
+    ne := cNaveEnemiga.crearDeSerializado( r.Match[1] );\r
+  r.Expression := '<navepesada>\s*(.+)\s*</navepesada>';\r
+  if r.Exec( mmSalida.Lines.Text ) then\r
+    np := cNavePesada.crearDeSerializado( r.Match[1] );\r
+  r.Expression := '<naveliviana>\s*(.+)\s*</naveliviana>';\r
+  if r.Exec( mmSalida.Lines.Text ) then\r
+    nl := cNaveLiviana.crearDeSerializado( r.Match[1] );\r
+  r.Expression := '<naveespia>\s*(.+)\s*</naveespia>';\r
+  if r.Exec( mmSalida.Lines.Text ) then\r
+    ni := cNaveEspia.crearDeSerializado( r.Match[1] );\r
+  r.Expression := '<navepropia>\s*(.+)\s*</navepropia>';\r
+  if r.Exec( mmSalida.Lines.Text ) then\r
+    nr := cNavePropia.crearDeSerializado( r.Match[1] );\r
+  if md.mGetObjetivo <> nil then\r
+    if l.mGetID = md.mGetObjetivo.mGetID then begin\r
+      mmSalida.Lines.Append( 'Objetivo del Misil Dirigido = Laser. Eliminando la copia...' );\r
+      ov.free;\r
+      ov := md.mGetObjetivo;\r
+    end;\r
+  if f.mGetObservador <> nil then\r
+    if m.mGetID = f.mGetObservador.mGetID then begin\r
+      mmSalida.Lines.Append( 'Observador del Filtro = Misil. Eliminando la copia...' );\r
+      m.free;\r
+      m := f.mGetObservador as cMisil;\r
+    end;\r
+{  mmSalida.Lines.Append( 'Vector: ' + v.mGetDebugInfo( DI_MAXI ) );\r
+  mmSalida.Lines.Append( 'Coordenadas: ' + c.mGetDebugInfo( DI_MAXI ) );\r
+  mmSalida.Lines.Append( 'Objeto Volador: ' + ov.mGetDebugInfo( DI_MAXI ) );\r
+  mmSalida.Lines.Append( 'Laser: ' + l.mGetDebugInfo( DI_MAXI ) );\r
+  mmSalida.Lines.Append( 'Misil: ' + m.mGetDebugInfo( DI_MAXI ) );\r
+  mmSalida.Lines.Append( 'Misil Dirigido: ' + md.mGetDebugInfo( DI_MAXI ) );\r
+}  mmSalida.Lines.Append( ' -- Terminado. --' );\r
+{  mmSalida.Lines.Append( ' -- Cambiando Valores. --' );\r
+  v.free;\r
+  c.free;\r
+  ov.free;\r
+  l.free;\r
+  m.free;\r
+  md.free;\r
+  v  := cVector.create( 1, 2, -1 );\r
+  c  := cCoordenadas.create;\r
+  ov := cObjetoVolador.create( v );\r
+  l  := cLaser.create;\r
+  m  := cMisil.create;\r
+  md := cMisilDirigido.create( ov );\r
+  mmSalida.Lines.Append( 'Vector: ' + v.mGetDebugInfo( DI_MAXI ) );\r
+  mmSalida.Lines.Append( 'Coordenadas: ' + c.mGetDebugInfo( DI_MAXI ) );\r
+  mmSalida.Lines.Append( 'Objeto Volador: ' + ov.mGetDebugInfo( DI_MAXI ) );\r
+  mmSalida.Lines.Append( 'Laser: ' + l.mGetDebugInfo( DI_MAXI ) );\r
+  mmSalida.Lines.Append( 'Misil: ' + m.mGetDebugInfo( DI_MAXI ) );\r
+  mmSalida.Lines.Append( 'Misil Dirigido: ' + md.mGetDebugInfo( DI_MAXI ) );\r
+  mmSalida.Lines.Append( ' -- Terminado. --' );\r
+}  mmSalida.Lines.Append( ' -- Serializando. --' );\r
+  mmSalida.Lines.Append( '<vector>' + v.mSerializar + '</vector>');\r
+  mmSalida.Lines.Append( '<coordenadas>' + c.mSerializar + '</coordenadas>' );\r
+  mmSalida.Lines.Append( '<ObjetoVolador>' + ov.mSerializar + '</ObjetoVolador>');\r
+  mmSalida.Lines.Append( '<laser>' + l.mSerializar + '</laser>');\r
+  mmSalida.Lines.Append( '<misil>' + m.mSerializar + '</misil>' );\r
+  mmSalida.Lines.Append( '<misildirigido>' + md.mSerializar + '</misildirigido>');\r
+  mmSalida.Lines.Append( '<filtro>' + f.mSerializar + '</filtro>');\r
+  mmSalida.Lines.Append( '<nave>' + n.mSerializar + '</nave>');\r
+  mmSalida.Lines.Append( '<naveenemiga>' + ne.mSerializar + '</naveenemiga>');\r
+  mmSalida.Lines.Append( '<navepesada>' + np.mSerializar + '</navepesada>');\r
+  mmSalida.Lines.Append( '<naveliviana>' + nl.mSerializar + '</naveliviana>');\r
+  mmSalida.Lines.Append( '<naveespia>' + ni.mSerializar + '</naveespia>');\r
+  mmSalida.Lines.Append( '<navepropia>' + nr.mSerializar + '</navepropia>');\r
+  mmSalida.Lines.Append( ' -- Terminado. --' );\r
+  v.free;\r
+  c.free;\r
+  ov.free;\r
+  r.free;\r
+end;\r
+\r
+end.\r
diff --git a/src/test/cb/CajaBcaFinal.txt b/src/test/cb/CajaBcaFinal.txt
new file mode 100644 (file)
index 0000000..e619720
--- /dev/null
@@ -0,0 +1,30 @@
+NaveLiviana1 cond1=true cond=2true Posición: X: 200,00000 | Y: 0,00000 | Z: 0,00000 | Modulo: 200,00000\r
+Energia: 60,00000 | Potencia: 1,00000 | Dimension: 3,00000\r
+Velocidad: X: -0,17000 | Y: 0,00000 | Z: 0,00000 | Modulo: 0,17000 \r
+//aca se ve como entro en las dos condiciones\r
+//y se cambio el madulo de la velocidad siendo ahora igual al de la nave propia. El camino fue el (0,1,2,3,4,5)\r
+Coordenadas:\r
+Versor i: X: -1,00000 | Y: 0,00000 | Z: 0,00000\r
+Versor j: X: 0,00000 | Y: -0,89443 | Z: -0,44721\r
+Versor k: X: 0,00000 | Y: -0,44721 | Z: 0,89443 | Misiles: 0 | Misiles Dirigidos: 0 | Campo de Radar: 2.000,00000\r
+\r
+NaveLiviana2  cond1=true cond2=false Posición: X: -200,00000 | Y: 0,00000 | Z: 0,00000 | Modulo: 200,00000\r
+Energia: 60,00000 | Potencia: 1,00000 | Dimension: 3,00000\r
+Velocidad: X: 0,05000 | Y: 0,00000 | Z: 0,00000 | Modulo: 0,05000\r
+// al ser su modulo de velocidad menor\r
+//que el de la nave propia no se produjo ningun cambio en él, pero se ve por el valor de cond1 que el camino fue(0,1,2,4,5)\r
+Coordenadas:\r
+Versor i: X: 1,00000 | Y: 0,00000 | Z: 0,00000\r
+Versor j: X: 0,00000 | Y: 1,00000 | Z: 0,00000\r
+Versor k: X: 0,00000 | Y: 0,00000 | Z: 1,00000 | Misiles: 0 | Misiles Dirigidos: 0 | Campo de Radar: 2.000,00000\r
+\r
+NaveLiviana3 cond1=false cond2=false Posición: X: 300,00000 | Y: 0,00000 | Z: 0,00000 | Modulo: 300,00000\r
+Energia: 60,00000 | Potencia: 1,00000 | Dimension: 3,00000\r
+Velocidad: X: -0,18000 | Y: 0,00000 | Z: 0,00000 | Modulo: 0,18000\r
+//en este caso tampoco hubo cambio del modulo de la\r
+//velocidad. Del valor de las variables logicas se puede ver que el camino fue el (0,1,4,5).\r
+Coordenadas:\r
+Versor i: X: -1,00000 | Y: 0,00000 | Z: 0,00000\r
+Versor j: X: 0,00000 | Y: -1,00000 | Z: 0,00000\r
+Versor k: X: 0,00000 | Y: 0,00000 | Z: 1,00000 | Misiles: 0 | Misiles Dirigidos: 0 | Campo de Radar: 2.000,00000\r
+\r
diff --git a/src/test/cb/NavesEnemigasTest.pas b/src/test/cb/NavesEnemigasTest.pas
new file mode 100644 (file)
index 0000000..07415b6
--- /dev/null
@@ -0,0 +1,309 @@
+{** Distintos tipos de Naves Enemigas }\r
+unit NavesEnemigas;\r
+\r
+interface\r
+\r
+uses\r
+  Tipos,\r
+  Vectores,\r
+  Nave,\r
+  NaveEnemiga,\r
+  NavePropia,\r
+  ObjetoVolador,\r
+  Armas;\r
+\r
+type\r
+  {** Es una nave con misiles y lasers (igual que la propia)\r
+      que se desplaza por el epacio hasta que encuentra una nave propia para atacar.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            5         metros\r
+      Potencia:             2         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              100       Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,17      metros/milisegundos (612 km/h)\r
+      Campo de radar:       2500      metros (2,5 km)\r
+      Misiles:              5\r
+      Misiles Dirigidos:    2\r
+      </PRE>}\r
+  cNavePesada = class( cNaveEnemiga )\r
+    private\r
+      aRadioMinimo: tLongitud; // Distancia minima a la nave propia\r
+    protected\r
+      {** Hace que se dispare un arma (todavía no está implementado)}\r
+      procedure mDisparar;\r
+    public\r
+      {** Constructor}\r
+      constructor create( pos : cVector = nil; vel : cVector = nil );\r
+      {** Método heredado que hace que la nave reaccione ante la presencia\r
+          de la nave propia (en este caso la atacará con lasers y misiles)}\r
+      procedure mReaccionar( np : cNavePropia );override;\r
+      {** Método heredado, se sobreescribe porque se dibuja de forma distinta}\r
+      function   mDibujar: string; override;\r
+  end;\r
+\r
+  {** Es una nave sin misiles, solo con lasers que\r
+      se desplaza por el epacio hasta que encuentra una nave propia para atacar.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            3         metros\r
+      Potencia:             1         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              60        Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,18      metros/milisegundos (648 km/h)\r
+      Campo de radar:       2000      metros (2 km)\r
+      Misiles:              0\r
+      Misiles Dirigidos:    0\r
+      </PRE>}\r
+  cNaveLiviana = class( cNaveEnemiga )\r
+    private\r
+      aRadioMinimo: tLongitud; // Distancia minima a la nave propia\r
+    protected\r
+      {** Dispara el laser (todavía no está implementado)}\r
+      procedure mDisparar;\r
+    public\r
+      {** Constructor}\r
+      constructor create( pos : cVector = nil; vel : cVector = nil );\r
+      {** Método heredado que hace que la nave reaccione ante la presencia\r
+          de la nave propia (en este caso la atacará con lasers)}\r
+      procedure mReaccionar( np : cNavePropia );override;\r
+      {** Método heredado, se sobreescribe porque se dibuja de forma distinta}\r
+      function   mDibujar: string; override;\r
+  end;\r
+\r
+  {** Es una nave sin armas que se desplaza por el epacio\r
+      hasta que encuentra una nave propia, en ese momento empieza a huir avisando a\r
+      las demas naves enemigas la ultima posicion de la nave propia.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            2         metros\r
+      Potencia:             1         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              30        Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,2       metros/milisegundos (720 km/h)\r
+      Campo de radar:       1500      metros (1,5 km)\r
+      Misiles:              0\r
+      Misiles Dirigidos:    0\r
+      </PRE>}\r
+  cNaveEspia = class( cNaveEnemiga )\r
+    private\r
+      aPosicionEnemiga: cVector; // Indica la posicion de la nave propia. Si todavía no\r
+                                 //  la encontró, su valor es nil\r
+    protected\r
+      {** Método heredado se modifica porque su forma de modificar la velocidad es diferente al\r
+          resto de las naves enemigas}\r
+      procedure mModificarVelocidad( np: cNavePropia; modulo: tLongitud = -1 ); override;\r
+    public\r
+      {** Constructor }\r
+      constructor create( pos : cVector = nil; vel : cVector = nil );\r
+      {** Método que indica si está avisando }\r
+      function mAvisando: boolean;\r
+      {** Método que devuelve la última posición en dónde vió a la nave propia (si está avisando)}\r
+      function mGetPosicionEnemiga: cVector;\r
+      {** Método heredado que hace que la nave reaccione ante la presencia\r
+          de la nave propia (en este caso huirá y empezará a avisar al resto de las naves que encuentre\r
+          sobre la última posición de la nave propia)}\r
+      procedure mReaccionar( np : cNavePropia );override;\r
+      {** Destructor}\r
+      destructor destroy; override;\r
+      {** Método heredado, se sobreescribe porque se dibuja de forma distinta}\r
+      function   mDibujar: string; override;\r
+  end;\r
+\r
+  {** Es una nave sin armas que se desplaza por el epacio\r
+      hasta que encuentra una nave propia y trata de chocarla.<br>\r
+      <u>Características:</u>\r
+      <PRE>\r
+      Dimensión:            2         metros\r
+      Potencia:             1         Cantidad de daño que hace por intervalo de tiempo\r
+      Energía:              30        Cantidad de daño que soporta antes de ser destruída\r
+      Velocidad máxima:     0,2       metros/milisegundos (720 km/h)\r
+      Campo de radar:       1000      metros (1 km)\r
+      Misiles:              0\r
+      Misiles Dirigidos:    0\r
+      </PRE>}\r
+  cNaveSuicida = class( cNaveEnemiga )\r
+    public\r
+      {** Constructor}\r
+      constructor create( pos : cVector = nil; vel : cVector = nil );\r
+      {** Método heredado que hace que la nave reaccione ante la presencia\r
+          de la nave propia (en este caso tratará de chocarla)}\r
+      procedure mReaccionar( np : cNavePropia );override;\r
+      {** Método heredado, se sobreescribe porque se dibuja de forma distinta}\r
+      function   mDibujar: string; override;\r
+  end;\r
+\r
+implementation\r
+\r
+{ cNavePesada }\r
+\r
+{** Crea una instancia de una nave pesada.\r
+    @param pos Vector posición\r
+    @param vel Vector velocidad}\r
+constructor cNavePesada.create(pos, vel: cVector);\r
+begin\r
+  // La dimensión es 5 m de radio, la potencia 2, la energía 100, tiene 5 misiles comunes,\r
+  //  2 dirigidos, su velocidad maxima es 0,17 m/mseg (612 km/h) y su Campo de radar 2,5 km\r
+  inherited create( pos, vel, 5 , 2, 100, 5 , 2, 0.17, 2500);\r
+  aRadioMinimo := 500;\r
+end;\r
+\r
+{** Hace que se dispare un arma (todavía no está implementado)}\r
+function cNavePesada.mDibujar: string;\r
+begin\r
+  result := '.\bitmaps\navepesada.bmp';\r
+end;\r
+\r
+procedure cNavePesada.mDisparar;\r
+begin\r
+  // Todavía no está implementado\r
+end;\r
+\r
+{** Método heredado que hace que la nave reaccione ante la presencia\r
+    de la nave propia cerca (en este caso la atacará con lasers y misiles)\r
+    @param np Nave Propia con la cual esta reaccionando}\r
+procedure cNavePesada.mReaccionar(np: cNavePropia);\r
+var\r
+  modulo: tLongitud;\r
+begin\r
+  modulo := mGetVelMax; // nuevo modulo de la velocidad igual a la velocidad maxima\r
+  if mGetDistancia( np ) < aRadioMinimo then // si esta cerca de la nave propia...\r
+    if np.mGetVelModulo < mGetVelMax then // si la vel de la nave propia es menor a la maxima\r
+      modulo := np.mGetVelocidad.mGetModulo; // nuevo modulo de la velocidad igual al de la nave propia\r
+  mModificarVelocidad( np, modulo ); // cambiar la velocidad segun la nave propia y el nuevo modulo\r
+  // Falta implementar la parte de disparos...\r
+  mDisparar;\r
+end;\r
+\r
+{ cNaveLiviana }\r
+\r
+{** Crea una instancia de una nave liviana.\r
+    @param pos Vector posición\r
+    @param vel Vector velocidad}\r
+constructor cNaveLiviana.create(pos, vel: cVector);\r
+begin\r
+  // La dimensión es 3 m de radio, la potencia 1, la energía 60, no tiene misiles comunes\r
+  //  ni dirigidos, su velocidad maxima es 0,18 m/mseg (648 km/h) y su Campo de radar 2 km\r
+  inherited create( pos, vel, 3, 1,60, 0, 0, 0.18, 2000);\r
+  aRadioMinimo := 250;\r
+end;\r
+\r
+{** Hace que se dispare un arma (todavía no está implementado)}\r
+function cNaveLiviana.mDibujar: string;\r
+begin\r
+  result := '.\bitmaps\naveliviana.bmp';\r
+end;\r
+\r
+procedure cNaveLiviana.mDisparar;\r
+begin\r
+  // Todavía no está implementado\r
+end;\r
+\r
+{** Método heredado que hace que la nave reaccione ante la presencia\r
+    de la nave propia (en este caso la atacará con lasers)\r
+    @param np Nave Propia con la cual esta reaccionando}\r
+procedure cNaveLiviana.mReaccionar(np: cNavePropia);\r
+var\r
+  modulo: tLongitud;\r
+begin\r
+  modulo := mGetVelMax; // nuevo modulo de la velocidad igual a la velocidad maxima\r
+  if mGetDistancia( np ) < aRadioMinimo then // si esta cerca de la nave propia...\r
+    if np.mGetVelModulo < mGetVelMax then // si la vel de la nave propia es menor a la maxima\r
+      modulo := np.mGetVelocidad.mGetModulo; // nuevo modulo de la velocidad igual al de la nave propia\r
+  mModificarVelocidad( np, modulo ); // cambiar la velocidad segun la nave propia y el nuevo modulo\r
+  // Falta implementar la parte de disparos...\r
+  mDisparar;\r
+end;\r
+\r
+{ cNaveEspia }\r
+\r
+{** Crea una instancia de una nave espía.\r
+    @param pos Vector posición\r
+    @param vel Vector velocidad}\r
+constructor cNaveEspia.create(pos, vel: cVector);\r
+begin\r
+  // La dimensión es 2 m de radio, la potencia 1, la energía 30, no tiene misiles comunes\r
+  //  ni dirigidos, su velocidad maxima es 0,2 m/mseg (720 km/h) y su Campo de radar 1,5 km\r
+  inherited create( pos, vel, 2, 1, 30, 0, 0, 0.2, 1500 );\r
+  aPosicionEnemiga := nil;\r
+end;\r
+\r
+{** Destructor}\r
+destructor cNaveEspia.destroy;\r
+begin\r
+  aPosicionEnemiga.free;\r
+  inherited;\r
+end;\r
+\r
+{** Método que indica si está avisando\r
+    @return <i>true</i> si está avisando, <i>false</i> si no lo está}\r
+function cNaveEspia.mAvisando: boolean;\r
+begin\r
+  result := ( aPosicionEnemiga <> nil ); // True si la posicion no es nil\r
+end;\r
+\r
+{** Método que devuelve la última posición en dónde vió a la nave propia (si está avisando)\r
+    @return Última posición donde detectó a la nave propia (<i>nil</i> si no la detecto nunca)}\r
+function cNaveEspia.mDibujar: string;\r
+begin\r
+  result := '.\bitmaps\naveespia.bmp';\r
+end;\r
+\r
+function cNaveEspia.mGetPosicionEnemiga: cVector;\r
+begin\r
+  result := cVector.create( aPosicionEnemiga );\r
+end;\r
+\r
+{** Modifica la velocidad de la nave en base a la nave propia.\r
+    @param np     Nave propia con la cual se calculará la dirección de la nueva velocidad\r
+    @param modulo Nuevo módulo de la velocidad}\r
+procedure cNaveEspia.mModificarVelocidad(np: cNavePropia; modulo: tLongitud);\r
+var\r
+  pos,          // Vector temporal\r
+  vel: cVector; // Vector temporal\r
+begin\r
+  pos := np.mGetPosicion;\r
+  vel := mGetPosicion.mRestar( pos ); // Crea un vector igual a su posicion\r
+                                      // Le resta la posicion de la nave propia\r
+  mSetVelModulo( mGetVelMax );        // Setea el modulo al maximo\r
+  mSetVelDir( vel );                  // Copia el vector a su velocidad\r
+  vel.free;                           // Libera el vector temporal\r
+  pos.free;                           // Libera el vector temporal\r
+end;\r
+\r
+{** Método heredado que hace que la nave reaccione ante la presencia\r
+    de la nave propia (en este caso huirá y empezará a avisar al resto de las naves que encuentre\r
+    sobre la última posición de la nave propia)\r
+    @param np Nave Propia con la cual esta reaccionando}\r
+procedure cNaveEspia.mReaccionar(np: cNavePropia);\r
+begin\r
+  mModificarVelocidad( np );\r
+  // Si ya tiene una posición, la modifica, si no crea una nueva\r
+  if aPosicionEnemiga <> nil then\r
+    aPosicionEnemiga.free;\r
+  aPosicionEnemiga := np.mGetPosicion;\r
+end;\r
+\r
+{ cNaveSuicida }\r
+\r
+{** Crea una instancia de una nave suicida.\r
+    @param pos Vector posición\r
+    @param vel Vector velocidad}\r
+constructor cNaveSuicida.create(pos, vel: cVector);\r
+begin\r
+  // La dimensión es 2 m de radio, la potencia 1, la energía 30, no tiene misiles comunes\r
+  //  ni dirigidos, su velocidad maxima es 0,2 m/mseg (720 km/h) y su Campo de radar 1 km\r
+  inherited create( pos, vel, 2, 1, 30, 0, 0, 0.2, 1000);\r
+end;\r
+\r
+{** Método heredado que hace que la nave reaccione ante la presencia\r
+    de la nave propia (en este caso tratará de chocarla)\r
+    @param np Nave Propia con la cual esta reaccionando}\r
+function cNaveSuicida.mDibujar: string;\r
+begin\r
+  result := '.\bitmaps\navesuicida.bmp';\r
+end;\r
+\r
+procedure cNaveSuicida.mReaccionar(np: cNavePropia);\r
+begin\r
+  mModificarVelocidad( np );\r
+end;\r
+\r
+end.\r
diff --git a/src/test/cb/negra..txt b/src/test/cb/negra..txt
new file mode 100644 (file)
index 0000000..34da7bd
--- /dev/null
@@ -0,0 +1,69 @@
+Recuperando:\r
+  "<X> 23,56  </X>\r
+<Y> 25,4E3 </Y>\r
+<Z> -12e-4 </Z>\r
+"\r
+  =\r
+  (23,56 ; 25400 ; -0,0012)\r
+\r
+Serializando:\r
+  (0 ; 0 ; 0)\r
+  =\r
+  "<X>0</X><Y>0</Y><Z>0</Z>"\r
+\r
+Recuperando:\r
+  "<X>0</X><Y>0</Y><Z>0</Z>"\r
+  =\r
+  (0 ; 0 ; 0)\r
+\r
+Serializando:\r
+  (-9,657E-5 ; 98,355 ; 25)\r
+  =\r
+  "<X>-9,657E-5</X><Y>98,355</Y><Z>25</Z>"\r
+\r
+Recuperando:\r
+  "<X>-9,657E-5</X><Y>98,355</Y><Z>25</Z>"\r
+  =\r
+  (-9,657E-5 ; 98,355 ; 25)\r
+\r
+Serializando:\r
+  (-9,657E-5 ; 1E27 ; -1E-12)\r
+  =\r
+  "<X>-9,657E-5</X><Y>1E27</Y><Z>-1E-12</Z>"\r
+\r
+Recuperando:\r
+  "<X>-9,657E-5</X><Y>1E27</Y><Z>-1E-12</Z>"\r
+  =\r
+  (-9,657E-5 ; 1E27 ; -1E-12)\r
+\r
+Serializando:\r
+  (-9,657E-5 ; 1E27 ; 1E99)\r
+  =\r
+  "<X>-9,657E-5</X><Y>1E27</Y><Z>1E99</Z>"\r
+\r
+Recuperando:\r
+  "<X>-9,657E-5</X><Y>1E27</Y><Z>1E99</Z>"\r
+  =\r
+  (-9,657E-5 ; 1E27 ; 1E99)\r
+\r
+Serializando:\r
+  (-9,657E-5 ; 1,1111E-38 ; 1E99)\r
+  =\r
+  "<X>-9,657E-5</X><Y>1,1111E-38</Y><Z>1E99</Z>"\r
+\r
+Recuperando:\r
+  "<X>-9,657E-5</X><Y>1,1111E-38</Y><Z>1E99</Z>"\r
+  =\r
+  (-9,657E-5 ; 1,1111E-38 ; 1E99)\r
+\r
+Serializando:\r
+  (1E-400 ; 33987336 ; 98867543)\r
+  =\r
+  "<X>1E-400</X><Y>33987336</Y><Z>98867543</Z>"\r
+\r
+Recuperando:\r
+  "<X>1E-400</X><Y>33987336</Y><Z>98867543</Z>"\r
+  =\r
+  (1E-400 ; 33987336 ; 98867543)\r
+\r
+\r
diff --git a/src/test/cn/SerializacionTest.dfm b/src/test/cn/SerializacionTest.dfm
new file mode 100644 (file)
index 0000000..bf57933
Binary files /dev/null and b/src/test/cn/SerializacionTest.dfm differ
diff --git a/src/test/cn/SerializacionTest.pas b/src/test/cn/SerializacionTest.pas
new file mode 100644 (file)
index 0000000..6df4ac9
--- /dev/null
@@ -0,0 +1,103 @@
+unit SerializacionTest;\r
+\r
+interface\r
+\r
+uses\r
+  RegExpr,\r
+  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\r
+  StdCtrls;\r
+\r
+type\r
+  TFormTest = class(TForm)\r
+    edtOX: TEdit;\r
+    Label1: TLabel;\r
+    Label2: TLabel;\r
+    edtOY: TEdit;\r
+    Label3: TLabel;\r
+    edtOZ: TEdit;\r
+    Label4: TLabel;\r
+    Label5: TLabel;\r
+    Label6: TLabel;\r
+    Label7: TLabel;\r
+    edtRX: TEdit;\r
+    edtRY: TEdit;\r
+    edtRZ: TEdit;\r
+    Label8: TLabel;\r
+    Label9: TLabel;\r
+    btnSerializar: TButton;\r
+    btnRecuperar: TButton;\r
+    memoSerializado: TMemo;\r
+    GroupBox1: TGroupBox;\r
+    memoHistorial: TMemo;\r
+    btnGuardarHistorial: TButton;\r
+    sdlgHistorial: TSaveDialog;\r
+    Label10: TLabel;\r
+    edtOID: TEdit;\r
+    edtRID: TEdit;\r
+    Label11: TLabel;\r
+    procedure btnSerializarClick(Sender: TObject);\r
+    procedure btnRecuperarClick(Sender: TObject);\r
+    procedure btnGuardarHistorialClick(Sender: TObject);\r
+  private\r
+    { Private declarations }\r
+  public\r
+    { Public declarations }\r
+  end;\r
+\r
+var\r
+  FormTest: TFormTest;\r
+\r
+implementation\r
+\r
+{$R *.DFM}\r
+\r
+uses\r
+  Vectores;\r
+\r
+procedure TFormTest.btnSerializarClick(Sender: TObject);\r
+var\r
+  v: cVector;\r
+begin\r
+  v := cVector.create( StrToFloat( edtOX.Text ),\r
+                       StrToFloat( edtOY.Text ),\r
+                       StrToFloat( edtOZ.Text ) );\r
+  edtOID.Text := v.mGetID;\r
+  memoSerializado.Lines.Text := v.mSerializar;\r
+  memoHistorial.Lines.Append( 'Serializando:' );\r
+  memoHistorial.Lines.Append( '  (' + FloatToStr( v.mGetX ) + ' ; ' +\r
+                                      FloatToStr( v.mGetY ) + ' ; ' +\r
+                                      FloatToStr( v.mGetZ ) + '): ' +\r
+                                      v.mGetID);\r
+  memoHistorial.Lines.Append( '  =' );\r
+  memoHistorial.Lines.Append( '  "' + memoSerializado.Lines.Text + '"' );\r
+  memoHistorial.Lines.Append( '' );\r
+  v.free;\r
+end;\r
+\r
+procedure TFormTest.btnRecuperarClick(Sender: TObject);\r
+var\r
+  v: cVector;\r
+begin\r
+  v := cVector.crearDeSerializado( memoSerializado.Lines.Text );\r
+  edtRX.Text := FloatToStr( v.mGetX );\r
+  edtRY.Text := FloatToStr( v.mGetY );\r
+  edtRZ.Text := FloatToStr( v.mGetZ );\r
+  edtRID.Text := v.mGetID;\r
+  memoHistorial.Lines.Append( 'Recuperando:' );\r
+  memoHistorial.Lines.Append( '  "' + memoSerializado.Lines.Text + '"' );\r
+  memoHistorial.Lines.Append( '  =' );\r
+  memoHistorial.Lines.Append( '  (' + edtRX.Text + ' ; ' +\r
+                                      edtRY.Text + ' ; ' +\r
+                                      edtRZ.Text + '): ' +\r
+                                      edtRID.Text );\r
+  memoHistorial.Lines.Append( '' );\r
+  v.free;\r
+end;\r
+\r
+procedure TFormTest.btnGuardarHistorialClick(Sender: TObject);\r
+begin\r
+  if sdlgHistorial.Execute then\r
+    memoHistorial.Lines.SaveToFile( sdlgHistorial.FileName );\r
+end;\r
+\r
+end.\r
diff --git a/src/test/cn/SerializationTest.cfg b/src/test/cn/SerializationTest.cfg
new file mode 100644 (file)
index 0000000..983eb9b
--- /dev/null
@@ -0,0 +1,34 @@
+-$A+\r
+-$B-\r
+-$C-\r
+-$D-\r
+-$E-\r
+-$F-\r
+-$G+\r
+-$H+\r
+-$I+\r
+-$J+\r
+-$K-\r
+-$L-\r
+-$M-\r
+-$N+\r
+-$O+\r
+-$P+\r
+-$Q-\r
+-$R-\r
+-$S-\r
+-$T-\r
+-$U-\r
+-$V+\r
+-$W-\r
+-$X+\r
+-$Y-\r
+-$Z1\r
+-cg\r
+-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;\r
+-H+\r
+-W+\r
+-M\r
+-$M16384,1048576\r
+-K$00400000\r
+-N..\..\..\dcu\r
diff --git a/src/test/cn/SerializationTest.dof b/src/test/cn/SerializationTest.dof
new file mode 100644 (file)
index 0000000..3e381da
--- /dev/null
@@ -0,0 +1,98 @@
+[Compiler]\r
+A=1\r
+B=0\r
+C=0\r
+D=0\r
+E=0\r
+F=0\r
+G=1\r
+H=1\r
+I=1\r
+J=1\r
+K=0\r
+L=0\r
+M=0\r
+N=1\r
+O=1\r
+P=1\r
+Q=0\r
+R=0\r
+S=0\r
+T=0\r
+U=0\r
+V=1\r
+W=0\r
+X=1\r
+Y=0\r
+Z=1\r
+ShowHints=1\r
+ShowWarnings=1\r
+UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;\r
+\r
+[Linker]\r
+MapFile=0\r
+OutputObjs=0\r
+ConsoleApp=1\r
+DebugInfo=0\r
+RemoteSymbols=0\r
+MinStackSize=16384\r
+MaxStackSize=1048576\r
+ImageBase=4194304\r
+ExeDescription=\r
+\r
+[Directories]\r
+OutputDir=\r
+UnitOutputDir=..\..\..\dcu\r
+PackageDLLOutputDir=\r
+PackageDCPOutputDir=\r
+SearchPath=\r
+Packages=VCL40;VCLX40;VCLDB40;VCLDBX40;VCLSMP40;QRPT40;TEEUI40;TEEDB40;TEE40;DSS40;ibevnt40;VCLMID40;NMFAST40;INETDB40;INET40\r
+Conditionals=\r
+DebugSourceDirs=\r
+UsePackages=0\r
+\r
+[Parameters]\r
+RunParams=\r
+HostApplication=\r
+\r
+[Version Info]\r
+IncludeVerInfo=1\r
+AutoIncBuild=0\r
+MajorVer=1\r
+MinorVer=0\r
+Release=0\r
+Build=0\r
+Debug=0\r
+PreRelease=0\r
+Special=0\r
+Private=1\r
+DLL=0\r
+Locale=11274\r
+CodePage=1252\r
+\r
+[Version Info Keys]\r
+CompanyName=Grupo 10\r
+FileDescription=AlgoWars - Prueba de caja negra\r
+FileVersion=1.0.0.0\r
+InternalName=SerializationTest\r
+LegalCopyright=Copyleft - GPL\r
+LegalTrademarks=\r
+OriginalFilename=SerializationTest.exe\r
+ProductName=AlgoWars\r
+ProductVersion=0.8.0.0\r
+Comments=Trabajo Práctico de Algoritmos y Programación III. Universidad de Buenos Aires - Facultad de Ingeniería. Prueba de caja negra en métodos de serialización de la clase cVector.\r
+PrivateBuild=Modulo para pruebas de caja negra\r
+\r
+[HistoryLists\hlConditionals]\r
+Count=1\r
+Item0=DebugAlgoWars\r
+\r
+[HistoryLists\hlUnitAliases]\r
+Count=1\r
+Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;\r
+\r
+[HistoryLists\hlUnitOutputDirectory]\r
+Count=3\r
+Item0=..\..\dcu\r
+Item1=..\..\..\dcu\r
+Item2=../../dcu\r
diff --git a/src/test/cn/SerializationTest.dpr b/src/test/cn/SerializationTest.dpr
new file mode 100644 (file)
index 0000000..57a6f50
--- /dev/null
@@ -0,0 +1,19 @@
+program SerializationTest;\r
+\r
+uses\r
+  Forms,\r
+  Vectores in '..\..\Vectores.pas',\r
+  SerializacionTest in 'SerializacionTest.pas' {FormTest},\r
+  Objeto in '..\..\Objeto.pas',\r
+  ObjetoPersistente in '..\..\ObjetoPersistente.pas',\r
+  Tipos in '..\..\Tipos.pas',\r
+  RegExpr in '..\..\RegExpr.pas';\r
+\r
+{$R *.RES}\r
+\r
+begin\r
+  Application.Initialize;\r
+  Application.Title := 'Prueba de Caja Negra: Serialización de Vectores';\r
+  Application.CreateForm(TFormTest, FormTest);\r
+  Application.Run;\r
+end.\r
diff --git a/src/test/cn/SerializationTest.dsk b/src/test/cn/SerializationTest.dsk
new file mode 100644 (file)
index 0000000..5a32590
--- /dev/null
@@ -0,0 +1,68 @@
+[Main Window]\r
+Create=1\r
+Visible=1\r
+State=0\r
+Left=0\r
+Top=0\r
+Width=1024\r
+Height=105\r
+MaxLeft=-1\r
+MaxTop=-1\r
+ClientWidth=1016\r
+ClientHeight=78\r
+\r
+[PropertyInspector]\r
+TBDockHeight=494\r
+LRDockWidth=190\r
+SplitPos=85\r
+\r
+[ProjectManager]\r
+TBDockHeight=303\r
+LRDockWidth=336\r
+\r
+[Modules]\r
+Count=0\r
+EditWindowCount=0\r
+\r
+[D:\develop\delphi\algowars\src\test\caja_negra\ProjectGroup1.bpg]\r
+FormState=0\r
+FormOnTop=0\r
+\r
+[D:\develop\delphi\algowars\src\test\caja_negra\SerializationTest.dpr]\r
+FormState=0\r
+FormOnTop=0\r
+\r
+[DockHosts]\r
+DockHostCount=0\r
+\r
+[Watches]\r
+Count=0\r
+\r
+[Breakpoints]\r
+Count=0\r
+\r
+[AddressBreakpoints]\r
+Count=0\r
+\r
+[PVCS Browser]\r
+Left=236\r
+Top=105\r
+Width=625\r
+Height=393\r
+State=0\r
+Visible=0\r
+\r
+[PVCS VDiff]\r
+Left=257\r
+Top=160\r
+Width=591\r
+Height=608\r
+Layout=1\r
+Orientation=1\r
+State=0\r
+Visible=0\r
+File1Color=16711680\r
+File2Color=255\r
+SpaceColor=16776960\r
+TextColor=0\r
+\r
diff --git a/src/test/cn/SerializationTest.res b/src/test/cn/SerializationTest.res
new file mode 100644 (file)
index 0000000..5b88bf2
Binary files /dev/null and b/src/test/cn/SerializationTest.res differ
diff --git a/src/test/cn/negra..txt b/src/test/cn/negra..txt
new file mode 100644 (file)
index 0000000..34da7bd
--- /dev/null
@@ -0,0 +1,69 @@
+Recuperando:\r
+  "<X> 23,56  </X>\r
+<Y> 25,4E3 </Y>\r
+<Z> -12e-4 </Z>\r
+"\r
+  =\r
+  (23,56 ; 25400 ; -0,0012)\r
+\r
+Serializando:\r
+  (0 ; 0 ; 0)\r
+  =\r
+  "<X>0</X><Y>0</Y><Z>0</Z>"\r
+\r
+Recuperando:\r
+  "<X>0</X><Y>0</Y><Z>0</Z>"\r
+  =\r
+  (0 ; 0 ; 0)\r
+\r
+Serializando:\r
+  (-9,657E-5 ; 98,355 ; 25)\r
+  =\r
+  "<X>-9,657E-5</X><Y>98,355</Y><Z>25</Z>"\r
+\r
+Recuperando:\r
+  "<X>-9,657E-5</X><Y>98,355</Y><Z>25</Z>"\r
+  =\r
+  (-9,657E-5 ; 98,355 ; 25)\r
+\r
+Serializando:\r
+  (-9,657E-5 ; 1E27 ; -1E-12)\r
+  =\r
+  "<X>-9,657E-5</X><Y>1E27</Y><Z>-1E-12</Z>"\r
+\r
+Recuperando:\r
+  "<X>-9,657E-5</X><Y>1E27</Y><Z>-1E-12</Z>"\r
+  =\r
+  (-9,657E-5 ; 1E27 ; -1E-12)\r
+\r
+Serializando:\r
+  (-9,657E-5 ; 1E27 ; 1E99)\r
+  =\r
+  "<X>-9,657E-5</X><Y>1E27</Y><Z>1E99</Z>"\r
+\r
+Recuperando:\r
+  "<X>-9,657E-5</X><Y>1E27</Y><Z>1E99</Z>"\r
+  =\r
+  (-9,657E-5 ; 1E27 ; 1E99)\r
+\r
+Serializando:\r
+  (-9,657E-5 ; 1,1111E-38 ; 1E99)\r
+  =\r
+  "<X>-9,657E-5</X><Y>1,1111E-38</Y><Z>1E99</Z>"\r
+\r
+Recuperando:\r
+  "<X>-9,657E-5</X><Y>1,1111E-38</Y><Z>1E99</Z>"\r
+  =\r
+  (-9,657E-5 ; 1,1111E-38 ; 1E99)\r
+\r
+Serializando:\r
+  (1E-400 ; 33987336 ; 98867543)\r
+  =\r
+  "<X>1E-400</X><Y>33987336</Y><Z>98867543</Z>"\r
+\r
+Recuperando:\r
+  "<X>1E-400</X><Y>33987336</Y><Z>98867543</Z>"\r
+  =\r
+  (1E-400 ; 33987336 ; 98867543)\r
+\r
+\r
diff --git a/src/test/serializado.eaw b/src/test/serializado.eaw
new file mode 100644 (file)
index 0000000..7f5dd7e
--- /dev/null
@@ -0,0 +1,751 @@
+<vector>\r
+  <id>ABCDEF</id>\r
+  <X>0</X>\r
+  <Y>1</Y>\r
+  <Z>-1</Z>\r
+</vector>\r
+\r
+<coordenadas>\r
+  <id>000001</id>\r
+  <i>\r
+    <id>000002</id>\r
+    <X>1</X>\r
+    <Y>0</Y>\r
+    <Z>0</Z>\r
+  </i>\r
+  <j>\r
+    <id>000003</id>\r
+    <X>0</X>\r
+    <Y>1</Y>\r
+    <Z>0</Z>\r
+  </j>\r
+  <k>\r
+    <id>000004</id>\r
+    <X>0</X>\r
+    <Y>0</Y>\r
+    <Z>1</Z>\r
+  </k>\r
+</coordenadas>\r
+\r
+<ObjetoVolador>\r
+  <id>BC60F8</id>\r
+  <posicion>\r
+    <id>000011</id>\r
+    <X>11</X>\r
+    <Y>-2</Y>\r
+    <Z>-21</Z>\r
+  </posicion>\r
+  <velocidad>0,025</velocidad>\r
+  <potencia>5</potencia>\r
+  <energia>150</energia>\r
+  <dimension>25</dimension>\r
+  <coordenadas>\r
+    <id>000100</id>\r
+    <i>\r
+      <id>000012</id>\r
+      <X>1</X>\r
+      <Y>0</Y>\r
+      <Z>0</Z>\r
+    </i>\r
+    <j>\r
+      <id>000013</id>\r
+      <X>0</X>\r
+      <Y>1</Y>\r
+      <Z>0</Z>\r
+    </j>\r
+    <k>\r
+      <id>000014</id>\r
+      <X>0</X>\r
+      <Y>0</Y>\r
+      <Z>1</Z>\r
+    </k>\r
+  </coordenadas>\r
+</ObjetoVolador>\r
+\r
+<laser>\r
+  <id>BC2DA0</id>\r
+  <posicion>\r
+    <id>BC6E44</id>\r
+    <X>4563</X>\r
+    <Y>1345</Y>\r
+    <Z>3545</Z>\r
+  </posicion>\r
+  <velocidad>0,2</velocidad>\r
+  <potencia>10</potencia>\r
+  <energia>120</energia>\r
+  <dimension>1</dimension>\r
+  <coordenadas>\r
+    <id>BC2E08</id>\r
+    <i>\r
+      <id>BC2E34</id>\r
+      <X>1</X>\r
+      <Y>0</Y>\r
+      <Z>0</Z>\r
+    </i>\r
+    <j>\r
+      <id>BC6DD8</id>\r
+      <X>0</X>\r
+      <Y>1</Y>\r
+      <Z>0</Z>\r
+    </j>\r
+    <k>\r
+      <id>BC6E04</id>\r
+      <X>0</X>\r
+      <Y>0</Y>\r
+      <Z>1</Z>\r
+    </k>\r
+  </coordenadas>\r
+  <duracion>3000</duracion>\r
+  <alcance>1200</alcance>\r
+  <velmaxima>0,4</velmaxima>\r
+</laser>\r
+\r
+<misil>\r
+  <id>BC3208</id>\r
+  <posicion>\r
+    <id>BC331C</id>\r
+    <X>0</X>\r
+    <Y>0</Y>\r
+    <Z>0</Z>\r
+  </posicion>\r
+  <velocidad>0</velocidad>\r
+  <potencia>20</potencia>\r
+  <energia>1</energia>\r
+  <dimension>0,5</dimension>\r
+  <coordenadas>\r
+    <id>BC6E98</id>\r
+    <i>\r
+      <id>BC325C</id>\r
+      <X>1</X>\r
+      <Y>0</Y>\r
+      <Z>0</Z>\r
+    </i>\r
+    <j>\r
+      <id>BC329C</id>\r
+      <X>0</X>\r
+      <Y>1</Y>\r
+      <Z>0</Z>\r
+    </j>\r
+    <k>\r
+      <id>BC32DC</id>\r
+      <X>0</X>\r
+      <Y>0</Y>\r
+      <Z>1</Z>\r
+    </k>\r
+  </coordenadas>\r
+  <duracion>5000</duracion>\r
+  <alcance>1500</alcance>\r
+  <velmaxima>0,3</velmaxima>\r
+</misil>\r
+\r
+<misildirigido>\r
+  <id>BC345C</id>\r
+  <posicion>\r
+    <id>BC35C0</id>\r
+    <X>0</X>\r
+    <Y>0</Y>\r
+    <Z>0</Z>\r
+  </posicion>\r
+  <velocidad>0,25</velocidad>\r
+  <potencia>30</potencia>\r
+  <energia>1</energia>\r
+  <dimension>0,7</dimension>\r
+  <coordenadas>\r
+    <id>BC34D4</id>\r
+    <i>\r
+      <id>BC3500</id>\r
+      <X>0,408248290463863016</X>\r
+      <Y>0,816496580927726033</Y>\r
+      <Z>-0,408248290463863016</Z>\r
+    </i>\r
+    <j>\r
+      <id>BC3540</id>\r
+      <X>-0,894427190999915879</X>\r
+      <Y>0,447213595499957939</Y>\r
+      <Z>0</Z>\r
+    </j>\r
+    <k>\r
+      <id>BC3580</id>\r
+      <X>0,182574185835055371</X>\r
+      <Y>0,365148371670110742</Y>\r
+      <Z>0,912870929175276856</Z>\r
+    </k>\r
+  </coordenadas>\r
+  <duracion>20000</duracion>\r
+  <alcance>2000</alcance>\r
+  <velmaxima>0,25</velmaxima>\r
+  <objetivo class=cLaser>\r
+    <id>BC2DA0</id>\r
+    <posicion>\r
+      <id>BC6E44</id>\r
+      <X>4563</X>\r
+      <Y>1345</Y>\r
+      <Z>3545</Z>\r
+    </posicion>\r
+    <velocidad>0,2</velocidad>\r
+    <potencia>10</potencia>\r
+    <energia>120</energia>\r
+    <dimension>1</dimension>\r
+    <coordenadas>\r
+      <id>BC2E08</id>\r
+      <i>\r
+        <id>BC2E34</id>\r
+        <X>1</X>\r
+        <Y>0</Y>\r
+        <Z>0</Z>\r
+      </i>\r
+      <j>\r
+        <id>BC6DD8</id>\r
+        <X>0</X>\r
+        <Y>1</Y>\r
+        <Z>0</Z>\r
+      </j>\r
+      <k>\r
+        <id>BC6E04</id>\r
+        <X>0</X>\r
+        <Y>0</Y>\r
+        <Z>1</Z>\r
+      </k>\r
+    </coordenadas>\r
+    <duracion>3000</duracion>\r
+    <alcance>1200</alcance>\r
+    <velmaxima>0,4</velmaxima>\r
+  </objetivo>\r
+  <lockarea>2000</lockarea>\r
+</misildirigido>\r
+\r
+<filtro>\r
+  <id>BC82B8</id>\r
+  <observador class=cMisil>\r
+    <id>BC3208</id>\r
+    <posicion>\r
+      <id>BC331C</id>\r
+      <X>0</X>\r
+      <Y>0</Y>\r
+      <Z>0</Z>\r
+    </posicion>\r
+    <velocidad>0</velocidad>\r
+    <potencia>20</potencia>\r
+    <energia>1</energia>\r
+    <dimension>0,5</dimension>\r
+    <coordenadas>\r
+      <id>BC6E98</id>\r
+      <i>\r
+        <id>BC325C</id>\r
+        <X>1</X>\r
+        <Y>0</Y>\r
+        <Z>0</Z>\r
+      </i>\r
+      <j>\r
+        <id>BC329C</id>\r
+        <X>0</X>\r
+        <Y>1</Y>\r
+        <Z>0</Z>\r
+      </j>\r
+      <k>\r
+        <id>BC32DC</id>\r
+        <X>0</X>\r
+        <Y>0</Y>\r
+        <Z>1</Z>\r
+      </k>\r
+    </coordenadas>\r
+    <duracion>5000</duracion>\r
+    <alcance>1500</alcance>\r
+    <velmaxima>0,3</velmaxima>\r
+  </observador>\r
+  <radiomaximo>5000</radiomaximo>\r
+  <radiominimo>0,5</radiominimo>\r
+  <cosapertura>0,707106781186547524</cosapertura>\r
+</filtro>\r
+\r
+<nave>\r
+  <id>BD0AA4</id>\r
+  <posicion>\r
+  <id>BC63D4</id>\r
+    <X>0</X>\r
+    <Y>0</Y>\r
+    <Z>0</Z>\r
+  </posicion>\r
+  <velocidad>0</velocidad>\r
+  <potencia>1</potencia>\r
+  <energia>100</energia>\r
+  <dimension>5</dimension>\r
+  <coordenadas>\r
+    <id>BD0898</id>\r
+    <i>\r
+      <id>BCDB38</id>\r
+      <X>1</X>\r
+      <Y>0</Y>\r
+      <Z>0</Z>\r
+    </i>\r
+    <j>\r
+      <id>BCB5F8</id>\r
+      <X>0</X>\r
+      <Y>1</Y>\r
+      <Z>0</Z>\r
+    </j>\r
+    <k>\r
+      <id>BC6394</id>\r
+      <X>0</X>\r
+      <Y>0</Y>\r
+      <Z>1</Z>\r
+    </k>\r
+  </coordenadas>\r
+  <misiles>0</misiles>\r
+  <misilesdirigidos>0</misilesdirigidos>\r
+  <velmaxima>0,2</velmaxima>\r
+  <retardolaser>1000</retardolaser>\r
+  <retardomisil>60000</retardomisil>\r
+  <retardomisdir>180000</retardomisdir>\r
+  <retardolasercont>0</retardolasercont>\r
+  <retardomisilcont>0</retardomisilcont>\r
+  <retardomisdircont>0</retardomisdircont>\r
+</nave>\r
+\r
+<naveenemiga>\r
+  <id>BD0AA5</id>\r
+  <posicion>\r
+  <id>BC63D5</id>\r
+    <X>0</X>\r
+    <Y>0</Y>\r
+    <Z>0</Z>\r
+  </posicion>\r
+  <velocidad>0</velocidad>\r
+  <potencia>1</potencia>\r
+  <energia>100</energia>\r
+  <dimension>5</dimension>\r
+  <coordenadas>\r
+    <id>BD0899</id>\r
+    <i>\r
+      <id>BCDB39</id>\r
+      <X>1</X>\r
+      <Y>0</Y>\r
+      <Z>0</Z>\r
+    </i>\r
+    <j>\r
+      <id>BCB5F0</id>\r
+      <X>0</X>\r
+      <Y>1</Y>\r
+      <Z>0</Z>\r
+    </j>\r
+    <k>\r
+      <id>BC6399</id>\r
+      <X>0</X>\r
+      <Y>0</Y>\r
+      <Z>1</Z>\r
+    </k>\r
+  </coordenadas>\r
+  <misiles>0</misiles>\r
+  <misilesdirigidos>0</misilesdirigidos>\r
+  <velmaxima>0,2</velmaxima>\r
+  <retardolaser>1000</retardolaser>\r
+  <retardomisil>60000</retardomisil>\r
+  <retardomisdir>180000</retardomisdir>\r
+  <retardolasercont>0</retardolasercont>\r
+  <retardomisilcont>0</retardomisilcont>\r
+  <retardomisdircont>0</retardomisdircont>\r
+  <camporadar>3000</camporadar>\r
+</naveenemiga>\r
+\r
+<navepesada>\r
+  <id>BD0AA6</id>\r
+  <posicion>\r
+  <id>BC63D6</id>\r
+    <X>0</X>\r
+    <Y>0</Y>\r
+    <Z>0</Z>\r
+  </posicion>\r
+  <velocidad>0</velocidad>\r
+  <potencia>1</potencia>\r
+  <energia>100</energia>\r
+  <dimension>5</dimension>\r
+  <coordenadas>\r
+    <id>BD0895</id>\r
+    <i>\r
+      <id>BCDB34</id>\r
+      <X>1</X>\r
+      <Y>0</Y>\r
+      <Z>0</Z>\r
+    </i>\r
+    <j>\r
+      <id>BCB5F3</id>\r
+      <X>0</X>\r
+      <Y>1</Y>\r
+      <Z>0</Z>\r
+    </j>\r
+    <k>\r
+      <id>BC6339</id>\r
+      <X>0</X>\r
+      <Y>0</Y>\r
+      <Z>1</Z>\r
+    </k>\r
+  </coordenadas>\r
+  <misiles>0</misiles>\r
+  <misilesdirigidos>0</misilesdirigidos>\r
+  <velmaxima>0,2</velmaxima>\r
+  <retardolaser>1000</retardolaser>\r
+  <retardomisil>60000</retardomisil>\r
+  <retardomisdir>180000</retardomisdir>\r
+  <retardolasercont>0</retardolasercont>\r
+  <retardomisilcont>0</retardomisilcont>\r
+  <retardomisdircont>0</retardomisdircont>\r
+  <camporadar>3000</camporadar>\r
+  <campominimo>600</campominimo>\r
+</navepesada>\r
+\r
+<naveliviana>\r
+  <id>BD0Ad5</id>\r
+  <posicion>\r
+  <id>BC63e5</id>\r
+    <X>0</X>\r
+    <Y>0</Y>\r
+    <Z>0</Z>\r
+  </posicion>\r
+  <velocidad>0</velocidad>\r
+  <potencia>1</potencia>\r
+  <energia>100</energia>\r
+  <dimension>5</dimension>\r
+  <coordenadas>\r
+    <id>Ba0899</id>\r
+    <i>\r
+      <id>aCDB39</id>\r
+      <X>1</X>\r
+      <Y>0</Y>\r
+      <Z>0</Z>\r
+    </i>\r
+    <j>\r
+      <id>aCB5F0</id>\r
+      <X>0</X>\r
+      <Y>1</Y>\r
+      <Z>0</Z>\r
+    </j>\r
+    <k>\r
+      <id>aC6399</id>\r
+      <X>0</X>\r
+      <Y>0</Y>\r
+      <Z>1</Z>\r
+    </k>\r
+  </coordenadas>\r
+  <misiles>0</misiles>\r
+  <misilesdirigidos>0</misilesdirigidos>\r
+  <velmaxima>0,2</velmaxima>\r
+  <retardolaser>1000</retardolaser>\r
+  <retardomisil>60000</retardomisil>\r
+  <retardomisdir>180000</retardomisdir>\r
+  <retardolasercont>0</retardolasercont>\r
+  <retardomisilcont>0</retardomisilcont>\r
+  <retardomisdircont>0</retardomisdircont>\r
+  <camporadar>3000</camporadar>\r
+  <campominimo>400</campominimo>\r
+</naveliviana>\r
+\r
+<naveespia>\r
+  <id>BD0bA5</id>\r
+  <posicion>\r
+  <id>BC6bD5</id>\r
+    <X>0</X>\r
+    <Y>0</Y>\r
+    <Z>0</Z>\r
+  </posicion>\r
+  <velocidad>0</velocidad>\r
+  <potencia>1</potencia>\r
+  <energia>100</energia>\r
+  <dimension>5</dimension>\r
+  <coordenadas>\r
+    <id>BDb899</id>\r
+    <i>\r
+      <id>BbDB39</id>\r
+      <X>1</X>\r
+      <Y>0</Y>\r
+      <Z>0</Z>\r
+    </i>\r
+    <j>\r
+      <id>BbB5F0</id>\r
+      <X>0</X>\r
+      <Y>1</Y>\r
+      <Z>0</Z>\r
+    </j>\r
+    <k>\r
+      <id>BCb399</id>\r
+      <X>0</X>\r
+      <Y>0</Y>\r
+      <Z>1</Z>\r
+    </k>\r
+  </coordenadas>\r
+  <misiles>0</misiles>\r
+  <misilesdirigidos>0</misilesdirigidos>\r
+  <velmaxima>0,2</velmaxima>\r
+  <retardolaser>1000</retardolaser>\r
+  <retardomisil>60000</retardomisil>\r
+  <retardomisdir>180000</retardomisdir>\r
+  <retardolasercont>0</retardolasercont>\r
+  <retardomisilcont>0</retardomisilcont>\r
+  <retardomisdircont>0</retardomisdircont>\r
+  <camporadar>3000</camporadar>\r
+  <posicionenemiga>\r
+    <id>BCDBb3</id>\r
+    <X>1</X>\r
+    <Y>0</Y>\r
+    <Z>0</Z>\r
+  </posicionenemiga>\r
+</naveespia>\r
+\r
+<navepropia>\r
+  <id>BD0FA4</id>\r
+  <posicion>\r
+  <id>BC6FD4</id>\r
+    <X>10</X>\r
+    <Y>20</Y>\r
+    <Z>30</Z>\r
+  </posicion>\r
+  <velocidad>0,1</velocidad>\r
+  <potencia>10</potencia>\r
+  <energia>300</energia>\r
+  <dimension>50</dimension>\r
+  <coordenadas>\r
+    <id>BDF898</id>\r
+    <i>\r
+      <id>BFDB38</id>\r
+      <X>1</X>\r
+      <Y>0</Y>\r
+      <Z>0</Z>\r
+    </i>\r
+    <j>\r
+      <id>FCB5F8</id>\r
+      <X>0</X>\r
+      <Y>1</Y>\r
+      <Z>0</Z>\r
+    </j>\r
+    <k>\r
+      <id>BF6394</id>\r
+      <X>0</X>\r
+      <Y>0</Y>\r
+      <Z>1</Z>\r
+    </k>\r
+  </coordenadas>\r
+  <misiles>0</misiles>\r
+  <misilesdirigidos>0</misilesdirigidos>\r
+  <velmaxima>0,25</velmaxima>\r
+  <retardolaser>1000</retardolaser>\r
+  <retardomisil>60000</retardomisil>\r
+  <retardomisdir>180000</retardomisdir>\r
+  <retardolasercont>0</retardolasercont>\r
+  <retardomisilcont>0</retardomisilcont>\r
+  <retardomisdircont>0</retardomisdircont>\r
+  <lockeado class=cNaveLiviana>\r
+    <id>BD0Ad5</id>\r
+    <posicion>\r
+    <id>BC63e5</id>\r
+      <X>0</X>\r
+      <Y>0</Y>\r
+      <Z>0</Z>\r
+    </posicion>\r
+    <velocidad>0</velocidad>\r
+    <potencia>1</potencia>\r
+    <energia>100</energia>\r
+    <dimension>5</dimension>\r
+    <coordenadas>\r
+      <id>Ba0899</id>\r
+      <i>\r
+        <id>aCDB39</id>\r
+        <X>1</X>\r
+        <Y>0</Y>\r
+        <Z>0</Z>\r
+      </i>\r
+      <j>\r
+        <id>aCB5F0</id>\r
+        <X>0</X>\r
+        <Y>1</Y>\r
+        <Z>0</Z>\r
+      </j>\r
+      <k>\r
+        <id>aC6399</id>\r
+        <X>0</X>\r
+        <Y>0</Y>\r
+        <Z>1</Z>\r
+      </k>\r
+    </coordenadas>\r
+    <misiles>0</misiles>\r
+    <misilesdirigidos>0</misilesdirigidos>\r
+    <velmaxima>0,2</velmaxima>\r
+    <retardolaser>1000</retardolaser>\r
+    <retardomisil>60000</retardomisil>\r
+    <retardomisdir>180000</retardomisdir>\r
+    <retardolasercont>0</retardolasercont>\r
+    <retardomisilcont>0</retardomisilcont>\r
+    <retardomisdircont>0</retardomisdircont>\r
+    <camporadar>3000</camporadar>\r
+    <campominimo>400</campominimo>\r
+  </lockeado>\r
+  <armaselec>7</armaselec>\r
+  <lockfiltro>\r
+    <id>BCF2B8</id>\r
+    <observador class=cMeteorito>\r
+      <id>BC60FF</id>\r
+      <posicion>\r
+        <id>00F011</id>\r
+        <X>11</X>\r
+        <Y>-2</Y>\r
+        <Z>-21</Z>\r
+      </posicion>\r
+      <velocidad>0,025</velocidad>\r
+      <potencia>5</potencia>\r
+      <energia>150</energia>\r
+      <dimension>25</dimension>\r
+      <coordenadas>\r
+        <id>0001F0</id>\r
+        <i>\r
+          <id>000F12</id>\r
+          <X>1</X>\r
+          <Y>0</Y>\r
+          <Z>0</Z>\r
+        </i>\r
+        <j>\r
+          <id>0000F3</id>\r
+          <X>0</X>\r
+          <Y>1</Y>\r
+          <Z>0</Z>\r
+        </j>\r
+        <k>\r
+          <id>F0001F</id>\r
+          <X>0</X>\r
+          <Y>0</Y>\r
+          <Z>1</Z>\r
+        </k>\r
+      </coordenadas>\r
+    </observador>\r
+    <radiomaximo>5000</radiomaximo>\r
+    <radiominimo>0,5</radiominimo>\r
+    <cosapertura>0,707106781186547524</cosapertura>\r
+  </lockfiltro>\r
+</navepropia>\r
+\r
+<navepropia>\r
+  <id>BD0FA4</id>\r
+  <posicion>\r
+    <id>BC6FD4</id>\r
+    <X>10</X>\r
+    <Y>20</Y>\r
+    <Z>30</Z>\r
+  </posicion>\r
+  <velocidad>0,1</velocidad>\r
+  <potencia>10</potencia>\r
+  <energia>300</energia>\r
+  <dimension>50</dimension>\r
+  <coordenadas>\r
+    <id>BDF898</id>\r
+    <i>\r
+      <id>BFDB38</id>\r
+      <X>1</X>\r
+      <Y>0</Y>\r
+      <Z>0</Z>\r
+    </i>\r
+    <j>\r
+      <id>FCB5F8</id>\r
+      <X>0</X>\r
+      <Y>1</Y>\r
+      <Z>0</Z>\r
+    </j>\r
+    <k>\r
+      <id>BF6394</id>\r
+      <X>0</X>\r
+      <Y>0</Y>\r
+      <Z>1</Z>\r
+    </k>\r
+  </coordenadas>\r
+  <misiles>0</misiles>\r
+  <misilesdirigidos>0</misilesdirigidos>\r
+  <velmaxima>0,25</velmaxima>\r
+  <retardolaser>1000</retardolaser>\r
+  <retardomisil>60000</retardomisil>\r
+  <retardomisdir>180000</retardomisdir>\r
+  <retardolasercont>0</retardolasercont>\r
+  <retardomisilcont>0</retardomisilcont>\r
+  <retardomisdircont>0</retardomisdircont>\r
+  <lockeado class=cNaveLiviana>\r
+    <id>BD0Ad5</id>\r
+    <posicion>\r
+      <id>BC63e5</id>\r
+      <X>0</X>\r
+      <Y>0</Y>\r
+      <Z>0</Z>\r
+    </posicion>\r
+    <velocidad>0</velocidad>\r
+    <potencia>1</potencia>\r
+    <energia>100</energia>\r
+    <dimension>5</dimension>\r
+    <coordenadas>\r
+      <id>Ba0899</id>\r
+      <i>\r
+        <id>aCDB39</id>\r
+        <X>1</X>\r
+        <Y>0</Y>\r
+        <Z>0</Z>\r
+      </i>\r
+      <j>\r
+        <id>aCB5F0</id>\r
+        <X>0</X>\r
+        <Y>1</Y>\r
+        <Z>0</Z>\r
+      </j>\r
+      <k>\r
+        <id>aC6399</id>\r
+        <X>0</X>\r
+        <Y>0</Y>\r
+        <Z>1</Z>\r
+      </k>\r
+    </coordenadas>\r
+    <misiles>0</misiles>\r
+    <misilesdirigidos>0</misilesdirigidos>\r
+    <velmaxima>0,2</velmaxima>\r
+    <retardolaser>1000</retardolaser>\r
+    <retardomisil>60000</retardomisil>\r
+    <retardomisdir>180000</retardomisdir>\r
+    <retardolasercont>0</retardolasercont>\r
+    <retardomisilcont>0</retardomisilcont>\r
+    <retardomisdircont>0</retardomisdircont>\r
+    <camporadar>3000</camporadar>\r
+    <campominimo>400</campominimo>\r
+  </lockeado>\r
+  <armaselec>7</armaselec>\r
+  <lockfiltro>\r
+    <id>BCF2B8</id>\r
+    <observador class=cMeteorito>\r
+      <id>BD03B0</id>\r
+      <posicion>\r
+        <id>BD0478</id>\r
+        <X>0</X>\r
+        <Y>0</Y>\r
+        <Z>0</Z>\r
+      </posicion>\r
+      <velocidad>0</velocidad>\r
+      <potencia>5</potencia>\r
+      <energia>20</energia>\r
+      <dimension>5</dimension>\r
+      <coordenadas>\r
+        <id>BD45B8</id>\r
+        <i>\r
+          <id>BFC81C</id>\r
+          <X>1</X>\r
+          <Y>0</Y>\r
+          <Z>0</Z>\r
+        </i>\r
+        <j>\r
+          <id>BD03F8</id>\r
+          <X>0</X>\r
+          <Y>1</Y>\r
+          <Z>0</Z>\r
+        </j>\r
+        <k>\r
+          <id>BD0438</id>\r
+          <X>0</X>\r
+          <Y>0</Y>\r
+          <Z>1</Z>\r
+        </k>\r
+      </coordenadas>\r
+    </observador>\r
+    <radiomaximo>5000</radiomaximo>\r
+    <radiominimo>0,5</radiominimo>\r
+    <cosapertura>0,707106781186547524</cosapertura>\r
+  </lockfiltro>\r
+</navepropia>\r
diff --git a/src/vista/Camara.pas b/src/vista/Camara.pas
new file mode 100644 (file)
index 0000000..dbcc61d
--- /dev/null
@@ -0,0 +1,287 @@
+{** Implementa una cámara que se encarga de representar los objetos en 2D.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    10/11/00: Se agrega el manejo de excepciones para evitar usar la camara cuando el cameraman fue destruido.\r
+              Para lograr esto se crea una excepcion (ECameramanDestruido) que se lanza cuando hay una excepcion\r
+              de violacion de acceso a memoria. Esta excepcion debe ser manejada por quien meneje la camara y puede\r
+              ser lanzada por mGetDebugInfo o mProyectar.\r
+    01/12/00: Se elimina el atributo aApertura porque era absolutamente inecesario.\r
+              Se cambia la estructura interna para que el filtrado de los objetos los realice un cFiltro.\r
+    07/12/00: Se agregan nuevos métodos (protegidos) para obtener información de la cámara para poder crear subclases,\r
+              para lo cual tambien se hace virtual el método mProyectar.\r
+    08/12/00: Se quita el método para setear el filtro y se agrega un contructor que admite un filtro para reemplazarlo.\r
+              Se cambia esta clase para que sea abstracta. Se deja la implementacion del método mProyectar para las\r
+              subclases exlusivamente ya que ahora es abstracto. La cámara frontal (que antes se implementaba en\r
+              esta unidad), ahora está implementado la unidad Camaras al igual que el resto.\r
+    </PRE>}\r
+unit Camara;\r
+\r
+interface\r
+\r
+uses\r
+  {$IFDEF DebugAlgoWars}\r
+  Objeto,\r
+  {$ENDIF}\r
+  Tipos,\r
+  Coordenadas,\r
+  Vectores,\r
+  ObjetoVolador,\r
+  NavePropia,\r
+  Espacio,\r
+  Classes,\r
+  Sysutils,\r
+  Filtro,\r
+  Lista;\r
+\r
+type\r
+  {** Datos de un Objeto Volador procesado por una cámara }\r
+  tProyectado = record\r
+    oOV:  cObjetoVolador;\r
+    x:    tLongitud;\r
+    y:    tLongitud;\r
+    tam:  tLongitud;\r
+  end;\r
+\r
+  {** Puntero a tProyectado}\r
+  tPProy = ^tProyectado;\r
+\r
+  {** Excepcion producida por la cámara si se utiliza cuando el cameraman fue destruido}\r
+  ECameramanDestruido = class( Exception )\r
+    public\r
+      {** Constructor}\r
+      constructor create;\r
+  end;\r
+\r
+  {** Implementa una cámara que se encarga de representar los objetos en 2D.}\r
+  cCamara = class{$IFDEF DebugAlgoWars}( cObjeto ){$ENDIF}\r
+    private\r
+      aCameraman:     cObjetoVolador; // Objeto volador que porta la camara\r
+      aRadioMaximo:   tLongitud;      // Alcance maximo de la camara (los\r
+                                      //  objetos mas lejanos no se veran)\r
+      aRadioMinimo:   tLongitud;      // Alcance minimo de la camara (los\r
+                                      //  objetos mas cercanos no se veran)\r
+      // Estos 3 ultimos atributos están ligados entre si (y son en parte redundantes)\r
+      aRadioPantalla: tLongitud;      // Radio de la pantalla.\r
+      aDistPantalla:  tLongitud;      // Distancia (mínima) hasta la pantalla\r
+      aCosApertura:   tAngulo;        // Coseno del Angulo de vision de la camara,\r
+                                      //   se almacena sólo el coseno porque el\r
+                                      //   ángulo en sí no se usa.\r
+      aFiltro:        cFiltro;        // Filtro que utiliza la cámara para evaluar\r
+                                      //  cuales objetos están visibles y cuales no.\r
+\r
+    protected\r
+      {** Obtiene la proyección del objeto volador en X, Y}\r
+      procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); virtual; abstract;\r
+      {** Devuelve el objeto portador de la cámara}\r
+      function mGetCameraman: cObjetoVolador;\r
+      {** Permite asignar un nuevo portador de la cámara}\r
+      procedure mSetCameraman( oOV: cObjetoVOlador );\r
+      {** Devuelve distancia a la pantalla}\r
+      function mGetDistPantalla: tLongitud;\r
+      {** Devuelve el radio mínimo de detección}\r
+      function mGetRadioMinimo: tLongitud;\r
+      {** Devuelve el radio máximo de detección}\r
+      function mGetRadioMaximo: tLongitud;\r
+      {** Asigna un nuevo filtro}\r
+      Procedure mSetFiltro( filtro: cFiltro );\r
+    public\r
+      {** Constructor}\r
+      constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 ); overload;\r
+      {** Procesa una lista de objetos, devolviendo solo los visibles en una lista de records tProyectado\r
+          ordenada ascendentemente por el tamaño proporcional (es decir, el objeto de tamaño menor está primero en la lista).}\r
+      function mProcesar( l: TList ): cLista;\r
+      {$IFDEF DebugAlgoWars}\r
+      {** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.}\r
+      function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;\r
+      {$ENDIF}\r
+      {** Obtiene el radio de la pantalla}\r
+      function mGetRadioPantalla: tLongitud;\r
+  end;\r
+\r
+\r
+implementation\r
+\r
+uses\r
+  Filtros,\r
+  Math;\r
+\r
+{** Funcion para ordenar los elementos de la lista que se devuelve\r
+    @param  item1 Item a comparar (puntero)\r
+    @param  item2 Item a comparar (puntero)\r
+    @return       <b>1</b> si item1 > item2<br>&nbsp;&nbsp;&nbsp;\r
+                  <b>-1</b> si item1 < item2<br>&nbsp;&nbsp;&nbsp;\r
+                  <b>0</b> si item1 = item2}\r
+function listSort( item1, item2: pointer ): integer;\r
+var\r
+  p1,\r
+  p2: tPProy;\r
+begin\r
+  p1 := tPProy( item1 );\r
+  p2 := tPProy( item2 );\r
+  result := 0;\r
+  if p1^.tam > p2^.tam then\r
+    result := 1\r
+  else\r
+    if p1^.tam < p2^.tam then\r
+      result := -1\r
+end;\r
+\r
+{ cCamara }\r
+\r
+{** Contructor\r
+    @param cameraman Objeto Volador en el que estará montada la cámara (obligatorio)\r
+    @param angulo         Angulo de apertura (visión) de la cámara (default = pi/4)\r
+    @param maximo         Distancia máxima en la que se considera visible a un objeto (default = 5000)\r
+    @param distPantalla   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default\r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador}\r
+constructor cCamara.create(cameraman: cObjetoVolador;\r
+  angulo: tAngulo; maximo: tLongitud;\r
+  distPantalla: tLongitud );\r
+begin\r
+  inherited create;\r
+  aCameraman    := cameraman;\r
+  aRadioMaximo  := maximo;\r
+  aCosApertura  := cos( angulo );\r
+  if distPantalla > 0 then begin // Si la distancia es positiva, se la asigna y calcula el radio minimo\r
+    aDistPantalla := distPantalla;\r
+    // El radio minimo se calcula basado en la formula sen(a) = adyacente / HIPOTENUSA\r
+    aRadioMinimo  := aDistPantalla / sin( angulo );\r
+  end else begin // Si es negativo o cero (se paso como default o mal), lo extrae del objeto volador\r
+    aRadioMinimo  := aCameraman.mGetDimension;\r
+    // La distancia a la pantalla se calcula basado en la formula sen(a) = ADYACENTE / hipotenusa\r
+    aDistPantalla := sin( angulo ) * aRadioMinimo;\r
+  end;\r
+  // El radio de la pantalla se calcula basado en la formula cos(a) = OPUESTO / hipotenusa\r
+  aRadioPantalla := aCosApertura * aRadioMinimo;\r
+  // Crea un filtro frontal\r
+  aFiltro := cFiltroFrontal.create( aCameraman, angulo, aRadioMaximo, aRadioMinimo )\r
+end;\r
+\r
+{** Procesa una lista de objetos, devolviendo solo los visibles en una lista de records tProyectado\r
+    ordenada ascendentemente por el tamaño proporcional (es decir, el objeto de tamaño menor está primero en la lista).\r
+    @return  Lista con los objetos visibles y sus posiciones y tamaños, en un registro\r
+             del tipo <i>tProyectado</i>, ordenados de forma ascendente según el tamaño.\r
+    @param l Lista con los objetos a procesar}\r
+function cCamara.mProcesar( l: TList ): cLista;\r
+var\r
+  lFiltrada:  TList;\r
+  lProcesada: cLista;\r
+  proy: tPProy;\r
+  oOV: cObjetoVolador;\r
+  i: integer;\r
+  x,\r
+  y,\r
+  tam: tLongitud;\r
+  sort: TListSortCompare;\r
+\r
+begin\r
+  lProcesada := cLista.create;\r
+  try\r
+    lFiltrada  := aFiltro.mFiltrar( l );\r
+  except\r
+    on e: EObservadorDestruido do\r
+      raise ECameramanDestruido.create;\r
+  end;\r
+  for i:=0 to lFiltrada.count - 1 do begin // recorre la lista de objetos\r
+    oOV := lFiltrada.items[i]; // obtiene el ObjetoVolador actual\r
+    new( proy );\r
+    mProyectar( oOV, x, y, tam );\r
+    proy^.oOV := oOV;\r
+    proy^.x := x;\r
+    proy^.y := y;\r
+    proy^.tam := tam;\r
+    lProcesada.Add( proy );\r
+  end;\r
+  sort := listSort;\r
+  lProcesada.Sort( sort );\r
+  result := lProcesada;\r
+  lFiltrada.free;\r
+end;\r
+\r
+{$IFDEF DebugAlgoWars}\r
+{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos:<br>\r
+    Siempre devuelve los valores de las componentes x, y, z y si debugLevel es mayor que DI_NORMAL,\r
+    también muestra el módulo.\r
+    @return             Cadena de texto con el estado del Objeto.\r
+    @param   debugLevel Cantidad de información requerida}\r
+function cCamara.mGetDebugInfo( debugLevel: tDebugInfo ): string;\r
+begin\r
+  // Construye la cadena dependiendo de la cantidad de informacion que se quiera obtener\r
+  result := 'Radio Máximo: ' + FloatToStrF( aRadioMaximo, ffNumber, 5, 5 ) +\r
+            ' | Radio Mínimo: ' + FloatToStrF( aRadioMinimo, ffNumber, 5, 5 ) +\r
+            ' | Radio de Pantalla: ' + FloatToStrF( aRadioPantalla, ffNumber, 5, 5 ) +\r
+            ' | Distancia de Pantalla: ' + FloatToStrF( aDistPantalla, ffNumber, 5, 5 );\r
+  try // Probamos que el cameraman no este destruido\r
+    if debugLevel = DI_NORMAL then\r
+      result := result + #13 + #10 +\r
+                'Cameraman: ' + aCameraman.mGetDebugInfo;\r
+    if debugLevel = DI_MAXI then\r
+      result := result + #13 + #10 +\r
+                'Cameraman: ' + aCameraman.mGetDebugInfo( debugLevel ); // + #13 + #10 +\r
+  except // Si esta destruido cae en una excepcion\r
+    on e: EAccessViolation do\r
+      raise ECameramanDestruido.create; // Creamos una nueva excepcion especial\r
+  end;\r
+end;\r
+{$ENDIF}\r
+\r
+{** Obtiene el radio de la pantalla\r
+    @return Radio de la pantalla}\r
+function cCamara.mGetRadioPantalla: tLongitud;\r
+begin\r
+  result := aRadioPantalla;\r
+end;\r
+\r
+{** Devuelve el objeto portador de la cámara\r
+    @return Objeto portador de la cámara}\r
+function cCamara.mGetCameraman: cObjetoVolador;\r
+begin\r
+  result := aCameraman;\r
+end;\r
+\r
+{** Permite asignar un nuevo portador de la cámara\r
+    @param oOV Objeto volador que será en nuevo portador de la cámara}\r
+procedure cCamara.mSetCameraman(oOV: cObjetoVOlador);\r
+begin\r
+  aCameraman := oOV;\r
+  aFiltro.mSetObservador( oOV );\r
+end;\r
+\r
+{** Devuelve distancia a la pantalla\r
+    @return Distancia a la pantalla}\r
+function cCamara.mGetDistPantalla: tLongitud;\r
+begin\r
+  result:=aDistPantalla;\r
+end;\r
+\r
+{** Devuelve el radio mínimo de detección\r
+    @return Radio mínimo de detección}\r
+function cCamara.mGetRadioMaximo: tLongitud;\r
+begin\r
+  result:=aRadioMaximo;\r
+end;\r
+\r
+{** Devuelve el radio máximo de detección\r
+    @return Radio máximo de detección}\r
+function cCamara.mGetRadioMinimo: tLongitud;\r
+begin\r
+  result:=aRadioMinimo;\r
+end;\r
+\r
+{** Asigna un nuevo filtro}\r
+procedure cCamara.mSetFiltro(filtro: cFiltro);\r
+begin\r
+  aFiltro.free;\r
+  aFiltro := filtro;\r
+end;\r
+\r
+{ ECameramanDestruido }\r
+\r
+{** Constructor}\r
+constructor ECameramanDestruido.create;\r
+begin\r
+  inherited create( 'El Cameraman fue destruido.' );\r
+end;\r
+\r
+end.\r
diff --git a/src/vista/Camaras.pas b/src/vista/Camaras.pas
new file mode 100644 (file)
index 0000000..e2da399
--- /dev/null
@@ -0,0 +1,629 @@
+{** Se implementan varias cámaras en diferentes direcciones.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    09/12/00: Se agrega la clase cCamaraMapa.\r
+    </PRE>}\r
+unit Camaras;\r
+\r
+interface\r
+\r
+uses\r
+  SysUtils,\r
+  Camara,\r
+  Tipos,\r
+  Vectores,\r
+  ObjetoVolador,\r
+  Lista;\r
+\r
+type\r
+  {** Implementa una cámara frontal.}\r
+  cCamaraFrontal = class( cCamara )\r
+    protected\r
+      {** Obtiene la proyección del objeto volador en X, Y}\r
+      procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;\r
+    public\r
+      {** Constructor}\r
+      constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );\r
+  end;\r
+\r
+  {** Implementa una cámara lateral derecha.}\r
+  cCamaraLatDer = class( cCamara )\r
+    protected\r
+      {** Obtiene la proyección del objeto volador en X, Y}\r
+      procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;\r
+      {** Constructor}\r
+      constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );\r
+  end;\r
+\r
+  {** Implementa una cámara lateral izquierda.}\r
+  cCamaraLatIzq = class( cCamara )\r
+    protected\r
+      {** Obtiene la proyección del objeto volador en X, Y}\r
+      procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;\r
+    public\r
+      {** Constructor}\r
+      constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );\r
+  end;\r
+\r
+  {** Implementa una cámara trasera.}\r
+  cCamaraTrasera = class( cCamara )\r
+    protected\r
+      {** Obtiene la proyección del objeto volador en X, Y}\r
+      procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;\r
+    public\r
+      {** Constructor}\r
+      constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );\r
+  end;\r
+\r
+  {** Implementa una cámara para ver hacia arriba.}\r
+  cCamaraArriba = class( cCamara )\r
+    protected\r
+      {** Obtiene la proyección del objeto volador en X, Y}\r
+      procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;\r
+    public\r
+      {** Constructor}\r
+      constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );\r
+  end;\r
+\r
+  {** Implementa una cámara para ver hacia abajo.}\r
+  cCamaraAbajo = class( cCamara )\r
+    protected\r
+      {** Obtiene la proyección del objeto volador en X, Y}\r
+      procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;\r
+    public\r
+      {** Constructor}\r
+      constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );\r
+  end;\r
+\r
+  {** Implementa una cámara para ver hacia abajo pero alejado del cameraman.\r
+      Es como si observara al cameraman desde arriba.}\r
+  cCamaraMapa = class( cCamara )\r
+    protected\r
+      {** Obtiene la proyección del objeto volador en X, Y}\r
+      procedure mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud); override;\r
+    public\r
+      {** Constructor}\r
+      constructor create( cameraman: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; distPantalla: tLongitud = 0 );\r
+  end;\r
+\r
+implementation\r
+\r
+uses\r
+  Filtros;\r
+\r
+{ cCamaraFrontal }\r
+\r
+{** Contructor\r
+    @param cameraman Objeto Volador en el que estará montada la cámara (obligatorio)\r
+    @param angulo         Angulo de apertura (visión) de la cámara (default = pi/4)\r
+    @param maximo         Distancia máxima en la que se considera visible a un objeto (default = 5000)\r
+    @param distPantalla   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default\r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador}\r
+constructor cCamaraFrontal.create(cameraman: cObjetoVolador; angulo: tAngulo; maximo: tLongitud; distPantalla: tLongitud);\r
+begin\r
+  inherited create(cameraman, angulo, maximo, distPantalla );\r
+  mSetFiltro( cFiltroFrontal.create( Cameraman, angulo, maximo, mGetRadioMinimo ) );\r
+end;\r
+\r
+{** Obtiene la proyección del objeto volador en X, Y\r
+    @param ov  Objeto volador a proyectar.\r
+    @param x   Valor de la proyección en X.\r
+    @param x   Valor de la proyección en Y.\r
+    @param tam Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es).\r
+               Varia entre 0 y 1}\r
+procedure cCamaraFrontal.mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud);\r
+var\r
+  posCam,\r
+  i,\r
+  vX,\r
+  vY,\r
+  v,\r
+  O,\r
+  OI: cVector;\r
+  distMax,\r
+  tmp: tLongitud;\r
+begin\r
+  // Lo primero que hay que hacer es hallar OI, para eso utilizaremos la siguiente formula:\r
+  //  OI = O.(d/D.O)\r
+  // En nuetro caso seria:\r
+  //  OI =   O . aDistPantalla\r
+  //        aCameraman.mGetI . 0\r
+  // Donde O = ov.mGetPosicion - aCameraman.mGetPosicion\r
+  try // Probamos que el cameraman no este destruido\r
+    posCam := mGetCameraman.mGetPosicion;\r
+  except // Si esta destruido cae en una excepcion\r
+    on e: EAccessViolation do raise ECameramanDestruido.create; // Creamos una nueva excepcion especial\r
+  end;\r
+  i := mGetCameraman.mGetI;\r
+  O := ov.mGetPosicion.mRestar( posCam );\r
+  OI := cVector.create( O ).mMultiplicar( mGetDistPantalla / i.mMultiplicarEsc( O ) );\r
+  // Ahora hallamos el vector v que pertenece a la pantalla, que nos dara las nuevas coordenadas respecto de ella.\r
+  //  v = OI - d.D\r
+  // En nuestro caso:\r
+  //  v = OI - ( aCameraman.mGetCoordenadas.mGetI . aDistPantalla )\r
+  v := cVector.create( OI ).mRestar( i.mMultiplicar( mGetDistPantalla ) );\r
+  // Ahora hallamos su proyeccion en el versor -j (que sera nuestro X de la pantalla)\r
+  //  Es -j porque tomaremos positivo hacia la derecha.\r
+  vX := mGetCameraman.mGetJ.mMultiplicar( -1 );\r
+  x := v.mMultiplicarEsc( vX );\r
+  // Ahora hallamos su proyeccion en el versor k (que sera nuestro Y de la pantalla)\r
+  vY := mGetCameraman.mGetK;\r
+  y := v.mMultiplicarEsc( vY );\r
+  // Ahora hallamos el tamaño proporcional (un numero entre 0 y 1, donde 0 es\r
+  //  lo mas lejano y 1 lo mas cercano). Se calcula de la siguiente forma:\r
+  // tam = 1  -      |O| - aRadioMinimo\r
+  //              aRadioMaximo - aRadioMinimo\r
+  // Donde O es el vector posicion respecto de la camara, y el " 1 - xxx ", es porque cuanto mas\r
+  //  lejos, menor tiene que ser el tamaño\r
+  tmp := O.mGetModulo - mGetRadioMinimo;\r
+  distMax := mGetRadioMaximo - mGetRadioMinimo;\r
+  tam := 1 - (tmp / distMax);\r
+  i.free;\r
+  posCam.free;\r
+  v.free;\r
+  vX.free;\r
+  vY.free;\r
+  OI.free;\r
+  O.free;\r
+end;\r
+\r
+{ cCamaraLatIzq }\r
+\r
+{** Contructor\r
+    @param cameraman Objeto Volador en el que estará montada la cámara (obligatorio)\r
+    @param angulo         Angulo de apertura (visión) de la cámara (default = pi/4)\r
+    @param maximo         Distancia máxima en la que se considera visible a un objeto (default = 5000)\r
+    @param distPantalla   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default\r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador}\r
+constructor cCamaraLatIzq.create(cameraman: cObjetoVolador; angulo: tAngulo; maximo: tLongitud; distPantalla: tLongitud);\r
+begin\r
+  inherited create(cameraman, angulo, maximo, distPantalla );\r
+  mSetFiltro( cFiltroLatIzq.create( Cameraman, angulo, maximo, mGetRadioMinimo ) );\r
+end;\r
+\r
+{** Obtiene la proyección del objeto volador en X, Y\r
+    @param ov  Objeto volador a proyectar.\r
+    @param x   Valor de la proyección en X.\r
+    @param x   Valor de la proyección en Y.\r
+    @param tam Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es).\r
+               Varia entre 0 y 1}\r
+procedure cCamaraLatIzq.mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud);\r
+var\r
+  posCam,\r
+  i,\r
+  vX,\r
+  vY,\r
+  v,\r
+  O,\r
+  OI: cVector;\r
+  distMax,\r
+  tmp: tLongitud;\r
+begin\r
+  // Lo primero que hay que hacer es hallar OI, para eso utilizaremos la siguiente formula:\r
+  //  OI = O.(d/D.O)\r
+  // En nuetro caso seria:\r
+  //  OI =   O . aDistPantalla\r
+  //        aCameraman.mGetI . 0\r
+  // Donde O = ov.mGetPosicion - mGetCameraman.mGetPosicion\r
+  try // Probamos que el cameraman no este destruido\r
+    posCam := mGetCameraman.mGetPosicion;\r
+  except // Si esta destruido cae en una excepcion\r
+    on e: EAccessViolation do raise ECameramanDestruido.create; // Creamos una nueva excepcion especial\r
+  end;\r
+  i := mGetCameraman.mGetJ;\r
+  O := ov.mGetPosicion.mRestar( posCam );\r
+  OI := cVector.create( O ).mMultiplicar( mGetDistPantalla / i.mMultiplicarEsc( O ) );\r
+  // Ahora hallamos el vector v que pertenece a la pantalla, que nos dara las nuevas coordenadas respecto de ella.\r
+  //  v = OI - d.D\r
+  // En nuestro caso:\r
+  //  v = OI - ( aCameraman.mGetCoordenadas.mGetI . aDistPantalla )\r
+  v := cVector.create( OI ).mRestar( i.mMultiplicar( mGetDistPantalla ) );\r
+  // Ahora hallamos su proyeccion en el versor -j (que sera nuestro X de la pantalla)\r
+  //  Es -j porque tomaremos positivo hacia la derecha.\r
+  vX := mGetCameraman.mGetI;\r
+  x := v.mMultiplicarEsc( vX );\r
+  // Ahora hallamos su proyeccion en el versor k (que sera nuestro Y de la pantalla)\r
+  vY := mGetCameraman.mGetK;\r
+  y := v.mMultiplicarEsc( vY );\r
+  // Ahora hallamos el tamaño proporcional (un numero entre 0 y 1, donde 0 es\r
+  //  lo mas lejano y 1 lo mas cercano). Se calcula de la siguiente forma:\r
+  // tam = 1  -      |O| - aRadioMinimo\r
+  //              aRadioMaximo - aRadioMinimo\r
+  // Donde O es el vector posicion respecto de la camara, y el " 1 - xxx ", es porque cuanto mas\r
+  //  lejos, menor tiene que ser el tamaño\r
+  tmp := O.mGetModulo - mGetRadioMinimo;\r
+  distMax := mGetRadioMaximo - mGetRadioMinimo;\r
+  tam := 1 - (tmp / distMax);\r
+  i.free;\r
+  posCam.free;\r
+  v.free;\r
+  vX.free;\r
+  vY.free;\r
+  OI.free;\r
+  O.free;\r
+end;\r
+\r
+{ cCamaraLatDer }\r
+\r
+{** Contructor\r
+    @param cameraman Objeto Volador en el que estará montada la cámara (obligatorio)\r
+    @param angulo         Angulo de apertura (visión) de la cámara (default = pi/4)\r
+    @param maximo         Distancia máxima en la que se considera visible a un objeto (default = 5000)\r
+    @param distPantalla   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default\r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador}\r
+constructor cCamaraLatDer.create(cameraman: cObjetoVolador; angulo: tAngulo; maximo: tLongitud; distPantalla: tLongitud);\r
+begin\r
+  inherited create(cameraman, angulo, maximo, distPantalla );\r
+  mSetFiltro( cFiltroLatDer.create( Cameraman, angulo, maximo, mGetRadioMinimo ) );\r
+end;\r
+\r
+{** Obtiene la proyección del objeto volador en X, Y\r
+    @param ov  Objeto volador a proyectar.\r
+    @param x   Valor de la proyección en X.\r
+    @param x   Valor de la proyección en Y.\r
+    @param tam Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es).\r
+               Varia entre 0 y 1}\r
+procedure cCamaraLatDer.mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud);\r
+var\r
+  posCam,\r
+  i,\r
+  vX,\r
+  vY,\r
+  v,\r
+  O,\r
+  OI: cVector;\r
+  distMax,\r
+  tmp: tLongitud;\r
+begin\r
+  // Lo primero que hay que hacer es hallar OI, para eso utilizaremos la siguiente formula:\r
+  //  OI = O.(d/D.O)\r
+  // En nuetro caso seria:\r
+  //  OI =   O . aDistPantalla\r
+  //        aCameraman.mGetI . 0\r
+  // Donde O = ov.mGetPosicion - mGetCameraman.mGetPosicion\r
+  try // Probamos que el cameraman no este destruido\r
+    posCam := mGetCameraman.mGetPosicion;\r
+  except // Si esta destruido cae en una excepcion\r
+    on e: EAccessViolation do raise ECameramanDestruido.create; // Creamos una nueva excepcion especial\r
+  end;\r
+  i := mGetCameraman.mGetJ.mMultiplicar(-1);\r
+  O := ov.mGetPosicion.mRestar( posCam );\r
+  OI := cVector.create( O ).mMultiplicar( mGetDistPantalla / i.mMultiplicarEsc( O ) );\r
+  // Ahora hallamos el vector v que pertenece a la pantalla, que nos dara las nuevas coordenadas respecto de ella.\r
+  //  v = OI - d.D\r
+  // En nuestro caso:\r
+  //  v = OI - ( aCameraman.mGetCoordenadas.mGetI . aDistPantalla )\r
+  v := cVector.create( OI ).mRestar( i.mMultiplicar( mGetDistPantalla ) );\r
+  // Ahora hallamos su proyeccion en el versor -j (que sera nuestro X de la pantalla)\r
+  //  Es -j porque tomaremos positivo hacia la derecha.\r
+  vX := mGetCameraman.mGetI.mMultiplicar(-1);\r
+  x := v.mMultiplicarEsc( vX );\r
+  // Ahora hallamos su proyeccion en el versor k (que sera nuestro Y de la pantalla)\r
+  vY := mGetCameraman.mGetK;\r
+  y := v.mMultiplicarEsc( vY );\r
+  // Ahora hallamos el tamaño proporcional (un numero entre 0 y 1, donde 0 es\r
+  //  lo mas lejano y 1 lo mas cercano). Se calcula de la siguiente forma:\r
+  // tam = 1  -      |O| - aRadioMinimo\r
+  //              aRadioMaximo - aRadioMinimo\r
+  // Donde O es el vector posicion respecto de la camara, y el " 1 - xxx ", es porque cuanto mas\r
+  //  lejos, menor tiene que ser el tamaño\r
+  tmp := O.mGetModulo - mGetRadioMinimo;\r
+  distMax := mGetRadioMaximo - mGetRadioMinimo;\r
+  tam := 1 - (tmp / distMax);\r
+  i.free;\r
+  posCam.free;\r
+  v.free;\r
+  vX.free;\r
+  vY.free;\r
+  OI.free;\r
+  O.free;\r
+end;\r
+\r
+{ cCamaraTrasera }\r
+\r
+{** Contructor\r
+    @param cameraman Objeto Volador en el que estará montada la cámara (obligatorio)\r
+    @param angulo         Angulo de apertura (visión) de la cámara (default = pi/4)\r
+    @param maximo         Distancia máxima en la que se considera visible a un objeto (default = 5000)\r
+    @param distPantalla   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default\r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador}\r
+constructor cCamaraTrasera.create(cameraman: cObjetoVolador; angulo: tAngulo; maximo: tLongitud; distPantalla: tLongitud);\r
+begin\r
+  inherited create(cameraman, angulo, maximo, distPantalla );\r
+  mSetFiltro( cFiltroTrasero.create( Cameraman, angulo, maximo, mGetRadioMinimo ) );\r
+end;\r
+\r
+{** Obtiene la proyección del objeto volador en X, Y\r
+    @param ov  Objeto volador a proyectar.\r
+    @param x   Valor de la proyección en X.\r
+    @param x   Valor de la proyección en Y.\r
+    @param tam Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es).\r
+               Varia entre 0 y 1}\r
+procedure cCamaraTrasera.mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud);\r
+var\r
+  posCam,\r
+  i,\r
+  vX,\r
+  vY,\r
+  v,\r
+  O,\r
+  OI: cVector;\r
+  distMax,\r
+  tmp: tLongitud;\r
+begin\r
+  // Lo primero que hay que hacer es hallar OI, para eso utilizaremos la siguiente formula:\r
+  //  OI = O.(d/D.O)\r
+  // En nuetro caso seria:\r
+  //  OI =   O . aDistPantalla\r
+  //        aCameraman.mGetI . 0\r
+  // Donde O = ov.mGetPosicion - mGetCameraman.mGetPosicion\r
+  try // Probamos que el cameraman no este destruido\r
+    posCam := mGetCameraman.mGetPosicion;\r
+  except // Si esta destruido cae en una excepcion\r
+    on e: EAccessViolation do raise ECameramanDestruido.create; // Creamos una nueva excepcion especial\r
+  end;\r
+  i := mGetCameraman.mGetI.mMultiplicar(-1);\r
+  O := ov.mGetPosicion.mRestar( posCam );\r
+  OI := cVector.create( O ).mMultiplicar( mGetDistPantalla / i.mMultiplicarEsc( O ) );\r
+  // Ahora hallamos el vector v que pertenece a la pantalla, que nos dara las nuevas coordenadas respecto de ella.\r
+  //  v = OI - d.D\r
+  // En nuestro caso:\r
+  //  v = OI - ( aCameraman.mGetCoordenadas.mGetI . aDistPantalla )\r
+  v := cVector.create( OI ).mRestar( i.mMultiplicar( mGetDistPantalla ) );\r
+  // Ahora hallamos su proyeccion en el versor -j (que sera nuestro X de la pantalla)\r
+  //  Es -j porque tomaremos positivo hacia la derecha.\r
+  vX := mGetCameraman.mGetJ;\r
+  x := v.mMultiplicarEsc( vX );\r
+  // Ahora hallamos su proyeccion en el versor k (que sera nuestro Y de la pantalla)\r
+  vY := mGetCameraman.mGetK;\r
+  y := v.mMultiplicarEsc( vY );\r
+  // Ahora hallamos el tamaño proporcional (un numero entre 0 y 1, donde 0 es\r
+  //  lo mas lejano y 1 lo mas cercano). Se calcula de la siguiente forma:\r
+  // tam = 1  -      |O| - aRadioMinimo\r
+  //              aRadioMaximo - aRadioMinimo\r
+  // Donde O es el vector posicion respecto de la camara, y el " 1 - xxx ", es porque cuanto mas\r
+  //  lejos, menor tiene que ser el tamaño\r
+  tmp := O.mGetModulo - mGetRadioMinimo;\r
+  distMax := mGetRadioMaximo - mGetRadioMinimo;\r
+  tam := 1 - (tmp / distMax);\r
+  i.free;\r
+  posCam.free;\r
+  v.free;\r
+  vX.free;\r
+  vY.free;\r
+  OI.free;\r
+  O.free;\r
+end;\r
+\r
+{ cCamaraArriba }\r
+\r
+{** Contructor\r
+    @param cameraman Objeto Volador en el que estará montada la cámara (obligatorio)\r
+    @param angulo         Angulo de apertura (visión) de la cámara (default = pi/4)\r
+    @param maximo         Distancia máxima en la que se considera visible a un objeto (default = 5000)\r
+    @param distPantalla   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default\r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador}\r
+constructor cCamaraArriba.create(cameraman: cObjetoVolador; angulo: tAngulo; maximo: tLongitud; distPantalla: tLongitud);\r
+begin\r
+  inherited create(cameraman, angulo, maximo, distPantalla );\r
+  mSetFiltro( cFiltroArriba.create( Cameraman, angulo, maximo, mGetRadioMinimo ) );\r
+end;\r
+\r
+{** Obtiene la proyección del objeto volador en X, Y\r
+    @param ov  Objeto volador a proyectar.\r
+    @param x   Valor de la proyección en X.\r
+    @param x   Valor de la proyección en Y.\r
+    @param tam Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es).\r
+               Varia entre 0 y 1}\r
+procedure cCamaraArriba.mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud);\r
+var\r
+  posCam,\r
+  i,\r
+  vX,\r
+  vY,\r
+  v,\r
+  O,\r
+  OI: cVector;\r
+  distMax,\r
+  tmp: tLongitud;\r
+begin\r
+  // Lo primero que hay que hacer es hallar OI, para eso utilizaremos la siguiente formula:\r
+  //  OI = O.(d/D.O)\r
+  // En nuetro caso seria:\r
+  //  OI =   O . aDistPantalla\r
+  //        aCameraman.mGetI . 0\r
+  // Donde O = ov.mGetPosicion - mGetCameraman.mGetPosicion\r
+  try // Probamos que el cameraman no este destruido\r
+    posCam := mGetCameraman.mGetPosicion;\r
+  except // Si esta destruido cae en una excepcion\r
+    on e: EAccessViolation do raise ECameramanDestruido.create; // Creamos una nueva excepcion especial\r
+  end;\r
+  i := mGetCameraman.mGetk;\r
+  O := ov.mGetPosicion.mRestar( posCam );\r
+  OI := cVector.create( O ).mMultiplicar( mGetDistPantalla / i.mMultiplicarEsc( O ) );\r
+  // Ahora hallamos el vector v que pertenece a la pantalla, que nos dara las nuevas coordenadas respecto de ella.\r
+  //  v = OI - d.D\r
+  // En nuestro caso:\r
+  //  v = OI - ( aCameraman.mGetCoordenadas.mGetI . aDistPantalla )\r
+  v := cVector.create( OI ).mRestar( i.mMultiplicar( mGetDistPantalla ) );\r
+  // Ahora hallamos su proyeccion en el versor -j (que sera nuestro X de la pantalla)\r
+  //  Es -j porque tomaremos positivo hacia la derecha.\r
+  vX := mGetCameraman.mGetJ;\r
+  x := v.mMultiplicarEsc( vX );\r
+  // Ahora hallamos su proyeccion en el versor k (que sera nuestro Y de la pantalla)\r
+  vY := mGetCameraman.mGetI.mMultiplicar(-1);\r
+  y := v.mMultiplicarEsc( vY );\r
+  // Ahora hallamos el tamaño proporcional (un numero entre 0 y 1, donde 0 es\r
+  //  lo mas lejano y 1 lo mas cercano). Se calcula de la siguiente forma:\r
+  // tam = 1  -      |O| - aRadioMinimo\r
+  //              aRadioMaximo - aRadioMinimo\r
+  // Donde O es el vector posicion respecto de la camara, y el " 1 - xxx ", es porque cuanto mas\r
+  //  lejos, menor tiene que ser el tamaño\r
+  tmp := O.mGetModulo - mGetRadioMinimo;\r
+  distMax := mGetRadioMaximo - mGetRadioMinimo;\r
+  tam := 1 - (tmp / distMax);\r
+  i.free;\r
+  posCam.free;\r
+  v.free;\r
+  vX.free;\r
+  vY.free;\r
+  OI.free;\r
+  O.free;\r
+end;\r
+\r
+{ cCamaraLatAbajo }\r
+\r
+{** Contructor\r
+    @param cameraman Objeto Volador en el que estará montada la cámara (obligatorio)\r
+    @param angulo         Angulo de apertura (visión) de la cámara (default = pi/4)\r
+    @param maximo         Distancia máxima en la que se considera visible a un objeto (default = 5000)\r
+    @param distPantalla   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default\r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador}\r
+constructor cCamaraAbajo.create(cameraman: cObjetoVolador; angulo: tAngulo; maximo: tLongitud; distPantalla: tLongitud);\r
+begin\r
+  inherited create(cameraman, angulo, maximo, distPantalla );\r
+  mSetFiltro( cFiltroAbajo.create( Cameraman, angulo, maximo, mGetRadioMinimo ) );\r
+end;\r
+\r
+{** Obtiene la proyección del objeto volador en X, Y\r
+    @param ov  Objeto volador a proyectar.\r
+    @param x   Valor de la proyección en X.\r
+    @param x   Valor de la proyección en Y.\r
+    @param tam Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es).\r
+               Varia entre 0 y 1}\r
+procedure cCamaraAbajo.mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud);\r
+var\r
+  posCam,\r
+  i,\r
+  vX,\r
+  vY,\r
+  v,\r
+  O,\r
+  OI: cVector;\r
+  distMax,\r
+  tmp: tLongitud;\r
+begin\r
+  // Lo primero que hay que hacer es hallar OI, para eso utilizaremos la siguiente formula:\r
+  //  OI = O.(d/D.O)\r
+  // En nuetro caso seria:\r
+  //  OI =   O . aDistPantalla\r
+  //        aCameraman.mGetI . 0\r
+  // Donde O = ov.mGetPosicion - mGetCameraman.mGetPosicion\r
+  try // Probamos que el cameraman no este destruido\r
+    posCam := mGetCameraman.mGetPosicion;\r
+  except // Si esta destruido cae en una excepcion\r
+    on e: EAccessViolation do raise ECameramanDestruido.create; // Creamos una nueva excepcion especial\r
+  end;\r
+  i := mGetCameraman.mGetk.mMultiplicar(-1);\r
+  O := ov.mGetPosicion.mRestar( posCam );\r
+  OI := cVector.create( O ).mMultiplicar( mGetDistPantalla / i.mMultiplicarEsc( O ) );\r
+  // Ahora hallamos el vector v que pertenece a la pantalla, que nos dara las nuevas coordenadas respecto de ella.\r
+  //  v = OI - d.D\r
+  // En nuestro caso:\r
+  //  v = OI - ( aCameraman.mGetCoordenadas.mGetI . aDistPantalla )\r
+  v := cVector.create( OI ).mRestar( i.mMultiplicar( mGetDistPantalla ) );\r
+  // Ahora hallamos su proyeccion en el versor -j (que sera nuestro X de la pantalla)\r
+  //  Es -j porque tomaremos positivo hacia la derecha.\r
+  vX := mGetCameraman.mGetj.mMultiplicar(-1);\r
+  x := v.mMultiplicarEsc( vX );\r
+  // Ahora hallamos su proyeccion en el versor k (que sera nuestro Y de la pantalla)\r
+  vY := mGetCameraman.mGetI;\r
+  y := v.mMultiplicarEsc( vY );\r
+  // Ahora hallamos el tamaño proporcional (un numero entre 0 y 1, donde 0 es\r
+  //  lo mas lejano y 1 lo mas cercano). Se calcula de la siguiente forma:\r
+  // tam = 1  -      |O| - aRadioMinimo\r
+  //              aRadioMaximo - aRadioMinimo\r
+  // Donde O es el vector posicion respecto de la camara, y el " 1 - xxx ", es porque cuanto mas\r
+  //  lejos, menor tiene que ser el tamaño\r
+  tmp := O.mGetModulo - mGetRadioMinimo;\r
+  distMax := mGetRadioMaximo - mGetRadioMinimo;\r
+  tam := 1 - (tmp / distMax);\r
+  i.free;\r
+  posCam.free;\r
+  v.free;\r
+  vX.free;\r
+  vY.free;\r
+  OI.free;\r
+  O.free;\r
+end;\r
+\r
+{ cCamaraMapa }\r
+\r
+{** Contructor\r
+    @param cameraman Objeto Volador en el que estará montada la cámara (obligatorio)\r
+    @param angulo         Angulo de apertura (visión) de la cámara (default = pi/4)\r
+    @param maximo         Distancia máxima en la que se considera visible a un objeto (default = 5000)\r
+    @param distPantalla   Distancia hasta la pantalla de proyección (default = 0). Si tiene el valor por default\r
+                            o cualquier valor menor o igual a cero, se usa el tamaño del objeto volador}\r
+constructor cCamaraMapa.create(cameraman: cObjetoVolador; angulo: tAngulo; maximo: tLongitud; distPantalla: tLongitud);\r
+begin\r
+  inherited create(cameraman, angulo, 5000{max}, 1000{min} );\r
+  mSetFiltro( cFiltroMapa.create( Cameraman, angulo, 5000{max}, mGetRadioMinimo ) );\r
+end;\r
+\r
+{** Obtiene la proyección del objeto volador en X, Y\r
+    @param ov  Objeto volador a proyectar.\r
+    @param x   Valor de la proyección en X.\r
+    @param x   Valor de la proyección en Y.\r
+    @param tam Tamaño porcentual del objeto (cuanto mas lejos esta, mas pequeño es).\r
+               Varia entre 0 y 1}\r
+procedure cCamaraMapa.mProyectar(ov: cObjetoVolador; var x, y, tam: tLongitud);\r
+var\r
+  desplazamiento,\r
+  posCam,\r
+  i,\r
+  vX,\r
+  vY,\r
+  v,\r
+  O,\r
+  OI: cVector;\r
+  distMax,\r
+  tmp: tLongitud;\r
+begin\r
+  // Lo primero que hay que hacer es hallar OI, para eso utilizaremos la siguiente formula:\r
+  //  OI = O.(d/D.O)\r
+  // En nuetro caso seria:\r
+  //  OI =   O . aDistPantalla\r
+  //        aCameraman.mGetI . 0\r
+  // Donde O = ov.mGetPosicion - mGetCameraman.mGetPosicion\r
+  try // Probamos que el cameraman no este destruido\r
+    desplazamiento := mGetCameraman.mGetk.mSetModulo( 3000 ); // Esta 3000 metros alejado del cameraman\r
+  except // Si esta destruido cae en una excepcion\r
+    on e: EAccessViolation do raise ECameramanDestruido.create; // Creamos una nueva excepcion especial\r
+  end;\r
+  posCam := mGetCameraman.mGetPosicion.mSumar( desplazamiento );\r
+  desplazamiento.free;\r
+  i := mGetCameraman.mGetk.mMultiplicar(-1);\r
+  O := ov.mGetPosicion.mRestar( posCam );\r
+  OI := cVector.create( O ).mMultiplicar( mGetDistPantalla / i.mMultiplicarEsc( O ) );\r
+  // Ahora hallamos el vector v que pertenece a la pantalla, que nos dara las nuevas coordenadas respecto de ella.\r
+  //  v = OI - d.D\r
+  // En nuestro caso:\r
+  //  v = OI - ( aCameraman.mGetCoordenadas.mGetI . aDistPantalla )\r
+  v := cVector.create( OI ).mRestar( i.mMultiplicar( mGetDistPantalla ) );\r
+  // Ahora hallamos su proyeccion en el versor -j (que sera nuestro X de la pantalla)\r
+  //  Es -j porque tomaremos positivo hacia la derecha.\r
+  vX := mGetCameraman.mGetj.mMultiplicar(-1);\r
+  x := v.mMultiplicarEsc( vX );\r
+  // Ahora hallamos su proyeccion en el versor k (que sera nuestro Y de la pantalla)\r
+  vY := mGetCameraman.mGetI;\r
+  y := v.mMultiplicarEsc( vY );\r
+  // Ahora hallamos el tamaño proporcional (un numero entre 0 y 1, donde 0 es\r
+  //  lo mas lejano y 1 lo mas cercano). Se calcula de la siguiente forma:\r
+  // tam = 1  -      |O| - aRadioMinimo\r
+  //              aRadioMaximo - aRadioMinimo\r
+  // Donde O es el vector posicion respecto de la camara, y el " 1 - xxx ", es porque cuanto mas\r
+  //  lejos, menor tiene que ser el tamaño\r
+  tmp := O.mGetModulo - mGetRadioMinimo;\r
+  distMax := mGetRadioMaximo - mGetRadioMinimo;\r
+  tam := 1 - (tmp / distMax);\r
+  i.free;\r
+  posCam.free;\r
+  v.free;\r
+  vX.free;\r
+  vY.free;\r
+  OI.free;\r
+  O.free;\r
+end;\r
+\r
+end.\r
diff --git a/src/vista/Filtro.pas b/src/vista/Filtro.pas
new file mode 100644 (file)
index 0000000..c2ea422
--- /dev/null
@@ -0,0 +1,294 @@
+{** Es una clase abstracta que representa filtro que recibe una lista de objetos y devuelve otra filtrada.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    06/12/00: Se agregan nuevos métodos (protegidos) para obtener información del filtro para poder crear subclases,\r
+              para lo cual tambien se hace virtual el método mVisible.\r
+    08/12/00: Se cambia esta clase para que sea abstracta. Se deja la implementacion del método mVisible para las\r
+              subclases exlusivamente ya que ahora es abstracto. El filtro frontal (que antes se implementaba en\r
+              esta unidad), ahora está implementado la unidad Filtros al igual que el resto.\r
+    </PRE>}\r
+unit Filtro;\r
+\r
+interface\r
+\r
+uses\r
+  Tipos,\r
+  ObjetoPersistente,\r
+  Vectores,\r
+  ObjetoVolador,\r
+  Classes,\r
+  Sysutils;\r
+\r
+type\r
+  {** Excepcion producida por el filtro si se utiliza cuando el observador fue destruido}\r
+  EObservadorDestruido = class( Exception )\r
+    public\r
+      {** Constructor}\r
+      constructor create;\r
+  end;\r
+\r
+  {** Es una clase abstracta que representa un filtro que recibe una lista de objetos y devuelve otra filtrada.}\r
+  cFiltro = class( cObjetoPersistente )\r
+    private\r
+      aObservador:    cObjetoVolador; // Objeto volador que observa a traves del filtro\r
+      aRadioMaximo:   tLongitud;      // Alcance maximo del filtro (los\r
+                                      //  objetos mas lejanos no se veran)\r
+      aRadioMinimo:   tLongitud;      // Alcance minimo del filtro (los\r
+                                      //  objetos mas cercanos no se veran)\r
+      aCosApertura:   tAngulo;        // Coseno del Angulo de captación del filtro,\r
+                                      //   se almacena sólo el coseno porque el\r
+                                      //   ángulo en sí no se usa.\r
+    protected\r
+      {** Verifica que un objeto volador pueda ser visto por la cámara}\r
+      function mVisible( ov: cObjetoVolador ): boolean; virtual; abstract;\r
+      {** Obtiene el radio mínimo}\r
+      function mGetRadioMinimo: tLongitud;\r
+      {** Obtiene el radio máximo}\r
+      function mGetRadioMaximo: tLongitud;\r
+      {** Obtiene el coseno de la apertura}\r
+      function mGetCosApertura: tAngulo;\r
+    public\r
+      {** Constructor}\r
+      constructor create( observador: cObjetoVolador; angulo: tAngulo = PI/4; maximo: tLongitud = 5000; minimo: tLongitud = -1 );\r
+      {** Procesa una lista de objetos, devolviendo solo los visibles en una lista ordenada ascendentemente por la distancia\r
+          (es decir, el objeto más cercano está primero en la lista).}\r
+      function mFiltrar( l: TList ): TList;\r
+      {** Obtiene un puntero al observador}\r
+      function mGetObservador: cObjetoVolador;\r
+      {** Establece el observador con un nuevo puntero}\r
+      procedure mSetObservador( ov: cObjetoVolador );\r
+      {$IFDEF DebugAlgoWars}\r
+      {** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.}\r
+      function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;\r
+      {$ENDIF}\r
+      // SERIALIZACION\r
+      {** Devuelve una cadena de texto con el objeto serializado.}\r
+      function mSerializar: string; override;\r
+      {** Recrea el objeto a partir de una cadena de texto con el objeto\r
+          serializado.}\r
+      procedure mDesSerializar( str: string ); override;\r
+  end;\r
+\r
+implementation\r
+\r
+uses\r
+  RegExpr,\r
+  SerializacionUtils,\r
+  Math;\r
+\r
+{ cFiltro }\r
+\r
+{** Contructor\r
+    @param observador Objeto Volador en el que estará montado el filtro (obligatorio)\r
+    @param angulo     Angulo de apertura (visión) del filtro (default = pi/4)\r
+    @param maximo     Distancia máxima en la que se considera visible a un objeto (default = 5000)\r
+    @param minimo     Distancia mínima en la que se considera visible a un objeto (default = -1).\r
+                      Si se especifica un valor negativo o cero, se toma la dimension del objeto volador}\r
+constructor cFiltro.create(observador: cObjetoVolador; angulo: tAngulo;\r
+  maximo: tLongitud; minimo: tLongitud);\r
+begin\r
+  inherited create;\r
+  aObservador  := observador;\r
+  aRadioMaximo  := maximo;\r
+  aCosApertura  := cos( angulo );\r
+  if minimo > 0 then // Si el radio minimo es positiva se lo asigna\r
+    aRadioMinimo  := minimo\r
+  else // Si es negativo o cero (se paso como default o mal), lo extrae del objeto volador\r
+    aRadioMinimo  := aObservador.mGetDimension;\r
+end;\r
+\r
+{** Filtra una lista de objetos, devolviendo solo los visibles.\r
+    @return  Lista con los objetos visibles.\r
+    @param l Lista con los objetos a procesar.}\r
+function cFiltro.mFiltrar( l: TList ): TList;\r
+var\r
+  lProcesada: TList;\r
+  oOV: cObjetoVolador;\r
+  i: word;\r
+begin\r
+  lProcesada := TList.create;\r
+  for i:=0 to l.count - 1 do begin // recorre la lista de objetos\r
+    oOV := l.items[i]; // obtiene el ObjetoVolador actual\r
+    if mVisible( oOV ) then\r
+      lProcesada.Add( oOV );\r
+  end;\r
+  result := lProcesada;\r
+end;\r
+\r
+{$IFDEF DebugAlgoWars}\r
+{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos:<br>\r
+    Siempre devuelve los valores de las componentes x, y, z y si debugLevel es mayor que DI_NORMAL,\r
+    también muestra el módulo.\r
+    @return             Cadena de texto con el estado del Objeto.\r
+    @param   debugLevel Cantidad de información requerida}\r
+function cFiltro.mGetDebugInfo( debugLevel: tDebugInfo ): string;\r
+begin\r
+  // Construye la cadena dependiendo de la cantidad de informacion que se quiera obtener\r
+  result := 'Radio Máximo: ' + FloatToStrF( aRadioMaximo, ffNumber, 5, 5 ) +\r
+            ' | Radio Mínimo: ' + FloatToStrF( aRadioMinimo, ffNumber, 5, 5 );\r
+  try // Probamos que el cameraman no este destruido\r
+    if debugLevel = DI_NORMAL then\r
+      result := result + #13 + #10 +\r
+                'Cameraman: ' + aObservador.mGetDebugInfo;\r
+    if debugLevel = DI_MAXI then\r
+      result := result + #13 + #10 +\r
+                'Cameraman: ' + aObservador.mGetDebugInfo( debugLevel ); // + #13 + #10 +\r
+  except // Si esta destruido cae en una excepcion\r
+    on e: EAccessViolation do\r
+      raise EObservadorDestruido.create; // Creamos una nueva excepcion especial\r
+  end;\r
+end;\r
+{$ENDIF}\r
+\r
+{** Obtiene un puntero al observador\r
+    @return Puntero al obervador}\r
+function cFiltro.mGetObservador: cObjetoVolador;\r
+begin\r
+  result := aObservador;\r
+end;\r
+\r
+{** Establece el observador con un nuevo puntero\r
+    @param Puntero al nuevo obervador}\r
+procedure cFiltro.mSetObservador(ov: cObjetoVolador);\r
+begin\r
+  aObservador := ov;\r
+end;\r
+\r
+{** Recrea el objeto a partir de una cadena de texto con el objeto\r
+    serializado.\r
+    @param str Cadena de texto con el objeto serializado.}\r
+procedure cFiltro.mDesSerializar(str: string);\r
+var\r
+  r: TRegExpr;\r
+begin\r
+  inherited mDesSerializar( str ); // SIEMPRE el ID debe ser el PRIMER atributo\r
+  r := TRegExpr.create;\r
+  // OBSERVADOR\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<observador\s+class=([\w\d]+)\s*>\s*(.+)\s*</observador>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      if r.Match[1] <> '0' then // Si tiene una clase determinada...\r
+        if aObservador <> nil then // Si no es nulo\r
+          // Puede caer en una EAccessViolation si esta destruido\r
+          aObservador.mDesSerializar( r.Match[2] ) // Lo deserializa\r
+        else // si es nulo\r
+          aObservador := restaurarObjeto( r.Match[1], r.Match[2] ) // lo crea segun su clase\r
+      else // Si no tiene una clase determinada, entonces se lo pone en nil\r
+        aObservador := nil\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el objetivo' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ESerializacion do begin // Si fueron de serializacion...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al deserializar la posicion: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer la posicion utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+    on e: EAccessViolation do begin // si el Objetivo fue destruido...\r
+      aObservador := restaurarObjeto( r.Match[1], r.Match[2] ) // lo crea segun su clase\r
+    end;\r
+  end;\r
+  // RADIOMAXIMO\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<radiomaximo>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</radiomaximo>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aRadioMaximo := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el radio maximo' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el radio maximo utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // RADIOMINIMO\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<radiominimo>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</radiominimo>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aRadioMinimo := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el radio minimo' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el radio minimo utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  // COSAPERTURA\r
+  try // se fija si hay errores al extraer los datos\r
+    r.Expression := '<cosapertura>\s*([+\-]?\d+(\,\d+)?([eE][+\-]?\d+)?)\s*</cosapertura>'; // contruye la expresion regular a buscar\r
+    if r.Exec ( str ) then // Ejecuta la expresion. Si la encuentra...\r
+      aCosApertura := StrToFloat( r.Match[1] )\r
+    else // si no encontro la experesion...\r
+      raise ESerializacion.create( 'No se encontro el coseno de la apertura' ); // cae en una excepcion\r
+  except // Si hubieron errores ...\r
+    on e: ERegExpr do begin // si fueron de expresiones regulares...\r
+      r.Free; // libera memoria\r
+      raise ESerializacion.create( ClassName + ': Error al extraer el coseno de la apertura utilizando expresiones regulares: ' + e.Message ); // cae en una excepcion\r
+    end;\r
+  end;\r
+  r.free;\r
+end;\r
+\r
+{** Devuelve una cadena de texto con el objeto serializado.\r
+    @return Cadena de texto con el objeto serializado.}\r
+function cFiltro.mSerializar: string;\r
+var\r
+  clase,\r
+  observador: string;\r
+begin\r
+  // Si el observador es nil o está destruido, se setea el atributo class del\r
+  // TAG objetivo como '0' y entre el TAG se indica que es nil. Si no se\r
+  // setea como el nombre de la clase y su expresion serializada respectivamente\r
+  observador := 'nil';\r
+  clase    := '0';\r
+  if aObservador <> nil then\r
+    try\r
+      observador := aObservador.mSerializar;\r
+      clase      := aObservador.ClassName;\r
+    except // Si esta destruido cambia la cadena de texto\r
+      on e: EAccessViolation do begin\r
+        observador := 'nil';\r
+        clase      := '0';\r
+      end;\r
+    end;\r
+  result := inherited mSerializar +\r
+            '<observador class=' + clase + '>' + observador + '</observador>' +\r
+            '<radiomaximo>' + FloatToStrF( aRadioMaximo, ffGeneral, 18, 0 ) + '</radiomaximo>' +\r
+            '<radiominimo>' + FloatToStrF( aRadioMinimo, ffGeneral, 18, 0 ) + '</radiominimo>' +\r
+            '<cosapertura>' + FloatToStrF( aCosApertura, ffGeneral, 18, 0 ) + '</cosapertura>';\r
+end;\r
+\r
+{** Obtiene el radio máximo\r
+    @return Radio máximo}\r
+function cFiltro.mGetRadioMaximo: tLongitud;\r
+begin\r
+  result := aRadioMaximo;\r
+end;\r
+\r
+{** Obtiene el radio mínimo\r
+    @return Radio mínimo}\r
+function cFiltro.mGetRadioMinimo: tLongitud;\r
+begin\r
+  result := aRadioMinimo;\r
+end;\r
+\r
+{** Obtiene el coseno de la apertura\r
+    @return Coseno de la apertura}\r
+function cFiltro.mGetCosApertura: tAngulo;\r
+begin\r
+  result := aCosApertura;\r
+end;\r
+\r
+{ EObservadorDestruido }\r
+\r
+{** Constructor}\r
+constructor EObservadorDestruido.create;\r
+begin\r
+  inherited create( 'El Observador fue destruido.' );\r
+end;\r
+\r
+end.\r
diff --git a/src/vista/Filtros.pas b/src/vista/Filtros.pas
new file mode 100644 (file)
index 0000000..ad53435
--- /dev/null
@@ -0,0 +1,350 @@
+{** Se implementan varios filtro en diferentes direcciones.<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    09/12/00: Se agrega la clase cFiltroMapa.\r
+    </PRE>}\r
+unit Filtros;\r
+\r
+interface\r
+\r
+uses\r
+  Tipos,\r
+  Vectores,\r
+  ObjetoVolador,\r
+  Sysutils,\r
+  Filtro;\r
+\r
+type\r
+\r
+  {** Implementa un filtro que "ve" hacia adelante.}\r
+  cFiltroFrontal = class( cFiltro )\r
+    protected\r
+      {** Verifica que un objeto volador pueda ser visto por la cámara}\r
+      function mVisible( ov: cObjetoVolador ): boolean; override;\r
+  end;\r
+\r
+  {** Implementa un filtro que "ve" hacia la izquierda.}\r
+  cFiltroLatIzq = class( cFiltro )\r
+    protected\r
+      {** Verifica que un objeto volador pueda ser visto por la cámara}\r
+      function mVisible( ov: cObjetoVolador ): boolean; override;\r
+  end;\r
+\r
+  {** Implementa un filtro que "ve" hacia la derecha.}\r
+  cFiltroLatDer = class( cFiltro )\r
+    protected\r
+      {** Verifica que un objeto volador pueda ser visto por la cámara}\r
+      function mVisible( ov: cObjetoVolador ): boolean; override;\r
+  end;\r
+\r
+  {** Implementa un filtro que "ve" hacia atrás.}\r
+  cFiltroTrasero = class( cFiltro )\r
+    protected\r
+      {** Verifica que un objeto volador pueda ser visto por la cámara}\r
+      function mVisible( ov: cObjetoVolador ): boolean; override;\r
+  end;\r
+\r
+  {** Implementa un filtro que "ve" hacia arriba.}\r
+  cFiltroArriba = class( cFiltro )\r
+    protected\r
+      {** Verifica que un objeto volador pueda ser visto por la cámara}\r
+      function mVisible( ov: cObjetoVolador ): boolean; override;\r
+  end;\r
+\r
+  {** Implementa un filtro que "ve" hacia abajo.}\r
+  cFiltroAbajo = class( cFiltro )\r
+    protected\r
+      {** Verifica que un objeto volador pueda ser visto por la cámara}\r
+      function mVisible( ov: cObjetoVolador ): boolean; override;\r
+  end;\r
+\r
+  {** Implementa un filtro que "ve" hacia abajo pero desde arriba a una cierta distancia\r
+      del observador. Es como si observara al observador mismo.}\r
+  cFiltroMapa = class( cFiltro )\r
+    protected\r
+      {** Verifica que un objeto volador pueda ser visto por la cámara}\r
+      function mVisible( ov: cObjetoVolador ): boolean; override;\r
+  end;\r
+\r
+  {** Implementa un filtro que "ve" hacia adelante y que además sólo puede\r
+      ver objetos del tipo cNave y cMeteorito.}\r
+  cFiltroLock = class( cFiltroFrontal )\r
+    protected\r
+      {** Verifica que un objeto volador pueda ser visto por la cámara}\r
+      function mVisible( ov: cObjetoVolador ): boolean; override;\r
+  end;\r
+\r
+implementation\r
+\r
+uses\r
+  Nave,\r
+  Meteorito;\r
+\r
+{ cFiltroFrontal }\r
+\r
+{** Verifica que un objeto volador pueda ser visto por la cámara\r
+    @param  ov Objeto volador que se quiere verificar si es visto por la cámara.\r
+    @return    <i>True</i> si lo ve, <i>False</i> si no.}\r
+function cFiltroFrontal.mVisible(ov: cObjetoVolador): boolean;\r
+var\r
+  posRel,             // vector posicion del objeto volador relativo a la camara\r
+  posCam,             // Posision del cameraman\r
+  dirCam:  cVector;   // vector con la direccion en la que apunta la camara\r
+  dist:    tLongitud; // Distancia entre la camara y el objeto\r
+  cosAlfa: tAngulo;   // Coseno del angulo que forman la dir de la camara y la pos del objeto\r
+begin\r
+  result := false;\r
+  try // Probamos que el cameraman no este destruido\r
+    dist := mGetObservador.mGetDistancia( ov );\r
+  except // Si esta destruido cae en una excepcion\r
+    on e: EAccessViolation do\r
+      raise EObservadorDestruido.create; // Creamos una nueva excepcion especial\r
+  end;\r
+  if ( dist > mGetRadioMinimo ) and\r
+     ( dist < mGetRadioMaximo ) then begin // Esta dentro de la distancia minima y maxima\r
+    // posRel es el vector posicion del objeto volador relativo a la camara: posRel = posOV - posCam\r
+    posRel := ov.mGetPosicion;\r
+    posCam := mGetObservador.mGetPosicion;\r
+    posRel.mRestar( posCam );\r
+    dirCam := mGetObservador.mGetI;\r
+    // Calcula el angulo entre las 2 posiciones ( A . B / |A| . |B| )\r
+    cosAlfa := posRel.mMultiplicarEsc( dirCam ) / ( posRel.mGetModulo * dirCam.mGetModulo);\r
+    // Ahora se comparan los cosenos, ya que es una funcion decreciente entre 0 y PI\r
+    if cosAlfa > mGetCosApertura then // Esta dentro del angulo de vision\r
+      result := true;\r
+    posRel.free;\r
+    posCam.free;\r
+    dirCam.free;\r
+  end;\r
+end;\r
+\r
+{ cFiltroLatIzq }\r
+\r
+{** Verifica que un objeto volador pueda ser visto por la cámara\r
+    @param  ov Objeto volador que se quiere verificar si es visto por la cámara.\r
+    @return    <i>True</i> si lo ve, <i>False</i> si no.}\r
+function cFiltroLatIzq.mVisible(ov: cObjetoVolador): boolean;\r
+var\r
+  posRel,             // vector posicion del objeto volador relativo a la camara\r
+  posCam,             // Posision del cameraman\r
+  dirCam:  cVector;   // vector con la direccion en la que apunta la camara\r
+  dist:    tLongitud; // Distancia entre la camara y el objeto\r
+  cosAlfa: tAngulo;   // Coseno del angulo que forman la dir de la camara y la pos del objeto\r
+begin\r
+  result := false;\r
+  try // Probamos que el cameraman no este destruido\r
+    dist := mGetObservador.mGetDistancia( ov );\r
+  except // Si esta destruido cae en una excepcion\r
+    on e: EAccessViolation do\r
+      raise EObservadorDestruido.create; // Creamos una nueva excepcion especial\r
+  end;\r
+  if ( dist > mGetRadioMinimo ) and\r
+     ( dist < mGetRadioMaximo ) then begin // Esta dentro de la distancia minima y maxima\r
+    // posRel es el vector posicion del objeto volador relativo a la camara: posRel = posOV - posCam\r
+    posRel := ov.mGetPosicion;\r
+    posCam := mGetObservador.mGetPosicion;\r
+    posRel.mRestar( posCam );\r
+    dirCam := mGetObservador.mGetJ;\r
+    // Calcula el angulo entre las 2 posiciones ( A . B / |A| . |B| )\r
+    cosAlfa := posRel.mMultiplicarEsc( dirCam ) / ( posRel.mGetModulo * dirCam.mGetModulo);\r
+    // Ahora se comparan los cosenos, ya que es una funcion decreciente entre 0 y PI\r
+    if cosAlfa > mGetCosApertura then // Esta dentro del angulo de vision\r
+      result := true;\r
+    posRel.free;\r
+    posCam.free;\r
+    dirCam.free;\r
+  end;\r
+end;\r
+\r
+{ cFiltroLatDer }\r
+\r
+function cFiltroLatDer.mVisible(ov: cObjetoVolador): boolean;\r
+var\r
+  posRel,             // vector posicion del objeto volador relativo a la camara\r
+  posCam,             // Posision del cameraman\r
+  dirCam:  cVector;   // vector con la direccion en la que apunta la camara\r
+  dist:    tLongitud; // Distancia entre la camara y el objeto\r
+  cosAlfa: tAngulo;   // Coseno del angulo que forman la dir de la camara y la pos del objeto\r
+begin\r
+  result := false;\r
+  try // Probamos que el cameraman no este destruido\r
+    dist := mGetObservador.mGetDistancia( ov );\r
+  except // Si esta destruido cae en una excepcion\r
+    on e: EAccessViolation do\r
+      raise EObservadorDestruido.create; // Creamos una nueva excepcion especial\r
+  end;\r
+  if ( dist > mGetRadioMinimo ) and\r
+     ( dist < mGetRadioMaximo ) then begin // Esta dentro de la distancia minima y maxima\r
+    // posRel es el vector posicion del objeto volador relativo a la camara: posRel = posOV - posCam\r
+    posRel := ov.mGetPosicion;\r
+    posCam := mGetObservador.mGetPosicion;\r
+    posRel.mRestar( posCam );\r
+    dirCam := mGetObservador.mGetJ.mMultiplicar(-1);\r
+    // Calcula el angulo entre las 2 posiciones ( A . B / |A| . |B| )\r
+    cosAlfa := posRel.mMultiplicarEsc( dirCam ) / ( posRel.mGetModulo * dirCam.mGetModulo);\r
+    // Ahora se comparan los cosenos, ya que es una funcion decreciente entre 0 y PI\r
+    if cosAlfa > mGetCosApertura then // Esta dentro del angulo de vision\r
+      result := true;\r
+    posRel.free;\r
+    posCam.free;\r
+    dirCam.free;\r
+  end;\r
+end;\r
+\r
+{ cFiltroTrasero }\r
+\r
+function cFiltroTrasero.mVisible(ov: cObjetoVolador): boolean;\r
+var\r
+  posRel,             // vector posicion del objeto volador relativo a la camara\r
+  posCam,             // Posision del cameraman\r
+  dirCam:  cVector;   // vector con la direccion en la que apunta la camara\r
+  dist:    tLongitud; // Distancia entre la camara y el objeto\r
+  cosAlfa: tAngulo;   // Coseno del angulo que forman la dir de la camara y la pos del objeto\r
+begin\r
+  result := false;\r
+  try // Probamos que el cameraman no este destruido\r
+    dist := mGetObservador.mGetDistancia( ov );\r
+  except // Si esta destruido cae en una excepcion\r
+    on e: EAccessViolation do\r
+      raise EObservadorDestruido.create; // Creamos una nueva excepcion especial\r
+  end;\r
+  if ( dist > mGetRadioMinimo ) and\r
+     ( dist < mGetRadioMaximo ) then begin // Esta dentro de la distancia minima y maxima\r
+    // posRel es el vector posicion del objeto volador relativo a la camara: posRel = posOV - posCam\r
+    posRel := ov.mGetPosicion;\r
+    posCam := mGetObservador.mGetPosicion;\r
+    posRel.mRestar( posCam );\r
+    dirCam := mGetObservador.mGetI.mMultiplicar(-1);\r
+    // Calcula el angulo entre las 2 posiciones ( A . B / |A| . |B| )\r
+    cosAlfa := posRel.mMultiplicarEsc( dirCam ) / ( posRel.mGetModulo * dirCam.mGetModulo);\r
+    // Ahora se comparan los cosenos, ya que es una funcion decreciente entre 0 y PI\r
+    if cosAlfa > mGetCosApertura then // Esta dentro del angulo de vision\r
+      result := true;\r
+    posRel.free;\r
+    posCam.free;\r
+    dirCam.free;\r
+  end;\r
+end;\r
+\r
+{ cFiltroArriba }\r
+\r
+function cFiltroArriba.mVisible(ov: cObjetoVolador): boolean;\r
+var\r
+  posRel,             // vector posicion del objeto volador relativo a la camara\r
+  posCam,             // Posision del cameraman\r
+  dirCam:  cVector;   // vector con la direccion en la que apunta la camara\r
+  dist:    tLongitud; // Distancia entre la camara y el objeto\r
+  cosAlfa: tAngulo;   // Coseno del angulo que forman la dir de la camara y la pos del objeto\r
+begin\r
+  result := false;\r
+  try // Probamos que el cameraman no este destruido\r
+    dist := mGetObservador.mGetDistancia( ov );\r
+  except // Si esta destruido cae en una excepcion\r
+    on e: EAccessViolation do\r
+      raise EObservadorDestruido.create; // Creamos una nueva excepcion especial\r
+  end;\r
+  if ( dist > mGetRadioMinimo ) and\r
+     ( dist < mGetRadioMaximo ) then begin // Esta dentro de la distancia minima y maxima\r
+    // posRel es el vector posicion del objeto volador relativo a la camara: posRel = posOV - posCam\r
+    posRel := ov.mGetPosicion;\r
+    posCam := mGetObservador.mGetPosicion;\r
+    posRel.mRestar( posCam );\r
+    dirCam := mGetObservador.mGetK;\r
+    // Calcula el angulo entre las 2 posiciones ( A . B / |A| . |B| )\r
+    cosAlfa := posRel.mMultiplicarEsc( dirCam ) / ( posRel.mGetModulo * dirCam.mGetModulo);\r
+    // Ahora se comparan los cosenos, ya que es una funcion decreciente entre 0 y PI\r
+    if cosAlfa > mGetCosApertura then // Esta dentro del angulo de vision\r
+      result := true;\r
+    posRel.free;\r
+    posCam.free;\r
+    dirCam.free;\r
+  end;\r
+end;\r
+\r
+{ cFiltroAbajo }\r
+\r
+function cFiltroAbajo.mVisible(ov: cObjetoVolador): boolean;\r
+var\r
+  posRel,             // vector posicion del objeto volador relativo a la camara\r
+  posCam,             // Posision del cameraman\r
+  dirCam:  cVector;   // vector con la direccion en la que apunta la camara\r
+  dist:    tLongitud; // Distancia entre la camara y el objeto\r
+  cosAlfa: tAngulo;   // Coseno del angulo que forman la dir de la camara y la pos del objeto\r
+begin\r
+  result := false;\r
+  try // Probamos que el cameraman no este destruido\r
+    dist := mGetObservador.mGetDistancia( ov );\r
+  except // Si esta destruido cae en una excepcion\r
+    on e: EAccessViolation do\r
+      raise EObservadorDestruido.create; // Creamos una nueva excepcion especial\r
+  end;\r
+  if ( dist > mGetRadioMinimo ) and\r
+     ( dist < mGetRadioMaximo ) then begin // Esta dentro de la distancia minima y maxima\r
+    // posRel es el vector posicion del objeto volador relativo a la camara: posRel = posOV - posCam\r
+    posRel := ov.mGetPosicion;\r
+    posCam := mGetObservador.mGetPosicion;\r
+    posRel.mRestar( posCam );\r
+    dirCam := mGetObservador.mGetK.mMultiplicar(-1);\r
+    // Calcula el angulo entre las 2 posiciones ( A . B / |A| . |B| )\r
+    cosAlfa := posRel.mMultiplicarEsc( dirCam ) / ( posRel.mGetModulo * dirCam.mGetModulo);\r
+    // Ahora se comparan los cosenos, ya que es una funcion decreciente entre 0 y PI\r
+    if cosAlfa > mGetCosApertura then // Esta dentro del angulo de vision\r
+      result := true;\r
+    posRel.free;\r
+    posCam.free;\r
+    dirCam.free;\r
+  end;\r
+end;\r
+\r
+{ cFiltroMapa }\r
+\r
+function cFiltroMapa.mVisible(ov: cObjetoVolador): boolean;\r
+var\r
+  desplazamiento,     // desplazamiento del filtro respecto del observador\r
+  posTmp,             // Vector posicion temporal\r
+  posRel,             // vector posicion del objeto volador relativo a la camara\r
+  posCam,             // Posision del cameraman\r
+  dirCam:  cVector;   // vector con la direccion en la que apunta la camara\r
+  dist:    tLongitud; // Distancia entre la camara y el objeto\r
+  cosAlfa: tAngulo;   // Coseno del angulo que forman la dir de la camara y la pos del objeto\r
+begin\r
+  result := false;\r
+  try // Probamos que el cameraman no este destruido\r
+    desplazamiento := mGetObservador.mGetk.mSetModulo( 3000 ); // Esta 3000 metros alejado del observador\r
+  except // Si esta destruido cae en una excepcion\r
+    on e: EAccessViolation do\r
+      raise EObservadorDestruido.create; // Creamos una nueva excepcion especial\r
+  end;\r
+  posCam := mGetObservador.mGetPosicion.mSumar( desplazamiento );\r
+  desplazamiento.free;\r
+  posTmp := ov.mGetPosicion;\r
+  dist := posCam.mGetDistancia( posTmp );\r
+  posTmp.free;\r
+  if ( dist > mGetRadioMinimo ) and\r
+     ( dist < mGetRadioMaximo ) then begin // Esta dentro de la distancia minima y maxima\r
+    // posRel es el vector posicion del objeto volador relativo a la camara: posRel = posOV - posCam\r
+    posRel := ov.mGetPosicion;\r
+    posRel.mRestar( posCam );\r
+    dirCam := mGetObservador.mGetK.mMultiplicar(-1);\r
+    // Calcula el angulo entre las 2 posiciones ( A . B / |A| . |B| )\r
+    cosAlfa := posRel.mMultiplicarEsc( dirCam ) / ( posRel.mGetModulo * dirCam.mGetModulo);\r
+    // Ahora se comparan los cosenos, ya que es una funcion decreciente entre 0 y PI\r
+    if cosAlfa > mGetCosApertura then // Esta dentro del angulo de vision\r
+      result := true;\r
+    posRel.free;\r
+    dirCam.free;\r
+  end;\r
+  posCam.free;\r
+end;\r
+\r
+{ cFiltroLock }\r
+\r
+{** Verifica que un objeto volador pueda ser visto por la cámara}\r
+function cFiltroLock.mVisible(ov: cObjetoVolador): boolean;\r
+begin\r
+  result := false;\r
+  if (ov is cNave) or (ov is cMeteorito) then\r
+    result := inherited mVisible( ov );\r
+end;\r
+\r
+end.\r
diff --git a/src/vista/Vista.pas b/src/vista/Vista.pas
new file mode 100644 (file)
index 0000000..6262bc5
--- /dev/null
@@ -0,0 +1,515 @@
+{** Interpreta y dibuja los datos del modelo en un formulario<br>\r
+    <i>Cambios:</i>\r
+    <PRE>\r
+    10/11/00: Se maneja la excepción para evitar usar la camara cuando el cameraman fue destruido (ECameramanDestruido).\r
+              Esta es propagada (por ahora) para que el controlador (formulario) frene el timer\r
+    02/12/00: Se mejoran los graficos usando transparencias en los bitmaps y se da la opcion de presentar\r
+              los graficos con transparencias (alta calidad) o no (a través del atributo aAltaCalidad y\r
+              los métodos mSetAltaCalidad, mSetBajaCalidad y mCambiarCalidad).\r
+              Se mejora la performance gracias a la nueva implementación de mDibujar, ya que los\r
+              bitmas se cargan una sola vez en memoria (en un array aBitmaps) en vez de cargarse\r
+              y liberarse cada vez que se actualiza la pantalla como sucedía anteriormente.\r
+              Se implementa el soporte de visualización de un objeto volador lockeado (utilizando\r
+              otra lista de bitmaps con los gráficos de los objetos lockeados, aBitmapsLockeados).\r
+    08/12/00: Se agregan múltiples cámaras: Derecha, Izquierda, Arriba, Abajo, Atrás, Del Misil. Para hacerlo\r
+              se agragega un array de camaras y un atributo que indica la camara actual. Tambien se agregan\r
+              métodos para cambiar la cámara actual, etc.\r
+              Se arregla el destructor que no liberaba todos los objetos.\r
+    09/12/00: Se reemplaza la vista del misil por una mas general (vista del arma) que permite ver a traves de\r
+              cualquier arma disparada. Se implementa correctamente esta vista.\r
+              Se agrega una vista tipo mapa.\r
+    18/12/00: Se corrige un bug que hacía que en ciertas circunstancias no se encuentren las imágenes, agragando\r
+              la ruta completa.\r
+    </PRE>}\r
+unit Vista;\r
+\r
+interface\r
+\r
+uses\r
+  {$IFDEF DebugAlgoWars}\r
+  Objeto,\r
+  {$ENDIF}\r
+  Windows,\r
+  SysUtils,\r
+  Graphics,\r
+  Forms,\r
+  Camara,\r
+  Tipos,\r
+  ObjetoVolador,\r
+  Espacio,\r
+  Armas,\r
+  Lista;\r
+\r
+type\r
+  tArrayBitmaps = array [OV_NAVEPESADA..OV_MISDIR] of TBitmap;\r
+  tArrayCamaras = array [CAMARA_FRONTAL..CAMARA_ARMA] of cCamara;\r
+\r
+  {** Interpreta y dibuja los datos del modelo en un formulario}\r
+  cVista = class{$IFDEF DebugAlgoWars}( cObjeto ){$ENDIF}\r
+    private\r
+      aFormulario:    TCustomForm;   // Formulario en el cual dibuja\r
+      aRegion:        HRgn;          // Región del formulario en la que dibuja\r
+      aCamara:        tCamaras;      // Cámara seleccionada actualmente\r
+      aCamaras:       tArrayCamaras; // Multiples cámaras\r
+      aBitmaps:       tArrayBitmaps; // Lista con los bitmaps\r
+      aBitmapsLocked: tArrayBitmaps; // Lista con los bitmaps\r
+      aAltaCalidad:   boolean;       // Indica si las imagenes se ven con transparencias.\r
+      {$IFDEF DebugAlgoWars}\r
+      aListaProy:     cLista;   // Lista de objetos proyectados (se guarda para poder\r
+                                //  implementar el método mGetDebugInfo\r
+      {$ENDIF}\r
+    protected\r
+      {** Obtiene el lado menor del formulario}\r
+      function mGetFormLado: integer;\r
+      {** Convierte el tamaño obtenido de la cámara a uno proporcional en píxeles}\r
+      function mGetTam( proy: tPProy ): integer;\r
+      {** Convierte la componente en x obtenida de la cámara a una proporcional en píxeles}\r
+      function mGetX( proy: tPProy ): integer;\r
+      {** Convierte la componente en y obtenida de la cámara a una proporcional en píxeles}\r
+      function mGetY( proy: tPProy ): integer;\r
+      {** Dibuja un ObjetoVolador}\r
+      procedure mDibujarOV( proy: tPProy );\r
+      {** Dibuja el ObjetoVolador lockeado por la nave propia}\r
+      procedure mDibujarOVLockeado( proy: tPProy );\r
+      {** Muestra un mensaje de game over}\r
+      procedure mGameOver;\r
+      {** Convierte un tipo tObjetosVoladores al nombre del archivo que guarda su bitmap}\r
+      function mObjetoVoladorToFilename( obj: tObjetosVoladores ): string;\r
+      {** Convierte un tipo tObjetosVoladores al nombre del archivo que guarda su bitmap lockeado}\r
+      function mObjetoVoladorLockedToFilename( obj: tObjetosVoladores ): string;\r
+      {** Crea una cámara según el tipo}\r
+      function mCrearCamara( cam: tCamaras; ov: cObjetoVolador ): cCamara;\r
+    public\r
+      {** Constructor}\r
+      constructor create( formulario: TCustomForm; ov: cObjetoVolador; calidad: boolean = true );\r
+      {** Dibuja todos los Objetos Voladores que ve la cámara}\r
+      procedure mDibujarVista( oEspacio: cEspacio );\r
+      {** Define el formulario en donde dibujar}\r
+      procedure mSetForm( oForm: TCustomForm );\r
+      {** Setea gráficos de alta calidad}\r
+      procedure mSetAltaCalidad;\r
+      {** Setea gráficos de baja calidad}\r
+      procedure mSetBajaCalidad;\r
+      {** Invierte la calidad de los gráficos. Es decir, si estaban en baja los pone\r
+          en alta y vice versa.}\r
+      procedure mCambiarCalidad;\r
+      {$IFDEF DebugAlgoWars}\r
+      {** Método heredado que devuelve un string con el estado del Objeto. Se utiliza para depurar\r
+          y la información entregada depende del parámetro tDebugInfo.}\r
+      function mGetDebugInfo( debugLevel: tDebugInfo = DI_MINI ): string; override;\r
+      {$ENDIF}\r
+      {** Permite realizar el cambio de camara}\r
+      procedure mCambiarCamara( cam: tCamaras );\r
+      {** Cambia a la siguiente cámara}\r
+      procedure mCamaraSiguiente;\r
+      {** Devuelve que camara esta activa}\r
+      function mGetCamaraStr: string;\r
+      {** Crea la cámara del arma}\r
+      procedure mCrearCamaraDeArma( a: cArma );\r
+      {** Destructor}\r
+      destructor destroy; override;\r
+  end;\r
+\r
+\r
+implementation\r
+\r
+uses\r
+  Camaras;\r
+\r
+{ cVista }\r
+\r
+{** Constructor\r
+    @param formulario Formulario en donde dibujará la vista\r
+    @param ov         Objeto Volador en el cual montar la cámara}\r
+constructor cVista.create(formulario: TCustomForm; ov: cObjetoVolador; calidad: boolean);\r
+var\r
+  obj:    tObjetosVoladores;\r
+  cam:    tCamaras;\r
+  bitmap: TBitmap;\r
+begin\r
+  inherited create;\r
+  for cam := CAMARA_FRONTAL to pred( CAMARA_ARMA ) do\r
+    aCamaras[cam] := mCrearCamara( cam, ov );\r
+  aCamaras[CAMARA_ARMA] := nil;\r
+  aCamara := CAMARA_FRONTAL;\r
+  aAltaCalidad := calidad;\r
+  {$IFDEF DebugAlgoWars}\r
+  aListaProy := nil;\r
+  {$ENDIF}\r
+  mSetForm( formulario );\r
+  // Carga gráficos Comunes\r
+  for obj := OV_NAVEPESADA to OV_MISDIR do begin\r
+    bitmap := TBitmap.create;\r
+    with bitmap do begin\r
+      LoadFromFile( mObjetoVoladorToFilename( obj ) );\r
+      TransparentColor := clBlack;\r
+      TransparentMode  := tmFixed;\r
+      Transparent      := aAltaCalidad;\r
+    end;\r
+    aBitmaps[obj] := bitmap;\r
+  end;\r
+  // Carga gráficos Lockeados\r
+  for obj := OV_NAVEPESADA to OV_NAVEPROPIA do begin\r
+    bitmap := TBitmap.create;\r
+    with bitmap do begin\r
+      LoadFromFile( mObjetoVoladorLockedToFilename( obj ) );\r
+      TransparentColor := clBlack;\r
+      TransparentMode  := tmFixed;\r
+      Transparent      := aAltaCalidad;\r
+    end;\r
+    aBitmapsLocked[obj] := bitmap;\r
+  end;\r
+end;\r
+\r
+{** Destructor}\r
+destructor cVista.destroy;\r
+var\r
+  obj: tObjetosVoladores;\r
+  cam: tCamaras;\r
+begin\r
+  for cam := CAMARA_FRONTAL to CAMARA_ARMA do\r
+    aCamaras[cam].free;\r
+  for obj := OV_NAVEPESADA to OV_MISDIR do begin\r
+    aBitmaps[obj].free;\r
+    aBitmapsLocked[obj].free;\r
+  end;\r
+  {$IFDEF DebugAlgoWars}\r
+  aListaProy.free;\r
+  {$ENDIF}\r
+end;\r
+\r
+{** Dibuja un ObjetoVolador\r
+    @param proy Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion\r
+                de un determinado objeto volador (proporcionado por la cámara)}\r
+procedure cVista.mDibujarOV(proy: tPProy);\r
+var\r
+  rect:   TRect;\r
+  tam:    integer;\r
+begin\r
+  tam := mGetTam(proy);\r
+  rect.Left   := mGetX(proy);\r
+  rect.top    := mGetY(proy);\r
+  rect.right  := rect.left + tam;\r
+  rect.bottom := rect.top  + tam;\r
+  // crea una region de dibujo //solo bmp\r
+  // asigna la region anterior\r
+  SelectClipRgn( aFormulario.canvas.handle, aRegion );\r
+  // dibuja el bmp entero entre los puntos de rect o rect1\r
+  aFormulario.canvas.StretchDraw( rect, aBitmaps[proy^.oOV.mDibujar] );\r
+end;\r
+\r
+{** Dibuja el ObjetoVolador lockeado por la nave propia\r
+    @param proy Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion\r
+                de un determinado objeto volador (proporcionado por la cámara)}\r
+procedure cVista.mDibujarOVLockeado(proy: tPProy);\r
+var\r
+  rect:    TRect;\r
+  tam:     integer;\r
+begin\r
+  tam := mGetTam(proy);\r
+  rect.Left   := mGetX(proy);\r
+  rect.top    := mGetY(proy);\r
+  rect.right  := rect.left + tam;\r
+  rect.bottom := rect.top  + tam;\r
+  // crea una region de dibujo //solo bmp\r
+  // asigna la region anterior\r
+  SelectClipRgn( aFormulario.canvas.handle, aRegion );\r
+  // dibuja el bmp entero entre los puntos de rect\r
+  aFormulario.canvas.StretchDraw( rect, aBitmapsLocked[proy^.oOV.mDibujar] );\r
+end;\r
+\r
+{** Dibuja todos los Objetos Voladores que ve la cámara\r
+    @param oEspacio Espacio del cual obtener la lista de objetos a interpretar por la cámara\r
+                    para dibujarlos}\r
+procedure cVista.mDibujarVista( oEspacio: cEspacio );\r
+var\r
+  i:  integer;\r
+  pProy: tPProy;\r
+  {$IFNDEF DebugAlgoWars}\r
+  aListaProy: cLista;\r
+  {$ENDIF}\r
+begin\r
+  {$IFDEF DebugAlgoWars}\r
+  // Libera la lista vieja\r
+  aListaProy.free;\r
+  aListaProy := nil;\r
+  {$ENDIF}\r
+  //mantiene el circulo negro\r
+  aFormulario.canvas.brush.Color := clblack;\r
+  aFormulario.canvas.ellipse( 0, 0, mGetFormLado, mGetFormLado );\r
+  if aCamaras[aCamara] = nil then // Si es la camara es nil\r
+    mCamaraSiguiente; // Selecciona la camara siguiente\r
+  try // Probamos que el cameraman no este destruido\r
+    aListaProy := aCamaras[aCamara].mProcesar( oEspacio.mGetObjetos );\r
+    for i := 0 to aListaProy.Count - 1 do begin\r
+      pProy := aListaProy.items[i];\r
+      // Si el objeto volador lockeado por la nave propia es el actual...\r
+      if oEspacio.mGetNavePropia.mGetLockeado = pProy^.oOV then\r
+        mDibujarOVLockeado( aListaProy.items[i] ) // lo dibuja de una forma distinta\r
+      else                                   // si no...\r
+        mDibujarOV( aListaProy.items[i] );        // lo dibuja de la forma normal\r
+    end;\r
+  except // Si esta destruido cae en una excepcion\r
+    on e: ENavePropiaDestruida do begin\r
+      mGameOver; // Muestra el mensaje de GAME OVER\r
+      raise; // Propaga la excepcion\r
+    end;\r
+    on e: ECameramanDestruido do begin // Si fue destruido el cameraman\r
+      mCamaraSiguiente; // pasa a la siguiente\r
+    end;\r
+  end;\r
+end;\r
+\r
+{** Obtiene el lado menor del formulario\r
+    @return El alto o el ancho del formulario, dependiendo de cual sea menor}\r
+function cVista.mGetFormLado: integer;\r
+begin\r
+ if aFormulario.ClientWidth > aFormulario.ClientHeight then\r
+    result := aFormulario.ClientHeight\r
+  else\r
+    result := aFormulario.ClientWidth;\r
+    //result:=409;\r
+end;\r
+\r
+{** Convierte el tamaño obtenido de la cámara a uno proporcional en píxeles\r
+    @param  proy Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion\r
+                 de un determinado objeto volador (proporcionado por la cámara)\r
+    @return      Tamaño del objeto en píxeles (tamaño del lado del cuadrado que se usará para\r
+                 dibujar el bitmap)}\r
+function cVista.mGetTam(proy: tPProy): integer;\r
+begin\r
+  // Se calcula tomando un valor de la supuesta cabina de 1/2 metro, a partir de ahi es una\r
+  //  regla de 3 simple.\r
+  // NOTA: como los objetos quedan demasiado grandes, en vez de tomarse 1/2 metro, se toma mas pequeña\r
+  // La dimension se multiplica por 2 porque es el radio de la nave\r
+  //  TAM = tam * (dim * 2) * (lado / 2) / 25 (metros) = tam * dim * lado / 25\r
+  result := round( proy^.tam * proy^.oOV.mGetDimension * mGetFormLado / 25 );\r
+end;\r
+\r
+{** Convierte la componente en x obtenida de la cámara a una proporcional en píxeles\r
+    @param  proy Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion\r
+                 de un determinado objeto volador (proporcionado por la cámara)\r
+    @return      Componente en X del objeto en píxeles (x de la esquina superior izquierdadel\r
+                 cuadrado que se usará para dibujar el bitmap)}\r
+function cVista.mGetX(proy: tPProy): integer;\r
+begin\r
+  // Se calcula por medio de una regla de 3 simple teniendo en cuenta los tamaños maximos y se le\r
+  //  resta la mitad del tamaño porque se dibuja a partir de la esquina superior izquierda, no a\r
+  //  partir del centro como es en el modelo.\r
+  result := round( proy^.x * (mGetFormLado / 2) / aCamaras[aCamara].mGetRadioPantalla + mGetFormLado / 2 ) -\r
+            mGetTam( proy ) div 2;\r
+end;\r
+\r
+{** Convierte la componente en y obtenida de la cámara a una proporcional en píxeles\r
+    @param  proy Puntero a un elemento del tipo tProyeccion con los datos de la proyeccion\r
+                 de un determinado objeto volador (proporcionado por la cámara)\r
+    @return      Componente en Y del objeto en píxeles (y de la esquina superior izquierdadel\r
+                 cuadrado que se usará para dibujar el bitmap)}\r
+function cVista.mGetY(proy: tPProy): integer;\r
+begin\r
+  // Se calcula por medio de una regla de 3 simple teniendo en cuenta los tamaños maximos y se le\r
+  //  resta la mitad del tamaño porque se dibuja a partir de la esquina superior izquierda, no a\r
+  //  partir del centro como es en el modelo.\r
+  result := round( proy^.y * (mGetFormLado / 2) / aCamaras[aCamara].mGetRadioPantalla + mGetFormLado / 2 ) -\r
+            mGetTam( proy ) div 2;\r
+end;\r
+\r
+{** Define el formulario en donde dibujar\r
+    @param oForm Formulario en el cual dibujará la vista}\r
+procedure cVista.mSetForm(oForm: TCustomForm);\r
+begin\r
+  aFormulario := oForm;\r
+  aRegion := CreateEllipticRgn( 0, 0, mGetFormLado, mGetFormLado );\r
+end;\r
+\r
+{$IFDEF DebugAlgoWars}\r
+{** Devuelve el estado del objeto basandose en la cantidad de datos requeridos.\r
+    @return            Cadena de texto con el estado del Objeto.\r
+    @param   debugLevel Cantidad de información requerida}\r
+function cVista.mGetDebugInfo( debugLevel: tDebugInfo ): string;\r
+var\r
+  i:    integer;  // contador\r
+  proy: tPProy;   // variable temporal para obtener info de la proyeccion\r
+  camInfo: string;\r
+begin\r
+  result := 'Cámara: ' + #13 + #10;\r
+  try // Probamos que el cameraman no este destruido\r
+    camInfo := aCamaras[aCamara].mGetDebugInfo( debugLevel );\r
+  except // Si esta destruido cae en una excepcion\r
+    on e: ECameramanDestruido do\r
+      camInfo := e.Message;\r
+  end;\r
+  result := result + camInfo;\r
+  // Genera el string con el estado del Espacio\r
+  if aListaProy <> nil then begin\r
+    for i := 0 to aListaProy.Count - 1 do begin\r
+      proy := aListaProy.Items[i];\r
+      result := result + #13 + #10 +\r
+                'ObjetoVolador Proyectado ' + IntToStr( i ) + ': ' + proy^.oOV.ClassName +\r
+                ' | X: ' + IntToStr( mGetX( proy ) ) +\r
+                ' | Y: ' + IntToStr( mGetY( proy ) ) +\r
+                ' | Tam: ' + IntToStr( mGetTam( proy ) );\r
+      if debugLevel > DI_NORMAL then\r
+        result := result + #13 + #10 +\r
+                  'X (cámara): ' + FloatToStrF( proy^.x, ffNumber, 5, 5 ) +\r
+                  ' | Y (cámara): ' + FloatToStrF( proy^.y, ffNumber, 5, 5 ) +\r
+                  ' | Tam (cámara): ' + FloatToStrF( proy^.tam, ffNumber, 5, 5 );\r
+    end;\r
+  end;\r
+end;\r
+{$ENDIF}\r
+\r
+{** Muestra un mensaje de game over}\r
+procedure cVista.mGameOver;\r
+var\r
+  rect: TRect;\r
+  bitm: TBitMap;\r
+begin\r
+  rect.Left   := 100;\r
+  rect.top    := 150;\r
+  rect.right  := 300;\r
+  rect.bottom := 250;\r
+  // crea una region de dibujo //solo bmp\r
+  // asigna la region anterior\r
+  SelectClipRgn( aFormulario.canvas.handle, aRegion );\r
+  // dibuja el bmp entero entre los puntos de rect o rect1\r
+  bitm := TBitMap.create;\r
+  bitm.LoadFromFile( 'bitmaps\gameover.bmp' );\r
+  aFormulario.canvas.StretchDraw( rect, bitm );\r
+  // canvas.stretchdraw(rect1,bitm);\r
+  bitm.free;\r
+end;\r
+\r
+{** Convierte un tipo tObjetosVoladores al nombre del archivo que guarda su bitmap\r
+    @param obj Tipo de objeto volador\r
+    @return Nombre del archivo que almacena el bitmap que lo representa}\r
+function cVista.mObjetoVoladorToFilename(obj: tObjetosVoladores): string;\r
+begin\r
+  result := ExtractFileDir( ParamStr( 0 ) ) + '\bitmaps\';\r
+  case obj of\r
+    OV_METEORITO:   result := result + 'meteorito.bmp';\r
+    OV_LASER:       result := result + 'laser.bmp';\r
+    OV_MISIL:       result := result + 'misil.bmp';\r
+    OV_MISDIR:      result := result + 'misildirigido.bmp';\r
+    OV_NAVEPROPIA:  result := result + 'navepropia.bmp';\r
+    OV_NAVEPESADA:  result := result + 'navepesada.bmp';\r
+    OV_NAVELIVIANA: result := result + 'naveliviana.bmp';\r
+    OV_NAVEESPIA:   result := result + 'naveespia.bmp';\r
+    OV_NAVESUICIDA: result := result + 'navesuicida.bmp';\r
+    else            result := result + 'desconocido.bmp';\r
+  end;\r
+end;\r
+\r
+{** Convierte un tipo tObjetosVoladores al nombre del archivo que guarda su bitmap lockeado\r
+    @param obj Tipo de objeto volador\r
+    @return Nombre del archivo que almacena el bitmap que lo representa}\r
+function cVista.mObjetoVoladorLockedToFilename(\r
+  obj: tObjetosVoladores): string;\r
+begin\r
+  result := ExtractFileDir( ParamStr( 0 ) ) + '\bitmaps\';\r
+  case obj of\r
+    OV_METEORITO:   result := result + 'meteorito_l.bmp';\r
+    OV_NAVEPROPIA:  result := result + 'navepropia_l.bmp';\r
+    OV_NAVEPESADA:  result := result + 'navepesada_l.bmp';\r
+    OV_NAVELIVIANA: result := result + 'naveliviana_l.bmp';\r
+    OV_NAVEESPIA:   result := result + 'naveespia_l.bmp';\r
+    OV_NAVESUICIDA: result := result + 'navesuicida_l.bmp';\r
+    else            result := result + 'desconocido_l.bmp';\r
+  end;\r
+end;\r
+\r
+{** Setea gráficos de alta calidad}\r
+procedure cVista.mSetAltaCalidad;\r
+begin\r
+  if not aAltaCalidad then // Si no estan seteados como de alta calidad...\r
+  mCambiarCalidad;\r
+end;\r
+\r
+{** Setea gráficos de baja calidad}\r
+procedure cVista.mSetBajaCalidad;\r
+begin\r
+  if aAltaCalidad then // Si no estan seteados como de alta calidad...\r
+  mCambiarCalidad;\r
+end;\r
+\r
+{** Invierte la calidad de los gráficos. Es decir, si estaban en baja los pone\r
+    en alta y vice versa.}\r
+procedure cVista.mCambiarCalidad;\r
+var\r
+  obj: tObjetosVoladores;\r
+begin\r
+  aAltaCalidad := not aAltaCalidad;\r
+  for obj := OV_NAVEPESADA to OV_MISDIR do\r
+    aBitmaps[obj].Transparent := aAltaCalidad;\r
+  for obj := OV_NAVEPESADA to OV_NAVEPROPIA do\r
+    aBitmapsLocked[obj].Transparent := aAltaCalidad;\r
+end;\r
+\r
+procedure cVista.mCambiarCamara(cam : tCamaras);\r
+begin\r
+  if aCamaras[cam] <>  nil then // Si esta creada es camara, la cambia\r
+    aCamara := cam;\r
+end;\r
+\r
+function cVista.mGetCamaraStr: string;\r
+begin\r
+  case aCamara of\r
+    CAMARA_FRONTAL: result := 'Cámara Frontal';\r
+    CAMARA_LATDER:  result := 'Cámara Lateral Derecha';\r
+    CAMARA_LATIZQ:  result := 'Cámara Lateral Izquierda';\r
+    CAMARA_TRASERA: result := 'Cámara Trasera';\r
+    CAMARA_ARRIBA:  result := 'Cámara Superior';\r
+    CAMARA_ABAJO:   result := 'Cámara Inferior';\r
+    CAMARA_MAPA:    result := 'Mapa del Escenario';\r
+    CAMARA_ARMA:    result := 'Cámara en el Arma';\r
+  end;\r
+end;\r
+\r
+{** Crea una cámara según el tipo\r
+    @param  cam Tipo de Cámara\r
+    @param  ov  Portador de la cámara\r
+    @return Nueva cámara creada}\r
+function cVista.mCrearCamara(cam: tCamaras; ov: cObjetoVolador): cCamara;\r
+begin\r
+  case cam of\r
+    CAMARA_FRONTAL: result := cCamaraFrontal.create( ov, 1 ); // Se la crea con un poco mas de angulo que el comun\r
+    CAMARA_LATDER:  result := cCamaraLatDer.create( ov, 1 );  // Se la crea con un poco mas de angulo que el comun\r
+    CAMARA_LATIZQ:  result := cCamaraLatIzq.create( ov, 1 );  // Se la crea con un poco mas de angulo que el comun\r
+    CAMARA_TRASERA: result := cCamaraTrasera.create( ov, 1 ); // Se la crea con un poco mas de angulo que el comun\r
+    CAMARA_ARRIBA:  result := cCamaraArriba.create( ov, 1 );  // Se la crea con un poco mas de angulo que el comun\r
+    CAMARA_ABAJO:   result := cCamaraAbajo.create( ov, 1 );   // Se la crea con un poco mas de angulo que el comun\r
+    CAMARA_MAPA:    result := cCamaraMapa.create( ov, 1 );    // Se la crea con un poco mas de angulo que el comun\r
+    CAMARA_ARMA:    result := cCamaraFrontal.create( ov, 1 ); // Se la crea con un poco mas de angulo que el comun\r
+  end;\r
+end;\r
+\r
+{** Cambia a la siguiente cámara}\r
+procedure cVista.mCamaraSiguiente;\r
+var\r
+  cam: tCamaras;\r
+begin\r
+  cam := succ( aCamara ); // Pasa a la próxima\r
+  if cam > CAMARA_ARMA then // Si se paso del ultimo ...\r
+    aCamara := CAMARA_FRONTAL // Vuelve a la primera\r
+  else\r
+    if cam = CAMARA_ARMA then // Si es la camara del misil...\r
+      if aCamaras[aCamara] = nil then // Si no esta activa...\r
+        aCamara := CAMARA_FRONTAL // Vuelve a la camara frontal\r
+      else // si esta todo normal...\r
+        aCamara := cam\r
+    else // si esta todo normal...\r
+        aCamara := cam\r
+end;\r
+\r
+{** Crea la cámara del arma\r
+    @param ov Objeto Volador portador de la camara}\r
+procedure cVista.mCrearCamaraDeArma(a: cArma);\r
+begin\r
+  if a <> nil then begin\r
+    if aCamaras[CAMARA_ARMA] <> nil then\r
+      aCamaras[CAMARA_ARMA].free;\r
+    aCamaras[CAMARA_ARMA] := mCrearCamara( CAMARA_ARMA, a );\r
+  end;\r
+end;\r
+\r
+end.
\ No newline at end of file
diff --git a/website/.htaccess b/website/.htaccess
new file mode 100644 (file)
index 0000000..42349c9
--- /dev/null
@@ -0,0 +1 @@
+Options Indexes FollowSymLinks MultiViews
diff --git a/website/Templates/normal.dwt b/website/Templates/normal.dwt
new file mode 100644 (file)
index 0000000..ace3003
--- /dev/null
@@ -0,0 +1,51 @@
+<html>\r
+<!-- #BeginEditable "doctitle" -->\r
+<title>AlgoWars - Episodio IV</title>\r
+<!-- #EndEditable -->\r
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\r
+<!-- #BeginEditable "docstyle" -->\r
+<style type="text/css">\r
+<!--\r
+p {  margin-top: 5px; margin-right: 0px; margin-bottom: 5px}\r
+body {  font-family: Arial, Helvetica, sans-serif; font-size: 14px}\r
+ul {  list-style-image:     url(../images/bullet.jpg); list-style-type: circle}\r
+li {  list-style-image:     url(../images/bullet.jpg); list-style-type: circle}\r
+td {  font-family: Arial, Helvetica, sans-serif; font-size: 12px}\r
+-->\r
+</style>\r
+<!-- #EndEditable -->\r
+\r
+\r
+\r
+</head>\r
+\r
+<body bgcolor="#000000" text="#FFFFFF" link="#66CCFF" vlink="#0099FF" alink="#33FFFF" leftmargin="5" topmargin="5" marginwidth="5" marginheight="5" onLoad="">\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#0033CC" size="4"><b><font color="#FF9999">AlgoWars</font></b></font></p>\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#FF9999" size="3"><b><font size="2">Episodio IV</font></b></font>\r
+</p>\r
+<p>&nbsp;</p>\r
+<p><font size="+1"><b><!-- #BeginEditable "T%EDtulo" -->{Título}<!-- #EndEditable --></b></font></p>\r
+<br>  <!-- #BeginEditable "Cuerpo" -->{Cuerpo}\r
+  <!-- #EndEditable -->\r
+\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+<center>\r
+    <a href="../main.html" target="mainFrame">Descripci&oacute;n</a> | <a href="../instalar.html" target="mainFrame">Instalar el Juego</a> | <a href="../configurar.html" target="mainFrame">Configurar un Escenario</a> | <a href="../jugar.html" target="mainFrame">C&oacute;mo Jugar</a> | <a href="../naves.html" target="mainFrame">Descripcion de Naves</a> | <a href="../screenshots.html" target="mainFrame">Screenshots</a> | <a href="../downloads.html" target="mainFrame">Downloads</a> | <a href="../desarrollo.html" target="mainFrame">Desarrollo<br>\r
+  </a>\r
+  \r
+  <b><font color="#CCCC00" size="2">\r
+  </font></b><br>\r
+      \r
+</center>\r
+<center>\r
+  <font size="1" face="Arial, Helvetica, sans-serif">\r
+  Copyleft 2000. Ante cualquier duda env&iacute;enos un <a href="mailto:info@algowars.luca.2t.net?subject=AlgoWars">e-mail</a>\r
+</font>\r
+</center>\r
+  </body>\r
+</html>\r
diff --git a/website/barra.html b/website/barra.html
new file mode 100644 (file)
index 0000000..065a0dc
--- /dev/null
@@ -0,0 +1,69 @@
+<html>\r
+<title>AlgoWars - Episodio IV</title>\r
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\r
+<style type="text/css">\r
+<!--\r
+p {  margin-top: 5px; margin-right: 0px; margin-bottom: 5px}\r
+body {  font-family: Arial, Helvetica, sans-serif; font-size: 14px}\r
+ul {  list-style-image:    url(images/bullet.jpg); list-style-type: circle}\r
+li {  list-style-image:    url(images/bullet.jpg); list-style-type: circle}\r
+td {  font-family: Arial, Helvetica, sans-serif; font-size: 12px}\r
+-->\r
+</style>\r
+\r
+<script language="JavaScript">\r
+<!--\r
+function MM_swapImgRestore() { //v3.0\r
+  var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;\r
+}\r
+\r
+function MM_preloadImages() { //v3.0\r
+  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();\r
+    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)\r
+    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}\r
+}\r
+\r
+function MM_findObj(n, d) { //v3.0\r
+  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {\r
+    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}\r
+  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];\r
+  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document); return x;\r
+}\r
+\r
+function MM_swapImage() { //v3.0\r
+  var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)\r
+   if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}\r
+}\r
+//-->\r
+</script>\r
+</head>\r
+\r
+<body bgcolor="#000000" text="#FFFFFF" link="#66CCFF" vlink="#0099FF" alink="#33FFFF" leftmargin="5" topmargin="5" marginwidth="5" marginheight="5" onLoad="MM_preloadImages('../images/meteorito_l.jpg','../images/naveespia_l.jpg','../images/naveliviana_l.jpg','../images/navepesada_l.jpg','../images/navepropia_l.jpg','../images/navesuicida_l.jpg')">\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#0033CC" size="4"><b><font color="#FF9999">AlgoWars</font></b></font></p>\r
+<p align="center"><img src="images/algowars.gif" width="32" height="32" align="absmiddle" border="0"></p>\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#FF9999" size="3"><b><font size="2">Episodio IV</font></b></font>\r
+</p>\r
+<br>\r
+\r
+\r
+  <a href="main.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('Image1','','images/meteorito_l.jpg',1)" target="mainFrame"><img name="Image1" border="0" src="images/meteorito.jpg" width="30" height="30" align="absmiddle">Descripci&oacute;n</a><br>\r
+  <a href="instalar.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('Image2','','images/naveespia_l.jpg',1)" target="mainFrame"><img name="Image2" border="0" src="images/naveespia.jpg" width="30" height="26" align="absmiddle">Instalar el Juego</a><br>\r
+  <a href="configurar.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('Image3','','images/naveliviana_l.jpg',1)" target="mainFrame"><img name="Image3" border="0" src="images/naveliviana.jpg" width="30" height="30" align="absmiddle">Configurar un Escenario</a><br>\r
+  <a href="jugar.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('Image4','','images/navepesada_l.jpg',1)" target="mainFrame"><img name="Image4" border="0" src="images/navepesada.jpg" width="30" height="28" align="absmiddle">C&oacute;mo Jugar</a><br>\r
+        <a href="naves.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('Image5','','images/navepropia_l.jpg',1)" target="mainFrame"><img name="Image5" border="0" src="images/navepropia.jpg" width="29" height="30" align="absmiddle">Descripcion de Naves</a><br>\r
+  <a href="screenshots.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('Image6','','images/navesuicida_l.jpg',1)" target="mainFrame"><img name="Image6" border="0" src="images/navesuicida.jpg" width="30" height="30" align="absmiddle">Screenshots</a><br>\r
+      <a href="downloads.html" target="mainFrame"><img src="images/download.gif" width="32" height="32" align="absmiddle" border="0">Downloads</a><br>\r
+      <a href="desarrollo.html" target="mainFrame"><img src="images/desarrolladores.gif" width="32" height="32" align="absmiddle" border="0">Desarrollo</a>\r
+<br>\r
+  \r
+  <b><font color="#CCCC00" size="2">\r
+  </font></b><br>\r
+      \r
+<center>\r
+  <font size="1" face="Arial, Helvetica, sans-serif">\r
+  Copyleft 2000. Ante cualquier duda env&iacute;enos un <a href="mailto:info@algowars.luca.2t.net?subject=AlgoWars">e-mail</a>\r
+</font>\r
+</center>\r
+\r
+</body>\r
+</html>\r
diff --git a/website/configurar.html b/website/configurar.html
new file mode 100644 (file)
index 0000000..f269626
--- /dev/null
@@ -0,0 +1,61 @@
+<html><!-- #BeginTemplate "/Templates/normal.dwt" -->\r
+<!-- #BeginEditable "doctitle" -->\r
+<title>AlgoWars - Episodio IV</title>\r
+<!-- #EndEditable -->\r
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\r
+<!-- #BeginEditable "docstyle" -->\r
+<style type="text/css">\r
+<!--\r
+p {  margin-top: 5px; margin-right: 0px; margin-bottom: 5px}\r
+body {  font-family: Arial, Helvetica, sans-serif; font-size: 14px}\r
+ul {  list-style-image:      url(images/bullet.jpg); list-style-type: circle}\r
+li {  list-style-image:      url(images/bullet.jpg); list-style-type: circle}\r
+td {  font-family: Arial, Helvetica, sans-serif; font-size: 12px}\r
+-->\r
+</style>\r
+<!-- #EndEditable -->\r
+\r
+\r
+\r
+</head>\r
+\r
+<body bgcolor="#000000" text="#FFFFFF" link="#66CCFF" vlink="#0099FF" alink="#33FFFF" leftmargin="5" topmargin="5" marginwidth="5" marginheight="5" onLoad="">\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#0033CC" size="4"><b><font color="#FF9999">AlgoWars</font></b></font></p>\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#FF9999" size="3"><b><font size="2">Episodio IV</font></b></font>\r
+</p>\r
+<p>&nbsp;</p>\r
+<p><font size="+1"><b><!-- #BeginEditable "T%EDtulo" --><font color="#FFCC00">&iquest;C&oacute;mo Configurar AlgoWars?</font><!-- #EndEditable --></b></font></p>\r
+<br>  <!-- #BeginEditable "Cuerpo" -->\r
+<p><img src="screenshots/menu_escenario.jpg" width="408" height="131" align="right">Configurar un escenario de AlgoWars es muy simple. Todo lo que tiene que hacer es iniciar el juego, hacer click en el men&uacute; Escenario y luego seleccionar la opci&oacute;n Configurar (o simplemente presionar Control-C en su teclado).</p>\r
+<p>Como se ve en la figura, tamb&iacute;en es posible Abrir un Escenario de una manera muy simple.</p>\r
+<p>Una vez en la pantalla de configuraci&oacute;n, puede elegir la posici&oacute;n y velocidad de su nave, como tambi&eacute;n puede agregar o quitar objetos del espacio. Los objetos entre los que puede elegir son: <a href="naves.html#navepesada">Nave Pesada</a>, <a href="naves.html#naveliviana">Nave Liviana</a>, <a href="naves.html#navesuicida">Nave Suicida</a>, <a href="naves.html#naveespia">Nave Esp&iacute;a</a>, <a href="naves.html#meteorito">Meteorito</a>, <a href="naves.html#laser">L&aacute;ser</a>, <a href="naves.html#misil">Misil</a> y <a href="naves.html#misildirigido">Misil Dirigido</a>.</p>\r
+<p>Puede encontrar una descripci&oacute;n m&aacute;s detallada en la <a href="naves.html">secci&oacute;n de descripci&oacute;n de las naves</a>.</p>\r
+<p>&nbsp;</p>\r
+<p align="center"><img src="screenshots/configurar.jpg" width="624" height="379"></p>\r
+<p align="center">&nbsp;</p>\r
+<p>Para cada objeto volador puede seleccionar la posici&oacute;n y velocidad inicial deseada. Una vez que se ajuste a sus deseos haga click en <font color="#FFCC99"><i>Agregar &gt;&gt;</i></font> para agregarlo al escenario. Si no est&aacute; conforme con un objeto anteriormente agregado puede extraerlo del Escenario simplemente presionando el bot&oacute;n <font color="#FFCC99"><i>&lt;&lt; Quitar</i></font>. Una vez que est&eacute; conforme con el Escenario creado haga click en <font color="#FFCC99"><i>Aceptar</i></font>. Si los cambios realizados no eran los que usted deseaba puede volver al juego sin que se modifique el Escenario presionando el bot&oacute;n <font color="#FFCC99"><i>Cancelar</i></font>.</p>\r
+<p>Una vez que termine de configurar el Escenario puede empezar a <a href="jugar.html">jugar</a>.<br>\r
+  </p>\r
+<!-- #EndEditable -->\r
+\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+<center>\r
+    <a href="main.html" target="mainFrame">Descripci&oacute;n</a> | <a href="instalar.html" target="mainFrame">Instalar el Juego</a> | <a href="configurar.html" target="mainFrame">Configurar un Escenario</a> | <a href="jugar.html" target="mainFrame">C&oacute;mo Jugar</a> | <a href="naves.html" target="mainFrame">Descripcion de Naves</a> | <a href="screenshots.html" target="mainFrame">Screenshots</a> | <a href="downloads.html" target="mainFrame">Downloads</a> | <a href="desarrollo.html" target="mainFrame">Desarrollo<br>\r
+  </a>\r
+  \r
+  <b><font color="#CCCC00" size="2">\r
+  </font></b><br>\r
+      \r
+</center>\r
+<center>\r
+  <font size="1" face="Arial, Helvetica, sans-serif">\r
+  Copyleft 2000. Ante cualquier duda env&iacute;enos un <a href="mailto:info@algowars.luca.2t.net?subject=AlgoWars">e-mail</a>\r
+</font>\r
+</center>\r
+  </body>\r
+<!-- #EndTemplate --></html>\r
diff --git a/website/desarrollo.html b/website/desarrollo.html
new file mode 100644 (file)
index 0000000..64f0a1c
--- /dev/null
@@ -0,0 +1,60 @@
+<html><!-- #BeginTemplate "/Templates/normal.dwt" -->\r
+<!-- #BeginEditable "doctitle" -->\r
+<title>AlgoWars - Episodio IV</title>\r
+<!-- #EndEditable -->\r
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\r
+<!-- #BeginEditable "docstyle" -->\r
+<style type="text/css">\r
+<!--\r
+p {  margin-top: 5px; margin-right: 0px; margin-bottom: 5px}\r
+body {  font-family: Arial, Helvetica, sans-serif; font-size: 14px}\r
+ul {  list-style-image:      url(images/bullet.jpg); list-style-type: circle}\r
+li {  list-style-image:      url(images/bullet.jpg); list-style-type: circle}\r
+td {  font-family: Arial, Helvetica, sans-serif; font-size: 12px}\r
+-->\r
+</style>\r
+<!-- #EndEditable -->\r
+\r
+\r
+\r
+</head>\r
+\r
+<body bgcolor="#000000" text="#FFFFFF" link="#66CCFF" vlink="#0099FF" alink="#33FFFF" leftmargin="5" topmargin="5" marginwidth="5" marginheight="5" onLoad="">\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#0033CC" size="4"><b><font color="#FF9999">AlgoWars</font></b></font></p>\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#FF9999" size="3"><b><font size="2">Episodio IV</font></b></font>\r
+</p>\r
+<p>&nbsp;</p>\r
+<p><font size="+1"><b><!-- #BeginEditable "T%EDtulo" --><font color="#FFCC00">S&oacute;lo para Desarrolladores</font><!-- #EndEditable --></b></font></p>\r
+<br>  <!-- #BeginEditable "Cuerpo" -->\r
+<p>En esta secci&oacute;n se presenta material y documentaci&oacute;n sobre el proyecto.</p>\r
+<p>Este proyecto fue implementado &iacute;ntegramente en Delphi 4.0. Las &aacute;reas de esta secci&oacute;n son las siguientes:</p>\r
+<blockquote>\r
+  <a href="proyecto/doc/HISTORY.TXT">Historial de cambios</a> - Este archivo documenta los cambios m&aacute;s significativos del proyecto.\r
+  <p><a href="proyecto/doc/src-html/AlgoWars.html">C&oacute;digo Fuente</a> - En formato HTML para poder navegarlo online.</p>\r
+<p><a href="proyecto/doc/ref/">Manual de Referencia</a> - En formato HTML. Se presentan todas las clases del proyecto, describiendo su funcionalidad y sus m&eacute;todos. Tambi&eacute;n se puede ver un &iacute;ndice por unidades con la descripci&oacute;n de los cambios ralizados en cada una.</p>\r
+  <p><a href="uml.html">Diagramas UML</a> - Diagramas de Clases, Jerarqu&iacute;a, Secuencias y Estado m&aacute;s destacados para una mejor comprensi&oacute;n del sistema.\r
+  </p>\r
+  </blockquote>\r
+<!-- #EndEditable -->\r
+\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+<center>\r
+    <a href="main.html" target="mainFrame">Descripci&oacute;n</a> | <a href="instalar.html" target="mainFrame">Instalar el Juego</a> | <a href="configurar.html" target="mainFrame">Configurar un Escenario</a> | <a href="jugar.html" target="mainFrame">C&oacute;mo Jugar</a> | <a href="naves.html" target="mainFrame">Descripcion de Naves</a> | <a href="screenshots.html" target="mainFrame">Screenshots</a> | <a href="downloads.html" target="mainFrame">Downloads</a> | <a href="desarrollo.html" target="mainFrame">Desarrollo<br>\r
+  </a>\r
+  \r
+  <b><font color="#CCCC00" size="2">\r
+  </font></b><br>\r
+      \r
+</center>\r
+<center>\r
+  <font size="1" face="Arial, Helvetica, sans-serif">\r
+  Copyleft 2000. Ante cualquier duda env&iacute;enos un <a href="mailto:info@algowars.luca.2t.net?subject=AlgoWars">e-mail</a>\r
+</font>\r
+</center>\r
+  </body>\r
+<!-- #EndTemplate --></html>\r
diff --git a/website/downloads.html b/website/downloads.html
new file mode 100644 (file)
index 0000000..01af202
--- /dev/null
@@ -0,0 +1,81 @@
+<html><!-- #BeginTemplate "/Templates/normal.dwt" -->\r
+<!-- #BeginEditable "doctitle" -->\r
+<title>AlgoWars - Episodio IV</title>\r
+<!-- #EndEditable -->\r
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\r
+<!-- #BeginEditable "docstyle" -->\r
+<style type="text/css">\r
+<!--\r
+p {  margin-top: 5px; margin-right: 0px; margin-bottom: 5px}\r
+body {  font-family: Arial, Helvetica, sans-serif; font-size: 14px}\r
+ul {  list-style-image:      url(images/bullet.jpg); list-style-type: circle}\r
+li {  list-style-image:      url(images/bullet.jpg); list-style-type: circle}\r
+td {  font-family: Arial, Helvetica, sans-serif; font-size: 12px}\r
+-->\r
+</style>\r
+<!-- #EndEditable -->\r
+\r
+\r
+\r
+</head>\r
+\r
+<body bgcolor="#000000" text="#FFFFFF" link="#66CCFF" vlink="#0099FF" alink="#33FFFF" leftmargin="5" topmargin="5" marginwidth="5" marginheight="5" onLoad="">\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#0033CC" size="4"><b><font color="#FF9999">AlgoWars</font></b></font></p>\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#FF9999" size="3"><b><font size="2">Episodio IV</font></b></font>\r
+</p>\r
+<p>&nbsp;</p>\r
+<p><font size="+1"><b><!-- #BeginEditable "T%EDtulo" --><font color="#FFCC00">Downloads</font><!-- #EndEditable --></b></font></p>\r
+<br>\r
+  <!-- #BeginEditable "Cuerpo" -->\r
+<p>En esta secci&oacute;n est&aacute;n los archivos m&aacute;s importantes que usted puede descargar directamente desde el sitio web.</p>\r
+<p>&nbsp;</p>\r
+<p><font color="#FF0000" size="+1">AlgoWars - Episodio IV</font>  versi&oacute;n 1.0</p>\r
+<blockquote>\r
+  <p><a href="proyecto/download/instalar.exe">Programa de Instalaci&oacute;n</a> | versión 1.0.1.3 | 607 KB</p>\r
+  <p><a href="proyecto/download/algowars_src.zip">C&oacute;digo Fuente del Proyecto completo</a> | 1,12 MB</p>\r
+  <p><a href="proyecto/download/">Otras Versiones</a></p>\r
+</blockquote>\r
+<p><font color="#FF0000" size="+1">AlgoWars - Episodio IV</font></p>\r
+<blockquote>\r
+  <p><a href="proyecto/doc/Manual.zip">Manual del Usuario</a> | 180 KB (comprimido) | Actualizado el 15/12/00</p>\r
+  <p><a href="proyecto/doc/algoref.zip">Manual de Referencia para el Programador</a> | 120 KB | HTML (comprimido para ver offline).</p>\r
+</blockquote>\r
+<p><font size="+1"><b><font color="#FF0000">Escenarios</font></b></font><br>\r
+  </p>\r
+<blockquote>\r
+  <a href="proyecto/bin/comun.eaw">Escenario por defecto que viene con el Juego</a> | 9 KB\r
+  <p><a href="escenarios/naves.eaw">Escenario con varias naves</a> | 11 KB</p>\r
+  <p><a href="escenarios/meteoritos.eaw">Escenario con varios meteoritos</a> | 6 KB</p>\r
+  <p><a href="mailto:luca@lucarella.com.ar?subject=Escenario">Env&iacute;enos</a> su Escenario para que aparezca en esta secci&oacute;n.</p>\r
+</blockquote>\r
+<p><b><font color="#FF0000" size="+1">Skins</font></b> - Im&aacute;genes nuevas para el Juego</p>\r
+<blockquote>\r
+  <p><a href="skins/default.zip">Im&aacute;genes por defecto que vienen con el Juego</a> | 120 KB</p>\r
+  <p><a href="skins/alfa.zip">Im&aacute;genes que se utilizaron en las primeras versiones del Juego</a> | 11 KB</p>\r
+  <p><a href="mailto:luca@lucarella.com.ar?subject=Skin">Env&iacute;enos</a> sus im&aacute;genes para que aparezca en esta secci&oacute;n.</p>\r
+  <p>&iquest;No sabe c&oacute;mo instalar las nuevas im&aacute;genes? Aver&iacute;guelo <a href="skins.html">aqu&iacute;</a>.</p>\r
+</blockquote>\r
+<p>&nbsp;</p>\r
+<!-- #EndEditable -->\r
+\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+<center>\r
+    <a href="main.html" target="mainFrame">Descripci&oacute;n</a> | <a href="instalar.html" target="mainFrame">Instalar el Juego</a> | <a href="configurar.html" target="mainFrame">Configurar un Escenario</a> | <a href="jugar.html" target="mainFrame">C&oacute;mo Jugar</a> | <a href="naves.html" target="mainFrame">Descripcion de Naves</a> | <a href="screenshots.html" target="mainFrame">Screenshots</a> | <a href="downloads.html" target="mainFrame">Downloads</a> | <a href="desarrollo.html" target="mainFrame">Desarrollo<br>\r
+  </a>\r
+  \r
+  <b><font color="#CCCC00" size="2">\r
+  </font></b><br>\r
+      \r
+</center>\r
+<center>\r
+  <font size="1" face="Arial, Helvetica, sans-serif">\r
+  Copyleft 2000. Ante cualquier duda env&iacute;enos un <a href="mailto:info@algowars.luca.2t.net?subject=AlgoWars">e-mail</a>\r
+</font>\r
+</center>\r
+  </body>\r
+<!-- #EndTemplate --></html>\r
diff --git a/website/images/algowars.gif b/website/images/algowars.gif
new file mode 100644 (file)
index 0000000..4fa1eda
Binary files /dev/null and b/website/images/algowars.gif differ
diff --git a/website/images/bullet.jpg b/website/images/bullet.jpg
new file mode 100644 (file)
index 0000000..d922b66
Binary files /dev/null and b/website/images/bullet.jpg differ
diff --git a/website/images/desarrolladores.gif b/website/images/desarrolladores.gif
new file mode 100644 (file)
index 0000000..a0b899d
Binary files /dev/null and b/website/images/desarrolladores.gif differ
diff --git a/website/images/desconocido.jpg b/website/images/desconocido.jpg
new file mode 100644 (file)
index 0000000..8e9086d
Binary files /dev/null and b/website/images/desconocido.jpg differ
diff --git a/website/images/desconocido_l.jpg b/website/images/desconocido_l.jpg
new file mode 100644 (file)
index 0000000..15e5957
Binary files /dev/null and b/website/images/desconocido_l.jpg differ
diff --git a/website/images/download.gif b/website/images/download.gif
new file mode 100644 (file)
index 0000000..ec7687f
Binary files /dev/null and b/website/images/download.gif differ
diff --git a/website/images/meteorito.jpg b/website/images/meteorito.jpg
new file mode 100644 (file)
index 0000000..9ff0a16
Binary files /dev/null and b/website/images/meteorito.jpg differ
diff --git a/website/images/meteorito_l.jpg b/website/images/meteorito_l.jpg
new file mode 100644 (file)
index 0000000..bc3dfa0
Binary files /dev/null and b/website/images/meteorito_l.jpg differ
diff --git a/website/images/naveespia.jpg b/website/images/naveespia.jpg
new file mode 100644 (file)
index 0000000..db6b00c
Binary files /dev/null and b/website/images/naveespia.jpg differ
diff --git a/website/images/naveespia_l.jpg b/website/images/naveespia_l.jpg
new file mode 100644 (file)
index 0000000..d089241
Binary files /dev/null and b/website/images/naveespia_l.jpg differ
diff --git a/website/images/naveliviana.jpg b/website/images/naveliviana.jpg
new file mode 100644 (file)
index 0000000..ed22396
Binary files /dev/null and b/website/images/naveliviana.jpg differ
diff --git a/website/images/naveliviana_l.jpg b/website/images/naveliviana_l.jpg
new file mode 100644 (file)
index 0000000..a1267b3
Binary files /dev/null and b/website/images/naveliviana_l.jpg differ
diff --git a/website/images/navepesada.jpg b/website/images/navepesada.jpg
new file mode 100644 (file)
index 0000000..8f1eb84
Binary files /dev/null and b/website/images/navepesada.jpg differ
diff --git a/website/images/navepesada_l.jpg b/website/images/navepesada_l.jpg
new file mode 100644 (file)
index 0000000..d9f95ee
Binary files /dev/null and b/website/images/navepesada_l.jpg differ
diff --git a/website/images/navepropia.jpg b/website/images/navepropia.jpg
new file mode 100644 (file)
index 0000000..b0799b3
Binary files /dev/null and b/website/images/navepropia.jpg differ
diff --git a/website/images/navepropia_l.jpg b/website/images/navepropia_l.jpg
new file mode 100644 (file)
index 0000000..c056d42
Binary files /dev/null and b/website/images/navepropia_l.jpg differ
diff --git a/website/images/navesuicida.jpg b/website/images/navesuicida.jpg
new file mode 100644 (file)
index 0000000..2b9cd90
Binary files /dev/null and b/website/images/navesuicida.jpg differ
diff --git a/website/images/navesuicida_l.jpg b/website/images/navesuicida_l.jpg
new file mode 100644 (file)
index 0000000..f7ca30a
Binary files /dev/null and b/website/images/navesuicida_l.jpg differ
diff --git a/website/index.html b/website/index.html
new file mode 100644 (file)
index 0000000..a32abf4
--- /dev/null
@@ -0,0 +1,14 @@
+<html>\r
+<head>\r
+<title>AlgoWars - Episodio IV</title>\r
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\r
+</head>\r
+\r
+<frameset cols="160,573*" frameborder="NO" border="0" framespacing="0" rows="*"> \r
+  <frame name="leftFrame" scrolling="NO" noresize src="barra.html" frameborder="NO">\r
+  <frame name="mainFrame" src="main.html" marginwidth="20">\r
+</frameset>\r
+<noframes><body bgcolor="#FFFFFF">\r
+\r
+</body></noframes>\r
+</html>\r
diff --git a/website/instalar.html b/website/instalar.html
new file mode 100644 (file)
index 0000000..ad29afd
--- /dev/null
@@ -0,0 +1,231 @@
+<html>\r
+   <!-- #BeginTemplate "/Templates/normal.dwt" -->\r
+   <!-- #BeginEditable "doctitle" -->\r
+\r
+   <head>\r
+      <meta\r
+       name="generator"\r
+       content=\r
+      "HTML Tidy for Linux/x86 (vers 1st February 2002), see www.w3.org">\r
+\r
+      <title>AlgoWars - Episodio IV</title>\r
+      <!-- #EndEditable -->\r
+      <meta\r
+       http-equiv="Content-Type"\r
+       content="text/html; charset=iso-8859-1">\r
+      <!-- #BeginEditable "docstyle" -->\r
+<style\r
+ type="text/css">\r
+<!--\r
+p {  margin-top: 5px; margin-right: 0px; margin-bottom: 5px}\r
+body {  font-family: Arial, Helvetica, sans-serif; font-size: 14px}\r
+ul {  list-style-image:      url(images/bullet.jpg); list-style-type: circle}\r
+li {  list-style-image:      url(images/bullet.jpg); list-style-type: circle}\r
+td {  font-family: Arial, Helvetica, sans-serif; font-size: 12px}\r
+-->\r
+</style>\r
+      <!-- #EndEditable -->\r
+<style\r
+ type="text/css">\r
+ body {\r
+  background-color: #000000;\r
+  color: #FFFFFF;\r
+ }\r
+ :link { color: #66CCFF }\r
+ :visited { color: #0099FF }\r
+ :active { color: #33FFFF }\r
+ div.c9 {font-family: Arial, Helvetica, sans-serif; font-size: 70%; text-align: center}\r
+ div.c8 {text-align: center}\r
+ p.c7 {text-align: center}\r
+ p.c6 {font-size: 119%}\r
+ span.c5 {color: #FFCC33}\r
+ p.c4 {color: #FF9999; font-family: Arial, Helvetica, sans-serif; text-align: center}\r
+ strong.c3 {font-size: 80%}\r
+ h3.c2 {color: #0033CC; font-family: Arial, Helvetica, sans-serif; text-align: center}\r
+ strong.c1 {color: #FF9999}\r
+</style>\r
+   </head>\r
+\r
+   <body\r
+    leftmargin="5"\r
+    topmargin="5"\r
+    marginwidth="5"\r
+    marginheight="5"\r
+    onload="">\r
+      <h3\r
+       class="c2"><strong\r
+       class="c1">AlgoWars</strong></h3>\r
+\r
+      <p\r
+       class="c4"><strong\r
+       class="c3">Episodio IV</strong></p>\r
+\r
+      <p>&#160;</p>\r
+\r
+      <p\r
+       class="c6"><strong><!-- #BeginEditable "T%EDtulo" --><span\r
+       class="c5">¿Cómo Instalar AlgoWars?</span>\r
+      <!-- #EndEditable --></strong></p>\r
+\r
+      <br>\r
+       <!-- #BeginEditable "Cuerpo" -->\r
+\r
+      <p>Instalar el programa es muy simple. Todo lo que tiene que hacer\r
+      es abrir el archivo <a\r
+       href="proyecto/download/instalar.exe">instalar.exe</a> y seguir\r
+      las instrucciones que aparecen en pantalla.</p>\r
+\r
+      <p>Para instalar el programa, primero asegúrese de tener al menos 1\r
+      MB de espacio disponible en el disco.</p>\r
+\r
+      <p>Ahora repasaremos brevemente el proceso de instalación. Al\r
+      iniciar el instalador, se econtrará con un mensaje de bienvenida.\r
+      Haga click en <img\r
+       alt="Siguiente"\r
+       src="screenshots/siguiente.jpg"\r
+       width="74"\r
+       height="22"\r
+       align="absmiddle"> para continuar.</p>\r
+\r
+      <p>Ahora podrá ver una pantalla con la licencia del programa, la\r
+      cual tendrá que aceptar para poder seguir con el proceso de\r
+      instalación. Para aceptar la licencia presione <img\r
+       alt="S&iacute;"\r
+       src="screenshots/si.jpg"\r
+       width="74"\r
+       height="22"\r
+       align="absmiddle">, si no está de acuerdo, presione <img\r
+       alt="No"\r
+       src="screenshots/no.jpg"\r
+       width="74"\r
+       height="22"\r
+       align="absmiddle"> para terminar con el proceso de\r
+      instalación.</p>\r
+\r
+      <p>na vez aceptada la licencia el programa le preguntará dónde\r
+      desea instalar AlgoWars en una pantalla como la siguiente:</p>\r
+\r
+      <p>&#160;</p>\r
+\r
+      <p\r
+       class="c7"><img\r
+       alt="Pantalla de Instalaci&oacute;n"\r
+       src="screenshots/inst1.jpg"\r
+       width="416"\r
+       height="315"></p>\r
+\r
+      <p\r
+       class="c7">&#160;</p>\r
+\r
+      <p>Luego de elegir el directorio deseado haga click en <img\r
+       alt="Siguiente"\r
+       src="screenshots/siguiente.jpg"\r
+       width="74"\r
+       height="22"\r
+       align="absmiddle"> para proceder. En este momento es posible que\r
+      aparezca una advertencia si está instalando el juego en un\r
+      directorio existente.</p>\r
+\r
+      <p>En la próxima pantalla se le da la posibilidad de crear un grupo\r
+      de programas (con sus correspondientes íconos) para un más fácil\r
+      acceso al juego. Esta pantalla tiene un aspecto similar a la\r
+      siguiente:</p>\r
+\r
+      <p>&#160;</p>\r
+\r
+      <p\r
+       class="c7"><img\r
+       alt="Pantalla de Instalaci&oacute;n"\r
+       src="screenshots/inst2.jpg"\r
+       width="414"\r
+       height="313"></p>\r
+\r
+      <p>&#160;</p>\r
+\r
+      <p>Si no desea crear ningún ícono, seleccione la opción. De lo\r
+      contrario elija el nombre del grupo de programas en dónde crearlo.\r
+      A continuación presiones <img\r
+       alt="Siguiente"\r
+       src="screenshots/siguiente.jpg"\r
+       width="74"\r
+       height="22"\r
+       align="absmiddle">.</p>\r
+\r
+      <p>Ahora verá un mensaje indicando que el sistema está listo para\r
+      ser instalado. Presione <img\r
+       alt="Instalar"\r
+       src="screenshots/instalar.jpg"\r
+       width="74"\r
+       height="22"\r
+       align="absmiddle"> para comenzar con la copia de los archivos.</p>\r
+\r
+      <p>A continuación verá una información útil sobre los cambios del\r
+      programa en sus diferentes versiones. Presione <img\r
+       alt="Siguiente"\r
+       src="screenshots/siguiente.jpg"\r
+       width="74"\r
+       height="22"\r
+       align="absmiddle"> una vez más para continuar.</p>\r
+\r
+      <p>Finalmente se muestra un mensaje indicando que el programa se\r
+      instaló con éxito. Puede presionar <img\r
+       alt="Terminar"\r
+       src="screenshots/terminar.jpg"\r
+       width="74"\r
+       height="22"\r
+       align="absmiddle"> para finalizar el proceso de instalación.</p>\r
+\r
+      <p>Esto es todo, ahora sélo tiene que <a\r
+       href="configurar.html">configurar un Escenario</a> y ya está listo\r
+      para <a\r
+       href="jugar.html">jugar</a>!\r
+      <br>\r
+      </p>\r
+      <!-- #EndEditable -->\r
+\r
+      <br>\r
+       \r
+      <br>\r
+       \r
+      <br>\r
+       \r
+      <br>\r
+       \r
+      <br>\r
+       \r
+      <br>\r
+\r
+      <div\r
+       class="c8">\r
+         <a\r
+          href="main.html"\r
+          target="mainFrame">Descripción</a> | <a\r
+          href="instalar.html"\r
+          target="mainFrame">Instalar el Juego</a> | <a\r
+          href="configurar.html"\r
+          target="mainFrame">Configurar un Escenario</a> | <a\r
+          href="jugar.html"\r
+          target="mainFrame">Cómo Jugar</a> | <a\r
+          href="naves.html"\r
+          target="mainFrame">Descripcion de Naves</a> | <a\r
+          href="screenshots.html"\r
+          target="mainFrame">Screenshots</a> | <a\r
+          href="downloads.html"\r
+          target="mainFrame">Downloads</a> | <a\r
+          href="desarrollo.html"\r
+          target="mainFrame">Desarrollo\r
+         <br>\r
+         </a>\r
+         <br>\r
+      </div>\r
+\r
+      <div\r
+       class="c9">\r
+         Copyleft 2000. Ante cualquier duda envíenos un <a\r
+          href=\r
+         "mailto:info@algowars.luca.2t.net?subject=AlgoWars">e-mail</a>\r
+      </div>\r
+      <!-- #EndTemplate -->\r
+   </body>\r
+</html>\r
+\r
diff --git a/website/jugar.html b/website/jugar.html
new file mode 100644 (file)
index 0000000..d6ce826
--- /dev/null
@@ -0,0 +1,88 @@
+<html><!-- #BeginTemplate "/Templates/normal.dwt" -->\r
+<!-- #BeginEditable "doctitle" -->\r
+<title>AlgoWars - Episodio IV</title>\r
+<!-- #EndEditable -->\r
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\r
+<!-- #BeginEditable "docstyle" -->\r
+<style type="text/css">\r
+<!--\r
+p {  margin-top: 5px; margin-right: 0px; margin-bottom: 5px}\r
+body {  font-family: Arial, Helvetica, sans-serif; font-size: 14px}\r
+ul {  list-style-image:      url(images/bullet.jpg); list-style-type: circle}\r
+li {  list-style-image:      url(images/bullet.jpg); list-style-type: circle}\r
+td {  font-family: Arial, Helvetica, sans-serif; font-size: 12px}\r
+-->\r
+</style>\r
+<!-- #EndEditable -->\r
+\r
+\r
+\r
+</head>\r
+\r
+<body bgcolor="#000000" text="#FFFFFF" link="#66CCFF" vlink="#0099FF" alink="#33FFFF" leftmargin="5" topmargin="5" marginwidth="5" marginheight="5" onLoad="">\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#0033CC" size="4"><b><font color="#FF9999">AlgoWars</font></b></font></p>\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#FF9999" size="3"><b><font size="2">Episodio IV</font></b></font>\r
+</p>\r
+<p>&nbsp;</p>\r
+<p><font size="+1"><b><!-- #BeginEditable "T%EDtulo" --><font color="#FFCC00">&iquest;C&oacute;mo Jugar?</font><!-- #EndEditable --></b></font></p>\r
+<br>  <!-- #BeginEditable "Cuerpo" -->\r
+<p><img src="screenshots/juego.jpg" width="408" height="479" align="right">Para jugar AlgoWars solamente hay que <a href="configurar.html">configurar un Escenario</a> (o usar el Escenario por defecto) y presionar el bot&oacute;n <font color="#FFCC99"><i>Iniciar</i></font>.</p>\r
+<p>Una vez que iniciamos el juego, podemos pausarlo en cualquier momento presionando simplemente el bot&oacute;n <font color="#FFCC99"><i>Pausa</i></font> y podemos reanudarlo volviendo a presionar dicho bot&oacute;n, ahora con la leyenda <font color="#FFCC99"><i>Continuar</i></font>.</p>\r
+<p>La nave del jugador puede realizar todo tipo de movimiento:</p>\r
+<p><b><font color="#FF0000">I</font></b>: Arriba</p>\r
+<p><b><font color="#FF0000">K</font></b>: Abajo</p>\r
+<p><b><font color="#FF0000">L</font></b>: Derecha</p>\r
+<p><b><font color="#FF0000">J</font></b>: Izquierda</p>\r
+<p><b><font color="#FF0000">U</font></b>: Rotar hacia la Derecha</p>\r
+<p><font color="#FF0000"><b>O</b></font>: Rotar hacia la Izquierda</p>\r
+<p><b><font color="#FF0000">Q</font></b>: Acelerar</p>\r
+<p><b><font color="#FF0000">A</font></b>: Desacelerar</p>\r
+<p>Para hacer uso del armamento se pueden utilizar las siguientes teclas:</p>\r
+<p><font color="#FF0000"><b>S</b></font>: Dispara el arma seleccionada</p>\r
+<p><font color="#FF0000"><b>W</b></font>: Selecciona el arma siguiente (con municiones)</p>\r
+<p><font color="#FF0000"><b>T</b></font>: Selecciona el siguiente objetivo (si est&aacute; a distancia)\r
+</p>\r
+<p>Para poder disparar un arma, est&aacute; debe estar en color <font color="#00FF00">verde</font>. Si el arma seleccionada se encuentra en <font color="#FF0000">rojo</font>, entonces quiere decir que se est&aacute; recargando y no est&aacute; a&uacute;n lista para dispara o que se qued&oacute; sin municiones. En este caso puede o bien seleccionar el arma siguiente o esperar que se recargue el arma actual.</p>\r
+<p>Adem&aacute;s de ver el juego a trav&eacute;s de la cabina de la nave, puede hacerlo a trav&eacute;s de una serie de vistas alternativas:</p>\r
+<p><b><font color="#FF0000">F1</font></b>: C&aacute;mara Frontal (de la cabina).</p>\r
+<p><b><font color="#FF0000">F2</font></b>: C&aacute;mara Lateral Derecha</p>\r
+<p><b><font color="#FF0000">F3</font></b>: C&aacute;mara Lateral Izquierda</p>\r
+<p><b><font color="#FF0000">F4</font></b>: C&aacute;mara Trasera</p>\r
+<p><b><font color="#FF0000">F5</font></b>: C&aacute;mara Superior (para mirar hacia arriba)</p>\r
+<p></p>\r
+<p><b><font color="#FF0000">F6</font></b>: C&aacute;mara Inferior (para mirar hacia abajo)</p>\r
+<p><b><font color="#FF0000">F7</font></b>: C&aacute;mara del Arma (para ver desde el &uacute;ltimo arma disparado)</p>\r
+<p><b><font color="#FF0000">M</font></b>:  Mapa.</p>\r
+<p>Tambi&eacute;n hay otras opciones extra con respecto a la visualizaci&oacute;n del juego:</p>\r
+<p><b><font color="#FF0000">Ctrl-H</font></b>: Activa/Desactiva la visualizaci&oacute;n de Alta Calidad (con transparencias)</p>\r
+<p><b><font color="#FF0000">Ctrl-B</font></b>: Activa/Desactiva el cambio autom&aacute;tico de la C&aacute;mara.</p>\r
+<p>Esta &uacute;ltima opci&oacute;n sirve para que el juego cambie a la C&aacute;mara del Arma autom&aacute;ticamente cada vez que el jugador dispara.</p>\r
+<p></p>\r
+<p></p>\r
+<p></p>\r
+<p>Adem&aacute;s existe la posibilidad de Guardar un juego para poder continuarlo en otro momento. Esto es tan simple como ir al Men&uacute; Juego, seleccionar <font color="#FFCC99"><i>Guardar ...</i></font> (<font color="#FF0000"><b>Ctrl-G</b></font>) y luego elegir el nombre y la ubicaci&oacute;n del archivo para almacenarlo o seleccionar <font color="#FFCC99"><i>Abrir ...</i></font>  (<font color="#FF0000"><b>Ctrl-A</b></font>) para recuperarlo.</p>\r
+<p>&nbsp;</p>\r
+<p align="center"><img src="screenshots/menu_juego.jpg" width="408" height="150"></p>\r
+<!-- #EndEditable -->\r
+\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+<center>\r
+    <a href="main.html" target="mainFrame">Descripci&oacute;n</a> | <a href="instalar.html" target="mainFrame">Instalar el Juego</a> | <a href="configurar.html" target="mainFrame">Configurar un Escenario</a> | <a href="jugar.html" target="mainFrame">C&oacute;mo Jugar</a> | <a href="naves.html" target="mainFrame">Descripcion de Naves</a> | <a href="screenshots.html" target="mainFrame">Screenshots</a> | <a href="downloads.html" target="mainFrame">Downloads</a> | <a href="desarrollo.html" target="mainFrame">Desarrollo<br>\r
+  </a>\r
+  \r
+  <b><font color="#CCCC00" size="2">\r
+  </font></b><br>\r
+      \r
+</center>\r
+<center>\r
+  <font size="1" face="Arial, Helvetica, sans-serif">\r
+  Copyleft 2000. Ante cualquier duda env&iacute;enos un <a href="mailto:info@algowars.luca.2t.net?subject=AlgoWars">e-mail</a>\r
+</font>\r
+</center>\r
+  </body>\r
+<!-- #EndTemplate --></html>\r
diff --git a/website/main.html b/website/main.html
new file mode 100644 (file)
index 0000000..fb6876b
--- /dev/null
@@ -0,0 +1,59 @@
+<html><!-- #BeginTemplate "/Templates/normal.dwt" -->\r
+<!-- #BeginEditable "doctitle" -->\r
+<title>AlgoWars - Episodio IV</title>\r
+<!-- #EndEditable -->\r
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\r
+<!-- #BeginEditable "docstyle" -->\r
+<style type="text/css">\r
+<!--\r
+p {  margin-top: 5px; margin-right: 0px; margin-bottom: 5px}\r
+body {  font-family: Arial, Helvetica, sans-serif; font-size: 14px}\r
+ul {  list-style-image:      url(images/bullet.jpg); list-style-type: circle}\r
+li {  list-style-image:      url(images/bullet.jpg); list-style-type: circle}\r
+td {  font-family: Arial, Helvetica, sans-serif; font-size: 12px}\r
+-->\r
+</style>\r
+<!-- #EndEditable -->\r
+\r
+\r
+\r
+</head>\r
+\r
+<body bgcolor="#000000" text="#FFFFFF" link="#66CCFF" vlink="#0099FF" alink="#33FFFF" leftmargin="5" topmargin="5" marginwidth="5" marginheight="5" onLoad="">\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#0033CC" size="4"><b><font color="#FF9999">AlgoWars</font></b></font></p>\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#FF9999" size="3"><b><font size="2">Episodio IV</font></b></font>\r
+</p>\r
+<p>&nbsp;</p>\r
+<p><font size="+1"><b><!-- #BeginEditable "T%EDtulo" --><font color="#FFCC66">Descripci&oacute;n del Programa</font><!-- #EndEditable --></b></font></p>\r
+<br>  <!-- #BeginEditable "Cuerpo" -->\r
+<p><br>\r
+AlgoWars es un  juego al estilo de un simulador de vuelo el cual se desplaza sobre un espacio tridimensional.</p>\r
+  <p>El Juagador pilotear una nave espacial, teniendo a su disposición una variedad de armas con las cuales deberá sortear peligros tales como meteoritos, naves y demás obstáculos.</p>\r
+  <p>A través de la cabina de la nave se verá el espacio, y sobre el tablero de la misma podrá obtenerse datos tales como velocidad, energía y misiles disponibles.</p>\r
+  <p>El juego comienza con una cantidad finita de obstáculos predeterminada por el usuario en el momento de la configuración.</p>\r
+  <p>Estos atacarán de diferentes formas a la nave del jugador, el cual podrá utilizar todos los recursos disponibles por el sistema para contrarestar dichos ataques.</p>\r
+  <p>&nbsp;</p>\r
+  <p>Nueva versión disponible! <a href="proyecto/download/instalar.exe">AlgoWars versi&oacute;n 1.0.1.3</a> (607KB).</p>\r
+  <p>Para ver los cambio principales puede observar el archivo <a href="proyecto/doc/CHANGES.TXT">CHANGES.TXT</a>.</p>\r
+  <!-- #EndEditable -->\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+<center>\r
+    <a href="main.html" target="mainFrame">Descripci&oacute;n</a> | <a href="instalar.html" target="mainFrame">Instalar el Juego</a> | <a href="configurar.html" target="mainFrame">Configurar un Escenario</a> | <a href="jugar.html" target="mainFrame">C&oacute;mo Jugar</a> | <a href="naves.html" target="mainFrame">Descripcion de Naves</a> | <a href="screenshots.html" target="mainFrame">Screenshots</a> | <a href="downloads.html" target="mainFrame">Downloads</a> | <a href="desarrollo.html" target="mainFrame">Desarrollo<br>\r
+  </a>\r
+  \r
+  <b><font color="#CCCC00" size="2">\r
+  </font></b><br>\r
+      \r
+</center>\r
+<center>\r
+  <font size="1" face="Arial, Helvetica, sans-serif">\r
+  Copyleft 2000. Ante cualquier duda env&iacute;enos un <a href="mailto:info@algowars.luca.2t.net?subject=AlgoWars">e-mail</a>\r
+</font>\r
+</center>\r
+  </body>\r
+<!-- #EndTemplate --></html>\r
diff --git a/website/naves.html b/website/naves.html
new file mode 100644 (file)
index 0000000..b1c0254
--- /dev/null
@@ -0,0 +1,411 @@
+<html>\r
+   <!-- #BeginTemplate "/Templates/normal.dwt" -->\r
+   <!-- #BeginEditable "doctitle" -->\r
+\r
+   <head>\r
+      <meta\r
+       name="generator"\r
+       content=\r
+      "HTML Tidy for Linux/x86 (vers 1st February 2002), see www.w3.org">\r
+\r
+      <title>AlgoWars - Episodio IV</title>\r
+      <!-- #EndEditable -->\r
+      <meta\r
+       http-equiv="Content-Type"\r
+       content="text/html; charset=iso-8859-1">\r
+      <!-- #BeginEditable "docstyle" -->\r
+<style\r
+ type="text/css">\r
+<!--\r
+p {  margin-top: 5px; margin-right: 0px; margin-bottom: 5px}\r
+body {  font-family: Arial, Helvetica, sans-serif; font-size: 14px}\r
+ul {  list-style-image:      url(images/bullet.jpg); list-style-type: circle}\r
+li {  list-style-image:      url(images/bullet.jpg); list-style-type: circle}\r
+td {  font-family: Arial, Helvetica, sans-serif; font-size: 12px}\r
+pre {  font-family: "Courier New", Courier, mono; font-size: 12px}\r
+-->\r
+</style>\r
+      <!-- #EndEditable -->\r
+<style\r
+ type="text/css">\r
+ body {\r
+  background-color: #000000;\r
+  color: #FFFFFF;\r
+ }\r
+ :link { color: #66CCFF }\r
+ :visited { color: #0099FF }\r
+ :active { color: #33FFFF }\r
+ div.c12 {font-family: Arial, Helvetica, sans-serif; font-size: 70%; text-align: center}\r
+ div.c11 {text-align: center}\r
+ p.c10 {color: #003399}\r
+ strong.c9 {color: #FFCC00; font-family: Verdana, Arial, Helvetica, sans-serif}\r
+ p.c8 {color: #CCFFFF; font-family: Verdana, Arial, Helvetica, sans-serif}\r
+ strong.c7 {color: #FFCC00}\r
+ p.c6 {font-size: 119%}\r
+ span.c5 {color: #FFCC00}\r
+ p.c4 {color: #FF9999; font-family: Arial, Helvetica, sans-serif; text-align: center}\r
+ strong.c3 {font-size: 80%}\r
+ h3.c2 {color: #0033CC; font-family: Arial, Helvetica, sans-serif; text-align: center}\r
+ strong.c1 {color: #FF9999}\r
+</style>\r
+   </head>\r
+\r
+   <body\r
+    leftmargin="5"\r
+    topmargin="5"\r
+    marginwidth="5"\r
+    marginheight="5"\r
+    onload="">\r
+      <h3\r
+       class="c2"><strong\r
+       class="c1">AlgoWars</strong></h3>\r
+\r
+      <p\r
+       class="c4"><strong\r
+       class="c3">Episodio IV</strong></p>\r
+\r
+      <p>&#160;</p>\r
+\r
+      <p\r
+       class="c6"><strong><!-- #BeginEditable "T%EDtulo" --><span\r
+       class="c5">Descripción de las Naves y otros Objetos del\r
+      Escenario</span><!-- #EndEditable --></strong></p>\r
+\r
+      <br>\r
+       <!-- #BeginEditable "Cuerpo" -->\r
+       \r
+\r
+      <p>A continuación se presenta una serie de pequeñas descripciones\r
+      sobre los posibles objetos voladores a incluir en el Escenario:</p>\r
+\r
+      <table\r
+       summary="Descripci&oacute;n de las naves"\r
+       width="100%"\r
+       border="0"\r
+       cellspacing="5"\r
+       cellpadding="10">\r
+         <tr>\r
+            <td\r
+             width="100"\r
+             align="center"\r
+             valign="middle"><img\r
+             alt="Nave Propia"\r
+             src="skins/default/navepropia.jpg"\r
+             width="100"\r
+             height="100"></td>\r
+\r
+            <td\r
+             align="left"\r
+             valign="top"\r
+             bgcolor="#003399">\r
+               <p\r
+                class="c8"><strong\r
+                class="c7"><a\r
+                name="navepropia"></a>Nave Del Jugador</strong></p>\r
+\r
+               <p><u>Características:</u></p>\r
+<pre>\r
+      Dimensión:            15        metros de radio\r
+      Potencia:             5         Cantidad de daño que hace\r
+      Energía:              100       Cantidad de daño que soporta\r
+      Velocidad máxima:     612       km/h\r
+      Misiles:              10\r
+      Misiles Dirigidos:    5\r
+</pre>\r
+            </td>\r
+         </tr>\r
+\r
+         <tr>\r
+            <td\r
+             align="center"\r
+             valign="middle"><img\r
+             alt="Nave Pesada"\r
+             src="skins/default/navepesada.jpg"\r
+             width="100"\r
+             height="92"></td>\r
+\r
+            <td\r
+             align="left"\r
+             valign="top"\r
+             bgcolor="#003399">\r
+               <p\r
+                class="c10"><strong\r
+                class="c9"><a\r
+                name="navepesada"></a>Nave Pesada</strong></p>\r
+\r
+               <p><u>Características:</u></p>\r
+<pre>\r
+      Dimensión:            25        metros de radio\r
+      Potencia:             2         Cantidad de daño que hace\r
+      Energía:              100       Cantidad de daño que soporta\r
+      Velocidad máxima:     612       km/h\r
+      Campo de radar:       5000      metros (5 km)\r
+      Misiles:              5\r
+      Misiles Dirigidos:    2\r
+</pre>\r
+            </td>\r
+         </tr>\r
+\r
+         <tr>\r
+            <td\r
+             align="center"\r
+             valign="middle"><img\r
+             alt="Nave Liviana"\r
+             src="skins/default/naveliviana.jpg"\r
+             width="93"\r
+             height="96"></td>\r
+\r
+            <td\r
+             align="left"\r
+             valign="top"\r
+             bgcolor="#003399">\r
+               <p\r
+                class="c10"><strong\r
+                class="c9"><a\r
+                name="naveliviana"></a>Nave Liviana</strong></p>\r
+\r
+               <p><u>Características:</u></p>\r
+<pre>\r
+      Dimensión:            15        metros de radio\r
+      Potencia:             1         Cantidad de daño que hace\r
+      Energía:              60        Cantidad de daño que soporta\r
+      Velocidad máxima:     648       km/h\r
+      Campo de radar:       3000      metros (3 km)\r
+      Misiles:              0\r
+      Misiles Dirigidos:    0\r
+</pre>\r
+            </td>\r
+         </tr>\r
+\r
+         <tr>\r
+            <td\r
+             align="center"\r
+             valign="middle"><img\r
+             alt="Nave Esp&iacute;a"\r
+             src="skins/default/naveespia.jpg"\r
+             width="100"\r
+             height="89"></td>\r
+\r
+            <td\r
+             align="left"\r
+             valign="top"\r
+             bgcolor="#003399">\r
+               <p\r
+                class="c10"><strong\r
+                class="c9"><a\r
+                name="naveespia"></a>Nave Espía</strong></p>\r
+\r
+               <p><u>Características:</u></p>\r
+<pre>\r
+      Dimensión:            10        metros de radio\r
+      Potencia:             1         Cantidad de daño que hace\r
+      Energía:              30        Cantidad de daño que soporta\r
+      Velocidad máxima:     720       km/h\r
+      Campo de radar:       2000      metros (2 km)\r
+      Misiles:              0\r
+      Misiles Dirigidos:    0\r
+</pre>\r
+            </td>\r
+         </tr>\r
+\r
+         <tr>\r
+            <td\r
+             align="center"\r
+             valign="middle"><img\r
+             alt="Nave Suicida"\r
+             src="skins/default/navesuicida.jpg"\r
+             width="100"\r
+             height="97"></td>\r
+\r
+            <td\r
+             align="left"\r
+             valign="top"\r
+             bgcolor="#003399">\r
+               <p\r
+                class="c10"><strong\r
+                class="c9"><a\r
+                name="navesuicida"></a>Nave Suicida</strong></p>\r
+\r
+               <p><u>Características:</u></p>\r
+<pre>\r
+      Dimensión:            10        metros de radio\r
+      Potencia:             4         Cantidad de daño que hace\r
+      Energía:              30        Cantidad de daño que soporta\r
+      Velocidad máxima:     720       km/h\r
+      Campo de radar:       2500      metros (2,5 km)\r
+      Misiles:              0\r
+      Misiles Dirigidos:    0\r
+</pre>\r
+            </td>\r
+         </tr>\r
+\r
+         <tr>\r
+            <td\r
+             align="center"\r
+             valign="middle"><img\r
+             alt="Meteorito"\r
+             src="skins/default/meteorito.jpg"\r
+             width="100"\r
+             height="100"></td>\r
+\r
+            <td\r
+             align="left"\r
+             valign="top"\r
+             bgcolor="#003399">\r
+               <p\r
+                class="c10"><strong\r
+                class="c9"><a\r
+                name="meteorito"></a>Meteorito</strong></p>\r
+\r
+               <p><u>Características:</u></p>\r
+<pre>\r
+      Dimensión:            5         metros de radio\r
+      Potencia:             5         Cantidad de daño que hace\r
+      Energía:              20        Cantidad de daño que soporta\r
+</pre>\r
+            </td>\r
+         </tr>\r
+\r
+         <tr>\r
+            <td\r
+             align="center"\r
+             valign="middle"><img\r
+             alt="Laser"\r
+             src="skins/default/laser.jpg"\r
+             width="32"\r
+             height="32"></td>\r
+\r
+            <td\r
+             align="left"\r
+             valign="top"\r
+             bgcolor="#003399">\r
+               <p\r
+                class="c10"><strong\r
+                class="c9"><a\r
+                name="laser"></a>Laser</strong></p>\r
+\r
+               <p><u>Características:</u></p>\r
+<pre>\r
+      Dimensión      0,1       metros de radio(10 cm)\r
+      Potencia:      1         Cantidad de daño que hace\r
+      Energía:       1         Cantidad de daño que soporta\r
+      Velocidad:     1440      km/h\r
+      Duración:      3000      milisegundos (3 segundos)\r
+      Alcance:       1,2       km\r
+</pre>\r
+            </td>\r
+         </tr>\r
+\r
+         <tr>\r
+            <td\r
+             align="center"\r
+             valign="middle"><img\r
+             alt="Misil"\r
+             src="skins/default/misil.jpg"\r
+             width="32"\r
+             height="32"></td>\r
+\r
+            <td\r
+             align="left"\r
+             valign="top"\r
+             bgcolor="#003399">\r
+               <p\r
+                class="c10"><strong\r
+                class="c9"><a\r
+                name="misil"></a>Misil</strong></p>\r
+\r
+               <p><u>Características:</u></p>\r
+<pre>\r
+      Dimensión      0,5       metros de radio (50 cm)\r
+      Potencia:      20        Cantidad de daño que hace\r
+      Energía:       1         Cantidad de daño que soporta\r
+      Velocidad:     1080      km/h\r
+      Duración:      5000      milisegundos (5 segundos)\r
+      Alcance:       1,5       km\r
+</pre>\r
+            </td>\r
+         </tr>\r
+\r
+         <tr>\r
+            <td\r
+             align="center"\r
+             valign="middle"><img\r
+             alt="Misil Dirigido"\r
+             src="skins/default/misildirigido.jpg"\r
+             width="32"\r
+             height="32"></td>\r
+\r
+            <td\r
+             align="left"\r
+             valign="top"\r
+             bgcolor="#003399">\r
+               <p\r
+                class="c10"><strong\r
+                class="c9"><a\r
+                name="misildirigido"></a>Misil Dirigido</strong></p>\r
+\r
+               <p><u>Características:</u></p>\r
+<pre>\r
+      Dimensión      0,7       metros de radio (70 cm)\r
+      Potencia:      30        Cantidad de daño que hace\r
+      Energía:       1         Cantidad de daño que soporta\r
+      Velocidad:     900       km/h\r
+      Alcance:       20000     milisegundos (20 segundos)\r
+      Duración:      5         km\r
+      Area de Lock:  2000      metros (2 km)\r
+</pre>\r
+            </td>\r
+         </tr>\r
+      </table>\r
+\r
+      <p><br>\r
+      </p>\r
+      <!-- #EndEditable -->\r
+\r
+      <br>\r
+       \r
+      <br>\r
+       \r
+      <br>\r
+       \r
+      <br>\r
+       \r
+      <br>\r
+       \r
+      <br>\r
+       \r
+\r
+      <div\r
+       class="c11">\r
+         <a\r
+          href="main.html"\r
+          target="mainFrame">Descripción</a> | <a\r
+          href="instalar.html"\r
+          target="mainFrame">Instalar el Juego</a> | <a\r
+          href="configurar.html"\r
+          target="mainFrame">Configurar un Escenario</a> | <a\r
+          href="jugar.html"\r
+          target="mainFrame">Cómo Jugar</a> | <a\r
+          href="naves.html"\r
+          target="mainFrame">Descripcion de Naves</a> | <a\r
+          href="screenshots.html"\r
+          target="mainFrame">Screenshots</a> | <a\r
+          href="downloads.html"\r
+          target="mainFrame">Downloads</a> | <a\r
+          href="desarrollo.html"\r
+          target="mainFrame">Desarrollo\r
+         <br>\r
+         </a>\r
+         <br>\r
+      </div>\r
+\r
+      <div\r
+       class="c12">\r
+         Copyleft 2000. Ante cualquier duda envíenos un <a\r
+          href=\r
+         "mailto:info@algowars.luca.2t.net?subject=AlgoWars">e-mail</a>\r
+      </div>\r
+      <!-- #EndTemplate -->\r
+   </body>\r
+</html>\r
+\r
diff --git a/website/screenshots.html b/website/screenshots.html
new file mode 100644 (file)
index 0000000..57e860d
--- /dev/null
@@ -0,0 +1,69 @@
+<html><!-- #BeginTemplate "/Templates/normal.dwt" -->\r
+<!-- #BeginEditable "doctitle" -->\r
+<title>AlgoWars - Episodio IV</title>\r
+<!-- #EndEditable -->\r
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\r
+<!-- #BeginEditable "docstyle" -->\r
+<style type="text/css">\r
+<!--\r
+p {  margin-top: 5px; margin-right: 0px; margin-bottom: 5px}\r
+body {  font-family: Arial, Helvetica, sans-serif; font-size: 14px}\r
+ul {  list-style-image:      url(images/bullet.jpg); list-style-type: circle}\r
+li {  list-style-image:      url(images/bullet.jpg); list-style-type: circle}\r
+td {  font-family: Arial, Helvetica, sans-serif; font-size: 12px}\r
+-->\r
+</style>\r
+<!-- #EndEditable -->\r
+\r
+\r
+\r
+</head>\r
+\r
+<body bgcolor="#000000" text="#FFFFFF" link="#66CCFF" vlink="#0099FF" alink="#33FFFF" leftmargin="5" topmargin="5" marginwidth="5" marginheight="5" onLoad="">\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#0033CC" size="4"><b><font color="#FF9999">AlgoWars</font></b></font></p>\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#FF9999" size="3"><b><font size="2">Episodio IV</font></b></font>\r
+</p>\r
+<p>&nbsp;</p>\r
+<p><font size="+1"><b><!-- #BeginEditable "T%EDtulo" --><font color="#FFCC00">Screenshots (Capturas de Pantalla)</font><!-- #EndEditable --></b></font></p>\r
+<br>  <!-- #BeginEditable "Cuerpo" -->\r
+<p>Pantallas de la <a href="instalar.html">Instalaci&oacute;n</a>:</p>\r
+<p>&nbsp;</p>\r
+<p><a href="screenshots/inst1.jpg"><img src="screenshots/inst1_tb.jpg" width="100" height="76" align="absmiddle" lowsrc="screenshots/inst1.jpg" border="0"></a> Elecci&oacute;n de la ubicaci&oacute;n.</p>\r
+<p>&nbsp;\r
+</p>\r
+<p><a href="screenshots/inst2.jpg"><img src="screenshots/inst2_tb.jpg" width="100" height="76" align="absmiddle" border="0"></a>\r
+Selecci&oacute;n del grupo de programas </p>\r
+<p>&nbsp;</p>\r
+<p>Pantallas de <a href="configurar.html">configuraci&oacute;n</a>:</p>\r
+<p>&nbsp;</p>\r
+<p><a href="screenshots/configurar.jpg"><img src="screenshots/configurar_tb.jpg" width="100" height="60" align="absmiddle" border="0"></a>  Configuraci&oacute;n del Escenario</p>\r
+<p>&nbsp;</p>\r
+<p>Pantallas del <a href="jugar.html">Juego</a>:</p>\r
+<p>&nbsp;</p>\r
+<p><a href="screenshots/juego.jpg"><img src="screenshots/juego_tb.jpg" width="86" height="100" align="absmiddle" border="0"></a> <a href="naves.html#naveliviana">Nave Liviana</a> lockeada a la que se le est&aacute; disparando un <a href="naves.html#misildirigido">Misil Dirigido</a>.</p>\r
+<p>&nbsp;</p>\r
+<p><a href="screenshots/juego2.jpg"><img src="screenshots/juego2_tb.jpg" width="86" height="100" align="absmiddle" border="0"></a> Dos <a href="naves.html#naveliviana">Naves Livianas</a>, una <a href="naves.html#naveespia">Nave Esp&iacute;a</a> y m&aacute;s abajo una <a href="naves.html#navesuicida">Nave Suicida</a>.</p>\r
+<p>&nbsp;</p>\r
+<!-- #EndEditable -->\r
+\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+<center>\r
+    <a href="main.html" target="mainFrame">Descripci&oacute;n</a> | <a href="instalar.html" target="mainFrame">Instalar el Juego</a> | <a href="configurar.html" target="mainFrame">Configurar un Escenario</a> | <a href="jugar.html" target="mainFrame">C&oacute;mo Jugar</a> | <a href="naves.html" target="mainFrame">Descripcion de Naves</a> | <a href="screenshots.html" target="mainFrame">Screenshots</a> | <a href="downloads.html" target="mainFrame">Downloads</a> | <a href="desarrollo.html" target="mainFrame">Desarrollo<br>\r
+  </a>\r
+  \r
+  <b><font color="#CCCC00" size="2">\r
+  </font></b><br>\r
+      \r
+</center>\r
+<center>\r
+  <font size="1" face="Arial, Helvetica, sans-serif">\r
+  Copyleft 2000. Ante cualquier duda env&iacute;enos un <a href="mailto:info@algowars.luca.2t.net?subject=AlgoWars">e-mail</a>\r
+</font>\r
+</center>\r
+  </body>\r
+<!-- #EndTemplate --></html>\r
diff --git a/website/screenshots/configurar.jpg b/website/screenshots/configurar.jpg
new file mode 100644 (file)
index 0000000..501f66e
Binary files /dev/null and b/website/screenshots/configurar.jpg differ
diff --git a/website/screenshots/configurar_tb.jpg b/website/screenshots/configurar_tb.jpg
new file mode 100644 (file)
index 0000000..17e8325
Binary files /dev/null and b/website/screenshots/configurar_tb.jpg differ
diff --git a/website/screenshots/inst1.jpg b/website/screenshots/inst1.jpg
new file mode 100644 (file)
index 0000000..0268166
Binary files /dev/null and b/website/screenshots/inst1.jpg differ
diff --git a/website/screenshots/inst1_tb.jpg b/website/screenshots/inst1_tb.jpg
new file mode 100644 (file)
index 0000000..ddb3318
Binary files /dev/null and b/website/screenshots/inst1_tb.jpg differ
diff --git a/website/screenshots/inst2.jpg b/website/screenshots/inst2.jpg
new file mode 100644 (file)
index 0000000..7b7485a
Binary files /dev/null and b/website/screenshots/inst2.jpg differ
diff --git a/website/screenshots/inst2_tb.jpg b/website/screenshots/inst2_tb.jpg
new file mode 100644 (file)
index 0000000..73e6f17
Binary files /dev/null and b/website/screenshots/inst2_tb.jpg differ
diff --git a/website/screenshots/instalar.jpg b/website/screenshots/instalar.jpg
new file mode 100644 (file)
index 0000000..7a12503
Binary files /dev/null and b/website/screenshots/instalar.jpg differ
diff --git a/website/screenshots/juego.jpg b/website/screenshots/juego.jpg
new file mode 100644 (file)
index 0000000..a61b06c
Binary files /dev/null and b/website/screenshots/juego.jpg differ
diff --git a/website/screenshots/juego2.jpg b/website/screenshots/juego2.jpg
new file mode 100644 (file)
index 0000000..2d6af8b
Binary files /dev/null and b/website/screenshots/juego2.jpg differ
diff --git a/website/screenshots/juego2_tb.jpg b/website/screenshots/juego2_tb.jpg
new file mode 100644 (file)
index 0000000..4af752d
Binary files /dev/null and b/website/screenshots/juego2_tb.jpg differ
diff --git a/website/screenshots/juego_tb.jpg b/website/screenshots/juego_tb.jpg
new file mode 100644 (file)
index 0000000..51895b6
Binary files /dev/null and b/website/screenshots/juego_tb.jpg differ
diff --git a/website/screenshots/menu_escenario.jpg b/website/screenshots/menu_escenario.jpg
new file mode 100644 (file)
index 0000000..f539d0f
Binary files /dev/null and b/website/screenshots/menu_escenario.jpg differ
diff --git a/website/screenshots/menu_juego.jpg b/website/screenshots/menu_juego.jpg
new file mode 100644 (file)
index 0000000..222d7c0
Binary files /dev/null and b/website/screenshots/menu_juego.jpg differ
diff --git a/website/screenshots/no.jpg b/website/screenshots/no.jpg
new file mode 100644 (file)
index 0000000..b8f97f3
Binary files /dev/null and b/website/screenshots/no.jpg differ
diff --git a/website/screenshots/si.jpg b/website/screenshots/si.jpg
new file mode 100644 (file)
index 0000000..435c626
Binary files /dev/null and b/website/screenshots/si.jpg differ
diff --git a/website/screenshots/siguiente.jpg b/website/screenshots/siguiente.jpg
new file mode 100644 (file)
index 0000000..6c14447
Binary files /dev/null and b/website/screenshots/siguiente.jpg differ
diff --git a/website/screenshots/terminar.jpg b/website/screenshots/terminar.jpg
new file mode 100644 (file)
index 0000000..7b4773c
Binary files /dev/null and b/website/screenshots/terminar.jpg differ
diff --git a/website/skins.html b/website/skins.html
new file mode 100644 (file)
index 0000000..406bf32
--- /dev/null
@@ -0,0 +1,53 @@
+<html><!-- #BeginTemplate "/Templates/normal.dwt" -->\r
+<!-- #BeginEditable "doctitle" -->\r
+<title>AlgoWars - Episodio IV</title>\r
+<!-- #EndEditable -->\r
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\r
+<!-- #BeginEditable "docstyle" -->\r
+<style type="text/css">\r
+<!--\r
+p {  margin-top: 5px; margin-right: 0px; margin-bottom: 5px}\r
+body {  font-family: Arial, Helvetica, sans-serif; font-size: 14px}\r
+ul {  list-style-image:       url(images/bullet.jpg); list-style-type: circle}\r
+li {  list-style-image:       url(images/bullet.jpg); list-style-type: circle}\r
+td {  font-family: Arial, Helvetica, sans-serif; font-size: 12px}\r
+-->\r
+</style>\r
+<!-- #EndEditable -->\r
+\r
+\r
+\r
+</head>\r
+\r
+<body bgcolor="#000000" text="#FFFFFF" link="#66CCFF" vlink="#0099FF" alink="#33FFFF" leftmargin="5" topmargin="5" marginwidth="5" marginheight="5" onLoad="">\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#0033CC" size="4"><b><font color="#FF9999">AlgoWars</font></b></font></p>\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#FF9999" size="3"><b><font size="2">Episodio IV</font></b></font>\r
+</p>\r
+<p>&nbsp;</p>\r
+<p><font size="+1"><b><!-- #BeginEditable "T%EDtulo" --><font color="#FFCC00">&iquest;C&oacute;mo instalar las im&aacute;genes de un Skin?</font><!-- #EndEditable --></b></font></p>\r
+<br>  <!-- #BeginEditable "Cuerpo" -->\r
+<p>Instalar las im&aacute;genes de un Skin es muy simple. Solamente tiene que <a href="downloads.html">descargar en nuevo Skin</a>. Luego debe descomprimir el archivo en el subdirectorio\r
+  llamado bitmaps que se encuentra en el directorio en donde <a href="instalar.html">instal&oacute; el juego</a>. Si no posee un programa para descompimir las im&aacute;genes, puede conseguirlo <a href="http://www.winzip.com">aqu&iacute;</a>.</p>\r
+<p>Recuerde que debe sobreescribir las im&aacute;genes anteriores, es por esto que si despues desea volver al Skin anterior debe hacer una copia de seguridad de este.</p>\r
+<!-- #EndEditable -->\r
+\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+<center>\r
+    <a href="main.html" target="mainFrame">Descripci&oacute;n</a> | <a href="instalar.html" target="mainFrame">Instalar el Juego</a> | <a href="configurar.html" target="mainFrame">Configurar un Escenario</a> | <a href="jugar.html" target="mainFrame">C&oacute;mo Jugar</a> | <a href="naves.html" target="mainFrame">Descripcion de Naves</a> | <a href="screenshots.html" target="mainFrame">Screenshots</a> | <a href="downloads.html" target="mainFrame">Downloads</a> | <a href="desarrollo.html" target="mainFrame">Desarrollo<br>\r
+  </a>\r
+  \r
+  <br>\r
+      \r
+</center>\r
+<center>\r
+  <font size="1" face="Arial, Helvetica, sans-serif">\r
+  Copyleft 2000. Ante cualquier duda env&iacute;enos un <a href="mailto:info@algowars.luca.2t.net?subject=AlgoWars">e-mail</a>\r
+</font>\r
+</center>\r
+  </body>\r
+<!-- #EndTemplate --></html>\r
diff --git a/website/stats/Apr-2002.html b/website/stats/Apr-2002.html
new file mode 100644 (file)
index 0000000..27ee064
--- /dev/null
@@ -0,0 +1,94 @@
+<HTML><BODY BGCOLOR=#EAE6D4><CENTER><FONT COLOR=#0000a0 SIZE=4><B>Mod gzip statistics for Apr 2002</B></FONT></CENTER><BR><CENTER><TABLE CELLPADDING=4 BORDER=1><TR><TD COLSPAN=2 ALIGN=CENTER><B>Response Codes</B></TD></TR><TR><TD> DECLINED:TOO_SMALL </TD><TD ALIGN=RIGHT> 10 <FONT COLOR=#707070> (1.7%) </FONT></TD></TR>
+<TR><TD> OK </TD><TD ALIGN=RIGHT> 61 <FONT COLOR=#707070> (10.3%) </FONT></TD></TR>
+<TR><TD> DECLINED:EXCLUDED </TD><TD ALIGN=RIGHT> 367 <FONT COLOR=#707070> (61.8%) </FONT></TD></TR>
+<TR><TD> SEND_AS_IS:RESPONSE_CONTENT_TYPE_EXCLUDED </TD><TD ALIGN=RIGHT> 1 <FONT COLOR=#707070> (0.2%) </FONT></TD></TR>
+<TR><TD> SEND_AS_IS:NO_200 </TD><TD ALIGN=RIGHT> 10 <FONT COLOR=#707070> (1.7%) </FONT></TD></TR>
+<TR><TD> DECHUNK:OK </TD><TD ALIGN=RIGHT> 27 <FONT COLOR=#707070> (4.5%) </FONT></TD></TR>
+<TR><TD> DECLINED:NO_ACCEPT_ENCODING </TD><TD ALIGN=RIGHT> 100 <FONT COLOR=#707070> (16.8%) </FONT></TD></TR>
+<TR><TD> DECLINED:UNHANDLED_REDIR </TD><TD ALIGN=RIGHT> 5 <FONT COLOR=#707070> (0.8%) </FONT></TD></TR>
+<TR><TD> SEND_AS_IS:BODY_MISSING </TD><TD ALIGN=RIGHT> 13 <FONT COLOR=#707070> (2.2%) </FONT></TD></TR>
+</TABLE></CENTER><BR>
+<CENTER><B>Daily statistics for Apr 2002</B></CENTER><CENTER><TABLE BORDER=1 CELLPADDING=3><TR><TD COLSPAN=5 ALIGN=CENTER><FONT SIZE=-1 COLOR=#707070><B>All objects  (kB) </B></FONT></TD><TD BGCOLOR=#DAD6C4 ALIGN=CENTER COLSPAN=4><FONT SIZE=-1 COLOR=#707070><B>Compressable objects  (kB) </B></FONT></TD></TR><TR><TD ALIGN=CENTER><B><FONT SIZE=-1>Day</FONT></B></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Hits </FONT></B><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#aa0000><B>Actual bytes</FONT></B></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#008000><B>Bytes sent</FONT></B></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Saved bytes</FONT></B></TD>
+<TD ALIGN=CENTER><B><FONT SIZE=-1>Hits</FONT></B></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#aa0000><B>Actual bytes</B></FONT></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#008000><B>Bytes sent</B></FONT></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Saved bytes</FONT></B></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>1</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>27 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (29.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>18 </FONT><FONT SIZE=-1 COLOR=#707070> (68.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (37.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>27 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (29.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 18 </FONT><FONT SIZE=-1 COLOR=#707070> (68.1%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>2</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>18 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (27.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT><FONT SIZE=-1 COLOR=#707070> (68.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (28.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>18 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (27.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 12 </FONT><FONT SIZE=-1 COLOR=#707070> (68.8%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>3</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>47 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>24 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT><FONT SIZE=-1 COLOR=#707070> (64.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>9 </FONT><FONT SIZE=-1 COLOR=#707070> (19.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>24 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 15 </FONT><FONT SIZE=-1 COLOR=#707070> (64.7%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>4</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>34 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>22 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (22.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>16 </FONT><FONT SIZE=-1 COLOR=#707070> (73.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (11.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>22 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (22.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 16 </FONT><FONT SIZE=-1 COLOR=#707070> (73.4%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>5</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>89 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>31 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (35.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>20 </FONT><FONT SIZE=-1 COLOR=#707070> (63.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>9 </FONT><FONT SIZE=-1 COLOR=#707070> (10.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>31 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (35.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 20 </FONT><FONT SIZE=-1 COLOR=#707070> (63.9%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>6</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>55 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>40 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>29 </FONT><FONT SIZE=-1 COLOR=#707070> (73.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (10.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>40 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 29 </FONT><FONT SIZE=-1 COLOR=#707070> (73.6%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>7</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>128 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>177 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>40 </FONT><FONT SIZE=-1 COLOR=#707070> (22.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>137 </FONT><FONT SIZE=-1 COLOR=#707070> (77.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>23 </FONT><FONT SIZE=-1 COLOR=#707070> (18.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>177 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>40 </FONT><FONT SIZE=-1 COLOR=#707070> (22.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 137 </FONT><FONT SIZE=-1 COLOR=#707070> (77.3%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>8</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>157 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1033 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>141 </FONT><FONT SIZE=-1 COLOR=#707070> (13.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>892 </FONT><FONT SIZE=-1 COLOR=#707070> (86.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>19 </FONT><FONT SIZE=-1 COLOR=#707070> (12.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1033 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>141 </FONT><FONT SIZE=-1 COLOR=#707070> (13.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 892 </FONT><FONT SIZE=-1 COLOR=#707070> (86.3%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>9</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>69 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>64 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>18 </FONT><FONT SIZE=-1 COLOR=#707070> (28.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>46 </FONT><FONT SIZE=-1 COLOR=#707070> (71.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>13 </FONT><FONT SIZE=-1 COLOR=#707070> (18.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>64 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>18 </FONT><FONT SIZE=-1 COLOR=#707070> (28.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 46 </FONT><FONT SIZE=-1 COLOR=#707070> (71.9%) </FONT></TD></TR>
+</TABLE><BR><BR></CENTER><FONT SIZE=2 COLOR=#707070>Report generated by <A HREF="http://wizard.ae.krakow.pl/~mike/mgstat/">mgstat 0.10</A> </BODY></HTML>
\ No newline at end of file
diff --git a/website/stats/Dec-2001.html b/website/stats/Dec-2001.html
new file mode 100644 (file)
index 0000000..34c2411
--- /dev/null
@@ -0,0 +1,262 @@
+<HTML><BODY BGCOLOR=#EAE6D4><CENTER><FONT COLOR=#0000a0 SIZE=4><B>Mod gzip statistics for Dec 2001</B></FONT></CENTER><BR><CENTER><TABLE CELLPADDING=4 BORDER=1><TR><TD COLSPAN=2 ALIGN=CENTER><B>Response Codes</B></TD></TR><TR><TD> DECLINED:TOO_SMALL </TD><TD ALIGN=RIGHT> 9 <FONT COLOR=#707070> (1.3%) </FONT></TD></TR>
+<TR><TD> OK </TD><TD ALIGN=RIGHT> 33 <FONT COLOR=#707070> (4.7%) </FONT></TD></TR>
+<TR><TD> DECLINED:EXCLUDED </TD><TD ALIGN=RIGHT> 179 <FONT COLOR=#707070> (25.8%) </FONT></TD></TR>
+<TR><TD> SEND_AS_IS:RESPONSE_CONTENT_TYPE_EXCLUDED </TD><TD ALIGN=RIGHT> 2 <FONT COLOR=#707070> (0.3%) </FONT></TD></TR>
+<TR><TD> SEND_AS_IS:NO_200 </TD><TD ALIGN=RIGHT> 2 <FONT COLOR=#707070> (0.3%) </FONT></TD></TR>
+<TR><TD> DECLINED:NO_ACCEPT_ENCODING </TD><TD ALIGN=RIGHT> 470 <FONT COLOR=#707070> (67.6%) </FONT></TD></TR>
+</TABLE></CENTER><BR>
+<CENTER><B>Daily statistics for Dec 2001</B></CENTER><CENTER><TABLE BORDER=1 CELLPADDING=3><TR><TD COLSPAN=5 ALIGN=CENTER><FONT SIZE=-1 COLOR=#707070><B>All objects  (kB) </B></FONT></TD><TD BGCOLOR=#DAD6C4 ALIGN=CENTER COLSPAN=4><FONT SIZE=-1 COLOR=#707070><B>Compressable objects  (kB) </B></FONT></TD></TR><TR><TD ALIGN=CENTER><B><FONT SIZE=-1>Day</FONT></B></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Hits </FONT></B><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#aa0000><B>Actual bytes</FONT></B></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#008000><B>Bytes sent</FONT></B></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Saved bytes</FONT></B></TD>
+<TD ALIGN=CENTER><B><FONT SIZE=-1>Hits</FONT></B></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#aa0000><B>Actual bytes</B></FONT></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#008000><B>Bytes sent</B></FONT></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Saved bytes</FONT></B></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>1</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>3</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>40 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>26 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (30.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>18 </FONT><FONT SIZE=-1 COLOR=#707070> (69.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (15.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>26 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (30.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 18 </FONT><FONT SIZE=-1 COLOR=#707070> (69.6%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>4</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>35 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>23 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (34.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT><FONT SIZE=-1 COLOR=#707070> (65.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (14.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>23 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (34.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 15 </FONT><FONT SIZE=-1 COLOR=#707070> (65.2%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>5</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>74 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>37 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT><FONT SIZE=-1 COLOR=#707070> (32.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>25 </FONT><FONT SIZE=-1 COLOR=#707070> (68.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (10.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>37 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT><FONT SIZE=-1 COLOR=#707070> (32.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 25 </FONT><FONT SIZE=-1 COLOR=#707070> (68.4%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>6</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>7</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>8</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>30 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>9</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>33 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>10</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>99 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (28.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (63.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (2.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (28.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 4 </FONT><FONT SIZE=-1 COLOR=#707070> (63.6%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>11</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>12</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>13</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>14</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>15</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>16</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>17</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>16 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>18</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>19</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>14 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>20</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>51 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>21</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>29 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>22</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>25 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>23</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>13 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>25</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>45 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>24 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT><FONT SIZE=-1 COLOR=#707070> (63.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (13.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>24 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 15 </FONT><FONT SIZE=-1 COLOR=#707070> (63.9%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>27</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>14 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (50.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (63.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (7.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (50.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 1 </FONT><FONT SIZE=-1 COLOR=#707070> (63.7%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>28</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>26 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT><FONT SIZE=-1 COLOR=#707070> (64.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (11.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 7 </FONT><FONT SIZE=-1 COLOR=#707070> (64.3%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>29</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>14 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (28.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (63.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (14.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (28.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 4 </FONT><FONT SIZE=-1 COLOR=#707070> (63.6%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>30</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>27 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>31</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>39 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+</TABLE><BR><BR></CENTER><FONT SIZE=2 COLOR=#707070>Report generated by <A HREF="http://wizard.ae.krakow.pl/~mike/mgstat/">mgstat 0.10</A> </BODY></HTML>
\ No newline at end of file
diff --git a/website/stats/Feb-2002.html b/website/stats/Feb-2002.html
new file mode 100644 (file)
index 0000000..abff485
--- /dev/null
@@ -0,0 +1,264 @@
+<HTML><BODY BGCOLOR=#EAE6D4><CENTER><FONT COLOR=#0000a0 SIZE=4><B>Mod gzip statistics for Feb 2002</B></FONT></CENTER><BR><CENTER><TABLE CELLPADDING=4 BORDER=1><TR><TD COLSPAN=2 ALIGN=CENTER><B>Response Codes</B></TD></TR><TR><TD> DECLINED:TOO_SMALL </TD><TD ALIGN=RIGHT> 13 <FONT COLOR=#707070> (1.6%) </FONT></TD></TR>
+<TR><TD> OK </TD><TD ALIGN=RIGHT> 96 <FONT COLOR=#707070> (12.0%) </FONT></TD></TR>
+<TR><TD> DECLINED:EXCLUDED </TD><TD ALIGN=RIGHT> 450 <FONT COLOR=#707070> (56.5%) </FONT></TD></TR>
+<TR><TD> SEND_AS_IS:RESPONSE_CONTENT_TYPE_EXCLUDED </TD><TD ALIGN=RIGHT> 2 <FONT COLOR=#707070> (0.3%) </FONT></TD></TR>
+<TR><TD> SEND_AS_IS:NO_200 </TD><TD ALIGN=RIGHT> 9 <FONT COLOR=#707070> (1.1%) </FONT></TD></TR>
+<TR><TD> DECHUNK:OK </TD><TD ALIGN=RIGHT> 34 <FONT COLOR=#707070> (4.3%) </FONT></TD></TR>
+<TR><TD> DECLINED:NO_ACCEPT_ENCODING </TD><TD ALIGN=RIGHT> 179 <FONT COLOR=#707070> (22.5%) </FONT></TD></TR>
+<TR><TD> DECLINED:NOT_GET_OR_POST </TD><TD ALIGN=RIGHT> 14 <FONT COLOR=#707070> (1.8%) </FONT></TD></TR>
+</TABLE></CENTER><BR>
+<CENTER><B>Daily statistics for Feb 2002</B></CENTER><CENTER><TABLE BORDER=1 CELLPADDING=3><TR><TD COLSPAN=5 ALIGN=CENTER><FONT SIZE=-1 COLOR=#707070><B>All objects  (kB) </B></FONT></TD><TD BGCOLOR=#DAD6C4 ALIGN=CENTER COLSPAN=4><FONT SIZE=-1 COLOR=#707070><B>Compressable objects  (kB) </B></FONT></TD></TR><TR><TD ALIGN=CENTER><B><FONT SIZE=-1>Day</FONT></B></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Hits </FONT></B><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#aa0000><B>Actual bytes</FONT></B></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#008000><B>Bytes sent</FONT></B></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Saved bytes</FONT></B></TD>
+<TD ALIGN=CENTER><B><FONT SIZE=-1>Hits</FONT></B></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#aa0000><B>Actual bytes</B></FONT></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#008000><B>Bytes sent</B></FONT></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Saved bytes</FONT></B></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>1</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>52 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>13 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (23.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT><FONT SIZE=-1 COLOR=#707070> (76.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (3.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>13 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (23.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 10 </FONT><FONT SIZE=-1 COLOR=#707070> (76.3%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>2</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>33 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>29 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT><FONT SIZE=-1 COLOR=#707070> (34.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>19 </FONT><FONT SIZE=-1 COLOR=#707070> (65.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (24.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>29 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT><FONT SIZE=-1 COLOR=#707070> (34.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 19 </FONT><FONT SIZE=-1 COLOR=#707070> (65.2%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>3</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>4</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>28 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>16 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (18.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT><FONT SIZE=-1 COLOR=#707070> (78.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (10.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>16 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (18.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 12 </FONT><FONT SIZE=-1 COLOR=#707070> (78.2%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>5</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>14 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (72.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (14.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 6 </FONT><FONT SIZE=-1 COLOR=#707070> (72.9%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>6</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>41 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>48 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>14 </FONT><FONT SIZE=-1 COLOR=#707070> (29.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>34 </FONT><FONT SIZE=-1 COLOR=#707070> (70.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (26.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>48 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>14 </FONT><FONT SIZE=-1 COLOR=#707070> (29.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 34 </FONT><FONT SIZE=-1 COLOR=#707070> (70.9%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>7</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>33 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (40.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (63.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (6.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (40.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 3 </FONT><FONT SIZE=-1 COLOR=#707070> (63.7%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>8</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>72 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>38 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT><FONT SIZE=-1 COLOR=#707070> (31.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>26 </FONT><FONT SIZE=-1 COLOR=#707070> (68.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (15.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>38 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT><FONT SIZE=-1 COLOR=#707070> (31.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 26 </FONT><FONT SIZE=-1 COLOR=#707070> (68.3%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>9</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>17 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (30.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (65.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (23.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (30.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 6 </FONT><FONT SIZE=-1 COLOR=#707070> (65.7%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>10</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>19 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (21.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT><FONT SIZE=-1 COLOR=#707070> (76.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (20.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>19 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (21.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 15 </FONT><FONT SIZE=-1 COLOR=#707070> (76.3%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>11</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (50.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (63.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (12.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (50.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 1 </FONT><FONT SIZE=-1 COLOR=#707070> (63.7%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>12</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>9 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (66.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (22.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 3 </FONT><FONT SIZE=-1 COLOR=#707070> (66.5%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>13</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (66.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (20.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 3 </FONT><FONT SIZE=-1 COLOR=#707070> (66.5%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>14</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>48 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>28 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT><FONT SIZE=-1 COLOR=#707070> (35.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>17 </FONT><FONT SIZE=-1 COLOR=#707070> (64.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT><FONT SIZE=-1 COLOR=#707070> (20.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>28 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT><FONT SIZE=-1 COLOR=#707070> (35.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 17 </FONT><FONT SIZE=-1 COLOR=#707070> (64.2%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>15</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>48 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>36 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (30.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>24 </FONT><FONT SIZE=-1 COLOR=#707070> (68.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (12.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>36 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (30.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 24 </FONT><FONT SIZE=-1 COLOR=#707070> (68.7%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>16</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>24 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>22 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (27.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT><FONT SIZE=-1 COLOR=#707070> (68.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (12.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>22 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (27.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 15 </FONT><FONT SIZE=-1 COLOR=#707070> (68.6%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>17</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (55.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT><FONT SIZE=-1 COLOR=#707070> (55.9%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>18</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>36 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>24 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>9 </FONT><FONT SIZE=-1 COLOR=#707070> (37.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>14 </FONT><FONT SIZE=-1 COLOR=#707070> (61.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>9 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>24 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>9 </FONT><FONT SIZE=-1 COLOR=#707070> (37.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 14 </FONT><FONT SIZE=-1 COLOR=#707070> (61.7%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>19</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>82 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>36 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>23 </FONT><FONT SIZE=-1 COLOR=#707070> (66.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT><FONT SIZE=-1 COLOR=#707070> (14.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>36 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 23 </FONT><FONT SIZE=-1 COLOR=#707070> (66.2%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>20</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>31 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>21 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>13 </FONT><FONT SIZE=-1 COLOR=#707070> (63.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (19.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>21 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 13 </FONT><FONT SIZE=-1 COLOR=#707070> (63.5%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>21</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (66.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (18.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 3 </FONT><FONT SIZE=-1 COLOR=#707070> (66.5%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>22</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>36 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>14 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (35.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>9 </FONT><FONT SIZE=-1 COLOR=#707070> (63.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (11.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>14 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (35.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 9 </FONT><FONT SIZE=-1 COLOR=#707070> (63.9%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>23</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>44 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>22 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (27.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>16 </FONT><FONT SIZE=-1 COLOR=#707070> (71.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (11.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>22 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (27.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 16 </FONT><FONT SIZE=-1 COLOR=#707070> (71.3%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>24</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (28.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (63.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (28.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 4 </FONT><FONT SIZE=-1 COLOR=#707070> (63.4%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>25</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>39 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (40.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>9 </FONT><FONT SIZE=-1 COLOR=#707070> (59.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>9 </FONT><FONT SIZE=-1 COLOR=#707070> (23.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (40.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 9 </FONT><FONT SIZE=-1 COLOR=#707070> (59.3%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>26</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>45 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>22 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT><FONT SIZE=-1 COLOR=#707070> (31.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>14 </FONT><FONT SIZE=-1 COLOR=#707070> (64.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (13.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>22 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT><FONT SIZE=-1 COLOR=#707070> (31.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 14 </FONT><FONT SIZE=-1 COLOR=#707070> (64.3%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>27</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (63.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (42.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 4 </FONT><FONT SIZE=-1 COLOR=#707070> (63.7%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>28</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (50.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (63.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (50.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (50.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 1 </FONT><FONT SIZE=-1 COLOR=#707070> (63.7%) </FONT></TD></TR>
+</TABLE><BR><BR></CENTER><FONT SIZE=2 COLOR=#707070>Report generated by <A HREF="http://wizard.ae.krakow.pl/~mike/mgstat/">mgstat 0.10</A> </BODY></HTML>
\ No newline at end of file
diff --git a/website/stats/Jan-2002.html b/website/stats/Jan-2002.html
new file mode 100644 (file)
index 0000000..7c05bdc
--- /dev/null
@@ -0,0 +1,291 @@
+<HTML><BODY BGCOLOR=#EAE6D4><CENTER><FONT COLOR=#0000a0 SIZE=4><B>Mod gzip statistics for Jan 2002</B></FONT></CENTER><BR><CENTER><TABLE CELLPADDING=4 BORDER=1><TR><TD COLSPAN=2 ALIGN=CENTER><B>Response Codes</B></TD></TR><TR><TD> DECLINED:TOO_SMALL </TD><TD ALIGN=RIGHT> 24 <FONT COLOR=#707070> (1.3%) </FONT></TD></TR>
+<TR><TD> OK </TD><TD ALIGN=RIGHT> 144 <FONT COLOR=#707070> (7.7%) </FONT></TD></TR>
+<TR><TD> DECLINED:EXCLUDED </TD><TD ALIGN=RIGHT> 607 <FONT COLOR=#707070> (32.7%) </FONT></TD></TR>
+<TR><TD> SEND_AS_IS:RESPONSE_CONTENT_TYPE_EXCLUDED </TD><TD ALIGN=RIGHT> 4 <FONT COLOR=#707070> (0.2%) </FONT></TD></TR>
+<TR><TD> SEND_AS_IS:NO_200 </TD><TD ALIGN=RIGHT> 20 <FONT COLOR=#707070> (1.1%) </FONT></TD></TR>
+<TR><TD> DECHUNK:OK </TD><TD ALIGN=RIGHT> 57 <FONT COLOR=#707070> (3.1%) </FONT></TD></TR>
+<TR><TD> DECLINED:NO_ACCEPT_ENCODING </TD><TD ALIGN=RIGHT> 995 <FONT COLOR=#707070> (53.5%) </FONT></TD></TR>
+<TR><TD> DECLINED:NOT_GET_OR_POST </TD><TD ALIGN=RIGHT> 8 <FONT COLOR=#707070> (0.4%) </FONT></TD></TR>
+</TABLE></CENTER><BR>
+<CENTER><B>Daily statistics for Jan 2002</B></CENTER><CENTER><TABLE BORDER=1 CELLPADDING=3><TR><TD COLSPAN=5 ALIGN=CENTER><FONT SIZE=-1 COLOR=#707070><B>All objects  (kB) </B></FONT></TD><TD BGCOLOR=#DAD6C4 ALIGN=CENTER COLSPAN=4><FONT SIZE=-1 COLOR=#707070><B>Compressable objects  (kB) </B></FONT></TD></TR><TR><TD ALIGN=CENTER><B><FONT SIZE=-1>Day</FONT></B></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Hits </FONT></B><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#aa0000><B>Actual bytes</FONT></B></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#008000><B>Bytes sent</FONT></B></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Saved bytes</FONT></B></TD>
+<TD ALIGN=CENTER><B><FONT SIZE=-1>Hits</FONT></B></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#aa0000><B>Actual bytes</B></FONT></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#008000><B>Bytes sent</B></FONT></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Saved bytes</FONT></B></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>1</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>57 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>2</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>59 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (30.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (63.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (5.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (30.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 6 </FONT><FONT SIZE=-1 COLOR=#707070> (63.6%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>3</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>21 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (36.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (62.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (14.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (36.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 6 </FONT><FONT SIZE=-1 COLOR=#707070> (62.1%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>4</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>76 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>43 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>14 </FONT><FONT SIZE=-1 COLOR=#707070> (32.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>29 </FONT><FONT SIZE=-1 COLOR=#707070> (67.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (14.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>43 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>14 </FONT><FONT SIZE=-1 COLOR=#707070> (32.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 29 </FONT><FONT SIZE=-1 COLOR=#707070> (67.5%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>5</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>42 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>23 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (34.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT><FONT SIZE=-1 COLOR=#707070> (64.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT><FONT SIZE=-1 COLOR=#707070> (16.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>23 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (34.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 15 </FONT><FONT SIZE=-1 COLOR=#707070> (64.8%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>6</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>68 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>7</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>8</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>70 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>49 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>16 </FONT><FONT SIZE=-1 COLOR=#707070> (32.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>33 </FONT><FONT SIZE=-1 COLOR=#707070> (67.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (15.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>49 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>16 </FONT><FONT SIZE=-1 COLOR=#707070> (32.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 33 </FONT><FONT SIZE=-1 COLOR=#707070> (67.6%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>9</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>98 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>38 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>13 </FONT><FONT SIZE=-1 COLOR=#707070> (34.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>25 </FONT><FONT SIZE=-1 COLOR=#707070> (65.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (11.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>38 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>13 </FONT><FONT SIZE=-1 COLOR=#707070> (34.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 25 </FONT><FONT SIZE=-1 COLOR=#707070> (65.9%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>10</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>50 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>46 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT><FONT SIZE=-1 COLOR=#707070> (32.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>30 </FONT><FONT SIZE=-1 COLOR=#707070> (66.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT><FONT SIZE=-1 COLOR=#707070> (30.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>46 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT><FONT SIZE=-1 COLOR=#707070> (32.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 30 </FONT><FONT SIZE=-1 COLOR=#707070> (66.3%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>11</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>142 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>47 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>16 </FONT><FONT SIZE=-1 COLOR=#707070> (34.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>31 </FONT><FONT SIZE=-1 COLOR=#707070> (66.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT><FONT SIZE=-1 COLOR=#707070> (8.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>47 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>16 </FONT><FONT SIZE=-1 COLOR=#707070> (34.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 31 </FONT><FONT SIZE=-1 COLOR=#707070> (66.2%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>12</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>31 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>39 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (28.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>27 </FONT><FONT SIZE=-1 COLOR=#707070> (71.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT><FONT SIZE=-1 COLOR=#707070> (22.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>39 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (28.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 27 </FONT><FONT SIZE=-1 COLOR=#707070> (71.4%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>13</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>55 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>382 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>76 </FONT><FONT SIZE=-1 COLOR=#707070> (19.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>305 </FONT><FONT SIZE=-1 COLOR=#707070> (79.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT><FONT SIZE=-1 COLOR=#707070> (18.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>382 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>76 </FONT><FONT SIZE=-1 COLOR=#707070> (19.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 305 </FONT><FONT SIZE=-1 COLOR=#707070> (79.9%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>14</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>73 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>43 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT><FONT SIZE=-1 COLOR=#707070> (34.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>27 </FONT><FONT SIZE=-1 COLOR=#707070> (63.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>13 </FONT><FONT SIZE=-1 COLOR=#707070> (17.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>43 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT><FONT SIZE=-1 COLOR=#707070> (34.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 27 </FONT><FONT SIZE=-1 COLOR=#707070> (63.6%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>15</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>104 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>189 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>38 </FONT><FONT SIZE=-1 COLOR=#707070> (20.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>151 </FONT><FONT SIZE=-1 COLOR=#707070> (79.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT><FONT SIZE=-1 COLOR=#707070> (6.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>189 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>38 </FONT><FONT SIZE=-1 COLOR=#707070> (20.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 151 </FONT><FONT SIZE=-1 COLOR=#707070> (79.8%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>16</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>136 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>17</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>112 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>28 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (28.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>19 </FONT><FONT SIZE=-1 COLOR=#707070> (69.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT><FONT SIZE=-1 COLOR=#707070> (6.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>28 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (28.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 19 </FONT><FONT SIZE=-1 COLOR=#707070> (69.3%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>18</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>25 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (20.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>19 </FONT><FONT SIZE=-1 COLOR=#707070> (77.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>25 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (20.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 19 </FONT><FONT SIZE=-1 COLOR=#707070> (77.3%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>19</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (61.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (16.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 3 </FONT><FONT SIZE=-1 COLOR=#707070> (61.8%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>20</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>39 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>25 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>9 </FONT><FONT SIZE=-1 COLOR=#707070> (36.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>16 </FONT><FONT SIZE=-1 COLOR=#707070> (64.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (20.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>25 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>9 </FONT><FONT SIZE=-1 COLOR=#707070> (36.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 16 </FONT><FONT SIZE=-1 COLOR=#707070> (64.4%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>21</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>89 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>33 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT><FONT SIZE=-1 COLOR=#707070> (30.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>23 </FONT><FONT SIZE=-1 COLOR=#707070> (69.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT><FONT SIZE=-1 COLOR=#707070> (7.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>33 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT><FONT SIZE=-1 COLOR=#707070> (30.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 23 </FONT><FONT SIZE=-1 COLOR=#707070> (69.5%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>22</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>107 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>27 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (29.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>18 </FONT><FONT SIZE=-1 COLOR=#707070> (69.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (5.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>27 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (29.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 18 </FONT><FONT SIZE=-1 COLOR=#707070> (69.3%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>23</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>68 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>25 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (32.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>17 </FONT><FONT SIZE=-1 COLOR=#707070> (67.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (5.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>25 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (32.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 17 </FONT><FONT SIZE=-1 COLOR=#707070> (67.5%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>24</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>9 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (11.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT><FONT SIZE=-1 COLOR=#707070> (80.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (8.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>9 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (11.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 7 </FONT><FONT SIZE=-1 COLOR=#707070> (80.7%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>25</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>16 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (31.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (69.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>16 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (31.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 11 </FONT><FONT SIZE=-1 COLOR=#707070> (69.8%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>26</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>132 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>116 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>30 </FONT><FONT SIZE=-1 COLOR=#707070> (25.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>85 </FONT><FONT SIZE=-1 COLOR=#707070> (73.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>30 </FONT><FONT SIZE=-1 COLOR=#707070> (22.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>116 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>30 </FONT><FONT SIZE=-1 COLOR=#707070> (25.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 85 </FONT><FONT SIZE=-1 COLOR=#707070> (73.5%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>27</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>28</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>19 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (50.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (63.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (5.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (50.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 1 </FONT><FONT SIZE=-1 COLOR=#707070> (63.7%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>29</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>64 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>44 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT><FONT SIZE=-1 COLOR=#707070> (34.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>28 </FONT><FONT SIZE=-1 COLOR=#707070> (64.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>16 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>44 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT><FONT SIZE=-1 COLOR=#707070> (34.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 28 </FONT><FONT SIZE=-1 COLOR=#707070> (64.7%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>30</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>34 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (20.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (66.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (2.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (20.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 3 </FONT><FONT SIZE=-1 COLOR=#707070> (66.7%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>31</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>69 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>36 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (30.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>25 </FONT><FONT SIZE=-1 COLOR=#707070> (69.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (4.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>36 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (30.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 25 </FONT><FONT SIZE=-1 COLOR=#707070> (69.3%) </FONT></TD></TR>
+</TABLE><BR><BR></CENTER><FONT SIZE=2 COLOR=#707070>Report generated by <A HREF="http://wizard.ae.krakow.pl/~mike/mgstat/">mgstat 0.10</A> </BODY></HTML>
\ No newline at end of file
diff --git a/website/stats/Mar-2002.html b/website/stats/Mar-2002.html
new file mode 100644 (file)
index 0000000..c02040b
--- /dev/null
@@ -0,0 +1,292 @@
+<HTML><BODY BGCOLOR=#EAE6D4><CENTER><FONT COLOR=#0000a0 SIZE=4><B>Mod gzip statistics for Mar 2002</B></FONT></CENTER><BR><CENTER><TABLE CELLPADDING=4 BORDER=1><TR><TD COLSPAN=2 ALIGN=CENTER><B>Response Codes</B></TD></TR><TR><TD> DECLINED:TOO_SMALL </TD><TD ALIGN=RIGHT> 61 <FONT COLOR=#707070> (2.4%) </FONT></TD></TR>
+<TR><TD> OK </TD><TD ALIGN=RIGHT> 316 <FONT COLOR=#707070> (12.7%) </FONT></TD></TR>
+<TR><TD> DECLINED:EXCLUDED </TD><TD ALIGN=RIGHT> 849 <FONT COLOR=#707070> (34.1%) </FONT></TD></TR>
+<TR><TD> SEND_AS_IS:RESPONSE_CONTENT_TYPE_EXCLUDED </TD><TD ALIGN=RIGHT> 11 <FONT COLOR=#707070> (0.4%) </FONT></TD></TR>
+<TR><TD> SEND_AS_IS:NO_200 </TD><TD ALIGN=RIGHT> 14 <FONT COLOR=#707070> (0.6%) </FONT></TD></TR>
+<TR><TD> DECHUNK:OK </TD><TD ALIGN=RIGHT> 415 <FONT COLOR=#707070> (16.7%) </FONT></TD></TR>
+<TR><TD> DECLINED:NO_ACCEPT_ENCODING </TD><TD ALIGN=RIGHT> 583 <FONT COLOR=#707070> (23.4%) </FONT></TD></TR>
+<TR><TD> DECLINED:NOT_GET_OR_POST </TD><TD ALIGN=RIGHT> 35 <FONT COLOR=#707070> (1.4%) </FONT></TD></TR>
+<TR><TD> DECLINED:HEAD_REQUEST </TD><TD ALIGN=RIGHT> 208 <FONT COLOR=#707070> (8.3%) </FONT></TD></TR>
+</TABLE></CENTER><BR>
+<CENTER><B>Daily statistics for Mar 2002</B></CENTER><CENTER><TABLE BORDER=1 CELLPADDING=3><TR><TD COLSPAN=5 ALIGN=CENTER><FONT SIZE=-1 COLOR=#707070><B>All objects  (kB) </B></FONT></TD><TD BGCOLOR=#DAD6C4 ALIGN=CENTER COLSPAN=4><FONT SIZE=-1 COLOR=#707070><B>Compressable objects  (kB) </B></FONT></TD></TR><TR><TD ALIGN=CENTER><B><FONT SIZE=-1>Day</FONT></B></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Hits </FONT></B><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#aa0000><B>Actual bytes</FONT></B></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#008000><B>Bytes sent</FONT></B></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Saved bytes</FONT></B></TD>
+<TD ALIGN=CENTER><B><FONT SIZE=-1>Hits</FONT></B></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#aa0000><B>Actual bytes</B></FONT></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#008000><B>Bytes sent</B></FONT></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Saved bytes</FONT></B></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>1</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>37 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>18 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (64.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (16.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>18 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 11 </FONT><FONT SIZE=-1 COLOR=#707070> (64.4%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>2</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>17 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (23.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT><FONT SIZE=-1 COLOR=#707070> (72.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (42.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>17 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (23.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 12 </FONT><FONT SIZE=-1 COLOR=#707070> (72.5%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>3</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>74 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>53 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>17 </FONT><FONT SIZE=-1 COLOR=#707070> (32.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>36 </FONT><FONT SIZE=-1 COLOR=#707070> (66.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>13 </FONT><FONT SIZE=-1 COLOR=#707070> (17.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>53 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>17 </FONT><FONT SIZE=-1 COLOR=#707070> (32.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 36 </FONT><FONT SIZE=-1 COLOR=#707070> (66.9%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>4</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>110 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>49 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>18 </FONT><FONT SIZE=-1 COLOR=#707070> (36.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>31 </FONT><FONT SIZE=-1 COLOR=#707070> (62.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>16 </FONT><FONT SIZE=-1 COLOR=#707070> (14.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>49 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>18 </FONT><FONT SIZE=-1 COLOR=#707070> (36.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 31 </FONT><FONT SIZE=-1 COLOR=#707070> (62.9%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>5</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>30 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>39 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (28.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>27 </FONT><FONT SIZE=-1 COLOR=#707070> (70.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (20.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>39 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (28.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 27 </FONT><FONT SIZE=-1 COLOR=#707070> (70.4%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>6</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>45 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (66.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (2.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 1 </FONT><FONT SIZE=-1 COLOR=#707070> (66.5%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>7</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>25 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (64.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (12.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 5 </FONT><FONT SIZE=-1 COLOR=#707070> (64.5%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>8</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1153 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4086 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>904 </FONT><FONT SIZE=-1 COLOR=#707070> (22.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3181 </FONT><FONT SIZE=-1 COLOR=#707070> (77.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>576 </FONT><FONT SIZE=-1 COLOR=#707070> (50.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4086 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>904 </FONT><FONT SIZE=-1 COLOR=#707070> (22.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 3181 </FONT><FONT SIZE=-1 COLOR=#707070> (77.9%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>9</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (58.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (10.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (33.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 1 </FONT><FONT SIZE=-1 COLOR=#707070> (58.6%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>10</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>81 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>26 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>9 </FONT><FONT SIZE=-1 COLOR=#707070> (34.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>17 </FONT><FONT SIZE=-1 COLOR=#707070> (65.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT><FONT SIZE=-1 COLOR=#707070> (8.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>26 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>9 </FONT><FONT SIZE=-1 COLOR=#707070> (34.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 17 </FONT><FONT SIZE=-1 COLOR=#707070> (65.3%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>11</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>88 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>198 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>39 </FONT><FONT SIZE=-1 COLOR=#707070> (19.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>158 </FONT><FONT SIZE=-1 COLOR=#707070> (79.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>9 </FONT><FONT SIZE=-1 COLOR=#707070> (10.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>198 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>39 </FONT><FONT SIZE=-1 COLOR=#707070> (19.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 158 </FONT><FONT SIZE=-1 COLOR=#707070> (79.9%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>12</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>56 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>24 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>17 </FONT><FONT SIZE=-1 COLOR=#707070> (70.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (8.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>24 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 17 </FONT><FONT SIZE=-1 COLOR=#707070> (70.9%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>13</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>155 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>38 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT><FONT SIZE=-1 COLOR=#707070> (31.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>26 </FONT><FONT SIZE=-1 COLOR=#707070> (69.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT><FONT SIZE=-1 COLOR=#707070> (6.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>38 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT><FONT SIZE=-1 COLOR=#707070> (31.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 26 </FONT><FONT SIZE=-1 COLOR=#707070> (69.0%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>14</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>34 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (59.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (5.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 2 </FONT><FONT SIZE=-1 COLOR=#707070> (59.5%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>15</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (72.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (10.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 2 </FONT><FONT SIZE=-1 COLOR=#707070> (72.8%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>16</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>19 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (28.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (63.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (10.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (28.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 4 </FONT><FONT SIZE=-1 COLOR=#707070> (63.6%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>17</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (18.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (78.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (100.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (18.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 8 </FONT><FONT SIZE=-1 COLOR=#707070> (78.4%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>18</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>93 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>17 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (35.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT><FONT SIZE=-1 COLOR=#707070> (64.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (6.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>17 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (35.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 10 </FONT><FONT SIZE=-1 COLOR=#707070> (64.3%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>19</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>24 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (14.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (85.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (4.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (14.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 6 </FONT><FONT SIZE=-1 COLOR=#707070> (85.5%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>20</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>47 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>39 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (28.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>27 </FONT><FONT SIZE=-1 COLOR=#707070> (70.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT><FONT SIZE=-1 COLOR=#707070> (14.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>39 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (28.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 27 </FONT><FONT SIZE=-1 COLOR=#707070> (70.8%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>21</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (50.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (63.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (50.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 1 </FONT><FONT SIZE=-1 COLOR=#707070> (63.7%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>22</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>27 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>20 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT><FONT SIZE=-1 COLOR=#707070> (75.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (11.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>20 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 15 </FONT><FONT SIZE=-1 COLOR=#707070> (75.1%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>23</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>28 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>30 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (26.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>21 </FONT><FONT SIZE=-1 COLOR=#707070> (70.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>30 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT><FONT SIZE=-1 COLOR=#707070> (26.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 21 </FONT><FONT SIZE=-1 COLOR=#707070> (70.8%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>24</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>25</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>57 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>51 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT><FONT SIZE=-1 COLOR=#707070> (29.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>36 </FONT><FONT SIZE=-1 COLOR=#707070> (70.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT><FONT SIZE=-1 COLOR=#707070> (21.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>51 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>15 </FONT><FONT SIZE=-1 COLOR=#707070> (29.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 36 </FONT><FONT SIZE=-1 COLOR=#707070> (70.9%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>26</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>93 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>35 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT><FONT SIZE=-1 COLOR=#707070> (34.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>23 </FONT><FONT SIZE=-1 COLOR=#707070> (64.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>13 </FONT><FONT SIZE=-1 COLOR=#707070> (14.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>35 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>12 </FONT><FONT SIZE=-1 COLOR=#707070> (34.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 23 </FONT><FONT SIZE=-1 COLOR=#707070> (64.5%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>27</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>145 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>730 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>142 </FONT><FONT SIZE=-1 COLOR=#707070> (19.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>587 </FONT><FONT SIZE=-1 COLOR=#707070> (80.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT><FONT SIZE=-1 COLOR=#707070> (7.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>730 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>142 </FONT><FONT SIZE=-1 COLOR=#707070> (19.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 587 </FONT><FONT SIZE=-1 COLOR=#707070> (80.5%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>28</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>20 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>14 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (35.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>9 </FONT><FONT SIZE=-1 COLOR=#707070> (63.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (25.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>14 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5 </FONT><FONT SIZE=-1 COLOR=#707070> (35.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 9 </FONT><FONT SIZE=-1 COLOR=#707070> (63.7%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>29</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (14.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6 </FONT><FONT SIZE=-1 COLOR=#707070> (85.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (16.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT><FONT SIZE=-1 COLOR=#707070> (14.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 6 </FONT><FONT SIZE=-1 COLOR=#707070> (85.5%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>30</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>14 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (21.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>10 </FONT><FONT SIZE=-1 COLOR=#707070> (75.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (100.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>14 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (21.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 10 </FONT><FONT SIZE=-1 COLOR=#707070> (75.3%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>31</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+</TABLE><BR><BR></CENTER><FONT SIZE=2 COLOR=#707070>Report generated by <A HREF="http://wizard.ae.krakow.pl/~mike/mgstat/">mgstat 0.10</A> </BODY></HTML>
\ No newline at end of file
diff --git a/website/stats/Nov-2001.html b/website/stats/Nov-2001.html
new file mode 100644 (file)
index 0000000..17ee4be
--- /dev/null
@@ -0,0 +1,102 @@
+<HTML><BODY BGCOLOR=#EAE6D4><CENTER><FONT COLOR=#0000a0 SIZE=4><B>Mod gzip statistics for Nov 2001</B></FONT></CENTER><BR><CENTER><TABLE CELLPADDING=4 BORDER=1><TR><TD COLSPAN=2 ALIGN=CENTER><B>Response Codes</B></TD></TR><TR><TD> - </TD><TD ALIGN=RIGHT> 1 <FONT COLOR=#707070> (0.4%) </FONT></TD></TR>
+<TR><TD> DECLINED:TOO_SMALL </TD><TD ALIGN=RIGHT> 10 <FONT COLOR=#707070> (4.1%) </FONT></TD></TR>
+<TR><TD> OK </TD><TD ALIGN=RIGHT> 35 <FONT COLOR=#707070> (14.2%) </FONT></TD></TR>
+<TR><TD> DECLINED:EXCLUDED </TD><TD ALIGN=RIGHT> 145 <FONT COLOR=#707070> (58.9%) </FONT></TD></TR>
+<TR><TD> SEND_AS_IS:RESPONSE_CONTENT_TYPE_EXCLUDED </TD><TD ALIGN=RIGHT> 4 <FONT COLOR=#707070> (1.6%) </FONT></TD></TR>
+<TR><TD> SEND_AS_IS:NO_200 </TD><TD ALIGN=RIGHT> 25 <FONT COLOR=#707070> (10.2%) </FONT></TD></TR>
+<TR><TD> DECHUNK:OK </TD><TD ALIGN=RIGHT> 8 <FONT COLOR=#707070> (3.3%) </FONT></TD></TR>
+<TR><TD> DECLINED:NO_ACCEPT_ENCODING </TD><TD ALIGN=RIGHT> 18 <FONT COLOR=#707070> (7.3%) </FONT></TD></TR>
+</TABLE></CENTER><BR>
+<CENTER><B>Daily statistics for Nov 2001</B></CENTER><CENTER><TABLE BORDER=1 CELLPADDING=3><TR><TD COLSPAN=5 ALIGN=CENTER><FONT SIZE=-1 COLOR=#707070><B>All objects  (kB) </B></FONT></TD><TD BGCOLOR=#DAD6C4 ALIGN=CENTER COLSPAN=4><FONT SIZE=-1 COLOR=#707070><B>Compressable objects  (kB) </B></FONT></TD></TR><TR><TD ALIGN=CENTER><B><FONT SIZE=-1>Day</FONT></B></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Hits </FONT></B><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#aa0000><B>Actual bytes</FONT></B></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#008000><B>Bytes sent</FONT></B></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Saved bytes</FONT></B></TD>
+<TD ALIGN=CENTER><B><FONT SIZE=-1>Hits</FONT></B></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#aa0000><B>Actual bytes</B></FONT></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#008000><B>Bytes sent</B></FONT></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Saved bytes</FONT></B></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>8</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>171 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>234 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>58 </FONT><FONT SIZE=-1 COLOR=#707070> (24.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>175 </FONT><FONT SIZE=-1 COLOR=#707070> (74.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>36 </FONT><FONT SIZE=-1 COLOR=#707070> (21.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>234 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>58 </FONT><FONT SIZE=-1 COLOR=#707070> (24.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 175 </FONT><FONT SIZE=-1 COLOR=#707070> (74.9%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>10</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>13</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>14</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>18 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (28.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (63.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (11.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (28.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 4 </FONT><FONT SIZE=-1 COLOR=#707070> (63.6%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>15</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>25 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (36.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT><FONT SIZE=-1 COLOR=#707070> (64.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>3 </FONT><FONT SIZE=-1 COLOR=#707070> (12.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>11 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (36.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 7 </FONT><FONT SIZE=-1 COLOR=#707070> (64.9%) </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>17</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>9 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>18</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>25</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>27</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT><FONT SIZE=-1 COLOR=#707070> (0.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>0 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 0 </FONT></TD></TR>
+<TR><TD ALIGN=CENTER><B><FONT SIZE=-1>28</FONT></b></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>14 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (28.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4 </FONT><FONT SIZE=-1 COLOR=#707070> (63.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (14.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>7 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2 </FONT><FONT SIZE=-1 COLOR=#707070> (28.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 4 </FONT><FONT SIZE=-1 COLOR=#707070> (63.6%) </FONT></TD></TR>
+</TABLE><BR><BR></CENTER><FONT SIZE=2 COLOR=#707070>Report generated by <A HREF="http://wizard.ae.krakow.pl/~mike/mgstat/">mgstat 0.10</A> </BODY></HTML>
\ No newline at end of file
diff --git a/website/stats/index.html b/website/stats/index.html
new file mode 100644 (file)
index 0000000..5c34da3
--- /dev/null
@@ -0,0 +1,102 @@
+<HTML><BODY BGCOLOR=#EAE6D4><HR><BR><CENTER><FONT COLOR=#000090 SIZE=4><B>Mod gzip statistics for algowars's Site - year 2001</B></FONT></CENTER><BR><BR>
+<CENTER><TABLE CELLPADDING=4 BORDER=1><TR><TD COLSPAN=2 ALIGN=CENTER><B>Response Codes</B></TD></TR><TR><TD> - </TD><TD ALIGN=RIGHT> 1 <FONT COLOR=#707070> (0.1%) </FONT></TD></TR>
+<TR><TD> DECLINED:TOO_SMALL </TD><TD ALIGN=RIGHT> 19 <FONT COLOR=#707070> (2.0%) </FONT></TD></TR>
+<TR><TD> OK </TD><TD ALIGN=RIGHT> 68 <FONT COLOR=#707070> (7.2%) </FONT></TD></TR>
+<TR><TD> DECLINED:EXCLUDED </TD><TD ALIGN=RIGHT> 324 <FONT COLOR=#707070> (34.4%) </FONT></TD></TR>
+<TR><TD> SEND_AS_IS:RESPONSE_CONTENT_TYPE_EXCLUDED </TD><TD ALIGN=RIGHT> 6 <FONT COLOR=#707070> (0.6%) </FONT></TD></TR>
+<TR><TD> SEND_AS_IS:NO_200 </TD><TD ALIGN=RIGHT> 27 <FONT COLOR=#707070> (2.9%) </FONT></TD></TR>
+<TR><TD> DECHUNK:OK </TD><TD ALIGN=RIGHT> 8 <FONT COLOR=#707070> (0.9%) </FONT></TD></TR>
+<TR><TD> DECLINED:NO_ACCEPT_ENCODING </TD><TD ALIGN=RIGHT> 488 <FONT COLOR=#707070> (51.9%) </FONT></TD></TR>
+</TABLE></CENTER><BR>
+<CENTER><TABLE BORDER=1 CELLPADDING=3><TR><TD COLSPAN=5 ALIGN=CENTER><FONT SIZE=-1 COLOR=#707070><B>All objects  (kB) </B></FONT></TD><TD BGCOLOR=#DAD6C4 ALIGN=CENTER COLSPAN=4><FONT SIZE=-1 COLOR=#707070><B>Compressable objects  (kB) </B></FONT></TD></TR><TR><TD ALIGN=CENTER><B><FONT SIZE=-1>Month</FONT></B></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Hits </FONT></B><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#aa0000><B>Actual bytes</FONT></B></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#008000><B>Bytes sent</FONT></B></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Saved bytes</FONT></B></TD>
+<TD ALIGN=CENTER><B><FONT SIZE=-1>Hits</FONT></B></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#aa0000><B>Actual bytes</B></FONT></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#008000><B>Bytes sent</B></FONT></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Saved bytes</FONT></B></TD></TR>
+<TR><TD><B><A HREF="Dec-2001.html"> <FONT SIZE=-1>Dec 2001</FONT></A></B></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>695 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>142 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>47 </FONT><FONT SIZE=-1 COLOR=#707070> (33.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>94 </FONT><FONT SIZE=-1 COLOR=#707070> (66.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>33 </FONT><FONT SIZE=-1 COLOR=#707070> (4.7%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>142 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>47 </FONT><FONT SIZE=-1 COLOR=#707070> (33.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 94 </FONT><FONT SIZE=-1 COLOR=#707070> (66.4%) </FONT></TD></TR>
+<TR><TD><B><A HREF="Nov-2001.html"> <FONT SIZE=-1>Nov 2001</FONT></A></B></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>246 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>261 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>68 </FONT><FONT SIZE=-1 COLOR=#707070> (26.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>192 </FONT><FONT SIZE=-1 COLOR=#707070> (73.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>43 </FONT><FONT SIZE=-1 COLOR=#707070> (17.5%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>261 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>68 </FONT><FONT SIZE=-1 COLOR=#707070> (26.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 192 </FONT><FONT SIZE=-1 COLOR=#707070> (73.8%) </FONT></TD></TR>
+<TR><TD BGCOLOR=#DAD6C4><B><FONT SIZE=-1>Total</FONT></B></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>941 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>403 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>116 </FONT><FONT SIZE=-1 COLOR=#707070> (28.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>287 </FONT><FONT SIZE=-1 COLOR=#707070> (71.2%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>76 </FONT><FONT SIZE=-1 COLOR=#707070> (8.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>403 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>116 </FONT><FONT SIZE=-1 COLOR=#707070> (28.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 287 </FONT><FONT SIZE=-1 COLOR=#707070> (71.2%) </FONT></TD></TR>
+</TABLE><BR>
+<HTML><BODY BGCOLOR=#EAE6D4><HR><BR><CENTER><FONT COLOR=#000090 SIZE=4><B>Mod gzip statistics for algowars's Site - year 2002</B></FONT></CENTER><BR><BR>
+<CENTER><TABLE CELLPADDING=4 BORDER=1><TR><TD COLSPAN=2 ALIGN=CENTER><B>Response Codes</B></TD></TR><TR><TD> DECLINED:TOO_SMALL </TD><TD ALIGN=RIGHT> 108 <FONT COLOR=#707070> (1.9%) </FONT></TD></TR>
+<TR><TD> OK </TD><TD ALIGN=RIGHT> 617 <FONT COLOR=#707070> (10.7%) </FONT></TD></TR>
+<TR><TD> DECLINED:EXCLUDED </TD><TD ALIGN=RIGHT> 2273 <FONT COLOR=#707070> (39.6%) </FONT></TD></TR>
+<TR><TD> SEND_AS_IS:RESPONSE_CONTENT_TYPE_EXCLUDED </TD><TD ALIGN=RIGHT> 18 <FONT COLOR=#707070> (0.3%) </FONT></TD></TR>
+<TR><TD> SEND_AS_IS:NO_200 </TD><TD ALIGN=RIGHT> 53 <FONT COLOR=#707070> (0.9%) </FONT></TD></TR>
+<TR><TD> DECHUNK:OK </TD><TD ALIGN=RIGHT> 533 <FONT COLOR=#707070> (9.3%) </FONT></TD></TR>
+<TR><TD> DECLINED:NO_ACCEPT_ENCODING </TD><TD ALIGN=RIGHT> 1857 <FONT COLOR=#707070> (32.3%) </FONT></TD></TR>
+<TR><TD> DECLINED:NOT_GET_OR_POST </TD><TD ALIGN=RIGHT> 57 <FONT COLOR=#707070> (1.0%) </FONT></TD></TR>
+<TR><TD> DECLINED:HEAD_REQUEST </TD><TD ALIGN=RIGHT> 208 <FONT COLOR=#707070> (3.6%) </FONT></TD></TR>
+<TR><TD> DECLINED:UNHANDLED_REDIR </TD><TD ALIGN=RIGHT> 5 <FONT COLOR=#707070> (0.1%) </FONT></TD></TR>
+<TR><TD> SEND_AS_IS:BODY_MISSING </TD><TD ALIGN=RIGHT> 13 <FONT COLOR=#707070> (0.2%) </FONT></TD></TR>
+</TABLE></CENTER><BR>
+<CENTER><TABLE BORDER=1 CELLPADDING=3><TR><TD COLSPAN=5 ALIGN=CENTER><FONT SIZE=-1 COLOR=#707070><B>All objects  (kB) </B></FONT></TD><TD BGCOLOR=#DAD6C4 ALIGN=CENTER COLSPAN=4><FONT SIZE=-1 COLOR=#707070><B>Compressable objects  (kB) </B></FONT></TD></TR><TR><TD ALIGN=CENTER><B><FONT SIZE=-1>Month</FONT></B></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Hits </FONT></B><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#aa0000><B>Actual bytes</FONT></B></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#008000><B>Bytes sent</FONT></B></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Saved bytes</FONT></B></TD>
+<TD ALIGN=CENTER><B><FONT SIZE=-1>Hits</FONT></B></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#aa0000><B>Actual bytes</B></FONT></TD><TD ALIGN=CENTER><FONT SIZE=-1 COLOR=#008000><B>Bytes sent</B></FONT></TD><TD ALIGN=CENTER><B><FONT SIZE=-1>Saved bytes</FONT></B></TD></TR>
+<TR><TD><B><A HREF="Apr-2002.html"> <FONT SIZE=-1>Apr 2002</FONT></A></B></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>594 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1439 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>250 </FONT><FONT SIZE=-1 COLOR=#707070> (17.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1189 </FONT><FONT SIZE=-1 COLOR=#707070> (82.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>88 </FONT><FONT SIZE=-1 COLOR=#707070> (14.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1439 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>250 </FONT><FONT SIZE=-1 COLOR=#707070> (17.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 1189 </FONT><FONT SIZE=-1 COLOR=#707070> (82.6%) </FONT></TD></TR>
+<TR><TD><B><A HREF="Mar-2002.html"> <FONT SIZE=-1>Mar 2002</FONT></A></B></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2492 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5565 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1258 </FONT><FONT SIZE=-1 COLOR=#707070> (22.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>4306 </FONT><FONT SIZE=-1 COLOR=#707070> (77.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>731 </FONT><FONT SIZE=-1 COLOR=#707070> (29.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5565 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1258 </FONT><FONT SIZE=-1 COLOR=#707070> (22.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 4306 </FONT><FONT SIZE=-1 COLOR=#707070> (77.4%) </FONT></TD></TR>
+<TR><TD><B><A HREF="Feb-2002.html"> <FONT SIZE=-1>Feb 2002</FONT></A></B></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>797 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>470 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>152 </FONT><FONT SIZE=-1 COLOR=#707070> (32.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>317 </FONT><FONT SIZE=-1 COLOR=#707070> (67.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>130 </FONT><FONT SIZE=-1 COLOR=#707070> (16.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>470 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>152 </FONT><FONT SIZE=-1 COLOR=#707070> (32.3%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 317 </FONT><FONT SIZE=-1 COLOR=#707070> (67.6%) </FONT></TD></TR>
+<TR><TD><B><A HREF="Jan-2002.html"> <FONT SIZE=-1>Jan 2002</FONT></A></B></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1859 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1329 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>353 </FONT><FONT SIZE=-1 COLOR=#707070> (26.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>975 </FONT><FONT SIZE=-1 COLOR=#707070> (73.4%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>201 </FONT><FONT SIZE=-1 COLOR=#707070> (10.8%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1329 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>353 </FONT><FONT SIZE=-1 COLOR=#707070> (26.6%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 975 </FONT><FONT SIZE=-1 COLOR=#707070> (73.4%) </FONT></TD></TR>
+<TR><TD BGCOLOR=#DAD6C4><B><FONT SIZE=-1>Total</FONT></B></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>5742 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8804 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2015 </FONT><FONT SIZE=-1 COLOR=#707070> (22.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>6788 </FONT><FONT SIZE=-1 COLOR=#707070> (77.1%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>1150 </FONT><FONT SIZE=-1 COLOR=#707070> (20.0%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>8804 </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1>2015 </FONT><FONT SIZE=-1 COLOR=#707070> (22.9%) </FONT></TD>
+<TD ALIGN=RIGHT><FONT SIZE=-1> 6788 </FONT><FONT SIZE=-1 COLOR=#707070> (77.1%) </FONT></TD></TR>
+</TABLE><BR>
+</CENTER><BR><BR></CENTER><FONT SIZE=2 COLOR=#707070>Report generated by <A HREF="http://wizard.ae.krakow.pl/~mike/mgstat/">mgstat 0.10</A> </BODY></HTML>
\ No newline at end of file
diff --git a/website/stats/mgstat.hist b/website/stats/mgstat.hist
new file mode 100644 (file)
index 0000000..c6a5fed
Binary files /dev/null and b/website/stats/mgstat.hist differ
diff --git a/website/stats/mgstat.pos b/website/stats/mgstat.pos
new file mode 100644 (file)
index 0000000..240f9f4
--- /dev/null
@@ -0,0 +1 @@
+55839 200.16.7.108 - - [09/Apr/2002:23:27:21 -0300] "GET /proyecto/download/instalar.exe HTTP/1.0" 200 621806 "http://www.algowars.luca.2y.net/instalar.html" "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" mod_gzip: DECLINED:EXCLUDED In:0 Out:0
diff --git a/website/test.php b/website/test.php
new file mode 100644 (file)
index 0000000..1402502
--- /dev/null
@@ -0,0 +1,3 @@
+<?
+        error( 'dkkdd
+?>
diff --git a/website/uml.html b/website/uml.html
new file mode 100644 (file)
index 0000000..e69bbf6
--- /dev/null
@@ -0,0 +1,71 @@
+<html><!-- #BeginTemplate "/Templates/normal.dwt" -->\r
+<!-- #BeginEditable "doctitle" -->\r
+<title>AlgoWars - Episodio IV</title>\r
+<!-- #EndEditable -->\r
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\r
+<!-- #BeginEditable "docstyle" -->\r
+<style type="text/css">\r
+<!--\r
+p {  margin-top: 5px; margin-right: 0px; margin-bottom: 5px}\r
+body {  font-family: Arial, Helvetica, sans-serif; font-size: 14px}\r
+ul {  list-style-image:       url(images/bullet.jpg); list-style-type: circle}\r
+li {  list-style-image:       url(images/bullet.jpg); list-style-type: circle}\r
+td {  font-family: Arial, Helvetica, sans-serif; font-size: 12px}\r
+-->\r
+</style>\r
+<!-- #EndEditable -->\r
+\r
+\r
+\r
+</head>\r
+\r
+<body bgcolor="#000000" text="#FFFFFF" link="#66CCFF" vlink="#0099FF" alink="#33FFFF" leftmargin="5" topmargin="5" marginwidth="5" marginheight="5" onLoad="">\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#0033CC" size="4"><b><font color="#FF9999">AlgoWars</font></b></font></p>\r
+<p align="center"><font face="Arial, Helvetica, sans-serif" color="#FF9999" size="3"><b><font size="2">Episodio IV</font></b></font>\r
+</p>\r
+<p>&nbsp;</p>\r
+<p><font size="+1"><b><!-- #BeginEditable "T%EDtulo" -->Diagramas UML<!-- #EndEditable --></b></font></p>\r
+<br>  <!-- #BeginEditable "Cuerpo" -->\r
+<p>A continuaci&oacute;n puede observar los diagramas UML:</p>\r
+<blockquote>\r
+  \r
+    \r
+  <p><a href="uml/jerarquia.gif">Diagrama de Jerarqu&iacute;a de Clases del Modelo</a>\r
+| 114 KB<br>\r
+    \r
+    <a href="uml/vista.gif">Diagrama de Jerarqu&iacute;a de Clases de la Vista y otras Clases Auxiliares</a>\r
+| 83 KB </p>\r
+  <p><a href="uml/diagrama.gif">Diagrama de Clases</a>\r
+| 83 KB </p>\r
+  <p><a href="uml/secuencia_actualizar.gif">Diagrama de Secuencias del m&eacute;todo mActualizar de la clase cEspacio</a>\r
+| 23 KB </p>\r
+  <p><a href="uml/secuencia_colisiones.gif">Diagrama de Secuencias del m&eacute;todo mDetectarColisiones de la clase cEspacio</a>\r
+| 47 KB </p>\r
+  <p><a href="uml/estado.gif">Diagrama de Estados de la Aplicaci&oacute;n</a>\r
+| 33 KB  \r
+  </p>\r
+  <p>&nbsp;</p>\r
+</blockquote>\r
+<!-- #EndEditable -->\r
+\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+  <br>\r
+<center>\r
+    <a href="main.html" target="mainFrame">Descripci&oacute;n</a> | <a href="instalar.html" target="mainFrame">Instalar el Juego</a> | <a href="configurar.html" target="mainFrame">Configurar un Escenario</a> | <a href="jugar.html" target="mainFrame">C&oacute;mo Jugar</a> | <a href="naves.html" target="mainFrame">Descripcion de Naves</a> | <a href="screenshots.html" target="mainFrame">Screenshots</a> | <a href="downloads.html" target="mainFrame">Downloads</a> | <a href="desarrollo.html" target="mainFrame">Desarrollo<br>\r
+  </a>\r
+  \r
+  <b><font color="#CCCC00" size="2">\r
+  </font></b><br>\r
+      \r
+</center>\r
+<center>\r
+  <font size="1" face="Arial, Helvetica, sans-serif">\r
+  Copyleft 2000. Ante cualquier duda env&iacute;enos un <a href="mailto:info@algowars.luca.2t.net?subject=AlgoWars">e-mail</a>\r
+</font>\r
+</center>\r
+  </body>\r
+<!-- #EndTemplate --></html>\r
diff --git a/website/uml/diagrama.gif b/website/uml/diagrama.gif
new file mode 100644 (file)
index 0000000..d87e81c
Binary files /dev/null and b/website/uml/diagrama.gif differ
diff --git a/website/uml/estado.gif b/website/uml/estado.gif
new file mode 100644 (file)
index 0000000..3acd8f5
Binary files /dev/null and b/website/uml/estado.gif differ
diff --git a/website/uml/jerarquia.gif b/website/uml/jerarquia.gif
new file mode 100644 (file)
index 0000000..0373b0a
Binary files /dev/null and b/website/uml/jerarquia.gif differ
diff --git a/website/uml/secuencia_actualizar.gif b/website/uml/secuencia_actualizar.gif
new file mode 100644 (file)
index 0000000..a5fd111
Binary files /dev/null and b/website/uml/secuencia_actualizar.gif differ
diff --git a/website/uml/secuencia_colisiones.gif b/website/uml/secuencia_colisiones.gif
new file mode 100644 (file)
index 0000000..a097210
Binary files /dev/null and b/website/uml/secuencia_colisiones.gif differ
diff --git a/website/uml/vista.gif b/website/uml/vista.gif
new file mode 100644 (file)
index 0000000..55ad070
Binary files /dev/null and b/website/uml/vista.gif differ