mirror of
https://github.com/TTimo/GtkRadiant.git
synced 2025-01-09 19:41:04 +00:00
Merge pull request #104 from QBall147/bspc
Added bspc to the solution (with initial ql support)
This commit is contained in:
commit
06ac3b72a5
188 changed files with 108960 additions and 1 deletions
|
@ -1,6 +1,6 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
# Visual Studio 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "radiant", "radiant\radiant.vcproj", "{65D02375-63EE-4A8A-9F8E-504B1D5A1D02}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{B957BA35-F807-4C84-85A2-C1F9AC56713B} = {B957BA35-F807-4C84-85A2-C1F9AC56713B}
|
||||
|
@ -188,6 +188,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vfsqlpk3", "plugins\vfsqlpk
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "q3map2_urt", "tools\urt\tools\quake3\q3map2\q3map2_urt.vcproj", "{7AF7537E-94C3-4680-8F5E-C1CE30DC2041}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bspc", "tools\quake3\bspc\bspc.vcproj", "{4E4EBC16-F345-4667-84E1-86633BAFDAE6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
|
@ -354,6 +356,10 @@ Global
|
|||
{7AF7537E-94C3-4680-8F5E-C1CE30DC2041}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{7AF7537E-94C3-4680-8F5E-C1CE30DC2041}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{7AF7537E-94C3-4680-8F5E-C1CE30DC2041}.Release|Win32.Build.0 = Release|Win32
|
||||
{4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
249
tools/quake3/bspc/.deps
Normal file
249
tools/quake3/bspc/.deps
Normal file
|
@ -0,0 +1,249 @@
|
|||
_files.o: _files.c
|
||||
aas_areamerging.o: aas_areamerging.c qbsp.h l_cmd.h l_math.h l_poly.h \
|
||||
l_threads.h deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h \
|
||||
l_utils.h l_log.h l_qfiles.h deps/qcommon/unzip.h deps/botlib/aasfile.h \
|
||||
aas_create.h aas_store.h deps/botlib/be_aas.h deps/botlib/be_aas_def.h
|
||||
aas_cfg.o: aas_cfg.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h deps/botlib/aasfile.h aas_store.h \
|
||||
deps/botlib/be_aas.h deps/botlib/be_aas_def.h aas_cfg.h \
|
||||
deps/botlib/l_precomp.h deps/botlib/l_struct.h deps/botlib/l_libvar.h
|
||||
aas_create.o: aas_create.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h deps/botlib/aasfile.h aas_create.h \
|
||||
aas_store.h deps/botlib/be_aas.h deps/botlib/be_aas_def.h aas_gsubdiv.h \
|
||||
aas_facemerging.h aas_areamerging.h aas_edgemelting.h aas_prunenodes.h \
|
||||
aas_cfg.h deps/qcommon/surfaceflags.h
|
||||
aas_edgemelting.o: aas_edgemelting.c qbsp.h l_cmd.h l_math.h l_poly.h \
|
||||
l_threads.h deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h \
|
||||
l_utils.h l_log.h l_qfiles.h deps/qcommon/unzip.h deps/botlib/aasfile.h \
|
||||
aas_create.h
|
||||
aas_facemerging.o: aas_facemerging.c qbsp.h l_cmd.h l_math.h l_poly.h \
|
||||
l_threads.h deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h \
|
||||
l_utils.h l_log.h l_qfiles.h deps/qcommon/unzip.h deps/botlib/aasfile.h \
|
||||
aas_create.h
|
||||
aas_file.o: aas_file.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h deps/botlib/aasfile.h aas_file.h \
|
||||
aas_store.h deps/botlib/be_aas.h deps/botlib/be_aas_def.h aas_create.h
|
||||
aas_gsubdiv.o: aas_gsubdiv.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h deps/botlib/aasfile.h aas_create.h \
|
||||
aas_store.h deps/botlib/be_aas.h deps/botlib/be_aas_def.h aas_cfg.h
|
||||
aas_map.o: aas_map.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h deps/botlib/aasfile.h aas_store.h \
|
||||
deps/botlib/be_aas.h deps/botlib/be_aas_def.h aas_cfg.h \
|
||||
deps/qcommon/surfaceflags.h
|
||||
aas_prunenodes.o: aas_prunenodes.c qbsp.h l_cmd.h l_math.h l_poly.h \
|
||||
l_threads.h deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h \
|
||||
l_utils.h l_log.h l_qfiles.h deps/qcommon/unzip.h deps/botlib/aasfile.h \
|
||||
aas_create.h
|
||||
aas_store.o: aas_store.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h deps/botlib/aasfile.h aas_file.h \
|
||||
aas_store.h deps/botlib/be_aas.h deps/botlib/be_aas_def.h aas_create.h \
|
||||
aas_cfg.h
|
||||
be_aas_bspc.o: be_aas_bspc.c deps/qcommon/q_shared.h \
|
||||
deps/qcommon/q_platform.h deps/qcommon/surfaceflags.h l_log.h l_qfiles.h \
|
||||
deps/qcommon/unzip.h deps/botlib/l_memory.h deps/botlib/l_script.h \
|
||||
deps/botlib/l_precomp.h deps/botlib/l_struct.h deps/botlib/aasfile.h \
|
||||
deps/botlib/botlib.h deps/botlib/be_aas.h deps/botlib/be_aas_def.h \
|
||||
deps/botlib/be_aas_main.h deps/botlib/be_aas_entity.h \
|
||||
deps/botlib/be_aas_sample.h deps/botlib/be_aas_cluster.h \
|
||||
deps/botlib/be_aas_reach.h deps/botlib/be_aas_route.h \
|
||||
deps/botlib/be_aas_routealt.h deps/botlib/be_aas_debug.h \
|
||||
deps/botlib/be_aas_file.h deps/botlib/be_aas_optimize.h \
|
||||
deps/botlib/be_aas_bsp.h deps/botlib/be_aas_move.h \
|
||||
deps/qcommon/cm_public.h deps/qcommon/qfiles.h
|
||||
be_aas_bspq3.o: deps/botlib/be_aas_bspq3.c deps/qcommon/q_shared.h \
|
||||
deps/qcommon/q_platform.h deps/qcommon/surfaceflags.h \
|
||||
deps/botlib/l_memory.h deps/botlib/l_script.h deps/botlib/l_precomp.h \
|
||||
deps/botlib/l_struct.h deps/botlib/aasfile.h deps/botlib/botlib.h \
|
||||
deps/botlib/be_aas.h deps/botlib/be_aas_funcs.h \
|
||||
deps/botlib/be_aas_main.h deps/botlib/be_aas_entity.h \
|
||||
deps/botlib/be_aas_sample.h deps/botlib/be_aas_cluster.h \
|
||||
deps/botlib/be_aas_reach.h deps/botlib/be_aas_route.h \
|
||||
deps/botlib/be_aas_routealt.h deps/botlib/be_aas_debug.h \
|
||||
deps/botlib/be_aas_file.h deps/botlib/be_aas_optimize.h \
|
||||
deps/botlib/be_aas_bsp.h deps/botlib/be_aas_move.h \
|
||||
deps/botlib/be_aas_def.h
|
||||
be_aas_cluster.o: deps/botlib/be_aas_cluster.c deps/qcommon/q_shared.h \
|
||||
deps/qcommon/q_platform.h deps/qcommon/surfaceflags.h \
|
||||
deps/botlib/l_memory.h deps/botlib/l_script.h deps/botlib/l_precomp.h \
|
||||
deps/botlib/l_struct.h deps/botlib/l_log.h deps/botlib/l_libvar.h \
|
||||
deps/botlib/aasfile.h deps/botlib/botlib.h deps/botlib/be_aas.h \
|
||||
deps/botlib/be_aas_funcs.h deps/botlib/be_aas_main.h \
|
||||
deps/botlib/be_aas_entity.h deps/botlib/be_aas_sample.h \
|
||||
deps/botlib/be_aas_cluster.h deps/botlib/be_aas_reach.h \
|
||||
deps/botlib/be_aas_route.h deps/botlib/be_aas_routealt.h \
|
||||
deps/botlib/be_aas_debug.h deps/botlib/be_aas_file.h \
|
||||
deps/botlib/be_aas_optimize.h deps/botlib/be_aas_bsp.h \
|
||||
deps/botlib/be_aas_move.h deps/botlib/be_aas_def.h
|
||||
be_aas_move.o: deps/botlib/be_aas_move.c deps/qcommon/q_shared.h \
|
||||
deps/qcommon/q_platform.h deps/qcommon/surfaceflags.h \
|
||||
deps/botlib/l_memory.h deps/botlib/l_script.h deps/botlib/l_precomp.h \
|
||||
deps/botlib/l_struct.h deps/botlib/l_libvar.h deps/botlib/aasfile.h \
|
||||
deps/botlib/botlib.h deps/botlib/be_aas.h deps/botlib/be_aas_funcs.h \
|
||||
deps/botlib/be_aas_main.h deps/botlib/be_aas_entity.h \
|
||||
deps/botlib/be_aas_sample.h deps/botlib/be_aas_cluster.h \
|
||||
deps/botlib/be_aas_reach.h deps/botlib/be_aas_route.h \
|
||||
deps/botlib/be_aas_routealt.h deps/botlib/be_aas_debug.h \
|
||||
deps/botlib/be_aas_file.h deps/botlib/be_aas_optimize.h \
|
||||
deps/botlib/be_aas_bsp.h deps/botlib/be_aas_move.h \
|
||||
deps/botlib/be_aas_def.h
|
||||
be_aas_optimize.o: deps/botlib/be_aas_optimize.c deps/qcommon/q_shared.h \
|
||||
deps/qcommon/q_platform.h deps/qcommon/surfaceflags.h \
|
||||
deps/botlib/l_libvar.h deps/botlib/l_memory.h deps/botlib/l_script.h \
|
||||
deps/botlib/l_precomp.h deps/botlib/l_struct.h deps/botlib/aasfile.h \
|
||||
deps/botlib/botlib.h deps/botlib/be_aas.h deps/botlib/be_aas_funcs.h \
|
||||
deps/botlib/be_aas_main.h deps/botlib/be_aas_entity.h \
|
||||
deps/botlib/be_aas_sample.h deps/botlib/be_aas_cluster.h \
|
||||
deps/botlib/be_aas_reach.h deps/botlib/be_aas_route.h \
|
||||
deps/botlib/be_aas_routealt.h deps/botlib/be_aas_debug.h \
|
||||
deps/botlib/be_aas_file.h deps/botlib/be_aas_optimize.h \
|
||||
deps/botlib/be_aas_bsp.h deps/botlib/be_aas_move.h \
|
||||
deps/botlib/be_interface.h deps/botlib/be_aas_def.h
|
||||
be_aas_reach.o: deps/botlib/be_aas_reach.c deps/qcommon/q_shared.h \
|
||||
deps/qcommon/q_platform.h deps/qcommon/surfaceflags.h \
|
||||
deps/botlib/l_log.h deps/botlib/l_memory.h deps/botlib/l_script.h \
|
||||
deps/botlib/l_libvar.h deps/botlib/l_precomp.h deps/botlib/l_struct.h \
|
||||
deps/botlib/aasfile.h deps/botlib/botlib.h deps/botlib/be_aas.h \
|
||||
deps/botlib/be_aas_funcs.h deps/botlib/be_aas_main.h \
|
||||
deps/botlib/be_aas_entity.h deps/botlib/be_aas_sample.h \
|
||||
deps/botlib/be_aas_cluster.h deps/botlib/be_aas_reach.h \
|
||||
deps/botlib/be_aas_route.h deps/botlib/be_aas_routealt.h \
|
||||
deps/botlib/be_aas_debug.h deps/botlib/be_aas_file.h \
|
||||
deps/botlib/be_aas_optimize.h deps/botlib/be_aas_bsp.h \
|
||||
deps/botlib/be_aas_move.h deps/botlib/be_aas_def.h
|
||||
be_aas_sample.o: deps/botlib/be_aas_sample.c deps/qcommon/q_shared.h \
|
||||
deps/qcommon/q_platform.h deps/qcommon/surfaceflags.h \
|
||||
deps/botlib/l_memory.h deps/botlib/l_script.h deps/botlib/l_precomp.h \
|
||||
deps/botlib/l_struct.h deps/botlib/aasfile.h deps/botlib/botlib.h \
|
||||
deps/botlib/be_aas.h deps/botlib/be_interface.h \
|
||||
deps/botlib/be_aas_funcs.h deps/botlib/be_aas_main.h \
|
||||
deps/botlib/be_aas_entity.h deps/botlib/be_aas_sample.h \
|
||||
deps/botlib/be_aas_cluster.h deps/botlib/be_aas_reach.h \
|
||||
deps/botlib/be_aas_route.h deps/botlib/be_aas_routealt.h \
|
||||
deps/botlib/be_aas_debug.h deps/botlib/be_aas_file.h \
|
||||
deps/botlib/be_aas_optimize.h deps/botlib/be_aas_bsp.h \
|
||||
deps/botlib/be_aas_move.h deps/botlib/be_aas_def.h
|
||||
brushbsp.o: brushbsp.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h deps/botlib/aasfile.h aas_store.h \
|
||||
deps/botlib/be_aas.h deps/botlib/be_aas_def.h aas_cfg.h
|
||||
bspc.o: bspc.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h deps/botlib/aasfile.h \
|
||||
deps/botlib/be_aas_cluster.h deps/botlib/be_aas_optimize.h aas_create.h \
|
||||
aas_store.h deps/botlib/be_aas.h deps/botlib/be_aas_def.h aas_file.h \
|
||||
aas_cfg.h be_aas_bspc.h
|
||||
cm_load.o: deps/qcommon/cm_load.c deps/qcommon/cm_local.h \
|
||||
deps/qcommon/q_shared.h deps/qcommon/q_platform.h \
|
||||
deps/qcommon/surfaceflags.h deps/qcommon/qcommon.h \
|
||||
deps/qcommon/cm_public.h deps/qcommon/qfiles.h deps/qcommon/cm_polylib.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h
|
||||
cm_patch.o: deps/qcommon/cm_patch.c deps/qcommon/cm_local.h \
|
||||
deps/qcommon/q_shared.h deps/qcommon/q_platform.h \
|
||||
deps/qcommon/surfaceflags.h deps/qcommon/qcommon.h \
|
||||
deps/qcommon/cm_public.h deps/qcommon/qfiles.h deps/qcommon/cm_polylib.h \
|
||||
deps/qcommon/cm_patch.h
|
||||
cm_test.o: deps/qcommon/cm_test.c deps/qcommon/cm_local.h \
|
||||
deps/qcommon/q_shared.h deps/qcommon/q_platform.h \
|
||||
deps/qcommon/surfaceflags.h deps/qcommon/qcommon.h \
|
||||
deps/qcommon/cm_public.h deps/qcommon/qfiles.h deps/qcommon/cm_polylib.h
|
||||
cm_trace.o: deps/qcommon/cm_trace.c deps/qcommon/cm_local.h \
|
||||
deps/qcommon/q_shared.h deps/qcommon/q_platform.h \
|
||||
deps/qcommon/surfaceflags.h deps/qcommon/qcommon.h \
|
||||
deps/qcommon/cm_public.h deps/qcommon/qfiles.h deps/qcommon/cm_polylib.h
|
||||
csg.o: csg.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h
|
||||
glfile.o: glfile.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h
|
||||
l_bsp_ent.o: l_bsp_ent.c l_cmd.h l_math.h l_mem.h l_log.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h
|
||||
l_bsp_hl.o: l_bsp_hl.c l_cmd.h l_math.h l_mem.h l_log.h \
|
||||
deps/botlib/l_script.h l_bsp_hl.h l_bsp_ent.h
|
||||
l_bsp_q1.o: l_bsp_q1.c l_cmd.h l_math.h l_mem.h l_log.h \
|
||||
deps/botlib/l_script.h l_bsp_q1.h l_bsp_ent.h
|
||||
l_bsp_q2.o: l_bsp_q2.c l_cmd.h l_math.h l_mem.h l_log.h l_poly.h \
|
||||
deps/botlib/l_script.h q2files.h l_bsp_q2.h l_bsp_ent.h
|
||||
l_bsp_q3.o: l_bsp_q3.c l_cmd.h l_math.h l_mem.h l_log.h l_poly.h \
|
||||
deps/botlib/l_script.h l_qfiles.h deps/qcommon/unzip.h l_bsp_q3.h \
|
||||
q3files.h l_bsp_ent.h
|
||||
l_bsp_sin.o: l_bsp_sin.c l_cmd.h l_math.h l_mem.h l_log.h l_poly.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h l_bsp_sin.h sinfiles.h
|
||||
l_cmd.o: l_cmd.c l_cmd.h l_log.h l_mem.h
|
||||
l_libvar.o: deps/botlib/l_libvar.c deps/qcommon/q_shared.h \
|
||||
deps/qcommon/q_platform.h deps/qcommon/surfaceflags.h \
|
||||
deps/botlib/l_memory.h deps/botlib/l_libvar.h
|
||||
l_log.o: l_log.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h
|
||||
l_math.o: l_math.c l_cmd.h l_math.h
|
||||
l_mem.o: l_mem.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h
|
||||
l_poly.o: l_poly.c l_cmd.h l_math.h l_poly.h l_log.h l_mem.h
|
||||
l_precomp.o: deps/botlib/l_precomp.c qbsp.h l_cmd.h l_math.h l_poly.h \
|
||||
l_threads.h deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h \
|
||||
l_utils.h l_log.h l_qfiles.h deps/qcommon/unzip.h deps/botlib/l_log.h \
|
||||
l_mem.h deps/botlib/l_precomp.h
|
||||
l_qfiles.o: l_qfiles.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h
|
||||
l_script.o: deps/botlib/l_script.c qbsp.h l_cmd.h l_math.h l_poly.h \
|
||||
l_threads.h deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h \
|
||||
l_utils.h l_log.h l_qfiles.h deps/qcommon/unzip.h deps/botlib/l_log.h \
|
||||
l_mem.h
|
||||
l_struct.o: deps/botlib/l_struct.c qbsp.h l_cmd.h l_math.h l_poly.h \
|
||||
l_threads.h deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h \
|
||||
l_utils.h l_log.h l_qfiles.h deps/qcommon/unzip.h deps/botlib/l_log.h \
|
||||
l_mem.h deps/botlib/l_precomp.h deps/botlib/l_struct.h
|
||||
l_threads.o: l_threads.c l_cmd.h l_threads.h l_log.h l_mem.h
|
||||
l_utils.o: l_utils.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h
|
||||
leakfile.o: leakfile.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h
|
||||
map.o: map.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h l_bsp_hl.h l_bsp_q1.h l_bsp_q2.h \
|
||||
l_bsp_q3.h q3files.h l_bsp_sin.h sinfiles.h deps/botlib/aasfile.h \
|
||||
aas_store.h deps/botlib/be_aas.h deps/botlib/be_aas_def.h aas_cfg.h
|
||||
map_hl.o: map_hl.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h l_bsp_hl.h aas_map.h
|
||||
map_q1.o: map_q1.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h l_bsp_q1.h aas_map.h
|
||||
map_q2.o: map_q2.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h deps/botlib/aasfile.h aas_store.h \
|
||||
deps/botlib/be_aas.h deps/botlib/be_aas_def.h aas_cfg.h aas_map.h \
|
||||
l_bsp_q2.h
|
||||
map_q3.o: map_q3.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h deps/botlib/aasfile.h aas_store.h \
|
||||
deps/botlib/be_aas.h deps/botlib/be_aas_def.h aas_cfg.h aas_map.h \
|
||||
l_bsp_q3.h q3files.h deps/qcommon/cm_patch.h deps/qcommon/surfaceflags.h
|
||||
map_sin.o: map_sin.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h l_bsp_sin.h sinfiles.h aas_map.h
|
||||
md4.o: deps/qcommon/md4.c
|
||||
nodraw.o: nodraw.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h
|
||||
portals.o: portals.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h
|
||||
textures.o: textures.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h l_bsp_q2.h
|
||||
tree.o: tree.c qbsp.h l_cmd.h l_math.h l_poly.h l_threads.h \
|
||||
deps/botlib/l_script.h l_bsp_ent.h q2files.h l_mem.h l_utils.h l_log.h \
|
||||
l_qfiles.h deps/qcommon/unzip.h
|
||||
unzip.o: deps/qcommon/unzip.c deps/qcommon/unzip.h
|
5
tools/quake3/bspc/.gitignore
vendored
Normal file
5
tools/quake3/bspc/.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
bspc_g
|
||||
bspc
|
||||
*.log
|
||||
*.o
|
||||
*.user
|
75
tools/quake3/bspc/Conscript
Normal file
75
tools/quake3/bspc/Conscript
Normal file
|
@ -0,0 +1,75 @@
|
|||
# bspc compile
|
||||
|
||||
Import qw( BSPC_BASE_CFLAGS BUILD_DIR INSTALL_DIR CC CXX LINK );
|
||||
|
||||
@BSPC_FILES = qw(
|
||||
aas_areamerging.c
|
||||
aas_cfg.c
|
||||
aas_create.c
|
||||
aas_edgemelting.c
|
||||
aas_facemerging.c
|
||||
aas_file.c
|
||||
aas_gsubdiv.c
|
||||
aas_map.c
|
||||
aas_prunenodes.c
|
||||
aas_store.c
|
||||
be_aas_bspc.c
|
||||
deps/botlib/be_aas_bspq3.c
|
||||
deps/botlib/be_aas_cluster.c
|
||||
deps/botlib/be_aas_move.c
|
||||
deps/botlib/be_aas_optimize.c
|
||||
deps/botlib/be_aas_reach.c
|
||||
deps/botlib/be_aas_sample.c
|
||||
brushbsp.c
|
||||
bspc.c
|
||||
deps/qcommon/cm_load.c
|
||||
deps/qcommon/cm_patch.c
|
||||
deps/qcommon/cm_test.c
|
||||
deps/qcommon/cm_trace.c
|
||||
csg.c
|
||||
glfile.c
|
||||
l_bsp_ent.c
|
||||
l_bsp_hl.c
|
||||
l_bsp_q1.c
|
||||
l_bsp_q2.c
|
||||
l_bsp_q3.c
|
||||
l_bsp_sin.c
|
||||
l_cmd.c
|
||||
deps/botlib/l_libvar.c
|
||||
l_log.c
|
||||
l_math.c
|
||||
l_mem.c
|
||||
l_poly.c
|
||||
deps/botlib/l_precomp.c
|
||||
l_qfiles.c
|
||||
deps/botlib/l_script.c
|
||||
deps/botlib/l_struct.c
|
||||
l_threads.c
|
||||
l_utils.c
|
||||
leakfile.c
|
||||
map.c
|
||||
map_hl.c
|
||||
map_q1.c
|
||||
map_q2.c
|
||||
map_q3.c
|
||||
map_sin.c
|
||||
deps/qcommon/md4.c
|
||||
nodraw.c
|
||||
portals.c
|
||||
textures.c
|
||||
tree.c
|
||||
deps/qcommon/unzip.c
|
||||
);
|
||||
$BSPC_REF = \@BSPC_FILES;
|
||||
|
||||
$env = new cons(
|
||||
CC => $CC,
|
||||
CXX => $CXX,
|
||||
LINK => $LINK,
|
||||
CFLAGS => $BSPC_BASE_CFLAGS,
|
||||
LIBS => '-ldl -lm -lpthread'
|
||||
);
|
||||
|
||||
Program $env 'bspc', @$BSPC_REF;
|
||||
# this should install to Q3 or something?
|
||||
Install $env $INSTALL_DIR, 'bspc';
|
339
tools/quake3/bspc/LICENSE
Normal file
339
tools/quake3/bspc/LICENSE
Normal file
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
109
tools/quake3/bspc/Makefile
Normal file
109
tools/quake3/bspc/Makefile
Normal file
|
@ -0,0 +1,109 @@
|
|||
CC=gcc
|
||||
CFLAGS=\
|
||||
-Dstricmp=strcasecmp -DCom_Memcpy=memcpy -DCom_Memset=memset \
|
||||
-DMAC_STATIC= -DQDECL= -DLINUX -DBSPC -D_FORTIFY_SOURCE=2 \
|
||||
-I. -Ideps -Wall
|
||||
|
||||
RELEASE_CFLAGS=-O3 -ffast-math
|
||||
DEBUG_CFLAGS=-g -O0 -ffast-math
|
||||
LDFLAGS=-lm -lpthread
|
||||
|
||||
DO_CC=$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
#############################################################################
|
||||
# SETUP AND BUILD BSPC
|
||||
#############################################################################
|
||||
|
||||
.c.o:
|
||||
$(DO_CC)
|
||||
|
||||
GAME_OBJS = \
|
||||
_files.o\
|
||||
aas_areamerging.o\
|
||||
aas_cfg.o\
|
||||
aas_create.o\
|
||||
aas_edgemelting.o\
|
||||
aas_facemerging.o\
|
||||
aas_file.o\
|
||||
aas_gsubdiv.o\
|
||||
aas_map.o\
|
||||
aas_prunenodes.o\
|
||||
aas_store.o\
|
||||
be_aas_bspc.o\
|
||||
deps/botlib/be_aas_bspq3.o\
|
||||
deps/botlib/be_aas_cluster.o\
|
||||
deps/botlib/be_aas_move.o\
|
||||
deps/botlib/be_aas_optimize.o\
|
||||
deps/botlib/be_aas_reach.o\
|
||||
deps/botlib/be_aas_sample.o\
|
||||
brushbsp.o\
|
||||
bspc.o\
|
||||
deps/qcommon/cm_load.o\
|
||||
deps/qcommon/cm_patch.o\
|
||||
deps/qcommon/cm_test.o\
|
||||
deps/qcommon/cm_trace.o\
|
||||
csg.o\
|
||||
glfile.o\
|
||||
l_bsp_ent.o\
|
||||
l_bsp_hl.o\
|
||||
l_bsp_q1.o\
|
||||
l_bsp_q2.o\
|
||||
l_bsp_q3.o\
|
||||
l_bsp_sin.o\
|
||||
l_cmd.o\
|
||||
deps/botlib/l_libvar.o\
|
||||
l_log.o\
|
||||
l_math.o\
|
||||
l_mem.o\
|
||||
l_poly.o\
|
||||
deps/botlib/l_precomp.o\
|
||||
l_qfiles.o\
|
||||
deps/botlib/l_script.o\
|
||||
deps/botlib/l_struct.o\
|
||||
l_threads.o\
|
||||
l_utils.o\
|
||||
leakfile.o\
|
||||
map.o\
|
||||
map_hl.o\
|
||||
map_q1.o\
|
||||
map_q2.o\
|
||||
map_q3.o\
|
||||
map_sin.o\
|
||||
deps/qcommon/md4.o\
|
||||
nodraw.o\
|
||||
portals.o\
|
||||
textures.o\
|
||||
tree.o\
|
||||
deps/qcommon/unzip.o
|
||||
|
||||
#tetrahedron.o
|
||||
|
||||
EXEC = bspc
|
||||
|
||||
all: release
|
||||
|
||||
debug: CFLAGS += $(DEBUG_CFLAGS)
|
||||
debug: $(EXEC)_g
|
||||
|
||||
release: CFLAGS += $(RELEASE_CFLAGS)
|
||||
release: $(EXEC)
|
||||
|
||||
$(EXEC): $(GAME_OBJS)
|
||||
$(CC) $(LDFLAGS) -o $@ $(GAME_OBJS)
|
||||
strip $@
|
||||
|
||||
$(EXEC)_g: $(GAME_OBJS)
|
||||
$(CC) $(LDFLAGS) -o $@ $(GAME_OBJS)
|
||||
|
||||
#############################################################################
|
||||
# MISC
|
||||
#############################################################################
|
||||
.PHONY: clean depend
|
||||
|
||||
clean:
|
||||
-rm -f $(GAME_OBJS) $(EXEC) $(EXEC)_g
|
||||
|
||||
depend:
|
||||
$(CC) $(CFLAGS) -MM $(GAME_OBJS:.o=.c) > .deps
|
||||
|
||||
include .deps
|
48
tools/quake3/bspc/README.md
Normal file
48
tools/quake3/bspc/README.md
Normal file
|
@ -0,0 +1,48 @@
|
|||
# bspc
|
||||
|
||||
This is the [Quake III: Arena](http://www.idsoftware.com/games/quake/quake3-arena/) BSP-to-AAS compiler.
|
||||
|
||||
## Downloading
|
||||
|
||||
You can download the latest version [here](https://github.com/bnoordhuis/bspc).
|
||||
|
||||
## Compiling
|
||||
|
||||
Dead simple:
|
||||
|
||||
make
|
||||
|
||||
## Usage
|
||||
|
||||
Straight from the source:
|
||||
|
||||
Usage: bspc [-<switch> [-<switch> ...]]
|
||||
Example 1: bspc -bsp2aas /quake3/baseq3/maps/mymap?.bsp
|
||||
Example 2: bspc -bsp2aas /quake3/baseq3/pak0.pk3/maps/q3dm*.bsp
|
||||
|
||||
Switches:
|
||||
bsp2aas <[pakfilter/]filter.bsp> = convert BSP to AAS
|
||||
reach <filter.bsp> = compute reachability & clusters
|
||||
cluster <filter.aas> = compute clusters
|
||||
aasopt <filter.aas> = optimize aas file
|
||||
aasinfo <filter.aas> = show AAS file info
|
||||
output <output path> = set output path
|
||||
threads <X> = set number of threads to X
|
||||
cfg <filename> = use this cfg file
|
||||
optimize = enable optimization
|
||||
noverbose = disable verbose output
|
||||
breadthfirst = breadth first bsp building
|
||||
nobrushmerge = don't merge brushes
|
||||
noliquids = don't write liquids to map
|
||||
freetree = free the bsp tree
|
||||
nocsg = disables brush chopping
|
||||
forcesidesvisible = force all sides to be visible
|
||||
grapplereach = calculate grapple reachabilities
|
||||
|
||||
## Support
|
||||
|
||||
[File a bug report](https://github.com/bnoordhuis/bspc/issues) if you run into issues.
|
||||
|
||||
## License
|
||||
|
||||
This program is licensed under the GNU Public License v2.0 and any later version.
|
63
tools/quake3/bspc/_files.c
Normal file
63
tools/quake3/bspc/_files.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
//===========================================================================
|
||||
//
|
||||
// Name: _files.c
|
||||
// Function:
|
||||
// Programmer: Mr Elusive
|
||||
// Last update: 1999-12-02
|
||||
// Tab Size: 4
|
||||
//===========================================================================
|
||||
|
||||
/*
|
||||
|
||||
aas_areamerging.c //AAS area merging
|
||||
aas_cfg.c //AAS configuration for different games
|
||||
aas_create.c //AAS creating
|
||||
aas_edgemelting.c //AAS edge melting
|
||||
aas_facemerging.c //AAS face merging
|
||||
aas_file.c //AAS file writing
|
||||
aas_gsubdiv.c //AAS gravitational and ladder subdivision
|
||||
aas_map.c //AAS map brush creation
|
||||
aas_prunenodes.c //AAS node pruning
|
||||
aas_store.c //AAS file storing
|
||||
|
||||
map.c //map file loading and writing
|
||||
map_hl.c //Half-Life map loading
|
||||
map_q1.c //Quake1 map loading
|
||||
map_q2.c //Quake2 map loading
|
||||
map_q3.c //Quake3 map loading
|
||||
map_sin.c //Sin map loading
|
||||
tree.c //BSP tree management + node pruning (*)
|
||||
brushbsp.c //brush bsp creation (*)
|
||||
portals.c //BSP portal creation and leaf filling (*)
|
||||
csg.c //Constructive Solid Geometry brush chopping (*)
|
||||
leakfile.c //leak file writing (*)
|
||||
textures.c //Quake2 BSP textures (*)
|
||||
|
||||
l_bsp_ent.c //BSP entity parsing
|
||||
l_bsp_hl.c //Half-Life BSP loading and writing
|
||||
l_bsp_q1.c //Quake1 BSP loading and writing
|
||||
l_bsp_q2.c //Quake2 BSP loading and writing
|
||||
l_bsp_q3.c //Quake2 BSP loading and writing
|
||||
l_bsp_sin.c //Sin BSP loading and writing
|
||||
l_cmd.c //cmd library
|
||||
l_log.c //log file library
|
||||
l_math.c //math library
|
||||
l_mem.c //memory management library
|
||||
l_poly.c //polygon (winding) library
|
||||
l_script.c //script file parsing library
|
||||
l_threads.c //multi-threading library
|
||||
l_utils.c //utility library
|
||||
l_qfiles.c //loading of quake files
|
||||
|
||||
gldraw.c //GL drawing (*)
|
||||
glfile.c //GL file writing (*)
|
||||
nodraw.c //no draw module (*)
|
||||
|
||||
bspc.c //BSPC Win32 console version
|
||||
winbspc.c //WinBSPC Win32 GUI version
|
||||
win32_terminal.c //Win32 terminal output
|
||||
win32_qfiles.c //Win32 game file management (also .pak .sin)
|
||||
win32_font.c //Win32 fonts
|
||||
win32_folder.c //Win32 folder dialogs
|
||||
|
||||
*/
|
390
tools/quake3/bspc/aas_areamerging.c
Normal file
390
tools/quake3/bspc/aas_areamerging.c
Normal file
|
@ -0,0 +1,390 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "qbsp.h"
|
||||
#include "botlib/aasfile.h"
|
||||
#include "aas_create.h"
|
||||
#include "aas_store.h"
|
||||
|
||||
#define CONVEX_EPSILON 0.3
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
tmp_node_t *AAS_RefreshMergedTree_r(tmp_node_t *tmpnode)
|
||||
{
|
||||
tmp_area_t *tmparea;
|
||||
|
||||
//if this is a solid leaf
|
||||
if (!tmpnode) return NULL;
|
||||
//if this is an area leaf
|
||||
if (tmpnode->tmparea)
|
||||
{
|
||||
tmparea = tmpnode->tmparea;
|
||||
while(tmparea->mergedarea) tmparea = tmparea->mergedarea;
|
||||
tmpnode->tmparea = tmparea;
|
||||
return tmpnode;
|
||||
} //end if
|
||||
//do the children recursively
|
||||
tmpnode->children[0] = AAS_RefreshMergedTree_r(tmpnode->children[0]);
|
||||
tmpnode->children[1] = AAS_RefreshMergedTree_r(tmpnode->children[1]);
|
||||
return tmpnode;
|
||||
} //end of the function AAS_RefreshMergedTree_r
|
||||
//===========================================================================
|
||||
// returns true if the two given faces would create a non-convex area at
|
||||
// the given sides, otherwise false is returned
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int NonConvex(tmp_face_t *face1, tmp_face_t *face2, int side1, int side2)
|
||||
{
|
||||
int i;
|
||||
winding_t *w1, *w2;
|
||||
plane_t *plane1, *plane2;
|
||||
|
||||
w1 = face1->winding;
|
||||
w2 = face2->winding;
|
||||
|
||||
plane1 = &mapplanes[face1->planenum ^ side1];
|
||||
plane2 = &mapplanes[face2->planenum ^ side2];
|
||||
|
||||
//check if one of the points of face1 is at the back of the plane of face2
|
||||
for (i = 0; i < w1->numpoints; i++)
|
||||
{
|
||||
if (DotProduct(plane2->normal, w1->p[i]) - plane2->dist < -CONVEX_EPSILON) return true;
|
||||
} //end for
|
||||
//check if one of the points of face2 is at the back of the plane of face1
|
||||
for (i = 0; i < w2->numpoints; i++)
|
||||
{
|
||||
if (DotProduct(plane1->normal, w2->p[i]) - plane1->dist < -CONVEX_EPSILON) return true;
|
||||
} //end for
|
||||
|
||||
return false;
|
||||
} //end of the function NonConvex
|
||||
//===========================================================================
|
||||
// try to merge the areas at both sides of the given face
|
||||
//
|
||||
// Parameter: seperatingface : face that seperates two areas
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_TryMergeFaceAreas(tmp_face_t *seperatingface)
|
||||
{
|
||||
int side1, side2, area1faceflags, area2faceflags;
|
||||
tmp_area_t *tmparea1, *tmparea2, *newarea;
|
||||
tmp_face_t *face1, *face2, *nextface1, *nextface2;
|
||||
|
||||
tmparea1 = seperatingface->frontarea;
|
||||
tmparea2 = seperatingface->backarea;
|
||||
|
||||
//areas must have the same presence type
|
||||
if (tmparea1->presencetype != tmparea2->presencetype) return false;
|
||||
//areas must have the same area contents
|
||||
if (tmparea1->contents != tmparea2->contents) return false;
|
||||
//areas must have the same bsp model inside (or both none)
|
||||
if (tmparea1->modelnum != tmparea2->modelnum) return false;
|
||||
|
||||
area1faceflags = 0;
|
||||
area2faceflags = 0;
|
||||
for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side1])
|
||||
{
|
||||
side1 = (face1->frontarea != tmparea1);
|
||||
//debug: check if the area belongs to the area
|
||||
if (face1->frontarea != tmparea1 &&
|
||||
face1->backarea != tmparea1) Error("face does not belong to area1");
|
||||
//just continue if the face is seperating the two areas
|
||||
//NOTE: a result of this is that ground and gap areas can
|
||||
// be merged if the seperating face is the gap
|
||||
if ((face1->frontarea == tmparea1 &&
|
||||
face1->backarea == tmparea2) ||
|
||||
(face1->frontarea == tmparea2 &&
|
||||
face1->backarea == tmparea1)) continue;
|
||||
//get area1 face flags
|
||||
area1faceflags |= face1->faceflags;
|
||||
if (AAS_GapFace(face1, side1)) area1faceflags |= FACE_GAP;
|
||||
//
|
||||
for (face2 = tmparea2->tmpfaces; face2; face2 = face2->next[side2])
|
||||
{
|
||||
side2 = (face2->frontarea != tmparea2);
|
||||
//debug: check if the area belongs to the area
|
||||
if (face2->frontarea != tmparea2 &&
|
||||
face2->backarea != tmparea2) Error("face does not belong to area2");
|
||||
//just continue if the face is seperating the two areas
|
||||
//NOTE: a result of this is that ground and gap areas can
|
||||
// be merged if the seperating face is the gap
|
||||
if ((face2->frontarea == tmparea1 &&
|
||||
face2->backarea == tmparea2) ||
|
||||
(face2->frontarea == tmparea2 &&
|
||||
face2->backarea == tmparea1)) continue;
|
||||
//get area2 face flags
|
||||
area2faceflags |= face2->faceflags;
|
||||
if (AAS_GapFace(face2, side2)) area2faceflags |= FACE_GAP;
|
||||
//if the two faces would create a non-convex area
|
||||
if (NonConvex(face1, face2, side1, side2)) return false;
|
||||
} //end for
|
||||
} //end for
|
||||
//if one area has gap faces (that aren't seperating the two areas)
|
||||
//and the other has ground faces (that aren't seperating the two areas),
|
||||
//the areas can't be merged
|
||||
if (((area1faceflags & FACE_GROUND) && (area2faceflags & FACE_GAP)) ||
|
||||
((area2faceflags & FACE_GROUND) && (area1faceflags & FACE_GAP)))
|
||||
{
|
||||
// Log_Print(" can't merge: ground/gap\n");
|
||||
return false;
|
||||
} //end if
|
||||
|
||||
// Log_Print("merged area %d & %d to %d with %d faces\n", tmparea1->areanum, tmparea2->areanum, newarea->areanum, numfaces);
|
||||
// return false;
|
||||
//
|
||||
//AAS_CheckArea(tmparea1);
|
||||
//AAS_CheckArea(tmparea2);
|
||||
//create the new area
|
||||
newarea = AAS_AllocTmpArea();
|
||||
newarea->presencetype = tmparea1->presencetype;
|
||||
newarea->contents = tmparea1->contents;
|
||||
newarea->modelnum = tmparea1->modelnum;
|
||||
newarea->tmpfaces = NULL;
|
||||
|
||||
//add all the faces (except the seperating ones) from the first area
|
||||
//to the new area
|
||||
for (face1 = tmparea1->tmpfaces; face1; face1 = nextface1)
|
||||
{
|
||||
side1 = (face1->frontarea != tmparea1);
|
||||
nextface1 = face1->next[side1];
|
||||
//don't add seperating faces
|
||||
if ((face1->frontarea == tmparea1 &&
|
||||
face1->backarea == tmparea2) ||
|
||||
(face1->frontarea == tmparea2 &&
|
||||
face1->backarea == tmparea1))
|
||||
{
|
||||
continue;
|
||||
} //end if
|
||||
//
|
||||
AAS_RemoveFaceFromArea(face1, tmparea1);
|
||||
AAS_AddFaceSideToArea(face1, side1, newarea);
|
||||
} //end for
|
||||
//add all the faces (except the seperating ones) from the second area
|
||||
//to the new area
|
||||
for (face2 = tmparea2->tmpfaces; face2; face2 = nextface2)
|
||||
{
|
||||
side2 = (face2->frontarea != tmparea2);
|
||||
nextface2 = face2->next[side2];
|
||||
//don't add seperating faces
|
||||
if ((face2->frontarea == tmparea1 &&
|
||||
face2->backarea == tmparea2) ||
|
||||
(face2->frontarea == tmparea2 &&
|
||||
face2->backarea == tmparea1))
|
||||
{
|
||||
continue;
|
||||
} //end if
|
||||
//
|
||||
AAS_RemoveFaceFromArea(face2, tmparea2);
|
||||
AAS_AddFaceSideToArea(face2, side2, newarea);
|
||||
} //end for
|
||||
//free all shared faces
|
||||
for (face1 = tmparea1->tmpfaces; face1; face1 = nextface1)
|
||||
{
|
||||
side1 = (face1->frontarea != tmparea1);
|
||||
nextface1 = face1->next[side1];
|
||||
//
|
||||
AAS_RemoveFaceFromArea(face1, face1->frontarea);
|
||||
AAS_RemoveFaceFromArea(face1, face1->backarea);
|
||||
AAS_FreeTmpFace(face1);
|
||||
} //end for
|
||||
//
|
||||
tmparea1->mergedarea = newarea;
|
||||
tmparea1->invalid = true;
|
||||
tmparea2->mergedarea = newarea;
|
||||
tmparea2->invalid = true;
|
||||
//
|
||||
AAS_CheckArea(newarea);
|
||||
AAS_FlipAreaFaces(newarea);
|
||||
// Log_Print("merged area %d & %d to %d with %d faces\n", tmparea1->areanum, tmparea2->areanum, newarea->areanum);
|
||||
return true;
|
||||
} //end of the function AAS_TryMergeFaceAreas
|
||||
//===========================================================================
|
||||
// try to merge areas
|
||||
// merged areas are added to the end of the convex area list so merging
|
||||
// will be tried for those areas as well
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: tmpaasworld
|
||||
//===========================================================================
|
||||
/*
|
||||
void AAS_MergeAreas(void)
|
||||
{
|
||||
int side, nummerges;
|
||||
tmp_area_t *tmparea, *othertmparea;
|
||||
tmp_face_t *face;
|
||||
|
||||
nummerges = 0;
|
||||
Log_Write("AAS_MergeAreas\r\n");
|
||||
qprintf("%6d areas merged", 1);
|
||||
//first merge grounded areas only
|
||||
//NOTE: this is useless because the area settings aren't available yet
|
||||
for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
|
||||
{
|
||||
// Log_Print("checking area %d\n", i);
|
||||
//if the area is invalid
|
||||
if (tmparea->invalid)
|
||||
{
|
||||
// Log_Print(" area invalid\n");
|
||||
continue;
|
||||
} //end if
|
||||
//
|
||||
// if (!(tmparea->settings->areaflags & AREA_GROUNDED)) continue;
|
||||
//
|
||||
for (face = tmparea->tmpfaces; face; face = face->next[side])
|
||||
{
|
||||
side = (face->frontarea != tmparea);
|
||||
//if the face has both a front and back area
|
||||
if (face->frontarea && face->backarea)
|
||||
{
|
||||
//
|
||||
if (face->frontarea == tmparea) othertmparea = face->backarea;
|
||||
else othertmparea = face->frontarea;
|
||||
// if (!(othertmparea->settings->areaflags & AREA_GROUNDED)) continue;
|
||||
// Log_Print(" checking area %d with %d\n", face->frontarea, face->backarea);
|
||||
if (AAS_TryMergeFaceAreas(face))
|
||||
{
|
||||
qprintf("\r%6d", ++nummerges);
|
||||
break;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end for
|
||||
} //end for
|
||||
//merge all areas
|
||||
for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
|
||||
{
|
||||
// Log_Print("checking area %d\n", i);
|
||||
//if the area is invalid
|
||||
if (tmparea->invalid)
|
||||
{
|
||||
// Log_Print(" area invalid\n");
|
||||
continue;
|
||||
} //end if
|
||||
//
|
||||
for (face = tmparea->tmpfaces; face; face = face->next[side])
|
||||
{
|
||||
side = (face->frontarea != tmparea);
|
||||
//if the face has both a front and back area
|
||||
if (face->frontarea && face->backarea)
|
||||
{
|
||||
// Log_Print(" checking area %d with %d\n", face->frontarea, face->backarea);
|
||||
if (AAS_TryMergeFaceAreas(face))
|
||||
{
|
||||
qprintf("\r%6d", ++nummerges);
|
||||
break;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end for
|
||||
} //end for
|
||||
Log_Print("\r%6d areas merged\n", nummerges);
|
||||
//refresh the merged tree
|
||||
AAS_RefreshMergedTree_r(tmpaasworld.nodes);
|
||||
} //end of the function AAS_MergeAreas*/
|
||||
|
||||
int AAS_GroundArea(tmp_area_t *tmparea)
|
||||
{
|
||||
tmp_face_t *face;
|
||||
int side;
|
||||
|
||||
for (face = tmparea->tmpfaces; face; face = face->next[side])
|
||||
{
|
||||
side = (face->frontarea != tmparea);
|
||||
if (face->faceflags & FACE_GROUND) return true;
|
||||
} //end for
|
||||
return false;
|
||||
} //end of the function AAS_GroundArea
|
||||
|
||||
void AAS_MergeAreas(void)
|
||||
{
|
||||
int side, nummerges, merges, groundfirst;
|
||||
tmp_area_t *tmparea, *othertmparea;
|
||||
tmp_face_t *face;
|
||||
|
||||
nummerges = 0;
|
||||
Log_Write("AAS_MergeAreas\r\n");
|
||||
qprintf("%6d areas merged", 1);
|
||||
//
|
||||
groundfirst = true;
|
||||
//for (i = 0; i < 4 || merges; i++)
|
||||
while(1)
|
||||
{
|
||||
//if (i < 2) groundfirst = true;
|
||||
//else groundfirst = false;
|
||||
//
|
||||
merges = 0;
|
||||
//first merge grounded areas only
|
||||
for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
|
||||
{
|
||||
//if the area is invalid
|
||||
if (tmparea->invalid)
|
||||
{
|
||||
continue;
|
||||
} //end if
|
||||
//
|
||||
if (groundfirst)
|
||||
{
|
||||
if (!AAS_GroundArea(tmparea)) continue;
|
||||
} //end if
|
||||
//
|
||||
for (face = tmparea->tmpfaces; face; face = face->next[side])
|
||||
{
|
||||
side = (face->frontarea != tmparea);
|
||||
//if the face has both a front and back area
|
||||
if (face->frontarea && face->backarea)
|
||||
{
|
||||
//
|
||||
if (face->frontarea == tmparea) othertmparea = face->backarea;
|
||||
else othertmparea = face->frontarea;
|
||||
//
|
||||
if (groundfirst)
|
||||
{
|
||||
if (!AAS_GroundArea(othertmparea)) continue;
|
||||
} //end if
|
||||
if (AAS_TryMergeFaceAreas(face))
|
||||
{
|
||||
qprintf("\r%6d", ++nummerges);
|
||||
merges++;
|
||||
break;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end for
|
||||
} //end for
|
||||
if (!merges)
|
||||
{
|
||||
if (groundfirst) groundfirst = false;
|
||||
else break;
|
||||
} //end if
|
||||
} //end for
|
||||
qprintf("\n");
|
||||
Log_Write("%6d areas merged\r\n", nummerges);
|
||||
//refresh the merged tree
|
||||
AAS_RefreshMergedTree_r(tmpaasworld.nodes);
|
||||
} //end of the function AAS_MergeAreas
|
24
tools/quake3/bspc/aas_areamerging.h
Normal file
24
tools/quake3/bspc/aas_areamerging.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
void AAS_MergeAreas(void);
|
||||
|
254
tools/quake3/bspc/aas_cfg.c
Normal file
254
tools/quake3/bspc/aas_cfg.c
Normal file
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "qbsp.h"
|
||||
//#include "float.h"
|
||||
#include "botlib/aasfile.h"
|
||||
#include "aas_store.h"
|
||||
#include "aas_cfg.h"
|
||||
#include "botlib/l_precomp.h"
|
||||
#include "botlib/l_struct.h"
|
||||
#include "botlib/l_libvar.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
//structure field offsets
|
||||
#define BBOX_OFS(x) offsetof(aas_bbox_t, x)
|
||||
#define CFG_OFS(x) offsetof(cfg_t, x)
|
||||
|
||||
//bounding box definition
|
||||
fielddef_t bbox_fields[] =
|
||||
{
|
||||
{"presencetype", BBOX_OFS(presencetype), FT_INT},
|
||||
{"flags", BBOX_OFS(flags), FT_INT},
|
||||
{"mins", BBOX_OFS(mins), FT_FLOAT|FT_ARRAY, 3},
|
||||
{"maxs", BBOX_OFS(maxs), FT_FLOAT|FT_ARRAY, 3},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
fielddef_t cfg_fields[] =
|
||||
{
|
||||
{"phys_gravitydirection", CFG_OFS(phys_gravitydirection), FT_FLOAT|FT_ARRAY, 3},
|
||||
{"phys_friction", CFG_OFS(phys_friction), FT_FLOAT},
|
||||
{"phys_stopspeed", CFG_OFS(phys_stopspeed), FT_FLOAT},
|
||||
{"phys_gravity", CFG_OFS(phys_gravity), FT_FLOAT},
|
||||
{"phys_waterfriction", CFG_OFS(phys_waterfriction), FT_FLOAT},
|
||||
{"phys_watergravity", CFG_OFS(phys_watergravity), FT_FLOAT},
|
||||
{"phys_maxvelocity", CFG_OFS(phys_maxvelocity), FT_FLOAT},
|
||||
{"phys_maxwalkvelocity", CFG_OFS(phys_maxwalkvelocity), FT_FLOAT},
|
||||
{"phys_maxcrouchvelocity", CFG_OFS(phys_maxcrouchvelocity), FT_FLOAT},
|
||||
{"phys_maxswimvelocity", CFG_OFS(phys_maxswimvelocity), FT_FLOAT},
|
||||
{"phys_walkaccelerate", CFG_OFS(phys_walkaccelerate), FT_FLOAT},
|
||||
{"phys_airaccelerate", CFG_OFS(phys_airaccelerate), FT_FLOAT},
|
||||
{"phys_swimaccelerate", CFG_OFS(phys_swimaccelerate), FT_FLOAT},
|
||||
{"phys_maxstep", CFG_OFS(phys_maxstep), FT_FLOAT},
|
||||
{"phys_maxsteepness", CFG_OFS(phys_maxsteepness), FT_FLOAT},
|
||||
{"phys_maxwaterjump", CFG_OFS(phys_maxwaterjump), FT_FLOAT},
|
||||
{"phys_maxbarrier", CFG_OFS(phys_maxbarrier), FT_FLOAT},
|
||||
{"phys_jumpvel", CFG_OFS(phys_jumpvel), FT_FLOAT},
|
||||
{"phys_falldelta5", CFG_OFS(phys_falldelta5), FT_FLOAT},
|
||||
{"phys_falldelta10", CFG_OFS(phys_falldelta10), FT_FLOAT},
|
||||
{"rs_waterjump", CFG_OFS(rs_waterjump), FT_FLOAT},
|
||||
{"rs_teleport", CFG_OFS(rs_teleport), FT_FLOAT},
|
||||
{"rs_barrierjump", CFG_OFS(rs_barrierjump), FT_FLOAT},
|
||||
{"rs_startcrouch", CFG_OFS(rs_startcrouch), FT_FLOAT},
|
||||
{"rs_startgrapple", CFG_OFS(rs_startgrapple), FT_FLOAT},
|
||||
{"rs_startwalkoffledge", CFG_OFS(rs_startwalkoffledge), FT_FLOAT},
|
||||
{"rs_startjump", CFG_OFS(rs_startjump), FT_FLOAT},
|
||||
{"rs_rocketjump", CFG_OFS(rs_rocketjump), FT_FLOAT},
|
||||
{"rs_bfgjump", CFG_OFS(rs_bfgjump), FT_FLOAT},
|
||||
{"rs_jumppad", CFG_OFS(rs_jumppad), FT_FLOAT},
|
||||
{"rs_aircontrolledjumppad", CFG_OFS(rs_aircontrolledjumppad), FT_FLOAT},
|
||||
{"rs_funcbob", CFG_OFS(rs_funcbob), FT_FLOAT},
|
||||
{"rs_startelevator", CFG_OFS(rs_startelevator), FT_FLOAT},
|
||||
{"rs_falldamage5", CFG_OFS(rs_falldamage5), FT_FLOAT},
|
||||
{"rs_falldamage10", CFG_OFS(rs_falldamage10), FT_FLOAT},
|
||||
{"rs_maxjumpfallheight", CFG_OFS(rs_maxjumpfallheight), FT_FLOAT},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
structdef_t bbox_struct =
|
||||
{
|
||||
sizeof(aas_bbox_t), bbox_fields
|
||||
};
|
||||
structdef_t cfg_struct =
|
||||
{
|
||||
sizeof(cfg_t), cfg_fields
|
||||
};
|
||||
|
||||
//global cfg
|
||||
cfg_t cfg;
|
||||
|
||||
//===========================================================================
|
||||
// the default Q3A configuration
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void DefaultCfg(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
// default all float values to infinite
|
||||
for (i = 0; cfg_fields[i].name; i++)
|
||||
{
|
||||
if ((cfg_fields[i].type & FT_TYPE) == FT_FLOAT)
|
||||
*(float *)( ((char*)&cfg) + cfg_fields[i].offset ) = FLT_MAX;
|
||||
} //end for
|
||||
//
|
||||
cfg.numbboxes = 2;
|
||||
//bbox 0
|
||||
cfg.bboxes[0].presencetype = PRESENCE_NORMAL;
|
||||
cfg.bboxes[0].flags = 0;
|
||||
cfg.bboxes[0].mins[0] = -15;
|
||||
cfg.bboxes[0].mins[1] = -15;
|
||||
cfg.bboxes[0].mins[2] = -24;
|
||||
cfg.bboxes[0].maxs[0] = 15;
|
||||
cfg.bboxes[0].maxs[1] = 15;
|
||||
cfg.bboxes[0].maxs[2] = 32;
|
||||
//bbox 1
|
||||
cfg.bboxes[1].presencetype = PRESENCE_CROUCH;
|
||||
cfg.bboxes[1].flags = 1;
|
||||
cfg.bboxes[1].mins[0] = -15;
|
||||
cfg.bboxes[1].mins[1] = -15;
|
||||
cfg.bboxes[1].mins[2] = -24;
|
||||
cfg.bboxes[1].maxs[0] = 15;
|
||||
cfg.bboxes[1].maxs[1] = 15;
|
||||
cfg.bboxes[1].maxs[2] = 16;
|
||||
//
|
||||
cfg.allpresencetypes = PRESENCE_NORMAL|PRESENCE_CROUCH;
|
||||
cfg.phys_gravitydirection[0] = 0;
|
||||
cfg.phys_gravitydirection[1] = 0;
|
||||
cfg.phys_gravitydirection[2] = -1;
|
||||
cfg.phys_maxsteepness = 0.7;
|
||||
} //end of the function DefaultCfg
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
char * QDECL va( char *format, ... )
|
||||
{
|
||||
va_list argptr;
|
||||
static char string[2][32000]; // in case va is called by nested functions
|
||||
static int index = 0;
|
||||
char *buf;
|
||||
|
||||
buf = string[index & 1];
|
||||
index++;
|
||||
|
||||
va_start (argptr, format);
|
||||
vsprintf (buf, format,argptr);
|
||||
va_end (argptr);
|
||||
|
||||
return buf;
|
||||
} //end of the function va
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void SetCfgLibVars(void)
|
||||
{
|
||||
int i;
|
||||
float value;
|
||||
|
||||
for (i = 0; cfg_fields[i].name; i++)
|
||||
{
|
||||
if ((cfg_fields[i].type & FT_TYPE) == FT_FLOAT)
|
||||
{
|
||||
value = *(float *)(((char*)&cfg) + cfg_fields[i].offset);
|
||||
if (value != FLT_MAX)
|
||||
{
|
||||
LibVarSet(cfg_fields[i].name, va("%f", value));
|
||||
} //end if
|
||||
} //end if
|
||||
} //end for
|
||||
} //end of the function SetCfgLibVars
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int LoadCfgFile(char *filename)
|
||||
{
|
||||
source_t *source;
|
||||
token_t token;
|
||||
int settingsdefined;
|
||||
|
||||
source = LoadSourceFile(filename);
|
||||
if (!source)
|
||||
{
|
||||
Log_Print("couldn't open cfg file %s\n", filename);
|
||||
return false;
|
||||
} //end if
|
||||
|
||||
settingsdefined = false;
|
||||
memset(&cfg, 0, sizeof(cfg_t));
|
||||
|
||||
while(PC_ReadToken(source, &token))
|
||||
{
|
||||
if (!stricmp(token.string, "bbox"))
|
||||
{
|
||||
if (cfg.numbboxes >= AAS_MAX_BBOXES)
|
||||
{
|
||||
SourceError(source, "too many bounding box volumes defined");
|
||||
} //end if
|
||||
if (!ReadStructure(source, &bbox_struct, (char *) &cfg.bboxes[cfg.numbboxes]))
|
||||
{
|
||||
FreeSource(source);
|
||||
return false;
|
||||
} //end if
|
||||
cfg.allpresencetypes |= cfg.bboxes[cfg.numbboxes].presencetype;
|
||||
cfg.numbboxes++;
|
||||
} //end if
|
||||
else if (!stricmp(token.string, "settings"))
|
||||
{
|
||||
if (settingsdefined)
|
||||
{
|
||||
SourceWarning(source, "settings already defined\n");
|
||||
} //end if
|
||||
settingsdefined = true;
|
||||
if (!ReadStructure(source, &cfg_struct, (char *) &cfg))
|
||||
{
|
||||
FreeSource(source);
|
||||
return false;
|
||||
} //end if
|
||||
} //end else if
|
||||
} //end while
|
||||
if (VectorLength(cfg.phys_gravitydirection) < 0.9 || VectorLength(cfg.phys_gravitydirection) > 1.1)
|
||||
{
|
||||
SourceError(source, "invalid gravity direction specified");
|
||||
} //end if
|
||||
if (cfg.numbboxes <= 0)
|
||||
{
|
||||
SourceError(source, "no bounding volumes specified");
|
||||
} //end if
|
||||
FreeSource(source);
|
||||
SetCfgLibVars();
|
||||
Log_Print("using cfg file %s\n", filename);
|
||||
return true;
|
||||
} //end of the function LoadCfgFile
|
77
tools/quake3/bspc/aas_cfg.h
Normal file
77
tools/quake3/bspc/aas_cfg.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#define BBOXFL_GROUNDED 1 //bounding box only valid when on ground
|
||||
#define BBOXFL_NOTGROUNDED 2 //bounding box only valid when NOT on ground
|
||||
|
||||
#ifndef FLT_MAX
|
||||
#define FLT_MAX 3.402823466e+38F
|
||||
#endif
|
||||
|
||||
typedef struct cfg_s
|
||||
{
|
||||
int numbboxes; //number of bounding boxes
|
||||
aas_bbox_t bboxes[AAS_MAX_BBOXES]; //all the bounding boxes
|
||||
int allpresencetypes; //or of all presence types
|
||||
// aas settings
|
||||
vec3_t phys_gravitydirection;
|
||||
float phys_friction;
|
||||
float phys_stopspeed;
|
||||
float phys_gravity;
|
||||
float phys_waterfriction;
|
||||
float phys_watergravity;
|
||||
float phys_maxvelocity;
|
||||
float phys_maxwalkvelocity;
|
||||
float phys_maxcrouchvelocity;
|
||||
float phys_maxswimvelocity;
|
||||
float phys_walkaccelerate;
|
||||
float phys_airaccelerate;
|
||||
float phys_swimaccelerate;
|
||||
float phys_maxstep;
|
||||
float phys_maxsteepness;
|
||||
float phys_maxwaterjump;
|
||||
float phys_maxbarrier;
|
||||
float phys_jumpvel;
|
||||
float phys_falldelta5;
|
||||
float phys_falldelta10;
|
||||
float rs_waterjump;
|
||||
float rs_teleport;
|
||||
float rs_barrierjump;
|
||||
float rs_startcrouch;
|
||||
float rs_startgrapple;
|
||||
float rs_startwalkoffledge;
|
||||
float rs_startjump;
|
||||
float rs_rocketjump;
|
||||
float rs_bfgjump;
|
||||
float rs_jumppad;
|
||||
float rs_aircontrolledjumppad;
|
||||
float rs_funcbob;
|
||||
float rs_startelevator;
|
||||
float rs_falldamage5;
|
||||
float rs_falldamage10;
|
||||
float rs_maxjumpfallheight;
|
||||
} cfg_t;
|
||||
|
||||
extern cfg_t cfg;
|
||||
|
||||
void DefaultCfg(void);
|
||||
int LoadCfgFile(char *filename);
|
1141
tools/quake3/bspc/aas_create.c
Normal file
1141
tools/quake3/bspc/aas_create.c
Normal file
File diff suppressed because it is too large
Load diff
136
tools/quake3/bspc/aas_create.h
Normal file
136
tools/quake3/bspc/aas_create.h
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#define AREA_PORTAL 1
|
||||
|
||||
//temporary AAS face
|
||||
typedef struct tmp_face_s
|
||||
{
|
||||
int num; //face number
|
||||
int planenum; //number of the plane the face is in
|
||||
winding_t *winding; //winding of the face
|
||||
struct tmp_area_s *frontarea; //area at the front of the face
|
||||
struct tmp_area_s *backarea; //area at the back of the face
|
||||
int faceflags; //flags of this face
|
||||
int aasfacenum; //the number of the aas face used for this face
|
||||
//double link list pointers for front and back area
|
||||
struct tmp_face_s *prev[2], *next[2];
|
||||
//links in the list with faces
|
||||
struct tmp_face_s *l_prev, *l_next;
|
||||
} tmp_face_t;
|
||||
|
||||
//temporary AAS area settings
|
||||
typedef struct tmp_areasettings_s
|
||||
{
|
||||
//could also add all kind of statistic fields
|
||||
int contents; //contents of the area
|
||||
int modelnum; //bsp model inside this area
|
||||
int areaflags; //area flags
|
||||
int presencetype; //how a bot can be present in this area
|
||||
int numreachableareas; //number of reachable areas from this one
|
||||
int firstreachablearea; //first reachable area in the reachable area index
|
||||
} tmp_areasettings_t;
|
||||
|
||||
//temporary AAS area
|
||||
typedef struct tmp_area_s
|
||||
{
|
||||
int areanum; //number of the area
|
||||
struct tmp_face_s *tmpfaces; //the faces of the area
|
||||
int presencetype; //presence type of the area
|
||||
int contents; //area contents
|
||||
int modelnum; //bsp model inside this area
|
||||
int invalid; //true if the area is invalid
|
||||
tmp_areasettings_t *settings; //area settings
|
||||
struct tmp_area_s *mergedarea; //points to the new area after merging
|
||||
//when mergedarea != 0 the area has only the
|
||||
//seperating face of the merged areas
|
||||
int aasareanum; //number of the aas area created for this tmp area
|
||||
//links in the list with areas
|
||||
struct tmp_area_s *l_prev, *l_next;
|
||||
} tmp_area_t;
|
||||
|
||||
//temporary AAS node
|
||||
typedef struct tmp_node_s
|
||||
{
|
||||
int planenum; //node plane number
|
||||
struct tmp_area_s *tmparea; //points to an area if this node is an area
|
||||
struct tmp_node_s *children[2]; //child nodes of this node
|
||||
} tmp_node_t;
|
||||
|
||||
#define NODEBUF_SIZE 128
|
||||
//node buffer
|
||||
typedef struct tmp_nodebuf_s
|
||||
{
|
||||
int numnodes;
|
||||
struct tmp_nodebuf_s *next;
|
||||
tmp_node_t nodes[NODEBUF_SIZE];
|
||||
} tmp_nodebuf_t;
|
||||
|
||||
//the whole temorary AAS
|
||||
typedef struct tmp_aas_s
|
||||
{
|
||||
//faces
|
||||
int numfaces;
|
||||
int facenum;
|
||||
tmp_face_t *faces;
|
||||
//areas
|
||||
int numareas;
|
||||
int areanum;
|
||||
tmp_area_t *areas;
|
||||
//area settings
|
||||
int numareasettings;
|
||||
tmp_areasettings_t *areasettings;
|
||||
//nodes
|
||||
int numnodes;
|
||||
tmp_node_t *nodes;
|
||||
//node buffer
|
||||
tmp_nodebuf_t *nodebuffer;
|
||||
} tmp_aas_t;
|
||||
|
||||
extern tmp_aas_t tmpaasworld;
|
||||
|
||||
//creates a .AAS file with the given name from an already loaded map
|
||||
void AAS_Create(char *aasfile);
|
||||
//adds a face side to an area
|
||||
void AAS_AddFaceSideToArea(tmp_face_t *tmpface, int side, tmp_area_t *tmparea);
|
||||
//remvoes a face from an area
|
||||
void AAS_RemoveFaceFromArea(tmp_face_t *tmpface, tmp_area_t *tmparea);
|
||||
//allocate a tmp face
|
||||
tmp_face_t *AAS_AllocTmpFace(void);
|
||||
//free the tmp face
|
||||
void AAS_FreeTmpFace(tmp_face_t *tmpface);
|
||||
//allocate a tmp area
|
||||
tmp_area_t *AAS_AllocTmpArea(void);
|
||||
//free a tmp area
|
||||
void AAS_FreeTmpArea(tmp_area_t *tmparea);
|
||||
//allocate a tmp node
|
||||
tmp_node_t *AAS_AllocTmpNode(void);
|
||||
//free a tmp node
|
||||
void AAS_FreeTmpNode(tmp_node_t *node);
|
||||
//checks if an area is ok
|
||||
void AAS_CheckArea(tmp_area_t *tmparea);
|
||||
//flips the area faces where needed
|
||||
void AAS_FlipAreaFaces(tmp_area_t *tmparea);
|
||||
//returns true if the face is a gap seen from the given side
|
||||
int AAS_GapFace(tmp_face_t *tmpface, int side);
|
||||
//returns true if the face is a ground face
|
||||
int AAS_GroundFace(tmp_face_t *tmpface);
|
108
tools/quake3/bspc/aas_edgemelting.c
Normal file
108
tools/quake3/bspc/aas_edgemelting.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "qbsp.h"
|
||||
#include "botlib/aasfile.h"
|
||||
#include "aas_create.h"
|
||||
|
||||
//===========================================================================
|
||||
// try to melt the windings of the two faces
|
||||
// FIXME: this is buggy
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_MeltFaceWinding(tmp_face_t *face1, tmp_face_t *face2)
|
||||
{
|
||||
int i, n;
|
||||
int splits = 0;
|
||||
winding_t *w2, *neww;
|
||||
plane_t *plane1;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!face1->winding) Error("face1 %d without winding", face1->num);
|
||||
if (!face2->winding) Error("face2 %d without winding", face2->num);
|
||||
#endif //DEBUG
|
||||
w2 = face2->winding;
|
||||
plane1 = &mapplanes[face1->planenum];
|
||||
for (i = 0; i < w2->numpoints; i++)
|
||||
{
|
||||
if (PointOnWinding(face1->winding, plane1->normal, plane1->dist, w2->p[i], &n))
|
||||
{
|
||||
neww = AddWindingPoint(face1->winding, w2->p[i], n);
|
||||
FreeWinding(face1->winding);
|
||||
face1->winding = neww;
|
||||
|
||||
splits++;
|
||||
} //end if
|
||||
} //end for
|
||||
return splits;
|
||||
} //end of the function AAS_MeltFaceWinding
|
||||
//===========================================================================
|
||||
// melt the windings of the area faces
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_MeltFaceWindingsOfArea(tmp_area_t *tmparea)
|
||||
{
|
||||
int side1, side2, num_windingsplits = 0;
|
||||
tmp_face_t *face1, *face2;
|
||||
|
||||
for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
|
||||
{
|
||||
side1 = face1->frontarea != tmparea;
|
||||
for (face2 = tmparea->tmpfaces; face2; face2 = face2->next[side2])
|
||||
{
|
||||
side2 = face2->frontarea != tmparea;
|
||||
if (face1 == face2) continue;
|
||||
num_windingsplits += AAS_MeltFaceWinding(face1, face2);
|
||||
} //end for
|
||||
} //end for
|
||||
return num_windingsplits;
|
||||
} //end of the function AAS_MeltFaceWindingsOfArea
|
||||
//===========================================================================
|
||||
// melt the windings of the faces of all areas
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_MeltAreaFaceWindings(void)
|
||||
{
|
||||
tmp_area_t *tmparea;
|
||||
int num_windingsplits = 0;
|
||||
|
||||
Log_Write("AAS_MeltAreaFaceWindings\r\n");
|
||||
qprintf("%6d edges melted", num_windingsplits);
|
||||
//NOTE: first convex area (zero) is a dummy
|
||||
for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
|
||||
{
|
||||
num_windingsplits += AAS_MeltFaceWindingsOfArea(tmparea);
|
||||
qprintf("\r%6d", num_windingsplits);
|
||||
} //end for
|
||||
qprintf("\n");
|
||||
Log_Write("%6d edges melted\r\n", num_windingsplits);
|
||||
} //end of the function AAS_MeltAreaFaceWindings
|
||||
|
24
tools/quake3/bspc/aas_edgemelting.h
Normal file
24
tools/quake3/bspc/aas_edgemelting.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
void AAS_MeltAreaFaceWindings(void);
|
||||
|
282
tools/quake3/bspc/aas_facemerging.c
Normal file
282
tools/quake3/bspc/aas_facemerging.c
Normal file
|
@ -0,0 +1,282 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "qbsp.h"
|
||||
#include "botlib/aasfile.h"
|
||||
#include "aas_create.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_TryMergeFaces(tmp_face_t *face1, tmp_face_t *face2)
|
||||
{
|
||||
winding_t *neww;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!face1->winding) Error("face1 %d without winding", face1->num);
|
||||
if (!face2->winding) Error("face2 %d without winding", face2->num);
|
||||
#endif //DEBUG
|
||||
//
|
||||
if (face1->faceflags != face2->faceflags) return false;
|
||||
//NOTE: if the front or back area is zero this doesn't mean there's
|
||||
//a real area. It means there's solid at that side of the face
|
||||
//if both faces have the same front area
|
||||
if (face1->frontarea == face2->frontarea)
|
||||
{
|
||||
//if both faces have the same back area
|
||||
if (face1->backarea == face2->backarea)
|
||||
{
|
||||
//if the faces are in the same plane
|
||||
if (face1->planenum == face2->planenum)
|
||||
{
|
||||
//if they have both a front and a back area (no solid on either side)
|
||||
if (face1->frontarea && face1->backarea)
|
||||
{
|
||||
neww = MergeWindings(face1->winding, face2->winding,
|
||||
mapplanes[face1->planenum].normal);
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
//this function is to be found in l_poly.c
|
||||
neww = TryMergeWinding(face1->winding, face2->winding,
|
||||
mapplanes[face1->planenum].normal);
|
||||
} //end else
|
||||
if (neww)
|
||||
{
|
||||
FreeWinding(face1->winding);
|
||||
face1->winding = neww;
|
||||
if (face2->frontarea) AAS_RemoveFaceFromArea(face2, face2->frontarea);
|
||||
if (face2->backarea) AAS_RemoveFaceFromArea(face2, face2->backarea);
|
||||
AAS_FreeTmpFace(face2);
|
||||
return true;
|
||||
} //end if
|
||||
} //end if
|
||||
else if ((face1->planenum & ~1) == (face2->planenum & ~1))
|
||||
{
|
||||
Log_Write("face %d and %d, same front and back area but flipped planes\r\n",
|
||||
face1->num, face2->num);
|
||||
} //end if
|
||||
} //end if
|
||||
} //end if
|
||||
return false;
|
||||
} //end of the function AAS_TryMergeFaces
|
||||
/*
|
||||
int AAS_TryMergeFaces(tmp_face_t *face1, tmp_face_t *face2)
|
||||
{
|
||||
winding_t *neww;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!face1->winding) Error("face1 %d without winding", face1->num);
|
||||
if (!face2->winding) Error("face2 %d without winding", face2->num);
|
||||
#endif //DEBUG
|
||||
//if the faces are in the same plane
|
||||
if ((face1->planenum & ~1) != (face2->planenum & ~1)) return false;
|
||||
// if (face1->planenum != face2->planenum) return false;
|
||||
//NOTE: if the front or back area is zero this doesn't mean there's
|
||||
//a real area. It means there's solid at that side of the face
|
||||
//if both faces have the same front area
|
||||
if (face1->frontarea != face2->frontarea ||
|
||||
face1->backarea != face2->backarea)
|
||||
{
|
||||
if (!face1->frontarea || !face1->backarea ||
|
||||
!face2->frontarea || !face2->backarea) return false;
|
||||
else if (face1->frontarea != face2->backarea ||
|
||||
face1->backarea != face2->frontarea) return false;
|
||||
// return false;
|
||||
} //end if
|
||||
//this function is to be found in l_poly.c
|
||||
neww = TryMergeWinding(face1->winding, face2->winding,
|
||||
mapplanes[face1->planenum].normal);
|
||||
if (!neww) return false;
|
||||
//
|
||||
FreeWinding(face1->winding);
|
||||
face1->winding = neww;
|
||||
//remove face2
|
||||
if (face2->frontarea)
|
||||
AAS_RemoveFaceFromArea(face2, &tmpaasworld.areas[face2->frontarea]);
|
||||
if (face2->backarea)
|
||||
AAS_RemoveFaceFromArea(face2, &tmpaasworld.areas[face2->backarea]);
|
||||
return true;
|
||||
} //end of the function AAS_TryMergeFaces*/
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_MergeAreaFaces(void)
|
||||
{
|
||||
int num_facemerges = 0;
|
||||
int side1, side2, restart;
|
||||
tmp_area_t *tmparea, *lasttmparea;
|
||||
tmp_face_t *face1, *face2;
|
||||
|
||||
Log_Write("AAS_MergeAreaFaces\r\n");
|
||||
qprintf("%6d face merges", num_facemerges);
|
||||
//NOTE: first convex area is a dummy
|
||||
lasttmparea = tmpaasworld.areas;
|
||||
for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
|
||||
{
|
||||
restart = false;
|
||||
//
|
||||
if (tmparea->invalid) continue;
|
||||
//
|
||||
for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
|
||||
{
|
||||
side1 = face1->frontarea != tmparea;
|
||||
for (face2 = face1->next[side1]; face2; face2 = face2->next[side2])
|
||||
{
|
||||
side2 = face2->frontarea != tmparea;
|
||||
//if succesfully merged
|
||||
if (AAS_TryMergeFaces(face1, face2))
|
||||
{
|
||||
//start over again after merging two faces
|
||||
restart = true;
|
||||
num_facemerges++;
|
||||
qprintf("\r%6d", num_facemerges);
|
||||
AAS_CheckArea(tmparea);
|
||||
break;
|
||||
} //end if
|
||||
} //end for
|
||||
if (restart)
|
||||
{
|
||||
tmparea = lasttmparea;
|
||||
break;
|
||||
} //end if
|
||||
} //end for
|
||||
lasttmparea = tmparea;
|
||||
} //end for
|
||||
qprintf("\n");
|
||||
Log_Write("%6d face merges\r\n", num_facemerges);
|
||||
} //end of the function AAS_MergeAreaFaces
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_MergePlaneFaces(tmp_area_t *tmparea, int planenum)
|
||||
{
|
||||
tmp_face_t *face1, *face2, *nextface2;
|
||||
winding_t *neww;
|
||||
int side1, side2;
|
||||
|
||||
for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
|
||||
{
|
||||
side1 = face1->frontarea != tmparea;
|
||||
if (face1->planenum != planenum) continue;
|
||||
//
|
||||
for (face2 = face1->next[side1]; face2; face2 = nextface2)
|
||||
{
|
||||
side2 = face2->frontarea != tmparea;
|
||||
nextface2 = face2->next[side2];
|
||||
//
|
||||
if ((face2->planenum & ~1) != (planenum & ~1)) continue;
|
||||
//
|
||||
neww = MergeWindings(face1->winding, face2->winding,
|
||||
mapplanes[face1->planenum].normal);
|
||||
FreeWinding(face1->winding);
|
||||
face1->winding = neww;
|
||||
if (face2->frontarea) AAS_RemoveFaceFromArea(face2, face2->frontarea);
|
||||
if (face2->backarea) AAS_RemoveFaceFromArea(face2, face2->backarea);
|
||||
AAS_FreeTmpFace(face2);
|
||||
//
|
||||
nextface2 = face1->next[side1];
|
||||
} //end for
|
||||
} //end for
|
||||
} //end of the function AAS_MergePlaneFaces
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_CanMergePlaneFaces(tmp_area_t *tmparea, int planenum)
|
||||
{
|
||||
tmp_area_t *frontarea, *backarea;
|
||||
tmp_face_t *face1;
|
||||
int side1, merge, faceflags;
|
||||
|
||||
frontarea = backarea = NULL;
|
||||
merge = false;
|
||||
for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
|
||||
{
|
||||
side1 = face1->frontarea != tmparea;
|
||||
if ((face1->planenum & ~1) != (planenum & ~1)) continue;
|
||||
if (!frontarea && !backarea)
|
||||
{
|
||||
frontarea = face1->frontarea;
|
||||
backarea = face1->backarea;
|
||||
faceflags = face1->faceflags;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if (frontarea != face1->frontarea) return false;
|
||||
if (backarea != face1->backarea) return false;
|
||||
if (faceflags != face1->faceflags) return false;
|
||||
merge = true;
|
||||
} //end else
|
||||
} //end for
|
||||
return merge;
|
||||
} //end of the function AAS_CanMergePlaneFaces
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_MergeAreaPlaneFaces(void)
|
||||
{
|
||||
int num_facemerges = 0;
|
||||
int side1;
|
||||
tmp_area_t *tmparea, *nexttmparea;
|
||||
tmp_face_t *face1;
|
||||
|
||||
Log_Write("AAS_MergePlaneFaces\r\n");
|
||||
qprintf("%6d plane face merges", num_facemerges);
|
||||
//NOTE: first convex area is a dummy
|
||||
for (tmparea = tmpaasworld.areas; tmparea; tmparea = nexttmparea)
|
||||
{
|
||||
nexttmparea = tmparea->l_next;
|
||||
//
|
||||
if (tmparea->invalid) continue;
|
||||
//
|
||||
for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
|
||||
{
|
||||
side1 = face1->frontarea != tmparea;
|
||||
//
|
||||
if (AAS_CanMergePlaneFaces(tmparea, face1->planenum))
|
||||
{
|
||||
AAS_MergePlaneFaces(tmparea, face1->planenum);
|
||||
nexttmparea = tmparea;
|
||||
num_facemerges++;
|
||||
qprintf("\r%6d", num_facemerges);
|
||||
break;
|
||||
} //end if
|
||||
} //end for
|
||||
} //end for
|
||||
qprintf("\n");
|
||||
Log_Write("%6d plane face merges\r\n", num_facemerges);
|
||||
} //end of the function AAS_MergeAreaPlaneFaces
|
24
tools/quake3/bspc/aas_facemerging.h
Normal file
24
tools/quake3/bspc/aas_facemerging.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
void AAS_MergeAreaFaces(void);
|
||||
void AAS_MergeAreaPlaneFaces(void);
|
549
tools/quake3/bspc/aas_file.c
Normal file
549
tools/quake3/bspc/aas_file.c
Normal file
|
@ -0,0 +1,549 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "qbsp.h"
|
||||
#include "botlib/aasfile.h"
|
||||
#include "aas_file.h"
|
||||
#include "aas_store.h"
|
||||
#include "aas_create.h"
|
||||
|
||||
#define AAS_Error Error
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_SwapAASData(void)
|
||||
{
|
||||
int i, j;
|
||||
//bounding boxes
|
||||
for (i = 0; i < aasworld.numbboxes; i++)
|
||||
{
|
||||
aasworld.bboxes[i].presencetype = LittleLong(aasworld.bboxes[i].presencetype);
|
||||
aasworld.bboxes[i].flags = LittleLong(aasworld.bboxes[i].flags);
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
aasworld.bboxes[i].mins[j] = LittleLong(aasworld.bboxes[i].mins[j]);
|
||||
aasworld.bboxes[i].maxs[j] = LittleLong(aasworld.bboxes[i].maxs[j]);
|
||||
} //end for
|
||||
} //end for
|
||||
//vertexes
|
||||
for (i = 0; i < aasworld.numvertexes; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
aasworld.vertexes[i][j] = LittleFloat(aasworld.vertexes[i][j]);
|
||||
} //end for
|
||||
//planes
|
||||
for (i = 0; i < aasworld.numplanes; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
aasworld.planes[i].normal[j] = LittleFloat(aasworld.planes[i].normal[j]);
|
||||
aasworld.planes[i].dist = LittleFloat(aasworld.planes[i].dist);
|
||||
aasworld.planes[i].type = LittleLong(aasworld.planes[i].type);
|
||||
} //end for
|
||||
//edges
|
||||
for (i = 0; i < aasworld.numedges; i++)
|
||||
{
|
||||
aasworld.edges[i].v[0] = LittleLong(aasworld.edges[i].v[0]);
|
||||
aasworld.edges[i].v[1] = LittleLong(aasworld.edges[i].v[1]);
|
||||
} //end for
|
||||
//edgeindex
|
||||
for (i = 0; i < aasworld.edgeindexsize; i++)
|
||||
{
|
||||
aasworld.edgeindex[i] = LittleLong(aasworld.edgeindex[i]);
|
||||
} //end for
|
||||
//faces
|
||||
for (i = 0; i < aasworld.numfaces; i++)
|
||||
{
|
||||
aasworld.faces[i].planenum = LittleLong(aasworld.faces[i].planenum);
|
||||
aasworld.faces[i].faceflags = LittleLong(aasworld.faces[i].faceflags);
|
||||
aasworld.faces[i].numedges = LittleLong(aasworld.faces[i].numedges);
|
||||
aasworld.faces[i].firstedge = LittleLong(aasworld.faces[i].firstedge);
|
||||
aasworld.faces[i].frontarea = LittleLong(aasworld.faces[i].frontarea);
|
||||
aasworld.faces[i].backarea = LittleLong(aasworld.faces[i].backarea);
|
||||
} //end for
|
||||
//face index
|
||||
for (i = 0; i < aasworld.faceindexsize; i++)
|
||||
{
|
||||
aasworld.faceindex[i] = LittleLong(aasworld.faceindex[i]);
|
||||
} //end for
|
||||
//convex areas
|
||||
for (i = 0; i < aasworld.numareas; i++)
|
||||
{
|
||||
aasworld.areas[i].areanum = LittleLong(aasworld.areas[i].areanum);
|
||||
aasworld.areas[i].numfaces = LittleLong(aasworld.areas[i].numfaces);
|
||||
aasworld.areas[i].firstface = LittleLong(aasworld.areas[i].firstface);
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
aasworld.areas[i].mins[j] = LittleFloat(aasworld.areas[i].mins[j]);
|
||||
aasworld.areas[i].maxs[j] = LittleFloat(aasworld.areas[i].maxs[j]);
|
||||
aasworld.areas[i].center[j] = LittleFloat(aasworld.areas[i].center[j]);
|
||||
} //end for
|
||||
} //end for
|
||||
//area settings
|
||||
for (i = 0; i < aasworld.numareasettings; i++)
|
||||
{
|
||||
aasworld.areasettings[i].contents = LittleLong(aasworld.areasettings[i].contents);
|
||||
aasworld.areasettings[i].areaflags = LittleLong(aasworld.areasettings[i].areaflags);
|
||||
aasworld.areasettings[i].presencetype = LittleLong(aasworld.areasettings[i].presencetype);
|
||||
aasworld.areasettings[i].cluster = LittleLong(aasworld.areasettings[i].cluster);
|
||||
aasworld.areasettings[i].clusterareanum = LittleLong(aasworld.areasettings[i].clusterareanum);
|
||||
aasworld.areasettings[i].numreachableareas = LittleLong(aasworld.areasettings[i].numreachableareas);
|
||||
aasworld.areasettings[i].firstreachablearea = LittleLong(aasworld.areasettings[i].firstreachablearea);
|
||||
} //end for
|
||||
//area reachability
|
||||
for (i = 0; i < aasworld.reachabilitysize; i++)
|
||||
{
|
||||
aasworld.reachability[i].areanum = LittleLong(aasworld.reachability[i].areanum);
|
||||
aasworld.reachability[i].facenum = LittleLong(aasworld.reachability[i].facenum);
|
||||
aasworld.reachability[i].edgenum = LittleLong(aasworld.reachability[i].edgenum);
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
aasworld.reachability[i].start[j] = LittleFloat(aasworld.reachability[i].start[j]);
|
||||
aasworld.reachability[i].end[j] = LittleFloat(aasworld.reachability[i].end[j]);
|
||||
} //end for
|
||||
aasworld.reachability[i].traveltype = LittleLong(aasworld.reachability[i].traveltype);
|
||||
aasworld.reachability[i].traveltime = LittleShort(aasworld.reachability[i].traveltime);
|
||||
} //end for
|
||||
//nodes
|
||||
for (i = 0; i < aasworld.numnodes; i++)
|
||||
{
|
||||
aasworld.nodes[i].planenum = LittleLong(aasworld.nodes[i].planenum);
|
||||
aasworld.nodes[i].children[0] = LittleLong(aasworld.nodes[i].children[0]);
|
||||
aasworld.nodes[i].children[1] = LittleLong(aasworld.nodes[i].children[1]);
|
||||
} //end for
|
||||
//cluster portals
|
||||
for (i = 0; i < aasworld.numportals; i++)
|
||||
{
|
||||
aasworld.portals[i].areanum = LittleLong(aasworld.portals[i].areanum);
|
||||
aasworld.portals[i].frontcluster = LittleLong(aasworld.portals[i].frontcluster);
|
||||
aasworld.portals[i].backcluster = LittleLong(aasworld.portals[i].backcluster);
|
||||
aasworld.portals[i].clusterareanum[0] = LittleLong(aasworld.portals[i].clusterareanum[0]);
|
||||
aasworld.portals[i].clusterareanum[1] = LittleLong(aasworld.portals[i].clusterareanum[1]);
|
||||
} //end for
|
||||
//cluster portal index
|
||||
for (i = 0; i < aasworld.portalindexsize; i++)
|
||||
{
|
||||
aasworld.portalindex[i] = LittleLong(aasworld.portalindex[i]);
|
||||
} //end for
|
||||
//cluster
|
||||
for (i = 0; i < aasworld.numclusters; i++)
|
||||
{
|
||||
aasworld.clusters[i].numareas = LittleLong(aasworld.clusters[i].numareas);
|
||||
aasworld.clusters[i].numportals = LittleLong(aasworld.clusters[i].numportals);
|
||||
aasworld.clusters[i].firstportal = LittleLong(aasworld.clusters[i].firstportal);
|
||||
} //end for
|
||||
} //end of the function AAS_SwapAASData
|
||||
//===========================================================================
|
||||
// dump the current loaded aas file
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_DumpAASData(void)
|
||||
{
|
||||
/*
|
||||
if (aasworld.vertexes) FreeMemory(aasworld.vertexes);
|
||||
aasworld.vertexes = NULL;
|
||||
if (aasworld.planes) FreeMemory(aasworld.planes);
|
||||
aasworld.planes = NULL;
|
||||
if (aasworld.edges) FreeMemory(aasworld.edges);
|
||||
aasworld.edges = NULL;
|
||||
if (aasworld.edgeindex) FreeMemory(aasworld.edgeindex);
|
||||
aasworld.edgeindex = NULL;
|
||||
if (aasworld.faces) FreeMemory(aasworld.faces);
|
||||
aasworld.faces = NULL;
|
||||
if (aasworld.faceindex) FreeMemory(aasworld.faceindex);
|
||||
aasworld.faceindex = NULL;
|
||||
if (aasworld.areas) FreeMemory(aasworld.areas);
|
||||
aasworld.areas = NULL;
|
||||
if (aasworld.areasettings) FreeMemory(aasworld.areasettings);
|
||||
aasworld.areasettings = NULL;
|
||||
if (aasworld.reachability) FreeMemory(aasworld.reachability);
|
||||
aasworld.reachability = NULL;
|
||||
*/
|
||||
aasworld.loaded = false;
|
||||
} //end of the function AAS_DumpAASData
|
||||
//===========================================================================
|
||||
// allocate memory and read a lump of a AAS file
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
char *AAS_LoadAASLump(FILE *fp, int offset, int length, void *buf)
|
||||
{
|
||||
if (!length)
|
||||
{
|
||||
printf("lump size 0\n");
|
||||
return buf;
|
||||
} //end if
|
||||
//seek to the data
|
||||
if (fseek(fp, offset, SEEK_SET))
|
||||
{
|
||||
AAS_Error("can't seek to lump\n");
|
||||
AAS_DumpAASData();
|
||||
fclose(fp);
|
||||
return 0;
|
||||
} //end if
|
||||
//allocate memory
|
||||
if (!buf) buf = (void *) GetClearedMemory(length);
|
||||
//read the data
|
||||
if (fread((char *) buf, 1, length, fp) != length)
|
||||
{
|
||||
AAS_Error("can't read lump\n");
|
||||
FreeMemory(buf);
|
||||
AAS_DumpAASData();
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
} //end if
|
||||
return buf;
|
||||
} //end of the function AAS_LoadAASLump
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_DData(unsigned char *data, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
data[i] ^= (unsigned char) i * 119;
|
||||
} //end for
|
||||
} //end of the function AAS_DData
|
||||
//===========================================================================
|
||||
// load an aas file
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean AAS_LoadAASFile(char *filename, int fpoffset, int fplength)
|
||||
{
|
||||
FILE *fp;
|
||||
aas_header_t header;
|
||||
int offset, length;
|
||||
|
||||
//dump current loaded aas file
|
||||
AAS_DumpAASData();
|
||||
//open the file
|
||||
fp = fopen(filename, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
AAS_Error("can't open %s\n", filename);
|
||||
return false;
|
||||
} //end if
|
||||
//seek to the correct position (in the pak file)
|
||||
if (fseek(fp, fpoffset, SEEK_SET))
|
||||
{
|
||||
AAS_Error("can't seek to file %s\n");
|
||||
fclose(fp);
|
||||
return false;
|
||||
} //end if
|
||||
//read the header
|
||||
if (fread(&header, sizeof(aas_header_t), 1, fp) != 1)
|
||||
{
|
||||
AAS_Error("can't read header of file %s\n", filename);
|
||||
fclose(fp);
|
||||
return false;
|
||||
} //end if
|
||||
//check header identification
|
||||
header.ident = LittleLong(header.ident);
|
||||
if (header.ident != AASID)
|
||||
{
|
||||
AAS_Error("%s is not an AAS file\n", filename);
|
||||
fclose(fp);
|
||||
return false;
|
||||
} //end if
|
||||
//check the version
|
||||
header.version = LittleLong(header.version);
|
||||
if (header.version != AASVERSION_OLD && header.version != AASVERSION)
|
||||
{
|
||||
AAS_Error("%s is version %i, not %i\n", filename, header.version, AASVERSION);
|
||||
fclose(fp);
|
||||
return false;
|
||||
} //end if
|
||||
//
|
||||
if (header.version == AASVERSION)
|
||||
{
|
||||
AAS_DData((unsigned char *) &header + 8, sizeof(aas_header_t) - 8);
|
||||
} //end if
|
||||
aasworld.bspchecksum = LittleLong(header.bspchecksum);
|
||||
//load the lumps:
|
||||
//bounding boxes
|
||||
offset = fpoffset + LittleLong(header.lumps[AASLUMP_BBOXES].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_BBOXES].filelen);
|
||||
aasworld.bboxes = (aas_bbox_t *) AAS_LoadAASLump(fp, offset, length, aasworld.bboxes);
|
||||
if (!aasworld.bboxes) return false;
|
||||
aasworld.numbboxes = length / sizeof(aas_bbox_t);
|
||||
//vertexes
|
||||
offset = fpoffset + LittleLong(header.lumps[AASLUMP_VERTEXES].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_VERTEXES].filelen);
|
||||
aasworld.vertexes = (aas_vertex_t *) AAS_LoadAASLump(fp, offset, length, aasworld.vertexes);
|
||||
if (!aasworld.vertexes) return false;
|
||||
aasworld.numvertexes = length / sizeof(aas_vertex_t);
|
||||
//planes
|
||||
offset = fpoffset + LittleLong(header.lumps[AASLUMP_PLANES].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_PLANES].filelen);
|
||||
aasworld.planes = (aas_plane_t *) AAS_LoadAASLump(fp, offset, length, aasworld.planes);
|
||||
if (!aasworld.planes) return false;
|
||||
aasworld.numplanes = length / sizeof(aas_plane_t);
|
||||
//edges
|
||||
offset = fpoffset + LittleLong(header.lumps[AASLUMP_EDGES].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_EDGES].filelen);
|
||||
aasworld.edges = (aas_edge_t *) AAS_LoadAASLump(fp, offset, length, aasworld.edges);
|
||||
if (!aasworld.edges) return false;
|
||||
aasworld.numedges = length / sizeof(aas_edge_t);
|
||||
//edgeindex
|
||||
offset = fpoffset + LittleLong(header.lumps[AASLUMP_EDGEINDEX].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_EDGEINDEX].filelen);
|
||||
aasworld.edgeindex = (aas_edgeindex_t *) AAS_LoadAASLump(fp, offset, length, aasworld.edgeindex);
|
||||
if (!aasworld.edgeindex) return false;
|
||||
aasworld.edgeindexsize = length / sizeof(aas_edgeindex_t);
|
||||
//faces
|
||||
offset = fpoffset + LittleLong(header.lumps[AASLUMP_FACES].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_FACES].filelen);
|
||||
aasworld.faces = (aas_face_t *) AAS_LoadAASLump(fp, offset, length, aasworld.faces);
|
||||
if (!aasworld.faces) return false;
|
||||
aasworld.numfaces = length / sizeof(aas_face_t);
|
||||
//faceindex
|
||||
offset = fpoffset + LittleLong(header.lumps[AASLUMP_FACEINDEX].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_FACEINDEX].filelen);
|
||||
aasworld.faceindex = (aas_faceindex_t *) AAS_LoadAASLump(fp, offset, length, aasworld.faceindex);
|
||||
if (!aasworld.faceindex) return false;
|
||||
aasworld.faceindexsize = length / sizeof(int);
|
||||
//convex areas
|
||||
offset = fpoffset + LittleLong(header.lumps[AASLUMP_AREAS].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_AREAS].filelen);
|
||||
aasworld.areas = (aas_area_t *) AAS_LoadAASLump(fp, offset, length, aasworld.areas);
|
||||
if (!aasworld.areas) return false;
|
||||
aasworld.numareas = length / sizeof(aas_area_t);
|
||||
//area settings
|
||||
offset = fpoffset + LittleLong(header.lumps[AASLUMP_AREASETTINGS].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_AREASETTINGS].filelen);
|
||||
aasworld.areasettings = (aas_areasettings_t *) AAS_LoadAASLump(fp, offset, length, aasworld.areasettings);
|
||||
if (!aasworld.areasettings) return false;
|
||||
aasworld.numareasettings = length / sizeof(aas_areasettings_t);
|
||||
//reachability list
|
||||
offset = fpoffset + LittleLong(header.lumps[AASLUMP_REACHABILITY].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_REACHABILITY].filelen);
|
||||
aasworld.reachability = (aas_reachability_t *) AAS_LoadAASLump(fp, offset, length, aasworld.reachability);
|
||||
if (length && !aasworld.reachability) return false;
|
||||
aasworld.reachabilitysize = length / sizeof(aas_reachability_t);
|
||||
//nodes
|
||||
offset = fpoffset + LittleLong(header.lumps[AASLUMP_NODES].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_NODES].filelen);
|
||||
aasworld.nodes = (aas_node_t *) AAS_LoadAASLump(fp, offset, length, aasworld.nodes);
|
||||
if (!aasworld.nodes) return false;
|
||||
aasworld.numnodes = length / sizeof(aas_node_t);
|
||||
//cluster portals
|
||||
offset = fpoffset + LittleLong(header.lumps[AASLUMP_PORTALS].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_PORTALS].filelen);
|
||||
aasworld.portals = (aas_portal_t *) AAS_LoadAASLump(fp, offset, length, aasworld.portals);
|
||||
if (length && !aasworld.portals) return false;
|
||||
aasworld.numportals = length / sizeof(aas_portal_t);
|
||||
//cluster portal index
|
||||
offset = fpoffset + LittleLong(header.lumps[AASLUMP_PORTALINDEX].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_PORTALINDEX].filelen);
|
||||
aasworld.portalindex = (aas_portalindex_t *) AAS_LoadAASLump(fp, offset, length, aasworld.portalindex);
|
||||
if (length && !aasworld.portalindex) return false;
|
||||
aasworld.portalindexsize = length / sizeof(aas_portalindex_t);
|
||||
//clusters
|
||||
offset = fpoffset + LittleLong(header.lumps[AASLUMP_CLUSTERS].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_CLUSTERS].filelen);
|
||||
aasworld.clusters = (aas_cluster_t *) AAS_LoadAASLump(fp, offset, length, aasworld.clusters);
|
||||
if (length && !aasworld.clusters) return false;
|
||||
aasworld.numclusters = length / sizeof(aas_cluster_t);
|
||||
//swap everything
|
||||
AAS_SwapAASData();
|
||||
//aas file is loaded
|
||||
aasworld.loaded = true;
|
||||
//close the file
|
||||
fclose(fp);
|
||||
return true;
|
||||
} //end of the function AAS_LoadAASFile
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_WriteAASLump(FILE *fp, aas_header_t *h, int lumpnum, void *data, int length)
|
||||
{
|
||||
aas_lump_t *lump;
|
||||
|
||||
lump = &h->lumps[lumpnum];
|
||||
|
||||
lump->fileofs = LittleLong(ftell(fp));
|
||||
lump->filelen = LittleLong(length);
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
if (fwrite(data, length, 1, fp) < 1)
|
||||
{
|
||||
Log_Print("error writing lump %s\n", lumpnum);
|
||||
fclose(fp);
|
||||
return false;
|
||||
} //end if
|
||||
} //end if
|
||||
return true;
|
||||
} //end of the function AAS_WriteAASLump
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShowNumReachabilities(int tt, char *name)
|
||||
{
|
||||
int i, num;
|
||||
|
||||
num = 0;
|
||||
for (i = 0; i < aasworld.reachabilitysize; i++)
|
||||
{
|
||||
if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == tt)
|
||||
num++;
|
||||
} //end for
|
||||
Log_Print("%6d %s\n", num, name);
|
||||
} //end of the function AAS_ShowNumReachabilities
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShowTotals(void)
|
||||
{
|
||||
Log_Print("numvertexes = %d\r\n", aasworld.numvertexes);
|
||||
Log_Print("numplanes = %d\r\n", aasworld.numplanes);
|
||||
Log_Print("numedges = %d\r\n", aasworld.numedges);
|
||||
Log_Print("edgeindexsize = %d\r\n", aasworld.edgeindexsize);
|
||||
Log_Print("numfaces = %d\r\n", aasworld.numfaces);
|
||||
Log_Print("faceindexsize = %d\r\n", aasworld.faceindexsize);
|
||||
Log_Print("numareas = %d\r\n", aasworld.numareas);
|
||||
Log_Print("numareasettings = %d\r\n", aasworld.numareasettings);
|
||||
Log_Print("reachabilitysize = %d\r\n", aasworld.reachabilitysize);
|
||||
Log_Print("numnodes = %d\r\n", aasworld.numnodes);
|
||||
Log_Print("numportals = %d\r\n", aasworld.numportals);
|
||||
Log_Print("portalindexsize = %d\r\n", aasworld.portalindexsize);
|
||||
Log_Print("numclusters = %d\r\n", aasworld.numclusters);
|
||||
AAS_ShowNumReachabilities(TRAVEL_WALK, "walk");
|
||||
AAS_ShowNumReachabilities(TRAVEL_CROUCH, "crouch");
|
||||
AAS_ShowNumReachabilities(TRAVEL_BARRIERJUMP, "barrier jump");
|
||||
AAS_ShowNumReachabilities(TRAVEL_JUMP, "jump");
|
||||
AAS_ShowNumReachabilities(TRAVEL_LADDER, "ladder");
|
||||
AAS_ShowNumReachabilities(TRAVEL_WALKOFFLEDGE, "walk off ledge");
|
||||
AAS_ShowNumReachabilities(TRAVEL_SWIM, "swim");
|
||||
AAS_ShowNumReachabilities(TRAVEL_WATERJUMP, "water jump");
|
||||
AAS_ShowNumReachabilities(TRAVEL_TELEPORT, "teleport");
|
||||
AAS_ShowNumReachabilities(TRAVEL_ELEVATOR, "elevator");
|
||||
AAS_ShowNumReachabilities(TRAVEL_ROCKETJUMP, "rocket jump");
|
||||
AAS_ShowNumReachabilities(TRAVEL_BFGJUMP, "bfg jump");
|
||||
AAS_ShowNumReachabilities(TRAVEL_GRAPPLEHOOK, "grapple hook");
|
||||
AAS_ShowNumReachabilities(TRAVEL_DOUBLEJUMP, "double jump");
|
||||
AAS_ShowNumReachabilities(TRAVEL_RAMPJUMP, "ramp jump");
|
||||
AAS_ShowNumReachabilities(TRAVEL_STRAFEJUMP, "strafe jump");
|
||||
AAS_ShowNumReachabilities(TRAVEL_JUMPPAD, "jump pad");
|
||||
AAS_ShowNumReachabilities(TRAVEL_FUNCBOB, "func bob");
|
||||
} //end of the function AAS_ShowTotals
|
||||
//===========================================================================
|
||||
// aas data is useless after writing to file because it is byte swapped
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean AAS_WriteAASFile(char *filename)
|
||||
{
|
||||
aas_header_t header;
|
||||
FILE *fp;
|
||||
|
||||
Log_Print("writing %s\n", filename);
|
||||
AAS_ShowTotals();
|
||||
//swap the aas data
|
||||
AAS_SwapAASData();
|
||||
//initialize the file header
|
||||
memset(&header, 0, sizeof(aas_header_t));
|
||||
header.ident = LittleLong(AASID);
|
||||
header.version = LittleLong(AASVERSION);
|
||||
header.bspchecksum = LittleLong(aasworld.bspchecksum);
|
||||
//open a new file
|
||||
fp = fopen(filename, "wb");
|
||||
if (!fp)
|
||||
{
|
||||
Log_Print("error opening %s\n", filename);
|
||||
return false;
|
||||
} //end if
|
||||
//write the header
|
||||
if (fwrite(&header, sizeof(aas_header_t), 1, fp) < 1)
|
||||
{
|
||||
fclose(fp);
|
||||
return false;
|
||||
} //end if
|
||||
//add the data lumps to the file
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_BBOXES, aasworld.bboxes,
|
||||
aasworld.numbboxes * sizeof(aas_bbox_t))) return false;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_VERTEXES, aasworld.vertexes,
|
||||
aasworld.numvertexes * sizeof(aas_vertex_t))) return false;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_PLANES, aasworld.planes,
|
||||
aasworld.numplanes * sizeof(aas_plane_t))) return false;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_EDGES, aasworld.edges,
|
||||
aasworld.numedges * sizeof(aas_edge_t))) return false;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_EDGEINDEX, aasworld.edgeindex,
|
||||
aasworld.edgeindexsize * sizeof(aas_edgeindex_t))) return false;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_FACES, aasworld.faces,
|
||||
aasworld.numfaces * sizeof(aas_face_t))) return false;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_FACEINDEX, aasworld.faceindex,
|
||||
aasworld.faceindexsize * sizeof(aas_faceindex_t))) return false;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_AREAS, aasworld.areas,
|
||||
aasworld.numareas * sizeof(aas_area_t))) return false;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_AREASETTINGS, aasworld.areasettings,
|
||||
aasworld.numareasettings * sizeof(aas_areasettings_t))) return false;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_REACHABILITY, aasworld.reachability,
|
||||
aasworld.reachabilitysize * sizeof(aas_reachability_t))) return false;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_NODES, aasworld.nodes,
|
||||
aasworld.numnodes * sizeof(aas_node_t))) return false;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_PORTALS, aasworld.portals,
|
||||
aasworld.numportals * sizeof(aas_portal_t))) return false;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_PORTALINDEX, aasworld.portalindex,
|
||||
aasworld.portalindexsize * sizeof(aas_portalindex_t))) return false;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_CLUSTERS, aasworld.clusters,
|
||||
aasworld.numclusters * sizeof(aas_cluster_t))) return false;
|
||||
//rewrite the header with the added lumps
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
AAS_DData((unsigned char *) &header + 8, sizeof(aas_header_t) - 8);
|
||||
if (fwrite(&header, sizeof(aas_header_t), 1, fp) < 1)
|
||||
{
|
||||
fclose(fp);
|
||||
return false;
|
||||
} //end if
|
||||
//close the file
|
||||
fclose(fp);
|
||||
return true;
|
||||
} //end of the function AAS_WriteAASFile
|
||||
|
25
tools/quake3/bspc/aas_file.h
Normal file
25
tools/quake3/bspc/aas_file.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
qboolean AAS_WriteAASFile(char *filename);
|
||||
qboolean AAS_LoadAASFile(char *filename, int fpoffset, int fplength);
|
||||
|
656
tools/quake3/bspc/aas_gsubdiv.c
Normal file
656
tools/quake3/bspc/aas_gsubdiv.c
Normal file
|
@ -0,0 +1,656 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "qbsp.h"
|
||||
#include "botlib/aasfile.h"
|
||||
#include "aas_create.h"
|
||||
#include "aas_store.h"
|
||||
#include "aas_cfg.h"
|
||||
|
||||
#define FACECLIP_EPSILON 0.2
|
||||
#define FACE_EPSILON 1.0
|
||||
|
||||
int numgravitationalsubdivisions = 0;
|
||||
int numladdersubdivisions = 0;
|
||||
|
||||
//NOTE: only do gravitational subdivision BEFORE area merging!!!!!!!
|
||||
// because the bsp tree isn't refreshes like with ladder subdivision
|
||||
|
||||
//===========================================================================
|
||||
// NOTE: the original face is invalid after splitting
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_SplitFace(tmp_face_t *face, vec3_t normal, float dist,
|
||||
tmp_face_t **frontface, tmp_face_t **backface)
|
||||
{
|
||||
winding_t *frontw, *backw;
|
||||
|
||||
//
|
||||
*frontface = *backface = NULL;
|
||||
|
||||
ClipWindingEpsilon(face->winding, normal, dist, FACECLIP_EPSILON, &frontw, &backw);
|
||||
|
||||
#ifdef DEBUG
|
||||
//
|
||||
if (frontw)
|
||||
{
|
||||
if (WindingIsTiny(frontw))
|
||||
{
|
||||
Log_Write("AAS_SplitFace: tiny back face\r\n");
|
||||
FreeWinding(frontw);
|
||||
frontw = NULL;
|
||||
} //end if
|
||||
} //end if
|
||||
if (backw)
|
||||
{
|
||||
if (WindingIsTiny(backw))
|
||||
{
|
||||
Log_Write("AAS_SplitFace: tiny back face\r\n");
|
||||
FreeWinding(backw);
|
||||
backw = NULL;
|
||||
} //end if
|
||||
} //end if
|
||||
#endif //DEBUG
|
||||
//if the winding was split
|
||||
if (frontw)
|
||||
{
|
||||
//check bounds
|
||||
(*frontface) = AAS_AllocTmpFace();
|
||||
(*frontface)->planenum = face->planenum;
|
||||
(*frontface)->winding = frontw;
|
||||
(*frontface)->faceflags = face->faceflags;
|
||||
} //end if
|
||||
if (backw)
|
||||
{
|
||||
//check bounds
|
||||
(*backface) = AAS_AllocTmpFace();
|
||||
(*backface)->planenum = face->planenum;
|
||||
(*backface)->winding = backw;
|
||||
(*backface)->faceflags = face->faceflags;
|
||||
} //end if
|
||||
} //end of the function AAS_SplitFace
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
winding_t *AAS_SplitWinding(tmp_area_t *tmparea, int planenum)
|
||||
{
|
||||
tmp_face_t *face;
|
||||
plane_t *plane;
|
||||
int side;
|
||||
winding_t *splitwinding;
|
||||
|
||||
//
|
||||
plane = &mapplanes[planenum];
|
||||
//create a split winding, first base winding for plane
|
||||
splitwinding = BaseWindingForPlane(plane->normal, plane->dist);
|
||||
//chop with all the faces of the area
|
||||
for (face = tmparea->tmpfaces; face && splitwinding; face = face->next[side])
|
||||
{
|
||||
//side of the face the original area was on
|
||||
side = face->frontarea != tmparea;
|
||||
plane = &mapplanes[face->planenum ^ side];
|
||||
ChopWindingInPlace(&splitwinding, plane->normal, plane->dist, 0); // PLANESIDE_EPSILON);
|
||||
} //end for
|
||||
return splitwinding;
|
||||
} //end of the function AAS_SplitWinding
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_TestSplitPlane(tmp_area_t *tmparea, vec3_t normal, float dist,
|
||||
int *facesplits, int *groundsplits, int *epsilonfaces)
|
||||
{
|
||||
int j, side, front, back, planenum;
|
||||
float d, d_front, d_back;
|
||||
tmp_face_t *face;
|
||||
winding_t *w;
|
||||
|
||||
*facesplits = *groundsplits = *epsilonfaces = 0;
|
||||
|
||||
planenum = FindFloatPlane(normal, dist);
|
||||
|
||||
w = AAS_SplitWinding(tmparea, planenum);
|
||||
if (!w) return false;
|
||||
FreeWinding(w);
|
||||
//
|
||||
for (face = tmparea->tmpfaces; face; face = face->next[side])
|
||||
{
|
||||
//side of the face the area is on
|
||||
side = face->frontarea != tmparea;
|
||||
|
||||
if ((face->planenum & ~1) == (planenum & ~1))
|
||||
{
|
||||
Log_Print("AAS_TestSplitPlane: tried face plane as splitter\n");
|
||||
return false;
|
||||
} //end if
|
||||
w = face->winding;
|
||||
//reset distance at front and back side of plane
|
||||
d_front = d_back = 0;
|
||||
//reset front and back flags
|
||||
front = back = 0;
|
||||
for (j = 0; j < w->numpoints; j++)
|
||||
{
|
||||
d = DotProduct(w->p[j], normal) - dist;
|
||||
if (d > d_front) d_front = d;
|
||||
if (d < d_back) d_back = d;
|
||||
|
||||
if (d > 0.4) // PLANESIDE_EPSILON)
|
||||
front = 1;
|
||||
if (d < -0.4) // PLANESIDE_EPSILON)
|
||||
back = 1;
|
||||
} //end for
|
||||
//check for an epsilon face
|
||||
if ( (d_front > FACECLIP_EPSILON && d_front < FACE_EPSILON)
|
||||
|| (d_back < -FACECLIP_EPSILON && d_back > -FACE_EPSILON) )
|
||||
{
|
||||
(*epsilonfaces)++;
|
||||
} //end if
|
||||
//if the face has points at both sides of the plane
|
||||
if (front && back)
|
||||
{
|
||||
(*facesplits)++;
|
||||
if (face->faceflags & FACE_GROUND)
|
||||
{
|
||||
(*groundsplits)++;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end for
|
||||
return true;
|
||||
} //end of the function AAS_TestSplitPlane
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_SplitArea(tmp_area_t *tmparea, int planenum, tmp_area_t **frontarea, tmp_area_t **backarea)
|
||||
{
|
||||
int side;
|
||||
tmp_area_t *facefrontarea, *facebackarea, *faceotherarea;
|
||||
tmp_face_t *face, *frontface, *backface, *splitface, *nextface;
|
||||
winding_t *splitwinding;
|
||||
plane_t *splitplane;
|
||||
|
||||
/*
|
||||
#ifdef AW_DEBUG
|
||||
int facesplits, groundsplits, epsilonface;
|
||||
Log_Print("\n----------------------\n");
|
||||
Log_Print("splitting area %d\n", areanum);
|
||||
Log_Print("with normal = \'%f %f %f\', dist = %f\n", normal[0], normal[1], normal[2], dist);
|
||||
AAS_TestSplitPlane(areanum, normal, dist,
|
||||
&facesplits, &groundsplits, &epsilonface);
|
||||
Log_Print("face splits = %d\nground splits = %d\n", facesplits, groundsplits);
|
||||
if (epsilonface) Log_Print("aaahh epsilon face\n");
|
||||
#endif //AW_DEBUG*/
|
||||
//the original area
|
||||
|
||||
AAS_FlipAreaFaces(tmparea);
|
||||
AAS_CheckArea(tmparea);
|
||||
//
|
||||
splitplane = &mapplanes[planenum];
|
||||
/* //create a split winding, first base winding for plane
|
||||
splitwinding = BaseWindingForPlane(splitplane->normal, splitplane->dist);
|
||||
//chop with all the faces of the area
|
||||
for (face = tmparea->tmpfaces; face && splitwinding; face = face->next[side])
|
||||
{
|
||||
//side of the face the original area was on
|
||||
side = face->frontarea != tmparea->areanum;
|
||||
plane = &mapplanes[face->planenum ^ side];
|
||||
ChopWindingInPlace(&splitwinding, plane->normal, plane->dist, 0); // PLANESIDE_EPSILON);
|
||||
} //end for*/
|
||||
splitwinding = AAS_SplitWinding(tmparea, planenum);
|
||||
if (!splitwinding)
|
||||
{
|
||||
/*
|
||||
#ifdef DEBUG
|
||||
AAS_TestSplitPlane(areanum, normal, dist,
|
||||
&facesplits, &groundsplits, &epsilonface);
|
||||
Log_Print("\nface splits = %d\nground splits = %d\n", facesplits, groundsplits);
|
||||
if (epsilonface) Log_Print("aaahh epsilon face\n");
|
||||
#endif //DEBUG*/
|
||||
Error("AAS_SplitArea: no split winding when splitting area %d\n", tmparea->areanum);
|
||||
} //end if
|
||||
//create a split face
|
||||
splitface = AAS_AllocTmpFace();
|
||||
//get the map plane
|
||||
splitface->planenum = planenum;
|
||||
//store the split winding
|
||||
splitface->winding = splitwinding;
|
||||
//the new front area
|
||||
(*frontarea) = AAS_AllocTmpArea();
|
||||
(*frontarea)->presencetype = tmparea->presencetype;
|
||||
(*frontarea)->contents = tmparea->contents;
|
||||
(*frontarea)->modelnum = tmparea->modelnum;
|
||||
(*frontarea)->tmpfaces = NULL;
|
||||
//the new back area
|
||||
(*backarea) = AAS_AllocTmpArea();
|
||||
(*backarea)->presencetype = tmparea->presencetype;
|
||||
(*backarea)->contents = tmparea->contents;
|
||||
(*backarea)->modelnum = tmparea->modelnum;
|
||||
(*backarea)->tmpfaces = NULL;
|
||||
//add the split face to the new areas
|
||||
AAS_AddFaceSideToArea(splitface, 0, (*frontarea));
|
||||
AAS_AddFaceSideToArea(splitface, 1, (*backarea));
|
||||
|
||||
//split all the faces of the original area
|
||||
for (face = tmparea->tmpfaces; face; face = nextface)
|
||||
{
|
||||
//side of the face the original area was on
|
||||
side = face->frontarea != tmparea;
|
||||
//next face of the original area
|
||||
nextface = face->next[side];
|
||||
//front area of the face
|
||||
facefrontarea = face->frontarea;
|
||||
//back area of the face
|
||||
facebackarea = face->backarea;
|
||||
//remove the face from both the front and back areas
|
||||
if (facefrontarea) AAS_RemoveFaceFromArea(face, facefrontarea);
|
||||
if (facebackarea) AAS_RemoveFaceFromArea(face, facebackarea);
|
||||
//split the face
|
||||
AAS_SplitFace(face, splitplane->normal, splitplane->dist, &frontface, &backface);
|
||||
//free the original face
|
||||
AAS_FreeTmpFace(face);
|
||||
//get the number of the area at the other side of the face
|
||||
if (side) faceotherarea = facefrontarea;
|
||||
else faceotherarea = facebackarea;
|
||||
//if there is an area at the other side of the original face
|
||||
if (faceotherarea)
|
||||
{
|
||||
if (frontface) AAS_AddFaceSideToArea(frontface, !side, faceotherarea);
|
||||
if (backface) AAS_AddFaceSideToArea(backface, !side, faceotherarea);
|
||||
} //end if
|
||||
//add the front and back part left after splitting the original face to the new areas
|
||||
if (frontface) AAS_AddFaceSideToArea(frontface, side, (*frontarea));
|
||||
if (backface) AAS_AddFaceSideToArea(backface, side, (*backarea));
|
||||
} //end for
|
||||
|
||||
if (!(*frontarea)->tmpfaces) Log_Print("AAS_SplitArea: front area without faces\n");
|
||||
if (!(*backarea)->tmpfaces) Log_Print("AAS_SplitArea: back area without faces\n");
|
||||
|
||||
tmparea->invalid = true;
|
||||
/*
|
||||
#ifdef AW_DEBUG
|
||||
for (i = 0, face = frontarea->tmpfaces; face; face = face->next[side])
|
||||
{
|
||||
side = face->frontarea != frontarea->areanum;
|
||||
i++;
|
||||
} //end for
|
||||
Log_Print("created front area %d with %d faces\n", frontarea->areanum, i);
|
||||
|
||||
for (i = 0, face = backarea->tmpfaces; face; face = face->next[side])
|
||||
{
|
||||
side = face->frontarea != backarea->areanum;
|
||||
i++;
|
||||
} //end for
|
||||
Log_Print("created back area %d with %d faces\n", backarea->areanum, i);
|
||||
#endif //AW_DEBUG*/
|
||||
|
||||
AAS_FlipAreaFaces((*frontarea));
|
||||
AAS_FlipAreaFaces((*backarea));
|
||||
//
|
||||
AAS_CheckArea((*frontarea));
|
||||
AAS_CheckArea((*backarea));
|
||||
} //end of the function AAS_SplitArea
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_FindBestAreaSplitPlane(tmp_area_t *tmparea, vec3_t normal, float *dist)
|
||||
{
|
||||
int side1, side2;
|
||||
int foundsplitter, facesplits, groundsplits, epsilonfaces, bestepsilonfaces;
|
||||
float bestvalue, value;
|
||||
tmp_face_t *face1, *face2;
|
||||
vec3_t tmpnormal, invgravity;
|
||||
float tmpdist;
|
||||
|
||||
//get inverse of gravity direction
|
||||
VectorCopy(cfg.phys_gravitydirection, invgravity);
|
||||
VectorInverse(invgravity);
|
||||
|
||||
foundsplitter = false;
|
||||
bestvalue = -999999;
|
||||
bestepsilonfaces = 0;
|
||||
//
|
||||
#ifdef AW_DEBUG
|
||||
Log_Print("finding split plane for area %d\n", tmparea->areanum);
|
||||
#endif //AW_DEBUG
|
||||
for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
|
||||
{
|
||||
//side of the face the area is on
|
||||
side1 = face1->frontarea != tmparea;
|
||||
//
|
||||
if (WindingIsTiny(face1->winding))
|
||||
{
|
||||
Log_Write("gsubdiv: area %d has a tiny winding\r\n", tmparea->areanum);
|
||||
continue;
|
||||
} //end if
|
||||
//if the face isn't a gap or ground there's no split edge
|
||||
if (!(face1->faceflags & FACE_GROUND) && !AAS_GapFace(face1, side1)) continue;
|
||||
//
|
||||
for (face2 = face1->next[side1]; face2; face2 = face2->next[side2])
|
||||
{
|
||||
//side of the face the area is on
|
||||
side2 = face2->frontarea != tmparea;
|
||||
//
|
||||
if (WindingIsTiny(face1->winding))
|
||||
{
|
||||
Log_Write("gsubdiv: area %d has a tiny winding\r\n", tmparea->areanum);
|
||||
continue;
|
||||
} //end if
|
||||
//if the face isn't a gap or ground there's no split edge
|
||||
if (!(face2->faceflags & FACE_GROUND) && !AAS_GapFace(face2, side2)) continue;
|
||||
//only split between gaps and ground
|
||||
if (!(((face1->faceflags & FACE_GROUND) && AAS_GapFace(face2, side2)) ||
|
||||
((face2->faceflags & FACE_GROUND) && AAS_GapFace(face1, side1)))) continue;
|
||||
//find a plane seperating the windings of the faces
|
||||
if (!FindPlaneSeperatingWindings(face1->winding, face2->winding, invgravity,
|
||||
tmpnormal, &tmpdist)) continue;
|
||||
#ifdef AW_DEBUG
|
||||
Log_Print("normal = \'%f %f %f\', dist = %f\n",
|
||||
tmpnormal[0], tmpnormal[1], tmpnormal[2], tmpdist);
|
||||
#endif //AW_DEBUG
|
||||
//get metrics for this vertical plane
|
||||
if (!AAS_TestSplitPlane(tmparea, tmpnormal, tmpdist,
|
||||
&facesplits, &groundsplits, &epsilonfaces))
|
||||
{
|
||||
continue;
|
||||
} //end if
|
||||
#ifdef AW_DEBUG
|
||||
Log_Print("face splits = %d\nground splits = %d\n",
|
||||
facesplits, groundsplits);
|
||||
#endif //AW_DEBUG
|
||||
value = 100 - facesplits - 2 * groundsplits;
|
||||
//avoid epsilon faces
|
||||
value += epsilonfaces * -1000;
|
||||
if (value > bestvalue)
|
||||
{
|
||||
VectorCopy(tmpnormal, normal);
|
||||
*dist = tmpdist;
|
||||
bestvalue = value;
|
||||
bestepsilonfaces = epsilonfaces;
|
||||
foundsplitter = true;
|
||||
} //end if
|
||||
} //end for
|
||||
} //end for
|
||||
if (bestepsilonfaces)
|
||||
{
|
||||
Log_Write("found %d epsilon faces trying to split area %d\r\n",
|
||||
epsilonfaces, tmparea->areanum);
|
||||
} //end else
|
||||
return foundsplitter;
|
||||
} //end of the function AAS_FindBestAreaSplitPlane
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
tmp_node_t *AAS_SubdivideArea_r(tmp_node_t *tmpnode)
|
||||
{
|
||||
int planenum;
|
||||
tmp_area_t *frontarea, *backarea;
|
||||
tmp_node_t *tmpnode1, *tmpnode2;
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
|
||||
if (AAS_FindBestAreaSplitPlane(tmpnode->tmparea, normal, &dist))
|
||||
{
|
||||
qprintf("\r%6d", ++numgravitationalsubdivisions);
|
||||
//
|
||||
planenum = FindFloatPlane(normal, dist);
|
||||
//split the area
|
||||
AAS_SplitArea(tmpnode->tmparea, planenum, &frontarea, &backarea);
|
||||
//
|
||||
tmpnode->tmparea = NULL;
|
||||
tmpnode->planenum = FindFloatPlane(normal, dist);
|
||||
//
|
||||
tmpnode1 = AAS_AllocTmpNode();
|
||||
tmpnode1->planenum = 0;
|
||||
tmpnode1->tmparea = frontarea;
|
||||
//
|
||||
tmpnode2 = AAS_AllocTmpNode();
|
||||
tmpnode2->planenum = 0;
|
||||
tmpnode2->tmparea = backarea;
|
||||
//subdivide the areas created by splitting recursively
|
||||
tmpnode->children[0] = AAS_SubdivideArea_r(tmpnode1);
|
||||
tmpnode->children[1] = AAS_SubdivideArea_r(tmpnode2);
|
||||
} //end if
|
||||
return tmpnode;
|
||||
} //end of the function AAS_SubdivideArea_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
tmp_node_t *AAS_GravitationalSubdivision_r(tmp_node_t *tmpnode)
|
||||
{
|
||||
//if this is a solid leaf
|
||||
if (!tmpnode) return NULL;
|
||||
//negative so it's an area
|
||||
if (tmpnode->tmparea) return AAS_SubdivideArea_r(tmpnode);
|
||||
//do the children recursively
|
||||
tmpnode->children[0] = AAS_GravitationalSubdivision_r(tmpnode->children[0]);
|
||||
tmpnode->children[1] = AAS_GravitationalSubdivision_r(tmpnode->children[1]);
|
||||
return tmpnode;
|
||||
} //end of the function AAS_GravitationalSubdivision_r
|
||||
//===========================================================================
|
||||
// NOTE: merge faces and melt edges first
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_GravitationalSubdivision(void)
|
||||
{
|
||||
Log_Write("AAS_GravitationalSubdivision\r\n");
|
||||
numgravitationalsubdivisions = 0;
|
||||
qprintf("%6i gravitational subdivisions", numgravitationalsubdivisions);
|
||||
//start with the head node
|
||||
AAS_GravitationalSubdivision_r(tmpaasworld.nodes);
|
||||
qprintf("\n");
|
||||
Log_Write("%6i gravitational subdivisions\r\n", numgravitationalsubdivisions);
|
||||
} //end of the function AAS_GravitationalSubdivision
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
tmp_node_t *AAS_RefreshLadderSubdividedTree_r(tmp_node_t *tmpnode, tmp_area_t *tmparea,
|
||||
tmp_node_t *tmpnode1, tmp_node_t *tmpnode2, int planenum)
|
||||
{
|
||||
//if this is a solid leaf
|
||||
if (!tmpnode) return NULL;
|
||||
//negative so it's an area
|
||||
if (tmpnode->tmparea)
|
||||
{
|
||||
if (tmpnode->tmparea == tmparea)
|
||||
{
|
||||
tmpnode->tmparea = NULL;
|
||||
tmpnode->planenum = planenum;
|
||||
tmpnode->children[0] = tmpnode1;
|
||||
tmpnode->children[1] = tmpnode2;
|
||||
} //end if
|
||||
return tmpnode;
|
||||
} //end if
|
||||
//do the children recursively
|
||||
tmpnode->children[0] = AAS_RefreshLadderSubdividedTree_r(tmpnode->children[0],
|
||||
tmparea, tmpnode1, tmpnode2, planenum);
|
||||
tmpnode->children[1] = AAS_RefreshLadderSubdividedTree_r(tmpnode->children[1],
|
||||
tmparea, tmpnode1, tmpnode2, planenum);
|
||||
return tmpnode;
|
||||
} //end of the function AAS_RefreshLadderSubdividedTree_r
|
||||
//===========================================================================
|
||||
// find an area with ladder faces and ground faces that are not connected
|
||||
// split the area with a horizontal plane at the lowest vertex of all
|
||||
// ladder faces in the area
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
tmp_node_t *AAS_LadderSubdivideArea_r(tmp_node_t *tmpnode)
|
||||
{
|
||||
int side1, i, planenum;
|
||||
int foundladderface, foundgroundface;
|
||||
float dist;
|
||||
tmp_area_t *tmparea, *frontarea, *backarea;
|
||||
tmp_face_t *face1;
|
||||
tmp_node_t *tmpnode1, *tmpnode2;
|
||||
vec3_t lowestpoint, normal = {0, 0, 1};
|
||||
plane_t *plane;
|
||||
winding_t *w;
|
||||
|
||||
tmparea = tmpnode->tmparea;
|
||||
//skip areas with a liquid
|
||||
if (tmparea->contents & (AREACONTENTS_WATER
|
||||
| AREACONTENTS_LAVA
|
||||
| AREACONTENTS_SLIME)) return tmpnode;
|
||||
//must be possible to stand in the area
|
||||
if (!(tmparea->presencetype & PRESENCE_NORMAL)) return tmpnode;
|
||||
//
|
||||
foundladderface = false;
|
||||
foundgroundface = false;
|
||||
lowestpoint[2] = 99999;
|
||||
//
|
||||
for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
|
||||
{
|
||||
//side of the face the area is on
|
||||
side1 = face1->frontarea != tmparea;
|
||||
//if the face is a ladder face
|
||||
if (face1->faceflags & FACE_LADDER)
|
||||
{
|
||||
plane = &mapplanes[face1->planenum];
|
||||
//the ladder face plane should be pretty much vertical
|
||||
if (DotProduct(plane->normal, normal) > -0.1)
|
||||
{
|
||||
foundladderface = true;
|
||||
//find lowest point
|
||||
for (i = 0; i < face1->winding->numpoints; i++)
|
||||
{
|
||||
if (face1->winding->p[i][2] < lowestpoint[2])
|
||||
{
|
||||
VectorCopy(face1->winding->p[i], lowestpoint);
|
||||
} //end if
|
||||
} //end for
|
||||
} //end if
|
||||
} //end if
|
||||
else if (face1->faceflags & FACE_GROUND)
|
||||
{
|
||||
foundgroundface = true;
|
||||
} //end else if
|
||||
} //end for
|
||||
//
|
||||
if ((!foundladderface) || (!foundgroundface)) return tmpnode;
|
||||
//
|
||||
for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
|
||||
{
|
||||
//side of the face the area is on
|
||||
side1 = face1->frontarea != tmparea;
|
||||
//if the face isn't a ground face
|
||||
if (!(face1->faceflags & FACE_GROUND)) continue;
|
||||
//the ground plane
|
||||
plane = &mapplanes[face1->planenum];
|
||||
//get the difference between the ground plane and the lowest point
|
||||
dist = DotProduct(plane->normal, lowestpoint) - plane->dist;
|
||||
//if the lowest point is very near one of the ground planes
|
||||
if (dist > -1 && dist < 1)
|
||||
{
|
||||
return tmpnode;
|
||||
} //end if
|
||||
} //end for
|
||||
//
|
||||
dist = DotProduct(normal, lowestpoint);
|
||||
planenum = FindFloatPlane(normal, dist);
|
||||
//
|
||||
w = AAS_SplitWinding(tmparea, planenum);
|
||||
if (!w) return tmpnode;
|
||||
FreeWinding(w);
|
||||
//split the area with a horizontal plane through the lowest point
|
||||
qprintf("\r%6d", ++numladdersubdivisions);
|
||||
//
|
||||
AAS_SplitArea(tmparea, planenum, &frontarea, &backarea);
|
||||
//
|
||||
tmpnode->tmparea = NULL;
|
||||
tmpnode->planenum = planenum;
|
||||
//
|
||||
tmpnode1 = AAS_AllocTmpNode();
|
||||
tmpnode1->planenum = 0;
|
||||
tmpnode1->tmparea = frontarea;
|
||||
//
|
||||
tmpnode2 = AAS_AllocTmpNode();
|
||||
tmpnode2->planenum = 0;
|
||||
tmpnode2->tmparea = backarea;
|
||||
//subdivide the areas created by splitting recursively
|
||||
tmpnode->children[0] = AAS_LadderSubdivideArea_r(tmpnode1);
|
||||
tmpnode->children[1] = AAS_LadderSubdivideArea_r(tmpnode2);
|
||||
//refresh the tree
|
||||
AAS_RefreshLadderSubdividedTree_r(tmpaasworld.nodes, tmparea, tmpnode1, tmpnode2, planenum);
|
||||
//
|
||||
return tmpnode;
|
||||
} //end of the function AAS_LadderSubdivideArea_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
tmp_node_t *AAS_LadderSubdivision_r(tmp_node_t *tmpnode)
|
||||
{
|
||||
//if this is a solid leaf
|
||||
if (!tmpnode) return 0;
|
||||
//negative so it's an area
|
||||
if (tmpnode->tmparea) return AAS_LadderSubdivideArea_r(tmpnode);
|
||||
//do the children recursively
|
||||
tmpnode->children[0] = AAS_LadderSubdivision_r(tmpnode->children[0]);
|
||||
tmpnode->children[1] = AAS_LadderSubdivision_r(tmpnode->children[1]);
|
||||
return tmpnode;
|
||||
} //end of the function AAS_LadderSubdivision_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_LadderSubdivision(void)
|
||||
{
|
||||
Log_Write("AAS_LadderSubdivision\r\n");
|
||||
numladdersubdivisions = 0;
|
||||
qprintf("%6i ladder subdivisions", numladdersubdivisions);
|
||||
//start with the head node
|
||||
AAS_LadderSubdivision_r(tmpaasworld.nodes);
|
||||
//
|
||||
qprintf("\n");
|
||||
Log_Write("%6i ladder subdivisions\r\n", numladdersubdivisions);
|
||||
} //end of the function AAS_LadderSubdivision
|
25
tools/quake3/bspc/aas_gsubdiv.h
Normal file
25
tools/quake3/bspc/aas_gsubdiv.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
//works with the global tmpaasworld
|
||||
void AAS_GravitationalSubdivision(void);
|
||||
void AAS_LadderSubdivision(void);
|
849
tools/quake3/bspc/aas_map.c
Normal file
849
tools/quake3/bspc/aas_map.c
Normal file
|
@ -0,0 +1,849 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "qbsp.h"
|
||||
#include "l_mem.h"
|
||||
#include "botlib/aasfile.h" //aas_bbox_t
|
||||
#include "aas_store.h" //AAS_MAX_BBOXES
|
||||
#include "aas_cfg.h"
|
||||
#include "qcommon/surfaceflags.h"
|
||||
|
||||
#define SPAWNFLAG_NOT_EASY 0x00000100
|
||||
#define SPAWNFLAG_NOT_MEDIUM 0x00000200
|
||||
#define SPAWNFLAG_NOT_HARD 0x00000400
|
||||
#define SPAWNFLAG_NOT_DEATHMATCH 0x00000800
|
||||
#define SPAWNFLAG_NOT_COOP 0x00001000
|
||||
|
||||
#define STATE_TOP 0
|
||||
#define STATE_BOTTOM 1
|
||||
#define STATE_UP 2
|
||||
#define STATE_DOWN 3
|
||||
|
||||
#define DOOR_START_OPEN 1
|
||||
#define DOOR_REVERSE 2
|
||||
#define DOOR_CRUSHER 4
|
||||
#define DOOR_NOMONSTER 8
|
||||
#define DOOR_TOGGLE 32
|
||||
#define DOOR_X_AXIS 64
|
||||
#define DOOR_Y_AXIS 128
|
||||
|
||||
#define BBOX_NORMAL_EPSILON 0.0001
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
vec_t BoxOriginDistanceFromPlane(vec3_t normal, vec3_t mins, vec3_t maxs, int side)
|
||||
{
|
||||
vec3_t v1, v2;
|
||||
int i;
|
||||
|
||||
if (side)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (normal[i] > BBOX_NORMAL_EPSILON) v1[i] = maxs[i];
|
||||
else if (normal[i] < -BBOX_NORMAL_EPSILON) v1[i] = mins[i];
|
||||
else v1[i] = 0;
|
||||
} //end for
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (normal[i] > BBOX_NORMAL_EPSILON) v1[i] = mins[i];
|
||||
else if (normal[i] < -BBOX_NORMAL_EPSILON) v1[i] = maxs[i];
|
||||
else v1[i] = 0;
|
||||
} //end for
|
||||
} //end else
|
||||
VectorCopy(normal, v2);
|
||||
VectorInverse(v2);
|
||||
return DotProduct(v1, v2);
|
||||
} //end of the function BoxOriginDistanceFromPlane
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
vec_t CapsuleOriginDistanceFromPlane(vec3_t normal, vec3_t mins, vec3_t maxs)
|
||||
{
|
||||
float offset_up, offset_down, width, radius;
|
||||
|
||||
width = maxs[0] - mins[0];
|
||||
// if the box is less high then it is wide
|
||||
if (maxs[2] - mins[2] < width) {
|
||||
width = maxs[2] - mins[2];
|
||||
}
|
||||
radius = width * 0.5;
|
||||
// offset to upper and lower sphere
|
||||
offset_up = maxs[2] - radius;
|
||||
offset_down = -mins[2] - radius;
|
||||
|
||||
// if normal points upward
|
||||
if ( normal[2] > 0 ) {
|
||||
// touches lower sphere first
|
||||
return normal[2] * offset_down + radius;
|
||||
}
|
||||
else {
|
||||
// touched upper sphere first
|
||||
return -normal[2] * offset_up + radius;
|
||||
}
|
||||
}
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ExpandMapBrush(mapbrush_t *brush, vec3_t mins, vec3_t maxs)
|
||||
{
|
||||
int sn;
|
||||
float dist;
|
||||
side_t *s;
|
||||
plane_t *plane;
|
||||
|
||||
for (sn = 0; sn < brush->numsides; sn++)
|
||||
{
|
||||
s = brush->original_sides + sn;
|
||||
plane = &mapplanes[s->planenum];
|
||||
dist = plane->dist;
|
||||
if (capsule_collision) {
|
||||
dist += CapsuleOriginDistanceFromPlane(plane->normal, mins, maxs);
|
||||
}
|
||||
else {
|
||||
dist += BoxOriginDistanceFromPlane(plane->normal, mins, maxs, 0);
|
||||
}
|
||||
s->planenum = FindFloatPlane(plane->normal, dist);
|
||||
//the side isn't a bevel after expanding
|
||||
s->flags &= ~SFL_BEVEL;
|
||||
//don't skip the surface
|
||||
s->surf &= ~SURF_SKIP;
|
||||
//make sure the texinfo is not TEXINFO_NODE
|
||||
//when player clip contents brushes are read from the bsp tree
|
||||
//they have the texinfo field set to TEXINFO_NODE
|
||||
//s->texinfo = 0;
|
||||
} //end for
|
||||
} //end of the function AAS_ExpandMapBrush
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_SetTexinfo(mapbrush_t *brush)
|
||||
{
|
||||
int n;
|
||||
side_t *side;
|
||||
|
||||
if (brush->contents & (CONTENTS_LADDER
|
||||
| CONTENTS_AREAPORTAL
|
||||
| CONTENTS_CLUSTERPORTAL
|
||||
| CONTENTS_TELEPORTER
|
||||
| CONTENTS_JUMPPAD
|
||||
| CONTENTS_DONOTENTER
|
||||
| CONTENTS_WATER
|
||||
| CONTENTS_LAVA
|
||||
| CONTENTS_SLIME
|
||||
| CONTENTS_WINDOW
|
||||
| CONTENTS_PLAYERCLIP))
|
||||
{
|
||||
//we just set texinfo to 0 because these brush sides MUST be used as
|
||||
//bsp splitters textured or not textured
|
||||
for (n = 0; n < brush->numsides; n++)
|
||||
{
|
||||
side = brush->original_sides + n;
|
||||
//side->flags |= SFL_TEXTURED|SFL_VISIBLE;
|
||||
side->texinfo = 0;
|
||||
} //end for
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
//only use brush sides as splitters if they are textured
|
||||
//texinfo of non-textured sides will be set to TEXINFO_NODE
|
||||
for (n = 0; n < brush->numsides; n++)
|
||||
{
|
||||
side = brush->original_sides + n;
|
||||
//don't use side as splitter (set texinfo to TEXINFO_NODE) if not textured
|
||||
if (side->flags & (SFL_TEXTURED|SFL_BEVEL)) side->texinfo = 0;
|
||||
else side->texinfo = TEXINFO_NODE;
|
||||
} //end for
|
||||
} //end else
|
||||
} //end of the function AAS_SetTexinfo
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void FreeBrushWindings(mapbrush_t *brush)
|
||||
{
|
||||
int n;
|
||||
side_t *side;
|
||||
//
|
||||
for (n = 0; n < brush->numsides; n++)
|
||||
{
|
||||
side = brush->original_sides + n;
|
||||
//
|
||||
if (side->winding) FreeWinding(side->winding);
|
||||
} //end for
|
||||
} //end of the function FreeBrushWindings
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_AddMapBrushSide(mapbrush_t *brush, int planenum)
|
||||
{
|
||||
side_t *side;
|
||||
//
|
||||
if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
|
||||
Error ("MAX_MAPFILE_BRUSHSIDES");
|
||||
//
|
||||
side = brush->original_sides + brush->numsides;
|
||||
side->original = NULL;
|
||||
side->winding = NULL;
|
||||
side->contents = brush->contents;
|
||||
side->flags &= ~(SFL_BEVEL|SFL_VISIBLE);
|
||||
side->surf = 0;
|
||||
side->planenum = planenum;
|
||||
side->texinfo = 0;
|
||||
//
|
||||
nummapbrushsides++;
|
||||
brush->numsides++;
|
||||
} //end of the function AAS_AddMapBrushSide
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_FixMapBrush(mapbrush_t *brush)
|
||||
{
|
||||
int i, j, planenum;
|
||||
float dist;
|
||||
winding_t *w;
|
||||
plane_t *plane, *plane1, *plane2;
|
||||
side_t *side;
|
||||
vec3_t normal;
|
||||
|
||||
//calculate the brush bounds
|
||||
ClearBounds(brush->mins, brush->maxs);
|
||||
for (i = 0; i < brush->numsides; i++)
|
||||
{
|
||||
plane = &mapplanes[brush->original_sides[i].planenum];
|
||||
w = BaseWindingForPlane(plane->normal, plane->dist);
|
||||
for (j = 0; j < brush->numsides && w; j++)
|
||||
{
|
||||
if (i == j) continue;
|
||||
//there are no brush bevels marked but who cares :)
|
||||
if (brush->original_sides[j].flags & SFL_BEVEL) continue;
|
||||
plane = &mapplanes[brush->original_sides[j].planenum^1];
|
||||
ChopWindingInPlace(&w, plane->normal, plane->dist, 0); //CLIP_EPSILON);
|
||||
} //end for
|
||||
|
||||
side = &brush->original_sides[i];
|
||||
side->winding = w;
|
||||
if (w)
|
||||
{
|
||||
for (j = 0; j < w->numpoints; j++)
|
||||
{
|
||||
AddPointToBounds(w->p[j], brush->mins, brush->maxs);
|
||||
} //end for
|
||||
} //end if
|
||||
} //end for
|
||||
//
|
||||
for (i = 0; i < brush->numsides; i++)
|
||||
{
|
||||
for (j = 0; j < brush->numsides; j++)
|
||||
{
|
||||
if (i == j) continue;
|
||||
plane1 = &mapplanes[brush->original_sides[i].planenum];
|
||||
plane2 = &mapplanes[brush->original_sides[j].planenum];
|
||||
if (WindingsNonConvex(brush->original_sides[i].winding,
|
||||
brush->original_sides[j].winding,
|
||||
plane1->normal, plane2->normal,
|
||||
plane1->dist, plane2->dist))
|
||||
{
|
||||
Log_Print("non convex brush");
|
||||
} //end if
|
||||
} //end for
|
||||
} //end for
|
||||
|
||||
//NOW close the fucking brush!!
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (brush->mins[i] < -MAX_MAP_BOUNDS)
|
||||
{
|
||||
VectorClear(normal);
|
||||
normal[i] = -1;
|
||||
dist = MAX_MAP_BOUNDS - 10;
|
||||
planenum = FindFloatPlane(normal, dist);
|
||||
//
|
||||
Log_Print("mins out of range: added extra brush side\n");
|
||||
AAS_AddMapBrushSide(brush, planenum);
|
||||
} //end if
|
||||
if (brush->maxs[i] > MAX_MAP_BOUNDS)
|
||||
{
|
||||
VectorClear(normal);
|
||||
normal[i] = 1;
|
||||
dist = MAX_MAP_BOUNDS - 10;
|
||||
planenum = FindFloatPlane(normal, dist);
|
||||
//
|
||||
Log_Print("maxs out of range: added extra brush side\n");
|
||||
AAS_AddMapBrushSide(brush, planenum);
|
||||
} //end if
|
||||
if (brush->mins[i] > MAX_MAP_BOUNDS || brush->maxs[i] < -MAX_MAP_BOUNDS)
|
||||
{
|
||||
Log_Print("entity %i, brush %i: no visible sides on brush\n", brush->entitynum, brush->brushnum);
|
||||
} //end if
|
||||
} //end for
|
||||
//free all the windings
|
||||
FreeBrushWindings(brush);
|
||||
} //end of the function AAS_FixMapBrush
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean AAS_MakeBrushWindings(mapbrush_t *ob)
|
||||
{
|
||||
int i, j;
|
||||
winding_t *w;
|
||||
side_t *side;
|
||||
plane_t *plane, *plane1, *plane2;
|
||||
|
||||
ClearBounds (ob->mins, ob->maxs);
|
||||
|
||||
for (i = 0; i < ob->numsides; i++)
|
||||
{
|
||||
plane = &mapplanes[ob->original_sides[i].planenum];
|
||||
w = BaseWindingForPlane(plane->normal, plane->dist);
|
||||
for (j = 0; j <ob->numsides && w; j++)
|
||||
{
|
||||
if (i == j) continue;
|
||||
if (ob->original_sides[j].flags & SFL_BEVEL) continue;
|
||||
plane = &mapplanes[ob->original_sides[j].planenum^1];
|
||||
ChopWindingInPlace(&w, plane->normal, plane->dist, 0); //CLIP_EPSILON);
|
||||
}
|
||||
|
||||
side = &ob->original_sides[i];
|
||||
side->winding = w;
|
||||
if (w)
|
||||
{
|
||||
side->flags |= SFL_VISIBLE;
|
||||
for (j = 0; j < w->numpoints; j++)
|
||||
AddPointToBounds (w->p[j], ob->mins, ob->maxs);
|
||||
}
|
||||
}
|
||||
//check if the brush is convex
|
||||
for (i = 0; i < ob->numsides; i++)
|
||||
{
|
||||
for (j = 0; j < ob->numsides; j++)
|
||||
{
|
||||
if (i == j) continue;
|
||||
plane1 = &mapplanes[ob->original_sides[i].planenum];
|
||||
plane2 = &mapplanes[ob->original_sides[j].planenum];
|
||||
if (WindingsNonConvex(ob->original_sides[i].winding,
|
||||
ob->original_sides[j].winding,
|
||||
plane1->normal, plane2->normal,
|
||||
plane1->dist, plane2->dist))
|
||||
{
|
||||
Log_Print("non convex brush");
|
||||
} //end if
|
||||
} //end for
|
||||
} //end for
|
||||
//check for out of bound brushes
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
//IDBUG: all the indexes into the mins and maxs were zero (not using i)
|
||||
if (ob->mins[i] < -MAX_MAP_BOUNDS || ob->maxs[i] > MAX_MAP_BOUNDS)
|
||||
{
|
||||
Log_Print("entity %i, brush %i: bounds out of range\n", ob->entitynum, ob->brushnum);
|
||||
Log_Print("ob->mins[%d] = %f, ob->maxs[%d] = %f\n", i, ob->mins[i], i, ob->maxs[i]);
|
||||
ob->numsides = 0; //remove the brush
|
||||
break;
|
||||
} //end if
|
||||
if (ob->mins[i] > MAX_MAP_BOUNDS || ob->maxs[i] < -MAX_MAP_BOUNDS)
|
||||
{
|
||||
Log_Print("entity %i, brush %i: no visible sides on brush\n", ob->entitynum, ob->brushnum);
|
||||
Log_Print("ob->mins[%d] = %f, ob->maxs[%d] = %f\n", i, ob->mins[i], i, ob->maxs[i]);
|
||||
ob->numsides = 0; //remove the brush
|
||||
break;
|
||||
} //end if
|
||||
} //end for
|
||||
return true;
|
||||
} //end of the function AAS_MakeBrushWindings
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
mapbrush_t *AAS_CopyMapBrush(mapbrush_t *brush, entity_t *mapent)
|
||||
{
|
||||
int n;
|
||||
mapbrush_t *newbrush;
|
||||
side_t *side, *newside;
|
||||
|
||||
if (nummapbrushes >= MAX_MAPFILE_BRUSHES)
|
||||
Error ("MAX_MAPFILE_BRUSHES");
|
||||
|
||||
newbrush = &mapbrushes[nummapbrushes];
|
||||
newbrush->original_sides = &brushsides[nummapbrushsides];
|
||||
newbrush->entitynum = brush->entitynum;
|
||||
newbrush->brushnum = nummapbrushes - mapent->firstbrush;
|
||||
newbrush->numsides = brush->numsides;
|
||||
newbrush->contents = brush->contents;
|
||||
|
||||
//copy the sides
|
||||
for (n = 0; n < brush->numsides; n++)
|
||||
{
|
||||
if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
|
||||
Error ("MAX_MAPFILE_BRUSHSIDES");
|
||||
side = brush->original_sides + n;
|
||||
|
||||
newside = newbrush->original_sides + n;
|
||||
newside->original = NULL;
|
||||
newside->winding = NULL;
|
||||
newside->contents = side->contents;
|
||||
newside->flags = side->flags;
|
||||
newside->surf = side->surf;
|
||||
newside->planenum = side->planenum;
|
||||
newside->texinfo = side->texinfo;
|
||||
nummapbrushsides++;
|
||||
} //end for
|
||||
//
|
||||
nummapbrushes++;
|
||||
mapent->numbrushes++;
|
||||
return newbrush;
|
||||
} //end of the function AAS_CopyMapBrush
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int mark_entities[MAX_MAP_ENTITIES];
|
||||
|
||||
int AAS_AlwaysTriggered_r(char *targetname)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!strlen(targetname)) {
|
||||
return false;
|
||||
}
|
||||
//
|
||||
for (i = 0; i < num_entities; i++) {
|
||||
// if the entity will activate the given targetname
|
||||
if ( !strcmp(targetname, ValueForKey(&entities[i], "target")) ) {
|
||||
// if this activator is present in deathmatch
|
||||
if (!(atoi(ValueForKey(&entities[i], "spawnflags")) & SPAWNFLAG_NOT_DEATHMATCH)) {
|
||||
// if it is a trigger_always entity
|
||||
if (!strcmp("trigger_always", ValueForKey(&entities[i], "classname"))) {
|
||||
return true;
|
||||
}
|
||||
// check for possible trigger_always entities activating this entity
|
||||
if ( mark_entities[i] ) {
|
||||
Warning( "entity %d, classname %s has recursive targetname %s\n", i,
|
||||
ValueForKey(&entities[i], "classname"), targetname );
|
||||
return false;
|
||||
}
|
||||
mark_entities[i] = true;
|
||||
if ( AAS_AlwaysTriggered_r(ValueForKey(&entities[i], "targetname")) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int AAS_AlwaysTriggered(char *targetname) {
|
||||
memset( mark_entities, 0, sizeof(mark_entities) );
|
||||
return AAS_AlwaysTriggered_r( targetname );
|
||||
}
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_ValidEntity(entity_t *mapent)
|
||||
{
|
||||
int i;
|
||||
char target[1024];
|
||||
|
||||
//all world brushes are used for AAS
|
||||
if (mapent == &entities[0])
|
||||
{
|
||||
return true;
|
||||
} //end if
|
||||
//some of the func_wall brushes are also used for AAS
|
||||
else if (!strcmp("func_wall", ValueForKey(mapent, "classname")))
|
||||
{
|
||||
//Log_Print("found func_wall entity %d\n", mapent - entities);
|
||||
//if the func wall is used in deathmatch
|
||||
if (!(atoi(ValueForKey(mapent, "spawnflags")) & SPAWNFLAG_NOT_DEATHMATCH))
|
||||
{
|
||||
//Log_Print("func_wall USED in deathmatch mode %d\n", atoi(ValueForKey(mapent, "spawnflags")));
|
||||
return true;
|
||||
} //end if
|
||||
} //end else if
|
||||
else if (!strcmp("func_door_rotating", ValueForKey(mapent, "classname")))
|
||||
{
|
||||
//if the func_door_rotating is present in deathmatch
|
||||
if (!(atoi(ValueForKey(mapent, "spawnflags")) & SPAWNFLAG_NOT_DEATHMATCH))
|
||||
{
|
||||
//if the func_door_rotating is always activated in deathmatch
|
||||
if (AAS_AlwaysTriggered(ValueForKey(mapent, "targetname")))
|
||||
{
|
||||
//Log_Print("found func_door_rotating in deathmatch\ntargetname %s\n", ValueForKey(mapent, "targetname"));
|
||||
return true;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end else if
|
||||
else if (!strcmp("trigger_hurt", ValueForKey(mapent, "classname")))
|
||||
{
|
||||
//"dmg" is the damage, for instance: "dmg" "666"
|
||||
return true;
|
||||
} //end else if
|
||||
else if (!strcmp("trigger_push", ValueForKey(mapent, "classname")))
|
||||
{
|
||||
return true;
|
||||
} //end else if
|
||||
else if (!strcmp("trigger_multiple", ValueForKey(mapent, "classname")))
|
||||
{
|
||||
//find out if the trigger_multiple is pointing to a target_teleporter
|
||||
strcpy(target, ValueForKey(mapent, "target"));
|
||||
for (i = 0; i < num_entities; i++)
|
||||
{
|
||||
//if the entity will activate the given targetname
|
||||
if (!strcmp(target, ValueForKey(&entities[i], "targetname")))
|
||||
{
|
||||
if (!strcmp("target_teleporter", ValueForKey(&entities[i], "classname")))
|
||||
{
|
||||
return true;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end for
|
||||
} //end else if
|
||||
else if (!strcmp("trigger_teleport", ValueForKey(mapent, "classname")))
|
||||
{
|
||||
return true;
|
||||
} //end else if
|
||||
else if (!strcmp("func_static", ValueForKey(mapent, "classname")))
|
||||
{
|
||||
//FIXME: easy/medium/hard/deathmatch specific?
|
||||
return true;
|
||||
} //end else if
|
||||
else if (!strcmp("func_door", ValueForKey(mapent, "classname")))
|
||||
{
|
||||
return true;
|
||||
} //end else if
|
||||
return false;
|
||||
} //end of the function AAS_ValidEntity
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_TransformPlane(int planenum, vec3_t origin, vec3_t angles)
|
||||
{
|
||||
float newdist, matrix[3][3];
|
||||
vec3_t normal;
|
||||
|
||||
//rotate the node plane
|
||||
VectorCopy(mapplanes[planenum].normal, normal);
|
||||
CreateRotationMatrix(angles, matrix);
|
||||
RotatePoint(normal, matrix);
|
||||
newdist = mapplanes[planenum].dist + DotProduct(normal, origin);
|
||||
return FindFloatPlane(normal, newdist);
|
||||
} //end of the function AAS_TransformPlane
|
||||
//===========================================================================
|
||||
// this function sets the func_rotating_door in it's final position
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_PositionFuncRotatingBrush(entity_t *mapent, mapbrush_t *brush)
|
||||
{
|
||||
int spawnflags, i;
|
||||
float distance;
|
||||
vec3_t movedir, angles, pos1, pos2;
|
||||
side_t *s;
|
||||
|
||||
spawnflags = FloatForKey(mapent, "spawnflags");
|
||||
VectorClear(movedir);
|
||||
if (spawnflags & DOOR_X_AXIS)
|
||||
movedir[2] = 1.0; //roll
|
||||
else if (spawnflags & DOOR_Y_AXIS)
|
||||
movedir[0] = 1.0; //pitch
|
||||
else // Z_AXIS
|
||||
movedir[1] = 1.0; //yaw
|
||||
|
||||
// check for reverse rotation
|
||||
if (spawnflags & DOOR_REVERSE)
|
||||
VectorInverse(movedir);
|
||||
|
||||
distance = FloatForKey(mapent, "distance");
|
||||
if (!distance) distance = 90;
|
||||
|
||||
GetVectorForKey(mapent, "angles", angles);
|
||||
VectorCopy(angles, pos1);
|
||||
VectorMA(angles, -distance, movedir, pos2);
|
||||
// if it starts open, switch the positions
|
||||
if (spawnflags & DOOR_START_OPEN)
|
||||
{
|
||||
VectorCopy(pos2, angles);
|
||||
VectorCopy(pos1, pos2);
|
||||
VectorCopy(angles, pos1);
|
||||
VectorInverse(movedir);
|
||||
} //end if
|
||||
//
|
||||
for (i = 0; i < brush->numsides; i++)
|
||||
{
|
||||
s = &brush->original_sides[i];
|
||||
s->planenum = AAS_TransformPlane(s->planenum, mapent->origin, pos2);
|
||||
} //end for
|
||||
//
|
||||
FreeBrushWindings(brush);
|
||||
AAS_MakeBrushWindings(brush);
|
||||
AddBrushBevels(brush);
|
||||
FreeBrushWindings(brush);
|
||||
} //end of the function AAS_PositionFuncRotatingBrush
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_PositionBrush(entity_t *mapent, mapbrush_t *brush)
|
||||
{
|
||||
side_t *s;
|
||||
float newdist;
|
||||
int i, notteam;
|
||||
char *model;
|
||||
|
||||
if (!strcmp(ValueForKey(mapent, "classname"), "func_door_rotating"))
|
||||
{
|
||||
AAS_PositionFuncRotatingBrush(mapent, brush);
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if (mapent->origin[0] || mapent->origin[1] || mapent->origin[2])
|
||||
{
|
||||
for (i = 0; i < brush->numsides; i++)
|
||||
{
|
||||
s = &brush->original_sides[i];
|
||||
newdist = mapplanes[s->planenum].dist +
|
||||
DotProduct(mapplanes[s->planenum].normal, mapent->origin);
|
||||
s->planenum = FindFloatPlane(mapplanes[s->planenum].normal, newdist);
|
||||
} //end for
|
||||
} //end if
|
||||
//if it's a trigger hurt
|
||||
if (!strcmp("trigger_hurt", ValueForKey(mapent, "classname")))
|
||||
{
|
||||
notteam = FloatForKey(mapent, "bot_notteam");
|
||||
if ( notteam == 1 ) {
|
||||
brush->contents |= CONTENTS_NOTTEAM1;
|
||||
}
|
||||
else if ( notteam == 2 ) {
|
||||
brush->contents |= CONTENTS_NOTTEAM2;
|
||||
}
|
||||
else {
|
||||
// always avoid so set lava contents
|
||||
brush->contents |= CONTENTS_LAVA;
|
||||
}
|
||||
} //end if
|
||||
//
|
||||
else if (!strcmp("trigger_push", ValueForKey(mapent, "classname")))
|
||||
{
|
||||
//set the jumppad contents
|
||||
brush->contents = CONTENTS_JUMPPAD;
|
||||
//Log_Print("found trigger_push brush\n");
|
||||
} //end if
|
||||
//
|
||||
else if (!strcmp("trigger_multiple", ValueForKey(mapent, "classname")))
|
||||
{
|
||||
//set teleporter contents
|
||||
brush->contents = CONTENTS_TELEPORTER;
|
||||
//Log_Print("found trigger_multiple teleporter brush\n");
|
||||
} //end if
|
||||
//
|
||||
else if (!strcmp("trigger_teleport", ValueForKey(mapent, "classname")))
|
||||
{
|
||||
//set teleporter contents
|
||||
brush->contents = CONTENTS_TELEPORTER;
|
||||
//Log_Print("found trigger_teleport teleporter brush\n");
|
||||
} //end if
|
||||
else if (!strcmp("func_door", ValueForKey(mapent, "classname")))
|
||||
{
|
||||
//set mover contents
|
||||
brush->contents = CONTENTS_MOVER;
|
||||
//get the model number
|
||||
model = ValueForKey(mapent, "model");
|
||||
brush->modelnum = atoi(model+1);
|
||||
} //end if
|
||||
} //end else
|
||||
} //end of the function AAS_PositionBrush
|
||||
//===========================================================================
|
||||
// uses the global cfg_t cfg
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_CreateMapBrushes(mapbrush_t *brush, entity_t *mapent, int addbevels)
|
||||
{
|
||||
int i;
|
||||
//side_t *s;
|
||||
mapbrush_t *bboxbrushes[16];
|
||||
|
||||
//if the brushes are not from an entity used for AAS
|
||||
if (!AAS_ValidEntity(mapent))
|
||||
{
|
||||
nummapbrushsides -= brush->numsides;
|
||||
brush->numsides = 0;
|
||||
return;
|
||||
} //end if
|
||||
//
|
||||
AAS_PositionBrush(mapent, brush);
|
||||
//from all normal solid brushes only the textured brush sides will
|
||||
//be used as bsp splitters, so set the right texinfo reference here
|
||||
AAS_SetTexinfo(brush);
|
||||
//remove contents detail flag, otherwise player clip contents won't be
|
||||
//bsped correctly for AAS!
|
||||
brush->contents &= ~CONTENTS_DETAIL;
|
||||
//if the brush has contents area portal it should be the only contents
|
||||
if (brush->contents & (CONTENTS_AREAPORTAL|CONTENTS_CLUSTERPORTAL))
|
||||
{
|
||||
brush->contents = CONTENTS_CLUSTERPORTAL;
|
||||
brush->leafnum = -1;
|
||||
} //end if
|
||||
//window and playerclip are used for player clipping, make them solid
|
||||
if (brush->contents & (CONTENTS_WINDOW | CONTENTS_PLAYERCLIP))
|
||||
{
|
||||
//
|
||||
brush->contents &= ~(CONTENTS_WINDOW | CONTENTS_PLAYERCLIP);
|
||||
brush->contents |= CONTENTS_SOLID;
|
||||
brush->leafnum = -1;
|
||||
} //end if
|
||||
//
|
||||
if (brush->contents & CONTENTS_BOTCLIP)
|
||||
{
|
||||
brush->contents = CONTENTS_SOLID;
|
||||
brush->leafnum = -1;
|
||||
} //end if
|
||||
//
|
||||
//Log_Write("brush %d contents = ", brush->brushnum);
|
||||
//PrintContents(brush->contents);
|
||||
//Log_Write("\r\n");
|
||||
//if not one of the following brushes then the brush is NOT used for AAS
|
||||
if (!(brush->contents & (CONTENTS_SOLID
|
||||
| CONTENTS_LADDER
|
||||
| CONTENTS_CLUSTERPORTAL
|
||||
| CONTENTS_DONOTENTER
|
||||
| CONTENTS_TELEPORTER
|
||||
| CONTENTS_JUMPPAD
|
||||
| CONTENTS_WATER
|
||||
| CONTENTS_LAVA
|
||||
| CONTENTS_SLIME
|
||||
| CONTENTS_MOVER
|
||||
)))
|
||||
{
|
||||
nummapbrushsides -= brush->numsides;
|
||||
brush->numsides = 0;
|
||||
return;
|
||||
} //end if
|
||||
//fix the map brush
|
||||
//AAS_FixMapBrush(brush);
|
||||
//if brush bevels should be added (for real map brushes, not bsp map brushes)
|
||||
if (addbevels)
|
||||
{
|
||||
//NOTE: we first have to get the mins and maxs of the brush before
|
||||
// creating the brush bevels... the mins and maxs are used to
|
||||
// create them. so we call MakeBrushWindings to get the mins
|
||||
// and maxs and then after creating the bevels we free the
|
||||
// windings because they are created for all sides (including
|
||||
// bevels) a little later
|
||||
AAS_MakeBrushWindings(brush);
|
||||
AddBrushBevels(brush);
|
||||
FreeBrushWindings(brush);
|
||||
} //end if
|
||||
//NOTE: add the brush to the WORLD entity!!!
|
||||
mapent = &entities[0];
|
||||
//there's at least one new brush for now
|
||||
nummapbrushes++;
|
||||
mapent->numbrushes++;
|
||||
//liquid brushes are expanded for the maximum possible bounding box
|
||||
if (brush->contents & (CONTENTS_WATER
|
||||
| CONTENTS_LAVA
|
||||
| CONTENTS_SLIME
|
||||
| CONTENTS_TELEPORTER
|
||||
| CONTENTS_JUMPPAD
|
||||
| CONTENTS_DONOTENTER
|
||||
| CONTENTS_MOVER
|
||||
))
|
||||
{
|
||||
brush->expansionbbox = 0;
|
||||
//NOTE: the first bounding box is the max
|
||||
//FIXME: use max bounding box created from all bboxes
|
||||
AAS_ExpandMapBrush(brush, cfg.bboxes[0].mins, cfg.bboxes[0].maxs);
|
||||
AAS_MakeBrushWindings(brush);
|
||||
} //end if
|
||||
//area portal brushes are NOT expanded
|
||||
else if (brush->contents & CONTENTS_CLUSTERPORTAL)
|
||||
{
|
||||
brush->expansionbbox = 0;
|
||||
//NOTE: the first bounding box is the max
|
||||
//FIXME: use max bounding box created from all bboxes
|
||||
AAS_ExpandMapBrush(brush, cfg.bboxes[0].mins, cfg.bboxes[0].maxs);
|
||||
AAS_MakeBrushWindings(brush);
|
||||
} //end if
|
||||
//all solid brushes are expanded for all bounding boxes
|
||||
else if (brush->contents & (CONTENTS_SOLID
|
||||
| CONTENTS_LADDER
|
||||
))
|
||||
{
|
||||
//brush for the first bounding box
|
||||
bboxbrushes[0] = brush;
|
||||
//make a copy for the other bounding boxes
|
||||
for (i = 1; i < cfg.numbboxes; i++)
|
||||
{
|
||||
bboxbrushes[i] = AAS_CopyMapBrush(brush, mapent);
|
||||
} //end for
|
||||
//expand every brush for it's bounding box and create windings
|
||||
for (i = 0; i < cfg.numbboxes; i++)
|
||||
{
|
||||
AAS_ExpandMapBrush(bboxbrushes[i], cfg.bboxes[i].mins, cfg.bboxes[i].maxs);
|
||||
bboxbrushes[i]->expansionbbox = cfg.bboxes[i].presencetype;
|
||||
AAS_MakeBrushWindings(bboxbrushes[i]);
|
||||
} //end for
|
||||
} //end else
|
||||
} //end of the function AAS_CreateMapBrushes
|
23
tools/quake3/bspc/aas_map.h
Normal file
23
tools/quake3/bspc/aas_map.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
void AAS_CreateMapBrushes(mapbrush_t *brush, entity_t *mapent, int addbevels);
|
89
tools/quake3/bspc/aas_prunenodes.c
Normal file
89
tools/quake3/bspc/aas_prunenodes.c
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "qbsp.h"
|
||||
#include "botlib/aasfile.h"
|
||||
#include "aas_create.h"
|
||||
|
||||
int c_numprunes;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
tmp_node_t *AAS_PruneNodes_r(tmp_node_t *tmpnode)
|
||||
{
|
||||
tmp_area_t *tmparea1, *tmparea2;
|
||||
|
||||
//if it is a solid leaf
|
||||
if (!tmpnode) return NULL;
|
||||
//
|
||||
if (tmpnode->tmparea) return tmpnode;
|
||||
//process the children first
|
||||
tmpnode->children[0] = AAS_PruneNodes_r(tmpnode->children[0]);
|
||||
tmpnode->children[1] = AAS_PruneNodes_r(tmpnode->children[1]);
|
||||
//if both children are areas
|
||||
if (tmpnode->children[0] && tmpnode->children[1] &&
|
||||
tmpnode->children[0]->tmparea && tmpnode->children[1]->tmparea)
|
||||
{
|
||||
tmparea1 = tmpnode->children[0]->tmparea;
|
||||
while(tmparea1->mergedarea) tmparea1 = tmparea1->mergedarea;
|
||||
|
||||
tmparea2 = tmpnode->children[1]->tmparea;
|
||||
while(tmparea2->mergedarea) tmparea2 = tmparea2->mergedarea;
|
||||
|
||||
if (tmparea1 == tmparea2)
|
||||
{
|
||||
c_numprunes++;
|
||||
tmpnode->tmparea = tmparea1;
|
||||
tmpnode->planenum = 0;
|
||||
AAS_FreeTmpNode(tmpnode->children[0]);
|
||||
AAS_FreeTmpNode(tmpnode->children[1]);
|
||||
tmpnode->children[0] = NULL;
|
||||
tmpnode->children[1] = NULL;
|
||||
return tmpnode;
|
||||
} //end if
|
||||
} //end if
|
||||
//if both solid leafs
|
||||
if (!tmpnode->children[0] && !tmpnode->children[1])
|
||||
{
|
||||
c_numprunes++;
|
||||
AAS_FreeTmpNode(tmpnode);
|
||||
return NULL;
|
||||
} //end if
|
||||
//
|
||||
return tmpnode;
|
||||
} //end of the function AAS_PruneNodes_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_PruneNodes(void)
|
||||
{
|
||||
Log_Write("AAS_PruneNodes\r\n");
|
||||
AAS_PruneNodes_r(tmpaasworld.nodes);
|
||||
Log_Print("%6d nodes pruned\r\n", c_numprunes);
|
||||
} //end of the function AAS_PruneNodes
|
24
tools/quake3/bspc/aas_prunenodes.h
Normal file
24
tools/quake3/bspc/aas_prunenodes.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
void AAS_PruneNodes(void);
|
||||
|
1082
tools/quake3/bspc/aas_store.c
Normal file
1082
tools/quake3/bspc/aas_store.c
Normal file
File diff suppressed because it is too large
Load diff
107
tools/quake3/bspc/aas_store.h
Normal file
107
tools/quake3/bspc/aas_store.h
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#define AAS_MAX_BBOXES 5
|
||||
#define AAS_MAX_VERTEXES 512000
|
||||
#define AAS_MAX_PLANES 65536
|
||||
#define AAS_MAX_EDGES 512000
|
||||
#define AAS_MAX_EDGEINDEXSIZE 512000
|
||||
#define AAS_MAX_FACES 512000
|
||||
#define AAS_MAX_FACEINDEXSIZE 512000
|
||||
#define AAS_MAX_AREAS 65536
|
||||
#define AAS_MAX_AREASETTINGS 65536
|
||||
#define AAS_MAX_REACHABILITYSIZE 65536
|
||||
#define AAS_MAX_NODES 256000
|
||||
#define AAS_MAX_PORTALS 65536
|
||||
#define AAS_MAX_PORTALINDEXSIZE 65536
|
||||
#define AAS_MAX_CLUSTERS 65536
|
||||
|
||||
#define BSPCINCLUDE
|
||||
#include "deps/botlib/be_aas.h"
|
||||
#include "deps/botlib/be_aas_def.h"
|
||||
|
||||
/*
|
||||
typedef struct bspc_aas_s
|
||||
{
|
||||
int loaded;
|
||||
int initialized; //true when AAS has been initialized
|
||||
int savefile; //set true when file should be saved
|
||||
//bounding boxes
|
||||
int numbboxes;
|
||||
aas_bbox_t *bboxes;
|
||||
//vertexes
|
||||
int numvertexes;
|
||||
aas_vertex_t *vertexes;
|
||||
//planes
|
||||
int numplanes;
|
||||
aas_plane_t *planes;
|
||||
//edges
|
||||
int numedges;
|
||||
aas_edge_t *edges;
|
||||
//edge index
|
||||
int edgeindexsize;
|
||||
aas_edgeindex_t *edgeindex;
|
||||
//faces
|
||||
int numfaces;
|
||||
aas_face_t *faces;
|
||||
//face index
|
||||
int faceindexsize;
|
||||
aas_faceindex_t *faceindex;
|
||||
//convex areas
|
||||
int numareas;
|
||||
aas_area_t *areas;
|
||||
//convex area settings
|
||||
int numareasettings;
|
||||
aas_areasettings_t *areasettings;
|
||||
//reachablity list
|
||||
int reachabilitysize;
|
||||
aas_reachability_t *reachability;
|
||||
//nodes of the bsp tree
|
||||
int numnodes;
|
||||
aas_node_t *nodes;
|
||||
//cluster portals
|
||||
int numportals;
|
||||
aas_portal_t *portals;
|
||||
//cluster portal index
|
||||
int portalindexsize;
|
||||
aas_portalindex_t *portalindex;
|
||||
//clusters
|
||||
int numclusters;
|
||||
aas_cluster_t *clusters;
|
||||
//
|
||||
int numreachabilityareas;
|
||||
float reachabilitytime;
|
||||
} bspc_aas_t;
|
||||
|
||||
extern bspc_aas_t aasworld;
|
||||
//*/
|
||||
|
||||
extern aas_t aasworld;
|
||||
|
||||
//stores the AAS file from the temporary AAS
|
||||
void AAS_StoreFile(char *filename);
|
||||
//returns a number of the given plane
|
||||
qboolean AAS_FindPlane(vec3_t normal, float dist, int *planenum);
|
||||
//allocates the maximum AAS memory for storage
|
||||
void AAS_AllocMaxAAS(void);
|
||||
//frees the maximum AAS memory for storage
|
||||
void AAS_FreeMaxAAS(void);
|
252
tools/quake3/bspc/aasfile.h
Normal file
252
tools/quake3/bspc/aasfile.h
Normal file
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
|
||||
//NOTE: int = default signed
|
||||
// default long
|
||||
|
||||
#define AASID (('S'<<24)+('A'<<16)+('A'<<8)+'E')
|
||||
#define AASVERSION_OLD 4
|
||||
#define AASVERSION 5
|
||||
|
||||
//presence types
|
||||
#define PRESENCE_NONE 1
|
||||
#define PRESENCE_NORMAL 2
|
||||
#define PRESENCE_CROUCH 4
|
||||
|
||||
//travel types
|
||||
#define MAX_TRAVELTYPES 32
|
||||
#define TRAVEL_INVALID 1 //temporary not possible
|
||||
#define TRAVEL_WALK 2 //walking
|
||||
#define TRAVEL_CROUCH 3 //crouching
|
||||
#define TRAVEL_BARRIERJUMP 4 //jumping onto a barrier
|
||||
#define TRAVEL_JUMP 5 //jumping
|
||||
#define TRAVEL_LADDER 6 //climbing a ladder
|
||||
#define TRAVEL_WALKOFFLEDGE 7 //walking of a ledge
|
||||
#define TRAVEL_SWIM 8 //swimming
|
||||
#define TRAVEL_WATERJUMP 9 //jump out of the water
|
||||
#define TRAVEL_TELEPORT 10 //teleportation
|
||||
#define TRAVEL_ELEVATOR 11 //travel by elevator
|
||||
#define TRAVEL_ROCKETJUMP 12 //rocket jumping required for travel
|
||||
#define TRAVEL_BFGJUMP 13 //bfg jumping required for travel
|
||||
#define TRAVEL_GRAPPLEHOOK 14 //grappling hook required for travel
|
||||
#define TRAVEL_DOUBLEJUMP 15 //double jump
|
||||
#define TRAVEL_RAMPJUMP 16 //ramp jump
|
||||
#define TRAVEL_STRAFEJUMP 17 //strafe jump
|
||||
#define TRAVEL_JUMPPAD 18 //jump pad
|
||||
#define TRAVEL_FUNCBOB 19 //func bob
|
||||
|
||||
//face flags
|
||||
#define FACE_SOLID 1 //just solid at the other side
|
||||
#define FACE_LADDER 2 //ladder
|
||||
#define FACE_GROUND 4 //standing on ground when in this face
|
||||
#define FACE_GAP 8 //gap in the ground
|
||||
#define FACE_LIQUID 16
|
||||
#define FACE_LIQUIDSURFACE 32
|
||||
|
||||
//area contents
|
||||
#define AREACONTENTS_WATER 1
|
||||
#define AREACONTENTS_LAVA 2
|
||||
#define AREACONTENTS_SLIME 4
|
||||
#define AREACONTENTS_CLUSTERPORTAL 8
|
||||
#define AREACONTENTS_TELEPORTAL 16
|
||||
#define AREACONTENTS_ROUTEPORTAL 32
|
||||
#define AREACONTENTS_TELEPORTER 64
|
||||
#define AREACONTENTS_JUMPPAD 128
|
||||
#define AREACONTENTS_DONOTENTER 256
|
||||
#define AREACONTENTS_VIEWPORTAL 512
|
||||
|
||||
//area flags
|
||||
#define AREA_GROUNDED 1 //bot can stand on the ground
|
||||
#define AREA_LADDER 2 //area contains one or more ladder faces
|
||||
#define AREA_LIQUID 4 //area contains a liquid
|
||||
|
||||
//aas file header lumps
|
||||
#define AAS_LUMPS 14
|
||||
#define AASLUMP_BBOXES 0
|
||||
#define AASLUMP_VERTEXES 1
|
||||
#define AASLUMP_PLANES 2
|
||||
#define AASLUMP_EDGES 3
|
||||
#define AASLUMP_EDGEINDEX 4
|
||||
#define AASLUMP_FACES 5
|
||||
#define AASLUMP_FACEINDEX 6
|
||||
#define AASLUMP_AREAS 7
|
||||
#define AASLUMP_AREASETTINGS 8
|
||||
#define AASLUMP_REACHABILITY 9
|
||||
#define AASLUMP_NODES 10
|
||||
#define AASLUMP_PORTALS 11
|
||||
#define AASLUMP_PORTALINDEX 12
|
||||
#define AASLUMP_CLUSTERS 13
|
||||
|
||||
//========== bounding box =========
|
||||
|
||||
//bounding box
|
||||
typedef struct aas_bbox_s
|
||||
{
|
||||
int presencetype;
|
||||
int flags;
|
||||
vec3_t mins, maxs;
|
||||
} aas_bbox_t;
|
||||
|
||||
//============ settings ===========
|
||||
|
||||
//reachability to another area
|
||||
typedef struct aas_reachability_s
|
||||
{
|
||||
int areanum; //number of the reachable area
|
||||
int facenum; //number of the face towards the other area
|
||||
int edgenum; //number of the edge towards the other area
|
||||
vec3_t start; //start point of inter area movement
|
||||
vec3_t end; //end point of inter area movement
|
||||
int traveltype; //type of travel required to get to the area
|
||||
unsigned short int traveltime;//travel time of the inter area movement
|
||||
} aas_reachability_t;
|
||||
|
||||
//area settings
|
||||
typedef struct aas_areasettings_s
|
||||
{
|
||||
//could also add all kind of statistic fields
|
||||
int contents; //contents of the convex area
|
||||
int areaflags; //several area flags
|
||||
int presencetype; //how a bot can be present in this convex area
|
||||
int cluster; //cluster the area belongs to, if negative it's a portal
|
||||
int clusterareanum; //number of the area in the cluster
|
||||
int numreachableareas; //number of reachable areas from this one
|
||||
int firstreachablearea; //first reachable area in the reachable area index
|
||||
} aas_areasettings_t;
|
||||
|
||||
//cluster portal
|
||||
typedef struct aas_portal_s
|
||||
{
|
||||
int areanum; //area that is the actual portal
|
||||
int frontcluster; //cluster at front of portal
|
||||
int backcluster; //cluster at back of portal
|
||||
int clusterareanum[2]; //number of the area in the front and back cluster
|
||||
} aas_portal_t;
|
||||
|
||||
//cluster portal index
|
||||
typedef int aas_portalindex_t;
|
||||
|
||||
//cluster
|
||||
typedef struct aas_cluster_s
|
||||
{
|
||||
int numareas; //number of areas in the cluster
|
||||
int numreachabilityareas; //number of areas with reachabilities
|
||||
int numportals; //number of cluster portals
|
||||
int firstportal; //first cluster portal in the index
|
||||
} aas_cluster_t;
|
||||
|
||||
//============ 3d definition ============
|
||||
|
||||
typedef vec3_t aas_vertex_t;
|
||||
|
||||
//just a plane in the third dimension
|
||||
typedef struct aas_plane_s
|
||||
{
|
||||
vec3_t normal; //normal vector of the plane
|
||||
float dist; //distance of the plane (normal vector * distance = point in plane)
|
||||
int type;
|
||||
} aas_plane_t;
|
||||
|
||||
//edge
|
||||
typedef struct aas_edge_s
|
||||
{
|
||||
int v[2]; //numbers of the vertexes of this edge
|
||||
} aas_edge_t;
|
||||
|
||||
//edge index, negative if vertexes are reversed
|
||||
typedef int aas_edgeindex_t;
|
||||
|
||||
//a face bounds a convex area, often it will also seperate two convex areas
|
||||
typedef struct aas_face_s
|
||||
{
|
||||
int planenum; //number of the plane this face is in
|
||||
int faceflags; //face flags (no use to create face settings for just this field)
|
||||
int numedges; //number of edges in the boundary of the face
|
||||
int firstedge; //first edge in the edge index
|
||||
int frontarea; //convex area at the front of this face
|
||||
int backarea; //convex area at the back of this face
|
||||
} aas_face_t;
|
||||
|
||||
//face index, stores a negative index if backside of face
|
||||
typedef int aas_faceindex_t;
|
||||
|
||||
//convex area with a boundary of faces
|
||||
typedef struct aas_area_s
|
||||
{
|
||||
int areanum; //number of this area
|
||||
//3d definition
|
||||
int numfaces; //number of faces used for the boundary of the convex area
|
||||
int firstface; //first face in the face index used for the boundary of the convex area
|
||||
vec3_t mins; //mins of the convex area
|
||||
vec3_t maxs; //maxs of the convex area
|
||||
vec3_t center; //'center' of the convex area
|
||||
} aas_area_t;
|
||||
|
||||
//nodes of the bsp tree
|
||||
typedef struct aas_node_s
|
||||
{
|
||||
int planenum;
|
||||
int children[2]; //child nodes of this node, or convex areas as leaves when negative
|
||||
//when a child is zero it's a solid leaf
|
||||
} aas_node_t;
|
||||
|
||||
//=========== aas file ===============
|
||||
|
||||
//header lump
|
||||
typedef struct
|
||||
{
|
||||
int fileofs;
|
||||
int filelen;
|
||||
} aas_lump_t;
|
||||
|
||||
//aas file header
|
||||
typedef struct aas_header_s
|
||||
{
|
||||
int ident;
|
||||
int version;
|
||||
int bspchecksum;
|
||||
//data entries
|
||||
aas_lump_t lumps[AAS_LUMPS];
|
||||
} aas_header_t;
|
||||
|
||||
|
||||
//====== additional information ======
|
||||
/*
|
||||
|
||||
- when a node child is a solid leaf the node child number is zero
|
||||
- two adjacent areas (sharing a plane at opposite sides) share a face
|
||||
this face is a portal between the areas
|
||||
- when an area uses a face from the faceindex with a positive index
|
||||
then the face plane normal points into the area
|
||||
- the face edges are stored counter clockwise using the edgeindex
|
||||
- two adjacent convex areas (sharing a face) only share One face
|
||||
this is a simple result of the areas being convex
|
||||
- the convex areas can't have a mixture of ground and gap faces
|
||||
other mixtures of faces in one area are allowed
|
||||
- areas with the AREACONTENTS_CLUSTERPORTAL in the settings have
|
||||
cluster number zero
|
||||
- edge zero is a dummy
|
||||
- face zero is a dummy
|
||||
- area zero is a dummy
|
||||
- node zero is a dummy
|
||||
*/
|
277
tools/quake3/bspc/be_aas_bspc.c
Normal file
277
tools/quake3/bspc/be_aas_bspc.c
Normal file
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "l_log.h"
|
||||
#include "l_qfiles.h"
|
||||
#include "botlib/l_memory.h"
|
||||
#include "botlib/l_script.h"
|
||||
#include "botlib/l_precomp.h"
|
||||
#include "botlib/l_struct.h"
|
||||
#include "botlib/aasfile.h"
|
||||
#include "botlib/botlib.h"
|
||||
#include "botlib/be_aas.h"
|
||||
#include "botlib/be_aas_def.h"
|
||||
#include "qcommon/cm_public.h"
|
||||
#include "be_aas_bspc.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
//#define BSPC
|
||||
|
||||
extern botlib_import_t botimport;
|
||||
extern qboolean capsule_collision;
|
||||
|
||||
botlib_import_t botimport;
|
||||
clipHandle_t worldmodel;
|
||||
|
||||
void Error (char *error, ...);
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_Error(char *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char text[1024];
|
||||
|
||||
va_start(argptr, fmt);
|
||||
vsprintf(text, fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
Error(text);
|
||||
} //end of the function AAS_Error
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int Sys_MilliSeconds(void)
|
||||
{
|
||||
return clock() * 1000 / CLOCKS_PER_SEC;
|
||||
} //end of the function Sys_MilliSeconds
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_DebugLine(vec3_t start, vec3_t end, int color)
|
||||
{
|
||||
} //end of the function AAS_DebugLine
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ClearShownDebugLines(void)
|
||||
{
|
||||
} //end of the function AAS_ClearShownDebugLines
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
char *BotImport_BSPEntityData(void)
|
||||
{
|
||||
return CM_EntityString();
|
||||
} //end of the function AAS_GetEntityData
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void BotImport_Trace(bsp_trace_t *bsptrace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask)
|
||||
{
|
||||
trace_t result;
|
||||
|
||||
CM_BoxTrace(&result, start, end, mins, maxs, worldmodel, contentmask, capsule_collision);
|
||||
|
||||
bsptrace->allsolid = result.allsolid;
|
||||
bsptrace->contents = result.contents;
|
||||
VectorCopy(result.endpos, bsptrace->endpos);
|
||||
bsptrace->ent = result.entityNum;
|
||||
bsptrace->fraction = result.fraction;
|
||||
bsptrace->exp_dist = 0;
|
||||
bsptrace->plane.dist = result.plane.dist;
|
||||
VectorCopy(result.plane.normal, bsptrace->plane.normal);
|
||||
bsptrace->plane.signbits = result.plane.signbits;
|
||||
bsptrace->plane.type = result.plane.type;
|
||||
bsptrace->sidenum = 0;
|
||||
bsptrace->startsolid = result.startsolid;
|
||||
bsptrace->surface.flags = result.surfaceFlags;
|
||||
} //end of the function BotImport_Trace
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int BotImport_PointContents(vec3_t p)
|
||||
{
|
||||
return CM_PointContents(p, worldmodel);
|
||||
} //end of the function BotImport_PointContents
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void *BotImport_GetMemory(int size)
|
||||
{
|
||||
return GetMemory(size);
|
||||
} //end of the function BotImport_GetMemory
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void BotImport_Print(int type, char *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char buf[1024];
|
||||
|
||||
va_start(argptr, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, argptr);
|
||||
fputs(buf, stdout);
|
||||
if (buf[0] != '\r') Log_Write(buf);
|
||||
va_end(argptr);
|
||||
} //end of the function BotImport_Print
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void BotImport_BSPModelMinsMaxsOrigin(int modelnum, vec3_t angles, vec3_t outmins, vec3_t outmaxs, vec3_t origin)
|
||||
{
|
||||
clipHandle_t h;
|
||||
vec3_t mins, maxs;
|
||||
float max;
|
||||
int i;
|
||||
|
||||
h = CM_InlineModel(modelnum);
|
||||
CM_ModelBounds(h, mins, maxs);
|
||||
//if the model is rotated
|
||||
if ((angles[0] || angles[1] || angles[2]))
|
||||
{ // expand for rotation
|
||||
|
||||
max = RadiusFromBounds(mins, maxs);
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
mins[i] = (mins[i] + maxs[i]) * 0.5 - max;
|
||||
maxs[i] = (mins[i] + maxs[i]) * 0.5 + max;
|
||||
} //end for
|
||||
} //end if
|
||||
if (outmins) VectorCopy(mins, outmins);
|
||||
if (outmaxs) VectorCopy(maxs, outmaxs);
|
||||
if (origin) VectorClear(origin);
|
||||
} //end of the function BotImport_BSPModelMinsMaxsOrigin
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void Com_DPrintf(char *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char buf[1024];
|
||||
|
||||
va_start(argptr, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, argptr);
|
||||
fputs(buf, stdout);
|
||||
if (buf[0] != '\r') Log_Write(buf);
|
||||
va_end(argptr);
|
||||
} //end of the function Com_DPrintf
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int COM_Compress( char *data_p ) {
|
||||
return strlen(data_p);
|
||||
}
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_InitBotImport(void)
|
||||
{
|
||||
botimport.BSPEntityData = BotImport_BSPEntityData;
|
||||
botimport.GetMemory = BotImport_GetMemory;
|
||||
botimport.FreeMemory = FreeMemory;
|
||||
botimport.Trace = BotImport_Trace;
|
||||
botimport.PointContents = BotImport_PointContents;
|
||||
botimport.Print = BotImport_Print;
|
||||
botimport.BSPModelMinsMaxsOrigin = BotImport_BSPModelMinsMaxsOrigin;
|
||||
} //end of the function AAS_InitBotImport
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_CalcReachAndClusters(struct quakefile_s *qf)
|
||||
{
|
||||
float time;
|
||||
|
||||
Log_Print("loading collision map...\n");
|
||||
//
|
||||
if (!qf->pakfile[0]) strcpy(qf->pakfile, qf->filename);
|
||||
//load the map
|
||||
CM_LoadMap((char *) qf, qfalse, &aasworld.bspchecksum);
|
||||
//get a handle to the world model
|
||||
worldmodel = CM_InlineModel(0); // 0 = world, 1 + are bmodels
|
||||
//initialize bot import structure
|
||||
AAS_InitBotImport();
|
||||
//load the BSP entity string
|
||||
AAS_LoadBSPFile();
|
||||
//init physics settings
|
||||
AAS_InitSettings();
|
||||
//initialize AAS link heap
|
||||
AAS_InitAASLinkHeap();
|
||||
//initialize the AAS linked entities for the new map
|
||||
AAS_InitAASLinkedEntities();
|
||||
//reset all reachabilities and clusters
|
||||
aasworld.reachabilitysize = 0;
|
||||
aasworld.numclusters = 0;
|
||||
//set all view portals as cluster portals in case we re-calculate the reachabilities and clusters (with -reach)
|
||||
AAS_SetViewPortalsAsClusterPortals();
|
||||
//calculate reachabilities
|
||||
AAS_InitReachability();
|
||||
time = 0;
|
||||
while(AAS_ContinueInitReachability(time)) time++;
|
||||
//calculate clusters
|
||||
AAS_InitClustering();
|
||||
} //end of the function AAS_CalcReachAndClusters
|
23
tools/quake3/bspc/be_aas_bspc.h
Normal file
23
tools/quake3/bspc/be_aas_bspc.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
void AAS_CalcReachAndClusters(struct quakefile_s *qf);
|
1872
tools/quake3/bspc/brushbsp.c
Normal file
1872
tools/quake3/bspc/brushbsp.c
Normal file
File diff suppressed because it is too large
Load diff
1036
tools/quake3/bspc/bspc.c
Normal file
1036
tools/quake3/bspc/bspc.c
Normal file
File diff suppressed because it is too large
Load diff
19
tools/quake3/bspc/bspc.sln
Normal file
19
tools/quake3/bspc/bspc.sln
Normal file
|
@ -0,0 +1,19 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bspc", "bspc.vcproj", "{4E4EBC16-F345-4667-84E1-86633BAFDAE6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
1771
tools/quake3/bspc/bspc.vcproj
Normal file
1771
tools/quake3/bspc/bspc.vcproj
Normal file
File diff suppressed because it is too large
Load diff
84
tools/quake3/bspc/cfgq3.c
Normal file
84
tools/quake3/bspc/cfgq3.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
//===========================================================================
|
||||
// BSPC configuration file
|
||||
// Quake3
|
||||
//===========================================================================
|
||||
|
||||
#define PRESENCE_NONE 1
|
||||
#define PRESENCE_NORMAL 2
|
||||
#define PRESENCE_CROUCH 4
|
||||
|
||||
bbox //30x30x56
|
||||
{
|
||||
presencetype PRESENCE_NORMAL
|
||||
flags 0x0000
|
||||
mins {-15, -15, -24}
|
||||
maxs {15, 15, 32}
|
||||
} //end bbox
|
||||
|
||||
bbox //30x30x40
|
||||
{
|
||||
presencetype PRESENCE_CROUCH
|
||||
flags 0x0001
|
||||
mins {-15, -15, -24}
|
||||
maxs {15, 15, 16}
|
||||
} //end bbox
|
||||
|
||||
settings
|
||||
{
|
||||
phys_gravitydirection {0, 0, -1}
|
||||
phys_friction 6
|
||||
phys_stopspeed 100
|
||||
phys_gravity 800
|
||||
phys_waterfriction 1
|
||||
phys_watergravity 400
|
||||
phys_maxvelocity 320
|
||||
phys_maxwalkvelocity 320
|
||||
phys_maxcrouchvelocity 100
|
||||
phys_maxswimvelocity 150
|
||||
phys_maxacceleration 2200
|
||||
phys_airaccelerate 0
|
||||
phys_maxstep 18
|
||||
phys_maxsteepness 0.7
|
||||
phys_maxwaterjump 19
|
||||
phys_maxbarrier 33
|
||||
phys_jumpvel 270
|
||||
phys_falldelta5 40
|
||||
phys_falldelta10 60
|
||||
rs_waterjump 400
|
||||
rs_teleport 50
|
||||
rs_barrierjump 100
|
||||
rs_startcrouch 300
|
||||
rs_startgrapple 500
|
||||
rs_startwalkoffledge 70
|
||||
rs_startjump 300
|
||||
rs_rocketjump 500
|
||||
rs_bfgjump 500
|
||||
rs_jumppad 250
|
||||
rs_aircontrolledjumppad 300
|
||||
rs_funcbob 300
|
||||
rs_startelevator 50
|
||||
rs_falldamage5 300
|
||||
rs_falldamage10 500
|
||||
rs_maxjumpfallheight 450
|
||||
} //end settings
|
1005
tools/quake3/bspc/csg.c
Normal file
1005
tools/quake3/bspc/csg.c
Normal file
File diff suppressed because it is too large
Load diff
267
tools/quake3/bspc/deps/botlib/aasfile.h
Normal file
267
tools/quake3/bspc/deps/botlib/aasfile.h
Normal file
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
|
||||
//NOTE: int = default signed
|
||||
// default long
|
||||
|
||||
#define AASID (('S'<<24)+('A'<<16)+('A'<<8)+'E')
|
||||
#define AASVERSION_OLD 4
|
||||
#define AASVERSION 5
|
||||
|
||||
//presence types
|
||||
#define PRESENCE_NONE 1
|
||||
#define PRESENCE_NORMAL 2
|
||||
#define PRESENCE_CROUCH 4
|
||||
|
||||
//travel types
|
||||
#define MAX_TRAVELTYPES 32
|
||||
#define TRAVEL_INVALID 1 //temporary not possible
|
||||
#define TRAVEL_WALK 2 //walking
|
||||
#define TRAVEL_CROUCH 3 //crouching
|
||||
#define TRAVEL_BARRIERJUMP 4 //jumping onto a barrier
|
||||
#define TRAVEL_JUMP 5 //jumping
|
||||
#define TRAVEL_LADDER 6 //climbing a ladder
|
||||
#define TRAVEL_WALKOFFLEDGE 7 //walking of a ledge
|
||||
#define TRAVEL_SWIM 8 //swimming
|
||||
#define TRAVEL_WATERJUMP 9 //jump out of the water
|
||||
#define TRAVEL_TELEPORT 10 //teleportation
|
||||
#define TRAVEL_ELEVATOR 11 //travel by elevator
|
||||
#define TRAVEL_ROCKETJUMP 12 //rocket jumping required for travel
|
||||
#define TRAVEL_BFGJUMP 13 //bfg jumping required for travel
|
||||
#define TRAVEL_GRAPPLEHOOK 14 //grappling hook required for travel
|
||||
#define TRAVEL_DOUBLEJUMP 15 //double jump
|
||||
#define TRAVEL_RAMPJUMP 16 //ramp jump
|
||||
#define TRAVEL_STRAFEJUMP 17 //strafe jump
|
||||
#define TRAVEL_JUMPPAD 18 //jump pad
|
||||
#define TRAVEL_FUNCBOB 19 //func bob
|
||||
|
||||
//additional travel flags
|
||||
#define TRAVELTYPE_MASK 0xFFFFFF
|
||||
#define TRAVELFLAG_NOTTEAM1 (1 << 24)
|
||||
#define TRAVELFLAG_NOTTEAM2 (2 << 24)
|
||||
|
||||
//face flags
|
||||
#define FACE_SOLID 1 //just solid at the other side
|
||||
#define FACE_LADDER 2 //ladder
|
||||
#define FACE_GROUND 4 //standing on ground when in this face
|
||||
#define FACE_GAP 8 //gap in the ground
|
||||
#define FACE_LIQUID 16 //face seperating two areas with liquid
|
||||
#define FACE_LIQUIDSURFACE 32 //face seperating liquid and air
|
||||
#define FACE_BRIDGE 64 //can walk over this face if bridge is closed
|
||||
|
||||
//area contents
|
||||
#define AREACONTENTS_WATER 1
|
||||
#define AREACONTENTS_LAVA 2
|
||||
#define AREACONTENTS_SLIME 4
|
||||
#define AREACONTENTS_CLUSTERPORTAL 8
|
||||
#define AREACONTENTS_TELEPORTAL 16
|
||||
#define AREACONTENTS_ROUTEPORTAL 32
|
||||
#define AREACONTENTS_TELEPORTER 64
|
||||
#define AREACONTENTS_JUMPPAD 128
|
||||
#define AREACONTENTS_DONOTENTER 256
|
||||
#define AREACONTENTS_VIEWPORTAL 512
|
||||
#define AREACONTENTS_MOVER 1024
|
||||
#define AREACONTENTS_NOTTEAM1 2048
|
||||
#define AREACONTENTS_NOTTEAM2 4096
|
||||
//number of model of the mover inside this area
|
||||
#define AREACONTENTS_MODELNUMSHIFT 24
|
||||
#define AREACONTENTS_MAXMODELNUM 0xFF
|
||||
#define AREACONTENTS_MODELNUM (AREACONTENTS_MAXMODELNUM << AREACONTENTS_MODELNUMSHIFT)
|
||||
|
||||
//area flags
|
||||
#define AREA_GROUNDED 1 //bot can stand on the ground
|
||||
#define AREA_LADDER 2 //area contains one or more ladder faces
|
||||
#define AREA_LIQUID 4 //area contains a liquid
|
||||
#define AREA_DISABLED 8 //area is disabled for routing when set
|
||||
#define AREA_BRIDGE 16 //area ontop of a bridge
|
||||
|
||||
//aas file header lumps
|
||||
#define AAS_LUMPS 14
|
||||
#define AASLUMP_BBOXES 0
|
||||
#define AASLUMP_VERTEXES 1
|
||||
#define AASLUMP_PLANES 2
|
||||
#define AASLUMP_EDGES 3
|
||||
#define AASLUMP_EDGEINDEX 4
|
||||
#define AASLUMP_FACES 5
|
||||
#define AASLUMP_FACEINDEX 6
|
||||
#define AASLUMP_AREAS 7
|
||||
#define AASLUMP_AREASETTINGS 8
|
||||
#define AASLUMP_REACHABILITY 9
|
||||
#define AASLUMP_NODES 10
|
||||
#define AASLUMP_PORTALS 11
|
||||
#define AASLUMP_PORTALINDEX 12
|
||||
#define AASLUMP_CLUSTERS 13
|
||||
|
||||
//========== bounding box =========
|
||||
|
||||
//bounding box
|
||||
typedef struct aas_bbox_s
|
||||
{
|
||||
int presencetype;
|
||||
int flags;
|
||||
vec3_t mins, maxs;
|
||||
} aas_bbox_t;
|
||||
|
||||
//============ settings ===========
|
||||
|
||||
//reachability to another area
|
||||
typedef struct aas_reachability_s
|
||||
{
|
||||
int areanum; //number of the reachable area
|
||||
int facenum; //number of the face towards the other area
|
||||
int edgenum; //number of the edge towards the other area
|
||||
vec3_t start; //start point of inter area movement
|
||||
vec3_t end; //end point of inter area movement
|
||||
int traveltype; //type of travel required to get to the area
|
||||
unsigned short int traveltime;//travel time of the inter area movement
|
||||
} aas_reachability_t;
|
||||
|
||||
//area settings
|
||||
typedef struct aas_areasettings_s
|
||||
{
|
||||
//could also add all kind of statistic fields
|
||||
int contents; //contents of the area
|
||||
int areaflags; //several area flags
|
||||
int presencetype; //how a bot can be present in this area
|
||||
int cluster; //cluster the area belongs to, if negative it's a portal
|
||||
int clusterareanum; //number of the area in the cluster
|
||||
int numreachableareas; //number of reachable areas from this one
|
||||
int firstreachablearea; //first reachable area in the reachable area index
|
||||
} aas_areasettings_t;
|
||||
|
||||
//cluster portal
|
||||
typedef struct aas_portal_s
|
||||
{
|
||||
int areanum; //area that is the actual portal
|
||||
int frontcluster; //cluster at front of portal
|
||||
int backcluster; //cluster at back of portal
|
||||
int clusterareanum[2]; //number of the area in the front and back cluster
|
||||
} aas_portal_t;
|
||||
|
||||
//cluster portal index
|
||||
typedef int aas_portalindex_t;
|
||||
|
||||
//cluster
|
||||
typedef struct aas_cluster_s
|
||||
{
|
||||
int numareas; //number of areas in the cluster
|
||||
int numreachabilityareas; //number of areas with reachabilities
|
||||
int numportals; //number of cluster portals
|
||||
int firstportal; //first cluster portal in the index
|
||||
} aas_cluster_t;
|
||||
|
||||
//============ 3d definition ============
|
||||
|
||||
typedef vec3_t aas_vertex_t;
|
||||
|
||||
//just a plane in the third dimension
|
||||
typedef struct aas_plane_s
|
||||
{
|
||||
vec3_t normal; //normal vector of the plane
|
||||
float dist; //distance of the plane (normal vector * distance = point in plane)
|
||||
int type;
|
||||
} aas_plane_t;
|
||||
|
||||
//edge
|
||||
typedef struct aas_edge_s
|
||||
{
|
||||
int v[2]; //numbers of the vertexes of this edge
|
||||
} aas_edge_t;
|
||||
|
||||
//edge index, negative if vertexes are reversed
|
||||
typedef int aas_edgeindex_t;
|
||||
|
||||
//a face bounds an area, often it will also seperate two areas
|
||||
typedef struct aas_face_s
|
||||
{
|
||||
int planenum; //number of the plane this face is in
|
||||
int faceflags; //face flags (no use to create face settings for just this field)
|
||||
int numedges; //number of edges in the boundary of the face
|
||||
int firstedge; //first edge in the edge index
|
||||
int frontarea; //area at the front of this face
|
||||
int backarea; //area at the back of this face
|
||||
} aas_face_t;
|
||||
|
||||
//face index, stores a negative index if backside of face
|
||||
typedef int aas_faceindex_t;
|
||||
|
||||
//area with a boundary of faces
|
||||
typedef struct aas_area_s
|
||||
{
|
||||
int areanum; //number of this area
|
||||
//3d definition
|
||||
int numfaces; //number of faces used for the boundary of the area
|
||||
int firstface; //first face in the face index used for the boundary of the area
|
||||
vec3_t mins; //mins of the area
|
||||
vec3_t maxs; //maxs of the area
|
||||
vec3_t center; //'center' of the area
|
||||
} aas_area_t;
|
||||
|
||||
//nodes of the bsp tree
|
||||
typedef struct aas_node_s
|
||||
{
|
||||
int planenum;
|
||||
int children[2]; //child nodes of this node, or areas as leaves when negative
|
||||
//when a child is zero it's a solid leaf
|
||||
} aas_node_t;
|
||||
|
||||
//=========== aas file ===============
|
||||
|
||||
//header lump
|
||||
typedef struct
|
||||
{
|
||||
int fileofs;
|
||||
int filelen;
|
||||
} aas_lump_t;
|
||||
|
||||
//aas file header
|
||||
typedef struct aas_header_s
|
||||
{
|
||||
int ident;
|
||||
int version;
|
||||
int bspchecksum;
|
||||
//data entries
|
||||
aas_lump_t lumps[AAS_LUMPS];
|
||||
} aas_header_t;
|
||||
|
||||
|
||||
//====== additional information ======
|
||||
/*
|
||||
|
||||
- when a node child is a solid leaf the node child number is zero
|
||||
- two adjacent areas (sharing a plane at opposite sides) share a face
|
||||
this face is a portal between the areas
|
||||
- when an area uses a face from the faceindex with a positive index
|
||||
then the face plane normal points into the area
|
||||
- the face edges are stored counter clockwise using the edgeindex
|
||||
- two adjacent convex areas (sharing a face) only share One face
|
||||
this is a simple result of the areas being convex
|
||||
- the areas can't have a mixture of ground and gap faces
|
||||
other mixtures of faces in one area are allowed
|
||||
- areas with the AREACONTENTS_CLUSTERPORTAL in the settings have
|
||||
the cluster number set to the negative portal number
|
||||
- edge zero is a dummy
|
||||
- face zero is a dummy
|
||||
- area zero is a dummy
|
||||
- node zero is a dummy
|
||||
*/
|
221
tools/quake3/bspc/deps/botlib/be_aas.h
Normal file
221
tools/quake3/bspc/deps/botlib/be_aas.h
Normal file
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
//
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas.h
|
||||
*
|
||||
* desc: Area Awareness System, stuff exported to the AI
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_aas.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAX_STRINGFIELD
|
||||
#define MAX_STRINGFIELD 80
|
||||
#endif
|
||||
|
||||
//travel flags
|
||||
#define TFL_INVALID 0x00000001 //traveling temporary not possible
|
||||
#define TFL_WALK 0x00000002 //walking
|
||||
#define TFL_CROUCH 0x00000004 //crouching
|
||||
#define TFL_BARRIERJUMP 0x00000008 //jumping onto a barrier
|
||||
#define TFL_JUMP 0x00000010 //jumping
|
||||
#define TFL_LADDER 0x00000020 //climbing a ladder
|
||||
#define TFL_WALKOFFLEDGE 0x00000080 //walking of a ledge
|
||||
#define TFL_SWIM 0x00000100 //swimming
|
||||
#define TFL_WATERJUMP 0x00000200 //jumping out of the water
|
||||
#define TFL_TELEPORT 0x00000400 //teleporting
|
||||
#define TFL_ELEVATOR 0x00000800 //elevator
|
||||
#define TFL_ROCKETJUMP 0x00001000 //rocket jumping
|
||||
#define TFL_BFGJUMP 0x00002000 //bfg jumping
|
||||
#define TFL_GRAPPLEHOOK 0x00004000 //grappling hook
|
||||
#define TFL_DOUBLEJUMP 0x00008000 //double jump
|
||||
#define TFL_RAMPJUMP 0x00010000 //ramp jump
|
||||
#define TFL_STRAFEJUMP 0x00020000 //strafe jump
|
||||
#define TFL_JUMPPAD 0x00040000 //jump pad
|
||||
#define TFL_AIR 0x00080000 //travel through air
|
||||
#define TFL_WATER 0x00100000 //travel through water
|
||||
#define TFL_SLIME 0x00200000 //travel through slime
|
||||
#define TFL_LAVA 0x00400000 //travel through lava
|
||||
#define TFL_DONOTENTER 0x00800000 //travel through donotenter area
|
||||
#define TFL_FUNCBOB 0x01000000 //func bobbing
|
||||
#define TFL_FLIGHT 0x02000000 //flight
|
||||
#define TFL_BRIDGE 0x04000000 //move over a bridge
|
||||
//
|
||||
#define TFL_NOTTEAM1 0x08000000 //not team 1
|
||||
#define TFL_NOTTEAM2 0x10000000 //not team 2
|
||||
|
||||
//default travel flags
|
||||
#define TFL_DEFAULT TFL_WALK|TFL_CROUCH|TFL_BARRIERJUMP|\
|
||||
TFL_JUMP|TFL_LADDER|\
|
||||
TFL_WALKOFFLEDGE|TFL_SWIM|TFL_WATERJUMP|\
|
||||
TFL_TELEPORT|TFL_ELEVATOR|\
|
||||
TFL_AIR|TFL_WATER|TFL_JUMPPAD|TFL_FUNCBOB
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SOLID_NOT, // no interaction with other objects
|
||||
SOLID_TRIGGER, // only touch when inside, after moving
|
||||
SOLID_BBOX, // touch on edge
|
||||
SOLID_BSP // bsp clip, touch on edge
|
||||
} solid_t;
|
||||
|
||||
//a trace is returned when a box is swept through the AAS world
|
||||
typedef struct aas_trace_s
|
||||
{
|
||||
qboolean startsolid; // if true, the initial point was in a solid area
|
||||
float fraction; // time completed, 1.0 = didn't hit anything
|
||||
vec3_t endpos; // final position
|
||||
int ent; // entity blocking the trace
|
||||
int lastarea; // last area the trace was in (zero if none)
|
||||
int area; // area blocking the trace (zero if none)
|
||||
int planenum; // number of the plane that was hit
|
||||
} aas_trace_t;
|
||||
|
||||
/* Defined in botlib.h
|
||||
|
||||
//bsp_trace_t hit surface
|
||||
typedef struct bsp_surface_s
|
||||
{
|
||||
char name[16];
|
||||
int flags;
|
||||
int value;
|
||||
} bsp_surface_t;
|
||||
|
||||
//a trace is returned when a box is swept through the BSP world
|
||||
typedef struct bsp_trace_s
|
||||
{
|
||||
qboolean allsolid; // if true, plane is not valid
|
||||
qboolean startsolid; // if true, the initial point was in a solid area
|
||||
float fraction; // time completed, 1.0 = didn't hit anything
|
||||
vec3_t endpos; // final position
|
||||
cplane_t plane; // surface normal at impact
|
||||
float exp_dist; // expanded plane distance
|
||||
int sidenum; // number of the brush side hit
|
||||
bsp_surface_t surface; // hit surface
|
||||
int contents; // contents on other side of surface hit
|
||||
int ent; // number of entity hit
|
||||
} bsp_trace_t;
|
||||
//
|
||||
*/
|
||||
|
||||
//entity info
|
||||
typedef struct aas_entityinfo_s
|
||||
{
|
||||
int valid; // true if updated this frame
|
||||
int type; // entity type
|
||||
int flags; // entity flags
|
||||
float ltime; // local time
|
||||
float update_time; // time between last and current update
|
||||
int number; // number of the entity
|
||||
vec3_t origin; // origin of the entity
|
||||
vec3_t angles; // angles of the model
|
||||
vec3_t old_origin; // for lerping
|
||||
vec3_t lastvisorigin; // last visible origin
|
||||
vec3_t mins; // bounding box minimums
|
||||
vec3_t maxs; // bounding box maximums
|
||||
int groundent; // ground entity
|
||||
int solid; // solid type
|
||||
int modelindex; // model used
|
||||
int modelindex2; // weapons, CTF flags, etc
|
||||
int frame; // model frame number
|
||||
int event; // impulse events -- muzzle flashes, footsteps, etc
|
||||
int eventParm; // even parameter
|
||||
int powerups; // bit flags
|
||||
int weapon; // determines weapon and flash model, etc
|
||||
int legsAnim; // mask off ANIM_TOGGLEBIT
|
||||
int torsoAnim; // mask off ANIM_TOGGLEBIT
|
||||
} aas_entityinfo_t;
|
||||
|
||||
// area info
|
||||
typedef struct aas_areainfo_s
|
||||
{
|
||||
int contents;
|
||||
int flags;
|
||||
int presencetype;
|
||||
int cluster;
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
vec3_t center;
|
||||
} aas_areainfo_t;
|
||||
|
||||
// client movement prediction stop events, stop as soon as:
|
||||
#define SE_NONE 0
|
||||
#define SE_HITGROUND 1 // the ground is hit
|
||||
#define SE_LEAVEGROUND 2 // there's no ground
|
||||
#define SE_ENTERWATER 4 // water is entered
|
||||
#define SE_ENTERSLIME 8 // slime is entered
|
||||
#define SE_ENTERLAVA 16 // lava is entered
|
||||
#define SE_HITGROUNDDAMAGE 32 // the ground is hit with damage
|
||||
#define SE_GAP 64 // there's a gap
|
||||
#define SE_TOUCHJUMPPAD 128 // touching a jump pad area
|
||||
#define SE_TOUCHTELEPORTER 256 // touching teleporter
|
||||
#define SE_ENTERAREA 512 // the given stoparea is entered
|
||||
#define SE_HITGROUNDAREA 1024 // a ground face in the area is hit
|
||||
#define SE_HITBOUNDINGBOX 2048 // hit the specified bounding box
|
||||
#define SE_TOUCHCLUSTERPORTAL 4096 // touching a cluster portal
|
||||
|
||||
typedef struct aas_clientmove_s
|
||||
{
|
||||
vec3_t endpos; //position at the end of movement prediction
|
||||
int endarea; //area at end of movement prediction
|
||||
vec3_t velocity; //velocity at the end of movement prediction
|
||||
aas_trace_t trace; //last trace
|
||||
int presencetype; //presence type at end of movement prediction
|
||||
int stopevent; //event that made the prediction stop
|
||||
int endcontents; //contents at the end of movement prediction
|
||||
float time; //time predicted ahead
|
||||
int frames; //number of frames predicted ahead
|
||||
} aas_clientmove_t;
|
||||
|
||||
// alternate route goals
|
||||
#define ALTROUTEGOAL_ALL 1
|
||||
#define ALTROUTEGOAL_CLUSTERPORTALS 2
|
||||
#define ALTROUTEGOAL_VIEWPORTALS 4
|
||||
|
||||
typedef struct aas_altroutegoal_s
|
||||
{
|
||||
vec3_t origin;
|
||||
int areanum;
|
||||
unsigned short starttraveltime;
|
||||
unsigned short goaltraveltime;
|
||||
unsigned short extratraveltime;
|
||||
} aas_altroutegoal_t;
|
||||
|
||||
// route prediction stop events
|
||||
#define RSE_NONE 0
|
||||
#define RSE_NOROUTE 1 //no route to goal
|
||||
#define RSE_USETRAVELTYPE 2 //stop as soon as on of the given travel types is used
|
||||
#define RSE_ENTERCONTENTS 4 //stop when entering the given contents
|
||||
#define RSE_ENTERAREA 8 //stop when entering the given area
|
||||
|
||||
typedef struct aas_predictroute_s
|
||||
{
|
||||
vec3_t endpos; //position at the end of movement prediction
|
||||
int endarea; //area at end of movement prediction
|
||||
int stopevent; //event that made the prediction stop
|
||||
int endcontents; //contents at the end of movement prediction
|
||||
int endtravelflags; //end travel flags
|
||||
int numareas; //number of areas predicted ahead
|
||||
int time; //time predicted ahead (in hundreth of a sec)
|
||||
} aas_predictroute_t;
|
89
tools/quake3/bspc/deps/botlib/be_aas_bsp.h
Normal file
89
tools/quake3/bspc/deps/botlib/be_aas_bsp.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_bsp.h
|
||||
*
|
||||
* desc: AAS
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_aas_bsp.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef AASINTERN
|
||||
//loads the given BSP file
|
||||
int AAS_LoadBSPFile(void);
|
||||
//dump the loaded BSP data
|
||||
void AAS_DumpBSPData(void);
|
||||
//unlink the given entity from the bsp tree leaves
|
||||
void AAS_UnlinkFromBSPLeaves(bsp_link_t *leaves);
|
||||
//link the given entity to the bsp tree leaves of the given model
|
||||
bsp_link_t *AAS_BSPLinkEntity(vec3_t absmins,
|
||||
vec3_t absmaxs,
|
||||
int entnum,
|
||||
int modelnum);
|
||||
|
||||
//calculates collision with given entity
|
||||
qboolean AAS_EntityCollision(int entnum,
|
||||
vec3_t start,
|
||||
vec3_t boxmins,
|
||||
vec3_t boxmaxs,
|
||||
vec3_t end,
|
||||
int contentmask,
|
||||
bsp_trace_t *trace);
|
||||
//for debugging
|
||||
void AAS_PrintFreeBSPLinks(char *str);
|
||||
//
|
||||
#endif //AASINTERN
|
||||
|
||||
#define MAX_EPAIRKEY 128
|
||||
|
||||
//trace through the world
|
||||
bsp_trace_t AAS_Trace( vec3_t start,
|
||||
vec3_t mins,
|
||||
vec3_t maxs,
|
||||
vec3_t end,
|
||||
int passent,
|
||||
int contentmask);
|
||||
//returns the contents at the given point
|
||||
int AAS_PointContents(vec3_t point);
|
||||
//returns true when p2 is in the PVS of p1
|
||||
qboolean AAS_inPVS(vec3_t p1, vec3_t p2);
|
||||
//returns true when p2 is in the PHS of p1
|
||||
qboolean AAS_inPHS(vec3_t p1, vec3_t p2);
|
||||
//returns true if the given areas are connected
|
||||
qboolean AAS_AreasConnected(int area1, int area2);
|
||||
//creates a list with entities totally or partly within the given box
|
||||
int AAS_BoxEntities(vec3_t absmins, vec3_t absmaxs, int *list, int maxcount);
|
||||
//gets the mins, maxs and origin of a BSP model
|
||||
void AAS_BSPModelMinsMaxsOrigin(int modelnum, vec3_t angles, vec3_t mins, vec3_t maxs, vec3_t origin);
|
||||
//handle to the next bsp entity
|
||||
int AAS_NextBSPEntity(int ent);
|
||||
//return the value of the BSP epair key
|
||||
int AAS_ValueForBSPEpairKey(int ent, char *key, char *value, int size);
|
||||
//get a vector for the BSP epair key
|
||||
int AAS_VectorForBSPEpairKey(int ent, char *key, vec3_t v);
|
||||
//get a float for the BSP epair key
|
||||
int AAS_FloatForBSPEpairKey(int ent, char *key, float *value);
|
||||
//get an integer for the BSP epair key
|
||||
int AAS_IntForBSPEpairKey(int ent, char *key, int *value);
|
||||
|
487
tools/quake3/bspc/deps/botlib/be_aas_bspq3.c
Normal file
487
tools/quake3/bspc/deps/botlib/be_aas_bspq3.c
Normal file
|
@ -0,0 +1,487 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_bspq3.c
|
||||
*
|
||||
* desc: BSP, Environment Sampling
|
||||
*
|
||||
* $Archive: /MissionPack/code/botlib/be_aas_bspq3.c $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "l_memory.h"
|
||||
#include "l_script.h"
|
||||
#include "l_precomp.h"
|
||||
#include "l_struct.h"
|
||||
#include "aasfile.h"
|
||||
#include "botlib.h"
|
||||
#include "be_aas.h"
|
||||
#include "be_aas_funcs.h"
|
||||
#include "be_aas_def.h"
|
||||
|
||||
extern botlib_import_t botimport;
|
||||
|
||||
//#define TRACE_DEBUG
|
||||
|
||||
#define ON_EPSILON 0.005
|
||||
//#define DEG2RAD( a ) (( a * M_PI ) / 180.0F)
|
||||
|
||||
#define MAX_BSPENTITIES 2048
|
||||
|
||||
typedef struct rgb_s
|
||||
{
|
||||
int red;
|
||||
int green;
|
||||
int blue;
|
||||
} rgb_t;
|
||||
|
||||
//bsp entity epair
|
||||
typedef struct bsp_epair_s
|
||||
{
|
||||
char *key;
|
||||
char *value;
|
||||
struct bsp_epair_s *next;
|
||||
} bsp_epair_t;
|
||||
|
||||
//bsp data entity
|
||||
typedef struct bsp_entity_s
|
||||
{
|
||||
bsp_epair_t *epairs;
|
||||
} bsp_entity_t;
|
||||
|
||||
//id Sofware BSP data
|
||||
typedef struct bsp_s
|
||||
{
|
||||
//true when bsp file is loaded
|
||||
int loaded;
|
||||
//entity data
|
||||
int entdatasize;
|
||||
char *dentdata;
|
||||
//bsp entities
|
||||
int numentities;
|
||||
bsp_entity_t entities[MAX_BSPENTITIES];
|
||||
} bsp_t;
|
||||
|
||||
//global bsp
|
||||
bsp_t bspworld;
|
||||
|
||||
|
||||
#ifdef BSP_DEBUG
|
||||
typedef struct cname_s
|
||||
{
|
||||
int value;
|
||||
char *name;
|
||||
} cname_t;
|
||||
|
||||
cname_t contentnames[] =
|
||||
{
|
||||
{CONTENTS_SOLID,"CONTENTS_SOLID"},
|
||||
{CONTENTS_WINDOW,"CONTENTS_WINDOW"},
|
||||
{CONTENTS_AUX,"CONTENTS_AUX"},
|
||||
{CONTENTS_LAVA,"CONTENTS_LAVA"},
|
||||
{CONTENTS_SLIME,"CONTENTS_SLIME"},
|
||||
{CONTENTS_WATER,"CONTENTS_WATER"},
|
||||
{CONTENTS_MIST,"CONTENTS_MIST"},
|
||||
{LAST_VISIBLE_CONTENTS,"LAST_VISIBLE_CONTENTS"},
|
||||
|
||||
{CONTENTS_AREAPORTAL,"CONTENTS_AREAPORTAL"},
|
||||
{CONTENTS_PLAYERCLIP,"CONTENTS_PLAYERCLIP"},
|
||||
{CONTENTS_MONSTERCLIP,"CONTENTS_MONSTERCLIP"},
|
||||
{CONTENTS_CURRENT_0,"CONTENTS_CURRENT_0"},
|
||||
{CONTENTS_CURRENT_90,"CONTENTS_CURRENT_90"},
|
||||
{CONTENTS_CURRENT_180,"CONTENTS_CURRENT_180"},
|
||||
{CONTENTS_CURRENT_270,"CONTENTS_CURRENT_270"},
|
||||
{CONTENTS_CURRENT_UP,"CONTENTS_CURRENT_UP"},
|
||||
{CONTENTS_CURRENT_DOWN,"CONTENTS_CURRENT_DOWN"},
|
||||
{CONTENTS_ORIGIN,"CONTENTS_ORIGIN"},
|
||||
{CONTENTS_MONSTER,"CONTENTS_MONSTER"},
|
||||
{CONTENTS_DEADMONSTER,"CONTENTS_DEADMONSTER"},
|
||||
{CONTENTS_DETAIL,"CONTENTS_DETAIL"},
|
||||
{CONTENTS_TRANSLUCENT,"CONTENTS_TRANSLUCENT"},
|
||||
{CONTENTS_LADDER,"CONTENTS_LADDER"},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
void PrintContents(int contents)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; contentnames[i].value; i++)
|
||||
{
|
||||
if (contents & contentnames[i].value)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "%s\n", contentnames[i].name);
|
||||
} //end if
|
||||
} //end for
|
||||
} //end of the function PrintContents
|
||||
|
||||
#endif // BSP_DEBUG
|
||||
//===========================================================================
|
||||
// traces axial boxes of any size through the world
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
bsp_trace_t AAS_Trace(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask)
|
||||
{
|
||||
bsp_trace_t bsptrace;
|
||||
botimport.Trace(&bsptrace, start, mins, maxs, end, passent, contentmask);
|
||||
return bsptrace;
|
||||
} //end of the function AAS_Trace
|
||||
//===========================================================================
|
||||
// returns the contents at the given point
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_PointContents(vec3_t point)
|
||||
{
|
||||
return botimport.PointContents(point);
|
||||
} //end of the function AAS_PointContents
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean AAS_EntityCollision(int entnum,
|
||||
vec3_t start, vec3_t boxmins, vec3_t boxmaxs, vec3_t end,
|
||||
int contentmask, bsp_trace_t *trace)
|
||||
{
|
||||
bsp_trace_t enttrace;
|
||||
|
||||
botimport.EntityTrace(&enttrace, start, boxmins, boxmaxs, end, entnum, contentmask);
|
||||
if (enttrace.fraction < trace->fraction)
|
||||
{
|
||||
Com_Memcpy(trace, &enttrace, sizeof(bsp_trace_t));
|
||||
return qtrue;
|
||||
} //end if
|
||||
return qfalse;
|
||||
} //end of the function AAS_EntityCollision
|
||||
//===========================================================================
|
||||
// returns true if in Potentially Hearable Set
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean AAS_inPVS(vec3_t p1, vec3_t p2)
|
||||
{
|
||||
return botimport.inPVS(p1, p2);
|
||||
} //end of the function AAS_InPVS
|
||||
//===========================================================================
|
||||
// returns true if in Potentially Visible Set
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean AAS_inPHS(vec3_t p1, vec3_t p2)
|
||||
{
|
||||
return qtrue;
|
||||
} //end of the function AAS_inPHS
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_BSPModelMinsMaxsOrigin(int modelnum, vec3_t angles, vec3_t mins, vec3_t maxs, vec3_t origin)
|
||||
{
|
||||
botimport.BSPModelMinsMaxsOrigin(modelnum, angles, mins, maxs, origin);
|
||||
} //end of the function AAS_BSPModelMinsMaxs
|
||||
//===========================================================================
|
||||
// unlinks the entity from all leaves
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_UnlinkFromBSPLeaves(bsp_link_t *leaves)
|
||||
{
|
||||
} //end of the function AAS_UnlinkFromBSPLeaves
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
bsp_link_t *AAS_BSPLinkEntity(vec3_t absmins, vec3_t absmaxs, int entnum, int modelnum)
|
||||
{
|
||||
return NULL;
|
||||
} //end of the function AAS_BSPLinkEntity
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_BoxEntities(vec3_t absmins, vec3_t absmaxs, int *list, int maxcount)
|
||||
{
|
||||
return 0;
|
||||
} //end of the function AAS_BoxEntities
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_NextBSPEntity(int ent)
|
||||
{
|
||||
ent++;
|
||||
if (ent >= 1 && ent < bspworld.numentities) return ent;
|
||||
return 0;
|
||||
} //end of the function AAS_NextBSPEntity
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_BSPEntityInRange(int ent)
|
||||
{
|
||||
if (ent <= 0 || ent >= bspworld.numentities)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "bsp entity out of range\n");
|
||||
return qfalse;
|
||||
} //end if
|
||||
return qtrue;
|
||||
} //end of the function AAS_BSPEntityInRange
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_ValueForBSPEpairKey(int ent, char *key, char *value, int size)
|
||||
{
|
||||
bsp_epair_t *epair;
|
||||
|
||||
value[0] = '\0';
|
||||
if (!AAS_BSPEntityInRange(ent)) return qfalse;
|
||||
for (epair = bspworld.entities[ent].epairs; epair; epair = epair->next)
|
||||
{
|
||||
if (!strcmp(epair->key, key))
|
||||
{
|
||||
strncpy(value, epair->value, size-1);
|
||||
value[size-1] = '\0';
|
||||
return qtrue;
|
||||
} //end if
|
||||
} //end for
|
||||
return qfalse;
|
||||
} //end of the function AAS_FindBSPEpair
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_VectorForBSPEpairKey(int ent, char *key, vec3_t v)
|
||||
{
|
||||
char buf[MAX_EPAIRKEY];
|
||||
double v1, v2, v3;
|
||||
|
||||
VectorClear(v);
|
||||
if (!AAS_ValueForBSPEpairKey(ent, key, buf, MAX_EPAIRKEY)) return qfalse;
|
||||
//scanf into doubles, then assign, so it is vec_t size independent
|
||||
v1 = v2 = v3 = 0;
|
||||
sscanf(buf, "%lf %lf %lf", &v1, &v2, &v3);
|
||||
v[0] = v1;
|
||||
v[1] = v2;
|
||||
v[2] = v3;
|
||||
return qtrue;
|
||||
} //end of the function AAS_VectorForBSPEpairKey
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_FloatForBSPEpairKey(int ent, char *key, float *value)
|
||||
{
|
||||
char buf[MAX_EPAIRKEY];
|
||||
|
||||
*value = 0;
|
||||
if (!AAS_ValueForBSPEpairKey(ent, key, buf, MAX_EPAIRKEY)) return qfalse;
|
||||
*value = atof(buf);
|
||||
return qtrue;
|
||||
} //end of the function AAS_FloatForBSPEpairKey
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_IntForBSPEpairKey(int ent, char *key, int *value)
|
||||
{
|
||||
char buf[MAX_EPAIRKEY];
|
||||
|
||||
*value = 0;
|
||||
if (!AAS_ValueForBSPEpairKey(ent, key, buf, MAX_EPAIRKEY)) return qfalse;
|
||||
*value = atoi(buf);
|
||||
return qtrue;
|
||||
} //end of the function AAS_IntForBSPEpairKey
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_FreeBSPEntities(void)
|
||||
{
|
||||
int i;
|
||||
bsp_entity_t *ent;
|
||||
bsp_epair_t *epair, *nextepair;
|
||||
|
||||
for (i = 1; i < bspworld.numentities; i++)
|
||||
{
|
||||
ent = &bspworld.entities[i];
|
||||
for (epair = ent->epairs; epair; epair = nextepair)
|
||||
{
|
||||
nextepair = epair->next;
|
||||
//
|
||||
if (epair->key) FreeMemory(epair->key);
|
||||
if (epair->value) FreeMemory(epair->value);
|
||||
FreeMemory(epair);
|
||||
} //end for
|
||||
} //end for
|
||||
bspworld.numentities = 0;
|
||||
} //end of the function AAS_FreeBSPEntities
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ParseBSPEntities(void)
|
||||
{
|
||||
script_t *script;
|
||||
token_t token;
|
||||
bsp_entity_t *ent;
|
||||
bsp_epair_t *epair;
|
||||
|
||||
script = LoadScriptMemory(bspworld.dentdata, bspworld.entdatasize, "entdata");
|
||||
SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES|SCFL_NOSTRINGESCAPECHARS);//SCFL_PRIMITIVE);
|
||||
|
||||
bspworld.numentities = 1;
|
||||
|
||||
while(PS_ReadToken(script, &token))
|
||||
{
|
||||
if (strcmp(token.string, "{"))
|
||||
{
|
||||
ScriptError(script, "invalid %s\n", token.string);
|
||||
AAS_FreeBSPEntities();
|
||||
FreeScript(script);
|
||||
return;
|
||||
} //end if
|
||||
if (bspworld.numentities >= MAX_BSPENTITIES)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "too many entities in BSP file\n");
|
||||
break;
|
||||
} //end if
|
||||
ent = &bspworld.entities[bspworld.numentities];
|
||||
bspworld.numentities++;
|
||||
ent->epairs = NULL;
|
||||
while(PS_ReadToken(script, &token))
|
||||
{
|
||||
if (!strcmp(token.string, "}")) break;
|
||||
epair = (bsp_epair_t *) GetClearedHunkMemory(sizeof(bsp_epair_t));
|
||||
epair->next = ent->epairs;
|
||||
ent->epairs = epair;
|
||||
if (token.type != TT_STRING)
|
||||
{
|
||||
ScriptError(script, "invalid %s\n", token.string);
|
||||
AAS_FreeBSPEntities();
|
||||
FreeScript(script);
|
||||
return;
|
||||
} //end if
|
||||
StripDoubleQuotes(token.string);
|
||||
epair->key = (char *) GetHunkMemory(strlen(token.string) + 1);
|
||||
strcpy(epair->key, token.string);
|
||||
if (!PS_ExpectTokenType(script, TT_STRING, 0, &token))
|
||||
{
|
||||
AAS_FreeBSPEntities();
|
||||
FreeScript(script);
|
||||
return;
|
||||
} //end if
|
||||
StripDoubleQuotes(token.string);
|
||||
epair->value = (char *) GetHunkMemory(strlen(token.string) + 1);
|
||||
strcpy(epair->value, token.string);
|
||||
} //end while
|
||||
if (strcmp(token.string, "}"))
|
||||
{
|
||||
ScriptError(script, "missing }\n");
|
||||
AAS_FreeBSPEntities();
|
||||
FreeScript(script);
|
||||
return;
|
||||
} //end if
|
||||
} //end while
|
||||
FreeScript(script);
|
||||
} //end of the function AAS_ParseBSPEntities
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_BSPTraceLight(vec3_t start, vec3_t end, vec3_t endpos, int *red, int *green, int *blue)
|
||||
{
|
||||
return 0;
|
||||
} //end of the function AAS_BSPTraceLight
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_DumpBSPData(void)
|
||||
{
|
||||
AAS_FreeBSPEntities();
|
||||
|
||||
if (bspworld.dentdata) FreeMemory(bspworld.dentdata);
|
||||
bspworld.dentdata = NULL;
|
||||
bspworld.entdatasize = 0;
|
||||
//
|
||||
bspworld.loaded = qfalse;
|
||||
Com_Memset( &bspworld, 0, sizeof(bspworld) );
|
||||
} //end of the function AAS_DumpBSPData
|
||||
//===========================================================================
|
||||
// load an bsp file
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_LoadBSPFile(void)
|
||||
{
|
||||
AAS_DumpBSPData();
|
||||
bspworld.entdatasize = strlen(botimport.BSPEntityData()) + 1;
|
||||
bspworld.dentdata = (char *) GetClearedHunkMemory(bspworld.entdatasize);
|
||||
Com_Memcpy(bspworld.dentdata, botimport.BSPEntityData(), bspworld.entdatasize);
|
||||
AAS_ParseBSPEntities();
|
||||
bspworld.loaded = qtrue;
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function AAS_LoadBSPFile
|
1545
tools/quake3/bspc/deps/botlib/be_aas_cluster.c
Normal file
1545
tools/quake3/bspc/deps/botlib/be_aas_cluster.c
Normal file
File diff suppressed because it is too large
Load diff
38
tools/quake3/bspc/deps/botlib/be_aas_cluster.h
Normal file
38
tools/quake3/bspc/deps/botlib/be_aas_cluster.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_cluster.h
|
||||
*
|
||||
* desc: AAS
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_aas_cluster.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef AASINTERN
|
||||
//initialize the AAS clustering
|
||||
void AAS_InitClustering(void);
|
||||
//
|
||||
void AAS_SetViewPortalsAsClusterPortals(void);
|
||||
#endif //AASINTERN
|
||||
|
777
tools/quake3/bspc/deps/botlib/be_aas_debug.c
Normal file
777
tools/quake3/bspc/deps/botlib/be_aas_debug.c
Normal file
|
@ -0,0 +1,777 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_debug.c
|
||||
*
|
||||
* desc: AAS debug code
|
||||
*
|
||||
* $Archive: /MissionPack/code/botlib/be_aas_debug.c $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "l_memory.h"
|
||||
#include "l_script.h"
|
||||
#include "l_precomp.h"
|
||||
#include "l_struct.h"
|
||||
#include "l_libvar.h"
|
||||
#include "aasfile.h"
|
||||
#include "botlib.h"
|
||||
#include "be_aas.h"
|
||||
#include "be_interface.h"
|
||||
#include "be_aas_funcs.h"
|
||||
#include "be_aas_def.h"
|
||||
|
||||
#define MAX_DEBUGLINES 1024
|
||||
#define MAX_DEBUGPOLYGONS 8192
|
||||
|
||||
int debuglines[MAX_DEBUGLINES];
|
||||
int debuglinevisible[MAX_DEBUGLINES];
|
||||
int numdebuglines;
|
||||
|
||||
static int debugpolygons[MAX_DEBUGPOLYGONS];
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ClearShownPolygons(void)
|
||||
{
|
||||
int i;
|
||||
//*
|
||||
for (i = 0; i < MAX_DEBUGPOLYGONS; i++)
|
||||
{
|
||||
if (debugpolygons[i]) botimport.DebugPolygonDelete(debugpolygons[i]);
|
||||
debugpolygons[i] = 0;
|
||||
} //end for
|
||||
//*/
|
||||
/*
|
||||
for (i = 0; i < MAX_DEBUGPOLYGONS; i++)
|
||||
{
|
||||
botimport.DebugPolygonDelete(i);
|
||||
debugpolygons[i] = 0;
|
||||
} //end for
|
||||
*/
|
||||
} //end of the function AAS_ClearShownPolygons
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShowPolygon(int color, int numpoints, vec3_t *points)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_DEBUGPOLYGONS; i++)
|
||||
{
|
||||
if (!debugpolygons[i])
|
||||
{
|
||||
debugpolygons[i] = botimport.DebugPolygonCreate(color, numpoints, points);
|
||||
break;
|
||||
} //end if
|
||||
} //end for
|
||||
} //end of the function AAS_ShowPolygon
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ClearShownDebugLines(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
//make all lines invisible
|
||||
for (i = 0; i < MAX_DEBUGLINES; i++)
|
||||
{
|
||||
if (debuglines[i])
|
||||
{
|
||||
//botimport.DebugLineShow(debuglines[i], NULL, NULL, LINECOLOR_NONE);
|
||||
botimport.DebugLineDelete(debuglines[i]);
|
||||
debuglines[i] = 0;
|
||||
debuglinevisible[i] = qfalse;
|
||||
} //end if
|
||||
} //end for
|
||||
} //end of the function AAS_ClearShownDebugLines
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_DebugLine(vec3_t start, vec3_t end, int color)
|
||||
{
|
||||
int line;
|
||||
|
||||
for (line = 0; line < MAX_DEBUGLINES; line++)
|
||||
{
|
||||
if (!debuglines[line])
|
||||
{
|
||||
debuglines[line] = botimport.DebugLineCreate();
|
||||
debuglinevisible[line] = qfalse;
|
||||
numdebuglines++;
|
||||
} //end if
|
||||
if (!debuglinevisible[line])
|
||||
{
|
||||
botimport.DebugLineShow(debuglines[line], start, end, color);
|
||||
debuglinevisible[line] = qtrue;
|
||||
return;
|
||||
} //end else
|
||||
} //end for
|
||||
} //end of the function AAS_DebugLine
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_PermanentLine(vec3_t start, vec3_t end, int color)
|
||||
{
|
||||
int line;
|
||||
|
||||
line = botimport.DebugLineCreate();
|
||||
botimport.DebugLineShow(line, start, end, color);
|
||||
} //end of the function AAS_PermenentLine
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_DrawPermanentCross(vec3_t origin, float size, int color)
|
||||
{
|
||||
int i, debugline;
|
||||
vec3_t start, end;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
VectorCopy(origin, start);
|
||||
start[i] += size;
|
||||
VectorCopy(origin, end);
|
||||
end[i] -= size;
|
||||
AAS_DebugLine(start, end, color);
|
||||
debugline = botimport.DebugLineCreate();
|
||||
botimport.DebugLineShow(debugline, start, end, color);
|
||||
} //end for
|
||||
} //end of the function AAS_DrawPermanentCross
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_DrawPlaneCross(vec3_t point, vec3_t normal, float dist, int type, int color)
|
||||
{
|
||||
int n0, n1, n2, j, line, lines[2];
|
||||
vec3_t start1, end1, start2, end2;
|
||||
|
||||
//make a cross in the hit plane at the hit point
|
||||
VectorCopy(point, start1);
|
||||
VectorCopy(point, end1);
|
||||
VectorCopy(point, start2);
|
||||
VectorCopy(point, end2);
|
||||
|
||||
n0 = type % 3;
|
||||
n1 = (type + 1) % 3;
|
||||
n2 = (type + 2) % 3;
|
||||
start1[n1] -= 6;
|
||||
start1[n2] -= 6;
|
||||
end1[n1] += 6;
|
||||
end1[n2] += 6;
|
||||
start2[n1] += 6;
|
||||
start2[n2] -= 6;
|
||||
end2[n1] -= 6;
|
||||
end2[n2] += 6;
|
||||
|
||||
start1[n0] = (dist - (start1[n1] * normal[n1] +
|
||||
start1[n2] * normal[n2])) / normal[n0];
|
||||
end1[n0] = (dist - (end1[n1] * normal[n1] +
|
||||
end1[n2] * normal[n2])) / normal[n0];
|
||||
start2[n0] = (dist - (start2[n1] * normal[n1] +
|
||||
start2[n2] * normal[n2])) / normal[n0];
|
||||
end2[n0] = (dist - (end2[n1] * normal[n1] +
|
||||
end2[n2] * normal[n2])) / normal[n0];
|
||||
|
||||
for (j = 0, line = 0; j < 2 && line < MAX_DEBUGLINES; line++)
|
||||
{
|
||||
if (!debuglines[line])
|
||||
{
|
||||
debuglines[line] = botimport.DebugLineCreate();
|
||||
lines[j++] = debuglines[line];
|
||||
debuglinevisible[line] = qtrue;
|
||||
numdebuglines++;
|
||||
} //end if
|
||||
else if (!debuglinevisible[line])
|
||||
{
|
||||
lines[j++] = debuglines[line];
|
||||
debuglinevisible[line] = qtrue;
|
||||
} //end else
|
||||
} //end for
|
||||
botimport.DebugLineShow(lines[0], start1, end1, color);
|
||||
botimport.DebugLineShow(lines[1], start2, end2, color);
|
||||
} //end of the function AAS_DrawPlaneCross
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShowBoundingBox(vec3_t origin, vec3_t mins, vec3_t maxs)
|
||||
{
|
||||
vec3_t bboxcorners[8];
|
||||
int lines[3];
|
||||
int i, j, line;
|
||||
|
||||
//upper corners
|
||||
bboxcorners[0][0] = origin[0] + maxs[0];
|
||||
bboxcorners[0][1] = origin[1] + maxs[1];
|
||||
bboxcorners[0][2] = origin[2] + maxs[2];
|
||||
//
|
||||
bboxcorners[1][0] = origin[0] + mins[0];
|
||||
bboxcorners[1][1] = origin[1] + maxs[1];
|
||||
bboxcorners[1][2] = origin[2] + maxs[2];
|
||||
//
|
||||
bboxcorners[2][0] = origin[0] + mins[0];
|
||||
bboxcorners[2][1] = origin[1] + mins[1];
|
||||
bboxcorners[2][2] = origin[2] + maxs[2];
|
||||
//
|
||||
bboxcorners[3][0] = origin[0] + maxs[0];
|
||||
bboxcorners[3][1] = origin[1] + mins[1];
|
||||
bboxcorners[3][2] = origin[2] + maxs[2];
|
||||
//lower corners
|
||||
Com_Memcpy(bboxcorners[4], bboxcorners[0], sizeof(vec3_t) * 4);
|
||||
for (i = 0; i < 4; i++) bboxcorners[4 + i][2] = origin[2] + mins[2];
|
||||
//draw bounding box
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
for (j = 0, line = 0; j < 3 && line < MAX_DEBUGLINES; line++)
|
||||
{
|
||||
if (!debuglines[line])
|
||||
{
|
||||
debuglines[line] = botimport.DebugLineCreate();
|
||||
lines[j++] = debuglines[line];
|
||||
debuglinevisible[line] = qtrue;
|
||||
numdebuglines++;
|
||||
} //end if
|
||||
else if (!debuglinevisible[line])
|
||||
{
|
||||
lines[j++] = debuglines[line];
|
||||
debuglinevisible[line] = qtrue;
|
||||
} //end else
|
||||
} //end for
|
||||
//top plane
|
||||
botimport.DebugLineShow(lines[0], bboxcorners[i],
|
||||
bboxcorners[(i+1)&3], LINECOLOR_RED);
|
||||
//bottom plane
|
||||
botimport.DebugLineShow(lines[1], bboxcorners[4+i],
|
||||
bboxcorners[4+((i+1)&3)], LINECOLOR_RED);
|
||||
//vertical lines
|
||||
botimport.DebugLineShow(lines[2], bboxcorners[i],
|
||||
bboxcorners[4+i], LINECOLOR_RED);
|
||||
} //end for
|
||||
} //end of the function AAS_ShowBoundingBox
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShowFace(int facenum)
|
||||
{
|
||||
int i, color, edgenum;
|
||||
aas_edge_t *edge;
|
||||
aas_face_t *face;
|
||||
aas_plane_t *plane;
|
||||
vec3_t start, end;
|
||||
|
||||
color = LINECOLOR_YELLOW;
|
||||
//check if face number is in range
|
||||
if (facenum >= aasworld.numfaces)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "facenum %d out of range\n", facenum);
|
||||
} //end if
|
||||
face = &aasworld.faces[facenum];
|
||||
//walk through the edges of the face
|
||||
for (i = 0; i < face->numedges; i++)
|
||||
{
|
||||
//edge number
|
||||
edgenum = abs(aasworld.edgeindex[face->firstedge + i]);
|
||||
//check if edge number is in range
|
||||
if (edgenum >= aasworld.numedges)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "edgenum %d out of range\n", edgenum);
|
||||
} //end if
|
||||
edge = &aasworld.edges[edgenum];
|
||||
if (color == LINECOLOR_RED) color = LINECOLOR_GREEN;
|
||||
else if (color == LINECOLOR_GREEN) color = LINECOLOR_BLUE;
|
||||
else if (color == LINECOLOR_BLUE) color = LINECOLOR_YELLOW;
|
||||
else color = LINECOLOR_RED;
|
||||
AAS_DebugLine(aasworld.vertexes[edge->v[0]],
|
||||
aasworld.vertexes[edge->v[1]],
|
||||
color);
|
||||
} //end for
|
||||
plane = &aasworld.planes[face->planenum];
|
||||
edgenum = abs(aasworld.edgeindex[face->firstedge]);
|
||||
edge = &aasworld.edges[edgenum];
|
||||
VectorCopy(aasworld.vertexes[edge->v[0]], start);
|
||||
VectorMA(start, 20, plane->normal, end);
|
||||
AAS_DebugLine(start, end, LINECOLOR_RED);
|
||||
} //end of the function AAS_ShowFace
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShowFacePolygon(int facenum, int color, int flip)
|
||||
{
|
||||
int i, edgenum, numpoints;
|
||||
vec3_t points[128];
|
||||
aas_edge_t *edge;
|
||||
aas_face_t *face;
|
||||
|
||||
//check if face number is in range
|
||||
if (facenum >= aasworld.numfaces)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "facenum %d out of range\n", facenum);
|
||||
} //end if
|
||||
face = &aasworld.faces[facenum];
|
||||
//walk through the edges of the face
|
||||
numpoints = 0;
|
||||
if (flip)
|
||||
{
|
||||
for (i = face->numedges-1; i >= 0; i--)
|
||||
{
|
||||
//edge number
|
||||
edgenum = aasworld.edgeindex[face->firstedge + i];
|
||||
edge = &aasworld.edges[abs(edgenum)];
|
||||
VectorCopy(aasworld.vertexes[edge->v[edgenum < 0]], points[numpoints]);
|
||||
numpoints++;
|
||||
} //end for
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
for (i = 0; i < face->numedges; i++)
|
||||
{
|
||||
//edge number
|
||||
edgenum = aasworld.edgeindex[face->firstedge + i];
|
||||
edge = &aasworld.edges[abs(edgenum)];
|
||||
VectorCopy(aasworld.vertexes[edge->v[edgenum < 0]], points[numpoints]);
|
||||
numpoints++;
|
||||
} //end for
|
||||
} //end else
|
||||
AAS_ShowPolygon(color, numpoints, points);
|
||||
} //end of the function AAS_ShowFacePolygon
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShowArea(int areanum, int groundfacesonly)
|
||||
{
|
||||
int areaedges[MAX_DEBUGLINES];
|
||||
int numareaedges, i, j, n, color = 0, line;
|
||||
int facenum, edgenum;
|
||||
aas_area_t *area;
|
||||
aas_face_t *face;
|
||||
aas_edge_t *edge;
|
||||
|
||||
//
|
||||
numareaedges = 0;
|
||||
//
|
||||
if (areanum < 0 || areanum >= aasworld.numareas)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "area %d out of range [0, %d]\n",
|
||||
areanum, aasworld.numareas);
|
||||
return;
|
||||
} //end if
|
||||
//pointer to the convex area
|
||||
area = &aasworld.areas[areanum];
|
||||
//walk through the faces of the area
|
||||
for (i = 0; i < area->numfaces; i++)
|
||||
{
|
||||
facenum = abs(aasworld.faceindex[area->firstface + i]);
|
||||
//check if face number is in range
|
||||
if (facenum >= aasworld.numfaces)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "facenum %d out of range\n", facenum);
|
||||
} //end if
|
||||
face = &aasworld.faces[facenum];
|
||||
//ground faces only
|
||||
if (groundfacesonly)
|
||||
{
|
||||
if (!(face->faceflags & (FACE_GROUND | FACE_LADDER))) continue;
|
||||
} //end if
|
||||
//walk through the edges of the face
|
||||
for (j = 0; j < face->numedges; j++)
|
||||
{
|
||||
//edge number
|
||||
edgenum = abs(aasworld.edgeindex[face->firstedge + j]);
|
||||
//check if edge number is in range
|
||||
if (edgenum >= aasworld.numedges)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "edgenum %d out of range\n", edgenum);
|
||||
} //end if
|
||||
//check if the edge is stored already
|
||||
for (n = 0; n < numareaedges; n++)
|
||||
{
|
||||
if (areaedges[n] == edgenum) break;
|
||||
} //end for
|
||||
if (n == numareaedges && numareaedges < MAX_DEBUGLINES)
|
||||
{
|
||||
areaedges[numareaedges++] = edgenum;
|
||||
} //end if
|
||||
} //end for
|
||||
//AAS_ShowFace(facenum);
|
||||
} //end for
|
||||
//draw all the edges
|
||||
for (n = 0; n < numareaedges; n++)
|
||||
{
|
||||
for (line = 0; line < MAX_DEBUGLINES; line++)
|
||||
{
|
||||
if (!debuglines[line])
|
||||
{
|
||||
debuglines[line] = botimport.DebugLineCreate();
|
||||
debuglinevisible[line] = qfalse;
|
||||
numdebuglines++;
|
||||
} //end if
|
||||
if (!debuglinevisible[line])
|
||||
{
|
||||
break;
|
||||
} //end else
|
||||
} //end for
|
||||
if (line >= MAX_DEBUGLINES) return;
|
||||
edge = &aasworld.edges[areaedges[n]];
|
||||
if (color == LINECOLOR_RED) color = LINECOLOR_BLUE;
|
||||
else if (color == LINECOLOR_BLUE) color = LINECOLOR_GREEN;
|
||||
else if (color == LINECOLOR_GREEN) color = LINECOLOR_YELLOW;
|
||||
else color = LINECOLOR_RED;
|
||||
botimport.DebugLineShow(debuglines[line],
|
||||
aasworld.vertexes[edge->v[0]],
|
||||
aasworld.vertexes[edge->v[1]],
|
||||
color);
|
||||
debuglinevisible[line] = qtrue;
|
||||
} //end for*/
|
||||
} //end of the function AAS_ShowArea
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShowAreaPolygons(int areanum, int color, int groundfacesonly)
|
||||
{
|
||||
int i, facenum;
|
||||
aas_area_t *area;
|
||||
aas_face_t *face;
|
||||
|
||||
//
|
||||
if (areanum < 0 || areanum >= aasworld.numareas)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "area %d out of range [0, %d]\n",
|
||||
areanum, aasworld.numareas);
|
||||
return;
|
||||
} //end if
|
||||
//pointer to the convex area
|
||||
area = &aasworld.areas[areanum];
|
||||
//walk through the faces of the area
|
||||
for (i = 0; i < area->numfaces; i++)
|
||||
{
|
||||
facenum = abs(aasworld.faceindex[area->firstface + i]);
|
||||
//check if face number is in range
|
||||
if (facenum >= aasworld.numfaces)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "facenum %d out of range\n", facenum);
|
||||
} //end if
|
||||
face = &aasworld.faces[facenum];
|
||||
//ground faces only
|
||||
if (groundfacesonly)
|
||||
{
|
||||
if (!(face->faceflags & (FACE_GROUND | FACE_LADDER))) continue;
|
||||
} //end if
|
||||
AAS_ShowFacePolygon(facenum, color, face->frontarea != areanum);
|
||||
} //end for
|
||||
} //end of the function AAS_ShowAreaPolygons
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_DrawCross(vec3_t origin, float size, int color)
|
||||
{
|
||||
int i;
|
||||
vec3_t start, end;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
VectorCopy(origin, start);
|
||||
start[i] += size;
|
||||
VectorCopy(origin, end);
|
||||
end[i] -= size;
|
||||
AAS_DebugLine(start, end, color);
|
||||
} //end for
|
||||
} //end of the function AAS_DrawCross
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_PrintTravelType(int traveltype)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
char *str;
|
||||
//
|
||||
switch(traveltype & TRAVELTYPE_MASK)
|
||||
{
|
||||
case TRAVEL_INVALID: str = "TRAVEL_INVALID"; break;
|
||||
case TRAVEL_WALK: str = "TRAVEL_WALK"; break;
|
||||
case TRAVEL_CROUCH: str = "TRAVEL_CROUCH"; break;
|
||||
case TRAVEL_BARRIERJUMP: str = "TRAVEL_BARRIERJUMP"; break;
|
||||
case TRAVEL_JUMP: str = "TRAVEL_JUMP"; break;
|
||||
case TRAVEL_LADDER: str = "TRAVEL_LADDER"; break;
|
||||
case TRAVEL_WALKOFFLEDGE: str = "TRAVEL_WALKOFFLEDGE"; break;
|
||||
case TRAVEL_SWIM: str = "TRAVEL_SWIM"; break;
|
||||
case TRAVEL_WATERJUMP: str = "TRAVEL_WATERJUMP"; break;
|
||||
case TRAVEL_TELEPORT: str = "TRAVEL_TELEPORT"; break;
|
||||
case TRAVEL_ELEVATOR: str = "TRAVEL_ELEVATOR"; break;
|
||||
case TRAVEL_ROCKETJUMP: str = "TRAVEL_ROCKETJUMP"; break;
|
||||
case TRAVEL_BFGJUMP: str = "TRAVEL_BFGJUMP"; break;
|
||||
case TRAVEL_GRAPPLEHOOK: str = "TRAVEL_GRAPPLEHOOK"; break;
|
||||
case TRAVEL_JUMPPAD: str = "TRAVEL_JUMPPAD"; break;
|
||||
case TRAVEL_FUNCBOB: str = "TRAVEL_FUNCBOB"; break;
|
||||
default: str = "UNKNOWN TRAVEL TYPE"; break;
|
||||
} //end switch
|
||||
botimport.Print(PRT_MESSAGE, "%s", str);
|
||||
#endif
|
||||
} //end of the function AAS_PrintTravelType
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_DrawArrow(vec3_t start, vec3_t end, int linecolor, int arrowcolor)
|
||||
{
|
||||
vec3_t dir, cross, p1, p2, up = {0, 0, 1};
|
||||
float dot;
|
||||
|
||||
VectorSubtract(end, start, dir);
|
||||
VectorNormalize(dir);
|
||||
dot = DotProduct(dir, up);
|
||||
if (dot > 0.99 || dot < -0.99) VectorSet(cross, 1, 0, 0);
|
||||
else CrossProduct(dir, up, cross);
|
||||
|
||||
VectorMA(end, -6, dir, p1);
|
||||
VectorCopy(p1, p2);
|
||||
VectorMA(p1, 6, cross, p1);
|
||||
VectorMA(p2, -6, cross, p2);
|
||||
|
||||
AAS_DebugLine(start, end, linecolor);
|
||||
AAS_DebugLine(p1, end, arrowcolor);
|
||||
AAS_DebugLine(p2, end, arrowcolor);
|
||||
} //end of the function AAS_DrawArrow
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShowReachability(aas_reachability_t *reach)
|
||||
{
|
||||
vec3_t dir, cmdmove, velocity;
|
||||
float speed, zvel;
|
||||
aas_clientmove_t move;
|
||||
|
||||
AAS_ShowAreaPolygons(reach->areanum, 5, qtrue);
|
||||
//AAS_ShowArea(reach->areanum, qtrue);
|
||||
AAS_DrawArrow(reach->start, reach->end, LINECOLOR_BLUE, LINECOLOR_YELLOW);
|
||||
//
|
||||
if ((reach->traveltype & TRAVELTYPE_MASK) == TRAVEL_JUMP ||
|
||||
(reach->traveltype & TRAVELTYPE_MASK) == TRAVEL_WALKOFFLEDGE)
|
||||
{
|
||||
AAS_HorizontalVelocityForJump(aassettings.phys_jumpvel, reach->start, reach->end, &speed);
|
||||
//
|
||||
VectorSubtract(reach->end, reach->start, dir);
|
||||
dir[2] = 0;
|
||||
VectorNormalize(dir);
|
||||
//set the velocity
|
||||
VectorScale(dir, speed, velocity);
|
||||
//set the command movement
|
||||
VectorClear(cmdmove);
|
||||
cmdmove[2] = aassettings.phys_jumpvel;
|
||||
//
|
||||
AAS_PredictClientMovement(&move, -1, reach->start, PRESENCE_NORMAL, qtrue,
|
||||
velocity, cmdmove, 3, 30, 0.1f,
|
||||
SE_HITGROUND|SE_ENTERWATER|SE_ENTERSLIME|
|
||||
SE_ENTERLAVA|SE_HITGROUNDDAMAGE, 0, qtrue);
|
||||
//
|
||||
if ((reach->traveltype & TRAVELTYPE_MASK) == TRAVEL_JUMP)
|
||||
{
|
||||
AAS_JumpReachRunStart(reach, dir);
|
||||
AAS_DrawCross(dir, 4, LINECOLOR_BLUE);
|
||||
} //end if
|
||||
} //end if
|
||||
else if ((reach->traveltype & TRAVELTYPE_MASK) == TRAVEL_ROCKETJUMP)
|
||||
{
|
||||
zvel = AAS_RocketJumpZVelocity(reach->start);
|
||||
AAS_HorizontalVelocityForJump(zvel, reach->start, reach->end, &speed);
|
||||
//
|
||||
VectorSubtract(reach->end, reach->start, dir);
|
||||
dir[2] = 0;
|
||||
VectorNormalize(dir);
|
||||
//get command movement
|
||||
VectorScale(dir, speed, cmdmove);
|
||||
VectorSet(velocity, 0, 0, zvel);
|
||||
//
|
||||
AAS_PredictClientMovement(&move, -1, reach->start, PRESENCE_NORMAL, qtrue,
|
||||
velocity, cmdmove, 30, 30, 0.1f,
|
||||
SE_ENTERWATER|SE_ENTERSLIME|
|
||||
SE_ENTERLAVA|SE_HITGROUNDDAMAGE|
|
||||
SE_TOUCHJUMPPAD|SE_HITGROUNDAREA, reach->areanum, qtrue);
|
||||
} //end else if
|
||||
else if ((reach->traveltype & TRAVELTYPE_MASK) == TRAVEL_JUMPPAD)
|
||||
{
|
||||
VectorSet(cmdmove, 0, 0, 0);
|
||||
//
|
||||
VectorSubtract(reach->end, reach->start, dir);
|
||||
dir[2] = 0;
|
||||
VectorNormalize(dir);
|
||||
//set the velocity
|
||||
//NOTE: the edgenum is the horizontal velocity
|
||||
VectorScale(dir, reach->edgenum, velocity);
|
||||
//NOTE: the facenum is the Z velocity
|
||||
velocity[2] = reach->facenum;
|
||||
//
|
||||
AAS_PredictClientMovement(&move, -1, reach->start, PRESENCE_NORMAL, qtrue,
|
||||
velocity, cmdmove, 30, 30, 0.1f,
|
||||
SE_ENTERWATER|SE_ENTERSLIME|
|
||||
SE_ENTERLAVA|SE_HITGROUNDDAMAGE|
|
||||
SE_TOUCHJUMPPAD|SE_HITGROUNDAREA, reach->areanum, qtrue);
|
||||
} //end else if
|
||||
} //end of the function AAS_ShowReachability
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShowReachableAreas(int areanum)
|
||||
{
|
||||
aas_areasettings_t *settings;
|
||||
static aas_reachability_t reach;
|
||||
static int index, lastareanum;
|
||||
static float lasttime;
|
||||
|
||||
if (areanum != lastareanum)
|
||||
{
|
||||
index = 0;
|
||||
lastareanum = areanum;
|
||||
} //end if
|
||||
settings = &aasworld.areasettings[areanum];
|
||||
//
|
||||
if (!settings->numreachableareas) return;
|
||||
//
|
||||
if (index >= settings->numreachableareas) index = 0;
|
||||
//
|
||||
if (AAS_Time() - lasttime > 1.5)
|
||||
{
|
||||
Com_Memcpy(&reach, &aasworld.reachability[settings->firstreachablearea + index], sizeof(aas_reachability_t));
|
||||
index++;
|
||||
lasttime = AAS_Time();
|
||||
AAS_PrintTravelType(reach.traveltype & TRAVELTYPE_MASK);
|
||||
botimport.Print(PRT_MESSAGE, "\n");
|
||||
} //end if
|
||||
AAS_ShowReachability(&reach);
|
||||
} //end of the function ShowReachableAreas
|
||||
|
||||
void AAS_FloodAreas_r(int areanum, int cluster, int *done)
|
||||
{
|
||||
int nextareanum, i, facenum;
|
||||
aas_area_t *area;
|
||||
aas_face_t *face;
|
||||
aas_areasettings_t *settings;
|
||||
aas_reachability_t *reach;
|
||||
|
||||
AAS_ShowAreaPolygons(areanum, 1, qtrue);
|
||||
//pointer to the convex area
|
||||
area = &aasworld.areas[areanum];
|
||||
settings = &aasworld.areasettings[areanum];
|
||||
//walk through the faces of the area
|
||||
for (i = 0; i < area->numfaces; i++)
|
||||
{
|
||||
facenum = abs(aasworld.faceindex[area->firstface + i]);
|
||||
face = &aasworld.faces[facenum];
|
||||
if (face->frontarea == areanum)
|
||||
nextareanum = face->backarea;
|
||||
else
|
||||
nextareanum = face->frontarea;
|
||||
if (!nextareanum)
|
||||
continue;
|
||||
if (done[nextareanum])
|
||||
continue;
|
||||
done[nextareanum] = qtrue;
|
||||
if (aasworld.areasettings[nextareanum].contents & AREACONTENTS_VIEWPORTAL)
|
||||
continue;
|
||||
if (AAS_AreaCluster(nextareanum) != cluster)
|
||||
continue;
|
||||
AAS_FloodAreas_r(nextareanum, cluster, done);
|
||||
} //end for
|
||||
//
|
||||
for (i = 0; i < settings->numreachableareas; i++)
|
||||
{
|
||||
reach = &aasworld.reachability[settings->firstreachablearea + i];
|
||||
nextareanum = reach->areanum;
|
||||
if (!nextareanum)
|
||||
continue;
|
||||
if (done[nextareanum])
|
||||
continue;
|
||||
done[nextareanum] = qtrue;
|
||||
if (aasworld.areasettings[nextareanum].contents & AREACONTENTS_VIEWPORTAL)
|
||||
continue;
|
||||
if (AAS_AreaCluster(nextareanum) != cluster)
|
||||
continue;
|
||||
/*
|
||||
if ((reach->traveltype & TRAVELTYPE_MASK) == TRAVEL_WALKOFFLEDGE)
|
||||
{
|
||||
AAS_DebugLine(reach->start, reach->end, 1);
|
||||
}
|
||||
*/
|
||||
AAS_FloodAreas_r(nextareanum, cluster, done);
|
||||
}
|
||||
}
|
||||
|
||||
void AAS_FloodAreas(vec3_t origin)
|
||||
{
|
||||
int areanum, cluster, *done;
|
||||
|
||||
done = (int *) GetClearedMemory(aasworld.numareas * sizeof(int));
|
||||
areanum = AAS_PointAreaNum(origin);
|
||||
cluster = AAS_AreaCluster(areanum);
|
||||
AAS_FloodAreas_r(areanum, cluster, done);
|
||||
}
|
62
tools/quake3/bspc/deps/botlib/be_aas_debug.h
Normal file
62
tools/quake3/bspc/deps/botlib/be_aas_debug.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_debug.h
|
||||
*
|
||||
* desc: AAS
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_aas_debug.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//clear the shown debug lines
|
||||
void AAS_ClearShownDebugLines(void);
|
||||
//
|
||||
void AAS_ClearShownPolygons(void);
|
||||
//show a debug line
|
||||
void AAS_DebugLine(vec3_t start, vec3_t end, int color);
|
||||
//show a permenent line
|
||||
void AAS_PermanentLine(vec3_t start, vec3_t end, int color);
|
||||
//show a permanent cross
|
||||
void AAS_DrawPermanentCross(vec3_t origin, float size, int color);
|
||||
//draw a cross in the plane
|
||||
void AAS_DrawPlaneCross(vec3_t point, vec3_t normal, float dist, int type, int color);
|
||||
//show a bounding box
|
||||
void AAS_ShowBoundingBox(vec3_t origin, vec3_t mins, vec3_t maxs);
|
||||
//show a face
|
||||
void AAS_ShowFace(int facenum);
|
||||
//show an area
|
||||
void AAS_ShowArea(int areanum, int groundfacesonly);
|
||||
//
|
||||
void AAS_ShowAreaPolygons(int areanum, int color, int groundfacesonly);
|
||||
//draw a cros
|
||||
void AAS_DrawCross(vec3_t origin, float size, int color);
|
||||
//print the travel type
|
||||
void AAS_PrintTravelType(int traveltype);
|
||||
//draw an arrow
|
||||
void AAS_DrawArrow(vec3_t start, vec3_t end, int linecolor, int arrowcolor);
|
||||
//visualize the given reachability
|
||||
void AAS_ShowReachability(struct aas_reachability_s *reach);
|
||||
//show the reachable areas from the given area
|
||||
void AAS_ShowReachableAreas(int areanum);
|
||||
|
306
tools/quake3/bspc/deps/botlib/be_aas_def.h
Normal file
306
tools/quake3/bspc/deps/botlib/be_aas_def.h
Normal file
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_def.h
|
||||
*
|
||||
* desc: AAS
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_aas_def.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//debugging on
|
||||
#define AAS_DEBUG
|
||||
|
||||
#define MAX_CLIENTS 64
|
||||
#define MAX_MODELS 256 // these are sent over the net as 8 bits
|
||||
#define MAX_SOUNDS 256 // so they cannot be blindly increased
|
||||
#define MAX_CONFIGSTRINGS 1024
|
||||
|
||||
#define CS_SCORES 32
|
||||
#define CS_MODELS (CS_SCORES+MAX_CLIENTS)
|
||||
#define CS_SOUNDS (CS_MODELS+MAX_MODELS)
|
||||
|
||||
#define DF_AASENTNUMBER(x) (x - aasworld.entities)
|
||||
#define DF_NUMBERAASENT(x) (&aasworld.entities[x])
|
||||
#define DF_AASENTCLIENT(x) (x - aasworld.entities - 1)
|
||||
#define DF_CLIENTAASENT(x) (&aasworld.entities[x + 1])
|
||||
|
||||
#ifndef MAX_PATH
|
||||
#define MAX_PATH MAX_QPATH
|
||||
#endif
|
||||
|
||||
//string index (for model, sound and image index)
|
||||
typedef struct aas_stringindex_s
|
||||
{
|
||||
int numindexes;
|
||||
char **index;
|
||||
} aas_stringindex_t;
|
||||
|
||||
//structure to link entities to areas and areas to entities
|
||||
typedef struct aas_link_s
|
||||
{
|
||||
int entnum;
|
||||
int areanum;
|
||||
struct aas_link_s *next_ent, *prev_ent;
|
||||
struct aas_link_s *next_area, *prev_area;
|
||||
} aas_link_t;
|
||||
|
||||
//structure to link entities to leaves and leaves to entities
|
||||
typedef struct bsp_link_s
|
||||
{
|
||||
int entnum;
|
||||
int leafnum;
|
||||
struct bsp_link_s *next_ent, *prev_ent;
|
||||
struct bsp_link_s *next_leaf, *prev_leaf;
|
||||
} bsp_link_t;
|
||||
|
||||
typedef struct bsp_entdata_s
|
||||
{
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
vec3_t absmins;
|
||||
vec3_t absmaxs;
|
||||
int solid;
|
||||
int modelnum;
|
||||
} bsp_entdata_t;
|
||||
|
||||
//entity
|
||||
typedef struct aas_entity_s
|
||||
{
|
||||
//entity info
|
||||
aas_entityinfo_t i;
|
||||
//links into the AAS areas
|
||||
aas_link_t *areas;
|
||||
//links into the BSP leaves
|
||||
bsp_link_t *leaves;
|
||||
} aas_entity_t;
|
||||
|
||||
typedef struct aas_settings_s
|
||||
{
|
||||
vec3_t phys_gravitydirection;
|
||||
float phys_friction;
|
||||
float phys_stopspeed;
|
||||
float phys_gravity;
|
||||
float phys_waterfriction;
|
||||
float phys_watergravity;
|
||||
float phys_maxvelocity;
|
||||
float phys_maxwalkvelocity;
|
||||
float phys_maxcrouchvelocity;
|
||||
float phys_maxswimvelocity;
|
||||
float phys_walkaccelerate;
|
||||
float phys_airaccelerate;
|
||||
float phys_swimaccelerate;
|
||||
float phys_maxstep;
|
||||
float phys_maxsteepness;
|
||||
float phys_maxwaterjump;
|
||||
float phys_maxbarrier;
|
||||
float phys_jumpvel;
|
||||
float phys_falldelta5;
|
||||
float phys_falldelta10;
|
||||
float rs_waterjump;
|
||||
float rs_teleport;
|
||||
float rs_barrierjump;
|
||||
float rs_startcrouch;
|
||||
float rs_startgrapple;
|
||||
float rs_startwalkoffledge;
|
||||
float rs_startjump;
|
||||
float rs_rocketjump;
|
||||
float rs_bfgjump;
|
||||
float rs_jumppad;
|
||||
float rs_aircontrolledjumppad;
|
||||
float rs_funcbob;
|
||||
float rs_startelevator;
|
||||
float rs_falldamage5;
|
||||
float rs_falldamage10;
|
||||
float rs_maxfallheight;
|
||||
float rs_maxjumpfallheight;
|
||||
} aas_settings_t;
|
||||
|
||||
#define CACHETYPE_PORTAL 0
|
||||
#define CACHETYPE_AREA 1
|
||||
|
||||
//routing cache
|
||||
typedef struct aas_routingcache_s
|
||||
{
|
||||
byte type; //portal or area cache
|
||||
float time; //last time accessed or updated
|
||||
int size; //size of the routing cache
|
||||
int cluster; //cluster the cache is for
|
||||
int areanum; //area the cache is created for
|
||||
vec3_t origin; //origin within the area
|
||||
float starttraveltime; //travel time to start with
|
||||
int travelflags; //combinations of the travel flags
|
||||
struct aas_routingcache_s *prev, *next;
|
||||
struct aas_routingcache_s *time_prev, *time_next;
|
||||
unsigned char *reachabilities; //reachabilities used for routing
|
||||
unsigned short int traveltimes[1]; //travel time for every area (variable sized)
|
||||
} aas_routingcache_t;
|
||||
|
||||
//fields for the routing algorithm
|
||||
typedef struct aas_routingupdate_s
|
||||
{
|
||||
int cluster;
|
||||
int areanum; //area number of the update
|
||||
vec3_t start; //start point the area was entered
|
||||
unsigned short int tmptraveltime; //temporary travel time
|
||||
unsigned short int *areatraveltimes; //travel times within the area
|
||||
qboolean inlist; //true if the update is in the list
|
||||
struct aas_routingupdate_s *next;
|
||||
struct aas_routingupdate_s *prev;
|
||||
} aas_routingupdate_t;
|
||||
|
||||
//reversed reachability link
|
||||
typedef struct aas_reversedlink_s
|
||||
{
|
||||
int linknum; //the aas_areareachability_t
|
||||
int areanum; //reachable from this area
|
||||
struct aas_reversedlink_s *next; //next link
|
||||
} aas_reversedlink_t;
|
||||
|
||||
//reversed area reachability
|
||||
typedef struct aas_reversedreachability_s
|
||||
{
|
||||
int numlinks;
|
||||
aas_reversedlink_t *first;
|
||||
} aas_reversedreachability_t;
|
||||
|
||||
//areas a reachability goes through
|
||||
typedef struct aas_reachabilityareas_s
|
||||
{
|
||||
int firstarea, numareas;
|
||||
} aas_reachabilityareas_t;
|
||||
|
||||
typedef struct aas_s
|
||||
{
|
||||
int loaded; //true when an AAS file is loaded
|
||||
int initialized; //true when AAS has been initialized
|
||||
int savefile; //set true when file should be saved
|
||||
int bspchecksum;
|
||||
//current time
|
||||
float time;
|
||||
int numframes;
|
||||
//name of the aas file
|
||||
char filename[MAX_PATH];
|
||||
char mapname[MAX_PATH];
|
||||
//bounding boxes
|
||||
int numbboxes;
|
||||
aas_bbox_t *bboxes;
|
||||
//vertexes
|
||||
int numvertexes;
|
||||
aas_vertex_t *vertexes;
|
||||
//planes
|
||||
int numplanes;
|
||||
aas_plane_t *planes;
|
||||
//edges
|
||||
int numedges;
|
||||
aas_edge_t *edges;
|
||||
//edge index
|
||||
int edgeindexsize;
|
||||
aas_edgeindex_t *edgeindex;
|
||||
//faces
|
||||
int numfaces;
|
||||
aas_face_t *faces;
|
||||
//face index
|
||||
int faceindexsize;
|
||||
aas_faceindex_t *faceindex;
|
||||
//convex areas
|
||||
int numareas;
|
||||
aas_area_t *areas;
|
||||
//convex area settings
|
||||
int numareasettings;
|
||||
aas_areasettings_t *areasettings;
|
||||
//reachablity list
|
||||
int reachabilitysize;
|
||||
aas_reachability_t *reachability;
|
||||
//nodes of the bsp tree
|
||||
int numnodes;
|
||||
aas_node_t *nodes;
|
||||
//cluster portals
|
||||
int numportals;
|
||||
aas_portal_t *portals;
|
||||
//cluster portal index
|
||||
int portalindexsize;
|
||||
aas_portalindex_t *portalindex;
|
||||
//clusters
|
||||
int numclusters;
|
||||
aas_cluster_t *clusters;
|
||||
//
|
||||
int numreachabilityareas;
|
||||
float reachabilitytime;
|
||||
//enities linked in the areas
|
||||
aas_link_t *linkheap; //heap with link structures
|
||||
int linkheapsize; //size of the link heap
|
||||
aas_link_t *freelinks; //first free link
|
||||
aas_link_t **arealinkedentities; //entities linked into areas
|
||||
//entities
|
||||
int maxentities;
|
||||
int maxclients;
|
||||
aas_entity_t *entities;
|
||||
//string indexes
|
||||
char *configstrings[MAX_CONFIGSTRINGS];
|
||||
int indexessetup;
|
||||
//index to retrieve travel flag for a travel type
|
||||
int travelflagfortype[MAX_TRAVELTYPES];
|
||||
//travel flags for each area based on contents
|
||||
int *areacontentstravelflags;
|
||||
//routing update
|
||||
aas_routingupdate_t *areaupdate;
|
||||
aas_routingupdate_t *portalupdate;
|
||||
//number of routing updates during a frame (reset every frame)
|
||||
int frameroutingupdates;
|
||||
//reversed reachability links
|
||||
aas_reversedreachability_t *reversedreachability;
|
||||
//travel times within the areas
|
||||
unsigned short ***areatraveltimes;
|
||||
//array of size numclusters with cluster cache
|
||||
aas_routingcache_t ***clusterareacache;
|
||||
aas_routingcache_t **portalcache;
|
||||
//cache list sorted on time
|
||||
aas_routingcache_t *oldestcache; // start of cache list sorted on time
|
||||
aas_routingcache_t *newestcache; // end of cache list sorted on time
|
||||
//maximum travel time through portal areas
|
||||
int *portalmaxtraveltimes;
|
||||
//areas the reachabilities go through
|
||||
int *reachabilityareaindex;
|
||||
aas_reachabilityareas_t *reachabilityareas;
|
||||
} aas_t;
|
||||
|
||||
#define AASINTERN
|
||||
|
||||
#ifndef BSPCINCLUDE
|
||||
|
||||
#include "be_aas_main.h"
|
||||
#include "be_aas_entity.h"
|
||||
#include "be_aas_sample.h"
|
||||
#include "be_aas_cluster.h"
|
||||
#include "be_aas_reach.h"
|
||||
#include "be_aas_route.h"
|
||||
#include "be_aas_routealt.h"
|
||||
#include "be_aas_debug.h"
|
||||
#include "be_aas_file.h"
|
||||
#include "be_aas_optimize.h"
|
||||
#include "be_aas_bsp.h"
|
||||
#include "be_aas_move.h"
|
||||
|
||||
#endif //BSPCINCLUDE
|
437
tools/quake3/bspc/deps/botlib/be_aas_entity.c
Normal file
437
tools/quake3/bspc/deps/botlib/be_aas_entity.c
Normal file
|
@ -0,0 +1,437 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_entity.c
|
||||
*
|
||||
* desc: AAS entities
|
||||
*
|
||||
* $Archive: /MissionPack/code/botlib/be_aas_entity.c $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "l_memory.h"
|
||||
#include "l_script.h"
|
||||
#include "l_precomp.h"
|
||||
#include "l_struct.h"
|
||||
#include "l_utils.h"
|
||||
#include "l_log.h"
|
||||
#include "aasfile.h"
|
||||
#include "botlib.h"
|
||||
#include "be_aas.h"
|
||||
#include "be_aas_funcs.h"
|
||||
#include "be_interface.h"
|
||||
#include "be_aas_def.h"
|
||||
|
||||
#define MASK_SOLID CONTENTS_PLAYERCLIP
|
||||
|
||||
//FIXME: these might change
|
||||
enum {
|
||||
ET_GENERAL,
|
||||
ET_PLAYER,
|
||||
ET_ITEM,
|
||||
ET_MISSILE,
|
||||
ET_MOVER
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_UpdateEntity(int entnum, bot_entitystate_t *state)
|
||||
{
|
||||
int relink;
|
||||
aas_entity_t *ent;
|
||||
vec3_t absmins, absmaxs;
|
||||
|
||||
if (!aasworld.loaded)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "AAS_UpdateEntity: not loaded\n");
|
||||
return BLERR_NOAASFILE;
|
||||
} //end if
|
||||
|
||||
ent = &aasworld.entities[entnum];
|
||||
|
||||
if (!state) {
|
||||
//unlink the entity
|
||||
AAS_UnlinkFromAreas(ent->areas);
|
||||
//unlink the entity from the BSP leaves
|
||||
AAS_UnlinkFromBSPLeaves(ent->leaves);
|
||||
//
|
||||
ent->areas = NULL;
|
||||
//
|
||||
ent->leaves = NULL;
|
||||
return BLERR_NOERROR;
|
||||
}
|
||||
|
||||
ent->i.update_time = AAS_Time() - ent->i.ltime;
|
||||
ent->i.type = state->type;
|
||||
ent->i.flags = state->flags;
|
||||
ent->i.ltime = AAS_Time();
|
||||
VectorCopy(ent->i.origin, ent->i.lastvisorigin);
|
||||
VectorCopy(state->old_origin, ent->i.old_origin);
|
||||
ent->i.solid = state->solid;
|
||||
ent->i.groundent = state->groundent;
|
||||
ent->i.modelindex = state->modelindex;
|
||||
ent->i.modelindex2 = state->modelindex2;
|
||||
ent->i.frame = state->frame;
|
||||
ent->i.event = state->event;
|
||||
ent->i.eventParm = state->eventParm;
|
||||
ent->i.powerups = state->powerups;
|
||||
ent->i.weapon = state->weapon;
|
||||
ent->i.legsAnim = state->legsAnim;
|
||||
ent->i.torsoAnim = state->torsoAnim;
|
||||
//number of the entity
|
||||
ent->i.number = entnum;
|
||||
//updated so set valid flag
|
||||
ent->i.valid = qtrue;
|
||||
//link everything the first frame
|
||||
if (aasworld.numframes == 1) relink = qtrue;
|
||||
else relink = qfalse;
|
||||
//
|
||||
if (ent->i.solid == SOLID_BSP)
|
||||
{
|
||||
//if the angles of the model changed
|
||||
if (!VectorCompare(state->angles, ent->i.angles))
|
||||
{
|
||||
VectorCopy(state->angles, ent->i.angles);
|
||||
relink = qtrue;
|
||||
} //end if
|
||||
//get the mins and maxs of the model
|
||||
//FIXME: rotate mins and maxs
|
||||
AAS_BSPModelMinsMaxsOrigin(ent->i.modelindex, ent->i.angles, ent->i.mins, ent->i.maxs, NULL);
|
||||
} //end if
|
||||
else if (ent->i.solid == SOLID_BBOX)
|
||||
{
|
||||
//if the bounding box size changed
|
||||
if (!VectorCompare(state->mins, ent->i.mins) ||
|
||||
!VectorCompare(state->maxs, ent->i.maxs))
|
||||
{
|
||||
VectorCopy(state->mins, ent->i.mins);
|
||||
VectorCopy(state->maxs, ent->i.maxs);
|
||||
relink = qtrue;
|
||||
} //end if
|
||||
VectorCopy(state->angles, ent->i.angles);
|
||||
} //end if
|
||||
//if the origin changed
|
||||
if (!VectorCompare(state->origin, ent->i.origin))
|
||||
{
|
||||
VectorCopy(state->origin, ent->i.origin);
|
||||
relink = qtrue;
|
||||
} //end if
|
||||
//if the entity should be relinked
|
||||
if (relink)
|
||||
{
|
||||
//don't link the world model
|
||||
if (entnum != ENTITYNUM_WORLD)
|
||||
{
|
||||
//absolute mins and maxs
|
||||
VectorAdd(ent->i.mins, ent->i.origin, absmins);
|
||||
VectorAdd(ent->i.maxs, ent->i.origin, absmaxs);
|
||||
//unlink the entity
|
||||
AAS_UnlinkFromAreas(ent->areas);
|
||||
//relink the entity to the AAS areas (use the larges bbox)
|
||||
ent->areas = AAS_LinkEntityClientBBox(absmins, absmaxs, entnum, PRESENCE_NORMAL);
|
||||
//unlink the entity from the BSP leaves
|
||||
AAS_UnlinkFromBSPLeaves(ent->leaves);
|
||||
//link the entity to the world BSP tree
|
||||
ent->leaves = AAS_BSPLinkEntity(absmins, absmaxs, entnum, 0);
|
||||
} //end if
|
||||
} //end if
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function AAS_UpdateEntity
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_EntityInfo(int entnum, aas_entityinfo_t *info)
|
||||
{
|
||||
if (!aasworld.initialized)
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "AAS_EntityInfo: aasworld not initialized\n");
|
||||
Com_Memset(info, 0, sizeof(aas_entityinfo_t));
|
||||
return;
|
||||
} //end if
|
||||
|
||||
if (entnum < 0 || entnum >= aasworld.maxentities)
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "AAS_EntityInfo: entnum %d out of range\n", entnum);
|
||||
Com_Memset(info, 0, sizeof(aas_entityinfo_t));
|
||||
return;
|
||||
} //end if
|
||||
|
||||
Com_Memcpy(info, &aasworld.entities[entnum].i, sizeof(aas_entityinfo_t));
|
||||
} //end of the function AAS_EntityInfo
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_EntityOrigin(int entnum, vec3_t origin)
|
||||
{
|
||||
if (entnum < 0 || entnum >= aasworld.maxentities)
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "AAS_EntityOrigin: entnum %d out of range\n", entnum);
|
||||
VectorClear(origin);
|
||||
return;
|
||||
} //end if
|
||||
|
||||
VectorCopy(aasworld.entities[entnum].i.origin, origin);
|
||||
} //end of the function AAS_EntityOrigin
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_EntityModelindex(int entnum)
|
||||
{
|
||||
if (entnum < 0 || entnum >= aasworld.maxentities)
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "AAS_EntityModelindex: entnum %d out of range\n", entnum);
|
||||
return 0;
|
||||
} //end if
|
||||
return aasworld.entities[entnum].i.modelindex;
|
||||
} //end of the function AAS_EntityModelindex
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_EntityType(int entnum)
|
||||
{
|
||||
if (!aasworld.initialized) return 0;
|
||||
|
||||
if (entnum < 0 || entnum >= aasworld.maxentities)
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "AAS_EntityType: entnum %d out of range\n", entnum);
|
||||
return 0;
|
||||
} //end if
|
||||
return aasworld.entities[entnum].i.type;
|
||||
} //end of the AAS_EntityType
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_EntityModelNum(int entnum)
|
||||
{
|
||||
if (!aasworld.initialized) return 0;
|
||||
|
||||
if (entnum < 0 || entnum >= aasworld.maxentities)
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "AAS_EntityModelNum: entnum %d out of range\n", entnum);
|
||||
return 0;
|
||||
} //end if
|
||||
return aasworld.entities[entnum].i.modelindex;
|
||||
} //end of the function AAS_EntityModelNum
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_OriginOfMoverWithModelNum(int modelnum, vec3_t origin)
|
||||
{
|
||||
int i;
|
||||
aas_entity_t *ent;
|
||||
|
||||
for (i = 0; i < aasworld.maxentities; i++)
|
||||
{
|
||||
ent = &aasworld.entities[i];
|
||||
if (ent->i.type == ET_MOVER)
|
||||
{
|
||||
if (ent->i.modelindex == modelnum)
|
||||
{
|
||||
VectorCopy(ent->i.origin, origin);
|
||||
return qtrue;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end for
|
||||
return qfalse;
|
||||
} //end of the function AAS_OriginOfMoverWithModelNum
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_EntitySize(int entnum, vec3_t mins, vec3_t maxs)
|
||||
{
|
||||
aas_entity_t *ent;
|
||||
|
||||
if (!aasworld.initialized) return;
|
||||
|
||||
if (entnum < 0 || entnum >= aasworld.maxentities)
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "AAS_EntitySize: entnum %d out of range\n", entnum);
|
||||
return;
|
||||
} //end if
|
||||
|
||||
ent = &aasworld.entities[entnum];
|
||||
VectorCopy(ent->i.mins, mins);
|
||||
VectorCopy(ent->i.maxs, maxs);
|
||||
} //end of the function AAS_EntitySize
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_EntityBSPData(int entnum, bsp_entdata_t *entdata)
|
||||
{
|
||||
aas_entity_t *ent;
|
||||
|
||||
ent = &aasworld.entities[entnum];
|
||||
VectorCopy(ent->i.origin, entdata->origin);
|
||||
VectorCopy(ent->i.angles, entdata->angles);
|
||||
VectorAdd(ent->i.origin, ent->i.mins, entdata->absmins);
|
||||
VectorAdd(ent->i.origin, ent->i.maxs, entdata->absmaxs);
|
||||
entdata->solid = ent->i.solid;
|
||||
entdata->modelnum = ent->i.modelindex - 1;
|
||||
} //end of the function AAS_EntityBSPData
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ResetEntityLinks(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < aasworld.maxentities; i++)
|
||||
{
|
||||
aasworld.entities[i].areas = NULL;
|
||||
aasworld.entities[i].leaves = NULL;
|
||||
} //end for
|
||||
} //end of the function AAS_ResetEntityLinks
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_InvalidateEntities(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < aasworld.maxentities; i++)
|
||||
{
|
||||
aasworld.entities[i].i.valid = qfalse;
|
||||
aasworld.entities[i].i.number = i;
|
||||
} //end for
|
||||
} //end of the function AAS_InvalidateEntities
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_UnlinkInvalidEntities(void)
|
||||
{
|
||||
int i;
|
||||
aas_entity_t *ent;
|
||||
|
||||
for (i = 0; i < aasworld.maxentities; i++)
|
||||
{
|
||||
ent = &aasworld.entities[i];
|
||||
if (!ent->i.valid)
|
||||
{
|
||||
AAS_UnlinkFromAreas( ent->areas );
|
||||
ent->areas = NULL;
|
||||
AAS_UnlinkFromBSPLeaves( ent->leaves );
|
||||
ent->leaves = NULL;
|
||||
} //end for
|
||||
} //end for
|
||||
} //end of the function AAS_UnlinkInvalidEntities
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_NearestEntity(vec3_t origin, int modelindex)
|
||||
{
|
||||
int i, bestentnum;
|
||||
float dist, bestdist;
|
||||
aas_entity_t *ent;
|
||||
vec3_t dir;
|
||||
|
||||
bestentnum = 0;
|
||||
bestdist = 99999;
|
||||
for (i = 0; i < aasworld.maxentities; i++)
|
||||
{
|
||||
ent = &aasworld.entities[i];
|
||||
if (ent->i.modelindex != modelindex) continue;
|
||||
VectorSubtract(ent->i.origin, origin, dir);
|
||||
if (abs(dir[0]) < 40)
|
||||
{
|
||||
if (abs(dir[1]) < 40)
|
||||
{
|
||||
dist = VectorLength(dir);
|
||||
if (dist < bestdist)
|
||||
{
|
||||
bestdist = dist;
|
||||
bestentnum = i;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end if
|
||||
} //end for
|
||||
return bestentnum;
|
||||
} //end of the function AAS_NearestEntity
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_BestReachableEntityArea(int entnum)
|
||||
{
|
||||
aas_entity_t *ent;
|
||||
|
||||
ent = &aasworld.entities[entnum];
|
||||
return AAS_BestReachableLinkArea(ent->areas);
|
||||
} //end of the function AAS_BestReachableEntityArea
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_NextEntity(int entnum)
|
||||
{
|
||||
if (!aasworld.loaded) return 0;
|
||||
|
||||
if (entnum < 0) entnum = -1;
|
||||
while(++entnum < aasworld.maxentities)
|
||||
{
|
||||
if (aasworld.entities[entnum].i.valid) return entnum;
|
||||
} //end while
|
||||
return 0;
|
||||
} //end of the function AAS_NextEntity
|
63
tools/quake3/bspc/deps/botlib/be_aas_entity.h
Normal file
63
tools/quake3/bspc/deps/botlib/be_aas_entity.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_entity.h
|
||||
*
|
||||
* desc: AAS
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_aas_entity.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef AASINTERN
|
||||
//invalidates all entity infos
|
||||
void AAS_InvalidateEntities(void);
|
||||
//unlink not updated entities
|
||||
void AAS_UnlinkInvalidEntities(void);
|
||||
//resets the entity AAS and BSP links (sets areas and leaves pointers to NULL)
|
||||
void AAS_ResetEntityLinks(void);
|
||||
//updates an entity
|
||||
int AAS_UpdateEntity(int ent, bot_entitystate_t *state);
|
||||
//gives the entity data used for collision detection
|
||||
void AAS_EntityBSPData(int entnum, bsp_entdata_t *entdata);
|
||||
#endif //AASINTERN
|
||||
|
||||
//returns the size of the entity bounding box in mins and maxs
|
||||
void AAS_EntitySize(int entnum, vec3_t mins, vec3_t maxs);
|
||||
//returns the BSP model number of the entity
|
||||
int AAS_EntityModelNum(int entnum);
|
||||
//returns the origin of an entity with the given model number
|
||||
int AAS_OriginOfMoverWithModelNum(int modelnum, vec3_t origin);
|
||||
//returns the best reachable area the entity is situated in
|
||||
int AAS_BestReachableEntityArea(int entnum);
|
||||
//returns the info of the given entity
|
||||
void AAS_EntityInfo(int entnum, aas_entityinfo_t *info);
|
||||
//returns the next entity
|
||||
int AAS_NextEntity(int entnum);
|
||||
//returns the origin of the entity
|
||||
void AAS_EntityOrigin(int entnum, vec3_t origin);
|
||||
//returns the entity type
|
||||
int AAS_EntityType(int entnum);
|
||||
//returns the model index of the entity
|
||||
int AAS_EntityModelindex(int entnum);
|
||||
|
582
tools/quake3/bspc/deps/botlib/be_aas_file.c
Normal file
582
tools/quake3/bspc/deps/botlib/be_aas_file.c
Normal file
|
@ -0,0 +1,582 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_file.c
|
||||
*
|
||||
* desc: AAS file loading/writing
|
||||
*
|
||||
* $Archive: /MissionPack/code/botlib/be_aas_file.c $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "l_memory.h"
|
||||
#include "l_script.h"
|
||||
#include "l_precomp.h"
|
||||
#include "l_struct.h"
|
||||
#include "l_libvar.h"
|
||||
#include "l_utils.h"
|
||||
#include "aasfile.h"
|
||||
#include "botlib.h"
|
||||
#include "be_aas.h"
|
||||
#include "be_aas_funcs.h"
|
||||
#include "be_interface.h"
|
||||
#include "be_aas_def.h"
|
||||
|
||||
//#define AASFILEDEBUG
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_SwapAASData(void)
|
||||
{
|
||||
int i, j;
|
||||
//bounding boxes
|
||||
for (i = 0; i < aasworld.numbboxes; i++)
|
||||
{
|
||||
aasworld.bboxes[i].presencetype = LittleLong(aasworld.bboxes[i].presencetype);
|
||||
aasworld.bboxes[i].flags = LittleLong(aasworld.bboxes[i].flags);
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
aasworld.bboxes[i].mins[j] = LittleLong(aasworld.bboxes[i].mins[j]);
|
||||
aasworld.bboxes[i].maxs[j] = LittleLong(aasworld.bboxes[i].maxs[j]);
|
||||
} //end for
|
||||
} //end for
|
||||
//vertexes
|
||||
for (i = 0; i < aasworld.numvertexes; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
aasworld.vertexes[i][j] = LittleFloat(aasworld.vertexes[i][j]);
|
||||
} //end for
|
||||
//planes
|
||||
for (i = 0; i < aasworld.numplanes; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
aasworld.planes[i].normal[j] = LittleFloat(aasworld.planes[i].normal[j]);
|
||||
aasworld.planes[i].dist = LittleFloat(aasworld.planes[i].dist);
|
||||
aasworld.planes[i].type = LittleLong(aasworld.planes[i].type);
|
||||
} //end for
|
||||
//edges
|
||||
for (i = 0; i < aasworld.numedges; i++)
|
||||
{
|
||||
aasworld.edges[i].v[0] = LittleLong(aasworld.edges[i].v[0]);
|
||||
aasworld.edges[i].v[1] = LittleLong(aasworld.edges[i].v[1]);
|
||||
} //end for
|
||||
//edgeindex
|
||||
for (i = 0; i < aasworld.edgeindexsize; i++)
|
||||
{
|
||||
aasworld.edgeindex[i] = LittleLong(aasworld.edgeindex[i]);
|
||||
} //end for
|
||||
//faces
|
||||
for (i = 0; i < aasworld.numfaces; i++)
|
||||
{
|
||||
aasworld.faces[i].planenum = LittleLong(aasworld.faces[i].planenum);
|
||||
aasworld.faces[i].faceflags = LittleLong(aasworld.faces[i].faceflags);
|
||||
aasworld.faces[i].numedges = LittleLong(aasworld.faces[i].numedges);
|
||||
aasworld.faces[i].firstedge = LittleLong(aasworld.faces[i].firstedge);
|
||||
aasworld.faces[i].frontarea = LittleLong(aasworld.faces[i].frontarea);
|
||||
aasworld.faces[i].backarea = LittleLong(aasworld.faces[i].backarea);
|
||||
} //end for
|
||||
//face index
|
||||
for (i = 0; i < aasworld.faceindexsize; i++)
|
||||
{
|
||||
aasworld.faceindex[i] = LittleLong(aasworld.faceindex[i]);
|
||||
} //end for
|
||||
//convex areas
|
||||
for (i = 0; i < aasworld.numareas; i++)
|
||||
{
|
||||
aasworld.areas[i].areanum = LittleLong(aasworld.areas[i].areanum);
|
||||
aasworld.areas[i].numfaces = LittleLong(aasworld.areas[i].numfaces);
|
||||
aasworld.areas[i].firstface = LittleLong(aasworld.areas[i].firstface);
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
aasworld.areas[i].mins[j] = LittleFloat(aasworld.areas[i].mins[j]);
|
||||
aasworld.areas[i].maxs[j] = LittleFloat(aasworld.areas[i].maxs[j]);
|
||||
aasworld.areas[i].center[j] = LittleFloat(aasworld.areas[i].center[j]);
|
||||
} //end for
|
||||
} //end for
|
||||
//area settings
|
||||
for (i = 0; i < aasworld.numareasettings; i++)
|
||||
{
|
||||
aasworld.areasettings[i].contents = LittleLong(aasworld.areasettings[i].contents);
|
||||
aasworld.areasettings[i].areaflags = LittleLong(aasworld.areasettings[i].areaflags);
|
||||
aasworld.areasettings[i].presencetype = LittleLong(aasworld.areasettings[i].presencetype);
|
||||
aasworld.areasettings[i].cluster = LittleLong(aasworld.areasettings[i].cluster);
|
||||
aasworld.areasettings[i].clusterareanum = LittleLong(aasworld.areasettings[i].clusterareanum);
|
||||
aasworld.areasettings[i].numreachableareas = LittleLong(aasworld.areasettings[i].numreachableareas);
|
||||
aasworld.areasettings[i].firstreachablearea = LittleLong(aasworld.areasettings[i].firstreachablearea);
|
||||
} //end for
|
||||
//area reachability
|
||||
for (i = 0; i < aasworld.reachabilitysize; i++)
|
||||
{
|
||||
aasworld.reachability[i].areanum = LittleLong(aasworld.reachability[i].areanum);
|
||||
aasworld.reachability[i].facenum = LittleLong(aasworld.reachability[i].facenum);
|
||||
aasworld.reachability[i].edgenum = LittleLong(aasworld.reachability[i].edgenum);
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
aasworld.reachability[i].start[j] = LittleFloat(aasworld.reachability[i].start[j]);
|
||||
aasworld.reachability[i].end[j] = LittleFloat(aasworld.reachability[i].end[j]);
|
||||
} //end for
|
||||
aasworld.reachability[i].traveltype = LittleLong(aasworld.reachability[i].traveltype);
|
||||
aasworld.reachability[i].traveltime = LittleShort(aasworld.reachability[i].traveltime);
|
||||
} //end for
|
||||
//nodes
|
||||
for (i = 0; i < aasworld.numnodes; i++)
|
||||
{
|
||||
aasworld.nodes[i].planenum = LittleLong(aasworld.nodes[i].planenum);
|
||||
aasworld.nodes[i].children[0] = LittleLong(aasworld.nodes[i].children[0]);
|
||||
aasworld.nodes[i].children[1] = LittleLong(aasworld.nodes[i].children[1]);
|
||||
} //end for
|
||||
//cluster portals
|
||||
for (i = 0; i < aasworld.numportals; i++)
|
||||
{
|
||||
aasworld.portals[i].areanum = LittleLong(aasworld.portals[i].areanum);
|
||||
aasworld.portals[i].frontcluster = LittleLong(aasworld.portals[i].frontcluster);
|
||||
aasworld.portals[i].backcluster = LittleLong(aasworld.portals[i].backcluster);
|
||||
aasworld.portals[i].clusterareanum[0] = LittleLong(aasworld.portals[i].clusterareanum[0]);
|
||||
aasworld.portals[i].clusterareanum[1] = LittleLong(aasworld.portals[i].clusterareanum[1]);
|
||||
} //end for
|
||||
//cluster portal index
|
||||
for (i = 0; i < aasworld.portalindexsize; i++)
|
||||
{
|
||||
aasworld.portalindex[i] = LittleLong(aasworld.portalindex[i]);
|
||||
} //end for
|
||||
//cluster
|
||||
for (i = 0; i < aasworld.numclusters; i++)
|
||||
{
|
||||
aasworld.clusters[i].numareas = LittleLong(aasworld.clusters[i].numareas);
|
||||
aasworld.clusters[i].numreachabilityareas = LittleLong(aasworld.clusters[i].numreachabilityareas);
|
||||
aasworld.clusters[i].numportals = LittleLong(aasworld.clusters[i].numportals);
|
||||
aasworld.clusters[i].firstportal = LittleLong(aasworld.clusters[i].firstportal);
|
||||
} //end for
|
||||
} //end of the function AAS_SwapAASData
|
||||
//===========================================================================
|
||||
// dump the current loaded aas file
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_DumpAASData(void)
|
||||
{
|
||||
aasworld.numbboxes = 0;
|
||||
if (aasworld.bboxes) FreeMemory(aasworld.bboxes);
|
||||
aasworld.bboxes = NULL;
|
||||
aasworld.numvertexes = 0;
|
||||
if (aasworld.vertexes) FreeMemory(aasworld.vertexes);
|
||||
aasworld.vertexes = NULL;
|
||||
aasworld.numplanes = 0;
|
||||
if (aasworld.planes) FreeMemory(aasworld.planes);
|
||||
aasworld.planes = NULL;
|
||||
aasworld.numedges = 0;
|
||||
if (aasworld.edges) FreeMemory(aasworld.edges);
|
||||
aasworld.edges = NULL;
|
||||
aasworld.edgeindexsize = 0;
|
||||
if (aasworld.edgeindex) FreeMemory(aasworld.edgeindex);
|
||||
aasworld.edgeindex = NULL;
|
||||
aasworld.numfaces = 0;
|
||||
if (aasworld.faces) FreeMemory(aasworld.faces);
|
||||
aasworld.faces = NULL;
|
||||
aasworld.faceindexsize = 0;
|
||||
if (aasworld.faceindex) FreeMemory(aasworld.faceindex);
|
||||
aasworld.faceindex = NULL;
|
||||
aasworld.numareas = 0;
|
||||
if (aasworld.areas) FreeMemory(aasworld.areas);
|
||||
aasworld.areas = NULL;
|
||||
aasworld.numareasettings = 0;
|
||||
if (aasworld.areasettings) FreeMemory(aasworld.areasettings);
|
||||
aasworld.areasettings = NULL;
|
||||
aasworld.reachabilitysize = 0;
|
||||
if (aasworld.reachability) FreeMemory(aasworld.reachability);
|
||||
aasworld.reachability = NULL;
|
||||
aasworld.numnodes = 0;
|
||||
if (aasworld.nodes) FreeMemory(aasworld.nodes);
|
||||
aasworld.nodes = NULL;
|
||||
aasworld.numportals = 0;
|
||||
if (aasworld.portals) FreeMemory(aasworld.portals);
|
||||
aasworld.portals = NULL;
|
||||
aasworld.numportals = 0;
|
||||
if (aasworld.portalindex) FreeMemory(aasworld.portalindex);
|
||||
aasworld.portalindex = NULL;
|
||||
aasworld.portalindexsize = 0;
|
||||
if (aasworld.clusters) FreeMemory(aasworld.clusters);
|
||||
aasworld.clusters = NULL;
|
||||
aasworld.numclusters = 0;
|
||||
//
|
||||
aasworld.loaded = qfalse;
|
||||
aasworld.initialized = qfalse;
|
||||
aasworld.savefile = qfalse;
|
||||
} //end of the function AAS_DumpAASData
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
#ifdef AASFILEDEBUG
|
||||
void AAS_FileInfo(void)
|
||||
{
|
||||
int i, n, optimized;
|
||||
|
||||
botimport.Print(PRT_MESSAGE, "version = %d\n", AASVERSION);
|
||||
botimport.Print(PRT_MESSAGE, "numvertexes = %d\n", aasworld.numvertexes);
|
||||
botimport.Print(PRT_MESSAGE, "numplanes = %d\n", aasworld.numplanes);
|
||||
botimport.Print(PRT_MESSAGE, "numedges = %d\n", aasworld.numedges);
|
||||
botimport.Print(PRT_MESSAGE, "edgeindexsize = %d\n", aasworld.edgeindexsize);
|
||||
botimport.Print(PRT_MESSAGE, "numfaces = %d\n", aasworld.numfaces);
|
||||
botimport.Print(PRT_MESSAGE, "faceindexsize = %d\n", aasworld.faceindexsize);
|
||||
botimport.Print(PRT_MESSAGE, "numareas = %d\n", aasworld.numareas);
|
||||
botimport.Print(PRT_MESSAGE, "numareasettings = %d\n", aasworld.numareasettings);
|
||||
botimport.Print(PRT_MESSAGE, "reachabilitysize = %d\n", aasworld.reachabilitysize);
|
||||
botimport.Print(PRT_MESSAGE, "numnodes = %d\n", aasworld.numnodes);
|
||||
botimport.Print(PRT_MESSAGE, "numportals = %d\n", aasworld.numportals);
|
||||
botimport.Print(PRT_MESSAGE, "portalindexsize = %d\n", aasworld.portalindexsize);
|
||||
botimport.Print(PRT_MESSAGE, "numclusters = %d\n", aasworld.numclusters);
|
||||
//
|
||||
for (n = 0, i = 0; i < aasworld.numareasettings; i++)
|
||||
{
|
||||
if (aasworld.areasettings[i].areaflags & AREA_GROUNDED) n++;
|
||||
} //end for
|
||||
botimport.Print(PRT_MESSAGE, "num grounded areas = %d\n", n);
|
||||
//
|
||||
botimport.Print(PRT_MESSAGE, "planes size %d bytes\n", aasworld.numplanes * sizeof(aas_plane_t));
|
||||
botimport.Print(PRT_MESSAGE, "areas size %d bytes\n", aasworld.numareas * sizeof(aas_area_t));
|
||||
botimport.Print(PRT_MESSAGE, "areasettings size %d bytes\n", aasworld.numareasettings * sizeof(aas_areasettings_t));
|
||||
botimport.Print(PRT_MESSAGE, "nodes size %d bytes\n", aasworld.numnodes * sizeof(aas_node_t));
|
||||
botimport.Print(PRT_MESSAGE, "reachability size %d bytes\n", aasworld.reachabilitysize * sizeof(aas_reachability_t));
|
||||
botimport.Print(PRT_MESSAGE, "portals size %d bytes\n", aasworld.numportals * sizeof(aas_portal_t));
|
||||
botimport.Print(PRT_MESSAGE, "clusters size %d bytes\n", aasworld.numclusters * sizeof(aas_cluster_t));
|
||||
|
||||
optimized = aasworld.numplanes * sizeof(aas_plane_t) +
|
||||
aasworld.numareas * sizeof(aas_area_t) +
|
||||
aasworld.numareasettings * sizeof(aas_areasettings_t) +
|
||||
aasworld.numnodes * sizeof(aas_node_t) +
|
||||
aasworld.reachabilitysize * sizeof(aas_reachability_t) +
|
||||
aasworld.numportals * sizeof(aas_portal_t) +
|
||||
aasworld.numclusters * sizeof(aas_cluster_t);
|
||||
botimport.Print(PRT_MESSAGE, "optimzed size %d KB\n", optimized >> 10);
|
||||
} //end of the function AAS_FileInfo
|
||||
#endif //AASFILEDEBUG
|
||||
//===========================================================================
|
||||
// allocate memory and read a lump of a AAS file
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
char *AAS_LoadAASLump(fileHandle_t fp, int offset, int length, int *lastoffset, int size)
|
||||
{
|
||||
char *buf;
|
||||
//
|
||||
if (!length)
|
||||
{
|
||||
//just alloc a dummy
|
||||
return (char *) GetClearedHunkMemory(size+1);
|
||||
} //end if
|
||||
//seek to the data
|
||||
if (offset != *lastoffset)
|
||||
{
|
||||
botimport.Print(PRT_WARNING, "AAS file not sequentially read\n");
|
||||
if (botimport.FS_Seek(fp, offset, FS_SEEK_SET))
|
||||
{
|
||||
AAS_Error("can't seek to aas lump\n");
|
||||
AAS_DumpAASData();
|
||||
botimport.FS_FCloseFile(fp);
|
||||
return 0;
|
||||
} //end if
|
||||
} //end if
|
||||
//allocate memory
|
||||
buf = (char *) GetClearedHunkMemory(length+1);
|
||||
//read the data
|
||||
if (length)
|
||||
{
|
||||
botimport.FS_Read(buf, length, fp );
|
||||
*lastoffset += length;
|
||||
} //end if
|
||||
return buf;
|
||||
} //end of the function AAS_LoadAASLump
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_DData(unsigned char *data, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
data[i] ^= (unsigned char) i * 119;
|
||||
} //end for
|
||||
} //end of the function AAS_DData
|
||||
//===========================================================================
|
||||
// load an aas file
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_LoadAASFile(char *filename)
|
||||
{
|
||||
fileHandle_t fp;
|
||||
aas_header_t header;
|
||||
int offset, length, lastoffset;
|
||||
|
||||
botimport.Print(PRT_MESSAGE, "trying to load %s\n", filename);
|
||||
//dump current loaded aas file
|
||||
AAS_DumpAASData();
|
||||
//open the file
|
||||
botimport.FS_FOpenFile( filename, &fp, FS_READ );
|
||||
if (!fp)
|
||||
{
|
||||
AAS_Error("can't open %s\n", filename);
|
||||
return BLERR_CANNOTOPENAASFILE;
|
||||
} //end if
|
||||
//read the header
|
||||
botimport.FS_Read(&header, sizeof(aas_header_t), fp );
|
||||
lastoffset = sizeof(aas_header_t);
|
||||
//check header identification
|
||||
header.ident = LittleLong(header.ident);
|
||||
if (header.ident != AASID)
|
||||
{
|
||||
AAS_Error("%s is not an AAS file\n", filename);
|
||||
botimport.FS_FCloseFile(fp);
|
||||
return BLERR_WRONGAASFILEID;
|
||||
} //end if
|
||||
//check the version
|
||||
header.version = LittleLong(header.version);
|
||||
//
|
||||
if (header.version != AASVERSION_OLD && header.version != AASVERSION)
|
||||
{
|
||||
AAS_Error("aas file %s is version %i, not %i\n", filename, header.version, AASVERSION);
|
||||
botimport.FS_FCloseFile(fp);
|
||||
return BLERR_WRONGAASFILEVERSION;
|
||||
} //end if
|
||||
//
|
||||
if (header.version == AASVERSION)
|
||||
{
|
||||
AAS_DData((unsigned char *) &header + 8, sizeof(aas_header_t) - 8);
|
||||
} //end if
|
||||
//
|
||||
aasworld.bspchecksum = atoi(LibVarGetString( "sv_mapChecksum"));
|
||||
if (LittleLong(header.bspchecksum) != aasworld.bspchecksum)
|
||||
{
|
||||
AAS_Error("aas file %s is out of date\n", filename);
|
||||
botimport.FS_FCloseFile(fp);
|
||||
return BLERR_WRONGAASFILEVERSION;
|
||||
} //end if
|
||||
//load the lumps:
|
||||
//bounding boxes
|
||||
offset = LittleLong(header.lumps[AASLUMP_BBOXES].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_BBOXES].filelen);
|
||||
aasworld.bboxes = (aas_bbox_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_bbox_t));
|
||||
aasworld.numbboxes = length / sizeof(aas_bbox_t);
|
||||
if (aasworld.numbboxes && !aasworld.bboxes) return BLERR_CANNOTREADAASLUMP;
|
||||
//vertexes
|
||||
offset = LittleLong(header.lumps[AASLUMP_VERTEXES].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_VERTEXES].filelen);
|
||||
aasworld.vertexes = (aas_vertex_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_vertex_t));
|
||||
aasworld.numvertexes = length / sizeof(aas_vertex_t);
|
||||
if (aasworld.numvertexes && !aasworld.vertexes) return BLERR_CANNOTREADAASLUMP;
|
||||
//planes
|
||||
offset = LittleLong(header.lumps[AASLUMP_PLANES].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_PLANES].filelen);
|
||||
aasworld.planes = (aas_plane_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_plane_t));
|
||||
aasworld.numplanes = length / sizeof(aas_plane_t);
|
||||
if (aasworld.numplanes && !aasworld.planes) return BLERR_CANNOTREADAASLUMP;
|
||||
//edges
|
||||
offset = LittleLong(header.lumps[AASLUMP_EDGES].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_EDGES].filelen);
|
||||
aasworld.edges = (aas_edge_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_edge_t));
|
||||
aasworld.numedges = length / sizeof(aas_edge_t);
|
||||
if (aasworld.numedges && !aasworld.edges) return BLERR_CANNOTREADAASLUMP;
|
||||
//edgeindex
|
||||
offset = LittleLong(header.lumps[AASLUMP_EDGEINDEX].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_EDGEINDEX].filelen);
|
||||
aasworld.edgeindex = (aas_edgeindex_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_edgeindex_t));
|
||||
aasworld.edgeindexsize = length / sizeof(aas_edgeindex_t);
|
||||
if (aasworld.edgeindexsize && !aasworld.edgeindex) return BLERR_CANNOTREADAASLUMP;
|
||||
//faces
|
||||
offset = LittleLong(header.lumps[AASLUMP_FACES].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_FACES].filelen);
|
||||
aasworld.faces = (aas_face_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_face_t));
|
||||
aasworld.numfaces = length / sizeof(aas_face_t);
|
||||
if (aasworld.numfaces && !aasworld.faces) return BLERR_CANNOTREADAASLUMP;
|
||||
//faceindex
|
||||
offset = LittleLong(header.lumps[AASLUMP_FACEINDEX].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_FACEINDEX].filelen);
|
||||
aasworld.faceindex = (aas_faceindex_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_faceindex_t));
|
||||
aasworld.faceindexsize = length / sizeof(aas_faceindex_t);
|
||||
if (aasworld.faceindexsize && !aasworld.faceindex) return BLERR_CANNOTREADAASLUMP;
|
||||
//convex areas
|
||||
offset = LittleLong(header.lumps[AASLUMP_AREAS].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_AREAS].filelen);
|
||||
aasworld.areas = (aas_area_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_area_t));
|
||||
aasworld.numareas = length / sizeof(aas_area_t);
|
||||
if (aasworld.numareas && !aasworld.areas) return BLERR_CANNOTREADAASLUMP;
|
||||
//area settings
|
||||
offset = LittleLong(header.lumps[AASLUMP_AREASETTINGS].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_AREASETTINGS].filelen);
|
||||
aasworld.areasettings = (aas_areasettings_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_areasettings_t));
|
||||
aasworld.numareasettings = length / sizeof(aas_areasettings_t);
|
||||
if (aasworld.numareasettings && !aasworld.areasettings) return BLERR_CANNOTREADAASLUMP;
|
||||
//reachability list
|
||||
offset = LittleLong(header.lumps[AASLUMP_REACHABILITY].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_REACHABILITY].filelen);
|
||||
aasworld.reachability = (aas_reachability_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_reachability_t));
|
||||
aasworld.reachabilitysize = length / sizeof(aas_reachability_t);
|
||||
if (aasworld.reachabilitysize && !aasworld.reachability) return BLERR_CANNOTREADAASLUMP;
|
||||
//nodes
|
||||
offset = LittleLong(header.lumps[AASLUMP_NODES].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_NODES].filelen);
|
||||
aasworld.nodes = (aas_node_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_node_t));
|
||||
aasworld.numnodes = length / sizeof(aas_node_t);
|
||||
if (aasworld.numnodes && !aasworld.nodes) return BLERR_CANNOTREADAASLUMP;
|
||||
//cluster portals
|
||||
offset = LittleLong(header.lumps[AASLUMP_PORTALS].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_PORTALS].filelen);
|
||||
aasworld.portals = (aas_portal_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_portal_t));
|
||||
aasworld.numportals = length / sizeof(aas_portal_t);
|
||||
if (aasworld.numportals && !aasworld.portals) return BLERR_CANNOTREADAASLUMP;
|
||||
//cluster portal index
|
||||
offset = LittleLong(header.lumps[AASLUMP_PORTALINDEX].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_PORTALINDEX].filelen);
|
||||
aasworld.portalindex = (aas_portalindex_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_portalindex_t));
|
||||
aasworld.portalindexsize = length / sizeof(aas_portalindex_t);
|
||||
if (aasworld.portalindexsize && !aasworld.portalindex) return BLERR_CANNOTREADAASLUMP;
|
||||
//clusters
|
||||
offset = LittleLong(header.lumps[AASLUMP_CLUSTERS].fileofs);
|
||||
length = LittleLong(header.lumps[AASLUMP_CLUSTERS].filelen);
|
||||
aasworld.clusters = (aas_cluster_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_cluster_t));
|
||||
aasworld.numclusters = length / sizeof(aas_cluster_t);
|
||||
if (aasworld.numclusters && !aasworld.clusters) return BLERR_CANNOTREADAASLUMP;
|
||||
//swap everything
|
||||
AAS_SwapAASData();
|
||||
//aas file is loaded
|
||||
aasworld.loaded = qtrue;
|
||||
//close the file
|
||||
botimport.FS_FCloseFile(fp);
|
||||
//
|
||||
#ifdef AASFILEDEBUG
|
||||
AAS_FileInfo();
|
||||
#endif //AASFILEDEBUG
|
||||
//
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function AAS_LoadAASFile
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
static int AAS_WriteAASLump_offset;
|
||||
|
||||
int AAS_WriteAASLump(fileHandle_t fp, aas_header_t *h, int lumpnum, void *data, int length)
|
||||
{
|
||||
aas_lump_t *lump;
|
||||
|
||||
lump = &h->lumps[lumpnum];
|
||||
|
||||
lump->fileofs = LittleLong(AAS_WriteAASLump_offset); //LittleLong(ftell(fp));
|
||||
lump->filelen = LittleLong(length);
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
botimport.FS_Write(data, length, fp );
|
||||
} //end if
|
||||
|
||||
AAS_WriteAASLump_offset += length;
|
||||
|
||||
return qtrue;
|
||||
} //end of the function AAS_WriteAASLump
|
||||
//===========================================================================
|
||||
// aas data is useless after writing to file because it is byte swapped
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean AAS_WriteAASFile(char *filename)
|
||||
{
|
||||
aas_header_t header;
|
||||
fileHandle_t fp;
|
||||
|
||||
botimport.Print(PRT_MESSAGE, "writing %s\n", filename);
|
||||
//swap the aas data
|
||||
AAS_SwapAASData();
|
||||
//initialize the file header
|
||||
Com_Memset(&header, 0, sizeof(aas_header_t));
|
||||
header.ident = LittleLong(AASID);
|
||||
header.version = LittleLong(AASVERSION);
|
||||
header.bspchecksum = LittleLong(aasworld.bspchecksum);
|
||||
//open a new file
|
||||
botimport.FS_FOpenFile( filename, &fp, FS_WRITE );
|
||||
if (!fp)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "error opening %s\n", filename);
|
||||
return qfalse;
|
||||
} //end if
|
||||
//write the header
|
||||
botimport.FS_Write(&header, sizeof(aas_header_t), fp);
|
||||
AAS_WriteAASLump_offset = sizeof(aas_header_t);
|
||||
//add the data lumps to the file
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_BBOXES, aasworld.bboxes,
|
||||
aasworld.numbboxes * sizeof(aas_bbox_t))) return qfalse;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_VERTEXES, aasworld.vertexes,
|
||||
aasworld.numvertexes * sizeof(aas_vertex_t))) return qfalse;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_PLANES, aasworld.planes,
|
||||
aasworld.numplanes * sizeof(aas_plane_t))) return qfalse;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_EDGES, aasworld.edges,
|
||||
aasworld.numedges * sizeof(aas_edge_t))) return qfalse;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_EDGEINDEX, aasworld.edgeindex,
|
||||
aasworld.edgeindexsize * sizeof(aas_edgeindex_t))) return qfalse;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_FACES, aasworld.faces,
|
||||
aasworld.numfaces * sizeof(aas_face_t))) return qfalse;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_FACEINDEX, aasworld.faceindex,
|
||||
aasworld.faceindexsize * sizeof(aas_faceindex_t))) return qfalse;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_AREAS, aasworld.areas,
|
||||
aasworld.numareas * sizeof(aas_area_t))) return qfalse;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_AREASETTINGS, aasworld.areasettings,
|
||||
aasworld.numareasettings * sizeof(aas_areasettings_t))) return qfalse;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_REACHABILITY, aasworld.reachability,
|
||||
aasworld.reachabilitysize * sizeof(aas_reachability_t))) return qfalse;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_NODES, aasworld.nodes,
|
||||
aasworld.numnodes * sizeof(aas_node_t))) return qfalse;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_PORTALS, aasworld.portals,
|
||||
aasworld.numportals * sizeof(aas_portal_t))) return qfalse;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_PORTALINDEX, aasworld.portalindex,
|
||||
aasworld.portalindexsize * sizeof(aas_portalindex_t))) return qfalse;
|
||||
if (!AAS_WriteAASLump(fp, &header, AASLUMP_CLUSTERS, aasworld.clusters,
|
||||
aasworld.numclusters * sizeof(aas_cluster_t))) return qfalse;
|
||||
//rewrite the header with the added lumps
|
||||
botimport.FS_Seek(fp, 0, FS_SEEK_SET);
|
||||
AAS_DData((unsigned char *) &header + 8, sizeof(aas_header_t) - 8);
|
||||
botimport.FS_Write(&header, sizeof(aas_header_t), fp);
|
||||
//close the file
|
||||
botimport.FS_FCloseFile(fp);
|
||||
return qtrue;
|
||||
} //end of the function AAS_WriteAASFile
|
42
tools/quake3/bspc/deps/botlib/be_aas_file.h
Normal file
42
tools/quake3/bspc/deps/botlib/be_aas_file.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_file.h
|
||||
*
|
||||
* desc: AAS
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_aas_file.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef AASINTERN
|
||||
//loads the AAS file with the given name
|
||||
int AAS_LoadAASFile(char *filename);
|
||||
//writes an AAS file with the given name
|
||||
qboolean AAS_WriteAASFile(char *filename);
|
||||
//dumps the loaded AAS data
|
||||
void AAS_DumpAASData(void);
|
||||
//print AAS file information
|
||||
void AAS_FileInfo(void);
|
||||
#endif //AASINTERN
|
||||
|
47
tools/quake3/bspc/deps/botlib/be_aas_funcs.h
Normal file
47
tools/quake3/bspc/deps/botlib/be_aas_funcs.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_funcs.h
|
||||
*
|
||||
* desc: AAS
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_aas_funcs.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef BSPCINCLUDE
|
||||
|
||||
#include "be_aas_main.h"
|
||||
#include "be_aas_entity.h"
|
||||
#include "be_aas_sample.h"
|
||||
#include "be_aas_cluster.h"
|
||||
#include "be_aas_reach.h"
|
||||
#include "be_aas_route.h"
|
||||
#include "be_aas_routealt.h"
|
||||
#include "be_aas_debug.h"
|
||||
#include "be_aas_file.h"
|
||||
#include "be_aas_optimize.h"
|
||||
#include "be_aas_bsp.h"
|
||||
#include "be_aas_move.h"
|
||||
|
||||
#endif //BSPCINCLUDE
|
429
tools/quake3/bspc/deps/botlib/be_aas_main.c
Normal file
429
tools/quake3/bspc/deps/botlib/be_aas_main.c
Normal file
|
@ -0,0 +1,429 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_main.c
|
||||
*
|
||||
* desc: AAS
|
||||
*
|
||||
* $Archive: /MissionPack/code/botlib/be_aas_main.c $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "l_memory.h"
|
||||
#include "l_libvar.h"
|
||||
#include "l_utils.h"
|
||||
#include "l_script.h"
|
||||
#include "l_precomp.h"
|
||||
#include "l_struct.h"
|
||||
#include "l_log.h"
|
||||
#include "aasfile.h"
|
||||
#include "botlib.h"
|
||||
#include "be_aas.h"
|
||||
#include "be_aas_funcs.h"
|
||||
#include "be_interface.h"
|
||||
#include "be_aas_def.h"
|
||||
|
||||
aas_t aasworld;
|
||||
|
||||
libvar_t *saveroutingcache;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void QDECL AAS_Error(char *fmt, ...)
|
||||
{
|
||||
char str[1024];
|
||||
va_list arglist;
|
||||
|
||||
va_start(arglist, fmt);
|
||||
vsprintf(str, fmt, arglist);
|
||||
va_end(arglist);
|
||||
botimport.Print(PRT_FATAL, str);
|
||||
} //end of the function AAS_Error
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
char *AAS_StringFromIndex(char *indexname, char *stringindex[], int numindexes, int index)
|
||||
{
|
||||
if (!aasworld.indexessetup)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "%s: index %d not setup\n", indexname, index);
|
||||
return "";
|
||||
} //end if
|
||||
if (index < 0 || index >= numindexes)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "%s: index %d out of range\n", indexname, index);
|
||||
return "";
|
||||
} //end if
|
||||
if (!stringindex[index])
|
||||
{
|
||||
if (index)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "%s: reference to unused index %d\n", indexname, index);
|
||||
} //end if
|
||||
return "";
|
||||
} //end if
|
||||
return stringindex[index];
|
||||
} //end of the function AAS_StringFromIndex
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_IndexFromString(char *indexname, char *stringindex[], int numindexes, char *string)
|
||||
{
|
||||
int i;
|
||||
if (!aasworld.indexessetup)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "%s: index not setup \"%s\"\n", indexname, string);
|
||||
return 0;
|
||||
} //end if
|
||||
for (i = 0; i < numindexes; i++)
|
||||
{
|
||||
if (!stringindex[i]) continue;
|
||||
if (!Q_stricmp(stringindex[i], string)) return i;
|
||||
} //end for
|
||||
return 0;
|
||||
} //end of the function AAS_IndexFromString
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
char *AAS_ModelFromIndex(int index)
|
||||
{
|
||||
return AAS_StringFromIndex("ModelFromIndex", &aasworld.configstrings[CS_MODELS], MAX_MODELS, index);
|
||||
} //end of the function AAS_ModelFromIndex
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_IndexFromModel(char *modelname)
|
||||
{
|
||||
return AAS_IndexFromString("IndexFromModel", &aasworld.configstrings[CS_MODELS], MAX_MODELS, modelname);
|
||||
} //end of the function AAS_IndexFromModel
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_UpdateStringIndexes(int numconfigstrings, char *configstrings[])
|
||||
{
|
||||
int i;
|
||||
//set string pointers and copy the strings
|
||||
for (i = 0; i < numconfigstrings; i++)
|
||||
{
|
||||
if (configstrings[i])
|
||||
{
|
||||
//if (aasworld.configstrings[i]) FreeMemory(aasworld.configstrings[i]);
|
||||
aasworld.configstrings[i] = (char *) GetMemory(strlen(configstrings[i]) + 1);
|
||||
strcpy(aasworld.configstrings[i], configstrings[i]);
|
||||
} //end if
|
||||
} //end for
|
||||
aasworld.indexessetup = qtrue;
|
||||
} //end of the function AAS_UpdateStringIndexes
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_Loaded(void)
|
||||
{
|
||||
return aasworld.loaded;
|
||||
} //end of the function AAS_Loaded
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_Initialized(void)
|
||||
{
|
||||
return aasworld.initialized;
|
||||
} //end of the function AAS_Initialized
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_SetInitialized(void)
|
||||
{
|
||||
aasworld.initialized = qtrue;
|
||||
botimport.Print(PRT_MESSAGE, "AAS initialized.\n");
|
||||
#ifdef DEBUG
|
||||
//create all the routing cache
|
||||
//AAS_CreateAllRoutingCache();
|
||||
//
|
||||
//AAS_RoutingInfo();
|
||||
#endif
|
||||
} //end of the function AAS_SetInitialized
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ContinueInit(float time)
|
||||
{
|
||||
//if no AAS file loaded
|
||||
if (!aasworld.loaded) return;
|
||||
//if AAS is already initialized
|
||||
if (aasworld.initialized) return;
|
||||
//calculate reachability, if not finished return
|
||||
if (AAS_ContinueInitReachability(time)) return;
|
||||
//initialize clustering for the new map
|
||||
AAS_InitClustering();
|
||||
//if reachability has been calculated and an AAS file should be written
|
||||
//or there is a forced data optimization
|
||||
if (aasworld.savefile || ((int)LibVarGetValue("forcewrite")))
|
||||
{
|
||||
//optimize the AAS data
|
||||
if ((int)LibVarValue("aasoptimize", "0")) AAS_Optimize();
|
||||
//save the AAS file
|
||||
if (AAS_WriteAASFile(aasworld.filename))
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "%s written succesfully\n", aasworld.filename);
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "couldn't write %s\n", aasworld.filename);
|
||||
} //end else
|
||||
} //end if
|
||||
//initialize the routing
|
||||
AAS_InitRouting();
|
||||
//at this point AAS is initialized
|
||||
AAS_SetInitialized();
|
||||
} //end of the function AAS_ContinueInit
|
||||
//===========================================================================
|
||||
// called at the start of every frame
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_StartFrame(float time)
|
||||
{
|
||||
aasworld.time = time;
|
||||
//unlink all entities that were not updated last frame
|
||||
AAS_UnlinkInvalidEntities();
|
||||
//invalidate the entities
|
||||
AAS_InvalidateEntities();
|
||||
//initialize AAS
|
||||
AAS_ContinueInit(time);
|
||||
//
|
||||
aasworld.frameroutingupdates = 0;
|
||||
//
|
||||
if (bot_developer)
|
||||
{
|
||||
if (LibVarGetValue("showcacheupdates"))
|
||||
{
|
||||
AAS_RoutingInfo();
|
||||
LibVarSet("showcacheupdates", "0");
|
||||
} //end if
|
||||
if (LibVarGetValue("showmemoryusage"))
|
||||
{
|
||||
PrintUsedMemorySize();
|
||||
LibVarSet("showmemoryusage", "0");
|
||||
} //end if
|
||||
if (LibVarGetValue("memorydump"))
|
||||
{
|
||||
PrintMemoryLabels();
|
||||
LibVarSet("memorydump", "0");
|
||||
} //end if
|
||||
} //end if
|
||||
//
|
||||
if (saveroutingcache->value)
|
||||
{
|
||||
AAS_WriteRouteCache();
|
||||
LibVarSet("saveroutingcache", "0");
|
||||
} //end if
|
||||
//
|
||||
aasworld.numframes++;
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function AAS_StartFrame
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
float AAS_Time(void)
|
||||
{
|
||||
return aasworld.time;
|
||||
} //end of the function AAS_Time
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ProjectPointOntoVector( vec3_t point, vec3_t vStart, vec3_t vEnd, vec3_t vProj )
|
||||
{
|
||||
vec3_t pVec, vec;
|
||||
|
||||
VectorSubtract( point, vStart, pVec );
|
||||
VectorSubtract( vEnd, vStart, vec );
|
||||
VectorNormalize( vec );
|
||||
// project onto the directional vector for this segment
|
||||
VectorMA( vStart, DotProduct( pVec, vec ), vec, vProj );
|
||||
} //end of the function AAS_ProjectPointOntoVector
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_LoadFiles(const char *mapname)
|
||||
{
|
||||
int errnum;
|
||||
char aasfile[MAX_PATH];
|
||||
// char bspfile[MAX_PATH];
|
||||
|
||||
strcpy(aasworld.mapname, mapname);
|
||||
//NOTE: first reset the entity links into the AAS areas and BSP leaves
|
||||
// the AAS link heap and BSP link heap are reset after respectively the
|
||||
// AAS file and BSP file are loaded
|
||||
AAS_ResetEntityLinks();
|
||||
// load bsp info
|
||||
AAS_LoadBSPFile();
|
||||
|
||||
//load the aas file
|
||||
Com_sprintf(aasfile, MAX_PATH, "maps/%s.aas", mapname);
|
||||
errnum = AAS_LoadAASFile(aasfile);
|
||||
if (errnum != BLERR_NOERROR)
|
||||
return errnum;
|
||||
|
||||
botimport.Print(PRT_MESSAGE, "loaded %s\n", aasfile);
|
||||
strncpy(aasworld.filename, aasfile, MAX_PATH);
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function AAS_LoadFiles
|
||||
//===========================================================================
|
||||
// called everytime a map changes
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_LoadMap(const char *mapname)
|
||||
{
|
||||
int errnum;
|
||||
|
||||
//if no mapname is provided then the string indexes are updated
|
||||
if (!mapname)
|
||||
{
|
||||
return 0;
|
||||
} //end if
|
||||
//
|
||||
aasworld.initialized = qfalse;
|
||||
//NOTE: free the routing caches before loading a new map because
|
||||
// to free the caches the old number of areas, number of clusters
|
||||
// and number of areas in a clusters must be available
|
||||
AAS_FreeRoutingCaches();
|
||||
//load the map
|
||||
errnum = AAS_LoadFiles(mapname);
|
||||
if (errnum != BLERR_NOERROR)
|
||||
{
|
||||
aasworld.loaded = qfalse;
|
||||
return errnum;
|
||||
} //end if
|
||||
//
|
||||
AAS_InitSettings();
|
||||
//initialize the AAS link heap for the new map
|
||||
AAS_InitAASLinkHeap();
|
||||
//initialize the AAS linked entities for the new map
|
||||
AAS_InitAASLinkedEntities();
|
||||
//initialize reachability for the new map
|
||||
AAS_InitReachability();
|
||||
//initialize the alternative routing
|
||||
AAS_InitAlternativeRouting();
|
||||
//everything went ok
|
||||
return 0;
|
||||
} //end of the function AAS_LoadMap
|
||||
//===========================================================================
|
||||
// called when the library is first loaded
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_Setup(void)
|
||||
{
|
||||
aasworld.maxclients = (int) LibVarValue("maxclients", "128");
|
||||
aasworld.maxentities = (int) LibVarValue("maxentities", "1024");
|
||||
// as soon as it's set to 1 the routing cache will be saved
|
||||
saveroutingcache = LibVar("saveroutingcache", "0");
|
||||
//allocate memory for the entities
|
||||
if (aasworld.entities) FreeMemory(aasworld.entities);
|
||||
aasworld.entities = (aas_entity_t *) GetClearedHunkMemory(aasworld.maxentities * sizeof(aas_entity_t));
|
||||
//invalidate all the entities
|
||||
AAS_InvalidateEntities();
|
||||
//force some recalculations
|
||||
//LibVarSet("forceclustering", "1"); //force clustering calculation
|
||||
//LibVarSet("forcereachability", "1"); //force reachability calculation
|
||||
aasworld.numframes = 0;
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function AAS_Setup
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_Shutdown(void)
|
||||
{
|
||||
AAS_ShutdownAlternativeRouting();
|
||||
//
|
||||
AAS_DumpBSPData();
|
||||
//free routing caches
|
||||
AAS_FreeRoutingCaches();
|
||||
//free aas link heap
|
||||
AAS_FreeAASLinkHeap();
|
||||
//free aas linked entities
|
||||
AAS_FreeAASLinkedEntities();
|
||||
//free the aas data
|
||||
AAS_DumpAASData();
|
||||
//free the entities
|
||||
if (aasworld.entities) FreeMemory(aasworld.entities);
|
||||
//clear the aasworld structure
|
||||
Com_Memset(&aasworld, 0, sizeof(aas_t));
|
||||
//aas has not been initialized
|
||||
aasworld.initialized = qfalse;
|
||||
//NOTE: as soon as a new .bsp file is loaded the .bsp file memory is
|
||||
// freed an reallocated, so there's no need to free that memory here
|
||||
//print shutdown
|
||||
botimport.Print(PRT_MESSAGE, "AAS shutdown.\n");
|
||||
} //end of the function AAS_Shutdown
|
61
tools/quake3/bspc/deps/botlib/be_aas_main.h
Normal file
61
tools/quake3/bspc/deps/botlib/be_aas_main.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_main.h
|
||||
*
|
||||
* desc: AAS
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_aas_main.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef AASINTERN
|
||||
|
||||
extern aas_t aasworld;
|
||||
|
||||
//AAS error message
|
||||
void QDECL AAS_Error(char *fmt, ...);
|
||||
//set AAS initialized
|
||||
void AAS_SetInitialized(void);
|
||||
//setup AAS with the given number of entities and clients
|
||||
int AAS_Setup(void);
|
||||
//shutdown AAS
|
||||
void AAS_Shutdown(void);
|
||||
//start a new map
|
||||
int AAS_LoadMap(const char *mapname);
|
||||
//start a new time frame
|
||||
int AAS_StartFrame(float time);
|
||||
#endif //AASINTERN
|
||||
|
||||
//returns true if AAS is initialized
|
||||
int AAS_Initialized(void);
|
||||
//returns true if the AAS file is loaded
|
||||
int AAS_Loaded(void);
|
||||
//returns the model name from the given index
|
||||
char *AAS_ModelFromIndex(int index);
|
||||
//returns the index from the given model name
|
||||
int AAS_IndexFromModel(char *modelname);
|
||||
//returns the current time
|
||||
float AAS_Time(void);
|
||||
//
|
||||
void AAS_ProjectPointOntoVector( vec3_t point, vec3_t vStart, vec3_t vEnd, vec3_t vProj );
|
1101
tools/quake3/bspc/deps/botlib/be_aas_move.c
Normal file
1101
tools/quake3/bspc/deps/botlib/be_aas_move.c
Normal file
File diff suppressed because it is too large
Load diff
71
tools/quake3/bspc/deps/botlib/be_aas_move.h
Normal file
71
tools/quake3/bspc/deps/botlib/be_aas_move.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_move.h
|
||||
*
|
||||
* desc: AAS
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_aas_move.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef AASINTERN
|
||||
extern aas_settings_t aassettings;
|
||||
#endif //AASINTERN
|
||||
|
||||
//movement prediction
|
||||
int AAS_PredictClientMovement(struct aas_clientmove_s *move,
|
||||
int entnum, vec3_t origin,
|
||||
int presencetype, int onground,
|
||||
vec3_t velocity, vec3_t cmdmove,
|
||||
int cmdframes,
|
||||
int maxframes, float frametime,
|
||||
int stopevent, int stopareanum, int visualize);
|
||||
//predict movement until bounding box is hit
|
||||
int AAS_ClientMovementHitBBox(struct aas_clientmove_s *move,
|
||||
int entnum, vec3_t origin,
|
||||
int presencetype, int onground,
|
||||
vec3_t velocity, vec3_t cmdmove,
|
||||
int cmdframes,
|
||||
int maxframes, float frametime,
|
||||
vec3_t mins, vec3_t maxs, int visualize);
|
||||
//returns true if on the ground at the given origin
|
||||
int AAS_OnGround(vec3_t origin, int presencetype, int passent);
|
||||
//returns true if swimming at the given origin
|
||||
int AAS_Swimming(vec3_t origin);
|
||||
//returns the jump reachability run start point
|
||||
void AAS_JumpReachRunStart(struct aas_reachability_s *reach, vec3_t runstart);
|
||||
//returns true if against a ladder at the given origin
|
||||
int AAS_AgainstLadder(vec3_t origin);
|
||||
//rocket jump Z velocity when rocket-jumping at origin
|
||||
float AAS_RocketJumpZVelocity(vec3_t origin);
|
||||
//bfg jump Z velocity when bfg-jumping at origin
|
||||
float AAS_BFGJumpZVelocity(vec3_t origin);
|
||||
//calculates the horizontal velocity needed for a jump and returns true this velocity could be calculated
|
||||
int AAS_HorizontalVelocityForJump(float zvel, vec3_t start, vec3_t end, float *velocity);
|
||||
//
|
||||
void AAS_SetMovedir(vec3_t angles, vec3_t movedir);
|
||||
//
|
||||
int AAS_DropToFloor(vec3_t origin, vec3_t mins, vec3_t maxs);
|
||||
//
|
||||
void AAS_InitSettings(void);
|
312
tools/quake3/bspc/deps/botlib/be_aas_optimize.c
Normal file
312
tools/quake3/bspc/deps/botlib/be_aas_optimize.c
Normal file
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_optimize.c
|
||||
*
|
||||
* desc: decreases the .aas file size after the reachabilities have
|
||||
* been calculated, just dumps all the faces, edges and vertexes
|
||||
*
|
||||
* $Archive: /MissionPack/code/botlib/be_aas_optimize.c $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "l_libvar.h"
|
||||
#include "l_memory.h"
|
||||
#include "l_script.h"
|
||||
#include "l_precomp.h"
|
||||
#include "l_struct.h"
|
||||
#include "aasfile.h"
|
||||
#include "botlib.h"
|
||||
#include "be_aas.h"
|
||||
#include "be_aas_funcs.h"
|
||||
#include "be_interface.h"
|
||||
#include "be_aas_def.h"
|
||||
|
||||
typedef struct optimized_s
|
||||
{
|
||||
//vertexes
|
||||
int numvertexes;
|
||||
aas_vertex_t *vertexes;
|
||||
//edges
|
||||
int numedges;
|
||||
aas_edge_t *edges;
|
||||
//edge index
|
||||
int edgeindexsize;
|
||||
aas_edgeindex_t *edgeindex;
|
||||
//faces
|
||||
int numfaces;
|
||||
aas_face_t *faces;
|
||||
//face index
|
||||
int faceindexsize;
|
||||
aas_faceindex_t *faceindex;
|
||||
//convex areas
|
||||
int numareas;
|
||||
aas_area_t *areas;
|
||||
//
|
||||
int *vertexoptimizeindex;
|
||||
int *edgeoptimizeindex;
|
||||
int *faceoptimizeindex;
|
||||
} optimized_t;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_KeepEdge(aas_edge_t *edge)
|
||||
{
|
||||
return 1;
|
||||
} //end of the function AAS_KeepFace
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_OptimizeEdge(optimized_t *optimized, int edgenum)
|
||||
{
|
||||
int i, optedgenum;
|
||||
aas_edge_t *edge, *optedge;
|
||||
|
||||
edge = &aasworld.edges[abs(edgenum)];
|
||||
if (!AAS_KeepEdge(edge)) return 0;
|
||||
|
||||
optedgenum = optimized->edgeoptimizeindex[abs(edgenum)];
|
||||
if (optedgenum)
|
||||
{
|
||||
//keep the edge reversed sign
|
||||
if (edgenum > 0) return optedgenum;
|
||||
else return -optedgenum;
|
||||
} //end if
|
||||
|
||||
optedge = &optimized->edges[optimized->numedges];
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (optimized->vertexoptimizeindex[edge->v[i]])
|
||||
{
|
||||
optedge->v[i] = optimized->vertexoptimizeindex[edge->v[i]];
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
VectorCopy(aasworld.vertexes[edge->v[i]], optimized->vertexes[optimized->numvertexes]);
|
||||
optedge->v[i] = optimized->numvertexes;
|
||||
optimized->vertexoptimizeindex[edge->v[i]] = optimized->numvertexes;
|
||||
optimized->numvertexes++;
|
||||
} //end else
|
||||
} //end for
|
||||
optimized->edgeoptimizeindex[abs(edgenum)] = optimized->numedges;
|
||||
optedgenum = optimized->numedges;
|
||||
optimized->numedges++;
|
||||
//keep the edge reversed sign
|
||||
if (edgenum > 0) return optedgenum;
|
||||
else return -optedgenum;
|
||||
} //end of the function AAS_OptimizeEdge
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_KeepFace(aas_face_t *face)
|
||||
{
|
||||
if (!(face->faceflags & FACE_LADDER)) return 0;
|
||||
else return 1;
|
||||
} //end of the function AAS_KeepFace
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_OptimizeFace(optimized_t *optimized, int facenum)
|
||||
{
|
||||
int i, edgenum, optedgenum, optfacenum;
|
||||
aas_face_t *face, *optface;
|
||||
|
||||
face = &aasworld.faces[abs(facenum)];
|
||||
if (!AAS_KeepFace(face)) return 0;
|
||||
|
||||
optfacenum = optimized->faceoptimizeindex[abs(facenum)];
|
||||
if (optfacenum)
|
||||
{
|
||||
//keep the face side sign
|
||||
if (facenum > 0) return optfacenum;
|
||||
else return -optfacenum;
|
||||
} //end if
|
||||
|
||||
optface = &optimized->faces[optimized->numfaces];
|
||||
Com_Memcpy(optface, face, sizeof(aas_face_t));
|
||||
|
||||
optface->numedges = 0;
|
||||
optface->firstedge = optimized->edgeindexsize;
|
||||
for (i = 0; i < face->numedges; i++)
|
||||
{
|
||||
edgenum = aasworld.edgeindex[face->firstedge + i];
|
||||
optedgenum = AAS_OptimizeEdge(optimized, edgenum);
|
||||
if (optedgenum)
|
||||
{
|
||||
optimized->edgeindex[optface->firstedge + optface->numedges] = optedgenum;
|
||||
optface->numedges++;
|
||||
optimized->edgeindexsize++;
|
||||
} //end if
|
||||
} //end for
|
||||
optimized->faceoptimizeindex[abs(facenum)] = optimized->numfaces;
|
||||
optfacenum = optimized->numfaces;
|
||||
optimized->numfaces++;
|
||||
//keep the face side sign
|
||||
if (facenum > 0) return optfacenum;
|
||||
else return -optfacenum;
|
||||
} //end of the function AAS_OptimizeFace
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_OptimizeArea(optimized_t *optimized, int areanum)
|
||||
{
|
||||
int i, facenum, optfacenum;
|
||||
aas_area_t *area, *optarea;
|
||||
|
||||
area = &aasworld.areas[areanum];
|
||||
optarea = &optimized->areas[areanum];
|
||||
Com_Memcpy(optarea, area, sizeof(aas_area_t));
|
||||
|
||||
optarea->numfaces = 0;
|
||||
optarea->firstface = optimized->faceindexsize;
|
||||
for (i = 0; i < area->numfaces; i++)
|
||||
{
|
||||
facenum = aasworld.faceindex[area->firstface + i];
|
||||
optfacenum = AAS_OptimizeFace(optimized, facenum);
|
||||
if (optfacenum)
|
||||
{
|
||||
optimized->faceindex[optarea->firstface + optarea->numfaces] = optfacenum;
|
||||
optarea->numfaces++;
|
||||
optimized->faceindexsize++;
|
||||
} //end if
|
||||
} //end for
|
||||
} //end of the function AAS_OptimizeArea
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_OptimizeAlloc(optimized_t *optimized)
|
||||
{
|
||||
optimized->vertexes = (aas_vertex_t *) GetClearedMemory(aasworld.numvertexes * sizeof(aas_vertex_t));
|
||||
optimized->numvertexes = 0;
|
||||
optimized->edges = (aas_edge_t *) GetClearedMemory(aasworld.numedges * sizeof(aas_edge_t));
|
||||
optimized->numedges = 1; //edge zero is a dummy
|
||||
optimized->edgeindex = (aas_edgeindex_t *) GetClearedMemory(aasworld.edgeindexsize * sizeof(aas_edgeindex_t));
|
||||
optimized->edgeindexsize = 0;
|
||||
optimized->faces = (aas_face_t *) GetClearedMemory(aasworld.numfaces * sizeof(aas_face_t));
|
||||
optimized->numfaces = 1; //face zero is a dummy
|
||||
optimized->faceindex = (aas_faceindex_t *) GetClearedMemory(aasworld.faceindexsize * sizeof(aas_faceindex_t));
|
||||
optimized->faceindexsize = 0;
|
||||
optimized->areas = (aas_area_t *) GetClearedMemory(aasworld.numareas * sizeof(aas_area_t));
|
||||
optimized->numareas = aasworld.numareas;
|
||||
//
|
||||
optimized->vertexoptimizeindex = (int *) GetClearedMemory(aasworld.numvertexes * sizeof(int));
|
||||
optimized->edgeoptimizeindex = (int *) GetClearedMemory(aasworld.numedges * sizeof(int));
|
||||
optimized->faceoptimizeindex = (int *) GetClearedMemory(aasworld.numfaces * sizeof(int));
|
||||
} //end of the function AAS_OptimizeAlloc
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_OptimizeStore(optimized_t *optimized)
|
||||
{
|
||||
//store the optimized vertexes
|
||||
if (aasworld.vertexes) FreeMemory(aasworld.vertexes);
|
||||
aasworld.vertexes = optimized->vertexes;
|
||||
aasworld.numvertexes = optimized->numvertexes;
|
||||
//store the optimized edges
|
||||
if (aasworld.edges) FreeMemory(aasworld.edges);
|
||||
aasworld.edges = optimized->edges;
|
||||
aasworld.numedges = optimized->numedges;
|
||||
//store the optimized edge index
|
||||
if (aasworld.edgeindex) FreeMemory(aasworld.edgeindex);
|
||||
aasworld.edgeindex = optimized->edgeindex;
|
||||
aasworld.edgeindexsize = optimized->edgeindexsize;
|
||||
//store the optimized faces
|
||||
if (aasworld.faces) FreeMemory(aasworld.faces);
|
||||
aasworld.faces = optimized->faces;
|
||||
aasworld.numfaces = optimized->numfaces;
|
||||
//store the optimized face index
|
||||
if (aasworld.faceindex) FreeMemory(aasworld.faceindex);
|
||||
aasworld.faceindex = optimized->faceindex;
|
||||
aasworld.faceindexsize = optimized->faceindexsize;
|
||||
//store the optimized areas
|
||||
if (aasworld.areas) FreeMemory(aasworld.areas);
|
||||
aasworld.areas = optimized->areas;
|
||||
aasworld.numareas = optimized->numareas;
|
||||
//free optimize indexes
|
||||
FreeMemory(optimized->vertexoptimizeindex);
|
||||
FreeMemory(optimized->edgeoptimizeindex);
|
||||
FreeMemory(optimized->faceoptimizeindex);
|
||||
} //end of the function AAS_OptimizeStore
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_Optimize(void)
|
||||
{
|
||||
int i, sign;
|
||||
optimized_t optimized;
|
||||
|
||||
AAS_OptimizeAlloc(&optimized);
|
||||
for (i = 1; i < aasworld.numareas; i++)
|
||||
{
|
||||
AAS_OptimizeArea(&optimized, i);
|
||||
} //end for
|
||||
//reset the reachability face pointers
|
||||
for (i = 0; i < aasworld.reachabilitysize; i++)
|
||||
{
|
||||
//NOTE: for TRAVEL_ELEVATOR the facenum is the model number of
|
||||
// the elevator
|
||||
if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == TRAVEL_ELEVATOR) continue;
|
||||
//NOTE: for TRAVEL_JUMPPAD the facenum is the Z velocity and the edgenum is the hor velocity
|
||||
if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == TRAVEL_JUMPPAD) continue;
|
||||
//NOTE: for TRAVEL_FUNCBOB the facenum and edgenum contain other coded information
|
||||
if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == TRAVEL_FUNCBOB) continue;
|
||||
//
|
||||
sign = aasworld.reachability[i].facenum;
|
||||
aasworld.reachability[i].facenum = optimized.faceoptimizeindex[abs(aasworld.reachability[i].facenum)];
|
||||
if (sign < 0) aasworld.reachability[i].facenum = -aasworld.reachability[i].facenum;
|
||||
sign = aasworld.reachability[i].edgenum;
|
||||
aasworld.reachability[i].edgenum = optimized.edgeoptimizeindex[abs(aasworld.reachability[i].edgenum)];
|
||||
if (sign < 0) aasworld.reachability[i].edgenum = -aasworld.reachability[i].edgenum;
|
||||
} //end for
|
||||
//store the optimized AAS data into aasworld
|
||||
AAS_OptimizeStore(&optimized);
|
||||
//print some nice stuff :)
|
||||
botimport.Print(PRT_MESSAGE, "AAS data optimized.\n");
|
||||
} //end of the function AAS_Optimize
|
33
tools/quake3/bspc/deps/botlib/be_aas_optimize.h
Normal file
33
tools/quake3/bspc/deps/botlib/be_aas_optimize.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_optimize.h
|
||||
*
|
||||
* desc: AAS
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_aas_optimize.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void AAS_Optimize(void);
|
||||
|
4547
tools/quake3/bspc/deps/botlib/be_aas_reach.c
Normal file
4547
tools/quake3/bspc/deps/botlib/be_aas_reach.c
Normal file
File diff suppressed because it is too large
Load diff
68
tools/quake3/bspc/deps/botlib/be_aas_reach.h
Normal file
68
tools/quake3/bspc/deps/botlib/be_aas_reach.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_reach.h
|
||||
*
|
||||
* desc: AAS
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_aas_reach.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef AASINTERN
|
||||
//initialize calculating the reachabilities
|
||||
void AAS_InitReachability(void);
|
||||
//continue calculating the reachabilities
|
||||
int AAS_ContinueInitReachability(float time);
|
||||
//
|
||||
int AAS_BestReachableLinkArea(aas_link_t *areas);
|
||||
#endif //AASINTERN
|
||||
|
||||
//returns true if the are has reachabilities to other areas
|
||||
int AAS_AreaReachability(int areanum);
|
||||
//returns the best reachable area and goal origin for a bounding box at the given origin
|
||||
int AAS_BestReachableArea(vec3_t origin, vec3_t mins, vec3_t maxs, vec3_t goalorigin);
|
||||
//returns the best jumppad area from which the bbox at origin is reachable
|
||||
int AAS_BestReachableFromJumpPadArea(vec3_t origin, vec3_t mins, vec3_t maxs);
|
||||
//returns the next reachability using the given model
|
||||
int AAS_NextModelReachability(int num, int modelnum);
|
||||
//returns the total area of the ground faces of the given area
|
||||
float AAS_AreaGroundFaceArea(int areanum);
|
||||
//returns true if the area is crouch only
|
||||
int AAS_AreaCrouch(int areanum);
|
||||
//returns true if a player can swim in this area
|
||||
int AAS_AreaSwim(int areanum);
|
||||
//returns true if the area is filled with a liquid
|
||||
int AAS_AreaLiquid(int areanum);
|
||||
//returns true if the area contains lava
|
||||
int AAS_AreaLava(int areanum);
|
||||
//returns true if the area contains slime
|
||||
int AAS_AreaSlime(int areanum);
|
||||
//returns true if the area has one or more ground faces
|
||||
int AAS_AreaGrounded(int areanum);
|
||||
//returns true if the area has one or more ladder faces
|
||||
int AAS_AreaLadder(int areanum);
|
||||
//returns true if the area is a jump pad
|
||||
int AAS_AreaJumpPad(int areanum);
|
||||
//returns true if the area is donotenter
|
||||
int AAS_AreaDoNotEnter(int areanum);
|
2209
tools/quake3/bspc/deps/botlib/be_aas_route.c
Normal file
2209
tools/quake3/bspc/deps/botlib/be_aas_route.c
Normal file
File diff suppressed because it is too large
Load diff
67
tools/quake3/bspc/deps/botlib/be_aas_route.h
Normal file
67
tools/quake3/bspc/deps/botlib/be_aas_route.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_route.h
|
||||
*
|
||||
* desc: AAS
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_aas_route.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef AASINTERN
|
||||
//initialize the AAS routing
|
||||
void AAS_InitRouting(void);
|
||||
//free the AAS routing caches
|
||||
void AAS_FreeRoutingCaches(void);
|
||||
//returns the travel time from start to end in the given area
|
||||
unsigned short int AAS_AreaTravelTime(int areanum, vec3_t start, vec3_t end);
|
||||
//
|
||||
void AAS_CreateAllRoutingCache(void);
|
||||
void AAS_WriteRouteCache(void);
|
||||
//
|
||||
void AAS_RoutingInfo(void);
|
||||
#endif //AASINTERN
|
||||
|
||||
//returns the travel flag for the given travel type
|
||||
int AAS_TravelFlagForType(int traveltype);
|
||||
//return the travel flag(s) for traveling through this area
|
||||
int AAS_AreaContentsTravelFlags(int areanum);
|
||||
//returns the index of the next reachability for the given area
|
||||
int AAS_NextAreaReachability(int areanum, int reachnum);
|
||||
//returns the reachability with the given index
|
||||
void AAS_ReachabilityFromNum(int num, struct aas_reachability_s *reach);
|
||||
//returns a random goal area and goal origin
|
||||
int AAS_RandomGoalArea(int areanum, int travelflags, int *goalareanum, vec3_t goalorigin);
|
||||
//enable or disable an area for routing
|
||||
int AAS_EnableRoutingArea(int areanum, int enable);
|
||||
//returns the travel time within the given area from start to end
|
||||
unsigned short int AAS_AreaTravelTime(int areanum, vec3_t start, vec3_t end);
|
||||
//returns the travel time from the area to the goal area using the given travel flags
|
||||
int AAS_AreaTravelTimeToGoalArea(int areanum, vec3_t origin, int goalareanum, int travelflags);
|
||||
//predict a route up to a stop event
|
||||
int AAS_PredictRoute(struct aas_predictroute_s *route, int areanum, vec3_t origin,
|
||||
int goalareanum, int travelflags, int maxareas, int maxtime,
|
||||
int stopevent, int stopcontents, int stoptfl, int stopareanum);
|
||||
|
||||
|
240
tools/quake3/bspc/deps/botlib/be_aas_routealt.c
Normal file
240
tools/quake3/bspc/deps/botlib/be_aas_routealt.c
Normal file
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_routealt.c
|
||||
*
|
||||
* desc: AAS
|
||||
*
|
||||
* $Archive: /MissionPack/code/botlib/be_aas_routealt.c $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "l_utils.h"
|
||||
#include "l_memory.h"
|
||||
#include "l_log.h"
|
||||
#include "l_script.h"
|
||||
#include "l_precomp.h"
|
||||
#include "l_struct.h"
|
||||
#include "aasfile.h"
|
||||
#include "botlib.h"
|
||||
#include "be_aas.h"
|
||||
#include "be_aas_funcs.h"
|
||||
#include "be_interface.h"
|
||||
#include "be_aas_def.h"
|
||||
|
||||
#define ENABLE_ALTROUTING
|
||||
//#define ALTROUTE_DEBUG
|
||||
|
||||
typedef struct midrangearea_s
|
||||
{
|
||||
int valid;
|
||||
unsigned short starttime;
|
||||
unsigned short goaltime;
|
||||
} midrangearea_t;
|
||||
|
||||
midrangearea_t *midrangeareas;
|
||||
int *clusterareas;
|
||||
int numclusterareas;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_AltRoutingFloodCluster_r(int areanum)
|
||||
{
|
||||
int i, otherareanum;
|
||||
aas_area_t *area;
|
||||
aas_face_t *face;
|
||||
|
||||
//add the current area to the areas of the current cluster
|
||||
clusterareas[numclusterareas] = areanum;
|
||||
numclusterareas++;
|
||||
//remove the area from the mid range areas
|
||||
midrangeareas[areanum].valid = qfalse;
|
||||
//flood to other areas through the faces of this area
|
||||
area = &aasworld.areas[areanum];
|
||||
for (i = 0; i < area->numfaces; i++)
|
||||
{
|
||||
face = &aasworld.faces[abs(aasworld.faceindex[area->firstface + i])];
|
||||
//get the area at the other side of the face
|
||||
if (face->frontarea == areanum) otherareanum = face->backarea;
|
||||
else otherareanum = face->frontarea;
|
||||
//if there is an area at the other side of this face
|
||||
if (!otherareanum) continue;
|
||||
//if the other area is not a midrange area
|
||||
if (!midrangeareas[otherareanum].valid) continue;
|
||||
//
|
||||
AAS_AltRoutingFloodCluster_r(otherareanum);
|
||||
} //end for
|
||||
} //end of the function AAS_AltRoutingFloodCluster_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_AlternativeRouteGoals(vec3_t start, int startareanum, vec3_t goal, int goalareanum, int travelflags,
|
||||
aas_altroutegoal_t *altroutegoals, int maxaltroutegoals,
|
||||
int type)
|
||||
{
|
||||
#ifndef ENABLE_ALTROUTING
|
||||
return 0;
|
||||
#else
|
||||
int i, j, bestareanum;
|
||||
int numaltroutegoals, nummidrangeareas;
|
||||
int starttime, goaltime, goaltraveltime;
|
||||
float dist, bestdist;
|
||||
vec3_t mid, dir;
|
||||
#ifdef ALTROUTE_DEBUG
|
||||
int startmillisecs;
|
||||
|
||||
startmillisecs = Sys_MilliSeconds();
|
||||
#endif
|
||||
|
||||
if (!startareanum || !goalareanum)
|
||||
return 0;
|
||||
//travel time towards the goal area
|
||||
goaltraveltime = AAS_AreaTravelTimeToGoalArea(startareanum, start, goalareanum, travelflags);
|
||||
//clear the midrange areas
|
||||
Com_Memset(midrangeareas, 0, aasworld.numareas * sizeof(midrangearea_t));
|
||||
numaltroutegoals = 0;
|
||||
//
|
||||
nummidrangeareas = 0;
|
||||
//
|
||||
for (i = 1; i < aasworld.numareas; i++)
|
||||
{
|
||||
//
|
||||
if (!(type & ALTROUTEGOAL_ALL))
|
||||
{
|
||||
if (!(type & ALTROUTEGOAL_CLUSTERPORTALS && (aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL)))
|
||||
{
|
||||
if (!(type & ALTROUTEGOAL_VIEWPORTALS && (aasworld.areasettings[i].contents & AREACONTENTS_VIEWPORTAL)))
|
||||
{
|
||||
continue;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end if
|
||||
//if the area has no reachabilities
|
||||
if (!AAS_AreaReachability(i)) continue;
|
||||
//tavel time from the area to the start area
|
||||
starttime = AAS_AreaTravelTimeToGoalArea(startareanum, start, i, travelflags);
|
||||
if (!starttime) continue;
|
||||
//if the travel time from the start to the area is greater than the shortest goal travel time
|
||||
if (starttime > (float) 1.1 * goaltraveltime) continue;
|
||||
//travel time from the area to the goal area
|
||||
goaltime = AAS_AreaTravelTimeToGoalArea(i, NULL, goalareanum, travelflags);
|
||||
if (!goaltime) continue;
|
||||
//if the travel time from the area to the goal is greater than the shortest goal travel time
|
||||
if (goaltime > (float) 0.8 * goaltraveltime) continue;
|
||||
//this is a mid range area
|
||||
midrangeareas[i].valid = qtrue;
|
||||
midrangeareas[i].starttime = starttime;
|
||||
midrangeareas[i].goaltime = goaltime;
|
||||
Log_Write("%d midrange area %d", nummidrangeareas, i);
|
||||
nummidrangeareas++;
|
||||
} //end for
|
||||
//
|
||||
for (i = 1; i < aasworld.numareas; i++)
|
||||
{
|
||||
if (!midrangeareas[i].valid) continue;
|
||||
//get the areas in one cluster
|
||||
numclusterareas = 0;
|
||||
AAS_AltRoutingFloodCluster_r(i);
|
||||
//now we've got a cluster with areas through which an alternative route could go
|
||||
//get the 'center' of the cluster
|
||||
VectorClear(mid);
|
||||
for (j = 0; j < numclusterareas; j++)
|
||||
{
|
||||
VectorAdd(mid, aasworld.areas[clusterareas[j]].center, mid);
|
||||
} //end for
|
||||
VectorScale(mid, 1.0 / numclusterareas, mid);
|
||||
//get the area closest to the center of the cluster
|
||||
bestdist = 999999;
|
||||
bestareanum = 0;
|
||||
for (j = 0; j < numclusterareas; j++)
|
||||
{
|
||||
VectorSubtract(mid, aasworld.areas[clusterareas[j]].center, dir);
|
||||
dist = VectorLength(dir);
|
||||
if (dist < bestdist)
|
||||
{
|
||||
bestdist = dist;
|
||||
bestareanum = clusterareas[j];
|
||||
} //end if
|
||||
} //end for
|
||||
//now we've got an area for an alternative route
|
||||
//FIXME: add alternative goal origin
|
||||
VectorCopy(aasworld.areas[bestareanum].center, altroutegoals[numaltroutegoals].origin);
|
||||
altroutegoals[numaltroutegoals].areanum = bestareanum;
|
||||
altroutegoals[numaltroutegoals].starttraveltime = midrangeareas[bestareanum].starttime;
|
||||
altroutegoals[numaltroutegoals].goaltraveltime = midrangeareas[bestareanum].goaltime;
|
||||
altroutegoals[numaltroutegoals].extratraveltime =
|
||||
(midrangeareas[bestareanum].starttime + midrangeareas[bestareanum].goaltime) -
|
||||
goaltraveltime;
|
||||
numaltroutegoals++;
|
||||
//
|
||||
#ifdef ALTROUTE_DEBUG
|
||||
AAS_ShowAreaPolygons(bestareanum, 1, qtrue);
|
||||
#endif
|
||||
//don't return more than the maximum alternative route goals
|
||||
if (numaltroutegoals >= maxaltroutegoals) break;
|
||||
} //end for
|
||||
#ifdef ALTROUTE_DEBUG
|
||||
botimport.Print(PRT_MESSAGE, "alternative route goals in %d msec\n", Sys_MilliSeconds() - startmillisecs);
|
||||
#endif
|
||||
return numaltroutegoals;
|
||||
#endif
|
||||
} //end of the function AAS_AlternativeRouteGoals
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_InitAlternativeRouting(void)
|
||||
{
|
||||
#ifdef ENABLE_ALTROUTING
|
||||
if (midrangeareas) FreeMemory(midrangeareas);
|
||||
midrangeareas = (midrangearea_t *) GetMemory(aasworld.numareas * sizeof(midrangearea_t));
|
||||
if (clusterareas) FreeMemory(clusterareas);
|
||||
clusterareas = (int *) GetMemory(aasworld.numareas * sizeof(int));
|
||||
#endif
|
||||
} //end of the function AAS_InitAlternativeRouting
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShutdownAlternativeRouting(void)
|
||||
{
|
||||
#ifdef ENABLE_ALTROUTING
|
||||
if (midrangeareas) FreeMemory(midrangeareas);
|
||||
midrangeareas = NULL;
|
||||
if (clusterareas) FreeMemory(clusterareas);
|
||||
clusterareas = NULL;
|
||||
numclusterareas = 0;
|
||||
#endif
|
||||
} //end of the function AAS_ShutdownAlternativeRouting
|
40
tools/quake3/bspc/deps/botlib/be_aas_routealt.h
Normal file
40
tools/quake3/bspc/deps/botlib/be_aas_routealt.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_routealt.h
|
||||
*
|
||||
* desc: AAS
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_aas_routealt.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef AASINTERN
|
||||
void AAS_InitAlternativeRouting(void);
|
||||
void AAS_ShutdownAlternativeRouting(void);
|
||||
#endif //AASINTERN
|
||||
|
||||
|
||||
int AAS_AlternativeRouteGoals(vec3_t start, int startareanum, vec3_t goal, int goalareanum, int travelflags,
|
||||
aas_altroutegoal_t *altroutegoals, int maxaltroutegoals,
|
||||
int type);
|
1394
tools/quake3/bspc/deps/botlib/be_aas_sample.c
Normal file
1394
tools/quake3/bspc/deps/botlib/be_aas_sample.c
Normal file
File diff suppressed because it is too large
Load diff
69
tools/quake3/bspc/deps/botlib/be_aas_sample.h
Normal file
69
tools/quake3/bspc/deps/botlib/be_aas_sample.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_sample.h
|
||||
*
|
||||
* desc: AAS
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_aas_sample.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef AASINTERN
|
||||
void AAS_InitAASLinkHeap(void);
|
||||
void AAS_InitAASLinkedEntities(void);
|
||||
void AAS_FreeAASLinkHeap(void);
|
||||
void AAS_FreeAASLinkedEntities(void);
|
||||
aas_face_t *AAS_AreaGroundFace(int areanum, vec3_t point);
|
||||
aas_face_t *AAS_TraceEndFace(aas_trace_t *trace);
|
||||
aas_plane_t *AAS_PlaneFromNum(int planenum);
|
||||
aas_link_t *AAS_AASLinkEntity(vec3_t absmins, vec3_t absmaxs, int entnum);
|
||||
aas_link_t *AAS_LinkEntityClientBBox(vec3_t absmins, vec3_t absmaxs, int entnum, int presencetype);
|
||||
qboolean AAS_PointInsideFace(int facenum, vec3_t point, float epsilon);
|
||||
qboolean AAS_InsideFace(aas_face_t *face, vec3_t pnormal, vec3_t point, float epsilon);
|
||||
void AAS_UnlinkFromAreas(aas_link_t *areas);
|
||||
#endif //AASINTERN
|
||||
|
||||
//returns the mins and maxs of the bounding box for the given presence type
|
||||
void AAS_PresenceTypeBoundingBox(int presencetype, vec3_t mins, vec3_t maxs);
|
||||
//returns the cluster the area is in (negative portal number if the area is a portal)
|
||||
int AAS_AreaCluster(int areanum);
|
||||
//returns the presence type(s) of the area
|
||||
int AAS_AreaPresenceType(int areanum);
|
||||
//returns the presence type(s) at the given point
|
||||
int AAS_PointPresenceType(vec3_t point);
|
||||
//returns the result of the trace of a client bbox
|
||||
aas_trace_t AAS_TraceClientBBox(vec3_t start, vec3_t end, int presencetype, int passent);
|
||||
//stores the areas the trace went through and returns the number of passed areas
|
||||
int AAS_TraceAreas(vec3_t start, vec3_t end, int *areas, vec3_t *points, int maxareas);
|
||||
//returns the areas the bounding box is in
|
||||
int AAS_BBoxAreas(vec3_t absmins, vec3_t absmaxs, int *areas, int maxareas);
|
||||
//return area information
|
||||
int AAS_AreaInfo( int areanum, aas_areainfo_t *info );
|
||||
//returns the area the point is in
|
||||
int AAS_PointAreaNum(vec3_t point);
|
||||
//
|
||||
int AAS_PointReachabilityAreaIndex( vec3_t point );
|
||||
//returns the plane the given face is in
|
||||
void AAS_FacePlane(int facenum, vec3_t normal, float *dist);
|
||||
|
790
tools/quake3/bspc/deps/botlib/be_ai_char.c
Normal file
790
tools/quake3/bspc/deps/botlib/be_ai_char.c
Normal file
|
@ -0,0 +1,790 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_ai_char.c
|
||||
*
|
||||
* desc: bot characters
|
||||
*
|
||||
* $Archive: /MissionPack/code/botlib/be_ai_char.c $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "l_log.h"
|
||||
#include "l_memory.h"
|
||||
#include "l_utils.h"
|
||||
#include "l_script.h"
|
||||
#include "l_precomp.h"
|
||||
#include "l_struct.h"
|
||||
#include "l_libvar.h"
|
||||
#include "aasfile.h"
|
||||
#include "botlib.h"
|
||||
#include "be_aas.h"
|
||||
#include "be_aas_funcs.h"
|
||||
#include "be_interface.h"
|
||||
#include "be_ai_char.h"
|
||||
|
||||
#define MAX_CHARACTERISTICS 80
|
||||
|
||||
#define CT_INTEGER 1
|
||||
#define CT_FLOAT 2
|
||||
#define CT_STRING 3
|
||||
|
||||
#define DEFAULT_CHARACTER "bots/default_c.c"
|
||||
|
||||
//characteristic value
|
||||
union cvalue
|
||||
{
|
||||
int integer;
|
||||
float _float;
|
||||
char *string;
|
||||
};
|
||||
//a characteristic
|
||||
typedef struct bot_characteristic_s
|
||||
{
|
||||
char type; //characteristic type
|
||||
union cvalue value; //characteristic value
|
||||
} bot_characteristic_t;
|
||||
|
||||
//a bot character
|
||||
typedef struct bot_character_s
|
||||
{
|
||||
char filename[MAX_QPATH];
|
||||
float skill;
|
||||
bot_characteristic_t c[1]; //variable sized
|
||||
} bot_character_t;
|
||||
|
||||
bot_character_t *botcharacters[MAX_CLIENTS + 1];
|
||||
|
||||
//========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//========================================================================
|
||||
bot_character_t *BotCharacterFromHandle(int handle)
|
||||
{
|
||||
if (handle <= 0 || handle > MAX_CLIENTS)
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "character handle %d out of range\n", handle);
|
||||
return NULL;
|
||||
} //end if
|
||||
if (!botcharacters[handle])
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "invalid character %d\n", handle);
|
||||
return NULL;
|
||||
} //end if
|
||||
return botcharacters[handle];
|
||||
} //end of the function BotCharacterFromHandle
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void BotDumpCharacter(bot_character_t *ch)
|
||||
{
|
||||
int i;
|
||||
|
||||
Log_Write("%s", ch->filename);
|
||||
Log_Write("skill %d\n", ch->skill);
|
||||
Log_Write("{\n");
|
||||
for (i = 0; i < MAX_CHARACTERISTICS; i++)
|
||||
{
|
||||
switch(ch->c[i].type)
|
||||
{
|
||||
case CT_INTEGER: Log_Write(" %4d %d\n", i, ch->c[i].value.integer); break;
|
||||
case CT_FLOAT: Log_Write(" %4d %f\n", i, ch->c[i].value._float); break;
|
||||
case CT_STRING: Log_Write(" %4d %s\n", i, ch->c[i].value.string); break;
|
||||
} //end case
|
||||
} //end for
|
||||
Log_Write("}\n");
|
||||
} //end of the function BotDumpCharacter
|
||||
//========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//========================================================================
|
||||
void BotFreeCharacterStrings(bot_character_t *ch)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CHARACTERISTICS; i++)
|
||||
{
|
||||
if (ch->c[i].type == CT_STRING)
|
||||
{
|
||||
FreeMemory(ch->c[i].value.string);
|
||||
} //end if
|
||||
} //end for
|
||||
} //end of the function BotFreeCharacterStrings
|
||||
//========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//========================================================================
|
||||
void BotFreeCharacter2(int handle)
|
||||
{
|
||||
if (handle <= 0 || handle > MAX_CLIENTS)
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "character handle %d out of range\n", handle);
|
||||
return;
|
||||
} //end if
|
||||
if (!botcharacters[handle])
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "invalid character %d\n", handle);
|
||||
return;
|
||||
} //end if
|
||||
BotFreeCharacterStrings(botcharacters[handle]);
|
||||
FreeMemory(botcharacters[handle]);
|
||||
botcharacters[handle] = NULL;
|
||||
} //end of the function BotFreeCharacter2
|
||||
//========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//========================================================================
|
||||
void BotFreeCharacter(int handle)
|
||||
{
|
||||
if (!LibVarGetValue("bot_reloadcharacters")) return;
|
||||
BotFreeCharacter2(handle);
|
||||
} //end of the function BotFreeCharacter
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void BotDefaultCharacteristics(bot_character_t *ch, bot_character_t *defaultch)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CHARACTERISTICS; i++)
|
||||
{
|
||||
if (ch->c[i].type) continue;
|
||||
//
|
||||
if (defaultch->c[i].type == CT_FLOAT)
|
||||
{
|
||||
ch->c[i].type = CT_FLOAT;
|
||||
ch->c[i].value._float = defaultch->c[i].value._float;
|
||||
} //end if
|
||||
else if (defaultch->c[i].type == CT_INTEGER)
|
||||
{
|
||||
ch->c[i].type = CT_INTEGER;
|
||||
ch->c[i].value.integer = defaultch->c[i].value.integer;
|
||||
} //end else if
|
||||
else if (defaultch->c[i].type == CT_STRING)
|
||||
{
|
||||
ch->c[i].type = CT_STRING;
|
||||
ch->c[i].value.string = (char *) GetMemory(strlen(defaultch->c[i].value.string)+1);
|
||||
strcpy(ch->c[i].value.string, defaultch->c[i].value.string);
|
||||
} //end else if
|
||||
} //end for
|
||||
} //end of the function BotDefaultCharacteristics
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
bot_character_t *BotLoadCharacterFromFile(char *charfile, int skill)
|
||||
{
|
||||
int indent, index, foundcharacter;
|
||||
bot_character_t *ch;
|
||||
source_t *source;
|
||||
token_t token;
|
||||
|
||||
foundcharacter = qfalse;
|
||||
//a bot character is parsed in two phases
|
||||
PC_SetBaseFolder(BOTFILESBASEFOLDER);
|
||||
source = LoadSourceFile(charfile);
|
||||
if (!source)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "counldn't load %s\n", charfile);
|
||||
return NULL;
|
||||
} //end if
|
||||
ch = (bot_character_t *) GetClearedMemory(sizeof(bot_character_t) +
|
||||
MAX_CHARACTERISTICS * sizeof(bot_characteristic_t));
|
||||
strcpy(ch->filename, charfile);
|
||||
while(PC_ReadToken(source, &token))
|
||||
{
|
||||
if (!strcmp(token.string, "skill"))
|
||||
{
|
||||
if (!PC_ExpectTokenType(source, TT_NUMBER, 0, &token))
|
||||
{
|
||||
FreeSource(source);
|
||||
BotFreeCharacterStrings(ch);
|
||||
FreeMemory(ch);
|
||||
return NULL;
|
||||
} //end if
|
||||
if (!PC_ExpectTokenString(source, "{"))
|
||||
{
|
||||
FreeSource(source);
|
||||
BotFreeCharacterStrings(ch);
|
||||
FreeMemory(ch);
|
||||
return NULL;
|
||||
} //end if
|
||||
//if it's the correct skill
|
||||
if (skill < 0 || token.intvalue == skill)
|
||||
{
|
||||
foundcharacter = qtrue;
|
||||
ch->skill = token.intvalue;
|
||||
while(PC_ExpectAnyToken(source, &token))
|
||||
{
|
||||
if (!strcmp(token.string, "}")) break;
|
||||
if (token.type != TT_NUMBER || !(token.subtype & TT_INTEGER))
|
||||
{
|
||||
SourceError(source, "expected integer index, found %s\n", token.string);
|
||||
FreeSource(source);
|
||||
BotFreeCharacterStrings(ch);
|
||||
FreeMemory(ch);
|
||||
return NULL;
|
||||
} //end if
|
||||
index = token.intvalue;
|
||||
if (index < 0 || index > MAX_CHARACTERISTICS)
|
||||
{
|
||||
SourceError(source, "characteristic index out of range [0, %d]\n", MAX_CHARACTERISTICS);
|
||||
FreeSource(source);
|
||||
BotFreeCharacterStrings(ch);
|
||||
FreeMemory(ch);
|
||||
return NULL;
|
||||
} //end if
|
||||
if (ch->c[index].type)
|
||||
{
|
||||
SourceError(source, "characteristic %d already initialized\n", index);
|
||||
FreeSource(source);
|
||||
BotFreeCharacterStrings(ch);
|
||||
FreeMemory(ch);
|
||||
return NULL;
|
||||
} //end if
|
||||
if (!PC_ExpectAnyToken(source, &token))
|
||||
{
|
||||
FreeSource(source);
|
||||
BotFreeCharacterStrings(ch);
|
||||
FreeMemory(ch);
|
||||
return NULL;
|
||||
} //end if
|
||||
if (token.type == TT_NUMBER)
|
||||
{
|
||||
if (token.subtype & TT_FLOAT)
|
||||
{
|
||||
ch->c[index].value._float = token.floatvalue;
|
||||
ch->c[index].type = CT_FLOAT;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
ch->c[index].value.integer = token.intvalue;
|
||||
ch->c[index].type = CT_INTEGER;
|
||||
} //end else
|
||||
} //end if
|
||||
else if (token.type == TT_STRING)
|
||||
{
|
||||
StripDoubleQuotes(token.string);
|
||||
ch->c[index].value.string = GetMemory(strlen(token.string)+1);
|
||||
strcpy(ch->c[index].value.string, token.string);
|
||||
ch->c[index].type = CT_STRING;
|
||||
} //end else if
|
||||
else
|
||||
{
|
||||
SourceError(source, "expected integer, float or string, found %s\n", token.string);
|
||||
FreeSource(source);
|
||||
BotFreeCharacterStrings(ch);
|
||||
FreeMemory(ch);
|
||||
return NULL;
|
||||
} //end else
|
||||
} //end if
|
||||
break;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
indent = 1;
|
||||
while(indent)
|
||||
{
|
||||
if (!PC_ExpectAnyToken(source, &token))
|
||||
{
|
||||
FreeSource(source);
|
||||
BotFreeCharacterStrings(ch);
|
||||
FreeMemory(ch);
|
||||
return NULL;
|
||||
} //end if
|
||||
if (!strcmp(token.string, "{")) indent++;
|
||||
else if (!strcmp(token.string, "}")) indent--;
|
||||
} //end while
|
||||
} //end else
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
SourceError(source, "unknown definition %s\n", token.string);
|
||||
FreeSource(source);
|
||||
BotFreeCharacterStrings(ch);
|
||||
FreeMemory(ch);
|
||||
return NULL;
|
||||
} //end else
|
||||
} //end while
|
||||
FreeSource(source);
|
||||
//
|
||||
if (!foundcharacter)
|
||||
{
|
||||
BotFreeCharacterStrings(ch);
|
||||
FreeMemory(ch);
|
||||
return NULL;
|
||||
} //end if
|
||||
return ch;
|
||||
} //end of the function BotLoadCharacterFromFile
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int BotFindCachedCharacter(char *charfile, float skill)
|
||||
{
|
||||
int handle;
|
||||
|
||||
for (handle = 1; handle <= MAX_CLIENTS; handle++)
|
||||
{
|
||||
if ( !botcharacters[handle] ) continue;
|
||||
if ( strcmp( botcharacters[handle]->filename, charfile ) == 0 &&
|
||||
(skill < 0 || fabs(botcharacters[handle]->skill - skill) < 0.01) )
|
||||
{
|
||||
return handle;
|
||||
} //end if
|
||||
} //end for
|
||||
return 0;
|
||||
} //end of the function BotFindCachedCharacter
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int BotLoadCachedCharacter(char *charfile, float skill, int reload)
|
||||
{
|
||||
int handle, cachedhandle, intskill;
|
||||
bot_character_t *ch = NULL;
|
||||
#ifdef DEBUG
|
||||
int starttime;
|
||||
|
||||
starttime = Sys_MilliSeconds();
|
||||
#endif //DEBUG
|
||||
|
||||
//find a free spot for a character
|
||||
for (handle = 1; handle <= MAX_CLIENTS; handle++)
|
||||
{
|
||||
if (!botcharacters[handle]) break;
|
||||
} //end for
|
||||
if (handle > MAX_CLIENTS) return 0;
|
||||
//try to load a cached character with the given skill
|
||||
if (!reload)
|
||||
{
|
||||
cachedhandle = BotFindCachedCharacter(charfile, skill);
|
||||
if (cachedhandle)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "loaded cached skill %f from %s\n", skill, charfile);
|
||||
return cachedhandle;
|
||||
} //end if
|
||||
} //end else
|
||||
//
|
||||
intskill = (int) (skill + 0.5);
|
||||
//try to load the character with the given skill
|
||||
ch = BotLoadCharacterFromFile(charfile, intskill);
|
||||
if (ch)
|
||||
{
|
||||
botcharacters[handle] = ch;
|
||||
//
|
||||
botimport.Print(PRT_MESSAGE, "loaded skill %d from %s\n", intskill, charfile);
|
||||
#ifdef DEBUG
|
||||
if (bot_developer)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "skill %d loaded in %d msec from %s\n", intskill, Sys_MilliSeconds() - starttime, charfile);
|
||||
} //end if
|
||||
#endif //DEBUG
|
||||
return handle;
|
||||
} //end if
|
||||
//
|
||||
botimport.Print(PRT_WARNING, "couldn't find skill %d in %s\n", intskill, charfile);
|
||||
//
|
||||
if (!reload)
|
||||
{
|
||||
//try to load a cached default character with the given skill
|
||||
cachedhandle = BotFindCachedCharacter(DEFAULT_CHARACTER, skill);
|
||||
if (cachedhandle)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "loaded cached default skill %d from %s\n", intskill, charfile);
|
||||
return cachedhandle;
|
||||
} //end if
|
||||
} //end if
|
||||
//try to load the default character with the given skill
|
||||
ch = BotLoadCharacterFromFile(DEFAULT_CHARACTER, intskill);
|
||||
if (ch)
|
||||
{
|
||||
botcharacters[handle] = ch;
|
||||
botimport.Print(PRT_MESSAGE, "loaded default skill %d from %s\n", intskill, charfile);
|
||||
return handle;
|
||||
} //end if
|
||||
//
|
||||
if (!reload)
|
||||
{
|
||||
//try to load a cached character with any skill
|
||||
cachedhandle = BotFindCachedCharacter(charfile, -1);
|
||||
if (cachedhandle)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "loaded cached skill %f from %s\n", botcharacters[cachedhandle]->skill, charfile);
|
||||
return cachedhandle;
|
||||
} //end if
|
||||
} //end if
|
||||
//try to load a character with any skill
|
||||
ch = BotLoadCharacterFromFile(charfile, -1);
|
||||
if (ch)
|
||||
{
|
||||
botcharacters[handle] = ch;
|
||||
botimport.Print(PRT_MESSAGE, "loaded skill %f from %s\n", ch->skill, charfile);
|
||||
return handle;
|
||||
} //end if
|
||||
//
|
||||
if (!reload)
|
||||
{
|
||||
//try to load a cached character with any skill
|
||||
cachedhandle = BotFindCachedCharacter(DEFAULT_CHARACTER, -1);
|
||||
if (cachedhandle)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "loaded cached default skill %f from %s\n", botcharacters[cachedhandle]->skill, charfile);
|
||||
return cachedhandle;
|
||||
} //end if
|
||||
} //end if
|
||||
//try to load a character with any skill
|
||||
ch = BotLoadCharacterFromFile(DEFAULT_CHARACTER, -1);
|
||||
if (ch)
|
||||
{
|
||||
botcharacters[handle] = ch;
|
||||
botimport.Print(PRT_MESSAGE, "loaded default skill %f from %s\n", ch->skill, charfile);
|
||||
return handle;
|
||||
} //end if
|
||||
//
|
||||
botimport.Print(PRT_WARNING, "couldn't load any skill from %s\n", charfile);
|
||||
//couldn't load any character
|
||||
return 0;
|
||||
} //end of the function BotLoadCachedCharacter
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int BotLoadCharacterSkill(char *charfile, float skill)
|
||||
{
|
||||
int ch, defaultch;
|
||||
|
||||
defaultch = BotLoadCachedCharacter(DEFAULT_CHARACTER, skill, qfalse);
|
||||
ch = BotLoadCachedCharacter(charfile, skill, LibVarGetValue("bot_reloadcharacters"));
|
||||
|
||||
if (defaultch && ch)
|
||||
{
|
||||
BotDefaultCharacteristics(botcharacters[ch], botcharacters[defaultch]);
|
||||
} //end if
|
||||
|
||||
return ch;
|
||||
} //end of the function BotLoadCharacterSkill
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int BotInterpolateCharacters(int handle1, int handle2, float desiredskill)
|
||||
{
|
||||
bot_character_t *ch1, *ch2, *out;
|
||||
int i, handle;
|
||||
float scale;
|
||||
|
||||
ch1 = BotCharacterFromHandle(handle1);
|
||||
ch2 = BotCharacterFromHandle(handle2);
|
||||
if (!ch1 || !ch2)
|
||||
return 0;
|
||||
//find a free spot for a character
|
||||
for (handle = 1; handle <= MAX_CLIENTS; handle++)
|
||||
{
|
||||
if (!botcharacters[handle]) break;
|
||||
} //end for
|
||||
if (handle > MAX_CLIENTS) return 0;
|
||||
out = (bot_character_t *) GetClearedMemory(sizeof(bot_character_t) +
|
||||
MAX_CHARACTERISTICS * sizeof(bot_characteristic_t));
|
||||
out->skill = desiredskill;
|
||||
strcpy(out->filename, ch1->filename);
|
||||
botcharacters[handle] = out;
|
||||
|
||||
scale = (float) (desiredskill - ch1->skill) / (ch2->skill - ch1->skill);
|
||||
for (i = 0; i < MAX_CHARACTERISTICS; i++)
|
||||
{
|
||||
//
|
||||
if (ch1->c[i].type == CT_FLOAT && ch2->c[i].type == CT_FLOAT)
|
||||
{
|
||||
out->c[i].type = CT_FLOAT;
|
||||
out->c[i].value._float = ch1->c[i].value._float +
|
||||
(ch2->c[i].value._float - ch1->c[i].value._float) * scale;
|
||||
} //end if
|
||||
else if (ch1->c[i].type == CT_INTEGER)
|
||||
{
|
||||
out->c[i].type = CT_INTEGER;
|
||||
out->c[i].value.integer = ch1->c[i].value.integer;
|
||||
} //end else if
|
||||
else if (ch1->c[i].type == CT_STRING)
|
||||
{
|
||||
out->c[i].type = CT_STRING;
|
||||
out->c[i].value.string = (char *) GetMemory(strlen(ch1->c[i].value.string)+1);
|
||||
strcpy(out->c[i].value.string, ch1->c[i].value.string);
|
||||
} //end else if
|
||||
} //end for
|
||||
return handle;
|
||||
} //end of the function BotInterpolateCharacters
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int BotLoadCharacter(char *charfile, float skill)
|
||||
{
|
||||
int firstskill, secondskill, handle;
|
||||
|
||||
//make sure the skill is in the valid range
|
||||
if (skill < 1.0) skill = 1.0;
|
||||
else if (skill > 5.0) skill = 5.0;
|
||||
//skill 1, 4 and 5 should be available in the character files
|
||||
if (skill == 1.0 || skill == 4.0 || skill == 5.0)
|
||||
{
|
||||
return BotLoadCharacterSkill(charfile, skill);
|
||||
} //end if
|
||||
//check if there's a cached skill
|
||||
handle = BotFindCachedCharacter(charfile, skill);
|
||||
if (handle)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "loaded cached skill %f from %s\n", skill, charfile);
|
||||
return handle;
|
||||
} //end if
|
||||
if (skill < 4.0)
|
||||
{
|
||||
//load skill 1 and 4
|
||||
firstskill = BotLoadCharacterSkill(charfile, 1);
|
||||
if (!firstskill) return 0;
|
||||
secondskill = BotLoadCharacterSkill(charfile, 4);
|
||||
if (!secondskill) return firstskill;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
//load skill 4 and 5
|
||||
firstskill = BotLoadCharacterSkill(charfile, 4);
|
||||
if (!firstskill) return 0;
|
||||
secondskill = BotLoadCharacterSkill(charfile, 5);
|
||||
if (!secondskill) return firstskill;
|
||||
} //end else
|
||||
//interpolate between the two skills
|
||||
handle = BotInterpolateCharacters(firstskill, secondskill, skill);
|
||||
if (!handle) return 0;
|
||||
//write the character to the log file
|
||||
BotDumpCharacter(botcharacters[handle]);
|
||||
//
|
||||
return handle;
|
||||
} //end of the function BotLoadCharacter
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int CheckCharacteristicIndex(int character, int index)
|
||||
{
|
||||
bot_character_t *ch;
|
||||
|
||||
ch = BotCharacterFromHandle(character);
|
||||
if (!ch) return qfalse;
|
||||
if (index < 0 || index >= MAX_CHARACTERISTICS)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "characteristic %d does not exist\n", index);
|
||||
return qfalse;
|
||||
} //end if
|
||||
if (!ch->c[index].type)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "characteristic %d is not initialized\n", index);
|
||||
return qfalse;
|
||||
} //end if
|
||||
return qtrue;
|
||||
} //end of the function CheckCharacteristicIndex
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
float Characteristic_Float(int character, int index)
|
||||
{
|
||||
bot_character_t *ch;
|
||||
|
||||
ch = BotCharacterFromHandle(character);
|
||||
if (!ch) return 0;
|
||||
//check if the index is in range
|
||||
if (!CheckCharacteristicIndex(character, index)) return 0;
|
||||
//an integer will be converted to a float
|
||||
if (ch->c[index].type == CT_INTEGER)
|
||||
{
|
||||
return (float) ch->c[index].value.integer;
|
||||
} //end if
|
||||
//floats are just returned
|
||||
else if (ch->c[index].type == CT_FLOAT)
|
||||
{
|
||||
return ch->c[index].value._float;
|
||||
} //end else if
|
||||
//cannot convert a string pointer to a float
|
||||
else
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "characteristic %d is not a float\n", index);
|
||||
return 0;
|
||||
} //end else if
|
||||
// return 0;
|
||||
} //end of the function Characteristic_Float
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
float Characteristic_BFloat(int character, int index, float min, float max)
|
||||
{
|
||||
float value;
|
||||
bot_character_t *ch;
|
||||
|
||||
ch = BotCharacterFromHandle(character);
|
||||
if (!ch) return 0;
|
||||
if (min > max)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "cannot bound characteristic %d between %f and %f\n", index, min, max);
|
||||
return 0;
|
||||
} //end if
|
||||
value = Characteristic_Float(character, index);
|
||||
if (value < min) return min;
|
||||
if (value > max) return max;
|
||||
return value;
|
||||
} //end of the function Characteristic_BFloat
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int Characteristic_Integer(int character, int index)
|
||||
{
|
||||
bot_character_t *ch;
|
||||
|
||||
ch = BotCharacterFromHandle(character);
|
||||
if (!ch) return 0;
|
||||
//check if the index is in range
|
||||
if (!CheckCharacteristicIndex(character, index)) return 0;
|
||||
//an integer will just be returned
|
||||
if (ch->c[index].type == CT_INTEGER)
|
||||
{
|
||||
return ch->c[index].value.integer;
|
||||
} //end if
|
||||
//floats are casted to integers
|
||||
else if (ch->c[index].type == CT_FLOAT)
|
||||
{
|
||||
return (int) ch->c[index].value._float;
|
||||
} //end else if
|
||||
else
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "characteristic %d is not a integer\n", index);
|
||||
return 0;
|
||||
} //end else if
|
||||
// return 0;
|
||||
} //end of the function Characteristic_Integer
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int Characteristic_BInteger(int character, int index, int min, int max)
|
||||
{
|
||||
int value;
|
||||
bot_character_t *ch;
|
||||
|
||||
ch = BotCharacterFromHandle(character);
|
||||
if (!ch) return 0;
|
||||
if (min > max)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "cannot bound characteristic %d between %d and %d\n", index, min, max);
|
||||
return 0;
|
||||
} //end if
|
||||
value = Characteristic_Integer(character, index);
|
||||
if (value < min) return min;
|
||||
if (value > max) return max;
|
||||
return value;
|
||||
} //end of the function Characteristic_BInteger
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void Characteristic_String(int character, int index, char *buf, int size)
|
||||
{
|
||||
bot_character_t *ch;
|
||||
|
||||
ch = BotCharacterFromHandle(character);
|
||||
if (!ch) return;
|
||||
//check if the index is in range
|
||||
if (!CheckCharacteristicIndex(character, index)) return;
|
||||
//an integer will be converted to a float
|
||||
if (ch->c[index].type == CT_STRING)
|
||||
{
|
||||
strncpy(buf, ch->c[index].value.string, size-1);
|
||||
buf[size-1] = '\0';
|
||||
return;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "characteristic %d is not a string\n", index);
|
||||
return;
|
||||
} //end else if
|
||||
return;
|
||||
} //end of the function Characteristic_String
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void BotShutdownCharacters(void)
|
||||
{
|
||||
int handle;
|
||||
|
||||
for (handle = 1; handle <= MAX_CLIENTS; handle++)
|
||||
{
|
||||
if (botcharacters[handle])
|
||||
{
|
||||
BotFreeCharacter2(handle);
|
||||
} //end if
|
||||
} //end for
|
||||
} //end of the function BotShutdownCharacters
|
||||
|
48
tools/quake3/bspc/deps/botlib/be_ai_char.h
Normal file
48
tools/quake3/bspc/deps/botlib/be_ai_char.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
//
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_ai_char.h
|
||||
*
|
||||
* desc: bot characters
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_ai_char.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//loads a bot character from a file
|
||||
int BotLoadCharacter(char *charfile, float skill);
|
||||
//frees a bot character
|
||||
void BotFreeCharacter(int character);
|
||||
//returns a float characteristic
|
||||
float Characteristic_Float(int character, int index);
|
||||
//returns a bounded float characteristic
|
||||
float Characteristic_BFloat(int character, int index, float min, float max);
|
||||
//returns an integer characteristic
|
||||
int Characteristic_Integer(int character, int index);
|
||||
//returns a bounded integer characteristic
|
||||
int Characteristic_BInteger(int character, int index, int min, int max);
|
||||
//returns a string characteristic
|
||||
void Characteristic_String(int character, int index, char *buf, int size);
|
||||
//free cached bot characters
|
||||
void BotShutdownCharacters(void);
|
3017
tools/quake3/bspc/deps/botlib/be_ai_chat.c
Normal file
3017
tools/quake3/bspc/deps/botlib/be_ai_chat.c
Normal file
File diff suppressed because it is too large
Load diff
113
tools/quake3/bspc/deps/botlib/be_ai_chat.h
Normal file
113
tools/quake3/bspc/deps/botlib/be_ai_chat.h
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
//
|
||||
/*****************************************************************************
|
||||
* name: be_ai_chat.h
|
||||
*
|
||||
* desc: char AI
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_ai_chat.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define MAX_MESSAGE_SIZE 256
|
||||
#define MAX_CHATTYPE_NAME 32
|
||||
#define MAX_MATCHVARIABLES 8
|
||||
|
||||
#define CHAT_GENDERLESS 0
|
||||
#define CHAT_GENDERFEMALE 1
|
||||
#define CHAT_GENDERMALE 2
|
||||
|
||||
#define CHAT_ALL 0
|
||||
#define CHAT_TEAM 1
|
||||
#define CHAT_TELL 2
|
||||
|
||||
//a console message
|
||||
typedef struct bot_consolemessage_s
|
||||
{
|
||||
int handle;
|
||||
float time; //message time
|
||||
int type; //message type
|
||||
char message[MAX_MESSAGE_SIZE]; //message
|
||||
struct bot_consolemessage_s *prev, *next; //prev and next in list
|
||||
} bot_consolemessage_t;
|
||||
|
||||
//match variable
|
||||
typedef struct bot_matchvariable_s
|
||||
{
|
||||
char offset;
|
||||
int length;
|
||||
} bot_matchvariable_t;
|
||||
//returned to AI when a match is found
|
||||
typedef struct bot_match_s
|
||||
{
|
||||
char string[MAX_MESSAGE_SIZE];
|
||||
int type;
|
||||
int subtype;
|
||||
bot_matchvariable_t variables[MAX_MATCHVARIABLES];
|
||||
} bot_match_t;
|
||||
|
||||
//setup the chat AI
|
||||
int BotSetupChatAI(void);
|
||||
//shutdown the chat AI
|
||||
void BotShutdownChatAI(void);
|
||||
//returns the handle to a newly allocated chat state
|
||||
int BotAllocChatState(void);
|
||||
//frees the chatstate
|
||||
void BotFreeChatState(int handle);
|
||||
//adds a console message to the chat state
|
||||
void BotQueueConsoleMessage(int chatstate, int type, char *message);
|
||||
//removes the console message from the chat state
|
||||
void BotRemoveConsoleMessage(int chatstate, int handle);
|
||||
//returns the next console message from the state
|
||||
int BotNextConsoleMessage(int chatstate, bot_consolemessage_t *cm);
|
||||
//returns the number of console messages currently stored in the state
|
||||
int BotNumConsoleMessages(int chatstate);
|
||||
//selects a chat message of the given type
|
||||
void BotInitialChat(int chatstate, char *type, int mcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7);
|
||||
//returns the number of initial chat messages of the given type
|
||||
int BotNumInitialChats(int chatstate, char *type);
|
||||
//find and select a reply for the given message
|
||||
int BotReplyChat(int chatstate, char *message, int mcontext, int vcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7);
|
||||
//returns the length of the currently selected chat message
|
||||
int BotChatLength(int chatstate);
|
||||
//enters the selected chat message
|
||||
void BotEnterChat(int chatstate, int clientto, int sendto);
|
||||
//get the chat message ready to be output
|
||||
void BotGetChatMessage(int chatstate, char *buf, int size);
|
||||
//checks if the first string contains the second one, returns index into first string or -1 if not found
|
||||
int StringContains(char *str1, char *str2, int casesensitive);
|
||||
//finds a match for the given string using the match templates
|
||||
int BotFindMatch(char *str, bot_match_t *match, unsigned long int context);
|
||||
//returns a variable from a match
|
||||
void BotMatchVariable(bot_match_t *match, int variable, char *buf, int size);
|
||||
//unify all the white spaces in the string
|
||||
void UnifyWhiteSpaces(char *string);
|
||||
//replace all the context related synonyms in the string
|
||||
void BotReplaceSynonyms(char *string, unsigned long int context);
|
||||
//loads a chat file for the chat state
|
||||
int BotLoadChatFile(int chatstate, char *chatfile, char *chatname);
|
||||
//store the gender of the bot in the chat state
|
||||
void BotSetChatGender(int chatstate, int gender);
|
||||
//store the bot name in the chat state
|
||||
void BotSetChatName(int chatstate, char *name, int client);
|
||||
|
134
tools/quake3/bspc/deps/botlib/be_ai_gen.c
Normal file
134
tools/quake3/bspc/deps/botlib/be_ai_gen.c
Normal file
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_ai_gen.c
|
||||
*
|
||||
* desc: genetic selection
|
||||
*
|
||||
* $Archive: /MissionPack/code/botlib/be_ai_gen.c $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "l_memory.h"
|
||||
#include "l_log.h"
|
||||
#include "l_utils.h"
|
||||
#include "l_script.h"
|
||||
#include "l_precomp.h"
|
||||
#include "l_struct.h"
|
||||
#include "aasfile.h"
|
||||
#include "botlib.h"
|
||||
#include "be_aas.h"
|
||||
#include "be_aas_funcs.h"
|
||||
#include "be_interface.h"
|
||||
#include "be_ai_gen.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int GeneticSelection(int numranks, float *rankings)
|
||||
{
|
||||
float sum, select;
|
||||
int i, index;
|
||||
|
||||
sum = 0;
|
||||
for (i = 0; i < numranks; i++)
|
||||
{
|
||||
if (rankings[i] < 0) continue;
|
||||
sum += rankings[i];
|
||||
} //end for
|
||||
if (sum > 0)
|
||||
{
|
||||
//select a bot where the ones with the higest rankings have
|
||||
//the highest chance of being selected
|
||||
select = random() * sum;
|
||||
for (i = 0; i < numranks; i++)
|
||||
{
|
||||
if (rankings[i] < 0) continue;
|
||||
sum -= rankings[i];
|
||||
if (sum <= 0) return i;
|
||||
} //end for
|
||||
} //end if
|
||||
//select a bot randomly
|
||||
index = random() * numranks;
|
||||
for (i = 0; i < numranks; i++)
|
||||
{
|
||||
if (rankings[index] >= 0) return index;
|
||||
index = (index + 1) % numranks;
|
||||
} //end for
|
||||
return 0;
|
||||
} //end of the function GeneticSelection
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int GeneticParentsAndChildSelection(int numranks, float *ranks, int *parent1, int *parent2, int *child)
|
||||
{
|
||||
float rankings[256], max;
|
||||
int i;
|
||||
|
||||
if (numranks > 256)
|
||||
{
|
||||
botimport.Print(PRT_WARNING, "GeneticParentsAndChildSelection: too many bots\n");
|
||||
*parent1 = *parent2 = *child = 0;
|
||||
return qfalse;
|
||||
} //end if
|
||||
for (max = 0, i = 0; i < numranks; i++)
|
||||
{
|
||||
if (ranks[i] < 0) continue;
|
||||
max++;
|
||||
} //end for
|
||||
if (max < 3)
|
||||
{
|
||||
botimport.Print(PRT_WARNING, "GeneticParentsAndChildSelection: too few valid bots\n");
|
||||
*parent1 = *parent2 = *child = 0;
|
||||
return qfalse;
|
||||
} //end if
|
||||
Com_Memcpy(rankings, ranks, sizeof(float) * numranks);
|
||||
//select first parent
|
||||
*parent1 = GeneticSelection(numranks, rankings);
|
||||
rankings[*parent1] = -1;
|
||||
//select second parent
|
||||
*parent2 = GeneticSelection(numranks, rankings);
|
||||
rankings[*parent2] = -1;
|
||||
//reverse the rankings
|
||||
max = 0;
|
||||
for (i = 0; i < numranks; i++)
|
||||
{
|
||||
if (rankings[i] < 0) continue;
|
||||
if (rankings[i] > max) max = rankings[i];
|
||||
} //end for
|
||||
for (i = 0; i < numranks; i++)
|
||||
{
|
||||
if (rankings[i] < 0) continue;
|
||||
rankings[i] = max - rankings[i];
|
||||
} //end for
|
||||
//select child
|
||||
*child = GeneticSelection(numranks, rankings);
|
||||
return qtrue;
|
||||
} //end of the function GeneticParentsAndChildSelection
|
33
tools/quake3/bspc/deps/botlib/be_ai_gen.h
Normal file
33
tools/quake3/bspc/deps/botlib/be_ai_gen.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
//
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_ai_gen.h
|
||||
*
|
||||
* desc: genetic selection
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_ai_gen.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
int GeneticParentsAndChildSelection(int numranks, float *ranks, int *parent1, int *parent2, int *child);
|
1821
tools/quake3/bspc/deps/botlib/be_ai_goal.c
Normal file
1821
tools/quake3/bspc/deps/botlib/be_ai_goal.c
Normal file
File diff suppressed because it is too large
Load diff
118
tools/quake3/bspc/deps/botlib/be_ai_goal.h
Normal file
118
tools/quake3/bspc/deps/botlib/be_ai_goal.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
//
|
||||
/*****************************************************************************
|
||||
* name: be_ai_goal.h
|
||||
*
|
||||
* desc: goal AI
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_ai_goal.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define MAX_AVOIDGOALS 256
|
||||
#define MAX_GOALSTACK 8
|
||||
|
||||
#define GFL_NONE 0
|
||||
#define GFL_ITEM 1
|
||||
#define GFL_ROAM 2
|
||||
#define GFL_DROPPED 4
|
||||
|
||||
//a bot goal
|
||||
typedef struct bot_goal_s
|
||||
{
|
||||
vec3_t origin; //origin of the goal
|
||||
int areanum; //area number of the goal
|
||||
vec3_t mins, maxs; //mins and maxs of the goal
|
||||
int entitynum; //number of the goal entity
|
||||
int number; //goal number
|
||||
int flags; //goal flags
|
||||
int iteminfo; //item information
|
||||
} bot_goal_t;
|
||||
|
||||
//reset the whole goal state, but keep the item weights
|
||||
void BotResetGoalState(int goalstate);
|
||||
//reset avoid goals
|
||||
void BotResetAvoidGoals(int goalstate);
|
||||
//remove the goal with the given number from the avoid goals
|
||||
void BotRemoveFromAvoidGoals(int goalstate, int number);
|
||||
//push a goal onto the goal stack
|
||||
void BotPushGoal(int goalstate, bot_goal_t *goal);
|
||||
//pop a goal from the goal stack
|
||||
void BotPopGoal(int goalstate);
|
||||
//empty the bot's goal stack
|
||||
void BotEmptyGoalStack(int goalstate);
|
||||
//dump the avoid goals
|
||||
void BotDumpAvoidGoals(int goalstate);
|
||||
//dump the goal stack
|
||||
void BotDumpGoalStack(int goalstate);
|
||||
//get the name name of the goal with the given number
|
||||
void BotGoalName(int number, char *name, int size);
|
||||
//get the top goal from the stack
|
||||
int BotGetTopGoal(int goalstate, bot_goal_t *goal);
|
||||
//get the second goal on the stack
|
||||
int BotGetSecondGoal(int goalstate, bot_goal_t *goal);
|
||||
//choose the best long term goal item for the bot
|
||||
int BotChooseLTGItem(int goalstate, vec3_t origin, int *inventory, int travelflags);
|
||||
//choose the best nearby goal item for the bot
|
||||
//the item may not be further away from the current bot position than maxtime
|
||||
//also the travel time from the nearby goal towards the long term goal may not
|
||||
//be larger than the travel time towards the long term goal from the current bot position
|
||||
int BotChooseNBGItem(int goalstate, vec3_t origin, int *inventory, int travelflags,
|
||||
bot_goal_t *ltg, float maxtime);
|
||||
//returns true if the bot touches the goal
|
||||
int BotTouchingGoal(vec3_t origin, bot_goal_t *goal);
|
||||
//returns true if the goal should be visible but isn't
|
||||
int BotItemGoalInVisButNotVisible(int viewer, vec3_t eye, vec3_t viewangles, bot_goal_t *goal);
|
||||
//search for a goal for the given classname, the index can be used
|
||||
//as a start point for the search when multiple goals are available with that same classname
|
||||
int BotGetLevelItemGoal(int index, char *classname, bot_goal_t *goal);
|
||||
//get the next camp spot in the map
|
||||
int BotGetNextCampSpotGoal(int num, bot_goal_t *goal);
|
||||
//get the map location with the given name
|
||||
int BotGetMapLocationGoal(char *name, bot_goal_t *goal);
|
||||
//returns the avoid goal time
|
||||
float BotAvoidGoalTime(int goalstate, int number);
|
||||
//set the avoid goal time
|
||||
void BotSetAvoidGoalTime(int goalstate, int number, float avoidtime);
|
||||
//initializes the items in the level
|
||||
void BotInitLevelItems(void);
|
||||
//regularly update dynamic entity items (dropped weapons, flags etc.)
|
||||
void BotUpdateEntityItems(void);
|
||||
//interbreed the goal fuzzy logic
|
||||
void BotInterbreedGoalFuzzyLogic(int parent1, int parent2, int child);
|
||||
//save the goal fuzzy logic to disk
|
||||
void BotSaveGoalFuzzyLogic(int goalstate, char *filename);
|
||||
//mutate the goal fuzzy logic
|
||||
void BotMutateGoalFuzzyLogic(int goalstate, float range);
|
||||
//loads item weights for the bot
|
||||
int BotLoadItemWeights(int goalstate, char *filename);
|
||||
//frees the item weights of the bot
|
||||
void BotFreeItemWeights(int goalstate);
|
||||
//returns the handle of a newly allocated goal state
|
||||
int BotAllocGoalState(int client);
|
||||
//free the given goal state
|
||||
void BotFreeGoalState(int handle);
|
||||
//setup the goal AI
|
||||
int BotSetupGoalAI(void);
|
||||
//shut down the goal AI
|
||||
void BotShutdownGoalAI(void);
|
3610
tools/quake3/bspc/deps/botlib/be_ai_move.c
Normal file
3610
tools/quake3/bspc/deps/botlib/be_ai_move.c
Normal file
File diff suppressed because it is too large
Load diff
142
tools/quake3/bspc/deps/botlib/be_ai_move.h
Normal file
142
tools/quake3/bspc/deps/botlib/be_ai_move.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
//
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_ai_move.h
|
||||
*
|
||||
* desc: movement AI
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_ai_move.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//movement types
|
||||
#define MOVE_WALK 1
|
||||
#define MOVE_CROUCH 2
|
||||
#define MOVE_JUMP 4
|
||||
#define MOVE_GRAPPLE 8
|
||||
#define MOVE_ROCKETJUMP 16
|
||||
#define MOVE_BFGJUMP 32
|
||||
//move flags
|
||||
#define MFL_BARRIERJUMP 1 //bot is performing a barrier jump
|
||||
#define MFL_ONGROUND 2 //bot is in the ground
|
||||
#define MFL_SWIMMING 4 //bot is swimming
|
||||
#define MFL_AGAINSTLADDER 8 //bot is against a ladder
|
||||
#define MFL_WATERJUMP 16 //bot is waterjumping
|
||||
#define MFL_TELEPORTED 32 //bot is being teleported
|
||||
#define MFL_GRAPPLEPULL 64 //bot is being pulled by the grapple
|
||||
#define MFL_ACTIVEGRAPPLE 128 //bot is using the grapple hook
|
||||
#define MFL_GRAPPLERESET 256 //bot has reset the grapple
|
||||
#define MFL_WALK 512 //bot should walk slowly
|
||||
// move result flags
|
||||
#define MOVERESULT_MOVEMENTVIEW 1 //bot uses view for movement
|
||||
#define MOVERESULT_SWIMVIEW 2 //bot uses view for swimming
|
||||
#define MOVERESULT_WAITING 4 //bot is waiting for something
|
||||
#define MOVERESULT_MOVEMENTVIEWSET 8 //bot has set the view in movement code
|
||||
#define MOVERESULT_MOVEMENTWEAPON 16 //bot uses weapon for movement
|
||||
#define MOVERESULT_ONTOPOFOBSTACLE 32 //bot is ontop of obstacle
|
||||
#define MOVERESULT_ONTOPOF_FUNCBOB 64 //bot is ontop of a func_bobbing
|
||||
#define MOVERESULT_ONTOPOF_ELEVATOR 128 //bot is ontop of an elevator (func_plat)
|
||||
#define MOVERESULT_BLOCKEDBYAVOIDSPOT 256 //bot is blocked by an avoid spot
|
||||
//
|
||||
#define MAX_AVOIDREACH 1
|
||||
#define MAX_AVOIDSPOTS 32
|
||||
// avoid spot types
|
||||
#define AVOID_CLEAR 0 //clear all avoid spots
|
||||
#define AVOID_ALWAYS 1 //avoid always
|
||||
#define AVOID_DONTBLOCK 2 //never totally block
|
||||
// restult types
|
||||
#define RESULTTYPE_ELEVATORUP 1 //elevator is up
|
||||
#define RESULTTYPE_WAITFORFUNCBOBBING 2 //waiting for func bobbing to arrive
|
||||
#define RESULTTYPE_BADGRAPPLEPATH 4 //grapple path is obstructed
|
||||
#define RESULTTYPE_INSOLIDAREA 8 //stuck in solid area, this is bad
|
||||
|
||||
//structure used to initialize the movement state
|
||||
//the or_moveflags MFL_ONGROUND, MFL_TELEPORTED and MFL_WATERJUMP come from the playerstate
|
||||
typedef struct bot_initmove_s
|
||||
{
|
||||
vec3_t origin; //origin of the bot
|
||||
vec3_t velocity; //velocity of the bot
|
||||
vec3_t viewoffset; //view offset
|
||||
int entitynum; //entity number of the bot
|
||||
int client; //client number of the bot
|
||||
float thinktime; //time the bot thinks
|
||||
int presencetype; //presencetype of the bot
|
||||
vec3_t viewangles; //view angles of the bot
|
||||
int or_moveflags; //values ored to the movement flags
|
||||
} bot_initmove_t;
|
||||
|
||||
//NOTE: the ideal_viewangles are only valid if MFL_MOVEMENTVIEW is set
|
||||
typedef struct bot_moveresult_s
|
||||
{
|
||||
int failure; //true if movement failed all together
|
||||
int type; //failure or blocked type
|
||||
int blocked; //true if blocked by an entity
|
||||
int blockentity; //entity blocking the bot
|
||||
int traveltype; //last executed travel type
|
||||
int flags; //result flags
|
||||
int weapon; //weapon used for movement
|
||||
vec3_t movedir; //movement direction
|
||||
vec3_t ideal_viewangles; //ideal viewangles for the movement
|
||||
} bot_moveresult_t;
|
||||
|
||||
#define bot_moveresult_t_cleared(x) bot_moveresult_t (x) = {0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, {0, 0, 0}}
|
||||
|
||||
typedef struct bot_avoidspot_s
|
||||
{
|
||||
vec3_t origin;
|
||||
float radius;
|
||||
int type;
|
||||
} bot_avoidspot_t;
|
||||
|
||||
//resets the whole move state
|
||||
void BotResetMoveState(int movestate);
|
||||
//moves the bot to the given goal
|
||||
void BotMoveToGoal(bot_moveresult_t *result, int movestate, bot_goal_t *goal, int travelflags);
|
||||
//moves the bot in the specified direction using the specified type of movement
|
||||
int BotMoveInDirection(int movestate, vec3_t dir, float speed, int type);
|
||||
//reset avoid reachability
|
||||
void BotResetAvoidReach(int movestate);
|
||||
//resets the last avoid reachability
|
||||
void BotResetLastAvoidReach(int movestate);
|
||||
//returns a reachability area if the origin is in one
|
||||
int BotReachabilityArea(vec3_t origin, int client);
|
||||
//view target based on movement
|
||||
int BotMovementViewTarget(int movestate, bot_goal_t *goal, int travelflags, float lookahead, vec3_t target);
|
||||
//predict the position of a player based on movement towards a goal
|
||||
int BotPredictVisiblePosition(vec3_t origin, int areanum, bot_goal_t *goal, int travelflags, vec3_t target);
|
||||
//returns the handle of a newly allocated movestate
|
||||
int BotAllocMoveState(void);
|
||||
//frees the movestate with the given handle
|
||||
void BotFreeMoveState(int handle);
|
||||
//initialize movement state before performing any movement
|
||||
void BotInitMoveState(int handle, bot_initmove_t *initmove);
|
||||
//add a spot to avoid (if type == AVOID_CLEAR all spots are removed)
|
||||
void BotAddAvoidSpot(int movestate, vec3_t origin, float radius, int type);
|
||||
//must be called every map change
|
||||
void BotSetBrushModelTypes(void);
|
||||
//setup movement AI
|
||||
int BotSetupMoveAI(void);
|
||||
//shutdown movement AI
|
||||
void BotShutdownMoveAI(void);
|
||||
|
543
tools/quake3/bspc/deps/botlib/be_ai_weap.c
Normal file
543
tools/quake3/bspc/deps/botlib/be_ai_weap.c
Normal file
|
@ -0,0 +1,543 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_ai_weap.c
|
||||
*
|
||||
* desc: weapon AI
|
||||
*
|
||||
* $Archive: /MissionPack/code/botlib/be_ai_weap.c $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "l_libvar.h"
|
||||
#include "l_log.h"
|
||||
#include "l_memory.h"
|
||||
#include "l_utils.h"
|
||||
#include "l_script.h"
|
||||
#include "l_precomp.h"
|
||||
#include "l_struct.h"
|
||||
#include "aasfile.h"
|
||||
#include "botlib.h"
|
||||
#include "be_aas.h"
|
||||
#include "be_aas_funcs.h"
|
||||
#include "be_interface.h"
|
||||
#include "be_ai_weight.h" //fuzzy weights
|
||||
#include "be_ai_weap.h"
|
||||
|
||||
//#define DEBUG_AI_WEAP
|
||||
|
||||
//structure field offsets
|
||||
#define WEAPON_OFS(x) (int)&(((weaponinfo_t *)0)->x)
|
||||
#define PROJECTILE_OFS(x) (int)&(((projectileinfo_t *)0)->x)
|
||||
|
||||
//weapon definition // bk001212 - static
|
||||
static fielddef_t weaponinfo_fields[] =
|
||||
{
|
||||
{"number", WEAPON_OFS(number), FT_INT}, //weapon number
|
||||
{"name", WEAPON_OFS(name), FT_STRING}, //name of the weapon
|
||||
{"level", WEAPON_OFS(level), FT_INT},
|
||||
{"model", WEAPON_OFS(model), FT_STRING}, //model of the weapon
|
||||
{"weaponindex", WEAPON_OFS(weaponindex), FT_INT}, //index of weapon in inventory
|
||||
{"flags", WEAPON_OFS(flags), FT_INT}, //special flags
|
||||
{"projectile", WEAPON_OFS(projectile), FT_STRING}, //projectile used by the weapon
|
||||
{"numprojectiles", WEAPON_OFS(numprojectiles), FT_INT}, //number of projectiles
|
||||
{"hspread", WEAPON_OFS(hspread), FT_FLOAT}, //horizontal spread of projectiles (degrees from middle)
|
||||
{"vspread", WEAPON_OFS(vspread), FT_FLOAT}, //vertical spread of projectiles (degrees from middle)
|
||||
{"speed", WEAPON_OFS(speed), FT_FLOAT}, //speed of the projectile (0 = instant hit)
|
||||
{"acceleration", WEAPON_OFS(acceleration), FT_FLOAT}, //"acceleration" * time (in seconds) + "speed" = projectile speed
|
||||
{"recoil", WEAPON_OFS(recoil), FT_FLOAT|FT_ARRAY, 3}, //amount of recoil the player gets from the weapon
|
||||
{"offset", WEAPON_OFS(offset), FT_FLOAT|FT_ARRAY, 3}, //projectile start offset relative to eye and view angles
|
||||
{"angleoffset", WEAPON_OFS(angleoffset), FT_FLOAT|FT_ARRAY, 3},//offset of the shoot angles relative to the view angles
|
||||
{"extrazvelocity", WEAPON_OFS(extrazvelocity), FT_FLOAT},//extra z velocity the projectile gets
|
||||
{"ammoamount", WEAPON_OFS(ammoamount), FT_INT}, //ammo amount used per shot
|
||||
{"ammoindex", WEAPON_OFS(ammoindex), FT_INT}, //index of ammo in inventory
|
||||
{"activate", WEAPON_OFS(activate), FT_FLOAT}, //time it takes to select the weapon
|
||||
{"reload", WEAPON_OFS(reload), FT_FLOAT}, //time it takes to reload the weapon
|
||||
{"spinup", WEAPON_OFS(spinup), FT_FLOAT}, //time it takes before first shot
|
||||
{"spindown", WEAPON_OFS(spindown), FT_FLOAT}, //time it takes before weapon stops firing
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
//projectile definition
|
||||
static fielddef_t projectileinfo_fields[] =
|
||||
{
|
||||
{"name", PROJECTILE_OFS(name), FT_STRING}, //name of the projectile
|
||||
{"model", WEAPON_OFS(model), FT_STRING}, //model of the projectile
|
||||
{"flags", PROJECTILE_OFS(flags), FT_INT}, //special flags
|
||||
{"gravity", PROJECTILE_OFS(gravity), FT_FLOAT}, //amount of gravity applied to the projectile [0,1]
|
||||
{"damage", PROJECTILE_OFS(damage), FT_INT}, //damage of the projectile
|
||||
{"radius", PROJECTILE_OFS(radius), FT_FLOAT}, //radius of damage
|
||||
{"visdamage", PROJECTILE_OFS(visdamage), FT_INT}, //damage of the projectile to visible entities
|
||||
{"damagetype", PROJECTILE_OFS(damagetype), FT_INT}, //type of damage (combination of the DAMAGETYPE_? flags)
|
||||
{"healthinc", PROJECTILE_OFS(healthinc), FT_INT}, //health increase the owner gets
|
||||
{"push", PROJECTILE_OFS(push), FT_FLOAT}, //amount a player is pushed away from the projectile impact
|
||||
{"detonation", PROJECTILE_OFS(detonation), FT_FLOAT}, //time before projectile explodes after fire pressed
|
||||
{"bounce", PROJECTILE_OFS(bounce), FT_FLOAT}, //amount the projectile bounces
|
||||
{"bouncefric", PROJECTILE_OFS(bouncefric), FT_FLOAT}, //amount the bounce decreases per bounce
|
||||
{"bouncestop", PROJECTILE_OFS(bouncestop), FT_FLOAT}, //minimum bounce value before bouncing stops
|
||||
//recurive projectile definition??
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
static structdef_t weaponinfo_struct =
|
||||
{
|
||||
sizeof(weaponinfo_t), weaponinfo_fields
|
||||
};
|
||||
static structdef_t projectileinfo_struct =
|
||||
{
|
||||
sizeof(projectileinfo_t), projectileinfo_fields
|
||||
};
|
||||
|
||||
//weapon configuration: set of weapons with projectiles
|
||||
typedef struct weaponconfig_s
|
||||
{
|
||||
int numweapons;
|
||||
int numprojectiles;
|
||||
projectileinfo_t *projectileinfo;
|
||||
weaponinfo_t *weaponinfo;
|
||||
} weaponconfig_t;
|
||||
|
||||
//the bot weapon state
|
||||
typedef struct bot_weaponstate_s
|
||||
{
|
||||
struct weightconfig_s *weaponweightconfig; //weapon weight configuration
|
||||
int *weaponweightindex; //weapon weight index
|
||||
} bot_weaponstate_t;
|
||||
|
||||
static bot_weaponstate_t *botweaponstates[MAX_CLIENTS+1];
|
||||
static weaponconfig_t *weaponconfig;
|
||||
|
||||
//========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//========================================================================
|
||||
int BotValidWeaponNumber(int weaponnum)
|
||||
{
|
||||
if (weaponnum <= 0 || weaponnum > weaponconfig->numweapons)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "weapon number out of range\n");
|
||||
return qfalse;
|
||||
} //end if
|
||||
return qtrue;
|
||||
} //end of the function BotValidWeaponNumber
|
||||
//========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//========================================================================
|
||||
bot_weaponstate_t *BotWeaponStateFromHandle(int handle)
|
||||
{
|
||||
if (handle <= 0 || handle > MAX_CLIENTS)
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "move state handle %d out of range\n", handle);
|
||||
return NULL;
|
||||
} //end if
|
||||
if (!botweaponstates[handle])
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "invalid move state %d\n", handle);
|
||||
return NULL;
|
||||
} //end if
|
||||
return botweaponstates[handle];
|
||||
} //end of the function BotWeaponStateFromHandle
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
#ifdef DEBUG_AI_WEAP
|
||||
void DumpWeaponConfig(weaponconfig_t *wc)
|
||||
{
|
||||
FILE *fp;
|
||||
int i;
|
||||
|
||||
fp = Log_FileStruct();
|
||||
if (!fp) return;
|
||||
for (i = 0; i < wc->numprojectiles; i++)
|
||||
{
|
||||
WriteStructure(fp, &projectileinfo_struct, (char *) &wc->projectileinfo[i]);
|
||||
Log_Flush();
|
||||
} //end for
|
||||
for (i = 0; i < wc->numweapons; i++)
|
||||
{
|
||||
WriteStructure(fp, &weaponinfo_struct, (char *) &wc->weaponinfo[i]);
|
||||
Log_Flush();
|
||||
} //end for
|
||||
} //end of the function DumpWeaponConfig
|
||||
#endif //DEBUG_AI_WEAP
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
weaponconfig_t *LoadWeaponConfig(char *filename)
|
||||
{
|
||||
int max_weaponinfo, max_projectileinfo;
|
||||
token_t token;
|
||||
char path[MAX_PATH];
|
||||
int i, j;
|
||||
source_t *source;
|
||||
weaponconfig_t *wc;
|
||||
weaponinfo_t weaponinfo;
|
||||
|
||||
max_weaponinfo = (int) LibVarValue("max_weaponinfo", "32");
|
||||
if (max_weaponinfo < 0)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "max_weaponinfo = %d\n", max_weaponinfo);
|
||||
max_weaponinfo = 32;
|
||||
LibVarSet("max_weaponinfo", "32");
|
||||
} //end if
|
||||
max_projectileinfo = (int) LibVarValue("max_projectileinfo", "32");
|
||||
if (max_projectileinfo < 0)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "max_projectileinfo = %d\n", max_projectileinfo);
|
||||
max_projectileinfo = 32;
|
||||
LibVarSet("max_projectileinfo", "32");
|
||||
} //end if
|
||||
strncpy(path, filename, MAX_PATH);
|
||||
PC_SetBaseFolder(BOTFILESBASEFOLDER);
|
||||
source = LoadSourceFile(path);
|
||||
if (!source)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "counldn't load %s\n", path);
|
||||
return NULL;
|
||||
} //end if
|
||||
//initialize weapon config
|
||||
wc = (weaponconfig_t *) GetClearedHunkMemory(sizeof(weaponconfig_t) +
|
||||
max_weaponinfo * sizeof(weaponinfo_t) +
|
||||
max_projectileinfo * sizeof(projectileinfo_t));
|
||||
wc->weaponinfo = (weaponinfo_t *) ((char *) wc + sizeof(weaponconfig_t));
|
||||
wc->projectileinfo = (projectileinfo_t *) ((char *) wc->weaponinfo +
|
||||
max_weaponinfo * sizeof(weaponinfo_t));
|
||||
wc->numweapons = max_weaponinfo;
|
||||
wc->numprojectiles = 0;
|
||||
//parse the source file
|
||||
while(PC_ReadToken(source, &token))
|
||||
{
|
||||
if (!strcmp(token.string, "weaponinfo"))
|
||||
{
|
||||
Com_Memset(&weaponinfo, 0, sizeof(weaponinfo_t));
|
||||
if (!ReadStructure(source, &weaponinfo_struct, (char *) &weaponinfo))
|
||||
{
|
||||
FreeMemory(wc);
|
||||
FreeSource(source);
|
||||
return NULL;
|
||||
} //end if
|
||||
if (weaponinfo.number < 0 || weaponinfo.number >= max_weaponinfo)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "weapon info number %d out of range in %s\n", weaponinfo.number, path);
|
||||
FreeMemory(wc);
|
||||
FreeSource(source);
|
||||
return NULL;
|
||||
} //end if
|
||||
Com_Memcpy(&wc->weaponinfo[weaponinfo.number], &weaponinfo, sizeof(weaponinfo_t));
|
||||
wc->weaponinfo[weaponinfo.number].valid = qtrue;
|
||||
} //end if
|
||||
else if (!strcmp(token.string, "projectileinfo"))
|
||||
{
|
||||
if (wc->numprojectiles >= max_projectileinfo)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "more than %d projectiles defined in %s\n", max_projectileinfo, path);
|
||||
FreeMemory(wc);
|
||||
FreeSource(source);
|
||||
return NULL;
|
||||
} //end if
|
||||
Com_Memset(&wc->projectileinfo[wc->numprojectiles], 0, sizeof(projectileinfo_t));
|
||||
if (!ReadStructure(source, &projectileinfo_struct, (char *) &wc->projectileinfo[wc->numprojectiles]))
|
||||
{
|
||||
FreeMemory(wc);
|
||||
FreeSource(source);
|
||||
return NULL;
|
||||
} //end if
|
||||
wc->numprojectiles++;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "unknown definition %s in %s\n", token.string, path);
|
||||
FreeMemory(wc);
|
||||
FreeSource(source);
|
||||
return NULL;
|
||||
} //end else
|
||||
} //end while
|
||||
FreeSource(source);
|
||||
//fix up weapons
|
||||
for (i = 0; i < wc->numweapons; i++)
|
||||
{
|
||||
if (!wc->weaponinfo[i].valid) continue;
|
||||
if (!wc->weaponinfo[i].name[0])
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "weapon %d has no name in %s\n", i, path);
|
||||
FreeMemory(wc);
|
||||
return NULL;
|
||||
} //end if
|
||||
if (!wc->weaponinfo[i].projectile[0])
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "weapon %s has no projectile in %s\n", wc->weaponinfo[i].name, path);
|
||||
FreeMemory(wc);
|
||||
return NULL;
|
||||
} //end if
|
||||
//find the projectile info and copy it to the weapon info
|
||||
for (j = 0; j < wc->numprojectiles; j++)
|
||||
{
|
||||
if (!strcmp(wc->projectileinfo[j].name, wc->weaponinfo[i].projectile))
|
||||
{
|
||||
Com_Memcpy(&wc->weaponinfo[i].proj, &wc->projectileinfo[j], sizeof(projectileinfo_t));
|
||||
break;
|
||||
} //end if
|
||||
} //end for
|
||||
if (j == wc->numprojectiles)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "weapon %s uses undefined projectile in %s\n", wc->weaponinfo[i].name, path);
|
||||
FreeMemory(wc);
|
||||
return NULL;
|
||||
} //end if
|
||||
} //end for
|
||||
if (!wc->numweapons) botimport.Print(PRT_WARNING, "no weapon info loaded\n");
|
||||
botimport.Print(PRT_MESSAGE, "loaded %s\n", path);
|
||||
return wc;
|
||||
} //end of the function LoadWeaponConfig
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int *WeaponWeightIndex(weightconfig_t *wwc, weaponconfig_t *wc)
|
||||
{
|
||||
int *index, i;
|
||||
|
||||
//initialize item weight index
|
||||
index = (int *) GetClearedMemory(sizeof(int) * wc->numweapons);
|
||||
|
||||
for (i = 0; i < wc->numweapons; i++)
|
||||
{
|
||||
index[i] = FindFuzzyWeight(wwc, wc->weaponinfo[i].name);
|
||||
} //end for
|
||||
return index;
|
||||
} //end of the function WeaponWeightIndex
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void BotFreeWeaponWeights(int weaponstate)
|
||||
{
|
||||
bot_weaponstate_t *ws;
|
||||
|
||||
ws = BotWeaponStateFromHandle(weaponstate);
|
||||
if (!ws) return;
|
||||
if (ws->weaponweightconfig) FreeWeightConfig(ws->weaponweightconfig);
|
||||
if (ws->weaponweightindex) FreeMemory(ws->weaponweightindex);
|
||||
} //end of the function BotFreeWeaponWeights
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int BotLoadWeaponWeights(int weaponstate, char *filename)
|
||||
{
|
||||
bot_weaponstate_t *ws;
|
||||
|
||||
ws = BotWeaponStateFromHandle(weaponstate);
|
||||
if (!ws) return BLERR_CANNOTLOADWEAPONWEIGHTS;
|
||||
BotFreeWeaponWeights(weaponstate);
|
||||
//
|
||||
ws->weaponweightconfig = ReadWeightConfig(filename);
|
||||
if (!ws->weaponweightconfig)
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "couldn't load weapon config %s\n", filename);
|
||||
return BLERR_CANNOTLOADWEAPONWEIGHTS;
|
||||
} //end if
|
||||
if (!weaponconfig) return BLERR_CANNOTLOADWEAPONCONFIG;
|
||||
ws->weaponweightindex = WeaponWeightIndex(ws->weaponweightconfig, weaponconfig);
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function BotLoadWeaponWeights
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void BotGetWeaponInfo(int weaponstate, int weapon, weaponinfo_t *weaponinfo)
|
||||
{
|
||||
bot_weaponstate_t *ws;
|
||||
|
||||
if (!BotValidWeaponNumber(weapon)) return;
|
||||
ws = BotWeaponStateFromHandle(weaponstate);
|
||||
if (!ws) return;
|
||||
if (!weaponconfig) return;
|
||||
Com_Memcpy(weaponinfo, &weaponconfig->weaponinfo[weapon], sizeof(weaponinfo_t));
|
||||
} //end of the function BotGetWeaponInfo
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int BotChooseBestFightWeapon(int weaponstate, int *inventory)
|
||||
{
|
||||
int i, index, bestweapon;
|
||||
float weight, bestweight;
|
||||
weaponconfig_t *wc;
|
||||
bot_weaponstate_t *ws;
|
||||
|
||||
ws = BotWeaponStateFromHandle(weaponstate);
|
||||
if (!ws) return 0;
|
||||
wc = weaponconfig;
|
||||
if (!weaponconfig) return 0;
|
||||
|
||||
//if the bot has no weapon weight configuration
|
||||
if (!ws->weaponweightconfig) return 0;
|
||||
|
||||
bestweight = 0;
|
||||
bestweapon = 0;
|
||||
for (i = 0; i < wc->numweapons; i++)
|
||||
{
|
||||
if (!wc->weaponinfo[i].valid) continue;
|
||||
index = ws->weaponweightindex[i];
|
||||
if (index < 0) continue;
|
||||
weight = FuzzyWeight(inventory, ws->weaponweightconfig, index);
|
||||
if (weight > bestweight)
|
||||
{
|
||||
bestweight = weight;
|
||||
bestweapon = i;
|
||||
} //end if
|
||||
} //end for
|
||||
return bestweapon;
|
||||
} //end of the function BotChooseBestFightWeapon
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void BotResetWeaponState(int weaponstate)
|
||||
{
|
||||
struct weightconfig_s *weaponweightconfig;
|
||||
int *weaponweightindex;
|
||||
bot_weaponstate_t *ws;
|
||||
|
||||
ws = BotWeaponStateFromHandle(weaponstate);
|
||||
if (!ws) return;
|
||||
weaponweightconfig = ws->weaponweightconfig;
|
||||
weaponweightindex = ws->weaponweightindex;
|
||||
|
||||
//Com_Memset(ws, 0, sizeof(bot_weaponstate_t));
|
||||
ws->weaponweightconfig = weaponweightconfig;
|
||||
ws->weaponweightindex = weaponweightindex;
|
||||
} //end of the function BotResetWeaponState
|
||||
//========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//========================================================================
|
||||
int BotAllocWeaponState(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= MAX_CLIENTS; i++)
|
||||
{
|
||||
if (!botweaponstates[i])
|
||||
{
|
||||
botweaponstates[i] = GetClearedMemory(sizeof(bot_weaponstate_t));
|
||||
return i;
|
||||
} //end if
|
||||
} //end for
|
||||
return 0;
|
||||
} //end of the function BotAllocWeaponState
|
||||
//========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//========================================================================
|
||||
void BotFreeWeaponState(int handle)
|
||||
{
|
||||
if (handle <= 0 || handle > MAX_CLIENTS)
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "move state handle %d out of range\n", handle);
|
||||
return;
|
||||
} //end if
|
||||
if (!botweaponstates[handle])
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "invalid move state %d\n", handle);
|
||||
return;
|
||||
} //end if
|
||||
BotFreeWeaponWeights(handle);
|
||||
FreeMemory(botweaponstates[handle]);
|
||||
botweaponstates[handle] = NULL;
|
||||
} //end of the function BotFreeWeaponState
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int BotSetupWeaponAI(void)
|
||||
{
|
||||
char *file;
|
||||
|
||||
file = LibVarString("weaponconfig", "weapons.c");
|
||||
weaponconfig = LoadWeaponConfig(file);
|
||||
if (!weaponconfig)
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "couldn't load the weapon config\n");
|
||||
return BLERR_CANNOTLOADWEAPONCONFIG;
|
||||
} //end if
|
||||
|
||||
#ifdef DEBUG_AI_WEAP
|
||||
DumpWeaponConfig(weaponconfig);
|
||||
#endif //DEBUG_AI_WEAP
|
||||
//
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function BotSetupWeaponAI
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void BotShutdownWeaponAI(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (weaponconfig) FreeMemory(weaponconfig);
|
||||
weaponconfig = NULL;
|
||||
|
||||
for (i = 1; i <= MAX_CLIENTS; i++)
|
||||
{
|
||||
if (botweaponstates[i])
|
||||
{
|
||||
BotFreeWeaponState(i);
|
||||
} //end if
|
||||
} //end for
|
||||
} //end of the function BotShutdownWeaponAI
|
||||
|
104
tools/quake3/bspc/deps/botlib/be_ai_weap.h
Normal file
104
tools/quake3/bspc/deps/botlib/be_ai_weap.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
//
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_ai_weap.h
|
||||
*
|
||||
* desc: weapon AI
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_ai_weap.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//projectile flags
|
||||
#define PFL_WINDOWDAMAGE 1 //projectile damages through window
|
||||
#define PFL_RETURN 2 //set when projectile returns to owner
|
||||
//weapon flags
|
||||
#define WFL_FIRERELEASED 1 //set when projectile is fired with key-up event
|
||||
//damage types
|
||||
#define DAMAGETYPE_IMPACT 1 //damage on impact
|
||||
#define DAMAGETYPE_RADIAL 2 //radial damage
|
||||
#define DAMAGETYPE_VISIBLE 4 //damage to all entities visible to the projectile
|
||||
|
||||
typedef struct projectileinfo_s
|
||||
{
|
||||
char name[MAX_STRINGFIELD];
|
||||
char model[MAX_STRINGFIELD];
|
||||
int flags;
|
||||
float gravity;
|
||||
int damage;
|
||||
float radius;
|
||||
int visdamage;
|
||||
int damagetype;
|
||||
int healthinc;
|
||||
float push;
|
||||
float detonation;
|
||||
float bounce;
|
||||
float bouncefric;
|
||||
float bouncestop;
|
||||
} projectileinfo_t;
|
||||
|
||||
typedef struct weaponinfo_s
|
||||
{
|
||||
int valid; //true if the weapon info is valid
|
||||
int number; //number of the weapon
|
||||
char name[MAX_STRINGFIELD];
|
||||
char model[MAX_STRINGFIELD];
|
||||
int level;
|
||||
int weaponindex;
|
||||
int flags;
|
||||
char projectile[MAX_STRINGFIELD];
|
||||
int numprojectiles;
|
||||
float hspread;
|
||||
float vspread;
|
||||
float speed;
|
||||
float acceleration;
|
||||
vec3_t recoil;
|
||||
vec3_t offset;
|
||||
vec3_t angleoffset;
|
||||
float extrazvelocity;
|
||||
int ammoamount;
|
||||
int ammoindex;
|
||||
float activate;
|
||||
float reload;
|
||||
float spinup;
|
||||
float spindown;
|
||||
projectileinfo_t proj; //pointer to the used projectile
|
||||
} weaponinfo_t;
|
||||
|
||||
//setup the weapon AI
|
||||
int BotSetupWeaponAI(void);
|
||||
//shut down the weapon AI
|
||||
void BotShutdownWeaponAI(void);
|
||||
//returns the best weapon to fight with
|
||||
int BotChooseBestFightWeapon(int weaponstate, int *inventory);
|
||||
//returns the information of the current weapon
|
||||
void BotGetWeaponInfo(int weaponstate, int weapon, weaponinfo_t *weaponinfo);
|
||||
//loads the weapon weights
|
||||
int BotLoadWeaponWeights(int weaponstate, char *filename);
|
||||
//returns a handle to a newly allocated weapon state
|
||||
int BotAllocWeaponState(void);
|
||||
//frees the weapon state
|
||||
void BotFreeWeaponState(int weaponstate);
|
||||
//resets the whole weapon state
|
||||
void BotResetWeaponState(int weaponstate);
|
912
tools/quake3/bspc/deps/botlib/be_ai_weight.c
Normal file
912
tools/quake3/bspc/deps/botlib/be_ai_weight.c
Normal file
|
@ -0,0 +1,912 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_ai_weight.c
|
||||
*
|
||||
* desc: fuzzy logic
|
||||
*
|
||||
* $Archive: /MissionPack/code/botlib/be_ai_weight.c $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "l_memory.h"
|
||||
#include "l_log.h"
|
||||
#include "l_utils.h"
|
||||
#include "l_script.h"
|
||||
#include "l_precomp.h"
|
||||
#include "l_struct.h"
|
||||
#include "l_libvar.h"
|
||||
#include "aasfile.h"
|
||||
#include "botlib.h"
|
||||
#include "be_aas.h"
|
||||
#include "be_aas_funcs.h"
|
||||
#include "be_interface.h"
|
||||
#include "be_ai_weight.h"
|
||||
|
||||
#define MAX_INVENTORYVALUE 999999
|
||||
#define EVALUATERECURSIVELY
|
||||
|
||||
#define MAX_WEIGHT_FILES 128
|
||||
weightconfig_t *weightFileList[MAX_WEIGHT_FILES];
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int ReadValue(source_t *source, float *value)
|
||||
{
|
||||
token_t token;
|
||||
|
||||
if (!PC_ExpectAnyToken(source, &token)) return qfalse;
|
||||
if (!strcmp(token.string, "-"))
|
||||
{
|
||||
SourceWarning(source, "negative value set to zero\n");
|
||||
if (!PC_ExpectTokenType(source, TT_NUMBER, 0, &token)) return qfalse;
|
||||
} //end if
|
||||
if (token.type != TT_NUMBER)
|
||||
{
|
||||
SourceError(source, "invalid return value %s\n", token.string);
|
||||
return qfalse;
|
||||
} //end if
|
||||
*value = token.floatvalue;
|
||||
return qtrue;
|
||||
} //end of the function ReadValue
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int ReadFuzzyWeight(source_t *source, fuzzyseperator_t *fs)
|
||||
{
|
||||
if (PC_CheckTokenString(source, "balance"))
|
||||
{
|
||||
fs->type = WT_BALANCE;
|
||||
if (!PC_ExpectTokenString(source, "(")) return qfalse;
|
||||
if (!ReadValue(source, &fs->weight)) return qfalse;
|
||||
if (!PC_ExpectTokenString(source, ",")) return qfalse;
|
||||
if (!ReadValue(source, &fs->minweight)) return qfalse;
|
||||
if (!PC_ExpectTokenString(source, ",")) return qfalse;
|
||||
if (!ReadValue(source, &fs->maxweight)) return qfalse;
|
||||
if (!PC_ExpectTokenString(source, ")")) return qfalse;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
fs->type = 0;
|
||||
if (!ReadValue(source, &fs->weight)) return qfalse;
|
||||
fs->minweight = fs->weight;
|
||||
fs->maxweight = fs->weight;
|
||||
} //end if
|
||||
if (!PC_ExpectTokenString(source, ";")) return qfalse;
|
||||
return qtrue;
|
||||
} //end of the function ReadFuzzyWeight
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void FreeFuzzySeperators_r(fuzzyseperator_t *fs)
|
||||
{
|
||||
if (!fs) return;
|
||||
if (fs->child) FreeFuzzySeperators_r(fs->child);
|
||||
if (fs->next) FreeFuzzySeperators_r(fs->next);
|
||||
FreeMemory(fs);
|
||||
} //end of the function FreeFuzzySeperators
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void FreeWeightConfig2(weightconfig_t *config)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < config->numweights; i++)
|
||||
{
|
||||
FreeFuzzySeperators_r(config->weights[i].firstseperator);
|
||||
if (config->weights[i].name) FreeMemory(config->weights[i].name);
|
||||
} //end for
|
||||
FreeMemory(config);
|
||||
} //end of the function FreeWeightConfig2
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void FreeWeightConfig(weightconfig_t *config)
|
||||
{
|
||||
if (!LibVarGetValue("bot_reloadcharacters")) return;
|
||||
FreeWeightConfig2(config);
|
||||
} //end of the function FreeWeightConfig
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
fuzzyseperator_t *ReadFuzzySeperators_r(source_t *source)
|
||||
{
|
||||
int newindent, index, def, founddefault;
|
||||
token_t token;
|
||||
fuzzyseperator_t *fs, *lastfs, *firstfs;
|
||||
|
||||
founddefault = qfalse;
|
||||
firstfs = NULL;
|
||||
lastfs = NULL;
|
||||
if (!PC_ExpectTokenString(source, "(")) return NULL;
|
||||
if (!PC_ExpectTokenType(source, TT_NUMBER, TT_INTEGER, &token)) return NULL;
|
||||
index = token.intvalue;
|
||||
if (!PC_ExpectTokenString(source, ")")) return NULL;
|
||||
if (!PC_ExpectTokenString(source, "{")) return NULL;
|
||||
if (!PC_ExpectAnyToken(source, &token)) return NULL;
|
||||
do
|
||||
{
|
||||
def = !strcmp(token.string, "default");
|
||||
if (def || !strcmp(token.string, "case"))
|
||||
{
|
||||
fs = (fuzzyseperator_t *) GetClearedMemory(sizeof(fuzzyseperator_t));
|
||||
fs->index = index;
|
||||
if (lastfs) lastfs->next = fs;
|
||||
else firstfs = fs;
|
||||
lastfs = fs;
|
||||
if (def)
|
||||
{
|
||||
if (founddefault)
|
||||
{
|
||||
SourceError(source, "switch already has a default\n");
|
||||
FreeFuzzySeperators_r(firstfs);
|
||||
return NULL;
|
||||
} //end if
|
||||
fs->value = MAX_INVENTORYVALUE;
|
||||
founddefault = qtrue;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if (!PC_ExpectTokenType(source, TT_NUMBER, TT_INTEGER, &token))
|
||||
{
|
||||
FreeFuzzySeperators_r(firstfs);
|
||||
return NULL;
|
||||
} //end if
|
||||
fs->value = token.intvalue;
|
||||
} //end else
|
||||
if (!PC_ExpectTokenString(source, ":") || !PC_ExpectAnyToken(source, &token))
|
||||
{
|
||||
FreeFuzzySeperators_r(firstfs);
|
||||
return NULL;
|
||||
} //end if
|
||||
newindent = qfalse;
|
||||
if (!strcmp(token.string, "{"))
|
||||
{
|
||||
newindent = qtrue;
|
||||
if (!PC_ExpectAnyToken(source, &token))
|
||||
{
|
||||
FreeFuzzySeperators_r(firstfs);
|
||||
return NULL;
|
||||
} //end if
|
||||
} //end if
|
||||
if (!strcmp(token.string, "return"))
|
||||
{
|
||||
if (!ReadFuzzyWeight(source, fs))
|
||||
{
|
||||
FreeFuzzySeperators_r(firstfs);
|
||||
return NULL;
|
||||
} //end if
|
||||
} //end if
|
||||
else if (!strcmp(token.string, "switch"))
|
||||
{
|
||||
fs->child = ReadFuzzySeperators_r(source);
|
||||
if (!fs->child)
|
||||
{
|
||||
FreeFuzzySeperators_r(firstfs);
|
||||
return NULL;
|
||||
} //end if
|
||||
} //end else if
|
||||
else
|
||||
{
|
||||
SourceError(source, "invalid name %s\n", token.string);
|
||||
return NULL;
|
||||
} //end else
|
||||
if (newindent)
|
||||
{
|
||||
if (!PC_ExpectTokenString(source, "}"))
|
||||
{
|
||||
FreeFuzzySeperators_r(firstfs);
|
||||
return NULL;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
FreeFuzzySeperators_r(firstfs);
|
||||
SourceError(source, "invalid name %s\n", token.string);
|
||||
return NULL;
|
||||
} //end else
|
||||
if (!PC_ExpectAnyToken(source, &token))
|
||||
{
|
||||
FreeFuzzySeperators_r(firstfs);
|
||||
return NULL;
|
||||
} //end if
|
||||
} while(strcmp(token.string, "}"));
|
||||
//
|
||||
if (!founddefault)
|
||||
{
|
||||
SourceWarning(source, "switch without default\n");
|
||||
fs = (fuzzyseperator_t *) GetClearedMemory(sizeof(fuzzyseperator_t));
|
||||
fs->index = index;
|
||||
fs->value = MAX_INVENTORYVALUE;
|
||||
fs->weight = 0;
|
||||
fs->next = NULL;
|
||||
fs->child = NULL;
|
||||
if (lastfs) lastfs->next = fs;
|
||||
else firstfs = fs;
|
||||
lastfs = fs;
|
||||
} //end if
|
||||
//
|
||||
return firstfs;
|
||||
} //end of the function ReadFuzzySeperators_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
weightconfig_t *ReadWeightConfig(char *filename)
|
||||
{
|
||||
int newindent, avail = 0, n;
|
||||
token_t token;
|
||||
source_t *source;
|
||||
fuzzyseperator_t *fs;
|
||||
weightconfig_t *config = NULL;
|
||||
#ifdef DEBUG
|
||||
int starttime;
|
||||
|
||||
starttime = Sys_MilliSeconds();
|
||||
#endif //DEBUG
|
||||
|
||||
if (!LibVarGetValue("bot_reloadcharacters"))
|
||||
{
|
||||
avail = -1;
|
||||
for( n = 0; n < MAX_WEIGHT_FILES; n++ )
|
||||
{
|
||||
config = weightFileList[n];
|
||||
if( !config )
|
||||
{
|
||||
if( avail == -1 )
|
||||
{
|
||||
avail = n;
|
||||
} //end if
|
||||
continue;
|
||||
} //end if
|
||||
if( strcmp( filename, config->filename ) == 0 )
|
||||
{
|
||||
//botimport.Print( PRT_MESSAGE, "retained %s\n", filename );
|
||||
return config;
|
||||
} //end if
|
||||
} //end for
|
||||
|
||||
if( avail == -1 )
|
||||
{
|
||||
botimport.Print( PRT_ERROR, "weightFileList was full trying to load %s\n", filename );
|
||||
return NULL;
|
||||
} //end if
|
||||
} //end if
|
||||
|
||||
PC_SetBaseFolder(BOTFILESBASEFOLDER);
|
||||
source = LoadSourceFile(filename);
|
||||
if (!source)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "counldn't load %s\n", filename);
|
||||
return NULL;
|
||||
} //end if
|
||||
//
|
||||
config = (weightconfig_t *) GetClearedMemory(sizeof(weightconfig_t));
|
||||
config->numweights = 0;
|
||||
Q_strncpyz( config->filename, filename, sizeof(config->filename) );
|
||||
//parse the item config file
|
||||
while(PC_ReadToken(source, &token))
|
||||
{
|
||||
if (!strcmp(token.string, "weight"))
|
||||
{
|
||||
if (config->numweights >= MAX_WEIGHTS)
|
||||
{
|
||||
SourceWarning(source, "too many fuzzy weights\n");
|
||||
break;
|
||||
} //end if
|
||||
if (!PC_ExpectTokenType(source, TT_STRING, 0, &token))
|
||||
{
|
||||
FreeWeightConfig(config);
|
||||
FreeSource(source);
|
||||
return NULL;
|
||||
} //end if
|
||||
StripDoubleQuotes(token.string);
|
||||
config->weights[config->numweights].name = (char *) GetClearedMemory(strlen(token.string) + 1);
|
||||
strcpy(config->weights[config->numweights].name, token.string);
|
||||
if (!PC_ExpectAnyToken(source, &token))
|
||||
{
|
||||
FreeWeightConfig(config);
|
||||
FreeSource(source);
|
||||
return NULL;
|
||||
} //end if
|
||||
newindent = qfalse;
|
||||
if (!strcmp(token.string, "{"))
|
||||
{
|
||||
newindent = qtrue;
|
||||
if (!PC_ExpectAnyToken(source, &token))
|
||||
{
|
||||
FreeWeightConfig(config);
|
||||
FreeSource(source);
|
||||
return NULL;
|
||||
} //end if
|
||||
} //end if
|
||||
if (!strcmp(token.string, "switch"))
|
||||
{
|
||||
fs = ReadFuzzySeperators_r(source);
|
||||
if (!fs)
|
||||
{
|
||||
FreeWeightConfig(config);
|
||||
FreeSource(source);
|
||||
return NULL;
|
||||
} //end if
|
||||
config->weights[config->numweights].firstseperator = fs;
|
||||
} //end if
|
||||
else if (!strcmp(token.string, "return"))
|
||||
{
|
||||
fs = (fuzzyseperator_t *) GetClearedMemory(sizeof(fuzzyseperator_t));
|
||||
fs->index = 0;
|
||||
fs->value = MAX_INVENTORYVALUE;
|
||||
fs->next = NULL;
|
||||
fs->child = NULL;
|
||||
if (!ReadFuzzyWeight(source, fs))
|
||||
{
|
||||
FreeMemory(fs);
|
||||
FreeWeightConfig(config);
|
||||
FreeSource(source);
|
||||
return NULL;
|
||||
} //end if
|
||||
config->weights[config->numweights].firstseperator = fs;
|
||||
} //end else if
|
||||
else
|
||||
{
|
||||
SourceError(source, "invalid name %s\n", token.string);
|
||||
FreeWeightConfig(config);
|
||||
FreeSource(source);
|
||||
return NULL;
|
||||
} //end else
|
||||
if (newindent)
|
||||
{
|
||||
if (!PC_ExpectTokenString(source, "}"))
|
||||
{
|
||||
FreeWeightConfig(config);
|
||||
FreeSource(source);
|
||||
return NULL;
|
||||
} //end if
|
||||
} //end if
|
||||
config->numweights++;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
SourceError(source, "invalid name %s\n", token.string);
|
||||
FreeWeightConfig(config);
|
||||
FreeSource(source);
|
||||
return NULL;
|
||||
} //end else
|
||||
} //end while
|
||||
//free the source at the end of a pass
|
||||
FreeSource(source);
|
||||
//if the file was located in a pak file
|
||||
botimport.Print(PRT_MESSAGE, "loaded %s\n", filename);
|
||||
#ifdef DEBUG
|
||||
if (bot_developer)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "weights loaded in %d msec\n", Sys_MilliSeconds() - starttime);
|
||||
} //end if
|
||||
#endif //DEBUG
|
||||
//
|
||||
if (!LibVarGetValue("bot_reloadcharacters"))
|
||||
{
|
||||
weightFileList[avail] = config;
|
||||
} //end if
|
||||
//
|
||||
return config;
|
||||
} //end of the function ReadWeightConfig
|
||||
#if 0
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean WriteFuzzyWeight(FILE *fp, fuzzyseperator_t *fs)
|
||||
{
|
||||
if (fs->type == WT_BALANCE)
|
||||
{
|
||||
if (fprintf(fp, " return balance(") < 0) return qfalse;
|
||||
if (!WriteFloat(fp, fs->weight)) return qfalse;
|
||||
if (fprintf(fp, ",") < 0) return qfalse;
|
||||
if (!WriteFloat(fp, fs->minweight)) return qfalse;
|
||||
if (fprintf(fp, ",") < 0) return qfalse;
|
||||
if (!WriteFloat(fp, fs->maxweight)) return qfalse;
|
||||
if (fprintf(fp, ");\n") < 0) return qfalse;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if (fprintf(fp, " return ") < 0) return qfalse;
|
||||
if (!WriteFloat(fp, fs->weight)) return qfalse;
|
||||
if (fprintf(fp, ";\n") < 0) return qfalse;
|
||||
} //end else
|
||||
return qtrue;
|
||||
} //end of the function WriteFuzzyWeight
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean WriteFuzzySeperators_r(FILE *fp, fuzzyseperator_t *fs, int indent)
|
||||
{
|
||||
if (!WriteIndent(fp, indent)) return qfalse;
|
||||
if (fprintf(fp, "switch(%d)\n", fs->index) < 0) return qfalse;
|
||||
if (!WriteIndent(fp, indent)) return qfalse;
|
||||
if (fprintf(fp, "{\n") < 0) return qfalse;
|
||||
indent++;
|
||||
do
|
||||
{
|
||||
if (!WriteIndent(fp, indent)) return qfalse;
|
||||
if (fs->next)
|
||||
{
|
||||
if (fprintf(fp, "case %d:", fs->value) < 0) return qfalse;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if (fprintf(fp, "default:") < 0) return qfalse;
|
||||
} //end else
|
||||
if (fs->child)
|
||||
{
|
||||
if (fprintf(fp, "\n") < 0) return qfalse;
|
||||
if (!WriteIndent(fp, indent)) return qfalse;
|
||||
if (fprintf(fp, "{\n") < 0) return qfalse;
|
||||
if (!WriteFuzzySeperators_r(fp, fs->child, indent + 1)) return qfalse;
|
||||
if (!WriteIndent(fp, indent)) return qfalse;
|
||||
if (fs->next)
|
||||
{
|
||||
if (fprintf(fp, "} //end case\n") < 0) return qfalse;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if (fprintf(fp, "} //end default\n") < 0) return qfalse;
|
||||
} //end else
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if (!WriteFuzzyWeight(fp, fs)) return qfalse;
|
||||
} //end else
|
||||
fs = fs->next;
|
||||
} while(fs);
|
||||
indent--;
|
||||
if (!WriteIndent(fp, indent)) return qfalse;
|
||||
if (fprintf(fp, "} //end switch\n") < 0) return qfalse;
|
||||
return qtrue;
|
||||
} //end of the function WriteItemFuzzyWeights_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean WriteWeightConfig(char *filename, weightconfig_t *config)
|
||||
{
|
||||
int i;
|
||||
FILE *fp;
|
||||
weight_t *ifw;
|
||||
|
||||
fp = fopen(filename, "wb");
|
||||
if (!fp) return qfalse;
|
||||
|
||||
for (i = 0; i < config->numweights; i++)
|
||||
{
|
||||
ifw = &config->weights[i];
|
||||
if (fprintf(fp, "\nweight \"%s\"\n", ifw->name) < 0) return qfalse;
|
||||
if (fprintf(fp, "{\n") < 0) return qfalse;
|
||||
if (ifw->firstseperator->index > 0)
|
||||
{
|
||||
if (!WriteFuzzySeperators_r(fp, ifw->firstseperator, 1)) return qfalse;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if (!WriteIndent(fp, 1)) return qfalse;
|
||||
if (!WriteFuzzyWeight(fp, ifw->firstseperator)) return qfalse;
|
||||
} //end else
|
||||
if (fprintf(fp, "} //end weight\n") < 0) return qfalse;
|
||||
} //end for
|
||||
fclose(fp);
|
||||
return qtrue;
|
||||
} //end of the function WriteWeightConfig
|
||||
#endif
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int FindFuzzyWeight(weightconfig_t *wc, char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < wc->numweights; i++)
|
||||
{
|
||||
if (!strcmp(wc->weights[i].name, name))
|
||||
{
|
||||
return i;
|
||||
} //end if
|
||||
} //end if
|
||||
return -1;
|
||||
} //end of the function FindFuzzyWeight
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
float FuzzyWeight_r(int *inventory, fuzzyseperator_t *fs)
|
||||
{
|
||||
float scale, w1, w2;
|
||||
|
||||
if (inventory[fs->index] < fs->value)
|
||||
{
|
||||
if (fs->child) return FuzzyWeight_r(inventory, fs->child);
|
||||
else return fs->weight;
|
||||
} //end if
|
||||
else if (fs->next)
|
||||
{
|
||||
if (inventory[fs->index] < fs->next->value)
|
||||
{
|
||||
//first weight
|
||||
if (fs->child) w1 = FuzzyWeight_r(inventory, fs->child);
|
||||
else w1 = fs->weight;
|
||||
//second weight
|
||||
if (fs->next->child) w2 = FuzzyWeight_r(inventory, fs->next->child);
|
||||
else w2 = fs->next->weight;
|
||||
//the scale factor
|
||||
scale = (inventory[fs->index] - fs->value) / (fs->next->value - fs->value);
|
||||
//scale between the two weights
|
||||
return scale * w1 + (1 - scale) * w2;
|
||||
} //end if
|
||||
return FuzzyWeight_r(inventory, fs->next);
|
||||
} //end else if
|
||||
return fs->weight;
|
||||
} //end of the function FuzzyWeight_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
float FuzzyWeightUndecided_r(int *inventory, fuzzyseperator_t *fs)
|
||||
{
|
||||
float scale, w1, w2;
|
||||
|
||||
if (inventory[fs->index] < fs->value)
|
||||
{
|
||||
if (fs->child) return FuzzyWeightUndecided_r(inventory, fs->child);
|
||||
else return fs->minweight + random() * (fs->maxweight - fs->minweight);
|
||||
} //end if
|
||||
else if (fs->next)
|
||||
{
|
||||
if (inventory[fs->index] < fs->next->value)
|
||||
{
|
||||
//first weight
|
||||
if (fs->child) w1 = FuzzyWeightUndecided_r(inventory, fs->child);
|
||||
else w1 = fs->minweight + random() * (fs->maxweight - fs->minweight);
|
||||
//second weight
|
||||
if (fs->next->child) w2 = FuzzyWeight_r(inventory, fs->next->child);
|
||||
else w2 = fs->next->minweight + random() * (fs->next->maxweight - fs->next->minweight);
|
||||
//the scale factor
|
||||
scale = (inventory[fs->index] - fs->value) / (fs->next->value - fs->value);
|
||||
//scale between the two weights
|
||||
return scale * w1 + (1 - scale) * w2;
|
||||
} //end if
|
||||
return FuzzyWeightUndecided_r(inventory, fs->next);
|
||||
} //end else if
|
||||
return fs->weight;
|
||||
} //end of the function FuzzyWeightUndecided_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
float FuzzyWeight(int *inventory, weightconfig_t *wc, int weightnum)
|
||||
{
|
||||
#ifdef EVALUATERECURSIVELY
|
||||
return FuzzyWeight_r(inventory, wc->weights[weightnum].firstseperator);
|
||||
#else
|
||||
fuzzyseperator_t *s;
|
||||
|
||||
s = wc->weights[weightnum].firstseperator;
|
||||
if (!s) return 0;
|
||||
while(1)
|
||||
{
|
||||
if (inventory[s->index] < s->value)
|
||||
{
|
||||
if (s->child) s = s->child;
|
||||
else return s->weight;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if (s->next) s = s->next;
|
||||
else return s->weight;
|
||||
} //end else
|
||||
} //end if
|
||||
return 0;
|
||||
#endif
|
||||
} //end of the function FuzzyWeight
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
float FuzzyWeightUndecided(int *inventory, weightconfig_t *wc, int weightnum)
|
||||
{
|
||||
#ifdef EVALUATERECURSIVELY
|
||||
return FuzzyWeightUndecided_r(inventory, wc->weights[weightnum].firstseperator);
|
||||
#else
|
||||
fuzzyseperator_t *s;
|
||||
|
||||
s = wc->weights[weightnum].firstseperator;
|
||||
if (!s) return 0;
|
||||
while(1)
|
||||
{
|
||||
if (inventory[s->index] < s->value)
|
||||
{
|
||||
if (s->child) s = s->child;
|
||||
else return s->minweight + random() * (s->maxweight - s->minweight);
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if (s->next) s = s->next;
|
||||
else return s->minweight + random() * (s->maxweight - s->minweight);
|
||||
} //end else
|
||||
} //end if
|
||||
return 0;
|
||||
#endif
|
||||
} //end of the function FuzzyWeightUndecided
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EvolveFuzzySeperator_r(fuzzyseperator_t *fs)
|
||||
{
|
||||
if (fs->child)
|
||||
{
|
||||
EvolveFuzzySeperator_r(fs->child);
|
||||
} //end if
|
||||
else if (fs->type == WT_BALANCE)
|
||||
{
|
||||
//every once in a while an evolution leap occurs, mutation
|
||||
if (random() < 0.01) fs->weight += crandom() * (fs->maxweight - fs->minweight);
|
||||
else fs->weight += crandom() * (fs->maxweight - fs->minweight) * 0.5;
|
||||
//modify bounds if necesary because of mutation
|
||||
if (fs->weight < fs->minweight) fs->minweight = fs->weight;
|
||||
else if (fs->weight > fs->maxweight) fs->maxweight = fs->weight;
|
||||
} //end else if
|
||||
if (fs->next) EvolveFuzzySeperator_r(fs->next);
|
||||
} //end of the function EvolveFuzzySeperator_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EvolveWeightConfig(weightconfig_t *config)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < config->numweights; i++)
|
||||
{
|
||||
EvolveFuzzySeperator_r(config->weights[i].firstseperator);
|
||||
} //end for
|
||||
} //end of the function EvolveWeightConfig
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void ScaleFuzzySeperator_r(fuzzyseperator_t *fs, float scale)
|
||||
{
|
||||
if (fs->child)
|
||||
{
|
||||
ScaleFuzzySeperator_r(fs->child, scale);
|
||||
} //end if
|
||||
else if (fs->type == WT_BALANCE)
|
||||
{
|
||||
//
|
||||
fs->weight = (fs->maxweight + fs->minweight) * scale;
|
||||
//get the weight between bounds
|
||||
if (fs->weight < fs->minweight) fs->weight = fs->minweight;
|
||||
else if (fs->weight > fs->maxweight) fs->weight = fs->maxweight;
|
||||
} //end else if
|
||||
if (fs->next) ScaleFuzzySeperator_r(fs->next, scale);
|
||||
} //end of the function ScaleFuzzySeperator_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void ScaleWeight(weightconfig_t *config, char *name, float scale)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (scale < 0) scale = 0;
|
||||
else if (scale > 1) scale = 1;
|
||||
for (i = 0; i < config->numweights; i++)
|
||||
{
|
||||
if (!strcmp(name, config->weights[i].name))
|
||||
{
|
||||
ScaleFuzzySeperator_r(config->weights[i].firstseperator, scale);
|
||||
break;
|
||||
} //end if
|
||||
} //end for
|
||||
} //end of the function ScaleWeight
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void ScaleFuzzySeperatorBalanceRange_r(fuzzyseperator_t *fs, float scale)
|
||||
{
|
||||
if (fs->child)
|
||||
{
|
||||
ScaleFuzzySeperatorBalanceRange_r(fs->child, scale);
|
||||
} //end if
|
||||
else if (fs->type == WT_BALANCE)
|
||||
{
|
||||
float mid = (fs->minweight + fs->maxweight) * 0.5;
|
||||
//get the weight between bounds
|
||||
fs->maxweight = mid + (fs->maxweight - mid) * scale;
|
||||
fs->minweight = mid + (fs->minweight - mid) * scale;
|
||||
if (fs->maxweight < fs->minweight)
|
||||
{
|
||||
fs->maxweight = fs->minweight;
|
||||
} //end if
|
||||
} //end else if
|
||||
if (fs->next) ScaleFuzzySeperatorBalanceRange_r(fs->next, scale);
|
||||
} //end of the function ScaleFuzzySeperatorBalanceRange_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void ScaleFuzzyBalanceRange(weightconfig_t *config, float scale)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (scale < 0) scale = 0;
|
||||
else if (scale > 100) scale = 100;
|
||||
for (i = 0; i < config->numweights; i++)
|
||||
{
|
||||
ScaleFuzzySeperatorBalanceRange_r(config->weights[i].firstseperator, scale);
|
||||
} //end for
|
||||
} //end of the function ScaleFuzzyBalanceRange
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int InterbreedFuzzySeperator_r(fuzzyseperator_t *fs1, fuzzyseperator_t *fs2,
|
||||
fuzzyseperator_t *fsout)
|
||||
{
|
||||
if (fs1->child)
|
||||
{
|
||||
if (!fs2->child || !fsout->child)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "cannot interbreed weight configs, unequal child\n");
|
||||
return qfalse;
|
||||
} //end if
|
||||
if (!InterbreedFuzzySeperator_r(fs2->child, fs2->child, fsout->child))
|
||||
{
|
||||
return qfalse;
|
||||
} //end if
|
||||
} //end if
|
||||
else if (fs1->type == WT_BALANCE)
|
||||
{
|
||||
if (fs2->type != WT_BALANCE || fsout->type != WT_BALANCE)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "cannot interbreed weight configs, unequal balance\n");
|
||||
return qfalse;
|
||||
} //end if
|
||||
fsout->weight = (fs1->weight + fs2->weight) / 2;
|
||||
if (fsout->weight > fsout->maxweight) fsout->maxweight = fsout->weight;
|
||||
if (fsout->weight > fsout->minweight) fsout->minweight = fsout->weight;
|
||||
} //end else if
|
||||
if (fs1->next)
|
||||
{
|
||||
if (!fs2->next || !fsout->next)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "cannot interbreed weight configs, unequal next\n");
|
||||
return qfalse;
|
||||
} //end if
|
||||
if (!InterbreedFuzzySeperator_r(fs1->next, fs2->next, fsout->next))
|
||||
{
|
||||
return qfalse;
|
||||
} //end if
|
||||
} //end if
|
||||
return qtrue;
|
||||
} //end of the function InterbreedFuzzySeperator_r
|
||||
//===========================================================================
|
||||
// config1 and config2 are interbreeded and stored in configout
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void InterbreedWeightConfigs(weightconfig_t *config1, weightconfig_t *config2,
|
||||
weightconfig_t *configout)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (config1->numweights != config2->numweights ||
|
||||
config1->numweights != configout->numweights)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "cannot interbreed weight configs, unequal numweights\n");
|
||||
return;
|
||||
} //end if
|
||||
for (i = 0; i < config1->numweights; i++)
|
||||
{
|
||||
InterbreedFuzzySeperator_r(config1->weights[i].firstseperator,
|
||||
config2->weights[i].firstseperator,
|
||||
configout->weights[i].firstseperator);
|
||||
} //end for
|
||||
} //end of the function InterbreedWeightConfigs
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void BotShutdownWeights(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < MAX_WEIGHT_FILES; i++ )
|
||||
{
|
||||
if (weightFileList[i])
|
||||
{
|
||||
FreeWeightConfig2(weightFileList[i]);
|
||||
weightFileList[i] = NULL;
|
||||
} //end if
|
||||
} //end for
|
||||
} //end of the function BotShutdownWeights
|
83
tools/quake3/bspc/deps/botlib/be_ai_weight.h
Normal file
83
tools/quake3/bspc/deps/botlib/be_ai_weight.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_ai_weight.h
|
||||
*
|
||||
* desc: fuzzy weights
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_ai_weight.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define WT_BALANCE 1
|
||||
#define MAX_WEIGHTS 128
|
||||
|
||||
//fuzzy seperator
|
||||
typedef struct fuzzyseperator_s
|
||||
{
|
||||
int index;
|
||||
int value;
|
||||
int type;
|
||||
float weight;
|
||||
float minweight;
|
||||
float maxweight;
|
||||
struct fuzzyseperator_s *child;
|
||||
struct fuzzyseperator_s *next;
|
||||
} fuzzyseperator_t;
|
||||
|
||||
//fuzzy weight
|
||||
typedef struct weight_s
|
||||
{
|
||||
char *name;
|
||||
struct fuzzyseperator_s *firstseperator;
|
||||
} weight_t;
|
||||
|
||||
//weight configuration
|
||||
typedef struct weightconfig_s
|
||||
{
|
||||
int numweights;
|
||||
weight_t weights[MAX_WEIGHTS];
|
||||
char filename[MAX_QPATH];
|
||||
} weightconfig_t;
|
||||
|
||||
//reads a weight configuration
|
||||
weightconfig_t *ReadWeightConfig(char *filename);
|
||||
//free a weight configuration
|
||||
void FreeWeightConfig(weightconfig_t *config);
|
||||
//writes a weight configuration, returns true if successfull
|
||||
qboolean WriteWeightConfig(char *filename, weightconfig_t *config);
|
||||
//find the fuzzy weight with the given name
|
||||
int FindFuzzyWeight(weightconfig_t *wc, char *name);
|
||||
//returns the fuzzy weight for the given inventory and weight
|
||||
float FuzzyWeight(int *inventory, weightconfig_t *wc, int weightnum);
|
||||
float FuzzyWeightUndecided(int *inventory, weightconfig_t *wc, int weightnum);
|
||||
//scales the weight with the given name
|
||||
void ScaleWeight(weightconfig_t *config, char *name, float scale);
|
||||
//scale the balance range
|
||||
void ScaleBalanceRange(weightconfig_t *config, float scale);
|
||||
//evolves the weight configuration
|
||||
void EvolveWeightConfig(weightconfig_t *config);
|
||||
//interbreed the weight configurations and stores the interbreeded one in configout
|
||||
void InterbreedWeightConfigs(weightconfig_t *config1, weightconfig_t *config2, weightconfig_t *configout);
|
||||
//frees cached weight configurations
|
||||
void BotShutdownWeights(void);
|
508
tools/quake3/bspc/deps/botlib/be_ea.c
Normal file
508
tools/quake3/bspc/deps/botlib/be_ea.c
Normal file
|
@ -0,0 +1,508 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_ea.c
|
||||
*
|
||||
* desc: elementary actions
|
||||
*
|
||||
* $Archive: /MissionPack/code/botlib/be_ea.c $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "l_memory.h"
|
||||
#include "l_script.h"
|
||||
#include "l_precomp.h"
|
||||
#include "l_struct.h"
|
||||
#include "botlib.h"
|
||||
#include "be_interface.h"
|
||||
|
||||
#define MAX_USERMOVE 400
|
||||
#define MAX_COMMANDARGUMENTS 10
|
||||
#define ACTION_JUMPEDLASTFRAME 128
|
||||
|
||||
bot_input_t *botinputs;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_Say(int client, char *str)
|
||||
{
|
||||
botimport.BotClientCommand(client, va("say %s", str) );
|
||||
} //end of the function EA_Say
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_SayTeam(int client, char *str)
|
||||
{
|
||||
botimport.BotClientCommand(client, va("say_team %s", str));
|
||||
} //end of the function EA_SayTeam
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_Tell(int client, int clientto, char *str)
|
||||
{
|
||||
botimport.BotClientCommand(client, va("tell %d, %s", clientto, str));
|
||||
} //end of the function EA_SayTeam
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_UseItem(int client, char *it)
|
||||
{
|
||||
botimport.BotClientCommand(client, va("use %s", it));
|
||||
} //end of the function EA_UseItem
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_DropItem(int client, char *it)
|
||||
{
|
||||
botimport.BotClientCommand(client, va("drop %s", it));
|
||||
} //end of the function EA_DropItem
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_UseInv(int client, char *inv)
|
||||
{
|
||||
botimport.BotClientCommand(client, va("invuse %s", inv));
|
||||
} //end of the function EA_UseInv
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_DropInv(int client, char *inv)
|
||||
{
|
||||
botimport.BotClientCommand(client, va("invdrop %s", inv));
|
||||
} //end of the function EA_DropInv
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_Gesture(int client)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
bi->actionflags |= ACTION_GESTURE;
|
||||
} //end of the function EA_Gesture
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_Command(int client, char *command)
|
||||
{
|
||||
botimport.BotClientCommand(client, command);
|
||||
} //end of the function EA_Command
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_SelectWeapon(int client, int weapon)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
bi->weapon = weapon;
|
||||
} //end of the function EA_SelectWeapon
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_Attack(int client)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
bi->actionflags |= ACTION_ATTACK;
|
||||
} //end of the function EA_Attack
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_Talk(int client)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
bi->actionflags |= ACTION_TALK;
|
||||
} //end of the function EA_Talk
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_Use(int client)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
bi->actionflags |= ACTION_USE;
|
||||
} //end of the function EA_Use
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_Respawn(int client)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
bi->actionflags |= ACTION_RESPAWN;
|
||||
} //end of the function EA_Respawn
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_Jump(int client)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
if (bi->actionflags & ACTION_JUMPEDLASTFRAME)
|
||||
{
|
||||
bi->actionflags &= ~ACTION_JUMP;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
bi->actionflags |= ACTION_JUMP;
|
||||
} //end if
|
||||
} //end of the function EA_Jump
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_DelayedJump(int client)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
if (bi->actionflags & ACTION_JUMPEDLASTFRAME)
|
||||
{
|
||||
bi->actionflags &= ~ACTION_DELAYEDJUMP;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
bi->actionflags |= ACTION_DELAYEDJUMP;
|
||||
} //end if
|
||||
} //end of the function EA_DelayedJump
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_Crouch(int client)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
bi->actionflags |= ACTION_CROUCH;
|
||||
} //end of the function EA_Crouch
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_Walk(int client)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
bi->actionflags |= ACTION_WALK;
|
||||
} //end of the function EA_Walk
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_Action(int client, int action)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
bi->actionflags |= action;
|
||||
} //end of function EA_Action
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_MoveUp(int client)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
bi->actionflags |= ACTION_MOVEUP;
|
||||
} //end of the function EA_MoveUp
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_MoveDown(int client)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
bi->actionflags |= ACTION_MOVEDOWN;
|
||||
} //end of the function EA_MoveDown
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_MoveForward(int client)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
bi->actionflags |= ACTION_MOVEFORWARD;
|
||||
} //end of the function EA_MoveForward
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_MoveBack(int client)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
bi->actionflags |= ACTION_MOVEBACK;
|
||||
} //end of the function EA_MoveBack
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_MoveLeft(int client)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
bi->actionflags |= ACTION_MOVELEFT;
|
||||
} //end of the function EA_MoveLeft
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_MoveRight(int client)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
bi->actionflags |= ACTION_MOVERIGHT;
|
||||
} //end of the function EA_MoveRight
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_Move(int client, vec3_t dir, float speed)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
VectorCopy(dir, bi->dir);
|
||||
//cap speed
|
||||
if (speed > MAX_USERMOVE) speed = MAX_USERMOVE;
|
||||
else if (speed < -MAX_USERMOVE) speed = -MAX_USERMOVE;
|
||||
bi->speed = speed;
|
||||
} //end of the function EA_Move
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_View(int client, vec3_t viewangles)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
VectorCopy(viewangles, bi->viewangles);
|
||||
} //end of the function EA_View
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_EndRegular(int client, float thinktime)
|
||||
{
|
||||
/*
|
||||
bot_input_t *bi;
|
||||
int jumped = qfalse;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
bi->actionflags &= ~ACTION_JUMPEDLASTFRAME;
|
||||
|
||||
bi->thinktime = thinktime;
|
||||
botimport.BotInput(client, bi);
|
||||
|
||||
bi->thinktime = 0;
|
||||
VectorClear(bi->dir);
|
||||
bi->speed = 0;
|
||||
jumped = bi->actionflags & ACTION_JUMP;
|
||||
bi->actionflags = 0;
|
||||
if (jumped) bi->actionflags |= ACTION_JUMPEDLASTFRAME;
|
||||
*/
|
||||
} //end of the function EA_EndRegular
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_GetInput(int client, float thinktime, bot_input_t *input)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
// int jumped = qfalse;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
// bi->actionflags &= ~ACTION_JUMPEDLASTFRAME;
|
||||
|
||||
bi->thinktime = thinktime;
|
||||
Com_Memcpy(input, bi, sizeof(bot_input_t));
|
||||
|
||||
/*
|
||||
bi->thinktime = 0;
|
||||
VectorClear(bi->dir);
|
||||
bi->speed = 0;
|
||||
jumped = bi->actionflags & ACTION_JUMP;
|
||||
bi->actionflags = 0;
|
||||
if (jumped) bi->actionflags |= ACTION_JUMPEDLASTFRAME;
|
||||
*/
|
||||
} //end of the function EA_GetInput
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_ResetInput(int client)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
int jumped = qfalse;
|
||||
|
||||
bi = &botinputs[client];
|
||||
bi->actionflags &= ~ACTION_JUMPEDLASTFRAME;
|
||||
|
||||
bi->thinktime = 0;
|
||||
VectorClear(bi->dir);
|
||||
bi->speed = 0;
|
||||
jumped = bi->actionflags & ACTION_JUMP;
|
||||
bi->actionflags = 0;
|
||||
if (jumped) bi->actionflags |= ACTION_JUMPEDLASTFRAME;
|
||||
} //end of the function EA_ResetInput
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int EA_Setup(void)
|
||||
{
|
||||
//initialize the bot inputs
|
||||
botinputs = (bot_input_t *) GetClearedHunkMemory(
|
||||
botlibglobals.maxclients * sizeof(bot_input_t));
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function EA_Setup
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EA_Shutdown(void)
|
||||
{
|
||||
FreeMemory(botinputs);
|
||||
botinputs = NULL;
|
||||
} //end of the function EA_Shutdown
|
66
tools/quake3/bspc/deps/botlib/be_ea.h
Normal file
66
tools/quake3/bspc/deps/botlib/be_ea.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
//
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_ea.h
|
||||
*
|
||||
* desc: elementary actions
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_ea.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//ClientCommand elementary actions
|
||||
void EA_Say(int client, char *str);
|
||||
void EA_SayTeam(int client, char *str);
|
||||
void EA_Command(int client, char *command );
|
||||
|
||||
void EA_Action(int client, int action);
|
||||
void EA_Crouch(int client);
|
||||
void EA_Walk(int client);
|
||||
void EA_MoveUp(int client);
|
||||
void EA_MoveDown(int client);
|
||||
void EA_MoveForward(int client);
|
||||
void EA_MoveBack(int client);
|
||||
void EA_MoveLeft(int client);
|
||||
void EA_MoveRight(int client);
|
||||
void EA_Attack(int client);
|
||||
void EA_Respawn(int client);
|
||||
void EA_Talk(int client);
|
||||
void EA_Gesture(int client);
|
||||
void EA_Use(int client);
|
||||
|
||||
//regular elementary actions
|
||||
void EA_SelectWeapon(int client, int weapon);
|
||||
void EA_Jump(int client);
|
||||
void EA_DelayedJump(int client);
|
||||
void EA_Move(int client, vec3_t dir, float speed);
|
||||
void EA_View(int client, vec3_t viewangles);
|
||||
|
||||
//send regular input to the server
|
||||
void EA_EndRegular(int client, float thinktime);
|
||||
void EA_GetInput(int client, float thinktime, bot_input_t *input);
|
||||
void EA_ResetInput(int client);
|
||||
//setup and shutdown routines
|
||||
int EA_Setup(void);
|
||||
void EA_Shutdown(void);
|
881
tools/quake3/bspc/deps/botlib/be_interface.c
Normal file
881
tools/quake3/bspc/deps/botlib/be_interface.c
Normal file
|
@ -0,0 +1,881 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_interface.c // bk010221 - FIXME - DEAD code elimination
|
||||
*
|
||||
* desc: bot library interface
|
||||
*
|
||||
* $Archive: /MissionPack/code/botlib/be_interface.c $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "l_memory.h"
|
||||
#include "l_log.h"
|
||||
#include "l_libvar.h"
|
||||
#include "l_script.h"
|
||||
#include "l_precomp.h"
|
||||
#include "l_struct.h"
|
||||
#include "aasfile.h"
|
||||
#include "botlib.h"
|
||||
#include "be_aas.h"
|
||||
#include "be_aas_funcs.h"
|
||||
#include "be_aas_def.h"
|
||||
#include "be_interface.h"
|
||||
|
||||
#include "be_ea.h"
|
||||
#include "be_ai_weight.h"
|
||||
#include "be_ai_goal.h"
|
||||
#include "be_ai_move.h"
|
||||
#include "be_ai_weap.h"
|
||||
#include "be_ai_chat.h"
|
||||
#include "be_ai_char.h"
|
||||
#include "be_ai_gen.h"
|
||||
|
||||
//library globals in a structure
|
||||
botlib_globals_t botlibglobals;
|
||||
|
||||
botlib_export_t be_botlib_export;
|
||||
botlib_import_t botimport;
|
||||
//
|
||||
int bot_developer;
|
||||
//qtrue if the library is setup
|
||||
int botlibsetup = qfalse;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// several functions used by the exported functions
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int Sys_MilliSeconds(void)
|
||||
{
|
||||
return clock() * 1000 / CLOCKS_PER_SEC;
|
||||
} //end of the function Sys_MilliSeconds
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean ValidClientNumber(int num, char *str)
|
||||
{
|
||||
if (num < 0 || num > botlibglobals.maxclients)
|
||||
{
|
||||
//weird: the disabled stuff results in a crash
|
||||
botimport.Print(PRT_ERROR, "%s: invalid client number %d, [0, %d]\n",
|
||||
str, num, botlibglobals.maxclients);
|
||||
return qfalse;
|
||||
} //end if
|
||||
return qtrue;
|
||||
} //end of the function BotValidateClientNumber
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean ValidEntityNumber(int num, char *str)
|
||||
{
|
||||
if (num < 0 || num > botlibglobals.maxentities)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "%s: invalid entity number %d, [0, %d]\n",
|
||||
str, num, botlibglobals.maxentities);
|
||||
return qfalse;
|
||||
} //end if
|
||||
return qtrue;
|
||||
} //end of the function BotValidateClientNumber
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean BotLibSetup(char *str)
|
||||
{
|
||||
if (!botlibglobals.botlibsetup)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "%s: bot library used before being setup\n", str);
|
||||
return qfalse;
|
||||
} //end if
|
||||
return qtrue;
|
||||
} //end of the function BotLibSetup
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int Export_BotLibSetup(void)
|
||||
{
|
||||
int errnum;
|
||||
|
||||
bot_developer = LibVarGetValue("bot_developer");
|
||||
memset( &botlibglobals, 0, sizeof(botlibglobals) ); // bk001207 - init
|
||||
//initialize byte swapping (litte endian etc.)
|
||||
// Swap_Init();
|
||||
Log_Open("botlib.log");
|
||||
//
|
||||
botimport.Print(PRT_MESSAGE, "------- BotLib Initialization -------\n");
|
||||
//
|
||||
botlibglobals.maxclients = (int) LibVarValue("maxclients", "128");
|
||||
botlibglobals.maxentities = (int) LibVarValue("maxentities", "1024");
|
||||
|
||||
errnum = AAS_Setup(); //be_aas_main.c
|
||||
if (errnum != BLERR_NOERROR) return errnum;
|
||||
errnum = EA_Setup(); //be_ea.c
|
||||
if (errnum != BLERR_NOERROR) return errnum;
|
||||
errnum = BotSetupWeaponAI(); //be_ai_weap.c
|
||||
if (errnum != BLERR_NOERROR)return errnum;
|
||||
errnum = BotSetupGoalAI(); //be_ai_goal.c
|
||||
if (errnum != BLERR_NOERROR) return errnum;
|
||||
errnum = BotSetupChatAI(); //be_ai_chat.c
|
||||
if (errnum != BLERR_NOERROR) return errnum;
|
||||
errnum = BotSetupMoveAI(); //be_ai_move.c
|
||||
if (errnum != BLERR_NOERROR) return errnum;
|
||||
|
||||
botlibsetup = qtrue;
|
||||
botlibglobals.botlibsetup = qtrue;
|
||||
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function Export_BotLibSetup
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int Export_BotLibShutdown(void)
|
||||
{
|
||||
if (!BotLibSetup("BotLibShutdown")) return BLERR_LIBRARYNOTSETUP;
|
||||
#ifndef DEMO
|
||||
//DumpFileCRCs();
|
||||
#endif //DEMO
|
||||
//
|
||||
BotShutdownChatAI(); //be_ai_chat.c
|
||||
BotShutdownMoveAI(); //be_ai_move.c
|
||||
BotShutdownGoalAI(); //be_ai_goal.c
|
||||
BotShutdownWeaponAI(); //be_ai_weap.c
|
||||
BotShutdownWeights(); //be_ai_weight.c
|
||||
BotShutdownCharacters(); //be_ai_char.c
|
||||
//shud down aas
|
||||
AAS_Shutdown();
|
||||
//shut down bot elemantary actions
|
||||
EA_Shutdown();
|
||||
//free all libvars
|
||||
LibVarDeAllocAll();
|
||||
//remove all global defines from the pre compiler
|
||||
PC_RemoveAllGlobalDefines();
|
||||
|
||||
//dump all allocated memory
|
||||
// DumpMemory();
|
||||
#ifdef DEBUG
|
||||
PrintMemoryLabels();
|
||||
#endif
|
||||
//shut down library log file
|
||||
Log_Shutdown();
|
||||
//
|
||||
botlibsetup = qfalse;
|
||||
botlibglobals.botlibsetup = qfalse;
|
||||
// print any files still open
|
||||
PC_CheckOpenSourceHandles();
|
||||
//
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function Export_BotLibShutdown
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int Export_BotLibVarSet(char *var_name, char *value)
|
||||
{
|
||||
LibVarSet(var_name, value);
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function Export_BotLibVarSet
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int Export_BotLibVarGet(char *var_name, char *value, int size)
|
||||
{
|
||||
char *varvalue;
|
||||
|
||||
varvalue = LibVarGetString(var_name);
|
||||
strncpy(value, varvalue, size-1);
|
||||
value[size-1] = '\0';
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function Export_BotLibVarGet
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int Export_BotLibStartFrame(float time)
|
||||
{
|
||||
if (!BotLibSetup("BotStartFrame")) return BLERR_LIBRARYNOTSETUP;
|
||||
return AAS_StartFrame(time);
|
||||
} //end of the function Export_BotLibStartFrame
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int Export_BotLibLoadMap(const char *mapname)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
int starttime = Sys_MilliSeconds();
|
||||
#endif
|
||||
int errnum;
|
||||
|
||||
if (!BotLibSetup("BotLoadMap")) return BLERR_LIBRARYNOTSETUP;
|
||||
//
|
||||
botimport.Print(PRT_MESSAGE, "------------ Map Loading ------------\n");
|
||||
//startup AAS for the current map, model and sound index
|
||||
errnum = AAS_LoadMap(mapname);
|
||||
if (errnum != BLERR_NOERROR) return errnum;
|
||||
//initialize the items in the level
|
||||
BotInitLevelItems(); //be_ai_goal.h
|
||||
BotSetBrushModelTypes(); //be_ai_move.h
|
||||
//
|
||||
botimport.Print(PRT_MESSAGE, "-------------------------------------\n");
|
||||
#ifdef DEBUG
|
||||
botimport.Print(PRT_MESSAGE, "map loaded in %d msec\n", Sys_MilliSeconds() - starttime);
|
||||
#endif
|
||||
//
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function Export_BotLibLoadMap
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int Export_BotLibUpdateEntity(int ent, bot_entitystate_t *state)
|
||||
{
|
||||
if (!BotLibSetup("BotUpdateEntity")) return BLERR_LIBRARYNOTSETUP;
|
||||
if (!ValidEntityNumber(ent, "BotUpdateEntity")) return BLERR_INVALIDENTITYNUMBER;
|
||||
|
||||
return AAS_UpdateEntity(ent, state);
|
||||
} //end of the function Export_BotLibUpdateEntity
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_TestMovementPrediction(int entnum, vec3_t origin, vec3_t dir);
|
||||
void ElevatorBottomCenter(aas_reachability_t *reach, vec3_t bottomcenter);
|
||||
int BotGetReachabilityToGoal(vec3_t origin, int areanum,
|
||||
int lastgoalareanum, int lastareanum,
|
||||
int *avoidreach, float *avoidreachtimes, int *avoidreachtries,
|
||||
bot_goal_t *goal, int travelflags, int movetravelflags,
|
||||
struct bot_avoidspot_s *avoidspots, int numavoidspots, int *flags);
|
||||
|
||||
int AAS_PointLight(vec3_t origin, int *red, int *green, int *blue);
|
||||
|
||||
int AAS_TraceAreas(vec3_t start, vec3_t end, int *areas, vec3_t *points, int maxareas);
|
||||
|
||||
int AAS_Reachability_WeaponJump(int area1num, int area2num);
|
||||
|
||||
int BotFuzzyPointReachabilityArea(vec3_t origin);
|
||||
|
||||
float BotGapDistance(vec3_t origin, vec3_t hordir, int entnum);
|
||||
|
||||
void AAS_FloodAreas(vec3_t origin);
|
||||
|
||||
int BotExportTest(int parm0, char *parm1, vec3_t parm2, vec3_t parm3)
|
||||
{
|
||||
|
||||
// return AAS_PointLight(parm2, NULL, NULL, NULL);
|
||||
|
||||
#ifdef DEBUG
|
||||
static int area = -1;
|
||||
static int line[2];
|
||||
int newarea, i, highlightarea, flood;
|
||||
// int reachnum;
|
||||
vec3_t eye, forward, right, end, origin;
|
||||
// vec3_t bottomcenter;
|
||||
// aas_trace_t trace;
|
||||
// aas_face_t *face;
|
||||
// aas_entity_t *ent;
|
||||
// bsp_trace_t bsptrace;
|
||||
// aas_reachability_t reach;
|
||||
// bot_goal_t goal;
|
||||
|
||||
// clock_t start_time, end_time;
|
||||
vec3_t mins = {-16, -16, -24};
|
||||
vec3_t maxs = {16, 16, 32};
|
||||
|
||||
// int areas[10], numareas;
|
||||
|
||||
|
||||
//return 0;
|
||||
|
||||
if (!aasworld.loaded) return 0;
|
||||
|
||||
/*
|
||||
if (parm0 & 1)
|
||||
{
|
||||
AAS_ClearShownPolygons();
|
||||
AAS_FloodAreas(parm2);
|
||||
} //end if
|
||||
return 0;
|
||||
*/
|
||||
for (i = 0; i < 2; i++) if (!line[i]) line[i] = botimport.DebugLineCreate();
|
||||
|
||||
// AAS_ClearShownDebugLines();
|
||||
|
||||
//if (AAS_AgainstLadder(parm2)) botimport.Print(PRT_MESSAGE, "against ladder\n");
|
||||
//BotOnGround(parm2, PRESENCE_NORMAL, 1, &newarea, &newarea);
|
||||
//botimport.Print(PRT_MESSAGE, "%f %f %f\n", parm2[0], parm2[1], parm2[2]);
|
||||
//*
|
||||
highlightarea = LibVarGetValue("bot_highlightarea");
|
||||
if (highlightarea > 0)
|
||||
{
|
||||
newarea = highlightarea;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
VectorCopy(parm2, origin);
|
||||
origin[2] += 0.5;
|
||||
//newarea = AAS_PointAreaNum(origin);
|
||||
newarea = BotFuzzyPointReachabilityArea(origin);
|
||||
} //end else
|
||||
|
||||
botimport.Print(PRT_MESSAGE, "\rtravel time to goal (%d) = %d ", botlibglobals.goalareanum,
|
||||
AAS_AreaTravelTimeToGoalArea(newarea, origin, botlibglobals.goalareanum, TFL_DEFAULT));
|
||||
//newarea = BotReachabilityArea(origin, qtrue);
|
||||
if (newarea != area)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "origin = %f, %f, %f\n", origin[0], origin[1], origin[2]);
|
||||
area = newarea;
|
||||
botimport.Print(PRT_MESSAGE, "new area %d, cluster %d, presence type %d\n",
|
||||
area, AAS_AreaCluster(area), AAS_PointPresenceType(origin));
|
||||
botimport.Print(PRT_MESSAGE, "area contents: ");
|
||||
if (aasworld.areasettings[area].contents & AREACONTENTS_WATER)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "water &");
|
||||
} //end if
|
||||
if (aasworld.areasettings[area].contents & AREACONTENTS_LAVA)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "lava &");
|
||||
} //end if
|
||||
if (aasworld.areasettings[area].contents & AREACONTENTS_SLIME)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "slime &");
|
||||
} //end if
|
||||
if (aasworld.areasettings[area].contents & AREACONTENTS_JUMPPAD)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "jump pad &");
|
||||
} //end if
|
||||
if (aasworld.areasettings[area].contents & AREACONTENTS_CLUSTERPORTAL)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "cluster portal &");
|
||||
} //end if
|
||||
if (aasworld.areasettings[area].contents & AREACONTENTS_VIEWPORTAL)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "view portal &");
|
||||
} //end if
|
||||
if (aasworld.areasettings[area].contents & AREACONTENTS_DONOTENTER)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "do not enter &");
|
||||
} //end if
|
||||
if (aasworld.areasettings[area].contents & AREACONTENTS_MOVER)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "mover &");
|
||||
} //end if
|
||||
if (!aasworld.areasettings[area].contents)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "empty");
|
||||
} //end if
|
||||
botimport.Print(PRT_MESSAGE, "\n");
|
||||
botimport.Print(PRT_MESSAGE, "travel time to goal (%d) = %d\n", botlibglobals.goalareanum,
|
||||
AAS_AreaTravelTimeToGoalArea(newarea, origin, botlibglobals.goalareanum, TFL_DEFAULT|TFL_ROCKETJUMP));
|
||||
/*
|
||||
VectorCopy(origin, end);
|
||||
end[2] += 5;
|
||||
numareas = AAS_TraceAreas(origin, end, areas, NULL, 10);
|
||||
AAS_TraceClientBBox(origin, end, PRESENCE_CROUCH, -1);
|
||||
botimport.Print(PRT_MESSAGE, "num areas = %d, area = %d\n", numareas, areas[0]);
|
||||
*/
|
||||
/*
|
||||
botlibglobals.goalareanum = newarea;
|
||||
VectorCopy(parm2, botlibglobals.goalorigin);
|
||||
botimport.Print(PRT_MESSAGE, "new goal %2.1f %2.1f %2.1f area %d\n",
|
||||
origin[0], origin[1], origin[2], newarea);
|
||||
*/
|
||||
} //end if
|
||||
//*
|
||||
flood = LibVarGetValue("bot_flood");
|
||||
if (parm0 & 1)
|
||||
{
|
||||
if (flood)
|
||||
{
|
||||
AAS_ClearShownPolygons();
|
||||
AAS_ClearShownDebugLines();
|
||||
AAS_FloodAreas(parm2);
|
||||
}
|
||||
else
|
||||
{
|
||||
botlibglobals.goalareanum = newarea;
|
||||
VectorCopy(parm2, botlibglobals.goalorigin);
|
||||
botimport.Print(PRT_MESSAGE, "new goal %2.1f %2.1f %2.1f area %d\n",
|
||||
origin[0], origin[1], origin[2], newarea);
|
||||
}
|
||||
} //end if*/
|
||||
if (flood)
|
||||
return 0;
|
||||
// if (parm0 & BUTTON_USE)
|
||||
// {
|
||||
// botlibglobals.runai = !botlibglobals.runai;
|
||||
// if (botlibglobals.runai) botimport.Print(PRT_MESSAGE, "started AI\n");
|
||||
// else botimport.Print(PRT_MESSAGE, "stopped AI\n");
|
||||
//* /
|
||||
/*
|
||||
goal.areanum = botlibglobals.goalareanum;
|
||||
reachnum = BotGetReachabilityToGoal(parm2, newarea, 1,
|
||||
ms.avoidreach, ms.avoidreachtimes,
|
||||
&goal, TFL_DEFAULT);
|
||||
if (!reachnum)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "goal not reachable\n");
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
AAS_ReachabilityFromNum(reachnum, &reach);
|
||||
AAS_ClearShownDebugLines();
|
||||
AAS_ShowArea(area, qtrue);
|
||||
AAS_ShowArea(reach.areanum, qtrue);
|
||||
AAS_DrawCross(reach.start, 6, LINECOLOR_BLUE);
|
||||
AAS_DrawCross(reach.end, 6, LINECOLOR_RED);
|
||||
//
|
||||
if ((reach.traveltype & TRAVELTYPE_MASK) == TRAVEL_ELEVATOR)
|
||||
{
|
||||
ElevatorBottomCenter(&reach, bottomcenter);
|
||||
AAS_DrawCross(bottomcenter, 10, LINECOLOR_GREEN);
|
||||
} //end if
|
||||
} //end else*/
|
||||
// botimport.Print(PRT_MESSAGE, "travel time to goal = %d\n",
|
||||
// AAS_AreaTravelTimeToGoalArea(area, origin, botlibglobals.goalareanum, TFL_DEFAULT));
|
||||
// botimport.Print(PRT_MESSAGE, "test rj from 703 to 716\n");
|
||||
// AAS_Reachability_WeaponJump(703, 716);
|
||||
// } //end if*/
|
||||
|
||||
/* face = AAS_AreaGroundFace(newarea, parm2);
|
||||
if (face)
|
||||
{
|
||||
AAS_ShowFace(face - aasworld.faces);
|
||||
} //end if*/
|
||||
/*
|
||||
AAS_ClearShownDebugLines();
|
||||
AAS_ShowArea(newarea, parm0 & BUTTON_USE);
|
||||
AAS_ShowReachableAreas(area);
|
||||
*/
|
||||
AAS_ClearShownPolygons();
|
||||
AAS_ClearShownDebugLines();
|
||||
AAS_ShowAreaPolygons(newarea, 1, parm0 & 4);
|
||||
if (parm0 & 2) AAS_ShowReachableAreas(area);
|
||||
else
|
||||
{
|
||||
static int lastgoalareanum, lastareanum;
|
||||
static int avoidreach[MAX_AVOIDREACH];
|
||||
static float avoidreachtimes[MAX_AVOIDREACH];
|
||||
static int avoidreachtries[MAX_AVOIDREACH];
|
||||
int reachnum, resultFlags;
|
||||
bot_goal_t goal;
|
||||
aas_reachability_t reach;
|
||||
|
||||
/*
|
||||
goal.areanum = botlibglobals.goalareanum;
|
||||
VectorCopy(botlibglobals.goalorigin, goal.origin);
|
||||
reachnum = BotGetReachabilityToGoal(origin, newarea,
|
||||
lastgoalareanum, lastareanum,
|
||||
avoidreach, avoidreachtimes, avoidreachtries,
|
||||
&goal, TFL_DEFAULT|TFL_FUNCBOB|TFL_ROCKETJUMP, TFL_DEFAULT|TFL_FUNCBOB|TFL_ROCKETJUMP,
|
||||
NULL, 0, &resultFlags);
|
||||
AAS_ReachabilityFromNum(reachnum, &reach);
|
||||
AAS_ShowReachability(&reach);
|
||||
*/
|
||||
int curarea;
|
||||
vec3_t curorigin;
|
||||
|
||||
goal.areanum = botlibglobals.goalareanum;
|
||||
VectorCopy(botlibglobals.goalorigin, goal.origin);
|
||||
VectorCopy(origin, curorigin);
|
||||
curarea = newarea;
|
||||
for ( i = 0; i < 100; i++ ) {
|
||||
if ( curarea == goal.areanum ) {
|
||||
break;
|
||||
}
|
||||
reachnum = BotGetReachabilityToGoal(curorigin, curarea,
|
||||
lastgoalareanum, lastareanum,
|
||||
avoidreach, avoidreachtimes, avoidreachtries,
|
||||
&goal, TFL_DEFAULT|TFL_FUNCBOB|TFL_ROCKETJUMP, TFL_DEFAULT|TFL_FUNCBOB|TFL_ROCKETJUMP,
|
||||
NULL, 0, &resultFlags);
|
||||
AAS_ReachabilityFromNum(reachnum, &reach);
|
||||
AAS_ShowReachability(&reach);
|
||||
VectorCopy(reach.end, origin);
|
||||
lastareanum = curarea;
|
||||
curarea = reach.areanum;
|
||||
}
|
||||
} //end else
|
||||
VectorClear(forward);
|
||||
//BotGapDistance(origin, forward, 0);
|
||||
/*
|
||||
if (parm0 & BUTTON_USE)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "test rj from 703 to 716\n");
|
||||
AAS_Reachability_WeaponJump(703, 716);
|
||||
} //end if*/
|
||||
|
||||
AngleVectors(parm3, forward, right, NULL);
|
||||
//get the eye 16 units to the right of the origin
|
||||
VectorMA(parm2, 8, right, eye);
|
||||
//get the eye 24 units up
|
||||
eye[2] += 24;
|
||||
//get the end point for the line to be traced
|
||||
VectorMA(eye, 800, forward, end);
|
||||
|
||||
// AAS_TestMovementPrediction(1, parm2, forward);
|
||||
/*
|
||||
//trace the line to find the hit point
|
||||
trace = AAS_TraceClientBBox(eye, end, PRESENCE_NORMAL, 1);
|
||||
if (!line[0]) line[0] = botimport.DebugLineCreate();
|
||||
botimport.DebugLineShow(line[0], eye, trace.endpos, LINECOLOR_BLUE);
|
||||
//
|
||||
AAS_ClearShownDebugLines();
|
||||
if (trace.ent)
|
||||
{
|
||||
ent = &aasworld.entities[trace.ent];
|
||||
AAS_ShowBoundingBox(ent->origin, ent->mins, ent->maxs);
|
||||
} //end if
|
||||
*/
|
||||
|
||||
/*
|
||||
start_time = clock();
|
||||
for (i = 0; i < 2000; i++)
|
||||
{
|
||||
AAS_Trace2(eye, mins, maxs, end, 1, MASK_PLAYERSOLID);
|
||||
// AAS_TraceClientBBox(eye, end, PRESENCE_NORMAL, 1);
|
||||
} //end for
|
||||
end_time = clock();
|
||||
botimport.Print(PRT_MESSAGE, "me %lu clocks, %lu CLOCKS_PER_SEC\n", end_time - start_time, CLOCKS_PER_SEC);
|
||||
start_time = clock();
|
||||
for (i = 0; i < 2000; i++)
|
||||
{
|
||||
AAS_Trace(eye, mins, maxs, end, 1, MASK_PLAYERSOLID);
|
||||
} //end for
|
||||
end_time = clock();
|
||||
botimport.Print(PRT_MESSAGE, "id %lu clocks, %lu CLOCKS_PER_SEC\n", end_time - start_time, CLOCKS_PER_SEC);
|
||||
*/
|
||||
|
||||
// TTimo: nested comments are BAD for gcc -Werror, use #if 0 instead..
|
||||
#if 0
|
||||
AAS_ClearShownDebugLines();
|
||||
//bsptrace = AAS_Trace(eye, NULL, NULL, end, 1, MASK_PLAYERSOLID);
|
||||
bsptrace = AAS_Trace(eye, mins, maxs, end, 1, MASK_PLAYERSOLID);
|
||||
if (!line[0]) line[0] = botimport.DebugLineCreate();
|
||||
botimport.DebugLineShow(line[0], eye, bsptrace.endpos, LINECOLOR_YELLOW);
|
||||
if (bsptrace.fraction < 1.0)
|
||||
{
|
||||
face = AAS_TraceEndFace(&trace);
|
||||
if (face)
|
||||
{
|
||||
AAS_ShowFace(face - aasworld.faces);
|
||||
} //end if
|
||||
|
||||
AAS_DrawPlaneCross(bsptrace.endpos,
|
||||
bsptrace.plane.normal,
|
||||
bsptrace.plane.dist + bsptrace.exp_dist,
|
||||
bsptrace.plane.type, LINECOLOR_GREEN);
|
||||
if (trace.ent)
|
||||
{
|
||||
ent = &aasworld.entities[trace.ent];
|
||||
AAS_ShowBoundingBox(ent->origin, ent->mins, ent->maxs);
|
||||
} //end if
|
||||
} //end if
|
||||
//bsptrace = AAS_Trace2(eye, NULL, NULL, end, 1, MASK_PLAYERSOLID);
|
||||
bsptrace = AAS_Trace2(eye, mins, maxs, end, 1, MASK_PLAYERSOLID);
|
||||
botimport.DebugLineShow(line[1], eye, bsptrace.endpos, LINECOLOR_BLUE);
|
||||
if (bsptrace.fraction < 1.0)
|
||||
{
|
||||
AAS_DrawPlaneCross(bsptrace.endpos,
|
||||
bsptrace.plane.normal,
|
||||
bsptrace.plane.dist,// + bsptrace.exp_dist,
|
||||
bsptrace.plane.type, LINECOLOR_RED);
|
||||
if (bsptrace.ent)
|
||||
{
|
||||
ent = &aasworld.entities[bsptrace.ent];
|
||||
AAS_ShowBoundingBox(ent->origin, ent->mins, ent->maxs);
|
||||
} //end if
|
||||
} //end if
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
} //end of the function BotExportTest
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
Init_AAS_Export
|
||||
============
|
||||
*/
|
||||
static void Init_AAS_Export( aas_export_t *aas ) {
|
||||
//--------------------------------------------
|
||||
// be_aas_entity.c
|
||||
//--------------------------------------------
|
||||
aas->AAS_EntityInfo = AAS_EntityInfo;
|
||||
//--------------------------------------------
|
||||
// be_aas_main.c
|
||||
//--------------------------------------------
|
||||
aas->AAS_Initialized = AAS_Initialized;
|
||||
aas->AAS_PresenceTypeBoundingBox = AAS_PresenceTypeBoundingBox;
|
||||
aas->AAS_Time = AAS_Time;
|
||||
//--------------------------------------------
|
||||
// be_aas_sample.c
|
||||
//--------------------------------------------
|
||||
aas->AAS_PointAreaNum = AAS_PointAreaNum;
|
||||
aas->AAS_PointReachabilityAreaIndex = AAS_PointReachabilityAreaIndex;
|
||||
aas->AAS_TraceAreas = AAS_TraceAreas;
|
||||
aas->AAS_BBoxAreas = AAS_BBoxAreas;
|
||||
aas->AAS_AreaInfo = AAS_AreaInfo;
|
||||
//--------------------------------------------
|
||||
// be_aas_bspq3.c
|
||||
//--------------------------------------------
|
||||
aas->AAS_PointContents = AAS_PointContents;
|
||||
aas->AAS_NextBSPEntity = AAS_NextBSPEntity;
|
||||
aas->AAS_ValueForBSPEpairKey = AAS_ValueForBSPEpairKey;
|
||||
aas->AAS_VectorForBSPEpairKey = AAS_VectorForBSPEpairKey;
|
||||
aas->AAS_FloatForBSPEpairKey = AAS_FloatForBSPEpairKey;
|
||||
aas->AAS_IntForBSPEpairKey = AAS_IntForBSPEpairKey;
|
||||
//--------------------------------------------
|
||||
// be_aas_reach.c
|
||||
//--------------------------------------------
|
||||
aas->AAS_AreaReachability = AAS_AreaReachability;
|
||||
//--------------------------------------------
|
||||
// be_aas_route.c
|
||||
//--------------------------------------------
|
||||
aas->AAS_AreaTravelTimeToGoalArea = AAS_AreaTravelTimeToGoalArea;
|
||||
aas->AAS_EnableRoutingArea = AAS_EnableRoutingArea;
|
||||
aas->AAS_PredictRoute = AAS_PredictRoute;
|
||||
//--------------------------------------------
|
||||
// be_aas_altroute.c
|
||||
//--------------------------------------------
|
||||
aas->AAS_AlternativeRouteGoals = AAS_AlternativeRouteGoals;
|
||||
//--------------------------------------------
|
||||
// be_aas_move.c
|
||||
//--------------------------------------------
|
||||
aas->AAS_Swimming = AAS_Swimming;
|
||||
aas->AAS_PredictClientMovement = AAS_PredictClientMovement;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
Init_EA_Export
|
||||
============
|
||||
*/
|
||||
static void Init_EA_Export( ea_export_t *ea ) {
|
||||
//ClientCommand elementary actions
|
||||
ea->EA_Command = EA_Command;
|
||||
ea->EA_Say = EA_Say;
|
||||
ea->EA_SayTeam = EA_SayTeam;
|
||||
|
||||
ea->EA_Action = EA_Action;
|
||||
ea->EA_Gesture = EA_Gesture;
|
||||
ea->EA_Talk = EA_Talk;
|
||||
ea->EA_Attack = EA_Attack;
|
||||
ea->EA_Use = EA_Use;
|
||||
ea->EA_Respawn = EA_Respawn;
|
||||
ea->EA_Crouch = EA_Crouch;
|
||||
ea->EA_MoveUp = EA_MoveUp;
|
||||
ea->EA_MoveDown = EA_MoveDown;
|
||||
ea->EA_MoveForward = EA_MoveForward;
|
||||
ea->EA_MoveBack = EA_MoveBack;
|
||||
ea->EA_MoveLeft = EA_MoveLeft;
|
||||
ea->EA_MoveRight = EA_MoveRight;
|
||||
|
||||
ea->EA_SelectWeapon = EA_SelectWeapon;
|
||||
ea->EA_Jump = EA_Jump;
|
||||
ea->EA_DelayedJump = EA_DelayedJump;
|
||||
ea->EA_Move = EA_Move;
|
||||
ea->EA_View = EA_View;
|
||||
ea->EA_GetInput = EA_GetInput;
|
||||
ea->EA_EndRegular = EA_EndRegular;
|
||||
ea->EA_ResetInput = EA_ResetInput;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
Init_AI_Export
|
||||
============
|
||||
*/
|
||||
static void Init_AI_Export( ai_export_t *ai ) {
|
||||
//-----------------------------------
|
||||
// be_ai_char.h
|
||||
//-----------------------------------
|
||||
ai->BotLoadCharacter = BotLoadCharacter;
|
||||
ai->BotFreeCharacter = BotFreeCharacter;
|
||||
ai->Characteristic_Float = Characteristic_Float;
|
||||
ai->Characteristic_BFloat = Characteristic_BFloat;
|
||||
ai->Characteristic_Integer = Characteristic_Integer;
|
||||
ai->Characteristic_BInteger = Characteristic_BInteger;
|
||||
ai->Characteristic_String = Characteristic_String;
|
||||
//-----------------------------------
|
||||
// be_ai_chat.h
|
||||
//-----------------------------------
|
||||
ai->BotAllocChatState = BotAllocChatState;
|
||||
ai->BotFreeChatState = BotFreeChatState;
|
||||
ai->BotQueueConsoleMessage = BotQueueConsoleMessage;
|
||||
ai->BotRemoveConsoleMessage = BotRemoveConsoleMessage;
|
||||
ai->BotNextConsoleMessage = BotNextConsoleMessage;
|
||||
ai->BotNumConsoleMessages = BotNumConsoleMessages;
|
||||
ai->BotInitialChat = BotInitialChat;
|
||||
ai->BotNumInitialChats = BotNumInitialChats;
|
||||
ai->BotReplyChat = BotReplyChat;
|
||||
ai->BotChatLength = BotChatLength;
|
||||
ai->BotEnterChat = BotEnterChat;
|
||||
ai->BotGetChatMessage = BotGetChatMessage;
|
||||
ai->StringContains = StringContains;
|
||||
ai->BotFindMatch = BotFindMatch;
|
||||
ai->BotMatchVariable = BotMatchVariable;
|
||||
ai->UnifyWhiteSpaces = UnifyWhiteSpaces;
|
||||
ai->BotReplaceSynonyms = BotReplaceSynonyms;
|
||||
ai->BotLoadChatFile = BotLoadChatFile;
|
||||
ai->BotSetChatGender = BotSetChatGender;
|
||||
ai->BotSetChatName = BotSetChatName;
|
||||
//-----------------------------------
|
||||
// be_ai_goal.h
|
||||
//-----------------------------------
|
||||
ai->BotResetGoalState = BotResetGoalState;
|
||||
ai->BotResetAvoidGoals = BotResetAvoidGoals;
|
||||
ai->BotRemoveFromAvoidGoals = BotRemoveFromAvoidGoals;
|
||||
ai->BotPushGoal = BotPushGoal;
|
||||
ai->BotPopGoal = BotPopGoal;
|
||||
ai->BotEmptyGoalStack = BotEmptyGoalStack;
|
||||
ai->BotDumpAvoidGoals = BotDumpAvoidGoals;
|
||||
ai->BotDumpGoalStack = BotDumpGoalStack;
|
||||
ai->BotGoalName = BotGoalName;
|
||||
ai->BotGetTopGoal = BotGetTopGoal;
|
||||
ai->BotGetSecondGoal = BotGetSecondGoal;
|
||||
ai->BotChooseLTGItem = BotChooseLTGItem;
|
||||
ai->BotChooseNBGItem = BotChooseNBGItem;
|
||||
ai->BotTouchingGoal = BotTouchingGoal;
|
||||
ai->BotItemGoalInVisButNotVisible = BotItemGoalInVisButNotVisible;
|
||||
ai->BotGetLevelItemGoal = BotGetLevelItemGoal;
|
||||
ai->BotGetNextCampSpotGoal = BotGetNextCampSpotGoal;
|
||||
ai->BotGetMapLocationGoal = BotGetMapLocationGoal;
|
||||
ai->BotAvoidGoalTime = BotAvoidGoalTime;
|
||||
ai->BotSetAvoidGoalTime = BotSetAvoidGoalTime;
|
||||
ai->BotInitLevelItems = BotInitLevelItems;
|
||||
ai->BotUpdateEntityItems = BotUpdateEntityItems;
|
||||
ai->BotLoadItemWeights = BotLoadItemWeights;
|
||||
ai->BotFreeItemWeights = BotFreeItemWeights;
|
||||
ai->BotInterbreedGoalFuzzyLogic = BotInterbreedGoalFuzzyLogic;
|
||||
ai->BotSaveGoalFuzzyLogic = BotSaveGoalFuzzyLogic;
|
||||
ai->BotMutateGoalFuzzyLogic = BotMutateGoalFuzzyLogic;
|
||||
ai->BotAllocGoalState = BotAllocGoalState;
|
||||
ai->BotFreeGoalState = BotFreeGoalState;
|
||||
//-----------------------------------
|
||||
// be_ai_move.h
|
||||
//-----------------------------------
|
||||
ai->BotResetMoveState = BotResetMoveState;
|
||||
ai->BotMoveToGoal = BotMoveToGoal;
|
||||
ai->BotMoveInDirection = BotMoveInDirection;
|
||||
ai->BotResetAvoidReach = BotResetAvoidReach;
|
||||
ai->BotResetLastAvoidReach = BotResetLastAvoidReach;
|
||||
ai->BotReachabilityArea = BotReachabilityArea;
|
||||
ai->BotMovementViewTarget = BotMovementViewTarget;
|
||||
ai->BotPredictVisiblePosition = BotPredictVisiblePosition;
|
||||
ai->BotAllocMoveState = BotAllocMoveState;
|
||||
ai->BotFreeMoveState = BotFreeMoveState;
|
||||
ai->BotInitMoveState = BotInitMoveState;
|
||||
ai->BotAddAvoidSpot = BotAddAvoidSpot;
|
||||
//-----------------------------------
|
||||
// be_ai_weap.h
|
||||
//-----------------------------------
|
||||
ai->BotChooseBestFightWeapon = BotChooseBestFightWeapon;
|
||||
ai->BotGetWeaponInfo = BotGetWeaponInfo;
|
||||
ai->BotLoadWeaponWeights = BotLoadWeaponWeights;
|
||||
ai->BotAllocWeaponState = BotAllocWeaponState;
|
||||
ai->BotFreeWeaponState = BotFreeWeaponState;
|
||||
ai->BotResetWeaponState = BotResetWeaponState;
|
||||
//-----------------------------------
|
||||
// be_ai_gen.h
|
||||
//-----------------------------------
|
||||
ai->GeneticParentsAndChildSelection = GeneticParentsAndChildSelection;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
GetBotLibAPI
|
||||
============
|
||||
*/
|
||||
botlib_export_t *GetBotLibAPI(int apiVersion, botlib_import_t *import) {
|
||||
assert(import); // bk001129 - this wasn't set for baseq3/
|
||||
botimport = *import;
|
||||
assert(botimport.Print); // bk001129 - pars pro toto
|
||||
|
||||
Com_Memset( &be_botlib_export, 0, sizeof( be_botlib_export ) );
|
||||
|
||||
if ( apiVersion != BOTLIB_API_VERSION ) {
|
||||
botimport.Print( PRT_ERROR, "Mismatched BOTLIB_API_VERSION: expected %i, got %i\n", BOTLIB_API_VERSION, apiVersion );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Init_AAS_Export(&be_botlib_export.aas);
|
||||
Init_EA_Export(&be_botlib_export.ea);
|
||||
Init_AI_Export(&be_botlib_export.ai);
|
||||
|
||||
be_botlib_export.BotLibSetup = Export_BotLibSetup;
|
||||
be_botlib_export.BotLibShutdown = Export_BotLibShutdown;
|
||||
be_botlib_export.BotLibVarSet = Export_BotLibVarSet;
|
||||
be_botlib_export.BotLibVarGet = Export_BotLibVarGet;
|
||||
|
||||
be_botlib_export.PC_AddGlobalDefine = PC_AddGlobalDefine;
|
||||
be_botlib_export.PC_LoadSourceHandle = PC_LoadSourceHandle;
|
||||
be_botlib_export.PC_FreeSourceHandle = PC_FreeSourceHandle;
|
||||
be_botlib_export.PC_ReadTokenHandle = PC_ReadTokenHandle;
|
||||
be_botlib_export.PC_SourceFileAndLine = PC_SourceFileAndLine;
|
||||
|
||||
be_botlib_export.BotLibStartFrame = Export_BotLibStartFrame;
|
||||
be_botlib_export.BotLibLoadMap = Export_BotLibLoadMap;
|
||||
be_botlib_export.BotLibUpdateEntity = Export_BotLibUpdateEntity;
|
||||
be_botlib_export.Test = BotExportTest;
|
||||
|
||||
return &be_botlib_export;
|
||||
}
|
57
tools/quake3/bspc/deps/botlib/be_interface.h
Normal file
57
tools/quake3/bspc/deps/botlib/be_interface.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_interface.h
|
||||
*
|
||||
* desc: botlib interface
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_interface.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//#define DEBUG //debug code
|
||||
#define RANDOMIZE //randomize bot behaviour
|
||||
|
||||
//FIXME: get rid of this global structure
|
||||
typedef struct botlib_globals_s
|
||||
{
|
||||
int botlibsetup; //true when the bot library has been setup
|
||||
int maxentities; //maximum number of entities
|
||||
int maxclients; //maximum number of clients
|
||||
float time; //the global time
|
||||
#ifdef DEBUG
|
||||
qboolean debug; //true if debug is on
|
||||
int goalareanum;
|
||||
vec3_t goalorigin;
|
||||
int runai;
|
||||
#endif
|
||||
} botlib_globals_t;
|
||||
|
||||
|
||||
extern botlib_globals_t botlibglobals;
|
||||
extern botlib_import_t botimport;
|
||||
extern int botDeveloper; //true if developer is on
|
||||
|
||||
//
|
||||
int Sys_MilliSeconds(void);
|
||||
|
516
tools/quake3/bspc/deps/botlib/botlib.h
Normal file
516
tools/quake3/bspc/deps/botlib/botlib.h
Normal file
|
@ -0,0 +1,516 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
//
|
||||
/*****************************************************************************
|
||||
* name: botlib.h
|
||||
*
|
||||
* desc: bot AI library
|
||||
*
|
||||
* $Archive: /source/code/game/botai.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define BOTLIB_API_VERSION 2
|
||||
|
||||
struct aas_clientmove_s;
|
||||
struct aas_entityinfo_s;
|
||||
struct aas_areainfo_s;
|
||||
struct aas_altroutegoal_s;
|
||||
struct aas_predictroute_s;
|
||||
struct bot_consolemessage_s;
|
||||
struct bot_match_s;
|
||||
struct bot_goal_s;
|
||||
struct bot_moveresult_s;
|
||||
struct bot_initmove_s;
|
||||
struct weaponinfo_s;
|
||||
|
||||
#define BOTFILESBASEFOLDER "botfiles"
|
||||
//debug line colors
|
||||
#define LINECOLOR_NONE -1
|
||||
#define LINECOLOR_RED 1//0xf2f2f0f0L
|
||||
#define LINECOLOR_GREEN 2//0xd0d1d2d3L
|
||||
#define LINECOLOR_BLUE 3//0xf3f3f1f1L
|
||||
#define LINECOLOR_YELLOW 4//0xdcdddedfL
|
||||
#define LINECOLOR_ORANGE 5//0xe0e1e2e3L
|
||||
|
||||
//Print types
|
||||
#define PRT_MESSAGE 1
|
||||
#define PRT_WARNING 2
|
||||
#define PRT_ERROR 3
|
||||
#define PRT_FATAL 4
|
||||
#define PRT_EXIT 5
|
||||
|
||||
//console message types
|
||||
#define CMS_NORMAL 0
|
||||
#define CMS_CHAT 1
|
||||
|
||||
//botlib error codes
|
||||
#define BLERR_NOERROR 0 //no error
|
||||
#define BLERR_LIBRARYNOTSETUP 1 //library not setup
|
||||
#define BLERR_INVALIDENTITYNUMBER 2 //invalid entity number
|
||||
#define BLERR_NOAASFILE 3 //no AAS file available
|
||||
#define BLERR_CANNOTOPENAASFILE 4 //cannot open AAS file
|
||||
#define BLERR_WRONGAASFILEID 5 //incorrect AAS file id
|
||||
#define BLERR_WRONGAASFILEVERSION 6 //incorrect AAS file version
|
||||
#define BLERR_CANNOTREADAASLUMP 7 //cannot read AAS file lump
|
||||
#define BLERR_CANNOTLOADICHAT 8 //cannot load initial chats
|
||||
#define BLERR_CANNOTLOADITEMWEIGHTS 9 //cannot load item weights
|
||||
#define BLERR_CANNOTLOADITEMCONFIG 10 //cannot load item config
|
||||
#define BLERR_CANNOTLOADWEAPONWEIGHTS 11 //cannot load weapon weights
|
||||
#define BLERR_CANNOTLOADWEAPONCONFIG 12 //cannot load weapon config
|
||||
|
||||
//action flags
|
||||
#define ACTION_ATTACK 0x0000001
|
||||
#define ACTION_USE 0x0000002
|
||||
#define ACTION_RESPAWN 0x0000008
|
||||
#define ACTION_JUMP 0x0000010
|
||||
#define ACTION_MOVEUP 0x0000020
|
||||
#define ACTION_CROUCH 0x0000080
|
||||
#define ACTION_MOVEDOWN 0x0000100
|
||||
#define ACTION_MOVEFORWARD 0x0000200
|
||||
#define ACTION_MOVEBACK 0x0000800
|
||||
#define ACTION_MOVELEFT 0x0001000
|
||||
#define ACTION_MOVERIGHT 0x0002000
|
||||
#define ACTION_DELAYEDJUMP 0x0008000
|
||||
#define ACTION_TALK 0x0010000
|
||||
#define ACTION_GESTURE 0x0020000
|
||||
#define ACTION_WALK 0x0080000
|
||||
#define ACTION_AFFIRMATIVE 0x0100000
|
||||
#define ACTION_NEGATIVE 0x0200000
|
||||
#define ACTION_GETFLAG 0x0800000
|
||||
#define ACTION_GUARDBASE 0x1000000
|
||||
#define ACTION_PATROL 0x2000000
|
||||
#define ACTION_FOLLOWME 0x8000000
|
||||
|
||||
//the bot input, will be converted to an usercmd_t
|
||||
typedef struct bot_input_s
|
||||
{
|
||||
float thinktime; //time since last output (in seconds)
|
||||
vec3_t dir; //movement direction
|
||||
float speed; //speed in the range [0, 400]
|
||||
vec3_t viewangles; //the view angles
|
||||
int actionflags; //one of the ACTION_? flags
|
||||
int weapon; //weapon to use
|
||||
} bot_input_t;
|
||||
|
||||
#ifndef BSPTRACE
|
||||
|
||||
#define BSPTRACE
|
||||
|
||||
//bsp_trace_t hit surface
|
||||
typedef struct bsp_surface_s
|
||||
{
|
||||
char name[16];
|
||||
int flags;
|
||||
int value;
|
||||
} bsp_surface_t;
|
||||
|
||||
//remove the bsp_trace_s structure definition l8r on
|
||||
//a trace is returned when a box is swept through the world
|
||||
typedef struct bsp_trace_s
|
||||
{
|
||||
qboolean allsolid; // if true, plane is not valid
|
||||
qboolean startsolid; // if true, the initial point was in a solid area
|
||||
float fraction; // time completed, 1.0 = didn't hit anything
|
||||
vec3_t endpos; // final position
|
||||
cplane_t plane; // surface normal at impact
|
||||
float exp_dist; // expanded plane distance
|
||||
int sidenum; // number of the brush side hit
|
||||
bsp_surface_t surface; // the hit point surface
|
||||
int contents; // contents on other side of surface hit
|
||||
int ent; // number of entity hit
|
||||
} bsp_trace_t;
|
||||
|
||||
#endif // BSPTRACE
|
||||
|
||||
//entity state
|
||||
typedef struct bot_entitystate_s
|
||||
{
|
||||
int type; // entity type
|
||||
int flags; // entity flags
|
||||
vec3_t origin; // origin of the entity
|
||||
vec3_t angles; // angles of the model
|
||||
vec3_t old_origin; // for lerping
|
||||
vec3_t mins; // bounding box minimums
|
||||
vec3_t maxs; // bounding box maximums
|
||||
int groundent; // ground entity
|
||||
int solid; // solid type
|
||||
int modelindex; // model used
|
||||
int modelindex2; // weapons, CTF flags, etc
|
||||
int frame; // model frame number
|
||||
int event; // impulse events -- muzzle flashes, footsteps, etc
|
||||
int eventParm; // even parameter
|
||||
int powerups; // bit flags
|
||||
int weapon; // determines weapon and flash model, etc
|
||||
int legsAnim; // mask off ANIM_TOGGLEBIT
|
||||
int torsoAnim; // mask off ANIM_TOGGLEBIT
|
||||
} bot_entitystate_t;
|
||||
|
||||
//bot AI library exported functions
|
||||
typedef struct botlib_import_s
|
||||
{
|
||||
//print messages from the bot library
|
||||
void (QDECL *Print)(int type, char *fmt, ...);
|
||||
//trace a bbox through the world
|
||||
void (*Trace)(bsp_trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask);
|
||||
//trace a bbox against a specific entity
|
||||
void (*EntityTrace)(bsp_trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int entnum, int contentmask);
|
||||
//retrieve the contents at the given point
|
||||
int (*PointContents)(vec3_t point);
|
||||
//check if the point is in potential visible sight
|
||||
int (*inPVS)(vec3_t p1, vec3_t p2);
|
||||
//retrieve the BSP entity data lump
|
||||
char *(*BSPEntityData)(void);
|
||||
//
|
||||
void (*BSPModelMinsMaxsOrigin)(int modelnum, vec3_t angles, vec3_t mins, vec3_t maxs, vec3_t origin);
|
||||
//send a bot client command
|
||||
void (*BotClientCommand)(int client, char *command);
|
||||
//memory allocation
|
||||
void *(*GetMemory)(int size); // allocate from Zone
|
||||
void (*FreeMemory)(void *ptr); // free memory from Zone
|
||||
int (*AvailableMemory)(void); // available Zone memory
|
||||
void *(*HunkAlloc)(int size); // allocate from hunk
|
||||
//file system access
|
||||
int (*FS_FOpenFile)( const char *qpath, fileHandle_t *file, fsMode_t mode );
|
||||
int (*FS_Read)( void *buffer, int len, fileHandle_t f );
|
||||
int (*FS_Write)( const void *buffer, int len, fileHandle_t f );
|
||||
void (*FS_FCloseFile)( fileHandle_t f );
|
||||
int (*FS_Seek)( fileHandle_t f, long offset, int origin );
|
||||
//debug visualisation stuff
|
||||
int (*DebugLineCreate)(void);
|
||||
void (*DebugLineDelete)(int line);
|
||||
void (*DebugLineShow)(int line, vec3_t start, vec3_t end, int color);
|
||||
//
|
||||
int (*DebugPolygonCreate)(int color, int numPoints, vec3_t *points);
|
||||
void (*DebugPolygonDelete)(int id);
|
||||
} botlib_import_t;
|
||||
|
||||
typedef struct aas_export_s
|
||||
{
|
||||
//-----------------------------------
|
||||
// be_aas_entity.h
|
||||
//-----------------------------------
|
||||
void (*AAS_EntityInfo)(int entnum, struct aas_entityinfo_s *info);
|
||||
//-----------------------------------
|
||||
// be_aas_main.h
|
||||
//-----------------------------------
|
||||
int (*AAS_Initialized)(void);
|
||||
void (*AAS_PresenceTypeBoundingBox)(int presencetype, vec3_t mins, vec3_t maxs);
|
||||
float (*AAS_Time)(void);
|
||||
//--------------------------------------------
|
||||
// be_aas_sample.c
|
||||
//--------------------------------------------
|
||||
int (*AAS_PointAreaNum)(vec3_t point);
|
||||
int (*AAS_PointReachabilityAreaIndex)( vec3_t point );
|
||||
int (*AAS_TraceAreas)(vec3_t start, vec3_t end, int *areas, vec3_t *points, int maxareas);
|
||||
int (*AAS_BBoxAreas)(vec3_t absmins, vec3_t absmaxs, int *areas, int maxareas);
|
||||
int (*AAS_AreaInfo)( int areanum, struct aas_areainfo_s *info );
|
||||
//--------------------------------------------
|
||||
// be_aas_bspq3.c
|
||||
//--------------------------------------------
|
||||
int (*AAS_PointContents)(vec3_t point);
|
||||
int (*AAS_NextBSPEntity)(int ent);
|
||||
int (*AAS_ValueForBSPEpairKey)(int ent, char *key, char *value, int size);
|
||||
int (*AAS_VectorForBSPEpairKey)(int ent, char *key, vec3_t v);
|
||||
int (*AAS_FloatForBSPEpairKey)(int ent, char *key, float *value);
|
||||
int (*AAS_IntForBSPEpairKey)(int ent, char *key, int *value);
|
||||
//--------------------------------------------
|
||||
// be_aas_reach.c
|
||||
//--------------------------------------------
|
||||
int (*AAS_AreaReachability)(int areanum);
|
||||
//--------------------------------------------
|
||||
// be_aas_route.c
|
||||
//--------------------------------------------
|
||||
int (*AAS_AreaTravelTimeToGoalArea)(int areanum, vec3_t origin, int goalareanum, int travelflags);
|
||||
int (*AAS_EnableRoutingArea)(int areanum, int enable);
|
||||
int (*AAS_PredictRoute)(struct aas_predictroute_s *route, int areanum, vec3_t origin,
|
||||
int goalareanum, int travelflags, int maxareas, int maxtime,
|
||||
int stopevent, int stopcontents, int stoptfl, int stopareanum);
|
||||
//--------------------------------------------
|
||||
// be_aas_altroute.c
|
||||
//--------------------------------------------
|
||||
int (*AAS_AlternativeRouteGoals)(vec3_t start, int startareanum, vec3_t goal, int goalareanum, int travelflags,
|
||||
struct aas_altroutegoal_s *altroutegoals, int maxaltroutegoals,
|
||||
int type);
|
||||
//--------------------------------------------
|
||||
// be_aas_move.c
|
||||
//--------------------------------------------
|
||||
int (*AAS_Swimming)(vec3_t origin);
|
||||
int (*AAS_PredictClientMovement)(struct aas_clientmove_s *move,
|
||||
int entnum, vec3_t origin,
|
||||
int presencetype, int onground,
|
||||
vec3_t velocity, vec3_t cmdmove,
|
||||
int cmdframes,
|
||||
int maxframes, float frametime,
|
||||
int stopevent, int stopareanum, int visualize);
|
||||
} aas_export_t;
|
||||
|
||||
typedef struct ea_export_s
|
||||
{
|
||||
//ClientCommand elementary actions
|
||||
void (*EA_Command)(int client, char *command );
|
||||
void (*EA_Say)(int client, char *str);
|
||||
void (*EA_SayTeam)(int client, char *str);
|
||||
//
|
||||
void (*EA_Action)(int client, int action);
|
||||
void (*EA_Gesture)(int client);
|
||||
void (*EA_Talk)(int client);
|
||||
void (*EA_Attack)(int client);
|
||||
void (*EA_Use)(int client);
|
||||
void (*EA_Respawn)(int client);
|
||||
void (*EA_MoveUp)(int client);
|
||||
void (*EA_MoveDown)(int client);
|
||||
void (*EA_MoveForward)(int client);
|
||||
void (*EA_MoveBack)(int client);
|
||||
void (*EA_MoveLeft)(int client);
|
||||
void (*EA_MoveRight)(int client);
|
||||
void (*EA_Crouch)(int client);
|
||||
|
||||
void (*EA_SelectWeapon)(int client, int weapon);
|
||||
void (*EA_Jump)(int client);
|
||||
void (*EA_DelayedJump)(int client);
|
||||
void (*EA_Move)(int client, vec3_t dir, float speed);
|
||||
void (*EA_View)(int client, vec3_t viewangles);
|
||||
//send regular input to the server
|
||||
void (*EA_EndRegular)(int client, float thinktime);
|
||||
void (*EA_GetInput)(int client, float thinktime, bot_input_t *input);
|
||||
void (*EA_ResetInput)(int client);
|
||||
} ea_export_t;
|
||||
|
||||
typedef struct ai_export_s
|
||||
{
|
||||
//-----------------------------------
|
||||
// be_ai_char.h
|
||||
//-----------------------------------
|
||||
int (*BotLoadCharacter)(char *charfile, float skill);
|
||||
void (*BotFreeCharacter)(int character);
|
||||
float (*Characteristic_Float)(int character, int index);
|
||||
float (*Characteristic_BFloat)(int character, int index, float min, float max);
|
||||
int (*Characteristic_Integer)(int character, int index);
|
||||
int (*Characteristic_BInteger)(int character, int index, int min, int max);
|
||||
void (*Characteristic_String)(int character, int index, char *buf, int size);
|
||||
//-----------------------------------
|
||||
// be_ai_chat.h
|
||||
//-----------------------------------
|
||||
int (*BotAllocChatState)(void);
|
||||
void (*BotFreeChatState)(int handle);
|
||||
void (*BotQueueConsoleMessage)(int chatstate, int type, char *message);
|
||||
void (*BotRemoveConsoleMessage)(int chatstate, int handle);
|
||||
int (*BotNextConsoleMessage)(int chatstate, struct bot_consolemessage_s *cm);
|
||||
int (*BotNumConsoleMessages)(int chatstate);
|
||||
void (*BotInitialChat)(int chatstate, char *type, int mcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7);
|
||||
int (*BotNumInitialChats)(int chatstate, char *type);
|
||||
int (*BotReplyChat)(int chatstate, char *message, int mcontext, int vcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7);
|
||||
int (*BotChatLength)(int chatstate);
|
||||
void (*BotEnterChat)(int chatstate, int client, int sendto);
|
||||
void (*BotGetChatMessage)(int chatstate, char *buf, int size);
|
||||
int (*StringContains)(char *str1, char *str2, int casesensitive);
|
||||
int (*BotFindMatch)(char *str, struct bot_match_s *match, unsigned long int context);
|
||||
void (*BotMatchVariable)(struct bot_match_s *match, int variable, char *buf, int size);
|
||||
void (*UnifyWhiteSpaces)(char *string);
|
||||
void (*BotReplaceSynonyms)(char *string, unsigned long int context);
|
||||
int (*BotLoadChatFile)(int chatstate, char *chatfile, char *chatname);
|
||||
void (*BotSetChatGender)(int chatstate, int gender);
|
||||
void (*BotSetChatName)(int chatstate, char *name, int client);
|
||||
//-----------------------------------
|
||||
// be_ai_goal.h
|
||||
//-----------------------------------
|
||||
void (*BotResetGoalState)(int goalstate);
|
||||
void (*BotResetAvoidGoals)(int goalstate);
|
||||
void (*BotRemoveFromAvoidGoals)(int goalstate, int number);
|
||||
void (*BotPushGoal)(int goalstate, struct bot_goal_s *goal);
|
||||
void (*BotPopGoal)(int goalstate);
|
||||
void (*BotEmptyGoalStack)(int goalstate);
|
||||
void (*BotDumpAvoidGoals)(int goalstate);
|
||||
void (*BotDumpGoalStack)(int goalstate);
|
||||
void (*BotGoalName)(int number, char *name, int size);
|
||||
int (*BotGetTopGoal)(int goalstate, struct bot_goal_s *goal);
|
||||
int (*BotGetSecondGoal)(int goalstate, struct bot_goal_s *goal);
|
||||
int (*BotChooseLTGItem)(int goalstate, vec3_t origin, int *inventory, int travelflags);
|
||||
int (*BotChooseNBGItem)(int goalstate, vec3_t origin, int *inventory, int travelflags,
|
||||
struct bot_goal_s *ltg, float maxtime);
|
||||
int (*BotTouchingGoal)(vec3_t origin, struct bot_goal_s *goal);
|
||||
int (*BotItemGoalInVisButNotVisible)(int viewer, vec3_t eye, vec3_t viewangles, struct bot_goal_s *goal);
|
||||
int (*BotGetLevelItemGoal)(int index, char *classname, struct bot_goal_s *goal);
|
||||
int (*BotGetNextCampSpotGoal)(int num, struct bot_goal_s *goal);
|
||||
int (*BotGetMapLocationGoal)(char *name, struct bot_goal_s *goal);
|
||||
float (*BotAvoidGoalTime)(int goalstate, int number);
|
||||
void (*BotSetAvoidGoalTime)(int goalstate, int number, float avoidtime);
|
||||
void (*BotInitLevelItems)(void);
|
||||
void (*BotUpdateEntityItems)(void);
|
||||
int (*BotLoadItemWeights)(int goalstate, char *filename);
|
||||
void (*BotFreeItemWeights)(int goalstate);
|
||||
void (*BotInterbreedGoalFuzzyLogic)(int parent1, int parent2, int child);
|
||||
void (*BotSaveGoalFuzzyLogic)(int goalstate, char *filename);
|
||||
void (*BotMutateGoalFuzzyLogic)(int goalstate, float range);
|
||||
int (*BotAllocGoalState)(int client);
|
||||
void (*BotFreeGoalState)(int handle);
|
||||
//-----------------------------------
|
||||
// be_ai_move.h
|
||||
//-----------------------------------
|
||||
void (*BotResetMoveState)(int movestate);
|
||||
void (*BotMoveToGoal)(struct bot_moveresult_s *result, int movestate, struct bot_goal_s *goal, int travelflags);
|
||||
int (*BotMoveInDirection)(int movestate, vec3_t dir, float speed, int type);
|
||||
void (*BotResetAvoidReach)(int movestate);
|
||||
void (*BotResetLastAvoidReach)(int movestate);
|
||||
int (*BotReachabilityArea)(vec3_t origin, int testground);
|
||||
int (*BotMovementViewTarget)(int movestate, struct bot_goal_s *goal, int travelflags, float lookahead, vec3_t target);
|
||||
int (*BotPredictVisiblePosition)(vec3_t origin, int areanum, struct bot_goal_s *goal, int travelflags, vec3_t target);
|
||||
int (*BotAllocMoveState)(void);
|
||||
void (*BotFreeMoveState)(int handle);
|
||||
void (*BotInitMoveState)(int handle, struct bot_initmove_s *initmove);
|
||||
void (*BotAddAvoidSpot)(int movestate, vec3_t origin, float radius, int type);
|
||||
//-----------------------------------
|
||||
// be_ai_weap.h
|
||||
//-----------------------------------
|
||||
int (*BotChooseBestFightWeapon)(int weaponstate, int *inventory);
|
||||
void (*BotGetWeaponInfo)(int weaponstate, int weapon, struct weaponinfo_s *weaponinfo);
|
||||
int (*BotLoadWeaponWeights)(int weaponstate, char *filename);
|
||||
int (*BotAllocWeaponState)(void);
|
||||
void (*BotFreeWeaponState)(int weaponstate);
|
||||
void (*BotResetWeaponState)(int weaponstate);
|
||||
//-----------------------------------
|
||||
// be_ai_gen.h
|
||||
//-----------------------------------
|
||||
int (*GeneticParentsAndChildSelection)(int numranks, float *ranks, int *parent1, int *parent2, int *child);
|
||||
} ai_export_t;
|
||||
|
||||
//bot AI library imported functions
|
||||
typedef struct botlib_export_s
|
||||
{
|
||||
//Area Awareness System functions
|
||||
aas_export_t aas;
|
||||
//Elementary Action functions
|
||||
ea_export_t ea;
|
||||
//AI functions
|
||||
ai_export_t ai;
|
||||
//setup the bot library, returns BLERR_
|
||||
int (*BotLibSetup)(void);
|
||||
//shutdown the bot library, returns BLERR_
|
||||
int (*BotLibShutdown)(void);
|
||||
//sets a library variable returns BLERR_
|
||||
int (*BotLibVarSet)(char *var_name, char *value);
|
||||
//gets a library variable returns BLERR_
|
||||
int (*BotLibVarGet)(char *var_name, char *value, int size);
|
||||
|
||||
//sets a C-like define returns BLERR_
|
||||
int (*PC_AddGlobalDefine)(char *string);
|
||||
int (*PC_LoadSourceHandle)(const char *filename);
|
||||
int (*PC_FreeSourceHandle)(int handle);
|
||||
int (*PC_ReadTokenHandle)(int handle, pc_token_t *pc_token);
|
||||
int (*PC_SourceFileAndLine)(int handle, char *filename, int *line);
|
||||
|
||||
//start a frame in the bot library
|
||||
int (*BotLibStartFrame)(float time);
|
||||
//load a new map in the bot library
|
||||
int (*BotLibLoadMap)(const char *mapname);
|
||||
//entity updates
|
||||
int (*BotLibUpdateEntity)(int ent, bot_entitystate_t *state);
|
||||
//just for testing
|
||||
int (*Test)(int parm0, char *parm1, vec3_t parm2, vec3_t parm3);
|
||||
} botlib_export_t;
|
||||
|
||||
//linking of bot library
|
||||
botlib_export_t *GetBotLibAPI( int apiVersion, botlib_import_t *import );
|
||||
|
||||
/* Library variables:
|
||||
|
||||
name: default: module(s): description:
|
||||
|
||||
"basedir" "" l_utils.c base directory
|
||||
"gamedir" "" l_utils.c game directory
|
||||
"cddir" "" l_utils.c CD directory
|
||||
|
||||
"log" "0" l_log.c enable/disable creating a log file
|
||||
"maxclients" "4" be_interface.c maximum number of clients
|
||||
"maxentities" "1024" be_interface.c maximum number of entities
|
||||
"bot_developer" "0" be_interface.c bot developer mode (it's "botDeveloper" in C to prevent symbol clash).
|
||||
|
||||
"phys_friction" "6" be_aas_move.c ground friction
|
||||
"phys_stopspeed" "100" be_aas_move.c stop speed
|
||||
"phys_gravity" "800" be_aas_move.c gravity value
|
||||
"phys_waterfriction" "1" be_aas_move.c water friction
|
||||
"phys_watergravity" "400" be_aas_move.c gravity in water
|
||||
"phys_maxvelocity" "320" be_aas_move.c maximum velocity
|
||||
"phys_maxwalkvelocity" "320" be_aas_move.c maximum walk velocity
|
||||
"phys_maxcrouchvelocity" "100" be_aas_move.c maximum crouch velocity
|
||||
"phys_maxswimvelocity" "150" be_aas_move.c maximum swim velocity
|
||||
"phys_walkaccelerate" "10" be_aas_move.c walk acceleration
|
||||
"phys_airaccelerate" "1" be_aas_move.c air acceleration
|
||||
"phys_swimaccelerate" "4" be_aas_move.c swim acceleration
|
||||
"phys_maxstep" "18" be_aas_move.c maximum step height
|
||||
"phys_maxsteepness" "0.7" be_aas_move.c maximum floor steepness
|
||||
"phys_maxbarrier" "32" be_aas_move.c maximum barrier height
|
||||
"phys_maxwaterjump" "19" be_aas_move.c maximum waterjump height
|
||||
"phys_jumpvel" "270" be_aas_move.c jump z velocity
|
||||
"phys_falldelta5" "40" be_aas_move.c
|
||||
"phys_falldelta10" "60" be_aas_move.c
|
||||
"rs_waterjump" "400" be_aas_move.c
|
||||
"rs_teleport" "50" be_aas_move.c
|
||||
"rs_barrierjump" "100" be_aas_move.c
|
||||
"rs_startcrouch" "300" be_aas_move.c
|
||||
"rs_startgrapple" "500" be_aas_move.c
|
||||
"rs_startwalkoffledge" "70" be_aas_move.c
|
||||
"rs_startjump" "300" be_aas_move.c
|
||||
"rs_rocketjump" "500" be_aas_move.c
|
||||
"rs_bfgjump" "500" be_aas_move.c
|
||||
"rs_jumppad" "250" be_aas_move.c
|
||||
"rs_aircontrolledjumppad" "300" be_aas_move.c
|
||||
"rs_funcbob" "300" be_aas_move.c
|
||||
"rs_startelevator" "50" be_aas_move.c
|
||||
"rs_falldamage5" "300" be_aas_move.c
|
||||
"rs_falldamage10" "500" be_aas_move.c
|
||||
"rs_maxjumpfallheight" "450" be_aas_move.c
|
||||
|
||||
"max_aaslinks" "4096" be_aas_sample.c maximum links in the AAS
|
||||
"max_routingcache" "4096" be_aas_route.c maximum routing cache size in KB
|
||||
"forceclustering" "0" be_aas_main.c force recalculation of clusters
|
||||
"forcereachability" "0" be_aas_main.c force recalculation of reachabilities
|
||||
"forcewrite" "0" be_aas_main.c force writing of aas file
|
||||
"aasoptimize" "0" be_aas_main.c enable aas optimization
|
||||
"sv_mapChecksum" "0" be_aas_main.c BSP file checksum
|
||||
"bot_visualizejumppads" "0" be_aas_reach.c visualize jump pads
|
||||
|
||||
"bot_reloadcharacters" "0" - reload bot character files
|
||||
"ai_gametype" "0" be_ai_goal.c game type
|
||||
"droppedweight" "1000" be_ai_goal.c additional dropped item weight
|
||||
"weapindex_rocketlauncher" "5" be_ai_move.c rl weapon index for rocket jumping
|
||||
"weapindex_bfg10k" "9" be_ai_move.c bfg weapon index for bfg jumping
|
||||
"weapindex_grapple" "10" be_ai_move.c grapple weapon index for grappling
|
||||
"entitytypemissile" "3" be_ai_move.c ET_MISSILE
|
||||
"offhandgrapple" "0" be_ai_move.c enable off hand grapple hook
|
||||
"cmd_grappleon" "grappleon" be_ai_move.c command to activate off hand grapple
|
||||
"cmd_grappleoff" "grappleoff" be_ai_move.c command to deactivate off hand grapple
|
||||
"itemconfig" "items.c" be_ai_goal.c item configuration file
|
||||
"weaponconfig" "weapons.c" be_ai_weap.c weapon configuration file
|
||||
"synfile" "syn.c" be_ai_chat.c file with synonyms
|
||||
"rndfile" "rnd.c" be_ai_chat.c file with random strings
|
||||
"matchfile" "match.c" be_ai_chat.c file with match strings
|
||||
"nochat" "0" be_ai_chat.c disable chats
|
||||
"max_messages" "1024" be_ai_chat.c console message heap size
|
||||
"max_weaponinfo" "32" be_ai_weap.c maximum number of weapon info
|
||||
"max_projectileinfo" "32" be_ai_weap.c maximum number of projectile info
|
||||
"max_iteminfo" "256" be_ai_goal.c maximum number of item info
|
||||
"max_levelitems" "256" be_ai_goal.c maximum number of level items
|
||||
|
||||
*/
|
||||
|
151
tools/quake3/bspc/deps/botlib/l_crc.c
Normal file
151
tools/quake3/bspc/deps/botlib/l_crc.c
Normal file
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: l_crc.c
|
||||
*
|
||||
* desc: CRC calculation
|
||||
*
|
||||
* $Archive: /MissionPack/CODE/botlib/l_crc.c $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "botlib.h"
|
||||
#include "be_interface.h" //for botimport.Print
|
||||
|
||||
|
||||
// FIXME: byte swap?
|
||||
|
||||
// this is a 16 bit, non-reflected CRC using the polynomial 0x1021
|
||||
// and the initial and final xor values shown below... in other words, the
|
||||
// CCITT standard CRC used by XMODEM
|
||||
|
||||
#define CRC_INIT_VALUE 0xffff
|
||||
#define CRC_XOR_VALUE 0x0000
|
||||
|
||||
unsigned short crctable[257] =
|
||||
{
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
||||
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
|
||||
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
|
||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
|
||||
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
|
||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
|
||||
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
|
||||
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
|
||||
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
|
||||
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
|
||||
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
|
||||
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
|
||||
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
|
||||
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
|
||||
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
|
||||
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
|
||||
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
|
||||
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
|
||||
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
|
||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
|
||||
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
|
||||
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
|
||||
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
|
||||
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
|
||||
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
|
||||
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void CRC_Init(unsigned short *crcvalue)
|
||||
{
|
||||
*crcvalue = CRC_INIT_VALUE;
|
||||
} //end of the function CRC_Init
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void CRC_ProcessByte(unsigned short *crcvalue, byte data)
|
||||
{
|
||||
*crcvalue = (*crcvalue << 8) ^ crctable[(*crcvalue >> 8) ^ data];
|
||||
} //end of the function CRC_ProcessByte
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
unsigned short CRC_Value(unsigned short crcvalue)
|
||||
{
|
||||
return crcvalue ^ CRC_XOR_VALUE;
|
||||
} //end of the function CRC_Value
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
unsigned short CRC_ProcessString(unsigned char *data, int length)
|
||||
{
|
||||
unsigned short crcvalue;
|
||||
int i, ind;
|
||||
|
||||
CRC_Init(&crcvalue);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
ind = (crcvalue >> 8) ^ data[i];
|
||||
if (ind < 0 || ind > 256) ind = 0;
|
||||
crcvalue = (crcvalue << 8) ^ crctable[ind];
|
||||
} //end for
|
||||
return CRC_Value(crcvalue);
|
||||
} //end of the function CRC_ProcessString
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void CRC_ContinueProcessString(unsigned short *crc, char *data, int length)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
*crc = (*crc << 8) ^ crctable[(*crc >> 8) ^ data[i]];
|
||||
} //end for
|
||||
} //end of the function CRC_ProcessString
|
29
tools/quake3/bspc/deps/botlib/l_crc.h
Normal file
29
tools/quake3/bspc/deps/botlib/l_crc.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
typedef unsigned short crc_t;
|
||||
|
||||
void CRC_Init(unsigned short *crcvalue);
|
||||
void CRC_ProcessByte(unsigned short *crcvalue, byte data);
|
||||
unsigned short CRC_Value(unsigned short crcvalue);
|
||||
unsigned short CRC_ProcessString(unsigned char *data, int length);
|
||||
void CRC_ContinueProcessString(unsigned short *crc, char *data, int length);
|
294
tools/quake3/bspc/deps/botlib/l_libvar.c
Normal file
294
tools/quake3/bspc/deps/botlib/l_libvar.c
Normal file
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: l_libvar.c
|
||||
*
|
||||
* desc: bot library variables
|
||||
*
|
||||
* $Archive: /MissionPack/code/botlib/l_libvar.c $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "l_memory.h"
|
||||
#include "l_libvar.h"
|
||||
|
||||
//list with library variables
|
||||
libvar_t *libvarlist;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
float LibVarStringValue(char *string)
|
||||
{
|
||||
int dotfound = 0;
|
||||
float value = 0;
|
||||
|
||||
while(*string)
|
||||
{
|
||||
if (*string < '0' || *string > '9')
|
||||
{
|
||||
if (dotfound || *string != '.')
|
||||
{
|
||||
return 0;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
dotfound = 10;
|
||||
string++;
|
||||
} //end if
|
||||
} //end if
|
||||
if (dotfound)
|
||||
{
|
||||
value = value + (float) (*string - '0') / (float) dotfound;
|
||||
dotfound *= 10;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
value = value * 10.0 + (float) (*string - '0');
|
||||
} //end else
|
||||
string++;
|
||||
} //end while
|
||||
return value;
|
||||
} //end of the function LibVarStringValue
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
libvar_t *LibVarAlloc(char *var_name)
|
||||
{
|
||||
libvar_t *v;
|
||||
|
||||
v = (libvar_t *) GetMemory(sizeof(libvar_t) + strlen(var_name) + 1);
|
||||
Com_Memset(v, 0, sizeof(libvar_t));
|
||||
v->name = (char *) v + sizeof(libvar_t);
|
||||
strcpy(v->name, var_name);
|
||||
//add the variable in the list
|
||||
v->next = libvarlist;
|
||||
libvarlist = v;
|
||||
return v;
|
||||
} //end of the function LibVarAlloc
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void LibVarDeAlloc(libvar_t *v)
|
||||
{
|
||||
if (v->string) FreeMemory(v->string);
|
||||
FreeMemory(v);
|
||||
} //end of the function LibVarDeAlloc
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void LibVarDeAllocAll(void)
|
||||
{
|
||||
libvar_t *v;
|
||||
|
||||
for (v = libvarlist; v; v = libvarlist)
|
||||
{
|
||||
libvarlist = libvarlist->next;
|
||||
LibVarDeAlloc(v);
|
||||
} //end for
|
||||
libvarlist = NULL;
|
||||
} //end of the function LibVarDeAllocAll
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
libvar_t *LibVarGet(char *var_name)
|
||||
{
|
||||
libvar_t *v;
|
||||
|
||||
for (v = libvarlist; v; v = v->next)
|
||||
{
|
||||
if (!Q_stricmp(v->name, var_name))
|
||||
{
|
||||
return v;
|
||||
} //end if
|
||||
} //end for
|
||||
return NULL;
|
||||
} //end of the function LibVarGet
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
char *LibVarGetString(char *var_name)
|
||||
{
|
||||
libvar_t *v;
|
||||
|
||||
v = LibVarGet(var_name);
|
||||
if (v)
|
||||
{
|
||||
return v->string;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
return "";
|
||||
} //end else
|
||||
} //end of the function LibVarGetString
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
float LibVarGetValue(char *var_name)
|
||||
{
|
||||
libvar_t *v;
|
||||
|
||||
v = LibVarGet(var_name);
|
||||
if (v)
|
||||
{
|
||||
return v->value;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
} //end else
|
||||
} //end of the function LibVarGetValue
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
libvar_t *LibVar(char *var_name, char *value)
|
||||
{
|
||||
libvar_t *v;
|
||||
v = LibVarGet(var_name);
|
||||
if (v) return v;
|
||||
//create new variable
|
||||
v = LibVarAlloc(var_name);
|
||||
//variable string
|
||||
v->string = (char *) GetMemory(strlen(value) + 1);
|
||||
strcpy(v->string, value);
|
||||
//the value
|
||||
v->value = LibVarStringValue(v->string);
|
||||
//variable is modified
|
||||
v->modified = qtrue;
|
||||
//
|
||||
return v;
|
||||
} //end of the function LibVar
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
char *LibVarString(char *var_name, char *value)
|
||||
{
|
||||
libvar_t *v;
|
||||
|
||||
v = LibVar(var_name, value);
|
||||
return v->string;
|
||||
} //end of the function LibVarString
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
float LibVarValue(char *var_name, char *value)
|
||||
{
|
||||
libvar_t *v;
|
||||
|
||||
v = LibVar(var_name, value);
|
||||
return v->value;
|
||||
} //end of the function LibVarValue
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void LibVarSet(char *var_name, char *value)
|
||||
{
|
||||
libvar_t *v;
|
||||
|
||||
v = LibVarGet(var_name);
|
||||
if (v)
|
||||
{
|
||||
FreeMemory(v->string);
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
v = LibVarAlloc(var_name);
|
||||
} //end else
|
||||
//variable string
|
||||
v->string = (char *) GetMemory(strlen(value) + 1);
|
||||
strcpy(v->string, value);
|
||||
//the value
|
||||
v->value = LibVarStringValue(v->string);
|
||||
//variable is modified
|
||||
v->modified = qtrue;
|
||||
} //end of the function LibVarSet
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean LibVarChanged(char *var_name)
|
||||
{
|
||||
libvar_t *v;
|
||||
|
||||
v = LibVarGet(var_name);
|
||||
if (v)
|
||||
{
|
||||
return v->modified;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
return qfalse;
|
||||
} //end else
|
||||
} //end of the function LibVarChanged
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void LibVarSetNotModified(char *var_name)
|
||||
{
|
||||
libvar_t *v;
|
||||
|
||||
v = LibVarGet(var_name);
|
||||
if (v)
|
||||
{
|
||||
v->modified = qfalse;
|
||||
} //end if
|
||||
} //end of the function LibVarSetNotModified
|
63
tools/quake3/bspc/deps/botlib/l_libvar.h
Normal file
63
tools/quake3/bspc/deps/botlib/l_libvar.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: l_libvar.h
|
||||
*
|
||||
* desc: botlib vars
|
||||
*
|
||||
* $Archive: /source/code/botlib/l_libvar.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//library variable
|
||||
typedef struct libvar_s
|
||||
{
|
||||
char *name;
|
||||
char *string;
|
||||
int flags;
|
||||
qboolean modified; // set each time the cvar is changed
|
||||
float value;
|
||||
struct libvar_s *next;
|
||||
} libvar_t;
|
||||
|
||||
//removes all library variables
|
||||
void LibVarDeAllocAll(void);
|
||||
//gets the library variable with the given name
|
||||
libvar_t *LibVarGet(char *var_name);
|
||||
//gets the string of the library variable with the given name
|
||||
char *LibVarGetString(char *var_name);
|
||||
//gets the value of the library variable with the given name
|
||||
float LibVarGetValue(char *var_name);
|
||||
//creates the library variable if not existing already and returns it
|
||||
libvar_t *LibVar(char *var_name, char *value);
|
||||
//creates the library variable if not existing already and returns the value
|
||||
float LibVarValue(char *var_name, char *value);
|
||||
//creates the library variable if not existing already and returns the value string
|
||||
char *LibVarString(char *var_name, char *value);
|
||||
//sets the library variable
|
||||
void LibVarSet(char *var_name, char *value);
|
||||
//returns true if the library variable has been modified
|
||||
qboolean LibVarChanged(char *var_name);
|
||||
//sets the library variable to unmodified
|
||||
void LibVarSetNotModified(char *var_name);
|
||||
|
169
tools/quake3/bspc/deps/botlib/l_log.c
Normal file
169
tools/quake3/bspc/deps/botlib/l_log.c
Normal file
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: l_log.c
|
||||
*
|
||||
* desc: log file
|
||||
*
|
||||
* $Archive: /MissionPack/CODE/botlib/l_log.c $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "botlib.h"
|
||||
#include "be_interface.h" //for botimport.Print
|
||||
#include "l_libvar.h"
|
||||
|
||||
#define MAX_LOGFILENAMESIZE 1024
|
||||
|
||||
typedef struct logfile_s
|
||||
{
|
||||
char filename[MAX_LOGFILENAMESIZE];
|
||||
FILE *fp;
|
||||
int numwrites;
|
||||
} logfile_t;
|
||||
|
||||
static logfile_t logfile;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void Log_Open(char *filename)
|
||||
{
|
||||
if (!LibVarValue("log", "0")) return;
|
||||
if (!filename || !strlen(filename))
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "openlog <filename>\n");
|
||||
return;
|
||||
} //end if
|
||||
if (logfile.fp)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "log file %s is already opened\n", logfile.filename);
|
||||
return;
|
||||
} //end if
|
||||
logfile.fp = fopen(filename, "wb");
|
||||
if (!logfile.fp)
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "can't open the log file %s\n", filename);
|
||||
return;
|
||||
} //end if
|
||||
strncpy(logfile.filename, filename, MAX_LOGFILENAMESIZE);
|
||||
botimport.Print(PRT_MESSAGE, "Opened log %s\n", logfile.filename);
|
||||
} //end of the function Log_Create
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void Log_Close(void)
|
||||
{
|
||||
if (!logfile.fp) return;
|
||||
if (fclose(logfile.fp))
|
||||
{
|
||||
botimport.Print(PRT_ERROR, "can't close log file %s\n", logfile.filename);
|
||||
return;
|
||||
} //end if
|
||||
logfile.fp = NULL;
|
||||
botimport.Print(PRT_MESSAGE, "Closed log %s\n", logfile.filename);
|
||||
} //end of the function Log_Close
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void Log_Shutdown(void)
|
||||
{
|
||||
if (logfile.fp) Log_Close();
|
||||
} //end of the function Log_Shutdown
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void QDECL Log_Write(char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (!logfile.fp) return;
|
||||
va_start(ap, fmt);
|
||||
vfprintf(logfile.fp, fmt, ap);
|
||||
va_end(ap);
|
||||
//fprintf(logfile.fp, "\r\n");
|
||||
fflush(logfile.fp);
|
||||
} //end of the function Log_Write
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void QDECL Log_WriteTimeStamped(char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (!logfile.fp) return;
|
||||
fprintf(logfile.fp, "%d %02d:%02d:%02d:%02d ",
|
||||
logfile.numwrites,
|
||||
(int) (botlibglobals.time / 60 / 60),
|
||||
(int) (botlibglobals.time / 60),
|
||||
(int) (botlibglobals.time),
|
||||
(int) ((int) (botlibglobals.time * 100)) -
|
||||
((int) botlibglobals.time) * 100);
|
||||
va_start(ap, fmt);
|
||||
vfprintf(logfile.fp, fmt, ap);
|
||||
va_end(ap);
|
||||
fprintf(logfile.fp, "\r\n");
|
||||
logfile.numwrites++;
|
||||
fflush(logfile.fp);
|
||||
} //end of the function Log_Write
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
FILE *Log_FilePointer(void)
|
||||
{
|
||||
return logfile.fp;
|
||||
} //end of the function Log_FilePointer
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void Log_Flush(void)
|
||||
{
|
||||
if (logfile.fp) fflush(logfile.fp);
|
||||
} //end of the function Log_Flush
|
||||
|
46
tools/quake3/bspc/deps/botlib/l_log.h
Normal file
46
tools/quake3/bspc/deps/botlib/l_log.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: l_log.h
|
||||
*
|
||||
* desc: log file
|
||||
*
|
||||
* $Archive: /source/code/botlib/l_log.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//open a log file
|
||||
void Log_Open(char *filename);
|
||||
//close the current log file
|
||||
void Log_Close(void);
|
||||
//close log file if present
|
||||
void Log_Shutdown(void);
|
||||
//write to the current opened log file
|
||||
void QDECL Log_Write(char *fmt, ...);
|
||||
//write to the current opened log file with a time stamp
|
||||
void QDECL Log_WriteTimeStamped(char *fmt, ...);
|
||||
//returns a pointer to the log file
|
||||
FILE *Log_FilePointer(void);
|
||||
//flush log file
|
||||
void Log_Flush(void);
|
||||
|
463
tools/quake3/bspc/deps/botlib/l_memory.c
Normal file
463
tools/quake3/bspc/deps/botlib/l_memory.c
Normal file
|
@ -0,0 +1,463 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: l_memory.c
|
||||
*
|
||||
* desc: memory allocation
|
||||
*
|
||||
* $Archive: /MissionPack/code/botlib/l_memory.c $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "botlib.h"
|
||||
#include "l_log.h"
|
||||
#include "be_interface.h"
|
||||
|
||||
//#define MEMDEBUG
|
||||
//#define MEMORYMANEGER
|
||||
|
||||
#define MEM_ID 0x12345678l
|
||||
#define HUNK_ID 0x87654321l
|
||||
|
||||
int allocatedmemory;
|
||||
int totalmemorysize;
|
||||
int numblocks;
|
||||
|
||||
#ifdef MEMORYMANEGER
|
||||
|
||||
typedef struct memoryblock_s
|
||||
{
|
||||
unsigned long int id;
|
||||
void *ptr;
|
||||
int size;
|
||||
#ifdef MEMDEBUG
|
||||
char *label;
|
||||
char *file;
|
||||
int line;
|
||||
#endif //MEMDEBUG
|
||||
struct memoryblock_s *prev, *next;
|
||||
} memoryblock_t;
|
||||
|
||||
memoryblock_t *memory;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void LinkMemoryBlock(memoryblock_t *block)
|
||||
{
|
||||
block->prev = NULL;
|
||||
block->next = memory;
|
||||
if (memory) memory->prev = block;
|
||||
memory = block;
|
||||
} //end of the function LinkMemoryBlock
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void UnlinkMemoryBlock(memoryblock_t *block)
|
||||
{
|
||||
if (block->prev) block->prev->next = block->next;
|
||||
else memory = block->next;
|
||||
if (block->next) block->next->prev = block->prev;
|
||||
} //end of the function UnlinkMemoryBlock
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
#ifdef MEMDEBUG
|
||||
void *GetMemoryDebug(unsigned long size, char *label, char *file, int line)
|
||||
#else
|
||||
void *GetMemory(unsigned long size)
|
||||
#endif //MEMDEBUG
|
||||
{
|
||||
void *ptr;
|
||||
memoryblock_t *block;
|
||||
assert(botimport.GetMemory); // bk001129 - was NULL'ed
|
||||
ptr = botimport.GetMemory(size + sizeof(memoryblock_t));
|
||||
block = (memoryblock_t *) ptr;
|
||||
block->id = MEM_ID;
|
||||
block->ptr = (char *) ptr + sizeof(memoryblock_t);
|
||||
block->size = size + sizeof(memoryblock_t);
|
||||
#ifdef MEMDEBUG
|
||||
block->label = label;
|
||||
block->file = file;
|
||||
block->line = line;
|
||||
#endif //MEMDEBUG
|
||||
LinkMemoryBlock(block);
|
||||
allocatedmemory += block->size;
|
||||
totalmemorysize += block->size + sizeof(memoryblock_t);
|
||||
numblocks++;
|
||||
return block->ptr;
|
||||
} //end of the function GetMemoryDebug
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
#ifdef MEMDEBUG
|
||||
void *GetClearedMemoryDebug(unsigned long size, char *label, char *file, int line)
|
||||
#else
|
||||
void *GetClearedMemory(unsigned long size)
|
||||
#endif //MEMDEBUG
|
||||
{
|
||||
void *ptr;
|
||||
#ifdef MEMDEBUG
|
||||
ptr = GetMemoryDebug(size, label, file, line);
|
||||
#else
|
||||
ptr = GetMemory(size);
|
||||
#endif //MEMDEBUG
|
||||
Com_Memset(ptr, 0, size);
|
||||
return ptr;
|
||||
} //end of the function GetClearedMemory
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
#ifdef MEMDEBUG
|
||||
void *GetHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
|
||||
#else
|
||||
void *GetHunkMemory(unsigned long size)
|
||||
#endif //MEMDEBUG
|
||||
{
|
||||
void *ptr;
|
||||
memoryblock_t *block;
|
||||
|
||||
ptr = botimport.HunkAlloc(size + sizeof(memoryblock_t));
|
||||
block = (memoryblock_t *) ptr;
|
||||
block->id = HUNK_ID;
|
||||
block->ptr = (char *) ptr + sizeof(memoryblock_t);
|
||||
block->size = size + sizeof(memoryblock_t);
|
||||
#ifdef MEMDEBUG
|
||||
block->label = label;
|
||||
block->file = file;
|
||||
block->line = line;
|
||||
#endif //MEMDEBUG
|
||||
LinkMemoryBlock(block);
|
||||
allocatedmemory += block->size;
|
||||
totalmemorysize += block->size + sizeof(memoryblock_t);
|
||||
numblocks++;
|
||||
return block->ptr;
|
||||
} //end of the function GetHunkMemoryDebug
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
#ifdef MEMDEBUG
|
||||
void *GetClearedHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
|
||||
#else
|
||||
void *GetClearedHunkMemory(unsigned long size)
|
||||
#endif //MEMDEBUG
|
||||
{
|
||||
void *ptr;
|
||||
#ifdef MEMDEBUG
|
||||
ptr = GetHunkMemoryDebug(size, label, file, line);
|
||||
#else
|
||||
ptr = GetHunkMemory(size);
|
||||
#endif //MEMDEBUG
|
||||
Com_Memset(ptr, 0, size);
|
||||
return ptr;
|
||||
} //end of the function GetClearedHunkMemory
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
memoryblock_t *BlockFromPointer(void *ptr, char *str)
|
||||
{
|
||||
memoryblock_t *block;
|
||||
|
||||
if (!ptr)
|
||||
{
|
||||
#ifdef MEMDEBUG
|
||||
//char *crash = (char *) NULL;
|
||||
//crash[0] = 1;
|
||||
botimport.Print(PRT_FATAL, "%s: NULL pointer\n", str);
|
||||
#endif // MEMDEBUG
|
||||
return NULL;
|
||||
} //end if
|
||||
block = (memoryblock_t *) ((char *) ptr - sizeof(memoryblock_t));
|
||||
if (block->id != MEM_ID && block->id != HUNK_ID)
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "%s: invalid memory block\n", str);
|
||||
return NULL;
|
||||
} //end if
|
||||
if (block->ptr != ptr)
|
||||
{
|
||||
botimport.Print(PRT_FATAL, "%s: memory block pointer invalid\n", str);
|
||||
return NULL;
|
||||
} //end if
|
||||
return block;
|
||||
} //end of the function BlockFromPointer
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void FreeMemory(void *ptr)
|
||||
{
|
||||
memoryblock_t *block;
|
||||
|
||||
block = BlockFromPointer(ptr, "FreeMemory");
|
||||
if (!block) return;
|
||||
UnlinkMemoryBlock(block);
|
||||
allocatedmemory -= block->size;
|
||||
totalmemorysize -= block->size + sizeof(memoryblock_t);
|
||||
numblocks--;
|
||||
//
|
||||
if (block->id == MEM_ID)
|
||||
{
|
||||
botimport.FreeMemory(block);
|
||||
} //end if
|
||||
} //end of the function FreeMemory
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AvailableMemory(void)
|
||||
{
|
||||
return botimport.AvailableMemory();
|
||||
} //end of the function AvailableMemory
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int MemoryByteSize(void *ptr)
|
||||
{
|
||||
memoryblock_t *block;
|
||||
|
||||
block = BlockFromPointer(ptr, "MemoryByteSize");
|
||||
if (!block) return 0;
|
||||
return block->size;
|
||||
} //end of the function MemoryByteSize
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void PrintUsedMemorySize(void)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "total allocated memory: %d KB\n", allocatedmemory >> 10);
|
||||
botimport.Print(PRT_MESSAGE, "total botlib memory: %d KB\n", totalmemorysize >> 10);
|
||||
botimport.Print(PRT_MESSAGE, "total memory blocks: %d\n", numblocks);
|
||||
} //end of the function PrintUsedMemorySize
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void PrintMemoryLabels(void)
|
||||
{
|
||||
memoryblock_t *block;
|
||||
int i;
|
||||
|
||||
PrintUsedMemorySize();
|
||||
i = 0;
|
||||
Log_Write("============= Botlib memory log ==============\r\n");
|
||||
Log_Write("\r\n");
|
||||
for (block = memory; block; block = block->next)
|
||||
{
|
||||
#ifdef MEMDEBUG
|
||||
if (block->id == HUNK_ID)
|
||||
{
|
||||
Log_Write("%6d, hunk %p, %8d: %24s line %6d: %s\r\n", i, block->ptr, block->size, block->file, block->line, block->label);
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
Log_Write("%6d, %p, %8d: %24s line %6d: %s\r\n", i, block->ptr, block->size, block->file, block->line, block->label);
|
||||
} //end else
|
||||
#endif //MEMDEBUG
|
||||
i++;
|
||||
} //end for
|
||||
} //end of the function PrintMemoryLabels
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void DumpMemory(void)
|
||||
{
|
||||
memoryblock_t *block;
|
||||
|
||||
for (block = memory; block; block = memory)
|
||||
{
|
||||
FreeMemory(block->ptr);
|
||||
} //end for
|
||||
totalmemorysize = 0;
|
||||
allocatedmemory = 0;
|
||||
} //end of the function DumpMemory
|
||||
|
||||
#else
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
#ifdef MEMDEBUG
|
||||
void *GetMemoryDebug(unsigned long size, char *label, char *file, int line)
|
||||
#else
|
||||
void *GetMemory(unsigned long size)
|
||||
#endif //MEMDEBUG
|
||||
{
|
||||
void *ptr;
|
||||
unsigned long int *memid;
|
||||
|
||||
ptr = botimport.GetMemory(size + sizeof(unsigned long int));
|
||||
if (!ptr) return NULL;
|
||||
memid = (unsigned long int *) ptr;
|
||||
*memid = MEM_ID;
|
||||
return (unsigned long int *) ((char *) ptr + sizeof(unsigned long int));
|
||||
} //end of the function GetMemory
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
#ifdef MEMDEBUG
|
||||
void *GetClearedMemoryDebug(unsigned long size, char *label, char *file, int line)
|
||||
#else
|
||||
void *GetClearedMemory(unsigned long size)
|
||||
#endif //MEMDEBUG
|
||||
{
|
||||
void *ptr;
|
||||
#ifdef MEMDEBUG
|
||||
ptr = GetMemoryDebug(size, label, file, line);
|
||||
#else
|
||||
ptr = GetMemory(size);
|
||||
#endif //MEMDEBUG
|
||||
Com_Memset(ptr, 0, size);
|
||||
return ptr;
|
||||
} //end of the function GetClearedMemory
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
#ifdef MEMDEBUG
|
||||
void *GetHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
|
||||
#else
|
||||
void *GetHunkMemory(unsigned long size)
|
||||
#endif //MEMDEBUG
|
||||
{
|
||||
void *ptr;
|
||||
unsigned long int *memid;
|
||||
|
||||
ptr = botimport.HunkAlloc(size + sizeof(unsigned long int));
|
||||
if (!ptr) return NULL;
|
||||
memid = (unsigned long int *) ptr;
|
||||
*memid = HUNK_ID;
|
||||
return (unsigned long int *) ((char *) ptr + sizeof(unsigned long int));
|
||||
} //end of the function GetHunkMemory
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
#ifdef MEMDEBUG
|
||||
void *GetClearedHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
|
||||
#else
|
||||
void *GetClearedHunkMemory(unsigned long size)
|
||||
#endif //MEMDEBUG
|
||||
{
|
||||
void *ptr;
|
||||
#ifdef MEMDEBUG
|
||||
ptr = GetHunkMemoryDebug(size, label, file, line);
|
||||
#else
|
||||
ptr = GetHunkMemory(size);
|
||||
#endif //MEMDEBUG
|
||||
Com_Memset(ptr, 0, size);
|
||||
return ptr;
|
||||
} //end of the function GetClearedHunkMemory
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void FreeMemory(void *ptr)
|
||||
{
|
||||
unsigned long int *memid;
|
||||
|
||||
memid = (unsigned long int *) ((char *) ptr - sizeof(unsigned long int));
|
||||
|
||||
if (*memid == MEM_ID)
|
||||
{
|
||||
botimport.FreeMemory(memid);
|
||||
} //end if
|
||||
} //end of the function FreeMemory
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AvailableMemory(void)
|
||||
{
|
||||
return botimport.AvailableMemory();
|
||||
} //end of the function AvailableMemory
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void PrintUsedMemorySize(void)
|
||||
{
|
||||
} //end of the function PrintUsedMemorySize
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void PrintMemoryLabels(void)
|
||||
{
|
||||
} //end of the function PrintMemoryLabels
|
||||
|
||||
#endif
|
76
tools/quake3/bspc/deps/botlib/l_memory.h
Normal file
76
tools/quake3/bspc/deps/botlib/l_memory.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: l_memory.h
|
||||
*
|
||||
* desc: memory management
|
||||
*
|
||||
* $Archive: /source/code/botlib/l_memory.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//#define MEMDEBUG
|
||||
|
||||
#ifdef MEMDEBUG
|
||||
#define GetMemory(size) GetMemoryDebug(size, #size, __FILE__, __LINE__);
|
||||
#define GetClearedMemory(size) GetClearedMemoryDebug(size, #size, __FILE__, __LINE__);
|
||||
//allocate a memory block of the given size
|
||||
void *GetMemoryDebug(unsigned long size, char *label, char *file, int line);
|
||||
//allocate a memory block of the given size and clear it
|
||||
void *GetClearedMemoryDebug(unsigned long size, char *label, char *file, int line);
|
||||
//
|
||||
#define GetHunkMemory(size) GetHunkMemoryDebug(size, #size, __FILE__, __LINE__);
|
||||
#define GetClearedHunkMemory(size) GetClearedHunkMemoryDebug(size, #size, __FILE__, __LINE__);
|
||||
//allocate a memory block of the given size
|
||||
void *GetHunkMemoryDebug(unsigned long size, char *label, char *file, int line);
|
||||
//allocate a memory block of the given size and clear it
|
||||
void *GetClearedHunkMemoryDebug(unsigned long size, char *label, char *file, int line);
|
||||
#else
|
||||
//allocate a memory block of the given size
|
||||
void *GetMemory(unsigned long size);
|
||||
//allocate a memory block of the given size and clear it
|
||||
void *GetClearedMemory(unsigned long size);
|
||||
//
|
||||
#ifdef BSPC
|
||||
#define GetHunkMemory GetMemory
|
||||
#define GetClearedHunkMemory GetClearedMemory
|
||||
#else
|
||||
//allocate a memory block of the given size
|
||||
void *GetHunkMemory(unsigned long size);
|
||||
//allocate a memory block of the given size and clear it
|
||||
void *GetClearedHunkMemory(unsigned long size);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//free the given memory block
|
||||
void FreeMemory(void *ptr);
|
||||
//returns the amount available memory
|
||||
int AvailableMemory(void);
|
||||
//prints the total used memory size
|
||||
void PrintUsedMemorySize(void);
|
||||
//print all memory blocks with label
|
||||
void PrintMemoryLabels(void);
|
||||
//returns the size of the memory block in bytes
|
||||
int MemoryByteSize(void *ptr);
|
||||
//free all allocated memory
|
||||
void DumpMemory(void);
|
3233
tools/quake3/bspc/deps/botlib/l_precomp.c
Normal file
3233
tools/quake3/bspc/deps/botlib/l_precomp.c
Normal file
File diff suppressed because it is too large
Load diff
180
tools/quake3/bspc/deps/botlib/l_precomp.h
Normal file
180
tools/quake3/bspc/deps/botlib/l_precomp.h
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: l_precomp.h
|
||||
*
|
||||
* desc: pre compiler
|
||||
*
|
||||
* $Archive: /source/code/botlib/l_precomp.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAX_PATH
|
||||
#define MAX_PATH MAX_QPATH
|
||||
#endif
|
||||
|
||||
#ifndef PATH_SEPERATORSTR
|
||||
#if defined(WIN32)|defined(_WIN32)|defined(__NT__)|defined(__WINDOWS__)|defined(__WINDOWS_386__)
|
||||
#define PATHSEPERATOR_STR "\\"
|
||||
#else
|
||||
#define PATHSEPERATOR_STR "/"
|
||||
#endif
|
||||
#endif
|
||||
#ifndef PATH_SEPERATORCHAR
|
||||
#if defined(WIN32)|defined(_WIN32)|defined(__NT__)|defined(__WINDOWS__)|defined(__WINDOWS_386__)
|
||||
#define PATHSEPERATOR_CHAR '\\'
|
||||
#else
|
||||
#define PATHSEPERATOR_CHAR '/'
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(BSPC) && !defined(QDECL)
|
||||
#define QDECL
|
||||
#endif
|
||||
|
||||
|
||||
#define DEFINE_FIXED 0x0001
|
||||
|
||||
#define BUILTIN_LINE 1
|
||||
#define BUILTIN_FILE 2
|
||||
#define BUILTIN_DATE 3
|
||||
#define BUILTIN_TIME 4
|
||||
#define BUILTIN_STDC 5
|
||||
|
||||
#define INDENT_IF 0x0001
|
||||
#define INDENT_ELSE 0x0002
|
||||
#define INDENT_ELIF 0x0004
|
||||
#define INDENT_IFDEF 0x0008
|
||||
#define INDENT_IFNDEF 0x0010
|
||||
|
||||
//macro definitions
|
||||
typedef struct define_s
|
||||
{
|
||||
char *name; //define name
|
||||
int flags; //define flags
|
||||
int builtin; // > 0 if builtin define
|
||||
int numparms; //number of define parameters
|
||||
token_t *parms; //define parameters
|
||||
token_t *tokens; //macro tokens (possibly containing parm tokens)
|
||||
struct define_s *next; //next defined macro in a list
|
||||
struct define_s *hashnext; //next define in the hash chain
|
||||
} define_t;
|
||||
|
||||
//indents
|
||||
//used for conditional compilation directives:
|
||||
//#if, #else, #elif, #ifdef, #ifndef
|
||||
typedef struct indent_s
|
||||
{
|
||||
int type; //indent type
|
||||
int skip; //true if skipping current indent
|
||||
script_t *script; //script the indent was in
|
||||
struct indent_s *next; //next indent on the indent stack
|
||||
} indent_t;
|
||||
|
||||
//source file
|
||||
typedef struct source_s
|
||||
{
|
||||
char filename[1024]; //file name of the script
|
||||
char includepath[1024]; //path to include files
|
||||
punctuation_t *punctuations; //punctuations to use
|
||||
script_t *scriptstack; //stack with scripts of the source
|
||||
token_t *tokens; //tokens to read first
|
||||
define_t *defines; //list with macro definitions
|
||||
define_t **definehash; //hash chain with defines
|
||||
indent_t *indentstack; //stack with indents
|
||||
int skip; // > 0 if skipping conditional code
|
||||
token_t token; //last read token
|
||||
} source_t;
|
||||
|
||||
|
||||
//read a token from the source
|
||||
int PC_ReadToken(source_t *source, token_t *token);
|
||||
//expect a certain token
|
||||
int PC_ExpectTokenString(source_t *source, char *string);
|
||||
//expect a certain token type
|
||||
int PC_ExpectTokenType(source_t *source, int type, int subtype, token_t *token);
|
||||
//expect a token
|
||||
int PC_ExpectAnyToken(source_t *source, token_t *token);
|
||||
//returns true when the token is available
|
||||
int PC_CheckTokenString(source_t *source, char *string);
|
||||
//returns true an reads the token when a token with the given type is available
|
||||
int PC_CheckTokenType(source_t *source, int type, int subtype, token_t *token);
|
||||
//skip tokens until the given token string is read
|
||||
int PC_SkipUntilString(source_t *source, char *string);
|
||||
//unread the last token read from the script
|
||||
void PC_UnreadLastToken(source_t *source);
|
||||
//unread the given token
|
||||
void PC_UnreadToken(source_t *source, token_t *token);
|
||||
//read a token only if on the same line, lines are concatenated with a slash
|
||||
int PC_ReadLine(source_t *source, token_t *token);
|
||||
//returns true if there was a white space in front of the token
|
||||
int PC_WhiteSpaceBeforeToken(token_t *token);
|
||||
//add a define to the source
|
||||
int PC_AddDefine(source_t *source, char *string);
|
||||
//add a globals define that will be added to all opened sources
|
||||
int PC_AddGlobalDefine(char *string);
|
||||
//remove the given global define
|
||||
int PC_RemoveGlobalDefine(char *name);
|
||||
//remove all globals defines
|
||||
void PC_RemoveAllGlobalDefines(void);
|
||||
//add builtin defines
|
||||
void PC_AddBuiltinDefines(source_t *source);
|
||||
//set the source include path
|
||||
void PC_SetIncludePath(source_t *source, char *path);
|
||||
//set the punction set
|
||||
void PC_SetPunctuations(source_t *source, punctuation_t *p);
|
||||
//set the base folder to load files from
|
||||
void PC_SetBaseFolder(char *path);
|
||||
//load a source file
|
||||
source_t *LoadSourceFile(const char *filename);
|
||||
//load a source from memory
|
||||
source_t *LoadSourceMemory(char *ptr, int length, char *name);
|
||||
//free the given source
|
||||
void FreeSource(source_t *source);
|
||||
//print a source error
|
||||
void QDECL SourceError(source_t *source, char *str, ...);
|
||||
//print a source warning
|
||||
void QDECL SourceWarning(source_t *source, char *str, ...);
|
||||
|
||||
#ifdef BSPC
|
||||
// some of BSPC source does include game/qcommon/q_shared.h and some does not
|
||||
// we define pc_token_s pc_token_t if needed (yes, it's ugly)
|
||||
#ifndef __Q_SHARED_H
|
||||
#define MAX_TOKENLENGTH 1024
|
||||
typedef struct pc_token_s
|
||||
{
|
||||
int type;
|
||||
int subtype;
|
||||
int intvalue;
|
||||
float floatvalue;
|
||||
char string[MAX_TOKENLENGTH];
|
||||
} pc_token_t;
|
||||
#endif //!_Q_SHARED_H
|
||||
#endif //BSPC
|
||||
|
||||
//
|
||||
int PC_LoadSourceHandle(const char *filename);
|
||||
int PC_FreeSourceHandle(int handle);
|
||||
int PC_ReadTokenHandle(int handle, pc_token_t *pc_token);
|
||||
int PC_SourceFileAndLine(int handle, char *filename, int *line);
|
||||
void PC_CheckOpenSourceHandles(void);
|
1441
tools/quake3/bspc/deps/botlib/l_script.c
Normal file
1441
tools/quake3/bspc/deps/botlib/l_script.c
Normal file
File diff suppressed because it is too large
Load diff
247
tools/quake3/bspc/deps/botlib/l_script.h
Normal file
247
tools/quake3/bspc/deps/botlib/l_script.h
Normal file
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: l_script.h
|
||||
*
|
||||
* desc: lexicographical parser
|
||||
*
|
||||
* $Archive: /source/code/botlib/l_script.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//undef if binary numbers of the form 0b... or 0B... are not allowed
|
||||
#define BINARYNUMBERS
|
||||
//undef if not using the token.intvalue and token.floatvalue
|
||||
#define NUMBERVALUE
|
||||
//use dollar sign also as punctuation
|
||||
#define DOLLAR
|
||||
|
||||
//maximum token length
|
||||
#define MAX_TOKEN 1024
|
||||
|
||||
#if defined(BSPC) && !defined(QDECL)
|
||||
#define QDECL
|
||||
#endif
|
||||
|
||||
|
||||
//script flags
|
||||
#define SCFL_NOERRORS 0x0001
|
||||
#define SCFL_NOWARNINGS 0x0002
|
||||
#define SCFL_NOSTRINGWHITESPACES 0x0004
|
||||
#define SCFL_NOSTRINGESCAPECHARS 0x0008
|
||||
#define SCFL_PRIMITIVE 0x0010
|
||||
#define SCFL_NOBINARYNUMBERS 0x0020
|
||||
#define SCFL_NONUMBERVALUES 0x0040
|
||||
|
||||
//token types
|
||||
#define TT_STRING 1 // string
|
||||
#define TT_LITERAL 2 // literal
|
||||
#define TT_NUMBER 3 // number
|
||||
#define TT_NAME 4 // name
|
||||
#define TT_PUNCTUATION 5 // punctuation
|
||||
|
||||
//string sub type
|
||||
//---------------
|
||||
// the length of the string
|
||||
//literal sub type
|
||||
//----------------
|
||||
// the ASCII code of the literal
|
||||
//number sub type
|
||||
//---------------
|
||||
#define TT_DECIMAL 0x0008 // decimal number
|
||||
#define TT_HEX 0x0100 // hexadecimal number
|
||||
#define TT_OCTAL 0x0200 // octal number
|
||||
#ifdef BINARYNUMBERS
|
||||
#define TT_BINARY 0x0400 // binary number
|
||||
#endif //BINARYNUMBERS
|
||||
#define TT_FLOAT 0x0800 // floating point number
|
||||
#define TT_INTEGER 0x1000 // integer number
|
||||
#define TT_LONG 0x2000 // long number
|
||||
#define TT_UNSIGNED 0x4000 // unsigned number
|
||||
//punctuation sub type
|
||||
//--------------------
|
||||
#define P_RSHIFT_ASSIGN 1
|
||||
#define P_LSHIFT_ASSIGN 2
|
||||
#define P_PARMS 3
|
||||
#define P_PRECOMPMERGE 4
|
||||
|
||||
#define P_LOGIC_AND 5
|
||||
#define P_LOGIC_OR 6
|
||||
#define P_LOGIC_GEQ 7
|
||||
#define P_LOGIC_LEQ 8
|
||||
#define P_LOGIC_EQ 9
|
||||
#define P_LOGIC_UNEQ 10
|
||||
|
||||
#define P_MUL_ASSIGN 11
|
||||
#define P_DIV_ASSIGN 12
|
||||
#define P_MOD_ASSIGN 13
|
||||
#define P_ADD_ASSIGN 14
|
||||
#define P_SUB_ASSIGN 15
|
||||
#define P_INC 16
|
||||
#define P_DEC 17
|
||||
|
||||
#define P_BIN_AND_ASSIGN 18
|
||||
#define P_BIN_OR_ASSIGN 19
|
||||
#define P_BIN_XOR_ASSIGN 20
|
||||
#define P_RSHIFT 21
|
||||
#define P_LSHIFT 22
|
||||
|
||||
#define P_POINTERREF 23
|
||||
#define P_CPP1 24
|
||||
#define P_CPP2 25
|
||||
#define P_MUL 26
|
||||
#define P_DIV 27
|
||||
#define P_MOD 28
|
||||
#define P_ADD 29
|
||||
#define P_SUB 30
|
||||
#define P_ASSIGN 31
|
||||
|
||||
#define P_BIN_AND 32
|
||||
#define P_BIN_OR 33
|
||||
#define P_BIN_XOR 34
|
||||
#define P_BIN_NOT 35
|
||||
|
||||
#define P_LOGIC_NOT 36
|
||||
#define P_LOGIC_GREATER 37
|
||||
#define P_LOGIC_LESS 38
|
||||
|
||||
#define P_REF 39
|
||||
#define P_COMMA 40
|
||||
#define P_SEMICOLON 41
|
||||
#define P_COLON 42
|
||||
#define P_QUESTIONMARK 43
|
||||
|
||||
#define P_PARENTHESESOPEN 44
|
||||
#define P_PARENTHESESCLOSE 45
|
||||
#define P_BRACEOPEN 46
|
||||
#define P_BRACECLOSE 47
|
||||
#define P_SQBRACKETOPEN 48
|
||||
#define P_SQBRACKETCLOSE 49
|
||||
#define P_BACKSLASH 50
|
||||
|
||||
#define P_PRECOMP 51
|
||||
#define P_DOLLAR 52
|
||||
//name sub type
|
||||
//-------------
|
||||
// the length of the name
|
||||
|
||||
//punctuation
|
||||
typedef struct punctuation_s
|
||||
{
|
||||
char *p; //punctuation character(s)
|
||||
int n; //punctuation indication
|
||||
struct punctuation_s *next; //next punctuation
|
||||
} punctuation_t;
|
||||
|
||||
//token
|
||||
typedef struct token_s
|
||||
{
|
||||
char string[MAX_TOKEN]; //available token
|
||||
int type; //last read token type
|
||||
int subtype; //last read token sub type
|
||||
#ifdef NUMBERVALUE
|
||||
unsigned long int intvalue; //integer value
|
||||
float floatvalue; //floating point value
|
||||
#endif //NUMBERVALUE
|
||||
char *whitespace_p; //start of white space before token
|
||||
char *endwhitespace_p; //start of white space before token
|
||||
int line; //line the token was on
|
||||
int linescrossed; //lines crossed in white space
|
||||
struct token_s *next; //next token in chain
|
||||
} token_t;
|
||||
|
||||
//script file
|
||||
typedef struct script_s
|
||||
{
|
||||
char filename[1024]; //file name of the script
|
||||
char *buffer; //buffer containing the script
|
||||
char *script_p; //current pointer in the script
|
||||
char *end_p; //pointer to the end of the script
|
||||
char *lastscript_p; //script pointer before reading token
|
||||
char *whitespace_p; //begin of the white space
|
||||
char *endwhitespace_p; //end of the white space
|
||||
int length; //length of the script in bytes
|
||||
int line; //current line in script
|
||||
int lastline; //line before reading token
|
||||
int tokenavailable; //set by UnreadLastToken
|
||||
int flags; //several script flags
|
||||
punctuation_t *punctuations; //the punctuations used in the script
|
||||
punctuation_t **punctuationtable;
|
||||
token_t token; //available token
|
||||
struct script_s *next; //next script in a chain
|
||||
} script_t;
|
||||
|
||||
//read a token from the script
|
||||
int PS_ReadToken(script_t *script, token_t *token);
|
||||
//expect a certain token
|
||||
int PS_ExpectTokenString(script_t *script, char *string);
|
||||
//expect a certain token type
|
||||
int PS_ExpectTokenType(script_t *script, int type, int subtype, token_t *token);
|
||||
//expect a token
|
||||
int PS_ExpectAnyToken(script_t *script, token_t *token);
|
||||
//returns true when the token is available
|
||||
int PS_CheckTokenString(script_t *script, char *string);
|
||||
//returns true an reads the token when a token with the given type is available
|
||||
int PS_CheckTokenType(script_t *script, int type, int subtype, token_t *token);
|
||||
//skip tokens until the given token string is read
|
||||
int PS_SkipUntilString(script_t *script, char *string);
|
||||
//unread the last token read from the script
|
||||
void PS_UnreadLastToken(script_t *script);
|
||||
//unread the given token
|
||||
void PS_UnreadToken(script_t *script, token_t *token);
|
||||
//returns the next character of the read white space, returns NULL if none
|
||||
char PS_NextWhiteSpaceChar(script_t *script);
|
||||
//remove any leading and trailing double quotes from the token
|
||||
void StripDoubleQuotes(char *string);
|
||||
//remove any leading and trailing single quotes from the token
|
||||
void StripSingleQuotes(char *string);
|
||||
//read a possible signed integer
|
||||
signed long int ReadSignedInt(script_t *script);
|
||||
//read a possible signed floating point number
|
||||
float ReadSignedFloat(script_t *script);
|
||||
//set an array with punctuations, NULL restores default C/C++ set
|
||||
void SetScriptPunctuations(script_t *script, punctuation_t *p);
|
||||
//set script flags
|
||||
void SetScriptFlags(script_t *script, int flags);
|
||||
//get script flags
|
||||
int GetScriptFlags(script_t *script);
|
||||
//reset a script
|
||||
void ResetScript(script_t *script);
|
||||
//returns true if at the end of the script
|
||||
int EndOfScript(script_t *script);
|
||||
//returns a pointer to the punctuation with the given number
|
||||
char *PunctuationFromNum(script_t *script, int num);
|
||||
//load a script from the given file at the given offset with the given length
|
||||
script_t *LoadScriptFile(const char *filename);
|
||||
//load a script from the given memory with the given length
|
||||
script_t *LoadScriptMemory(char *ptr, int length, char *name);
|
||||
//free a script
|
||||
void FreeScript(script_t *script);
|
||||
//set the base folder to load files from
|
||||
void PS_SetBaseFolder(char *path);
|
||||
//print a script error with filename and line number
|
||||
void QDECL ScriptError(script_t *script, char *str, ...);
|
||||
//print a script warning with filename and line number
|
||||
void QDECL ScriptWarning(script_t *script, char *str, ...);
|
||||
|
||||
|
462
tools/quake3/bspc/deps/botlib/l_struct.c
Normal file
462
tools/quake3/bspc/deps/botlib/l_struct.c
Normal file
|
@ -0,0 +1,462 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: l_struct.c
|
||||
*
|
||||
* desc: structure reading / writing
|
||||
*
|
||||
* $Archive: /MissionPack/CODE/botlib/l_struct.c $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef BOTLIB
|
||||
#include "qcommon/q_shared.h"
|
||||
#include "botlib.h" //for the include of be_interface.h
|
||||
#include "l_script.h"
|
||||
#include "l_precomp.h"
|
||||
#include "l_struct.h"
|
||||
#include "l_utils.h"
|
||||
#include "be_interface.h"
|
||||
#endif //BOTLIB
|
||||
|
||||
#ifdef BSPC
|
||||
//include files for usage in the BSP Converter
|
||||
#include "../../qbsp.h"
|
||||
#include "l_log.h"
|
||||
#include "../../l_mem.h"
|
||||
#include "l_precomp.h"
|
||||
#include "l_struct.h"
|
||||
|
||||
#define qtrue true
|
||||
#define qfalse false
|
||||
#endif //BSPC
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
fielddef_t *FindField(fielddef_t *defs, char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; defs[i].name; i++)
|
||||
{
|
||||
if (!strcmp(defs[i].name, name)) return &defs[i];
|
||||
} //end for
|
||||
return NULL;
|
||||
} //end of the function FindField
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean ReadNumber(source_t *source, fielddef_t *fd, void *p)
|
||||
{
|
||||
token_t token;
|
||||
int negative = qfalse;
|
||||
long int intval, intmin = 0, intmax = 0;
|
||||
double floatval;
|
||||
|
||||
if (!PC_ExpectAnyToken(source, &token)) return 0;
|
||||
|
||||
//check for minus sign
|
||||
if (token.type == TT_PUNCTUATION)
|
||||
{
|
||||
if (fd->type & FT_UNSIGNED)
|
||||
{
|
||||
SourceError(source, "expected unsigned value, found %s", token.string);
|
||||
return 0;
|
||||
} //end if
|
||||
//if not a minus sign
|
||||
if (strcmp(token.string, "-"))
|
||||
{
|
||||
SourceError(source, "unexpected punctuation %s", token.string);
|
||||
return 0;
|
||||
} //end if
|
||||
negative = qtrue;
|
||||
//read the number
|
||||
if (!PC_ExpectAnyToken(source, &token)) return 0;
|
||||
} //end if
|
||||
//check if it is a number
|
||||
if (token.type != TT_NUMBER)
|
||||
{
|
||||
SourceError(source, "expected number, found %s", token.string);
|
||||
return 0;
|
||||
} //end if
|
||||
//check for a float value
|
||||
if (token.subtype & TT_FLOAT)
|
||||
{
|
||||
if ((fd->type & FT_TYPE) != FT_FLOAT)
|
||||
{
|
||||
SourceError(source, "unexpected float");
|
||||
return 0;
|
||||
} //end if
|
||||
floatval = token.floatvalue;
|
||||
if (negative) floatval = -floatval;
|
||||
if (fd->type & FT_BOUNDED)
|
||||
{
|
||||
if (floatval < fd->floatmin || floatval > fd->floatmax)
|
||||
{
|
||||
SourceError(source, "float out of range [%f, %f]", fd->floatmin, fd->floatmax);
|
||||
return 0;
|
||||
} //end if
|
||||
} //end if
|
||||
*(float *) p = (float) floatval;
|
||||
return 1;
|
||||
} //end if
|
||||
//
|
||||
intval = token.intvalue;
|
||||
if (negative) intval = -intval;
|
||||
//check bounds
|
||||
if ((fd->type & FT_TYPE) == FT_CHAR)
|
||||
{
|
||||
if (fd->type & FT_UNSIGNED) {intmin = 0; intmax = 255;}
|
||||
else {intmin = -128; intmax = 127;}
|
||||
} //end if
|
||||
if ((fd->type & FT_TYPE) == FT_INT)
|
||||
{
|
||||
if (fd->type & FT_UNSIGNED) {intmin = 0; intmax = 65535;}
|
||||
else {intmin = -32768; intmax = 32767;}
|
||||
} //end else if
|
||||
if ((fd->type & FT_TYPE) == FT_CHAR || (fd->type & FT_TYPE) == FT_INT)
|
||||
{
|
||||
if (fd->type & FT_BOUNDED)
|
||||
{
|
||||
intmin = Maximum(intmin, fd->floatmin);
|
||||
intmax = Minimum(intmax, fd->floatmax);
|
||||
} //end if
|
||||
if (intval < intmin || intval > intmax)
|
||||
{
|
||||
SourceError(source, "value %d out of range [%d, %d]", intval, intmin, intmax);
|
||||
return 0;
|
||||
} //end if
|
||||
} //end if
|
||||
else if ((fd->type & FT_TYPE) == FT_FLOAT)
|
||||
{
|
||||
if (fd->type & FT_BOUNDED)
|
||||
{
|
||||
if (intval < fd->floatmin || intval > fd->floatmax)
|
||||
{
|
||||
SourceError(source, "value %d out of range [%f, %f]", intval, fd->floatmin, fd->floatmax);
|
||||
return 0;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end else if
|
||||
//store the value
|
||||
if ((fd->type & FT_TYPE) == FT_CHAR)
|
||||
{
|
||||
if (fd->type & FT_UNSIGNED) *(unsigned char *) p = (unsigned char) intval;
|
||||
else *(char *) p = (char) intval;
|
||||
} //end if
|
||||
else if ((fd->type & FT_TYPE) == FT_INT)
|
||||
{
|
||||
if (fd->type & FT_UNSIGNED) *(unsigned int *) p = (unsigned int) intval;
|
||||
else *(int *) p = (int) intval;
|
||||
} //end else
|
||||
else if ((fd->type & FT_TYPE) == FT_FLOAT)
|
||||
{
|
||||
*(float *) p = (float) intval;
|
||||
} //end else
|
||||
return 1;
|
||||
} //end of the function ReadNumber
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean ReadChar(source_t *source, fielddef_t *fd, void *p)
|
||||
{
|
||||
token_t token;
|
||||
|
||||
if (!PC_ExpectAnyToken(source, &token)) return 0;
|
||||
|
||||
//take literals into account
|
||||
if (token.type == TT_LITERAL)
|
||||
{
|
||||
StripSingleQuotes(token.string);
|
||||
*(char *) p = token.string[0];
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
PC_UnreadLastToken(source);
|
||||
if (!ReadNumber(source, fd, p)) return 0;
|
||||
} //end if
|
||||
return 1;
|
||||
} //end of the function ReadChar
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int ReadString(source_t *source, fielddef_t *fd, void *p)
|
||||
{
|
||||
token_t token;
|
||||
|
||||
if (!PC_ExpectTokenType(source, TT_STRING, 0, &token)) return 0;
|
||||
//remove the double quotes
|
||||
StripDoubleQuotes(token.string);
|
||||
//copy the string
|
||||
strncpy((char *) p, token.string, MAX_STRINGFIELD);
|
||||
//make sure the string is closed with a zero
|
||||
((char *)p)[MAX_STRINGFIELD-1] = '\0';
|
||||
//
|
||||
return 1;
|
||||
} //end of the function ReadString
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int ReadStructure(source_t *source, structdef_t *def, char *structure)
|
||||
{
|
||||
token_t token;
|
||||
fielddef_t *fd;
|
||||
void *p;
|
||||
int num;
|
||||
|
||||
if (!PC_ExpectTokenString(source, "{")) return 0;
|
||||
while(1)
|
||||
{
|
||||
if (!PC_ExpectAnyToken(source, &token)) return qfalse;
|
||||
//if end of structure
|
||||
if (!strcmp(token.string, "}")) break;
|
||||
//find the field with the name
|
||||
fd = FindField(def->fields, token.string);
|
||||
if (!fd)
|
||||
{
|
||||
SourceError(source, "unknown structure field %s", token.string);
|
||||
return qfalse;
|
||||
} //end if
|
||||
if (fd->type & FT_ARRAY)
|
||||
{
|
||||
num = fd->maxarray;
|
||||
if (!PC_ExpectTokenString(source, "{")) return qfalse;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
num = 1;
|
||||
} //end else
|
||||
p = (void *)(structure + fd->offset);
|
||||
while (num-- > 0)
|
||||
{
|
||||
if (fd->type & FT_ARRAY)
|
||||
{
|
||||
if (PC_CheckTokenString(source, "}")) break;
|
||||
} //end if
|
||||
switch(fd->type & FT_TYPE)
|
||||
{
|
||||
case FT_CHAR:
|
||||
{
|
||||
if (!ReadChar(source, fd, p)) return qfalse;
|
||||
p = (char *) p + sizeof(char);
|
||||
break;
|
||||
} //end case
|
||||
case FT_INT:
|
||||
{
|
||||
if (!ReadNumber(source, fd, p)) return qfalse;
|
||||
p = (char *) p + sizeof(int);
|
||||
break;
|
||||
} //end case
|
||||
case FT_FLOAT:
|
||||
{
|
||||
if (!ReadNumber(source, fd, p)) return qfalse;
|
||||
p = (char *) p + sizeof(float);
|
||||
break;
|
||||
} //end case
|
||||
case FT_STRING:
|
||||
{
|
||||
if (!ReadString(source, fd, p)) return qfalse;
|
||||
p = (char *) p + MAX_STRINGFIELD;
|
||||
break;
|
||||
} //end case
|
||||
case FT_STRUCT:
|
||||
{
|
||||
if (!fd->substruct)
|
||||
{
|
||||
SourceError(source, "BUG: no sub structure defined");
|
||||
return qfalse;
|
||||
} //end if
|
||||
ReadStructure(source, fd->substruct, (char *) p);
|
||||
p = (char *) p + fd->substruct->size;
|
||||
break;
|
||||
} //end case
|
||||
} //end switch
|
||||
if (fd->type & FT_ARRAY)
|
||||
{
|
||||
if (!PC_ExpectAnyToken(source, &token)) return qfalse;
|
||||
if (!strcmp(token.string, "}")) break;
|
||||
if (strcmp(token.string, ","))
|
||||
{
|
||||
SourceError(source, "expected a comma, found %s", token.string);
|
||||
return qfalse;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end while
|
||||
} //end while
|
||||
return qtrue;
|
||||
} //end of the function ReadStructure
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int WriteIndent(FILE *fp, int indent)
|
||||
{
|
||||
while(indent-- > 0)
|
||||
{
|
||||
if (fprintf(fp, "\t") < 0) return qfalse;
|
||||
} //end while
|
||||
return qtrue;
|
||||
} //end of the function WriteIndent
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int WriteFloat(FILE *fp, float value)
|
||||
{
|
||||
char buf[128];
|
||||
int l;
|
||||
|
||||
sprintf(buf, "%f", value);
|
||||
l = strlen(buf);
|
||||
//strip any trailing zeros
|
||||
while(l-- > 1)
|
||||
{
|
||||
if (buf[l] != '0' && buf[l] != '.') break;
|
||||
if (buf[l] == '.')
|
||||
{
|
||||
buf[l] = 0;
|
||||
break;
|
||||
} //end if
|
||||
buf[l] = 0;
|
||||
} //end while
|
||||
//write the float to file
|
||||
if (fprintf(fp, "%s", buf) < 0) return 0;
|
||||
return 1;
|
||||
} //end of the function WriteFloat
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int WriteStructWithIndent(FILE *fp, structdef_t *def, char *structure, int indent)
|
||||
{
|
||||
int i, num;
|
||||
void *p;
|
||||
fielddef_t *fd;
|
||||
|
||||
if (!WriteIndent(fp, indent)) return qfalse;
|
||||
if (fprintf(fp, "{\r\n") < 0) return qfalse;
|
||||
|
||||
indent++;
|
||||
for (i = 0; def->fields[i].name; i++)
|
||||
{
|
||||
fd = &def->fields[i];
|
||||
if (!WriteIndent(fp, indent)) return qfalse;
|
||||
if (fprintf(fp, "%s\t", fd->name) < 0) return qfalse;
|
||||
p = (void *)(structure + fd->offset);
|
||||
if (fd->type & FT_ARRAY)
|
||||
{
|
||||
num = fd->maxarray;
|
||||
if (fprintf(fp, "{") < 0) return qfalse;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
num = 1;
|
||||
} //end else
|
||||
while(num-- > 0)
|
||||
{
|
||||
switch(fd->type & FT_TYPE)
|
||||
{
|
||||
case FT_CHAR:
|
||||
{
|
||||
if (fprintf(fp, "%d", *(char *) p) < 0) return qfalse;
|
||||
p = (char *) p + sizeof(char);
|
||||
break;
|
||||
} //end case
|
||||
case FT_INT:
|
||||
{
|
||||
if (fprintf(fp, "%d", *(int *) p) < 0) return qfalse;
|
||||
p = (char *) p + sizeof(int);
|
||||
break;
|
||||
} //end case
|
||||
case FT_FLOAT:
|
||||
{
|
||||
if (!WriteFloat(fp, *(float *)p)) return qfalse;
|
||||
p = (char *) p + sizeof(float);
|
||||
break;
|
||||
} //end case
|
||||
case FT_STRING:
|
||||
{
|
||||
if (fprintf(fp, "\"%s\"", (char *) p) < 0) return qfalse;
|
||||
p = (char *) p + MAX_STRINGFIELD;
|
||||
break;
|
||||
} //end case
|
||||
case FT_STRUCT:
|
||||
{
|
||||
if (!WriteStructWithIndent(fp, fd->substruct, structure, indent)) return qfalse;
|
||||
p = (char *) p + fd->substruct->size;
|
||||
break;
|
||||
} //end case
|
||||
} //end switch
|
||||
if (fd->type & FT_ARRAY)
|
||||
{
|
||||
if (num > 0)
|
||||
{
|
||||
if (fprintf(fp, ",") < 0) return qfalse;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if (fprintf(fp, "}") < 0) return qfalse;
|
||||
} //end else
|
||||
} //end if
|
||||
} //end while
|
||||
if (fprintf(fp, "\r\n") < 0) return qfalse;
|
||||
} //end for
|
||||
indent--;
|
||||
|
||||
if (!WriteIndent(fp, indent)) return qfalse;
|
||||
if (fprintf(fp, "}\r\n") < 0) return qfalse;
|
||||
return qtrue;
|
||||
} //end of the function WriteStructWithIndent
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int WriteStructure(FILE *fp, structdef_t *def, char *structure)
|
||||
{
|
||||
return WriteStructWithIndent(fp, def, structure, 0);
|
||||
} //end of the function WriteStructure
|
||||
|
76
tools/quake3/bspc/deps/botlib/l_struct.h
Normal file
76
tools/quake3/bspc/deps/botlib/l_struct.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: l_struct.h
|
||||
*
|
||||
* desc: structure reading/writing
|
||||
*
|
||||
* $Archive: /source/code/botlib/l_struct.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define MAX_STRINGFIELD 80
|
||||
//field types
|
||||
#define FT_CHAR 1 // char
|
||||
#define FT_INT 2 // int
|
||||
#define FT_FLOAT 3 // float
|
||||
#define FT_STRING 4 // char [MAX_STRINGFIELD]
|
||||
#define FT_STRUCT 6 // struct (sub structure)
|
||||
//type only mask
|
||||
#define FT_TYPE 0x00FF // only type, clear subtype
|
||||
//sub types
|
||||
#define FT_ARRAY 0x0100 // array of type
|
||||
#define FT_BOUNDED 0x0200 // bounded value
|
||||
#define FT_UNSIGNED 0x0400
|
||||
|
||||
//structure field definition
|
||||
typedef struct fielddef_s
|
||||
{
|
||||
char *name; //name of the field
|
||||
size_t offset; //offset in the structure
|
||||
int type; //type of the field
|
||||
//type specific fields
|
||||
int maxarray; //maximum array size
|
||||
float floatmin, floatmax; //float min and max
|
||||
struct structdef_s *substruct; //sub structure
|
||||
} fielddef_t;
|
||||
|
||||
//structure definition
|
||||
typedef struct structdef_s
|
||||
{
|
||||
int size;
|
||||
fielddef_t *fields;
|
||||
} structdef_t;
|
||||
|
||||
//read a structure from a script
|
||||
int ReadStructure(source_t *source, structdef_t *def, char *structure);
|
||||
//write a structure to a file
|
||||
int WriteStructure(FILE *fp, structdef_t *def, char *structure);
|
||||
//writes indents
|
||||
int WriteIndent(FILE *fp, int indent);
|
||||
//writes a float without traling zeros
|
||||
int WriteFloat(FILE *fp, float value);
|
||||
|
||||
|
37
tools/quake3/bspc/deps/botlib/l_utils.h
Normal file
37
tools/quake3/bspc/deps/botlib/l_utils.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* name: l_util.h
|
||||
*
|
||||
* desc: utils
|
||||
*
|
||||
* $Archive: /source/code/botlib/l_util.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define Vector2Angles(v,a) vectoangles(v,a)
|
||||
#ifndef MAX_PATH
|
||||
#define MAX_PATH MAX_QPATH
|
||||
#endif
|
||||
#define Maximum(x,y) (x > y ? x : y)
|
||||
#define Minimum(x,y) (x < y ? x : y)
|
55
tools/quake3/bspc/deps/botlib/lcc.mak
Normal file
55
tools/quake3/bspc/deps/botlib/lcc.mak
Normal file
|
@ -0,0 +1,55 @@
|
|||
#
|
||||
# Makefile for Gladiator Bot library: gladiator.dll
|
||||
# Intended for LCC-Win32
|
||||
#
|
||||
|
||||
CC=lcc
|
||||
CFLAGS=-DC_ONLY -o
|
||||
OBJS= be_aas_bspq2.obj \
|
||||
be_aas_bsphl.obj \
|
||||
be_aas_cluster.obj \
|
||||
be_aas_debug.obj \
|
||||
be_aas_entity.obj \
|
||||
be_aas_file.obj \
|
||||
be_aas_light.obj \
|
||||
be_aas_main.obj \
|
||||
be_aas_move.obj \
|
||||
be_aas_optimize.obj \
|
||||
be_aas_reach.obj \
|
||||
be_aas_route.obj \
|
||||
be_aas_routealt.obj \
|
||||
be_aas_sample.obj \
|
||||
be_aas_sound.obj \
|
||||
be_ai2_dm.obj \
|
||||
be_ai2_dmnet.obj \
|
||||
be_ai2_main.obj \
|
||||
be_ai_char.obj \
|
||||
be_ai_chat.obj \
|
||||
be_ai_goal.obj \
|
||||
be_ai_load.obj \
|
||||
be_ai_move.obj \
|
||||
be_ai_weap.obj \
|
||||
be_ai_weight.obj \
|
||||
be_ea.obj \
|
||||
be_interface.obj \
|
||||
l_crc.obj \
|
||||
l_libvar.obj \
|
||||
l_log.obj \
|
||||
l_memory.obj \
|
||||
l_precomp.obj \
|
||||
l_script.obj \
|
||||
l_struct.obj \
|
||||
l_utils.obj \
|
||||
q_shared.obj
|
||||
|
||||
all: gladiator.dll
|
||||
|
||||
gladiator.dll: $(OBJS)
|
||||
lcclnk -dll -entry GetBotAPI *.obj botlib.def -o gladiator.dll
|
||||
|
||||
clean:
|
||||
del *.obj gladiator.dll
|
||||
|
||||
%.obj: %.c
|
||||
$(CC) $(CFLAGS) $<
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue