Integrated RPG-X2 rpgxEF edition into the rpgxEF repo

... not quite content with where the project files lie but it is ok for
now.
... compiling works fine so far (only tested mingw32 right now)
This commit is contained in:
Walter Julius Hennecke 2012-08-04 12:54:37 +02:00
parent 21151db397
commit a39565b783
361 changed files with 319185 additions and 74746 deletions

225
Makefile
View file

@ -30,16 +30,16 @@ ifndef BUILD_STANDALONE
BUILD_STANDALONE =
endif
ifndef BUILD_CLIENT
BUILD_CLIENT =
BUILD_CLIENT = 0
endif
ifndef BUILD_CLIENT_SMP
BUILD_CLIENT_SMP =
endif
ifndef BUILD_SERVER
BUILD_SERVER =
BUILD_SERVER = 0
endif
ifndef BUILD_GAME_SO
BUILD_GAME_SO = 0
BUILD_GAME_SO = 1
endif
ifndef BUILD_GAME_QVM
BUILD_GAME_QVM = 0
@ -48,7 +48,7 @@ ifndef BUILD_BASEGAME
BUILD_BASEGAME =
endif
ifndef BUILD_MISSIONPACK
BUILD_MISSIONPACK=
BUILD_MISSIONPACK= 0
endif
BUILD_ELITEFORCE = 1
@ -125,7 +125,7 @@ endif
endif
ifndef BASEGAME
BASEGAME=baseq3
BASEGAME=rpgxEF
endif
ifndef BASEGAME_CFLAGS
@ -244,7 +244,7 @@ CGDIR=$(MOUNT_DIR)/cgame
BLIBDIR=$(MOUNT_DIR)/botlib
NDIR=$(MOUNT_DIR)/null
UIDIR=$(MOUNT_DIR)/ui
Q3UIDIR=$(MOUNT_DIR)/q3_ui
Q3UIDIR=$(MOUNT_DIR)/ui
JPDIR=$(MOUNT_DIR)/jpeg-8c
SPEEXDIR=$(MOUNT_DIR)/libspeex
ZDIR=$(MOUNT_DIR)/zlib
@ -384,7 +384,11 @@ ifneq (,$(findstring "$(PLATFORM)", "linux" "gnu_kfreebsd" "kfreebsd-gnu"))
SHLIBEXT=so
SHLIBCFLAGS=-fPIC -fvisibility=hidden
SHLIBLDFLAGS=-shared $(LDFLAGS)
SHLIBLDFLAGS=-shared $(LDFLAGS) -pthread
ifeq ($(VM_USE_SQL), 1)
SHLIBCFLAGS+=-DSQL
endif
THREAD_LIBS=-lpthread
LIBS=-ldl -lm
@ -503,7 +507,11 @@ ifeq ($(PLATFORM),darwin)
SHLIBEXT=dylib
SHLIBCFLAGS=-fPIC -fno-common
SHLIBLDFLAGS=-dynamiclib $(LDFLAGS) -Wl,-U,_com_altivec
SHLIBLDFLAGS=-dynamiclib $(LDFLAGS) -Wl,-U,_com_altivec -pthread
ifeq ($(VM_USE_SQL), 1)
SHLIBCFLAGS+=-DSQL
endif
NOTSHLIBCFLAGS=-mdynamic-no-pic
@ -565,6 +573,10 @@ ifeq ($(PLATFORM),mingw32)
SHLIBEXT=dll
SHLIBCFLAGS=
SHLIBLDFLAGS=-shared $(LDFLAGS)
ifeq ($(VM_USE_SQL), 1)
SHLIBCFLAGS+=-DSQL
endif
BINEXT=.exe
@ -653,7 +665,11 @@ ifeq ($(PLATFORM),freebsd)
SHLIBEXT=so
SHLIBCFLAGS=-fPIC
SHLIBLDFLAGS=-shared $(LDFLAGS)
SHLIBLDFLAGS=-shared $(LDFLAGS) -lpthread
ifeq ($(VM_USE_SQL), 1)
SHLIBCFLAGS+=-DSQL
endif
THREAD_LIBS=-lpthread
# don't need -ldl (FreeBSD)
@ -721,8 +737,12 @@ ifeq ($(PLATFORM),openbsd)
SHLIBEXT=so
SHLIBNAME=.$(SHLIBEXT)
SHLIBCFLAGS=-fPIC
SHLIBLDFLAGS=-shared $(LDFLAGS)
SHLIBLDFLAGS=-shared $(LDFLAGS) -lpthread
ifeq ($(VM_USE_SQL), 1)
SHLIBCFLAGS+=-DSQL
endif
THREAD_LIBS=-pthread
LIBS=-lm
@ -762,8 +782,12 @@ ifeq ($(PLATFORM),netbsd)
LIBS=-lm
SHLIBEXT=so
SHLIBCFLAGS=-fPIC
SHLIBLDFLAGS=-shared $(LDFLAGS)
SHLIBLDFLAGS=-shared $(LDFLAGS) -lpthread
THREAD_LIBS=-lpthread
ifeq ($(VM_USE_SQL), 1)
SHLIBCFLAGS+=-DSQL
endif
BASE_CFLAGS = -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes
@ -793,8 +817,12 @@ ifeq ($(PLATFORM),irix64)
SHLIBEXT=so
SHLIBCFLAGS=
SHLIBLDFLAGS=-shared
SHLIBLDFLAGS=-shared -lptrhead
ifeq ($(VM_USE_SQL), 1)
SHLIBCFLAGS+=-DSQL
endif
LIBS=-ldl -lm -lgen
# FIXME: The X libraries probably aren't necessary?
CLIENT_LIBS=-L/usr/X11/$(LIB) $(SDL_LIBS) \
@ -853,8 +881,12 @@ ifeq ($(PLATFORM),sunos)
SHLIBEXT=so
SHLIBCFLAGS=-fPIC
SHLIBLDFLAGS=-shared $(LDFLAGS)
SHLIBLDFLAGS=-shared $(LDFLAGS) -pthread
ifeq ($(VM_USE_SQL), 1)
SHLIBCFLAGS+=-DSQL
endif
THREAD_LIBS=-lpthread
LIBS=-lsocket -lnsl -ldl -lm
@ -1073,13 +1105,13 @@ endef
define DO_GAME_CC
$(echo_cmd) "GAME_CC $<"
$(Q)$(CC) $(BASEGAME_CFLAGS) -DQAGAME $(SHLIBCFLAGS) $(CFLAGS) $(OPTIMIZEVM) -o $@ -c $<
$(Q)$(CC) $(BASEGAME_CFLAGS) -DQAGAME -DLUA_COMPAT_ALL $(SHLIBCFLAGS) $(CFLAGS) $(OPTIMIZEVM) -o $@ -c $<
$(Q)$(DO_QVM_DEP)
endef
define DO_CGAME_CC
$(echo_cmd) "CGAME_CC $<"
$(Q)$(CC) $(BASEGAME_CFLAGS) -DCGAME $(SHLIBCFLAGS) $(CFLAGS) $(OPTIMIZEVM) -o $@ -c $<
$(Q)$(CC) $(BASEGAME_CFLAGS) -DCGAME -DLUA_COMPAT_ALL $(SHLIBCFLAGS) $(CFLAGS) $(OPTIMIZEVM) -o $@ -c $<
$(Q)$(DO_QVM_DEP)
endef
@ -1993,35 +2025,88 @@ $(B)/$(SERVERBIN)$(FULLBINEXT): $(Q3DOBJ)
## BASEQ3 CGAME
#############################################################################
CGLUAOBJ = \
$(B)/$(BASEGAME)/cgame/lapi.o \
$(B)/$(BASEGAME)/cgame/lauxlib.o \
$(B)/$(BASEGAME)/cgame/lbaselib.o \
$(B)/$(BASEGAME)/cgame/lbitlib.o \
$(B)/$(BASEGAME)/cgame/lcode.o \
$(B)/$(BASEGAME)/cgame/lcorolib.o \
$(B)/$(BASEGAME)/cgame/lctype.o \
$(B)/$(BASEGAME)/cgame/ldblib.o \
$(B)/$(BASEGAME)/cgame/ldebug.o \
$(B)/$(BASEGAME)/cgame/ldo.o \
$(B)/$(BASEGAME)/cgame/ldump.o \
$(B)/$(BASEGAME)/cgame/lfunc.o \
$(B)/$(BASEGAME)/cgame/lgc.o \
$(B)/$(BASEGAME)/cgame/linit.o \
$(B)/$(BASEGAME)/cgame/liolib.o \
$(B)/$(BASEGAME)/cgame/llex.o \
$(B)/$(BASEGAME)/cgame/lmathlib.o \
$(B)/$(BASEGAME)/cgame/lmem.o \
$(B)/$(BASEGAME)/cgame/loadlib.o \
$(B)/$(BASEGAME)/cgame/lobject.o \
$(B)/$(BASEGAME)/cgame/lopcodes.o \
$(B)/$(BASEGAME)/cgame/loslib.o \
$(B)/$(BASEGAME)/cgame/lparser.o \
$(B)/$(BASEGAME)/cgame/lstate.o \
$(B)/$(BASEGAME)/cgame/lstring.o \
$(B)/$(BASEGAME)/cgame/lstrlib.o \
$(B)/$(BASEGAME)/cgame/ltable.o \
$(B)/$(BASEGAME)/cgame/ltablib.o \
$(B)/$(BASEGAME)/cgame/ltm.o \
$(B)/$(BASEGAME)/cgame/lua.o \
$(B)/$(BASEGAME)/cgame/luac.o \
$(B)/$(BASEGAME)/cgame/lundump.o \
$(B)/$(BASEGAME)/cgame/lvm.o \
$(B)/$(BASEGAME)/cgame/lzio.o
Q3CGOBJ_ = \
$(B)/$(BASEGAME)/cgame/cg_main.o \
$(B)/$(BASEGAME)/cgame/bg_misc.o \
$(B)/$(BASEGAME)/cgame/bg_pmove.o \
$(B)/$(BASEGAME)/cgame/bg_slidemove.o \
$(B)/$(BASEGAME)/cgame/bg_lib.o \
$(B)/$(BASEGAME)/cgame/cg_consolecmds.o \
$(B)/$(BASEGAME)/cgame/cg_draw.o \
$(B)/$(BASEGAME)/cgame/cg_drawtools.o \
$(B)/$(BASEGAME)/cgame/cg_effects.o \
$(B)/$(BASEGAME)/cgame/cg_ents.o \
$(B)/$(BASEGAME)/cgame/cg_event.o \
$(B)/$(BASEGAME)/cgame/cg_info.o \
$(B)/$(BASEGAME)/cgame/cg_env.o \
$(B)/$(BASEGAME)/cgame/cg_localents.o \
$(B)/$(BASEGAME)/cgame/cg_info.o \
$(B)/$(BASEGAME)/cgame/cg_marks.o \
$(B)/$(BASEGAME)/cgame/cg_particles.o \
$(B)/$(BASEGAME)/cgame/cg_players.o \
$(B)/$(BASEGAME)/cgame/cg_playerstate.o \
$(B)/$(BASEGAME)/cgame/cg_predict.o \
$(B)/$(BASEGAME)/cgame/cg_screenfx.o \
$(B)/$(BASEGAME)/cgame/cg_scoreboard.o \
$(B)/$(BASEGAME)/cgame/cg_servercmds.o \
$(B)/$(BASEGAME)/cgame/cg_snapshot.o \
$(B)/$(BASEGAME)/cgame/cg_view.o \
$(B)/$(BASEGAME)/cgame/cg_weapons.o \
$(B)/$(BASEGAME)/cgame/cg_lua.o \
$(B)/$(BASEGAME)/cgame/lua_vector.o \
$(B)/$(BASEGAME)/cgame/lua_qmath.o \
$(B)/$(BASEGAME)/cgame/lua_cfx.o \
$(B)/$(BASEGAME)/cgame/lua_cent.o \
$(B)/$(BASEGAME)/cgame/lua_refent.o \
$(B)/$(BASEGAME)/cgame/fx_transporter.o \
$(B)/$(BASEGAME)/cgame/fx_tetrion.o \
$(B)/$(BASEGAME)/cgame/fx_disruptor.o \
$(B)/$(BASEGAME)/cgame/fx_hypospray.o \
$(B)/$(BASEGAME)/cgame/fx_quantum.o \
$(B)/$(BASEGAME)/cgame/fx_phaser.o \
$(B)/$(BASEGAME)/cgame/fx_misc.o \
$(B)/$(BASEGAME)/cgame/fx_lib.o \
$(B)/$(BASEGAME)/cgame/fx_item.o \
$(B)/$(BASEGAME)/cgame/fx_grenade.o \
$(B)/$(BASEGAME)/cgame/fx_compression.o \
\
$(B)/$(BASEGAME)/qcommon/q_math.o \
$(B)/$(BASEGAME)/qcommon/q_shared.o
$(B)/$(BASEGAME)/cgame/q_math.o \
$(B)/$(BASEGAME)/cgame/q_shared.o
Q3CGOBJ = $(Q3CGOBJ_) $(B)/$(BASEGAME)/cgame/cg_syscalls.o
Q3CGOBJ = $(Q3CGOBJ_) $(B)/$(BASEGAME)/cgame/cg_syscalls.o $(CGLUAOBJ)
Q3CGVMOBJ = $(Q3CGOBJ_:%.o=%.asm)
$(B)/$(BASEGAME)/cgame$(SHLIBNAME): $(Q3CGOBJ)
@ -2037,7 +2122,6 @@ $(B)/$(BASEGAME)/vm/cgame.qvm: $(Q3CGVMOBJ) $(CGDIR)/cg_syscalls.asm $(Q3ASM)
#############################################################################
MPCGOBJ_ = \
$(B)/$(MISSIONPACK)/cgame/cg_main.o \
$(B)/$(MISSIONPACK)/cgame/bg_misc.o \
$(B)/$(MISSIONPACK)/cgame/bg_pmove.o \
$(B)/$(MISSIONPACK)/cgame/bg_slidemove.o \
@ -2052,6 +2136,7 @@ MPCGOBJ_ = \
$(B)/$(MISSIONPACK)/cgame/cg_info.o \
$(B)/$(MISSIONPACK)/cgame/cg_localents.o \
$(B)/$(MISSIONPACK)/cgame/cg_marks.o \
$(B)/$(MISSIONPACK)/cgame/cg_main.o \
$(B)/$(MISSIONPACK)/cgame/cg_particles.o \
$(B)/$(MISSIONPACK)/cgame/cg_players.o \
$(B)/$(MISSIONPACK)/cgame/cg_playerstate.o \
@ -2083,6 +2168,42 @@ $(B)/$(MISSIONPACK)/vm/cgame.qvm: $(MPCGVMOBJ) $(CGDIR)/cg_syscalls.asm $(Q3ASM)
## BASEQ3 GAME
#############################################################################
GLUAOBJ = \
$(B)/$(BASEGAME)/game/lapi.o \
$(B)/$(BASEGAME)/game/lauxlib.o \
$(B)/$(BASEGAME)/game/lbaselib.o \
$(B)/$(BASEGAME)/game/lbitlib.o \
$(B)/$(BASEGAME)/game/lcode.o \
$(B)/$(BASEGAME)/game/lcorolib.o \
$(B)/$(BASEGAME)/game/lctype.o \
$(B)/$(BASEGAME)/game/ldblib.o \
$(B)/$(BASEGAME)/game/ldebug.o \
$(B)/$(BASEGAME)/game/ldo.o \
$(B)/$(BASEGAME)/game/ldump.o \
$(B)/$(BASEGAME)/game/lfunc.o \
$(B)/$(BASEGAME)/game/lgc.o \
$(B)/$(BASEGAME)/game/linit.o \
$(B)/$(BASEGAME)/game/liolib.o \
$(B)/$(BASEGAME)/game/llex.o \
$(B)/$(BASEGAME)/game/lmathlib.o \
$(B)/$(BASEGAME)/game/lmem.o \
$(B)/$(BASEGAME)/game/loadlib.o \
$(B)/$(BASEGAME)/game/lobject.o \
$(B)/$(BASEGAME)/game/lopcodes.o \
$(B)/$(BASEGAME)/game/loslib.o \
$(B)/$(BASEGAME)/game/lparser.o \
$(B)/$(BASEGAME)/game/lstate.o \
$(B)/$(BASEGAME)/game/lstring.o \
$(B)/$(BASEGAME)/game/lstrlib.o \
$(B)/$(BASEGAME)/game/ltable.o \
$(B)/$(BASEGAME)/game/ltablib.o \
$(B)/$(BASEGAME)/game/ltm.o \
$(B)/$(BASEGAME)/game/lua.o \
$(B)/$(BASEGAME)/game/luac.o \
$(B)/$(BASEGAME)/game/lundump.o \
$(B)/$(BASEGAME)/game/lvm.o \
$(B)/$(BASEGAME)/game/lzio.o
Q3GOBJ_ = \
$(B)/$(BASEGAME)/game/g_main.o \
$(B)/$(BASEGAME)/game/ai_chat.o \
@ -2091,11 +2212,10 @@ Q3GOBJ_ = \
$(B)/$(BASEGAME)/game/ai_dmq3.o \
$(B)/$(BASEGAME)/game/ai_main.o \
$(B)/$(BASEGAME)/game/ai_team.o \
$(B)/$(BASEGAME)/game/ai_vcmd.o \
$(B)/$(BASEGAME)/game/bg_misc.o \
$(B)/$(BASEGAME)/game/bg_pmove.o \
$(B)/$(BASEGAME)/game/bg_slidemove.o \
$(B)/$(BASEGAME)/game/bg_lib.o \
$(B)/$(BASEGAME)/game/bg_oums.o \
$(B)/$(BASEGAME)/game/g_active.o \
$(B)/$(BASEGAME)/game/g_arenas.o \
$(B)/$(BASEGAME)/game/g_bot.o \
@ -2115,11 +2235,33 @@ Q3GOBJ_ = \
$(B)/$(BASEGAME)/game/g_trigger.o \
$(B)/$(BASEGAME)/game/g_utils.o \
$(B)/$(BASEGAME)/game/g_weapon.o \
$(B)/$(BASEGAME)/game/g_ui.o \
$(B)/$(BASEGAME)/game/g_lua.o \
$(B)/$(BASEGAME)/game/g_usable.o \
$(B)/$(BASEGAME)/game/g_turrets.o \
$(B)/$(BASEGAME)/game/g_log.o \
$(B)/$(BASEGAME)/game/g_fx.o \
$(B)/$(BASEGAME)/game/g_sql.o \
$(B)/$(BASEGAME)/game/g_breakable.o \
$(B)/$(BASEGAME)/game/g_cinematic.o \
$(B)/$(BASEGAME)/game/lua_game.o \
$(B)/$(BASEGAME)/game/lua_entity.o \
$(B)/$(BASEGAME)/game/lua_vector.o \
$(B)/$(BASEGAME)/game/lua_mover.o \
$(B)/$(BASEGAME)/game/lua_qmath.o \
$(B)/$(BASEGAME)/game/lua_cinematic.o \
$(B)/$(BASEGAME)/game/lua_sound.o \
$(B)/$(BASEGAME)/game/lua_weapons.o \
$(B)/$(BASEGAME)/game/lua_trace.o \
$(B)/$(BASEGAME)/game/lua_cvar.o \
$(B)/$(BASEGAME)/game/sqlite3.o \
$(B)/$(BASEGAME)/game/md5.o \
$(B)/$(BASEGAME)/game/list.o \
\
$(B)/$(BASEGAME)/qcommon/q_math.o \
$(B)/$(BASEGAME)/qcommon/q_shared.o
$(B)/$(BASEGAME)/game/q_math.o \
$(B)/$(BASEGAME)/game/q_shared.o
Q3GOBJ = $(Q3GOBJ_) $(B)/$(BASEGAME)/game/g_syscalls.o
Q3GOBJ = $(Q3GOBJ_) $(B)/$(BASEGAME)/game/g_syscalls.o $(GLUAOBJ)
Q3GVMOBJ = $(Q3GOBJ_:%.o=%.asm)
$(B)/$(BASEGAME)/qagame$(SHLIBNAME): $(Q3GOBJ)
@ -2190,35 +2332,28 @@ $(B)/$(MISSIONPACK)/vm/qagame.qvm: $(MPGVMOBJ) $(GDIR)/g_syscalls.asm $(Q3ASM)
Q3UIOBJ_ = \
$(B)/$(BASEGAME)/ui/ui_main.o \
$(B)/$(BASEGAME)/ui/bg_misc.o \
$(B)/$(BASEGAME)/ui/bg_lib.o \
$(B)/$(BASEGAME)/ui/ui_addbots.o \
$(B)/$(BASEGAME)/ui/ui_atoms.o \
$(B)/$(BASEGAME)/ui/ui_cdkey.o \
$(B)/$(BASEGAME)/ui/ui_cinematics.o \
$(B)/$(BASEGAME)/ui/ui_confirm.o \
$(B)/$(BASEGAME)/ui/ui_connect.o \
$(B)/$(BASEGAME)/ui/ui_controls2.o \
$(B)/$(BASEGAME)/ui/ui_credits.o \
$(B)/$(BASEGAME)/ui/ui_demo2.o \
$(B)/$(BASEGAME)/ui/ui_display.o \
$(B)/$(BASEGAME)/ui/ui_gameinfo.o \
$(B)/$(BASEGAME)/ui/ui_ingame.o \
$(B)/$(BASEGAME)/ui/ui_loadconfig.o \
$(B)/$(BASEGAME)/ui/ui_menu.o \
$(B)/$(BASEGAME)/ui/ui_mfield.o \
$(B)/$(BASEGAME)/ui/ui_mods.o \
$(B)/$(BASEGAME)/ui/ui_network.o \
$(B)/$(BASEGAME)/ui/ui_options.o \
$(B)/$(BASEGAME)/ui/ui_playermodel.o \
$(B)/$(BASEGAME)/ui/ui_players.o \
$(B)/$(BASEGAME)/ui/ui_playersettings.o \
$(B)/$(BASEGAME)/ui/ui_preferences.o \
$(B)/$(BASEGAME)/ui/ui_qmenu.o \
$(B)/$(BASEGAME)/ui/ui_removebots.o \
$(B)/$(BASEGAME)/ui/ui_saveconfig.o \
$(B)/$(BASEGAME)/ui/ui_serverinfo.o \
$(B)/$(BASEGAME)/ui/ui_servers2.o \
$(B)/$(BASEGAME)/ui/ui_setup.o \
$(B)/$(BASEGAME)/ui/ui_sound.o \
$(B)/$(BASEGAME)/ui/ui_sparena.o \
$(B)/$(BASEGAME)/ui/ui_specifyserver.o \
@ -2229,9 +2364,16 @@ Q3UIOBJ_ = \
$(B)/$(BASEGAME)/ui/ui_team.o \
$(B)/$(BASEGAME)/ui/ui_teamorders.o \
$(B)/$(BASEGAME)/ui/ui_video.o \
$(B)/$(BASEGAME)/ui/ui_turbolift.o \
$(B)/$(BASEGAME)/ui/ui_transporter.o \
$(B)/$(BASEGAME)/ui/ui_motd.o \
$(B)/$(BASEGAME)/ui/ui_admin.o \
$(B)/$(BASEGAME)/ui/ui_fonts.o \
$(B)/$(BASEGAME)/ui/ui_emotes.o \
$(B)/$(BASEGAME)/ui/ui_cvars.o \
\
$(B)/$(BASEGAME)/qcommon/q_math.o \
$(B)/$(BASEGAME)/qcommon/q_shared.o
$(B)/$(BASEGAME)/ui/q_math.o \
$(B)/$(BASEGAME)/ui/q_shared.o
Q3UIOBJ = $(Q3UIOBJ_) $(B)/$(MISSIONPACK)/ui/ui_syscalls.o
Q3UIVMOBJ = $(Q3UIOBJ_:%.o=%.asm)
@ -2377,6 +2519,12 @@ endif
$(B)/$(BASEGAME)/cgame/bg_%.o: $(GDIR)/bg_%.c
$(DO_CGAME_CC)
$(B)/$(BASEGAME)/cgame/l%.o: $(GDIR)/l%.c
$(DO_CGAME_CC)
$(B)/$(BASEGAME)/cgame/q_%.o: $(GDIR)/q_%.c
$(DO_CGAME_CC)
$(B)/$(BASEGAME)/cgame/%.o: $(CGDIR)/%.c
$(DO_CGAME_CC)
@ -2399,6 +2547,8 @@ $(B)/$(MISSIONPACK)/cgame/bg_%.asm: $(GDIR)/bg_%.c $(Q3LCC)
$(B)/$(MISSIONPACK)/cgame/%.asm: $(CGDIR)/%.c $(Q3LCC)
$(DO_CGAME_Q3LCC_MISSIONPACK)
$(B)/$(BASEGAME)/game/q_%.o: $(GDIR)/q_%.c
$(DO_GAME_CC)
$(B)/$(BASEGAME)/game/%.o: $(GDIR)/%.c
$(DO_GAME_CC)
@ -2416,6 +2566,9 @@ $(B)/$(MISSIONPACK)/game/%.asm: $(GDIR)/%.c $(Q3LCC)
$(B)/$(BASEGAME)/ui/bg_%.o: $(GDIR)/bg_%.c
$(DO_UI_CC)
$(B)/$(BASEGAME)/ui/q_%.o: $(GDIR)/q_%.c
$(DO_UI_CC)
$(B)/$(BASEGAME)/ui/%.o: $(Q3UIDIR)/%.c
$(DO_UI_CC)

249
code/cgame/Makefile Normal file
View file

@ -0,0 +1,249 @@
default: so
so: build_so
# determine arch and platform
ARCH=$(shell uname -m | sed -e s/i.86/i386/)
PLATFORM=$(shell uname|sed -e s/_.*//|tr '[:upper:]' '[:lower:]')
# compiler to use for building shared objects
CC = gcc
# cross compiling
ifneq ($(PLATFORM), mingw32)
ifeq ($(TARGET), win32)
PLATFORM=mingw32
ARCH=x86
CC=i686-w64-mingw32-gcc
CFLAGS+=-m32
endif
ifeq ($(TARGET), win64)
PLATFORM=mingw32
ARCH=x64
CC=x86_64-w64-mingw32-gcc
CFLAGS+=-m64
endif
else
# we are compiling on windows
ARCH=x86
endif
# cflags for the compiler
ifeq ($(PLATFORM), mingw32)
SOCFLAGS = $(CFLAGS)
else
SOCFLAGS = $(CFLAGS) -fPIC
endif
# set extension
ifeq ($(PLATFORM), mingw32)
EXT=dll
else
EXT=so
endif
# warning level
ifeq ($(DEBUG), 1)
WL=-Wall
else
WL=-Wall -Wno-unused-but-set-variable
endif
# cgame objects
OBJ = \
fx_transporter.o \
fx_tetrion.o \
fx_disruptor.o \
fx_hypospray.o \
fx_quantum.o \
fx_phaser.o \
fx_misc.o \
fx_lib.o \
fx_item.o \
fx_grenade.o \
fx_compression.o \
cg_weapons.o \
cg_view.o \
cg_snapshot.o \
cg_servercmds.o \
cg_screenfx.o \
cg_scoreboard.o \
cg_predict.o \
cg_playerstate.o \
cg_players.o \
cg_marks.o \
cg_main.o \
cg_localents.o \
cg_info.o \
cg_event.o \
cg_env.o \
cg_ents.o \
cg_effects.o \
cg_drawtools.o \
cg_draw.o \
cg_consolecmds.o \
cg_lua.o \
lua_vector.o \
lua_qmath.o \
lua_cfx.o \
lua_cent.o \
lua_refent.o \
# depency objects from game
OBJDEP = \
q_shared.o \
q_math.o \
bg_misc.o \
bg_pmove.o \
bg_slidemove.o
# object for syscalls to the engine
SOOBJ = \
cg_syscalls.o
# objects for lua
LUAOBJ = \
lapi.o \
lauxlib.o \
lbaselib.o \
lbitlib.o \
lcode.o \
lcorolib.o \
lctype.o \
ldblib.o \
ldebug.o \
ldo.o \
ldump.o \
lfunc.o \
lgc.o \
linit.o \
liolib.o \
llex.o \
lmathlib.o \
lmem.o \
loadlib.o \
lobject.o \
lopcodes.o \
loslib.o \
lparser.o \
lstate.o \
lstring.o \
lstrlib.o \
ltable.o \
ltablib.o \
ltm.o \
lua.o \
luac.o \
lundump.o \
lvm.o \
lzio.o
# do cc for shared library
ifeq ($(DEBUG), 1)
DO_SOCC = $(CC) $(SOCFLAGS) $(WL) -g3 $(DEFINES) -o $@ -c $<
else
DO_SOCC = $(CC) $(SOCFLAGS) $(WL) $(DEFINES) -o $@ -c $<
endif
# do cc for lua
ifeq ($(DEBUG), 1)
DO_LUACC = $(CC) -O2 -Wall $(SOCFLAGS) -DLUA_COMPAT_ALL -o $@ -c $<
else
DO_LUACC = $(CC) -O2 -Wall -g3 $(SOCFLAGS) -DLUA_COMPAT_ALL -o $@ -c $<
endif
build_so: DO_CC=$(DO_SOCC)
# cgame
cg_consolecmds.o : cg_consolecmds.c; $(DO_CC)
cg_draw.o : cg_draw.c; $(DO_CC)
cg_drawtools.o : cg_drawtools.c; $(DO_CC)
cg_effects.o : cg_effects.c; $(DO_CC)
cg_ents.o : cg_ents.c; $(DO_CC)
cg_env.o : cg_env.c; $(DO_CC)
cg_event.o : cg_event.c; $(DO_CC)
cg_info.o : cg_info.c; $(DO_CC)
cg_localents.o : cg_localents.c; $(DO_CC)
cg_main.o : cg_main.c; $(DO_CC)
cg_marks.o : cg_marks.c; $(DO_CC)
cg_players.o : cg_players.c; $(DO_CC)
cg_playerstate.o : cg_playerstate.c; $(DO_CC)
cg_predict.o : cg_predict.c; $(DO_CC)
cg_scoreboard.o : cg_scoreboard.c; $(DO_CC)
cg_screenfx.o : cg_screenfx.c; $(DO_CC)
cg_servercmds.o : cg_servercmds.c; $(DO_CC)
cg_snapshot.o : cg_snapshot.c; $(DO_CC)
cg_view.o : cg_view.c; $(DO_CC)
cg_weapons.o : cg_weapons.c; $(DO_CC)
cg_lua.o : cg_lua.c; $(DO_CC)
fx_compression.o : fx_compression.c; $(DO_CC)
fx_grenade.o : fx_grenade.c; $(DO_CC)
fx_item.o : fx_item.c; $(DO_CC)
fx_lib.o : fx_lib.c; $(DO_CC)
fx_misc.o : fx_misc.c; $(DO_CC)
fx_phaser.o : fx_phaser.c; $(DO_CC)
fx_quantum.o : fx_quantum.c; $(DO_CC)
fx_hypospray.o : fx_hypospray.c; $(DO_CC)
fx_disruptor.o : fx_disruptor.c; $(DO_CC)
fx_tetrion.o : fx_tetrion.c; $(DO_CC)
fx_transporter.o : fx_transporter.c; $(DO_CC)
lua_qmath.o: ../game/lua_qmath.c; $(DO_CC)
lua_vector.o: ../game/lua_vector.c; $(DO_CC)
lua_cfx.o: lua_cfx.c; $(DO_CC)
lua_cent.o: lua_cent.c; $(DO_CC)
lua_refent.o: lua_refent.c; $(DO_CC);
# dependencies from game
q_shared.o: ../game/q_shared.c; $(DO_CC)
q_math.o: ../game/q_math.c; $(DO_CC)
bg_misc.o: ../game/bg_misc.c; $(DO_CC)
bg_pmove.o: ../game/bg_pmove.c; $(DO_CC)
bg_slidemove.o: ../game/bg_slidemove.c; $(DO_CC)
# cgame syscalls
cg_syscalls.o : cg_syscalls.c; $(DO_CC)
# lua
lapi.o: ../game/lapi.c; $(DO_LUACC)
lauxlib.o: ../game/lauxlib.c; $(DO_LUACC)
lbaselib.o: ../game/lbaselib.c; $(DO_LUACC)
lbitlib.o: ../game/lbitlib.c; $(DO_LUACC)
lcode.o: ../game/lcode.c; $(DO_LUACC)
lcorolib.o: ../game/lcorolib.c; $(DO_LUACC)
lctype.o: ../game/lctype.c; $(DO_LUACC)
ldblib.o: ../game/ldblib.c; $(DO_LUACC)
ldebug.o: ../game/ldebug.c; $(DO_LUACC)
ldo.o: ../game/ldo.c; $(DO_LUACC)
ldump.o: ../game/ldump.c; $(DO_LUACC)
lfunc.o: ../game/lfunc.c; $(DO_LUACC)
lgc.o: ../game/lgc.c; $(DO_LUACC)
linit.o: ../game/linit.c; $(DO_LUACC)
liolib.o: ../game/liolib.c; $(DO_LUACC)
llex.o: ../game/llex.c; $(DO_LUACC)
lmathlib.o: ../game/lmathlib.c; $(DO_LUACC)
lmem.o: ../game/lmem.c; $(DO_LUACC)
loadlib.o: ../game/loadlib.c; $(DO_LUACC)
lobject.o: ../game/lobject.c; $(DO_LUACC)
lopcodes.o: ../game/lopcodes.c; $(DO_LUACC)
loslib.o: ../game/loslib.c; $(DO_LUACC)
lparser.o: ../game/lparser.c; $(DO_LUACC)
lstate.o: ../game/lstate.c; $(DO_LUACC)
lstring.o: ../game/lstring.c; $(DO_LUACC)
lstrlib.o: ../game/lstrlib.c; $(DO_LUACC)
ltable.o: ../game/ltable.c; $(DO_LUACC)
ltablib.o: ../game/ltablib.c; $(DO_LUACC)
ltm.o: ../game/ltm.c; $(DO_LUACC)
lua.o: ../game/lua.c; $(DO_LUACC)
luac.o: ../game/luac.c; $(DO_LUACC)
lundump.o: ../game/lundump.c; $(DO_LUACC)
lvm.o: ../game/lvm.c; $(DO_LUACC)
lzio.o: ../game/lzio.c; $(DO_LUACC)
build_so: $(OBJDEP) $(OBJ) $(SOOBJ) $(LUAOBJ)
ifeq ($(PLATFORM), mingw32)
$(CC) -shared -Wl,--export-all-symbols,-soname,cgame$(ARCH).$(EXT) -o cgame$(ARCH).$(EXT) $(OBJ) $(OBJDEP) $(SOOBJ) $(LUAOBJ) -lm
else
$(CC) -shared -Wl,--export-dynamic,-soname,cgame$(ARCH).$(EXT) -o cgame$(ARCH).$(EXT) $(OBJ) $(OBJDEP) $(SOOBJ) $(LUAOBJ) -lm -lpthread
endif
clean:
rm -f *.o *.$(EXT)

3
code/cgame/Todo.txt Normal file
View file

@ -0,0 +1,3 @@
- Find and remove unused things
- Run static code analysis and fix things
- Completely debug

1798
code/cgame/cg_anims.h Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,29 +1,10 @@
/*
===========================================================================
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
===========================================================================
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_effects.c -- these functions generate localentities, usually as a result
// of event processing
#include "cg_local.h"
#include "fx_local.h"
/*
@ -39,10 +20,6 @@ void CG_BubbleTrail( vec3_t start, vec3_t end, float spacing ) {
float len;
int i;
if ( cg_noProjectileTrail.integer ) {
return;
}
VectorCopy (start, move);
VectorSubtract (end, start, vec);
len = VectorNormalize (vec);
@ -65,11 +42,12 @@ void CG_BubbleTrail( vec3_t start, vec3_t end, float spacing ) {
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
re = &le->refEntity;
re->shaderTime = cg.time / 1000.0f;
//re->shaderTime = cg.time / 1000.0f;
re->shaderTime = cg.time * 0.001f;
re->reType = RT_SPRITE;
re->rotation = 0;
re->radius = 3;
re->data.sprite.rotation = 0;
re->data.sprite.radius = 3;
re->customShader = cgs.media.waterBubbleShader;
re->shaderRGBA[0] = 0xff;
re->shaderRGBA[1] = 0xff;
@ -101,33 +79,26 @@ localEntity_t *CG_SmokePuff( const vec3_t p, const vec3_t vel,
float r, float g, float b, float a,
float duration,
int startTime,
int fadeInTime,
int leFlags,
qhandle_t hShader ) {
static int seed = 0x92;
localEntity_t *le;
refEntity_t *re;
// int fadeInTime = startTime + duration / 2;
le = CG_AllocLocalEntity();
le->leFlags = leFlags;
le->radius = radius;
le->data.sprite.radius = radius;
re = &le->refEntity;
re->rotation = Q_random( &seed ) * 360;
re->radius = radius;
re->shaderTime = startTime / 1000.0f;
re->data.sprite.rotation = Q_random( &seed ) * 360;
re->data.sprite.radius = radius;
//re->shaderTime = startTime / 1000.0f;
re->shaderTime = startTime * 0.001f;
le->leType = LE_MOVE_SCALE_FADE;
le->startTime = startTime;
le->fadeInTime = fadeInTime;
le->endTime = startTime + duration;
if ( fadeInTime > startTime ) {
le->lifeRate = 1.0 / ( le->endTime - le->fadeInTime );
}
else {
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
}
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
le->color[0] = r;
le->color[1] = g;
le->color[2] = b;
@ -157,7 +128,7 @@ localEntity_t *CG_SmokePuff( const vec3_t p, const vec3_t vel,
}
re->reType = RT_SPRITE;
re->radius = le->radius;
re->data.sprite.radius = le->data.sprite.radius;
return le;
}
@ -167,12 +138,15 @@ localEntity_t *CG_SmokePuff( const vec3_t p, const vec3_t vel,
CG_SpawnEffect
Player teleporting in or out
RPG-X: RedTechie Added refEntity_t *ent_legs, refEntity_t *ent_torso, refEntity_t *ent_head
==================
*/
void CG_SpawnEffect( vec3_t org ) {
void CG_SpawnEffect( vec3_t org, refEntity_t *ent_legs, refEntity_t *ent_torso, refEntity_t *ent_head ) {
localEntity_t *le;
refEntity_t *re;
FX_Transporter(org);
le = CG_AllocLocalEntity();
le->leFlags = 0;
le->leType = LE_FADE_RGB;
@ -181,247 +155,64 @@ void CG_SpawnEffect( vec3_t org ) {
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
le->color[0] = le->color[1] = le->color[2] = le->color[3] = 1.0;
re = &le->refEntity;
//RPG-X: RedTechie - Added for better trans effect - dosnt work right now
//ent_legs->shaderTime = cg.time / 1000.0f;
//ent_head->shaderTime = cg.time / 1000.0f;
//ent_torso->shaderTime = cg.time / 1000.0f;
//ent_legs->customShader = cgs.media.teleportEffectShader;
//trap_R_AddRefEntityToScene( ent_legs );
//ent_head->customShader = cgs.media.teleportEffectShader;
//trap_R_AddRefEntityToScene( ent_head );
//ent_torso->customShader = cgs.media.teleportEffectShader;
//trap_R_AddRefEntityToScene( ent_torso );
//RPG-X: RedTechie - Playing with transporter crap
//re->shaderTime = cg.time / 1000.0f;
re->shaderTime = cg.time * 0.001f;
re = &le->refEntity;
re->reType = RT_MODEL;
re->shaderTime = cg.time / 1000.0f;
//re->shaderTime = cg.time / 1000.0f;
re->shaderTime = cg.time * 0.001f;
#ifndef MISSIONPACK
re->customShader = cgs.media.teleportEffectShader;
#endif
re->hModel = cgs.media.teleportEffectModel;
AxisClear( re->axis );
VectorCopy( org, re->origin );
#ifdef MISSIONPACK
re->origin[2] += 16;
#else
re->origin[2] -= 24;
#endif
}
#ifdef MISSIONPACK
/*
===============
CG_LightningBoltBeam
===============
*/
void CG_LightningBoltBeam( vec3_t start, vec3_t end ) {
void CG_QFlashEvent( vec3_t org ) {
localEntity_t *le;
refEntity_t *beam;
/*refEntity_t *re;
le = CG_AllocLocalEntity();
le->leFlags = 0;
le->leType = LE_SHOWREFENTITY;
le->startTime = cg.time;
le->endTime = cg.time + 50;
beam = &le->refEntity;
VectorCopy( start, beam->origin );
// this is the end point
VectorCopy( end, beam->oldorigin );
beam->reType = RT_LIGHTNING;
beam->customShader = cgs.media.lightningShader;
}
/*
==================
CG_KamikazeEffect
==================
*/
void CG_KamikazeEffect( vec3_t org ) {
localEntity_t *le;
refEntity_t *re;
le = CG_AllocLocalEntity();
le->leFlags = 0;
le->leType = LE_KAMIKAZE;
le->startTime = cg.time;
le->endTime = cg.time + 3000;//2250;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
le->color[0] = le->color[1] = le->color[2] = le->color[3] = 1.0;
VectorClear(le->angles.trBase);
re = &le->refEntity;
re->reType = RT_MODEL;
re->shaderTime = cg.time / 1000.0f;
re->hModel = cgs.media.kamikazeEffectModel;
VectorCopy( org, re->origin );
}
/*
==================
CG_ObeliskExplode
==================
*/
void CG_ObeliskExplode( vec3_t org, int entityNum ) {
localEntity_t *le;
vec3_t origin;
// create an explosion
VectorCopy( org, origin );
origin[2] += 64;
le = CG_MakeExplosion( origin, vec3_origin,
cgs.media.dishFlashModel,
cgs.media.rocketExplosionShader,
600, qtrue );
le->light = 300;
le->lightColor[0] = 1;
le->lightColor[1] = 0.75;
le->lightColor[2] = 0.0;
}
/*
==================
CG_ObeliskPain
==================
*/
void CG_ObeliskPain( vec3_t org ) {
float r;
sfxHandle_t sfx;
// hit sound
r = rand() & 3;
if ( r < 2 ) {
sfx = cgs.media.obeliskHitSound1;
} else if ( r == 2 ) {
sfx = cgs.media.obeliskHitSound2;
} else {
sfx = cgs.media.obeliskHitSound3;
}
trap_S_StartSound ( org, ENTITYNUM_NONE, CHAN_BODY, sfx );
}
/*
==================
CG_InvulnerabilityImpact
==================
*/
void CG_InvulnerabilityImpact( vec3_t org, vec3_t angles ) {
localEntity_t *le;
refEntity_t *re;
int r;
sfxHandle_t sfx;
le = CG_AllocLocalEntity();
le->leFlags = 0;
le->leType = LE_INVULIMPACT;
le->startTime = cg.time;
le->endTime = cg.time + 1000;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
le->color[0] = le->color[1] = le->color[2] = le->color[3] = 1.0;
re = &le->refEntity;
re->reType = RT_MODEL;
re->shaderTime = cg.time / 1000.0f;
re->hModel = cgs.media.invulnerabilityImpactModel;
VectorCopy( org, re->origin );
AnglesToAxis( angles, re->axis );
r = rand() & 3;
if ( r < 2 ) {
sfx = cgs.media.invulnerabilityImpactSound1;
} else if ( r == 2 ) {
sfx = cgs.media.invulnerabilityImpactSound2;
} else {
sfx = cgs.media.invulnerabilityImpactSound3;
}
trap_S_StartSound (org, ENTITYNUM_NONE, CHAN_BODY, sfx );
}
/*
==================
CG_InvulnerabilityJuiced
==================
*/
void CG_InvulnerabilityJuiced( vec3_t org ) {
localEntity_t *le;
refEntity_t *re;
vec3_t angles;
le = CG_AllocLocalEntity();
le->leFlags = 0;
le->leType = LE_INVULJUICED;
le->startTime = cg.time;
le->endTime = cg.time + 10000;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
le->color[0] = le->color[1] = le->color[2] = le->color[3] = 1.0;
re = &le->refEntity;
re->reType = RT_MODEL;
re->shaderTime = cg.time / 1000.0f;
re->hModel = cgs.media.invulnerabilityJuicedModel;
VectorCopy( org, re->origin );
VectorClear(angles);
AnglesToAxis( angles, re->axis );
trap_S_StartSound (org, ENTITYNUM_NONE, CHAN_BODY, cgs.media.invulnerabilityJuicedSound );
}
#endif
/*
==================
CG_ScorePlum
==================
*/
void CG_ScorePlum( int client, vec3_t org, int score ) {
localEntity_t *le;
refEntity_t *re;
vec3_t angles;
static vec3_t lastPos;
// only visualize for the client that scored
if (client != cg.predictedPlayerState.clientNum || cg_scorePlum.integer == 0) {
return;
}
le = CG_AllocLocalEntity();
le->leFlags = 0;
le->leType = LE_SCOREPLUM;
le->startTime = cg.time;
le->endTime = cg.time + 4000;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
le->leFlags = LEF_SINE_SCALE;
le->leType = LE_PARTICLE;
le->color[0] = le->color[1] = le->color[2] = le->color[3] = 1.0;
le->radius = score;
VectorCopy( org, le->pos.trBase );
if (org[2] >= lastPos[2] - 20 && org[2] <= lastPos[2] + 20) {
le->pos.trBase[2] -= 20;
}
le->startTime = cg.time;
le->endTime = cg.time + 600;
//CG_Printf( "Plum origin %i %i %i -- %i\n", (int)org[0], (int)org[1], (int)org[2], (int)Distance(org, lastPos));
VectorCopy(org, lastPos);
le->color[0] = le->color[1] = le->color[2] = le->color[3] = 1.0f;
le->data.particle.radius = 30;
le->data.particle.dradius = 5;
re = &le->refEntity;
re->customShader = cgs.media.qFlashSprite;
re->reType = RT_SPRITE;
re->radius = 16;
VectorCopy( org, re->origin );
VectorCopy( org, re->oldorigin );*/
VectorClear(angles);
AnglesToAxis( angles, re->axis );
le = FX_AddParticle( org, vec3_origin, qfalse, 110.0f, 109.0f,
1.0f, 1.0f, 0, 0,
290, cgs.media.qFlashSprite, 0 );
le->leFlags = LEF_SINE_SCALE | LEF_REVERSE_SCALE;
le->refEntity.renderfx |= RF_DEPTHHACK;
}
@ -432,7 +223,7 @@ CG_MakeExplosion
*/
localEntity_t *CG_MakeExplosion( vec3_t origin, vec3_t dir,
qhandle_t hModel, qhandle_t shader,
int msec, qboolean isSprite ) {
int msec, float scale, qboolean isSprite ) {
float ang;
localEntity_t *ex;
int offset;
@ -450,7 +241,7 @@ localEntity_t *CG_MakeExplosion( vec3_t origin, vec3_t dir,
ex->leType = LE_SPRITE_EXPLOSION;
// randomly rotate sprite orientation
ex->refEntity.rotation = rand() % 360;
ex->refEntity.data.sprite.rotation = rand() % 360;
VectorScale( dir, 16, tmpVec );
VectorAdd( tmpVec, origin, newOrigin );
} else {
@ -471,7 +262,8 @@ localEntity_t *CG_MakeExplosion( vec3_t origin, vec3_t dir,
ex->endTime = ex->startTime + msec;
// bias the time so all shader effects start correctly
ex->refEntity.shaderTime = ex->startTime / 1000.0f;
//ex->refEntity.shaderTime = ex->startTime / 1000.0f;
ex->refEntity.shaderTime = ex->startTime * 0.001f;
ex->refEntity.hModel = hModel;
ex->refEntity.customShader = shader;
@ -480,12 +272,91 @@ localEntity_t *CG_MakeExplosion( vec3_t origin, vec3_t dir,
VectorCopy( newOrigin, ex->refEntity.origin );
VectorCopy( newOrigin, ex->refEntity.oldorigin );
//Scale the explosion
if (scale != 1) {
ex->refEntity.nonNormalizedAxes = qtrue;
VectorScale( ex->refEntity.axis[0], scale, ex->refEntity.axis[0] );
VectorScale( ex->refEntity.axis[1], scale, ex->refEntity.axis[1] );
VectorScale( ex->refEntity.axis[2], scale, ex->refEntity.axis[2] );
}
ex->color[0] = ex->color[1] = ex->color[2] = 1.0;
return ex;
}
localEntity_t *CG_MakeExplosion2( vec3_t origin, vec3_t dir,
qhandle_t hModel, int numFrames, qhandle_t shader,
int msec, qboolean isSprite, float scale, int flags) {
float ang;
localEntity_t *ex;
int offset;
vec3_t tmpVec, newOrigin;
if ( msec <= 0 ) {
CG_Error( "CG_MakeExplosion: msec = %i", msec );
}
// skew the time a bit so they aren't all in sync
offset = rand() & 63;
ex = CG_AllocLocalEntity();
if ( isSprite ) {
ex->leType = LE_SPRITE_EXPLOSION;
// randomly rotate sprite orientation
ex->refEntity.data.sprite.rotation = rand() % 360;
VectorScale( dir, 16, tmpVec );
VectorAdd( tmpVec, origin, newOrigin );
} else {
ex->leType = LE_EXPLOSION;
VectorCopy( origin, newOrigin );
// set axis with random rotate
if ( !dir ) {
AxisClear( ex->refEntity.axis );
} else {
ang = rand() % 360;
VectorCopy( dir, ex->refEntity.axis[0] );
RotateAroundDirection( ex->refEntity.axis, ang );
}
}
ex->startTime = cg.time - offset;
ex->endTime = ex->startTime + msec;
// bias the time so all shader effects start correctly
//ex->refEntity.shaderTime = ex->startTime / 1000.0f;
ex->refEntity.shaderTime = ex->startTime * 0.001f;
ex->refEntity.hModel = hModel;
ex->refEntity.customShader = shader;
ex->lifeRate = (float)numFrames / msec;
ex->leFlags = flags;
//Scale the explosion
if (scale != 1) {
ex->refEntity.nonNormalizedAxes = qtrue;
VectorScale( ex->refEntity.axis[0], scale, ex->refEntity.axis[0] );
VectorScale( ex->refEntity.axis[1], scale, ex->refEntity.axis[1] );
VectorScale( ex->refEntity.axis[2], scale, ex->refEntity.axis[2] );
}
// set origin
VectorCopy( newOrigin, ex->refEntity.origin );
VectorCopy( newOrigin, ex->refEntity.oldorigin );
ex->color[0] = ex->color[1] = ex->color[2] = 1.0;
return ex;
}
/*
=================
CG_Bleed
@ -493,7 +364,7 @@ CG_Bleed
This is the spurt of blood when a character gets hit
=================
*/
void CG_Bleed( vec3_t origin, int entityNum ) {
/*void CG_Bleed( vec3_t origin, int entityNum ) {
localEntity_t *ex;
if ( !cg_blood.integer ) {
@ -508,8 +379,8 @@ void CG_Bleed( vec3_t origin, int entityNum ) {
VectorCopy ( origin, ex->refEntity.origin);
ex->refEntity.reType = RT_SPRITE;
ex->refEntity.rotation = rand() % 360;
ex->refEntity.radius = 24;
ex->refEntity.data.sprite.rotation = rand() % 360;
ex->refEntity.data.sprite.radius = 16;
ex->refEntity.customShader = cgs.media.bloodExplosionShader;
@ -517,202 +388,222 @@ void CG_Bleed( vec3_t origin, int entityNum ) {
if ( entityNum == cg.snap->ps.clientNum ) {
ex->refEntity.renderfx |= RF_THIRD_PERSON;
}
}
}*/
/*
==================
CG_LaunchGib
==================
-------------------------
CG_ExplosionEffects
Used to find the player and shake the camera if close enough
intensity ranges from 1 (minor tremble) to 16 (major quake)
-------------------------
*/
void CG_LaunchGib( vec3_t origin, vec3_t velocity, qhandle_t hModel ) {
localEntity_t *le;
refEntity_t *re;
le = CG_AllocLocalEntity();
re = &le->refEntity;
void CG_ExplosionEffects( vec3_t origin, int intensity, int radius)
{
//FIXME: When exactly is the vieworg calculated in relation to the rest of the frame?s
le->leType = LE_FRAGMENT;
le->startTime = cg.time;
le->endTime = le->startTime + 5000 + random() * 3000;
vec3_t dir;
float dist, intensityScale;
float realIntensity;
VectorCopy( origin, re->origin );
AxisCopy( axisDefault, re->axis );
re->hModel = hModel;
VectorSubtract( cg.refdef.vieworg, origin, dir );
dist = VectorNormalize( dir );
le->pos.trType = TR_GRAVITY;
VectorCopy( origin, le->pos.trBase );
VectorCopy( velocity, le->pos.trDelta );
le->pos.trTime = cg.time;
//Use the dir to add kick to the explosion
le->bounceFactor = 0.6f;
le->leBounceSoundType = LEBS_BLOOD;
le->leMarkType = LEMT_BLOOD;
}
/*
===================
CG_GibPlayer
Generated a bunch of gibs launching out from the bodies location
===================
*/
#define GIB_VELOCITY 250
#define GIB_JUMP 250
void CG_GibPlayer( vec3_t playerOrigin ) {
vec3_t origin, velocity;
if ( !cg_blood.integer ) {
if ( dist > radius )
return;
intensityScale = 1 - ( dist / (float) radius );
realIntensity = intensity * intensityScale;
CG_CameraShake( realIntensity, 500, qfalse );
}
/*
=================
CG_Seeker
=================
*/
/*void CG_Seeker( centity_t *cent )
{
refEntity_t re;
vec3_t seekerOrg, viewAng;
float angle;
angle = cg.time/100.0f;
seekerOrg[0] = cent->lerpOrigin[0] + 18 * cos(angle);
seekerOrg[1] = cent->lerpOrigin[1] + 18 * sin(angle);
seekerOrg[2] = cent->lerpOrigin[2] + cg.predictedPlayerState.viewheight + 8 + (3*cos(cg.time/150.0f));
memset( &re, 0, sizeof( re ) );
re.reType = RT_MODEL;
VectorCopy ( seekerOrg, re.origin);
re.hModel = cgs.media.seekerModel;
re.shaderTime = (cg.time / 1000.0f);
VectorCopy (cent->lerpAngles , viewAng); // so the seeker faces the same direction the player is
viewAng[0] = -90; // but, we don't want the seeker facing up or down, always horizontal
AnglesToAxis( viewAng, re.axis );
VectorScale(re.axis[0], 0.5, re.axis[0]);
VectorScale(re.axis[1], 0.5, re.axis[1]);
VectorScale(re.axis[2], 0.5, re.axis[2]);
re.nonNormalizedAxes=qtrue;
trap_R_AddRefEntityToScene( &re );
}*/
/*
-------------------------
CG_Smoke
TiM: Ported from EF SP
-------------------------
*/
//void CG_Smoke( vec3_t origin, vec3_t dir, float radius, float speed, qhandle_t shader )
//{
// vec3_t velocity/*, accel*/;
// int i;
// for ( i = 0; i < 3; i++ )
// {
// velocity[i] = dir[i] + ( 0.2f * crandom());
// }
// VectorScale( velocity, speed, velocity );
//VectorScale( velocity, -0.25f, accel );
//accel[2] = random() * 12.0f + 6.0f;
// FX_AddSprite( origin,
// velocity,
// qfalse, //accel
// radius + (crandom() * radius * 0.5f ),
// radius + (crandom() * radius),
// 0.9f + crandom(),
// 0.0f,
// 16.0f + random() * 45.0f,
// 0.5f,
// 2000,
// shader ); //flags
//}
qboolean SmokeThink( localEntity_t *le )
{
vec3_t velocity/*, accel*/;
vec3_t origin;
vec3_t dir;
float speed;
int i;
VectorCopy( le->data.spawner.dir, dir );
//clamp the smoke vector
//Smoke should always go up
dir[2] = Com_Clamp( 0.85f, 1.0f, dir[2] );
for ( i = 0; i < 3; i++ )
{
velocity[i] = dir[i] + ( 0.2f * crandom());
}
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
if ( rand() & 1 ) {
CG_LaunchGib( origin, velocity, cgs.media.gibSkull );
} else {
CG_LaunchGib( origin, velocity, cgs.media.gibBrain );
}
VectorMA( le->refEntity.origin, 1, le->data.spawner.dir, origin);
// allow gibs to be turned off for speed
if ( !cg_gibs.integer ) {
return;
}
//slow down the smoke the smaller it gets
//else it scatters too much
speed = le->data.spawner.data1 * 2.4;
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
CG_LaunchGib( origin, velocity, cgs.media.gibAbdomen );
VectorScale( velocity, speed, velocity ); //speed
//VectorScale( velocity, -0.25f, accel );
//accel[2] = random() * 12.0f + 6.0f;
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
CG_LaunchGib( origin, velocity, cgs.media.gibArm );
FX_AddSprite( origin,
velocity,
qfalse, //accel
le->data.spawner.data1 + (crandom() * le->data.spawner.data1 * 0.5f ),
le->data.spawner.data1 + (crandom() * le->data.spawner.data1),
0.8 /*+ crandom()*/,
0.0,
16.0f + random() * 45.0f,
0.5f,
7000,
cgs.media.smokeShader ); //flags
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
CG_LaunchGib( origin, velocity, cgs.media.gibChest );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
CG_LaunchGib( origin, velocity, cgs.media.gibFist );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
CG_LaunchGib( origin, velocity, cgs.media.gibFoot );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
CG_LaunchGib( origin, velocity, cgs.media.gibForearm );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
CG_LaunchGib( origin, velocity, cgs.media.gibIntestine );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
CG_LaunchGib( origin, velocity, cgs.media.gibLeg );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
CG_LaunchGib( origin, velocity, cgs.media.gibLeg );
return qtrue;
}
/*
==================
CG_LaunchGib
==================
======================
CG_Smoke
Creates a smoke effect
======================
*/
void CG_LaunchExplode( vec3_t origin, vec3_t velocity, qhandle_t hModel ) {
localEntity_t *le;
refEntity_t *re;
le = CG_AllocLocalEntity();
re = &le->refEntity;
le->leType = LE_FRAGMENT;
le->startTime = cg.time;
le->endTime = le->startTime + 10000 + random() * 6000;
VectorCopy( origin, re->origin );
AxisCopy( axisDefault, re->axis );
re->hModel = hModel;
le->pos.trType = TR_GRAVITY;
VectorCopy( origin, le->pos.trBase );
VectorCopy( velocity, le->pos.trDelta );
le->pos.trTime = cg.time;
le->bounceFactor = 0.1f;
le->leBounceSoundType = LEBS_BRASS;
le->leMarkType = LEMT_NONE;
void CG_Smoke( vec3_t position, vec3_t dir, int killTime, int radius )
{
//CG_Printf( " %f %f %f\n", dir[0], dir[1], dir[2] );
// give it a lifetime of 10 seconds because the refresh thinktime in g_fx.c is 10 seconds
FX_AddSpawner( position, dir, NULL, NULL, qfalse, 0, 0.15, killTime, SmokeThink, radius ); //
}
#define EXP_VELOCITY 100
#define EXP_JUMP 150
/*
===================
CG_GibPlayer
======================
FireThink
Generated a bunch of gibs launching out from the bodies location
===================
Engage fire effect
RPG-X | Marcin | 24/12/2008
======================
*/
void CG_BigExplode( vec3_t playerOrigin ) {
vec3_t origin, velocity;
qboolean FireThink( localEntity_t *le )
{
vec3_t direction;
vec3_t origin;
if ( !cg_blood.integer ) {
return;
}
VectorCopy( le->data.spawner.dir, direction );
VectorMA( le->refEntity.origin, 1, direction, origin );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*EXP_VELOCITY;
velocity[1] = crandom()*EXP_VELOCITY;
velocity[2] = EXP_JUMP + crandom()*EXP_VELOCITY;
CG_LaunchExplode( origin, velocity, cgs.media.smoke2 );
origin[2] += 60.0f / (80.0f / le->data.spawner.data1); // extra offset
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*EXP_VELOCITY;
velocity[1] = crandom()*EXP_VELOCITY;
velocity[2] = EXP_JUMP + crandom()*EXP_VELOCITY;
CG_LaunchExplode( origin, velocity, cgs.media.smoke2 );
FX_AddSprite( origin,
0,
qfalse,
le->data.spawner.data1,
0,
1.0f,
0.0f,
0,
0.5f,
600,
cgs.media.fireShader );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*EXP_VELOCITY*1.5;
velocity[1] = crandom()*EXP_VELOCITY*1.5;
velocity[2] = EXP_JUMP + crandom()*EXP_VELOCITY;
CG_LaunchExplode( origin, velocity, cgs.media.smoke2 );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*EXP_VELOCITY*2.0;
velocity[1] = crandom()*EXP_VELOCITY*2.0;
velocity[2] = EXP_JUMP + crandom()*EXP_VELOCITY;
CG_LaunchExplode( origin, velocity, cgs.media.smoke2 );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*EXP_VELOCITY*2.5;
velocity[1] = crandom()*EXP_VELOCITY*2.5;
velocity[2] = EXP_JUMP + crandom()*EXP_VELOCITY;
CG_LaunchExplode( origin, velocity, cgs.media.smoke2 );
return qtrue;
}
/*
======================
CG_Fire
Creates a fire effect
RPG-X | Marcin | 24/12/2008
======================
*/
void CG_Fire( vec3_t position, vec3_t direction, int killTime, int radius, int fxEnt )
{
if(fxEnt)
FX_AddSpawner( position, direction, NULL, NULL, qfalse, 500, 0, killTime + 1000, FireThink, radius );
else
FX_AddSpawner( position, direction, NULL, NULL, qfalse, 500, 0, killTime, FireThink, radius );
}
//localEntity_t *FX_AddSprite(vec3_t origin, vec3_t velocity, qboolean gravity, float scale, float dscale,
// float startalpha, float endalpha, float roll, float elasticity,
// float killTime, qhandle_t shader)

File diff suppressed because it is too large Load diff

2181
code/cgame/cg_env.c Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,37 +1,17 @@
/*
===========================================================================
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
===========================================================================
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_info.c -- display information while data is being loading
#include "cg_local.h"
#include "cg_text.h"
#define MAX_LOADING_PLAYER_ICONS 16
#define MAX_LOADING_ITEM_ICONS 26
static int loadingPlayerIconCount;
static int loadingItemIconCount;
static qhandle_t loadingPlayerIcons[MAX_LOADING_PLAYER_ICONS];
static qhandle_t loadingItemIcons[MAX_LOADING_ITEM_ICONS];
static qhandle_t loadingPlayerIcon;
static qhandle_t loadingItemIcon;
void CG_LoadBar(void);
/*
===================
@ -39,22 +19,23 @@ CG_DrawLoadingIcons
===================
*/
static void CG_DrawLoadingIcons( void ) {
int n;
// int n;
int x, y;
for( n = 0; n < loadingPlayerIconCount; n++ ) {
x = 16 + n * 78;
y = 324-40;
CG_DrawPic( x, y, 64, 64, loadingPlayerIcons[n] );
}
trap_R_SetColor( colorTable[CT_WHITE]);
for( n = 0; n < loadingItemIconCount; n++ ) {
y = 400-40;
if( n >= 13 ) {
y += 40;
}
x = 16 + n % 13 * 48;
CG_DrawPic( x, y, 32, 32, loadingItemIcons[n] );
x= 500;
y = 342;
if (loadingPlayerIcon)
{
CG_DrawPic( x, y, 64, 64, loadingPlayerIcon );
}
else if (loadingItemIcon)
{
trap_R_SetColor(colorTable[CT_LTPURPLE1]);
CG_DrawPic( x, y, 64, 64, cgs.media.weaponbox2 );
trap_R_SetColor( NULL);
CG_DrawPic( x, y, 64, 64, loadingItemIcon );
}
}
@ -80,9 +61,9 @@ void CG_LoadingItem( int itemNum ) {
gitem_t *item;
item = &bg_itemlist[itemNum];
if ( item->icon && loadingItemIconCount < MAX_LOADING_ITEM_ICONS ) {
loadingItemIcons[loadingItemIconCount++] = trap_R_RegisterShaderNoMip( item->icon );
if ( item->icon ) {
loadingItemIcon = trap_R_RegisterShaderNoMip( item->icon );
}
CG_LoadingString( item->pickup_name );
@ -102,39 +83,32 @@ void CG_LoadingClient( int clientNum ) {
info = CG_ConfigString( CS_PLAYERS + clientNum );
if ( loadingPlayerIconCount < MAX_LOADING_PLAYER_ICONS ) {
Q_strncpyz( model, Info_ValueForKey( info, "model" ), sizeof( model ) );
skin = strrchr( model, '/' );
if ( skin ) {
*skin++ = '\0';
} else {
skin = "default";
}
Com_sprintf( iconName, MAX_QPATH, "models/players/%s/icon_%s.tga", model, skin );
loadingPlayerIcons[loadingPlayerIconCount] = trap_R_RegisterShaderNoMip( iconName );
if ( !loadingPlayerIcons[loadingPlayerIconCount] ) {
Com_sprintf( iconName, MAX_QPATH, "models/players/characters/%s/icon_%s.tga", model, skin );
loadingPlayerIcons[loadingPlayerIconCount] = trap_R_RegisterShaderNoMip( iconName );
}
if ( !loadingPlayerIcons[loadingPlayerIconCount] ) {
Com_sprintf( iconName, MAX_QPATH, "models/players/%s/icon_%s.tga", DEFAULT_MODEL, "default" );
loadingPlayerIcons[loadingPlayerIconCount] = trap_R_RegisterShaderNoMip( iconName );
}
if ( loadingPlayerIcons[loadingPlayerIconCount] ) {
loadingPlayerIconCount++;
}
Q_strncpyz( model, Info_ValueForKey( info, "model" ), sizeof( model ) );
skin = strchr( model, '/' );
if ( skin ) {
//*skin++ = '\0';
//} else {
// skin = "default";
model[strlen(model) - strlen(skin)] = '\0';
}
//RPG-X: MODEL SYSTEM CHANGE
Com_sprintf( iconName, MAX_QPATH, "models/players_rpgx/%s/model_icon.jpg", model );
//Com_sprintf( iconName, MAX_QPATH, "models/players/%s/icon_%s.jpg", model, skin );
//CG_Printf( S_COLOR_RED "Loading %s\n", iconName );
loadingPlayerIcon = trap_R_RegisterShaderNoMip( iconName ); //iconName;
Q_strncpyz( personality, Info_ValueForKey( info, "n" ), sizeof(personality) );
Q_CleanStr( personality );
if( cgs.gametype == GT_SINGLE_PLAYER ) {
trap_S_RegisterSound( va( "sound/player/announce/%s.wav", personality ), qtrue );
}
trap_S_RegisterSound( va( "sound/voice/computer/misc/%s.wav", model ) ); //not exactly right since it'll miss subskins, but better than using personality
}//precache sound played in g_bot.c, PlayerIntroSound
CG_LoadingString( personality );
}
@ -143,17 +117,22 @@ void CG_LoadingClient( int clientNum ) {
CG_DrawInformation
Draw all the status / pacifier stuff during level loading
this overlays the ui version in ui_connect.c, UI_DrawConnectScreen
====================
*/
extern void CG_AddGameModNameToGameName( char *gamename );
void CG_DrawInformation( void ) {
const char *s;
const char *info;
const char *sysInfo;
int y;
int value;
int y,x;
// int value;
qhandle_t levelshot;
qhandle_t detail;
// qhandle_t detail;
char buf[1024];
int strlength,length;
//trap_Cvar_Set ("rpg_playIntro", "1");
info = CG_ConfigString( CS_SERVERINFO );
sysInfo = CG_ConfigString( CS_SYSTEMINFO );
@ -161,55 +140,94 @@ void CG_DrawInformation( void ) {
s = Info_ValueForKey( info, "mapname" );
levelshot = trap_R_RegisterShaderNoMip( va( "levelshots/%s.tga", s ) );
if ( !levelshot ) {
levelshot = trap_R_RegisterShaderNoMip( "menu/art/unknownmap" );
levelshot = trap_R_RegisterShaderNoMip( "levelshots/unknownmap" );
}
cgs.widescreen.state = WIDESCREEN_NONE;
trap_R_SetColor( colorTable[CT_BLACK] );
CG_DrawPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, cgs.media.whiteShader );
cgs.widescreen.state = WIDESCREEN_CENTER;
trap_R_SetColor( colorTable[CT_DKGREY] );
CG_DrawPic( 11, 60, 260, 196, cgs.media.whiteShader );
trap_R_SetColor( NULL );
CG_DrawPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, levelshot );
CG_DrawPic( 13, 62, 256, 192, levelshot ); //correct aspect
// trap_R_SetColor( colorTable[CT_LTGREY] );
// CG_DrawPic( 418, 82, 132, 132, cgs.media.whiteShader );
// trap_R_SetColor( NULL );
// CG_DrawPic( 420, 84, 128, 128, levelshot );
// blend a detail texture over it
detail = trap_R_RegisterShader( "levelShotDetail" );
trap_R_DrawStretchPic( 0, 0, cgs.glconfig.vidWidth, cgs.glconfig.vidHeight, 0, 0, 2.5, 2, detail );
// detail = trap_R_RegisterShader( "levelShotDetail" );
// trap_R_DrawStretchPic( 0, 0, cgs.glconfig.vidWidth, cgs.glconfig.vidHeight, 0, 0, 1, 1, detail );
// draw the icons of things as they are loaded
UI_DrawProportionalString( 10, 10, ingame_text[IGT_HOLODECKSIMULATION], UI_BIGFONT, colorTable[CT_LTORANGE] );
strlength = UI_ProportionalStringWidth(ingame_text[IGT_HOLODECKSIMULATION],UI_BIGFONT);
length = 582 - (strlength + 6);
trap_R_SetColor( colorTable[CT_DKORANGE]);
CG_DrawPic( 10 + strlength + 6, 11, length, 22,cgs.media.whiteShader);
// CG_DrawPic( 224, 11, 368, 22,cgs.media.whiteShader);
CG_DrawPic( 595, 11, 32, 32,cgs.media.halfroundr_22); // Right End
trap_R_SetColor( colorTable[CT_DKPURPLE1]);
CG_DrawPic( 274+333, 232, -32, 32,cgs.media.corner_12_18); // LR
CG_DrawPic( 274+333, 84, -32, -32,cgs.media.corner_12_18); // UR
CG_DrawPic( 274, 60, 314, 18,cgs.media.whiteShader); // Top
CG_DrawPic( 274, 238, 314, 18,cgs.media.whiteShader); //Bottom
CG_DrawPic( 274, 75, 10, 170,cgs.media.whiteShader); // Left
CG_DrawPic( 274+321, 78, 12, 162,cgs.media.whiteShader); // Right
CG_LoadBar();
// draw the icons of thiings as they are loaded
CG_DrawLoadingIcons();
// the first 150 rows are reserved for the client connection
// screen to write into
if ( cg.infoScreenText[0] ) {
UI_DrawProportionalString( 320, 128-32, va("Loading... %s", cg.infoScreenText),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
UI_DrawProportionalString( 320, 442, va("%s ... %s", ingame_text[IGT_LOADING], cg.infoScreenText),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_LTGOLD1]);
} else {
UI_DrawProportionalString( 320, 128-32, "Awaiting snapshot...",
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
UI_DrawProportionalString( 320, 442, va("%s...", ingame_text[IGT_SNAPSHOT]),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_LTGOLD1] );
}
// draw info string information
y = 180-32;
y = 107;
x = 288;
// don't print server lines if playing a local game
trap_Cvar_VariableStringBuffer( "sv_running", buf, sizeof( buf ) );
if ( !atoi( buf ) ) {
// server hostname
Q_strncpyz(buf, Info_ValueForKey( info, "sv_hostname" ), 1024);
Q_CleanStr(buf);
UI_DrawProportionalString( 320, y, buf,
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
UI_DrawProportionalString( x, y, buf, UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
// pure server
s = Info_ValueForKey( sysInfo, "sv_pure" );
if ( s[0] == '1' ) {
UI_DrawProportionalString( 320, y, "Pure Server",
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
UI_DrawProportionalString( x, y, ingame_text[IGT_PURESERVER],
UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
}
// server-specific message of the day
s = CG_ConfigString( CS_MOTD );
if ( s[0] ) {
UI_DrawProportionalString( 320, y, s,
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
UI_DrawProportionalString(320, y, s,
UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
}
@ -220,78 +238,631 @@ void CG_DrawInformation( void ) {
// map-specific message (long map name)
s = CG_ConfigString( CS_MESSAGE );
if ( s[0] ) {
UI_DrawProportionalString( 320, y, s,
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
UI_DrawProportionalString( x, y, s,
UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
}
// cheats warning
s = Info_ValueForKey( sysInfo, "sv_cheats" );
if ( s[0] == '1' ) {
UI_DrawProportionalString( 320, y, "CHEATS ARE ENABLED",
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
UI_DrawProportionalString( x, y, ingame_text[IGT_CHEATSAREENABLED],
UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
}
// RPG-X | Marcin | 24/12/2008
// privacy thing :p
// translate later
s = Info_ValueForKey( info, "rpg_respectPrivacy" );
if ( atoi( s ) != 0 ) {
UI_DrawProportionalString( x, y, "PRIVACY MODE ^5ON",
UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
} else {
UI_DrawProportionalString( x, y, "PRIVACY MODE ^1OFF",
UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
}
// game type
switch ( cgs.gametype ) {
switch ( cgs.gametype )
{
case GT_FFA:
s = "Free For All";
s = ingame_text[IGT_GAME_FREEFORALL];
break;
case GT_SINGLE_PLAYER:
s = "Single Player";
s = ingame_text[IGT_GAME_SINGLEPLAYER];
break;
case GT_TOURNAMENT:
s = "Tournament";
s = ingame_text[IGT_GAME_TOURNAMENT];
break;
case GT_TEAM:
s = "Team Deathmatch";
s = ingame_text[IGT_GAME_TEAMHOLOMATCH];
break;
case GT_CTF:
s = "Capture The Flag";
s = ingame_text[IGT_GAME_CAPTUREFLAG];
break;
#ifdef MISSIONPACK
case GT_1FCTF:
s = "One Flag CTF";
break;
case GT_OBELISK:
s = "Overload";
break;
case GT_HARVESTER:
s = "Harvester";
break;
#endif
default:
s = "Unknown Gametype";
s = ingame_text[IGT_GAME_UNKNOWN];
break;
}
UI_DrawProportionalString( 320, y, s,
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
{
char gamename[1024];
Q_strncpyz( gamename, s, sizeof(gamename) );
CG_AddGameModNameToGameName( gamename );
UI_DrawProportionalString( x, y, gamename, UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
}
y += PROP_HEIGHT;
value = atoi( Info_ValueForKey( info, "timelimit" ) );
/* value = atoi( Info_ValueForKey( info, "timelimit" ) );
if ( value ) {
UI_DrawProportionalString( 320, y, va( "timelimit %i", value ),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
UI_DrawProportionalString( x, y, va( "%s %i",ingame_text[IGT_TIME_LIMIT], value ),
UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
}
if (cgs.gametype < GT_CTF ) {
if (cgs.gametype != GT_CTF) {
value = atoi( Info_ValueForKey( info, "fraglimit" ) );
if ( value ) {
UI_DrawProportionalString( 320, y, va( "fraglimit %i", value ),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
UI_DrawProportionalString( x, y, va( "%s %i", ingame_text[IGT_POINT_LIMIT],value ),
UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
}
}
if (cgs.gametype >= GT_CTF) {
if (cgs.gametype == GT_CTF) {
value = atoi( Info_ValueForKey( info, "capturelimit" ) );
if ( value ) {
UI_DrawProportionalString( 320, y, va( "capturelimit %i", value ),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
UI_DrawProportionalString( x, y, va( "%s %i",ingame_text[IGT_CAPTURE_LIMIT], value ),
UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
}
}*/
cgs.widescreen.state = WIDESCREEN_NONE;
}
/*
====================
CG_LoadBar
====================
*/
void CG_LoadBar(void)
{
int x,y,pad;
// Round LCARS buttons
y = 309;
x = 10;
pad = 22;
// First Bit (0987)
if (cg.loadLCARSStage < 1)
{
trap_R_SetColor( colorTable[CT_VDKBROWN1]); //PURPLE3]);
}
else
{
trap_R_SetColor( colorTable[CT_VLTGOLD1]);
CG_DrawPic( x + 222 - 20,y + 14, 16, 16,cgs.media.circle2);
UI_DrawProportionalString( x + 222, y + 14, ingame_text[IGT_REPLICATION_MATRIX],UI_SMALLFONT, colorTable[CT_VLTGOLD1]);
trap_R_SetColor( colorTable[CT_LTBROWN1]); //VLTPURPLE3]);
}
CG_DrawPic( x + 18, y +102, 128, 64,cgs.media.loading1);
if (cg.loadLCARSStage < 2)
{
trap_R_SetColor( colorTable[CT_VDKBLUE1]);
}
else
{
trap_R_SetColor( colorTable[CT_VLTGOLD1]);
CG_DrawPic( x + 222 - 20,y + 14, 16, 16,cgs.media.circle);
trap_R_SetColor( colorTable[CT_LTBLUE1]);
}
CG_DrawPic( x, y + 37, 64, 64,cgs.media.loading2);
if (cg.loadLCARSStage < 3)
{
trap_R_SetColor( colorTable[CT_DKGOLD1]); //VDKPURPLE1]);
}
else
{
trap_R_SetColor( colorTable[CT_VLTGOLD1]);
CG_DrawPic( x + 222 - 20,y + 14+pad, 16, 16,cgs.media.circle2);
UI_DrawProportionalString( x + 222, y + 14 + pad, ingame_text[IGT_HOLOGRAPHIC_PROJECTORS],UI_SMALLFONT, colorTable[CT_VLTGOLD1]);
trap_R_SetColor( colorTable[CT_LTGOLD1]); //LTPURPLE1]);
}
CG_DrawPic( x + 17, y, 128, 64,cgs.media.loading3);
if (cg.loadLCARSStage < 4)
{
trap_R_SetColor( colorTable[CT_VDKBLUE1]); //VDKPURPLE2]);
}
else
{
trap_R_SetColor( colorTable[CT_VLTGOLD1]);
CG_DrawPic( x + 222 - 20,y + 14+pad, 16, 16,cgs.media.circle);
trap_R_SetColor( colorTable[CT_LTBLUE1]); //PURPLE2]);
}
CG_DrawPic( x + 99, y, 128, 128,cgs.media.loading4);
if (cg.loadLCARSStage < 5)
{
trap_R_SetColor( colorTable[CT_VDKBROWN1]); //BLUE2]);
}
else
{
trap_R_SetColor( colorTable[CT_VLTGOLD1]);
CG_DrawPic( x + 222 - 20,y + 14+pad+pad, 16, 16,cgs.media.circle2);
UI_DrawProportionalString( x + 222, y + 14 + pad + pad, ingame_text[IGT_SIMULATION_DATA_BASE],UI_SMALLFONT, colorTable[CT_VLTGOLD1]);
trap_R_SetColor( colorTable[CT_LTBROWN1]); //VLTBLUE2]);
}
CG_DrawPic( x +137, y + 81, 64, 64,cgs.media.loading5);
if (cg.loadLCARSStage < 6)
{
trap_R_SetColor( colorTable[CT_VDKRED1]); //ORANGE]);
}
else
{
trap_R_SetColor( colorTable[CT_VLTGOLD1]);
CG_DrawPic( x + 222 - 20,y + 14+pad+pad, 16, 16,cgs.media.circle);
trap_R_SetColor( colorTable[CT_DKRED1]); //LTORANGE]);
}
CG_DrawPic( x + 45, y + 99, 128, 64,cgs.media.loading6);
if (cg.loadLCARSStage < 7)
{
trap_R_SetColor( colorTable[CT_VDKRED1]); //BLUE2]);
}
else
{
trap_R_SetColor( colorTable[CT_VLTGOLD1]);
CG_DrawPic( x + 222 - 20,y + 14+pad+pad+pad, 16, 16,cgs.media.circle2);
UI_DrawProportionalString( x + 222, y + 14 + pad + pad + pad, ingame_text[IGT_SAFETY_LOCKS],UI_SMALLFONT, colorTable[CT_VLTGOLD1]);
trap_R_SetColor( colorTable[CT_DKRED1]); //LTBLUE2]);
}
CG_DrawPic( x + 38, y + 24, 64, 128,cgs.media.loading7);
if (cg.loadLCARSStage < 8)
{
trap_R_SetColor( colorTable[CT_VDKBROWN1]); //PURPLE1]);
}
else
{
trap_R_SetColor( colorTable[CT_VLTGOLD1]);
CG_DrawPic( x + 222 - 20,y + 14+pad+pad+pad, 16, 16,cgs.media.circle);
trap_R_SetColor( colorTable[CT_LTBROWN1]); //PURPLE1]);
}
CG_DrawPic( x + 78, y + 20, 128, 64,cgs.media.loading8);
if (cg.loadLCARSStage < 9)
{
trap_R_SetColor( colorTable[CT_VDKBLUE2]); //VDKBROWN1]);
}
else
{
trap_R_SetColor( colorTable[CT_DKBLUE2]); //VLTBROWN1]);
}
CG_DrawPic( x +112, y + 66, 64, 128,cgs.media.loading9);
if (cg.loadLCARSStage < 9)
{
trap_R_SetColor( colorTable[CT_VDKORANGE]); //DKBLUE2]);
}
else
{
trap_R_SetColor( colorTable[CT_LTORANGE]); //LTBLUE2]);
}
CG_DrawPic( x + 62, y + 44, 128, 128,cgs.media.loadingcircle); // Center arrows
cg.loadLCARScnt++;
if (cg.loadLCARScnt > 3)
{
cg.loadLCARScnt = 0;
}
trap_R_SetColor( colorTable[CT_VDKBLUE1]); //DKPURPLE2]);
CG_DrawPic( x + 61, y + 43, 32, 32,cgs.media.loadingquarter); // Quad UL
CG_DrawPic( x + 135, y + 43, -32, 32,cgs.media.loadingquarter); // Quad UR
CG_DrawPic( x + 135, y +117, -32, -32,cgs.media.loadingquarter); // Quad LR
CG_DrawPic( x + 61, y +117, 32, -32,cgs.media.loadingquarter); // Quad LL
trap_R_SetColor( colorTable[CT_LTBLUE1]); //LTPURPLE2]);
switch (cg.loadLCARScnt)
{
case 0 :
CG_DrawPic( x + 61, y + 43, 32, 32,cgs.media.loadingquarter); // Quad UL
break;
case 1 :
CG_DrawPic( x + 135, y + 43, -32, 32,cgs.media.loadingquarter); // Quad UR
break;
case 2 :
CG_DrawPic( x + 135, y +117, -32, -32,cgs.media.loadingquarter); // Quad LR
break;
case 3 :
CG_DrawPic( x + 61, y +117, 32, -32,cgs.media.loadingquarter); // Quad LL
break;
}
UI_DrawProportionalString( x + 21, y + 150, "0987",UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 3, y + 90, "18",UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 24, y + 20, "7",UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 93, y + 5, "51",UI_RIGHT|UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 103, y + 5, "35",UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 165, y + 83, "21",UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 101, y + 149, "67",UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 123, y + 36, "8",UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 90, y + 65, "1",UI_RIGHT|UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 105, y + 65, "2",UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 105, y + 87, "3",UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 91, y + 87, "4",UI_RIGHT|UI_TINYFONT, colorTable[CT_BLACK]);
trap_R_SetColor( colorTable[CT_DKGOLD1]); //DKBROWN1]);
y +=10;
CG_DrawPic( x + 130, y - 10 , 64, 16,cgs.media.loadingtrim);
CG_DrawPic( x + 130, y + 150, 64, -16,cgs.media.loadingtrim);
CG_DrawPic( x + 150, y - 10, 432, 8, cgs.media.whiteShader); // Top line
CG_DrawPic( x + 150, y + 142, 432, 8, cgs.media.whiteShader); // Bottom line
CG_DrawPic( x + 583, y - 7, 16, 151, cgs.media.whiteShader); // Side line
CG_DrawPic( x + 580, y + 1, 32, -16,cgs.media.loadingcorner);
CG_DrawPic( x + 580, y + 139, 32, 16,cgs.media.loadingcorner);
}
static int missionYcnt;
static int missionYpos;
static int missionInfoScreenY;
#define OBJ_HORIZONTAL_BORDER_X 15 // Where graphic starts
#define OBJ_HORIZONTAL_BORDER_WIDTH 30 // Thickness of graphic
#define OBJ_TEXT_X_BORDER_LEFT 10 // Distance from right edge of graphic to circle graphic
#define OBJ_TEXT_X_BORDER_RIGHT 10 // Distance from right edge of text to right edge of screen
#define OBJ_CIRCLE_SIZE 16 // Size of circle graphic
#define OBJ_CIRCLE_TEXT_MARGIN 4 // Distance between circle and text
#define OBJ_TEXT_XPOS (OBJ_HORIZONTAL_BORDER_X + OBJ_HORIZONTAL_BORDER_WIDTH + OBJ_TEXT_X_BORDER_LEFT)
#define OBJ_SCREEN_HEIGHT 428
#define OBJ_SCREEN_YMARGIN 8
#define OBJ_SCREEN_Y2MARGIN 4
#define OBJ_SCREEN_YBORDERTOP 20
#define OBJ_SCREEN_YBORDERBOT 8
#define OBJ_NORMAL_LINE_HEIGHT (PROP_HEIGHT * 1.15)
#define OBJ_ADDITIONAL_LINE_HEIGHT .20
/*
====================
ObjectivePrint_Line
====================
*/
static void ObjectivePrint_Line(int strIndex,int color,centity_t *cent)
{
char *str,*strBegin;
int y,pixelLen,charLen;
char holdText[1024], holdText2[2];
char finalText[MAX_OBJ_LENGTH];
int len,len_s,maxPixLength,charHeight;
assert(cgs.objectives[strIndex].text);
str = cgs.objectives[strIndex].text;
len = strlen(str);
len++;
Q_strncpyz(finalText,str,len);
len_s = strlen(str);
pixelLen = UI_ProportionalStringWidth(finalText,UI_SMALLFONT);
str = finalText;
maxPixLength = SCREEN_WIDTH - (OBJ_TEXT_XPOS + OBJ_TEXT_X_BORDER_RIGHT + OBJ_CIRCLE_SIZE + OBJ_CIRCLE_TEXT_MARGIN);
charHeight = OBJ_NORMAL_LINE_HEIGHT;
if (missionYcnt) // Not the very first objective to be printed?
{
missionYpos += (PROP_HEIGHT * OBJ_ADDITIONAL_LINE_HEIGHT); // Add a little space between objective lines
}
y =missionYpos + (charHeight * (missionYcnt));
trap_R_SetColor( colorTable[color]);
if (cgs.objectives[strIndex].complete)
{
CG_DrawPic( OBJ_TEXT_XPOS,y, OBJ_CIRCLE_SIZE, OBJ_CIRCLE_SIZE,cgs.media.circle);
}
else
{
CG_DrawPic( OBJ_TEXT_XPOS,y, OBJ_CIRCLE_SIZE, OBJ_CIRCLE_SIZE,cgs.media.circle2);
}
if (pixelLen < maxPixLength) // One shot - small enough to print entirely on one line
{
UI_DrawProportionalString(OBJ_TEXT_XPOS + OBJ_CIRCLE_SIZE + OBJ_CIRCLE_TEXT_MARGIN, y,str, UI_SMALLFONT, colorTable[color] );
++missionYcnt;
}
// Text is too long, break into lines.
else
{
pixelLen = 0;
charLen = 0;
holdText2[1] = '\0';
strBegin = str;
while( *str )
{
holdText2[0] = *str;
pixelLen += UI_ProportionalStringWidth(holdText2,UI_SMALLFONT);
pixelLen += 2; // For kerning
++charLen;
if (pixelLen > maxPixLength )
{ //Reached max length of this line
//step back until we find a space
while ((charLen) && (*str != ' ' ))
{
--str;
--charLen;
}
if (*str==' ')
{
++str; // To get past space
}
Q_strncpyz( holdText, strBegin, charLen);
holdText[charLen] = '\0';
strBegin = str;
pixelLen = 0;
charLen = 1;
y = missionYpos + (charHeight * missionYcnt);
UI_DrawProportionalString(OBJ_TEXT_XPOS + OBJ_CIRCLE_SIZE + OBJ_CIRCLE_TEXT_MARGIN, y, holdText, UI_SMALLFONT, colorTable[color] );
++missionYcnt;
}
else if (*(str+1) == '\0')
{
++charLen;
y = missionYpos + (charHeight * missionYcnt);
Q_strncpyz( holdText, strBegin, charLen);
UI_DrawProportionalString(OBJ_TEXT_XPOS + OBJ_CIRCLE_SIZE + OBJ_CIRCLE_TEXT_MARGIN, y, holdText, UI_SMALLFONT, colorTable[color] );
++missionYcnt;
break;
}
++str;
}
}
}
static int Objective_LineCnt(int strIndex,centity_t *cent)
{
char *str,*strBegin;
int pixelLen,charLen;
char holdText[1024], holdText2[2];
char finalText[MAX_OBJ_LENGTH];
int len,len_s,maxPixLength;
int lineCnt;
assert(cgs.objectives[strIndex].text);
str = cgs.objectives[strIndex].text;
len = strlen(str);
len++;
Q_strncpyz(finalText,str,len);
len_s = strlen(str);
pixelLen = UI_ProportionalStringWidth(finalText,UI_SMALLFONT);
lineCnt = 0;
maxPixLength = SCREEN_WIDTH - (OBJ_TEXT_XPOS + OBJ_TEXT_X_BORDER_RIGHT + OBJ_CIRCLE_SIZE + OBJ_CIRCLE_TEXT_MARGIN);
str = finalText;
if (pixelLen < maxPixLength) // One shot - small enough to print entirely on one line
{
lineCnt = 1;
}
// Text is too long, break into lines.
else
{
pixelLen = 0;
charLen = 0;
holdText2[1] = '\0';
strBegin = str;
while( *str )
{
holdText2[0] = *str;
pixelLen += UI_ProportionalStringWidth(holdText2,UI_SMALLFONT);
pixelLen += 2; // For kerning
++charLen;
if (pixelLen > maxPixLength )
{ //Reached max length of this line
//step back until we find a space
while ((charLen) && (*str != ' ' ))
{
--str;
--charLen;
}
if (*str==' ')
{
++str; // To get past space
}
Q_strncpyz( holdText, strBegin, charLen);
holdText[charLen] = '\0';
strBegin = str;
pixelLen = 0;
charLen = 1;
lineCnt++;
}
else if (*(str+1) == '\0')
{
++charLen;
lineCnt++;
break;
}
++str;
}
}
return (lineCnt);
}
/*
====================
Objectives_Draw
====================
*/
static void Objectives_Draw( centity_t *cent )
{
int objCnt,i,lineCnt,maxLines;
int total,textYCnt,length,color;
vec4_t newColor;
objCnt=0;
for (i=0;i<MAX_OBJECTIVES;i++)
{
if (cgs.objectives[i].text[0])
{
objCnt++;
}
}
lineCnt = 0;
// Count the number of lines.
for (i=0;i<objCnt;i++)
{
if (cgs.objectives[i].text[0])
{
lineCnt += Objective_LineCnt(i,cent);
}
}
maxLines = OBJ_SCREEN_HEIGHT /OBJ_NORMAL_LINE_HEIGHT;
if (lineCnt > maxLines) // Too many lines?
{
lineCnt = maxLines;
}
if (lineCnt==0) // Show there are no objectives
{
Q_strncpyz(cgs.objectives[0].text,ingame_text[IGT_NONETEXT],sizeof(cgs.objectives[0].text));
}
textYCnt = lineCnt * OBJ_NORMAL_LINE_HEIGHT;
// For the space between objectives
textYCnt += (objCnt-1) * (OBJ_ADDITIONAL_LINE_HEIGHT * PROP_HEIGHT);
// Calc starting Y of text
total = OBJ_SCREEN_YMARGIN + OBJ_SCREEN_YMARGIN + OBJ_SCREEN_Y2MARGIN + OBJ_SCREEN_Y2MARGIN +
OBJ_SCREEN_YBORDERTOP + OBJ_SCREEN_YBORDERBOT + textYCnt;
if (OBJ_SCREEN_HEIGHT < total) // This should never happen (but just in case)
{
total = OBJ_SCREEN_HEIGHT;
}
missionInfoScreenY = ((OBJ_SCREEN_HEIGHT - total) /2) + (OBJ_SCREEN_YMARGIN + OBJ_SCREEN_YBORDERTOP);
missionYcnt = 0;
missionYpos = missionInfoScreenY;
// Print top of frame
trap_R_SetColor( colorTable[CT_DKPURPLE3]);
CG_DrawPic( OBJ_HORIZONTAL_BORDER_X + 10, missionInfoScreenY - (OBJ_SCREEN_YMARGIN + OBJ_SCREEN_YBORDERTOP) ,
SCREEN_WIDTH - (OBJ_HORIZONTAL_BORDER_X + OBJ_TEXT_X_BORDER_RIGHT + 10), OBJ_SCREEN_YBORDERTOP, cgs.media.whiteShader); // Middle column
// Print bottom of frame
CG_DrawPic( OBJ_HORIZONTAL_BORDER_X + 10, missionInfoScreenY - OBJ_SCREEN_YMARGIN + textYCnt + (2 * OBJ_SCREEN_YMARGIN),
SCREEN_WIDTH - (OBJ_HORIZONTAL_BORDER_X + OBJ_TEXT_X_BORDER_RIGHT + 10), OBJ_SCREEN_YBORDERBOT, cgs.media.whiteShader); // Middle column
length = (missionInfoScreenY - OBJ_SCREEN_YMARGIN + textYCnt + (2 * OBJ_SCREEN_YMARGIN)) - (missionInfoScreenY - (OBJ_SCREEN_YMARGIN + OBJ_SCREEN_YBORDERTOP)) - 15;
// Print left hand column of frame
CG_DrawPic( OBJ_HORIZONTAL_BORDER_X, (missionInfoScreenY - (OBJ_SCREEN_YMARGIN + OBJ_SCREEN_YBORDERTOP)) + 10,
OBJ_HORIZONTAL_BORDER_WIDTH, length, cgs.media.whiteShader); // Middle column
// Top corner
trap_R_SetColor( colorTable[CT_DKPURPLE3]);
CG_DrawPic( OBJ_HORIZONTAL_BORDER_X,
missionInfoScreenY - (OBJ_SCREEN_YMARGIN + OBJ_SCREEN_YBORDERTOP),
32, 32, cgs.media.corner_ul_20_30); // Top corner
// Bottom corner
CG_DrawPic( OBJ_HORIZONTAL_BORDER_X,
(missionInfoScreenY - OBJ_SCREEN_YMARGIN + textYCnt + (2 * OBJ_SCREEN_YMARGIN))-5,
32, 32, cgs.media.corner_ll_8_30); // Bottom corner
UI_DrawProportionalString( OBJ_HORIZONTAL_BORDER_X + 30, missionInfoScreenY - (OBJ_SCREEN_YMARGIN + OBJ_SCREEN_YBORDERTOP) + 2, ingame_text[IGT_OBJECTIVES],UI_SMALLFONT, colorTable[CT_BLACK]);
// Print the background
newColor[0] = colorTable[CT_BLACK][0];
newColor[1] = colorTable[CT_BLACK][1];
newColor[2] = colorTable[CT_BLACK][2];
newColor[3] = 0.5;
trap_R_SetColor(newColor);
CG_DrawPic( (OBJ_TEXT_XPOS - OBJ_TEXT_X_BORDER_LEFT), missionInfoScreenY - OBJ_SCREEN_YMARGIN, SCREEN_WIDTH - ((OBJ_TEXT_XPOS - OBJ_TEXT_X_BORDER_LEFT)+OBJ_TEXT_X_BORDER_RIGHT) , textYCnt + (2 * OBJ_SCREEN_YMARGIN), cgs.media.whiteShader);
// Print the lines
for (i=0;i<objCnt;i++)
{
if (cgs.objectives[i].text[0])
{
if (cgs.objectives[i].complete)
{
color = CT_DKGOLD1;
}
else
{
color = CT_VLTGOLD1;
}
ObjectivePrint_Line(i,color,cent);
}
}
}
/*
====================
CG_DrawObjectiveInformation
====================
*/
void CG_DrawObjectiveInformation( void )
{
centity_t *cent;
// Don't show if dead
if (cg.predictedPlayerState.pm_type == PM_DEAD)
{
return;
}
cent = &cg_entities[cg.snap->ps.clientNum];
Objectives_Draw(cent);
}

View file

@ -0,0 +1,25 @@
/***************************************************
Copyright TiM - UberGames, 2005
cg_lensflares.c - Stores all of the functions
required to draw a dynamic lensflare ingame
The flare is broken up and drawn in separate passes:
Ambient Glow - Colored hazy glow (controlled by a vec4_t)
that expands around the core
Direct Glow - Much stronger glow that surrounds the
core directly
White Core - The actual white, focussed part of the flare
Anamorphic Streak - Horizontal line running through
the flare (Current rage in lensflare FX)
Lens Reflections - Circular parts that go in the opposite dir
of the flare itself
***************************************************/
//#include "cg_local.h"
//#include "cg_text.h"

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

373
code/cgame/cg_lua.c Normal file
View file

@ -0,0 +1,373 @@
// g_lua.c
#include "cg_lua.h"
#ifdef CG_LUA
lvm_t *lVM[NUM_VMS];
fileHandle_t lualog;
void QDECL LUA_DEBUG(const char *fmt, ...)
{
va_list argptr;
char text[1024];
if(cg_debugLua.integer >= 1)
{
va_start(argptr, fmt);
Com_sprintf(text, sizeof(text), fmt, argptr);
va_end(argptr);
CG_Printf(S_COLOR_YELLOW "LUA DEBUG:" S_COLOR_WHITE " %s\n", text);
}
}
void QDECL LUA_LOG(const char *fmt, ...)
{
va_list argptr;
char buff[1024], string[1024];
int min, tens, sec;
va_start(argptr, fmt);
Com_sprintf(buff, sizeof(buff), fmt, argptr);
va_end(argptr);
if(cg_logLua.integer) {
sec = cg.time / 1000;
min = sec / 60;
sec -= min * 60;
tens = sec / 10;
sec -= tens * 10;
Com_sprintf(string, sizeof(string), "%i:%i%i %s", min, tens, sec, buff);
trap_FS_Write(string, strlen(string), lualog);
}
}
qboolean LoadLuaFile(char *path, int num_vm)
{
int flen = 0;
char *code;
fileHandle_t f;
lvm_t *vm;
flen = trap_FS_FOpenFile(path, &f, FS_READ);
if(flen < 0)
{
LUA_LOG("Lua: can not open file %s\n", path);
CG_Printf(S_COLOR_YELLOW "Lua: can not open file %s\n", path);
trap_FS_FCloseFile(f);
return qfalse;
}
else
{
code = (char *)malloc(flen + 1);
if(!code) return qfalse;
trap_FS_Read(code, flen, f);
*(code + flen) = '\0';
trap_FS_FCloseFile(f);
vm = (lvm_t *) malloc(sizeof(lvm_t));
if(vm == NULL)
{
LUA_LOG("Lua: failed to allocate memory for lua VM\n");
CG_Printf(S_COLOR_YELLOW "Lua: failed to allocate memory for lua VM\n");
return qfalse;
}
memset(vm, 0, sizeof(lvm_t));
vm->id = -1;
Q_strncpyz(vm->filename, path, sizeof(vm->filename));
vm->code = code;
vm->code_size = flen;
vm->error = 0;
if(CG_LuaStartVM(vm) == qfalse)
{
CG_LuaStopVM(vm);
vm = NULL;
return qfalse;
}
else
{
vm->id = num_vm;
lVM[num_vm] = vm;
return qtrue;
}
}
//return qfalse;
}
qboolean CG_LuaInit()
{
char fxfilename[MAX_QPATH];
fileHandle_t fxfile;
CG_Printf("------- CG_LuaInit -------\n");
// read map fx file
// open log file
if(cg_logLua.integer) {
trap_FS_FOpenFile("cg_lua.log", &lualog, FS_APPEND);
}
CG_Printf("------- CG_LuaInit Finish -------\n");
return qtrue;
}
qboolean CG_LuaResume(lvm_t *vm, lua_State *T, char *func, int nargs) {
int res = lua_resume(T, nargs);
if(res == LUA_ERRRUN) {
LUA_LOG("Lua: %s error running lua script: %s\n", func, lua_tostring(T, -1));
CG_Printf(S_COLOR_YELLOW "Lua: %s error running lua script: %s\n", func, lua_tostring(T, -1));
lua_pop(T, 1);
vm->error++;
return qfalse;
} else if(res == LUA_ERRMEM) {
LUA_LOG("Lua: memory allocation error #2 ( %s )\n", vm->filename);
vm->error++;
return qfalse;
} else if(res == LUA_ERRERR) {
LUA_LOG("Lua: traceback error ( %s )\n", vm->filename);
CG_Printf(S_COLOR_YELLOW "Lua: traceback error ( %s )\n", vm->filename);
vm->error++;
return qfalse;
}
return qtrue;
}
qboolean CG_LuaCall(lvm_t * vm, char *func, int nargs, int nresults)
{
int res = lua_pcall(vm->L, nargs, nresults, 0);
if(res == LUA_ERRRUN)
{
LUA_LOG("Lua: %s error running lua script: %s\n", func, lua_tostring(vm->L, -1));
CG_Printf(S_COLOR_YELLOW "Lua: %s error running lua script: %s\n", func, lua_tostring(vm->L, -1));
lua_pop(vm->L, 1);
vm->error++;
return qfalse;
}
else if(res == LUA_ERRMEM)
{
LUA_LOG("Lua: memory allocation error #2 ( %s )\n", vm->filename);
vm->error++;
return qfalse;
}
else if(res == LUA_ERRERR)
{
LUA_LOG("Lua: traceback error ( %s )\n", vm->filename);
CG_Printf(S_COLOR_YELLOW "Lua: traceback error ( %s )\n", vm->filename);
vm->error++;
return qfalse;
}
return qtrue;
}
#define SAY_ALL 0
#define SAY_TEAM 1
qboolean CG_LuaGetFunctionT(lua_State *T, char *name)
{
if(T)
{
lua_getglobal(T, name);
if(lua_isfunction(T, -1))
{
return qtrue;
}
else
{
lua_pop(T, 1);
return qfalse;
}
}
return qfalse;
}
qboolean CG_LuaGetFunction(lvm_t * vm, char *name)
{
if(vm->L)
{
lua_getglobal(vm->L, name);
if(lua_isfunction(vm->L, -1))
{
return qtrue;
}
else
{
lua_pop(vm->L, 1);
return qfalse;
}
}
return qfalse;
}
qboolean CG_LuaStartVM(lvm_t * vm)
{
int res = 0;
char homepath[MAX_QPATH], gamepath[MAX_QPATH];
vm->L = luaL_newstate();
if(!vm->L)
{
LUA_LOG("Lua: Lua failed to initialise.\n");
return qfalse;
}
luaL_openlibs(vm->L);
trap_Cvar_VariableStringBuffer("fs_homepath", homepath, sizeof(homepath));
trap_Cvar_VariableStringBuffer("fs_game", gamepath, sizeof(gamepath));
lua_getglobal(vm->L, LUA_LOADLIBNAME);
if(lua_istable(vm->L, -1))
{
lua_pushstring(vm->L, va("%s%s%s%s?.lua;%s%s%s%slualib%slua%s?.lua",
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP,
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP));
lua_setfield(vm->L, -2, "path");
lua_pushstring(vm->L, va("%s%s%s%s?.%s;%s%s%s%slualib%sclibs%s?.%s",
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, EXTENSION,
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP, EXTENSION));
lua_setfield(vm->L, -2, "cpath");
}
lua_pop(vm->L, 1);
Lua_RegisterGlobal(vm->L, "LUA_PATH", va("%s%s%s%s?.lua;%s%s%s%slualib%slua%s?.lua",
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP,
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP));
Lua_RegisterGlobal(vm->L, "LUA_CPATH", va("%s%s%s%s?.%s;%s%s%s%slualib%sclibs%s?.%s",
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, EXTENSION,
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP, EXTENSION));
Lua_RegisterGlobal(vm->L, "LUA_DIRSEP", LUA_DIRSEP);
lua_newtable(vm->L);
Lua_RegConstInteger(vm->L, CS_PLAYERS);
Lua_RegConstInteger(vm->L, EXEC_NOW);
Lua_RegConstInteger(vm->L, EXEC_INSERT);
Lua_RegConstInteger(vm->L, EXEC_APPEND);
Lua_RegConstInteger(vm->L, FS_READ);
Lua_RegConstInteger(vm->L, FS_WRITE);
Lua_RegConstInteger(vm->L, FS_APPEND);
Lua_RegConstInteger(vm->L, FS_APPEND_SYNC);
Lua_RegConstInteger(vm->L, SAY_ALL);
Lua_RegConstInteger(vm->L, SAY_TEAM);
Lua_RegConstString(vm->L, HOSTARCH);
luaopen_base(vm->L);
luaopen_string(vm->L);
luaopen_coroutine(vm->L);
Luaopen_Qmath(vm->L);
Luaopen_Vector(vm->L);
res = luaL_loadbuffer(vm->L, vm->code, vm->code_size, vm->filename);
if(res == LUA_ERRSYNTAX)
{
LUA_LOG("Lua: syntax error during pre-compilation: %s\n", (char *)lua_tostring(vm->L, -1));
CG_Printf(S_COLOR_YELLOW "Lua: syntax error: %s\n", (char *)lua_tostring(vm->L, -1));
lua_pop(vm->L, 1);
vm->error++;
return qfalse;
}
else if(res == LUA_ERRMEM)
{
LUA_LOG("Lua: memory allocation error #1 ( %s )\n", vm->filename);
vm->error++;
return qfalse;
}
if(!CG_LuaCall(vm, "CG_LuaStartVM", 0, 0))
return qfalse;
LUA_LOG("Lua: Loading %s\n", vm->filename);
return qtrue;
}
void CG_LuaStopVM(lvm_t * vm)
{
if(vm == NULL)
return;
if(vm->code != NULL)
{
free(vm->code);
vm->code = NULL;
}
if(vm->id >= 0)
{
if(lVM[vm->id] == vm)
lVM[vm->id] = NULL;
if(!vm->error)
{
LUA_LOG("Lua: Lua module [%s] unloaded.\n", vm->filename);
}
}
free(vm);
}
void CG_LuaShutdown()
{
int i;
lvm_t *vm;
for(i = 0; i < NUM_VMS; i++)
{
vm = lVM[i];
if(vm)
{
CG_LuaStopVM(vm);
}
}
trap_FS_FCloseFile(lualog);
}
void CG_LuaStatus(void)
{
int i, cnt = 0;
for(i = 0; i < NUM_VMS; i++)
if(lVM[i])
cnt++;
if(cnt == 0)
{
CG_Printf("Lua: no scripts loaded.\n");
return;
}
else if(cnt == 1)
{
CG_Printf("Lua: showing lua information ( 1 module loaded )\n");
}
else
{
CG_Printf("Lua: showing lua information ( %d modules loaded )\n", cnt);
}
CG_Printf("%-2s %-24s\n", "VM", "Filename");
CG_Printf("-- ------------------------\n");
for(i = 0; i < NUM_VMS; i++)
{
if(lVM[i])
{
CG_Printf("%2d %-24s\n", lVM[i]->id, lVM[i]->filename);
}
}
CG_Printf("-- ------------------------\n");
}
lvm_t *CG_LuaGetVM(lua_State * L)
{
int i;
for(i = 0; i < NUM_VMS; i++)
if(lVM[i] && lVM[i]->L == L)
return lVM[i];
return NULL;
}
#endif

99
code/cgame/cg_lua.h Normal file
View file

@ -0,0 +1,99 @@
#ifndef _G_LUA_H
#define _G_LUA_H
#include "cg_local.h"
#if (defined __linux__ || defined __WIN32__) // linux or mingw
#include "../game/lua.h"
#include "../game/lauxlib.h"
#include "../game/lualib.h"
#else
#include "../game/lua.h"
#include "../game/lauxlib.h"
#include "../game/lualib.h"
#endif
#define NUM_VMS 1
#if defined __linux__
#define HOSTARCH "UNIX"
#define EXTENSION "so"
#elif defined WIN32
#define HOSTARCH "WIN32"
#define EXTENSION "dll"
#elif defined __APPLE__
#define HOSTARCH "UNIX"
#define EXTENSION "dylib"
#endif
#define Lua_RegisterGlobal(L, n, v) (lua_pushstring(L, v), lua_setglobal(L, n))
#define Lua_RegConstInteger(L, n) (lua_pushstring(L, #n), lua_pushinteger(L, n), lua_settable(L, -3))
#define Lua_RegConstString(L, n) (lua_pushstring(L, #n), lua_pushstring(L, n), lua_settable(L, -3))
typedef struct {
int id;
char filename[MAX_QPATH];
char *code;
int code_size;
int error;
lua_State *L;
} lvm_t;
extern lvm_t *lVM[NUM_VMS];
void QDECL LUA_DEBUG(const char *fmt, ...);
void QDECL LUA_LOG(const char *fmt, ...);
qboolean CG_LuaInit(void);
qboolean CG_LuaCall(lvm_t *vm, char *func, int nargs, int nresults);
qboolean CG_LuaResume(lvm_t *vm, lua_State *T, char *func, int nargs);
qboolean CG_LuaGetFunction(lvm_t *vm, char *name);
qboolean CG_LuaGetFunctionT(lua_State *T, char *name);
qboolean CG_LuaStartVM(lvm_t *vm);
void CG_LuaStopVM(lvm_t *vm);
void CG_LuaShutdown(void);
void CG_LuaStatus(void);
lvm_t *CG_LuaGetVM(lua_State *L);
// lua_cgame.c
int Luaopen_CGame(lua_State *L);
// lua_qmath.c
int Luaopen_Qmath(lua_State *L);
// lua_vector.c
int Luaopen_Vector(lua_State *L);
void Lua_PushVector(lua_State *L, vec3_t v);
vec_t *Lua_GetVector(lua_State *L, int argNum);
int Lua_IsVector(lua_State *L, int index);
vec3_t *Lua_GetVectorMisc(lua_State *L, int *index);
// lua_cfx.c
typedef struct {
char luaFunc[MAX_QPATH];
} cfx_t;
typedef struct {
cfx_t **cfx;
int cnt;
} cfxList_t;
void Lua_CFX_LoadMapFxFile(void);
// lua_cent.c
typedef struct {
centity_t *e;
} cent_t;
int Luaopen_Cent(lua_State *L);
void Lua_PushCent(lua_State *L, centity_t *ent);
cent_t *Lua_GetCent(lua_State *L, int argNum);
// lua_refent.c
typedef struct {
refEntity_t *r;
} rent_t;
int Luaopen_Rent(lua_State *L);
void Lua_PushRent(lua_State *L, refEntity_t *rent);
rent_t *Lua_GetRent(lua_State *L, int argNum);
#endif

File diff suppressed because it is too large Load diff

1792
code/cgame/cg_main.c.orig Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,24 +1,4 @@
/*
===========================================================================
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
===========================================================================
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_marks.c -- wall marks
@ -36,7 +16,6 @@ MARK POLYS
markPoly_t cg_activeMarkPolys; // double linked list
markPoly_t *cg_freeMarkPolys; // single linked list
markPoly_t cg_markPolys[MAX_MARK_POLYS];
static int markTotal;
/*
===================
@ -65,6 +44,8 @@ CG_FreeMarkPoly
==================
*/
void CG_FreeMarkPoly( markPoly_t *le ) {
if(!le) return;
if ( !le->prevMark ) {
CG_Error( "CG_FreeLocalEntity: not active" );
}
@ -140,18 +121,22 @@ void CG_ImpactMark( qhandle_t markShader, const vec3_t origin, const vec3_t dir,
vec3_t markPoints[MAX_MARK_POINTS];
vec3_t projection;
#ifdef _DEBUG
if (!markShader)
{
Com_Printf("CG_ImpactMark: NULL shader\n");
}
#endif
if ( !cg_addMarks.integer ) {
return;
}
if ( radius <= 0 ) {
CG_Error( "CG_ImpactMark called with <= 0 radius" );
//CG_Error( "CG_ImpactMark called with <= 0 radius" );
return;
}
//if ( markTotal >= MAX_MARK_POLYS ) {
// return;
//}
// create the texture axis
VectorNormalize2( dir, axis[0] );
PerpendicularVector( axis[1], axis[0] );
@ -217,7 +202,6 @@ void CG_ImpactMark( qhandle_t markShader, const vec3_t origin, const vec3_t dir,
mark->color[2] = blue;
mark->color[3] = alpha;
memcpy( mark->verts, verts, mf->numPoints * sizeof( verts[0] ) );
markTotal++;
}
}
@ -227,8 +211,9 @@ void CG_ImpactMark( qhandle_t markShader, const vec3_t origin, const vec3_t dir,
CG_AddMarks
===============
*/
#define MARK_TOTAL_TIME 10000
#define MARK_FADE_TIME 1000
#define MARK_TOTAL_TIME 500000
#define MARK_FADE_TIME 50000
#define MARK_DIV_3000 1.0/3000.0
void CG_AddMarks( void ) {
int j;
@ -255,7 +240,7 @@ void CG_AddMarks( void ) {
// fade out the energy bursts
if ( mp->markShader == cgs.media.energyMarkShader ) {
fade = 450 - 450 * ( (cg.time - mp->time ) / 3000.0 );
fade = 450 - 450 * ( (cg.time - mp->time ) * MARK_DIV_3000 );
if ( fade < 255 ) {
if ( fade < 0 ) {
fade = 0;
@ -291,3 +276,4 @@ void CG_AddMarks( void ) {
trap_R_AddPolyToScene( mp->markShader, mp->poly.numVerts, mp->verts );
}
}

View file

@ -0,0 +1,84 @@
#include "cg_local.h"
#define MAX_MOTIONBLURDOTS 20
typedef struct motionblurDot_s {
qboolean active;
refEntity_t refEnt;
int startTime;
int lifeTime;
} motionblurDot_t;
//static motionblurDot_t cg_motionblurDots[MAX_MOTIONBLURDOTS];
void CG_MotionBlur(void) {
//motionblurDot_t *dot;
//vec3_t pos, axis[3];
//int i;
/*if ( !cg.snap->ps.powerups[PW_BOOST] && cg.snap->ps.timers[tmZanzoken] < 1 && !cg.snap->ps.timers[tmTransform]) {
cg.refdef.rdflags &= ~RDF_MOTIONBLUR;
//for ( i = 0; i < MAX_MOTIONBLURDOTS; i++ ) {
// cg_motionblurDots[i].active = qfalse;
//}
return;
}*/
cg.refdef.rdflags |= RDF_MOTIONBLUR;
/*
// Destroy dots over lifetime
for ( i = 0; i < MAX_MOTIONBLURDOTS; i++ ) {
dot = &cg_motionblurDots[i];
if ( dot->lifeTime + dot->startTime < cg.time ) {
dot->active = qfalse;
}
}
// Create new dots
for ( i = 0; i < MAX_MOTIONBLURDOTS; i++ ) {
dot = &cg_motionblurDots[i];
if ( dot->active )
continue;
VectorCopy( cg.predictedPlayerEntity.lerpOrigin, pos );
VectorNormalize2( cg.predictedPlayerState.velocity, axis[0] );
VectorMA( pos, 300, axis[0], pos );
RotateAroundDirection( axis, crandom() * 360 );
VectorMA( pos, 120, axis[2], pos );
memset( &(dot->refEnt), 0, sizeof(refEntity_t));
dot->refEnt.reType = RT_SPRITE;
dot->refEnt.radius = 2;
dot->refEnt.customShader = cgs.media.whiteShader;
dot->refEnt.shaderRGBA[0] = 255;
dot->refEnt.shaderRGBA[1] = 255;
dot->refEnt.shaderRGBA[2] = 255;
dot->refEnt.shaderRGBA[3] = 128;
VectorCopy( pos, dot->refEnt.origin );
dot->lifeTime = 250 + crandom() * 100;
dot->startTime = cg.time + crandom() * 150;
dot->active = qtrue;
}
// Render dots
for ( i = 0; i < MAX_MOTIONBLURDOTS; i++ ) {
dot = &cg_motionblurDots[i];
if ( dot->startTime > cg.time )
continue;
trap_R_AddRefEntityToScene( &(dot->refEnt));
}
*/
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,24 +1,4 @@
/*
===========================================================================
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
===========================================================================
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_playerstate.c -- this file acts on changes in a new playerState_t
// With normal play, this will be done after local prediction, but when
@ -40,21 +20,33 @@ void CG_CheckAmmo( void ) {
int previous;
int weapons;
if ( cg.lowAmmoWarning > 2 )
{//a timed message, draws for a specific amount of time
if ( cg.lowAmmoWarning > cg.frametime )
{
cg.lowAmmoWarning -= cg.frametime;
}
else
{
cg.lowAmmoWarning = 0;
}
return;
}
// see about how many seconds of ammo we have remaining
weapons = cg.snap->ps.stats[ STAT_WEAPONS ];
total = 0;
for ( i = WP_MACHINEGUN ; i < WP_NUM_WEAPONS ; i++ ) {
//TiM
//for ( i = WP_5 ; i < WP_NUM_WEAPONS ; i++ ) {
for ( i = WP_1 ; i < WP_NUM_WEAPONS ; i++ ) {
if ( ! ( weapons & ( 1 << i ) ) ) {
continue;
}
switch ( i ) {
case WP_ROCKET_LAUNCHER:
case WP_GRENADE_LAUNCHER:
case WP_RAILGUN:
case WP_SHOTGUN:
#ifdef MISSIONPACK
case WP_PROX_LAUNCHER:
#endif
case WP_10:
case WP_8:
case WP_1:
case WP_6:
total += cg.snap->ps.ammo[i] * 1000;
break;
default:
@ -76,9 +68,10 @@ void CG_CheckAmmo( void ) {
}
// play a sound on transitions
if ( cg.lowAmmoWarning != previous ) {
// RPG-X | Phenix | 13/02/2005
/*if ( cg.lowAmmoWarning != previous ) {
trap_S_StartLocalSound( cgs.media.noAmmoSound, CHAN_LOCAL_SOUND );
}
}*/
}
/*
@ -86,7 +79,7 @@ void CG_CheckAmmo( void ) {
CG_DamageFeedback
==============
*/
void CG_DamageFeedback( int yawByte, int pitchByte, int damage ) {
void CG_DamageFeedback( int yawByte, int pitchByte, int damage, int shielddamage ) {
float left, front, up;
float kick;
int health;
@ -106,7 +99,8 @@ void CG_DamageFeedback( int yawByte, int pitchByte, int damage ) {
} else {
scale = 40.0 / health;
}
kick = damage * scale;
kick = (damage + shielddamage*0.5) * scale;
if (kick < 5)
kick = 5;
@ -140,7 +134,7 @@ void CG_DamageFeedback( int yawByte, int pitchByte, int damage ) {
dir[2] = 0;
dist = VectorLength( dir );
if ( dist < 0.1 ) {
dist = 0.1f;
dist = 0.1;
}
cg.v_dmg_roll = kick * left;
@ -148,7 +142,7 @@ void CG_DamageFeedback( int yawByte, int pitchByte, int damage ) {
cg.v_dmg_pitch = -kick * front;
if ( front <= 0.1 ) {
front = 0.1f;
front = 0.1;
}
cg.damageX = -left / front;
cg.damageY = up / dist;
@ -169,11 +163,25 @@ void CG_DamageFeedback( int yawByte, int pitchByte, int damage ) {
cg.damageY = -1.0;
}
// don't let the screen flashes vary as much
if ( kick > 10 ) {
kick = 10;
cg.damageValue = damage * scale;
if (cg.damageValue > 10)
{
cg.damageValue = 1.0;
}
cg.damageValue = kick;
else
{
cg.damageValue *= 0.1;
}
cg.damageShieldValue = shielddamage;
if (cg.damageShieldValue > 10)
{
cg.damageShieldValue = 1.0;
}
else
{
cg.damageShieldValue *= 0.1;
}
cg.v_dmg_time = cg.time + DAMAGE_TIME;
cg.damageTime = cg.snap->serverTime;
}
@ -199,7 +207,6 @@ void CG_Respawn( void ) {
cg.weaponSelect = cg.snap->ps.weapon;
}
extern char *eventnames[];
/*
==============
@ -226,104 +233,56 @@ void CG_CheckPlayerstateEvents( playerState_t *ps, playerState_t *ops ) {
// or the server told us to play another event instead of a predicted event we already issued
// or something the server told us changed our prediction causing a different event
|| (i > ops->eventSequence - MAX_PS_EVENTS && ps->events[i & (MAX_PS_EVENTS-1)] != ops->events[i & (MAX_PS_EVENTS-1)]) ) {
event = ps->events[ i & (MAX_PS_EVENTS-1) ];
cent->currentState.event = event;
cent->currentState.eventParm = ps->eventParms[ i & (MAX_PS_EVENTS-1) ];
CG_EntityEvent( cent, cent->lerpOrigin );
cg.predictableEvents[ i & (MAX_PREDICTED_EVENTS-1) ] = event;
// cg.predictableEvents[ i & (MAX_PREDICTED_EVENTS-1) ] = event;
cg.eventSequence++;
// cg.eventSequence++;
}
}
}
/*
==================
CG_CheckChangedPredictableEvents
==================
*/
void CG_CheckChangedPredictableEvents( playerState_t *ps ) {
int i;
int event;
centity_t *cent;
cent = &cg.predictedPlayerEntity;
for ( i = ps->eventSequence - MAX_PS_EVENTS ; i < ps->eventSequence ; i++ ) {
//
if (i >= cg.eventSequence) {
continue;
}
// if this event is not further back in than the maximum predictable events we remember
if (i > cg.eventSequence - MAX_PREDICTED_EVENTS) {
// if the new playerstate event is different from a previously predicted one
if ( ps->events[i & (MAX_PS_EVENTS-1)] != cg.predictableEvents[i & (MAX_PREDICTED_EVENTS-1) ] ) {
event = ps->events[ i & (MAX_PS_EVENTS-1) ];
cent->currentState.event = event;
cent->currentState.eventParm = ps->eventParms[ i & (MAX_PS_EVENTS-1) ];
CG_EntityEvent( cent, cent->lerpOrigin );
cg.predictableEvents[ i & (MAX_PREDICTED_EVENTS-1) ] = event;
if ( cg_showmiss.integer ) {
CG_Printf("WARNING: changed predicted event\n");
}
}
}
}
}
/*
==================
pushReward
==================
*/
static void pushReward(sfxHandle_t sfx, qhandle_t shader, int rewardCount) {
if (cg.rewardStack < (MAX_REWARDSTACK-1)) {
cg.rewardStack++;
cg.rewardSound[cg.rewardStack] = sfx;
cg.rewardShader[cg.rewardStack] = shader;
cg.rewardCount[cg.rewardStack] = rewardCount;
}
}
/*
==================
CG_CheckLocalSounds
==================
*/
void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) {
int highScore, reward;
#ifdef MISSIONPACK
int health, armor;
#endif
sfxHandle_t sfx;
void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops )
{
// int highScore;
// don't play the sounds if the player just changed teams
if ( ps->persistant[PERS_TEAM] != ops->persistant[PERS_TEAM] ) {
return;
}
// The most important thing to know is if you are doing damage.
//RPG-X - TiM
/*if ( ps->persistant[PERS_HITS] > ops->persistant[PERS_HITS] )
{
int diffhit, diffshields;
// hit changes
if ( ps->persistant[PERS_HITS] > ops->persistant[PERS_HITS] ) {
#ifdef MISSIONPACK
armor = ps->persistant[PERS_ATTACKEE_ARMOR] & 0xff;
health = ps->persistant[PERS_ATTACKEE_ARMOR] >> 8;
if (armor > 50 ) {
trap_S_StartLocalSound( cgs.media.hitSoundHighArmor, CHAN_LOCAL_SOUND );
} else if (armor || health > 100) {
trap_S_StartLocalSound( cgs.media.hitSoundLowArmor, CHAN_LOCAL_SOUND );
} else {
diffhit = ps->persistant[PERS_HITS] - ops->persistant[PERS_HITS];
diffshields = ps->persistant[PERS_SHIELDS] - ops->persistant[PERS_SHIELDS];
if (diffshields > diffhit/2)
{ // We also hit shields along the way, so consider them "pierced".
trap_S_StartLocalSound( cgs.media.shieldPierceSound, CHAN_LOCAL_SOUND );
}
else
{ // Shields didn't really stand in our way.
trap_S_StartLocalSound( cgs.media.hitSound, CHAN_LOCAL_SOUND );
}
#else
trap_S_StartLocalSound( cgs.media.hitSound, CHAN_LOCAL_SOUND );
#endif
} else if ( ps->persistant[PERS_HITS] < ops->persistant[PERS_HITS] ) {
}
// The second most important thing to worry about is whether you hurt a friend.
else if ( ps->persistant[PERS_HITS] < ops->persistant[PERS_HITS] )
{
trap_S_StartLocalSound( cgs.media.hitTeamSound, CHAN_LOCAL_SOUND );
}
// Finally if all this damage bounced off the shields, indicate this.
else if (ps->persistant[PERS_SHIELDS] > ops->persistant[PERS_SHIELDS])
{
// hit shields and the damage didn't go through
trap_S_StartLocalSound( cgs.media.shieldHitSound, CHAN_LOCAL_SOUND );
}*/
// health changes of more than -1 should make pain sounds
if ( ps->stats[STAT_HEALTH] < ops->stats[STAT_HEALTH] - 1 ) {
@ -339,104 +298,79 @@ void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) {
}
// reward sounds
reward = qfalse;
if (ps->persistant[PERS_CAPTURES] != ops->persistant[PERS_CAPTURES]) {
pushReward(cgs.media.captureAwardSound, cgs.media.medalCapture, ps->persistant[PERS_CAPTURES]);
reward = qtrue;
//Com_Printf("capture\n");
}
if (ps->persistant[PERS_IMPRESSIVE_COUNT] != ops->persistant[PERS_IMPRESSIVE_COUNT]) {
#ifdef MISSIONPACK
if (ps->persistant[PERS_IMPRESSIVE_COUNT] == 1) {
sfx = cgs.media.firstImpressiveSound;
} else {
sfx = cgs.media.impressiveSound;
//RPG-X: RedTechie - No reward or frag limit sounds
/*if ( ps->persistant[PERS_REWARD_COUNT] > ops->persistant[PERS_REWARD_COUNT] ) {
switch ( ps->persistant[PERS_REWARD] ) {
case REWARD_IMPRESSIVE:
trap_S_StartLocalSound( cgs.media.rewardImpressiveSound, CHAN_ANNOUNCER );
cg.rewardTime = cg.time;
cg.rewardShader = cgs.media.medalImpressive;
cg.rewardCount = ps->persistant[PERS_IMPRESSIVE_COUNT];
break;
case REWARD_EXCELLENT:
trap_S_StartLocalSound( cgs.media.rewardExcellentSound, CHAN_ANNOUNCER );
cg.rewardTime = cg.time;
cg.rewardShader = cgs.media.medalExcellent;
cg.rewardCount = ps->persistant[PERS_EXCELLENT_COUNT];
break;
case REWARD_DENIED:
trap_S_StartLocalSound( cgs.media.rewardDeniedSound, CHAN_ANNOUNCER );
break;
case REWARD_FIRST_STRIKE:
trap_S_StartLocalSound( cgs.media.rewardFirstStrikeSound, CHAN_ANNOUNCER);
cg.rewardTime = cg.time;
cg.rewardShader = cgs.media.medalFirstStrike;
cg.rewardCount = 1;
break;
case REWARD_STREAK:
// Play a different sound depending on how long the streak is.
cg.rewardTime = cg.time;
cg.rewardCount = 1;
if (ps->persistant[PERS_STREAK_COUNT] >= STREAK_CHAMPION)
{
trap_S_StartLocalSound( cgs.media.rewardChampionSound, CHAN_ANNOUNCER);
cg.rewardShader = cgs.media.medalChampion;
}
else if (ps->persistant[PERS_STREAK_COUNT] >= STREAK_MASTER)
{
trap_S_StartLocalSound( cgs.media.rewardMasterSound, CHAN_ANNOUNCER);
cg.rewardShader = cgs.media.medalMaster;
}
else if (ps->persistant[PERS_STREAK_COUNT] >= STREAK_EXPERT)
{
trap_S_StartLocalSound( cgs.media.rewardExpertSound, CHAN_ANNOUNCER);
cg.rewardShader = cgs.media.medalExpert;
}
else if (ps->persistant[PERS_STREAK_COUNT] >= STREAK_ACE)
{
trap_S_StartLocalSound( cgs.media.rewardAceSound, CHAN_ANNOUNCER);
cg.rewardShader = cgs.media.medalAce;
}
break;
default:
CG_Error( "Bad reward_t" );
}
#else
sfx = cgs.media.impressiveSound;
#endif
pushReward(sfx, cgs.media.medalImpressive, ps->persistant[PERS_IMPRESSIVE_COUNT]);
reward = qtrue;
//Com_Printf("impressive\n");
}
if (ps->persistant[PERS_EXCELLENT_COUNT] != ops->persistant[PERS_EXCELLENT_COUNT]) {
#ifdef MISSIONPACK
if (ps->persistant[PERS_EXCELLENT_COUNT] == 1) {
sfx = cgs.media.firstExcellentSound;
} else {
sfx = cgs.media.excellentSound;
}
#else
sfx = cgs.media.excellentSound;
#endif
pushReward(sfx, cgs.media.medalExcellent, ps->persistant[PERS_EXCELLENT_COUNT]);
reward = qtrue;
//Com_Printf("excellent\n");
}
if (ps->persistant[PERS_GAUNTLET_FRAG_COUNT] != ops->persistant[PERS_GAUNTLET_FRAG_COUNT]) {
#ifdef MISSIONPACK
if (ops->persistant[PERS_GAUNTLET_FRAG_COUNT] == 1) {
sfx = cgs.media.firstHumiliationSound;
} else {
sfx = cgs.media.humiliationSound;
}
#else
sfx = cgs.media.humiliationSound;
#endif
pushReward(sfx, cgs.media.medalGauntlet, ps->persistant[PERS_GAUNTLET_FRAG_COUNT]);
reward = qtrue;
//Com_Printf("guantlet frag\n");
}
if (ps->persistant[PERS_DEFEND_COUNT] != ops->persistant[PERS_DEFEND_COUNT]) {
pushReward(cgs.media.defendSound, cgs.media.medalDefend, ps->persistant[PERS_DEFEND_COUNT]);
reward = qtrue;
//Com_Printf("defend\n");
}
if (ps->persistant[PERS_ASSIST_COUNT] != ops->persistant[PERS_ASSIST_COUNT]) {
pushReward(cgs.media.assistSound, cgs.media.medalAssist, ps->persistant[PERS_ASSIST_COUNT]);
reward = qtrue;
//Com_Printf("assist\n");
}
// if any of the player event bits changed
if (ps->persistant[PERS_PLAYEREVENTS] != ops->persistant[PERS_PLAYEREVENTS]) {
if ((ps->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_DENIEDREWARD) !=
(ops->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_DENIEDREWARD)) {
trap_S_StartLocalSound( cgs.media.deniedSound, CHAN_ANNOUNCER );
}
else if ((ps->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_GAUNTLETREWARD) !=
(ops->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_GAUNTLETREWARD)) {
trap_S_StartLocalSound( cgs.media.humiliationSound, CHAN_ANNOUNCER );
}
else if ((ps->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_HOLYSHIT) !=
(ops->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_HOLYSHIT)) {
trap_S_StartLocalSound( cgs.media.holyShitSound, CHAN_ANNOUNCER );
}
reward = qtrue;
}
// check for flag pickup
if ( cgs.gametype > GT_TEAM ) {
if ((ps->powerups[PW_REDFLAG] != ops->powerups[PW_REDFLAG] && ps->powerups[PW_REDFLAG]) ||
(ps->powerups[PW_BLUEFLAG] != ops->powerups[PW_BLUEFLAG] && ps->powerups[PW_BLUEFLAG]) ||
(ps->powerups[PW_NEUTRALFLAG] != ops->powerups[PW_NEUTRALFLAG] && ps->powerups[PW_NEUTRALFLAG]) )
} else {
// lead changes (only if no reward)
if ( !cg.warmup && !(cg.predictedPlayerState.introTime > cg.time) )
{
trap_S_StartLocalSound( cgs.media.youHaveFlagSound, CHAN_ANNOUNCER );
}
}
// lead changes
if (!reward) {
//
if ( !cg.warmup ) {
// never play lead changes during warmup
// never play lead changes during warmup or holo doors
if ( ps->persistant[PERS_RANK] != ops->persistant[PERS_RANK] ) {
if ( cgs.gametype < GT_TEAM) {
if ( cgs.gametype >= GT_TEAM ) {
if ( ps->persistant[PERS_RANK] == 2 ) {
trap_S_StartLocalSound( cgs.media.teamsTiedSound, CHAN_ANNOUNCER );
} else if ( ps->persistant[PERS_RANK] == 0 ) {
trap_S_StartLocalSound( cgs.media.redLeadsSound, CHAN_ANNOUNCER );
} else if ( ps->persistant[PERS_RANK] == 1 ) {
trap_S_StartLocalSound( cgs.media.blueLeadsSound, CHAN_ANNOUNCER );
}
} else {
if ( ps->persistant[PERS_RANK] == 0 ) {
CG_AddBufferedSound(cgs.media.takenLeadSound);
trap_S_StartLocalSound( cgs.media.takenLeadSound, CHAN_ANNOUNCER );
} else if ( ps->persistant[PERS_RANK] == RANK_TIED_FLAG ) {
CG_AddBufferedSound(cgs.media.tiedLeadSound);
trap_S_StartLocalSound( cgs.media.tiedLeadSound, CHAN_ANNOUNCER );
} else if ( ( ops->persistant[PERS_RANK] & ~RANK_TIED_FLAG ) == 0 ) {
CG_AddBufferedSound(cgs.media.lostLeadSound);
trap_S_StartLocalSound( cgs.media.lostLeadSound, CHAN_ANNOUNCER );
}
}
}
@ -448,43 +382,71 @@ void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) {
int msec;
msec = cg.time - cgs.levelStartTime;
if ( !( cg.timelimitWarnings & 4 ) && msec > ( cgs.timelimit * 60 + 2 ) * 1000 ) {
cg.timelimitWarnings |= 1 | 2 | 4;
trap_S_StartLocalSound( cgs.media.suddenDeathSound, CHAN_ANNOUNCER );
}
else if ( !( cg.timelimitWarnings & 2 ) && msec > (cgs.timelimit - 1) * 60 * 1000 ) {
cg.timelimitWarnings |= 1 | 2;
trap_S_StartLocalSound( cgs.media.oneMinuteSound, CHAN_ANNOUNCER );
}
else if ( cgs.timelimit > 5 && !( cg.timelimitWarnings & 1 ) && msec > (cgs.timelimit - 5) * 60 * 1000 ) {
if ( cgs.timelimit > 5 && !( cg.timelimitWarnings & 1 ) && msec > (cgs.timelimit - 5) * 60 * 1000 ) {
cg.timelimitWarnings |= 1;
trap_S_StartLocalSound( cgs.media.fiveMinuteSound, CHAN_ANNOUNCER );
}
if ( !( cg.timelimitWarnings & 2 ) && msec > (cgs.timelimit - 1) * 60 * 1000 ) {
cg.timelimitWarnings |= 2;
trap_S_StartLocalSound( cgs.media.oneMinuteSound, CHAN_ANNOUNCER );
}
if ( !( cg.timelimitWarnings & 4 ) && msec > ( cgs.timelimit * 60 + 2 ) * 1000 ) {
cg.timelimitWarnings |= 4;
trap_S_StartLocalSound( cgs.media.suddenDeathSound, CHAN_ANNOUNCER );
}
}
// fraglimit warnings
if ( cgs.fraglimit > 0 && cgs.gametype < GT_CTF) {
if ( cgs.fraglimit > 0 && cgs.gametype != GT_CTF ) {
highScore = cgs.scores1;
if (cgs.gametype == GT_TEAM && cgs.scores2 > highScore) {
highScore = cgs.scores2;
}
if ( !( cg.fraglimitWarnings & 4 ) && highScore == (cgs.fraglimit - 1) ) {
cg.fraglimitWarnings |= 1 | 2 | 4;
CG_AddBufferedSound(cgs.media.oneFragSound);
}
else if ( cgs.fraglimit > 2 && !( cg.fraglimitWarnings & 2 ) && highScore == (cgs.fraglimit - 2) ) {
cg.fraglimitWarnings |= 1 | 2;
CG_AddBufferedSound(cgs.media.twoFragSound);
}
else if ( cgs.fraglimit > 3 && !( cg.fraglimitWarnings & 1 ) && highScore == (cgs.fraglimit - 3) ) {
if ( cgs.fraglimit > 3 && !( cg.fraglimitWarnings & 1 ) && highScore == (cgs.fraglimit - 3) ) {
cg.fraglimitWarnings |= 1;
CG_AddBufferedSound(cgs.media.threeFragSound);
trap_S_StartLocalSound( cgs.media.threeFragSound, CHAN_ANNOUNCER );
}
}
if ( cgs.fraglimit > 2 && !( cg.fraglimitWarnings & 2 ) && highScore == (cgs.fraglimit - 2) ) {
cg.fraglimitWarnings |= 2;
trap_S_StartLocalSound( cgs.media.twoFragSound, CHAN_ANNOUNCER );
}
if ( !( cg.fraglimitWarnings & 4 ) && highScore == (cgs.fraglimit - 1) ) {
cg.fraglimitWarnings |= 4;
trap_S_StartLocalSound( cgs.media.oneFragSound, CHAN_ANNOUNCER );
}
}*/
}
void CG_CheckDamageDealt(playerState_t *ps, playerState_t *ops)
{
static int damagetime;
static int damageamount;
if (cg_reportDamage.integer)
{
if (ps->persistant[PERS_HITS] > ops->persistant[PERS_HITS])
{ // We did some damage this frame.
if (damagetime+1000 < cg.time)
{ // Start a new tally.
damageamount = ps->persistant[PERS_HITS] - ops->persistant[PERS_HITS];
damagetime = cg.time;
}
else
{ // Add to a tally that's already here.
damageamount += ps->persistant[PERS_HITS] - ops->persistant[PERS_HITS];
}
}
// Report the sum of damage done this second.
if (damageamount > 0 && (damagetime+1000 <= cg.time))
{
Com_Printf("Damage this second: %d\n", damageamount);
damageamount = 0;
}
}
}
/*
===============
CG_TransitionPlayerState
@ -500,8 +462,8 @@ void CG_TransitionPlayerState( playerState_t *ps, playerState_t *ops ) {
}
// damage events (player is getting wounded)
if ( ps->damageEvent != ops->damageEvent && ps->damageCount ) {
CG_DamageFeedback( ps->damageYaw, ps->damagePitch, ps->damageCount );
if ( ps->damageEvent != ops->damageEvent && (ps->damageCount || ps->damageShieldCount)) {
CG_DamageFeedback( ps->damageYaw, ps->damagePitch, ps->damageCount, ps->damageShieldCount);
}
// respawning
@ -509,13 +471,13 @@ void CG_TransitionPlayerState( playerState_t *ps, playerState_t *ops ) {
CG_Respawn();
}
if ( cg.mapRestart ) {
/* if ( cg.mapRestart ) { //q3 update -not tested yet
CG_Respawn();
cg.mapRestart = qfalse;
}
*/
if ( cg.snap->ps.pm_type != PM_INTERMISSION
&& ps->persistant[PERS_TEAM] != TEAM_SPECTATOR ) {
&& ps->persistant[PERS_TEAM] != TEAM_SPECTATOR /*&& !(ps->eFlags&EF_ELIMINATED)*/) {
CG_CheckLocalSounds( ps, ops );
}
@ -530,5 +492,9 @@ void CG_TransitionPlayerState( playerState_t *ps, playerState_t *ops ) {
cg.duckChange = ps->viewheight - ops->viewheight;
cg.duckTime = cg.time;
}
#ifdef _DEBUG
CG_CheckDamageDealt(ps, ops);
#endif //_DEBUG
}

View file

@ -1,24 +1,4 @@
/*
===========================================================================
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
===========================================================================
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_predict.c -- this file generates cg.predictedPlayerState by either
// interpolating between snapshots from the server or locally predicting
@ -82,6 +62,8 @@ CG_ClipMoveToEntities
====================
*/
#define SHIELD_HALFTHICKNESS 4 // should correspond with the #define in g_active.c
static void CG_ClipMoveToEntities ( const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end,
int skipNumber, int mask, trace_t *tr ) {
int i, x, zd, zu;
@ -105,11 +87,71 @@ static void CG_ClipMoveToEntities ( const vec3_t start, const vec3_t mins, const
cmodel = trap_CM_InlineModel( ent->modelindex );
VectorCopy( cent->lerpAngles, angles );
BG_EvaluateTrajectory( &cent->currentState.pos, cg.physicsTime, origin );
} else {
}
else if (ent->eFlags & EF_SHIELD_BOX_X)
{ // "specially" encoded bbox for x-axis aligned shield
//CG_Printf( S_COLOR_RED "Mins[ %d %d %d ] Maxs[ %d %d %d ]\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2] );
//this is a bit of a hack. Only deny entry to elements
//that do not specifiy collision boundaries.
//This will mean things like players won't be affected
//(there'll be a slight jerk as the server boots them back)
//but any FX like phaser beams will be.
if ( !mins || !VectorCompare( mins, vec3_origin ) || !VectorCompare( maxs, vec3_origin ) )
continue;
/*x = (ent->solid & 255); // i on server side
zd = ((ent->solid>>8) & 255); // j on server side
zu = ((ent->solid>>16) & 255); // k on server side*/
x = (ent->time2 & 1023); // i on server side
zd = ((ent->time2>>10) & 1023); // j on server side
zu = ((ent->time2>>20) & 1023); // k on server side
bmins[0] = -x; //-zd
bmaxs[0] = zd; //x
bmins[1] = -SHIELD_HALFTHICKNESS;
bmaxs[1] = SHIELD_HALFTHICKNESS;
bmins[2] = 0;
bmaxs[2] = zu;
cmodel = trap_CM_TempBoxModel( bmins, bmaxs );
VectorCopy( vec3_origin, angles );
VectorCopy( cent->lerpOrigin, origin );
//CG_Printf( S_COLOR_RED "X Aligned! Bmins = [ %f %f %f ],\nBMaxs = [%f %f %f]\n", bmins[0], bmins[1], bmins[2], bmaxs[0],bmaxs[1],bmaxs[2] );
}
else if (ent->eFlags & EF_SHIELD_BOX_Y)
{ // "specially" encoded bbox for y-axis aligned shield
/*x = (ent->solid & 255); // i on server side
zd = ((ent->solid>>8) & 255); // j on server side
zu = ((ent->solid>>16) & 255); // k on server side*/
if ( !VectorCompare( mins, vec3_origin ) || !VectorCompare( maxs, vec3_origin ) )
continue;
x = (ent->time2 & 1023); // i on server side
zd = ((ent->time2>>10) & 1023); // j on server side
zu = ((ent->time2>>20) & 1023); // k on server side
bmins[1] = -x;
bmaxs[1] = zd;
bmins[0] = -SHIELD_HALFTHICKNESS;
bmaxs[0] = SHIELD_HALFTHICKNESS;
bmins[2] = 0;
bmaxs[2] = zu;
cmodel = trap_CM_TempBoxModel( bmins, bmaxs );
VectorCopy( vec3_origin, angles );
VectorCopy( cent->lerpOrigin, origin );
}
else
{
// encoded bbox
x = (ent->solid & 255);
zd = ((ent->solid>>8) & 255);
zu = ((ent->solid>>16) & 255) - 32;
x = (ent->solid & 255); // i on server side
zd = ((ent->solid>>8) & 255); // j on server side
zu = ((ent->solid>>16) & 255) - 32; // k on server side
bmins[0] = bmins[1] = -x;
bmaxs[0] = bmaxs[1] = x;
@ -186,7 +228,7 @@ int CG_PointContents( const vec3_t point, int passEntityNum ) {
continue;
}
contents |= trap_CM_TransformedPointContents( point, cmodel, cent->lerpOrigin, cent->lerpAngles );
contents |= trap_CM_TransformedPointContents( point, cmodel, ent->origin, ent->angles );
}
return contents;
@ -261,19 +303,27 @@ CG_TouchItem
static void CG_TouchItem( centity_t *cent ) {
gitem_t *item;
//RPG-X | Marcin | 03/12/2008
//this can't be predicted because as don't know whether USE was pressed...
if (qtrue) {
return;
}
if ( !cg_predictItems.integer ) {
return;
}
if ( !BG_PlayerTouchesItem( &cg.predictedPlayerState, &cent->currentState, cg.time ) ) {
return;
}
// never pick an item up twice in a prediction
if ( cent->miscTime == cg.time ) {
return;
}
if ( !BG_PlayerTouchesItem( &cg.predictedPlayerState, &cent->currentState, cg.time ) ) {
return;
}
if ( !BG_CanItemBeGrabbed( cgs.gametype, &cent->currentState, &cg.predictedPlayerState ) ) {
// RPG-X: Marcin: Can't predict this any more sorry - 30/12/2008
if ( 0 ) /* ( !BG_CanItemBeGrabbed( &cent->currentState, &cg.predictedPlayerState ) ) */ {
return; // can't hold it
}
@ -281,38 +331,45 @@ static void CG_TouchItem( centity_t *cent ) {
// Special case for flags.
// We don't predict touching our own flag
#ifdef MISSIONPACK
if( cgs.gametype == GT_1FCTF ) {
if( item->giTag != PW_NEUTRALFLAG ) {
if (item->giType == IT_TEAM)
{ // NOTE: This code used to JUST check giTag. The problem is that the giTag for PW_REDFLAG
// is the same as WP_9. The giTag should be a SUBCHECK after giType.
/*if (cg.predictedPlayerState.persistant[PERS_TEAM] == TEAM_RED &&
item->giTag == PW_REDFLAG)
return;*/
if (cg.predictedPlayerState.persistant[PERS_TEAM] == TEAM_BLUE &&
item->giTag == PW_BORG_ADAPT)
return;
}
if (!(cent->currentState.eFlags & (EF_ITEMPLACEHOLDER | EF_NODRAW)))
{
// grab it
BG_AddPredictableEventToPlayerstate( EV_ITEM_PICKUP, cent->currentState.modelindex , &cg.predictedPlayerState);
// Draw the techy-itemplaceholder for weapons and powerups, not ammo, etc.
if (item->giType == IT_WEAPON || item->giType == IT_POWERUP)
{ // draw it "gridded out"
cent->currentState.eFlags |= EF_ITEMPLACEHOLDER;
}
else
{ // remove it from the frame so it won't be drawn
cent->currentState.eFlags |= EF_NODRAW;
// kef -- special client-only flag to prevent double pickup sounds
//cent->currentState.eFlags |= EF_CLIENT_NODRAW;
}
// if its a weapon, give them some predicted ammo so the autoswitch will work
if ( item->giType == IT_WEAPON )
{
cg.predictedPlayerState.stats[ STAT_WEAPONS ] |= 1 << item->giTag;
if ( !cg.predictedPlayerState.ammo[ item->giTag ] ) {
cg.predictedPlayerState.ammo[ item->giTag ] = 1;
}
}
}
#endif
if( cgs.gametype == GT_CTF ) {
if (cg.predictedPlayerState.persistant[PERS_TEAM] == TEAM_RED &&
item->giTag == PW_REDFLAG)
return;
if (cg.predictedPlayerState.persistant[PERS_TEAM] == TEAM_BLUE &&
item->giTag == PW_BLUEFLAG)
return;
}
// grab it
BG_AddPredictableEventToPlayerstate( EV_ITEM_PICKUP, cent->currentState.modelindex , &cg.predictedPlayerState);
// remove it from the frame so it won't be drawn
cent->currentState.eFlags |= EF_NODRAW;
// don't touch it again this prediction
cent->miscTime = cg.time;
// if it's a weapon, give them some predicted ammo so the autoswitch will work
if ( item->giType == IT_WEAPON ) {
cg.predictedPlayerState.stats[ STAT_WEAPONS ] |= 1 << item->giTag;
if ( !cg.predictedPlayerState.ammo[ item->giTag ] ) {
cg.predictedPlayerState.ammo[ item->giTag ] = 1;
}
}
}
@ -368,21 +425,35 @@ static void CG_TouchTriggerPrediction( void ) {
}
if ( ent->eType == ET_TELEPORT_TRIGGER ) {
cg.hyperspace = qtrue;
} else if ( ent->eType == ET_PUSH_TRIGGER ) {
BG_TouchJumpPad( &cg.predictedPlayerState, ent );
//cg.hyperspace = qtrue;
continue;
} else {
float s;
vec3_t dir;
// we hit this push trigger
if ( spectator ) {
continue;
}
// flying characters don't hit bounce pads
if ( cg.predictedPlayerState.powerups[PW_FLIGHT] ) {
continue;
}
// if we are already flying along the bounce direction, don't play sound again
VectorNormalize2( ent->origin2, dir );
s = DotProduct( cg.predictedPlayerState.velocity, dir );
if ( s < 500 ) {
// don't play the event sound again if we are in a fat trigger
BG_AddPredictableEventToPlayerstate( EV_JUMP_PAD, 0, &cg.predictedPlayerState );
}
VectorCopy( ent->origin2, cg.predictedPlayerState.velocity );
}
}
// if we didn't touch a jump pad this pmove frame
if ( cg.predictedPlayerState.jumppad_frame != cg.predictedPlayerState.pmove_framecount ) {
cg.predictedPlayerState.jumppad_frame = 0;
cg.predictedPlayerState.jumppad_ent = 0;
}
}
/*
=================
CG_PredictPlayerState
@ -415,6 +486,7 @@ void CG_PredictPlayerState( void ) {
qboolean moved;
usercmd_t oldestCmd;
usercmd_t latestCmd;
char temp_string[200];
cg.hyperspace = qfalse; // will be set if touching a trigger_teleport
@ -424,6 +496,11 @@ void CG_PredictPlayerState( void ) {
if ( !cg.validPPS ) {
cg.validPPS = qtrue;
cg.predictedPlayerState = cg.snap->ps;
// if we need to, we should check our model cvar and update it with the right value from the userinfo strings
// since it may have been modified by the server
Com_sprintf(temp_string, sizeof(temp_string), "%s/%s/%s", cgs.clientinfo[cg.predictedPlayerState.clientNum].charName, cgs.clientinfo[cg.predictedPlayerState.clientNum].modelName,
cgs.clientinfo[cg.predictedPlayerState.clientNum].skinName);
updateSkin(cg.predictedPlayerState.clientNum, temp_string);
}
@ -443,16 +520,22 @@ void CG_PredictPlayerState( void ) {
cg_pmove.ps = &cg.predictedPlayerState;
cg_pmove.trace = CG_Trace;
cg_pmove.pointcontents = CG_PointContents;
cg_pmove.admin = cgs.clientinfo[cg.snap->ps.clientNum].isAdmin;
cg_pmove.medic = cgs.classData[cgs.clientinfo[cg.snap->ps.clientNum].pClass].isMedic;
cg_pmove.borg = cgs.classData[cgs.clientinfo[cg.snap->ps.clientNum].pClass].isBorg;
if ( cg_pmove.ps->pm_type == PM_DEAD ) {
cg_pmove.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY;
}
else {
cg_pmove.tracemask = MASK_PLAYERSOLID;
}
if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR ) {
if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR /*|| (cg.snap->ps.eFlags&EF_ELIMINATED)*/ ) {
cg_pmove.tracemask &= ~CONTENTS_BODY; // spectators can fly through bodies
}
cg_pmove.noFootsteps = ( cgs.dmflags & DF_NO_FOOTSTEPS ) > 0;
cg_pmove.pModDisintegration = cgs.pModDisintegration > 0;
// save the state before the pmove so we can detect transitions
oldPlayerState = cg.predictedPlayerState;
@ -487,26 +570,12 @@ void CG_PredictPlayerState( void ) {
cg.physicsTime = cg.snap->serverTime;
}
if ( pmove_msec.integer < 8 ) {
trap_Cvar_Set("pmove_msec", "8");
}
else if (pmove_msec.integer > 33) {
trap_Cvar_Set("pmove_msec", "33");
}
cg_pmove.pmove_fixed = pmove_fixed.integer;// | cg_pmove_fixed.integer;
cg_pmove.pmove_msec = pmove_msec.integer;
// run cmds
moved = qfalse;
for ( cmdNum = current - CMD_BACKUP + 1 ; cmdNum <= current ; cmdNum++ ) {
// get the command
trap_GetUserCmd( cmdNum, &cg_pmove.cmd );
if ( cg_pmove.pmove_fixed ) {
PM_UpdateViewAngles( cg_pmove.ps, &cg_pmove.cmd );
}
// don't do anything if the time is before the snapshot player time
if ( cg_pmove.cmd.serverTime <= cg.predictedPlayerState.commandTime ) {
continue;
@ -517,6 +586,14 @@ void CG_PredictPlayerState( void ) {
continue;
}
/*if (cg.predictedPlayerState.introTime > cg.time) //what's this for? TiM: I think it's for the holoIntro...
{
cg_pmove.cmd.buttons = 0;
cg_pmove.cmd.weapon = 0;
// cg_pmove.cmd.angles[0] = cg_pmove.cmd.angles[1] = cg_pmove.cmd.angles[2] = 0;
cg_pmove.cmd.forwardmove = cg_pmove.cmd.rightmove = cg_pmove.cmd.upmove = 0;
}*/
// check for a prediction error from last frame
// on a lan, this will often be the exact value
// from the snapshot, but on a wan we will have
@ -571,23 +648,12 @@ void CG_PredictPlayerState( void ) {
}
}
// don't predict gauntlet firing, which is only supposed to happen
// when it actually inflicts damage
cg_pmove.gauntletHit = qfalse;
if ( cg_pmove.pmove_fixed ) {
cg_pmove.cmd.serverTime = ((cg_pmove.cmd.serverTime + pmove_msec.integer-1) / pmove_msec.integer) * pmove_msec.integer;
}
Pmove (&cg_pmove);
moved = qtrue;
// add push trigger movement effects
CG_TouchTriggerPrediction();
// check for predictable events that changed from previous predictions
//CG_CheckChangedPredictableEvents(&cg.predictedPlayerState);
}
if ( cg_showmiss.integer > 1 ) {
@ -615,12 +681,13 @@ void CG_PredictPlayerState( void ) {
// fire events and other transition triggered things
CG_TransitionPlayerState( &cg.predictedPlayerState, &oldPlayerState );
if ( cg_showmiss.integer ) {
/* if ( cg_showmiss.integer ) {
if (cg.eventSequence > cg.predictedPlayerState.eventSequence) {
CG_Printf("WARNING: double event\n");
cg.eventSequence = cg.predictedPlayerState.eventSequence;
}
}
*/
}

View file

@ -1,27 +1,11 @@
/*
===========================================================================
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
===========================================================================
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
#define CMD_BACKUP 64
#define CMD_MASK (CMD_BACKUP - 1)
// allow a lot of command backups for very fast systems
@ -53,13 +37,6 @@ typedef struct {
int serverCommandSequence; // snapshot becomes current
} snapshot_t;
enum {
CGAME_EVENT_NONE,
CGAME_EVENT_TEAMMENU,
CGAME_EVENT_SCOREBOARD,
CGAME_EVENT_EDITHUD
};
/*
==================================================================
@ -69,8 +46,9 @@ functions imported from the main executable
==================================================================
*/
#define CGAME_IMPORT_API_VERSION 4
#define CGAME_IMPORT_API_VERSION 3
//these must match up with cg_syscalls.asm
typedef enum {
CG_PRINT,
CG_ERROR,
@ -133,7 +111,7 @@ typedef enum {
CG_MEMORY_REMAINING,
CG_R_REGISTERSHADER3D, //59
CG_CVAR_SET_NO_MODIFY, // 60
CG_R_REMAP_SHADER,
CG_R_REMAP_SHADER,
CG_MEMSET = 100,
CG_MEMCPY,
@ -147,6 +125,8 @@ typedef enum {
CG_TESTPRINTINT,
CG_TESTPRINTFLOAT,
} cgameImport_t;
//these must match up with cg_syscalls.asm
/*
@ -159,7 +139,7 @@ functions exported to the main executable
typedef enum {
CG_INIT,
// void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum )
// void CG_Init( int serverMessageNum, int serverCommandSequence )
// called when the level loads or when the renderer is restarted
// all media should be registered at this time
// cgame will display loading status by calling SCR_Update, which
@ -186,7 +166,7 @@ typedef enum {
CG_CROSSHAIR_PLAYER,
// int (*CG_CrosshairPlayer)( void );
CG_LAST_ATTACKER,
CG_LAST_ATTACKER
// int (*CG_LastAttacker)( void );
} cgameExport_t;

File diff suppressed because it is too large Load diff

434
code/cgame/cg_screenfx.c Normal file
View file

@ -0,0 +1,434 @@
#include "cg_local.h"
#include "cg_screenfx.h"
// this is the list of currently drawing fx and their start times and end times
screenFX_t theScreenFX;
int CG_GetScreenEffectEndTime(int event)
{
switch (event)
{
case SCREENFX_TRANSPORTER:
return cg.time + 1000;
case SCREENFX_SP_TRANSPORTER_IN:
return cg.time + 4000;
case SCREENFX_SP_TRANSPORTER_OUT:
return cg.time + 8000;
default:
return 0;
}
}
// maybe play a sound or something?
void CG_BeginScreenEffect(int event)
{
switch (event)
{
case SCREENFX_TRANSPORTER:
break;
default:
break;
}
}
// when adding a new effect, we'll either take an empty slot in theScreenFX or
//overwrite the oldest effect
void CG_AddFullScreenEffect(int screenfx, int clientNum)
{
int i = 0, oldestTime = cg.time, oldestEffect = 0;
if (clientNum != cg.predictedPlayerState.clientNum)
{ // only add screen effects for our client
return;
}
for (i = 0; i < MAX_SCREENFX; i++)
{
// if we already have one of these effects going, just add to the duration of
//the existing one...don't create a new instance of the same effect
if (theScreenFX.events[i] == screenfx)
{
theScreenFX.cgStartTimes[i] = cg.time;
theScreenFX.cgEndTimes[i] = CG_GetScreenEffectEndTime(screenfx);
return;
}
else if (theScreenFX.cgStartTimes[i])
{
if (theScreenFX.cgStartTimes[i] < oldestTime)
{
oldestTime = theScreenFX.cgStartTimes[i];
oldestEffect = i;
}
}
//Hack-didily-ack - TiM: If were already one powerup, switch to the next
else if ( screenfx == SCREENFX_SP_TRANSPORTER_OUT ) {
if ( theScreenFX.events[i] == SCREENFX_SP_TRANSPORTER_IN ) {
theScreenFX.events[i] = 0;
theScreenFX.cgStartTimes[i] = 0;
theScreenFX.cgEndTimes[i] = 0;
}
}
else if ( screenfx == SCREENFX_SP_TRANSPORTER_IN ) {
if ( theScreenFX.events[i] == SCREENFX_SP_TRANSPORTER_OUT ) {
theScreenFX.events[i] = 0;
theScreenFX.cgStartTimes[i] = 0;
theScreenFX.cgEndTimes[i] = 0;
}
}
else
{
oldestTime = theScreenFX.cgStartTimes[i];
oldestEffect = i;
}
}
theScreenFX.events[oldestEffect] = screenfx;
theScreenFX.cgStartTimes[oldestEffect] = cg.time;
theScreenFX.cgEndTimes[oldestEffect] = CG_GetScreenEffectEndTime(screenfx);
CG_BeginScreenEffect(screenfx);
}
/*
===============
CG_DrawScreenQuad
===============
*/
static void CG_DrawScreenQuad(float alpha, qhandle_t screenshader)
{
refEntity_t ent;
float radius;
// ragePro systems can't fade blends, so don't obscure the screen
if ( cgs.glconfig.hardwareType == GLHW_RAGEPRO ) {
return;
}
if (cg.refdef.fov_x > 120)
{
return; // Too wide to show this.
}
else if (cg.refdef.fov_x > 80)
{
radius = 8.0 + (cg.refdef.fov_x - 80)*0.2;
}
else
{
radius = 8.0;
}
memset( &ent, 0, sizeof( ent ) );
ent.reType = RT_SPRITE;
ent.renderfx = RF_FIRST_PERSON;
VectorMA( cg.refdef.vieworg, 8, cg.refdef.viewaxis[0], ent.origin );
ent.data.sprite.radius = radius;
ent.customShader = screenshader;
ent.shaderRGBA[0] = alpha * 255;
ent.shaderRGBA[1] = alpha * 255;
ent.shaderRGBA[2] = alpha * 255;
ent.shaderRGBA[3] = 255;
trap_R_AddRefEntityToScene( &ent );
}
/*
static void CG_DrawDirectionalScreenQuad(float alpha, qhandle_t screenshader)
{
refEntity_t ent;
vec3_t screencenter;
byte topleft, topright, lowleft, lowright, top, low, left, right;
float val;
// ragePro systems can't fade blends, so don't obscure the screen
if ( cgs.glconfig.hardwareType == GLHW_RAGEPRO ) {
return;
}
// Set up all the basic info about this refentity
VectorMA( cg.refdef.vieworg, 8, cg.refdef.viewaxis[0], screencenter);
memset( &ent, 0, sizeof( ent ) );
ent.reType = RT_ALPHAVERTPOLY;
ent.renderfx = RF_FIRST_PERSON;
ent.data.sprite.radius = 4;
ent.customShader = screenshader;
* (unsigned int *) ent.shaderRGBA = 0xffffffff;
* (unsigned int *) ent.data.sprite.vertRGBA[0] = 0xffffffff;
* (unsigned int *) ent.data.sprite.vertRGBA[1] = 0xffffffff;
* (unsigned int *) ent.data.sprite.vertRGBA[2] = 0xffffffff;
* (unsigned int *) ent.data.sprite.vertRGBA[3] = 0xffffffff;
// left
val = alpha*(0.5 + 0.5*(cg.damageX - fabs(cg.damageY)));
if (val<0)
left=0;
else if (val>1.0)
left=255;
else
left=255.0*val;
// upper left
val = alpha*(0.5*(cg.damageX + cg.damageY));
if (val<0)
topleft=0;
else if (val>1.0)
topleft=255;
else
topleft=255.0*val;
// top
val = alpha*(0.5 + 0.5*(-fabs(cg.damageX) + cg.damageY));
if (val<0)
top=0;
else if (val>1.0)
top=255;
else
top=255.0*val;
// upper right
val = alpha*(0.5*(-cg.damageX + cg.damageY));
if (val<0)
topright=0;
else if (val>1.0)
topright=255;
else
topright=255.0*val;
// right
val = alpha*(0.5 + 0.5*(-cg.damageX - fabs(cg.damageY)));
if (val<0)
right=0;
else if (val>1.0)
right=255;
else
right=255.0*val;
// lower right
val = alpha*(0.5*(-cg.damageX - cg.damageY));
if (val<0)
lowright=0;
else if (val>1.0)
lowright=255;
else
lowright=255.0*val;
// bottom
val = alpha*(0.5 + 0.5*(-fabs(cg.damageX) - cg.damageY));
if (val<0)
low=0;
else if (val>1.0)
low=255;
else
low=255.0*val;
// lower left
val = alpha*(0.5*(cg.damageX - cg.damageY));
if (val<0)
lowleft=0;
else if (val>1.0)
lowleft=255;
else
lowleft=255.0*val;
// Draw the upper left corner
VectorMA(screencenter, 4, cg.refdef.viewaxis[1], ent.origin);
VectorMA(ent.origin, 4, cg.refdef.viewaxis[2], ent.origin);
ent.data.sprite.vertRGBA[0][3] = topleft;
ent.data.sprite.vertRGBA[1][3] = top;
ent.data.sprite.vertRGBA[2][3] = 0;
ent.data.sprite.vertRGBA[3][3] = left;
trap_R_AddRefEntityToScene( &ent );
// Draw topper right corner
VectorMA(screencenter, -4, cg.refdef.viewaxis[1], ent.origin);
VectorMA(ent.origin, 4, cg.refdef.viewaxis[2], ent.origin);
ent.data.sprite.vertRGBA[0][3] = top;
ent.data.sprite.vertRGBA[1][3] = topright;
ent.data.sprite.vertRGBA[2][3] = right;
ent.data.sprite.vertRGBA[3][3] = 0;
trap_R_AddRefEntityToScene( &ent );
// Draw lower right corner
VectorMA(screencenter, -4, cg.refdef.viewaxis[1], ent.origin);
VectorMA(ent.origin, -4, cg.refdef.viewaxis[2], ent.origin);
ent.data.sprite.vertRGBA[0][3] = 0;
ent.data.sprite.vertRGBA[1][3] = right;
ent.data.sprite.vertRGBA[2][3] = lowright;
ent.data.sprite.vertRGBA[3][3] = low;
trap_R_AddRefEntityToScene( &ent );
// Draw lower left corner
VectorMA(screencenter, 4, cg.refdef.viewaxis[1], ent.origin);
VectorMA(ent.origin, -4, cg.refdef.viewaxis[2], ent.origin);
ent.data.sprite.vertRGBA[0][3] = left;
ent.data.sprite.vertRGBA[1][3] = 0;
ent.data.sprite.vertRGBA[2][3] = low;
ent.data.sprite.vertRGBA[3][3] = lowleft;
trap_R_AddRefEntityToScene( &ent );
}
*/
static void CG_DrawScreenBlob(float redalpha, float greenalpha)
{
refEntity_t ent;
float alphascale;
float bluealpha = 0;
// ragePro systems can't fade blends, so don't obscure the screen
if ( cgs.glconfig.hardwareType == GLHW_RAGEPRO ) {
return;
}
memset( &ent, 0, sizeof( ent ) );
ent.reType = RT_SPRITE;
ent.renderfx = RF_FIRST_PERSON;
// Available input:
// cg.damageValue: Range from 0 to 1, indicating the amount of damage.
// cg.damageX and cg_damageY: Range from -1 to 1, indicating the location of the damage.
VectorMA( cg.refdef.vieworg, 8, cg.refdef.viewaxis[0], ent.origin );
VectorMA( ent.origin, cg.damageX * -8, cg.refdef.viewaxis[1], ent.origin );
VectorMA( ent.origin, cg.damageY * 8, cg.refdef.viewaxis[2], ent.origin );
// Here's the scoop: The closer we are to the center, the more transparent this blob is.
alphascale = (2*fabs(cg.damageX)+fabs(cg.damageY))/3.0;
redalpha *= alphascale;
greenalpha *= alphascale;
if (redalpha > greenalpha)
{
ent.data.sprite.radius = cg.damageValue * 15 * redalpha;
}
else
{
ent.data.sprite.radius = cg.damageShieldValue * 15 * greenalpha;
}
/* if (redalpha < 0.01)
{ // Just shield damage
ent.customShader = cgs.media.shieldBlobShader;
// Set all colors to the same as green, since the shader is green
redalpha = bluealpha = greenalpha;
}
else*/ if (greenalpha < 0.01)
{ // Just pain damage
ent.customShader = cgs.media.painBlobShader;
// Set all colors to the same as red, since the shader is red
greenalpha = bluealpha = redalpha;
}
else
{ // Both
ent.customShader = cgs.media.painShieldBlobShader;
}
ent.shaderRGBA[0] = 0xff * redalpha;
ent.shaderRGBA[1] = 0xff * greenalpha;
ent.shaderRGBA[2] = 0xff * bluealpha;
ent.shaderRGBA[3] = 0xff;
trap_R_AddRefEntityToScene( &ent );
}
void CG_DrawFullScreenEffect(int screenfx, int start, int end)
{
float alpha, alpha2 = 0.0; //TiM - second alpha
int end2, start2;
alpha = (float)(end-cg.time)/(float)(end-start);
switch (screenfx)
{
case SCREENFX_TRANSPORTER:
CG_DrawScreenQuad(alpha, cgs.media.teleportEffectShader);
break;
case SCREENFX_SP_TRANSPORTER_IN:
end2=end - 2500;
CG_DrawScreenQuad( alpha, cgs.media.teleportEffectShader);
//Fade in a white quad a little later
if (cg.time <= end2 ) {
alpha2 = (float)(end2-cg.time)/(float)(end2-start);
CG_DrawScreenQuad( alpha2, cgs.media.white2Shader);
}
break;
case SCREENFX_SP_TRANSPORTER_OUT:
start2=start+2500;
end2=end - 4000;
alpha = (float)(end2-cg.time)/(float)(end2-start);
CG_DrawScreenQuad(( 1.0f - alpha), cgs.media.teleportEffectShader);
if ( cg.time >= start2 ) {
alpha2 = (float)(end2-cg.time)/(float)(end2-start2);
if ( cg.time >= end2 )
alpha2=0.0f;
CG_DrawScreenQuad( ( 1.0f - alpha2), cgs.media.white2Shader);
}
break;
default:
break;
}
}
void CG_DrawFullScreenFX( void )
{
int i = 0, t;
float alpha, redalpha, greenalpha;
if ( (cg.snap->ps.clientNum != cg.predictedPlayerState.clientNum) || cg.renderingThirdPerson )
{
return;
}
t = cg.time - cg.damageTime;
if ( t > 0 && t < DAMAGE_TIME)
{ // Draw the blobs.
alpha = 1.0 - ((float)t / (float)DAMAGE_TIME);
redalpha = alpha*cg.damageValue*1.5;
if (redalpha > 1.0)
{
redalpha = 1.0;
}
greenalpha = alpha*cg.damageShieldValue*1.5;
if (greenalpha > 1.0)
{
greenalpha = 1.0;
}
CG_DrawScreenBlob(redalpha, greenalpha);
}
for (i = 0; i < MAX_SCREENFX; i++)
{
if (theScreenFX.cgEndTimes[i])
{
if (theScreenFX.cgEndTimes[i] <= cg.time)
{
// remove this effect
theScreenFX.events[i] = 0;
theScreenFX.cgStartTimes[i] = 0;
theScreenFX.cgEndTimes[i] = 0;
}
else
{
// still drawing this effect
CG_DrawFullScreenEffect(theScreenFX.events[i],theScreenFX.cgStartTimes[i],theScreenFX.cgEndTimes[i]);
}
}
}
}

28
code/cgame/cg_screenfx.h Normal file
View file

@ -0,0 +1,28 @@
//
// full-screen effects like beaming in/out, static from being hit, etc.
//
enum screenfx_e
{
SCREENFX_HIT,
SCREENFX_HALFSHIELDHIT,
SCREENFX_FULLSHIELDHIT,
SCREENFX_TRANSPORTER,
SCREENFX_SP_TRANSPORTER_IN,
SCREENFX_SP_TRANSPORTER_OUT,
MAX_SCREENFX
};
typedef struct screenFX_s
{
int events[MAX_SCREENFX];
int cgStartTimes[MAX_SCREENFX];
int cgEndTimes[MAX_SCREENFX];
} screenFX_t;
extern screenFX_t theScreenFX;
void CG_AddFullScreenEffect(int screenfx, int clientNum);
void CG_DrawFullScreenFX();

File diff suppressed because it is too large Load diff

View file

@ -1,24 +1,4 @@
/*
===========================================================================
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
===========================================================================
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_snapshot.c -- things that happen on snapshot transition,
// not necessarily every single rendered frame
@ -33,13 +13,12 @@ CG_ResetEntity
==================
*/
static void CG_ResetEntity( centity_t *cent ) {
// if the previous snapshot this entity was updated in is at least
// an event window back in time then we can reset the previous event
if ( cent->snapShotTime < cg.time - EVENT_VALID_MSEC ) {
cent->previousEvent = 0;
}
// if an event is set, assume it is new enough to use
// if the event had timed out, it would have been cleared
cent->previousEvent = 0;
cent->trailTime = cg.snap->serverTime;
cent->thinkFlag = 0;
VectorCopy (cent->currentState.origin, cent->lerpOrigin);
VectorCopy (cent->currentState.angles, cent->lerpAngles);
@ -55,8 +34,24 @@ CG_TransitionEntity
cent->nextState is moved to cent->currentState and events are fired
===============
*/
static void CG_TransitionEntity( centity_t *cent ) {
static void CG_TransitionEntity( centity_t *cent )
{
/* qboolean bNoDrawFlag = (cent->currentState.eFlags & EF_CLIENT_NODRAW);
if (cent->nextState.eFlags & EF_NODRAW)
{
// kef -- remove our special client-only flag because the game now believes we should have EF_NODRAW
bNoDrawFlag = qfalse;
}
*/
// kef -- this will automatically remove EF_CLIENT_NODRAW because the game never sets it
cent->currentState = cent->nextState;
/* if (bNoDrawFlag)
{
cent->currentState.eFlags |= EF_NODRAW;
cent->currentState.eFlags |= EF_CLIENT_NODRAW;
}
*/
cent->currentValid = qtrue;
// reset if the entity wasn't in the last frame or was teleported
@ -105,8 +100,7 @@ void CG_SetInitialSnapshot( snapshot_t *snap ) {
state = &cg.snap->entities[ i ];
cent = &cg_entities[ state->number ];
memcpy(&cent->currentState, state, sizeof(entityState_t));
//cent->currentState = *state;
cent->currentState = *state;
cent->interpolate = qfalse;
cent->currentValid = qtrue;
@ -132,9 +126,11 @@ static void CG_TransitionSnapshot( void ) {
if ( !cg.snap ) {
CG_Error( "CG_TransitionSnapshot: NULL cg.snap" );
return;
}
if ( !cg.nextSnap ) {
CG_Error( "CG_TransitionSnapshot: NULL cg.nextSnap" );
return;
}
// execute any server string commands before transitioning entities
@ -160,9 +156,6 @@ static void CG_TransitionSnapshot( void ) {
for ( i = 0 ; i < cg.snap->numEntities ; i++ ) {
cent = &cg_entities[ cg.snap->entities[ i ].number ];
CG_TransitionEntity( cent );
// remember time of snapshot this entity was last updated in
cent->snapShotTime = cg.snap->serverTime;
}
cg.nextSnap = NULL;
@ -176,6 +169,11 @@ static void CG_TransitionSnapshot( void ) {
// teleporting checks are irrespective of prediction
if ( ( ps->eFlags ^ ops->eFlags ) & EF_TELEPORT_BIT ) {
cg.thisFrameTeleport = qtrue; // will be cleared by prediction code
//TiM - since the cg_view.c file seems to be out of scope here,
//manually reset the 3rd view
CG_ResetThirdPersonViewDamp();
cg.thirdPersonNoLerp = qtrue;
}
// if we are not doing client side movement prediction for any
@ -184,6 +182,7 @@ static void CG_TransitionSnapshot( void ) {
|| cg_nopredict.integer || cg_synchronousClients.integer ) {
CG_TransitionPlayerState( ps, ops );
}
}
}
@ -211,8 +210,7 @@ static void CG_SetNextSnap( snapshot_t *snap ) {
es = &snap->entities[num];
cent = &cg_entities[ es->number ];
memcpy(&cent->nextState, es, sizeof(entityState_t));
//cent->nextState = *es;
cent->nextState = *es;
// if this frame is a teleport, or the entity wasn't in the
// previous frame, don't interpolate
@ -261,7 +259,7 @@ static snapshot_t *CG_ReadNextSnapshot( void ) {
snapshot_t *dest;
if ( cg.latestSnapshotNum > cgs.processedSnapshotNum + 1000 ) {
CG_Printf( "WARNING: CG_ReadNextSnapshot: way out of range, %i > %i\n",
CG_Printf( "WARNING: CG_ReadNextSnapshot: way out of range, %i > %i",
cg.latestSnapshotNum, cgs.processedSnapshotNum );
}
@ -277,11 +275,6 @@ static snapshot_t *CG_ReadNextSnapshot( void ) {
cgs.processedSnapshotNum++;
r = trap_GetSnapshot( cgs.processedSnapshotNum, dest );
// FIXME: why would trap_GetSnapshot return a snapshot with the same server time
if ( cg.snap && r && dest->serverTime == cg.snap->serverTime ) {
//continue;
}
// if it succeeded, return
if ( r ) {
CG_AddLagometerSnapshotInfo( dest );
@ -371,10 +364,10 @@ void CG_ProcessSnapshots( void ) {
CG_SetNextSnap( snap );
// if time went backwards, we have a level restart
if ( cg.nextSnap->serverTime < cg.snap->serverTime ) {
CG_Error( "CG_ProcessSnapshots: Server time went backwards" );
return;
}
}
@ -390,6 +383,7 @@ void CG_ProcessSnapshots( void ) {
// assert our valid conditions upon exiting
if ( cg.snap == NULL ) {
CG_Error( "CG_ProcessSnapshots: cg.snap == NULL" );
return;
}
if ( cg.time < cg.snap->serverTime ) {
// this can happen right after a vid_restart

View file

@ -1,95 +1,66 @@
code
equ trap_Print -1
equ trap_Error -2
equ trap_Milliseconds -3
equ trap_Cvar_Register -4
equ trap_Cvar_Update -5
equ trap_Cvar_Set -6
equ trap_Cvar_VariableStringBuffer -7
equ trap_Argc -8
equ trap_Argv -9
equ trap_Args -10
equ trap_FS_FOpenFile -11
equ trap_FS_Read -12
equ trap_FS_Write -13
equ trap_FS_FCloseFile -14
equ trap_SendConsoleCommand -15
equ trap_AddCommand -16
equ trap_SendClientCommand -17
equ trap_UpdateScreen -18
equ trap_CM_LoadMap -19
equ trap_CM_NumInlineModels -20
equ trap_CM_InlineModel -21
equ trap_CM_LoadModel -22
equ trap_CM_TempBoxModel -23
equ trap_CM_PointContents -24
equ trap_Print -1
equ trap_Error -2
equ trap_Milliseconds -3
equ trap_Cvar_Register -4
equ trap_Cvar_Update -5
equ trap_Cvar_Set -6
equ trap_Cvar_VariableStringBuffer -7
equ trap_Argc -8
equ trap_Argv -9
equ trap_Args -10
equ trap_FS_FOpenFile -11
equ trap_FS_Read -12
equ trap_FS_Write -13
equ trap_FS_FCloseFile -14
equ trap_SendConsoleCommand -15
equ trap_AddCommand -16
equ trap_SendClientCommand -17
equ trap_UpdateScreen -18
equ trap_CM_LoadMap -19
equ trap_CM_NumInlineModels -20
equ trap_CM_InlineModel -21
equ trap_CM_LoadModel -22
equ trap_CM_TempBoxModel -23
equ trap_CM_PointContents -24
equ trap_CM_TransformedPointContents -25
equ trap_CM_BoxTrace -26
equ trap_CM_TransformedBoxTrace -27
equ trap_CM_MarkFragments -28
equ trap_S_StartSound -29
equ trap_S_StartLocalSound -30
equ trap_S_ClearLoopingSounds -31
equ trap_S_AddLoopingSound -32
equ trap_S_UpdateEntityPosition -33
equ trap_S_Respatialize -34
equ trap_S_RegisterSound -35
equ trap_S_StartBackgroundTrack -36
equ trap_R_LoadWorldMap -37
equ trap_R_RegisterModel -38
equ trap_R_RegisterSkin -39
equ trap_R_RegisterShader -40
equ trap_R_ClearScene -41
equ trap_R_AddRefEntityToScene -42
equ trap_R_AddPolyToScene -43
equ trap_R_AddLightToScene -44
equ trap_R_RenderScene -45
equ trap_R_SetColor -46
equ trap_R_DrawStretchPic -47
equ trap_R_ModelBounds -48
equ trap_R_LerpTag -49
equ trap_GetGlconfig -50
equ trap_GetGameState -51
equ trap_GetCurrentSnapshotNumber -52
equ trap_GetSnapshot -53
equ trap_GetServerCommand -54
equ trap_GetCurrentCmdNumber -55
equ trap_GetUserCmd -56
equ trap_SetUserCmdValue -57
equ trap_R_RegisterShaderNoMip -58
equ trap_MemoryRemaining -59
equ trap_R_RegisterFont -60
equ trap_Key_IsDown -61
equ trap_Key_GetCatcher -62
equ trap_Key_SetCatcher -63
equ trap_Key_GetKey -64
equ trap_PC_AddGlobalDefine -65
equ trap_PC_LoadSource -66
equ trap_PC_FreeSource -67
equ trap_PC_ReadToken -68
equ trap_PC_SourceFileAndLine -69
equ trap_S_StopBackgroundTrack -70
equ trap_RealTime -71
equ trap_SnapVector -72
equ trap_RemoveCommand -73
equ trap_R_LightForPoint -74
equ trap_CIN_PlayCinematic -75
equ trap_CIN_StopCinematic -76
equ trap_CIN_RunCinematic -77
equ trap_CIN_DrawCinematic -78
equ trap_CIN_SetExtents -79
equ trap_R_RemapShader -80
equ trap_S_AddRealLoopingSound -81
equ trap_S_StopLoopingSound -82
equ trap_CM_TempCapsuleModel -83
equ trap_CM_CapsuleTrace -84
equ trap_CM_TransformedCapsuleTrace -85
equ trap_R_AddAdditiveLightToScene -86
equ trap_GetEntityToken -87
equ trap_R_AddPolysToScene -88
equ trap_R_inPVS -89
equ trap_FS_Seek -90
equ trap_CM_BoxTrace -26
equ trap_CM_TransformedBoxTrace -27
equ trap_CM_MarkFragments -28
equ trap_S_StartSound -29
equ trap_S_StartLocalSound -30
equ trap_S_ClearLoopingSounds -31
equ trap_S_AddLoopingSound -32
equ trap_S_UpdateEntityPosition -33
equ trap_S_Respatialize -34
equ trap_S_RegisterSound -35
equ trap_S_StartBackgroundTrack -36
equ trap_R_LoadWorldMap -37
equ trap_R_RegisterModel -38
equ trap_R_RegisterSkin -39
equ trap_R_RegisterShader -40
equ trap_R_ClearScene -41
equ trap_R_AddRefEntityToScene -42
equ trap_R_AddPolyToScene -43
equ trap_R_AddLightToScene -44
equ trap_R_RenderScene -45
equ trap_R_SetColor -46
equ trap_R_DrawStretchPic -47
equ trap_R_ModelBounds -48
equ trap_R_LerpTag -49
equ trap_GetGlconfig -50
equ trap_GetGameState -51
equ trap_GetCurrentSnapshotNumber -52
equ trap_GetSnapshot -53
equ trap_GetServerCommand -54
equ trap_GetCurrentCmdNumber -55
equ trap_GetUserCmd -56
equ trap_SetUserCmdValue -57
equ trap_R_RegisterShaderNoMip -58
equ trap_MemoryRemaining -59
equ trap_R_RegisterShader3D -60
equ trap_Cvar_Set_No_Modify -61
equ memset -101
equ memcpy -102
@ -102,5 +73,6 @@ equ floor -108
equ ceil -109
equ testPrintInt -110
equ testPrintFloat -111
equ acos -112
equ trap_R_RemapShader -201
equ trap_R_AddPolysToScene -202

View file

@ -1,56 +1,39 @@
/*
===========================================================================
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
===========================================================================
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_syscalls.c -- this file is only included when building a dll
// cg_syscalls.asm is included instead when building a qvm
#ifdef Q3_VM
#error "Do not use in VM build"
#endif
#include "cg_local.h"
//TiM | Hack coz VC 6 can't understand Thilo's defnitions :S
//typedef int intptr_t;
static intptr_t (QDECL *syscall)( intptr_t arg, ... ) = (intptr_t (QDECL *)( intptr_t, ...))-1;
Q_EXPORT void dllEntry( intptr_t (QDECL *syscallptr)( intptr_t arg,... ) ) {
void dllEntry( intptr_t (QDECL *syscallptr)( intptr_t arg,... ) ) {
syscall = syscallptr;
}
/*static int (QDECL *syscall)( int arg, ... ) = (int (QDECL *)( int, ...))-1;
void dllEntry( int (QDECL *syscallptr)( int arg,... ) ) {
syscall = syscallptr;
}*/
int PASSFLOAT( float x ) {
floatint_t fi;
fi.f = x;
return fi.i;
float floatTemp;
floatTemp = x;
return *(int *)&floatTemp;
}
void trap_Print( const char *fmt ) {
syscall( CG_PRINT, fmt );
}
void trap_Error(const char *fmt)
{
syscall(CG_ERROR, fmt);
// shut up GCC warning about returning functions, because we know better
exit(1);
void trap_Error( const char *fmt ) {
syscall( CG_ERROR, fmt );
}
int trap_Milliseconds( void ) {
@ -69,6 +52,10 @@ void trap_Cvar_Set( const char *var_name, const char *value ) {
syscall( CG_CVAR_SET, var_name, value );
}
void trap_Cvar_Set_No_Modify( const char *var_name, const char *value ) {
syscall( CG_CVAR_SET_NO_MODIFY, var_name, value );
}
void trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ) {
syscall( CG_CVAR_VARIABLESTRINGBUFFER, var_name, buffer, bufsize );
}
@ -101,10 +88,6 @@ void trap_FS_FCloseFile( fileHandle_t f ) {
syscall( CG_FS_FCLOSEFILE, f );
}
int trap_FS_Seek( fileHandle_t f, long offset, int origin ) {
return syscall( CG_FS_SEEK, f, offset, origin );
}
void trap_SendConsoleCommand( const char *text ) {
syscall( CG_SENDCONSOLECOMMAND, text );
}
@ -113,10 +96,6 @@ void trap_AddCommand( const char *cmdName ) {
syscall( CG_ADDCOMMAND, cmdName );
}
void trap_RemoveCommand( const char *cmdName ) {
syscall( CG_REMOVECOMMAND, cmdName );
}
void trap_SendClientCommand( const char *s ) {
syscall( CG_SENDCLIENTCOMMAND, s );
}
@ -141,10 +120,6 @@ clipHandle_t trap_CM_TempBoxModel( const vec3_t mins, const vec3_t maxs ) {
return syscall( CG_CM_TEMPBOXMODEL, mins, maxs );
}
clipHandle_t trap_CM_TempCapsuleModel( const vec3_t mins, const vec3_t maxs ) {
return syscall( CG_CM_TEMPCAPSULEMODEL, mins, maxs );
}
int trap_CM_PointContents( const vec3_t p, clipHandle_t model ) {
return syscall( CG_CM_POINTCONTENTS, p, model );
}
@ -159,12 +134,6 @@ void trap_CM_BoxTrace( trace_t *results, const vec3_t start, const vec3_t end,
syscall( CG_CM_BOXTRACE, results, start, end, mins, maxs, model, brushmask );
}
void trap_CM_CapsuleTrace( trace_t *results, const vec3_t start, const vec3_t end,
const vec3_t mins, const vec3_t maxs,
clipHandle_t model, int brushmask ) {
syscall( CG_CM_CAPSULETRACE, results, start, end, mins, maxs, model, brushmask );
}
void trap_CM_TransformedBoxTrace( trace_t *results, const vec3_t start, const vec3_t end,
const vec3_t mins, const vec3_t maxs,
clipHandle_t model, int brushmask,
@ -172,13 +141,6 @@ void trap_CM_TransformedBoxTrace( trace_t *results, const vec3_t start, const ve
syscall( CG_CM_TRANSFORMEDBOXTRACE, results, start, end, mins, maxs, model, brushmask, origin, angles );
}
void trap_CM_TransformedCapsuleTrace( trace_t *results, const vec3_t start, const vec3_t end,
const vec3_t mins, const vec3_t maxs,
clipHandle_t model, int brushmask,
const vec3_t origin, const vec3_t angles ) {
syscall( CG_CM_TRANSFORMEDCAPSULETRACE, results, start, end, mins, maxs, model, brushmask, origin, angles );
}
int trap_CM_MarkFragments( int numPoints, const vec3_t *points,
const vec3_t projection,
int maxPoints, vec3_t pointBuffer,
@ -194,22 +156,14 @@ void trap_S_StartLocalSound( sfxHandle_t sfx, int channelNum ) {
syscall( CG_S_STARTLOCALSOUND, sfx, channelNum );
}
void trap_S_ClearLoopingSounds( qboolean killall ) {
syscall( CG_S_CLEARLOOPINGSOUNDS, killall );
void trap_S_ClearLoopingSounds( void ) {
syscall( CG_S_CLEARLOOPINGSOUNDS );
}
void trap_S_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx ) {
syscall( CG_S_ADDLOOPINGSOUND, entityNum, origin, velocity, sfx );
}
void trap_S_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx ) {
syscall( CG_S_ADDREALLOOPINGSOUND, entityNum, origin, velocity, sfx );
}
void trap_S_StopLoopingSound( int entityNum ) {
syscall( CG_S_STOPLOOPINGSOUND, entityNum );
}
void trap_S_UpdateEntityPosition( int entityNum, const vec3_t origin ) {
syscall( CG_S_UPDATEENTITYPOSITION, entityNum, origin );
}
@ -218,8 +172,8 @@ void trap_S_Respatialize( int entityNum, const vec3_t origin, vec3_t axis[3], in
syscall( CG_S_RESPATIALIZE, entityNum, origin, axis, inwater );
}
sfxHandle_t trap_S_RegisterSound( const char *sample, qboolean compressed ) {
return syscall( CG_S_REGISTERSOUND, sample, compressed );
sfxHandle_t trap_S_RegisterSound( const char *sample ) {
return syscall( CG_S_REGISTERSOUND, sample );
}
void trap_S_StartBackgroundTrack( const char *intro, const char *loop ) {
@ -242,12 +196,12 @@ qhandle_t trap_R_RegisterShader( const char *name ) {
return syscall( CG_R_REGISTERSHADER, name );
}
qhandle_t trap_R_RegisterShaderNoMip( const char *name ) {
return syscall( CG_R_REGISTERSHADERNOMIP, name );
qhandle_t trap_R_RegisterShader3D( const char *name ) {
return syscall( CG_R_REGISTERSHADER3D, name );
}
void trap_R_RegisterFont(const char *fontName, int pointSize, fontInfo_t *font) {
syscall(CG_R_REGISTERFONT, fontName, pointSize, font );
qhandle_t trap_R_RegisterShaderNoMip( const char *name ) {
return syscall( CG_R_REGISTERSHADERNOMIP, name );
}
void trap_R_ClearScene( void ) {
@ -262,22 +216,10 @@ void trap_R_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *
syscall( CG_R_ADDPOLYTOSCENE, hShader, numVerts, verts );
}
void trap_R_AddPolysToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts, int num ) {
syscall( CG_R_ADDPOLYSTOSCENE, hShader, numVerts, verts, num );
}
int trap_R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir ) {
return syscall( CG_R_LIGHTFORPOINT, point, ambientLight, directedLight, lightDir );
}
void trap_R_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b ) {
syscall( CG_R_ADDLIGHTTOSCENE, org, PASSFLOAT(intensity), PASSFLOAT(r), PASSFLOAT(g), PASSFLOAT(b) );
}
void trap_R_AddAdditiveLightToScene( const vec3_t org, float intensity, float r, float g, float b ) {
syscall( CG_R_ADDADDITIVELIGHTTOSCENE, org, PASSFLOAT(intensity), PASSFLOAT(r), PASSFLOAT(g), PASSFLOAT(b) );
}
void trap_R_RenderScene( const refdef_t *fd ) {
syscall( CG_R_RENDERSCENE, fd );
}
@ -295,13 +237,9 @@ void trap_R_ModelBounds( clipHandle_t model, vec3_t mins, vec3_t maxs ) {
syscall( CG_R_MODELBOUNDS, model, mins, maxs );
}
int trap_R_LerpTag( orientation_t *tag, clipHandle_t mod, int startFrame, int endFrame,
void trap_R_LerpTag( orientation_t *tag, clipHandle_t mod, int startFrame, int endFrame,
float frac, const char *tagName ) {
return syscall( CG_R_LERPTAG, tag, mod, startFrame, endFrame, PASSFLOAT(frac), tagName );
}
void trap_R_RemapShader( const char *oldShader, const char *newShader, const char *timeOffset ) {
syscall( CG_R_REMAP_SHADER, oldShader, newShader, timeOffset );
syscall( CG_R_LERPTAG, tag, mod, startFrame, endFrame, PASSFLOAT(frac), tagName );
}
void trap_GetGlconfig( glconfig_t *glconfig ) {
@ -348,101 +286,6 @@ int trap_MemoryRemaining( void ) {
return syscall( CG_MEMORY_REMAINING );
}
qboolean trap_Key_IsDown( int keynum ) {
return syscall( CG_KEY_ISDOWN, keynum );
}
int trap_Key_GetCatcher( void ) {
return syscall( CG_KEY_GETCATCHER );
}
void trap_Key_SetCatcher( int catcher ) {
syscall( CG_KEY_SETCATCHER, catcher );
}
int trap_Key_GetKey( const char *binding ) {
return syscall( CG_KEY_GETKEY, binding );
}
int trap_PC_AddGlobalDefine( char *define ) {
return syscall( CG_PC_ADD_GLOBAL_DEFINE, define );
}
int trap_PC_LoadSource( const char *filename ) {
return syscall( CG_PC_LOAD_SOURCE, filename );
}
int trap_PC_FreeSource( int handle ) {
return syscall( CG_PC_FREE_SOURCE, handle );
}
int trap_PC_ReadToken( int handle, pc_token_t *pc_token ) {
return syscall( CG_PC_READ_TOKEN, handle, pc_token );
}
int trap_PC_SourceFileAndLine( int handle, char *filename, int *line ) {
return syscall( CG_PC_SOURCE_FILE_AND_LINE, handle, filename, line );
}
void trap_S_StopBackgroundTrack( void ) {
syscall( CG_S_STOPBACKGROUNDTRACK );
}
int trap_RealTime(qtime_t *qtime) {
return syscall( CG_REAL_TIME, qtime );
}
void trap_SnapVector( float *v ) {
syscall( CG_SNAPVECTOR, v );
}
// this returns a handle. arg0 is the name in the format "idlogo.roq", set arg1 to NULL, alteredstates to qfalse (do not alter gamestate)
int trap_CIN_PlayCinematic( const char *arg0, int xpos, int ypos, int width, int height, int bits) {
return syscall(CG_CIN_PLAYCINEMATIC, arg0, xpos, ypos, width, height, bits);
}
// stops playing the cinematic and ends it. should always return FMV_EOF
// cinematics must be stopped in reverse order of when they are started
e_status trap_CIN_StopCinematic(int handle) {
return syscall(CG_CIN_STOPCINEMATIC, handle);
}
// will run a frame of the cinematic but will not draw it. Will return FMV_EOF if the end of the cinematic has been reached.
e_status trap_CIN_RunCinematic (int handle) {
return syscall(CG_CIN_RUNCINEMATIC, handle);
}
// draws the current frame
void trap_CIN_DrawCinematic (int handle) {
syscall(CG_CIN_DRAWCINEMATIC, handle);
}
// allows you to resize the animation dynamically
void trap_CIN_SetExtents (int handle, int x, int y, int w, int h) {
syscall(CG_CIN_SETEXTENTS, handle, x, y, w, h);
}
/*
qboolean trap_loadCamera( const char *name ) {
return syscall( CG_LOADCAMERA, name );
}
void trap_startCamera(int time) {
syscall(CG_STARTCAMERA, time);
}
qboolean trap_getCameraInfo( int time, vec3_t *origin, vec3_t *angles) {
return syscall( CG_GETCAMERAINFO, time, origin, angles );
}
*/
qboolean trap_GetEntityToken( char *buffer, int bufferSize ) {
return syscall( CG_GET_ENTITY_TOKEN, buffer, bufferSize );
}
qboolean trap_R_inPVS( const vec3_t p1, const vec3_t p2 ) {
return syscall( CG_R_INPVS, p1, p2 );
void trap_R_RemapShader( const char *oldShader, const char *newShader, const char *timeOffset ) {
syscall( CG_R_REMAP_SHADER, oldShader, newShader, timeOffset );
}

246
code/cgame/cg_text.h Normal file
View file

@ -0,0 +1,246 @@
#ifndef __CG_TEXT_H__
#define __CG_TEXT_H__
// Ingame Text enum
typedef enum
{
IGT_NONE,
IGT_OUTOFAMMO,
IGT_LOWAMMO,
// Scoreboard
IGT_FRAGGEDBY,
IGT_ASSIMILATEDBY,
IGT_PLACEDWITH,
IGT_SPECTATOR,
IGT_WAITINGTOPLAY,
IGT_USETEAMMENU,
IGT_FOLLOWING,
IGT_LOADING,
IGT_AWAITINGSNAPSHOT,
IGT_PURESERVER,
IGT_CHEATSAREENABLED,
IGT_TIMELIMIT,
IGT_FRAGLIMIT,
IGT_CAPTURELIMIT,
IGT_READY,
IGT_SB_SCORE,
IGT_SB_LOC,
IGT_SB_PING,
IGT_SB_TIME,
IGT_SB_NAME,
IGT_REDTEAM,
IGT_BLUETEAM,
IGT_SAY,
IGT_SAY_TEAM,
IGT_SAY_CLASS,
IGT_POINT_LIMIT,
IGT_TIME_LIMIT,
IGT_CAPTURE_LIMIT,
IGT_GAME_FREEFORALL,
IGT_GAME_SINGLEPLAYER,
IGT_GAME_TOURNAMENT,
IGT_GAME_TEAMHOLOMATCH,
IGT_GAME_CAPTUREFLAG,
IGT_GAME_UNKNOWN,
IGT_YOUELIMINATED,
IGT_YOUASSIMILATED,
IGT_PLACEWITH,
IGT_SUICIDES,
IGT_CRATERED,
IGT_WASSQUISHED,
IGT_SANK,
IGT_MELTED,
IGT_INTOLAVA,
IGT_SAWLIGHT,
IGT_WRONGPLACE,
IGT_TRIPPEDHERGRENADE,
IGT_TRIPPEDITSGRENADE,
IGT_TRIPPEDHISGRENADE,
IGT_BLEWHERSELFUP,
IGT_BLEWITSELFUP,
IGT_BLEWHIMSELFUP,
IGT_MELTEDHERSELF,
IGT_MELTEDITSELF,
IGT_MELTEDHIMSELF,
IGT_SMALLERGUN,
IGT_DESTROYEDHERSELF,
IGT_DESTROYEDITSELF,
IGT_DESTROYEDHIMSELF,
IGT_TIEDFOR,
IGT_REDTEAMLEADS,
IGT_BLUETEAMLEADS,
IGT_TO ,
IGT_TEAMSARETIED,
IGT_ATE,
IGT_GRENADE,
IGT_WITHINBLASTRADIUS,
IGT_ALMOSTEVADED,
IGT_PHOTONBURST,
IGT_DISPATCHEDBY,
IGT_SCAVENGERWEAPON,
IGT_NEARLYAVOIDED,
IGT_RAILEDBY,
IGT_ELECTROCUTEDBY,
IGT_DESTROYEDBY,
IGT_TETRYONPULSE,
IGT_BLASTEDBY,
IGT_STASISWEAPON,
IGT_WASWITHIN,
IGT_TRANSPORTERBEAM,
IGT_WASELIMINATEDBY,
IGT_WASELIMINATED,
IGT_SNAPSHOT,
IGT_REPLICATION_MATRIX,
IGT_HOLOGRAPHIC_PROJECTORS,
IGT_SIMULATION_DATA_BASE,
IGT_SAFETY_LOCKS,
IGT_HOLODECKSIMULATION,
IGT_USEDTEAMMENU,
IGT_CONNECTIONINTERRUPTED,
IGT_VOTE,
IGT_YES,
IGT_NO,
IGT_WAITINGFORPLAYERS,
IGT_STARTSIN,
IGT_NONETEXT,
IGT_EFFICIENCY,
IGT_SHARPSHOOTER,
IGT_UNTOUCHABLE,
IGT_LOGISTICS,
IGT_TACTICIAN,
IGT_DEMOLITIONIST,
IGT_STREAK,
IGT_ROLE,
IGT_SECTION31,
IGT_ACE,
IGT_EXPERT,
IGT_MASTER,
IGT_CHAMPION,
IGT_MVP,
IGT_DEFENDER,
IGT_WARRIOR,
IGT_CARRIER,
IGT_INTERCEPTOR,
IGT_BRAVERY,
IGT_TIED_FOR,
IGT_YOUR_RANK,
IGT_YOUR_TEAM,
IGT_WON,
IGT_LOST,
IGT_TEAMS_TIED,
IGT_1ST,
IGT_2ND,
IGT_3RD,
IGT_WINNER,
IGT_CAPTURES,
IGT_POINTS,
IGT_OVERALL,
IGT_CLICK_PLAY_AGAIN,
IGT_TITLEELIMINATED,
IGT_WORSTENEMY,
IGT_FAVORITEWEAPON,
IGT_CONNECTING,
IGT_SPECTABBREV,
IGT_VICTOR,
IGT_DEFEATED,
IGT_DROWNING,
IGT_CORROSION,
IGT_BOILING,
IGT_COMPRESSION,
IGT_TRANSPORTERACCIDENT,
IGT_IMPACT,
IGT_SUICIDE,
IGT_LASERBURNS,
IGT_MISADVENTURE,
IGT_PHASERBURNS,
IGT_ENERGYSCARS,
IGT_SNIPED,
IGT_INFINITEMODULATION,
IGT_GUNNEDDOWN,
IGT_SCAVENGED,
IGT_PERMANENTSTASIS,
IGT_BLASTED,
IGT_MINED,
IGT_PERFORATED,
IGT_DISRUPTED,
IGT_WELDED,
IGT_DEGAUSSED,
IGT_DESTROYED,
IGT_ANNIHILATED,
IGT_VAPORIZED,
IGT_AUTOGUNNED,
IGT_KNOCKOUT,
IGT_ASSIMILATED,
IGT_ZAPPED,
IGT_UNKNOWN,
IGT_CASUALTY,
IGT_METHOD,
IGT_OBITELIMINATED,
IGT_CREDIT,
IGT_PLEASE,
IGT_11TH,
IGT_12TH,
IGT_13TH,
IGT_NUM_ST,
IGT_NUM_ND,
IGT_NUM_RD,
IGT_NUM_TH,
IGT_PLAYERS,
IGT_OBJECTIVES,
IGT_GAME_ELIMINATION,
IGT_GAME_ASSIMILATION,
IGT_GAME_ACTIONHERO,
IGT_GAME_SPECIALTIES,
IGT_GAME_DISINTEGRATION,
//RPG-X: RedTechie Added new text definitions
IGT_SB_RANK,
IGT_SB_RPGCLASS,
IGT_SB_HEALTHBARLCARS,
IGT_SB_HEALTHSTATUS1,
IGT_SB_HEALTHSTATUS2,
IGT_SB_HEALTHSTATUS3,
IGT_SB_HEALTHSTATUS4,
IGT_SB_HEALTHSTATUS5,
IGT_SB_HEALTHSTATUS6,
IGT_SB_FLIGHTSTATUS,
IGT_SB_CLOAKSTATUS,
IGT_SB_EVOSUITSTATUS,
IGT_PINGEDOUT,
IGT_FORCEFIELDDEATH,
IGT_FORCEDSUICIDE,
IGT_MAX
} ingameTextType_t;
extern char *ingame_text[IGT_MAX];
#endif //__CG_TEXT_H__

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

3
code/cgame/cgame.def Normal file
View file

@ -0,0 +1,3 @@
EXPORTS
vmMain
dllEntry

337
code/cgame/cgame.dsp Normal file
View file

@ -0,0 +1,337 @@
# Microsoft Developer Studio Project File - Name="cgame" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=cgame - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "cgame.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "cgame.mak" CFG="cgame - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "cgame - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "cgame - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/StarTrek/Code-DM/cgame", VFJBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "cgame - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /G6 /W4 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 /nologo /base:"0x30000000" /subsystem:windows /dll /map /machine:I386 /out:"../Release/cgamex86.dll"
# SUBTRACT LINK32 /incremental:yes /debug
!ELSEIF "$(CFG)" == "cgame - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /G5 /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 /nologo /base:"0x30000000" /subsystem:windows /dll /map /debug /machine:I386 /out:"../debug/cgamex86.dll"
# SUBTRACT LINK32 /profile /incremental:no /nodefaultlib
!ENDIF
# Begin Target
# Name "cgame - Win32 Release"
# Name "cgame - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "c"
# Begin Source File
SOURCE=..\game\bg_lib.c
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\game\bg_misc.c
# End Source File
# Begin Source File
SOURCE=..\game\bg_oums.c
# End Source File
# Begin Source File
SOURCE=..\game\bg_pmove.c
# End Source File
# Begin Source File
SOURCE=..\game\bg_slidemove.c
# End Source File
# Begin Source File
SOURCE=.\cg_consolecmds.c
# End Source File
# Begin Source File
SOURCE=.\cg_draw.c
# End Source File
# Begin Source File
SOURCE=.\cg_drawtools.c
# End Source File
# Begin Source File
SOURCE=.\cg_effects.c
# End Source File
# Begin Source File
SOURCE=.\cg_ents.c
# End Source File
# Begin Source File
SOURCE=.\cg_env.c
# End Source File
# Begin Source File
SOURCE=.\cg_event.c
# End Source File
# Begin Source File
SOURCE=.\cg_info.c
# End Source File
# Begin Source File
SOURCE=.\cg_localents.c
# End Source File
# Begin Source File
SOURCE=.\cg_main.c
# End Source File
# Begin Source File
SOURCE=.\cg_marks.c
# End Source File
# Begin Source File
SOURCE=.\cg_players.c
# End Source File
# Begin Source File
SOURCE=.\cg_playerstate.c
# End Source File
# Begin Source File
SOURCE=.\cg_predict.c
# End Source File
# Begin Source File
SOURCE=.\cg_scoreboard.c
# End Source File
# Begin Source File
SOURCE=.\cg_screenfx.c
# End Source File
# Begin Source File
SOURCE=.\cg_servercmds.c
# End Source File
# Begin Source File
SOURCE=.\cg_snapshot.c
# End Source File
# Begin Source File
SOURCE=.\cg_syscalls.c
# End Source File
# Begin Source File
SOURCE=.\cg_view.c
# End Source File
# Begin Source File
SOURCE=.\cg_weapons.c
# End Source File
# Begin Source File
SOURCE=.\fx_borg.c
# End Source File
# Begin Source File
SOURCE=.\fx_compression.c
# End Source File
# Begin Source File
SOURCE=.\fx_dreadnought.c
# End Source File
# Begin Source File
SOURCE=.\fx_grenade.c
# End Source File
# Begin Source File
SOURCE=.\fx_imod.c
# End Source File
# Begin Source File
SOURCE=.\fx_item.c
# End Source File
# Begin Source File
SOURCE=.\fx_lib.c
# End Source File
# Begin Source File
SOURCE=.\fx_misc.c
# End Source File
# Begin Source File
SOURCE=.\fx_phaser.c
# End Source File
# Begin Source File
SOURCE=.\fx_quantum.c
# End Source File
# Begin Source File
SOURCE=.\fx_scavenger.c
# End Source File
# Begin Source File
SOURCE=.\fx_stasis.c
# End Source File
# Begin Source File
SOURCE=.\fx_tetrion.c
# End Source File
# Begin Source File
SOURCE=.\fx_transporter.c
# End Source File
# Begin Source File
SOURCE=..\game\q_math.c
# End Source File
# Begin Source File
SOURCE=..\game\q_shared.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h"
# Begin Source File
SOURCE=..\game\bg_local.h
# End Source File
# Begin Source File
SOURCE=..\game\bg_oums.h
# End Source File
# Begin Source File
SOURCE=..\game\bg_public.h
# End Source File
# Begin Source File
SOURCE=.\cg_anims.h
# End Source File
# Begin Source File
SOURCE=.\cg_local.h
# End Source File
# Begin Source File
SOURCE=.\cg_public.h
# End Source File
# Begin Source File
SOURCE=.\cg_screenfx.h
# End Source File
# Begin Source File
SOURCE=.\cg_text.h
# End Source File
# Begin Source File
SOURCE=.\cgame.def
# End Source File
# Begin Source File
SOURCE=.\fx_local.h
# End Source File
# Begin Source File
SOURCE=..\game\q_shared.h
# End Source File
# Begin Source File
SOURCE=..\game\surfaceflags.h
# End Source File
# Begin Source File
SOURCE=.\tr_types.h
# End Source File
# End Group
# Begin Source File
SOURCE=.\cg_syscalls.asm
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=.\cgame.bat
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=.\cgame.q3asm
# PROP Exclude_From_Build 1
# End Source File
# End Target
# End Project

29
code/cgame/cgame.dsw Normal file
View file

@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "cgame"=".\cgame.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

BIN
code/cgame/cgame.opt Normal file

Binary file not shown.

147
code/cgame/cgame.plg Normal file
View file

@ -0,0 +1,147 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: cgame - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\marcin\LOCALS~1\Temp\RSP194.tmp" with contents
[
/nologo /G5 /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"Release/" /Fp"Release/cgame.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c
"C:\stvoy\code-dm\game\bg_misc.c"
"C:\stvoy\code-dm\game\bg_pmove.c"
"C:\stvoy\code-dm\game\bg_slidemove.c"
"C:\stvoy\code-dm\cgame\cg_consolecmds.c"
"C:\stvoy\code-dm\cgame\cg_draw.c"
"C:\stvoy\code-dm\cgame\cg_drawtools.c"
"C:\stvoy\code-dm\cgame\cg_effects.c"
"C:\stvoy\code-dm\cgame\cg_ents.c"
"C:\stvoy\code-dm\cgame\cg_env.c"
"C:\stvoy\code-dm\cgame\cg_event.c"
"C:\stvoy\code-dm\cgame\cg_info.c"
"C:\stvoy\code-dm\cgame\cg_localents.c"
"C:\stvoy\code-dm\cgame\cg_main.c"
"C:\stvoy\code-dm\cgame\cg_marks.c"
"C:\stvoy\code-dm\cgame\cg_players.c"
"C:\stvoy\code-dm\cgame\cg_playerstate.c"
"C:\stvoy\code-dm\cgame\cg_predict.c"
"C:\stvoy\code-dm\cgame\cg_scoreboard.c"
"C:\stvoy\code-dm\cgame\cg_screenfx.c"
"C:\stvoy\code-dm\cgame\cg_servercmds.c"
"C:\stvoy\code-dm\cgame\cg_snapshot.c"
"C:\stvoy\code-dm\cgame\cg_syscalls.c"
"C:\stvoy\code-dm\cgame\cg_view.c"
"C:\stvoy\code-dm\cgame\cg_weapons.c"
"C:\stvoy\code-dm\cgame\fx_borg.c"
"C:\stvoy\code-dm\cgame\fx_compression.c"
"C:\stvoy\code-dm\cgame\fx_dreadnought.c"
"C:\stvoy\code-dm\cgame\fx_grenade.c"
"C:\stvoy\code-dm\cgame\fx_imod.c"
"C:\stvoy\code-dm\cgame\fx_item.c"
"C:\stvoy\code-dm\cgame\fx_lib.c"
"C:\stvoy\code-dm\cgame\fx_misc.c"
"C:\stvoy\code-dm\cgame\fx_phaser.c"
"C:\stvoy\code-dm\cgame\fx_quantum.c"
"C:\stvoy\code-dm\cgame\fx_scavenger.c"
"C:\stvoy\code-dm\cgame\fx_stasis.c"
"C:\stvoy\code-dm\cgame\fx_tetrion.c"
"C:\stvoy\code-dm\cgame\fx_transporter.c"
]
Creating command line "cl.exe @C:\DOCUME~1\marcin\LOCALS~1\Temp\RSP194.tmp"
Creating temporary file "C:\DOCUME~1\marcin\LOCALS~1\Temp\RSP195.tmp" with contents
[
/nologo /base:"0x30000000" /subsystem:windows /dll /incremental:yes /pdb:"Release/cgamex86.pdb" /map:"Release/cgamex86.map" /debug /machine:I386 /def:".\cgame.def" /out:"../debug/cgamex86.dll" /implib:"Release/cgamex86.lib"
".\Release\bg_misc.obj"
".\Release\bg_oums.obj"
".\Release\bg_pmove.obj"
".\Release\bg_slidemove.obj"
".\Release\cg_consolecmds.obj"
".\Release\cg_draw.obj"
".\Release\cg_drawtools.obj"
".\Release\cg_effects.obj"
".\Release\cg_ents.obj"
".\Release\cg_env.obj"
".\Release\cg_event.obj"
".\Release\cg_info.obj"
".\Release\cg_localents.obj"
".\Release\cg_main.obj"
".\Release\cg_marks.obj"
".\Release\cg_players.obj"
".\Release\cg_playerstate.obj"
".\Release\cg_predict.obj"
".\Release\cg_scoreboard.obj"
".\Release\cg_screenfx.obj"
".\Release\cg_servercmds.obj"
".\Release\cg_snapshot.obj"
".\Release\cg_syscalls.obj"
".\Release\cg_view.obj"
".\Release\cg_weapons.obj"
".\Release\fx_borg.obj"
".\Release\fx_compression.obj"
".\Release\fx_dreadnought.obj"
".\Release\fx_grenade.obj"
".\Release\fx_imod.obj"
".\Release\fx_item.obj"
".\Release\fx_lib.obj"
".\Release\fx_misc.obj"
".\Release\fx_phaser.obj"
".\Release\fx_quantum.obj"
".\Release\fx_scavenger.obj"
".\Release\fx_stasis.obj"
".\Release\fx_tetrion.obj"
".\Release\fx_transporter.obj"
".\Release\q_math.obj"
".\Release\q_shared.obj"
]
Creating command line "link.exe @C:\DOCUME~1\marcin\LOCALS~1\Temp\RSP195.tmp"
<h3>Output Window</h3>
Compiling...
bg_misc.c
bg_pmove.c
bg_slidemove.c
cg_consolecmds.c
cg_draw.c
cg_drawtools.c
cg_effects.c
cg_ents.c
cg_env.c
cg_event.c
cg_info.c
cg_localents.c
cg_main.c
cg_marks.c
cg_players.c
cg_playerstate.c
cg_predict.c
cg_scoreboard.c
cg_screenfx.c
cg_servercmds.c
cg_snapshot.c
cg_syscalls.c
cg_view.c
cg_weapons.c
fx_borg.c
fx_compression.c
fx_dreadnought.c
fx_grenade.c
fx_imod.c
fx_item.c
fx_lib.c
fx_misc.c
fx_phaser.c
fx_quantum.c
fx_scavenger.c
fx_stasis.c
fx_tetrion.c
fx_transporter.c
Linking...
Creating library Release/cgamex86.lib and object Release/cgamex86.exp
<h3>Results</h3>
cgamex86.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

42
code/cgame/cgame.q3asm Normal file
View file

@ -0,0 +1,42 @@
-o "C:\stvoy\code-DM\vm\cgame"
cg_main
..\cg_syscalls
cg_consolecmds
cg_draw
cg_drawtools
cg_effects
cg_ents
cg_env
cg_event
cg_info
cg_localents
cg_marks
cg_players
cg_playerstate
cg_predict
cg_scoreboard
cg_screenfx
cg_servercmds
cg_snapshot
cg_view
cg_weapons
bg_slidemove
bg_pmove
bg_lib
bg_misc
q_math
q_shared
fx_compression
fx_imod
fx_misc
fx_lib
fx_phaser
fx_scavenger
fx_tetrion
fx_transporter
fx_grenade
fx_quantum
fx_stasis
fx_item
fx_dreadnought
fx_borg

1354
code/cgame/cgame.vcproj Normal file

File diff suppressed because it is too large Load diff

499
code/cgame/cgame.vcxproj Normal file
View file

@ -0,0 +1,499 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{EBB0D9E9-00FC-4DBA-AF4A-4052FE9B17B1}</ProjectGuid>
<RootNamespace>cgame</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\Debug\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\MinGW\include;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Release/cgame.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>lua\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;XTRA;G_LUA;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\Release/cgame.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
<ObjectFileName>.\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
<BrowseInformation>true</BrowseInformation>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;lua52.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>C:\Program Files\Raven\Star Trek Voyager Elite Force\RPG-X2\cgamex86.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ModuleDefinitionFile>.\cgame.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Release/cgamex86.pdb</ProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>.\Release/cgamex86.map</MapFileName>
<SubSystem>Windows</SubSystem>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<BaseAddress>0x30000000</BaseAddress>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>.\Release/cgamex86.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Release/cgame.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<AdditionalOptions>/analyze %(AdditionalOptions)</AdditionalOptions>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<StructMemberAlignment>4Bytes</StructMemberAlignment>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\Release/cgame.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
<ObjectFileName>.\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
<BrowseInformation>
</BrowseInformation>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../Release/cgamex86.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ModuleDefinitionFile>.\cgame.def</ModuleDefinitionFile>
<ProgramDatabaseFile>.\Release/cgamex86.pdb</ProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>.\Release/cgamex86.map</MapFileName>
<SubSystem>Windows</SubSystem>
<BaseAddress>0x30000000</BaseAddress>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>.\Release/cgamex86.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\game\bg_lib.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="..\game\bg_misc.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="..\game\bg_oums.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="..\game\bg_pmove.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="..\game\bg_slidemove.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_consolecmds.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_draw.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_drawtools.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_effects.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_ents.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_env.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_event.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_info.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_localents.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_lua.c" />
<ClCompile Include="cg_main.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_marks.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_players.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_playerstate.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_predict.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_scoreboard.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_screenfx.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_servercmds.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_snapshot.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_syscalls.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_view.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_weapons.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_compression.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_disruptor.c" />
<ClCompile Include="fx_grenade.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_hypospray.c" />
<ClCompile Include="fx_item.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_lib.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_misc.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_phaser.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_quantum.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_tetrion.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_transporter.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="..\game\q_math.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="..\game\q_shared.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="lua_cent.c" />
<ClCompile Include="lua_cfx.c" />
<ClCompile Include="lua_refent.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\game\bg_local.h" />
<ClInclude Include="..\game\bg_public.h" />
<ClInclude Include="cg_anims.h" />
<ClInclude Include="cg_local.h" />
<ClInclude Include="cg_lua.h" />
<ClInclude Include="cg_public.h" />
<ClInclude Include="cg_screenfx.h" />
<ClInclude Include="cg_text.h" />
<ClInclude Include="fx_local.h" />
<ClInclude Include="..\game\q_shared.h" />
<ClInclude Include="..\game\surfaceflags.h" />
<ClInclude Include="tr_types.h" />
</ItemGroup>
<ItemGroup>
<None Include="cgame.def" />
<CustomBuildStep Include="cg_syscalls.asm">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="cgame.bat">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="cgame.q3asm">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,195 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{90a720d9-41f5-4abf-91d4-5c109cd2d702}</UniqueIdentifier>
<Extensions>c</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{76164a83-7a3a-4473-b6db-f151d30a82d7}</UniqueIdentifier>
<Extensions>h</Extensions>
</Filter>
<Filter Include="Source Files\lua">
<UniqueIdentifier>{cc31ca7a-00a9-49ce-9830-b91beeffb091}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\game\bg_lib.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\game\bg_misc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\game\bg_oums.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\game\bg_pmove.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\game\bg_slidemove.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_consolecmds.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_draw.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_drawtools.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_effects.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_ents.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_env.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_event.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_info.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_localents.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_main.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_marks.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_players.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_playerstate.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_predict.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_scoreboard.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_screenfx.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_servercmds.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_snapshot.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_syscalls.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_view.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_weapons.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_compression.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_grenade.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_item.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_lib.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_misc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_phaser.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_quantum.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_tetrion.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_transporter.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\game\q_math.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\game\q_shared.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_hypospray.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_disruptor.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_lua.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="lua_cfx.c">
<Filter>Source Files\lua</Filter>
</ClCompile>
<ClCompile Include="lua_cent.c">
<Filter>Source Files\lua</Filter>
</ClCompile>
<ClCompile Include="lua_refent.c">
<Filter>Source Files\lua</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\game\bg_local.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\game\bg_public.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cg_anims.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cg_local.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cg_public.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cg_screenfx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cg_text.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="fx_local.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\game\q_shared.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\game\surfaceflags.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="tr_types.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cg_lua.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="cgame.def">
<Filter>Header Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<CustomBuildStep Include="cg_syscalls.asm" />
<CustomBuildStep Include="cgame.bat" />
<CustomBuildStep Include="cgame.q3asm" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>

434
code/cgame/fx_compression.c Normal file
View file

@ -0,0 +1,434 @@
//Compression rifle weapon effects
#include "cg_local.h"
#include "fx_local.h"
qboolean AltCompressionAftereffect(localEntity_t *le)
{
localEntity_t *cyl = NULL;
qhandle_t shader = cgs.media.compressionAltBlastShader;
float percentLife = 1.0 - (le->endTime - cg.time)*le->lifeRate;
float alpha = 0.6 - (0.6*percentLife);
float length = 20;
vec3_t vec2, dir2;
cyl = FX_AddCylinder( le->refEntity.origin,
le->data.spawner.dir,
length,// height,
0,// dheight,
10,//10+(30*(1-percentLife)),// scale,
210,// dscale,
10+(30*percentLife),// scale2,
210,// dscale2,
alpha,// startalpha,
0.0,// endalpha,
500,// killTime,
shader,
15);// bias );
cyl->leFlags |= LEF_ONE_FRAME;
VectorMA(le->refEntity.origin, length*2.0, le->data.spawner.dir, vec2);
VectorScale(le->data.spawner.dir, -1.0, dir2);
cyl = FX_AddCylinder( vec2,
dir2,
length,// height,
0,// dheight,
10,//10+(30*(1-percentLife)),// scale,
210,// dscale,
10+(30*percentLife),// scale2,
210,// dscale2,
alpha,// startalpha,
0.0,// endalpha,
500,// killTime,
shader,
15);// bias );
cyl->leFlags |= LEF_ONE_FRAME;
return qtrue;
}
/*
-------------------------
FX_CompressionShot
-------------------------
*/
#define MAXRANGE_CRIFLE 8192
void FX_CompressionShot( vec3_t start, vec3_t dir )
{
localEntity_t *le;
vec3_t end;
trace_t trace;
qboolean render_impact = qtrue;
centity_t *traceEnt = NULL;
int clientNum = -1;
VectorMA(start, MAXRANGE_CRIFLE, dir, end);
CG_Trace( &trace, start, NULL, NULL, end, 0, MASK_SHOT );
// draw the beam
le = FX_AddLine(start, trace.endpos, 1.0, 2.0, 0.0, 1.0, 1.0, 100.0, cgs.media.prifleBolt);
le->leFlags |= LEF_ONE_FRAME;
// draw an impact at the endpoint of the trace
// If the beam hits a skybox, etc. it would look foolish to add in an explosion
if ( trace.surfaceFlags & SURF_NOIMPACT )
{
render_impact = qfalse;
}
if ( render_impact )
{
traceEnt = &cg_entities[trace.entityNum];
clientNum = traceEnt->currentState.clientNum;
if ( (trace.entityNum != ENTITYNUM_WORLD) && (clientNum >= 0 || clientNum < MAX_CLIENTS) )
{
FX_CompressionHit(trace.endpos);
}
else
{
FX_CompressionExplosion(start, trace.endpos, trace.plane.normal, qfalse);
}
}
}
/*
-------------------------
FX_CompressionShot
-------------------------
*/
void FX_CompressionAltShot( vec3_t start, vec3_t dir )
{
vec3_t end, vel = {0,0,0};
trace_t trace;
qboolean render_impact = qtrue;
centity_t *traceEnt = NULL;
int clientNum = -1;
VectorMA(start, MAXRANGE_CRIFLE, dir, end);
CG_Trace( &trace, start, NULL, NULL, end, cg_entities[cg.predictedPlayerState.clientNum].currentState.number, MASK_SHOT );
// draw the beam
FX_AddLine( start, trace.endpos, 1.0f, 3.0f, 0.0f, 1.0f, 0.0f, 350/*125.0f*/, cgs.media.sparkShader );
FX_AddLine( start, trace.endpos, 1.0f, 6.0f, 20.0f, 0.6f, 0.0f, 800/*175.0f*/, cgs.media.phaserShader);//compressionAltBeamShader );
FX_AddSpawner( start, dir, vel, NULL, qfalse, 0,
0, 500, AltCompressionAftereffect, 10 );
// draw an impact at the endpoint of the trace
// If the beam hits a skybox, etc. it would look foolish to add in an explosion
if ( trace.surfaceFlags & SURF_NOIMPACT )
{
render_impact = qfalse;
}
if ( render_impact )
{
traceEnt = &cg_entities[trace.entityNum];
clientNum = traceEnt->currentState.clientNum;
if ( (trace.entityNum != ENTITYNUM_WORLD) && (clientNum >= 0 || clientNum < MAX_CLIENTS) )
{
FX_CompressionHit(trace.endpos);
}
else
{
FX_CompressionExplosion(start, trace.endpos, trace.plane.normal, qtrue);
}
}
}
/*
-------------------------
FX_CompressionExplosion
-------------------------
*/
void FX_CompressionExplosion( vec3_t start, vec3_t origin, vec3_t normal, qboolean altfire )
{
localEntity_t *le;
vec3_t dir;
vec3_t velocity; //, shot_dir;
vec3_t hitpos;
float scale, dscale;
int i, j, numSparks;
weaponInfo_t *weaponInfo = &cg_weapons[WP_6];
float distance;
vec3_t color = {0.7, 0.43, 0.44};
int size = 2;
//FX_CompressionHit( origin ); //TiM: let's test if the rifle doesn't make stuff explode when its shot :)
//return;
//Sparks
//TiM: Calc spark count off proximity to effect
VectorSubtract ( cg.refdef.vieworg, origin, dir );
distance = VectorNormalize( dir );
distance = 50 * ( 1.0f - (distance / 128) ) ;
distance = Com_Clamp( 25, 50, distance );
numSparks = distance + (random() * 4.0f); //4
if (altfire)
{
numSparks *= 1.5f;
}
for ( i = 0; i < numSparks; i++ )
{
scale = 10.0f + (random() * 1.0f); //.25
dscale = -scale;
//Randomize the direction
for (j = 0; j < 3; j ++ )
{
//if ( j !=5 )
//dir[j] = normal[j] + (0.75 * crandom());
//else
dir[j] = normal[j] + (-1 * crandom()); //0.75
}
VectorNormalize(dir);
//set the speed
VectorScale( dir, 200 + (50 * crandom()), velocity); //200
le = FX_AddTrail( origin,
velocity,
qtrue, //qtrue
12.0f,//4
-12.0f,//4
scale,
-scale,
1.0f,
1.0f,
0.5f,
1000.0f, //1000
cgs.media.orangeStarShader);
// FXE_Spray( normal, 200, 50, 0.4f, le);
}
VectorMA( origin, 8, normal, dir );
VectorSet(velocity, 0, 0, 8);
/*
FX_AddSprite( dir,
velocity,
qfalse,
(altfire?50.0f:32.0f),
16.0f,
1.0f,
0.0f,
random()*45.0f,
0.0f,
(altfire?1300.0f:1000.0f),
cgs.media.steamShader );
*/
//Orient the explosions to face the camera
VectorSubtract( cg.refdef.vieworg, origin, dir );
VectorNormalize( dir );
if (!altfire)
{
CG_InitLensFlare( origin,
350, 350,
color, 1.2, 2.0, 1600, 200,
color, 1600, 200, 800, 20, qtrue,
0, 0, qfalse, qtrue,
qfalse, 1.0, cg.time, 0, 0, 210);
VectorMA(origin, size, normal, hitpos);
FX_AddSprite( hitpos, NULL, qfalse, size * size * 15.0f, -150.0f,
1.0f, 0.0f, 360*random(), 0, 400, cgs.media.liteRedParticleShader );
FX_AddSprite( hitpos, NULL, qfalse, size * size * 25.0f, -150.0f,
1.0f, 0.0f, 0.0f, 0, 400, cgs.media.liteRedParticleStreakShader );
le = CG_MakeExplosion2( origin, dir, cgs.media.explosionModel, 5, cgs.media.electricalExplosionSlowShader,
475, qfalse, 1.2f + ( crandom() * 0.3f), LEF_NONE);
le->light = 150;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 0.8f, 0.8f, 1.0f );
CG_ImpactMark( cgs.media.compressionMarkShader, origin, normal, random()*360, 1,1,1,1, qfalse, 12, qfalse );
//Shake the camera
CG_ExplosionEffects( origin, 1, 200 );
}
else
{
le = CG_MakeExplosion2( origin, dir, cgs.media.explosionModel, 5, cgs.media.electricalExplosionSlowShader,
500, qfalse, 2.2f + ( crandom() * 0.4f), LEF_NONE);
le->light = 200;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 0.8f, 0.8f, 1.0f );
CG_ImpactMark( cgs.media.compressionMarkShader, origin, normal, random()*360, 1,1,1,1, qfalse, 28, qfalse );
//Shake the camera
CG_ExplosionEffects( origin, 2, 240 );
}
// nice explosion sound at the point of impact
trap_S_StartSound(origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->mainHitSound);
}
/*
-------------------------
FX_CompressionHit
-------------------------
*/
void FX_CompressionHit( vec3_t origin )
{
FX_AddSprite( origin,
NULL,
qfalse,
32.0f,
-32.0f,
1.0f,
1.0f,
random()*360,
0.0f,
250.0f,
cgs.media.prifleImpactShader );
//FIXME: Play an impact sound with a body
// trap_S_StartSound (origin, NULL, 0, cgi_S_RegisterSound ("sound/weapons/prifle/fire.wav") );
}
void FX_PrifleBeamFire( vec3_t startpos, vec3_t endpos, vec3_t normal, qboolean spark, qboolean impact, qboolean empty )
{
refEntity_t beam;
sfxHandle_t sfx;
float size;
vec3_t velocity;
int sparks;
vec3_t rgb = { 1,0.9,0.6}, rgb2={1,0.3,0};
//vec3_t rgb3 = { 1.0, 1.0, 1.0 };
sfx = 0;
// Draw beam first.
memset( &beam, 0, sizeof( beam ) );
VectorCopy( startpos, beam.origin);
VectorCopy( endpos, beam.oldorigin );
beam.reType = RT_LINE;
if (empty)
{
beam.customShader = cgs.media.phaserEmptyShader;
}
else
{
beam.customShader = cgs.media.prifleBeam;
}
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff;
beam.shaderRGBA[1] = 0xff;
beam.shaderRGBA[2] = 0xff;
beam.shaderRGBA[3] = 0xff;
if (empty)
{
beam.data.line.width = 1.0f + ( crandom() * 0.6f );
}
else
{
beam.data.line.width = 2.5f + ( crandom() * 0.6f );
}
beam.data.line.stscale = 5.0;
trap_R_AddRefEntityToScene( &beam );
// Now draw the hit graphic
// no explosion at LG impact, it is added with the beam
if ( sfx )
{
Com_Printf("playing %s\n", "phaser sound");
trap_S_StartSound( endpos, ENTITYNUM_WORLD, CHAN_AUTO, sfx );
}
//
// impact mark
//
if (impact)
{
if (!empty)
{ // normal.
CG_ImpactMark( cgs.media.scavMarkShader, endpos, normal, random()*360, 1,1,1,0.2, qfalse,
random() + 1, qfalse );
//VectorCopy( endpos, phaserFlare.worldCoord );
/*CG_InitLensFlare( endpos,
80,
80,
rgb,
1.2,
1.5,
1600,
200,
colorTable[CT_BLACK],
1600,
200,
80,
5,
qfalse,
5,
40,
qfalse,
qfalse,
qfalse,
1.0,
1.0,
200.0,
200.0,
200.0 );*/
//CG_InitLensFlare( endpos,
// 30, 30,
// rgb, 1.2, 2.0, 1600, 200,
// colorTable[CT_BLACK], 1600, 200, 410, 15, qfalse,
// 0, 0, qfalse, qtrue,
// qfalse, 1.0, cg.time, 0, 0, 50);
//TiM : Add your basic cheesy 'seen-way-too-much-in-movies-these-days' anamorphic lens streak :)
//CG_DrawLensFlare( &phaserFlare );
//FX_AddSprite( endpos, NULL, qfalse, random() * 1.25 + 5.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 50.0, cgs.media.blueParticleStreakShader ); //1.5f
//FX_AddQuad2( endpos, normal, random() * 1.25 + 8.0f, 0.0f, 1.0f, 1.0f, rgb3, rgb3, 270, 50.0, cgs.media.blueParticleStreakShader );
//eh... looked bad :P
FX_AddQuad2( endpos, normal, random() * 1.25 + 1.5f, 0.0f, 1.0f, 0.0f, rgb, rgb2, rand() % 360, 500 + random() * 200,
cgs.media.sunnyFlareShader );
}
else
{ // Wuss hit when empty.
FX_AddQuad2( endpos, normal, random() * .75 + 1.0f, 0.0f, 0.5f, 0.0f, rgb, rgb2, rand() % 360, 300 + random() * 200,
cgs.media.sunnyFlareShader );
}
}
// "Fun" sparks... Not when empty.
if ( spark && !empty)
{
sparks = (rand() & 1) + 1;
for(;sparks>0;sparks--)
{
size = 0.2f + (random() * 0.4);
FXE_Spray( normal, 200, 75, 0.8f, velocity);
if (rand() & LEF_USE_COLLISION)
{ // This spark bounces.
FX_AddTrail( endpos, velocity, qtrue, 5.0f, -15.0f,
size, -size, 1.0f, 0.5f, 0.4f, 500.0f, cgs.media.sparkShader);
}
else
{
FX_AddTrail( endpos, velocity, qtrue, 5.0f, -15.0f,
size, -size, 1.0f, 0.5f, 0.0, 500.0f, cgs.media.sparkShader);
}
}
}
}

296
code/cgame/fx_disruptor.c Normal file
View file

@ -0,0 +1,296 @@
#include "cg_local.h"
#include "fx_local.h"
/*
-------------------------
FX_OrientedBolt
Creates new bolts for a while
-------------------------
*/
void FX_OrientedBolt( vec3_t start, vec3_t end, vec3_t dir )
{
vec3_t mid;
VectorSubtract( end, start, mid );
VectorScale( mid, 0.1f + (random() * 0.8), mid );
VectorAdd( start, mid, mid );
VectorMA(mid, 3.0f + (random() * 10.0f), dir, mid );
//FX_AddElectricity( mid, start, 0.5, 0.75 + random() * 0.75, 0.0, 1.0, 0.5, 300.0f + random() * 300, cgs.media.bolt2Shader, DEFAULT_DEVIATION);
//FX_AddElectricity( mid, end, 0.5, 0.75 + random() * 0.75, 1.0, 1.0, 0.5, 300.0f + random() * 300, cgs.media.bolt2Shader, DEFAULT_DEVIATION);
FX_AddElectricity( mid, start, 0.5, 0.75 + random() * 0.75, 0.0, 1.0, 0.5, 300.0f + random() * 300, cgs.media.borgLightningShaders[2], DEFAULT_DEVIATION);
FX_AddElectricity( mid, end, 0.5, 0.75 + random() * 0.75, 1.0, 1.0, 0.5, 300.0f + random() * 300, cgs.media.borgLightningShaders[3], DEFAULT_DEVIATION);
}
/*
-------------------------
FX_DisruptorDischarge
Fun "crawling" electricity ( credit goes to Josh for this one )
-------------------------
*/
void FX_DisruptorDischarge( vec3_t origin, vec3_t normal, int count, float dist_out, float dist_side )
{
trace_t trace;
vec3_t org, dir, dest;
vec3_t vr;
int i;
int discharge = dist_side;
vectoangles( normal, dir );
dir[ROLL] += random() * 360;
for (i = 0; i < count; i++)
{
//Move out a set distance
VectorMA( origin, dist_out, normal, org );
//Even out the hits
dir[ROLL] += (360 / count) + (rand() & 31);
AngleVectors( dir, NULL, vr, NULL );
//Move to the side in a random direction
discharge += (int)( crandom() * 8.0f );
VectorMA( org, discharge, vr, org );
//Trace back to find a surface
VectorMA( org, -dist_out * 3, normal, dest );
CG_Trace( &trace, org, NULL, NULL, dest, 0, MASK_SHOT );
//No surface found, start over
if (trace.fraction == 1)
continue;
//Connect the two points with bolts
FX_OrientedBolt( origin, trace.endpos, normal );
//TiM : Aww screw it. Add a lens flare. ^_^
CG_InitLensFlare( trace.endpos,
10, 10,
colorTable[CT_GREEN], 1.2, 2.0, 1600, 500,
colorTable[CT_GREEN], 1600, 500, 100, 5, qtrue,
0, 0, qfalse, qtrue,
qfalse, 1.0, cg.time, 0, 0, 300.0f + random() * 300);
}
}
/*
-------------------------
FX_DisruptorWeaponHitWall
Main fire impact
-------------------------
*/
#define NUM_DISCHARGES 6
#define DISCHARGE_DIST 8
#define DISCHARGE_SIDE_DIST 24
void FX_DisruptorWeaponHitWall( vec3_t origin, vec3_t dir, int size )
{
vec3_t vel, /*accel,*/ hitpos, direction, org;
//int i, t;
weaponInfo_t *weaponInfo = &cg_weapons[WP_10];
CG_InitLensFlare( origin,
375, 375,
colorTable[CT_GREEN], 1.2, 2.0, 1600, 200,
colorTable[CT_GREEN], 1600, 200, 800, 20, qtrue,
0, 0, qfalse, qtrue,
qfalse, 1.0, cg.time, 0, 0, 200);
// Generate "crawling" electricity // eh, don't it doesn't look that great.
FX_DisruptorDischarge( origin, dir, NUM_DISCHARGES, DISCHARGE_DIST, DISCHARGE_SIDE_DIST );
VectorMA(origin, size, dir, hitpos);
// Set an oriented residual glow effect
FX_AddQuad( hitpos, dir, size * size * 15.0f, -150.0f,
1.0f, 0.0f, 0, 300, cgs.media.greenParticleShader );
CG_ImpactMark( cgs.media.scavMarkShader, origin, dir, random()*360, 1,1,1,0.6, qfalse,
size * 12 + 1, qfalse );
FX_AddSprite( hitpos, NULL, qfalse, size * size * 15.0f, -150.0f,
1.0f, 0.0f, 360*random(), 0, 400, cgs.media.greenParticleShader );
/* FX_AddSprite( hitpos, NULL, qfalse, size * size * 15.0f, -150.0f,
1.0f, 0.0f, 360*random(), 0, 400, cgs.media.greenParticleStreakShader ); */
FX_AddSprite( hitpos, NULL, qfalse, size * size * 25.0f, -150.0f,
1.0f, 0.0f, 0.0f, 0, 400, cgs.media.greenParticleStreakShader );
VectorSubtract( cg.refdef.vieworg, origin, direction );
VectorNormalize( direction );
VectorMA( origin, 12, direction, org );
VectorMA( org, 8, dir, direction );
VectorSet(vel, 0, 0, 32 ); //8
FX_AddSprite( origin,
vel, qfalse,
random() * 4 + 2, 12,
0.6 + random() * 0.4, 0.0,
random() * 180,
0.0,
random() * 200 + 1200, //300
cgs.media.steamShader );
//FX_AddSprite(
// Only play the impact sound and throw off the purple particles when it's the main projectile
/* if ( size < 3 )
return;
for ( i = 0; i < 4; i++ )
{
for ( t = 0; t < 3; t++ )
vel[t] = ( dir[t] + crandom() * 0.9 ) * ( random() * 100 + 250 );
VectorScale( vel, -2.2, accel );
FX_AddSprite( hitpos, vel, qfalse, random() * 8 + 8, 0, 1.0, 0.0, 0.0, 0.0, 200, cgs.media.purpleParticleShader );
}*/
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->mainHitSound );
}
void FX_DisruptorBeamFire( vec3_t startpos, vec3_t endpos, vec3_t normal, qboolean spark, qboolean impact, qboolean empty )
{
refEntity_t beam;
sfxHandle_t sfx;
float size;
vec3_t velocity;
int sparks;
vec3_t rgb = { 1,0.9,0.6}, rgb2={1,0.3,0};
//vec3_t rgb3 = { 1.0, 1.0, 1.0 };
sfx = 0;
// Draw beam first.
memset( &beam, 0, sizeof( beam ) );
VectorCopy( startpos, beam.origin);
VectorCopy( endpos, beam.oldorigin );
beam.reType = RT_LINE;
if (empty)
{
beam.customShader = cgs.media.phaserEmptyShader;
}
else
{
beam.customShader = cgs.media.disruptorBeam;
}
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff;
beam.shaderRGBA[1] = 0xff;
beam.shaderRGBA[2] = 0xff;
beam.shaderRGBA[3] = 0xff;
if (empty)
{
beam.data.line.width = 1.0f + ( crandom() * 0.6f );
}
else
{
beam.data.line.width = 1.5f + ( crandom() * 0.6f );
}
beam.data.line.stscale = 5.0;
trap_R_AddRefEntityToScene( &beam );
// Now draw the hit graphic
// no explosion at LG impact, it is added with the beam
if ( sfx )
{
Com_Printf("playing %s\n", "phaser sound");
trap_S_StartSound( endpos, ENTITYNUM_WORLD, CHAN_AUTO, sfx );
}
//
// impact mark
//
if (impact)
{
if (!empty)
{ // normal.
CG_ImpactMark( cgs.media.scavMarkShader, endpos, normal, random()*360, 1,1,1,0.2, qfalse,
random() + 1, qfalse );
//VectorCopy( endpos, phaserFlare.worldCoord );
/*CG_InitLensFlare( endpos,
80,
80,
rgb,
1.2,
1.5,
1600,
200,
colorTable[CT_BLACK],
1600,
200,
80,
5,
qfalse,
5,
40,
qfalse,
qfalse,
qfalse,
1.0,
1.0,
200.0,
200.0,
200.0 );*/
//CG_InitLensFlare( endpos,
// 30, 30,
// rgb, 1.2, 2.0, 1600, 200,
// colorTable[CT_BLACK], 1600, 200, 410, 15, qfalse,
// 0, 0, qfalse, qtrue,
// qfalse, 1.0, cg.time, 0, 0, 50);
//TiM : Add your basic cheesy 'seen-way-too-much-in-movies-these-days' anamorphic lens streak :)
//CG_DrawLensFlare( &phaserFlare );
//FX_AddSprite( endpos, NULL, qfalse, random() * 1.25 + 5.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 50.0, cgs.media.blueParticleStreakShader ); //1.5f
//FX_AddQuad2( endpos, normal, random() * 1.25 + 8.0f, 0.0f, 1.0f, 1.0f, rgb3, rgb3, 270, 50.0, cgs.media.blueParticleStreakShader );
//eh... looked bad :P
FX_AddQuad2( endpos, normal, random() * 1.25 + 1.5f, 0.0f, 1.0f, 0.0f, rgb, rgb2, rand() % 360, 500 + random() * 200,
cgs.media.sunnyFlareShader );
}
else
{ // Wuss hit when empty.
FX_AddQuad2( endpos, normal, random() * .75 + 1.0f, 0.0f, 0.5f, 0.0f, rgb, rgb2, rand() % 360, 300 + random() * 200,
cgs.media.sunnyFlareShader );
}
}
// "Fun" sparks... Not when empty.
if ( spark && !empty)
{
sparks = (rand() & 1) + 1;
for(;sparks>0;sparks--)
{
size = 0.2f + (random() * 0.4);
FXE_Spray( normal, 200, 75, 0.8f, velocity);
if (rand() & LEF_USE_COLLISION)
{ // This spark bounces.
FX_AddTrail( endpos, velocity, qtrue, 5.0f, -15.0f,
size, -size, 1.0f, 0.5f, 0.4f, 500.0f, cgs.media.sparkShader);
}
else
{
FX_AddTrail( endpos, velocity, qtrue, 5.0f, -15.0f,
size, -size, 1.0f, 0.5f, 0.0, 500.0f, cgs.media.sparkShader);
}
}
}
}

350
code/cgame/fx_grenade.c Normal file
View file

@ -0,0 +1,350 @@
#include "cg_local.h"
#include "fx_local.h"
/*
-------------------------
FX_GrenadeThink
-------------------------
*/
void FX_GrenadeThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
FX_AddSprite( cent->lerpOrigin, NULL, qfalse, 8.0f + random() * 32.0f, 0.0f, 0.75f, 0.75f, 0, 0.0f, 1, cgs.media.dkorangeParticleShader );
if ( rand() & 1 )
FX_AddSprite( cent->lerpOrigin, NULL, qfalse, 16.0f + random() * 32.0f, 0.0f, 0.6f, 0.6f, 0, 0.0f, 1, cgs.media.yellowParticleShader );
}
/*
-------------------------
FX_GrenadeHitWall
-------------------------
*/
void FX_GrenadeHitWall( vec3_t origin, vec3_t normal )
{
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.grenadeExplodeSound );
CG_SurfaceExplosion( origin, normal, 8, 1, qfalse );
}
/*
-------------------------
FX_GrenadeHitPlayer
-------------------------
*/
void FX_GrenadeHitPlayer( vec3_t origin, vec3_t normal )
{
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.grenadeExplodeSound );
CG_SurfaceExplosion( origin, normal, 8, 1, qfalse );
}
/*
-------------------------
FX_GrenadeExplode
-------------------------
*/
void FX_GrenadeExplode( vec3_t origin, vec3_t normal )
{
localEntity_t *le;
qhandle_t null = 0;
vec3_t direction, org, vel;
int i;
VectorSet( direction, 0,0,1 );
// Add an explosion and tag a light to it
le = CG_MakeExplosion2( origin, direction, cgs.media.nukeModel, 5, null, 250, qfalse, 25.0f, LEF_FADE_RGB);
le->light = 150;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 1.0f, 0.6f, 0.2f );
// Ground ring
FX_AddQuad( origin, normal, 5, 100, 1.0, 0.0, random() * 360, 300, cgs.media.bigShockShader );
// Flare
VectorMA( origin, 12, direction, org );
FX_AddSprite( org, NULL, qfalse, 160.0, -160.0, 1.0, 0.0, 0.0, 0.0, 200, cgs.media.sunnyFlareShader );//, FXF_NON_LINEAR_FADE );
for (i = 0; i < 12; i++)
{
float width, length;
FXE_Spray( normal, 470, 325, 0.5f, vel);
length = 24.0 + random() * 12;
width = 0.5 + random() * 2;
FX_AddTrail( origin, vel, qtrue, length, -length, width, -width,
1.0f, 1.0f, 0.5f, 1000.0f, cgs.media.orangeTrailShader);
}
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.grenadeExplodeSound );
// Smoke and impact
// FX_AddSpawner( origin, normal, NULL, NULL, 100, 25.0f, 2000.0f, (void *) CG_SmokeSpawn, NULL, 1024 );
CG_ImpactMark( cgs.media.compressionMarkShader, origin, normal, random()*360, 1,1,1,1.0, qfalse,
random() * 16 + 48, qfalse );
}
/*void FX_GrenadeShrapnelExplode( vec3_t origin, vec3_t norm )
{
localEntity_t *le;
vec3_t direction, org, vel;
int i;
VectorCopy( norm, direction);
// Add an explosion and tag a light to it
le = CG_MakeExplosion2( origin, direction, cgs.media.nukeModel, 5, (qhandle_t)NULL, 250, qfalse, 25.0f, LEF_FADE_RGB);
le->light = 150;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 1.0f, 0.6f, 0.2f );
// Ground ring
FX_AddQuad( origin, norm, 5, 100, 1.0, 0.0, random() * 360, 300, cgs.media.bigShockShader );
// Flare
VectorMA( origin, 12, direction, org );
FX_AddSprite( org, NULL, qfalse, 160.0, -160.0, 1.0, 0.0, 0.0, 0.0, 200, cgs.media.sunnyFlareShader );//, FXF_NON_LINEAR_FADE );
for (i = 0; i < 12; i++)
{
float width, length;
FXE_Spray( norm, 470, 325, 0.5f, vel);
length = 24.0 + random() * 12;
width = 0.5 + random() * 2;
FX_AddTrail( origin, vel, qtrue, length, -length, width, -width,
1.0f, 1.0f, 0.5f, 1000.0f, cgs.media.orangeTrailShader);
}
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.grenadeExnull
// Smoke and impact
CG_ImpactMark( cgs.media.compressionMarkShader, origin, norm, random()*360, 1,1,1,1.0, qfalse,
random() * 16 + 48, qfalse );
}*/
//-----------------------------------
//By: RedTechie - Imported/Modifyed from SP
//-----------------------------------
void FX_GrenadeShrapnelExplode( vec3_t origin, vec3_t norm )
{
localEntity_t *le;
//FXTrail *fx;
vec3_t direction, org, vel;
int i;
CG_InitLensFlare( origin,
350, 350,
colorTable[CT_DKRED1], 1.2, 2.0, 1600, 200,
colorTable[CT_DKRED1], 1600, 200, 800, 20, qtrue,
0, 0, qfalse, qtrue,
qfalse, 1.0, cg.time, 90, 0, 300);
//Orient the explosions to face the camera
VectorSubtract( cg.refdef.vieworg, origin, direction );
VectorNormalize( direction );
VectorMA( origin, 12, direction, org );
// Add an explosion and tag a light to it
le = CG_MakeExplosion2( org, direction, cgs.media.explosionModel, 6, cgs.media.surfaceExplosionShader, 700, qfalse, 1.2f + (random()*0.5f),LEF_FADE_RGB ); //RPG-X: RedTechie - Scale use to be 1.2f + (random()*0.3f)
le->light = 150;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 1.0f, 0.6f, 0.6f );
VectorMA( org, 8, norm, direction );
VectorSet(vel, 0, 0, 8);
//Some smoke
FX_AddSprite( direction,
vel,
qfalse,
20.0f + random()*50.0f,//1.2f + (random()*0.5f),//60.0f - random()*60.0f
16.0f,
100.0f,//1.0f
100.0f,//0.0f
random()*45.0f,
-12.0f,
8000.0f,
cgs.media.steamShader );
for ( i = 0; i < 6; i++)
{
float width, length;
FXE_Spray( norm, 500, 175, 0.8f, vel);//, (FXPrimitive *) fx
length = 24.0 + random() * 12;
width = 0.5 + random() * 2;
FX_AddTrail( origin, vel, qtrue, length, -length, width, -width,
1.0f, 1.0f, 0.5f, 2500.0f, cgs.media.orangeTrailShader);//RPG-X: RedTechie - Killtime use to be 1000.0f
/*FX_AddTrail( origin, NULL, NULL, 16.0f, -15.0f,
1.5, -1.5, 1.0f, 1.0f, 0.2f, 1000.0f, cgs.media.orangeTrailShader, rand() & FXF_BOUNCE );
*/
/*if ( fx == NULL )
return;*/
}
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.grenadeAltExplodeSnd );
CG_ImpactMark( cgs.media.compressionMarkShader, origin, norm, random()*360, 1,1,1,1.0, qfalse,
random() * 16 + 48, qfalse );
CG_ExplosionEffects( origin, 2.0, 350 );
}
qboolean GrenadeBeep(localEntity_t *le)
{
weaponInfo_t *weaponInfo = &cg_weapons[WP_8];
trap_S_StartSound(le->refEntity.origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->altHitSound);
return qtrue;
}
/*
-------------------------
FX_GrenadeShrapnelBits
By: RedTechie - From SP
-------------------------
*/
/*void FX_BlowBits( vec3_t start, vec3_t end, vec3_t dir, vec3_t user )
{
vec3_t diff, org;
float len;
// FXLine *fx;
VectorSubtract( end, start, diff );
len = VectorNormalize( diff ) * ( 0.2 + random() * 0.3 );
VectorMA( start, len, diff, org );
//fx =
FX_AddLine( end, start, (int)(random() * 3.2f), 2.0f + random() * 2, 0, 0.5f, 0.1f, 150 + random() * 150, cgs.media.orangeTrailShader );
//if ( fx == NULL )
// return;
//fx->SetFlags( FXF_SHRINK );
FX_AddQuad( end, dir, NULL, NULL, 1.0f, 64.0f, 1.0, 0.0, random() * 360.0f, 0.0f, 0.0, 200, cgs.media.orangeRingShader );
// FX_AddQuad( end, dir, NULL, NULL, 20.0, -15.0, 0.6, 0.4, 0.0,0.0,0.0,450, cgs.media.borgEyeFlareShader );
}
*/
#define FX_GRENADE_ALT_STICK_TIME 2500
void FX_GrenadeShrapnelBits( vec3_t start )
{
vec3_t zero = {0, 0, 0};
// check G_MissileStick() to make sure this killtime coincides with that nextthink
FX_AddSpawner( start, zero, NULL, NULL, qfalse, 300,
0, FX_GRENADE_ALT_STICK_TIME, GrenadeBeep, 10 );
}
/*
-------------------------
FX_fxfunc_Explosion
-------------------------
*/
void FX_fxfunc_Explosion( vec3_t start, vec3_t origin, vec3_t normal )
{
localEntity_t *le;
vec3_t dir;
vec3_t velocity;
// vec3_t end;
// trace_t trace;
float scale, dscale;
int i, j, numSparks;
//weaponInfo_t *weaponInfo = &cg_weapons[WP_6];
//float scale, dscale;
// int s;
// vec3_t new_org;
//Sparks
numSparks = 20 + (random() * 4.0f);//4
for ( i = 0; i < numSparks; i++ )
{
scale = 0.25f + (random() * 1.0f);
dscale = -scale;
//Randomize the direction
for (j = 0; j < 3; j ++ )
{
dir[j] = normal[j] + (0.75 * crandom());
}
VectorNormalize(dir);
//set the speed
VectorScale( dir, 200 + (50 * crandom()), velocity);
le = FX_AddTrail( origin,
velocity,
qtrue,
4.0f,
-4.0f,
scale,
-scale,
1.0f,
1.0f,
0.5f,
1000.0f,
cgs.media.sparkShader);
}
VectorMA( origin, 8, normal, dir );
VectorSet(velocity, 0, 0, 8);
// Smoke puffs
FX_AddSprite( dir,
velocity,
qfalse,
20.0f + random()*60.0f,//2.2f + ( crandom() * 0.9f),//60.0f - random()*60.0f
16.0f,
100.0f,//1.0f
100.0f,//0.0f
random()*45.0f,
-12.0f,
8000.0f,
cgs.media.steamShader );
//Orient the explosions to face the camera
VectorSubtract( cg.refdef.vieworg, origin, dir );
VectorNormalize( dir );
le = CG_MakeExplosion2( origin, dir, cgs.media.explosionModel, 5, cgs.media.electricalExplosionSlowShader, 475, qfalse, 2.2f + ( crandom() * 0.9f), LEF_NONE);//RPG-X: RedTechie - Scale use to be - 1.2f + ( crandom() * 0.3f)
le->light = 150;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 0.8f, 0.8f, 1.0f );
CG_ImpactMark( cgs.media.compressionMarkShader, origin, normal, random()*360, 1,1,1,1.0, qfalse,
random() * 16 + 48, qfalse );
//CG_ImpactMark( cgs.media.compressionMarkShader, origin, normal, random()*360, 1,1,1,1, qfalse, 12, qfalse );
//Shake the camera
CG_ExplosionEffects( origin, 2, 400 );
// nice explosion sound at the point of impact
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.grenadeAltExplodeSnd );
//trap_S_StartSound(origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->mainHitSound);
}
/*
-------------------------
FX_fxfunc_Shot
-------------------------
*/
#define MAXRANGE_CRIFLE 8192
void FX_fxfunc_Shot( vec3_t start, vec3_t dir )
{
vec3_t end;
trace_t trace;
VectorMA(start, MAXRANGE_CRIFLE, dir, end);
CG_Trace( &trace, start, NULL, NULL, end, 0, MASK_SHOT );
//FX_CompressionExplosion(start, trace.endpos, trace.plane.normal, qfalse );
FX_fxfunc_Explosion(start, trace.endpos, trace.plane.normal);
}

59
code/cgame/fx_hypospray.c Normal file
View file

@ -0,0 +1,59 @@
#include "cg_local.h"
#include "fx_local.h"
/*
-------------------------
FX_HypoSpray
Redtechie: RPG-X Added
FIXME! FIXME! FIXME! FIXME! Im not spraying in the direction some one shoots me!
TiM: Fixed! An improperly formatted directional vector was being sent. it's all good now :)
-------------------------
*/
#define NUM_HYPO_PUFFS 20
void FX_HypoSpray( vec3_t origin, vec3_t dir, qboolean red ) // When not red, it'll be blue
{
vec3_t color, vel, accel, angles, work;
float scale, dscale;
int i;
localEntity_t *le;
vectoangles( dir, angles );
for ( i = 0; i < NUM_HYPO_PUFFS; i++ )
{
if ( red )
{
VectorSet( color, 1.0f, random() * 0.4f, random() * 0.4f ); // mostly red
}
else
{
VectorSet( color, random() * 0.5f, random() * 0.5f + 0.5f, 1.0f ); // mostly blue
}
VectorCopy( angles, work );
work[0] += crandom() * 12.0f;
work[1] += crandom() * 12.0f;
AngleVectors( work, vel, NULL, NULL );
scale = random() * 256.0f + 128.0f;
VectorScale( vel, scale, vel );
VectorScale( vel, random() * -0.3f, accel );
scale = random() * 4.0f + 2.0f;
dscale = random() * 64.0f + 24.0f;
//localEntity_t *FX_AddSprite(vec3_t origin, vec3_t velocity, qboolean gravity, float scale, float dscale,
// float startalpha, float endalpha, float roll, float elasticity,
// float killTime, qhandle_t shader);
le = FX_AddSprite( origin, vel, qfalse, scale, dscale, 0.8f + random() * 0.2f, 0.0f, crandom() * 50, /*crandom() * 5*/0, 1000, cgs.media.steamShader );
VectorSet(le->data.sprite.startRGB, random() * 0.5f, random() * 0.5f + 0.5f, 1.0f );// mostly blue
}
}

306
code/cgame/fx_item.c Normal file
View file

@ -0,0 +1,306 @@
#include "cg_local.h"
#include "fx_local.h"
//
// detpack
//
#define NUM_RING_SHADERS 6
qboolean DetpackAftereffect(localEntity_t *le)
{
localEntity_t *cyl = NULL;
qhandle_t shader = cgs.media.phaserShader;
qhandle_t slowRingShaders[NUM_RING_SHADERS];
float percentLife = 1.0 - (le->endTime - cg.time)*le->lifeRate;
float alpha = 0.6 - (0.6*percentLife*percentLife);
// data for shell
float shellLife = percentLife + .2;
float height1 = 20 + (percentLife * 150);
float height2 =(50*percentLife);
float scale1 = 40 + (percentLife * 1500);
float scale2 = 20 + (percentLife * 1200);
// data for flat energy rings
float ringLife = percentLife + .5;
float scale3 = 200 + (percentLife * 3400);
float scale4 = 100 + (percentLife * 3000);
float scale5 = 20 + (percentLife * 1000);
float scale6 = 10 + (percentLife * 200);
float ringAlpha = 0.6 - (0.6*ringLife*ringLife);
vec3_t up = {0,0,1},origin1;
slowRingShaders[0] = cgs.media.testDetpackRingShader1;
slowRingShaders[1] = cgs.media.testDetpackRingShader2;
slowRingShaders[2] = cgs.media.testDetpackRingShader3;
slowRingShaders[3] = cgs.media.testDetpackRingShader4;
slowRingShaders[4] = cgs.media.testDetpackRingShader5;
slowRingShaders[5] = cgs.media.testDetpackRingShader6;
// slower, inner ring
VectorCopy(le->refEntity.origin, origin1);
if (NUM_RING_SHADERS == le->data.spawner.data1)
{
le->data.spawner.data1 = 0;
}
else if (le->data.spawner.data1 < 0)
{
le->data.spawner.data1 = 0;
}
shader = slowRingShaders[le->data.spawner.data1++];
// fast, outer ring
cyl = FX_AddCylinder( origin1,
up,
0.1,// height,
0,// dheight,
scale5,// scale,
0,// dscale,
scale6,// scale2,
0,// dscale2,
ringAlpha,// startalpha,
0.0,// endalpha,
500,// killTime,
shader,
15);// bias );
cyl->leFlags |= LEF_ONE_FRAME;
if (shellLife <= 1.0f)
{
origin1[2] += height2;
shader = cgs.media.phaserShader;
cyl = FX_AddCylinder( origin1,
up,
height1,// height,
0,// dheight,
scale1,// scale,
0,// dscale,
scale2,// scale2,
0,// dscale2,
alpha,// startalpha,
0.0,// endalpha,
500,// killTime,
shader,
15);// bias );
cyl->leFlags |= LEF_ONE_FRAME;
cyl = FX_AddCylinder( le->refEntity.origin,
up,
height2, // height,
0, // dheight,
scale1, // scale,
0, // dscale,
scale1, // scale2,
0, // dscale2,
alpha, // startalpha,
0.0, // endalpha,
500, // killTime,
shader,
15); // bias );
cyl->leFlags |= LEF_ONE_FRAME;
}
// flat energy wave thingy
if (ringLife <= 1.0f)
{
shader = cgs.media.testDetpackShader3;
VectorCopy(le->refEntity.origin, origin1);
// fast, outer ring
cyl = FX_AddCylinder( origin1,
up,
0.1,// height,
0,// dheight,
scale3,// scale,
0,// dscale,
scale4,// scale2,
0,// dscale2,
ringAlpha,// startalpha,
0.0,// endalpha,
500,// killTime,
shader,
15);// bias );
cyl->leFlags |= LEF_ONE_FRAME;
}
return qtrue;
}
void FX_Detpack(vec3_t origin)
{
localEntity_t *le;
qhandle_t null = 0;
vec3_t direction, org, vel, norm = {0,0,1};
int i;
VectorCopy( norm, direction);
// Add an explosion and tag a light to it
le = CG_MakeExplosion2( origin, direction, cgs.media.nukeModel, 5, null, 250, qfalse, 100.0f, LEF_FADE_RGB);
le->light = 300;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 1.0f, 0.6f, 0.2f );
// Ground ring
// FX_AddQuad( origin, norm, 5, 150, 1.0, 0.0, random() * 360, 600, cgs.media.bigShockShader );
// Flare
VectorMA( origin, 12, direction, org );
FX_AddSprite( org, NULL, qfalse, 160.0, -160.0, 1.0, 0.0, 0.0, 0.0, 500, cgs.media.sunnyFlareShader );//, FXF_NON_LINEAR_FADE );
for (i = 0; i < 12; i++)
{
float width, length;
FXE_Spray( norm, 470, 325, 0.5f, vel);
length = 50.0 + random() * 12;
width = 1.5 + random() * 2;
FX_AddTrail( origin, vel, qtrue, length, -length, width, -width,
1.0f, 1.0f, 0.5f, 1000.0f, cgs.media.orangeTrailShader);
}
// trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.detpackExplodeSound );
// Smoke and impact
CG_ImpactMark( cgs.media.compressionMarkShader, origin, norm, random()*360, 1,1,1,1.0, qfalse,
random() * 16 + 48, qfalse );
// mondo explosion shock wave cloud thing
le = FX_AddSpawner( origin, norm, NULL, NULL, qfalse, 0,
0, 1500, DetpackAftereffect, 10 );
le->data.spawner.data1 = 0;
// shake absolutely _everyone_
CG_ExplosionEffects(origin, 5.0f, 8092);
}
//
// portable shield
//
//RPG-X ToDo: Modify force field Code Here
void FX_DrawPortableShield(centity_t *cent)
{
int xaxis, height, posWidth, negWidth, team; // light;
vec3_t start, end, normal;
//vec4_t RGBA;
float halfHeight;
localEntity_t *le;
qhandle_t shader;
if (cent->currentState.eFlags & EF_NODRAW)
{
return;
}
// decode the data stored in time2
//pos = ((cent->currentState.time2 >> 32) & 1);
//vert = ((cent->currentState.time2 >> 31) & 1);
xaxis = ((cent->currentState.time2 >> 30) & 1); //24
height = ((cent->currentState.time2 >> 20) & 1023); //16
posWidth = ((cent->currentState.time2 >> 10) & 1023); //8
negWidth = (cent->currentState.time2 & 1023);
team = (cent->currentState.otherEntityNum2);
halfHeight = (float)height * .5;
/*if ( !vert )
{*/
VectorCopy(cent->lerpOrigin, start);
VectorCopy(cent->lerpOrigin, end);
start[2] += halfHeight;
end[2] += halfHeight;
VectorClear(normal);
if (xaxis) // drawing along x-axis
{
start[0] -= negWidth;
end[0] += posWidth;
normal[1] = 1;
}
else
{
start[1] -= negWidth;
end[1] += posWidth;
normal[0] = 1;
}
//}
//else
//{
// VectorCopy(cent->lerpOrigin, start);
// VectorCopy(cent->lerpOrigin, end);
// if ( xaxis ) {
// start[1] += halfHeight;
// end[1] += halfHeight;
// }
// else
// {
// start[0] += halfHeight;
// end[0] += halfHeight;
// }
// VectorClear(normal);
// if (xaxis) // drawing along x-axis
// {
// start[0] -= negWidth;
// end[0] += posWidth;
// normal[2] = 1;
// }
// else
// {
// start[1] -= negWidth;
// end[1] += posWidth;
// normal[2] = 1;
// }
//}
// draw a rectangle o' shieldness
/*
if (team == TEAM_RED)
{
if (cent->currentState.eFlags & EF_ITEMPLACEHOLDER)
{ // Damaged.
shader = cgs.media.shieldDamageShaderRed;
}
else
{
shader = cgs.media.shieldActivateShaderRed;
}
}
else
{*/
//TiM - Show the forcefield when the place flag is active only
//This way, we canhave it flare on events, and invisible the rest of the time
//tho make sure admins can see it
if((int)cent->currentState.origin2[0] == 1) {
shader = cgs.media.shieldActivateShaderBorg;
}
else if((int)cent->currentState.origin2[0] == 2) {
shader = cgs.media.shieldActivateShaderYellow;
}
else if((int)cent->currentState.origin2[0] == 3) {
shader = cgs.media.shieldActivateShaderRed;
}
else {
shader = cgs.media.shieldActivateShaderBlue;
}
if ( cent->currentState.eFlags & EF_ITEMPLACEHOLDER || cgs.clientinfo[cg.snap->ps.clientNum].isAdmin/*cg.snap->ps.persistant[PERS_CLASS] == PC_ADMIN*/ )
le = FX_AddOrientedLine(start, end, normal, 1.0f, height, 0.0f, 1.0f, 1.0f, 50.0, shader);
//TiM
//if (cent->currentState.eFlags & EF_ITEMPLACEHOLDER)
//{ // Damaged.
// shader = cgs.media.shieldDamageShaderBlue;
//}
//else
//{
// shader = cgs.media.shieldActivateShaderBlue;
//}
//-
// }
//le = FX_AddOrientedLine(start, end, normal, 1.0f, height, 0.0f, 1.0f, 1.0f, 50.0, shader);
// le->leFlags |= LEF_ONE_FRAME;
}

1170
code/cgame/fx_lib.c Normal file

File diff suppressed because it is too large Load diff

180
code/cgame/fx_local.h Normal file
View file

@ -0,0 +1,180 @@
#define DEFAULT_DEVIATION 0.5
/*
* fx_*.c
*/
void FXE_Spray (vec3_t direction, float speed, float variation, float cone, vec3_t velocity);
localEntity_t *FX_AddLine(vec3_t start, vec3_t end, float stScale, float scale, float dscale,
float startalpha, float endalpha, float killTime, qhandle_t shader);
localEntity_t *FX_AddLine2(vec3_t start, vec3_t end, float stScale, float width1, float dwidth1, float width2, float dwidth2,
float startalpha, float endalpha, vec3_t startRGB, vec3_t endRGB, float killTime, qhandle_t shader);
localEntity_t *FX_AddLine3(vec3_t start, vec3_t end, float stScale, float scale, float dscale,
float startalpha, float endalpha, vec3_t startRGB, vec3_t endRGB, float killTime, qhandle_t shader);
localEntity_t *FX_AddOrientedLine(vec3_t start, vec3_t end, vec3_t normal, float stScale, float scale,
float dscale, float startalpha, float endalpha, float killTime, qhandle_t shader);
localEntity_t *FX_AddTrail( vec3_t origin, vec3_t velocity, qboolean gravity, float length, float dlength,
float scale, float dscale, float startalpha, float endalpha,
float elasticity, float killTime, qhandle_t shader);
localEntity_t *FX_AddTrail2( vec3_t origin, vec3_t velocity, qboolean gravity, float length, float dlength,
float scale, float dscale, float startalpha, float endalpha, vec3_t startRGB, vec3_t endRGB,
float elasticity, float killTime, qhandle_t shader);
localEntity_t *FX_AddSprite(vec3_t origin, vec3_t velocity, qboolean gravity, float scale, float dscale,
float startalpha, float endalpha, float roll, float elasticity,
float killTime, qhandle_t shader);
localEntity_t *FX_AddSprite2(vec3_t origin, vec3_t velocity, qboolean gravity, float scale, float dscale,
float startalpha, float endalpha, vec3_t startRGB, vec3_t endRGB, float roll, float elasticity,
float killTime, qhandle_t shader);
localEntity_t *FX_AddSprite3(vec3_t origin, vec3_t velocity, vec3_t acceleration, float scale, float dscale,
float startalpha, float endalpha, float roll, float elasticity,
float killTime, qhandle_t shader);
localEntity_t *FX_AddBezier(vec3_t start, vec3_t end, vec3_t cpoint1, vec3_t cpoint2, vec3_t cpointvel1,
vec3_t cpointvel2,vec3_t cpointacc1, vec3_t cpointacc2, float width,
float killTime, qhandle_t shader);
localEntity_t *FX_AddQuad( vec3_t origin, vec3_t normal, float scale, float dscale,
float startalpha, float endalpha, float roll, float killTime, qhandle_t shader );
localEntity_t *FX_AddQuad2( vec3_t origin, vec3_t normal, float scale, float dscale, float startalpha, float endalpha,
vec3_t startRGB, vec3_t endRGB, float roll, float killTime, qhandle_t shader );
localEntity_t *FX_AddCylinder( vec3_t start,
vec3_t normal,
float height,
float dheight,
float scale,
float dscale,
float scale2,
float dscale2,
float startalpha,
float endalpha,
float killTime,
qhandle_t shader,
float bias );
localEntity_t *FX_AddCylinder2( vec3_t start,
vec3_t normal,
float height,
float dheight,
float scale,
float dscale,
float scale2,
float dscale2,
float startalpha,
float endalpha,
vec3_t startRGB,
vec3_t endRGB,
float killTime,
qhandle_t shader,
float bias );
localEntity_t *FX_AddCylinder( vec3_t start,
vec3_t normal,
float height,
float dheight,
float scale,
float dscale,
float scale2,
float dscale2,
float startalpha,
float endalpha,
float killTime,
qhandle_t shader,
float bias );
localEntity_t *FX_AddElectricity( vec3_t origin, vec3_t origin2, float stScale, float scale, float dscale,
float startalpha, float endalpha, float killTime, qhandle_t shader, float deviation );
localEntity_t *FX_AddParticle( vec3_t origin, vec3_t velocity, qboolean gravity, float scale, float dscale,
float startalpha, float endalpha, float roll, float elasticity,
float killTime, qhandle_t shader, qboolean (*thinkFn)(localEntity_t *le));
localEntity_t *FX_AddSpawner( vec3_t origin, vec3_t dir, vec3_t velocity, vec3_t user, qboolean gravity, int delay,
float variance, float killTime, qboolean (*thinkFn)(localEntity_t *le), int radius );
/*
* phaser
*/
void FX_PhaserFire( vec3_t start, vec3_t end, vec3_t normal, qboolean spark, qboolean impact, qboolean empty );
void FX_PhaserAltFire( vec3_t start, vec3_t end, vec3_t normal, qboolean spark, qboolean impact, qboolean empty );
/*
* compression rifle
*/
void FX_CompressionShot( vec3_t start, vec3_t end );
void FX_CompressionAltShot( vec3_t start, vec3_t end );
void FX_CompressionExplosion( vec3_t start, vec3_t origin, vec3_t normal, qboolean altfire );
void FX_CompressionHit( vec3_t origin );
void FX_PrifleBeamFire( vec3_t startpos, vec3_t endpos, vec3_t normal, qboolean spark, qboolean impact, qboolean empty );
void FX_ProbeBeam( vec3_t origin, vec3_t dir, int clientNum, qboolean alt_fire );
void FX_RegenBeam( vec3_t origin, vec3_t dir, int clientNum, qboolean alt_fire );
/*
* tetrion disruptor
*/
void FX_TetrionShot( vec3_t start, vec3_t forward );
/*
* Scavenger Rifle
*/
void FX_HypoSpray( vec3_t origin, vec3_t dir, qboolean red );
/*
* Grenade launcher
*/
void FX_GrenadeThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_GrenadeHitWall( vec3_t origin, vec3_t normal );
void FX_GrenadeHitPlayer( vec3_t origin, vec3_t normal );
void FX_GrenadeExplode( vec3_t origin, vec3_t normal );
void FX_GrenadeShrapnelExplode( vec3_t origin, vec3_t norm );
void FX_GrenadeShrapnelBits( vec3_t start);
void FX_fxfunc_Explosion( vec3_t start, vec3_t origin, vec3_t normal );
void FX_fxfunc_Shot( vec3_t start, vec3_t dir );
/*
* detpack
*/
void FX_Detpack(vec3_t origin);
/*
* Disruptor Weapon
*/
void FX_DisruptorBeamFire( vec3_t startpos, vec3_t endpos, vec3_t normal, qboolean spark, qboolean impact, qboolean empty );
void FX_DisruptorWeaponHitWall( vec3_t origin, vec3_t dir, int size );
/*
* Quantum Burst
*/
void FX_QuantumThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_QuantumAltThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_QuantumHitWall( vec3_t origin, vec3_t normal );
void FX_QuantumAltHitWall( vec3_t origin, vec3_t normal );
void FX_QuantumColumns( vec3_t origin );
/*
* transporter
*/
void FX_Transporter(vec3_t origin);
void FX_TransporterPad( vec3_t origin );
void FX_SPTransporterLensFlares( centity_t* cent, vec3_t headVector, int startTime );
/* Holdable, portable shield item */
void FX_DrawPortableShield(centity_t *cent);
/* Shield */
void FX_PlayerShieldHit( centity_t *cent );
/*
* Miscellaneous FX
*/
void FX_Disruptor( vec3_t org, float length );
void FX_ExplodeBits( vec3_t org);
void FX_qFlash( centity_t* cent, vec3_t org, int timeIndex );
/*
* sin table
*/
void fxRandCircumferencePos(vec3_t center, vec3_t normal, float radius, vec3_t out);

286
code/cgame/fx_misc.c Normal file
View file

@ -0,0 +1,286 @@
#include "cg_local.h"
#include "fx_local.h"
/*
-------------------------
FX_Disruptor
-------------------------
*/
void DisruptorShards(vec3_t org)
{
vec3_t normal, end;
// Pick a random endpoint
VectorSet( normal, crandom(), crandom(), crandom() );
VectorNormalize( normal );
end[0] = org[0] + ( normal[0] * ( 48 + crandom() * 16 ));
end[1] = org[1] + ( normal[1] * ( 48 + crandom() * 16 ));
end[2] = org[2] + ( normal[2] * ( 64 + crandom() * 24 ));
// Draw a light shard, use a couple of different kinds so it doesn't look too homogeneous
if( rand() & 1 )
{
FX_AddLine( org, end, 1.0, random() * 0.5 + 0.5, 12.0, random() * 0.1 + 0.1, 0.0, 200 + random() * 350, cgs.media.orangeParticleShader );
}
else
{
FX_AddLine( org, end, 1.0, random() * 0.5 + 0.5, 12.0, random() * 0.1 + 0.1, 0.0, 200 + random() * 350, cgs.media.yellowParticleShader );
}
}
qboolean MakeDisruptorShard( localEntity_t *le )
{
DisruptorShards(le->refEntity.origin);
return(qtrue);
}
// Effect used when scav beams in--this wouldn't work well for a scav on the ground if they were to beam out
void FX_Disruptor( vec3_t org, float length )
{//FIXME: make it move with owner?
vec3_t org1, org2, normal={0,0,1};
int t;
VectorMA( org, 48, normal, org1 );
VectorMA( org, -48, normal, org2 );
// This is the core
FX_AddLine( org1, org2, 1.0, 0.1, 48.0, 1.0, 0.0, length, cgs.media.dkorangeParticleShader );
// Spawn a bunch to get the effect going
for (t=0; t < 12; t++ )
{
DisruptorShards( org);
}
// Keep spawning the light shards for a while.
FX_AddSpawner( org, normal, NULL, NULL, qfalse, 20, 10, length*0.75, MakeDisruptorShard, 0);
}
void FX_EnergyGibs(vec3_t origin )
{
localEntity_t *le;
refEntity_t *re;
vec3_t dir;
int i, j, k;
int chunkModel=0;
float baseScale = 0.7f, dist;
int numChunks;
numChunks = irandom( 10, 15 );
VectorSubtract(cg.snap->ps.origin, origin, dir);
dist = VectorLength(dir);
if (dist > 512)
{
numChunks *= 512.0/dist; // 1/2 at 1024, 1/4 at 2048, etc.
}
for ( i = 0; i < numChunks; i++ )
{
chunkModel = cgs.media.chunkModels[MT_METAL][irandom(0,5)];
le = CG_AllocLocalEntity();
re = &le->refEntity;
le->leType = LE_FRAGMENT;
le->endTime = cg.time + 2000;
VectorCopy( origin, re->origin );
for ( j = 0; j < 3; j++ )
{
re->origin[j] += crandom() * 12;
}
VectorCopy( re->origin, le->pos.trBase );
//Velocity
VectorSet( dir, crandom(), crandom(), crandom() );
VectorScale( dir, flrandom( 300, 500 ), le->pos.trDelta );
//Angular Velocity
VectorSet( le->angles.trBase, crandom() * 360, crandom() * 360, crandom() * 360 );
VectorSet( le->angles.trDelta, crandom() * 90, crandom() * 90, crandom() * 90 );
AxisCopy( axisDefault, re->axis );
le->data.fragment.radius = flrandom(baseScale * 0.4f, baseScale * 0.8f );
re->nonNormalizedAxes = qtrue;
re->hModel = chunkModel;
re->renderfx |= RF_CAP_FRAMES;
re->customShader = cgs.media.quantumDisruptorShader;
re->shaderTime = cg.time/1000.0f;
le->pos.trType = TR_GRAVITY;
le->pos.trTime = cg.time;
le->angles.trType = TR_INTERPOLATE;
le->angles.trTime = cg.time;
le->bounceFactor = 0.2f + random() * 0.2f;
le->leFlags |= LEF_TUMBLE;
re->shaderRGBA[0] = re->shaderRGBA[1] = re->shaderRGBA[2] = re->shaderRGBA[3] = 255;
// Make sure that we have the desired start size set
for( k = 0; k < 3; k++)
{
VectorScale(le->refEntity.axis[k], le->data.fragment.radius, le->refEntity.axis[k]);
}
}
}
void FX_ExplodeBits( vec3_t org)
{
float width, length;
vec3_t vel, pos;
int i;
FX_EnergyGibs(org);
for (i = 0; i < 32; i++)
{
VectorSet(vel, flrandom(-320,320), flrandom(-320,320), flrandom(-100,320));
VectorCopy(org, pos);
pos[2] += flrandom(-8, 8);
length = flrandom(10,20);
width = flrandom(2.0,4.0);
FX_AddTrail( pos, vel, qtrue, length, -length, width, -width,
1.0f, 1.0f, 0.5f, 1000.0f, cgs.media.orangeTrailShader);
}
}
#define Q_FLASH_SIZE 110
void FX_qFlash( centity_t* cent, vec3_t org, int timeIndex ) {
trace_t tr;
refEntity_t flare;
float frac;
if ( cg.predictedPlayerState.clientNum != cent->currentState.clientNum ) {
CG_Trace( &tr, cg.refdef.vieworg, NULL, NULL,
cent->lerpOrigin, cg.predictedPlayerState.clientNum, CONTENTS_SOLID );
if ( tr.fraction != 1 ) {
return;
}
}
memset( &flare, 0, sizeof( flare ) );
flare.reType = RT_SPRITE;
flare.shaderRGBA[0] = 0xff;
flare.shaderRGBA[1] = 0xff;
flare.shaderRGBA[2] = 0xff;
flare.shaderRGBA[3] = 0xff;
flare.data.sprite.rotation = 0;
flare.nonNormalizedAxes = qtrue; //needed for effective scaling
flare.customShader = cgs.media.qFlashSprite;
flare.renderfx |= RF_DEPTHHACK;
VectorCopy( org, flare.origin );
//find the basic ratio
frac = (float)(cg.time - timeIndex) / (float)( Q_FLASH_TIME );
//apply a sine function to it to make it less linear
//calculated using the fine graph prog @ http://math.umn.edu/~garrett/a08/Graph.html
frac = ( 0.65f * sin( 4.5f * frac - 0.6f ) + 0.35f );
frac = Com_Clamp( 0.0f, 1.0f, frac );
//CG_Printf( "%f\n", frac );
flare.data.sprite.radius = (float)Q_FLASH_SIZE * frac;
trap_R_AddRefEntityToScene( &flare );
}
#define PROBE_BEAM_LENGTH 32
//TiM - Beam FX for the Neutrino Probe weapon
void FX_ProbeBeam( vec3_t origin, vec3_t dir, int clientNum, qboolean alt_fire )
{
trace_t tr;
refEntity_t beam;
vec3_t end;
float scale;
memset( &beam, 0, sizeof( beam ) );
if ( alt_fire )
scale = flrandom(7.0f, 12.0f);
else
scale = Q_fabs( 12.0f * sin( cg.time * 0.1f ) );
VectorMA( origin, PROBE_BEAM_LENGTH, dir, end );
CG_Trace( &tr, origin, NULL, NULL, end, clientNum, CONTENTS_SOLID );
trap_R_AddLightToScene( origin, 20, 114.0f / 255, 164.0f / 255, 1.0f );
VectorCopy( origin, beam.origin);
VectorCopy( tr.endpos, beam.oldorigin );
beam.reType = RT_LINE;
beam.customShader = cgs.media.probeBeam;
beam.shaderRGBA[0] = 0xff;
beam.shaderRGBA[1] = 0xff;
beam.shaderRGBA[2] = 0xff;
beam.shaderRGBA[3] = 0xff;
AxisClear( beam.axis );
beam.data.line.width = scale*0.1;
beam.data.line.width2 = scale;
beam.data.line.stscale = 1.0;
trap_R_AddRefEntityToScene( &beam );
if ( tr.fraction != 1.0f )
{
float radius;
if ( alt_fire )
radius = flrandom(1.5f, 3.0f) * (1.0 - (tr.fraction*0.3));
else
radius = flrandom(0.5f, 1.5f) * (1.0 - (tr.fraction*0.3));
if ( !radius )
return;
CG_ImpactMark( cgs.media.probeDecal, tr.endpos, tr.plane.normal, 0, 1, 1, 1, 0.2*(1.0-tr.fraction), qfalse, radius, qtrue );
trap_R_AddLightToScene( origin, radius*5, 114.0f / 255, 164.0f / 255, 1.0f );
}
}
#define REGEN_BEAM_LENGTH 64
void FX_RegenBeam( vec3_t origin, vec3_t dir, int clientNum, qboolean alt_fire )
{
trace_t tr;
vec3_t end;
VectorMA( origin, REGEN_BEAM_LENGTH, dir, end );
CG_Trace( &tr, origin, NULL, NULL, end, clientNum, CONTENTS_SOLID );
trap_R_AddLightToScene( origin, 30, 235.0f / 255, 74.0f / 255, 102.0f / 255 );
if ( tr.fraction != 1.0f )
{
float radius;
if ( alt_fire )
radius = flrandom(1.5f, 3.0f) * (1.0 - (tr.fraction*0.3));
else
radius = flrandom(0.5f, 1.5f) * (1.0 - (tr.fraction*0.3));
if ( !radius )
return;
CG_ImpactMark( cgs.media.regenDecal, tr.endpos, tr.plane.normal, 0, 1, 1, 1, 0.2*(1.0-tr.fraction), qfalse, radius, qtrue );
trap_R_AddLightToScene( origin, radius*5, 235.0f / 255, 74.0f / 255, 102.0f / 255 );
}
}

357
code/cgame/fx_phaser.c Normal file
View file

@ -0,0 +1,357 @@
//Phaser
#include "cg_local.h"
#include "fx_local.h"
/*
-------------------------
FX_PhaserFire
-------------------------
*/
lensFlare_t phaserFlare = { {0.0,0.0,0.0},
20,
20,
{1.0, 0.7, 0.13},
1.2,
1.5,
20,
300,
{0.0, 0.0, 0.0},
20,
300,
80,
5,
qfalse,
5,
40,
qfalse,
qfalse,
qtrue,
1.0,
1.0,
1.0,
1.0,
1.0,
qtrue };
void FX_PhaserFire( vec3_t startpos, vec3_t endpos, vec3_t normal, qboolean spark, qboolean impact, qboolean empty )
{
refEntity_t beam;
sfxHandle_t sfx;
float size;
vec3_t velocity;
int sparks;
vec3_t rgb = { 1,0.9,0.6}, rgb2={1,0.3,0};
//vec3_t rgb3 = { 1.0, 1.0, 1.0 };
sfx = 0;
// Draw beam first.
memset( &beam, 0, sizeof( beam ) );
VectorCopy( startpos, beam.origin);
VectorCopy( endpos, beam.oldorigin );
beam.reType = RT_LINE;
if (empty)
{
beam.customShader = cgs.media.phaserEmptyShader;
}
else
{
beam.customShader = cgs.media.phaserShader;
}
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff;
beam.shaderRGBA[1] = 0xff;
beam.shaderRGBA[2] = 0xff;
beam.shaderRGBA[3] = 0xff;
if (empty)
{
beam.data.line.width = 1.0f + ( crandom() * 0.6f );
}
else
{
beam.data.line.width = 2.0f + ( crandom() * 0.6f );
}
beam.data.line.stscale = 5.0;
trap_R_AddRefEntityToScene( &beam );
// Now draw the hit graphic
// no explosion at LG impact, it is added with the beam
if ( sfx )
{
Com_Printf("playing %s\n", "phaser sound");
trap_S_StartSound( endpos, ENTITYNUM_WORLD, CHAN_AUTO, sfx );
}
//
// impact mark
//
if (impact)
{
if (!empty)
{ // normal.
CG_ImpactMark( cgs.media.scavMarkShader, endpos, normal, random()*360, 1,1,1,0.2, qfalse,
random() + 1, qfalse );
//VectorCopy( endpos, phaserFlare.worldCoord );
/*CG_InitLensFlare( endpos,
80,
80,
rgb,
1.2,
1.5,
1600,
200,
colorTable[CT_BLACK],
1600,
200,
80,
5,
qfalse,
5,
40,
qfalse,
qfalse,
qfalse,
1.0,
1.0,
200.0,
200.0,
200.0 );*/
//CG_InitLensFlare( endpos,
// 30, 30,
// rgb, 1.2, 2.0, 1600, 200,
// colorTable[CT_BLACK], 1600, 200, 410, 15, qfalse,
// 0, 0, qfalse, qtrue,
// qfalse, 1.0, cg.time, 0, 0, 50);
//TiM : Add your basic cheesy 'seen-way-too-much-in-movies-these-days' anamorphic lens streak :)
//CG_DrawLensFlare( &phaserFlare );
//FX_AddSprite( endpos, NULL, qfalse, random() * 1.25 + 5.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 50.0, cgs.media.blueParticleStreakShader ); //1.5f
//FX_AddQuad2( endpos, normal, random() * 1.25 + 8.0f, 0.0f, 1.0f, 1.0f, rgb3, rgb3, 270, 50.0, cgs.media.blueParticleStreakShader );
//eh... looked bad :P
FX_AddQuad2( endpos, normal, random() * 1.25 + 1.5f, 0.0f, 1.0f, 0.0f, rgb, rgb2, rand() % 360, 500 + random() * 200,
cgs.media.sunnyFlareShader );
}
else
{ // Wuss hit when empty.
FX_AddQuad2( endpos, normal, random() * .75 + 1.0f, 0.0f, 0.5f, 0.0f, rgb, rgb2, rand() % 360, 300 + random() * 200,
cgs.media.sunnyFlareShader );
}
}
// "Fun" sparks... Not when empty.
if ( spark && !empty)
{
sparks = (rand() & 1) + 1;
for(;sparks>0;sparks--)
{
size = 0.2f + (random() * 0.4);
FXE_Spray( normal, 200, 75, 0.8f, velocity);
if (rand() & LEF_USE_COLLISION)
{ // This spark bounces.
FX_AddTrail( endpos, velocity, qtrue, 5.0f, -15.0f,
size, -size, 1.0f, 0.5f, 0.4f, 500.0f, cgs.media.sparkShader);
}
else
{
FX_AddTrail( endpos, velocity, qtrue, 5.0f, -15.0f,
size, -size, 1.0f, 0.5f, 0.0, 500.0f, cgs.media.sparkShader);
}
}
}
}
/*
-------------------------
FX_PhaserAltFire
-------------------------
*/
#define PHASER_ALT_CONE_LEN 256
void FX_PhaserAltFire( vec3_t start, vec3_t end, vec3_t normal, qboolean spark, qboolean impact, qboolean empty )
{
float scale = flrandom(13.0f, 17.0f), scale2 = flrandom(2.0f, 6.0f);
vec3_t vel, diff, end2;
int i = 0, sparks = 0;
refEntity_t beam;
vec3_t rgb = { 1,0.6,0.5}, rgb2={1,0.3,0};
float len;
int color;
VectorSubtract(end, start, diff);
len = VectorNormalize(diff);
color = 0xff * flrandom(0.75, 1.0);
if (empty)
{ // More faint and shaky line.
scale *= flrandom(0.25,0.75);
}
if (len > PHASER_ALT_CONE_LEN)
{ // Draw beam in two parts...
// Draw main beam first.
VectorMA(start, PHASER_ALT_CONE_LEN, diff, end2);
// Draw starting cone
memset( &beam, 0, sizeof( beam ) );
VectorCopy( start, beam.origin);
VectorCopy( end2, beam.oldorigin );
beam.reType = RT_LINE2;
if (empty)
{
beam.customShader = cgs.media.phaserAltEmptyShader;
}
else
{
beam.customShader = cgs.media.phaserAltShader;
}
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff;
beam.shaderRGBA[1] = 0xff*0.3;
beam.shaderRGBA[2] = 0;
beam.shaderRGBA[3] = 0xff;
beam.data.line.width = scale*0.1;
beam.data.line.width2 = scale;
beam.data.line.stscale = 1.0;
trap_R_AddRefEntityToScene( &beam );
// Draw big thick normal beam for the rest.
memset( &beam, 0, sizeof( beam ) );
VectorCopy( end2, beam.oldorigin);
VectorCopy( end, beam.origin );
beam.reType = RT_LINE;
if (empty)
{
beam.customShader = cgs.media.phaserAltEmptyShader;
}
else
{
beam.customShader = cgs.media.phaserAltShader;
}
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff;
beam.shaderRGBA[1] = 0xff*0.3;
beam.shaderRGBA[2] = 0;
beam.shaderRGBA[3] = 0xff;
beam.data.line.width = scale;
beam.data.line.stscale = 1.0;
trap_R_AddRefEntityToScene( &beam );
// Draw beam core, all one bit.
memset( &beam, 0, sizeof( beam ) );
VectorCopy( start, beam.origin);
VectorCopy( end, beam.oldorigin );
beam.reType = RT_LINE2;
beam.customShader = cgs.media.phaserShader;
AxisClear( beam.axis );
beam.shaderRGBA[0] = color*0.75f;
beam.shaderRGBA[1] = 0xff*0.5f;
beam.shaderRGBA[2] = 0xff*0.5f;
beam.shaderRGBA[3] = 0xff;
beam.data.line.width = scale2*0.2;
beam.data.line.width2 = scale2;
beam.data.line.stscale = 1.0;
trap_R_AddRefEntityToScene( &beam );
}
else
{ // Draw beam in two parts...
// Draw beam first.
memset( &beam, 0, sizeof( beam ) );
VectorCopy( start, beam.origin);
VectorCopy( end, beam.oldorigin );
beam.reType = RT_LINE2;
beam.customShader = cgs.media.phaserAltShader;
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff;
beam.shaderRGBA[1] = 0xff*0.3;
beam.shaderRGBA[2] = 0;
beam.shaderRGBA[3] = 0xff;
beam.data.line.width = scale*0.1;
beam.data.line.width2 = scale;
beam.data.line.stscale = 1.0;
trap_R_AddRefEntityToScene( &beam );
// just one beam is never enough
memset( &beam, 0, sizeof( beam ) );
VectorCopy( start, beam.origin);
VectorCopy( end, beam.oldorigin );
beam.reType = RT_LINE2;
beam.customShader = cgs.media.phaserShader;
AxisClear( beam.axis );
beam.shaderRGBA[0] = color*0.75f;
beam.shaderRGBA[1] = 0xff*0.5f;
beam.shaderRGBA[2] = 0xff*0.5f;
beam.shaderRGBA[3] = 0xff;
beam.data.line.width = scale2*0.2;
beam.data.line.width2 = scale2;
beam.data.line.stscale = 1.0;
trap_R_AddRefEntityToScene( &beam );
}
// Phaser beam
// FX_AddLine( start, end, 1.0f, scale, 0.0f, 0.9f, 0.9f, 2, cgs.media.phaserShader );
// FX_AddLine( start, end, 1.0f, scale * 0.5f, 0.0f, 0.8f, 0.8f, 2, cgs.media.phaserShader );
// Per frame impact mark
FX_AddQuad( end, normal, random() * 1.5 + 1.75f, 0.0f, 1.0f, 0.0f, 0.0f, 1, cgs.media.sparkShader );
FX_AddQuad( end, normal, random() * 5 + 2.75f, 0.0f, 1.0f, 0.0f, 0.0f, 1, cgs.media.yellowParticleShader );
// Multi frame impacts--never do this when it hits a player because it will just look stupid
if ( impact )
{
FX_AddQuad2( end, normal, random() * 2.0 + 5.0f, 2.5f, 0.6f, 0.0f, rgb, rgb2, 0.0f, 500 + random() * 200,
cgs.media.sunnyFlareShader );
CG_ImpactMark( cgs.media.scavMarkShader, end, normal, random()*360, 1,1,1,0.1, qfalse,
random() + 6.0, qfalse );
}
// "Fun" sparks
if ( spark )
{
// kef -- fixme. dunno what the deal is with this velocity vector
VectorClear(vel);
sparks = (rand() & 3) + 1;
// Set random starting pos...
end2[0] = flrandom(-1.0, 1.0) + end[0];
end2[1] = flrandom(-1.0, 1.0) + end[1];
end2[2] = flrandom(-1.0, 1.0) + end[2];
for( i = 0; i < sparks; i++ )
{
scale = 0.5f + (random() * 0.5);
FXE_Spray( normal, 200, 75, 0.8f, /*1024*/vel);
FX_AddTrail2( end2, vel, qfalse,
8.0f, -8.0f,
scale, -scale, 0.5f, 0.0f, rgb, rgb2, 0.4f, 500.0f, cgs.media.sparkShader );
}
VectorMA(end, -8, diff, end2);
// Add a hit sprite over everything...
memset( &beam, 0, sizeof( beam ) );
VectorCopy( end2, beam.origin);
beam.reType = RT_SPRITE;
beam.customShader = cgs.media.sunnyFlareShader;
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff*1.0f;
beam.shaderRGBA[1] = 0xff*0.9f;
beam.shaderRGBA[2] = 0xff*0.8f;
beam.shaderRGBA[3] = 0xff;
beam.data.sprite.radius = random()*2.0 + 9.0;
trap_R_AddRefEntityToScene( &beam );
}
}

356
code/cgame/fx_quantum.c Normal file
View file

@ -0,0 +1,356 @@
#include "cg_local.h"
#include "fx_local.h"
void FX_QuantumThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t line1end, line2end, axis[3], rgb;
AxisClear( axis );
// convert direction of travel into axis
if ( VectorNormalize2( cent->currentState.pos.trDelta, axis[0] ) == 0 ) {
axis[0][2] = 1;
}
// spin as it moves
RotateAroundDirection( axis, cg.time * 0.3f );// * 1.25f );
VectorMA( cent->lerpOrigin, -24.0f, axis[1], line1end );
VectorMA( cent->lerpOrigin, 24.0f, axis[1], line2end );
FX_AddLine( line1end, line2end, 1.0f, random() * 6 + 2, 0.0f, 0.2 + random() * 0.2, 0.0f, 1, cgs.media.yellowParticleShader );
AxisClear( axis );
// convert direction of travel into axis
if ( VectorNormalize2( cent->currentState.pos.trDelta, axis[0] ) == 0 ) {
axis[0][2] = 1;
}
// spin as it moves
RotateAroundDirection( axis, -cg.time * 0.3f );// * 1.25f );
VectorMA( cent->lerpOrigin, -48.0f, axis[2], line1end );
VectorMA( cent->lerpOrigin, 48.0f, axis[2], line2end );
FX_AddLine( line1end, line2end, 1.0f, random() * 5 + 2, 0.0f, 0.1 + random() * 0.2, 0.0f, 1, cgs.media.yellowParticleShader );
VectorSet( rgb, 1.0f, 0.45f, 0.15f ); // orange
FX_AddSprite( cent->lerpOrigin, NULL,qfalse,random() * 60 + 30, 4, 0.5f, 0.0f, 0, 0.0f, 1.0f, cgs.media.orangeParticleShader );
FX_AddSprite2(cent->lerpOrigin, NULL,qfalse,random() * 10 + 60, 0.0f, 0.1f, 0.1f, rgb, rgb, 0.0f, 0.0f, 1, cgs.media.whiteRingShader );
FX_AddSprite( cent->lerpOrigin, NULL,qfalse,random() * 16 + 8, 4, 0.5f, 0.0f, 0, 0.0f, 1.0f, cgs.media.yellowParticleShader );
/*
VectorCopy( cent->lerpOrigin, quantumFlare.worldCoord );
VectorCopy( colorTable[CT_CYAN], quantumFlare.glowColor );
VectorCopy( colorTable[CT_CYAN], quantumFlare.streakColor );
CG_DrawLensFlare( quantumFlare );*/
}
/*
-------------------------
FX_QuantumAltThink
-------------------------
*/
void FX_QuantumAltThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t line1end, line2end, axis[3], vel, rgb;
float scale;
AxisClear( axis );
// convert direction of travel into axis
if ( VectorNormalize2( cent->currentState.pos.trDelta, axis[0] ) == 0 ) {
axis[0][2] = 1;
}
// spin as it moves
RotateAroundDirection( axis, cg.time * 0.3f );// * 1.25f );
VectorMA( cent->lerpOrigin, -48.0f, axis[1], line1end );
VectorMA( cent->lerpOrigin, 48.0f, axis[1], line2end );
FX_AddLine( line1end, line2end, 1.0f, random() * 6 + 2, 0.0f, 0.2 + random() * 0.2, 0.0f, 1, cgs.media.yellowParticleShader );
VectorMA( cent->lerpOrigin, -48.0f, axis[2], line1end );
VectorMA( cent->lerpOrigin, 48.0f, axis[2], line2end );
FX_AddLine( line1end, line2end, 1.0f, random() * 5 + 2, 0.0f, 0.2 + random() * 0.2, 0.0f, 1, cgs.media.yellowParticleShader );
VectorSet( rgb, 1.0f, 0.45f, 0.15f ); // orange
FX_AddSprite( cent->lerpOrigin, NULL,qfalse,random() * 60 + 30, 4, 0.5f, 0.0f, 0, 0.0f, 1.0f, cgs.media.orangeParticleShader );
FX_AddSprite2(cent->lerpOrigin, NULL,qfalse,random() * 10 + 60, 0.0f, 0.1f, 0.1f, rgb, rgb, 0.0f, 0.0f, 1, cgs.media.whiteRingShader );
FX_AddSprite( cent->lerpOrigin, NULL,qfalse,random() * 16 + 8, 4, 0.5f, 0.0f, 0, 0.0f, 1.0f, cgs.media.yellowParticleShader );
scale = ( 2.0f + cos( cg.time * ( M_PI * 0.001f * 4 ))) * 0.5f;
// Unlike the main fire, I'm leaving around this center core for a moment as a trail...
VectorScale( cent->currentState.pos.trDelta, 0.25f, vel );
FX_AddSprite( cent->lerpOrigin, NULL,qfalse,scale * 8 + 2, scale * -5.0f, 0.8f, 0.0f, 0, 0, 300.0f, cgs.media.sunnyFlareShader);
// Tack on a sprite trail so we can see the cool tracking at work.
VectorSet( vel, flrandom(-12, 12), flrandom(-12, 12), flrandom(-12, 12));
VectorMA( vel, 0.25f, cent->currentState.pos.trDelta, vel);
if ( rand() & 1 )
FX_AddSprite( cent->lerpOrigin, vel,qfalse,random() * 12.0f + scale * 14, -10, 0.2f + random() * 0.2f, 0.0, random()*360, 0, 800 + random() * 200.0f,
cgs.media.orangeRingShader );
else
FX_AddSprite2(cent->lerpOrigin, vel,qfalse,random() * 12.0f + scale * 14, -10, 0.5, 0.0, rgb, rgb, random()*360, 0, 800 + random() * 200.0f,
cgs.media.whiteRingShader );
}
/*
-------------------------
FX_QuantumHitWall
-------------------------
*/
void FX_QuantumHitWall( vec3_t origin, vec3_t normal )
{
localEntity_t *le = NULL;
vec3_t dir, org;
vec3_t vel;
float scale;
int i;
weaponInfo_t *weaponInfo = &cg_weapons[WP_9];
CG_InitLensFlare( origin,
400, 400,
colorTable[CT_YELLOW], 1.2, 2.0, 1600, 200,
colorTable[CT_YELLOW], 1600, 200, 800, 35, qtrue,
0, 0, qfalse, qtrue,
qfalse, 1.0, cg.time, 0, 0, 200);
for ( i = 0; i < 12; i++ )
{
VectorSet( dir, normal[0] + crandom() * 2, normal[1] + crandom() * 2, normal[2] + crandom() );
VectorNormalize( dir );
scale = random() * 300 + 300;
VectorScale( dir, scale, vel );
vel[2] += 300;
if ( rand() & 1 )
{
// FX_AddParticle( origin, vel, qfalse, random() * 14 + 2, -2.0, 0.9, 0.1, 0.0, 0.0, 300 + random() * 100, cgs.media.yellowParticleShader, explosionTailThink );
scale = random()*14+2;
// Instead of the particle code, which seems redundant and doesn't fade real well, try adding the projectile...
le=FX_AddSprite(origin, vel, qfalse, scale, -scale, 0.9, 0.5, 0.0, 0.0, 200 + random() * 100, cgs.media.yellowParticleShader);
// ...with a trail that overlaps it exactly.
FX_AddTrail(origin, vel, qfalse, 80, -40, scale, -scale, 0.8, 0.4, 0.0, 300, cgs.media.orangeTrailShader);
}
else
{
// FX_AddParticle( origin, vel, qfalse, random() * 14 + 2, -2.0, 0.9, 0.1, 0.0, 0.0, 450 + random() * 200, cgs.media.sunnyFlareShader, explosionTailThink );
scale = random()*14+6;
// Instead of the particle code, which seems redundant and doesn't fade real well, try adding the projectile...
le=FX_AddSprite(origin, vel, qfalse, scale, -scale, 0.9, 0.5, 0.0, 0.0, 350 + random() * 150, cgs.media.sunnyFlareShader);
// ...with a trail that overlaps it exactly.
FX_AddTrail(origin, vel, qfalse, 80, -40, scale, -scale, 0.8, 0.4, 0.0, 500, cgs.media.orangeTrailShader);
}
}
// Always face the camera
VectorSubtract( cg.refdef.vieworg, origin, dir );
VectorNormalize( dir );
// Main explosion, tag with light
le = CG_MakeExplosion2( origin, normal, (qhandle_t)0, 1, cgs.media.quantumExplosionShader, 600, qtrue, 3 + crandom(), 0 );
le->light = 150;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 1.0f, 1.0f, 0.6f );
// Create sphere
CG_MakeExplosion2( origin, dir, cgs.media.explosionModel, 5, cgs.media.quantumFlashShader, 150, qfalse, 4.6f + ( crandom() * 0.3f), 0 );
// Make an offset explosion
for ( i = 0; i < 3; i++ ) {
org[i] = origin[i] + crandom() * 4;
}
CG_MakeExplosion( org, dir, 0, cgs.media.quantumExplosionShader, 700, 1, qtrue );
CG_ImpactMark( cgs.media.compressionMarkShader, origin, normal, random()*360, 1,1,1,1.0, qfalse,
random() * 16 + 48, qfalse );
CG_ExplosionEffects( origin, 3.0f, 256 );
// One big bright quick flash
FX_AddSprite( origin, NULL, qfalse, 100, -100, 1.0, 1.0, 0, 0, 300, cgs.media.sunnyFlareShader);
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->mainHitSound );
}
/*
-------------------------
FX_QuantumAltHitWall
-------------------------
*/
void FX_QuantumAltHitWall( vec3_t origin, vec3_t normal )
{
localEntity_t *le = NULL;
vec3_t dir, org;
vec3_t vel;
float scale;
int i;
vec3_t RGB={1.0, 0.6, 0.3}, RGB2={1.0, 0.3, 0.0};
weaponInfo_t *weaponInfo = &cg_weapons[WP_9];
CG_InitLensFlare( origin,
500, 500,
colorTable[CT_YELLOW], 1.2, 2.0, 1600, 200,
colorTable[CT_YELLOW], 1600, 200, 800, 35, qtrue,
1600, 200, qfalse, qfalse,
qfalse, 1.0, cg.time, 0, 0, 350);
for ( i = 0; i < 12; i++ )
{
VectorSet( dir, normal[0] + crandom() * 2, normal[1] + crandom() * 2, normal[2] + crandom() );
VectorNormalize( dir );
scale = random() * 500 + 500;
VectorScale( dir, scale, vel );
vel[2] += 300;
if ( rand() & 1 )
{
// FX_AddParticle( origin, vel, qfalse, random() * 14 + 2, -2.0, 0.9, 0.1, 0.0, 0.0, 300 + random() * 100, cgs.media.yellowParticleShader, explosionTailThink );
scale = random()*14+2;
// Instead of the particle code, which seems redundant and doesn't fade real well, try adding the projectile...
le=FX_AddSprite2(origin, vel, qfalse, scale, -scale, 0.9, 0.5, RGB, RGB2, 0.0, 0.0, 200 + random() * 100, cgs.media.yellowParticleShader);
// ...with a trail that overlaps it exactly.
FX_AddTrail2(origin, vel, qfalse, 80, -40, scale, -scale, 0.8, 0.4, RGB, RGB2, 0.0, 300, cgs.media.orangeTrailShader);
}
else
{
// FX_AddParticle( origin, vel, qfalse, random() * 14 + 2, -2.0, 0.9, 0.1, 0.0, 0.0, 450 + random() * 200, cgs.media.sunnyFlareShader, explosionTailThink );
scale = random()*14+6;
// Instead of the particle code, which seems redundant and doesn't fade real well, try adding the projectile...
le=FX_AddSprite2(origin, vel, qfalse, scale, -scale, 0.9, 0.5, RGB, RGB2, 0.0, 0.0, 350 + random() * 150, cgs.media.sunnyFlareShader);
// ...with a trail that overlaps it exactly.
FX_AddTrail2(origin, vel, qfalse, 80, -40, scale, -scale, 0.8, 0.4, RGB, RGB2, 0.0, 500, cgs.media.orangeTrailShader);
}
}
// Always face the camera
VectorSubtract( cg.refdef.vieworg, origin, dir );
VectorNormalize( dir );
// Main explosion, tag with light
le = CG_MakeExplosion2( origin, normal, (qhandle_t)0, 1, cgs.media.quantumExplosionShader, 600, qtrue, 3 + crandom(), 0 );
le->light = 150;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 1.0f, 1.0f, 0.6f );
// Create sphere
CG_MakeExplosion2( origin, dir, cgs.media.explosionModel, 5, cgs.media.quantumFlashShader, 150, qfalse, 5.4f + ( crandom() * 0.3f), 0 );
// Make an offset explosion
for ( i = 0; i < 3; i++ ) {
org[i] = origin[i] + crandom() * 4;
}
CG_MakeExplosion( org, dir, 0, cgs.media.quantumExplosionShader, 700, 1, qtrue );
CG_ImpactMark( cgs.media.compressionMarkShader, origin, normal, random()*360, 1,1,1,1.0, qfalse,
random() * 16 + 48, qfalse );
CG_ExplosionEffects( origin, 3.0f, 256 );
// One big bright quick flash
FX_AddSprite( origin, NULL, qfalse, 200, -200, 1.0, 1.0, 0, 0, 400, cgs.media.sunnyFlareShader);
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->altHitSound );
}
qboolean FX_QuantumSparkle( localEntity_t *le)
{
int t, i;
vec3_t org, v;
for ( i = 0; i < 4; i ++ )
{
VectorCopy( le->refEntity.origin, org );
for ( t = 0; t < 3; t++ )
{
org[t] = le->refEntity.origin[t] + crandom() * 12;
v[t] = crandom() * 18.0f;
}
FX_AddSprite( org, v, qfalse, random() * 1 + 1, -4, 0.5f, 1.0f, 0.0f, 0.0f, 125 + random() * 100, cgs.media.yellowParticleShader);
}
return qtrue;
}
void FX_QuantumFizzles( vec3_t origin )
{
float v;
vec3_t dir, vel, org;
int i;
for ( i = 0; i < 32; i++ )
{
v = random() * 6.0f + 6.0f;
VectorSet( dir, crandom(), crandom(), crandom() );
VectorNormalize( dir );
VectorScale( dir, v, vel );
org[0] = origin[0] + dir[0] * 48;
org[1] = origin[1] + dir[1] * 48;
org[2] = origin[2] + dir[2] * 64;
FX_AddSpawner( org, dir, vel, NULL, qfalse, 125, 10 + random() * 30, 200 + random() * 400, FX_QuantumSparkle, 1024 );
}
}
void FX_QuantumColumns( vec3_t origin )
{
vec3_t dir, bottom, top;
vec3_t sizeMin = {-4, -4, -1};
vec3_t sizeMax = {-4, -4, 1};
trace_t trace;
localEntity_t *le;
//Orient the explosions to face the camera
VectorSubtract( cg.refdef.vieworg, origin, dir );
VectorNormalize( dir );
//=== Sound ===
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.quantumBoom );
//=== columns ===
VectorCopy( origin, bottom );
bottom[2] -= 256;
trap_CM_BoxTrace( &trace, origin, bottom, sizeMin, sizeMax, 0, MASK_OPAQUE );
VectorCopy( trace.endpos, bottom );
VectorCopy( origin, top );
top[2] += 256;
trap_CM_BoxTrace( &trace, origin, top, sizeMin, sizeMax, 0, MASK_OPAQUE );
VectorCopy( trace.endpos, top );
//found floor and ceiling, now do columns and ring explosions:
//ceiling
VectorSet( dir, 0, 0, -1 );
le = FX_AddCylinder( top, dir, top[2] - origin[2], (origin[2] - top[2]), 40, 100, 20, 50, 1.0, 0.0, 1000, cgs.media.quantumRingShader, 1.5 );
le->refEntity.data.cylinder.wrap = qtrue;
le->refEntity.data.cylinder.stscale = 6;
//floor
VectorSet( dir, 0, 0, 1 );
le = FX_AddCylinder( bottom, dir, origin[2] - bottom[2], (bottom[2] - origin[2]), 40, 100, 20, 50, 1.0, 0.0, 1000, cgs.media.quantumRingShader, 1.5 );
le->refEntity.data.cylinder.wrap = qtrue;
le->refEntity.data.cylinder.stscale = 6;
FX_QuantumFizzles( origin );
// Main explosion, tag with light
le = CG_MakeExplosion2( origin, dir, (qhandle_t)0, 1, cgs.media.quantumExplosionShader, 600, qtrue, 3 + crandom(), 0 );
le->light = 150;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 1.0f, 1.0f, 0.6f );
}

56
code/cgame/fx_tetrion.c Normal file
View file

@ -0,0 +1,56 @@
#include "cg_local.h"
#include "fx_local.h"
/*
-------------------------
FX_TetrionShot
-------------------------
*/
#define MAXRANGE_TETRION 5000000 //RPG-X: J2J OLD: 8192
void FX_TetrionShot( vec3_t start, vec3_t forward ) // TODO check whether I'm needed
{
trace_t trace;
vec3_t end, dir, new_start, new_end, radial, start2, spreadFwd;
float off, len, i, numBullets = 3;
float firingRadius = 6, minDeviation = 0.95, maxDeviation = 1.1;
qboolean render_impact = qtrue;
for (i = 0; i < numBullets; i++)
{
render_impact = qtrue;
// determine new firing position
fxRandCircumferencePos(start, forward, firingRadius, new_start);
VectorSubtract(new_start, start, radial);
VectorMA(start, 10, forward, start2);
VectorMA(start2, flrandom(minDeviation, maxDeviation), radial, start2);
VectorSubtract(start2, new_start, spreadFwd);
VectorNormalize(spreadFwd);
// determine new end position for this bullet. give the endpoint some spread, too.
VectorMA(new_start, MAXRANGE_TETRION, spreadFwd, end);
CG_Trace( &trace, new_start, NULL, NULL, end, cg_entities[cg.predictedPlayerState.clientNum].currentState.number, MASK_SHOT );
// Get the length of the whole shot
VectorSubtract( trace.endpos, new_start, dir );
len = VectorNormalize( dir );
// Don't do tracers when it gets really short
if ( len >= 64 )
{
// Move the end_point in a bit so the tracer doesn't always trace the full line length--this isn't strictly necessary, but it does
// add a bit of variance
off = flrandom(0.7, 1.0);
VectorMA( new_start, len * off, dir, new_end );
// Draw the tracer
FX_AddLine( new_end, new_start, 1.0f, 1.5f + random(), 0.0f, flrandom(0.3,0.6), 0.0,
flrandom(300,500), cgs.media.borgFlareShader );
}
// put the impact effect where this tracer hits
if (len >= 32)
{
// Rendering things like impacts when hitting a sky box would look bad, but you still want to see the tracer
if ( trace.surfaceFlags & SURF_NOIMPACT )
{
render_impact = qfalse;
}
}
}
}

293
code/cgame/fx_transporter.c Normal file
View file

@ -0,0 +1,293 @@
#include "cg_local.h"
#include "fx_local.h"
/*
-------------------------
SPTransporterLensFlares
TiM: Judging from the title,
you just KNOW it's mine ;)
Anyway, the point of this
function is to render 4
sprites and then scale + move
them in a way reminisicant
of ST: Voyager's transporter FX.
I wrote this instead of using the
already made FX spawning functions
because they don't let u track an origin.
To stop the particle
from rendering within the character, I'm going to
use the DEPTHHACK renderflag, the flag
originally used for the weapon models
in first-person mode. :)
Planned timing:
0 - 500 : Flare spawns, and scales up to it's main size (width parameter)
500 - 1500 : Flare moves up the height/2 of model (height parameter)
1500 - 2000 : Flare scales down and disappears ( width * 1.0 - (timeScale) )
-------------------------
*/
void FX_SPTransporterLensFlares( centity_t* cent, vec3_t headVector, int startTime ) {
refEntity_t flare;
trace_t tr;
int i;
int direction = 1;
int timeOffset = 0; //250 - time between first and second flares appearing;
float ratio;
float dlightRatio;
vec3_t origin, tempOrigin;
int width;
int height;
//Hrmm... we have a glitch lol. Since DEPTHHACK is on, the flare will be drawn
//from ANYWHERE IN THE LEVEL! O_o
//So.... uh, we'll do a trace between ourselves and the entity this is attached
//to, and if they can't see each other, screw it. :P
if ( cg.predictedPlayerState.clientNum != cent->currentState.clientNum ) {
CG_Trace( &tr, cg.refdef.vieworg, NULL, NULL,
cent->lerpOrigin, cg.predictedPlayerState.clientNum, CONTENTS_SOLID );
if ( tr.fraction != 1 ) {
return;
}
}
/*else {
Com_Printf( "Origin: { %f, %f, %f }\n", cent->lerpOrigin[0], cent->lerpOrigin[1], cent->lerpOrigin[2] );
Com_Printf( "HeadVector: { %f, %f, %f }\n", headVector[0], headVector[1], headVector[2] );
return;
}*/
//calculate the necessary data we need to place the origin in the direct center of the model
memset( &flare, 0, sizeof( flare ) );
//Bah. I thought lerpOrigin was at the base of the feet. Turns out it's at the knees O_o
//This little hack should help that
VectorCopy( cent->lerpOrigin, tempOrigin );
tempOrigin[2] -= 24;
//If the distance means we're not lying down
if ( ( headVector[2] - tempOrigin[2] ) > 8 ) {
//find the average between our lerp origin and headVector to find the center
//VectorAdd( headVector, tempOrigin, origin );
//VectorScale( origin, 0.5, origin );
VectorAverage( headVector, tempOrigin, origin );
width = 30;
height = (headVector[2] - tempOrigin[2]) / 2;
}
else {
width = 30;
height = 4;
VectorCopy( cent->lerpOrigin, origin);
}
flare.reType = RT_SPRITE;
flare.shaderRGBA[0] = 0xff;
flare.shaderRGBA[1] = 0xff;
flare.shaderRGBA[2] = 0xff;
flare.shaderRGBA[3] = 0xff;
flare.data.sprite.rotation = 0;
flare.nonNormalizedAxes = qtrue; //needed for effective scaling
flare.renderfx |= RF_DEPTHHACK; //DEPTHHACK renders the element over everything else. Useful in this lens flare simulation case :)
//loop 4 times = 4 flares. :)
for (i = 0; i < 4; i++ ) {
VectorClear( flare.origin );
VectorCopy( origin, flare.origin);
//the first two flares are the main ones
if ( i < 2 ) {
flare.customShader = cgs.media.transport1Shader; //1
timeOffset = startTime;
}
else { // the second two spawn a little later
flare.customShader = cgs.media.transport2Shader;
timeOffset = startTime + 650; //750
}
//the second flare each round goes down instead of up
if ( i % 2 == 0)
direction = 1;
else
direction = -1;
//===========================
if ( cg.time > timeOffset + 2000 ) {
continue;
}
//Phase 1: flares get bigger
if ( cg.time < timeOffset + 500 ) {
ratio = ((float)(cg.time - timeOffset) * 0.002);
if (ratio < 0 )
ratio = 0.0f;
else if (ratio > 1 )
ratio = 1.0f;
flare.data.sprite.radius = (float)width * ratio;
/*if ( i ==0 )
Com_Printf( "Phase 1 Radius: %f\n", flare.data.sprite.radius );*/
}
//Phase 2: flares move up/down character
if ( ( cg.time < timeOffset + 1500 ) && ( cg.time >= timeOffset + 500 ) ) {
ratio = ( (float)(cg.time - (timeOffset + 500) ) * 0.001 );
if (ratio < 0 )
ratio = 0.0f;
else if (ratio > 1 )
ratio = 1.0f;
flare.data.sprite.radius = (float)width;
flare.origin[2] += (float)direction * (float)height * ratio;
/*if (i == 0 )
Com_Printf( "Phase 2 Location: %f\n", flare.origin[2] );*/
}
//Phase 3: flares get smaller
if ( ( cg.time < timeOffset + 2000 ) && ( cg.time >= timeOffset + 1500 ) ) {
ratio = 1.0f - (float)(cg.time - ( timeOffset + 1500 ) ) * 0,002;
if (ratio < 0 )
ratio = 0.0f;
else if (ratio > 1 )
ratio = 1.0f;
flare.origin[2] += ((float)height * (float)direction);
flare.data.sprite.radius = (float)width * ratio;
/*if ( i == 0 )
Com_Printf( "Phase 3 Radius: %f\n", flare.data.sprite.radius );*/
}
trap_R_AddRefEntityToScene( &flare );
}
//dynamic light calculation
if ( cg.time < ( startTime + 2000 ) ) {
dlightRatio = (float)( cg.time - startTime ) * 0,0005;
}
else {
dlightRatio = 1.0f - (float)( cg.time - ( startTime + 2000 ) ) * 0,0005;
}
//dynamic light FX
trap_R_AddLightToScene( origin, 80.0f * dlightRatio, 0.345, 0.624, 0.835 );
}
/*
-------------------------
TransporterParticle
-------------------------
*/
qboolean TransporterParticle( localEntity_t *le)
{
vec3_t org, velocity = { 0, 0, 68 };
vec3_t accel = { 0, 0, -12 };
float scale, dscale;
qhandle_t shader;
VectorCopy( le->refEntity.origin, org );
org[2] += 0;//38;
shader = ( le->data.spawner.dir[0] == 0 ) ? cgs.media.trans1Shader : cgs.media.trans2Shader;
scale = ( le->data.spawner.dir[0] == 0 ) ? 2.0 : 4.0;
dscale = ( le->data.spawner.dir[0] == 0 ) ? 4.0 : 24.0;
le->data.spawner.dir[0]++;
FX_AddSprite( org,
velocity,
qfalse,
scale,
dscale,
1.0f,
0.0f,
0,
0.0f,
450.0f,
shader );
VectorScale( velocity, -1, velocity );
VectorScale( accel, -1, accel );
FX_AddSprite( org,
velocity,
qfalse,
scale,
dscale,
1.0f,
0.0f,
0,
0.0f,
450.0f,
shader );
return qtrue;
}
/*
-------------------------
TransporterPad
-------------------------
*/
qboolean TransporterPad( localEntity_t *le)
{
vec3_t org;
vec3_t up = {0,0,1};
float scale, dscale;
qhandle_t shader;
VectorCopy( le->refEntity.origin, org );
org[2] -= 3;
shader = cgs.media.trans1Shader;
scale = 20.0;
dscale = 2.0;
FX_AddQuad( org,
up,
scale,
dscale,
1.0f,
0.0f,
0,
950.0f,
shader );
return qtrue;
}
/*
-------------------------
FX_Transporter
-------------------------
*/
void FX_Transporter( vec3_t origin )
{
vec3_t up = {0,0,1};
FX_AddSpawner( origin, up, NULL, NULL, qfalse, 0, 0, 200, TransporterParticle, 0 );
// trap_S_StartSound( origin, NULL, CHAN_AUTO, cgs.media.teleInSound );
}
/*
-------------------------
FX_TransporterPad
-------------------------
*/
void FX_TransporterPad( vec3_t origin )
{
vec3_t up = {0,0,1};
FX_AddSpawner( origin, up, NULL, NULL, qfalse, 1000, 0, 0, TransporterPad, 0 );
}

75
code/cgame/lua_cent.c Normal file
View file

@ -0,0 +1,75 @@
#include "cg_lua.h"
#ifdef CG_LUA
static int Cent_GC(lua_State * L)
{
return 0;
}
static int Cent_ToString(lua_State * L)
{
cent_t *cent;
centity_t *ent;
char buf[MAX_STRING_CHARS];
cent = Lua_GetCent(L, 1);
ent = cent->e;
Com_sprintf(buf, sizeof(buf), "centity: id=%d pointer=%p\n", ent - cg_entities, ent);
lua_pushstring(L, buf);
return 1;
}
static const luaL_Reg Centity_ctor[] = {
{NULL, NULL}
};
static const luaL_Reg Centity_meta[] = {
{"__gc", Cent_GC},
{"__tostring", Cent_ToString},
{NULL, NULL}
};
/*void dummy(gentity_t *ent) {
ent->timestamp;
}*/
int Luaopen_Cent(lua_State * L)
{
luaL_newmetatable(L, "cgame.centity");
lua_pushstring(L, "__index");
lua_pushvalue(L, -2);
lua_settable(L, -3);
luaL_register(L, NULL, Centity_meta);
luaL_register(L, "centity", Centity_ctor);
return 1;
}
void Lua_PushCent(lua_State * L, centity_t * ent)
{
cent_t *cent;
if(!ent)
lua_pushnil(L);
else {
cent = (cent_t *)lua_newuserdata(L, sizeof(cent_t));
luaL_getmetatable(L, "cgame.centity");
lua_setmetatable(L, -2);
cent->e = ent;
}
}
cent_t *Lua_GetCent(lua_State * L, int argNum)
{
void *ud;
ud = luaL_checkudata(L, argNum, "cgame.centity");
luaL_argcheck(L, ud != NULL, argNum, "\'centity\' expected");
return (cent_t *) ud;
}
#endif

19
code/cgame/lua_cfx.c Normal file
View file

@ -0,0 +1,19 @@
#include "cg_lua.h"
#ifdef CG_LUA
void Lua_CFX_ParseMapFxFile(fileHandle_t *f) {
// TODO
}
void Lua_CFX_LoadMapFxFile(void) {
char filename[MAX_QPATH];
fileHandle_t file;
sprintf(filename, "maps/%s.fx", cgs.mapname);
trap_FS_FOpenFile(filename, &file, FS_READ);
if(!file) return;
Lua_CFX_ParseMapFxFile(&file);
}
#endif

475
code/cgame/lua_refent.c Normal file
View file

@ -0,0 +1,475 @@
#include "cg_lua.h"
#ifdef CG_LUA
#include "cg_lua.h"
#ifdef CG_LUA
static int Refent_GC(lua_State * L)
{
return 0;
}
static int Refent_ToString(lua_State * L)
{
rent_t *rent;
refEntity_t *ent;
char buf[MAX_STRING_CHARS];
rent = Lua_GetRent(L, 1);
ent = rent->r;
Com_sprintf(buf, sizeof(buf), "centity: pointer=%p\n", ent);
lua_pushstring(L, buf);
return 1;
}
static int Refent_GetRenderfx(lua_State *L) {
rent_t *rent;
rent = Lua_GetRent(L, 1);
lua_pushinteger(L, rent->r->renderfx);
return 1;
}
static int Refent_SetRenderfx(lua_State *L) {
rent_t *rent;
int renderfx;
rent = Lua_GetRent(L, 1);
renderfx = (int)luaL_checknumber(L, 2);
rent->r->renderfx = renderfx;
return 1;
}
static int Refent_GetType(lua_State *L) {
rent_t *rent;
rent = Lua_GetRent(L, 1);
lua_pushinteger(L, rent->r->reType);
return 1;
}
static int Refent_SetType(lua_State *L) {
rent_t *rent;
refEntityType_t type;
rent = Lua_GetRent(L, 1);
type = (refEntityType_t)((int)luaL_checknumber(L, 2));
if(type < 0 || type >= RT_MAX_REF_ENTITY_TYPE)
return 1;
return 1;
}
static int Refent_GetHmodel(lua_State *L) {
rent_t *rent;
rent = Lua_GetRent(L, 1);
lua_pushinteger(L, rent->r->hModel);
return 1;
}
static int Refent_SetHmodel(lua_State *L) {
rent_t *rent;
int hmodel;
rent = Lua_GetRent(L, 1);
hmodel = (int)luaL_checknumber(L, 2);
rent->r->hModel = hmodel;
return 1;
}
static int Refent_GetLightingOrigin(lua_State *L) {
rent_t *rent;
rent = Lua_GetRent(L, 1);
Lua_PushVector(L, rent->r->lightingOrigin);
return 1;
}
static int Refent_SetLightingOrigin(lua_State *L) {
rent_t *rent;
vec_t *origin;
rent = Lua_GetRent(L, 1);
origin = Lua_GetVector(L, 2);
VectorCopy(origin, rent->r->lightingOrigin);
return 1;
}
static int Refent_GetShadowPlane(lua_State *L) {
rent_t *rent;
rent = Lua_GetRent(L, 1);
lua_pushnumber(L, rent->r->shadowPlane);
return 1;
}
static int Refent_SetShadowPlane(lua_State *L) {
rent_t *rent;
float sp;
rent = Lua_GetRent(L, 1);
sp = (float)luaL_checknumber(L, 2);
rent->r->shadowPlane = sp;
return 1;
}
static int Refent_GetAxis0(lua_State *L) {
rent_t *rent;
rent = Lua_GetRent(L, 1);
Lua_PushVector(L, rent->r->axis[0]);
return 1;
}
static int Refent_SetAxis0(lua_State *L) {
rent_t *rent;
vec_t *axis;
rent = Lua_GetRent(L, 1);
axis = Lua_GetVector(L, 2);
VectorCopy(axis, rent->r->axis[0]);
return 1;
}
static int Refent_GetAxis1(lua_State *L) {
rent_t *rent;
rent = Lua_GetRent(L, 1);
Lua_PushVector(L, rent->r->axis[1]);
return 1;
}
static int Refent_SetAxis1(lua_State *L) {
rent_t *rent;
vec_t *axis;
rent = Lua_GetRent(L, 1);
axis = Lua_GetVector(L, 2);
VectorCopy(axis, rent->r->axis[1]);
return 1;
}
static int Refent_GetAxis2(lua_State *L) {
rent_t *rent;
rent = Lua_GetRent(L, 1);
Lua_PushVector(L, rent->r->axis[2]);
return 1;
}
static int Refent_SetAxis2(lua_State *L) {
rent_t *rent;
vec_t *axis;
rent = Lua_GetRent(L, 1);
axis = Lua_GetVector(L, 2);
VectorCopy(axis, rent->r->axis[2]);
return 1;
}
static int Refent_UseNormAxis(lua_State *L) {
rent_t *rent;
rent = Lua_GetRent(L, 1);
lua_pushboolean(L, (int)(!(rent->r->nonNormalizedAxes)));
return 1;
}
static int Refent_SetUseNormAxis(lua_State *L) {
rent_t *rent;
qboolean b;
rent = Lua_GetRent(L, 1);
b = (qboolean)lua_toboolean(L, 2);
rent->r->nonNormalizedAxes = (qboolean)(!b);
return 1;
}
static int Refent_GetOrigin(lua_State *L) {
rent_t *rent;
rent = Lua_GetRent(L, 1);
Lua_PushVector(L, rent->r->origin);
return 1;
}
static int Refent_SetOrigin(lua_State *L) {
rent_t *rent;
vec_t *origin;
rent = Lua_GetRent(L, 1);
origin = Lua_GetVector(L, 1);
VectorCopy(origin, rent->r->origin);
return 1;
}
static int Refent_GetFrame(lua_State *L) {
rent_t *rent;
rent = Lua_GetRent(L, 1);
lua_pushinteger(L, rent->r->frame);
return 1;
}
static int Refent_SetFrame(lua_State *L) {
rent_t *rent;
int frame;
rent = Lua_GetRent(L, 1);
frame = (int)luaL_checknumber(L, 2);
rent->r->frame = frame;
return 1;
}
static int Refent_GetOldOrigin(lua_State *L) {
rent_t *rent;
rent = Lua_GetRent(L, 1);
Lua_PushVector(L, rent->r->oldorigin);
return 1;
}
static int Refent_SetOldOrigin(lua_State *L) {
rent_t *rent;
vec_t *vec;
rent = Lua_GetRent(L, 1);
vec = Lua_GetVector(L, 2);
VectorCopy(vec, rent->r->oldorigin);
return 1;
}
static int Refent_GetOldFrame(lua_State *L) {
rent_t *rent;
rent = Lua_GetRent(L, 1);
lua_pushinteger(L, rent->r->oldframe);
return 1;
}
static int Refent_SetOldFrame(lua_State *L) {
rent_t *rent;
int of;
rent = Lua_GetRent(L, 1);
of = (int)luaL_checknumber(L, 2);
rent->r->oldframe = of;
return 1;
}
static int Refent_GetBacklerp(lua_State *L) {
rent_t *rent;
rent = Lua_GetRent(L, 1);
lua_pushnumber(L, rent->r->backlerp);
return 1;
}
static int Refent_SetBacklerp(lua_State *L) {
rent_t *rent;
float bl;
rent = Lua_GetRent(L, 1);
bl = (float)luaL_checknumber(L, 2);
rent->r->backlerp = bl;
return 1;
}
static int Refent_GetSkinNum(lua_State *L) {
rent_t *rent;
rent = Lua_GetRent(L, 1);
lua_pushinteger(L, rent->r->skinNum);
return 1;
}
static int Refent_SetSkinNum(lua_State *L) {
rent_t *rent;
int sn;
rent = Lua_GetRent(L, 1);
sn = (int)luaL_checknumber(L, 2);
rent->r->skinNum = sn;
return 1;
}
static int Refent_GetCustomSkin(lua_State *L) {
rent_t *rent;
rent = Lua_GetRent(L, 1);
lua_pushinteger(L, rent->r->customSkin);
return 1;
}
static int Refent_SetCustomSkin(lua_State *L) {
rent_t *rent;
int cs;
rent = Lua_GetRent(L, 1);
cs = (int)luaL_checknumber(L, 2);
rent->r->customSkin = cs;
return 1;
}
static int Refent_GetCustomShader(lua_State *L) {
rent_t *rent;
rent = Lua_GetRent(L, 1);
lua_pushinteger(L, rent->r->customShader);
return 1;
}
static int Refent_SetCustomShader(lua_State *L) {
rent_t *rent;
int cs;
rent = Lua_GetRent(L, 1);
cs = (int)luaL_checknumber(L, 2);
rent->r->customShader = cs;
return 1;
}
static const luaL_Reg Refentity_ctor[] = {
{NULL, NULL}
};
static const luaL_Reg Refentity_meta[] = {
{"__gc", Refent_GC},
{"__tostring", Refent_ToString},
{"GetType", Refent_GetType},
{"SetType", Refent_SetType},
{"GetRenderfx", Refent_GetRenderfx},
{"SetRenderfx", Refent_SetRenderfx},
{"GetHmodel", Refent_GetHmodel},
{"SetHmodel", Refent_SetHmodel},
{"GetLightingOrigin", Refent_GetLightingOrigin},
{"SetLightingOrigin", Refent_SetLightingOrigin},
{"GetShadowPlane", Refent_GetShadowPlane},
{"SetShadowPlane", Refent_SetShadowPlane},
{"GetAxis0", Refent_GetAxis0},
{"SetAxis0", Refent_SetAxis0},
{"GetAxis1", Refent_GetAxis1},
{"SetAxis1", Refent_SetAxis1},
{"GetAxis2", Refent_GetAxis2},
{"SetAxis2", Refent_SetAxis2},
{"UseNormalizedAxis", Refent_UseNormAxis},
{"SetUseNormalizedAxis", Refent_SetUseNormAxis},
{"GetOrigin", Refent_GetOrigin},
{"GetBeamFrom", Refent_GetOrigin},
{"SetOrigin", Refent_SetOrigin},
{"SetBeamFrom", Refent_SetOrigin},
{"GetFrame", Refent_GetFrame},
{"GetModelBeamDiameter", Refent_GetFrame},
{"SetFrame", Refent_SetFrame},
{"SetModelBeamDiameter", Refent_SetFrame},
{"GetOldOrigin", Refent_GetOldOrigin},
{"GetModelBeamTo", Refent_GetOldOrigin},
{"SetOldOrigin", Refent_SetOldOrigin},
{"SetModelBeamTo", Refent_SetOldOrigin},
{"GetOldFrame", Refent_GetOldFrame},
{"SetOldFrame", Refent_SetOldFrame},
{"GetBacklerp", Refent_GetBacklerp},
{"SetBacklerp", Refent_SetBacklerp},
{"GetSkinNum", Refent_GetSkinNum},
{"SetSkinNum", Refent_SetSkinNum},
{"GetCustomSkin", Refent_GetCustomSkin},
{"SetCustomSkin", Refent_SetCustomSkin},
{"GetCustomShader", Refent_GetCustomShader},
{"SetCustomShader", Refent_SetCustomShader},
{NULL, NULL}
};
int Luaopen_Rent(lua_State * L)
{
luaL_newmetatable(L, "cgame.refentity");
lua_pushstring(L, "__index");
lua_pushvalue(L, -2);
lua_settable(L, -3);
luaL_register(L, NULL, Refentity_meta);
luaL_register(L, "refentity", Refentity_ctor);
return 1;
}
void Lua_PushRent(lua_State * L, refEntity_t * rent)
{
rent_t *refent;
if(!rent)
lua_pushnil(L);
else {
refent = (rent_t *)lua_newuserdata(L, sizeof(cent_t));
luaL_getmetatable(L, "cgame.refentity");
lua_setmetatable(L, -2);
refent->r = rent;
}
}
rent_t *Lua_GetRent(lua_State * L, int argNum)
{
void *ud;
ud = luaL_checkudata(L, argNum, "cgame.refentity");
luaL_argcheck(L, ud != NULL, argNum, "\'refentity\' expected");
return (rent_t *) ud;
}
#endif
#endif

252
code/cgame/tr_types.h Normal file
View file

@ -0,0 +1,252 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
#ifndef __TR_TYPES_H
#define __TR_TYPES_H
#define MAX_DLIGHTS 32 // can't be increased, because bit flags are used on surfaces
#define ENTITYNUM_BITS 11 // can't be increased without changing drawsurf bit packing
#define MAX_ENTITIES ((1<<ENTITYNUM_BITS) - 1)
// renderfx flags
#define RF_LOWLIGHT 0x0001 // subtract ambient to keep it in the dark
#define RF_THIRD_PERSON 0x0002 // don't draw through eyes, only mirrors (player bodies, chat sprites)
#define RF_FIRST_PERSON 0x0004 // only draw through eyes (view weapon, damage blood blob)
#define RF_DEPTHHACK 0x0008 // for view weapon Z crunching
#define RF_FULLBRIGHT 0x0010 // Render with a bright ambient light.
#define RF_NOSHADOW 0x0040 // don't add stencil shadows
#define RF_LIGHTING_ORIGIN 0x0080 // use refEntity->lightingOrigin instead of refEntity->origin
// for lighting. This allows entities to sink into the floor
// with their origin going solid, and allows all parts of a
// player to get the same lighting
#define RF_SHADOW_PLANE 0x0100 // use refEntity->shadowPlane
#define RF_WRAP_FRAMES 0x0200 // mod the model frames by the maxframes to allow continuous
// animation without needing to know the frame count
#define RF_CAP_FRAMES 0x0400 // cap the model frames by the maxframes for one shot anims
#define RF_FORCE_ENT_ALPHA 0x0800 // Models should use ent alpha regardless of what the shader says.
// refdef flags
#define RDF_NOWORLDMODEL 1 // used for player configuration screen
#define RDF_HYPERSPACE 4 // teleportation effect
typedef struct {
vec3_t xyz;
float st[2];
byte modulate[4];
} polyVert_t;
typedef struct poly_s {
qhandle_t hShader;
int numVerts;
polyVert_t *verts;
} poly_t;
typedef enum {
RT_MODEL,
RT_SPRITE,
RT_ORIENTEDSPRITE, // Replaces RT_POLY, which wasn't used. --Pat
RT_ALPHAVERTPOLY, // Individual alpha levels on each vertex
RT_BEAM,
RT_RAIL_CORE,
RT_RAIL_RINGS,
RT_LIGHTNING,
RT_PORTALSURFACE, // doesn't draw anything, just info for portals
RT_LINE, // New type for Trek MP --Pat
RT_ORIENTEDLINE,
RT_LINE2, // New line type for Trek MP, with taper support --Pat
RT_BEZIER, // what he said --keith
RT_CYLINDER, // Yet another Trek primitive!
RT_ELECTRICITY, // Yet another Trek primitive!
RT_MAX_REF_ENTITY_TYPE
} refEntityType_t;
typedef struct {
refEntityType_t reType;
int renderfx;
qhandle_t hModel; // opaque type outside refresh
// most recent data
vec3_t lightingOrigin; // so multi-part models can be lit identically (RF_LIGHTING_ORIGIN)
float shadowPlane; // projection shadows go here, stencils go slightly lower
vec3_t axis[3]; // rotation vectors
qboolean nonNormalizedAxes; // axis are not normalized, i.e. they have scale
float origin[3]; // also used as MODEL_BEAM's "from"
int frame; // also used as MODEL_BEAM's diameter
// previous data for frame interpolation
float oldorigin[3]; // also used as MODEL_BEAM's "to"
int oldframe;
float backlerp; // 0.0 = current, 1.0 = old
// texturing
int skinNum; // inline skin index
qhandle_t customSkin; // NULL for default skin
qhandle_t customShader; // use one image for the entire thing
// misc
byte shaderRGBA[4]; // colors used by rgbgen entity shaders
float shaderTexCoord[2]; // texture coordinates used by tcMod entity modifiers
float shaderTime; // subtracted from refdef time to control effect start times
// extra sprite information
union {
struct
{
float rotation;
float radius;
byte vertRGBA[4][4];
} sprite;
struct
{
float width;
float width2;
float stscale;
} line;
struct // that whole put-the-opening-brace-on-the-same-line-as-the-beginning-of-the-definition coding style is fecal
// TiM: You're a fecal. I prefer that style :D
// TiM: (c)2008 You're a you're a fecal. ;P I've grown to like the other one now.... it's way easier to read XD
{
float width;
vec3_t control1;
vec3_t control2;
} bezier;
struct
{
float width;
float width2;
float stscale;
float height;
float bias;
qboolean wrap;
} cylinder;
struct
{
float width;
float deviation;
float stscale;
qboolean wrap;
qboolean taper;
} electricity;
} data;
} refEntity_t;
#define MAX_RENDER_STRINGS 8
#define MAX_RENDER_STRING_LENGTH 32
typedef struct {
int x, y, width, height;
float fov_x, fov_y;
vec3_t vieworg;
vec3_t viewaxis[3]; // transformation matrix
// time in milliseconds for shader effects and other time dependent rendering issues
int time;
int rdflags; // RDF_NOWORLDMODEL, etc
// 1 bits will prevent the associated area from rendering at all
byte areamask[MAX_MAP_AREA_BYTES];
// text messages for deform text shaders
// char text[MAX_RENDER_STRINGS][MAX_RENDER_STRING_LENGTH];
} refdef_t;
typedef enum {
STEREO_CENTER,
STEREO_LEFT,
STEREO_RIGHT
} stereoFrame_t;
/*
** glconfig_t
**
** Contains variables specific to the OpenGL configuration
** being run right now. These are constant once the OpenGL
** subsystem is initialized.
*/
typedef enum {
TC_NONE,
TC_S3TC,
TC_S3TC_DXT
} textureCompression_t;
typedef enum {
GLDRV_ICD, // driver is integrated with window system
// WARNING: there are tests that check for
// > GLDRV_ICD for minidriverness, so this
// should always be the lowest value in this
// enum set
GLDRV_STANDALONE, // driver is a non-3Dfx standalone driver
GLDRV_VOODOO // driver is a 3Dfx standalone driver
} glDriverType_t;
typedef enum {
GLHW_GENERIC, // where everthing works the way it should
GLHW_3DFX_2D3D, // Voodoo Banshee or Voodoo3, relevant since if this is
// the hardware type then there can NOT exist a secondary
// display adapter
GLHW_RIVA128, // where you can't interpolate alpha
GLHW_RAGEPRO, // where you can't modulate alpha on alpha textures
GLHW_PERMEDIA2 // where you don't have src*dst
} glHardwareType_t;
typedef struct {
char renderer_string[MAX_STRING_CHARS];
char vendor_string[MAX_STRING_CHARS];
char version_string[MAX_STRING_CHARS];
char extensions_string[2*MAX_STRING_CHARS];
int maxTextureSize; // queried from GL
int maxActiveTextures; // multitexture ability
int colorBits, depthBits, stencilBits;
glDriverType_t driverType;
glHardwareType_t hardwareType;
qboolean deviceSupportsGamma;
textureCompression_t textureCompression;
qboolean textureEnvAddAvailable;
qboolean textureFilterAnisotropicAvailable;
int vidWidth, vidHeight;
// aspect is the screen's physical width / height, which may be different
// than scrWidth / scrHeight if the pixels are non-square
// normal screens should be 4/3, but wide aspect monitors may be 16/9
float windowAspect;
int displayFrequency;
// synonymous with "does rendering consume the entire screen?", therefore
// a Voodoo or Voodoo2 will have this set to TRUE, as will a Win32 ICD that
// used CDS.
qboolean isFullscreen;
qboolean stereoEnabled;
qboolean smpActive; // dual processor
} glconfig_t;
#if !defined _WIN32
#define _3DFX_DRIVER_NAME "libMesaVoodooGL.so"
#define OPENGL_DRIVER_NAME "libGL.so"
#else
#define _3DFX_DRIVER_NAME "3dfxvgl"
#define OPENGL_DRIVER_NAME "opengl32"
#endif // !defined _WIN32
#endif // __TR_TYPES_H

281
code/game/Makefile Normal file
View file

@ -0,0 +1,281 @@
default: so
so: build_so
# determine arch and platform
ARCH=$(shell uname -m | sed -e s/i.86/i386/)
PLATFORM=$(shell uname|sed -e s/_.*//|tr '[:upper:]' '[:lower:]')
# compiler to use for building shared objects
CC = gcc
# cross compiling
ifneq ($(PLATFORM), mingw32)
ifeq ($(TARGET), win32)
PLATFORM=mingw32
ARCH=x86
CC=i686-w64-mingw32-gcc
CFLAGS+=-m32
endif
ifeq ($(TARGET), win64)
PLATFORM=mingw32
ARCH=x64
CC=x86_64-w64-mingw32-gcc
CFLAGS+=-m64
endif
else
#we are compiling on windows
ARCH=x86
endif
# cflags for the compiler
ifeq ($(PLATFORM), mingw32)
SOCFLAGS = $(CFLAGS)
else
SOCFLAGS = $(CFLAGS) -fPIC
endif
# set extension
ifeq ($(PLATFORM), mingw32)
EXT=dll
else
EXT=so
endif
# warning level
ifeq ($(DEBUG), 1)
WL=-Wall
else
WL=-Wall -Wno-unused-but-set-variable
endif
#defines
DEFINES=
ifeq ($(SQL), 1)
DEFINES+=-DSQL
endif
# game objects
OBJ = \
g_ui.o \
g_lua.o \
q_shared.o \
q_math.o \
g_weapon.o \
g_utils.o \
g_usable.o \
g_turrets.o \
g_trigger.o \
g_team.o \
g_target.o \
g_svcmds.o \
g_spawn.o \
g_session.o \
g_mover.o \
g_missile.o \
g_misc.o \
g_mem.o \
g_main.o \
g_log.o \
g_items.o \
g_fx.o \
g_combat.o \
g_sql.o \
g_cmds.o \
g_client.o \
g_breakable.o \
g_bot.o \
g_arenas.o \
g_active.o \
g_cinematic.o \
bg_slidemove.o \
bg_pmove.o \
bg_oums.o \
bg_misc.o \
ai_team.o \
ai_main.o \
ai_dmq3.o \
ai_dmnet.o \
ai_cmd.o \
ai_chat.o \
lua_game.o \
lua_entity.o \
lua_vector.o \
lua_mover.o \
lua_qmath.o \
lua_cinematic.o \
lua_sound.o \
lua_weapons.o \
lua_trace.o \
lua_cvar.o \
sqlite3.o \
md5.o \
list.o
# game object for syscalls to the engine
SOOBJ = \
g_syscalls.o
# objects for lua
LUAOBJ = \
lapi.o \
lauxlib.o \
lbaselib.o \
lbitlib.o \
lcode.o \
lcorolib.o \
lctype.o \
ldblib.o \
ldebug.o \
ldo.o \
ldump.o \
lfunc.o \
lgc.o \
linit.o \
liolib.o \
llex.o \
lmathlib.o \
lmem.o \
loadlib.o \
lobject.o \
lopcodes.o \
loslib.o \
lparser.o \
lstate.o \
lstring.o \
lstrlib.o \
ltable.o \
ltablib.o \
ltm.o \
lua.o \
luac.o \
lundump.o \
lvm.o \
lzio.o
# sqlite
SQLITE= \
sqlite3.o
# do cc for shared library
ifeq ($(DEBUG), 1)
DO_SOCC = $(CC) $(SOCFLAGS) $(WL) -g3 $(DEFINES) -o $@ -c $<
else
DO_SOCC = $(CC) $(SOCFLAGS) $(WL) $(DEFINES) -o $@ -c $<
endif
# do cc for lua
ifeq ($(DEBUF), 1)
DO_LUACC = $(CC) -O2 -Wall -g3 $(SOCFLAGS) -DLUA_COMPAT_ALL -o $@ -c $<
else
DO_LUACC = $(CC) -O2 -Wall $(SOCFLAGS) -DLUA_COMPAT_ALL -o $@ -c $<
endif
build_so: DO_CC=$(DO_SOCC)
# game
ai_chat.o : ai_chat.c; $(DO_CC)
ai_cmd.o : ai_cmd.c; $(DO_CC)
ai_dmnet.o : ai_dmnet.c; $(DO_CC)
ai_dmq3.o : ai_dmq3.c; $(DO_CC)
ai_main.o : ai_main.c; $(DO_CC)
ai_team.o : ai_team.c; $(DO_CC)
bg_misc.o : bg_misc.c; $(DO_CC)
bg_pmove.o : bg_pmove.c; $(DO_CC)
bg_slidemove.o : bg_slidemove.c; $(DO_CC)
g_active.o : g_active.c; $(DO_CC)
g_arenas.o : g_arenas.c; $(DO_CC)
g_bot.o : g_bot.c; $(DO_CC)
g_breakable.o : g_breakable.c; $(DO_CC)
g_client.o : g_client.c; $(DO_CC)
g_cmds.o : g_cmds.c; $(DO_CC)
g_combat.o : g_combat.c; $(DO_CC)
g_fx.o : g_fx.c; $(DO_CC)
g_items.o : g_items.c; $(DO_CC)
g_log.o : g_log.c; $(DO_CC)
g_main.o : g_main.c; $(DO_CC)
g_mem.o : g_mem.c; $(DO_CC)
g_misc.o : g_misc.c; $(DO_CC)
g_missile.o : g_missile.c; $(DO_CC)
g_mover.o : g_mover.c; $(DO_CC)
g_session.o : g_session.c; $(DO_CC)
g_spawn.o : g_spawn.c; $(DO_CC)
g_svcmds.o : g_svcmds.c; $(DO_CC)
g_target.o : g_target.c; $(DO_CC)
g_team.o : g_team.c; $(DO_CC)
g_trigger.o : g_trigger.c; $(DO_CC)
g_turrets.o : g_turrets.c; $(DO_CC)
g_usable.o : g_usable.c; $(DO_CC)
g_utils.o : g_utils.c; $(DO_CC)
g_weapon.o : g_weapon.c; $(DO_CC)
q_math.o : q_math.c; $(DO_CC)
q_shared.o : q_shared.c; $(DO_CC)
g_lua.o: g_lua.c; $(DO_CC)
g_ui.o: g_ui.c; $(DO_CC)
g_sql.o: g_sql.c; $(DO_CC)
g_cinematic.o: g_cinematic.c; $(DO_CC)
bg_oums.o : bg_oums.c; $(DO_CC)
lua_game.o: lua_game.c; $(DO_CC)
lua_entity.o: lua_entity.c; $(DO_CC)
lua_mover.o: lua_mover.c; $(DO_CC)
lua_qmath.o: lua_qmath.c; $(DO_CC)
lua_vector.o: lua_vector.c; $(DO_CC)
lua_cinematic.o: lua_cinematic.c; $(DO_CC)
lua_sound.o: lua_sound.c; $(DO_CC)
lua_weapons.o: lua_weapons.c; $(DO_CC)
lua_trace.o: lua_trace.c; $(DO_CC)
lua_cvar.o: lua_cvar.c; $(DO_CC)
sqlite3.o: sqlite3.c; $(DO_CC)
md5.o: md5.c; $(DO_CC)
list.o: list.c; $(DO_CC)
# game syscalls
g_syscalls.o : g_syscalls.c; $(DO_CC)
# bg_lib
bg_lib.o : bg_lib.c; $(DO_CC)
# lua
lapi.o: lapi.c; $(DO_LUACC)
lauxlib.o: lauxlib.c; $(DO_LUACC)
lbaselib.o: lbaselib.c; $(DO_LUACC)
lbitlib.o: lbitlib.c; $(DO_LUACC)
lcode.o: lcode.c; $(DO_LUACC)
lcorolib.o: lcorolib.c; $(DO_LUACC)
lctype.o: lctype.c; $(DO_LUACC)
ldblib.o: ldblib.c; $(DO_LUACC)
ldebug.o: ldebug.c; $(DO_LUACC)
ldo.o: ldo.c; $(DO_LUACC)
ldump.o: ldump.c; $(DO_LUACC)
lfunc.o: lfunc.c; $(DO_LUACC)
lgc.o: lgc.c; $(DO_LUACC)
linit.o: linit.c; $(DO_LUACC)
liolib.o: liolib.c; $(DO_LUACC)
llex.o: llex.c; $(DO_LUACC)
lmathlib.o: lmathlib.c; $(DO_LUACC)
lmem.o: lmem.c; $(DO_LUACC)
loadlib.o: loadlib.c; $(DO_LUACC)
lobject.o: lobject.c; $(DO_LUACC)
lopcodes.o: lopcodes.c; $(DO_LUACC)
loslib.o: loslib.c; $(DO_LUACC)
lparser.o: lparser.c; $(DO_LUACC)
lstate.o: lstate.c; $(DO_LUACC)
lstring.o: lstring.c; $(DO_LUACC)
lstrlib.o: lstrlib.c; $(DO_LUACC)
ltable.o: ltable.c; $(DO_LUACC)
ltablib.o: ltablib.c; $(DO_LUACC)
ltm.o: ltm.c; $(DO_LUACC)
lua.o: lua.c; $(DO_LUACC)
luac.o: luac.c; $(DO_LUACC)
lundump.o: lundump.c; $(DO_LUACC)
lvm.o: lvm.c; $(DO_LUACC)
lzio.o: lzio.c; $(DO_LUACC)
build_so: $(OBJ) $(SOOBJ) $(LUAOBJ)
ifeq ($(PLATFORM), mingw32)
$(CC) -shared -Wl,--export-all-symbols,-soname,qqgame$(ARCH).$(EXT) -o qagame$(ARCH).$(EXT) $(OBJ) $(SOOBJ) $(LUAOBJ) -lm
else
$(CC) -shared -Wl,--export-dynamic,-soname,qagame$(ARCH).$(EXT) -o qagame$(ARCH).$(EXT) $(OBJ) $(SOOBJ) $(LUAOBJ) -lm -lpthread
endif
clean:
rm -f *.o *.$(EXT)

4
code/game/ToDo.txt Normal file
View file

@ -0,0 +1,4 @@
- Debug
- Static code analysis?
- throw out unused things
- Holodeck Entity ...

View file

@ -1,24 +1,4 @@
/*
===========================================================================
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
===========================================================================
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
@ -26,20 +6,24 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* desc: Quake3 bot AI
*
* $Archive: /MissionPack/code/game/ai_chat.c $
* $Archive: /StarTrek/Code-DM/game/ai_chat.c $
* $Author: Mgummelt $
* $Revision: 7 $
* $Modtime: 3/09/01 11:52a $
* $Date: 3/09/01 12:02p $
*
*****************************************************************************/
#include "g_local.h"
#include "../botlib/botlib.h"
#include "../botlib/be_aas.h"
#include "../botlib/be_ea.h"
#include "../botlib/be_ai_char.h"
#include "../botlib/be_ai_chat.h"
#include "../botlib/be_ai_gen.h"
#include "../botlib/be_ai_goal.h"
#include "../botlib/be_ai_move.h"
#include "../botlib/be_ai_weap.h"
#include "botlib.h"
#include "be_aas.h"
#include "be_ea.h"
#include "be_ai_char.h"
#include "be_ai_chat.h"
#include "be_ai_gen.h"
#include "be_ai_goal.h"
#include "be_ai_move.h"
#include "be_ai_weap.h"
//
#include "ai_main.h"
#include "ai_dmq3.h"
@ -52,13 +36,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "syn.h" //synonyms
#include "match.h" //string matching types and vars
// for the voice chats
#ifdef MISSIONPACK
#include "../../ui/menudef.h"
#endif
#define TIME_BETWEENCHATTING 25
/*
==================
@ -68,13 +45,13 @@ BotNumActivePlayers
int BotNumActivePlayers(void) {
int i, num;
char buf[MAX_INFO_STRING];
static int maxclients;
static int maxclis;
if (!maxclients)
maxclients = trap_Cvar_VariableIntegerValue("sv_maxclients");
if (!maxclis)
maxclis = trap_Cvar_VariableIntegerValue("sv_maxclients");
num = 0;
for (i = 0; i < maxclients && i < MAX_CLIENTS; i++) {
for (i = 0; i < maxclis && i < MAX_CLIENTS; i++) {
trap_GetConfigstring(CS_PLAYERS+i, buf, sizeof(buf));
//if no config string or no name
if (!strlen(buf) || !strlen(Info_ValueForKey(buf, "n"))) continue;
@ -94,14 +71,14 @@ BotIsFirstInRankings
int BotIsFirstInRankings(bot_state_t *bs) {
int i, score;
char buf[MAX_INFO_STRING];
static int maxclients;
static int maxclis;
playerState_t ps;
if (!maxclients)
maxclients = trap_Cvar_VariableIntegerValue("sv_maxclients");
if (!maxclis)
maxclis = trap_Cvar_VariableIntegerValue("sv_maxclients");
score = bs->cur_ps.persistant[PERS_SCORE];
for (i = 0; i < maxclients && i < MAX_CLIENTS; i++) {
for (i = 0; i < maxclis && i < MAX_CLIENTS; i++) {
trap_GetConfigstring(CS_PLAYERS+i, buf, sizeof(buf));
//if no config string or no name
if (!strlen(buf) || !strlen(Info_ValueForKey(buf, "n"))) continue;
@ -122,14 +99,14 @@ BotIsLastInRankings
int BotIsLastInRankings(bot_state_t *bs) {
int i, score;
char buf[MAX_INFO_STRING];
static int maxclients;
static int maxclis;
playerState_t ps;
if (!maxclients)
maxclients = trap_Cvar_VariableIntegerValue("sv_maxclients");
if (!maxclis)
maxclis = trap_Cvar_VariableIntegerValue("sv_maxclients");
score = bs->cur_ps.persistant[PERS_SCORE];
for (i = 0; i < maxclients && i < MAX_CLIENTS; i++) {
for (i = 0; i < maxclis && i < MAX_CLIENTS; i++) {
trap_GetConfigstring(CS_PLAYERS+i, buf, sizeof(buf));
//if no config string or no name
if (!strlen(buf) || !strlen(Info_ValueForKey(buf, "n"))) continue;
@ -151,15 +128,15 @@ char *BotFirstClientInRankings(void) {
int i, bestscore, bestclient;
char buf[MAX_INFO_STRING];
static char name[32];
static int maxclients;
static int maxclis;
playerState_t ps;
if (!maxclients)
maxclients = trap_Cvar_VariableIntegerValue("sv_maxclients");
if (!maxclis)
maxclis = trap_Cvar_VariableIntegerValue("sv_maxclients");
bestscore = -999999;
bestclient = 0;
for (i = 0; i < maxclients && i < MAX_CLIENTS; i++) {
for (i = 0; i < maxclis && i < MAX_CLIENTS; i++) {
trap_GetConfigstring(CS_PLAYERS+i, buf, sizeof(buf));
//if no config string or no name
if (!strlen(buf) || !strlen(Info_ValueForKey(buf, "n"))) continue;
@ -185,15 +162,15 @@ char *BotLastClientInRankings(void) {
int i, worstscore, bestclient;
char buf[MAX_INFO_STRING];
static char name[32];
static int maxclients;
static int maxclis;
playerState_t ps;
if (!maxclients)
maxclients = trap_Cvar_VariableIntegerValue("sv_maxclients");
if (!maxclis)
maxclis = trap_Cvar_VariableIntegerValue("sv_maxclients");
worstscore = 999999;
bestclient = 0;
for (i = 0; i < maxclients && i < MAX_CLIENTS; i++) {
for (i = 0; i < maxclis && i < MAX_CLIENTS; i++) {
trap_GetConfigstring(CS_PLAYERS+i, buf, sizeof(buf));
//if no config string or no name
if (!strlen(buf) || !strlen(Info_ValueForKey(buf, "n"))) continue;
@ -219,15 +196,15 @@ char *BotRandomOpponentName(bot_state_t *bs) {
int i, count;
char buf[MAX_INFO_STRING];
int opponents[MAX_CLIENTS], numopponents;
static int maxclients;
static int maxclis;
static char name[32];
if (!maxclients)
maxclients = trap_Cvar_VariableIntegerValue("sv_maxclients");
if (!maxclis)
maxclis = trap_Cvar_VariableIntegerValue("sv_maxclients");
numopponents = 0;
opponents[0] = 0;
for (i = 0; i < maxclients && i < MAX_CLIENTS; i++) {
for (i = 0; i < maxclis && i < MAX_CLIENTS; i++) {
if (i == bs->client) continue;
//
trap_GetConfigstring(CS_PLAYERS+i, buf, sizeof(buf));
@ -280,27 +257,32 @@ BotWeaponNameForMeansOfDeath
char *BotWeaponNameForMeansOfDeath(int mod) {
switch(mod) {
case MOD_SHOTGUN: return "Shotgun";
case MOD_GAUNTLET: return "Gauntlet";
case MOD_MACHINEGUN: return "Machinegun";
case MOD_PHASER:
case MOD_PHASER_ALT: return "Phaser";
case MOD_CRIFLE:
case MOD_CRIFLE_SPLASH:
case MOD_CRIFLE_ALT:
case MOD_CRIFLE_ALT_SPLASH: return "Compression Rifle";
case MOD_IMOD:
case MOD_IMOD_ALT: return "Infinity Modulator";
case MOD_SCAVENGER:
case MOD_SCAVENGER_ALT:
case MOD_SCAVENGER_ALT_SPLASH: return "Scavenger Rifle";
case MOD_STASIS:
case MOD_STASIS_ALT: return "Stasis Weapon";
case MOD_GRENADE:
case MOD_GRENADE_SPLASH: return "Grenade Launcher";
case MOD_ROCKET:
case MOD_ROCKET_SPLASH: return "Rocket Launcher";
case MOD_PLASMA:
case MOD_PLASMA_SPLASH: return "Plasmagun";
case MOD_RAILGUN: return "Railgun";
case MOD_LIGHTNING: return "Lightning Gun";
case MOD_BFG:
case MOD_BFG_SPLASH: return "BFG10K";
#ifdef MISSIONPACK
case MOD_NAIL: return "Nailgun";
case MOD_CHAINGUN: return "Chaingun";
case MOD_PROXIMITY_MINE: return "Proximity Launcher";
case MOD_KAMIKAZE: return "Kamikaze";
case MOD_JUICED: return "Prox mine";
#endif
case MOD_GRAPPLE: return "Grapple";
case MOD_GRENADE_SPLASH:
case MOD_GRENADE_ALT_SPLASH: return "Grenade Launcher";
case MOD_TETRION:
case MOD_TETRION_ALT: return "Tetryon Disruptor";
case MOD_DREADNOUGHT:
case MOD_DREADNOUGHT_ALT: return "Arc Welder";
case MOD_QUANTUM:
case MOD_QUANTUM_SPLASH:
case MOD_QUANTUM_ALT:
case MOD_QUANTUM_ALT_SPLASH: return "Photon Burst Cannon";
case MOD_KNOCKOUT: return "Hypo";
default: return "[unknown weapon]";
}
}
@ -313,26 +295,17 @@ BotRandomWeaponName
char *BotRandomWeaponName(void) {
int rnd;
#ifdef MISSIONPACK
rnd = random() * 11.9;
#else
rnd = random() * 8.9;
#endif
switch(rnd) {
case 0: return "Gauntlet";
case 1: return "Shotgun";
case 2: return "Machinegun";
case 3: return "Grenade Launcher";
case 4: return "Rocket Launcher";
case 5: return "Plasmagun";
case 6: return "Railgun";
case 7: return "Lightning Gun";
#ifdef MISSIONPACK
case 8: return "Nailgun";
case 9: return "Chaingun";
case 10: return "Proximity Launcher";
#endif
default: return "BFG10K";
case 0: return "Phaser";
case 1: return "Compression Rifle";
case 2: return "Infinity Modulator";
case 3: return "Scavenger Rifle";
case 4: return "Stasis Weapon";
case 5: return "Grenade Launcher";
case 6: return "Tetryon Disruptor";
case 7: return "Dermal Regenerator";
default: return "Photon Burst Cannon";
}
}
@ -342,8 +315,9 @@ BotVisibleEnemies
==================
*/
int BotVisibleEnemies(bot_state_t *bs) {
float vis;
float vis, dist;
int i;
vec3_t dir;
aas_entityinfo_t entinfo;
for (i = 0; i < MAX_CLIENTS; i++) {
@ -359,6 +333,9 @@ int BotVisibleEnemies(bot_state_t *bs) {
if (EntityIsInvisible(&entinfo) && !EntityIsShooting(&entinfo)) {
continue;
}
//calculate the distance towards the enemy
VectorSubtract(entinfo.origin, bs->origin, dir);
dist = VectorLength(dir);
//if on the same team
if (BotSameTeam(bs, i)) continue;
//check if the enemy is visible
@ -381,7 +358,6 @@ int BotValidChatPosition(bot_state_t *bs) {
if (BotIsDead(bs)) return qtrue;
//never start chatting with a powerup
if (bs->inventory[INVENTORY_QUAD] ||
bs->inventory[INVENTORY_ENVIRONMENTSUIT] ||
bs->inventory[INVENTORY_HASTE] ||
bs->inventory[INVENTORY_INVISIBILITY] ||
bs->inventory[INVENTORY_REGEN] ||
@ -418,12 +394,10 @@ int BotChat_EnterGame(bot_state_t *bs) {
float rnd;
if (bot_nochat.integer) return qfalse;
if (bs->lastchat_time > FloatTime() - TIME_BETWEENCHATTING) return qfalse;
if (bs->lastchat_time > trap_AAS_Time() - 3) return qfalse;
//don't chat in teamplay
if (TeamPlayIsOn()) return qfalse;
// don't chat in tournament mode
if (gametype == GT_TOURNAMENT) return qfalse;
rnd = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_ENTEREXITGAME, 0, 1);
rnd = 0;
if (!bot_fastchat.integer) {
if (random() > rnd) return qfalse;
}
@ -436,7 +410,7 @@ int BotChat_EnterGame(bot_state_t *bs) {
"[invalid var]", // 3
BotMapTitle(), // 4
NULL);
bs->lastchat_time = FloatTime();
bs->lastchat_time = trap_AAS_Time();
bs->chatto = CHAT_ALL;
return qtrue;
}
@ -451,12 +425,10 @@ int BotChat_ExitGame(bot_state_t *bs) {
float rnd;
if (bot_nochat.integer) return qfalse;
if (bs->lastchat_time > FloatTime() - TIME_BETWEENCHATTING) return qfalse;
if (bs->lastchat_time > trap_AAS_Time() - 3) return qfalse;
//don't chat in teamplay
if (TeamPlayIsOn()) return qfalse;
// don't chat in tournament mode
if (gametype == GT_TOURNAMENT) return qfalse;
rnd = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_ENTEREXITGAME, 0, 1);
rnd = 0;
if (!bot_fastchat.integer) {
if (random() > rnd) return qfalse;
}
@ -469,7 +441,7 @@ int BotChat_ExitGame(bot_state_t *bs) {
"[invalid var]", // 3
BotMapTitle(), // 4
NULL);
bs->lastchat_time = FloatTime();
bs->lastchat_time = trap_AAS_Time();
bs->chatto = CHAT_ALL;
return qtrue;
}
@ -485,15 +457,10 @@ int BotChat_StartLevel(bot_state_t *bs) {
if (bot_nochat.integer) return qfalse;
if (BotIsObserver(bs)) return qfalse;
if (bs->lastchat_time > FloatTime() - TIME_BETWEENCHATTING) return qfalse;
if (bs->lastchat_time > trap_AAS_Time() - 3) return qfalse;
//don't chat in teamplay
if (TeamPlayIsOn()) {
trap_EA_Command(bs->client, "vtaunt");
return qfalse;
}
// don't chat in tournament mode
if (gametype == GT_TOURNAMENT) return qfalse;
rnd = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_STARTENDLEVEL, 0, 1);
if (TeamPlayIsOn()) return qfalse;
rnd = 0;
if (!bot_fastchat.integer) {
if (random() > rnd) return qfalse;
}
@ -501,7 +468,7 @@ int BotChat_StartLevel(bot_state_t *bs) {
BotAI_BotInitialChat(bs, "level_start",
EasyClientName(bs->client, name, 32), // 0
NULL);
bs->lastchat_time = FloatTime();
bs->lastchat_time = trap_AAS_Time();
bs->chatto = CHAT_ALL;
return qtrue;
}
@ -517,18 +484,10 @@ int BotChat_EndLevel(bot_state_t *bs) {
if (bot_nochat.integer) return qfalse;
if (BotIsObserver(bs)) return qfalse;
if (bs->lastchat_time > FloatTime() - TIME_BETWEENCHATTING) return qfalse;
// teamplay
if (TeamPlayIsOn())
{
if (BotIsFirstInRankings(bs)) {
trap_EA_Command(bs->client, "vtaunt");
}
return qtrue;
}
// don't chat in tournament mode
if (gametype == GT_TOURNAMENT) return qfalse;
rnd = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_STARTENDLEVEL, 0, 1);
if (bs->lastchat_time > trap_AAS_Time() - 3) return qfalse;
//don't chat in teamplay
if (TeamPlayIsOn()) return qfalse;
rnd = 0;
if (!bot_fastchat.integer) {
if (random() > rnd) return qfalse;
}
@ -561,7 +520,7 @@ int BotChat_EndLevel(bot_state_t *bs) {
BotMapTitle(), // 4
NULL);
}
bs->lastchat_time = FloatTime();
bs->lastchat_time = trap_AAS_Time();
bs->chatto = CHAT_ALL;
return qtrue;
}
@ -576,10 +535,8 @@ int BotChat_Death(bot_state_t *bs) {
float rnd;
if (bot_nochat.integer) return qfalse;
if (bs->lastchat_time > FloatTime() - TIME_BETWEENCHATTING) return qfalse;
rnd = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_DEATH, 0, 1);
// don't chat in tournament mode
if (gametype == GT_TOURNAMENT) return qfalse;
if (bs->lastchat_time > trap_AAS_Time() - 3) return qfalse;
rnd = 0;
//if fast chatting is off
if (!bot_fastchat.integer) {
if (random() > rnd) return qfalse;
@ -598,11 +555,8 @@ int BotChat_Death(bot_state_t *bs) {
}
else
{
//teamplay
if (TeamPlayIsOn()) {
trap_EA_Command(bs->client, "vtaunt");
return qtrue;
}
//don't chat in teamplay
if (TeamPlayIsOn()) return qfalse;
//
if (bs->botdeathtype == MOD_WATER)
BotAI_BotInitialChat(bs, "death_drown", BotRandomOpponentName(bs), NULL);
@ -615,17 +569,16 @@ int BotChat_Death(bot_state_t *bs) {
else if (bs->botsuicide || //all other suicides by own weapon
bs->botdeathtype == MOD_CRUSH ||
bs->botdeathtype == MOD_SUICIDE ||
bs->botdeathtype == MOD_RESPAWN ||
bs->botdeathtype == MOD_TARGET_LASER ||
bs->botdeathtype == MOD_TRIGGER_HURT ||
bs->botdeathtype == MOD_UNKNOWN)
bs->botdeathtype == MOD_UNKNOWN ||
bs->botdeathtype == MOD_EXPLOSION)
BotAI_BotInitialChat(bs, "death_suicide", BotRandomOpponentName(bs), NULL);
else if (bs->botdeathtype == MOD_TELEFRAG)
BotAI_BotInitialChat(bs, "death_telefrag", name, NULL);
#ifdef MISSIONPACK
else if (bs->botdeathtype == MOD_KAMIKAZE && trap_BotNumInitialChats(bs->cs, "death_kamikaze"))
BotAI_BotInitialChat(bs, "death_kamikaze", name, NULL);
#endif
else {
#if 0
if ((bs->botdeathtype == MOD_GAUNTLET ||
bs->botdeathtype == MOD_RAILGUN ||
bs->botdeathtype == MOD_BFG ||
@ -648,7 +601,10 @@ int BotChat_Death(bot_state_t *bs) {
NULL);
}
//choose between insult and praise
else if (random() < trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_INSULT, 0, 1)) {
else
#endif //0
if (random() < trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_INSULT, 0, 1)) {
BotAI_BotInitialChat(bs, "death_insult",
name, // 0
BotWeaponNameForMeansOfDeath(bs->botdeathtype), // 1
@ -663,7 +619,7 @@ int BotChat_Death(bot_state_t *bs) {
}
bs->chatto = CHAT_ALL;
}
bs->lastchat_time = FloatTime();
bs->lastchat_time = trap_AAS_Time();
return qtrue;
}
@ -677,10 +633,8 @@ int BotChat_Kill(bot_state_t *bs) {
float rnd;
if (bot_nochat.integer) return qfalse;
if (bs->lastchat_time > FloatTime() - TIME_BETWEENCHATTING) return qfalse;
rnd = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_KILL, 0, 1);
// don't chat in tournament mode
if (gametype == GT_TOURNAMENT) return qfalse;
if (bs->lastchat_time > trap_AAS_Time() - 3) return qfalse;
rnd = 0;
//if fast chat is off
if (!bot_fastchat.integer) {
if (random() > rnd) return qfalse;
@ -701,24 +655,20 @@ int BotChat_Kill(bot_state_t *bs) {
else
{
//don't chat in teamplay
if (TeamPlayIsOn()) {
trap_EA_Command(bs->client, "vtaunt");
return qfalse; // don't wait
}
if (TeamPlayIsOn()) return qfalse;
//
#if 0
if (bs->enemydeathtype == MOD_GAUNTLET) {
BotAI_BotInitialChat(bs, "kill_gauntlet", name, NULL);
}
else if (bs->enemydeathtype == MOD_RAILGUN) {
BotAI_BotInitialChat(bs, "kill_rail", name, NULL);
}
#endif // 0
else if (bs->enemydeathtype == MOD_TELEFRAG) {
BotAI_BotInitialChat(bs, "kill_telefrag", name, NULL);
}
#ifdef MISSIONPACK
else if (bs->botdeathtype == MOD_KAMIKAZE && trap_BotNumInitialChats(bs->cs, "kill_kamikaze"))
BotAI_BotInitialChat(bs, "kill_kamikaze", name, NULL);
#endif
//choose between insult and praise
else if (random() < trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_INSULT, 0, 1)) {
BotAI_BotInitialChat(bs, "kill_insult", name, NULL);
@ -727,7 +677,7 @@ int BotChat_Kill(bot_state_t *bs) {
BotAI_BotInitialChat(bs, "kill_praise", name, NULL);
}
}
bs->lastchat_time = FloatTime();
bs->lastchat_time = trap_AAS_Time();
return qtrue;
}
@ -741,14 +691,12 @@ int BotChat_EnemySuicide(bot_state_t *bs) {
float rnd;
if (bot_nochat.integer) return qfalse;
if (bs->lastchat_time > FloatTime() - TIME_BETWEENCHATTING) return qfalse;
if (bs->lastchat_time > trap_AAS_Time() - 3) return qfalse;
if (BotNumActivePlayers() <= 1) return qfalse;
//
rnd = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_ENEMYSUICIDE, 0, 1);
rnd = 0;
//don't chat in teamplay
if (TeamPlayIsOn()) return qfalse;
// don't chat in tournament mode
if (gametype == GT_TOURNAMENT) return qfalse;
//if fast chat is off
if (!bot_fastchat.integer) {
if (random() > rnd) return qfalse;
@ -760,7 +708,7 @@ int BotChat_EnemySuicide(bot_state_t *bs) {
if (bs->enemy >= 0) EasyClientName(bs->enemy, name, 32);
else strcpy(name, "");
BotAI_BotInitialChat(bs, "enemy_suicide", name, NULL);
bs->lastchat_time = FloatTime();
bs->lastchat_time = trap_AAS_Time();
bs->chatto = CHAT_ALL;
return qtrue;
}
@ -776,7 +724,7 @@ int BotChat_HitTalking(bot_state_t *bs) {
float rnd;
if (bot_nochat.integer) return qfalse;
if (bs->lastchat_time > FloatTime() - TIME_BETWEENCHATTING) return qfalse;
if (bs->lastchat_time > trap_AAS_Time() - 3) return qfalse;
if (BotNumActivePlayers() <= 1) return qfalse;
lasthurt_client = g_entities[bs->client].client->lasthurt_client;
if (!lasthurt_client) return qfalse;
@ -784,11 +732,9 @@ int BotChat_HitTalking(bot_state_t *bs) {
//
if (lasthurt_client < 0 || lasthurt_client >= MAX_CLIENTS) return qfalse;
//
rnd = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_HITTALKING, 0, 1);
rnd = 0;
//don't chat in teamplay
if (TeamPlayIsOn()) return qfalse;
// don't chat in tournament mode
if (gametype == GT_TOURNAMENT) return qfalse;
//if fast chat is off
if (!bot_fastchat.integer) {
if (random() > rnd * 0.5) return qfalse;
@ -796,10 +742,10 @@ int BotChat_HitTalking(bot_state_t *bs) {
if (!BotValidChatPosition(bs)) return qfalse;
//
ClientName(g_entities[bs->client].client->lasthurt_client, name, sizeof(name));
weap = BotWeaponNameForMeansOfDeath(g_entities[bs->client].client->lasthurt_mod);
weap = BotWeaponNameForMeansOfDeath(g_entities[bs->client].client->lasthurt_client);
//
BotAI_BotInitialChat(bs, "hit_talking", name, weap, NULL);
bs->lastchat_time = FloatTime();
bs->lastchat_time = trap_AAS_Time();
bs->chatto = CHAT_ALL;
return qtrue;
}
@ -822,13 +768,11 @@ int BotChat_HitNoDeath(bot_state_t *bs) {
if (lasthurt_client < 0 || lasthurt_client >= MAX_CLIENTS) return qfalse;
//
if (bot_nochat.integer) return qfalse;
if (bs->lastchat_time > FloatTime() - TIME_BETWEENCHATTING) return qfalse;
if (bs->lastchat_time > trap_AAS_Time() - 3) return qfalse;
if (BotNumActivePlayers() <= 1) return qfalse;
rnd = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_HITNODEATH, 0, 1);
rnd = 0;
//don't chat in teamplay
if (TeamPlayIsOn()) return qfalse;
// don't chat in tournament mode
if (gametype == GT_TOURNAMENT) return qfalse;
//if fast chat is off
if (!bot_fastchat.integer) {
if (random() > rnd * 0.5) return qfalse;
@ -844,7 +788,7 @@ int BotChat_HitNoDeath(bot_state_t *bs) {
weap = BotWeaponNameForMeansOfDeath(g_entities[bs->client].client->lasthurt_mod);
//
BotAI_BotInitialChat(bs, "hit_nodeath", name, weap, NULL);
bs->lastchat_time = FloatTime();
bs->lastchat_time = trap_AAS_Time();
bs->chatto = CHAT_ALL;
return qtrue;
}
@ -860,13 +804,11 @@ int BotChat_HitNoKill(bot_state_t *bs) {
aas_entityinfo_t entinfo;
if (bot_nochat.integer) return qfalse;
if (bs->lastchat_time > FloatTime() - TIME_BETWEENCHATTING) return qfalse;
if (bs->lastchat_time > trap_AAS_Time() - 3) return qfalse;
if (BotNumActivePlayers() <= 1) return qfalse;
rnd = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_HITNOKILL, 0, 1);
rnd = 0;
//don't chat in teamplay
if (TeamPlayIsOn()) return qfalse;
// don't chat in tournament mode
if (gametype == GT_TOURNAMENT) return qfalse;
//if fast chat is off
if (!bot_fastchat.integer) {
if (random() > rnd * 0.5) return qfalse;
@ -882,7 +824,7 @@ int BotChat_HitNoKill(bot_state_t *bs) {
weap = BotWeaponNameForMeansOfDeath(g_entities[bs->enemy].client->lasthurt_mod);
//
BotAI_BotInitialChat(bs, "hit_nokill", name, weap, NULL);
bs->lastchat_time = FloatTime();
bs->lastchat_time = trap_AAS_Time();
bs->chatto = CHAT_ALL;
return qtrue;
}
@ -898,36 +840,29 @@ int BotChat_Random(bot_state_t *bs) {
if (bot_nochat.integer) return qfalse;
if (BotIsObserver(bs)) return qfalse;
if (bs->lastchat_time > FloatTime() - TIME_BETWEENCHATTING) return qfalse;
// don't chat in tournament mode
if (gametype == GT_TOURNAMENT) return qfalse;
if (bs->lastchat_time > trap_AAS_Time() - 3) return qfalse;
//don't chat in teamplay
if (TeamPlayIsOn()) return qfalse;
//don't chat when doing something important :)
if (bs->ltgtype == LTG_TEAMHELP ||
bs->ltgtype == LTG_TEAMACCOMPANY ||
bs->ltgtype == LTG_RUSHBASE) return qfalse;
//
rnd = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_RANDOM, 0, 1);
rnd = 0;
if (random() > bs->thinktime * 0.1) return qfalse;
if (!bot_fastchat.integer) {
if (random() > rnd) return qfalse;
if (random() > 0.25) return qfalse;
}
if (BotNumActivePlayers() <= 1) return qfalse;
//
if (!BotValidChatPosition(bs)) return qfalse;
//
if (BotVisibleEnemies(bs)) return qfalse;
//
if (bs->lastkilledplayer == bs->client) {
strcpy(name, BotRandomOpponentName(bs));
}
else {
EasyClientName(bs->lastkilledplayer, name, sizeof(name));
}
if (TeamPlayIsOn()) {
trap_EA_Command(bs->client, "vtaunt");
return qfalse; // don't wait
}
//
if (random() < trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_MISC, 0, 1)) {
BotAI_BotInitialChat(bs, "random_misc",
@ -949,7 +884,7 @@ int BotChat_Random(bot_state_t *bs) {
BotRandomWeaponName(), // 5
NULL);
}
bs->lastchat_time = FloatTime();
bs->lastchat_time = trap_AAS_Time();
bs->chatto = CHAT_ALL;
return qtrue;
}
@ -960,11 +895,10 @@ BotChatTime
==================
*/
float BotChatTime(bot_state_t *bs) {
//int cpm;
int cpm;
//cpm = trap_Characteristic_BInteger(bs->character, CHARACTERISTIC_CHAT_CPM, 1, 4000);
return 2.0; //(float) trap_BotChatLength(bs->cs) * 30 / cpm;
cpm = 4000;
return 4000;
}
/*
@ -988,7 +922,7 @@ void BotChatTest(bot_state_t *bs) {
"[invalid var]", // 3
BotMapTitle(), // 4
NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "game_exit");
for (i = 0; i < num; i++)
@ -1000,7 +934,7 @@ void BotChatTest(bot_state_t *bs) {
"[invalid var]", // 3
BotMapTitle(), // 4
NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "level_start");
for (i = 0; i < num; i++)
@ -1008,7 +942,7 @@ void BotChatTest(bot_state_t *bs) {
BotAI_BotInitialChat(bs, "level_start",
EasyClientName(bs->client, name, 32), // 0
NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "level_end_victory");
for (i = 0; i < num; i++)
@ -1020,7 +954,7 @@ void BotChatTest(bot_state_t *bs) {
BotLastClientInRankings(), // 3
BotMapTitle(), // 4
NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "level_end_lose");
for (i = 0; i < num; i++)
@ -1032,7 +966,7 @@ void BotChatTest(bot_state_t *bs) {
BotLastClientInRankings(), // 3
BotMapTitle(), // 4
NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "level_end");
for (i = 0; i < num; i++)
@ -1044,7 +978,7 @@ void BotChatTest(bot_state_t *bs) {
BotLastClientInRankings(), // 3
BotMapTitle(), // 4
NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
EasyClientName(bs->lastkilledby, name, sizeof(name));
num = trap_BotNumInitialChats(bs->cs, "death_drown");
@ -1052,37 +986,37 @@ void BotChatTest(bot_state_t *bs) {
{
//
BotAI_BotInitialChat(bs, "death_drown", name, NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "death_slime");
for (i = 0; i < num; i++)
{
BotAI_BotInitialChat(bs, "death_slime", name, NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "death_lava");
for (i = 0; i < num; i++)
{
BotAI_BotInitialChat(bs, "death_lava", name, NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "death_cratered");
for (i = 0; i < num; i++)
{
BotAI_BotInitialChat(bs, "death_cratered", name, NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "death_suicide");
for (i = 0; i < num; i++)
{
BotAI_BotInitialChat(bs, "death_suicide", name, NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "death_telefrag");
for (i = 0; i < num; i++)
{
BotAI_BotInitialChat(bs, "death_telefrag", name, NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "death_gauntlet");
for (i = 0; i < num; i++)
@ -1091,7 +1025,7 @@ void BotChatTest(bot_state_t *bs) {
name, // 0
BotWeaponNameForMeansOfDeath(bs->botdeathtype), // 1
NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "death_rail");
for (i = 0; i < num; i++)
@ -1100,7 +1034,7 @@ void BotChatTest(bot_state_t *bs) {
name, // 0
BotWeaponNameForMeansOfDeath(bs->botdeathtype), // 1
NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "death_bfg");
for (i = 0; i < num; i++)
@ -1109,7 +1043,7 @@ void BotChatTest(bot_state_t *bs) {
name, // 0
BotWeaponNameForMeansOfDeath(bs->botdeathtype), // 1
NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "death_insult");
for (i = 0; i < num; i++)
@ -1118,7 +1052,7 @@ void BotChatTest(bot_state_t *bs) {
name, // 0
BotWeaponNameForMeansOfDeath(bs->botdeathtype), // 1
NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "death_praise");
for (i = 0; i < num; i++)
@ -1127,7 +1061,7 @@ void BotChatTest(bot_state_t *bs) {
name, // 0
BotWeaponNameForMeansOfDeath(bs->botdeathtype), // 1
NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
//
EasyClientName(bs->lastkilledplayer, name, 32);
@ -1137,37 +1071,37 @@ void BotChatTest(bot_state_t *bs) {
{
//
BotAI_BotInitialChat(bs, "kill_gauntlet", name, NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "kill_rail");
for (i = 0; i < num; i++)
{
BotAI_BotInitialChat(bs, "kill_rail", name, NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "kill_telefrag");
for (i = 0; i < num; i++)
{
BotAI_BotInitialChat(bs, "kill_telefrag", name, NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "kill_insult");
for (i = 0; i < num; i++)
{
BotAI_BotInitialChat(bs, "kill_insult", name, NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "kill_praise");
for (i = 0; i < num; i++)
{
BotAI_BotInitialChat(bs, "kill_praise", name, NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "enemy_suicide");
for (i = 0; i < num; i++)
{
BotAI_BotInitialChat(bs, "enemy_suicide", name, NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
ClientName(g_entities[bs->client].client->lasthurt_client, name, sizeof(name));
weap = BotWeaponNameForMeansOfDeath(g_entities[bs->client].client->lasthurt_client);
@ -1175,19 +1109,19 @@ void BotChatTest(bot_state_t *bs) {
for (i = 0; i < num; i++)
{
BotAI_BotInitialChat(bs, "hit_talking", name, weap, NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "hit_nodeath");
for (i = 0; i < num; i++)
{
BotAI_BotInitialChat(bs, "hit_nodeath", name, weap, NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "hit_nokill");
for (i = 0; i < num; i++)
{
BotAI_BotInitialChat(bs, "hit_nokill", name, weap, NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
//
if (bs->lastkilledplayer == bs->client) {
@ -1209,7 +1143,7 @@ void BotChatTest(bot_state_t *bs) {
BotMapTitle(), // 4
BotRandomWeaponName(), // 5
NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
num = trap_BotNumInitialChats(bs->cs, "random_insult");
for (i = 0; i < num; i++)
@ -1222,6 +1156,6 @@ void BotChatTest(bot_state_t *bs) {
BotMapTitle(), // 4
BotRandomWeaponName(), // 5
NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
}

View file

@ -1,24 +1,4 @@
/*
===========================================================================
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
===========================================================================
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
@ -26,7 +6,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* desc: Quake3 bot AI
*
* $Archive: /source/code/botai/ai_chat.c $
* $Archive: /StarTrek/Code-DM/game/ai_chat.h $
* $Author: Jmonroe $
* $Revision: 1 $
* $Modtime: 1/21/00 10:12p $
* $Date: 1/25/00 6:26p $
*
*****************************************************************************/
@ -52,10 +36,10 @@ int BotChat_Kill(bot_state_t *bs);
int BotChat_EnemySuicide(bot_state_t *bs);
//
int BotChat_Random(bot_state_t *bs);
// time the selected chat takes to type in
//! time the selected chat takes to type in
float BotChatTime(bot_state_t *bs);
// returns true if the bot can chat at the current position
//! returns true if the bot can chat at the current position
int BotValidChatPosition(bot_state_t *bs);
// test the initial bot chats
//! test the initial bot chats
void BotChatTest(bot_state_t *bs);

File diff suppressed because it is too large Load diff

View file

@ -1,24 +1,4 @@
/*
===========================================================================
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
===========================================================================
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
@ -26,12 +6,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* desc: Quake3 bot AI
*
* $Archive: /source/code/botai/ai_chat.c $
* $Archive: /StarTrek/Code-DM/game/ai_cmd.h $
* $Author: Jmonroe $
* $Revision: 1 $
* $Modtime: 1/21/00 10:12p $
* $Date: 1/25/00 6:26p $
*
*****************************************************************************/
extern int notleader[MAX_CLIENTS];
int BotMatchMessage(bot_state_t *bs, char *message);
void BotPrintTeamGoal(bot_state_t *bs);

File diff suppressed because it is too large Load diff

View file

@ -1,24 +1,4 @@
/*
===========================================================================
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
===========================================================================
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
@ -26,24 +6,28 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* desc: Quake3 bot AI
*
* $Archive: /source/code/botai/ai_chat.c $
* $Archive: /StarTrek/Code-DM/game/ai_dmnet.h $
* $Author: Jmonroe $
* $Revision: 1 $
* $Modtime: 1/21/00 10:12p $
* $Date: 1/25/00 6:26p $
*
*****************************************************************************/
#define MAX_NODESWITCHES 50
void AIEnter_Intermission(bot_state_t *bs, char *s);
void AIEnter_Observer(bot_state_t *bs, char *s);
void AIEnter_Respawn(bot_state_t *bs, char *s);
void AIEnter_Stand(bot_state_t *bs, char *s);
void AIEnter_Seek_ActivateEntity(bot_state_t *bs, char *s);
void AIEnter_Seek_NBG(bot_state_t *bs, char *s);
void AIEnter_Seek_LTG(bot_state_t *bs, char *s);
void AIEnter_Seek_Camp(bot_state_t *bs, char *s);
void AIEnter_Battle_Fight(bot_state_t *bs, char *s);
void AIEnter_Battle_Chase(bot_state_t *bs, char *s);
void AIEnter_Battle_Retreat(bot_state_t *bs, char *s);
void AIEnter_Battle_NBG(bot_state_t *bs, char *s);
void AIEnter_Intermission(bot_state_t *bs);
void AIEnter_Observer(bot_state_t *bs);
void AIEnter_Respawn(bot_state_t *bs);
void AIEnter_Stand(bot_state_t *bs);
void AIEnter_Seek_ActivateEntity(bot_state_t *bs);
void AIEnter_Seek_NBG(bot_state_t *bs);
void AIEnter_Seek_LTG(bot_state_t *bs);
void AIEnter_Seek_Camp(bot_state_t *bs);
void AIEnter_Battle_Fight(bot_state_t *bs);
void AIEnter_Battle_Chase(bot_state_t *bs);
void AIEnter_Battle_Retreat(bot_state_t *bs);
void AIEnter_Battle_NBG(bot_state_t *bs);
int AINode_Intermission(bot_state_t *bs);
int AINode_Observer(bot_state_t *bs);
int AINode_Respawn(bot_state_t *bs);

File diff suppressed because it is too large Load diff

2857
code/game/ai_dmq3.c.orig Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,24 +1,4 @@
/*
===========================================================================
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
===========================================================================
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
@ -26,153 +6,102 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* desc: Quake3 bot AI
*
* $Archive: /source/code/botai/ai_chat.c $
* $Archive: /StarTrek/Code-DM/game/ai_dmq3.h $
* $Author: Dkramer $
* $Revision: 2 $
* $Modtime: 6/21/00 4:35p $
* $Date: 6/27/00 10:06a $
*
*****************************************************************************/
//setup the deathmatch AI
//!setup the deathmatch AI
void BotSetupDeathmatchAI(void);
//shutdown the deathmatch AI
//!shutdown the deathmatch AI
void BotShutdownDeathmatchAI(void);
//let the bot live within its deathmatch AI net
//!let the bot live within it's deathmatch AI net
void BotDeathmatchAI(bot_state_t *bs, float thinktime);
//free waypoints
//!free waypoints
void BotFreeWaypoints(bot_waypoint_t *wp);
//choose a weapon
//!choose a weapon
void BotChooseWeapon(bot_state_t *bs);
//setup movement stuff
//!setup movement stuff
void BotSetupForMovement(bot_state_t *bs);
//update the inventory
//!update the inventory
void BotUpdateInventory(bot_state_t *bs);
//update the inventory during battle
//!update the inventory during battle
void BotUpdateBattleInventory(bot_state_t *bs, int enemy);
//use holdable items during battle
//! should I detonate the detpack now
qboolean BotShouldDetonateDetPack(bot_state_t *bs);
//!use holdable items during battle
void BotBattleUseItems(bot_state_t *bs);
//return true if the bot is dead
//!return true if the bot is dead
qboolean BotIsDead(bot_state_t *bs);
//returns true if the bot is in observer mode
//!returns true if the bot is in observer mode
qboolean BotIsObserver(bot_state_t *bs);
//returns true if the bot is in the intermission
//!returns true if the bot is in the intermission
qboolean BotIntermission(bot_state_t *bs);
//returns true if the bot is in lava or slime
//!returns true if the bot is in lava or slime
qboolean BotInLavaOrSlime(bot_state_t *bs);
//returns true if the entity is dead
//!returns true if the entity is dead
qboolean EntityIsDead(aas_entityinfo_t *entinfo);
//returns true if the entity is invisible
//!returns true if the entity is invisible
qboolean EntityIsInvisible(aas_entityinfo_t *entinfo);
//returns true if the entity is shooting
//!returns true if the entity is shooting
qboolean EntityIsShooting(aas_entityinfo_t *entinfo);
#ifdef MISSIONPACK
//returns true if this entity has the kamikaze
qboolean EntityHasKamikaze(aas_entityinfo_t *entinfo);
#endif
// set a user info key/value pair
void BotSetUserInfo(bot_state_t *bs, char *key, char *value);
// set the team status (offense, defense etc.)
void BotSetTeamStatus(bot_state_t *bs);
//returns the name of the client
//!returns the name of the client
char *ClientName(int client, char *name, int size);
//returns an simplyfied client name
//!returns an simplyfied client name
char *EasyClientName(int client, char *name, int size);
//returns the skin used by the client
//!returns the skin used by the client
char *ClientSkin(int client, char *skin, int size);
// returns the appropriate synonym context for the current game type and situation
int BotSynonymContext(bot_state_t *bs);
// set last ordered task
int BotSetLastOrderedTask(bot_state_t *bs);
// selection of goals for teamplay
void BotTeamGoals(bot_state_t *bs, int retreat);
//returns the aggression of the bot in the range [0, 100]
//!returns the aggression of the bot in the range [0, 100]
float BotAggression(bot_state_t *bs);
//returns how bad the bot feels
float BotFeelingBad(bot_state_t *bs);
//returns true if the bot wants to retreat
//!returns true if the bot wants to retreat
int BotWantsToRetreat(bot_state_t *bs);
//returns true if the bot wants to chase
//!returns true if the bot wants to chase
int BotWantsToChase(bot_state_t *bs);
//returns true if the bot wants to help
//!returns true if the bot wants to help
int BotWantsToHelp(bot_state_t *bs);
//returns true if the bot can and wants to rocketjump
//!returns true if the bot can and wants to rocketjump
int BotCanAndWantsToRocketJump(bot_state_t *bs);
// returns true if the bot has a persistant powerup and a weapon
int BotHasPersistantPowerupAndWeapon(bot_state_t *bs);
//returns true if the bot wants to and goes camping
//!returns true if the bot wants to and goes camping
int BotWantsToCamp(bot_state_t *bs);
//the bot will perform attack movements
//!the bot will perform attack movements
bot_moveresult_t BotAttackMove(bot_state_t *bs, int tfl);
//returns true if the bot and the entity are in the same team
//!returns true if the bot and the entity are in the same team
int BotSameTeam(bot_state_t *bs, int entnum);
//returns true if teamplay is on
//!returns true if teamplay is on
int TeamPlayIsOn(void);
// returns the client number of the team mate flag carrier (-1 if none)
int BotTeamFlagCarrier(bot_state_t *bs);
//returns visible team mate flag carrier if available
//!returns visible team mate flag carrier if available
int BotTeamFlagCarrierVisible(bot_state_t *bs);
//returns visible enemy flag carrier if available
int BotEnemyFlagCarrierVisible(bot_state_t *bs);
//get the number of visible teammates and enemies
void BotVisibleTeamMatesAndEnemies(bot_state_t *bs, int *teammates, int *enemies, float range);
//returns true if within the field of vision for the given angles
qboolean InFieldOfVision(vec3_t viewangles, float fov, vec3_t angles);
//returns true and sets the .enemy field when an enemy is found
//!returns true and sets the .enemy field when an enemy is found
int BotFindEnemy(bot_state_t *bs, int curenemy);
//returns a roam goal
//!returns a roam goal
void BotRoamGoal(bot_state_t *bs, vec3_t goal);
//returns entity visibility in the range [0, 1]
//!returns entity visibility in the range [0, 1]
float BotEntityVisible(int viewer, vec3_t eye, vec3_t viewangles, float fov, int ent);
//the bot will aim at the current enemy
//!the bot will aim at the current enemy
void BotAimAtEnemy(bot_state_t *bs);
//check if the bot should attack
//!check if the bot should attack
void BotCheckAttack(bot_state_t *bs);
//AI when the bot is blocked
//!AI when the bot is blocked
void BotAIBlocked(bot_state_t *bs, bot_moveresult_t *moveresult, int activate);
//AI to predict obstacles
int BotAIPredictObstacles(bot_state_t *bs, bot_goal_t *goal);
//enable or disable the areas the blocking entity is in
void BotEnableActivateGoalAreas(bot_activategoal_t *activategoal, int enable);
//pop an activate goal from the stack
int BotPopFromActivateGoalStack(bot_state_t *bs);
//clear the activate goal stack
void BotClearActivateGoalStack(bot_state_t *bs);
//returns the team the bot is in
int BotTeam(bot_state_t *bs);
//retuns the opposite team of the bot
int BotOppositeTeam(bot_state_t *bs);
//returns the flag the bot is carrying (CTFFLAG_?)
//!returns the CTF team the bot is in
int BotCTFTeam(bot_state_t *bs);
//!returns the flag the bot is carrying (CTFFLAG_?)
int BotCTFCarryingFlag(bot_state_t *bs);
//remember the last ordered task
void BotRememberLastOrderedTask(bot_state_t *bs);
//set ctf goals (defend base, get enemy flag) during seek
//!set ctf goals (defend base, get enemy flag) during seek
void BotCTFSeekGoals(bot_state_t *bs);
//set ctf goals (defend base, get enemy flag) during retreat
//!set ctf goals (defend base, get enemy flag) during retreat
void BotCTFRetreatGoals(bot_state_t *bs);
//
#ifdef MISSIONPACK
int Bot1FCTFCarryingFlag(bot_state_t *bs);
int BotHarvesterCarryingCubes(bot_state_t *bs);
void Bot1FCTFSeekGoals(bot_state_t *bs);
void Bot1FCTFRetreatGoals(bot_state_t *bs);
void BotObeliskSeekGoals(bot_state_t *bs);
void BotObeliskRetreatGoals(bot_state_t *bs);
void BotGoHarvest(bot_state_t *bs);
void BotHarvesterSeekGoals(bot_state_t *bs);
void BotHarvesterRetreatGoals(bot_state_t *bs);
int BotTeamCubeCarrierVisible(bot_state_t *bs);
int BotEnemyCubeCarrierVisible(bot_state_t *bs);
#endif
//get a random alternate route goal towards the given base
int BotGetAlternateRouteGoal(bot_state_t *bs, int base);
//returns either the alternate route goal or the given goal
bot_goal_t *BotAlternateRoute(bot_state_t *bs, bot_goal_t *goal);
//create a new waypoint
//!create a new waypoint
bot_waypoint_t *BotCreateWayPoint(char *name, vec3_t origin, int areanum);
//find a waypoint with the given name
//!find a waypoint with the given name
bot_waypoint_t *BotFindWayPoint(bot_waypoint_t *waypoints, char *name);
//strstr but case insensitive
//!strstr but case insensitive
char *stristr(char *str, char *charset);
//returns the number of the client with the given name
//!returns the number of the client with the given name
int ClientFromName(char *name);
int ClientOnSameTeamFromName(bot_state_t *bs, char *name);
//
int BotPointAreaNum(vec3_t origin);
//
@ -185,9 +114,13 @@ void BotMapScripts(bot_state_t *bs);
//CTF skins
#define CTF_SKIN_REDTEAM "red"
#define CTF_SKIN_BLUETEAM "blue"
//CTF teams
#define CTF_TEAM_NONE 0
#define CTF_TEAM_RED 1
#define CTF_TEAM_BLUE 2
extern int gametype; //game type
extern int maxclients; //maximum number of clients
extern int gametype; //!<game type
extern int maxclients; //!<maximum number of clients
extern vmCvar_t bot_grapple;
extern vmCvar_t bot_rocketjump;
@ -198,9 +131,4 @@ extern vmCvar_t bot_challenge;
extern bot_goal_t ctf_redflag;
extern bot_goal_t ctf_blueflag;
#ifdef MISSIONPACK
extern bot_goal_t ctf_neutralflag;
extern bot_goal_t redobelisk;
extern bot_goal_t blueobelisk;
extern bot_goal_t neutralobelisk;
#endif

View file

@ -1,24 +1,4 @@
/*
===========================================================================
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
===========================================================================
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
@ -26,46 +6,44 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* desc: Quake3 bot AI
*
* $Archive: /MissionPack/code/game/ai_main.c $
* $Archive: /StarTrek/Code-DM/game/ai_main.c $
* $Author: Jmonroe $
* $Revision: 4 $
* $Modtime: 11/30/00 5:17p $
* $Date: 11/30/00 5:19p $
*
*****************************************************************************/
#include "g_local.h"
#include "../qcommon/q_shared.h"
#include "../botlib/botlib.h" //bot lib interface
#include "../botlib/be_aas.h"
#include "../botlib/be_ea.h"
#include "../botlib/be_ai_char.h"
#include "../botlib/be_ai_chat.h"
#include "../botlib/be_ai_gen.h"
#include "../botlib/be_ai_goal.h"
#include "../botlib/be_ai_move.h"
#include "../botlib/be_ai_weap.h"
#include "q_shared.h"
#include "botlib.h" //bot lib interface
#include "be_aas.h"
#include "be_ea.h"
#include "be_ai_char.h"
#include "be_ai_chat.h"
#include "be_ai_gen.h"
#include "be_ai_goal.h"
#include "be_ai_move.h"
#include "be_ai_weap.h"
//
#include "ai_main.h"
#include "ai_dmq3.h"
#include "ai_chat.h"
#include "ai_cmd.h"
#include "ai_dmnet.h"
#include "ai_vcmd.h"
//
#include "chars.h"
#include "inv.h"
#include "syn.h"
#ifndef MAX_PATH
#define MAX_PATH 144
#endif
#define AI_MAX_PATH 144
//bot states
bot_state_t *botstates[MAX_CLIENTS];
//number of bots
int numbots;
//floating point time
float floattime;
//time to do a regular update
float regularupdate_time;
//
@ -74,17 +52,15 @@ int bot_interbreedmatchcount;
//
vmCvar_t bot_thinktime;
vmCvar_t bot_memorydump;
vmCvar_t bot_saveroutingcache;
vmCvar_t bot_pause;
vmCvar_t bot_report;
vmCvar_t bot_testsolid;
vmCvar_t bot_testclusters;
vmCvar_t bot_developer;
vmCvar_t bot_interbreedchar;
vmCvar_t bot_interbreedbots;
vmCvar_t bot_interbreedcycle;
vmCvar_t bot_interbreedwrite;
qboolean bot_setupComplete = qfalse;
void ExitLevel( void );
@ -99,7 +75,7 @@ void QDECL BotAI_Print(int type, char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
Q_vsnprintf(str, sizeof(str), fmt, ap);
vsprintf(str, fmt, ap);
va_end(ap);
switch(type) {
@ -235,7 +211,9 @@ void QDECL BotAI_BotInitialChat( bot_state_t *bs, char *type, ... ) {
}
va_end(ap);
mcontext = BotSynonymContext(bs);
mcontext = CONTEXT_NORMAL|CONTEXT_NEARBYITEM|CONTEXT_NAMES;
if (BotCTFTeam(bs) == CTF_TEAM_RED) mcontext |= CONTEXT_CTFREDTEAM;
else mcontext |= CONTEXT_CTFBLUETEAM;
trap_BotInitialChat( bs->cs, type, mcontext, vars[0], vars[1], vars[2], vars[3], vars[4], vars[5], vars[6], vars[7] );
}
@ -243,31 +221,23 @@ void QDECL BotAI_BotInitialChat( bot_state_t *bs, char *type, ... ) {
/*
==================
BotTestAAS
BotTestSolid
==================
*/
void BotTestAAS(vec3_t origin) {
void BotTestSolid(vec3_t origin) {
int areanum;
aas_areainfo_t info;
if( !bot_setupComplete ) {
return;
}
trap_Cvar_Update(&bot_testsolid);
trap_Cvar_Update(&bot_testclusters);
if (bot_testsolid.integer) {
if (!trap_AAS_Initialized()) return;
areanum = BotPointAreaNum(origin);
if (areanum) BotAI_Print(PRT_MESSAGE, "\remtpy area");
else BotAI_Print(PRT_MESSAGE, "\r^1SOLID area");
}
else if (bot_testclusters.integer) {
if (!trap_AAS_Initialized()) return;
areanum = BotPointAreaNum(origin);
if (!areanum)
BotAI_Print(PRT_MESSAGE, "\r^1Solid! ");
else {
trap_AAS_AreaInfo(areanum, &info);
BotAI_Print(PRT_MESSAGE, "\rarea %d, cluster %d ", areanum, info.cluster);
}
}
}
/*
@ -278,34 +248,18 @@ BotReportStatus
void BotReportStatus(bot_state_t *bs) {
char goalname[MAX_MESSAGE_SIZE];
char netname[MAX_MESSAGE_SIZE];
char *leader, flagstatus[32];
char *leader, *flagstatus;
//
ClientName(bs->client, netname, sizeof(netname));
if (Q_stricmp(netname, bs->teamleader) == 0) leader = "L";
else leader = " ";
strcpy(flagstatus, " ");
if (gametype == GT_CTF) {
if (BotCTFCarryingFlag(bs)) {
if (BotTeam(bs) == TEAM_RED) strcpy(flagstatus, S_COLOR_RED"F ");
else strcpy(flagstatus, S_COLOR_BLUE"F ");
}
if (BotCTFCarryingFlag(bs)) {
if (BotCTFTeam(bs) == TEAM_RED) flagstatus = S_COLOR_RED"F";
else flagstatus = S_COLOR_BLUE"F";
}
#ifdef MISSIONPACK
else if (gametype == GT_1FCTF) {
if (Bot1FCTFCarryingFlag(bs)) {
if (BotTeam(bs) == TEAM_RED) strcpy(flagstatus, S_COLOR_RED"F ");
else strcpy(flagstatus, S_COLOR_BLUE"F ");
}
else {
flagstatus = " ";
}
else if (gametype == GT_HARVESTER) {
if (BotHarvesterCarryingCubes(bs)) {
if (BotTeam(bs) == TEAM_RED) Com_sprintf(flagstatus, sizeof(flagstatus), S_COLOR_RED"%2d", bs->inventory[INVENTORY_REDCUBE]);
else Com_sprintf(flagstatus, sizeof(flagstatus), S_COLOR_BLUE"%2d", bs->inventory[INVENTORY_BLUECUBE]);
}
}
#endif
switch(bs->ltgtype) {
case LTG_TEAMHELP:
{
@ -363,16 +317,6 @@ void BotReportStatus(bot_state_t *bs) {
BotAI_Print(PRT_MESSAGE, "%-20s%s%s: returning flag\n", netname, leader, flagstatus);
break;
}
case LTG_ATTACKENEMYBASE:
{
BotAI_Print(PRT_MESSAGE, "%-20s%s%s: attacking the enemy base\n", netname, leader, flagstatus);
break;
}
case LTG_HARVEST:
{
BotAI_Print(PRT_MESSAGE, "%-20s%s%s: harvesting\n", netname, leader, flagstatus);
break;
}
default:
{
BotAI_Print(PRT_MESSAGE, "%-20s%s%s: roaming\n", netname, leader, flagstatus);
@ -418,146 +362,6 @@ void BotTeamplayReport(void) {
}
}
/*
==================
BotSetInfoConfigString
==================
*/
void BotSetInfoConfigString(bot_state_t *bs) {
char goalname[MAX_MESSAGE_SIZE];
char netname[MAX_MESSAGE_SIZE];
char action[MAX_MESSAGE_SIZE];
char *leader, carrying[32], *cs;
bot_goal_t goal;
//
ClientName(bs->client, netname, sizeof(netname));
if (Q_stricmp(netname, bs->teamleader) == 0) leader = "L";
else leader = " ";
strcpy(carrying, " ");
if (gametype == GT_CTF) {
if (BotCTFCarryingFlag(bs)) {
strcpy(carrying, "F ");
}
}
#ifdef MISSIONPACK
else if (gametype == GT_1FCTF) {
if (Bot1FCTFCarryingFlag(bs)) {
strcpy(carrying, "F ");
}
}
else if (gametype == GT_HARVESTER) {
if (BotHarvesterCarryingCubes(bs)) {
if (BotTeam(bs) == TEAM_RED) Com_sprintf(carrying, sizeof(carrying), "%2d", bs->inventory[INVENTORY_REDCUBE]);
else Com_sprintf(carrying, sizeof(carrying), "%2d", bs->inventory[INVENTORY_BLUECUBE]);
}
}
#endif
switch(bs->ltgtype) {
case LTG_TEAMHELP:
{
EasyClientName(bs->teammate, goalname, sizeof(goalname));
Com_sprintf(action, sizeof(action), "helping %s", goalname);
break;
}
case LTG_TEAMACCOMPANY:
{
EasyClientName(bs->teammate, goalname, sizeof(goalname));
Com_sprintf(action, sizeof(action), "accompanying %s", goalname);
break;
}
case LTG_DEFENDKEYAREA:
{
trap_BotGoalName(bs->teamgoal.number, goalname, sizeof(goalname));
Com_sprintf(action, sizeof(action), "defending %s", goalname);
break;
}
case LTG_GETITEM:
{
trap_BotGoalName(bs->teamgoal.number, goalname, sizeof(goalname));
Com_sprintf(action, sizeof(action), "getting item %s", goalname);
break;
}
case LTG_KILL:
{
ClientName(bs->teamgoal.entitynum, goalname, sizeof(goalname));
Com_sprintf(action, sizeof(action), "killing %s", goalname);
break;
}
case LTG_CAMP:
case LTG_CAMPORDER:
{
Com_sprintf(action, sizeof(action), "camping");
break;
}
case LTG_PATROL:
{
Com_sprintf(action, sizeof(action), "patrolling");
break;
}
case LTG_GETFLAG:
{
Com_sprintf(action, sizeof(action), "capturing flag");
break;
}
case LTG_RUSHBASE:
{
Com_sprintf(action, sizeof(action), "rushing base");
break;
}
case LTG_RETURNFLAG:
{
Com_sprintf(action, sizeof(action), "returning flag");
break;
}
case LTG_ATTACKENEMYBASE:
{
Com_sprintf(action, sizeof(action), "attacking the enemy base");
break;
}
case LTG_HARVEST:
{
Com_sprintf(action, sizeof(action), "harvesting");
break;
}
default:
{
trap_BotGetTopGoal(bs->gs, &goal);
trap_BotGoalName(goal.number, goalname, sizeof(goalname));
Com_sprintf(action, sizeof(action), "roaming %s", goalname);
break;
}
}
cs = va("l\\%s\\c\\%s\\a\\%s",
leader,
carrying,
action);
trap_SetConfigstring (CS_BOTINFO + bs->client, cs);
}
/*
==============
BotUpdateInfoConfigStrings
==============
*/
void BotUpdateInfoConfigStrings(void) {
int i;
char buf[MAX_INFO_STRING];
for (i = 0; i < maxclients && i < MAX_CLIENTS; i++) {
//
if ( !botstates[i] || !botstates[i]->inuse )
continue;
//
trap_GetConfigstring(CS_PLAYERS+i, buf, sizeof(buf));
//if no config string or no name
if (!strlen(buf) || !strlen(Info_ValueForKey(buf, "n")))
continue;
BotSetInfoConfigString(botstates[i]);
}
}
/*
==============
BotInterbreedBots
@ -663,7 +467,7 @@ void BotInterbreeding(void) {
//shutdown all the bots
for (i = 0; i < MAX_CLIENTS; i++) {
if (botstates[i] && botstates[i]->inuse) {
BotAIShutdownClient(botstates[i]->client, qfalse);
BotAIShutdownClient(botstates[i]->client);
}
}
//make sure all item weight configs are reloaded and Not shared
@ -761,48 +565,25 @@ BotChangeViewAngles
==============
*/
void BotChangeViewAngles(bot_state_t *bs, float thinktime) {
float diff, factor, maxchange, anglespeed, disired_speed;
float diff, factor, maxchange, anglespeed;
int i;
if (bs->ideal_viewangles[PITCH] > 180) bs->ideal_viewangles[PITCH] -= 360;
//
if (bs->enemy >= 0) {
factor = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_VIEW_FACTOR, 0.01f, 1);
maxchange = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_VIEW_MAXCHANGE, 1, 1800);
}
else {
factor = 0.05f;
maxchange = 360;
}
if (maxchange < 240) maxchange = 240;
factor = 1;
maxchange = 1800;
maxchange *= thinktime;
for (i = 0; i < 2; i++) {
//
if (bot_challenge.integer) {
//smooth slowdown view model
diff = abs(AngleDifference(bs->viewangles[i], bs->ideal_viewangles[i]));
anglespeed = diff * factor;
if (anglespeed > maxchange) anglespeed = maxchange;
bs->viewangles[i] = BotChangeViewAngle(bs->viewangles[i],
bs->ideal_viewangles[i], anglespeed);
}
else {
//over reaction view model
bs->viewangles[i] = AngleMod(bs->viewangles[i]);
bs->ideal_viewangles[i] = AngleMod(bs->ideal_viewangles[i]);
diff = AngleDifference(bs->viewangles[i], bs->ideal_viewangles[i]);
disired_speed = diff * factor;
bs->viewanglespeed[i] += (bs->viewanglespeed[i] - disired_speed);
if (bs->viewanglespeed[i] > 180) bs->viewanglespeed[i] = maxchange;
if (bs->viewanglespeed[i] < -180) bs->viewanglespeed[i] = -maxchange;
anglespeed = bs->viewanglespeed[i];
if (anglespeed > maxchange) anglespeed = maxchange;
if (anglespeed < -maxchange) anglespeed = -maxchange;
bs->viewangles[i] += anglespeed;
bs->viewangles[i] = AngleMod(bs->viewangles[i]);
//demping
bs->viewanglespeed[i] *= 0.45 * (1 - factor);
for (i = 0; i < 2; i++)
{
//smooth slowdown view model
diff = abs(AngleDifference(bs->viewangles[i], bs->ideal_viewangles[i]));
anglespeed = diff * factor;
if (anglespeed > maxchange)
{
anglespeed = maxchange;
}
bs->viewangles[i] = BotChangeViewAngle(bs->viewangles[i], bs->ideal_viewangles[i], anglespeed);
//BotAI_Print(PRT_MESSAGE, "ideal_angles %f %f\n", bs->ideal_viewangles[0], bs->ideal_viewangles[1], bs->ideal_viewangles[2]);`
//bs->viewangles[i] = bs->ideal_viewangles[i];
}
@ -821,10 +602,11 @@ void BotInputToUserCommand(bot_input_t *bi, usercmd_t *ucmd, int delta_angles[3]
vec3_t angles, forward, right;
short temp;
int j;
float f, r, u, m;
//clear the whole structure
memset(ucmd, 0, sizeof(usercmd_t));
//
//Com_Printf("dir = %f %f %f speed = %f\n", bi->dir[0], bi->dir[1], bi->dir[2], bi->speed);
//the duration for the user command in milli seconds
ucmd->serverTime = time;
//
@ -839,13 +621,11 @@ void BotInputToUserCommand(bot_input_t *bi, usercmd_t *ucmd, int delta_angles[3]
if (bi->actionflags & ACTION_GESTURE) ucmd->buttons |= BUTTON_GESTURE;
if (bi->actionflags & ACTION_USE) ucmd->buttons |= BUTTON_USE_HOLDABLE;
if (bi->actionflags & ACTION_WALK) ucmd->buttons |= BUTTON_WALKING;
if (bi->actionflags & ACTION_AFFIRMATIVE) ucmd->buttons |= BUTTON_AFFIRMATIVE;
if (bi->actionflags & ACTION_NEGATIVE) ucmd->buttons |= BUTTON_NEGATIVE;
if (bi->actionflags & ACTION_GETFLAG) ucmd->buttons |= BUTTON_GETFLAG;
if (bi->actionflags & ACTION_GUARDBASE) ucmd->buttons |= BUTTON_GUARDBASE;
if (bi->actionflags & ACTION_PATROL) ucmd->buttons |= BUTTON_PATROL;
if (bi->actionflags & ACTION_FOLLOWME) ucmd->buttons |= BUTTON_FOLLOWME;
//
if (bi->actionflags & ACTION_ALT_ATTACK)
{
ucmd->buttons |= BUTTON_ALT_ATTACK;
}
ucmd->weapon = bi->weapon;
//set the view angles
//NOTE: the ucmd->angles are the angles WITHOUT the delta angles
@ -875,37 +655,21 @@ void BotInputToUserCommand(bot_input_t *bi, usercmd_t *ucmd, int delta_angles[3]
//bot input speed is in the range [0, 400]
bi->speed = bi->speed * 127 / 400;
//set the view independent movement
f = DotProduct(forward, bi->dir);
r = DotProduct(right, bi->dir);
u = abs(forward[2]) * bi->dir[2];
m = fabs(f);
if (fabs(r) > m) {
m = fabs(r);
}
if (fabs(u) > m) {
m = fabs(u);
}
if (m > 0) {
f *= bi->speed / m;
r *= bi->speed / m;
u *= bi->speed / m;
}
ucmd->forwardmove = f;
ucmd->rightmove = r;
ucmd->upmove = u;
if (bi->actionflags & ACTION_MOVEFORWARD) ucmd->forwardmove = 127;
if (bi->actionflags & ACTION_MOVEBACK) ucmd->forwardmove = -127;
if (bi->actionflags & ACTION_MOVELEFT) ucmd->rightmove = -127;
if (bi->actionflags & ACTION_MOVERIGHT) ucmd->rightmove = 127;
ucmd->forwardmove = DotProduct(forward, bi->dir) * bi->speed;
ucmd->rightmove = DotProduct(right, bi->dir) * bi->speed;
ucmd->upmove = abs(forward[2]) * bi->dir[2] * bi->speed;
//normal keyboard movement
if (bi->actionflags & ACTION_MOVEFORWARD) ucmd->forwardmove += 127;
if (bi->actionflags & ACTION_MOVEBACK) ucmd->forwardmove -= 127;
if (bi->actionflags & ACTION_MOVELEFT) ucmd->rightmove -= 127;
if (bi->actionflags & ACTION_MOVERIGHT) ucmd->rightmove += 127;
//jump/moveup
if (bi->actionflags & ACTION_JUMP) ucmd->upmove = 127;
if (bi->actionflags & ACTION_JUMP) ucmd->upmove += 127;
//crouch/movedown
if (bi->actionflags & ACTION_CROUCH) ucmd->upmove = -127;
if (bi->actionflags & ACTION_CROUCH) ucmd->upmove -= 127;
//
//Com_Printf("forward = %d right = %d up = %d\n", ucmd.forwardmove, ucmd.rightmove, ucmd.upmove);
//Com_Printf("ucmd->serverTime = %d\n", ucmd->serverTime);
}
/*
@ -943,33 +707,12 @@ BotAIRegularUpdate
==============
*/
void BotAIRegularUpdate(void) {
if (regularupdate_time < FloatTime()) {
if (regularupdate_time < trap_AAS_Time()) {
trap_BotUpdateEntityItems();
regularupdate_time = FloatTime() + 0.3;
regularupdate_time = trap_AAS_Time() + 0.3;
}
}
/*
==============
RemoveColorEscapeSequences
==============
*/
void RemoveColorEscapeSequences( char *text ) {
int i, l;
l = 0;
for ( i = 0; text[i]; i++ ) {
if (Q_IsColorString(&text[i])) {
i++;
continue;
}
if (text[i] > 0x7E)
continue;
text[l++] = text[i];
}
text[l] = '\0';
}
/*
==============
BotAI
@ -991,15 +734,15 @@ int BotAI(int client, float thinktime) {
//retrieve the current client state
BotAI_GetClientState( client, &bs->cur_ps );
//retrieve any waiting server commands
while( trap_BotGetServerCommand(client, buf, sizeof(buf)) ) {
//retrieve any waiting console messages
while( trap_BotGetConsoleMessage(client, buf, sizeof(buf)) ) {
//have buf point to the command and args to the command arguments
args = strchr( buf, ' ');
if (!args) continue;
*args++ = '\0';
//remove color espace sequences from the arguments
RemoveColorEscapeSequences( args );
Q_CleanStr( args );
if (!Q_stricmp(buf, "cp "))
{ /*CenterPrintf*/ }
@ -1023,17 +766,6 @@ int BotAI(int client, float thinktime) {
args[strlen(args)-1] = '\0';
trap_BotQueueConsoleMessage(bs->cs, CMS_CHAT, args);
}
#ifdef MISSIONPACK
else if (!Q_stricmp(buf, "vchat")) {
BotVoiceChatCommand(bs, SAY_ALL, args);
}
else if (!Q_stricmp(buf, "vtchat")) {
BotVoiceChatCommand(bs, SAY_TEAM, args);
}
else if (!Q_stricmp(buf, "vtell")) {
BotVoiceChatCommand(bs, SAY_TELL, args);
}
#endif
else if (!Q_stricmp(buf, "scores"))
{ /*FIXME: parse scores?*/ }
else if (!Q_stricmp(buf, "clientLevelShot"))
@ -1086,94 +818,21 @@ void BotScheduleBotThink(void) {
}
}
/*
==============
BotWriteSessionData
==============
*/
void BotWriteSessionData(bot_state_t *bs) {
const char *s;
const char *var;
s = va(
"%i %i %i %i %i %i %i %i"
" %f %f %f"
" %f %f %f"
" %f %f %f",
bs->lastgoal_decisionmaker,
bs->lastgoal_ltgtype,
bs->lastgoal_teammate,
bs->lastgoal_teamgoal.areanum,
bs->lastgoal_teamgoal.entitynum,
bs->lastgoal_teamgoal.flags,
bs->lastgoal_teamgoal.iteminfo,
bs->lastgoal_teamgoal.number,
bs->lastgoal_teamgoal.origin[0],
bs->lastgoal_teamgoal.origin[1],
bs->lastgoal_teamgoal.origin[2],
bs->lastgoal_teamgoal.mins[0],
bs->lastgoal_teamgoal.mins[1],
bs->lastgoal_teamgoal.mins[2],
bs->lastgoal_teamgoal.maxs[0],
bs->lastgoal_teamgoal.maxs[1],
bs->lastgoal_teamgoal.maxs[2]
);
var = va( "botsession%i", bs->client );
trap_Cvar_Set( var, s );
}
/*
==============
BotReadSessionData
==============
*/
void BotReadSessionData(bot_state_t *bs) {
char s[MAX_STRING_CHARS];
const char *var;
var = va( "botsession%i", bs->client );
trap_Cvar_VariableStringBuffer( var, s, sizeof(s) );
sscanf(s,
"%i %i %i %i %i %i %i %i"
" %f %f %f"
" %f %f %f"
" %f %f %f",
&bs->lastgoal_decisionmaker,
&bs->lastgoal_ltgtype,
&bs->lastgoal_teammate,
&bs->lastgoal_teamgoal.areanum,
&bs->lastgoal_teamgoal.entitynum,
&bs->lastgoal_teamgoal.flags,
&bs->lastgoal_teamgoal.iteminfo,
&bs->lastgoal_teamgoal.number,
&bs->lastgoal_teamgoal.origin[0],
&bs->lastgoal_teamgoal.origin[1],
&bs->lastgoal_teamgoal.origin[2],
&bs->lastgoal_teamgoal.mins[0],
&bs->lastgoal_teamgoal.mins[1],
&bs->lastgoal_teamgoal.mins[2],
&bs->lastgoal_teamgoal.maxs[0],
&bs->lastgoal_teamgoal.maxs[1],
&bs->lastgoal_teamgoal.maxs[2]
);
}
/*
==============
BotAISetupClient
==============
*/
int BotAISetupClient(int client, struct bot_settings_s *settings, qboolean restart) {
char filename[MAX_PATH], name[MAX_PATH], gender[MAX_PATH];
int BotAISetupClient(int client, struct bot_settings_s *settings) {
char filename[AI_MAX_PATH], name[AI_MAX_PATH], gender[AI_MAX_PATH];
bot_state_t *bs;
int errnum;
if (!botstates[client]) botstates[client] = G_Alloc(sizeof(bot_state_t));
bs = botstates[client];
if(!bs) return qfalse;
if (bs && bs->inuse) {
BotAI_Print(PRT_FATAL, "BotAISetupClient: client %d already setup\n", client);
return qfalse;
@ -1187,7 +846,7 @@ int BotAISetupClient(int client, struct bot_settings_s *settings, qboolean resta
//load the bot character
bs->character = trap_BotLoadCharacter(settings->characterfile, settings->skill);
if (!bs->character) {
BotAI_Print(PRT_FATAL, "couldn't load skill %f from %s\n", settings->skill, settings->characterfile);
BotAI_Print(PRT_FATAL, "couldn't load skill %d from %s\n", settings->skill, settings->characterfile);
return qfalse;
}
//copy the settings
@ -1195,7 +854,7 @@ int BotAISetupClient(int client, struct bot_settings_s *settings, qboolean resta
//allocate a goal state
bs->gs = trap_BotAllocGoalState(client);
//load the item weights
trap_Characteristic_String(bs->character, CHARACTERISTIC_ITEMWEIGHTS, filename, MAX_PATH);
trap_Characteristic_String(bs->character, CHARACTERISTIC_ITEMWEIGHTS, filename, AI_MAX_PATH);
errnum = trap_BotLoadItemWeights(bs->gs, filename);
if (errnum != BLERR_NOERROR) {
trap_BotFreeGoalState(bs->gs);
@ -1204,7 +863,7 @@ int BotAISetupClient(int client, struct bot_settings_s *settings, qboolean resta
//allocate a weapon state
bs->ws = trap_BotAllocWeaponState();
//load the weapon weights
trap_Characteristic_String(bs->character, CHARACTERISTIC_WEAPONWEIGHTS, filename, MAX_PATH);
trap_Characteristic_String(bs->character, CHARACTERISTIC_WEAPONWEIGHTS, filename, AI_MAX_PATH);
errnum = trap_BotLoadWeaponWeights(bs->ws, filename);
if (errnum != BLERR_NOERROR) {
trap_BotFreeGoalState(bs->gs);
@ -1214,8 +873,8 @@ int BotAISetupClient(int client, struct bot_settings_s *settings, qboolean resta
//allocate a chat state
bs->cs = trap_BotAllocChatState();
//load the chat file
trap_Characteristic_String(bs->character, CHARACTERISTIC_CHAT_FILE, filename, MAX_PATH);
trap_Characteristic_String(bs->character, CHARACTERISTIC_CHAT_NAME, name, MAX_PATH);
trap_Characteristic_String(bs->character, CHARACTERISTIC_CHAT_FILE, filename, AI_MAX_PATH);
trap_Characteristic_String(bs->character, CHARACTERISTIC_CHAT_NAME, name, AI_MAX_PATH);
errnum = trap_BotLoadChatFile(bs->cs, filename, name);
if (errnum != BLERR_NOERROR) {
trap_BotFreeChatState(bs->cs);
@ -1224,7 +883,7 @@ int BotAISetupClient(int client, struct bot_settings_s *settings, qboolean resta
return qfalse;
}
//get the gender characteristic
trap_Characteristic_String(bs->character, CHARACTERISTIC_GENDER, gender, MAX_PATH);
trap_Characteristic_String(bs->character, CHARACTERISTIC_GENDER, gender, AI_MAX_PATH);
//set the chat gender
if (*gender == 'f' || *gender == 'F') trap_BotSetChatGender(bs->cs, CHAT_GENDERFEMALE);
else if (*gender == 'm' || *gender == 'M') trap_BotSetChatGender(bs->cs, CHAT_GENDERMALE);
@ -1234,9 +893,9 @@ int BotAISetupClient(int client, struct bot_settings_s *settings, qboolean resta
bs->client = client;
bs->entitynum = client;
bs->setupcount = 4;
bs->entergame_time = FloatTime();
bs->entergame_time = trap_AAS_Time();
bs->ms = trap_BotAllocMoveState();
bs->walker = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_WALKER, 0, 1);
bs->walker = 0;
numbots++;
if (trap_Cvar_VariableIntegerValue("bot_testichat")) {
@ -1249,10 +908,6 @@ int BotAISetupClient(int client, struct bot_settings_s *settings, qboolean resta
if (bot_interbreed) {
trap_BotMutateGoalFuzzyLogic(bs->gs, 1);
}
// if we kept the bot client
if (restart) {
BotReadSessionData(bs);
}
//bot has been setup succesfully
return qtrue;
}
@ -1262,7 +917,7 @@ int BotAISetupClient(int client, struct bot_settings_s *settings, qboolean resta
BotAIShutdownClient
==============
*/
int BotAIShutdownClient(int client, qboolean restart) {
int BotAIShutdownClient(int client) {
bot_state_t *bs;
bs = botstates[client];
@ -1271,10 +926,6 @@ int BotAIShutdownClient(int client, qboolean restart) {
return qfalse;
}
if (restart) {
BotWriteSessionData(bs);
}
if (BotChat_ExitGame(bs)) {
trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
}
@ -1291,8 +942,6 @@ int BotAIShutdownClient(int client, qboolean restart) {
//
BotFreeWaypoints(bs->checkpoints);
BotFreeWaypoints(bs->patrolpoints);
//clear activate goal stack
BotClearActivateGoalStack(bs);
//clear the bot state
memset(bs, 0, sizeof(bot_state_t));
//set the inuse flag to qfalse
@ -1382,10 +1031,6 @@ int BotAILoadMap( int restart ) {
return qtrue;
}
#ifdef MISSIONPACK
void ProximityMine_Trigger( gentity_t *trigger, gentity_t *other, trace_t *trace );
#endif
/*
==================
BotAIStartFrame
@ -1409,14 +1054,12 @@ int BotAIStartFrame(int time) {
trap_Cvar_Update(&bot_testrchat);
trap_Cvar_Update(&bot_thinktime);
trap_Cvar_Update(&bot_memorydump);
trap_Cvar_Update(&bot_saveroutingcache);
trap_Cvar_Update(&bot_pause);
trap_Cvar_Update(&bot_report);
if (bot_report.integer) {
// BotTeamplayReport();
// trap_Cvar_Set("bot_report", "0");
BotUpdateInfoConfigStrings();
BotTeamplayReport();
trap_Cvar_Set("bot_report", "0");
}
if (bot_pause.integer) {
@ -1442,10 +1085,6 @@ int BotAIStartFrame(int time) {
trap_BotLibVarSet("memorydump", "1");
trap_Cvar_Set("bot_memorydump", "0");
}
if (bot_saveroutingcache.integer) {
trap_BotLibVarSet("saveroutingcache", "1");
trap_Cvar_Set("bot_saveroutingcache", "0");
}
//check if bot interbreeding is activated
BotInterbreeding();
//cap the bot think time
@ -1490,7 +1129,7 @@ int BotAIStartFrame(int time) {
continue;
}
// do not update missiles
if (ent->s.eType == ET_MISSILE && ent->s.weapon != WP_GRAPPLING_HOOK) {
if (ent->s.eType == ET_MISSILE) {
trap_BotLibUpdateEntity(i, NULL);
continue;
}
@ -1499,15 +1138,6 @@ int BotAIStartFrame(int time) {
trap_BotLibUpdateEntity(i, NULL);
continue;
}
#ifdef MISSIONPACK
// never link prox mine triggers
if (ent->r.contents == CONTENTS_TRIGGER) {
if (ent->touch == ProximityMine_Trigger) {
trap_BotLibUpdateEntity(i, NULL);
continue;
}
}
#endif
//
memset(&state, 0, sizeof(bot_entitystate_t));
//
@ -1541,8 +1171,6 @@ int BotAIStartFrame(int time) {
BotAIRegularUpdate();
}
floattime = trap_AAS_Time();
// execute scheduled bot AI
for( i = 0; i < MAX_CLIENTS; i++ ) {
if( !botstates[i] || !botstates[i]->inuse ) {
@ -1585,7 +1213,8 @@ BotInitLibrary
==============
*/
int BotInitLibrary(void) {
char buf[144];
int gt;
char buf[144];
//set the maxclients and maxentities library variables before calling BotSetupLibrary
trap_Cvar_VariableStringBuffer("sv_maxclients", buf, sizeof(buf));
@ -1603,16 +1232,25 @@ int BotInitLibrary(void) {
trap_Cvar_VariableStringBuffer("max_levelitems", buf, sizeof(buf));
if (strlen(buf)) trap_BotLibVarSet("max_levelitems", buf);
//game type
trap_Cvar_VariableStringBuffer("g_gametype", buf, sizeof(buf));
if (!strlen(buf)) strcpy(buf, "0");
trap_BotLibVarSet("g_gametype", buf);
gt = trap_Cvar_VariableIntegerValue("g_gametype");
if( gt == GT_SINGLE_PLAYER ) {
gt = AIGT_SINGLE_PLAYER;
}
else if( gt >= GT_TEAM ) {
gt = AIGT_TEAM;
}
else {
gt = AIGT_OTHER;
}
trap_BotLibVarSet("ai_gametype", va("%i", gt));
//bot developer mode and log file
trap_BotLibVarSet("bot_developer", bot_developer.string);
trap_Cvar_VariableStringBuffer("logfile", buf, sizeof(buf));
trap_Cvar_VariableStringBuffer("bot_developer", buf, sizeof(buf));
if (!strlen(buf)) strcpy(buf, "0");
trap_BotLibVarSet("bot_developer", buf);
trap_BotLibVarSet("log", buf);
//no chatting
trap_Cvar_VariableStringBuffer("bot_nochat", buf, sizeof(buf));
if (strlen(buf)) trap_BotLibVarSet("nochat", buf);
if (strlen(buf)) trap_BotLibVarSet("nochat", "0");
//visualize jump pads
trap_Cvar_VariableStringBuffer("bot_visualizejumppads", buf, sizeof(buf));
if (strlen(buf)) trap_BotLibVarSet("bot_visualizejumppads", buf);
@ -1628,9 +1266,6 @@ int BotInitLibrary(void) {
//no AAS optimization
trap_Cvar_VariableStringBuffer("bot_aasoptimize", buf, sizeof(buf));
if (strlen(buf)) trap_BotLibVarSet("aasoptimize", buf);
//
trap_Cvar_VariableStringBuffer("bot_saveroutingcache", buf, sizeof(buf));
if (strlen(buf)) trap_BotLibVarSet("saveroutingcache", buf);
//reload instead of cache bot character files
trap_Cvar_VariableStringBuffer("bot_reloadcharacters", buf, sizeof(buf));
if (!strlen(buf)) strcpy(buf, "0");
@ -1641,13 +1276,9 @@ int BotInitLibrary(void) {
//game directory
trap_Cvar_VariableStringBuffer("fs_game", buf, sizeof(buf));
if (strlen(buf)) trap_BotLibVarSet("gamedir", buf);
//home directory
trap_Cvar_VariableStringBuffer("fs_homepath", buf, sizeof(buf));
if (strlen(buf)) trap_BotLibVarSet("homedir", buf);
//
#ifdef MISSIONPACK
trap_BotLibDefine("MISSIONPACK");
#endif
//cd directory
trap_Cvar_VariableStringBuffer("fs_cdpath", buf, sizeof(buf));
if (strlen(buf)) trap_BotLibVarSet("cddir", buf);
//setup the bot library
return trap_BotLibSetup();
}
@ -1660,14 +1291,17 @@ BotAISetup
int BotAISetup( int restart ) {
int errnum;
#ifdef RANDOMIZE
srand((unsigned)time(NULL));
#endif //RANDOMIZE
bot_setupComplete = qtrue;
trap_Cvar_Register(&bot_thinktime, "bot_thinktime", "100", CVAR_CHEAT);
trap_Cvar_Register(&bot_memorydump, "bot_memorydump", "0", CVAR_CHEAT);
trap_Cvar_Register(&bot_saveroutingcache, "bot_saveroutingcache", "0", CVAR_CHEAT);
trap_Cvar_Register(&bot_pause, "bot_pause", "0", CVAR_CHEAT);
trap_Cvar_Register(&bot_report, "bot_report", "0", CVAR_CHEAT);
trap_Cvar_Register(&bot_testsolid, "bot_testsolid", "0", CVAR_CHEAT);
trap_Cvar_Register(&bot_testclusters, "bot_testclusters", "0", CVAR_CHEAT);
trap_Cvar_Register(&bot_developer, "bot_developer", "0", CVAR_CHEAT);
trap_Cvar_Register(&bot_interbreedchar, "bot_interbreedchar", "", 0);
trap_Cvar_Register(&bot_interbreedbots, "bot_interbreedbots", "10", 0);
trap_Cvar_Register(&bot_interbreedcycle, "bot_interbreedcycle", "20", 0);
@ -1700,7 +1334,7 @@ int BotAIShutdown( int restart ) {
//shutdown all the bots in the botlib
for (i = 0; i < MAX_CLIENTS; i++) {
if (botstates[i] && botstates[i]->inuse) {
BotAIShutdownClient(botstates[i]->client, restart);
BotAIShutdownClient(botstates[i]->client);
}
}
//don't shutdown the bot library

View file

@ -1,24 +1,4 @@
/*
===========================================================================
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
===========================================================================
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
@ -26,7 +6,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* desc: Quake3 bot AI
*
* $Archive: /source/code/botai/ai_chat.c $
* $Archive: /StarTrek/Code-DM/game/ai_main.h $
* $Author: Jmonroe $
* $Revision: 1 $
* $Modtime: 1/21/00 10:12p $
* $Date: 1/25/00 6:26p $
*
*****************************************************************************/
@ -35,61 +19,53 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define MAX_ITEMS 256
//bot flags
#define BFL_STRAFERIGHT 1 //strafe to the right
#define BFL_ATTACKED 2 //bot has attacked last ai frame
#define BFL_ATTACKJUMPED 4 //bot jumped during attack last frame
#define BFL_AIMATENEMY 8 //bot aimed at the enemy this frame
#define BFL_AVOIDRIGHT 16 //avoid obstacles by going to the right
#define BFL_IDEALVIEWSET 32 //bot has ideal view angles set
#define BFL_FIGHTSUICIDAL 64 //bot is in a suicidal fight
#define BFL_STRAFERIGHT 1 //!<strafe to the right
#define BFL_ATTACKED 2 //!<bot has attacked last ai frame
#define BFL_ATTACKJUMPED 4 //!<bot jumped during attack last frame
#define BFL_AIMATENEMY 8 //!<bot aimed at the enemy this frame
#define BFL_AVOIDRIGHT 16 //!<avoid obstacles by going to the right
#define BFL_IDEALVIEWSET 32 //!<bot has ideal view angles set
#define BFL_FIGHTSUICIDAL 64 //!<bot is in a suicidal fight
//long term goal types
#define LTG_TEAMHELP 1 //help a team mate
#define LTG_TEAMACCOMPANY 2 //accompany a team mate
#define LTG_DEFENDKEYAREA 3 //defend a key area
#define LTG_GETFLAG 4 //get the enemy flag
#define LTG_RUSHBASE 5 //rush to the base
#define LTG_RETURNFLAG 6 //return the flag
#define LTG_CAMP 7 //camp somewhere
#define LTG_CAMPORDER 8 //ordered to camp somewhere
#define LTG_PATROL 9 //patrol
#define LTG_GETITEM 10 //get an item
#define LTG_KILL 11 //kill someone
#define LTG_HARVEST 12 //harvest skulls
#define LTG_ATTACKENEMYBASE 13 //attack the enemy base
#define LTG_MAKELOVE_UNDER 14
#define LTG_MAKELOVE_ONTOP 15
#define LTG_TEAMHELP 1 //!<help a team mate
#define LTG_TEAMACCOMPANY 2 //!<accompany a team mate
#define LTG_DEFENDKEYAREA 3 //!<defend a key area
#define LTG_GETFLAG 4 //!<get the enemy flag
#define LTG_RUSHBASE 5 //!<rush to the base
#define LTG_RETURNFLAG 6 //!<return the flag
#define LTG_CAMP 7 //!<camp somewhere
#define LTG_CAMPORDER 8 //!<ordered to camp somewhere
#define LTG_PATROL 9 //!<patrol
#define LTG_GETITEM 10 //!<get an item
#define LTG_KILL 11 //!<kill someone
//some goal dedication times
#define TEAM_HELP_TIME 60 //1 minute teamplay help time
#define TEAM_ACCOMPANY_TIME 600 //10 minutes teamplay accompany time
#define TEAM_DEFENDKEYAREA_TIME 600 //10 minutes ctf defend base time
#define TEAM_CAMP_TIME 600 //10 minutes camping time
#define TEAM_PATROL_TIME 600 //10 minutes patrolling time
#define TEAM_LEAD_TIME 600 //10 minutes taking the lead
#define TEAM_GETITEM_TIME 60 //1 minute
#define TEAM_KILL_SOMEONE 180 //3 minute to kill someone
#define TEAM_ATTACKENEMYBASE_TIME 600 //10 minutes
#define TEAM_HARVEST_TIME 120 //2 minutes
#define CTF_GETFLAG_TIME 600 //10 minutes ctf get flag time
#define CTF_RUSHBASE_TIME 120 //2 minutes ctf rush base time
#define CTF_RETURNFLAG_TIME 180 //3 minutes to return the flag
#define CTF_ROAM_TIME 60 //1 minute ctf roam time
#define TEAM_HELP_TIME 10 //!<1 minute teamplay help time
#define TEAM_ACCOMPANY_TIME 10 //!<10 minutes teamplay accompany time
#define TEAM_DEFENDKEYAREA_TIME 600 //!<5 minutes ctf defend base time
#define TEAM_CAMP_TIME 10 //!<10 minutes camping time
#define TEAM_PATROL_TIME 600 //!<10 minutes patrolling time
#define TEAM_LEAD_TIME 600 //!<10 minutes taking the lead
#define TEAM_GETITEM_TIME 10 //!<1 minute
#define TEAM_KILL_SOMEONE 10 //!<3 minute to kill someone
#define CTF_GETFLAG_TIME 600 //!<5 minutes ctf get flag time
#define CTF_RUSHBASE_TIME 600 //!<2 minutes ctf rush base time
#define CTF_RETURNFLAG_TIME 600 //!<3 minutes to return the flag
#define CTF_ROAM_TIME 600 //!<1 minute ctf roam time
//patrol flags
#define PATROL_LOOP 1
#define PATROL_REVERSE 2
#define PATROL_BACK 4
//teamplay task preference
#define TEAMTP_DEFENDER 1
#define TEAMTP_ATTACKER 2
//CTF task preference
#define CTFTP_DEFENDER 1
#define CTFTP_ATTACKER 2
//CTF strategy
#define CTFS_AGRESSIVE 1
#define CTFS_PASSIVE 1
//copied from the aas file header
#define PRESENCE_NONE 1
#define PRESENCE_NORMAL 2
#define PRESENCE_CROUCH 4
//
#define MAX_PROXMINES 64
//check points
//!check points
typedef struct bot_waypoint_s
{
int inuse;
@ -98,193 +74,150 @@ typedef struct bot_waypoint_s
struct bot_waypoint_s *next, *prev;
} bot_waypoint_t;
#define MAX_ACTIVATESTACK 8
#define MAX_ACTIVATEAREAS 32
typedef struct bot_activategoal_s
{
int inuse;
bot_goal_t goal; //goal to activate (buttons etc.)
float time; //time to activate something
float start_time; //time starting to activate something
float justused_time; //time the goal was used
int shoot; //true if bot has to shoot to activate
int weapon; //weapon to be used for activation
vec3_t target; //target to shoot at to activate something
vec3_t origin; //origin of the blocking entity to activate
int areas[MAX_ACTIVATEAREAS]; //routing areas disabled by blocking entity
int numareas; //number of disabled routing areas
int areasdisabled; //true if the areas are disabled for the routing
struct bot_activategoal_s *next; //next activate goal on stack
} bot_activategoal_t;
//bot state
//!bot state
typedef struct bot_state_s
{
int inuse; //true if this state is used by a bot client
int botthink_residual; //residual for the bot thinks
int client; //client number of the bot
int entitynum; //entity number of the bot
playerState_t cur_ps; //current player state
int last_eFlags; //last ps flags
usercmd_t lastucmd; //usercmd from last frame
int entityeventTime[MAX_GENTITIES]; //last entity event time
int inuse; //!<true if this state is used by a bot client
int botthink_residual; //!<residual for the bot thinks
int client; //!<client number of the bot
int entitynum; //!<entity number of the bot
playerState_t cur_ps; //!<current player state
int last_eFlags; //!<last ps flags
usercmd_t lastucmd; //!<usercmd from last frame
int entityeventTime[1024]; //!<last entity event time
//
bot_settings_t settings; //several bot settings
int (*ainode)(struct bot_state_s *bs); //current AI node
float thinktime; //time the bot thinks this frame
vec3_t origin; //origin of the bot
vec3_t velocity; //velocity of the bot
int presencetype; //presence type of the bot
vec3_t eye; //eye coordinates of the bot
int areanum; //the number of the area the bot is in
int inventory[MAX_ITEMS]; //string with items amounts the bot has
int tfl; //the travel flags the bot uses
int flags; //several flags
int respawn_wait; //wait until respawned
int lasthealth; //health value previous frame
int lastkilledplayer; //last killed player
int lastkilledby; //player that last killed this bot
int botdeathtype; //the death type of the bot
int enemydeathtype; //the death type of the enemy
int botsuicide; //true when the bot suicides
int enemysuicide; //true when the enemy of the bot suicides
int setupcount; //true when the bot has just been setup
int map_restart; //true when the map is being restarted
int entergamechat; //true when the bot used an enter game chat
int num_deaths; //number of time this bot died
int num_kills; //number of kills of this bot
int revenge_enemy; //the revenge enemy
int revenge_kills; //number of kills the enemy made
int lastframe_health; //health value the last frame
int lasthitcount; //number of hits last frame
int chatto; //chat to all or team
float walker; //walker charactertic
float ltime; //local bot time
float entergame_time; //time the bot entered the game
float ltg_time; //long term goal time
float nbg_time; //nearby goal time
float respawn_time; //time the bot takes to respawn
float respawnchat_time; //time the bot started a chat during respawn
float chase_time; //time the bot will chase the enemy
float enemyvisible_time; //time the enemy was last visible
float check_time; //time to check for nearby items
float stand_time; //time the bot is standing still
float lastchat_time; //time the bot last selected a chat
float kamikaze_time; //time to check for kamikaze usage
float invulnerability_time; //time to check for invulnerability usage
float standfindenemy_time; //time to find enemy while standing
float attackstrafe_time; //time the bot is strafing in one dir
float attackcrouch_time; //time the bot will stop crouching
float attackchase_time; //time the bot chases during actual attack
float attackjump_time; //time the bot jumped during attack
float enemysight_time; //time before reacting to enemy
float enemydeath_time; //time the enemy died
float enemyposition_time; //time the position and velocity of the enemy were stored
float defendaway_time; //time away while defending
float defendaway_range; //max travel time away from defend area
float rushbaseaway_time; //time away from rushing to the base
float attackaway_time; //time away from attacking the enemy base
float harvestaway_time; //time away from harvesting
float ctfroam_time; //time the bot is roaming in ctf
float killedenemy_time; //time the bot killed the enemy
float arrive_time; //time arrived (at companion)
float lastair_time; //last time the bot had air
float teleport_time; //last time the bot teleported
float camp_time; //last time camped
float weaponchange_time; //time the bot started changing weapons
float firethrottlewait_time; //amount of time to wait
float firethrottleshoot_time; //amount of time to shoot
float notblocked_time; //last time the bot was not blocked
float blockedbyavoidspot_time; //time blocked by an avoid spot
float predictobstacles_time; //last time the bot predicted obstacles
int predictobstacles_goalareanum; //last goal areanum the bot predicted obstacles for
bot_settings_t settings; //!<several bot settings
int (*ainode)(struct bot_state_s *bs); //!<current AI node
float thinktime; //!<time the bot thinks this frame
vec3_t origin; //!<origin of the bot
vec3_t velocity; //!<velocity of the bot
int presencetype; //!<presence type of the bot
vec3_t eye; //!<eye coordinates of the bot
int areanum; //!<the number of the area the bot is in
int inventory[MAX_ITEMS]; //!<string with items amounts the bot has
int tfl; //!<the travel flags the bot uses
int flags; //!<several flags
int respawn_wait; //!<wait until respawned
int lasthealth; //!<health value previous frame
int lastkilledplayer; //!<last killed player
int lastkilledby; //!<player that last killed this bot
int botdeathtype; //!<the death type of the bot
int enemydeathtype; //!<the death type of the enemy
int botsuicide; //!<true when the bot suicides
int enemysuicide; //!<true when the enemy of the bot suicides
int setupcount; //!<true when the bot has just been setup
int entergamechat; //!<true when the bot used an enter game chat
int num_deaths; //!<number of time this bot died
int num_kills; //!<number of kills of this bot
int revenge_enemy; //!<the revenge enemy
int revenge_kills; //!<number of kills the enemy made
int lastframe_health; //!<health value the last frame
int lasthitcount; //!<number of hits last frame
int chatto; //!<chat to all or team
float walker; //!<walker charactertic
float ltime; //!<local bot time
float entergame_time; //!<time the bot entered the game
float ltg_time; //!<long term goal time
float nbg_time; //!<nearby goal time
float respawn_time; //!<time the bot takes to respawn
float respawnchat_time; //!<time the bot started a chat during respawn
float chase_time; //!<time the bot will chase the enemy
float enemyvisible_time; //!<time the enemy was last visible
float check_time; //!<time to check for nearby items
float stand_time; //!<time the bot is standing still
float lastchat_time; //!<time the bot last selected a chat
float standfindenemy_time; //!<time to find enemy while standing
float attackstrafe_time; //!<time the bot is strafing in one dir
float attackcrouch_time; //!<time the bot will stop crouching
float attackchase_time; //!<time the bot chases during actual attack
float attackjump_time; //!<time the bot jumped during attack
float enemysight_time; //!<time before reacting to enemy
float enemydeath_time; //!<time the enemy died
float enemyposition_time; //!<time the position and velocity of the enemy were stored
float activate_time; //!<time to activate something
float activatemessage_time; //!<time to show activate message
float defendaway_time; //!<time away while defending
float defendaway_range; //!<max travel time away from defend area
float rushbaseaway_time; //!<time away from rushing to the base
float ctfroam_time; //!<time the bot is roaming in ctf
float killedenemy_time; //!<time the bot killed the enemy
float arrive_time; //!<time arrived (at companion)
float lastair_time; //!<last time the bot had air
float teleport_time; //!<last time the bot teleported
float camp_time; //!<last time camped
float camp_range; //!<camp range
float weaponchange_time; //!<time the bot started changing weapons
float firethrottlewait_time; //!<amount of time to wait
float firethrottleshoot_time; //!<amount of time to shoot
float notblocked_time; //!<last time the bot was not blocked
vec3_t aimtarget;
vec3_t enemyvelocity; //enemy velocity 0.5 secs ago during battle
vec3_t enemyorigin; //enemy origin 0.5 secs ago during battle
vec3_t enemyvelocity; //!<enemy velocity 0.5 secs ago during battle
vec3_t enemyorigin; //!<enemy origin 0.5 secs ago during battle
//
int kamikazebody; //kamikaze body
int proxmines[MAX_PROXMINES];
int numproxmines;
int character; //!<the bot character
int ms; //!<move state of the bot
int gs; //!<goal state of the bot
int cs; //!<chat state of the bot
int ws; //!<weapon state of the bot
//
int character; //the bot character
int ms; //move state of the bot
int gs; //goal state of the bot
int cs; //chat state of the bot
int ws; //weapon state of the bot
//
int enemy; //enemy entity number
int lastenemyareanum; //last reachability area the enemy was in
vec3_t lastenemyorigin; //last origin of the enemy in the reachability area
int weaponnum; //current weapon number
vec3_t viewangles; //current view angles
vec3_t ideal_viewangles; //ideal view angles
int enemy; //!<enemy entity number
int lastenemyareanum; //!<last reachability area the enemy was in
vec3_t lastenemyorigin; //!<last origin of the enemy in the reachability area
int weaponnum; //!<current weapon number
vec3_t viewangles; //!<current view angles
vec3_t ideal_viewangles; //!<ideal view angles
vec3_t viewanglespeed;
//
int ltgtype; //long term goal type
// team goals
int teammate; //team mate involved in this team goal
int decisionmaker; //player who decided to go for this goal
int ordered; //true if ordered to do something
float order_time; //time ordered to do something
int owndecision_time; //time the bot made its own decision
bot_goal_t teamgoal; //the team goal
bot_goal_t altroutegoal; //alternative route goal
float reachedaltroutegoal_time; //time the bot reached the alt route goal
float teammessage_time; //time to message team mates what the bot is doing
float teamgoal_time; //time to stop helping team mate
float teammatevisible_time; //last time the team mate was NOT visible
int teamtaskpreference; //team task preference
// last ordered team goal
int lastgoal_decisionmaker;
int lastgoal_ltgtype;
int lastgoal_teammate;
bot_goal_t lastgoal_teamgoal;
// for leading team mates
int lead_teammate; //team mate the bot is leading
bot_goal_t lead_teamgoal; //team goal while leading
float lead_time; //time leading someone
float leadvisible_time; //last time the team mate was visible
float leadmessage_time; //last time a messaged was sent to the team mate
float leadbackup_time; //time backing up towards team mate
int ltgtype; //!<long term goal type
//
char teamleader[32]; //netname of the team leader
float askteamleader_time; //time asked for team leader
float becometeamleader_time; //time the bot will become the team leader
float teamgiveorders_time; //time to give team orders
float lastflagcapture_time; //last time a flag was captured
int numteammates; //number of team mates
int redflagstatus; //0 = at base, 1 = not at base
int blueflagstatus; //0 = at base, 1 = not at base
int neutralflagstatus; //0 = at base, 1 = our team has flag, 2 = enemy team has flag, 3 = enemy team dropped the flag
int flagstatuschanged; //flag status changed
int forceorders; //true if forced to give orders
int flagcarrier; //team mate carrying the enemy flag
int ctfstrategy; //ctf strategy
char subteam[32]; //sub team name
float formation_dist; //formation team mate intervening space
bot_activategoal_t *activatestack; //first activate goal on the stack
bot_activategoal_t activategoalheap[MAX_ACTIVATESTACK]; //activate goal heap
bot_waypoint_t *checkpoints; //check points
bot_waypoint_t *patrolpoints; //patrol points
bot_waypoint_t *curpatrolpoint; //current patrol point the bot is going for
int patrolflags; //patrol flags
int teammate; //!<team mate
bot_goal_t teamgoal; //!<the team goal
float teammessage_time; //!<time to message team mates what the bot is doing
float teamgoal_time; //!<time to stop helping team mate
float teammatevisible_time; //!<last time the team mate was NOT visible
//
int lead_teammate; //!<team mate the bot is leading
bot_goal_t lead_teamgoal; //!<team goal while leading
float lead_time; //!<time leading someone
float leadvisible_time; //!<last time the team mate was visible
float leadmessage_time; //!<last time a messaged was sent to the team mate
float leadbackup_time; //!<time backing up towards team mate
//
char teamleader[32]; //!<netname of the team leader
float askteamleader_time; //!<time asked for team leader
float becometeamleader_time; //!<time the bot will become the team leader
float teamgiveorders_time; //!<time to give team orders
float lastflagcapture_time; //!<last time a flag was captured
int numteammates; //!<number of team mates
int redflagstatus; //!<0 = at base, 1 = not at base
int blueflagstatus; //!<0 = at base, 1 = not at base
int flagstatuschanged; //!<flag status changed
int forceorders; //!<true if forced to give orders
int flagcarrier; //!<team mate carrying the enemy flag
int ctfstrategy; //!<ctf strategy
char subteam[32]; //!<sub team name
float formation_dist; //!<formation team mate intervening space
char formation_teammate[16]; //!<netname of the team mate the bot uses for relative positioning
float formation_angle; //!<angle relative to the formation team mate
vec3_t formation_dir; //!<the direction the formation is moving in
vec3_t formation_origin; //!<origin the bot uses for relative positioning
bot_goal_t formation_goal; //!<formation goal
bot_goal_t activategoal; //!<goal to activate (buttons etc.)
bot_waypoint_t *checkpoints; //!<check points
bot_waypoint_t *patrolpoints; //!<patrol points
bot_waypoint_t *curpatrolpoint; //!<current patrol point the bot is going for
int patrolflags; //!<patrol flags
} bot_state_t;
//resets the whole bot state
//!resets the whole bot state
void BotResetState(bot_state_t *bs);
//returns the number of bots in the game
//!returns the number of bots in the game
int NumBots(void);
//returns info about the entity
//!returns info about the entity
void BotEntityInfo(int entnum, aas_entityinfo_t *info);
extern float floattime;
#define FloatTime() floattime
// from the game source
void QDECL BotAI_Print(int type, char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
void QDECL BotAI_Print(int type, char *fmt, ...);
void QDECL QDECL BotAI_BotInitialChat( bot_state_t *bs, char *type, ... );
void BotAI_Trace(bsp_trace_t *bsptrace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask);
int BotAI_GetClientState( int clientNum, playerState_t *state );

File diff suppressed because it is too large Load diff

View file

@ -1,24 +1,4 @@
/*
===========================================================================
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
===========================================================================
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
@ -26,14 +6,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* desc: Quake3 bot AI
*
* $Archive: /source/code/botai/ai_chat.c $
* $Archive: /StarTrek/Code-DM/game/ai_team.h $
* $Author: Jmonroe $
* $Revision: 1 $
* $Modtime: 1/21/00 10:12p $
* $Date: 1/25/00 6:26p $
*
*****************************************************************************/
void BotTeamAI(bot_state_t *bs);
int BotGetTeamMateTaskPreference(bot_state_t *bs, int teammate);
void BotSetTeamMateTaskPreference(bot_state_t *bs, int teammate, int preference);
void BotVoiceChat(bot_state_t *bs, int toclient, char *voicechat);
void BotVoiceChatOnly(bot_state_t *bs, int toclient, char *voicechat);
int BotGetTeamMateCTFPreference(bot_state_t *bs, int teammate);
void BotSetTeamMateCTFPreference(bot_state_t *bs, int teammate, int preference);

View file

@ -1,551 +0,0 @@
/*
===========================================================================
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: ai_vcmd.c
*
* desc: Quake3 bot AI
*
* $Archive: /MissionPack/code/game/ai_vcmd.c $
*
*****************************************************************************/
#include "g_local.h"
#include "../botlib/botlib.h"
#include "../botlib/be_aas.h"
#include "../botlib/be_ea.h"
#include "../botlib/be_ai_char.h"
#include "../botlib/be_ai_chat.h"
#include "../botlib/be_ai_gen.h"
#include "../botlib/be_ai_goal.h"
#include "../botlib/be_ai_move.h"
#include "../botlib/be_ai_weap.h"
//
#include "ai_main.h"
#include "ai_dmq3.h"
#include "ai_chat.h"
#include "ai_cmd.h"
#include "ai_dmnet.h"
#include "ai_team.h"
#include "ai_vcmd.h"
//
#include "chars.h" //characteristics
#include "inv.h" //indexes into the inventory
#include "syn.h" //synonyms
#include "match.h" //string matching types and vars
// for the voice chats
#include "../../ui/menudef.h"
typedef struct voiceCommand_s
{
char *cmd;
void (*func)(bot_state_t *bs, int client, int mode);
} voiceCommand_t;
/*
==================
BotVoiceChat_GetFlag
==================
*/
void BotVoiceChat_GetFlag(bot_state_t *bs, int client, int mode) {
//
if (gametype == GT_CTF) {
if (!ctf_redflag.areanum || !ctf_blueflag.areanum)
return;
}
#ifdef MISSIONPACK
else if (gametype == GT_1FCTF) {
if (!ctf_neutralflag.areanum || !ctf_redflag.areanum || !ctf_blueflag.areanum)
return;
}
#endif
else {
return;
}
//
bs->decisionmaker = client;
bs->ordered = qtrue;
bs->order_time = FloatTime();
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//set the ltg type
bs->ltgtype = LTG_GETFLAG;
//set the team goal time
bs->teamgoal_time = FloatTime() + CTF_GETFLAG_TIME;
// get an alternate route in ctf
if (gametype == GT_CTF) {
//get an alternative route goal towards the enemy base
BotGetAlternateRouteGoal(bs, BotOppositeTeam(bs));
}
//
BotSetTeamStatus(bs);
// remember last ordered task
BotRememberLastOrderedTask(bs);
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotVoiceChat_Offense
==================
*/
void BotVoiceChat_Offense(bot_state_t *bs, int client, int mode) {
if ( gametype == GT_CTF
#ifdef MISSIONPACK
|| gametype == GT_1FCTF
#endif
) {
BotVoiceChat_GetFlag(bs, client, mode);
return;
}
#ifdef MISSIONPACK
if (gametype == GT_HARVESTER) {
//
bs->decisionmaker = client;
bs->ordered = qtrue;
bs->order_time = FloatTime();
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//set the ltg type
bs->ltgtype = LTG_HARVEST;
//set the team goal time
bs->teamgoal_time = FloatTime() + TEAM_HARVEST_TIME;
bs->harvestaway_time = 0;
//
BotSetTeamStatus(bs);
// remember last ordered task
BotRememberLastOrderedTask(bs);
}
else
#endif
{
//
bs->decisionmaker = client;
bs->ordered = qtrue;
bs->order_time = FloatTime();
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//set the ltg type
bs->ltgtype = LTG_ATTACKENEMYBASE;
//set the team goal time
bs->teamgoal_time = FloatTime() + TEAM_ATTACKENEMYBASE_TIME;
bs->attackaway_time = 0;
//
BotSetTeamStatus(bs);
// remember last ordered task
BotRememberLastOrderedTask(bs);
}
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotVoiceChat_Defend
==================
*/
void BotVoiceChat_Defend(bot_state_t *bs, int client, int mode) {
#ifdef MISSIONPACK
if ( gametype == GT_OBELISK || gametype == GT_HARVESTER) {
//
switch(BotTeam(bs)) {
case TEAM_RED: memcpy(&bs->teamgoal, &redobelisk, sizeof(bot_goal_t)); break;
case TEAM_BLUE: memcpy(&bs->teamgoal, &blueobelisk, sizeof(bot_goal_t)); break;
default: return;
}
}
else
#endif
if (gametype == GT_CTF
#ifdef MISSIONPACK
|| gametype == GT_1FCTF
#endif
) {
//
switch(BotTeam(bs)) {
case TEAM_RED: memcpy(&bs->teamgoal, &ctf_redflag, sizeof(bot_goal_t)); break;
case TEAM_BLUE: memcpy(&bs->teamgoal, &ctf_blueflag, sizeof(bot_goal_t)); break;
default: return;
}
}
else {
return;
}
//
bs->decisionmaker = client;
bs->ordered = qtrue;
bs->order_time = FloatTime();
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//set the ltg type
bs->ltgtype = LTG_DEFENDKEYAREA;
//get the team goal time
bs->teamgoal_time = FloatTime() + TEAM_DEFENDKEYAREA_TIME;
//away from defending
bs->defendaway_time = 0;
//
BotSetTeamStatus(bs);
// remember last ordered task
BotRememberLastOrderedTask(bs);
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotVoiceChat_DefendFlag
==================
*/
void BotVoiceChat_DefendFlag(bot_state_t *bs, int client, int mode) {
BotVoiceChat_Defend(bs, client, mode);
}
/*
==================
BotVoiceChat_Patrol
==================
*/
void BotVoiceChat_Patrol(bot_state_t *bs, int client, int mode) {
//
bs->decisionmaker = client;
//
bs->ltgtype = 0;
bs->lead_time = 0;
bs->lastgoal_ltgtype = 0;
//
BotAI_BotInitialChat(bs, "dismissed", NULL);
trap_BotEnterChat(bs->cs, client, CHAT_TELL);
BotVoiceChatOnly(bs, -1, VOICECHAT_ONPATROL);
//
BotSetTeamStatus(bs);
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotVoiceChat_Camp
==================
*/
void BotVoiceChat_Camp(bot_state_t *bs, int client, int mode) {
int areanum;
aas_entityinfo_t entinfo;
char netname[MAX_NETNAME];
//
bs->teamgoal.entitynum = -1;
BotEntityInfo(client, &entinfo);
//if info is valid (in PVS)
if (entinfo.valid) {
areanum = BotPointAreaNum(entinfo.origin);
if (areanum) { // && trap_AAS_AreaReachability(areanum)) {
//NOTE: just assume the bot knows where the person is
//if (BotEntityVisible(bs->entitynum, bs->eye, bs->viewangles, 360, client)) {
bs->teamgoal.entitynum = client;
bs->teamgoal.areanum = areanum;
VectorCopy(entinfo.origin, bs->teamgoal.origin);
VectorSet(bs->teamgoal.mins, -8, -8, -8);
VectorSet(bs->teamgoal.maxs, 8, 8, 8);
//}
}
}
//if the other is not visible
if (bs->teamgoal.entitynum < 0) {
BotAI_BotInitialChat(bs, "whereareyou", EasyClientName(client, netname, sizeof(netname)), NULL);
trap_BotEnterChat(bs->cs, client, CHAT_TELL);
return;
}
//
bs->decisionmaker = client;
bs->ordered = qtrue;
bs->order_time = FloatTime();
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//set the ltg type
bs->ltgtype = LTG_CAMPORDER;
//get the team goal time
bs->teamgoal_time = FloatTime() + TEAM_CAMP_TIME;
//the teammate that requested the camping
bs->teammate = client;
//not arrived yet
bs->arrive_time = 0;
//
BotSetTeamStatus(bs);
// remember last ordered task
BotRememberLastOrderedTask(bs);
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotVoiceChat_FollowMe
==================
*/
void BotVoiceChat_FollowMe(bot_state_t *bs, int client, int mode) {
int areanum;
aas_entityinfo_t entinfo;
char netname[MAX_NETNAME];
bs->teamgoal.entitynum = -1;
BotEntityInfo(client, &entinfo);
//if info is valid (in PVS)
if (entinfo.valid) {
areanum = BotPointAreaNum(entinfo.origin);
if (areanum) { // && trap_AAS_AreaReachability(areanum)) {
bs->teamgoal.entitynum = client;
bs->teamgoal.areanum = areanum;
VectorCopy(entinfo.origin, bs->teamgoal.origin);
VectorSet(bs->teamgoal.mins, -8, -8, -8);
VectorSet(bs->teamgoal.maxs, 8, 8, 8);
}
}
//if the other is not visible
if (bs->teamgoal.entitynum < 0) {
BotAI_BotInitialChat(bs, "whereareyou", EasyClientName(client, netname, sizeof(netname)), NULL);
trap_BotEnterChat(bs->cs, client, CHAT_TELL);
return;
}
//
bs->decisionmaker = client;
bs->ordered = qtrue;
bs->order_time = FloatTime();
//the team mate
bs->teammate = client;
//last time the team mate was assumed visible
bs->teammatevisible_time = FloatTime();
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//get the team goal time
bs->teamgoal_time = FloatTime() + TEAM_ACCOMPANY_TIME;
//set the ltg type
bs->ltgtype = LTG_TEAMACCOMPANY;
bs->formation_dist = 3.5 * 32; //3.5 meter
bs->arrive_time = 0;
//
BotSetTeamStatus(bs);
// remember last ordered task
BotRememberLastOrderedTask(bs);
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotVoiceChat_FollowFlagCarrier
==================
*/
void BotVoiceChat_FollowFlagCarrier(bot_state_t *bs, int client, int mode) {
int carrier;
carrier = BotTeamFlagCarrier(bs);
if (carrier >= 0)
BotVoiceChat_FollowMe(bs, carrier, mode);
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotVoiceChat_ReturnFlag
==================
*/
void BotVoiceChat_ReturnFlag(bot_state_t *bs, int client, int mode) {
//if not in CTF mode
if (
gametype != GT_CTF
#ifdef MISSIONPACK
&& gametype != GT_1FCTF
#endif
) {
return;
}
//
bs->decisionmaker = client;
bs->ordered = qtrue;
bs->order_time = FloatTime();
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//set the ltg type
bs->ltgtype = LTG_RETURNFLAG;
//set the team goal time
bs->teamgoal_time = FloatTime() + CTF_RETURNFLAG_TIME;
bs->rushbaseaway_time = 0;
BotSetTeamStatus(bs);
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotVoiceChat_StartLeader
==================
*/
void BotVoiceChat_StartLeader(bot_state_t *bs, int client, int mode) {
ClientName(client, bs->teamleader, sizeof(bs->teamleader));
}
/*
==================
BotVoiceChat_StopLeader
==================
*/
void BotVoiceChat_StopLeader(bot_state_t *bs, int client, int mode) {
char netname[MAX_MESSAGE_SIZE];
if (!Q_stricmp(bs->teamleader, ClientName(client, netname, sizeof(netname)))) {
bs->teamleader[0] = '\0';
notleader[client] = qtrue;
}
}
/*
==================
BotVoiceChat_WhoIsLeader
==================
*/
void BotVoiceChat_WhoIsLeader(bot_state_t *bs, int client, int mode) {
char netname[MAX_MESSAGE_SIZE];
if (!TeamPlayIsOn()) return;
ClientName(bs->client, netname, sizeof(netname));
//if this bot IS the team leader
if (!Q_stricmp(netname, bs->teamleader)) {
BotAI_BotInitialChat(bs, "iamteamleader", NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_TEAM);
BotVoiceChatOnly(bs, -1, VOICECHAT_STARTLEADER);
}
}
/*
==================
BotVoiceChat_WantOnDefense
==================
*/
void BotVoiceChat_WantOnDefense(bot_state_t *bs, int client, int mode) {
char netname[MAX_NETNAME];
int preference;
preference = BotGetTeamMateTaskPreference(bs, client);
preference &= ~TEAMTP_ATTACKER;
preference |= TEAMTP_DEFENDER;
BotSetTeamMateTaskPreference(bs, client, preference);
//
EasyClientName(client, netname, sizeof(netname));
BotAI_BotInitialChat(bs, "keepinmind", netname, NULL);
trap_BotEnterChat(bs->cs, client, CHAT_TELL);
BotVoiceChatOnly(bs, client, VOICECHAT_YES);
trap_EA_Action(bs->client, ACTION_AFFIRMATIVE);
}
/*
==================
BotVoiceChat_WantOnOffense
==================
*/
void BotVoiceChat_WantOnOffense(bot_state_t *bs, int client, int mode) {
char netname[MAX_NETNAME];
int preference;
preference = BotGetTeamMateTaskPreference(bs, client);
preference &= ~TEAMTP_DEFENDER;
preference |= TEAMTP_ATTACKER;
BotSetTeamMateTaskPreference(bs, client, preference);
//
EasyClientName(client, netname, sizeof(netname));
BotAI_BotInitialChat(bs, "keepinmind", netname, NULL);
trap_BotEnterChat(bs->cs, client, CHAT_TELL);
BotVoiceChatOnly(bs, client, VOICECHAT_YES);
trap_EA_Action(bs->client, ACTION_AFFIRMATIVE);
}
void BotVoiceChat_Dummy(bot_state_t *bs, int client, int mode) {
}
voiceCommand_t voiceCommands[] = {
{VOICECHAT_GETFLAG, BotVoiceChat_GetFlag},
{VOICECHAT_OFFENSE, BotVoiceChat_Offense },
{VOICECHAT_DEFEND, BotVoiceChat_Defend },
{VOICECHAT_DEFENDFLAG, BotVoiceChat_DefendFlag },
{VOICECHAT_PATROL, BotVoiceChat_Patrol },
{VOICECHAT_CAMP, BotVoiceChat_Camp },
{VOICECHAT_FOLLOWME, BotVoiceChat_FollowMe },
{VOICECHAT_FOLLOWFLAGCARRIER, BotVoiceChat_FollowFlagCarrier },
{VOICECHAT_RETURNFLAG, BotVoiceChat_ReturnFlag },
{VOICECHAT_STARTLEADER, BotVoiceChat_StartLeader },
{VOICECHAT_STOPLEADER, BotVoiceChat_StopLeader },
{VOICECHAT_WHOISLEADER, BotVoiceChat_WhoIsLeader },
{VOICECHAT_WANTONDEFENSE, BotVoiceChat_WantOnDefense },
{VOICECHAT_WANTONOFFENSE, BotVoiceChat_WantOnOffense },
{NULL, BotVoiceChat_Dummy}
};
int BotVoiceChatCommand(bot_state_t *bs, int mode, char *voiceChat) {
int i, clientNum;
//int voiceOnly, color;
char *ptr, buf[MAX_MESSAGE_SIZE], *cmd;
if (!TeamPlayIsOn()) {
return qfalse;
}
if ( mode == SAY_ALL ) {
return qfalse; // don't do anything with voice chats to everyone
}
Q_strncpyz(buf, voiceChat, sizeof(buf));
cmd = buf;
for (ptr = cmd; *cmd && *cmd > ' '; cmd++);
while (*cmd && *cmd <= ' ') *cmd++ = '\0';
//voiceOnly = atoi(ptr);
for (ptr = cmd; *cmd && *cmd > ' '; cmd++);
while (*cmd && *cmd <= ' ') *cmd++ = '\0';
clientNum = atoi(ptr);
for (ptr = cmd; *cmd && *cmd > ' '; cmd++);
while (*cmd && *cmd <= ' ') *cmd++ = '\0';
//color = atoi(ptr);
if (!BotSameTeam(bs, clientNum)) {
return qfalse;
}
for (i = 0; voiceCommands[i].cmd; i++) {
if (!Q_stricmp(cmd, voiceCommands[i].cmd)) {
voiceCommands[i].func(bs, clientNum, mode);
return qtrue;
}
}
return qfalse;
}

View file

@ -1,36 +0,0 @@
/*
===========================================================================
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: ai_vcmd.h
*
* desc: Quake3 bot AI
*
* $Archive: /source/code/botai/ai_vcmd.c $
*
*****************************************************************************/
int BotVoiceChatCommand(bot_state_t *bs, int mode, char *voicechat);
void BotVoiceChat_Defend(bot_state_t *bs, int client, int mode);

165
code/game/be_aas.h Normal file
View file

@ -0,0 +1,165 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: be_aas.h
*
* desc: Area Awareness System, stuff exported to the AI
*
* $Archive: /StarTrek/Code-DM/game/be_aas.h $
* $Author: Jmonroe $
* $Revision: 1 $
* $Modtime: 1/21/00 10:12p $
* $Date: 1/25/00 6:26p $
*
*****************************************************************************/
#ifndef MAX_STRINGFIELD
#define MAX_STRINGFIELD 80
#endif
//travel flags
#define TFL_INVALID 0x0000001 //!<traveling temporary not possible
#define TFL_WALK 0x0000002 //!<walking
#define TFL_CROUCH 0x0000004 //!<crouching
#define TFL_BARRIERJUMP 0x0000008 //!<jumping onto a barrier
#define TFL_JUMP 0x0000010 //!<jumping
#define TFL_LADDER 0x0000020 //!<climbing a ladder
#define TFL_WALKOFFLEDGE 0x0000080 //!<walking of a ledge
#define TFL_SWIM 0x0000100 //!<swimming
#define TFL_WATERJUMP 0x0000200 //!<jumping out of the water
#define TFL_TELEPORT 0x0000400 //!<teleporting
#define TFL_ELEVATOR 0x0000800 //!<elevator
#define TFL_ROCKETJUMP 0x0001000 //!<rocket jumping
#define TFL_BFGJUMP 0x0002000 //!<bfg jumping
#define TFL_GRAPPLEHOOK 0x0004000 //!<grappling hook
#define TFL_DOUBLEJUMP 0x0008000 //!<double jump
#define TFL_RAMPJUMP 0x0010000 //!<ramp jump
#define TFL_STRAFEJUMP 0x0020000 //!<strafe jump
#define TFL_JUMPPAD 0x0040000 //!<jump pad
#define TFL_AIR 0x0080000 //!<travel through air
#define TFL_WATER 0x0100000 //!<travel through water
#define TFL_SLIME 0x0200000 //!<travel through slime
#define TFL_LAVA 0x0400000 //!<travel through lava
#define TFL_DONOTENTER 0x0800000 //!<travel through donotenter area
#define TFL_FUNCBOB 0x1000000 //!<func bobbing
#define TFL_FLIGHT 0x2000000 //!<flight
//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;
//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
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
float endcontents; //!<contents at the end of movement prediction
float time; //!<time predicted ahead
int frames; //!<number of frames predicted ahead
} aas_clientmove_t;
typedef struct aas_altroutegoal_s
{
vec3_t origin;
int areanum;
unsigned short starttraveltime;
unsigned short goaltraveltime;
unsigned short extratraveltime;
} aas_altroutegoal_t;

32
code/game/be_ai_char.h Normal file
View file

@ -0,0 +1,32 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: be_ai_char.h
*
* desc: bot characters
*
* $Archive: /StarTrek/Code-DM/game/be_ai_char.h $
* $Author: Jmonroe $
* $Revision: 1 $
* $Modtime: 1/21/00 10:12p $
* $Date: 1/25/00 6:26p $
*
*****************************************************************************/
//!loads a bot character from a file
int BotLoadCharacter(char *charfile, int skill);
//!frees a bot character
void BotFreeCharacter(int character);
//!float characteristic
float Characteristic_Float(int character, int index);
//!bounded float characteristic
float Characteristic_BFloat(int character, int index, float min, float max);
//!integer characteristic
int Characteristic_Integer(int character, int index);
//!bounded integer characteristic
int Characteristic_BInteger(int character, int index, int min, int max);
//!string characteristic
void Characteristic_String(int character, int index, char *buf, int size);
//!free cached bot characters
void BotShutdownCharacters(void);

97
code/game/be_ai_chat.h Normal file
View file

@ -0,0 +1,97 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: be_ai_chat.h
*
* desc: char AI
*
* $Archive: /StarTrek/Code-DM/game/be_ai_chat.h $
* $Author: Jmonroe $
* $Revision: 1 $
* $Modtime: 1/21/00 10:12p $
* $Date: 1/25/00 6:26p $
*
*****************************************************************************/
#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
//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);
//!enters 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 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 client, 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
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);

17
code/game/be_ai_gen.h Normal file
View file

@ -0,0 +1,17 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: be_ai_gen.h
*
* desc: genetic selection
*
* $Archive: /StarTrek/Code-DM/game/be_ai_gen.h $
* $Author: Jmonroe $
* $Revision: 1 $
* $Modtime: 1/21/00 10:12p $
* $Date: 1/25/00 6:27p $
*
*****************************************************************************/
int GeneticParentsAndChildSelection(int numranks, float *ranks, int *parent1, int *parent2, int *child);

95
code/game/be_ai_goal.h Normal file
View file

@ -0,0 +1,95 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: be_ai_goal.h
*
* desc: goal AI
*
* $Archive: /StarTrek/Code-DM/game/be_ai_goal.h $
* $Author: Mgummelt $
* $Revision: 2 $
* $Modtime: 3/12/01 1:53p $
* $Date: 3/12/01 4:43p $
*
*****************************************************************************/
#define MAX_AVOIDGOALS 64
#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
void BotPushGoal(int goalstate, bot_goal_t *goal);
//!pop a goal
void BotPopGoal(int goalstate);
//!makes the bot's goal stack empty
void BotEmptyGoalStack(int goalstate);
//!dump the avoid goals
void BotDumpAvoidGoals(int goalstate);
//!dump the goal stack
void BotDumpGoalStack(int goalstate);
//!name of the goal
void BotGoalName(int number, char *name, int size);
//!get goal from top of stack
int BotGetTopGoal(int goalstate, bot_goal_t *goal);
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, qboolean botRoamsOnly);
//!choose the best nearby goal item for the bot
int BotChooseNBGItem(int goalstate, vec3_t origin, int *inventory, int travelflags,
bot_goal_t *ltg, float maxtime, qboolean botRoamsOnly);
//!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);
//!get some info about a level item
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);
//!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);

108
code/game/be_ai_move.h Normal file
View file

@ -0,0 +1,108 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: be_ai_move.h
*
* desc: movement AI
*
* $Archive: /StarTrek/Code-DM/game/be_ai_move.h $
* $Author: Jmonroe $
* $Revision: 1 $
* $Modtime: 1/21/00 10:12p $
* $Date: 1/25/00 6:27p $
*
*****************************************************************************/
//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 MAX_AVOIDREACH 1
//
#define RESULTTYPE_ELEVATORUP 1 //!<elevator is up
#define RESULTTYPE_WAITFORFUNCBOBBING 2 //!<waiting for func bobbing to arrive
#define RESULTTYPE_BADGRAPPLEPATH 4 //!<grapple path is obstructured
//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;
//!resets the whole movestate
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
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
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
void BotInitMoveState(int handle, bot_initmove_t *initmove);
//!must be called every map change
void BotSetBrushModelTypes(void);
//!setup movement AI
int BotSetupMoveAI(void);
//!shutdown movement AI
void BotShutdownMoveAI(void);

88
code/game/be_ai_weap.h Normal file
View file

@ -0,0 +1,88 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: be_ai_weap.h
*
* desc: weapon AI
*
* $Archive: /StarTrek/Code-DM/game/be_ai_weap.h $
* $Author: Mgummelt $
* $Revision: 2 $
* $Modtime: 3/12/01 3:08p $
* $Date: 3/12/01 4:43p $
*
*****************************************************************************/
//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, qboolean meleeRange);
//!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);

52
code/game/be_ea.h Normal file
View file

@ -0,0 +1,52 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: be_ea.h
*
* desc: elementary actions
*
* $Archive: /StarTrek/Code-DM/game/be_ea.h $
* $Author: Dkramer $
* $Revision: 2 $
* $Modtime: 4/21/00 2:20p $
* $Date: 4/24/00 11:25a $
*
*****************************************************************************/
//ClientCommand elementary actions
void EA_Say(int client, char *str);
void EA_SayTeam(int client, char *str);
void EA_SayClass(int client, char *str);
void EA_UseItem(int client, char *it);
void EA_DropItem(int client, char *it);
void EA_UseInv(int client, char *inv);
void EA_DropInv(int client, char *inv);
void EA_Command(int client, char *command );
//regular elementary actions
void EA_SelectWeapon(int client, int weapon);
void EA_Attack(int client);
void EA_Alt_Attack(int client);
void EA_Respawn(int client);
void EA_Talk(int client);
void EA_Gesture(int client);
void EA_Use(int client);
void EA_Jump(int client);
void EA_DelayedJump(int client);
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_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);

File diff suppressed because it is too large Load diff

View file

@ -1,43 +1,12 @@
/*
===========================================================================
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
===========================================================================
*/
// bg_lib.h -- standard C library replacement routines used by code
// compiled for the virtual machine
// This file is NOT included on native builds
#if !defined( BG_LIB_H ) && defined( Q3_VM )
#define BG_LIB_H
//Ignore __attribute__ on non-gcc platforms
#ifndef __GNUC__
#ifndef __attribute__
#define __attribute__(x)
#endif
#endif
#ifdef Q3_VM
#error "Q3_VM is defined - QVMs are no longer supported by RPG-X2"
#ifndef NULL
#define NULL ((void *)0)
#endif
typedef unsigned int size_t;
typedef int size_t;
typedef char * va_list;
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
@ -45,37 +14,21 @@ typedef char * va_list;
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end(ap) ( ap = (va_list)0 )
#define CHAR_BIT 8 /* number of bits in a char */
#define SCHAR_MAX 0x7f /* maximum signed char value */
#define SCHAR_MIN (-SCHAR_MAX - 1) /* minimum signed char value */
#define UCHAR_MAX 0xff /* maximum unsigned char value */
#define CHAR_BIT 8 /* number of bits in a char */
#define SCHAR_MIN (-128) /* minimum signed char value */
#define SCHAR_MAX 127 /* maximum signed char value */
#define UCHAR_MAX 0xff /* maximum unsigned char value */
#define SHRT_MAX 0x7fff /* maximum (signed) short value */
#define SHRT_MIN (-SHRT_MAX - 1) /* minimum (signed) short value */
#define SHRT_MIN (-32768) /* minimum (signed) short value */
#define SHRT_MAX 32767 /* maximum (signed) short value */
#define USHRT_MAX 0xffff /* maximum unsigned short value */
#define INT_MAX 0x7fffffff /* maximum (signed) int value */
#define INT_MIN (-INT_MAX - 1) /* minimum (signed) int value */
#define INT_MIN (-2147483647 - 1) /* minimum (signed) int value */
#define INT_MAX 2147483647 /* maximum (signed) int value */
#define UINT_MAX 0xffffffff /* maximum unsigned int value */
#define LONG_MAX 0x7fffffffL /* maximum (signed) long value */
#define LONG_MIN (-LONG_MAX - 1) /* minimum (signed) long value */
#define LONG_MIN (-2147483647L - 1) /* minimum (signed) long value */
#define LONG_MAX 2147483647L /* maximum (signed) long value */
#define ULONG_MAX 0xffffffffUL /* maximum unsigned long value */
#define isalnum(c) (isalpha(c) || isdigit(c))
#define isalpha(c) (isupper(c) || islower(c))
#define isascii(c) ((c) > 0 && (c) <= 0x7f)
#define iscntrl(c) (((c) >= 0) && (((c) <= 0x1f) || ((c) == 0x7f)))
#define isdigit(c) ((c) >= '0' && (c) <= '9')
#define isgraph(c) ((c) != ' ' && isprint(c))
#define islower(c) ((c) >= 'a' && (c) <= 'z')
#define isprint(c) ((c) >= ' ' && (c) <= '~')
#define ispunct(c) (((c) > ' ' && (c) <= '~') && !isalnum(c))
#define isspace(c) ((c) == ' ' || (c) == '\f' || (c) == '\n' || (c) == '\r' || \
(c) == '\t' || (c) == '\v')
#define isupper(c) ((c) >= 'A' && (c) <= 'Z')
#define isxdigit(c) (isxupper(c) || isxlower(c))
#define isxlower(c) (isdigit(c) || (c >= 'a' && c <= 'f'))
#define isxupper(c) (isdigit(c) || (c >= 'A' && c <= 'F'))
// Misc functions
typedef int cmp_t(const void *, const void *);
void qsort(void *a, size_t n, size_t es, cmp_t *cmp);
@ -88,7 +41,6 @@ char *strcat( char *strDestination, const char *strSource );
char *strcpy( char *strDestination, const char *strSource );
int strcmp( const char *string1, const char *string2 );
char *strchr( const char *string, int c );
char *strrchr(const char *string, int c);
char *strstr( const char *string, const char *strCharSet );
char *strncpy( char *strDest, const char *strSource, size_t count );
int tolower( int c );
@ -96,14 +48,11 @@ int toupper( int c );
double atof( const char *string );
double _atof( const char **stringPtr );
double strtod( const char *nptr, char **endptr );
int atoi( const char *string );
int _atoi( const char **stringPtr );
long strtol( const char *nptr, char **endptr, int base );
int Q_vsnprintf( char *buffer, size_t length, const char *fmt, va_list argptr );
int sscanf( const char *buffer, const char *fmt, ... ) __attribute__ ((format (scanf, 2, 3)));
int vsprintf( char *buffer, const char *fmt, va_list argptr );
int sscanf( const char *buffer, const char *fmt, ... );
// Memory functions
void *memmove( void *dest, const void *src, size_t count );
@ -120,6 +69,5 @@ double atan2( double y, double x );
double tan( double x );
int abs( int n );
double fabs( double x );
double acos( double x );
#endif // BG_LIB_H
#endif // Q3_VM

View file

@ -1,28 +1,8 @@
/*
===========================================================================
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
===========================================================================
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
// bg_local.h -- local definitions for the bg (both games) files
#define MIN_WALK_NORMAL 0.7f // can't walk on very steep slopes
#define MIN_WALK_NORMAL 0.7 // can't walk on very steep slopes
#define STEPSIZE 18
@ -31,7 +11,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define TIMER_LAND 130
#define TIMER_GESTURE (34*66+50)
#define OVERCLIP 1.001f
#define OVERCLIP 1.001
// all of the locals will be zeroed before each
// pmove, just to make damn sure we don't have
@ -56,20 +37,6 @@ typedef struct {
extern pmove_t *pm;
extern pml_t pml;
// movement parameters
extern float pm_stopspeed;
extern float pm_duckScale;
extern float pm_swimScale;
extern float pm_accelerate;
extern float pm_airaccelerate;
extern float pm_wateraccelerate;
extern float pm_flyaccelerate;
extern float pm_friction;
extern float pm_waterfriction;
extern float pm_flightfriction;
extern int c_pmove;
void PM_ClipVelocity( vec3_t in, vec3_t normal, vec3_t out, float overbounce );
@ -80,3 +47,4 @@ qboolean PM_SlideMove( qboolean gravity );
void PM_StepSlideMove( qboolean gravity );

File diff suppressed because it is too large Load diff

2
code/game/bg_oums.c Normal file
View file

@ -0,0 +1,2 @@

4
code/game/bg_oums.h Normal file
View file

@ -0,0 +1,4 @@
/*
bg_OUMS.h
ONLINE USER MANAGEMENT SYSTEM
*/

12
code/game/bg_panimate.c Normal file
View file

@ -0,0 +1,12 @@
//===========================================================
// Name: bg_panimate.c
// Developer: Timothy 'TiM' Oliver
// Date: 16/2/2006
// Function: Global character animation functions. Utilised
// in CG and G for animation loading + handling.
// Based off of logic from EF SP.
//===========================================================
#include "q_shared.h"
#include "bg_public.h"

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,28 +1,8 @@
/*
===========================================================================
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
===========================================================================
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
// bg_slidemove.c -- part of bg_pmove functionality
#include "../qcommon/q_shared.h"
#include "q_shared.h"
#include "bg_public.h"
#include "bg_local.h"
@ -37,10 +17,11 @@ output: origin, velocity, impacts, stairup boolean
/*
==================
PM_SlideMove
Returns qtrue if the velocity was clipped in some way
==================
*/
/**
* Returns qtrue if the velocity was clipped in some way
*/
#define MAX_CLIP_PLANES 5
qboolean PM_SlideMove( qboolean gravity ) {
int bumpcount, numbumps;
@ -57,20 +38,21 @@ qboolean PM_SlideMove( qboolean gravity ) {
float into;
vec3_t endVelocity;
vec3_t endClipVelocity;
playerState_t *ps = pm->ps;
numbumps = 4;
VectorCopy (pm->ps->velocity, primal_velocity);
VectorCopy (ps->velocity, primal_velocity);
if ( gravity ) {
VectorCopy( pm->ps->velocity, endVelocity );
endVelocity[2] -= pm->ps->gravity * pml.frametime;
pm->ps->velocity[2] = ( pm->ps->velocity[2] + endVelocity[2] ) * 0.5;
VectorCopy( ps->velocity, endVelocity );
endVelocity[2] -= ps->gravity * pml.frametime;
ps->velocity[2] = ( ps->velocity[2] + endVelocity[2] ) * 0.5;
primal_velocity[2] = endVelocity[2];
if ( pml.groundPlane ) {
// slide along the ground plane
PM_ClipVelocity (pm->ps->velocity, pml.groundTrace.plane.normal,
pm->ps->velocity, OVERCLIP );
PM_ClipVelocity (ps->velocity, pml.groundTrace.plane.normal,
ps->velocity, OVERCLIP );
}
}
@ -85,26 +67,26 @@ qboolean PM_SlideMove( qboolean gravity ) {
}
// never turn against original velocity
VectorNormalize2( pm->ps->velocity, planes[numplanes] );
VectorNormalize2( ps->velocity, planes[numplanes] );
numplanes++;
for ( bumpcount=0 ; bumpcount < numbumps ; bumpcount++ ) {
// calculate position we are trying to move to
VectorMA( pm->ps->origin, time_left, pm->ps->velocity, end );
VectorMA( ps->origin, time_left, ps->velocity, end );
// see if we can make it there
pm->trace ( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, pm->tracemask);
pm->trace ( &trace, ps->origin, pm->mins, pm->maxs, end, ps->clientNum, pm->tracemask);
if (trace.allsolid) {
// entity is completely trapped in another solid
pm->ps->velocity[2] = 0; // don't build up falling damage, but allow sideways acceleration
ps->velocity[2] = 0; // don't build up falling damage, but allow sideways acceleration
return qtrue;
}
if (trace.fraction > 0) {
// actually covered some distance
VectorCopy (trace.endpos, pm->ps->origin);
VectorCopy (trace.endpos, ps->origin);
}
if (trace.fraction == 1) {
@ -118,7 +100,7 @@ qboolean PM_SlideMove( qboolean gravity ) {
if (numplanes >= MAX_CLIP_PLANES) {
// this shouldn't really happen
VectorClear( pm->ps->velocity );
VectorClear( ps->velocity );
return qtrue;
}
@ -129,7 +111,7 @@ qboolean PM_SlideMove( qboolean gravity ) {
//
for ( i = 0 ; i < numplanes ; i++ ) {
if ( DotProduct( trace.plane.normal, planes[i] ) > 0.99 ) {
VectorAdd( trace.plane.normal, pm->ps->velocity, pm->ps->velocity );
VectorAdd( trace.plane.normal, ps->velocity, ps->velocity );
break;
}
}
@ -145,7 +127,7 @@ qboolean PM_SlideMove( qboolean gravity ) {
// find a plane that it enters
for ( i = 0 ; i < numplanes ; i++ ) {
into = DotProduct( pm->ps->velocity, planes[i] );
into = DotProduct( ps->velocity, planes[i] );
if ( into >= 0.1 ) {
continue; // move doesn't interact with the plane
}
@ -156,7 +138,7 @@ qboolean PM_SlideMove( qboolean gravity ) {
}
// slide along the plane
PM_ClipVelocity (pm->ps->velocity, planes[i], clipVelocity, OVERCLIP );
PM_ClipVelocity (ps->velocity, planes[i], clipVelocity, OVERCLIP );
// slide along the plane
PM_ClipVelocity (endVelocity, planes[i], endClipVelocity, OVERCLIP );
@ -182,7 +164,7 @@ qboolean PM_SlideMove( qboolean gravity ) {
// slide the original velocity along the crease
CrossProduct (planes[i], planes[j], dir);
VectorNormalize( dir );
d = DotProduct( dir, pm->ps->velocity );
d = DotProduct( dir, ps->velocity );
VectorScale( dir, d, clipVelocity );
CrossProduct (planes[i], planes[j], dir);
@ -200,25 +182,25 @@ qboolean PM_SlideMove( qboolean gravity ) {
}
// stop dead at a tripple plane interaction
VectorClear( pm->ps->velocity );
VectorClear( ps->velocity );
return qtrue;
}
}
// if we have fixed all interactions, try another move
VectorCopy( clipVelocity, pm->ps->velocity );
VectorCopy( clipVelocity, ps->velocity );
VectorCopy( endClipVelocity, endVelocity );
break;
}
}
if ( gravity ) {
VectorCopy( endVelocity, pm->ps->velocity );
VectorCopy( endVelocity, ps->velocity );
}
// don't change velocity if in a timer (FIXME: is this correct?)
if ( pm->ps->pm_time ) {
VectorCopy( primal_velocity, pm->ps->velocity );
if ( ps->pm_time ) {
VectorCopy( primal_velocity, ps->velocity );
}
return ( bumpcount != 0 );
@ -227,20 +209,20 @@ qboolean PM_SlideMove( qboolean gravity ) {
/*
==================
PM_StepSlideMove
==================
*/
void PM_StepSlideMove( qboolean gravity ) {
vec3_t start_o, start_v;
// vec3_t down_o, down_v;
vec3_t down_o, down_v;
vec3_t slideMove, stepUpMove;
trace_t trace;
// float down_dist, up_dist;
// vec3_t delta, delta2;
vec3_t up, down;
float stepSize;
playerState_t *ps = pm->ps;
VectorCopy (pm->ps->origin, start_o);
VectorCopy (pm->ps->velocity, start_v);
VectorCopy (ps->origin, start_o);
VectorCopy (ps->velocity, start_v);
if ( PM_SlideMove( gravity ) == 0 ) {
return; // we got exactly where we wanted to go first try
@ -248,22 +230,22 @@ void PM_StepSlideMove( qboolean gravity ) {
VectorCopy(start_o, down);
down[2] -= STEPSIZE;
pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
pm->trace (&trace, start_o, pm->mins, pm->maxs, down, ps->clientNum, pm->tracemask);
VectorSet(up, 0, 0, 1);
// never step up when you still have up velocity
if ( pm->ps->velocity[2] > 0 && (trace.fraction == 1.0 ||
if ( ps->velocity[2] > 0 && (trace.fraction == 1.0 ||
DotProduct(trace.plane.normal, up) < 0.7)) {
return;
}
//VectorCopy (pm->ps->origin, down_o);
//VectorCopy (pm->ps->velocity, down_v);
VectorCopy (ps->origin, down_o);
VectorCopy (ps->velocity, down_v);
VectorCopy (start_o, up);
up[2] += STEPSIZE;
// test the player position if they were a stepheight higher
pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask);
pm->trace (&trace, up, pm->mins, pm->maxs, up, ps->clientNum, pm->tracemask);
if ( trace.allsolid ) {
if ( pm->debugLevel ) {
Com_Printf("%i:bend can't step\n", c_pmove);
@ -271,31 +253,43 @@ void PM_StepSlideMove( qboolean gravity ) {
return; // can't step up
}
stepSize = trace.endpos[2] - start_o[2];
// try slidemove from this position
VectorCopy (trace.endpos, pm->ps->origin);
VectorCopy (start_v, pm->ps->velocity);
VectorCopy (up, ps->origin);
VectorCopy (start_v, ps->velocity);
PM_SlideMove( gravity );
// push down the final amount
VectorCopy (pm->ps->origin, down);
down[2] -= stepSize;
pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
if ( !trace.allsolid ) {
VectorCopy (trace.endpos, pm->ps->origin);
//compare the initial slidemove and this slidemove from a step up position
VectorSubtract( down_o, start_o, slideMove );
VectorSubtract( trace.endpos, ps->origin, stepUpMove );
if ( fabs(stepUpMove[0]) < 0.1 && fabs(stepUpMove[1]) < 0.1 && VectorLengthSquared( slideMove ) > VectorLengthSquared( stepUpMove ) )
{
//slideMove was better, use it
VectorCopy (down_o, ps->origin);
VectorCopy (down_v, ps->velocity);
}
if ( trace.fraction < 1.0 ) {
PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
else
{
// push down the final amount
VectorCopy (ps->origin, down);
down[2] -= STEPSIZE;
pm->trace (&trace, ps->origin, pm->mins, pm->maxs, down, ps->clientNum, pm->tracemask);
if ( !trace.allsolid ) {
VectorCopy (trace.endpos, ps->origin);
}
if ( trace.fraction < 1.0 ) {
PM_ClipVelocity( ps->velocity, trace.plane.normal, ps->velocity, OVERCLIP );
}
}
#if 0
// if the down trace can trace back to the original position directly, don't step
pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, start_o, pm->ps->clientNum, pm->tracemask);
pm->trace( &trace, ps->origin, pm->mins, pm->maxs, start_o, ps->clientNum, pm->tracemask);
if ( trace.fraction == 1.0 ) {
// use the original move
VectorCopy (down_o, pm->ps->origin);
VectorCopy (down_v, pm->ps->velocity);
VectorCopy (down_o, ps->origin);
VectorCopy (down_v, ps->velocity);
if ( pm->debugLevel ) {
Com_Printf("%i:bend\n", c_pmove);
}
@ -305,7 +299,7 @@ void PM_StepSlideMove( qboolean gravity ) {
// use the step move
float delta;
delta = pm->ps->origin[2] - start_o[2];
delta = ps->origin[2] - start_o[2];
if ( delta > 2 ) {
if ( delta < 7 ) {
PM_AddEvent( EV_STEP_4 );

78
code/game/botai.h Normal file
View file

@ -0,0 +1,78 @@
/*****************************************************************************
* name: botai.h
*
* desc: bot AI
*
* $Archive: /StarTrek/Code-DM/game/botai.h $
* $Author: Jmonroe $
* $Revision: 1 $
* $Modtime: 1/21/00 10:12p $
* $Date: 1/25/00 6:27p $
*
*****************************************************************************/
//some maxs
#define MAX_NETNAME 36
#define MAX_FILEPATH 144
//bot settings
typedef struct bot_settings_s
{
char characterfile[MAX_FILEPATH];
int skill;
char team[MAX_FILEPATH];
} bot_settings_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
// ai_main.c
int BotAISetupClient( int client, bot_settings_t *settings );
//
// imported functions used for the BotAI
//
// from the server
/*
void trap_Cvar_Register( vmCvar_t *cvar, const char *var_name, const char *value, int flags );
void trap_Cvar_Update( vmCvar_t *cvar );
void trap_Cvar_Set( const char *var_name, const char *value );
int trap_Cvar_VariableIntegerValue( const char *var_name );
void trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize );
void trap_GetConfigstring( int num, char *buffer, int bufferSize );
void trap_GetServerinfo( char *buffer, int bufferSize );
int trap_PointContents( const vec3_t point, int passEntityNum );
qboolean trap_InPVS( const vec3_t p1, const vec3_t p2 );
int trap_BotAllocateClient( void );
void trap_BotFreeClient( int clientNum );
*/

475
code/game/botlib.h Normal file
View file

@ -0,0 +1,475 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: botlib.h
*
* desc: bot AI library
*
* $Archive: /StarTrek/Code-DM/game/botlib.h $
* $Author: Mgummelt $
* $Revision: 4 $
* $Modtime: 3/12/01 3:08p $
* $Date: 3/12/01 4:43p $
*
*****************************************************************************/
#define BOTLIB_API_VERSION 2
struct aas_clientmove_s;
struct aas_entityinfo_s;
struct bot_consolemessage_s;
struct bot_match_s;
struct bot_goal_s;
struct bot_moveresult_s;
struct bot_initmove_s;
struct weaponinfo_s;
//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 1
#define ACTION_USE 2
#define ACTION_RESPAWN 4
#define ACTION_JUMP 8
#define ACTION_MOVEUP 8
#define ACTION_CROUCH 16
#define ACTION_MOVEDOWN 16
#define ACTION_MOVEFORWARD 32
#define ACTION_MOVEBACK 64
#define ACTION_MOVELEFT 128
#define ACTION_MOVERIGHT 256
#define ACTION_DELAYEDJUMP 512
#define ACTION_TALK 1024
#define ACTION_GESTURE 2048
#define ACTION_WALK 4096
#define ACTION_ALT_ATTACK 8192
/**
* 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
/**
* entitystate for bots
*/
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);
void (*FreeMemory)(void *ptr);
void *(*HunkAlloc)(int size);
//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;
/**
* needed for bot navigation
*/
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_TraceAreas)(vec3_t start, vec3_t end, int *areas, vec3_t *points, int maxareas);
//--------------------------------------------
// 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);
//--------------------------------------------
// 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_Say)(int client, char *str);
void (*EA_SayTeam)(int client, char *str);
void (*EA_SayClass)(int client, char *str);
void (*EA_UseItem)(int client, char *it);
void (*EA_DropItem)(int client, char *it);
void (*EA_UseInv)(int client, char *inv);
void (*EA_DropInv)(int client, char *inv);
void (*EA_Gesture)(int client);
void (*EA_Command)(int client, char *command );
//regular elementary actions
void (*EA_SelectWeapon)(int client, int weapon);
void (*EA_Talk)(int client);
void (*EA_Attack)(int client);
void (*EA_Alt_Attack)(int client);
void (*EA_Use)(int client);
void (*EA_Respawn)(int client);
void (*EA_Jump)(int client);
void (*EA_DelayedJump)(int client);
void (*EA_Crouch)(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_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, int 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);
//-----------------------------------
// 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, qboolean botRoamsOnly);
int (*BotChooseNBGItem)(int goalstate, vec3_t origin, int *inventory, int travelflags,
struct bot_goal_s *ltg, float maxtime, qboolean botRoamsOnly);
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 (*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);
//-----------------------------------
// be_ai_weap.h
//-----------------------------------
int (*BotChooseBestFightWeapon)(int weaponstate, int *inventory, qboolean meleeRange);
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 (*BotLibDefine)(char *string);
//!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
"sv_friction" "6" be_aas_move.c ground friction
"sv_stopspeed" "100" be_aas_move.c stop speed
"sv_gravity" "800" be_aas_move.c gravity value
"sv_waterfriction" "1" be_aas_move.c water friction
"sv_watergravity" "400" be_aas_move.c gravity in water
"sv_maxvelocity" "320" be_aas_move.c maximum velocity
"sv_maxwalkvelocity" "320" be_aas_move.c maximum walk velocity
"sv_maxcrouchvelocity" "100" be_aas_move.c maximum crouch velocity
"sv_maxswimvelocity" "150" be_aas_move.c maximum swim velocity
"sv_walkaccelerate" "10" be_aas_move.c walk acceleration
"sv_airaccelerate" "1" be_aas_move.c air acceleration
"sv_swimaccelerate" "4" be_aas_move.c swim acceleration
"sv_maxstep" "18" be_aas_move.c maximum step height
"sv_maxsteepness" "0.7" be_aas_move.c maximum floor steepness
"sv_maxbarrier" "32" be_aas_move.c maximum barrier height
"sv_maxwaterjump" "19" be_aas_move.c maximum waterjump height
"sv_jumpvel" "270" be_aas_move.c jump z velocity
"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
"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
*/

Some files were not shown because too many files have changed in this diff Show more